     1                                  ; ****************************************************************************
     2                                  ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Last Update: 02/07/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[06D8]              	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[DED9]              	mov	[mem_1m_1k], cx
   160 00000017 8916[E0D9]              	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[A9D8]                	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[09D8]          <1> 	inc	byte [hdc]	; count of hard disks (EDD present)
    42 0000004E 8816[08D8]          <1>         mov     [last_drv], dl  ; last hard disk number
    43 00000052 BB[8CD7]            <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[0AD8]            <1> 	mov	si, fd0_type
    61                              <1> L3:
    62                              <1> 	; 14/01/2015
    63 00000063 8816[07D8]          <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[0AD8]          <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[09D8]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[07D8]          <1>         mov     [drv], dl
    94 0000008E 8816[08D8]          <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[09D8]          <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[07D8]          <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[07D8]          <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[07D8]          <1> 	inc	byte [drv]
   148 000000FD BB[8CD7]            <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[09D8]            <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[07D8]          <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[07D8]          <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[C0FF]            <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[0CD8]          <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[0AD8]          <1> 	sub	bx, hd0_type - 2 ; 15/01/2015
   188 00000155 81C3[56D8]          <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[56D8]          <1> 	sub	bx, drv.status
   197 00000167 C1E302              <1> 	shl	bx, 2
   198 0000016A 81C3[3AD8]          <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[0CD8]00        <1> 	mov	byte [bx+hd0_type], 0 ; not a valid disk drive !		
   301 000001F4 808F[58D8]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[58D8]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[08D8]          <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[07D8]          <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[56D8]          <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[56D8]          <1> 	sub	bx, drv.status
   353 0000024A D0E3                <1> 	shl	bl, 1
   354 0000024C 81C3[10D8]          <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[10D8]          <1> 	sub	bx, drv.cylinders
   359 00000258 81C3[1ED8]          <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[1ED8]          <1>         sub     bx, drv.heads
   365 00000267 81C3[2CD8]          <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[2CD8]          <1>         sub     bx, drv.spt
   370 00000276 D1E3                <1> 	shl	bx, 1
   371 00000278 81C3[3AD8]          <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[A0D0]                  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 B96C090000              	mov  ecx, (bss_end - bss_start)/4
   276                                  	;shr  ecx, 2 ; bss section is already aligned for double words
   277 000002EA BF[10DA0000]            	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[DED90000]        	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[00DD0000]          	mov	[free_pages], ecx
   301 0000030B 668B15[E0D90000]        	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[00DD0000]          	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[FCDC0000]            	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[10DD0000]          	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[F8DC0000]          	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[08DD0000]            	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[10DD0000]        	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[00DD0000]          	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[FCDC0000]          	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[00DD0000]          	sub	[free_pages], ecx ; 07/11/2014
   430                                  	;
   431 000003F0 8B35[F8DC0000]          	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[F8DC0000]          	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[FCDC0000]          	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[0CDD0000]            	mov	[first_page], eax
   502 0000045F A3[04DD0000]            	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[F8DC0000]                    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[E2D90000]            	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[ACD00000]            	mov	esi, ilist
   594 000004C1 8D3D[10DA0000]          	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[A6D00000]        	lidt 	[idtd]
   641                                  	;
   642                                  	; TSS descriptor setup ; 24/03/2015
   643 0000051A B8[90DC0000]            	mov	eax, task_state_segment
   644 0000051F 66A3[9AD00000]          	mov	[gdt_tss0], ax
   645 00000525 C1C010                  	rol	eax, 16
   646 00000528 A2[9CD00000]            	mov	[gdt_tss1], al
   647 0000052D 8825[9FD00000]          	mov	[gdt_tss2], ah
   648 00000533 66C705[F6DC0000]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[FCDC0000]          	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[94DC0000]          	mov	[tss.esp0], esp
   682 00000561 66C705[98DC0000]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 E800140000              	call	_set_cpos	; 24/01/2016
   709                                  	;
   710                                  	; 06/11/2014
   711 00000585 E8F9180000              	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[0CD80000]          	mov	edx, [hd0_type] ; hd0, hd1, hd2, hd3
   718 00000591 668B1D[0AD80000]        	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[E5D80000]            	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 E839130000              	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 E830280000              	CALL	DSKETTE_SETUP	; Initialize Floppy Disks
   756                                  	;
   757 000005C7 09D2                    	or	edx, edx
   758 000005C9 7407                            jz      short di3
   759                                  di2:
   760 000005CB E86E280000              	call   	DISK_SETUP	; Initialize Fixed Disks
   761 000005D0 72CF                            jc      short setup_error
   762                                  di3:
   763 000005D2 E880180000              	call	setup_rtc_int	; 22/05/2015 (dsectrpm.s)
   764                                  	;
   765 000005D7 E8ECC90000              	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 E8583F0000              	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[26DD0000]          	mov	bl, [ptty]	; active_page
   814 000005EA 89DE                    	mov	esi, ebx
   815 000005EC 66D1E6                  	shl 	si, 1
   816 000005EF 81C6[28DD0000]          	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 E8DB120000              	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[98FE0000]          	mov	[cr3reg], ecx ; save current cr3 register value/content
   914                                  	;
   915 00000646 3B0D[F8DC0000]          	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[D8F10000]            	mov 	[u.r0], eax
   921 00000654 89E1                    	mov	ecx, esp
   922 00000656 83C130                  	add	ecx, ESPACE ; 4 * 12 (stack frame)	
   923 00000659 890D[D0F10000]          	mov	[u.sp], ecx ; kernel stack pointer at the start of interrupt
   924 0000065F 8925[D4F10000]          	mov	[u.usp], esp ; kernel stack points to user's registers   
   925                                  	;
   926 00000665 8B0D[F8DC0000]          	mov	ecx, [k_page_dir]
   927 0000066B 0F22D9                  	mov	cr3, ecx
   928                                  T3:
   929                                  	;sti				; INTERRUPTS BACK ON
   930 0000066E 66FF05[78DD0000]        	INC	word [TIMER_LOW]	; INCREMENT TIME
   931 00000675 7507                    	JNZ	short T4		; GO TO TEST_DAY
   932 00000677 66FF05[7ADD0000]        	INC	word [TIMER_HIGH]	; INCREMENT HIGH WORD OF TIME
   933                                  T4:					; TEST_DAY
   934 0000067E 66833D[7ADD0000]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[78DD0000]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[78DD0000]            	mov	[TIMER_LH], eax
   945                                  	;	
   946 0000069A C605[7CDD0000]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[7FDD0000]            	mov	al, [MOTOR_COUNT]
   957 000006A8 FEC8                    	dec	al
   958                                  	;mov	[CS:MOTOR_COUNT], al	; DECREMENT DISKETTE MOTOR CONTROL
   959 000006AA A2[7FDD0000]            	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[7EDD0000]          	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 E8E3BE0000              	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[7DEA0000]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[7DEA0000]            	mov	[p_change], al ; 0
   997                                  	;
   998 000006DE 803D[CDF10000]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[1AF20000]            	mov	[u.quant], al ; 0
  1006                                  
  1007                                  timer_int_return: ; 23/05/2016 - jump from 'rtc_int' ('rtc_int_2')
  1008 000006EC A1[98FE0000]            	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[CDF10000]          	inc	byte [sysflg] 	; now, we are in system space
  1021                                  	;
  1022 00000702 E988A00000                      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[76DD0000]          	mov	ah, [RTC_2Hz] ;  2 Hz interrupt to 1 Hz function
  1039 00000715 80F401                  	xor	ah, 1
  1040 00000718 8825[76DD0000]          	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[98FE0000]          	mov	[cr3reg], ecx ; save current cr3 register value/content
  1064                                  	;
  1065 0000073A 3B0D[F8DC0000]          	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[D8F10000]            	mov 	[u.r0], eax
  1071 00000748 89E1                    	mov	ecx, esp
  1072 0000074A 83C130                  	add	ecx, ESPACE ; 4 * 12 (stack frame)	
  1073 0000074D 890D[D0F10000]          	mov	[u.sp], ecx ; kernel stack pointer at the start of interrupt
  1074 00000753 8925[D4F10000]          	mov	[u.usp], esp ; kernel stack points to user's registers   
  1075                                  	;
  1076 00000759 8B0D[F8DC0000]          	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[22C80000]        	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[1EC80000]        	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[64D80000]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[64D80000]                  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[B4FF0000]          	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[F8DC0000]          	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 E883310000              	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[B8FF0000]          	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[92D80000]          	mov	[excnstr], ax
  1423                                  	;
  1424                                  	; 29/08/2014
  1425 00000947 A1[B8FF0000]            	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[9DD80000]            	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[4A1F0000]          	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[82D80000]            	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[6CD80000]            	mov	esi, int_msg ; message offset
  1507                                  piemsg:
  1508                                          ; 27/08/2014
  1509 000009A4 8105[64D80000]A000-             add     dword [scr_row], 0A0h
  1509 000009AC 0000               
  1510 000009AE 8B3D[64D80000]                  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 E8183B0000              	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 E82A3B0000              	call	CMOS_READ
  1545 000009DA A2[68DD0000]            	mov	[time_seconds], al 
  1546 000009DF B002                    	mov	al, CMOS_MINUTES
  1547 000009E1 E81E3B0000              	call	CMOS_READ
  1548 000009E6 A2[69DD0000]            	mov	[time_minutes], al 
  1549 000009EB B004                    	mov	al, CMOS_HOURS
  1550 000009ED E8123B0000              	call	CMOS_READ
  1551 000009F2 A2[6ADD0000]                    mov     [time_hours], al
  1552 000009F7 B006                    	mov	al, CMOS_DAY_WEEK 
  1553 000009F9 E8063B0000              	call	CMOS_READ
  1554 000009FE A2[6BDD0000]            	mov	[date_wday], al
  1555 00000A03 B007                     	mov	al, CMOS_DAY_MONTH
  1556 00000A05 E8FA3A0000              	call	CMOS_READ
  1557 00000A0A A2[6CDD0000]            	mov	[date_day], al
  1558 00000A0F B008                    	mov	al, CMOS_MONTH
  1559 00000A11 E8EE3A0000              	call	CMOS_READ
  1560 00000A16 A2[6DDD0000]            	mov	[date_month], al
  1561 00000A1B B009                    	mov	al, CMOS_YEAR
  1562 00000A1D E8E23A0000              	call	CMOS_READ
  1563 00000A22 A2[6EDD0000]            	mov	[date_year], al
  1564 00000A27 B032                    	mov	al, CMOS_CENTURY
  1565 00000A29 E8D63A0000              	call	CMOS_READ
  1566 00000A2E A2[6FDD0000]            	mov	[date_century], al
  1567                                  	;
  1568 00000A33 B000                    	mov	al, CMOS_SECONDS
  1569 00000A35 E8CA3A0000              	call 	CMOS_READ
  1570 00000A3A 3A05[68DD0000]          	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[7FEA0000]00        	cmp	byte [timer_events], 0 ; 07/06/2016
  1592 00000A4A 7649                    	jna	short rtc_p5
  1593                                  
  1594 00000A4C 8A0D[7FEA0000]          	mov	cl, [timer_events]
  1595                                  
  1596 00000A52 BE[9CFE0000]            	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 E8BDBA0000              	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[F2D20000]      <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[F2D20000]        <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[F4D20000]        <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[F1D20000]        <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[02D30000]      <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[FED20000]      <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[02D30000]      <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[FED20000]      <1>         mov     ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
   302 00000BD7 3B1D[02D30000]      <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[FED20000]      <1>         mov    	ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
   317 00000BE8 3B1D[02D30000]      <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[F3D20000]      <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[FED20000]      <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[FED20000]      <1>         mov     ebx, [BUFFER_HEAD]      ; GET HEAD POINTER
   342 00000C22 3B1D[02D30000]      <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[F3D20000]      <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[FAD20000]      <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[F6D20000]      <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[F3D20000]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[F3D20000]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[F3D20000]      <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[F4D20000]      <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[F4D20000]40    <1> 	or	byte [KB_FLAG_3], LC_AB ; INDICATE 1ST ID WAS OK
   614                              <1> RST_RD_ID:
   615 00000D1D 8025[F4D20000]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[F4D20000]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[F1D20000]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[F4D20000]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[F4D20000]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[F4D20000]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[DED10000]        <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[DCD10000]        <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[F2D20000]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[F2D20000]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[F2D20000]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[F2D20000]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[F1D20000]      <1> 	mov	bl, [KB_FLAG]		; PUT STATE FLAGS IN BL
   726 00000E11 BF[D8D10000]        <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[D9D10000]      <1>         sub     edi, _K6+1              ; ADJUST PTR TO SCAN CODE MATCH
   735 00000E2B 8AA7[E0D10000]      <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[F1D20000]      <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[F4D20000]      <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[F2D20000]      <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[F2D20000]      <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[F2D20000]      <1>         or      [KB_FLAG_1], ah 	; INDICATE THAT THE KEY IS DEPRESSED
   791 00000EAE 3025[F1D20000]      <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[F1D20000]      <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[F4D20000]      <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[F2D20000]      <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[F4D20000]        <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[F2D20000]      <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[F1D20000]      <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[F5D20000]        <1> 	mov	al, [ALT_INPUT]
   837 00000F1C B400                <1> 	mov	ah, 0			; SCAN CODE OF 0
   838 00000F1E 8825[F5D20000]      <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[F2D20000]      <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[F2D20000]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[F2D20000]F7    <1> 	and	byte [KB_FLAG_1], ~HOLD_STATE ; TURN OFF THE HOLD STATE BIT
   859                              <1> 	;
   860                              <1> K26:
   861 00000F4D 8025[F4D20000]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[F2D20000]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[B4D10000]        <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[B5D10000]      <1> 	sub	edi, K30+1		; DI NOW HAS ENTRY VALUE
   945 00000FDE A0[F5D20000]        <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[F5D20000]        <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[F5D20000]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[FED20000]      <1> 	mov	ebx, [BUFFER_HEAD] 	; RESET BUFFER TO EMPTY
  1028 00001085 891D[02D30000]      <1> 	mov	[BUFFER_TAIL], ebx
  1029 0000108B C605[F0D20000]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 E81B360000          <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[F2D20000]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[26D30000]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[27D30000]        <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[F2D20000]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[E8D10000]        <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[F4D20000]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[BED10000]        <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[40D20000]        <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[98D20000]        <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[40D20000]        <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[98D20000]        <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[F4D20000]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[F4D20000]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[26DD0000]      <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 E81D040000          <1> 	call	set_active_page
  1264 0000121F 6658                <1> 	pop	ax
  1265                              <1> K61:					; NOT-CAPS-STATE
  1266 00001221 8B1D[02D30000]      <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[FED20000]      <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[02D30000]      <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 E88B070000          <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[F3D20000]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[F3D20000]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[F3D20000]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[F3D20000]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[F3D20000]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[F3D20000]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[F3D20000]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[F3D20000]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[F3D20000]F8    <1> 	and	byte [KB_FLAG_2], 0F8h	; ~KB_LEDS ; CLEAR MODE INDICATOR BITS
  1391 000012F5 0805[F3D20000]      <1> 	or	[KB_FLAG_2], al 	; SAVE PRESENT INDICATORS FOR NEXT TIME
  1392 000012FB F605[F3D20000]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[F3D20000]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[F3D20000]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[F1D20000]        <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: 02/07/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 [CE130000]          <1> M1:	dd	SET_MODE	; TABLE OF ROUTINES WITHIN VIDEO I/O
   191 0000133D [E9150000]          <1> 	dd	SET_CTYPE
   192 00001341 [01160000]          <1> 	dd	SET_CPOS
   193 00001345 [0B160000]          <1> 	dd	READ_CURSOR
   194 00001349 [D3130000]          <1> 	dd	VIDEO_RETURN	; READ_LPEN
   195 0000134D [32160000]          <1> 	dd	ACT_DISP_PAGE
   196 00001351 [B0160000]          <1> 	dd	SCROLL_UP
   197 00001355 [B7170000]          <1> 	dd	SCROLL_DOWN
   198 00001359 [1B180000]          <1> 	dd	READ_AC_CURRENT
   199 0000135D [63180000]          <1> 	dd	WRITE_AC_CURRENT
   200 00001361 [76180000]          <1> 	dd	WRITE_C_CURRENT
   201 00001365 [A61D0000]          <1> 	dd	SET_COLOR
   202 00001369 [E61D0000]          <1> 	dd	WRITE_DOT
   203 0000136D [CF1D0000]          <1> 	dd	READ_DOT
   204 00001371 [E5180000]          <1> 	dd	WRITE_TTY
   205 00001375 [B7130000]          <1> 	dd	VIDEO_STATE
   206 00001379 [D3130000]          <1> 	dd	VIDEO_RETURN	; RESERVED
   207 0000137D [D3130000]          <1> 	dd	VIDEO_RETURN	; RESERVED
   208 00001381 [D3130000]          <1> 	dd	VIDEO_RETURN	; RESERVED
   209 00001385 [3F1A0000]          <1> 	dd	WRITE_STRING  ; 23/06/2016 (TRDOS 386)
   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[74EA0000]        <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> VIDEO_STATE:
   251                              <1> 	; 26/06/2016
   252                              <1> 	; 12/05/2016
   253                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   254                              <1> 
   255                              <1> ;---------------------------------------------------
   256                              <1> ; VIDEO STATE
   257                              <1> ;  RETURNS THE CURRENT VIDEO STATE IN AX
   258                              <1> ;  AH = NUMBER OF COLUMNS ON THE SCREEN
   259                              <1> ;  AL = CURRENT VIDEO MODE
   260                              <1> ;  BH = CURRENT ACTIVE PAGE
   261                              <1> ;---------------------------------------------------
   262                              <1> 
   263 000013B7 8A25[28D30000]      <1> 	mov	ah, [CRT_COLS]	; GET NUMBER OF COLUMNS
   264 000013BD A0[26D30000]        <1> 	mov	al, [CRT_MODE]	; CURRENT MODE
   265                              <1> 	;movzx	esi, al
   266                              <1> 	;mov	ah, [esi+M6] 
   267                              <1> 	; BH = active page
   268 000013C2 8A3D[26DD0000]      <1> 	mov	bh, [ACTIVE_PAGE] ; GET CURRENT ACTIVE PAGE
   269 000013C8 5D                  <1> 	pop	ebp		; RECOVER REGISTERS
   270 000013C9 5F                  <1> 	pop	edi
   271 000013CA 5E                  <1> 	pop	esi
   272 000013CB 59                  <1> 	pop	ecx		; DISCARD SAVED BX
   273 000013CC EB0E                <1> 	jmp	short M15	; RETURN TO CALLER
   274                              <1> 
   275                              <1> 	; 02/07/2016
   276                              <1> 	; 26/06/2016
   277                              <1> 	; 24/06/2016
   278                              <1> 	; 29/05/2016 - TRDOS 386 (TRDOS v2.0)
   279                              <1> SET_MODE:
   280                              <1> 	; For 32 bit TRDOS and Retro UNIX 386:
   281                              <1> 	;	valid video mode: 03h only!
   282                              <1> 	;	(VGA modes will be selected with another routine)
   283                              <1> 	;
   284                              <1> 	; set_txt_mode ; 80*25 (16 fore colors, 8 back colors)
   285                              <1> 
   286                              <1> ;------------------------------------------------------
   287                              <1> ; SET MODE					      :
   288                              <1> ;	THIS ROUTINE INITIALIZES THE ATTACHMENT TO    :
   289                              <1> ;	THE SELECTED MODE, THE SCREEN IS BLANKED.     :
   290                              <1> ; INPUT						      :
   291                              <1> ;	(AL) - MODE SELECTED (RANGE 0-7)	      :
   292                              <1> ; OUTPUT					      :
   293                              <1> ;	NONE					      :
   294                              <1> ;------------------------------------------------------
   295                              <1> 
   296 000013CE E815000000          <1> 	call	_set_mode ; 24/06/2016 (set_txt_mode)
   297                              <1> 
   298                              <1> ; 12/05/2016
   299                              <1> ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   300                              <1> 
   301                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
   302                              <1> 
   303                              <1> VIDEO_RETURN:
   304 000013D3 A1[74EA0000]        <1> 	mov	eax, [video_eax] ; 12/05/2016
   305                              <1> _video_return:
   306 000013D8 5D                  <1> 	pop	ebp
   307 000013D9 5F                  <1> 	pop	edi
   308 000013DA 5E                  <1> 	pop	esi
   309 000013DB 5B                  <1> 	pop	ebx
   310                              <1> M15:	; VIDEO_RETURN_C
   311 000013DC 59                  <1> 	pop	ecx
   312 000013DD 5A                  <1> 	pop	edx
   313 000013DE 1F                  <1> 	pop	ds
   314 000013DF 07                  <1> 	pop	es	; RECOVER SEGMENTS
   315 000013E0 CF                  <1> 	iret		; ALL DONE
   316                              <1> 
   317                              <1> set_txt_mode:
   318                              <1> 	; 27/06/2016
   319 000013E1 B003                <1> 	mov	al, 3
   320 000013E3 E98D000000          <1>         jmp     _sm_3
   321                              <1> 
   322                              <1> ; 02/07/2016
   323                              <1> ; 26/06/2016
   324                              <1> ; 24/06/2016 (set_txt_mode -> _set_mode)
   325                              <1> ; 17/06/2016
   326                              <1> ; 29/05/2016
   327                              <1> ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   328                              <1> _set_mode:
   329                              <1>         ;mov    dx, 03D4h  ; address of color card
   330 000013E8 3C07                <1> 	cmp	al, 7
   331 000013EA 7208                <1> 	jb	short _M8
   332 000013EC 0F87F6010000        <1>         ja      _M15    ; > 7 is not applicable, here!
   333 000013F2 B002                <1> 	mov	al, 2	; force mode 2, text, 80*25, composite	
   334                              <1> _M8:
   335                              <1> 	; 24/06/2016
   336 000013F4 31F6                <1> 	xor	esi, esi
   337 000013F6 3805[26D30000]      <1> 	cmp	[CRT_MODE], al  ; current mode = requested mode ?
   338 000013FC 7536                <1> 	jne	short _sm_1
   339 000013FE 3C03                <1> 	cmp	al, 3		; text, 80*25 color, default mode
   340                              <1> 				; for TRDOS 386 MainProg
   341 00001400 0F859D000000        <1>         jne     M8      ;  multiscreen is only for mode 3
   342                              <1> 
   343                              <1> 	; If '_set_mode' procedure is called for video mode 3
   344                              <1> 	;     while video mode is 3, video page will be cleared
   345                              <1> 	;     and cursor position of video page will be reset.	  
   346                              <1> 	
   347                              <1> 	; set active page start offset address & clear length
   348 00001406 31F6                <1> 	xor	esi, esi
   349 00001408 8A0D[26DD0000]      <1> 	mov	cl, [ACTIVE_PAGE]
   350 0000140E 20C9                <1> 	and	cl, cl
   351 00001410 740D                <1> 	jz	short _sm_0
   352 00001412 66BEA00F            <1> 	mov	si, 80*25*2 ; 4000
   353 00001416 FEC9                <1> 	dec	cl
   354 00001418 7405                <1> 	jz	short _sm_0
   355 0000141A 66D3E6              <1> 	shl	si, cl ; 4000 * video page number (0 to 7)
   356 0000141D 28C9                <1> 	sub	cl, cl ; 0
   357                              <1> _sm_0:
   358 0000141F 668935[14DD0000]    <1> 	mov	[CRT_START], si
   359 00001426 FE05[80EA0000]      <1> 	inc	byte [set_mode_clear]
   360 0000142C 880D[82EA0000]      <1> 	mov	byte [p_crt_mode], cl ; 0
   361 00001432 EB74                <1> 	jmp	short _M9	
   362                              <1> _sm_1:  
   363 00001434 803D[26D30000]03    <1> 	cmp	byte [CRT_MODE], 3
   364 0000143B 7534                <1>         jne     short _sm_2
   365                              <1> 
   366                              <1> 	; If '_set_mode' procedure is called for a video mode
   367                              <1> 	;     except video mode 3, while current video mode
   368                              <1> 	;     is 3; all video pages of mode 3 will be copied 
   369                              <1> 	;     to 0B0000h address as backup, before mode change.	
   370                              <1> 
   371                              <1> 	; save video pages
   372 0000143D BE00800B00          <1> 	mov	esi, 0B8000h
   373 00001442 BF00000B00          <1> 	mov	edi, 0B0000h
   374 00001447 B900200000          <1> 	mov	ecx, (0B8000h-0B0000h)/4
   375 0000144C F3A5                <1> 	rep	movsd	
   376                              <1> 
   377                              <1> 	;mov	byte [set_mode_clear], cl ; 0
   378                              <1> 
   379 0000144E C605[82EA0000]03    <1> 	mov	byte [p_crt_mode], 3 ; previous mode, backup sign
   380 00001455 8A0D[26DD0000]      <1> 	mov	cl, [ACTIVE_PAGE]
   381 0000145B 880D[83EA0000]      <1> 	mov	byte [p_crt_page], cl
   382                              <1> 
   383                              <1> 	; save cursor positions
   384 00001461 BE[16DD0000]        <1> 	mov	esi, CURSOR_POSN
   385 00001466 BF[86EA0000]        <1> 	mov	edi, cursor_pposn    ; cursor positions backup
   386 0000146B B104                <1> 	mov	cl, 4
   387 0000146D F3A5                <1> 	rep	movsd
   388 0000146F EB32                <1> 	jmp	short M8  
   389                              <1>  _sm_2:
   390 00001471 3C03                <1> 	cmp	al, 3		; text, 80*25 color, default mode
   391                              <1> 				; for TRDOS 386 MainProg
   392 00001473 752E                <1> 	jne	short M8  ;  multiscreen is only for mode 3
   393                              <1> 
   394                              <1> 	; If '_set_mode' procedure is called for video mode 3
   395                              <1> 	;     while video mode is not 3 and if there is video
   396                              <1> 	;     page backup for video mode 3, all (of 8) mode 3
   397                              <1> 	;     video pages will be restored from 0B0000h.
   398                              <1> _sm_3:
   399 00001475 803D[82EA0000]03    <1> 	cmp	byte [p_crt_mode], 3 ; previous mode, backup sign
   400 0000147C 7525                <1> 	jne	short M8 ; there is no (multiscreen) video pages
   401                              <1> 			  ; to be restored
   402 0000147E 8A0D[83EA0000]      <1> 	mov	cl, [p_crt_page]
   403 00001484 880D[26DD0000]      <1> 	mov	[ACTIVE_PAGE], cl
   404 0000148A 66BEA00F            <1> 	mov	si, 80*25*2
   405 0000148E 66D3E6              <1> 	shl	si, cl
   406 00001491 6681EEA00F          <1> 	sub	si, 80*25*2
   407 00001496 668935[14DD0000]    <1> 	mov	[CRT_START], si
   408 0000149D FE05[80EA0000]      <1> 	inc	byte [set_mode_clear]
   409                              <1> M8:
   410 000014A3 A2[26D30000]        <1> 	mov	[CRT_MODE], al  ; save mode in global variable
   411                              <1> _M9:
   412 000014A8 0FB6F0              <1> 	movzx	esi, al		; set table pointer, indexed by mode
   413 000014AB 8A86[6AD30000]      <1> 	mov	al, [esi+M7]	; get the mode set value from table
   414 000014B1 A2[27D30000]        <1> 	mov	[CRT_MODE_SET], al ; save the mode set value
   415 000014B6 2437                <1> 	and	al, 037h	; video off, save high resolution bit	
   416                              <1> 	;push	dx  		; save port value
   417                              <1> 	;add	dx, 4		; point to control register
   418 000014B8 66BAD803            <1> 	mov	dx, 3D8h
   419 000014BC EE                  <1> 	out	dx, al		; reset video to off to suppress rolling
   420                              <1> 	;pop	dx
   421                              <1> 	; 24/06/2016
   422 000014BD BB[2AD30000]        <1> 	mov	ebx, video_params ; initialization table
   423 000014C2 B910000000          <1> 	mov	ecx, 16
   424 000014C7 A0[26D30000]        <1> 	mov	al, [CRT_MODE]	; mode number
   425 000014CC 3C02                <1> 	cmp	al, 2		; determine which one to use
   426 000014CE 7208                <1> 	jb	short M9	; mode is 0 or 1
   427 000014D0 01CB                <1> 	add	ebx, ecx	; next row of initialization table
   428 000014D2 3C04                <1> 	cmp	al, 4
   429 000014D4 7202                <1> 	jb	short M9	; mode is 2 or 3
   430 000014D6 01CB                <1> 	add	ebx, ecx	; move to graphics row of init table	
   431                              <1> 
   432                              <1> ;-----	eBX POINTS TO CORRECT ROW OF INITIALIZATION TABLE	
   433                              <1> 
   434                              <1> M9:
   435 000014D8 668B430A            <1> 	mov	ax, [ebx+10]      ; get the cursor mode from the table	
   436 000014DC 86E0                <1> 	xchg 	ah, al
   437 000014DE 66A3[82D30000]      <1> 	mov	[CURSOR_MODE], ax ; save (reset) cursor mode
   438 000014E4 30E4                <1> 	xor	ah, ah		  ; ah is register number during loop 
   439                              <1> 	
   440                              <1> ;-----	LOOP THROUGH TABLE, OUTPUTTING REGISTER ADDRESS, THEN VALUE FROM TABLE
   441                              <1> 	;mov	ecx, 16 ; 16/01/2016
   442                              <1> M10:			;  initialization loop
   443 000014E6 88E0                <1> 	mov	al, ah 	; get 6845 register number
   444 000014E8 EE                  <1> 	out	dx, al
   445 000014E9 6642                <1> 	inc	dx      ; point to data port
   446 000014EB FEC4                <1> 	inc	ah	; next register value
   447 000014ED 8A03                <1> 	mov	al, [ebx] ; get table value
   448 000014EF EE                  <1> 	out	dx, al	; out to chip
   449 000014F0 43                  <1> 	inc	ebx	; next in table
   450 000014F1 664A                <1> 	dec	dx	; back to pointer register
   451 000014F3 E2F1                <1> 	loop	M10	; do the whole table
   452                              <1> 
   453                              <1> 	; 24/06/2016
   454                              <1> 	; TRDOS 386 (TRDOS v2) 'set mode' modification
   455                              <1> 	; (for multiscreen feature):
   456                              <1> 	; If '_set_mode' procedure is called for video mode 3
   457                              <1> 	;     while video mode is 3, video page will be cleared
   458                              <1> 	;     and cursor position of video page will be reset.	  
   459                              <1> 	; If '_set_mode' procedure is called for a video mode
   460                              <1> 	;     except video mode 3, while current video mode
   461                              <1> 	;     is 3; all video pages of mode 3 will be copied 
   462                              <1> 	;     to 0B8000h address as backup, before mode change.	 	
   463                              <1> 	; If '_set_mode' procedure is called for video mode 3
   464                              <1> 	;     while video mode is not 3 and if there is video
   465                              <1> 	;     page backup for video mode 3, all (of 8) mode 3
   466                              <1> 	;     video pages will be restored from 0B0000h.
   467                              <1> 	;
   468                              <1> 	; 24/06/2016
   469 000014F5 380D[80EA0000]      <1> 	cmp	byte [set_mode_clear], cl ; 0
   470 000014FB 7657                <1> 	jna	short M11
   471                              <1> 
   472 000014FD 803D[82EA0000]03    <1> 	cmp	byte [p_crt_mode], 3 
   473 00001504 7520                <1> 	jne	short _M10
   474                              <1> 
   475                              <1> 	; Previous video mode is 3
   476                              <1> 	; New video mode is 3 while current video mode is not 3
   477                              <1> 	; (multi screen) video pages will be restored from 0B0000h
   478                              <1> 
   479                              <1> 	; restore video pages
   480 00001506 BE00000B00          <1> 	mov	esi, 0B0000h
   481 0000150B BF00800B00          <1> 	mov	edi, 0B8000h
   482 00001510 66B90020            <1> 	mov	cx, 8000h/4
   483 00001514 F3A5                <1> 	rep	movsd
   484                              <1> 
   485                              <1> 	; restore cursor positions
   486 00001516 BE[86EA0000]        <1> 	mov	esi, cursor_pposn
   487 0000151B BF[16DD0000]        <1> 	mov	edi, CURSOR_POSN
   488                              <1> 	;mov	ecx, 4	; clear all cursor positions (16 bytes)
   489 00001520 B104                <1> 	mov	cl, 4
   490 00001522 F3A5                <1> 	rep 	movsd
   491                              <1> 
   492 00001524 EB61                <1> 	jmp	short _M13
   493                              <1> _M10:
   494                              <1> 	; clear video page
   495 00001526 66B9D007            <1> 	mov	cx, 80*25 ; ecx = 2000
   496 0000152A 66B82007            <1> 	mov	ax, 0720h
   497 0000152E BF00800B00          <1> 	mov	edi, 0B8000h ; [crt_base]
   498 00001533 66033D[14DD0000]    <1> 	add	di, [CRT_START]
   499 0000153A F366AB              <1> 	rep	stosw	; FILL THE REGEN BUFFER WITH BLANKS
   500 0000153D BF[16DD0000]        <1> 	mov	edi, CURSOR_POSN
   501 00001542 0FB605[26DD0000]    <1> 	movzx	eax, byte [ACTIVE_PAGE]
   502 00001549 D0E0                <1> 	shl	al, 1 ; * 2
   503 0000154B 01C7                <1> 	add	edi, eax
   504 0000154D 30C0                <1> 	xor	al, al
   505 0000154F 668907              <1> 	mov	[edi], ax ; reset cursor position
   506 00001552 EB33                <1> 	jmp	short _M13
   507                              <1> 
   508                              <1> M11:
   509                              <1> ;-----	FILL REGEN AREA WITH BLANK
   510 00001554 6631C0              <1> 	xor	ax, ax  
   511 00001557 66A3[14DD0000]      <1> 	mov	[CRT_START], ax  ; start address saved in global
   512 0000155D A2[26DD0000]        <1> 	mov	[ACTIVE_PAGE], al ; 0 ; (re)set page value
   513 00001562 B900200000          <1> 	mov	ecx, 8192 ; number of words in color card
   514                              <1> 	; 24/06/2016
   515 00001567 803D[26D30000]04    <1> 	cmp	byte [CRT_MODE], 4	; test for graphics
   516 0000156E 7304                <1> 	jnb	short M13		; fill for graphics mode (ax = 0)
   517                              <1> M12:
   518                              <1> 	; black background, light gray character color, space character
   519 00001570 66B82007            <1> 	mov	ax, 0720h ; fill char for alpha - attribute
   520                              <1> M13:			  ; clear buffer
   521                              <1> 	; 24/06/2016
   522 00001574 BF00800B00          <1> 	mov	edi, 0B8000h ; [crt_base]
   523                              <1> 	;	
   524 00001579 F366AB              <1> 	rep	stosw	; FILL THE REGEN BUFFER WITH BLANKS
   525                              <1> 
   526                              <1> ;-----	SET CURSOR POSITIONS
   527 0000157C BF[16DD0000]        <1> 	mov	edi, CURSOR_POSN
   528                              <1> 	;mov	ecx, 4	; clear all cursor positions (16 bytes)
   529 00001581 B104                <1> 	mov	cl, 4
   530 00001583 31C0                <1> 	xor	eax, eax
   531 00001585 F3AB                <1> 	rep 	stosd	; fill with zeroes
   532                              <1> _M13:
   533                              <1> ;-----	ENABLE VIDEO AND CORRECT PORT SETTING
   534                              <1> 	;mov	dx, 3D4h ; mov dx, word [ADDR_6845]
   535                              <1> 			 ; prepare to output to video enable port
   536                              <1> 	;add	dx,4	 ; point to the mode control gerister
   537 00001587 66BAD803            <1> 	mov	dx, 3D8h
   538 0000158B A0[27D30000]        <1> 	mov	al, [CRT_MODE_SET] ; get the mode set value
   539 00001590 EE                  <1> 	out	dx, al	 ; set video enable port
   540                              <1> 
   541                              <1> ;----- 	DETERMINE NUMBER OF COLUMNS, BOTH FOR ENTIRE DISPLAY
   542                              <1> ;----- 	AND THE NUMBER TO BE USED FOR TTY INTERFACE
   543                              <1> 
   544 00001591 0FB635[26D30000]    <1> 	movzx	esi, byte [CRT_MODE] ; 24/06/2016
   545 00001598 8A86[62D30000]      <1> 	mov	al, [esi+M6]   ; get number of columns on this screen
   546 0000159E A2[28D30000]        <1> 	mov	[CRT_COLS], al ; initialize number of columns count
   547                              <1> 	;
   548                              <1> 	;and	si, 000Eh    ; word offset into clear length table
   549 000015A3 6683E606            <1> 	and	si, 6
   550 000015A7 668B86[5AD30000]    <1> 	mov	ax, [esi+M5] ; length to clear
   551                              <1> 
   552 000015AE 66A3[84EA0000]      <1> 	mov	[CRT_LEN], ax
   553                              <1> 
   554                              <1> ;-----	SET UP OVERSCAN REGISTER
   555 000015B4 6642                <1> 	inc	dx	; set overscan port to a default
   556 000015B6 B030                <1> 	mov	al, 30h	; 30H value for all modes except 640X200 bw
   557 000015B8 803D[26D30000]06    <1> 	CMP	byte  [CRT_MODE], 6 ; SEE IF THE MODE IS 640X200 BW
   558 000015BF 7502                <1> 	JNZ	short M14 ; IF NOT 640X200, THEN GO TO REGULAR
   559 000015C1 B03F                <1> 	MOV	AL,3FH	  ; IF IT IS 640X200, THEN PUT IN 3FH
   560                              <1> M14:
   561 000015C3 EE                  <1> 	out	dx, al	; output the correct value to 3D9 port
   562                              <1> 	;mov	[CRT_PALETTE], al ; save the value for future use
   563                              <1> _M14:
   564                              <1> 	; 24/06/2016
   565 000015C4 380D[80EA0000]      <1> 	cmp	byte [set_mode_clear], cl ; 0
   566 000015CA 761C                <1> 	jna	short _M15
   567                              <1> 
   568 000015CC 880D[80EA0000]      <1> 	mov	byte [set_mode_clear], cl ; 0
   569                              <1> 
   570 000015D2 880D[82EA0000]      <1> 	mov	byte [p_crt_mode], cl ; 0
   571                              <1> 
   572 000015D8 0FB61D[26DD0000]    <1> 	movzx	ebx, byte [ACTIVE_PAGE]
   573 000015DF 668B0D[14DD0000]    <1> 	mov	cx, [CRT_START]
   574 000015E6 EB6E                <1> 	jmp	short _M16
   575                              <1> _M15:
   576                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
   577 000015E8 C3                  <1> 	retn
   578                              <1> 
   579                              <1> SET_CTYPE:
   580                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   581 000015E9 E805000000          <1> 	call	_set_ctype
   582 000015EE E9E0FDFFFF          <1>         jmp     VIDEO_RETURN
   583                              <1> 
   584                              <1> _set_ctype:
   585                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
   586                              <1> 	;
   587                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   588                              <1> 
   589                              <1> 	; (CH) = BITS 4-0 = START LINE FOR CURSOR
   590                              <1> 	;  ** HARDWARE WILL ALWAYS CAUSE BLINK
   591                              <1> 	;  ** SETTING BIT 5 OR 6 WILL CAUSE ERRATIC BLINKING
   592                              <1> 	;     OR NO CURSOR AT ALL
   593                              <1> 	; (CL) = BITS 4-0 = END LINE FOR CURSOR
   594                              <1> 
   595                              <1> ;------------------------------------------------
   596                              <1> ; SET_CTYPE
   597                              <1> ;	THIS ROUTINE SETS THE CURSOR VALUE
   598                              <1> ; INPUT
   599                              <1> ;	(CX) HAS CURSOR VALUE CH-START LINE, CL-STOP LINE
   600                              <1> ; OUTPUT	
   601                              <1> ;	NONE
   602                              <1> ;------------------------------------------------
   603                              <1> 
   604 000015F3 B40A                <1> 	mov	ah, 10	; 6845 register for cursor set
   605 000015F5 66890D[82D30000]    <1> 	mov	[CURSOR_MODE], cx ; save in data area
   606                              <1> 	;call	m16	; output cx register
   607                              <1> 	;retn
   608 000015FC E9AF030000          <1>         jmp     m16
   609                              <1> 
   610                              <1> SET_CPOS:
   611                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   612 00001601 E87F030000          <1> 	call	_set_cpos
   613 00001606 E9C8FDFFFF          <1>         jmp     VIDEO_RETURN
   614                              <1> 
   615                              <1> READ_CURSOR:
   616                              <1> 	; 12/05/2016
   617                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   618                              <1> 	;
   619                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   620                              <1> 
   621                              <1> ;------------------------------------------------------
   622                              <1> ; READ_CURSOR
   623                              <1> ;	THIS ROUTINE READS THE CURRENT CURSOR VALUE FROM THE
   624                              <1> ;	845, FORMATS IT, AND SENDS IT BACK TO THE CALLER
   625                              <1> ; INPUT
   626                              <1> ;	BH - PAGE OF CURSOR
   627                              <1> ; OUTPUT
   628                              <1> ;	DX - ROW, COLUMN OF THE CURRENT CURSOR POSITION
   629                              <1> ;	CX - CURRENT CURSOR MODE
   630                              <1> ;------------------------------------------------------
   631                              <1> 
   632                              <1> 	; BH = Video page number (0 to 7)
   633                              <1> 	
   634 0000160B E815000000          <1> 	call	get_cpos
   635 00001610 0FB70D[82D30000]    <1> 	movzx	ecx, word [CURSOR_MODE]
   636                              <1> 
   637 00001617 5D                  <1> 	pop	ebp
   638 00001618 5F                  <1> 	pop	edi
   639 00001619 5E                  <1> 	pop	esi
   640 0000161A 5B                  <1> 	pop	ebx
   641 0000161B 58                  <1> 	pop	eax	; DISCARD SAVED CX AND DX
   642 0000161C 58                  <1> 	pop	eax
   643 0000161D A1[74EA0000]        <1> 	mov	eax, [video_eax] ; 12/05/2016
   644 00001622 1F                  <1> 	pop	ds
   645 00001623 07                  <1> 	pop	es
   646 00001624 CF                  <1> 	iret
   647                              <1> 
   648                              <1> get_cpos:
   649                              <1> 	; 12/05/2016
   650                              <1> 	; 16/01/2016
   651                              <1> 	; BH = Video page number (0 to 7)
   652                              <1> 	;
   653 00001625 D0E7                <1> 	shl	bh, 1 ; WORD OFFSET
   654 00001627 0FB6F7              <1> 	movzx	esi, bh 
   655 0000162A 0FB796[16DD0000]    <1> 	movzx	edx, word [esi+CURSOR_POSN]
   656 00001631 C3                  <1> 	retn
   657                              <1> 
   658                              <1> ACT_DISP_PAGE:
   659                              <1> 	; 26/06/2016
   660                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   661                              <1> 	;
   662                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   663                              <1> 	;
   664                              <1> ;-----------------------------------------------------
   665                              <1> ; ACT_DISP_PAGE
   666                              <1> ;	THIS ROUTINE SETS THE ACTIVE DISPLAY PAGE, ALLOWING
   667                              <1> ;	THE FULL USE OF THE MEMORY SET ASIDE FOR THE VIDEO ATTACHMENT
   668                              <1> ; INPUT
   669                              <1> ;	AL HAS THE NEW ACTIVE DISPLAY PAGE
   670                              <1> ; OUTPUT
   671                              <1> ;	THE 6845 IS RESET TO DISPLAY THAT PAGE
   672                              <1> ;-----------------------------------------------------
   673                              <1> 
   674 00001632 E805000000          <1> 	call	set_active_page
   675 00001637 E997FDFFFF          <1>         jmp     VIDEO_RETURN
   676                              <1> 
   677                              <1> set_active_page:   ; tty_sw
   678                              <1> 	; 26/06/2016
   679                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   680                              <1> 	; 30/06/2015
   681                              <1> 	; 04/03/2014  (act_disp_page --> tty_sw)
   682                              <1> 	; 10/12/2013
   683                              <1> 	; 04/12/2013
   684                              <1> 	;
   685 0000163C A2[26DD0000]        <1> 	mov	[ACTIVE_PAGE], al ; save active page value ; [ptty]
   686                              <1> 	; 27/06/2015
   687 00001641 0FB6D8              <1> 	movzx	ebx, al
   688                              <1> 	;
   689 00001644 6698                <1> 	cbw	; 07/09/2014 (ah=0)
   690 00001646 66F725[84EA0000]    <1> 	mul	word [CRT_LEN]  ; get saved length of regen buffer
   691                              <1> 				; display page times regen length
   692                              <1> 	; 10/12/2013
   693 0000164D 66A3[14DD0000]      <1> 	mov	[CRT_START], ax ; save start address for later
   694 00001653 6689C1              <1> 	mov	cx, ax ; start address to cx
   695                              <1> _M16:
   696                              <1> 	;sar	cx, 1
   697 00001656 66D1E9              <1> 	shr	cx, 1	; divide by 2 for 6845 handling
   698 00001659 B40C                <1> 	mov	ah, 12	; 6845 register for start address
   699 0000165B E850030000          <1> 	call	m16
   700                              <1> 	;sal	bx, 1
   701                              <1> 	; 01/09/2014
   702 00001660 D0E3                <1> 	shl	bl, 1	; *2 for word offset
   703 00001662 81C3[16DD0000]      <1> 	add	ebx, CURSOR_POSN
   704 00001668 668B13              <1> 	mov	dx, [ebx] ; get cursor for this page
   705                              <1> 	; 16/01/2016
   706                              <1> 	;call	m18
   707                              <1> 	;retn
   708 0000166B E92C030000          <1> 	jmp	m18
   709                              <1> 
   710                              <1> position:
   711                              <1> 	; 24/06/2016
   712                              <1> 	; 12/05/2016 - TRDOS 386 (TRDOS v2.0)
   713                              <1> 	; 27/06/2015
   714                              <1> 	; 02/09/2014
   715                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
   716                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1)
   717                              <1> 	;
   718                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   719                              <1> 	;
   720                              <1> ;-----------------------------------------
   721                              <1> ; POSITION
   722                              <1> ;	THIS SERVICE ROUTINE CALCULATES THE REGEN BUFFER ADDRESS
   723                              <1> ;	OF A CHARACTER IN THE ALPHA MODE
   724                              <1> ; INPUT
   725                              <1> ;	AX = ROW, COLUMN POSITION
   726                              <1> ; OUTPUT
   727                              <1> ;	AX = OFFSET OF CHAR POSITION IN REGEN BUFFER
   728                              <1> ;-----------------------------------------
   729                              <1> 
   730                              <1> 	; DX = ROW, COLUMN POSITION
   731 00001670 0FB605[28D30000]    <1> 	movzx	eax, byte [CRT_COLS] ; 24/06/2016
   732 00001677 F6E6                <1> 	mul	dh	 ; row value
   733 00001679 30F6                <1> 	xor	dh, dh   ; 0	
   734 0000167B 6601D0              <1> 	add	ax, dx	 ; add column value to the result
   735 0000167E 66D1E0              <1> 	shl	ax, 1	; * 2 for attribute bytes
   736                              <1> 		; EAX = AX = OFFSET OF CHAR POSITION IN REGEN BUFFER 
   737 00001681 C3                  <1> 	retn
   738                              <1> 
   739                              <1> find_position:
   740                              <1> 	; 24/06/2016
   741                              <1> 	; 12/05/2016 - TRDOS 386 (TRDOS v2.0)
   742                              <1> 	; 27/06/2015
   743                              <1> 	; 07/09/2014
   744                              <1> 	; 02/09/2014
   745                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
   746                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   747                              <1> 
   748 00001682 0FB6CF              <1> 	movzx	ecx, bh ; video page number
   749 00001685 89CE                <1> 	mov	esi, ecx
   750 00001687 66D1E6              <1> 	shl	si, 1
   751 0000168A 668B96[16DD0000]    <1> 	mov	dx, [esi+CURSOR_POSN]
   752 00001691 740C                <1> 	jz	short p21
   753 00001693 6631F6              <1> 	xor	si, si
   754                              <1> p20:
   755 00001696 660335[84EA0000]    <1> 	add	si, [CRT_LEN] ; 24/06/2016
   756                              <1> 	;add	si, 80*25*2 ; add length of buffer for one page		
   757 0000169D E2F7                <1> 	loop	p20
   758                              <1> p21:
   759 0000169F 6621D2              <1> 	and	dx, dx
   760 000016A2 7407                <1> 	jz	short p22
   761 000016A4 E8C7FFFFFF          <1> 	call 	position ; determine location in regen in page
   762 000016A9 01C6                <1> 	add	esi, eax ; add location to start of regen page
   763                              <1> p22:	
   764                              <1> 	;mov	dx, [addr_6845] ; get base address of active display			
   765                              <1> 	;mov	dx, 03D4h ; I/O address of color card
   766                              <1> 	;add	dx, 6	; point at status port
   767 000016AB 66BADA03            <1> 	mov	dx, 03DAh ; status port
   768                              <1> 	; cx = 0
   769 000016AF C3                  <1> 	retn
   770                              <1> 
   771                              <1> SCROLL_UP:
   772                              <1> 	; 26/06/2016
   773                              <1> 	; 12/05/2016
   774                              <1> 	; 30/01/2016
   775                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   776                              <1> 	; 07/09/2014
   777                              <1> 	; 02/09/2014
   778                              <1> 	; 01/09/2014 (Retro UNIX 386 v1 - beginning)
   779                              <1> 	; 04/04/2014
   780                              <1> 	; 04/12/2013
   781                              <1> 	;
   782                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   783                              <1> 	;
   784                              <1> ;----------------------------------------------
   785                              <1> ; SCROLL UP
   786                              <1> ;	THIS ROUTINE MOVES A BLOCK OF CHARACTERS UP
   787                              <1> ;	ON THE SCREEN
   788                              <1> ; INPUT
   789                              <1> ;	(AH) = CURRENT CRT MODE
   790                              <1> ;	(AL) = NUMBER OF ROWS TO SCROLL
   791                              <1> ;	(CX) = ROW/COLUMN OF UPPER LEFT CORNER
   792                              <1> ;	(DX) = ROW/COLUMN OF LOWER RIGHT CORNER
   793                              <1> ;	(BH) = ATTRIBUTE TO BE USED ON BLANKED LINE
   794                              <1> ;	(DS) = DATA SEGMENT
   795                              <1> ;	(ES) = REGEN BUFFER SEGMENT
   796                              <1> ; OUTPUT
   797                              <1> ;	NONE -- THE REGEN BUFFER IS MODIFIED
   798                              <1> ;--------------------------------------------
   799                              <1> 
   800 000016B0 E805000000          <1> 	call	_scroll_up
   801 000016B5 E919FDFFFF          <1>         jmp     VIDEO_RETURN
   802                              <1> 
   803                              <1> _scroll_up:  ; from 'write_tty'
   804                              <1> 	;
   805                              <1> 	; cl = left upper column
   806                              <1> 	; ch = left upper row
   807                              <1> 	; dl = right lower column
   808                              <1> 	; dh = right lower row
   809                              <1> 	;
   810                              <1> 	; al = line count 
   811                              <1> 	; bl = attribute to be used on blanked line	
   812                              <1> 	; bh = video page number (0 to 7)
   813                              <1> 
   814 000016BA E889000000          <1> 	call	test_line_count ; 16/01/2016
   815                              <1> 
   816                              <1> 	;mov	ah, [CRT_MODE] ; current video mode	
   817                              <1> 	;cmp	ah, 4
   818                              <1>  	;jb	short n1
   819 000016BF 803D[26D30000]04    <1> 	cmp	byte [CRT_MODE], 4
   820 000016C6 0F8339040000        <1>         jnb     GRAPHICS_UP ; 26/06/2016
   821                              <1> 
   822                              <1> 	;cmp	ah, 7 ; TEST FOR BW CARD
   823                              <1> 	;jne	GRAPHICS_UP
   824                              <1> n1:
   825 000016CC 88DC                <1> 	mov	ah, bl ; attribute
   826 000016CE 6650                <1> 	push	ax ; *
   827                              <1> 	;mov 	esi, [CRT_BASE]
   828 000016D0 BE00800B00          <1>         mov     esi, 0B8000h  
   829 000016D5 3A3D[26DD0000]      <1>         cmp     bh, [ACTIVE_PAGE]
   830 000016DB 750B                <1> 	jne	short n2
   831                              <1> 	;
   832 000016DD 66A1[14DD0000]      <1>         mov     ax, [CRT_START]
   833 000016E3 6601C6              <1>         add     si, ax
   834 000016E6 EB11                <1>         jmp     short n4
   835                              <1> n2:
   836 000016E8 20FF                <1>         and     bh, bh
   837 000016EA 740D                <1> 	jz	short n4
   838 000016EC 88F8                <1> 	mov	al, bh
   839                              <1> n3:
   840 000016EE 660335[84EA0000]    <1>         add	si, [CRT_LEN]
   841 000016F5 FEC8                <1>         dec	al
   842 000016F7 75F5                <1> 	jnz	short n3
   843                              <1> n4:	
   844 000016F9 E85D000000          <1> 	call	scroll_position ; 16/01/2016
   845 000016FE 7420                <1>         jz      short n6 
   846                              <1> 
   847 00001700 01CE                <1>         add     esi, ecx ; from address for scroll
   848 00001702 88F5                <1> 	mov	ch, dh  ; #rows in block
   849 00001704 28C5                <1> 	sub	ch, al	; #rows to be moved
   850                              <1> n5:
   851 00001706 E894000000          <1> 	call	n10 ; 16/01/2016
   852                              <1> 	
   853 0000170B 51                  <1>         push	ecx
   854 0000170C 0FB60D[28D30000]    <1> 	movzx	ecx, byte [CRT_COLS] 
   855 00001713 00C9                <1> 	add	cl, cl
   856 00001715 01CE                <1>         add	esi, ecx  ; next line
   857 00001717 01CF                <1>         add	edi, ecx
   858 00001719 59                  <1> 	pop	ecx
   859                              <1> 
   860 0000171A FECD                <1> 	dec	ch	 ; count of lines to move
   861 0000171C 75E8                <1> 	jnz	short n5 ; row loop
   862                              <1> 	; ch = 0
   863 0000171E 88C6                <1> 	mov	dh, al	 ; #rows	
   864                              <1> n6:
   865                              <1> 	; attribute in ah
   866 00001720 B020                <1> 	mov	al, ' '	 ; fill with blanks
   867                              <1> n7:
   868 00001722 E885000000          <1> 	call	n11 ; 16/01/2016
   869                              <1> 
   870 00001727 8A0D[28D30000]      <1> 	mov	cl, [CRT_COLS]
   871 0000172D 00C9                <1> 	add	cl, cl
   872 0000172F 01CF                <1>         add	edi, ecx
   873                              <1> 
   874 00001731 FECE                <1> 	dec	dh
   875 00001733 75ED                <1> 	jnz	short n7
   876                              <1> n16:
   877 00001735 3A3D[26DD0000]      <1> 	cmp	bh, [ACTIVE_PAGE]
   878 0000173B 750A                <1> 	jne	short n8
   879                              <1> 	
   880                              <1> 	;cmp	byte [CRT_MODE], 7	; is this the black and white card
   881                              <1> 	;je	short n8		; if so, skip the mode reset
   882                              <1> 
   883 0000173D A0[27D30000]        <1> 	mov	al, [CRT_MODE_SET] ; get the value of mode set
   884 00001742 66BAD803            <1> 	mov	dx, 03D8h ; always set color card port
   885 00001746 EE                  <1> 	out	dx, al
   886                              <1> n8:
   887 00001747 C3                  <1> 	retn
   888                              <1> 
   889                              <1> test_line_count:
   890                              <1> 	; 12/05/2016
   891                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   892                              <1> 	; 07/09/2014 (scroll_up)
   893 00001748 08C0                <1> 	or	al, al
   894 0000174A 740E                <1> 	jz	short al_set2
   895 0000174C 6652                <1> 	push	dx
   896 0000174E 28EE                <1> 	sub	dh, ch  ; subtract upper row from lower row number
   897 00001750 FEC6                <1> 	inc	dh	; adjust difference by 1
   898 00001752 38C6                <1> 	cmp	dh, al 	; line count = amount of rows in window?
   899 00001754 7502                <1> 	jne	short al_set1 ; if not the we're all set
   900 00001756 30C0                <1> 	xor	al, al	; otherwise set al to zero
   901                              <1> al_set1:
   902 00001758 665A                <1> 	pop	dx
   903                              <1> al_set2:
   904 0000175A C3                  <1> 	retn
   905                              <1> 
   906                              <1> scroll_position:
   907                              <1> 	; 26/06/2016
   908                              <1> 	; 30/01/2016
   909                              <1>         ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   910                              <1> 	; 07/09/2014 (scroll_up)
   911                              <1> 
   912 0000175B 6652                <1> 	push	dx
   913 0000175D 6689CA              <1> 	mov	dx, cx	; now, upper left position in DX
   914 00001760 E80BFFFFFF          <1> 	call	position
   915 00001765 01C6                <1> 	add	esi, eax
   916 00001767 89F7                <1> 	mov	edi, esi
   917 00001769 665A                <1> 	pop	dx	; lower right position in DX
   918 0000176B 6629CA              <1> 	sub	dx, cx
   919 0000176E FEC6                <1> 	inc	dh	; dh = #rows 
   920 00001770 FEC2                <1> 	inc	dl	; dl = #cols in block
   921 00001772 59                  <1> 	pop	ecx 	; return address
   922 00001773 6658                <1> 	pop	ax	; * ; al = line count, ah = attribute
   923 00001775 51                  <1> 	push	ecx	; return address
   924 00001776 0FB7C8              <1> 	movzx	ecx, ax
   925 00001779 8A25[28D30000]      <1> 	mov	ah, [CRT_COLS]
   926 0000177F F6E4                <1> 	mul	ah	; determine offset to from address
   927 00001781 6601C0              <1> 	add	ax, ax  ; *2 for attribute byte
   928                              <1> 	;
   929 00001784 6650                <1> 	push	ax	; offset 
   930 00001786 6652                <1> 	push	dx
   931                              <1> 	;
   932                              <1> 	; 04/04/2014
   933 00001788 66BADA03            <1> 	mov	dx, 3DAh ; guaranteed to be color card here	
   934                              <1> n9:                      ; wait_display_enable
   935 0000178C EC                  <1>         in      al, dx   ; get port
   936 0000178D A808                <1> 	test	al, RVRT ; wait for vertical retrace	
   937 0000178F 74FB                <1> 	jz	short n9 ; wait_display_enable
   938 00001791 B025                <1> 	mov	al, 25h
   939 00001793 B2D8                <1> 	mov	dl, 0D8h ; address control port
   940 00001795 EE                  <1> 	out	dx, al	; turn off video during vertical retrace
   941 00001796 665A                <1> 	pop	dx	; #rows, #cols
   942 00001798 6658                <1>        	pop	ax	; offset
   943 0000179A 6691                <1> 	xchg	ax, cx	; 
   944                              <1> 	; ecx = offset, al = line count, ah = attribute
   945                              <1> 	;
   946 0000179C 08C0                <1> 	or	al, al
   947 0000179E C3                  <1> 	retn
   948                              <1> n10:
   949                              <1> 	; Move rows
   950 0000179F 88D1                <1> 	mov	cl, dl	; get # of cols to move
   951 000017A1 56                  <1> 	push	esi
   952 000017A2 57                  <1> 	push	edi	; save start address
   953                              <1> n10r:
   954 000017A3 66A5                <1> 	movsw		; move that line on screen
   955 000017A5 FEC9                <1> 	dec	cl
   956 000017A7 75FA                <1>         jnz     short n10r
   957 000017A9 5F                  <1> 	pop	edi
   958 000017AA 5E                  <1> 	pop	esi	; recover addresses
   959 000017AB C3                  <1> 	retn
   960                              <1> n11:
   961                              <1> 	; Clear rows
   962                              <1>                 	; dh =  #rows
   963 000017AC 88D1                <1>         mov	cl, dl	; get # of cols to clear
   964 000017AE 57                  <1>         push    edi     ; save address
   965                              <1> n11r:
   966 000017AF 66AB                <1>         stosw           ; store fill character
   967 000017B1 FEC9                <1> 	dec	cl
   968 000017B3 75FA                <1>         jnz     short n11r
   969 000017B5 5F                  <1>         pop     edi     ; recover address
   970 000017B6 C3                  <1> 	retn
   971                              <1> 
   972                              <1> SCROLL_DOWN:
   973                              <1> 	; 27/06/2016
   974                              <1> 	; 26/06/2016
   975                              <1> 	; 12/05/2016
   976                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   977                              <1> 	;
   978                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   979                              <1> 
   980                              <1> ;------------------------------------------
   981                              <1> ; SCROLL DOWN
   982                              <1> ;	THIS ROUTINE MOVES THE CHARACTERS WITHIN A DEFINED
   983                              <1> ;	BLOCK DOWN ON THE SCREEN, FILLING THE TOP LINES
   984                              <1> ;	WITH A DEFINED CHARACTER
   985                              <1> ; INPUT
   986                              <1> ;	(AH) = CURRENT CRT MODE
   987                              <1> ;	(AL) = NUMBER OF LINES TO SCROLL
   988                              <1> ;	(CX) = UPPER LEFT CORNER OF RECION
   989                              <1> ;	(DX) = LOWER RIGHT CORNER OF REGION
   990                              <1> ;	(BH) = FILL CHARACTER
   991                              <1> ;	(DS) = DATA SEGMENT
   992                              <1> ;	(ES) = REGEN SEGMENT
   993                              <1> ; OUTPUT
   994                              <1> ;	NONE -- SCREEN IS SCROLLED
   995                              <1> ;------------------------------------------
   996                              <1> 
   997 000017B7 E805000000          <1> 	call	_scroll_down
   998 000017BC E912FCFFFF          <1>         jmp     VIDEO_RETURN
   999                              <1> 
  1000                              <1> _scroll_down: ; 27/06/2016
  1001                              <1> 
  1002                              <1> 	; cl = left upper column
  1003                              <1> 	; ch = left upper row
  1004                              <1> 	; dl = right lower column
  1005                              <1> 	; dh = right lower row
  1006                              <1> 	;
  1007                              <1> 	; al = line count 
  1008                              <1> 	; bl = attribute to be used on blanked line	
  1009                              <1> 	; bh = video page number (0 to 7)
  1010                              <1> 
  1011                              <1> 	; !!!!
  1012 000017C1 FD                  <1> 	std		; DIRECTION FOR SCROLL DOWN
  1013                              <1> 	; !!!!
  1014 000017C2 E881FFFFFF          <1> 	call	test_line_count ; 16/01/2016
  1015                              <1> 	
  1016                              <1> 	;mov	ah, [CRT_MODE] ; current video mode	
  1017                              <1> 	;cmp	ah, 4
  1018                              <1>  	;jb	short n12
  1019 000017C7 803D[26D30000]04    <1> 	cmp	byte [CRT_MODE], 4
  1020 000017CE 0F8397030000        <1>         jnb     GRAPHICS_DOWN ; 26/06/2016
  1021                              <1> 
  1022                              <1> 	;cmp	ah, 7 ; TEST FOR BW CARD
  1023                              <1> 	;jne	GRAPHICS_DOWN
  1024                              <1> 
  1025                              <1> n12:			; CONTINUE_DOWN
  1026 000017D4 88DC                <1> 	mov	ah, bl
  1027 000017D6 6650                <1> 	push	ax	; * ; save attribute in ah
  1028 000017D8 6689D0              <1> 	mov	ax, dx	; LOWER RIGHT CORNER
  1029 000017DB E87BFFFFFF          <1> 	call	scroll_position	; GET REGEN LOCATION
  1030 000017E0 741F                <1> 	jz	short n14
  1031 000017E2 29CE                <1> 	sub	esi, ecx  ; SI IS FROM ADDRESS
  1032 000017E4 88F5                <1> 	mov	ch, dh  ; #rows in block
  1033 000017E6 28C5                <1> 	sub	ch, al	; #rows to be moved
  1034                              <1> n13:
  1035 000017E8 E8B2FFFFFF          <1> 	call	n10	; MOVE ONE ROW
  1036                              <1> 
  1037 000017ED 51                  <1> 	push	ecx
  1038 000017EE 8A0D[28D30000]      <1> 	mov	cl, [CRT_COLS] 
  1039 000017F4 00C9                <1> 	add	cl, cl
  1040 000017F6 29CE                <1>         sub	esi, ecx  ; next line
  1041 000017F8 29CF                <1>         sub	edi, ecx
  1042 000017FA 59                  <1>         pop	ecx
  1043                              <1> 	
  1044 000017FB FECD                <1> 	dec	ch	 ; count of lines to move
  1045 000017FD 75E9                <1> 	jnz	short n13 ; row loop
  1046                              <1> 	; ch = 0
  1047 000017FF 88C6                <1> 	mov	dh, al	 ; #rows
  1048                              <1> n14:
  1049                              <1> 	; attribute in ah
  1050 00001801 B020                <1> 	mov	al, ' '	 ; fill with blanks
  1051                              <1> n15:
  1052 00001803 E8A4FFFFFF          <1> 	call	n11 ; 16/01/2016
  1053                              <1> 
  1054 00001808 8A0D[28D30000]      <1> 	mov	cl, [CRT_COLS]
  1055 0000180E 00C9                <1> 	add	cl, cl
  1056 00001810 29CF                <1>         sub	edi, ecx
  1057                              <1>         
  1058 00001812 FECE                <1> 	dec	dh
  1059 00001814 75ED                <1> 	jnz	short n15
  1060                              <1> 	;
  1061 00001816 E91AFFFFFF          <1> 	jmp	n16 ; 27/06/2016
  1062                              <1> 
  1063                              <1> ;	cmp	bh, [ACTIVE_PAGE]
  1064                              <1> ;	jne	short n16
  1065                              <1> ;
  1066                              <1> ;	;cmp	byte [CRT_MODE], 7	; is this the black and white card
  1067                              <1> ;	;je	short n16		; if so, skip the mode reset
  1068                              <1> ;
  1069                              <1> ;	mov	al, [CRT_MODE_SET] ; get the value of mode set
  1070                              <1> ;	mov	dx, 03D8h ; always set color card port
  1071                              <1> ;	out	dx, al
  1072                              <1> ;n16:
  1073                              <1> ;	; !!!!
  1074                              <1> ;	cld		; Clear direction flag !
  1075                              <1> ;	; !!!!
  1076                              <1> ;	retn
  1077                              <1> 
  1078                              <1> READ_AC_CURRENT:
  1079                              <1> 	; 26/06/2016
  1080                              <1> 	; 12/05/2016
  1081                              <1> 	; 18/01/2016
  1082                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  1083                              <1> 	;
  1084                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  1085                              <1> 	;
  1086                              <1> 
  1087 0000181B E805000000          <1> 	call	_read_ac_current
  1088                              <1> 	; 12/05/2016
  1089                              <1>         ;jmp     VIDEO_RETURN
  1090 00001820 E9B3FBFFFF          <1> 	jmp	_video_return
  1091                              <1> 
  1092                              <1> ;------------------------------------------------------------------------
  1093                              <1> ; READ_AC_CURRENT							:
  1094                              <1> ;	THIS ROUTINE READS THE ATTRIBUTE AND CHARACTER AT THE CURRENT	:
  1095                              <1> ;	CURSOR POSITION AND RETURNS THEM TO THE CALLER			:
  1096                              <1> ; INPUT									:
  1097                              <1> ;	(AH) = CURRENT CRT MODE						:
  1098                              <1> ;	(BH) = DISPLAY PAGE ( ALPHA MODES ONLY )			:
  1099                              <1> ;	(DS) = DATA SEGMENT						:
  1100                              <1> ;	(ES) = REGEN SEGMENT						:
  1101                              <1> ; OUTPUT								:
  1102                              <1> ;	(AL) = CHARACTER READ						:
  1103                              <1> ;	(AH) = ATTRIBUTE READ						:
  1104                              <1> ;------------------------------------------------------------------------
  1105                              <1> 
  1106                              <1> _read_ac_current:
  1107                              <1> 	; 26/06/2016
  1108                              <1> 	; 12/05/2016 
  1109                              <1> 	; 18/01/2016
  1110                              <1> 
  1111                              <1> 	;mov	ah, [CRT_MODE] ; current video mode	
  1112                              <1> 	;cmp	ah, 4
  1113                              <1>  	;jb	short p10
  1114 00001825 803D[26D30000]04    <1> 	cmp	byte [CRT_MODE], 4
  1115 0000182C 0F839E040000        <1>         jnb     GRAPHICS_READ ; 26/06/2016
  1116                              <1> 
  1117                              <1> 	;cmp	ah, 7 ; TEST FOR BW CARD
  1118                              <1> 	;jne	GRAPHICS_READ
  1119                              <1> p10:
  1120 00001832 E84BFEFFFF          <1> 	call	find_position	; GET REGEN LOCATION AND PORT ADDRESS
  1121                              <1> 	;
  1122                              <1> 	; esi = regen location
  1123                              <1> 	; dx = status port
  1124                              <1> 	;
  1125 00001837 8A25[26D30000]      <1> 	mov	ah, [CRT_MODE]	
  1126 0000183D 80EC02              <1> 	sub	ah, 2
  1127 00001840 D0EC                <1> 	shr	ah, 1
  1128 00001842 7515                <1> 	jnz	short p13
  1129                              <1> 
  1130                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE IF COLOR 80
  1131                              <1> p11:
  1132 00001844 FB                  <1> 	sti		; enable interrupts first
  1133 00001845 3A3D[26DD0000]      <1> 	cmp     bh, [ACTIVE_PAGE]
  1134 0000184B 750C                <1> 	jne	short p13 
  1135 0000184D FA                  <1> 	cli 		; block interrupts for single loop
  1136 0000184E EC                  <1> 	in	al, dx	; get status from the adapter
  1137 0000184F A801                <1> 	test	al, RHRZ ; is horizontal retrace low
  1138 00001851 75F1                <1> 	jnz	short p11 ; wait until it is
  1139                              <1> p12:			;  wait for either retrace high
  1140 00001853 EC                  <1> 	in	al, dx ; get status again
  1141 00001854 A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
  1142 00001856 74FB                <1> 	jz	short p12 ; wait until either retrace active
  1143 00001858 FB                  <1> 	sti
  1144                              <1> p13:
  1145 00001859 81C600800B00        <1> 	add	esi, 0B8000h 
  1146 0000185F 668B06              <1> 	mov	ax, [esi]
  1147                              <1> 
  1148 00001862 C3                  <1> 	retn	; 18/01/2016
  1149                              <1> 
  1150                              <1> WRITE_AC_CURRENT:
  1151                              <1> 	; 26/06/2016
  1152                              <1> 	; 24/06/2016
  1153                              <1> 	; 12/05/2016
  1154                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  1155                              <1> 	;
  1156                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  1157                              <1> 	;
  1158                              <1> ;----------------------------------------------------------------
  1159                              <1> ; WRITE_AC_CURRENT						:
  1160                              <1> ;	THTS ROUTINE WRITES THE ATTRIBUTE AND CHARACTER		:
  1161                              <1> ;	AT THE CURRENT CURSOR POSITION				:
  1162                              <1> ; INPUT								:
  1163                              <1> ;	(AH) = CURRENT CRT MODE					:
  1164                              <1> ;	(BH) = DISPLAY PAGE					:
  1165                              <1> ;	(CX) = COUNT OF CHARACTERS TO WRITE			:
  1166                              <1> ;	(AL) = CHAR TO WRITE					:
  1167                              <1> ;	(BL) = ATTRIBUTE OF CHAR TO WRITE			:
  1168                              <1> ;	(DS) = DATA SEGMENT					:
  1169                              <1> ;	(ES) = REGEN SEGMENT					:
  1170                              <1> ; OUTPUT							:
  1171                              <1> ;	DISPLAY REGEN BUFFER UPDATED				:
  1172                              <1> ;----------------------------------------------------------------
  1173                              <1> 
  1174 00001863 E821000000          <1> 	call	_write_c_current
  1175                              <1> 
  1176 00001868 0FB6F7              <1> 	movzx	esi, bh ; video page number (0 to 7)	
  1177 0000186B 889E[72D30000]      <1> 	mov	[esi+chr_attrib], bl ; color/attribute
  1178                              <1> 
  1179 00001871 E95DFBFFFF          <1>         jmp     VIDEO_RETURN
  1180                              <1> 
  1181                              <1> WRITE_C_CURRENT:
  1182                              <1> 	; 26/06/2016
  1183                              <1> 	; 12/05/2016
  1184                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  1185                              <1> 	;
  1186                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  1187                              <1> 	;
  1188                              <1> ;----------------------------------------------------------------
  1189                              <1> ; WRITE_C_CURRENT						:
  1190                              <1> ;	THIS ROUTINE WRITES THE CHARACTER AT			:
  1191                              <1> ;	THE CURRENT CURSOR POSITION, ATTRIBUTE UNCHANGED	:
  1192                              <1> ; INPUT								:
  1193                              <1> ;	(AH) = CURRENT CRT MODE					:
  1194                              <1> ;	(BH) = DISPLAY PAGE					:
  1195                              <1> ;	(CX) = COUNT OF CHARACTERS TO WRITE			:
  1196                              <1> ;	(AL) = CHAR TO WRITE					:
  1197                              <1> ;	(DS) = DATA SEGMENT					:
  1198                              <1> ;	(ES) = REGEN SEGMENT					:
  1199                              <1> ; OUTPUT							:
  1200                              <1> ;	DISPLAY REGEN BUFFER UPDATED				:
  1201                              <1> ;----------------------------------------------------------------
  1202                              <1> 
  1203                              <1> 	;and	bh, 7 ; video page number (<= 7)
  1204 00001876 0FB6F7              <1> 	movzx	esi, bh	
  1205 00001879 8A9E[72D30000]      <1> 	mov	bl, [esi+chr_attrib]
  1206                              <1> 
  1207 0000187F E805000000          <1> 	call	_write_c_current
  1208 00001884 E94AFBFFFF          <1>         jmp     VIDEO_RETURN
  1209                              <1> 
  1210                              <1> _write_c_current:  ; from 'write_tty'
  1211                              <1> 	; 26/06/2016
  1212                              <1> 	; 24/06/2016
  1213                              <1> 	; 12/05/2016
  1214                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  1215                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1216                              <1> 	; 18/01/2014
  1217                              <1> 	; 04/12/2013
  1218                              <1> 	;
  1219                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  1220                              <1> 
  1221                              <1> 	;mov	ah, [CRT_MODE] ; current video mode	
  1222                              <1> 	;cmp	ah, 4
  1223                              <1>  	;jb	short p40
  1224 00001889 803D[26D30000]04    <1> 	cmp	byte [CRT_MODE], 4
  1225 00001890 0F8371030000        <1>         jnb     GRAPHICS_WRITE ; 26/06/2016
  1226                              <1> 
  1227                              <1> 	;cmp	ah, 7 ; TEST FOR BW CARD
  1228                              <1> 	;jne	GRAPHICS_WRITE
  1229                              <1> p40:
  1230                              <1> 	; al = character
  1231                              <1> 	; bl = color/attribute
  1232                              <1> 	; bh = video page
  1233                              <1> 	; cx = count of characters to write
  1234 00001896 6652                <1> 	push	dx
  1235 00001898 88DC                <1> 	mov	ah, bl  ; color/attribute (12/05/2016)
  1236 0000189A 6650                <1> 	push	ax	; save character & attribute/color
  1237 0000189C 6651                <1> 	push	cx
  1238 0000189E E8DFFDFFFF          <1> 	call 	find_position  ; get regen location and port address
  1239 000018A3 6659                <1> 	pop	cx
  1240                              <1> 	; esi = regen location
  1241                              <1> 	; dx = status port
  1242                              <1> 	;
  1243 000018A5 81C600800B00        <1> 	add	esi, 0B8000h ; 30/08/2014 (crt_base) 
  1244                              <1> 	;
  1245 000018AB 8A25[26D30000]      <1> 	mov	ah, [CRT_MODE]	
  1246 000018B1 80EC02              <1> 	sub	ah, 2
  1247 000018B4 D0EC                <1> 	shr	ah, 1
  1248 000018B6 7519                <1> 	jnz	short p44    ; 26/06/2016
  1249                              <1> 
  1250                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE IF COLOR 80
  1251                              <1> p41:
  1252 000018B8 FB                  <1> 	sti		; enable interrupts first
  1253 000018B9 3A3D[26DD0000]      <1> 	cmp     bh, [ACTIVE_PAGE]
  1254 000018BF 7510                <1> 	jne	short p44 
  1255 000018C1 FA                  <1> 	cli 		; block interrupts for single loop
  1256 000018C2 EC                  <1> 	in	al, dx	; get status from the adapter
  1257 000018C3 A808                <1> 	test	al, RVRT ; check for vertical retrace first
  1258 000018C5 7509                <1> 	jnz	short p43 ; Do fast write now if vertical retrace
  1259 000018C7 A801                <1> 	test	al, RHRZ ; is horizontal retrace low
  1260 000018C9 75ED                <1> 	jnz	short p41 ; wait until it is
  1261                              <1> p42:			;  wait for either retrace high
  1262 000018CB EC                  <1> 	in	al, dx ; get status again
  1263 000018CC A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
  1264 000018CE 74FB                <1> 	jz	short p42 ; wait until either retrace active
  1265                              <1> p43:	
  1266 000018D0 FB                  <1> 	sti
  1267                              <1> p44:
  1268 000018D1 668B0424            <1> 	mov	ax, [esp] ; restore the character (al) & attribute (ah)
  1269 000018D5 668906              <1> 	mov	[esi], ax
  1270                              <1> 
  1271 000018D8 6649                <1> 	dec	cx
  1272 000018DA 7404                <1> 	jz	short p45
  1273                              <1> 
  1274 000018DC 46                  <1> 	inc	esi
  1275 000018DD 46                  <1> 	inc	esi
  1276 000018DE EBD8                <1> 	jmp	short p41
  1277                              <1> p45:	
  1278 000018E0 6658                <1> 	pop	ax
  1279 000018E2 665A                <1> 	pop	dx
  1280 000018E4 C3                  <1> 	retn
  1281                              <1> 
  1282                              <1> ; 26/06/2016
  1283                              <1> ; 24/06/2016
  1284                              <1> ; 12/05/2016
  1285                              <1> ; 18/01/2016
  1286                              <1> ; 16/01/2016 - TRDOS 386 (TRDOS v2.0)
  1287                              <1> ; 30/06/2015
  1288                              <1> ; 27/06/2015
  1289                              <1> ; 11/03/2015
  1290                              <1> ; 02/09/2014
  1291                              <1> ; 30/08/2014
  1292                              <1> ; VIDEO FUNCTIONS
  1293                              <1> ; (write_tty - Retro UNIX 8086 v1 - U9.ASM, 01/02/2014)
  1294                              <1> 
  1295                              <1> WRITE_TTY:
  1296                              <1> 	; 01/07/2016
  1297                              <1> 	; 26/06/2016
  1298                              <1> 	; 24/06/2016
  1299                              <1> 	; 13/05/2016
  1300                              <1> 	; 12/05/2016
  1301                              <1> 	; 30/01/2016
  1302                              <1> 	; 18/01/2016
  1303                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  1304                              <1> 	; 13/08/2015
  1305                              <1> 	; 02/09/2014
  1306                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  1307                              <1> 	; 01/02/2014 (Retro UNIX 8086 v1 - last update)
  1308                              <1> 	; 03/12/2013 (Retro UNIX 8086 v1 - beginning)	
  1309                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
  1310                              <1> 	;
  1311                              <1> 	; INPUT -> AL = Character to be written
  1312                              <1> 	;	   BL = Color (Forecolor, Backcolor)
  1313                              <1> 	;	   BH = Video Page (0 to 7)
  1314                              <1> 
  1315                              <1> 	; 13/05/2016
  1316                              <1> 	;call	_write_tty
  1317                              <1> 	; 01/07/2016
  1318 000018E5 E818000000          <1> 	call	_write_tty_m3
  1319 000018EA E9E4FAFFFF          <1> 	jmp	VIDEO_RETURN
  1320                              <1> 
  1321                              <1> RVRT	equ	00001000b	; VIDEO VERTICAL RETRACE BIT
  1322                              <1> RHRZ	equ	00000001b	; VIDEO HORIZONTAL RETRACE BIT
  1323                              <1> 
  1324                              <1> ; Derived from "WRITE_TTY" procedure of IBM "pc-at" rombios source code
  1325                              <1> ; (06/10/1985), 'video.asm', INT 10H, VIDEO_IO
  1326                              <1> ;
  1327                              <1> ; 06/10/85  VIDEO DISPLAY BIOS
  1328                              <1> ;
  1329                              <1> ;--- WRITE_TTY ------------------------------------------------------------------
  1330                              <1> ;										:
  1331                              <1> ;   THIS INTERFACE PROVIDES A TELETYPE LIKE INTERFACE TO THE			:
  1332                              <1> ;   VIDEO CARDS. THE INPUT CHARACTER IS WRITTEN TO THE CURRENT			:
  1333                              <1> ;   CURSOR POSITION, AND THE CURSOR IS MOVED TO THE NEXT POSITION.		:
  1334                              <1> ;   IF THE CURSOR LEAVES THE LAST COLUMN OF THE FIELD, THE COLUMN		:
  1335                              <1> ;   IS SET TO ZERO, AND THE ROW VALUE IS INCREMENTED. IF THE ROW		:
  1336                              <1> ;   ROW VALUE LEAVES THE FIELD, THE CURSOR IS PLACED ON THE LAST ROW,		:
  1337                              <1> ;   FIRST COLUMN, AND THE ENTIRE SCREEN IS SCROLLED UP ONE LINE.		:
  1338                              <1> ;   WHEN THE SCREEN IS SCROLLED UP, THE ATTRIBUTE FOR FILLING THE		:
  1339                              <1> ;   NEWLY BLANKED LINE IS READ FROM THE CURSOR POSITION ON THE PREVIOUS		:
  1340                              <1> ;   LINE BEFORE THE SCROLL, IN CHARACTER MODE. IN GRAPHICS MODE,		:
  1341                              <1> ;   THE 0 COLOR IS USED.							:
  1342                              <1> ;   ENTRY --									:
  1343                              <1> ;     (AH) = CURRENT CRT MODE							:
  1344                              <1> ;     (AL) = CHARACTER TO BE WRITTEN						:
  1345                              <1> ;	    NOTE THAT BACK SPACE, CARRIAGE RETURN, BELL AND LINE FEED ARE	:
  1346                              <1> ;	    HANDLED AS COMMANDS RATHER THAN AS DISPLAY GRAPHICS CHARACTERS	:
  1347                              <1> ;     (BL) = FOREGROUND COLOR FOR CHAR WRITE IF CURRENTLY IN A GRAPHICS MODE	:
  1348                              <1> ;   EXIT -- 									:
  1349                              <1> ;     ALL REGISTERS SAVED							:
  1350                              <1> ;--------------------------------------------------------------------------------
  1351                              <1> 
  1352                              <1> ; 26/06/2016
  1353                              <1> ; 24/06/2016
  1354                              <1> _write_tty:	; 13/05/2016
  1355 000018EF FA                  <1> 	cli
  1356                              <1> 	;
  1357                              <1> 	; 01/09/2014
  1358 000018F0 803D[26D30000]03    <1> 	cmp	byte [CRT_MODE], 3
  1359 000018F7 7409                <1> 	je	short _write_tty_m3
  1360                              <1> 	;
  1361                              <1> set_mode_3:
  1362 000018F9 53                  <1> 	push	ebx
  1363 000018FA 50                  <1> 	push	eax
  1364 000018FB E8E8FAFFFF          <1> 	call	_set_mode
  1365 00001900 58                  <1> 	pop	eax
  1366 00001901 5B                  <1> 	pop	ebx
  1367                              <1> 	;
  1368                              <1> _write_tty_m3: ; 24/06/2016 (m3 -> _write_tty_m3)
  1369 00001902 0FB6F7              <1> 	movzx 	esi, bh ; 12/05/2016
  1370 00001905 66D1E6              <1> 	shl	si, 1
  1371 00001908 81C6[16DD0000]      <1> 	add	esi, CURSOR_POSN
  1372 0000190E 668B16              <1> 	mov	dx, [esi]
  1373                              <1> 	;
  1374                              <1> 	; dx now has the current cursor position
  1375                              <1> 	;
  1376 00001911 3C0D                <1> 	cmp	al, 0Dh	; CR	; is it carriage return or control character
  1377 00001913 7636                <1> 	jbe	short u8
  1378                              <1> 	;
  1379                              <1> 	; write the char to the screen
  1380                              <1> u0:	
  1381                              <1> 	; al = character
  1382                              <1> 	; bl = attribute/color
  1383                              <1> 	; bh = video page number (0 to 7)
  1384                              <1> 	;
  1385 00001915 66B90100            <1> 	mov	cx, 1  ; 24/06/2016
  1386                              <1> 	; cx = count of characters to write
  1387                              <1> 	;
  1388 00001919 E86BFFFFFF          <1> 	call	_write_c_current ; 16/01/2015
  1389                              <1> 	;
  1390                              <1> 	; position the cursor for next char
  1391 0000191E FEC2                <1> 	inc	dl		; next column
  1392 00001920 3A15[28D30000]      <1> 	cmp	dl, [CRT_COLS]  ; test for column overflow 
  1393 00001926 755D                <1>         jne     _set_cpos
  1394 00001928 B200                <1> 	mov	dl, 0		; column = 0
  1395                              <1> u10:				; (line feed found)
  1396 0000192A 80FE18              <1> 	cmp	dh, 25-1 	; check for last row
  1397 0000192D 7218                <1> 	jb 	short u6
  1398                              <1> 	;
  1399                              <1> 	; scroll required
  1400                              <1> u1:	
  1401                              <1> 	; SET CURSOR POSITION (04/12/2013)
  1402 0000192F E851000000          <1> 	call	_set_cpos
  1403                              <1> 	;
  1404                              <1> 	; determine value to fill with during scroll
  1405                              <1> u2:
  1406                              <1> 	; bh = video page number
  1407                              <1> 	;
  1408 00001934 E8ECFEFFFF          <1> 	call _read_ac_current ; 18/01/2016
  1409                              <1> 	;
  1410                              <1> 	; al = character, ah = attribute
  1411                              <1> 	; bh = video page number 	
  1412                              <1> u3:
  1413                              <1> 	;;mov	ax, 0601h 	; scroll one line
  1414                              <1> 	;;sub	cx, cx		; upper left corner
  1415                              <1> 	;;mov	dh, 25-1 	; lower right row
  1416                              <1> 	;;;mov	dl, [CRT_COLS]
  1417                              <1> 	;mov	dl, 80		; lower right column	
  1418                              <1> 	;;dec	dl
  1419                              <1> 	;;mov	dl, 79
  1420                              <1> 
  1421                              <1> 	;;call	scroll_up	; 04/12/2013
  1422                              <1> 	;;; 11/03/2015
  1423                              <1> 	; 02/09/2014
  1424                              <1> 	;;;mov	cx, [crt_ulc] ; Upper left corner  (0000h)
  1425                              <1> 	;;;mov	dx, [crt_lrc] ; Lower right corner (184Fh)
  1426                              <1> 	; 11/03/2015
  1427 00001939 6629C9              <1> 	sub	cx, cx
  1428 0000193C 66BA4F18            <1> 	mov	dx, 184Fh ; dl = 79 (column), dh = 24 (row)
  1429                              <1> 	;
  1430 00001940 B001                <1> 	mov	al, 1		; scroll 1 line up
  1431                              <1> 		; ah = attribute
  1432                              <1> 	;mov	bl, al ; 12/05/2016
  1433 00001942 E973FDFFFF          <1> 	jmp	_scroll_up	; 16/01/2016
  1434                              <1> ;u4:
  1435                              <1> 	;;int	10h		; video-call return
  1436                              <1> 				; scroll up the screen
  1437                              <1> 				; tty return
  1438                              <1> ;u5:
  1439                              <1> 	;retn			; return to the caller
  1440                              <1> 
  1441                              <1> u6:				; set-cursor-inc
  1442 00001947 FEC6                <1> 	inc	dh		; next row
  1443                              <1> 				; set cursor
  1444                              <1> ;u7:					
  1445                              <1> 	;;mov	ah, 02h
  1446                              <1> 	;;jmp	short u4 	; establish the new cursor
  1447                              <1> 	;call	_set_cpos
  1448                              <1> 	;jmp 	short u5
  1449 00001949 EB3A                <1> 	jmp     _set_cpos
  1450                              <1> 
  1451                              <1> 	; check for control characters
  1452                              <1> u8:
  1453 0000194B 7436                <1> 	je	short u9
  1454 0000194D 3C0A                <1> 	cmp	al, 0Ah		; is it a line feed (0Ah)
  1455 0000194F 74D9                <1> 	je	short u10
  1456 00001951 3C07                <1> 	cmp	al, 07h 	; is it a bell
  1457 00001953 747A                <1> 	je	short u11
  1458 00001955 3C08                <1> 	cmp	al, 08h		; is it a backspace
  1459                              <1> 	;jne	short u0
  1460 00001957 7422                <1> 	je	short bs	; 12/12/2013
  1461                              <1> 	; 12/12/2013 (tab stop)
  1462 00001959 3C09                <1> 	cmp	al, 09h		; is it a tab stop
  1463 0000195B 75B8                <1> 	jne	short u0
  1464 0000195D 88D0                <1> 	mov	al, dl
  1465 0000195F 6698                <1> 	cbw
  1466 00001961 B108                <1> 	mov	cl, 8
  1467 00001963 F6F1                <1> 	div	cl
  1468 00001965 28E1                <1> 	sub	cl, ah
  1469                              <1> ts:
  1470                              <1> 	; 02/09/2014
  1471                              <1> 	; 01/09/2014
  1472 00001967 B020                <1> 	mov	al, 20h
  1473                              <1> tsloop:
  1474 00001969 6651                <1> 	push	cx
  1475 0000196B 6650                <1> 	push	ax
  1476                              <1> 	;mov	bh, [ACTIVE_PAGE]
  1477 0000196D E890FFFFFF          <1> 	call	_write_tty_m3 ; 24/06/2016 (m3 -> _write_tty_m3)
  1478 00001972 6658                <1> 	pop	ax  ; ah = attribute/color
  1479 00001974 6659                <1> 	pop	cx
  1480 00001976 FEC9                <1> 	dec	cl
  1481 00001978 75EF                <1> 	jnz	short tsloop
  1482 0000197A C3                  <1> 	retn
  1483                              <1> bs:	
  1484                              <1> 	; back space found
  1485                              <1> 
  1486 0000197B 08D2                <1> 	or	dl, dl 		; is it already at start of line
  1487                              <1> 	;je	short u7 	; set_cursor
  1488 0000197D 7406                <1> 	jz	short _set_cpos
  1489 0000197F 664A                <1> 	dec	dx     		; no -- just move it back
  1490                              <1> 	;jmp	short u7
  1491 00001981 EB02                <1> 	jmp	short _set_cpos
  1492                              <1> 
  1493                              <1> 	; carriage return found
  1494                              <1> u9:
  1495 00001983 B200                <1> 	mov	dl, 0 		; move to first column
  1496                              <1> 	;jmp	short u7
  1497                              <1> 	;jmp	short _set_cpos ; 30/01/2016
  1498                              <1> 
  1499                              <1> 	; line feed found
  1500                              <1> ;u10:
  1501                              <1> ;	cmp	dh, 25-1 	; bottom of screen
  1502                              <1> ;	jne	short u6 	; no, just set the cursor
  1503                              <1> ;       jmp     u1              ; yes, scroll the screen
  1504                              <1> 
  1505                              <1> _set_cpos:
  1506                              <1> 	; 12/05/2016 - TRDOS 386 (TRDOS v2.0)
  1507                              <1> 	; 27/06/2015
  1508                              <1> 	; 01/09/2014
  1509                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1510                              <1> 	;
  1511                              <1> 	; 04/12/2013 - 12/12/2013 (Retro UNIX 8086 v1) 
  1512                              <1> 	;
  1513                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  1514                              <1> 	;
  1515                              <1> ;----------------------------------------------
  1516                              <1> ; SET_CPOS
  1517                              <1> ;	THIS ROUTINE SETS THE CURRENT CURSOR POSITION TO THE
  1518                              <1> ;	NEW X-Y VALUES PASSED
  1519                              <1> ; INPUT
  1520                              <1> ;	DX - ROW,COLUMN OF NEW CURSOR
  1521                              <1> ;	BH - DISPLAY PAGE OF CURSOR
  1522                              <1> ; OUTPUT
  1523                              <1> ;	CURSOR ID SET AT 6845 IF DISPLAY PAGE IS CURRENT DISPLAY
  1524                              <1> ;----------------------------------------------
  1525                              <1> 	;
  1526 00001985 BE[16DD0000]        <1> 	mov	esi, CURSOR_POSN
  1527 0000198A 0FB6C7              <1>         movzx   eax, bh	; BH = video page number
  1528                              <1> ;	or	al, al
  1529                              <1> ;	jz	short _set_cpos_0
  1530 0000198D D0E0                <1>         shl     al, 1   ; word offset
  1531 0000198F 01C6                <1>         add     esi, eax
  1532                              <1> ;_set_cpos_0:
  1533 00001991 668916              <1> 	mov	[esi], dx ; save the pointer
  1534 00001994 383D[26DD0000]      <1> 	cmp	[ACTIVE_PAGE], bh
  1535 0000199A 7532                <1> 	jne	short m17
  1536                              <1> 	;call	m18	; CURSOR SET
  1537                              <1> ;m17:			; SET_CPOS_RETURN
  1538                              <1> 	; 01/09/2014
  1539                              <1> ;	retn
  1540                              <1> 		; DX  = row/column
  1541                              <1> m18:
  1542 0000199C E8CFFCFFFF          <1> 	call	position ; determine location in regen buffer	
  1543 000019A1 668B0D[14DD0000]    <1> 	mov	cx, [CRT_START]
  1544 000019A8 6601C1              <1> 	add	cx, ax  ; add char position in regen buffer
  1545                              <1> 			; to the start address (offset) for this page
  1546 000019AB 66D1E9              <1> 	shr	cx, 1	; divide by 2 for char only count
  1547 000019AE B40E                <1> 	mov	ah, 14	; register number for cursor
  1548                              <1> 	;call	m16	; output value to the 6845	
  1549                              <1> 	;retn
  1550                              <1> 
  1551                              <1> 	;-----	THIS ROUTINE OUTPUTS THE CX REGISTER
  1552                              <1> 	;	TO THE 6845 REGISTERS NAMED IN (AH)
  1553                              <1> m16:
  1554 000019B0 FA                  <1> 	cli
  1555                              <1> 	;mov	dx, [addr_6845] ; address register
  1556 000019B1 66BAD403            <1> 	mov 	dx, 03D4h ; I/O address of color card
  1557 000019B5 88E0                <1> 	mov	al, ah	; get value
  1558 000019B7 EE                  <1> 	out	dx, al	; register set
  1559 000019B8 6642                <1> 	inc	dx	; data register
  1560 000019BA EB00                <1> 	jmp	$+2	; i/o delay
  1561 000019BC 88E8                <1> 	mov	al, ch	; data
  1562 000019BE EE                  <1> 	out	dx, al	
  1563 000019BF 664A                <1> 	dec	dx	
  1564 000019C1 88E0                <1> 	mov	al, ah
  1565 000019C3 FEC0                <1> 	inc	al	; point to other data register
  1566 000019C5 EE                  <1> 	out	dx, al	; set for second register
  1567 000019C6 6642                <1> 	inc	dx
  1568 000019C8 EB00                <1> 	jmp	$+2	; i/o delay
  1569 000019CA 88C8                <1> 	mov	al, cl	; second data value
  1570 000019CC EE                  <1> 	out	dx, al
  1571 000019CD FB                  <1> 	sti
  1572                              <1> m17:
  1573 000019CE C3                  <1> 	retn
  1574                              <1> 
  1575                              <1> beeper: 
  1576                              <1> 	; 12/05/2016 - TRDOS 386 (TRDOS v2.0)
  1577                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1578                              <1> 	; 18/01/2014
  1579                              <1> 	; 03/12/2013
  1580                              <1> 	; bell found
  1581                              <1> u11:
  1582 000019CF FB                  <1> 	sti
  1583 000019D0 3A3D[26DD0000]      <1> 	cmp	bh, [ACTIVE_PAGE]
  1584 000019D6 7551                <1> 	jne	short u12	; Do not sound the beep 
  1585                              <1> 				; if it is not written on the active page
  1586 000019D8 66B93305            <1> 	mov	cx, 1331 	; divisor for 896 hz tone
  1587 000019DC B31F                <1> 	mov	bl, 31		; set count for 31/64 second for beep
  1588                              <1> 	;call	beep		; sound the pod bell
  1589                              <1> 	;jmp	short u5 	; tty_return
  1590                              <1> 	;retn
  1591                              <1> 	
  1592                              <1> TIMER	equ 	040h   		; 8254 TIMER - BASE ADDRESS
  1593                              <1> PORT_B	equ	061h		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  1594                              <1> GATE2	equ	00000001b	; TIMER 2 INPUT CATE CLOCK BIT
  1595                              <1> SPK2	equ	00000010b	; SPEAKER OUTPUT DATA ENABLE BIT
  1596                              <1> 
  1597                              <1> beep:
  1598                              <1> 	; 07/02/2015
  1599                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1600                              <1> 	; 18/01/2014
  1601                              <1> 	; 03/12/2013
  1602                              <1> 	;
  1603                              <1> 	; TEST4.ASM - 06/10/85  POST AND BIOS UTILITY ROUTINES
  1604                              <1> 	;
  1605                              <1> 	; ROUTINE TO SOUND THE BEEPER USING TIMER 2 FOR TONE
  1606                              <1> 	;
  1607                              <1> 	; ENTRY:
  1608                              <1> 	;    (BL) = DURATION COUNTER ( 1 FOR 1/64 SECOND )
  1609                              <1> 	;    (CX) = FREQUENCY DIVISOR (1193180/FREQUENCY) (1331 FOR 886 HZ)
  1610                              <1> 	; EXIT:				:
  1611                              <1> 	;    (AX),(BL),(CX) MODIFIED.
  1612                              <1> 
  1613 000019DE 9C                  <1> 	pushf  ; 18/01/2014	; save interrupt status
  1614 000019DF FA                  <1> 	cli			; block interrupts during update
  1615 000019E0 B0B6                <1> 	mov	al, 10110110b	; select timer 2, lsb, msb binary
  1616 000019E2 E643                <1> 	out	TIMER+3, al 	; write timer mode register
  1617 000019E4 EB00                <1> 	jmp	$+2		; I/O delay
  1618 000019E6 88C8                <1> 	mov	al, cl		; divisor for hz (low)
  1619 000019E8 E642                <1> 	out	TIMER+2,AL	; write timer 2 count - lsb
  1620 000019EA EB00                <1> 	jmp	$+2		; I/O delay
  1621 000019EC 88E8                <1> 	mov	al, ch		; divisor for hz (high)
  1622 000019EE E642                <1> 	out	TIMER+2, al	; write timer 2 count - msb
  1623 000019F0 E461                <1> 	in	al, PORT_B	; get current setting of port
  1624 000019F2 88C4                <1> 	mov	ah, al		; save that setting
  1625 000019F4 0C03                <1> 	or	al, GATE2+SPK2	; gate timer 2 and turn speaker on
  1626 000019F6 E661                <1> 	out	PORT_B, al	; and restore interrupt status
  1627                              <1> 	;popf	; 18/01/2014
  1628 000019F8 FB                  <1> 	sti
  1629                              <1> g7:				; 1/64 second per count (bl)
  1630 000019F9 B90B040000          <1> 	mov	ecx, 1035	; delay count for 1/64 of a second	
  1631 000019FE E827000000          <1> 	call	waitf		; go to beep delay 1/64 count
  1632 00001A03 FECB                <1> 	dec	bl		; (bl) length count expired?
  1633 00001A05 75F2                <1> 	jnz	short g7	; no - continue beeping speaker
  1634                              <1> 	;
  1635                              <1> 	;pushf			; save interrupt status
  1636 00001A07 FA                  <1> 	cli  	; 18/01/2014	; block interrupts during update
  1637 00001A08 E461                <1> 	in	al, PORT_B	; get current port value
  1638                              <1>         ;or      al, not (GATE2+SPK2) ; isolate current speaker bits in case
  1639 00001A0A 0CFC                <1>         or      al, ~(GATE2+SPK2)
  1640 00001A0C 20C4                <1>         and	ah, al		; someone turned them off during beep
  1641 00001A0E 88E0                <1> 	mov	al, ah		; recover value of port
  1642                              <1>         ;or      al, not (GATE2+SPK2) ; force speaker data off
  1643 00001A10 0CFC                <1> 	or 	al, ~(GATE2+SPK2) ; isolate current speaker bits in case
  1644 00001A12 E661                <1> 	out	PORT_B, al	; and stop speaker timer
  1645                              <1> 	;popf			; restore interrupt flag state
  1646 00001A14 FB                  <1> 	sti
  1647 00001A15 B90B040000          <1> 	mov	ecx, 1035	; force 1/64 second delay (short)
  1648 00001A1A E80B000000          <1> 	call	waitf		; minimum delay between all beeps
  1649                              <1> 	;pushf			; save interrupt status
  1650 00001A1F FA                  <1> 	cli			; block interrupts during update
  1651 00001A20 E461                <1> 	in	al, PORT_B	; get current port value in case	
  1652 00001A22 2403                <1> 	and	al, GATE2+SPK2	; someone turned them on
  1653 00001A24 08E0                <1> 	or	al, ah		; recover value of port_b
  1654 00001A26 E661                <1> 	out	PORT_B, al	; restore speaker status
  1655 00001A28 9D                  <1> 	popf			; restore interrupt flag state
  1656                              <1> u12:	
  1657 00001A29 C3                  <1> 	retn
  1658                              <1> 
  1659                              <1> REFRESH_BIT equ	00010000b 	; REFRESH TEST BIT
  1660                              <1> 
  1661                              <1> WAITF:
  1662                              <1> waitf:
  1663                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1664                              <1> 	; 03/12/2013
  1665                              <1> 	;
  1666                              <1> ;	push ax			; save work register (ah)	
  1667                              <1> ;waitf1:
  1668                              <1> 				; use timer 1 output bits
  1669                              <1> ;	in	al, PORT_B	; read current counter output status
  1670                              <1> ;	and	al, REFRESH_BIT	; mask for refresh determine bit
  1671                              <1> ;	cmp	al, ah		; did it just change
  1672                              <1> ;	je	short waitf1	; wait for a change in output line
  1673                              <1> ;	;
  1674                              <1> ;	mov	ah, al		; save new lflag state
  1675                              <1> ;	loop	waitf1		; decrement half cycles till count end		
  1676                              <1> ;	;
  1677                              <1> ;	pop	ax		; restore (ah)
  1678                              <1> ;	retn			; return (cx)=0
  1679                              <1> 
  1680                              <1> ; 06/02/2015 (unix386.s <-- dsectrm2.s)
  1681                              <1> ; 17/12/2014 (dsectrm2.s)
  1682                              <1> ; WAITF
  1683                              <1> ; /// IBM PC-XT Model 286 System BIOS Source Code - Test 4 - 06/10/85 ///
  1684                              <1> ;
  1685                              <1> ;---WAITF-----------------------------------------------------------------------
  1686                              <1> ;	FIXED TIME WAIT ROUTINE (HARDWARE CONTROLLED - NOT PROCESSOR)
  1687                              <1> ; ENTRY:
  1688                              <1> ;	(CX) =	COUNT OF 15.085737 MICROSECOND INTERVALS TO WAIT
  1689                              <1> ;	      	MEMORY REFRESH TIMER 1 OUTPUT USED AS REFERENCE
  1690                              <1> ; EXIT:
  1691                              <1> ;	       	AFTER (CX) TIME COUNT (PLUS OR MINUS 16 MICROSECONDS)
  1692                              <1> ;	(CX) = 0	
  1693                              <1> ;-------------------------------------------------------------------------------
  1694                              <1> 
  1695                              <1> ; Refresh period: 30 micro seconds (15-80 us)
  1696                              <1> ; (16/12/2014 - AWARDBIOS 1999 - ATORGS.ASM, WAIT_REFRESH)
  1697                              <1> 
  1698                              <1> ;WAITF:					; DELAY FOR (CX)*15.085737 US
  1699 00001A2A 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER (AH)
  1700                              <1> 	; 16/12/2014
  1701                              <1> 	;shr	cx, 1			; convert to count of 30 micro seconds
  1702 00001A2C D1E9                <1> 	shr	ecx, 1	; 21/02/2015
  1703                              <1> ;17/12/2014	
  1704                              <1> ;WAITF1:
  1705                              <1> ;	IN	AL, PORT_B   ;061h	; READ CURRENT COUNTER OUTPUT STATUS
  1706                              <1> ;	AND	AL, REFRESH_BIT	;00010000b ; MASK FOR REFRESH DETERMINE BIT
  1707                              <1> ;	CMP	AL, AH			; DID IT JUST CHANGE
  1708                              <1> ;	JE	short WAITF1		; WAIT FOR A CHANGE IN OUTPUT LINE
  1709                              <1> ;	MOV	AH, AL			; SAVE NEW FLAG STATE
  1710                              <1> ;	LOOP	WAITF1			; DECREMENT HALF CYCLES TILL COUNT END		
  1711                              <1> 	;
  1712                              <1> 	; 17/12/2014
  1713                              <1> 	;
  1714                              <1> 	; Modification from 'WAIT_REFRESH' procedure of AWARD BIOS - 1999
  1715                              <1> 	;
  1716                              <1> ;WAIT_REFRESH:  Uses port 61, bit 4 to have CPU speed independent waiting.
  1717                              <1> ;   	INPUT:  CX = number of refresh periods to wait
  1718                              <1> ;     	       (refresh periods = 1 per 30 microseconds on most machines)
  1719                              <1> WR_STATE_0:
  1720 00001A2E E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  1721 00001A30 A810                <1> 	TEST	AL,010H
  1722 00001A32 74FA                <1> 	JZ	SHORT WR_STATE_0
  1723                              <1> WR_STATE_1:
  1724 00001A34 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  1725 00001A36 A810                <1> 	TEST	AL,010H
  1726 00001A38 75FA                <1> 	JNZ	SHORT WR_STATE_1
  1727 00001A3A E2F2                <1>         LOOP    WR_STATE_0
  1728                              <1> 	;
  1729 00001A3C 6658                <1> 	POP	AX			; RESTORE (AH)
  1730 00001A3E C3                  <1> 	RETn				; (CX) = 0
  1731                              <1> 
  1732                              <1> ; 01/07/2016
  1733                              <1> ; 24/06/2016
  1734                              <1> ; 23/06/2016 - TRDOS 386 (TRDOS v2.0)
  1735                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  1736                              <1> ;-------------------------------------------------------------------------------
  1737                              <1> ; WRITE_STRING								       :
  1738                              <1> ;	THIS ROUTINE WRITES A STRING OF CHARACTERS TO THE CRT.		       :
  1739                              <1> ; INPUT 								       :
  1740                              <1> ;	(AL) = WRITE STRING COMMAND  0 - 3				       :
  1741                              <1> ;	(BH) = DISPLAY PAGE (ACTIVE PAGE)				       :
  1742                              <1> ;	(CX) = COUNT OF CHARACTERS TO WRITE, IF (CX) = 0 THEN RETURN	       :
  1743                              <1> ;	(DX) = CURSOR POSITION FOR START OF STRING WRITE		       :
  1744                              <1> ;	(BL) = ATTRIBUTE OF CHARACTER TO WRITE IF (AL) = 0  OR	(AL) = 1       :
  1745                              <1> ;	(eBP) = SOURCE STRING OFFSET					       :
  1746                              <1> ; OUTPUT								       :
  1747                              <1> ;	NONE								       :
  1748                              <1> ;-------------------------------------------------------------------------------
  1749                              <1> 
  1750                              <1> ; AL = 00h: Assign all characters the attribute in BL; do not update cursor
  1751                              <1> ; AL = 01h: Assign all characters the attribute in BL; update cursor
  1752                              <1> ; AL = 02h: Use attributes in string; do not update cursor
  1753                              <1> ; AL = 03h: Use attributes in string; update cursor
  1754                              <1> 
  1755                              <1> WRITE_STRING:
  1756 00001A3F A2[81EA0000]        <1> 	mov	[w_str_cmd], al		; save (AL) command
  1757 00001A44 3C04                <1> 	CMP	AL, 4			; TEST FOR INVALID WRITE STRING OPTION
  1758 00001A46 0F8387F9FFFF        <1> 	JNB	VIDEO_RETURN		; IF OPTION INVALID THEN RETURN
  1759                              <1> 
  1760                              <1>         ;JCXZ   VIDEO_RETURN            ; IF ZERO LENGTH STRING THEN RETURN
  1761                              <1> 
  1762 00001A4C 67E351              <1>         jcxz    P55			; 01/07/2016
  1763                              <1> 
  1764                              <1> 
  1765                              <1> 	; 01/07/2016
  1766                              <1> 	;and	ecx, 0FFFFh
  1767                              <1> 	; ECX = byte count
  1768                              <1> 	;push	ecx
  1769 00001A4F 89EE                <1> 	mov	esi, ebp ; user buffer
  1770 00001A51 BF00000700          <1> 	mov	edi, Cluster_Buffer  ; system buffer
  1771 00001A56 E884A90000          <1> 	call	transfer_from_user_buffer
  1772                              <1> 	;pop	ecx
  1773 00001A5B 0F8272F9FFFF        <1> 	jc	VIDEO_RETURN
  1774                              <1> 	; ecx = transfer (byte) count = character count
  1775 00001A61 BD00000700          <1> 	mov	ebp, Cluster_Buffer
  1776                              <1> 	;
  1777 00001A66 0FB6F7              <1> 	movzx	esi, bh			; GET CURRENT CURSOR PAGE
  1778 00001A69 66D1E6              <1> 	SAL	SI,1			; CONVERT TO PAGE OFFSET  (SI= PAGE)
  1779                              <1> 	; *****
  1780 00001A6C 66FFB6[16DD0000]    <1> 	PUSH	word [eSI+CURSOR_POSN]	; SAVE CURRENT CURSOR POSITION IN STACK
  1781                              <1> 
  1782                              <1> 	;MOV	AX,0200H		; SET NEW CURSOR POSITION
  1783                              <1> 	;INT	10H
  1784                              <1> P50next:	
  1785 00001A73 53                  <1> 	push	ebx ; ****
  1786 00001A74 51                  <1> 	push	ecx ; ***
  1787 00001A75 56                  <1> 	push	esi ; **
  1788 00001A76 52                  <1> 	push	edx ; *
  1789 00001A77 E809FFFFFF          <1> 	call	_set_cpos
  1790                              <1> P50:
  1791 00001A7C 8A4500              <1> 	MOV	AL, [eBP]		; GET CHARACTER FROM INPUT STRING
  1792 00001A7F 45                  <1> 	INC	eBP			; BUMP POINTER TO CHARACTER
  1793                              <1> 
  1794                              <1> ;-----	TEST FOR SPECIAL CHARACTER'S
  1795                              <1> 
  1796 00001A80 3C08                <1> 	CMP	AL, 08H			; IS IT A BACKSPACE
  1797 00001A82 740C                <1> 	JE	short P51		; BACK_SPACE
  1798 00001A84 3C0D                <1> 	CMP	AL, 0Dh ; CR		; IS IT CARRIAGE RETURN
  1799 00001A86 7408                <1> 	JE	short P51		; CAR_RET
  1800 00001A88 3C0A                <1> 	CMP	AL, 0Ah ; LF		; IS IT A LINE FEED
  1801 00001A8A 7404                <1> 	JE	short P51		; LINE_FEED
  1802 00001A8C 3C07                <1> 	CMP	AL, 07h			; IS IT A BELL
  1803 00001A8E 7515                <1> 	JNE	short P52		; IF NOT THEN DO WRITE CHARACTER
  1804                              <1> P51:
  1805                              <1> 	;MOV	AH,0EH			; TTY_CHARACTER_WRITE
  1806                              <1> 	;INT	10H			; WRITE TTY CHARACTER TO THE CRT
  1807                              <1> 	
  1808 00001A90 E86DFEFFFF          <1> 	call	_write_tty_m3
  1809                              <1> 
  1810 00001A95 5A                  <1> 	pop	edx ; *
  1811 00001A96 5E                  <1> 	pop	esi ; **
  1812                              <1> 
  1813 00001A97 668B96[16DD0000]    <1> 	MOV	DX, [eSI+CURSOR_POSN]	; GET CURRENT CURSOR POSITION
  1814 00001A9E EB46                <1> 	JMP	SHORT P54		; SET CURSOR POSITION AND CONTINUE
  1815                              <1> P55:
  1816 00001AA0 E92EF9FFFF          <1> 	JMP	VIDEO_RETURN
  1817                              <1> P52:
  1818 00001AA5 66B90100            <1> 	MOV	CX, 1			; SET CHARACTER WRITE AMOUNT TO ONE
  1819 00001AA9 803D[81EA0000]02    <1> 	CMP	byte [w_str_cmd], 2	; IS THE ATTRIBUTE IN THE STRING
  1820 00001AB0 7204                <1> 	JB	short P53		; IF NOT THEN SKIP
  1821 00001AB2 8A5D00              <1> 	MOV	BL, [eBP]		; ELSE GET NEW ATTRIBUTE
  1822 00001AB5 45                  <1> 	INC	eBP			; BUMP STRING POINTER
  1823                              <1> P53:
  1824                              <1> 	;MOV	AH,09H			; GOT_CHARACTER
  1825                              <1> 	;INT	10H			; WRITE CHARACTER TO THE CRT
  1826                              <1> 
  1827 00001AB6 E8CEFDFFFF          <1> 	call	_write_c_current
  1828                              <1> 	
  1829 00001ABB 5A                  <1> 	pop	edx ; *	
  1830                              <1> 	
  1831 00001ABC 0FB6F7              <1> 	movzx	esi, bh ; video page number (0 to 7)	
  1832 00001ABF 889E[72D30000]      <1> 	mov	[esi+chr_attrib], bl ; color/attribute
  1833                              <1> 
  1834 00001AC5 FEC2                <1> 	INC	DL			; INCREMENT COLUMN COUNTER
  1835 00001AC7 3A15[28D30000]      <1> 	CMP	DL, [CRT_COLS]		; IF COLS ARE WITHIN RANGE FOR THIS MODE
  1836 00001ACD 7217                <1> 	JB	short P54		;    THEN GO TO COLUMNS SET
  1837 00001ACF FEC6                <1> 	INC	DH			; BUMP ROW COUNTER BY ONE
  1838 00001AD1 28D2                <1> 	SUB	DL, DL			; SET COLUMN COUNTER TO ZERO
  1839 00001AD3 80FE19              <1> 	CMP	DH, 25			; IF ROWS ARE LESS THAN 25 THEN
  1840 00001AD6 720E                <1> 	JB	short P54		; GO TO ROWS_COLUMNS_SET
  1841                              <1> 
  1842 00001AD8 66B80A0E            <1> 	MOV	AX,0E0AH		; ELSE SCROLL SCREEN
  1843                              <1> 	;INT	10H			; RESET ROW COUNTER TO 24
  1844                              <1> 
  1845 00001ADC E821FEFFFF          <1> 	call	_write_tty_m3
  1846                              <1> 	
  1847 00001AE1 66BA0018            <1> 	mov	dx, 1800h		; Column = 0, Row = 24
  1848 00001AE5 5E                  <1> 	pop	esi ; **
  1849                              <1> P54:
  1850                              <1> 					; ROW_COLUMNS_SET
  1851                              <1> 	;MOV	AX,0200H		; SET NEW CURSOR POSITION COMMAND
  1852                              <1> 	;INT	10H			; ESTABLISH NEW CURSOR POSITION
  1853                              <1> 
  1854 00001AE6 59                  <1> 	pop	ecx ; ***
  1855 00001AE7 5B                  <1> 	pop	ebx ; ****
  1856                              <1> 
  1857                              <1> 	;LOOP	P50			; DO IT ONCE MORE UNTIL (CX) = ZERO
  1858 00001AE8 6649                <1> 	dec	cx
  1859 00001AEA 7587                <1> 	jnz	short P50next
  1860                              <1> 
  1861 00001AEC 665A                <1> 	POP	DX  ; *****		; RESTORE OLD CURSOR COORDINATES
  1862                              <1> 	
  1863 00001AEE F605[81EA0000]01    <1> 	test	byte [w_str_cmd], 1	; IF CURSOR WAS NOT TO BE MOVED
  1864 00001AF5 0F85D8F8FFFF        <1> 	JNZ	VIDEO_RETURN		; THEN EXIT WITHOUT RESETTING OLD VALUE
  1865                              <1> 	
  1866                              <1> 	;MOV	AX,0200H		; ELSE RESTORE OLD CURSOR POSITION
  1867                              <1> 	;INT	10H
  1868                              <1> 					; DONE - EXIT WRITE STRING
  1869 00001AFB E885FEFFFF          <1> 	call	_set_cpos
  1870 00001B00 E9CEF8FFFF          <1> 	JMP	VIDEO_RETURN		; RETURN TO CALLER
  1871                              <1> 
  1872                              <1> 
  1873                              <1> ; 27/06/2016 - TRDOS 386 (TRDOS v2.0)
  1874                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  1875                              <1> ;------------------------------------------------------
  1876                              <1> ;  SCROLL UP
  1877                              <1> ;   THIS ROUTINE SCROLLS UP THE INFORMATION ON THE CRT
  1878                              <1> ; ENTRY ---
  1879                              <1> ;  CH,CL = UPPER LEFT CORNER OF REGION TO SCROLL
  1880                              <1> ;  DH,DL = LOWER RIGHT CORNER OF REGION TO SCROLL
  1881                              <1> ;   BOTH OF THE ABOVE ARE IN CHARACTER POSITIONS
  1882                              <1> ;  BH = FILL VALUE FOR BLANKED LINES
  1883                              <1> ;  AL = # LINES TO SCROLL (AL=0 MEANS BLANK THE ENTIRE FIELD)
  1884                              <1> ;  DS = DATA SEGMENT
  1885                              <1> ;  ES = REGEN SEGMENT
  1886                              <1> ; EXIT --
  1887                              <1> ;  NOTHING, THE SCREEN IS SCROLLED
  1888                              <1> ;--------------------------------------------------------
  1889                              <1> 
  1890                              <1> 	; cl = upper left column
  1891                              <1> 	; ch = upper left row
  1892                              <1> 	; dl = lower rigth column
  1893                              <1> 	; dh = lower right row
  1894                              <1> 	;
  1895                              <1> 	; al = line count (AL=0 means blank entire fields)
  1896                              <1> 	; bl = fill value for blanked lines	
  1897                              <1> 	; bh = unused
  1898                              <1> 
  1899                              <1> GRAPHICS_UP:
  1900 00001B05 88C7                <1> 	MOV	bh, al			; save line count in BH
  1901 00001B07 6689C8              <1> 	MOV	AX, CX			; GET UPPER LEFT POSITION INTO AX REG
  1902                              <1> 
  1903                              <1> ;-----	USE CHARACTER SUBROUTINE FOR POSITIONING
  1904                              <1> ;-----	ADDRESS RETURNED IS MULTIPLIED BY 2 FROM CORRECT VALUE
  1905                              <1> 
  1906 00001B0A E884020000          <1> 	CALL	GRAPH_POSN
  1907 00001B0F 0FB7F8              <1> 	MOVzx	eDI, AX			; SAVE RESULT AS DESTINATION ADDRESS
  1908                              <1> 
  1909                              <1> ;-----	DETERMINE SIZE OF WINDOW
  1910                              <1> 
  1911 00001B12 6629CA              <1> 	SUB	DX, CX
  1912 00001B15 6681C20101          <1>         ADD     DX, 101h                ; ADJUST VALUES
  1913 00001B1A C0E602              <1> 	SAL	DH, 2			; MULTIPLY ROWS BY 4 AT 8 VERT DOTS/CHAR
  1914                              <1> 					; AND EVEN/ODD ROWS
  1915                              <1> ;-----	DETERMINE CRT MODE
  1916                              <1> 
  1917 00001B1D 803D[26D30000]06    <1> 	CMP	byte [CRT_MODE], 6	; TEST FOR MEDIUM RES
  1918 00001B24 7305                <1>         JNC     short _R7_              ; FIND_SOURCE
  1919                              <1> 
  1920                              <1> ;-----	MEDIUM RES UP
  1921 00001B26 D0E2                <1> 	SAL	DL, 1			; # COLUMNS * 2, SINCE 2 BYTES/CHAR
  1922 00001B28 66D1E7              <1> 	SAL	DI, 1			; OFFSET *2 SINCE 2 BYTES/CHAR
  1923                              <1> 
  1924                              <1> ;-----	DETERMINE THE SOURCE ADDRESS IN THE BUFFER
  1925                              <1> _R7_:                                   ; FIND_SOURCE
  1926 00001B2B 81C700800B00        <1> 	add	edi, 0B8000h
  1927 00001B31 C0E702              <1> 	sal	bh, 2			; multiply number of lines by 4
  1928 00001B34 7431                <1>         JZ      short _R11              ; IF ZERO, THEN BLANK ENTIRE FIELD
  1929 00001B36 B050                <1> 	MOV	AL, 80			; 80 BYTES/ROW
  1930 00001B38 F6E7                <1> 	mul	bh			; determine offset to source
  1931 00001B3A 0FB7F0              <1> 	movzx	esi, ax			; offset to source
  1932 00001B3D 01FE                <1> 	add	eSI, eDI		; SET UP SOURCE
  1933 00001B3F 88F4                <1> 	MOV	AH, DH			; NUMBER OF ROWS IN FIELD
  1934 00001B41 28FC                <1> 	sub	ah, bh			; determine number to move
  1935                              <1> 
  1936                              <1> ;-----	LOOP THROUGH, MOVING ONE ROW AT A TIME, BOTH EVEN AND ODD FIELDS
  1937                              <1> _R8:                                    ; ROW_LOOP
  1938 00001B43 E890000000          <1>         CALL    _R17                    ; MOVE ONE ROW
  1939 00001B48 6681EEB01F          <1> 	SUB	SI, 2000h-80		; MOVE TO NEXT ROW
  1940 00001B4D 6681EFB01F          <1> 	SUB	DI, 2000h-80
  1941 00001B52 FECC                <1> 	DEC	AH			; NUMBER OF ROWS TO MOVE
  1942 00001B54 75ED                <1>         JNZ     short _R8               ; CONTINUE TILL ALL MOVED
  1943                              <1> 
  1944                              <1> ;-----	FILL IN THE VACATED LINE(S)
  1945                              <1> _R9:                                    ; CLEAR ENTRY
  1946 00001B56 88D8                <1> 	mov	al, bl			; attribute to fill with
  1947                              <1> _R10_:
  1948 00001B58 E897000000          <1>         CALL    _R18                    ; CLEAR THAT ROW
  1949 00001B5D 6681EFB01F          <1> 	SUB	DI, 2000h-80		; POINT TO NEXT LINE
  1950 00001B62 FECF                <1> 	dec	bh			; number of lines to fill
  1951 00001B64 75F2                <1>         JNZ     short _R10_             ; CLEAR LOOP
  1952 00001B66 C3                  <1> 	retn				; EVERYYHING DONE
  1953                              <1> 
  1954                              <1> _R11:                                   ; BLANK_FIELD
  1955 00001B67 88F7                <1> 	mov	bh, dh			; set blank count to everything in field
  1956 00001B69 EBEB                <1>         JMP     short _R9               ; CLEAR THE FIELD
  1957                              <1> 
  1958                              <1> ; 27/06/2016 - TRDOS 386 (TRDOS v2.0)
  1959                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  1960                              <1> ;------------------------------------------------------
  1961                              <1> ; SCROLL DOWN
  1962                              <1> ;  THIS ROUTINE SCROLLS DOWN THE INFORMATION ON THE CRT
  1963                              <1> ; ENTRY --
  1964                              <1> ;  CH,CL = UPPER LEFT CORNER OF REGION TO SCROLL
  1965                              <1> ;  DH,DL = LOWER RIGHT CORNER OF REGION TO SCROLL
  1966                              <1> ;   BOTH OF THE ABOVE ARE IN CHARACTER POSITIONS
  1967                              <1> ;  BH = FILL VALUE FOR BLANKED LINES
  1968                              <1> ;  AL = # LINES TO SCROLL (AL=0 MEANS BLANK THE ENTIRE FIELD)
  1969                              <1> ;  DS = DATA SEGMENT
  1970                              <1> ;  ES = REGEN SEGMENT
  1971                              <1> ; EXIT --
  1972                              <1> ;  NOTHING, THE SCREEN IS SCROLLED
  1973                              <1> ;--------------------------------------------------------
  1974                              <1> 
  1975                              <1> 	; cl = upper left column
  1976                              <1> 	; ch = upper left row
  1977                              <1> 	; dl = lower rigth column
  1978                              <1> 	; dh = lower right row
  1979                              <1> 	;
  1980                              <1> 	; al = line count (AL=0 means blank entire fields)
  1981                              <1> 	; bl = fill value for blanked lines	
  1982                              <1> 	; bh = unused
  1983                              <1> 
  1984                              <1> GRAPHICS_DOWN:
  1985                              <1> 	;STD				; SET DIRECTION
  1986 00001B6B 88C7                <1> 	MOV	bh, al			; save line count in BH
  1987 00001B6D 6689D0              <1> 	MOV	AX, DX			; GET LOWER RIGHT POSITION INTO AX REG
  1988                              <1> 
  1989                              <1> ;-----	USE CHARACTER SUBROUTINE FOR POSITIONING
  1990                              <1> ;-----	ADDRESS RETURNED IS MULTIPLIED BY 2 FROM CORRECT VALUE
  1991                              <1> 
  1992 00001B70 E81E020000          <1> 	CALL	GRAPH_POSN
  1993 00001B75 0FB7F8              <1> 	MOVzx	eDI, AX			; SAVE RESULT AS DESTINATION ADDRESS
  1994                              <1> 
  1995                              <1> ;-----	DETERMINE SIZE OF WINDOW
  1996                              <1> 
  1997 00001B78 6629CA              <1> 	SUB	DX, CX
  1998 00001B7B 6681C20101          <1>         ADD     DX, 101h                ; ADJUST VALUES
  1999 00001B80 C0E602              <1> 	SAL	DH, 2			; MULTIPLY ROWS BY 4 AT 8 VERT DOTS/CHAR
  2000                              <1> 					; AND EVEN/ODD ROWS
  2001                              <1> 
  2002                              <1> ;-----	DETERMINE CRT MODE
  2003                              <1> 
  2004 00001B83 803D[26D30000]06    <1> 	CMP	byte [CRT_MODE], 6	; TEST FOR MEDIUM RES
  2005 00001B8A 7307                <1>         JNC     short _R12              ; FIND_SOURCE_DOWN
  2006                              <1> 
  2007                              <1> ;-----	MEDIUM RES DOWN
  2008 00001B8C D0E2                <1> 	SAL	DL, 1			; # COLUMNS * 2, SINCE 2 BYTES/CHAR
  2009 00001B8E 66D1E7              <1> 	SAL	DI, 1			; OFFSET *2 SINCE 2 BYTES/CHAR
  2010 00001B91 6647                <1> 	INC	DI			; POINT TO LAST BYTE
  2011                              <1> 
  2012                              <1> ;-----	DETERMINE THE SOURCE ADDRESS IN THE BUFFER
  2013                              <1> 
  2014                              <1> _R12:                                   ; FIND_SOURCE_DOWN
  2015 00001B93 81C700800B00        <1> 	add	edi, 0B8000h		
  2016 00001B99 6681C7F000          <1> 	ADD	DI, 240			; POINT TO LAST ROW OF PIXELS
  2017 00001B9E C0E702              <1> 	sal	bh, 2			; multiply number of lines by 4
  2018 00001BA1 74(06)              <1> 	JZ	short 6			; IF ZERO, THEN BLANK ENTIRE FIELD
  2019 00001BA3 B050                <1> 	MOV	AL, 80			; 80 BYTES/ROW
  2020 00001BA5 F6E7                <1> 	mul	bh			; determine offset to source
  2021 00001BA7 89FE                <1> 	MOV	eSI, eDI		; SET UP SOURCE
  2022 00001BA9 6629C6              <1> 	SUB	SI, AX			; SUBTRACT THE OFFSET
  2023 00001BAC 88F4                <1> 	MOV	AH, DH			; NUMBER OF ROWS IN FIELD
  2024 00001BAE 28FC                <1> 	sub	ah, bh			; determine number to move
  2025                              <1> 
  2026                              <1> ;-----	LOOP THROUGH, MOVING ONE ROW AT A TIME, BOTH EVEN AND ODD FIELDS
  2027                              <1> 
  2028                              <1> _R13:                                   ; ROW_LOOP_DOWN
  2029 00001BB0 E823000000          <1>         CALL    _R17                    ; MOVE ONE ROW
  2030 00001BB5 6681EE5020          <1> 	SUB	SI, 2000h+80		; MOVE TO NEXT ROW
  2031 00001BBA 6681EF5020          <1> 	SUB	DI, 2000h+80
  2032 00001BBF FECC                <1> 	DEC	AH			; NUMBER OF ROWS TO MOVE
  2033 00001BC1 75ED                <1>         JNZ     short _R13              ; CONTINUE TILL ALL MOVED
  2034                              <1> 
  2035                              <1> ;-----	FILL IN THE VACATED LINE(S)
  2036                              <1> _R14:                                   ; CLEAR_ENTRY_DOWN
  2037 00001BC3 88D8                <1> 	mov	al, bl			; attribute to fill with
  2038                              <1> _R15_:                                  ; CLEAR_LOOP_DOWN
  2039 00001BC5 E82A000000          <1> 	CALL	_R18			; CLEAR A ROW
  2040 00001BCA 6681EF5020          <1> 	SUB	DI, 2000h+80		; POINT TO NEXT LINE
  2041 00001BCF FECF                <1> 	dec	bh			; number of lines to fill
  2042 00001BD1 75F2                <1>         JNZ     short _R15_             ; CLEAR_LOOP_DOWN
  2043                              <1> 
  2044 00001BD3 C3                  <1> 	retn				; EVERYYHING DONE
  2045                              <1> 
  2046                              <1> _R16:                                   ; BLANK_FIELD_DOWN
  2047 00001BD4 88F7                <1> 	mov	bh, dh			; set blank count to everything in field
  2048 00001BD6 EBEB                <1>         JMP     short _R14              ; CLEAR THE FIELD
  2049                              <1> 
  2050                              <1> ; 27/06/2016 - TRDOS 386 (TRDOS v2.0)
  2051                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  2052                              <1> 
  2053                              <1> ;-----	ROUTINE TO MOVE ONE ROW OF INFORMATION
  2054                              <1> 
  2055                              <1> _R17:
  2056 00001BD8 0FB6CA              <1> 	MOVzx	ecx, DL			; NUMBER OF BYTES IN THE ROW
  2057 00001BDB 56                  <1> 	PUSH	eSI
  2058 00001BDC 57                  <1> 	PUSH	eDI			; SAVE POINTERS
  2059 00001BDD F3A4                <1> 	REP	MOVSB			; MOVE THE EVEN FIELD
  2060 00001BDF 5F                  <1> 	POP	eDI
  2061 00001BE0 5E                  <1> 	POP	eSI
  2062 00001BE1 6681C60020          <1> 	ADD	SI, 2000h
  2063 00001BE6 6681C70020          <1> 	ADD	DI, 2000h		; POINT TO THE ODD FIELD
  2064 00001BEB 56                  <1> 	PUSH	eSI
  2065 00001BEC 57                  <1> 	PUSH	eDI			; SAVE THE POINTERS
  2066 00001BED 88D1                <1> 	MOV	CL, DL			; COUNT BACK
  2067 00001BEF F3A4                <1> 	REP	MOVSB			; MOVE THE ODD FIELD
  2068 00001BF1 5F                  <1> 	POP	eDI
  2069 00001BF2 5E                  <1> 	POP	eSI			; POINTERS BACK
  2070 00001BF3 C3                  <1> 	RETn				; RETURN TO CALLER
  2071                              <1> 
  2072                              <1> ;-----	CLEAR A SINGLE ROW
  2073                              <1> 
  2074                              <1> _R18:
  2075 00001BF4 0FB6CA              <1> 	MOVzx	ecx, DL			; NUMBER OF BYTES IN FIELD
  2076 00001BF7 57                  <1> 	PUSH	eDI			; SAVE POINTER
  2077 00001BF8 F3AA                <1> 	REP	STOSB			; STORE THE NEW VALUE
  2078 00001BFA 5F                  <1> 	POP	eDI			; POINTER BACK
  2079 00001BFB 6681C70020          <1> 	ADD	DI, 2000h		; POINT TO ODD FIELD
  2080 00001C00 57                  <1> 	PUSH	eDI
  2081 00001C01 88D1                <1> 	MOV	CL, DL
  2082 00001C03 F3AA                <1> 	REP	STOSB			; FILL THE ODD FIELD
  2083 00001C05 5F                  <1> 	POP	eDI
  2084 00001C06 C3                  <1> 	RETn				; RETURN TO CALLER
  2085                              <1> 
  2086                              <1> ; 01/07/2016
  2087                              <1> ; 30/06/2016 - TRDOS 386 (TRDOS v2.0)
  2088                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  2089                              <1> ;--------------------------------------------------
  2090                              <1> ; GRAPHICS WRITE
  2091                              <1> ;  THIS ROUTINE WRITES THE ASCII CHARACTER TO THE CURRENT
  2092                              <1> ;  POSITION ON THE SCREEN.
  2093                              <1> ; ENTRY --
  2094                              <1> ;  AL = CHARACTER TO WRITE
  2095                              <1> ;  BL = COLOR ATTRIBUTE TO BE USED FOR FOREGROUND COLOR
  2096                              <1> ;	IF BIT 7 IS SET, THE CHAR IS XOR'D INTO THE REGEN BUFFER
  2097                              <1> ;	(0 IS USED FOR THE BACKGROUND COLOR)
  2098                              <1> ;  CX = NUMBER OF CHARS TO WRITE
  2099                              <1> ;  DS = DATA SEGMENT
  2100                              <1> ;  ES = REGEN SEGMENT
  2101                              <1> ; EXIT --
  2102                              <1> ;  NOTHING IS RETURNED
  2103                              <1> ;
  2104                              <1> ; GRAPHICS READ
  2105                              <1> ;  THIS ROUTINE READS THE ASCII CHARACTER AT THE CURRENT CURSOR
  2106                              <1> ;  POSITION ON THE SCREEN BY MATCHING THE DOTS ON THE SCREEN TO THE
  2107                              <1> ;  CHARACTER GENERATOR CODE POINTS
  2108                              <1> ; ENTRY --
  2109                              <1> ;  NONE (0 IS ASSUMED AS THE BACKGROUND COLOR)
  2110                              <1> ; EXIT --
  2111                              <1> ;  AL = CHARACTER READ AT THAT POSITION (0 RETURNED IF NONE FOUND)
  2112                              <1> ;
  2113                              <1> ; FOR BOTH ROUTINES, THE IMAGES USED TO FORM CHARS ARE CONTAINED IN ROM
  2114                              <1> ;  FOR THE 1ST 128 CHARS.  TO ACCESS CHARS IN THE SECOND HALF, THE USER
  2115                              <1> ;  MUST INITIALIZE THE VECTOR AT INTERRUPT 1FH (LOCATION 0007CH) TO
  2116                              <1> ;  POINT TO THE USER SUPPLIED TABLE OF GRAPHIC IMAGES (8X8 BOXES).
  2117                              <1> ;  FAILURE TO DO SO WILL CAUSE IN STRANGE RESULTS
  2118                              <1> ;-----------------------------------------------------
  2119                              <1> 
  2120                              <1> GRAPHICS_WRITE:
  2121 00001C07 25FF000000          <1> 	and 	eax, 0FFh		; ZERO TO HIGH OF CODE POINT
  2122 00001C0C 50                  <1> 	PUSH	eAX			; SAVE CODE POINT VALUE
  2123                              <1> 
  2124                              <1> ;-----	DETERMINE POSITION IN REGEN BUFFER TO PUT CODE POINTS
  2125                              <1> 
  2126 00001C0D E87A010000          <1> 	CALL	S26			; FIND LOCATION IN REGEN BUFFER
  2127 00001C12 89C7                <1> 	MOV	eDI, eAX		; REGEN POINTER IN DI
  2128                              <1> 
  2129                              <1> ;-----	DETERMINE REGION TO GET CODE POINTS FROM
  2130                              <1> 
  2131 00001C14 58                  <1> 	POP	eAX			; RECOVER CODE POINT
  2132 00001C15 3C80                <1> 	CMP	AL, 80H			; IS IT IN SECOND HALF
  2133 00001C17 7307                <1> 	JAE	short S1		; YES
  2134                              <1> 
  2135                              <1> ;-----	IMAGE IS IN FIRST HALF, CONTAINED IN ROM
  2136                              <1> 
  2137 00001C19 BE[84D30000]        <1> 	MOV	eSI, CRT_CHAR_GEN	; OFFSET OF IMAGES
  2138 00001C1E EB13                <1> 	JMP	SHORT S2		; DETERMINE_MODE
  2139                              <1> 
  2140                              <1> ;-----	IMAGE IS IN SECOND HALF, IN USER MEMORY
  2141                              <1> 
  2142                              <1> S1:					; EXTEND_CHAR
  2143 00001C20 2C80                <1> 	SUB	AL, 80H			; ZERO ORIGIN FOR SECOND HALF
  2144                              <1> 	; 01/07/2016
  2145 00001C22 8B35[96EA0000]      <1> 	mov	esi, [EXT_PTR]		; GET THE OFFSET OF THE TABLE
  2146 00001C28 09F6                <1> 	or	esi, esi		; Check for valid table defined
  2147 00001C2A 7507                <1> 	jnz	short S2		; Continue if esi not 0
  2148                              <1> 
  2149 00001C2C 28C0                <1> 	sub	al, al ; 0		; else set ax = 0 for "null"
  2150 00001C2E BE[84D30000]        <1> 	MOV	eSI, CRT_CHAR_GEN	; POINT TO DEFAULT TABLE OFFSET
  2151                              <1> 
  2152                              <1> ;-----	DETERMINE GRAPHICS MODE IN OPERATION
  2153                              <1> 
  2154                              <1> S2:					; DETERMINE_MODE
  2155 00001C33 66C1E003            <1> 	SAL	AX, 3			; MULTIPLY CODE POINT VALUE BY 8
  2156 00001C37 01C6                <1> 	ADD	eSI, eAX		; SI HAS OFFSET OF DESIRED CODES
  2157                              <1> 	
  2158 00001C39 803D[26D30000]06    <1> 	CMP	byte [CRT_MODE], 6
  2159 00001C40 7231                <1> 	JC	short S7		; TEST FOR MEDIUM RESOLUTION MODE
  2160                              <1> 
  2161                              <1> ;-----	HIGH RESOLUTION MODE
  2162                              <1> 
  2163 00001C42 81C700800B00        <1> 	add	edi, 0B8000h
  2164                              <1> _S3:					; HIGH_CHAR
  2165 00001C48 57                  <1> 	PUSH	eDI			; SAVE REGEN POINTER
  2166 00001C49 56                  <1> 	PUSH	eSI			; SAVE CODE POINTER
  2167 00001C4A B604                <1> 	MOV	DH, 4			; NUMBER OF TIMES THROUGH LOOP
  2168                              <1> S4:
  2169 00001C4C AC                  <1> 	LODSB				; GET BYTE FROM CODE POINTS
  2170 00001C4D F6C380              <1> 	TEST	BL, 80H			; SHOULD WE USE THE FUNCTION
  2171 00001C50 7515                <1> 	JNZ	short S6		; TO PUT CHAR IN
  2172 00001C52 AA                  <1> 	STOSB				; STORE IN REGEN BUFFER
  2173 00001C53 AC                  <1> 	LODSB
  2174                              <1> S5:
  2175 00001C54 8887FF1F0000        <1> 	MOV	[eDI+2000H-1], AL ; STORE IN SECOND HALF
  2176 00001C5A 83C74F              <1> 	ADD	eDI, 79			; MOVE TO NEXT ROW IN REGEN
  2177 00001C5D FECE                <1> 	DEC	DH			; DONE WITH LOOP
  2178 00001C5F 75EB                <1> 	JNZ	short S4
  2179 00001C61 5E                  <1> 	POP	eSI
  2180 00001C62 5F                  <1> 	POP	eDI			; RECOVER REGEN POINTER
  2181 00001C63 47                  <1> 	INC	eDI			; POINT TO NEXT CHAR POSITION
  2182 00001C64 E2E2                <1> 	LOOP	_S3			; MORE CHARS TO WRITE
  2183 00001C66 C3                  <1> 	retn
  2184                              <1> 
  2185                              <1> S6:
  2186 00001C67 3207                <1> 	XOR	AL, [eDI]		; EXCLUSIVE OR WITH CURRENT
  2187 00001C69 AA                  <1> 	STOSB				; STORE THE CODE POINT
  2188 00001C6A AC                  <1> 	LODSB				; AGAIN FOR ODD FIELD
  2189 00001C6B 3287FF1F0000        <1> 	XOR	AL, [eDI+2000H-1]
  2190 00001C71 EBE1                <1> 	JMP	short S5		; BACK TO MAINSTREAM
  2191                              <1> 
  2192                              <1> ;-----	MEDIUM RESOLUTION WRITE
  2193                              <1> S7:					; MED_RES_WRITE
  2194 00001C73 88DA                <1> 	MOV	DL, BL			; SAVE HIGH COLOR BIT
  2195 00001C75 66D1E7              <1> 	SAL	DI, 1			; OFFSET*2 SINCE 2 BYTES/CHAR
  2196                              <1> 					; EXPAND BL TO FULL WORD OF COLOR
  2197 00001C78 80E303              <1> 	AND	BL, 3			; ISOLATE THE COLOR BITS ( LOW 2 BITS )
  2198 00001C7B B055                <1> 	MOV	AL, 055H 		; GET BIT CONVERSION MULTIPLIER
  2199 00001C7D F6E3                <1> 	MUL	BL			; EXPAND 2 COLOR BITS TO 4 REPLICATIONS
  2200 00001C7F 88C3                <1> 	MOV	BL, AL			; PLACE BACK IN WORK REGISTER
  2201 00001C81 88C7                <1> 	MOV	BH, AL			; EXPAND TO 8 REPLICATIONS OF COLOR BITS
  2202 00001C83 81C700800B00        <1> 	add	edi, 0B8000h
  2203                              <1> S8:                                     ; MED_CHAR
  2204 00001C89 57                  <1> 	PUSH	eDI			; SAVE REGEN POINTER
  2205 00001C8A 56                  <1> 	PUSH	eSI			; SAVE THE CODE POINTER
  2206 00001C8B B604                <1> 	MOV	DH, 4			; NUMBER OF LOOPS
  2207                              <1> S9:
  2208 00001C8D AC                  <1> 	LODSB				; GET CODE POINT
  2209 00001C8E E8C7000000          <1> 	CALL	S21			; DOUBLE UP ALL THE BITS
  2210 00001C93 6621D8              <1> 	AND	AX, BX			; CONVERT TO FOREGROUND COLOR ( 0 BACK )
  2211 00001C96 86E0                <1> 	XCHG	AH, AL			; SWAP HIGH/LOW BYTES FOR WORD MOVE
  2212 00001C98 F6C280              <1> 	TEST	DL, 80H			; IS THIS XOR FUNCTION
  2213 00001C9B 7403                <1> 	JZ	short _S10		; NO, STORE IT IN AS IS
  2214 00001C9D 663307              <1> 	XOR	AX, [eDI]		; DO FUNCTION WITH LOW/HIGH
  2215                              <1> _S10:
  2216 00001CA0 668907              <1> 	MOV	[eDI], AX		; STORE FIRST BYTE HIGH, SECOND LOW
  2217 00001CA3 AC                  <1> 	LODSB				; GET CODE POINT
  2218 00001CA4 E8B1000000          <1> 	CALL	S21
  2219 00001CA9 6621D8              <1> 	AND	AX, BX			; CONVERT TO COLOR
  2220 00001CAC 86E0                <1> 	XCHG	AH, AL			; SWAP HIGH/LOW BYTES FOR WORD MOVE
  2221 00001CAE F6C280              <1> 	TEST	DL, 80H			; AGAIN, IS THIS XOR FUNCTION
  2222 00001CB1 7407                <1> 	JZ	short S11		; NO, JUST STORE THE VALUES
  2223 00001CB3 66338700200000      <1> 	XOR	AX, [eDI+2000H]		; FUNCTION WITH FIRST HALF LOW
  2224                              <1> S11:
  2225 00001CBA 66898700200000      <1> 	MOV	[eDI+2000H], AX		; STORE SECOND PORTION HIGH
  2226 00001CC1 6683C750            <1> 	ADD	DI, 80			; POINT TO NEXT LOCATION
  2227 00001CC5 FECE                <1> 	DEC	DH
  2228 00001CC7 75C4                <1> 	JNZ	short S9		; KEEP GOING
  2229 00001CC9 5E                  <1> 	POP	eSI			; RECOVER CODE POINTER
  2230 00001CCA 5F                  <1> 	POP	eDI			; RECOVER REGEN POINTER
  2231 00001CCB 47                  <1> 	INC	eDI			; POINT TO NEXT CHAR POSITION
  2232 00001CCC 47                  <1> 	INC	eDI
  2233 00001CCD E2BA                <1> 	LOOP	S8			; MORE TO WRITE
  2234 00001CCF C3                  <1> 	retn
  2235                              <1> 
  2236                              <1> ; 01/07/2016
  2237                              <1> ; 30/06/2016 - TRDOS 386 (TRDOS v2.0)
  2238                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  2239                              <1> ;----------------------------------------
  2240                              <1> ; GRAPHICS READ
  2241                              <1> ;----------------------------------------
  2242                              <1> GRAPHICS_READ:
  2243 00001CD0 E8B7000000          <1> 	CALL	S26			; CONVERTED TO OFFSET IN REGEN
  2244 00001CD5 89C6                <1> 	MOV	eSI, eAX		; SAVE IN SI
  2245 00001CD7 81C600800B00        <1> 	add	esi, 0B8000h		; 01/07/2016
  2246 00001CDD 83EC08              <1> 	SUB	eSP, 8			; ALLOCATE SPACE FOR THE READ CODE POINT
  2247 00001CE0 89E5                <1> 	MOV	eBP, eSP		; POINTER TO SAVE AREA
  2248                              <1> 
  2249                              <1> ;-----	DETERMINE GRAPHICS MODES
  2250 00001CE2 B604                <1> 	mov	dh, 4			; number of passes ; 01/07/2016
  2251 00001CE4 803D[26D30000]06    <1> 	CMP	byte [CRT_MODE], 6
  2252 00001CEB 7219                <1> 	JC	short S13		; MEDIUM RESOLUTION
  2253                              <1> 
  2254                              <1> ;-----	HIGH RESOLUTION READ
  2255                              <1> ;-----	GET VALUES FROM REGEN BUFFER AND CONVERT TO CODE POINT
  2256                              <1> 	;MOV	DH,4			; NUMBER OF PASSES
  2257                              <1> S12:
  2258 00001CED 8A06                <1> 	MOV	AL, [eSI] 		; GET FIRST BYTE
  2259 00001CEF 884500              <1> 	MOV	[eBP], AL 		; SAVE IN STORAGE AREA
  2260 00001CF2 45                  <1> 	INC	eBP			; NEXT LOCATION
  2261 00001CF3 8A8600200000        <1> 	MOV	AL, [eSI+2000H]		; GET LOWER REGION BYTE
  2262 00001CF9 884500              <1> 	MOV	[eBP], AL 		; ADJUST AND STORE
  2263 00001CFC 45                  <1> 	INC	eBP
  2264 00001CFD 83C650              <1> 	ADD	eSI, 80			; POINTER INTO REGEN
  2265 00001D00 FECE                <1> 	DEC	DH			; LOOP CONTROL
  2266 00001D02 75E9                <1> 	JNZ	short S12		; DO IT SOME MORE
  2267 00001D04 EB1D                <1> 	JMP	SHORT S15		; GO MATCH THE SAVED CODE POINTS
  2268                              <1> 
  2269                              <1> ;-----	MEDIUM RESOLUTION READ
  2270                              <1> S13:	
  2271 00001D06 66D1E6              <1> 	SAL	SI, 1			; OFFSET*2 SINCE 2 BYTES/CHAR
  2272                              <1> 	;MOV	DH, 4			; NUMBER OF PASSES
  2273                              <1> S14:
  2274 00001D09 E861000000          <1> 	CALL	S23			; GET BYTES FROM REGEN INTO SINGLE SAVE
  2275 00001D0E 81C6FE1F0000        <1> 	ADD	eSI, 2000H-2		; GO TO LOWER REGION
  2276 00001D14 E856000000          <1> 	CALL	S23			; GET THIS PAIR INTO SAVE
  2277 00001D19 81EEB21F0000        <1> 	SUB	eSI, 2000H-80+2		; ADJUST POINTER BACK INTO UPPER
  2278 00001D1F FECE                <1> 	DEC	DH
  2279 00001D21 75E6                <1> 	JNZ	short S14		; KEEP GOING UNTIL ALL 8 DONE
  2280                              <1> 
  2281                              <1> ;-----	SAVE AREA HAS CHARACTER IN IT, MATCH IT
  2282                              <1> S15:					; FIND_CHAR
  2283 00001D23 BF[84D30000]        <1> 	MOV	eDI, CRT_CHAR_GEN	; ESTABLISH ADDRESSING
  2284 00001D28 83ED08              <1> 	SUB	eBP, 8			; ADJUST POINTER TO START OF SAVE AREA
  2285 00001D2B 89EE                <1> 	MOV	eSI, eBP
  2286 00001D2D B000                <1> 	MOV	AL, 0			; CURRENT CODE POINT BEING MATCHED
  2287                              <1> S16:
  2288                              <1> 	;MOV	DX, 128			; NUMBER TO TEST AGAINST
  2289 00001D2F B280                <1> 	mov	dl, 128
  2290                              <1> S17:
  2291 00001D31 56                  <1> 	PUSH	eSI			; SAVE SAVE AREA POINTER
  2292 00001D32 57                  <1> 	PUSH	eDI			; SAVE CODE POINTER
  2293                              <1> 	;MOV	eCX, 4			; NUMBER OF WORDS TO MATCH
  2294                              <1> 	;REPE	CMPSW			; COMPARE THE 8 BYTES AS WORDS
  2295 00001D33 A7                  <1> 	cmpsd				; compare first 4 bytes 
  2296 00001D34 7501                <1> 	jne	short _S19		; 
  2297 00001D36 A7                  <1> 	cmpsd				; compare last 4 bytes
  2298                              <1> _S19:
  2299 00001D37 5F                  <1> 	POP	eDI			; RECOVER THE POINTERS
  2300 00001D38 5E                  <1> 	POP	eSI
  2301                              <1> 	;JZ	short S18		; IF ZERO FLAG SET, THEN MATCH OCCURRED
  2302 00001D39 741B                <1> 	je	short S18
  2303                              <1> 	;
  2304 00001D3B FEC0                <1> 	INC	AL			; NO MATCH, MOVE ON TO NEXT
  2305 00001D3D 83C708              <1> 	ADD	eDI, 8			; NEXT CODE POINT
  2306                              <1> 	;DEC	DX			; LOOP CONTROL
  2307 00001D40 FECA                <1> 	dec	dl
  2308 00001D42 75ED                <1> 	JNZ	short S17		; DO ALL OF THEM
  2309                              <1> 
  2310                              <1> ;-----	CHAR NOT MATCHED, MIGHT BE IN USER SUPPLIED SECOND HALF
  2311                              <1> 	;CMP	AL, 0			; AL<> 0 IF ONLY 1ST HALF SCANNED
  2312                              <1> 	;JE	short S18		; IF = 0, THEN ALL HAS BEEN SCANNED
  2313 00001D44 20C0                <1> 	and	al, al
  2314 00001D46 740E                <1> 	jz	short S18
  2315 00001D48 8B3D[96EA0000]      <1> 	mov	edi, [EXT_PTR]		; GET POINTER
  2316 00001D4E 09FF                <1> 	or	edi, edi		; If zf = 1, then it doesn't exist
  2317 00001D50 7404                <1> 	JZ	short S18		; NO SENSE LOOKING
  2318 00001D52 B080                <1> 	MOV	AL, 128			; ORIGIN FOR SECOND HALF
  2319 00001D54 EBD9                <1> 	JMP	short S16		; GO BACK AND TRY FOR IT
  2320                              <1> 
  2321                              <1> ;-----	CHARACTER IS FOUND ( AL=0 IF NOT FOUND )
  2322                              <1> S18:	
  2323 00001D56 83C408              <1> 	ADD	eSP, 8			; READJUST THE STACK, THROW AWAY SAVE
  2324 00001D59 C3                  <1> 	retn				; ALL DONE
  2325                              <1> 
  2326                              <1> ; 30/06/2016 - TRDOS 386 (TRDOS v2.0)
  2327                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  2328                              <1> ;--------------------------------------------
  2329                              <1> ; EXPAND BYTE
  2330                              <1> ;  THIS ROUTINE TAKES THE BYTE IN AL AND DOUBLES ALL
  2331                              <1> ;  OF THE BITS, TURNING THE 8 BITS INTO 16 BITS.
  2332                              <1> ;  THE RESULT IS LEFT IN AX
  2333                              <1> ;--------------------------------------------
  2334                              <1> S21:
  2335 00001D5A 6651                <1> 	PUSH	CX			; SAVE REGISTER
  2336                              <1> 	;MOV	CX, 8			; SHIFT COUNT REGISTER FOR ONE BYTE
  2337 00001D5C B108                <1> 	mov	cl, 8
  2338                              <1> S22:
  2339 00001D5E D0C8                <1> 	ROR	AL,1			; SHIFT BITS, LOW BIT INTO CARRY FLAG
  2340 00001D60 66D1DD              <1> 	RCR	BP,1			; MOVE CARRY FLAG (LOW BIT INTO RESULTS
  2341 00001D63 66D1FD              <1> 	SAR	BP,1			; SIGN EXTEND HIGH BIT (DOUBLE IT)
  2342                              <1> 	;LOOP	S22			; REPEAT FOR ALL 8 BITS
  2343 00001D66 FEC9                <1> 	dec	cl
  2344 00001D68 75F4                <1> 	jnz	short S22
  2345 00001D6A 6695                <1> 	XCHG	AX, BP			; MOVE RESULTS TO PARAMETER REGISTER
  2346 00001D6C 6659                <1> 	POP	CX			; RECOVER REGISTER
  2347 00001D6E C3                  <1> 	RETn				; ALL DONE
  2348                              <1> 
  2349                              <1> ; 01/07/2016 - TRDOS 386 (TRDOS v2.0)
  2350                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  2351                              <1> ;--------------------------------------------------
  2352                              <1> ; MED_READ_BYTE
  2353                              <1> ; THIS ROUTINE WILL TAKE 2 BYTES FROM THE REGEN BUFFER,
  2354                              <1> ;  COMPARE AGAINST THE CURRENT FOREGROUND COLOR, AND PLACE
  2355                              <1> ;  THE CORRESPONDING ON/OFF BIT PATTERN INTO THE CURRENT
  2356                              <1> ;  POSITION IN THE SAVE AREA
  2357                              <1> ; ENTRY --
  2358                              <1> ;  SI,DS = POINTER TO REGEN AREA OF INTEREST
  2359                              <1> ;  BX = EXPANDED FOREGROUND COLOR
  2360                              <1> ;  BP = POINTER TO SAVE AREA
  2361                              <1> ; EXIT --
  2362                              <1> ;  SI AND BP ARE INCREMENTED
  2363                              <1> ;----------------------------------------------------
  2364                              <1> S23:
  2365 00001D6F 66AD                <1> 	LODSW				; GET FIRST BYTE AND SECOND BYTES
  2366 00001D71 86C4                <1> 	XCHG	AL, AH			; SWAP FOR COMPARE
  2367 00001D73 66B900C0            <1> 	MOV	CX, 0C000H		; 2 BIT MASK TO TEST THE ENTRIES
  2368 00001D77 B200                <1> 	MOV	DL, 0			; RESULT REGISTER
  2369                              <1> S24:
  2370 00001D79 6685C8              <1> 	TEST	AX, CX			; IS THIS SECTION BACKCROUND?
  2371 00001D7C 7401                <1>         JZ      short S25               ; IF ZERO, IT IS BACKGROUND (CARRY=0)
  2372 00001D7E F9                  <1> 	STC				; WASN'T, SO SET CARRY
  2373                              <1> S25:
  2374 00001D7F D0D2                <1> 	RCL	DL, 1			; MOVE THAT BIT INTO THE RESULT
  2375 00001D81 66C1E902            <1> 	SHR	CX, 2			; MOVE THE MASK TO THE RIGHT BY 2 BITS
  2376 00001D85 73F2                <1> 	JNC	short S24		; DO IT AGAIN IF MASK DIDN'T FALL OUT
  2377 00001D87 885500              <1> 	MOV	[eBP], DL 		; STORE RESULT IN SAVE AREA
  2378 00001D8A 45                  <1> 	INC	eBP			; ADJUST POINTER
  2379 00001D8B C3                  <1> 	RETn				; ALL DONE
  2380                              <1> 
  2381                              <1> ; 30/06/2016 - TRDOS 386 (TRDOS v2.0)
  2382                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  2383                              <1> ;-----------------------------------------
  2384                              <1> ; V4_POSITION
  2385                              <1> ;  THIS ROUTINE TAKES THE CURSOR POSITION CONTAINED IN
  2386                              <1> ;  THE MEMORY LOCATION, AND CONVERTS IT INTO AN OFFSET
  2387                              <1> ;  INTO THE REGEN BUFFER, ASSUMING ONE BYTE/CHAR.
  2388                              <1> ;  FOR MEDIUM RESOLUTION GRAPHICS, THE NUMBER MUST
  2389                              <1> ;  BE DOUBLED.
  2390                              <1> ; ENTRY -- NO REGISTERS,MEMORY LOCATION @CURSOR_POSN IS USED
  2391                              <1> ; EXIT--
  2392                              <1> ;  AX CONTAINS OFFSET INTO REGEN BUFFER
  2393                              <1> ;-----------------------------------------
  2394                              <1> S26:
  2395 00001D8C 0FB705[16DD0000]    <1> 	movzx	eax, word [CURSOR_POSN]	; GET CURRENT CURSOR
  2396                              <1> GRAPH_POSN:
  2397 00001D93 53                  <1> 	PUSH	eBX			; SAVE REGISTER
  2398 00001D94 0FB6D8              <1> 	movzx	ebx, al			; SAVE A COPY OF CURRENT CURSOR
  2399 00001D97 A0[28D30000]        <1> 	MOV	AL, [CRT_COLS]		; GET BYTES PER COLUMN
  2400 00001D9C F6E4                <1> 	MUL	AH			; MULTIPLY BY ROWS
  2401 00001D9E 66C1E002            <1> 	SHL	AX, 2			; MULTIPLY * 4 SINCE 4 ROWS/BYTE
  2402 00001DA2 01D8                <1> 	ADD	eAX, eBX		; DETERMINE OFFSET
  2403 00001DA4 5B                  <1> 	POP	eBX			; RECOVER POINTER
  2404 00001DA5 C3                  <1> 	RETn				; ALL DONE
  2405                              <1> 
  2406                              <1> ; 01/07/2016 - TRDOS 386 (TRDOS v2.0)
  2407                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  2408                              <1> ;---------------------------------------------
  2409                              <1> ; SET_COLOR
  2410                              <1> ;	THIS ROUTINE SILL ESTABLISH THE BACKGROUND COLOR, THE OVERSCAN COLOR,
  2411                              <1> ;	AND THE FOREGROUND COLOR SET FOR MEDIUM RESOLUTION GRAPHICS
  2412                              <1> ; INPUT
  2413                              <1> ;	(BH) HAS COLOR ID
  2414                              <1> ;		IF BH=0, THE BACKGROUND COLOR VALUE IS SET
  2415                              <1> ;			FROM THE LOW BITS OF BL (0-31)
  2416                              <1> ;		IF BH=1, THE PALETTE SELECTION IS MADE
  2417                              <1> ;			BASED ON THE LOW BIT OF BL:
  2418                              <1> ;				0 = GREEN, RED, YELLOW FOR COLORS 1,2,3
  2419                              <1> ;				1 = BLUE, CYAN, MAGENTA FOR COLORS 1,2,3
  2420                              <1> ;	(BL) HAS THE COLOR VALUE TO BE USED
  2421                              <1> ; OUTPUT
  2422                              <1> ;	THE COLOR SELECTION IS UPDATED
  2423                              <1> ;----------------------------------------------
  2424                              <1> SET_COLOR:
  2425                              <1> 	;MOV	DX, [ADDR_6845]		; I/O PORT FOR PALETTE
  2426                              <1> 	;mov	dx, 3D4h
  2427                              <1> 	;ADD	DX,5			; OVERSCAN PORT
  2428 00001DA6 66BAD903            <1> 	mov	dx, 3D9h
  2429 00001DAA A0[29D30000]        <1> 	MOV	AL, [CRT_PALETTE] 	; GET THE CURRENT PALETTE VALUE
  2430 00001DAF 08FF                <1> 	OR	BH, BH			; IS THIS COLOR 0?
  2431 00001DB1 7512                <1> 	JNZ	short M20		; OUTPUT COLOR 1
  2432                              <1> 
  2433                              <1> ;-----	HANDLE COLOR 0 BY SETTING THE BACKGROUND COLOR
  2434                              <1> 
  2435 00001DB3 24E0                <1> 	AND	AL, 0E0H 		; TURN OFF LOW 5 BITS OF CURRENT
  2436 00001DB5 80E31F              <1> 	AND	BL, 01FH 		; TURN OFF HIGH 3 BITS OF INPUT VALUE
  2437 00001DB8 08D8                <1> 	OR	AL, BL			; PUT VALUE INTO REGISTER
  2438                              <1> M19:					; OUTPUT THE PALETTE
  2439 00001DBA EE                  <1> 	OUT	DX, AL			; OUTPUT COLOR SELECTION TO 3D9 PORT
  2440 00001DBB A2[29D30000]        <1> 	MOV	[CRT_PALETTE], AL 	; SAVE THE COLOR VALUE
  2441 00001DC0 E90EF6FFFF          <1> 	JMP	VIDEO_RETURN
  2442                              <1> 
  2443                              <1> ;-----	HANDLE COLOR 1 BY SELECTING THE PALETTE TO BE USED
  2444                              <1> 
  2445                              <1> M20:
  2446 00001DC5 24DF                <1> 	AND	AL, 0DFH 		; TURN OFF PALETTE SELECT BIT
  2447 00001DC7 D0EB                <1> 	SHR	BL, 1			; TEST THE LOW ORDER BIT OF BL
  2448 00001DC9 73EF                <1> 	JNC	short M19		; ALREADY DONE
  2449 00001DCB 0C20                <1> 	OR	AL, 20H			; TURN ON PALETTE SELECT BIT
  2450 00001DCD EBEB                <1> 	JMP	short M19		; GO DO IT
  2451                              <1> 
  2452                              <1> ; 01/07/2016 - TRDOS 386 (TRDOS v2.0)
  2453                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  2454                              <1> ;--------------------------------------------
  2455                              <1> ; READ DOT -- WRITE DOT
  2456                              <1> ; THESE ROUTINES WILL WRITE A DOT, OR READ THE
  2457                              <1> ;  DOT AT THE INDICATED LOCATION
  2458                              <1> ; ENTRY --
  2459                              <1> ;   DX = ROW (0-199)	(THE ACTUAL VALUE DEPENDS ON THE MODE)
  2460                              <1> ;   CX = COLUMN ( 0-639) ( THE VALUES ARE NOT RANGE CHECKED )
  2461                              <1> ;   AL = DOT VALUE TO WRITE (1,2 OR 4 BITS DEPENDING ON MODE,
  2462                              <1> ;	REQUIRED FOR WRITE DOT ONLY, RIGHT JUSTIFIED)
  2463                              <1> ;	BIT 7 OF AL = 1 INDICATES XOR THE VALUE INTO THE LOCATION
  2464                              <1> ;   DS = DATA SEGMENT
  2465                              <1> ;   ES = REGEN SEGMENT
  2466                              <1> ;
  2467                              <1> ; EXIT
  2468                              <1> ;	AL = DOT VALUE READ, RIGHT JUSTIFIED, READ ONLY
  2469                              <1> ;----------------------------------------------
  2470                              <1> 
  2471                              <1> READ_DOT:
  2472 00001DCF E837000000          <1> 	CALL	R3			; DETERMINE BYTE POSITION OF DOT
  2473 00001DD4 8A06                <1> 	MOV	AL, [eSI]		; GET THE BYTE
  2474 00001DD6 20E0                <1> 	AND	AL, AH			; MASK OFF THE OTHER BITS IN THE BYTE
  2475 00001DD8 D2E0                <1> 	SHL	AL, CL			; LEFT JUSTIFY THE VALUE
  2476 00001DDA 88F1                <1> 	MOV	CL, DH			; GET NUMBER OF BITS IN RESULT
  2477 00001DDC D2C0                <1> 	ROL	AL, CL			; RIGHT JUSTIFY THE RESULT
  2478                              <1> 	;JMP	VIDEO_RETURN		; RETURN FROM VIDEO I/O
  2479 00001DDE 0FB6C0              <1> 	movzx	eax, al
  2480 00001DE1 E9F2F5FFFF          <1> 	jmp	_video_return
  2481                              <1> 
  2482                              <1> ; 01/07/2016 - TRDOS 386 (TRDOS v2.0)
  2483                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  2484                              <1> 
  2485                              <1> WRITE_DOT:
  2486                              <1> 	;PUSH	AX			; SAVE DOT VALUE
  2487 00001DE6 6650                <1> 	PUSH	AX			; TWICE
  2488 00001DE8 E81E000000          <1> 	CALL	R3			; DETERMINE BYTE POSITION OF THE DOT
  2489 00001DED D2E8                <1> 	SHR	AL, CL			; SHIFT TO SET UP THE BITS FOR OUTPUT
  2490 00001DEF 20E0                <1> 	AND	AL, AH			; STRIP OFF THE OTHER BITS
  2491 00001DF1 8A0E                <1> 	MOV	CL, [eSI]		; GET THE CURRENT BYTE
  2492 00001DF3 665B                <1> 	POP	BX			; RECOVER XOR FLAG
  2493 00001DF5 F6C380              <1> 	TEST	BL, 80H			; IS IT ON
  2494 00001DF8 750D                <1> 	JNZ	short R2		; YES, XOR THE DOT
  2495 00001DFA F6D4                <1> 	NOT	AH			; SET MASK TO REMOVE THE INDICATED BITS
  2496 00001DFC 20E1                <1> 	AND	CL, AH
  2497 00001DFE 08C8                <1> 	OR	AL, CL			; OR IN THE NEW VALUE OF THOSE BITS
  2498                              <1> R1:					; FINISH_DOT
  2499 00001E00 8806                <1> 	MOV	[eSI], AL		; RESTORE THE BYTE IN MEMORY
  2500                              <1> 	;POP	AX
  2501 00001E02 E9CCF5FFFF          <1> 	JMP	VIDEO_RETURN		; RETURN FROM VIDEO I/O
  2502                              <1> R2:					; XOR_DOT
  2503 00001E07 30C8                <1> 	XOR	AL, CL			; EXCLUSIVE OR THE DOTS
  2504 00001E09 EBF5                <1> 	JMP	short R1		; FINISH UP THE WRITING
  2505                              <1> 
  2506                              <1> ; 01/07/2016 - TRDOS 386 (TRDOS v2.0)
  2507                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  2508                              <1> 
  2509                              <1> ;----------------------------------------------
  2510                              <1> ; THIS SUBROUTINE DETERMINES THE REGEN BYTE LOCATION OF THE
  2511                              <1> ; INDICATED ROW COLUMN VALUE IN GRAPHICS MODE.
  2512                              <1> ; ENTRY --
  2513                              <1> ;  DX = ROW VALUE (0-199)
  2514                              <1> ;  CX = COLUMN VALUE (0-639)
  2515                              <1> ; EXIT --
  2516                              <1> ;  SI = OFFSET INTO REGEN BUFFER FOR BYTE OF INTEREST
  2517                              <1> ;  AH = MASK TO STRIP OFF THE BITS OF INTEREST
  2518                              <1> ;  CL = BITS TO SHIFT TO RIGHT JUSTIFY THE MASK IN AH
  2519                              <1> ;  DH = # BITS IN RESULT
  2520                              <1> ;  BX = MODIFIED
  2521                              <1> ;-----------------------------------------------
  2522                              <1> R3:
  2523                              <1> 
  2524                              <1> ;-----	DETERMINE 1ST BYTE IN INDICATED ROW BY MULTIPLYING ROW VALUE BY 40
  2525                              <1> ;-----	 ( LOW BIT OF ROW DETERMINES EVEN/ODD, 80 BYTES/ROW )
  2526                              <1> 
  2527 00001E0B 0FB7F0              <1> 	movzx	esi, ax			; WILL SAVE AL AND AH DURING OPERATION
  2528 00001E0E B028                <1> 	MOV	AL, 40
  2529 00001E10 F6E2                <1> 	MUL	DL			; AX= ADDRESS OF START OF INDICATED ROW
  2530 00001E12 A808                <1> 	TEST	AL, 08H 		; TEST FOR EVEN/ODD ROW CALCULATED
  2531 00001E14 7404                <1> 	JZ	short R4		; JUMP IF EVEN ROW
  2532 00001E16 6605D81F            <1> 	ADD	AX, 2000H-40		; OFFSET TO LOCATION OF ODD ROWS ADJUST
  2533                              <1> R4:					; EVEN_ROW
  2534 00001E1A 6696                <1> 	XCHG	SI, AX			; MOVE POINTER TO (SI) AND RECOVER (AX)
  2535 00001E1C 81C600800B00        <1> 	add	esi, 0B8000h
  2536 00001E22 6689CA              <1> 	MOV	DX, CX			; COLUMN VALUE TO DX
  2537                              <1> 
  2538                              <1> ;-----	DETERMINE GRAPHICS MODE CURRENTLY IN EFFECT
  2539                              <1> 
  2540                              <1> ; SET UP THE REGISTERS ACCORDING TO THE MODE
  2541                              <1> ; CH = MASK FOR LOW OF COLUMN ADDRESS ( 7/3 FOR HIGH/MED RES )
  2542                              <1> ; CL = # OF ADDRESS BITS IN COLUMN VALUE ( 3/2 FOR H/M )
  2543                              <1> ; BL = MASK TO SELECT BITS FROM POINTED BYTE ( 80H/C0H FOR H/M )
  2544                              <1> ; BH = NUMBER OF VALID BITS IN POINTED BYTE ( 1/2 FOR H/M )
  2545                              <1> 
  2546 00001E25 66BBC002            <1> 	MOV	BX, 2C0H
  2547 00001E29 66B90203            <1> 	MOV	CX, 302H 		; SET PARMS FOR MED RES
  2548 00001E2D 803D[26D30000]06    <1> 	CMP	byte [CRT_MODE], 6
  2549 00001E34 7208                <1> 	JC	short R5		; HANDLE IF MED RES
  2550 00001E36 66BB8001            <1> 	MOV	BX, 180H
  2551 00001E3A 66B90307            <1> 	MOV	CX, 703H 		; SET PARMS FOR HIGH RES
  2552                              <1> 
  2553                              <1> ;-----	DETERMINE BIT OFFSET IN BYTE FROM COLUMN MASK
  2554                              <1> R5:
  2555 00001E3E 20D5                <1> 	AND	CH, DL			; ADDRESS OF PEL WITHIN BYTE TO CH
  2556                              <1> 
  2557                              <1> ;-----	DETERMINE BYTE OFFSET FOR THIS LOCATION IN COLUMN
  2558                              <1> 
  2559 00001E40 66D3EA              <1> 	SHR	DX, CL			; SHIFT BY CORRECT AMOUNT
  2560 00001E43 6601D6              <1> 	ADD	SI, DX			; INCREMENT THE POINTER
  2561 00001E46 88FE                <1> 	MOV	DH, BH			; GET THE # OF BITS IN RESULT TO DH
  2562                              <1> 
  2563                              <1> ;-----	MULTIPLY BH (VALID BITS IN BYTE) BY CH (BIT OFFSET)
  2564                              <1> 
  2565 00001E48 28C9                <1> 	SUB	CL, CL			; ZERO INTO STORAGE LOCATION
  2566                              <1> R6:
  2567 00001E4A D0C8                <1> 	ROR	AL, 1			; LEFT JUSTIFY VALUE IN AL (FOR WRITE)
  2568 00001E4C 00E9                <1> 	ADD	CL, CH			; ADD IN THE BIT OFFSET VALUE
  2569 00001E4E FECF                <1> 	DEC	BH			; LOOP CONTROL
  2570 00001E50 75F8                <1> 	JNZ	short R6		; ON EXIT, CL HAS COUNT TO RESTORE BITS
  2571 00001E52 88DC                <1> 	MOV	AH, BL			;  GET MASK TO AH
  2572 00001E54 D2EC                <1> 	SHR	AH, CL			;  MOVE THE MASK TO CORRECT LOCATION
  2573 00001E56 C3                  <1> 	RETn				;  RETURN WITH EVERYTHING SET UP
  2574                              <1> 
  2575                              <1> ; % include 'vidata.s' ; VIDEO DATA
  2576                              <1> 
  2577                              <1> ; /// End Of VIDEO FUNCTIONS ///
  1682                                  
  1683                                  setup_rtc_int:
  1684                                  ; source: http://wiki.osdev.org/RTC
  1685 00001E57 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 00001E58 B08A                    	mov	al, 8Ah 
  1692 00001E5A E670                    	out	70h, al ; set index to register A, disable NMI
  1693 00001E5C 90                      	nop
  1694 00001E5D E471                    	in	al, 71h ; get initial value of register A
  1695 00001E5F 88C4                    	mov 	ah, al
  1696 00001E61 80E4F0                  	and	ah, 0F0h
  1697 00001E64 B08A                    	mov	al, 8Ah 
  1698 00001E66 E670                    	out	70h, al ; reset index to register A
  1699 00001E68 88E0                    	mov	al, ah
  1700 00001E6A 0C0F                    	or	al, 0Fh	; new rate (0Fh -> 15)
  1701 00001E6C E671                    	out	71h, al ; write only our rate to A. Note, rate is the bottom 4 bits. 
  1702                                  	; enable RTC interrupt
  1703 00001E6E B08B                    	mov	al, 8Bh ;
  1704 00001E70 E670                    	out	70h, al ; select register B and disable NMI
  1705 00001E72 90                      	nop
  1706 00001E73 E471                    	in	al, 71h ; read the current value of register B
  1707 00001E75 88C4                    	mov	ah, al  ;
  1708 00001E77 B08B                    	mov 	al, 8Bh ;
  1709 00001E79 E670                    	out	70h, al ; set the index again (a read will reset the index to register B)	
  1710 00001E7B 88E0                    	mov	al, ah  ;
  1711 00001E7D 0C40                    	or	al, 40h ;
  1712 00001E7F E671                    	out	71h, al ; write the previous value ORed with 0x40. This turns on bit 6 of register B
  1713 00001E81 FB                      	sti
  1714 00001E82 C3                      	retn
  1715                                  
  1716                                  ; Write memory information
  1717                                  ; 29/01/2016
  1718                                  ; 06/11/2014
  1719                                  ; 14/08/2015 
  1720                                  memory_info:	
  1721 00001E83 A1[FCDC0000]            	mov	eax, [memory_size] ; in pages
  1722 00001E88 50                      	push	eax
  1723 00001E89 C1E00C                  	shl	eax, 12		   ; in bytes
  1724 00001E8C BB0A000000              	mov	ebx, 10
  1725 00001E91 89D9                    	mov	ecx, ebx	   ; 10
  1726 00001E93 BE[0DD90000]            	mov	esi, mem_total_b_str	
  1727 00001E98 E8BD000000              	call	bintdstr
  1728 00001E9D 58                      	pop	eax
  1729 00001E9E B107                    	mov	cl, 7
  1730 00001EA0 BE[31D90000]            	mov	esi, mem_total_p_str
  1731 00001EA5 E8B0000000              	call	bintdstr	
  1732                                  	; 14/08/2015
  1733 00001EAA E8C8000000              	call	calc_free_mem
  1734                                  	; edx = calculated free pages
  1735                                  	; ecx = 0
  1736 00001EAF A1[00DD0000]            	mov 	eax, [free_pages]
  1737 00001EB4 39D0                    	cmp	eax, edx ; calculated free mem value 
  1738                                  		; and initial free mem value are same or not?
  1739 00001EB6 751D                    	jne 	short pmim ; print mem info with '?' if not
  1740 00001EB8 52                      	push 	edx ; free memory in pages	
  1741                                  	;mov 	eax, edx
  1742 00001EB9 C1E00C                  	shl	eax, 12 ; convert page count
  1743                                  			; to byte count
  1744 00001EBC B10A                    	mov	cl, 10
  1745 00001EBE BE[51D90000]            	mov	esi, free_mem_b_str
  1746 00001EC3 E892000000              	call	bintdstr
  1747 00001EC8 58                      	pop	eax
  1748 00001EC9 B107                    	mov	cl, 7
  1749 00001ECB BE[75D90000]            	mov	esi, free_mem_p_str
  1750 00001ED0 E885000000              	call	bintdstr
  1751                                  pmim:
  1752 00001ED5 BE[FBD80000]            	mov	esi, msg_memory_info
  1753                                  	;
  1754 00001EDA B407                    	mov	ah, 07h ; Black background, 
  1755                                  			; light gray forecolor
  1756                                  print_kmsg: ; 29/01/2016
  1757 00001EDC 8825[27DD0000]          	mov	[ccolor], ah
  1758                                  pkmsg_loop:
  1759 00001EE2 AC                      	lodsb
  1760 00001EE3 08C0                    	or	al, al
  1761 00001EE5 7410                    	jz	short pkmsg_ok
  1762 00001EE7 56                      	push	esi
  1763                                  	; 13/05/2016
  1764 00001EE8 0FB61D[27DD0000]        	movzx	ebx, byte [ccolor]
  1765                                  			; Video page 0 (bh=0)
  1766 00001EEF E8FBF9FFFF              	call	_write_tty
  1767 00001EF4 5E                      	pop	esi
  1768 00001EF5 EBEB                    	jmp	short pkmsg_loop
  1769                                  pkmsg_ok:
  1770 00001EF7 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 00001EF8 53                      	push	ebx
  1786 00001EF9 31DB                    	xor	ebx, ebx
  1787 00001EFB 88C3                    	mov	bl, al
  1788 00001EFD C0EB04                  	shr	bl, 4
  1789 00001F00 8A9B[4A1F0000]          	mov	bl, [ebx+hexchrs] 	 	
  1790 00001F06 86D8                    	xchg	bl, al
  1791 00001F08 80E30F                  	and	bl, 0Fh
  1792 00001F0B 8AA3[4A1F0000]          	mov	ah, [ebx+hexchrs] 
  1793 00001F11 5B                      	pop	ebx	
  1794 00001F12 C3                      	retn
  1795                                  
  1796                                  wordtohex:
  1797                                  	; INPUT ->
  1798                                  	; 	AX = word (binary number)
  1799                                  	; OUTPUT ->
  1800                                  	;	EAX = hexadecimal string
  1801                                  	;
  1802 00001F13 53                      	push	ebx
  1803 00001F14 31DB                    	xor	ebx, ebx
  1804 00001F16 86E0                    	xchg	ah, al
  1805 00001F18 6650                    	push	ax
  1806 00001F1A 88E3                    	mov	bl, ah
  1807 00001F1C C0EB04                  	shr	bl, 4
  1808 00001F1F 8A83[4A1F0000]          	mov	al, [ebx+hexchrs] 	 	
  1809 00001F25 88E3                    	mov	bl, ah
  1810 00001F27 80E30F                  	and	bl, 0Fh
  1811 00001F2A 8AA3[4A1F0000]          	mov	ah, [ebx+hexchrs]
  1812 00001F30 C1E010                  	shl	eax, 16
  1813 00001F33 6658                    	pop	ax
  1814 00001F35 5B                      	pop	ebx
  1815 00001F36 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 00001F38 50                      	push	eax
  1832 00001F39 C1E810                  	shr	eax, 16
  1833 00001F3C E8D2FFFFFF              	call	wordtohex
  1834 00001F41 89C2                    	mov	edx, eax
  1835 00001F43 58                      	pop	eax
  1836 00001F44 E8CAFFFFFF              	call	wordtohex
  1837 00001F49 C3                      	retn
  1838                                  
  1839                                  ; 10/05/2015
  1840                                  hex_digits:
  1841                                  hexchrs:
  1842 00001F4A 303132333435363738-     	db '0123456789ABCDEF'
  1842 00001F53 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 00001F5A 01CE                    	add	esi, ecx
  1855                                  btdstr0:
  1856 00001F5C 4E                      	dec	esi
  1857 00001F5D 31D2                    	xor	edx, edx
  1858 00001F5F F7F3                    	div	ebx
  1859 00001F61 80C230                  	add	dl, 30h
  1860 00001F64 8816                    	mov	[esi], dl
  1861 00001F66 FEC9                    	dec	cl
  1862 00001F68 740C                    	jz	btdstr2
  1863 00001F6A 09C0                    	or	eax, eax
  1864 00001F6C 75EE                    	jnz	short btdstr0
  1865                                  btdstr1:
  1866 00001F6E 4E                      	dec	esi
  1867 00001F6F C60620                          mov     byte [esi], 20h ; blank space
  1868 00001F72 FEC9                    	dec	cl
  1869 00001F74 75F8                    	jnz	short btdstr1
  1870                                  btdstr2:
  1871 00001F76 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 00001F77 31D2                    	xor	edx, edx
  1880                                  	;xor	ecx, ecx
  1881 00001F79 668B0D[10DD0000]        	mov	cx, [mat_size] ; in pages
  1882 00001F80 C1E10A                  	shl	ecx, 10	; 1024 dwords per page
  1883 00001F83 BE00001000              	mov	esi, MEM_ALLOC_TBL
  1884                                  cfm0:
  1885 00001F88 AD                      	lodsd
  1886 00001F89 51                      	push	ecx
  1887 00001F8A B920000000              	mov	ecx, 32
  1888                                  cfm1:
  1889 00001F8F D1E8                    	shr	eax, 1
  1890 00001F91 7301                    	jnc	short cfm2
  1891 00001F93 42                      	inc	edx
  1892                                  cfm2:
  1893 00001F94 E2F9                    	loop	cfm1
  1894 00001F96 59                      	pop	ecx
  1895 00001F97 E2EF                    	loop	cfm0
  1896 00001F99 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 00001F9A 9C                  <1> 	pushfd
    31 00001F9B 0E                  <1> 	push 	cs
    32 00001F9C E809000000          <1> 	call 	DISKETTE_IO_1
    33 00001FA1 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 00001FA2 9C                  <1> 	pushfd
   457 00001FA3 0E                  <1> 	push 	cs
   458 00001FA4 E801000000          <1> 	call 	DISKETTE_IO_1
   459 00001FA9 C3                  <1> 	retn	
   460                              <1> 
   461                              <1> DISKETTE_IO_1:
   462                              <1> 
   463 00001FAA FB                  <1> 	STI				; INTERRUPTS BACK ON
   464 00001FAB 55                  <1> 	PUSH	eBP			; USER REGISTER
   465 00001FAC 57                  <1> 	PUSH	eDI			; USER REGISTER
   466 00001FAD 52                  <1> 	PUSH	eDX			; HEAD #, DRIVE # OR USER REGISTER
   467 00001FAE 53                  <1> 	PUSH	eBX			; BUFFER OFFSET PARAMETER OR REGISTER
   468 00001FAF 51                  <1> 	PUSH	eCX			; TRACK #-SECTOR # OR USER REGISTER
   469 00001FB0 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 00001FB2 06                  <1> 	push	es ; 06/02/2015	
   484 00001FB3 1E                  <1> 	PUSH	DS			; BUFFER SEGMENT PARM OR USER REGISTER
   485 00001FB4 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 00001FB5 66B91000            <1> 	mov	cx, KDATA
   490 00001FB9 8ED9                <1>         mov     ds, cx
   491 00001FBB 8EC1                <1>         mov     es, cx
   492                              <1> 
   493                              <1> 	;CMP	AH,(FNC_TAE-FNC_TAB)/2	; CHECK FOR > LARGEST FUNCTION
   494 00001FBD 80FC19              <1> 	cmp	ah,(FNC_TAE-FNC_TAB)/4  ; 18/02/2015
   495 00001FC0 7202                <1> 	JB	short OK_FUNC		; FUNCTION OK
   496 00001FC2 B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
   497                              <1> OK_FUNC:
   498 00001FC4 80FC01              <1> 	CMP	AH,1			; RESET OR STATUS ?
   499 00001FC7 760C                <1> 	JBE	short OK_DRV		; IF RESET OR STATUS DRIVE ALWAYS OK
   500 00001FC9 80FC08              <1> 	CMP	AH,8			; READ DRIVE PARMS ?
   501 00001FCC 7407                <1> 	JZ	short OK_DRV		; IF SO DRIVE CHECKED LATER
   502 00001FCE 80FA01              <1> 	CMP	DL,1			; DRIVES 0 AND 1 OK
   503 00001FD1 7602                <1> 	JBE	short OK_DRV		; IF 0 OR 1 THEN JUMP
   504 00001FD3 B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
   505                              <1> OK_DRV:
   506 00001FD5 31C9                <1> 	xor	ecx, ecx
   507                              <1> 	;mov	esi, ecx ; 08/02/2015
   508 00001FD7 89CF                <1> 	mov	edi, ecx ; 08/02/2015
   509 00001FD9 88E1                <1> 	MOV	CL,AH			; CL = FUNCTION
   510                              <1> 	;XOR	CH,CH			; CX = FUNCTION
   511                              <1> 	;SHL	CL, 1			; FUNCTION TIMES 2
   512 00001FDB C0E102              <1> 	SHL	CL, 2 ; 20/02/2015	; FUNCTION TIMES 4 (for 32 bit offset)
   513 00001FDE BB[16200000]        <1> 	MOV	eBX,FNC_TAB		; LOAD START OF FUNCTION TABLE
   514 00001FE3 01CB                <1> 	ADD	eBX,eCX			; ADD OFFSET INTO TABLE => ROUTINE
   515 00001FE5 88F4                <1> 	MOV	AH,DH			; AX = HEAD #,# OF SECTORS OR DASD TYPE
   516 00001FE7 30F6                <1> 	XOR	DH,DH			; DX = DRIVE #
   517 00001FE9 6689C6              <1> 	MOV	SI,AX			; SI = HEAD #,# OF SECTORS OR DASD TYPE
   518 00001FEC 6689D7              <1> 	MOV     DI,DX                   ; DI = DRIVE #
   519                              <1> 	;
   520                              <1> 	; 11/12/2014
   521 00001FEF 8815[FDD70000]      <1>         mov     [cfd], dl               ; current floppy drive (for 'GET_PARM')        
   522                              <1> 	;
   523 00001FF5 8A25[80DD0000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; LOAD STATUS TO AH FOR STATUS FUNCTION
   524 00001FFB C605[80DD0000]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 00002002 FF13                <1> 	CALL	dWORD [eBX]		; CALL THE REQUESTED FUNCTION
   545 00002004 5E                  <1> 	POP	eSI			; RESTORE ALL REGISTERS
   546 00002005 1F                  <1> 	POP	DS
   547 00002006 07                  <1> 	pop	es	; 06/02/2015
   548 00002007 59                  <1> 	POP	eCX
   549 00002008 5B                  <1> 	POP	eBX
   550 00002009 5A                  <1> 	POP	eDX
   551 0000200A 5F                  <1> 	POP	eDI
   552 0000200B 89E5                <1> 	MOV	eBP, eSP
   553 0000200D 50                  <1> 	PUSH	eAX
   554 0000200E 9C                  <1> 	PUSHFd
   555 0000200F 58                  <1> 	POP	eAX
   556                              <1> 	;MOV	[BP+6], AX
   557 00002010 89450C              <1> 	mov	[ebp+12], eax  ; 18/02/2015, flags
   558 00002013 58                  <1> 	POP	eAX
   559 00002014 5D                  <1> 	POP	eBP
   560 00002015 CF                  <1> 	IRETd
   561                              <1> 
   562                              <1> ;-------------------------------------------------------------------------------
   563                              <1> ; DW --> dd (06/02/2015)
   564 00002016 [7A200000]          <1> FNC_TAB	dd	DSK_RESET		; AH = 00H; RESET
   565 0000201A [F3200000]          <1> 	dd	DSK_STATUS		; AH = 01H; STATUS
   566 0000201E [04210000]          <1> 	dd	DSK_READ		; AH = 02H; READ
   567 00002022 [15210000]          <1> 	dd	DSK_WRITE		; AH = 03H; WRITE
   568 00002026 [26210000]          <1> 	dd	DSK_VERF		; AH = 04H; VERIFY
   569 0000202A [37210000]          <1> 	dd	DSK_FORMAT		; AH = 05H; FORMAT
   570 0000202E [BC210000]          <1> 	dd	FNC_ERR			; AH = 06H; INVALID
   571 00002032 [BC210000]          <1> 	dd	FNC_ERR			; AH = 07H; INVALID
   572 00002036 [C9210000]          <1> 	dd	DSK_PARMS		; AH = 08H; READ DRIVE PARAMETERS
   573 0000203A [BC210000]          <1> 	dd	FNC_ERR			; AH = 09H; INVALID
   574 0000203E [BC210000]          <1> 	dd	FNC_ERR			; AH = 0AH; INVALID
   575 00002042 [BC210000]          <1> 	dd	FNC_ERR			; AH = 0BH; INVALID
   576 00002046 [BC210000]          <1> 	dd	FNC_ERR			; AH = 0CH; INVALID
   577 0000204A [BC210000]          <1> 	dd	FNC_ERR			; AH = 0DH; INVALID
   578 0000204E [BC210000]          <1> 	dd	FNC_ERR			; AH = 0EH; INVALID
   579 00002052 [BC210000]          <1> 	dd	FNC_ERR			; AH = 0FH; INVALID
   580 00002056 [BC210000]          <1> 	dd	FNC_ERR			; AH = 10H; INVALID
   581 0000205A [BC210000]          <1> 	dd	FNC_ERR			; AH = 11H; INVALID
   582 0000205E [BC210000]          <1> 	dd	FNC_ERR			; AH = 12H; INVALID
   583 00002062 [BC210000]          <1> 	dd	FNC_ERR			; AH = 13H; INVALID
   584 00002066 [BC210000]          <1> 	dd	FNC_ERR			; AH = 14H; INVALID
   585 0000206A [A1220000]          <1> 	dd	DSK_TYPE		; AH = 15H; READ DASD TYPE
   586 0000206E [CC220000]          <1> 	dd	DSK_CHANGE		; AH = 16H; CHANGE STATUS
   587 00002072 [06230000]          <1> 	dd	FORMAT_SET		; AH = 17H; SET DASD TYPE
   588 00002076 [89230000]          <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 0000207A 66BAF203            <1> 	MOV	DX,03F2H		; ADAPTER CONTROL PORT
   599 0000207E FA                  <1> 	CLI				; NO INTERRUPTS
   600 0000207F A0[7EDD0000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
   601 00002084 243F                <1> 	AND	AL,00111111B		; KEEP SELECTED AND MOTOR ON BITS
   602 00002086 C0C004              <1> 	ROL	AL,4			; MOTOR VALUE TO HIGH NIBBLE
   603                              <1> 					; DRIVE SELECT TO LOW NIBBLE
   604 00002089 0C08                <1> 	OR	AL,00001000B		; TURN ON INTERRUPT ENABLE
   605 0000208B EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
   606 0000208C C605[7DDD0000]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 00002093 E6EB                <2>  out 0ebh,al
   612                              <1> 
   613                              <1> 	; 17/12/2014 
   614                              <1> 	; AWARD BIOS 1999 - RESETDRIVES (ADISK.ASM)
   615 00002095 B915000000          <1> 	mov	ecx, WAITCPU_RESET_ON	; cx = 21 -- Min. 14 micro seconds !?
   616                              <1> wdw1:
   617                              <1> 	NEWIODELAY   ; 27/02/2015
   617 0000209A E6EB                <2>  out 0ebh,al
   618 0000209C E2FC                <1> 	loop	wdw1
   619                              <1> 	;
   620 0000209E 0C04                <1> 	OR	AL,00000100B		; TURN OFF RESET BIT
   621 000020A0 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
   622                              <1> 	; 16/12/2014
   623                              <1> 	IODELAY
   623 000020A1 EB00                <2>  jmp short $+2
   623 000020A3 EB00                <2>  jmp short $+2
   624                              <1> 	;
   625                              <1> 	;STI				; ENABLE THE INTERRUPTS
   626 000020A5 E83C0C0000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
   627 000020AA 723E                <1> 	JC	short DR_ERR		; IF ERROR, RETURN IT
   628 000020AC 66B9C000            <1> 	MOV	CX,11000000B		; CL = EXPECTED @NEC_STATUS
   629                              <1> NXT_DRV:
   630 000020B0 6651                <1> 	PUSH	CX			; SAVE FOR CALL
   631 000020B2 B8[E8200000]        <1> 	MOV	eAX, DR_POP_ERR 	; LOAD NEC_OUTPUT ERROR ADDRESS
   632 000020B7 50                  <1> 	PUSH	eAX			; "
   633 000020B8 B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
   634 000020BA E81A0B0000          <1> 	CALL	NEC_OUTPUT
   635 000020BF 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
   636 000020C0 E8510C0000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
   637 000020C5 6659                <1> 	POP	CX			; RESTORE AFTER CALL
   638 000020C7 7221                <1> 	JC	short DR_ERR		; ERROR RETURN
   639 000020C9 3A0D[81DD0000]      <1> 	CMP	CL, [NEC_STATUS]	; TEST FOR DRIVE READY TRANSITION
   640 000020CF 7519                <1> 	JNZ	short DR_ERR		; EVERYTHING OK
   641 000020D1 FEC1                <1> 	INC	CL			; NEXT EXPECTED @NEC_STATUS
   642 000020D3 80F9C3              <1> 	CMP	CL,11000011B		; ALL POSSIBLE DRIVES CLEARED
   643 000020D6 76D8                <1> 	JBE	short NXT_DRV		; FALL THRU IF 11000100B OR >
   644                              <1> 	;
   645 000020D8 E869030000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
   646                              <1> RESBAC:
   647 000020DD E81D090000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   648 000020E2 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   649 000020E5 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   650 000020E7 C3                  <1> 	RETn		
   651                              <1> DR_POP_ERR:
   652 000020E8 6659                <1> 	POP	CX			; CLEAR STACK
   653                              <1> DR_ERR:
   654 000020EA 800D[80DD0000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; SET ERROR CODE
   655 000020F1 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 000020F3 8825[80DD0000]      <1> 	MOV	[DSKETTE_STATUS],AH	; PUT BACK FOR SETUP END
   667 000020F9 E801090000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   668 000020FE 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   669 00002101 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   670 00002103 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 00002104 8025[7EDD0000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
   691 0000210B 66B846E6            <1> 	MOV	AX,0E646H		; AX = NEC COMMAND, DMA COMMAND
   692 0000210F E83C040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   693 00002114 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 00002115 66B84AC5            <1> 	MOV	AX,0C54AH		; AX = NEC COMMAND, DMA COMMAND
   714 00002119 800D[7EDD0000]80    <1>         OR      byte [MOTOR_STATUS],10000000B ; INDICATE WRITE OPERATION
   715 00002120 E82B040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   716 00002125 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 00002126 8025[7EDD0000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
   734 0000212D 66B842E6            <1> 	MOV	AX,0E642H		; AX = NEC COMMAND, DMA COMMAND
   735 00002131 E81A040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   736 00002136 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 00002137 E853030000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
   755 0000213C E84F050000          <1> 	CALL	FMT_INIT		; ESTABLISH STATE IF UNESTABLISHED
   756 00002141 800D[7EDD0000]80    <1>         OR      byte [MOTOR_STATUS], 10000000B ; INDICATE WRITE OPERATION
   757 00002148 E897050000          <1> 	CALL	MED_CHANGE		; CHECK MEDIA CHANGE AND RESET IF SO
   758 0000214D 725D                <1>         JC      short FM_DON            ; MEDIA CHANGED, SKIP
   759 0000214F E8F2020000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
   760 00002154 E8FD050000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMPT RATE IS SAME AS LAST RATE
   761 00002159 7405                <1>         JZ      short FM_WR             ; YES, SKIP SPECIFY COMMAND
   762 0000215B E8D4050000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO CONTROLLER
   763                              <1> FM_WR:
   764 00002160 E88A060000          <1> 	CALL	FMTDMA_SET		; SET UP THE DMA FOR FORMAT
   765 00002165 7245                <1>         JC      short FM_DON            ; RETURN WITH ERROR
   766 00002167 B44D                <1> 	MOV	AH,04DH			; ESTABLISH THE FORMAT COMMAND
   767 00002169 E8E7060000          <1> 	CALL	NEC_INIT		; INITIALIZE THE NEC
   768 0000216E 723C                <1>         JC      short FM_DON            ; ERROR - EXIT
   769 00002170 B8[AC210000]        <1>         MOV     eAX, FM_DON             ; LOAD ERROR ADDRESS
   770 00002175 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
   771 00002176 B203                <1> 	MOV	DL,3			; BYTES/SECTOR VALUE TO NEC
   772 00002178 E856090000          <1> 	CALL	GET_PARM
   773 0000217D E8570A0000          <1> 	CALL	NEC_OUTPUT
   774 00002182 B204                <1> 	MOV	DL,4			; SECTORS/TRACK VALUE TO NEC
   775 00002184 E84A090000          <1> 	CALL	GET_PARM
   776 00002189 E84B0A0000          <1> 	CALL	NEC_OUTPUT
   777 0000218E B207                <1> 	MOV	DL,7			; GAP LENGTH VALUE TO NEC
   778 00002190 E83E090000          <1> 	CALL	GET_PARM
   779 00002195 E83F0A0000          <1> 	CALL	NEC_OUTPUT
   780 0000219A B208                <1> 	MOV	DL,8			; FILLER BYTE TO NEC
   781 0000219C E832090000          <1> 	CALL	GET_PARM
   782 000021A1 E8330A0000          <1> 	CALL	NEC_OUTPUT
   783 000021A6 58                  <1> 	POP	eAX			; THROW AWAY ERROR
   784 000021A7 E827070000          <1> 	CALL	NEC_TERM		; TERMINATE, RECEIVE STATUS, ETC,
   785                              <1> FM_DON:
   786 000021AC E80F030000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   787 000021B1 E849080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   788 000021B6 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   789 000021B9 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   790 000021BB 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 000021BC 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
   801 000021BF B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
   802 000021C1 8825[80DD0000]      <1> 	MOV	[DSKETTE_STATUS],AH	; STORE IN DATA AREA
   803 000021C7 F9                  <1> 	STC				; SET CARRY INDICATING ERROR
   804 000021C8 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 000021C9 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 000021CE 29D2                <1> 	sub	edx, edx
   849 000021D0 66A1[0AD80000]      <1> 	mov     ax, [fd0_type]
   850 000021D6 6621C0              <1> 	and     ax, ax
   851 000021D9 0F848A000000        <1>         jz      NON_DRV
   852 000021DF FEC2                <1> 	inc     dl
   853 000021E1 20E4                <1> 	and     ah, ah
   854 000021E3 7402                <1> 	jz      short STO_DL
   855 000021E5 FEC2                <1> 	inc     dl
   856                              <1> STO_DL:
   857                              <1> 	;MOV	[BP+4],DL		; STORE NUMBER OF DRIVES
   858 000021E7 895508              <1> 	mov	[ebp+8], edx ; 20/02/2015	 	
   859 000021EA 6683FF01            <1> 	CMP	DI,1			; CHECK FOR VALID DRIVE
   860 000021EE 777C                <1> 	JA	short NON_DRV1		; DRIVE INVALID
   861                              <1> 	;MOV	BYTE [BP+5],1		; MAXIMUM HEAD NUMBER =	1
   862 000021F0 C6450901            <1> 	mov	byte [ebp+9], 1  ; 20/02/2015	
   863 000021F4 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 000021F9 740F                <1> 	JZ	short CHK_EST		; JUMP IF SO
   868 000021FB E81B020000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   869 00002200 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 00002202 8A4B04              <1> 	MOV     CL, [eBX+MD.SEC_TRK]     ; GET SECTOR/TRACK
   873 00002205 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]     ; GET MAX. TRACK NUMBER
   874 00002208 EB36                <1> 	JMP	SHORT STO_CX		; CMOS GOOD, USE CMOS
   875                              <1> CHK_EST:
   876 0000220A 8AA7[8DDD0000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; LOAD STATE FOR THIS DRIVE
   877 00002210 F6C410              <1> 	TEST	AH,MED_DET		; CHECK FOR ESTABLISHED STATE
   878 00002213 7457                <1> 	JZ	short NON_DRV1		; CMOS BAD/INVALID OR UNESTABLISHED
   879                              <1> USE_EST:
   880 00002215 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE STATE
   881 00002218 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
   882 0000221B 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 0000221D B001                <1> 	MOV	AL,01			; DRIVE TYPE 1 (360KB)
   887 0000221F E8F7010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   888 00002224 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   889 00002227 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   890 0000222A F687[8DDD0000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; 80 TRACK ?
   891 00002231 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 00002233 B004                <1> 	MOV	AL,04			; DRIVE TYPE 4 (1.44MB)
   897 00002235 E8E1010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   898 0000223A 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   899 0000223D 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   900                              <1> STO_CX:
   901 00002240 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 00002243 57                  <1> 	push	edi
   914 00002244 8B7D04              <1> 	mov	edi, [ebp+4]  		; ebx (input), user's buffer address
   915 00002247 0FB6C0              <1> 	movzx	eax, al
   916 0000224A 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 0000224D A3[78EA0000]        <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 00002252 89DE                <1> 	mov	esi, ebx 		; floppy disk parameter table (16 bytes)
   922 00002254 B910000000          <1> 	mov	ecx, 16 ; 16 bytes
   923 00002259 E837A10000          <1>         call    transfer_to_user_buffer ; trdosk6.s (16/05/2016)
   924 0000225E 5F                  <1> 	pop	edi	
   925                              <1> DP_OUT:
   926 0000225F E85C020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   927 00002264 6631C0              <1> 	XOR	AX,AX			; CLEAR
   928 00002267 F8                  <1> 	CLC
   929 00002268 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 00002269 895508              <1> 	mov	[ebp+8], edx ; 0 ; 20/02/2015
   936                              <1> NON_DRV1:
   937 0000226C 6681FF8000          <1> 	CMP	DI,80H			; CHECK FOR FIXED MEDIA TYPE REQUEST
   938 00002271 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 00002273 E848020000          <1> 	CALL	XLAT_OLD		; ELSE TRANSLATE TO COMPATIBLE MODE
   943 00002278 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
   944 0000227B B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
   945 0000227D F9                  <1> 	STC
   946 0000227E C3                  <1> 	RETn
   947                              <1> 
   948                              <1> NON_DRV2:
   949                              <1> 	;XOR	AX,AX			; CLEAR PARMS IF NO DRIVES OR CMOS BAD
   950 0000227F 31C0                <1> 	xor	eax, eax	
   951 00002281 66894500            <1> 	MOV	[eBP],AX		; TRACKS, SECTORS/TRACK = 0
   952                              <1> 	;MOV	[BP+5],AH		; HEAD = 0
   953 00002285 886509              <1> 	mov	[ebp+9], ah ; 06/02/2015
   954                              <1> 	;MOV	[BP+6],AX		; OFFSET TO DISK_BASE = 0
   955 00002288 89450C              <1> 	mov	[ebp+12], eax
   956                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
   957 0000228B 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 0000228D B002                <1> 	MOV	AL,02			; DRIVE TYPE 2 (1.2MB)
   963 0000228F E887010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   964 00002294 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   965 00002297 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   966 0000229A 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
   967 0000229D 74A1                <1> 	JZ	short STO_CX		; MUST BE 1.2MB DRIVE
   968 0000229F 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 000022A1 E8E9010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
   980 000022A6 8A87[8DDD0000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET PRESENT STATE INFORMATION
   981 000022AC 08C0                <1> 	OR	AL,AL			; CHECK FOR NO DRIVE
   982 000022AE 7418                <1> 	JZ	short NO_DRV
   983 000022B0 B401                <1> 	MOV	AH,NOCHGLN		; NO CHANGE LINE FOR 40 TRACK DRIVE
   984 000022B2 A801                <1> 	TEST	AL,TRK_CAPA		; IS THIS DRIVE AN 80 TRACK DRIVE?
   985 000022B4 7402                <1> 	JZ	short DT_BACK			; IF NO JUMP
   986 000022B6 B402                <1> 	MOV	AH,CHGLN		; CHANGE LINE FOR 80 TRACK DRIVE
   987                              <1> DT_BACK:
   988 000022B8 6650                <1> 	PUSH	AX			; SAVE RETURN VALUE
   989 000022BA E801020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   990 000022BF 6658                <1> 	POP	AX			; RESTORE RETURN VALUE
   991 000022C1 F8                  <1> 	CLC				; NO ERROR
   992 000022C2 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   993 000022C5 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   994 000022C7 C3                  <1> 	RETn
   995                              <1> NO_DRV:	
   996 000022C8 30E4                <1> 	XOR	AH,AH			; NO DRIVE PRESENT OR UNKNOWN
   997 000022CA 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 000022CC E8BE010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1011 000022D1 8A87[8DDD0000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET MEDIA STATE INFORMATION
  1012 000022D7 08C0                <1> 	OR	AL,AL			; DRIVE PRESENT ?
  1013 000022D9 7422                <1> 	JZ	short DC_NON		; JUMP IF NO DRIVE
  1014 000022DB A801                <1> 	TEST	AL,TRK_CAPA		; 80 TRACK DRIVE ?
  1015 000022DD 7407                <1> 	JZ	short SETIT		; IF SO , CHECK CHANGE LINE
  1016                              <1> DC0:
  1017 000022DF E88D0A0000          <1>         CALL    READ_DSKCHNG            ; GO CHECK STATE OF DISK CHANGE LINE
  1018 000022E4 7407                <1> 	JZ	short FINIS		; CHANGE LINE NOT ACTIVE
  1019                              <1> 
  1020 000022E6 C605[80DD0000]06    <1> SETIT:	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; INDICATE MEDIA REMOVED
  1021                              <1> 
  1022 000022ED E8CE010000          <1> FINIS:	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1023 000022F2 E808070000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1024 000022F7 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  1025 000022FA 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  1026 000022FC C3                  <1> 	RETn
  1027                              <1> DC_NON:
  1028 000022FD 800D[80DD0000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; SET TIMEOUT, NO DRIVE
  1029 00002304 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 00002306 E884010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1045 0000230B 6656                <1> 	PUSH	SI			; SAVE DASD TYPE
  1046 0000230D 6689F0              <1> 	MOV	AX,SI			; AH = ? , AL , DASD TYPE
  1047 00002310 30E4                <1> 	XOR	AH,AH			; AH , 0 , AL , DASD TYPE
  1048 00002312 6689C6              <1> 	MOV	SI,AX			; SI = DASD TYPE
  1049 00002315 80A7[8DDD0000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  1050 0000231C 664E                <1> 	DEC	SI			; CHECK FOR 320/360K MEDIA & DRIVE
  1051 0000231E 7509                <1> 	JNZ	short NOT_320		; BYPASS IF NOT
  1052 00002320 808F[8DDD0000]90    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_250 ; SET TO 320/360
  1053 00002327 EB48                <1> 	JMP	SHORT S0
  1054                              <1> 
  1055                              <1> NOT_320:
  1056 00002329 E8B6030000          <1> 	CALL	MED_CHANGE		; CHECK FOR TIME_OUT
  1057 0000232E 803D[80DD0000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT
  1058 00002335 743A                <1> 	JZ	short S0		; IF TIME OUT TELL CALLER
  1059                              <1> S3:
  1060 00002337 664E                <1> 	DEC	SI			; CHECK FOR 320/360K IN 1.2M DRIVE
  1061 00002339 7509                <1> 	JNZ	short NOT_320_12	; BYPASS IF NOT
  1062 0000233B 808F[8DDD0000]70    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+DBL_STEP+RATE_300 ; SET STATE
  1063 00002342 EB2D                <1> 	JMP	SHORT S0
  1064                              <1> 
  1065                              <1> NOT_320_12:
  1066 00002344 664E                <1> 	DEC	SI			; CHECK FOR 1.2M MEDIA IN 1.2M DRIVE
  1067 00002346 7509                <1> 	JNZ	short NOT_12		; BYPASS IF NOT
  1068 00002348 808F[8DDD0000]10    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_500 ; SET STATE VARIABLE
  1069 0000234F EB20                <1> 	JMP	SHORT S0		; RETURN TO CALLER
  1070                              <1> 
  1071                              <1> NOT_12:	
  1072 00002351 664E                <1> 	DEC	SI			; CHECK FOR SET DASD TYPE 04
  1073 00002353 752B                <1> 	JNZ	short FS_ERR		; BAD COMMAND EXIT IF NOT VALID TYPE
  1074                              <1> 
  1075 00002355 F687[8DDD0000]04    <1> 	TEST	byte [DSK_STATE+eDI], DRV_DET ; DRIVE DETERMINED ?
  1076 0000235C 740B                <1> 	JZ	short ASSUME		; IF STILL NOT DETERMINED ASSUME
  1077 0000235E B050                <1> 	MOV	AL,MED_DET+RATE_300
  1078 00002360 F687[8DDD0000]02    <1>         TEST    byte [DSK_STATE+eDI], FMT_CAPA ; MULTIPLE FORMAT CAPABILITY ?
  1079 00002367 7502                <1> 	JNZ	short OR_IT_IN		; IF 1.2 M THEN DATA RATE 300
  1080                              <1> 
  1081                              <1> ASSUME:
  1082 00002369 B090                <1> 	MOV	AL,MED_DET+RATE_250	; SET UP
  1083                              <1> 
  1084                              <1> OR_IT_IN:
  1085 0000236B 0887[8DDD0000]      <1> 	OR	[DSK_STATE+eDI], AL	; OR IN THE CORRECT STATE
  1086                              <1> S0:
  1087 00002371 E84A010000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1088 00002376 E884060000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1089 0000237B 665B                <1> 	POP	BX			; GET SAVED AL TO BL
  1090 0000237D 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  1091 0000237F C3                  <1> 	RETn
  1092                              <1> 
  1093                              <1> FS_ERR:
  1094 00002380 C605[80DD0000]01    <1> 	MOV	byte [DSKETTE_STATUS], BAD_CMD ; UNKNOWN STATE,BAD COMMAND
  1095 00002387 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 00002389 E801010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1120 0000238E F687[8DDD0000]01    <1>         TEST    byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR CHANGE LINE AVAILABLE
  1121 00002395 7415                <1> 	JZ	short SM_CMOS		; JUMP IF 40 TRACK DRIVE
  1122 00002397 E848030000          <1> 	CALL	MED_CHANGE		; RESET CHANGE LINE
  1123 0000239C 803D[80DD0000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT ; IF TIME OUT TELL CALLER
  1124 000023A3 746B                <1> 	JE	short SM_RTN
  1125 000023A5 C605[80DD0000]00    <1> 	MOV	byte [DSKETTE_STATUS], 0 ; CLEAR STATUS
  1126                              <1> SM_CMOS:
  1127 000023AC 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 000023B1 745D                <1> 	JZ	short SM_RTN		; RETURN IF SO
  1132 000023B3 E863000000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  1133 000023B8 7231                <1> 	JC	short MD_NOT_FND	; TYPE NOT IN TABLE (BAD CMOS)
  1134 000023BA 57                  <1> 	PUSH	eDI			; SAVE REG.
  1135 000023BB 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR. TYPE TABLE
  1136 000023BD B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1137                              <1> DR_SEARCH:
  1138 000023C2 8AA3[88D70000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  1139 000023C8 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  1140 000023CB 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH ?
  1141 000023CD 7516                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT DRIVE TYPE
  1142                              <1> DR_FND:
  1143 000023CF 8BBB[89D70000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAM TABLE
  1144                              <1> MD_SEARCH:
  1145 000023D5 8A6704              <1>         MOV     AH, [eDI+MD.SEC_TRK]    ; GET SECTOR/TRACK
  1146 000023D8 386500              <1> 	CMP	[eBP],AH		; MATCH?
  1147 000023DB 7508                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT MEDIA
  1148 000023DD 8A670B              <1>         MOV     AH, [eDI+MD.MAX_TRK]    ; GET MAX. TRACK #
  1149 000023E0 386501              <1> 	CMP 	[eBP+1],AH		; MATCH?
  1150 000023E3 740F                <1> 	JE	short MD_FND		; YES, GO GET RATE
  1151                              <1> NXT_MD:
  1152                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  1153 000023E5 83C305              <1>         add	ebx, 5 ; 18/02/2015
  1154 000023E8 E2D8                <1> 	LOOP    DR_SEARCH
  1155 000023EA 5F                  <1> 	POP	eDI			; RESTORE REG.
  1156                              <1> MD_NOT_FND:
  1157 000023EB C605[80DD0000]0C    <1> 	MOV	byte [DSKETTE_STATUS], MED_NOT_FND ; ERROR, MEDIA TYPE NOT FOUND
  1158 000023F2 EB1C                <1> 	JMP	SHORT SM_RTN		; RETURN
  1159                              <1> MD_FND:
  1160 000023F4 8A470C              <1>         MOV     AL, [eDI+MD.RATE]       ; GET RATE
  1161 000023F7 3C40                <1> 	CMP	AL,RATE_300		; DOUBLE STEP REQUIRED FOR RATE 300
  1162 000023F9 7502                <1> 	JNE	short MD_SET
  1163 000023FB 0C20                <1> 	OR	AL,DBL_STEP
  1164                              <1> MD_SET:
  1165                              <1> 	;MOV	[BP+6],DI		; SAVE TABLE POINTER IN STACK
  1166 000023FD 897D0C              <1> 	mov	[ebp+12], edi ; 18/02/2015
  1167 00002400 0C10                <1> 	OR	AL,MED_DET		; SET MEDIA ESTABLISHED
  1168 00002402 5F                  <1> 	POP	eDI
  1169 00002403 80A7[8DDD0000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  1170 0000240A 0887[8DDD0000]      <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 00002410 E8AB000000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1175 00002415 E8E5050000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1176 0000241A 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 0000241B 6650                <1> 	PUSH	AX			
  1193 0000241D 51                  <1> 	PUSH	eCX
  1194 0000241E 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  1195 00002420 B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1196                              <1> TYPE_CHK:	
  1197 00002425 8AA3[88D70000]      <1> 	MOV	AH,[DR_TYPE+eBX]	; GET DRIVE TYPE
  1198 0000242B 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  1199 0000242D 740D                <1> 	JE	short DR_TYPE_VALID	; YES, RETURN WITH CARRY RESET
  1200                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  1201 0000242F 83C305              <1>         add	ebx, 5	; 16/02/2015 (32 bit address modification)
  1202 00002432 E2F1                <1> 	LOOP    TYPE_CHK
  1203                              <1> 	;
  1204 00002434 BB[E7D70000]        <1> 	mov	ebx, MD_TBL6		; 1.44MB fd parameter table
  1205                              <1> 					; Default for GET_PARM (11/12/2014)
  1206                              <1> 	;
  1207 00002439 F9                  <1> 	STC				; DRIVE TYPE NOT FOUND IN TABLE
  1208 0000243A EB06                <1> 	JMP	SHORT TYPE_RTN
  1209                              <1> DR_TYPE_VALID:
  1210 0000243C 8B9B[89D70000]      <1> 	MOV	eBX,[DR_TYPE+eBX+1] 	; BX = MEDIA TABLE
  1211                              <1> TYPE_RTN:
  1212 00002442 59                  <1> 	POP	eCX
  1213 00002443 6658                <1> 	POP	AX
  1214 00002445 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 00002446 50                  <1> 	PUSH	eAX			; SAVE AX
  1226 00002447 B8[6D240000]        <1> 	MOV	eAX, SPECBAC		; LOAD ERROR ADDRESS
  1227 0000244C 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1228 0000244D B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  1229 0000244F E885070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1230 00002454 28D2                <1> 	SUB	DL,DL			; FIRST SPECIFY BYTE
  1231 00002456 E878060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  1232 0000245B E879070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1233 00002460 B201                <1> 	MOV	DL,1			; SECOND SPECIFY BYTE
  1234 00002462 E86C060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  1235 00002467 E86D070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1236 0000246C 58                  <1> 	POP	eAX			; POP ERROR RETURN
  1237                              <1> SPECBAC:
  1238 0000246D 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  1239 0000246E 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 0000246F 50                  <1> 	PUSH	eAX			; SAVE RATE DATA
  1251 00002470 B8[8D240000]        <1> 	MOV	eAX, SPEC_ESBAC		; LOAD ERROR ADDRESS
  1252 00002475 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1253 00002476 B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  1254 00002478 E85C070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1255 0000247D 8A23                <1>         MOV     AH, [eBX+MD.SPEC1]      ; GET 1ST SPECIFY BYTE
  1256 0000247F E855070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1257 00002484 8A6301              <1>         MOV     AH, [eBX+MD.SPEC2]      ; GET SECOND SPECIFY BYTE
  1258 00002487 E84D070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1259 0000248C 58                  <1> 	POP	eAX			; POP ERROR RETURN
  1260                              <1> SPEC_ESBAC:
  1261 0000248D 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  1262 0000248E 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 0000248F 83FF01              <1> 	CMP	eDI,1				; VALID DRIVE
  1273 00002492 7725                <1> 	JA	short XN_OUT			; IF INVALID BACK
  1274 00002494 80BF[8DDD0000]00    <1> 	CMP	byte [DSK_STATE+eDI], 0		; NO DRIVE ?
  1275 0000249B 741D                <1> 	JZ	short DO_DET			; IF NO DRIVE ATTEMPT DETERMINE
  1276 0000249D 6689F9              <1> 	MOV	CX,DI				; CX = DRIVE NUMBER
  1277 000024A0 C0E102              <1> 	SHL	CL,2				; CL = SHIFT COUNT, A=0, B=4
  1278 000024A3 A0[8CDD0000]        <1> 	MOV	AL, [HF_CNTRL]			; DRIVE INFORMATION
  1279 000024A8 D2C8                <1> 	ROR	AL,CL				; TO LOW NIBBLE
  1280 000024AA 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA	; KEEP DRIVE BITS
  1281 000024AC 80A7[8DDD0000]F8    <1>         AND     byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA)
  1282 000024B3 0887[8DDD0000]      <1> 	OR	[DSK_STATE+eDI], AL		; UPDATE DRIVE STATE
  1283                              <1> XN_OUT:
  1284 000024B9 C3                  <1> 	RETn
  1285                              <1> DO_DET:
  1286 000024BA E8BF080000          <1> 	CALL	DRIVE_DET			; TRY TO DETERMINE
  1287 000024BF 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 000024C0 83FF01              <1> 	CMP	eDI,1			; VALID DRIVE ?
  1298                              <1>         ;JA     short XO_OUT            ; IF INVALID BACK
  1299 000024C3 0F8786000000        <1>         ja      XO_OUT
  1300 000024C9 80BF[8DDD0000]00    <1>         CMP	byte [DSK_STATE+eDI],0	; NO DRIVE ?
  1301 000024D0 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 000024D2 6689F9              <1> 	MOV	CX,DI			; CX = DRIVE NUMBER
  1306 000024D5 C0E102              <1> 	SHL	CL,2			; CL = SHIFT COUNT, A=0, B=4
  1307 000024D8 B402                <1> 	MOV	AH,FMT_CAPA		; LOAD MULTIPLE DATA RATE BIT MASK
  1308 000024DA D2CC                <1> 	ROR	AH,CL			; ROTATE BY MASK
  1309 000024DC 8425[8CDD0000]      <1> 	TEST	[HF_CNTRL], AH		; MULTIPLE-DATA RATE DETERMINED ?
  1310 000024E2 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 000024E4 B407                <1> 	MOV	AH,DRV_DET+FMT_CAPA+TRK_CAPA ; MASK TO KEEP
  1315 000024E6 D2CC                <1> 	ROR	AH,CL			; FIX MASK TO KEEP
  1316 000024E8 F6D4                <1> 	NOT	AH			; TRANSLATE MASK
  1317 000024EA 2025[8CDD0000]      <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 000024F0 8A87[8DDD0000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; ACCESS STATE
  1322 000024F6 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA ; KEEP DRIVE BITS
  1323 000024F8 D2C8                <1> 	ROR	AL,CL			; FIX FOR THIS DRIVE
  1324 000024FA 0805[8CDD0000]      <1> 	OR	[HF_CNTRL], AL		; UPDATE SAVED DRIVE STATE
  1325                              <1> 
  1326                              <1> ;-----	TRANSLATE TO COMPATIBILITY MODE
  1327                              <1> 
  1328                              <1> SAVE_SET:
  1329 00002500 8AA7[8DDD0000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  1330 00002506 88E7                <1> 	MOV	BH,AH			; TO BH FOR LATER
  1331 00002508 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE
  1332 0000250B 80FC00              <1> 	CMP	AH,RATE_500		; RATE 500 ?
  1333 0000250E 7410                <1> 	JZ	short CHK_144		; YES 1.2/1.2 OR 1.44/1.44
  1334 00002510 B001                <1> 	MOV	AL,M3D1U		; AL = 360 IN 1.2 UNESTABLISHED
  1335 00002512 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
  1336 00002515 7518                <1> 	JNZ	short CHK_250		; NO, 360/360, 720/720 OR 720/1.44
  1337 00002517 F6C720              <1> 	TEST	BH,DBL_STEP		; CHECK FOR DOUBLE STEP
  1338 0000251A 751F                <1> 	JNZ	short TST_DET		; MUST BE 360 IN 1.2
  1339                              <1> UNKNO:
  1340 0000251C B007                <1> 	MOV	AL,MED_UNK		; NONE OF THE ABOVE
  1341 0000251E EB22                <1> 	JMP	SHORT AL_SET		; PROCESS COMPLETE
  1342                              <1> CHK_144:
  1343 00002520 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 00002525 74F5                <1> 	jz	short UNKNO ;; 20/02/2015
  1347 00002527 3C02                <1> 	CMP	AL,2			; 1.2MB DRIVE ?
  1348 00002529 75F1                <1> 	JNE	short UNKNO		; NO, GO SET 'NONE OF ABOVE'
  1349 0000252B B002                <1> 	MOV	AL,M1D1U		; AL = 1.2 IN 1.2 UNESTABLISHED
  1350 0000252D EB0C                <1> 	JMP	SHORT TST_DET
  1351                              <1> CHK_250:
  1352 0000252F B000                <1> 	MOV	AL,M3D3U		; AL = 360 IN 360 UNESTABLISHED
  1353 00002531 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
  1354 00002534 75E6                <1> 	JNZ	short UNKNO		; IF SO FALL IHRU
  1355 00002536 F6C701              <1> 	TEST	BH,TRK_CAPA		; 80 TRACK CAPABILITY ?
  1356 00002539 75E1                <1> 	JNZ	short UNKNO		; IF SO JUMP, FALL THRU TEST DET
  1357                              <1> TST_DET:
  1358 0000253B F6C710              <1> 	TEST	BH,MED_DET		; DETERMINED ?
  1359 0000253E 7402                <1> 	JZ	short AL_SET		; IF NOT THEN SET
  1360 00002540 0403                <1> 	ADD	AL,3			; MAKE DETERMINED/ESTABLISHED
  1361                              <1> AL_SET:
  1362 00002542 80A7[8DDD0000]F8    <1> 	AND	byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA) ; CLEAR DRIVE
  1363 00002549 0887[8DDD0000]      <1> 	OR	[DSK_STATE+eDI], AL	; REPLACE WITH COMPATIBLE MODE
  1364                              <1> XO_OUT:
  1365 0000254F 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 00002550 6650                <1> 	PUSH	AX			; SAVE DMA, NEC PARAMETERS
  1379 00002552 E838FFFFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1380 00002557 E8F3000000          <1> 	CALL	SETUP_STATE		; INITIALIZE START AND END RATE
  1381 0000255C 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  1382                              <1> DO_AGAIN:
  1383 0000255E 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  1384 00002560 E87F010000          <1> 	CALL	MED_CHANGE		; MEDIA CHANGE AND RESET IF CHANGED
  1385 00002565 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  1386 00002567 0F82C9000000        <1>         JC      RWV_END                 ; MEDIA CHANGE ERROR OR TIME-OUT
  1387                              <1> RWV:
  1388 0000256D 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  1389 0000256F 8AB7[8DDD0000]      <1> 	MOV	DH, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1390 00002575 80E6C0              <1> 	AND	DH,RATE_MSK		; KEEP ONLY RATE
  1391 00002578 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 0000257D 7451                <1> 	jz	short RWV_ASSUME ; 20/02/2015
  1395 0000257F 3C01                <1> 	CMP	AL,1			; 40 TRACK DRIVE?
  1396 00002581 750D                <1> 	JNE	short RWV_1		; NO, BYPASS CMOS VALIDITY CHECK
  1397 00002583 F687[8DDD0000]01    <1> 	TEST	byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR 40 TRACK DRIVE
  1398 0000258A 7413                <1> 	JZ	short RWV_2		; YES, CMOS IS CORRECT
  1399 0000258C B002                <1> 	MOV	AL,2			; CHANGE TO 1.2M
  1400 0000258E EB0F                <1> 	JMP	SHORT RWV_2
  1401                              <1> RWV_1:
  1402 00002590 720D                <1> 	JB	short RWV_2		; NO DRIVE SPECIFIED, CONTINUE
  1403 00002592 F687[8DDD0000]01    <1> 	TEST    byte [DSK_STATE+eDI], TRK_CAPA ; IS IT REALLY 40 TRACK?
  1404 00002599 7504                <1> 	JNZ	short RWV_2		; NO, 80 TRACK
  1405 0000259B B001                <1> 	MOV	AL,1			; IT IS 40 TRACK, FIX CMOS VALUE
  1406 0000259D EB04                <1> 	jmp	short rwv_3
  1407                              <1> RWV_2:
  1408 0000259F 08C0                <1> 	OR	AL,AL			; TEST FOR NO DRIVE
  1409 000025A1 742D                <1> 	JZ	short RWV_ASSUME	; ASSUME TYPE, USE MAX TRACK
  1410                              <1> rwv_3:
  1411 000025A3 E873FEFFFF          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL.
  1412 000025A8 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 000025AA 57                  <1> 	PUSH	eDI			; SAVE DRIVE #
  1417 000025AB 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  1418 000025AD B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1419                              <1> RWV_DR_SEARCH:
  1420 000025B2 8AA3[88D70000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  1421 000025B8 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  1422 000025BB 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  1423 000025BD 750B                <1> 	JNE	short RWV_NXT_MD	; NO, CHECK NEXT DRIVE TYPE
  1424                              <1> RWV_DR_FND:
  1425 000025BF 8BBB[89D70000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAMETER TABLE
  1426                              <1> RWV_MD_SEARH:
  1427 000025C5 3A770C              <1>         CMP     DH, [eDI+MD.RATE]       ; MATCH?
  1428 000025C8 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 000025CA 83C305              <1> 	add	eBX, 5
  1432 000025CD E2E3                <1> 	LOOP	RWV_DR_SEARCH
  1433 000025CF 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  1434                              <1> 
  1435                              <1> ;-----	ASSUME PRIMARY DRIVE IS INSTALLED AS SHIPPED
  1436                              <1> 
  1437                              <1> RWV_ASSUME:
  1438 000025D0 BB[A6D70000]        <1> 	MOV	eBX, MD_TBL1		; POINT TO 40 TRACK 250 KBS
  1439 000025D5 F687[8DDD0000]01    <1> 	TEST 	byte [DSK_STATE+eDI], TRK_CAPA ; TEST FOR 80 TRACK
  1440 000025DC 740A                <1> 	JZ	short RWV_MD_FND1	; MUST BE 40 TRACK
  1441 000025DE BB[C0D70000]        <1> 	MOV	eBX, MD_TBL3		; POINT TO 80 TRACK 500 KBS
  1442 000025E3 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 000025E5 89FB                <1> 	MOV	eBX,eDI			; BX = MEDIA/DRIVE PARAMETER TABLE
  1448 000025E7 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 000025E8 E882FEFFFF          <1> 	CALL	SEND_SPEC_MD
  1454 000025ED E864010000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMP RATE IS SAME AS LAST RATE
  1455 000025F2 7405                <1> 	JZ	short RWV_DBL		; YES,SKIP SEND RATE COMMAND
  1456 000025F4 E83B010000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO NEC
  1457                              <1> RWV_DBL:
  1458 000025F9 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1459 000025FA E822040000          <1> 	CALL	SETUP_DBL		; CHECK FOR DOUBLE STEP
  1460 000025FF 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  1461 00002600 7226                <1> 	JC	short CHK_RET		; ERROR FROM READ ID, POSSIBLE RETRY
  1462 00002602 6658                <1> 	POP	AX			; RESTORE NEC, DMA COMMAND
  1463 00002604 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1464 00002606 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1465 00002607 E861010000          <1> 	CALL	DMA_SETUP		; SET UP THE DMA
  1466 0000260C 5B                  <1> 	POP	eBX 
  1467 0000260D 6658                <1> 	POP	AX			; RESTORE NEC COMMAND
  1468 0000260F 722F                <1> 	JC	short RWV_BAC		; CHECK FOR DMA BOUNDARY ERROR
  1469 00002611 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1470 00002613 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1471 00002614 E83C020000          <1> 	CALL	NEC_INIT		; INITIALIZE NEC
  1472 00002619 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  1473 0000261A 720C                <1> 	JC	short CHK_RET		; ERROR - EXIT
  1474 0000261C E866020000          <1> 	CALL	RWV_COM			; OP CODE COMMON TO READ/WRITE/VERIFY
  1475 00002621 7205                <1> 	JC	short CHK_RET		; ERROR - EXIT
  1476 00002623 E8AB020000          <1> 	CALL	NEC_TERM		; TERMINATE, GET STATUS, ETC.
  1477                              <1> CHK_RET:
  1478 00002628 E84A030000          <1> 	CALL	RETRY			; CHECK FOR, SETUP RETRY
  1479 0000262D 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY PARAMETER
  1480 0000262F 7305                <1> 	JNC	short RWV_END		; CY = 0 NO RETRY
  1481 00002631 E928FFFFFF          <1>         JMP     DO_AGAIN                ; CY = 1 MEANS RETRY
  1482                              <1> RWV_END:
  1483 00002636 E8F4020000          <1> 	CALL	DSTATE			; ESTABLISH STATE IF SUCCESSFUL
  1484 0000263B E887030000          <1> 	CALL	NUM_TRANS		; AL = NUMBER TRANSFERRED
  1485                              <1> RWV_BAC:				; BAD DMA ERROR ENTRY
  1486 00002640 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  1487 00002642 E879FEFFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1488 00002647 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  1489 00002649 E8B1030000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1490 0000264E C3                  <1> 	RETn
  1491                              <1> 
  1492                              <1> ;-------------------------------------------------------------------------------
  1493                              <1> ; SETUP_STATE:	INITIALIZES START AND END RATES.
  1494                              <1> ;-------------------------------------------------------------------------------
  1495                              <1> SETUP_STATE:
  1496 0000264F F687[8DDD0000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; MEDIA DETERMINED ?
  1497 00002656 7537                <1> 	JNZ	short J1C		; NO STATES IF DETERMINED
  1498 00002658 66B84000            <1>         MOV     AX,(RATE_500*256)+RATE_300  ; AH = START RATE, AL = END RATE
  1499 0000265C F687[8DDD0000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE ?
  1500 00002663 740D                <1> 	JZ	short AX_SET		; DO NOT KNOW DRIVE
  1501 00002665 F687[8DDD0000]02    <1> 	TEST	byte [DSK_STATE+eDI], FMT_CAPA ; MULTI-RATE?
  1502 0000266C 7504                <1> 	JNZ	short AX_SET		; JUMP IF YES
  1503 0000266E 66B88080            <1>         MOV     AX,RATE_250*257         ; START A END RATE 250 FOR 360 DRIVE
  1504                              <1> AX_SET:	
  1505 00002672 80A7[8DDD0000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP) ; TURN OFF THE RATE
  1506 00002679 08A7[8DDD0000]      <1> 	OR	[DSK_STATE+eDI], AH	; RATE FIRST TO TRY
  1507 0000267F 8025[88DD0000]F3    <1> 	AND	byte [LASTRATE], ~STRT_MSK ; ERASE LAST TO TRY RATE BITS
  1508 00002686 C0C804              <1> 	ROR	AL,4			; TO OPERATION LAST RATE LOCATION
  1509 00002689 0805[88DD0000]      <1> 	OR	[LASTRATE], AL		; LAST RATE
  1510                              <1> J1C:	
  1511 0000268F 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 00002690 F687[8DDD0000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; IS MEDIA ESTABLISHED
  1518 00002697 7546                <1> 	JNZ	short F1_OUT		; IF SO RETURN
  1519 00002699 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 0000269E 7440                <1> 	jz	short CL_DRV ;; 20/02/2015
  1523 000026A0 FEC8                <1> 	DEC	AL			; MAKE ZERO ORIGIN
  1524                              <1> 	;;JS	short CL_DRV		; NO DRIVE IF AL 0
  1525 000026A2 8AA7[8DDD0000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; AH = CURRENT STATE
  1526 000026A8 80E40F              <1> 	AND	AH, ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR
  1527 000026AB 08C0                <1> 	OR	AL,AL			; CHECK FOR 360
  1528 000026AD 7505                <1> 	JNZ	short N_360		; IF 360 WILL BE 0
  1529 000026AF 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; ESTABLISH MEDIA
  1530 000026B2 EB25                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  1531                              <1> N_360:	
  1532 000026B4 FEC8                <1> 	DEC	AL			; 1.2 M DRIVE
  1533 000026B6 7505                <1> 	JNZ	short N_12		; JUMP IF NOT
  1534                              <1> F1_RATE:
  1535 000026B8 80CC10              <1> 	OR	AH,MED_DET+RATE_500	; SET FORMAT RATE
  1536 000026BB EB1C                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  1537                              <1> N_12:	
  1538 000026BD FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 3
  1539 000026BF 750F                <1> 	JNZ	short N_720		; JUMP IF NOT
  1540 000026C1 F6C404              <1> 	TEST	AH,DRV_DET		; IS DRIVE DETERMINED
  1541 000026C4 7410                <1> 	JZ	short ISNT_12		; TREAT AS NON 1.2 DRIVE
  1542 000026C6 F6C402              <1> 	TEST	AH,FMT_CAPA		; IS 1.2M
  1543 000026C9 740B                <1> 	JZ	short ISNT_12		; JUMP IF NOT
  1544 000026CB 80CC50              <1> 	OR	AH,MED_DET+RATE_300	; RATE 300
  1545 000026CE EB09                <1> 	JMP	SHORT SKP_STATE		; CONTINUE
  1546                              <1> N_720:
  1547 000026D0 FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 4
  1548 000026D2 750C                <1> 	JNZ	short CL_DRV		; NO DRIVE, CMOS BAD
  1549 000026D4 EBE2                <1> 	JMP	SHORT F1_RATE
  1550                              <1> ISNT_12: 
  1551 000026D6 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; MUST BE RATE 250
  1552                              <1> 
  1553                              <1> SKP_STATE:
  1554 000026D9 88A7[8DDD0000]      <1> 	MOV	[DSK_STATE+eDI], AH	; STORE AWAY
  1555                              <1> F1_OUT:
  1556 000026DF C3                  <1> 	RETn
  1557                              <1> CL_DRV:	
  1558 000026E0 30E4                <1> 	XOR	AH,AH			; CLEAR STATE
  1559 000026E2 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 000026E4 E888060000          <1> 	CALL	READ_DSKCHNG		; READ DISK CHANCE LINE STATE
  1571 000026E9 7447                <1> 	JZ	short MC_OUT		; BYPASS HANDLING DISK CHANGE LINE
  1572 000026EB 80A7[8DDD0000]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 000026F2 6689F9              <1> 	MOV	CX,DI			; CL = DRIVE 0
  1579 000026F5 B001                <1> 	MOV	AL,1			; MOTOR ON BIT MASK
  1580 000026F7 D2E0                <1> 	SHL	AL,CL			; TO APPROPRIATE POSITION
  1581 000026F9 F6D0                <1> 	NOT	AL			; KEEP ALL BUT MOTOR ON
  1582 000026FB FA                  <1> 	CLI				; NO INTERRUPTS
  1583 000026FC 2005[7EDD0000]      <1> 	AND	[MOTOR_STATUS], AL	; TURN MOTOR OFF INDICATOR
  1584 00002702 FB                  <1> 	STI				; INTERRUPTS ENABLED
  1585 00002703 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 00002708 E86DF9FFFF          <1> 	CALL	DSK_RESET		; RESET NEC
  1590 0000270D B501                <1> 	MOV	CH,01H			; MOVE TO CYLINDER 1
  1591 0000270F E8FF040000          <1> 	CALL	SEEK			; ISSUE SEEK
  1592 00002714 30ED                <1> 	XOR	CH,CH			; MOVE TO CYLINDER 0
  1593 00002716 E8F8040000          <1> 	CALL	SEEK			; ISSUE SEEK
  1594 0000271B C605[80DD0000]06    <1> 	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; STORE IN STATUS
  1595                              <1> OK1:
  1596 00002722 E84A060000          <1> 	CALL	READ_DSKCHNG		; CHECK MEDIA CHANGED AGAIN
  1597 00002727 7407                <1> 	JZ	short OK2		; IF ACTIVE, NO DISKETTE, TIMEOUT
  1598                              <1> OK4:
  1599 00002729 C605[80DD0000]80    <1> 	MOV	byte [DSKETTE_STATUS], TIME_OUT ; TIMEOUT IF DRIVE EMPTY
  1600                              <1> OK2:		
  1601 00002730 F9                  <1> 	STC				; MEDIA CHANGED, SET CY
  1602 00002731 C3                  <1> 	RETn
  1603                              <1> MC_OUT:
  1604 00002732 F8                  <1> 	CLC				; NO MEDIA CHANGED, CLEAR CY
  1605 00002733 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 00002734 6650                <1> 	PUSH	AX			; SAVE REG.
  1616 00002736 8025[88DD0000]3F    <1> 	AND	byte [LASTRATE], ~SEND_MSK ; ELSE CLEAR LAST RATE ATTEMPTED
  1617 0000273D 8A87[8DDD0000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1618 00002743 24C0                <1> 	AND	AL,SEND_MSK		; KEEP ONLY RATE BITS
  1619 00002745 0805[88DD0000]      <1> 	OR	[LASTRATE], AL		; SAVE NEW RATE FOR NEXT CHECK
  1620 0000274B C0C002              <1> 	ROL	AL,2			; MOVE TO BIT OUTPUT POSITIONS
  1621 0000274E 66BAF703            <1> 	MOV	DX,03F7H		; OUTPUT NEW DATA RATE
  1622 00002752 EE                  <1> 	OUT	DX,AL
  1623 00002753 6658                <1> 	POP	AX			; RESTORE REG.
  1624 00002755 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 00002756 6650                <1> 	PUSH	AX			; SAVE REG
  1638 00002758 2225[88DD0000]      <1> 	AND	AH, [LASTRATE]		; GET LAST DATA RATE SELECTED
  1639 0000275E 8A87[8DDD0000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1640 00002764 6625C0C0            <1>         AND     AX, SEND_MSK*257        ; KEEP ONLY RATE BITS OF BOTH
  1641 00002768 38E0                <1> 	CMP	AL, AH			; COMPARE TO PREVIOUSLY TRIED
  1642                              <1> 					; ZF = 1 RATE IS THE SAME
  1643 0000276A 6658                <1> 	POP	AX			; RESTORE REG.
  1644 0000276C 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 0000276D 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  1674 00002770 F7C2000000FF        <1> 	test	edx, 0FF000000h		; 16 MB limit (22/08/2015, bugfix)
  1675 00002776 756E                <1> 	jnz	short dma_bnd_err_stc
  1676                              <1> 	;
  1677 00002778 6650                <1> 	push	ax			; DMA command
  1678 0000277A 52                  <1> 	push	edx			; *
  1679 0000277B B203                <1> 	mov	dl, 3			; GET BYTES/SECTOR PARAMETER
  1680 0000277D E851030000          <1> 	call	GET_PARM		; 
  1681 00002782 88E1                <1> 	mov	cl, ah 			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  1682 00002784 6689F0              <1> 	mov	ax, si			; Sector count
  1683 00002787 88C4                <1> 	mov	ah, al			; AH =  # OF SECTORS
  1684 00002789 28C0                <1> 	sub	al, al			; AL = 0, AX = # SECTORS * 256
  1685 0000278B 66D1E8              <1> 	shr	ax, 1			; AX = # SECTORS * 128
  1686 0000278E 66D3E0              <1> 	shl	ax, cl			; SHIFT BY PARAMETER VALUE
  1687 00002791 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  1688 00002793 6689C1              <1> 	mov	cx, ax
  1689 00002796 5A                  <1> 	pop	edx			; *
  1690 00002797 6658                <1> 	pop	ax
  1691 00002799 3C42                <1> 	cmp	al, 42h
  1692 0000279B 7507                <1>         jne     short NOT_VERF
  1693 0000279D BA0000FF00          <1> 	mov	edx, 0FF0000h
  1694 000027A2 EB08                <1> 	jmp	short J33
  1695                              <1> NOT_VERF:
  1696 000027A4 6601CA              <1> 	add	dx, cx			; check for overflow
  1697 000027A7 723E                <1> 	jc	short dma_bnd_err
  1698                              <1> 	;
  1699 000027A9 6629CA              <1> 	sub	dx, cx			; Restore start address
  1700                              <1> J33:
  1701 000027AC FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1702 000027AD E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1703                              <1> 	IODELAY				; WAIT FOR I/O
  1703 000027AF EB00                <2>  jmp short $+2
  1703 000027B1 EB00                <2>  jmp short $+2
  1704 000027B3 E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1705 000027B5 89D0                <1> 	mov	eax, edx		; Buffer address
  1706 000027B7 E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1707                              <1> 	IODELAY				; WAIT FOR I/O
  1707 000027B9 EB00                <2>  jmp short $+2
  1707 000027BB EB00                <2>  jmp short $+2
  1708 000027BD 88E0                <1> 	MOV	AL,AH
  1709 000027BF E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1710 000027C1 C1E810              <1> 	shr	eax, 16
  1711                              <1> 	IODELAY				; I/O WAIT STATE
  1711 000027C4 EB00                <2>  jmp short $+2
  1711 000027C6 EB00                <2>  jmp short $+2
  1712 000027C8 E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  1713                              <1> 	IODELAY
  1713 000027CA EB00                <2>  jmp short $+2
  1713 000027CC EB00                <2>  jmp short $+2
  1714 000027CE 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  1715 000027D1 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1716                              <1> 	IODELAY				; WAIT FOR I/O
  1716 000027D3 EB00                <2>  jmp short $+2
  1716 000027D5 EB00                <2>  jmp short $+2
  1717 000027D7 88E0                <1> 	MOV	AL, AH
  1718 000027D9 E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1719                              <1> 	IODELAY
  1719 000027DB EB00                <2>  jmp short $+2
  1719 000027DD EB00                <2>  jmp short $+2
  1720 000027DF FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  1721 000027E0 B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  1722 000027E2 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1723                              <1> 
  1724 000027E4 F8                  <1> 	clc	; 04/02/2016
  1725 000027E5 C3                  <1> 	retn
  1726                              <1> 
  1727                              <1> dma_bnd_err_stc:
  1728 000027E6 F9                  <1> 	stc
  1729                              <1> dma_bnd_err:
  1730 000027E7 C605[80DD0000]09    <1> 	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  1731 000027EE 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 000027EF 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  1818 000027F2 F7C20000F0FF        <1> 	test	edx, 0FFF00000h		; 16 MB limit
  1819 000027F8 75EC                <1> 	jnz	short dma_bnd_err_stc
  1820                              <1> 	;
  1821 000027FA 6652                <1> 	push	dx			; *
  1822 000027FC B204                <1> 	mov	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  1823 000027FE E8D0020000          <1> 	call	GET_PARM		; "
  1824 00002803 88E0                <1> 	mov	al, ah			; AL = SECTORS/TRACK VALUE
  1825 00002805 28E4                <1> 	sub	ah, ah			; AX = SECTORS/TRACK VALUE
  1826 00002807 66C1E002            <1> 	shl	ax, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  1827 0000280B 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  1828 0000280D 6689C1              <1> 	mov	cx, ax
  1829 00002810 665A                <1> 	pop	dx			; *
  1830 00002812 6601CA              <1> 	add	dx, cx			; check for overflow
  1831 00002815 72D0                <1> 	jc	short dma_bnd_err
  1832                              <1> 	;
  1833 00002817 6629CA              <1> 	sub	dx, cx			; Restore start address
  1834                              <1> 	;
  1835 0000281A B04A                <1> 	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  1836 0000281C FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1837 0000281D E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1838                              <1> 	IODELAY				; WAIT FOR I/O
  1838 0000281F EB00                <2>  jmp short $+2
  1838 00002821 EB00                <2>  jmp short $+2
  1839 00002823 E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1840 00002825 89D0                <1> 	mov	eax, edx		; Buffer address
  1841 00002827 E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1842                              <1> 	IODELAY				; WAIT FOR I/O
  1842 00002829 EB00                <2>  jmp short $+2
  1842 0000282B EB00                <2>  jmp short $+2
  1843 0000282D 88E0                <1> 	MOV	AL,AH
  1844 0000282F E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1845 00002831 C1E810              <1> 	shr	eax, 16
  1846                              <1> 	IODELAY				; I/O WAIT STATE
  1846 00002834 EB00                <2>  jmp short $+2
  1846 00002836 EB00                <2>  jmp short $+2
  1847 00002838 E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  1848                              <1> 	IODELAY
  1848 0000283A EB00                <2>  jmp short $+2
  1848 0000283C EB00                <2>  jmp short $+2
  1849 0000283E 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  1850 00002841 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1851                              <1> 	IODELAY				; WAIT FOR I/O
  1851 00002843 EB00                <2>  jmp short $+2
  1851 00002845 EB00                <2>  jmp short $+2
  1852 00002847 88E0                <1> 	MOV	AL, AH
  1853 00002849 E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1854                              <1> 	IODELAY
  1854 0000284B EB00                <2>  jmp short $+2
  1854 0000284D EB00                <2>  jmp short $+2
  1855 0000284F FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  1856 00002850 B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  1857 00002852 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1858 00002854 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 00002855 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1933 00002857 E8BC020000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON FOR SPECIFIC DRIVE
  1934                              <1> 
  1935                              <1> ;-----	DO THE SEEK OPERATION
  1936                              <1> 
  1937 0000285C 8A6D01              <1> 	MOV	CH,[eBP+1]		; CH = TRACK #
  1938 0000285F E8AF030000          <1> 	CALL	SEEK			; MOVE TO CORRECT TRACK
  1939 00002864 6658                <1> 	POP	AX			; RECOVER COMMAND
  1940 00002866 721E                <1> 	JC	short ER_1		; ERROR ON SEEK
  1941 00002868 BB[86280000]        <1> 	MOV	eBX, ER_1		; LOAD ERROR ADDRESS
  1942 0000286D 53                  <1> 	PUSH	eBX			; PUSH NEC_OUT ERROR RETURN
  1943                              <1> 
  1944                              <1> ;-----	SEND OUT THE PARAMETERS TO THE CONTROLLER
  1945                              <1> 
  1946 0000286E E866030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE OPERATION COMMAND
  1947 00002873 6689F0              <1> 	MOV	AX,SI			; AH = HEAD #
  1948 00002876 89FB                <1> 	MOV	eBX,eDI			; BL = DRIVE #
  1949 00002878 C0E402              <1> 	SAL	AH,2			; MOVE IT TO BIT 2
  1950 0000287B 80E404              <1> 	AND	AH,00000100B		; ISOLATE THAT BIT
  1951 0000287E 08DC                <1> 	OR	AH,BL			; OR IN THE DRIVE NUMBER
  1952 00002880 E854030000          <1> 	CALL	NEC_OUTPUT		; FALL THRU CY SET IF ERROR
  1953 00002885 5B                  <1> 	POP	eBX			; THROW AWAY ERROR RETURN
  1954                              <1> ER_1:
  1955 00002886 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 00002887 B8[D2280000]        <1> 	MOV	eAX, ER_2		; LOAD ERROR ADDRESS
  1967 0000288C 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1968 0000288D 8A6501              <1> 	MOV	AH,[eBP+1]		; OUTPUT TRACK #
  1969 00002890 E844030000          <1> 	CALL	NEC_OUTPUT
  1970 00002895 6689F0              <1> 	MOV	AX,SI			; OUTPUT HEAD #
  1971 00002898 E83C030000          <1> 	CALL	NEC_OUTPUT
  1972 0000289D 8A6500              <1>         MOV     AH,[eBP]                ; OUTPUT SECTOR #
  1973 000028A0 E834030000          <1> 	CALL	NEC_OUTPUT
  1974 000028A5 B203                <1> 	MOV	DL,3			; BYTES/SECTOR PARAMETER FROM BLOCK
  1975 000028A7 E827020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  1976 000028AC E828030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  1977 000028B1 B204                <1> 	MOV	DL,4			; EOT PARAMETER FROM BLOCK
  1978 000028B3 E81B020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  1979 000028B8 E81C030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  1980 000028BD 8A6305              <1>         MOV     AH, [eBX+MD.GAP]        ; GET GAP LENGTH
  1981                              <1> _R15:
  1982 000028C0 E814030000          <1> 	CALL	NEC_OUTPUT
  1983 000028C5 B206                <1> 	MOV	DL,6			; DTL PARAMETER PROM BLOCK
  1984 000028C7 E807020000          <1> 	CALL	GET_PARM		;  TO THE NEC
  1985 000028CC E808030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  1986 000028D1 58                  <1> 	POP	eAX			; THROW AWAY ERROR EXIT
  1987                              <1> ER_2:
  1988 000028D2 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 000028D3 56                  <1> 	PUSH	eSI			; SAVE HEAD #, # OF SECTORS
  2002 000028D4 E80D040000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  2003 000028D9 9C                  <1> 	PUSHF
  2004 000028DA E837040000          <1> 	CALL	RESULTS			; GET THE NEC STATUS
  2005 000028DF 724B                <1> 	JC	short SET_END_POP
  2006 000028E1 9D                  <1> 	POPF
  2007 000028E2 723E                <1> 	JC	short SET_END		; LOOK FOR ERROR
  2008                              <1> 
  2009                              <1> ;-----	CHECK THE RESULTS RETURNED BY THE CONTROLLER
  2010                              <1> 
  2011 000028E4 FC                  <1> 	CLD				; SET THE CORRECT DIRECTION
  2012 000028E5 BE[81DD0000]        <1> 	MOV	eSI, NEC_STATUS		; POINT TO STATUS FIELD
  2013 000028EA AC                  <1> 	lodsb				; GET ST0
  2014 000028EB 24C0                <1> 	AND	AL,11000000B		; TEST FOR NORMAL TERMINATION
  2015 000028ED 7433                <1> 	JZ	short SET_END
  2016 000028EF 3C40                <1> 	CMP	AL,01000000B		; TEST FOR ABNORMAL TERMINATION
  2017 000028F1 7527                <1> 	JNZ	short J18		; NOT ABNORMAL, BAD NEC
  2018                              <1> 
  2019                              <1> ;-----	ABNORMAL TERMINATION, FIND OUT WHY
  2020                              <1> 
  2021 000028F3 AC                  <1> 	lodsb				; GET ST1
  2022 000028F4 D0E0                <1> 	SAL	AL,1			; TEST FOR EDT FOUND
  2023 000028F6 B404                <1> 	MOV	AH,RECORD_NOT_FND
  2024 000028F8 7222                <1> 	JC	short J19
  2025 000028FA C0E002              <1> 	SAL	AL,2
  2026 000028FD B410                <1> 	MOV	AH,BAD_CRC
  2027 000028FF 721B                <1> 	JC	short J19
  2028 00002901 D0E0                <1> 	SAL	AL,1			; TEST FOR DMA OVERRUN
  2029 00002903 B408                <1> 	MOV	AH,BAD_DMA
  2030 00002905 7215                <1> 	JC	short J19
  2031 00002907 C0E002              <1> 	SAL	AL,2			; TEST FOR RECORD NOT FOUND
  2032 0000290A B404                <1> 	MOV	AH,RECORD_NOT_FND
  2033 0000290C 720E                <1> 	JC	short J19
  2034 0000290E D0E0                <1> 	SAL	AL,1
  2035 00002910 B403                <1> 	MOV	AH,WRITE_PROTECT	; TEST FOR WRITE_PROTECT
  2036 00002912 7208                <1> 	JC	short J19
  2037 00002914 D0E0                <1> 	SAL	AL,1			; TEST MISSING ADDRESS MARK
  2038 00002916 B402                <1> 	MOV	AH,BAD_ADDR_MARK
  2039 00002918 7202                <1> 	JC	short J19
  2040                              <1> 
  2041                              <1> ;----- 	NEC MUST HAVE FAILED
  2042                              <1> J18:
  2043 0000291A B420                <1> 	MOV	AH,BAD_NEC
  2044                              <1> J19:
  2045 0000291C 0825[80DD0000]      <1> 	OR	[DSKETTE_STATUS], AH
  2046                              <1> SET_END:
  2047 00002922 803D[80DD0000]01    <1> 	CMP	byte [DSKETTE_STATUS], 1 ; SET ERROR CONDITION
  2048 00002929 F5                  <1> 	CMC
  2049 0000292A 5E                  <1> 	POP	eSI
  2050 0000292B C3                  <1> 	RETn				; RESTORE HEAD #, # OF SECTORS
  2051                              <1> 
  2052                              <1> SET_END_POP:
  2053 0000292C 9D                  <1> 	POPF
  2054 0000292D EBF3                <1> 	JMP	SHORT SET_END
  2055                              <1> 
  2056                              <1> ;-------------------------------------------------------------------------------
  2057                              <1> ; DSTATE:	ESTABLISH STATE UPON SUCCESSFUL OPERATION.
  2058                              <1> ;-------------------------------------------------------------------------------
  2059                              <1> DSTATE:
  2060 0000292F 803D[80DD0000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  2061 00002936 753E                <1> 	JNZ	short SETBAC		    ; IF ERROR JUMP
  2062 00002938 808F[8DDD0000]10    <1> 	OR	byte [DSK_STATE+eDI],MED_DET ; NO ERROR, MARK MEDIA AS DETERMINED
  2063 0000293F F687[8DDD0000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE DETERMINED ?
  2064 00002946 752E                <1> 	JNZ	short SETBAC		; IF DETERMINED NO TRY TO DETERMINE
  2065 00002948 8A87[8DDD0000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  2066 0000294E 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  2067 00002950 3C80                <1> 	CMP	AL,RATE_250		; RATE 250 ?
  2068 00002952 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 00002954 E871010000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  2073                              <1> 	;;20/02/2015
  2074                              <1> 	;;JC	short M_12		; CMOS BAD
  2075 00002959 7414                <1> 	jz	short M_12 ;; 20/02/2015
  2076 0000295B 3C04                <1> 	CMP	AL, 4			; 1.44MB DRIVE ?
  2077 0000295D 7410                <1> 	JE	short M_12		; YES
  2078                              <1> M_720:
  2079 0000295F 80A7[8DDD0000]FD    <1> 	AND	byte [DSK_STATE+eDI], ~FMT_CAPA ; TURN OFF FORMAT CAPABILITY
  2080 00002966 808F[8DDD0000]04    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET  ; MARK DRIVE DETERMINED
  2081 0000296D EB07                <1> 	JMP	SHORT SETBAC		; BACK
  2082                              <1> M_12:	
  2083 0000296F 808F[8DDD0000]06    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET+FMT_CAPA 
  2084                              <1> 					; TURN ON DETERMINED & FMT CAPA
  2085                              <1> SETBAC:
  2086 00002976 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 00002977 803D[80DD0000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; GET STATUS OF OPERATION
  2097 0000297E 7445                <1> 	JZ	short NO_RETRY		; SUCCESSFUL OPERATION
  2098 00002980 803D[80DD0000]80    <1> 	CMP	byte [DSKETTE_STATUS],TIME_OUT ; IF TIME OUT NO RETRY
  2099 00002987 743C                <1> 	JZ	short NO_RETRY
  2100 00002989 8AA7[8DDD0000]      <1> 	MOV	AH,[DSK_STATE+eDI]	; GET MEDIA STATE OF DRIVE
  2101 0000298F F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED/DETERMINED ?
  2102 00002992 7531                <1> 	JNZ	short NO_RETRY		; IF ESTABLISHED STATE THEN TRUE ERROR
  2103 00002994 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE RATE
  2104 00002997 8A2D[88DD0000]      <1> 	MOV	CH,[LASTRATE]		; GET START OPERATION STATE
  2105 0000299D C0C504              <1> 	ROL	CH,4			; TO CORRESPONDING BITS
  2106 000029A0 80E5C0              <1> 	AND	CH,RATE_MSK		; ISOLATE RATE BITS
  2107 000029A3 38E5                <1> 	CMP	CH,AH			; ALL RATES TRIED
  2108 000029A5 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 000029A7 80FC01              <1> 	CMP	AH,RATE_500+1		; SET CY FOR RATE 500
  2116 000029AA D0DC                <1> 	RCR	AH,1			; TO NEXT STATE
  2117 000029AC 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE BITS
  2118 000029AF 80A7[8DDD0000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP)
  2119                              <1> 					; RATE, DBL STEP OFF
  2120 000029B6 08A7[8DDD0000]      <1> 	OR	[DSK_STATE+eDI],AH	; TURN ON NEW RATE
  2121 000029BC C605[80DD0000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; RESET STATUS FOR RETRY
  2122 000029C3 F9                  <1> 	STC				; SET CARRY FOR RETRY
  2123 000029C4 C3                  <1> 	RETn				; RETRY RETURN
  2124                              <1> 
  2125                              <1> NO_RETRY:
  2126 000029C5 F8                  <1> 	CLC				; CLEAR CARRY NO RETRY
  2127 000029C6 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 000029C7 30C0                <1> 	XOR	AL,AL			; CLEAR FOR ERROR
  2142 000029C9 803D[80DD0000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  2143 000029D0 752C                <1> 	JNZ	NT_OUT			; IF ERROR 0 TRANSFERRED
  2144 000029D2 B204                <1> 	MOV	DL,4			; SECTORS/TRACK OFFSET TO DL
  2145 000029D4 E8FA000000          <1> 	CALL	GET_PARM		; AH = SECTORS/TRACK
  2146 000029D9 8A1D[86DD0000]      <1> 	MOV	BL, [NEC_STATUS+5]	; GET ENDING SECTOR
  2147 000029DF 6689F1              <1> 	MOV	CX,SI			; CH = HEAD # STARTED
  2148 000029E2 3A2D[85DD0000]      <1> 	CMP	CH, [NEC_STATUS+4]	; GET HEAD ENDED UP ON
  2149 000029E8 750D                <1> 	JNZ	DIF_HD			; IF ON SAME HEAD, THEN NO ADJUST
  2150 000029EA 8A2D[84DD0000]      <1> 	MOV	CH, [NEC_STATUS+3]	; GET TRACK ENDED UP ON
  2151 000029F0 3A6D01              <1> 	CMP	CH,[eBP+1]		; IS IT ASKED FOR TRACK
  2152 000029F3 7404                <1> 	JZ	short SAME_TRK		; IF SAME TRACK NO INCREASE
  2153 000029F5 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  2154                              <1> DIF_HD:
  2155 000029F7 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  2156                              <1> SAME_TRK:
  2157 000029F9 2A5D00              <1> 	SUB	BL,[eBP]		; SUBTRACT START FROM END
  2158 000029FC 88D8                <1> 	MOV	AL,BL			; TO AL
  2159                              <1> NT_OUT:
  2160 000029FE 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 000029FF B202                <1> 	MOV	DL,2			; GET THE MOTOR WAIT PARAMETER
  2172 00002A01 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  2173 00002A03 E8CB000000          <1> 	CALL	GET_PARM
  2174 00002A08 8825[7FDD0000]      <1> 	MOV	[MOTOR_COUNT],AH	; STORE UPON RETURN
  2175 00002A0E 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  2176 00002A10 8A25[80DD0000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; GET STATUS OF OPERATION
  2177 00002A16 08E4                <1> 	OR	AH,AH			; CHECK FOR ERROR
  2178 00002A18 7402                <1> 	JZ	short NUN_ERR		; NO ERROR
  2179 00002A1A 30C0                <1> 	XOR	AL,AL			; CLEAR NUMBER RETURNED
  2180                              <1> NUN_ERR: 
  2181 00002A1C 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  2182 00002A1F F5                  <1> 	CMC				; SUCCESS OR FAILURE
  2183 00002A20 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 00002A21 8AA7[8DDD0000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  2195 00002A27 F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED STATE ?
  2196 00002A2A 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 00002A2C C605[7DDD0000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  2201 00002A33 E8E0000000          <1> 	CALL	MOTOR_ON		; ENSURE MOTOR STAY ON
  2202 00002A38 B500                <1> 	MOV	CH,0			; LOAD TRACK 0
  2203 00002A3A E8D4010000          <1> 	CALL	SEEK			; SEEK TO TRACK 0
  2204 00002A3F E868000000          <1> 	CALL	READ_ID			; READ ID FUNCTION
  2205 00002A44 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 00002A46 66B95004            <1> 	MOV	CX,0450H 		; START, MAX TRACKS
  2210 00002A4A F687[8DDD0000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; TEST FOR 80 TRACK CAPABILITY
  2211 00002A51 7402                <1> 	JZ	short CNT_OK		; IF NOT COUNT IS SETUP
  2212 00002A53 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 00002A55 C605[7FDD0000]FF    <1>         MOV     byte [MOTOR_COUNT], 0FFH ; ENSURE MOTOR STAYS ON FOR OPERATION 
  2220 00002A5C 6651                <1> 	PUSH	CX			; SAVE TRACK, COUNT
  2221 00002A5E C605[80DD0000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR STATUS, EXPECT ERRORS
  2222 00002A65 6631C0              <1> 	XOR	AX,AX			; CLEAR AX
  2223 00002A68 D0ED                <1> 	SHR	CH,1			; HALVE TRACK, CY = HEAD
  2224 00002A6A C0D003              <1> 	RCL	AL,3			; AX = HEAD IN CORRECT BIT
  2225 00002A6D 6650                <1> 	PUSH	AX			; SAVE HEAD
  2226 00002A6F E89F010000          <1> 	CALL	SEEK			; SEEK TO TRACK
  2227 00002A74 6658                <1> 	POP	AX			; RESTORE HEAD
  2228 00002A76 6609C7              <1> 	OR	DI,AX			; DI = HEAD OR'ED DRIVE
  2229 00002A79 E82E000000          <1> 	CALL	READ_ID			; READ ID HEAD 0
  2230 00002A7E 9C                  <1> 	PUSHF				; SAVE RETURN FROM READ_ID
  2231 00002A7F 6681E7FB00          <1> 	AND	DI,11111011B		; TURN OFF HEAD 1 BIT
  2232 00002A84 9D                  <1> 	POPF				; RESTORE ERROR RETURN
  2233 00002A85 6659                <1> 	POP	CX			; RESTORE COUNT
  2234 00002A87 7308                <1> 	JNC	short DO_CHK		; IF OK, ASKED = RETURNED TRACK ?
  2235 00002A89 FEC5                <1> 	INC	CH			; INC FOR NEXT TRACK
  2236 00002A8B 38CD                <1> 	CMP	CH,CL			; REACHED MAXIMUM YET
  2237 00002A8D 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 00002A8F F9                  <1> 	STC				; SET CARRY FOR ERROR
  2243 00002A90 C3                  <1> 	RETn				; SETUP_DBL ERROR EXIT
  2244                              <1> 
  2245                              <1> DO_CHK:
  2246 00002A91 8A0D[84DD0000]      <1> 	MOV	CL, [NEC_STATUS+3]	; LOAD RETURNED TRACK
  2247 00002A97 888F[91DD0000]      <1> 	MOV	[DSK_TRK+eDI], CL	; STORE TRACK NUMBER
  2248 00002A9D D0ED                <1> 	SHR	CH,1			; HALVE TRACK
  2249 00002A9F 38CD                <1> 	CMP	CH,CL			; IS IT THE SAME AS ASKED FOR TRACK
  2250 00002AA1 7407                <1> 	JZ	short NO_DBL		; IF SAME THEN NO DOUBLE STEP
  2251 00002AA3 808F[8DDD0000]20    <1> 	OR	byte [DSK_STATE+eDI],DBL_STEP ; TURN ON DOUBLE STEP REQUIRED
  2252                              <1> NO_DBL:
  2253 00002AAA F8                  <1> 	CLC				; CLEAR ERROR FLAG
  2254 00002AAB 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 00002AAC B8[C92A0000]        <1> 	MOV	eAX, ER_3		; MOVE NEC OUTPUT ERROR ADDRESS
  2267 00002AB1 50                  <1> 	PUSH	eAX
  2268 00002AB2 B44A                <1> 	MOV	AH,4AH			; READ ID COMMAND
  2269 00002AB4 E820010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  2270 00002AB9 6689F8              <1> 	MOV	AX,DI			; DRIVE # TO AH, HEAD 0
  2271 00002ABC 88C4                <1> 	MOV	AH,AL
  2272 00002ABE E816010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  2273 00002AC3 E80BFEFFFF          <1> 	CALL	NEC_TERM		; WAIT FOR OPERATION, GET STATUS
  2274 00002AC8 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  2275                              <1> ER_3:
  2276 00002AC9 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 00002ACA 8A87[0AD80000]      <1> mov	al, [eDI+fd0_type]
  2289 00002AD0 20C0                <1> and 	al, al ; 18/12/2014
  2290 00002AD2 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 00002AD3 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 00002AD4 87D3                <1> 	XCHG	eDX,eBX			; BL = INDEX
  2329                              <1> 	;SUB	BH,BH			; BX = INDEX
  2330 00002AD6 81E3FF000000        <1> 	and	ebx, 0FFh
  2331                              <1>     	;LDS	SI, [DISK_POINTER]	; POINT TO BLOCK
  2332                              <1> 	;
  2333                              <1> 	; 17/12/2014
  2334 00002ADC 66A1[FDD70000]      <1> 	mov	ax, [cfd] ; current (AL) and previous fd (AH)
  2335 00002AE2 38E0                <1> 	cmp	al, ah
  2336 00002AE4 7425                <1> 	je	short gpndc
  2337 00002AE6 A2[FED70000]        <1> 	mov	[pfd], al ; current drive -> previous drive
  2338 00002AEB 53                  <1> 	push	ebx ; 08/02/2015
  2339 00002AEC 88C3                <1> 	mov	bl, al 
  2340                              <1> 	; 11/12/2014
  2341 00002AEE 8A83[0AD80000]      <1> 	mov	al, [eBX+fd0_type]	; Drive type (0,1,2,3,4)
  2342                              <1> 	; 18/12/2014
  2343 00002AF4 20C0                <1> 	and	al, al
  2344 00002AF6 7507                <1> 	jnz	short gpdtc
  2345 00002AF8 BB[E7D70000]        <1> 	mov	ebx, MD_TBL6		; 1.44 MB param. tbl. (default)
  2346 00002AFD EB05                <1>         jmp     short gpdpu
  2347                              <1> gpdtc:	
  2348 00002AFF E817F9FFFF          <1> 	call	DR_TYPE_CHECK
  2349                              <1> 	; cf = 1 -> eBX points to 1.44MB fd parameter table (default)
  2350                              <1> gpdpu:
  2351 00002B04 891D[84D70000]      <1> 	mov	[DISK_POINTER], ebx
  2352 00002B0A 5B                  <1> 	pop	ebx
  2353                              <1> gpndc:
  2354 00002B0B 8B35[84D70000]      <1> 	mov	esi, [DISK_POINTER] ; 08/02/2015, si -> esi
  2355 00002B11 8A241E              <1> 	MOV	AH, [eSI+eBX]		; GET THE WORD
  2356 00002B14 87D3                <1> 	XCHG	eDX,eBX			; RESTORE BX
  2357 00002B16 5E                  <1> 	POP	eSI
  2358                              <1> 	;POP	DS
  2359 00002B17 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 00002B18 53                  <1> 	PUSH	eBX			; SAVE REG.
  2382 00002B19 E82A000000          <1> 	CALL	TURN_ON			; TURN ON MOTOR
  2383 00002B1E 7226                <1> 	JC	short MOT_IS_ON		; IF CY=1 NO WAIT
  2384 00002B20 E89BF9FFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  2385 00002B25 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 00002B2A B20A                <1> 	MOV	DL,10			; GET THE MOTOR WAIT PARAMETER
  2390 00002B2C 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 00002B31 80FC08              <1> 	cmp	ah, 8
  2395                              <1> 	;JAE	short GP2		; IF YES, CONTINUE
  2396 00002B34 7702                <1> 	ja	short J13
  2397                              <1> 	;MOV	AL,8			; ONE SECOND WAIT FOR MOTOR START UP
  2398 00002B36 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 00002B38 B95E200000          <1> 	MOV	eCX,8286		; COUNT FOR 1/8 SECOND AT 15.085737 US
  2405 00002B3D E8E8EEFFFF          <1> 	CALL	WAITF			; GO TO FIXED WAIT ROUTINE
  2406                              <1> 	;DEC	AL			; DECREMENT TIME VALUE
  2407 00002B42 FECC                <1> 	dec	ah
  2408 00002B44 75F2                <1> 	JNZ	short J13		; ARE WE DONE YET
  2409                              <1> MOT_IS_ON:
  2410 00002B46 5B                  <1> 	POP	eBX			; RESTORE REG.
  2411 00002B47 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 00002B48 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2425 00002B4A 88D9                <1> 	MOV	CL,BL			; CL = DRIVE #
  2426 00002B4C C0C304              <1> 	ROL	BL,4			; BL = DRIVE SELECT
  2427 00002B4F FA                  <1> 	CLI				; NO INTERRUPTS WHILE DETERMINING STATUS
  2428 00002B50 C605[7FDD0000]FF    <1> 	MOV	byte [MOTOR_COUNT],0FFH	; ENSURE MOTOR STAYS ON FOR OPERATION
  2429 00002B57 A0[7EDD0000]        <1> 	MOV	AL, [MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  2430 00002B5C 2430                <1> 	AND	AL,00110000B		; KEEP ONLY DRIVE SELECT BITS
  2431 00002B5E B401                <1> 	MOV	AH,1			; MASK FOR DETERMINING MOTOR BIT
  2432 00002B60 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 00002B62 38D8                <1> 	CMP	AL,BL			; REQUESTED DRIVE ALREADY SELECTED ?
  2439 00002B64 7508                <1> 	JNZ	short TURN_IT_ON	; IF NOT SELECTED JUMP
  2440 00002B66 8425[7EDD0000]      <1> 	TEST	AH, [MOTOR_STATUS]	; TEST MOTOR ON BIT
  2441 00002B6C 7535                <1> 	JNZ	short NO_MOT_WAIT	; JUMP IF MOTOR ON AND SELECTED
  2442                              <1> 
  2443                              <1> TURN_IT_ON:
  2444 00002B6E 08DC                <1> 	OR	AH,BL			; AH = DRIVE SELECT AND MOTOR ON
  2445 00002B70 8A3D[7EDD0000]      <1> 	MOV	BH,[MOTOR_STATUS]	; SAVE COPY OF @MOTOR_STATUS BEFORE
  2446 00002B76 80E70F              <1> 	AND	BH,00001111B		; KEEP ONLY MOTOR BITS
  2447 00002B79 8025[7EDD0000]CF    <1> 	AND	byte [MOTOR_STATUS],11001111B ; CLEAR OUT DRIVE SELECT
  2448 00002B80 0825[7EDD0000]      <1> 	OR	[MOTOR_STATUS],AH	; OR IN DRIVE SELECTED AND MOTOR ON
  2449 00002B86 A0[7EDD0000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  2450 00002B8B 88C3                <1> 	MOV	BL,AL			; BL=@MOTOR_STATUS AFTER, BH=BEFORE
  2451 00002B8D 80E30F              <1> 	AND	BL,00001111B		; KEEP ONLY MOTOR BITS
  2452 00002B90 FB                  <1> 	STI				; ENABLE INTERRUPTS AGAIN
  2453 00002B91 243F                <1> 	AND	AL,00111111B		; STRIP AWAY UNWANTED BITS
  2454 00002B93 C0C004              <1> 	ROL	AL,4			; PUT BITS IN DESIRED POSITIONS
  2455 00002B96 0C0C                <1> 	OR	AL,00001100B		; NO RESET, ENABLE DMA/INTERRUPT
  2456 00002B98 66BAF203            <1> 	MOV	DX,03F2H		; SELECT DRIVE AND TURN ON MOTOR
  2457 00002B9C EE                  <1> 	OUT	DX,AL
  2458 00002B9D 38FB                <1> 	CMP	BL,BH			; NEW MOTOR TURNED ON ?
  2459                              <1> 	;JZ	short NO_MOT_WAIT	; NO WAIT REQUIRED IF JUST SELECT
  2460 00002B9F 7403                <1> 	je	short no_mot_w1 ; 27/02/2015 
  2461 00002BA1 F8                  <1> 	CLC				; (re)SET CARRY MEANING WAIT
  2462 00002BA2 C3                  <1> 	RETn
  2463                              <1> 
  2464                              <1> NO_MOT_WAIT:
  2465 00002BA3 FB                  <1> 	sti
  2466                              <1> no_mot_w1: ; 27/02/2015
  2467 00002BA4 F9                  <1> 	STC				; SET NO WAIT REQUIRED
  2468                              <1> 	;STI				; INTERRUPTS BACK ON
  2469 00002BA5 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 00002BA6 B209                <1> 	MOV	DL,9			; GET HEAD SETTLE PARAMETER
  2481 00002BA8 E826FFFFFF          <1> 	CALL	GET_PARM
  2482 00002BAD 08E4                <1> 	or	ah, ah	; 17/12/2014
  2483 00002BAF 7519                <1> 	jnz	short DO_WAT
  2484 00002BB1 F605[7EDD0000]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 00002BB8 741E                <1> 	jz	short HW_DONE
  2489 00002BBA B40F                <1> 	MOV	AH,HD12_SETTLE		; LOAD 1.2M HEAD SETTLE MINIMUM
  2490 00002BBC 8A87[8DDD0000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  2491 00002BC2 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  2492 00002BC4 3C80                <1> 	CMP	AL,RATE_250		; 1.2 M DRIVE ?
  2493 00002BC6 7502                <1> 	JNZ	short DO_WAT		; DEFAULT HEAD SETTLE LOADED
  2494                              <1> ;GP3:
  2495 00002BC8 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 00002BCA B942000000          <1> 	MOV	eCX,66			; COUNT AT 15.085737 US PER COUNT
  2509 00002BCF E856EEFFFF          <1> 	CALL	WAITF			; DELAY FOR 1 MILLISECOND
  2510                              <1> 	;DEC	AL			; DECREMENT THE COUNT
  2511 00002BD4 FECC                <1> 	dec	ah
  2512 00002BD6 75F2                <1> 	JNZ	short J29		; DO AL MILLISECOND # OF TIMES
  2513                              <1> HW_DONE:
  2514 00002BD8 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 00002BD9 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 00002BDD 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 00002BE2 EC                  <1> 	IN	AL,DX			; GET STATUS
  2587 00002BE3 24C0                <1> 	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  2588 00002BE5 3C80                <1> 	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  2589 00002BE7 7418                <1> 	JZ	short J27		; STATUS AND DIRECTION OK
  2590                              <1> WFPS_HI:
  2591 00002BE9 E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  2592 00002BEB A810                <1> 	TEST	AL,010H			; transition on memory
  2593 00002BED 75FA                <1> 	JNZ	SHORT WFPS_HI		; refresh.
  2594                              <1> WFPS_LO:
  2595 00002BEF E461                <1> 	IN	AL, PORT_B		; SYS1
  2596 00002BF1 A810                <1> 	TEST	AL,010H
  2597 00002BF3 74FA                <1> 	JZ	SHORT WFPS_LO
  2598                              <1> 	;LOOP	SHORT WFPS_CHECK_PORT
  2599 00002BF5 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 00002BF7 800D[80DD0000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  2623                              <1> 	;POP	BX			; RESTORE REG.
  2624 00002BFE 58                  <1> 	POP	eAX ; 08/02/2015	; DISCARD THE RETURN ADDRESS
  2625 00002BFF F9                  <1> 	STC				; INDICATE ERROR TO CALLER
  2626 00002C00 C3                  <1> 	RETn
  2627                              <1> 
  2628                              <1> ;-----	DIRECTION AND STATUS OK; OUTPUT BYTE
  2629                              <1> 
  2630                              <1> J27:	
  2631 00002C01 88E0                <1> 	MOV	AL,AH			; GET BYTE TO OUTPUT
  2632 00002C03 6642                <1> 	INC	DX			; DATA PORT = STATUS PORT + 1
  2633 00002C05 EE                  <1> 	OUT	DX,AL			; OUTPUT THE BYTE
  2634                              <1> 	;;NEWIODELAY  ;; 27/02/2015
  2635                              <1> 	; 27/02/2015
  2636 00002C06 9C                  <1> 	PUSHF				; SAVE FLAGS
  2637 00002C07 B903000000          <1> 	MOV	eCX, 3			; 30 TO 45 MICROSECONDS WAIT FOR
  2638 00002C0C E819EEFFFF          <1> 	CALL 	WAITF			; NEC FLAGS UPDATE CYCLE
  2639 00002C11 9D                  <1> 	POPF				; RESTORE FLAGS FOR EXIT
  2640                              <1> 	;POP	BX			; RESTORE REG
  2641 00002C12 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 00002C13 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2657 00002C15 B001                <1> 	MOV	AL,1			; ESTABLISH MASK FOR RECALIBRATE TEST
  2658 00002C17 86CB                <1> 	XCHG	CL,BL			; SET DRIVE VALULE INTO CL
  2659 00002C19 D2C0                <1> 	ROL	AL,CL			; SHIFT MASK BY THE DRIVE VALUE
  2660 00002C1B 86CB                <1> 	XCHG	CL,BL			; RECOVER TRACK VALUE
  2661 00002C1D 8405[7DDD0000]      <1> 	TEST	AL,[SEEK_STATUS]	; TEST FOR RECALIBRATE REQUIRED
  2662 00002C23 7526                <1> 	JNZ	short J28A		; JUMP IF RECALIBRATE NOT REQUIRED
  2663                              <1> 
  2664 00002C25 0805[7DDD0000]      <1> 	OR	[SEEK_STATUS],AL	; TURN ON THE NO RECALIBRATE BIT IN FLAG
  2665 00002C2B E862000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  2666 00002C30 730E                <1> 	JNC	short AFT_RECAL		; RECALIBRATE DONE
  2667                              <1> 
  2668                              <1> ;-----	ISSUE RECALIBRATE FOR 80 TRACK DISKETTES
  2669                              <1> 
  2670 00002C32 C605[80DD0000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR OUT INVALID STATUS
  2671 00002C39 E854000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  2672 00002C3E 7251                <1> 	JC	short RB		; IF RECALIBRATE FAILS TWICE THEN ERROR
  2673                              <1> 
  2674                              <1> AFT_RECAL:
  2675 00002C40 C687[91DD0000]00    <1>         MOV     byte [DSK_TRK+eDI],0    ; SAVE NEW CYLINDER AS PRESENT POSITION
  2676 00002C47 08ED                <1> 	OR	CH,CH			; CHECK FOR SEEK TO TRACK 0
  2677 00002C49 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 00002C4B F687[8DDD0000]20    <1> J28A:	TEST	byte [DSK_STATE+eDI],DBL_STEP ; CHECK FOR DOUBLE STEP REQUIRED
  2682 00002C52 7402                <1> 	JZ	short _R7		; SINGLE STEP REQUIRED BYPASS DOUBLE
  2683 00002C54 D0E5                <1> 	SHL	CH,1			; DOUBLE NUMBER OF STEP TO TAKE
  2684                              <1> 
  2685 00002C56 3AAF[91DD0000]      <1> _R7:	CMP	CH, [DSK_TRK+eDI]	; SEE IF ALREADY AT THE DESIRED TRACK
  2686 00002C5C 7433                <1> 	JE	short RB		; IF YES, DO NOT NEED TO SEEK
  2687                              <1> 
  2688 00002C5E BA[912C0000]        <1> 	MOV	eDX, NEC_ERR		; LOAD RETURN ADDRESS
  2689 00002C63 52                  <1> 	PUSH	eDX ; (*)		; ON STACK FOR NEC OUTPUT ERROR
  2690 00002C64 88AF[91DD0000]      <1> 	MOV	[DSK_TRK+eDI],CH	; SAVE NEW CYLINDER AS PRESENT POSITION
  2691 00002C6A B40F                <1> 	MOV	AH,0FH			; SEEK COMMAND TO NEC
  2692 00002C6C E868FFFFFF          <1> 	CALL	NEC_OUTPUT
  2693 00002C71 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2694 00002C73 88DC                <1> 	MOV	AH,BL			; OUTPUT DRIVE NUMBER
  2695 00002C75 E85FFFFFFF          <1> 	CALL	NEC_OUTPUT
  2696 00002C7A 8AA7[91DD0000]      <1> 	MOV	AH, [DSK_TRK+eDI]	; GET CYLINDER NUMBER
  2697 00002C80 E854FFFFFF          <1> 	CALL	NEC_OUTPUT
  2698 00002C85 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 00002C8A 9C                  <1> 	PUSHF				; SAVE STATUS
  2704 00002C8B E816FFFFFF          <1> 	CALL	HD_WAIT			; WAIT FOR HEAD SETTLE TIME
  2705 00002C90 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 00002C91 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 00002C92 6651                <1> 	PUSH	CX
  2722 00002C94 B8[B02C0000]        <1> 	MOV	eAX, RC_BACK		; LOAD NEC_OUTPUT ERROR
  2723 00002C99 50                  <1> 	PUSH	eAX
  2724 00002C9A B407                <1> 	MOV	AH,07H			; RECALIBRATE COMMAND
  2725 00002C9C E838FFFFFF          <1> 	CALL	NEC_OUTPUT
  2726 00002CA1 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2727 00002CA3 88DC                <1> 	MOV	AH,BL
  2728 00002CA5 E82FFFFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE DRIVE NUMBER
  2729 00002CAA E804000000          <1> 	CALL	CHK_STAT_2		; GET THE INTERRUPT AND SENSE INT STATUS
  2730 00002CAF 58                  <1> 	POP	eAX			; THROW AWAY ERROR
  2731                              <1> RC_BACK:
  2732 00002CB0 6659                <1> 	POP	CX
  2733 00002CB2 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 00002CB3 B8[DB2C0000]        <1>         MOV     eAX, CS_BACK            ; LOAD NEC_OUTPUT ERROR ADDRESS
  2745 00002CB8 50                  <1> 	PUSH	eAX
  2746 00002CB9 E828000000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  2747 00002CBE 721A                <1> 	JC	short J34		; IF ERROR, RETURN IT
  2748 00002CC0 B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
  2749 00002CC2 E812FFFFFF          <1> 	CALL	NEC_OUTPUT
  2750 00002CC7 E84A000000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
  2751 00002CCC 720C                <1> 	JC	short J34
  2752 00002CCE A0[81DD0000]        <1> 	MOV	AL,[NEC_STATUS]		; GET THE FIRST STATUS BYTE
  2753 00002CD3 2460                <1> 	AND	AL,01100000B		; ISOLATE THE BITS
  2754 00002CD5 3C60                <1> 	CMP	AL,01100000B		; TEST FOR CORRECT VALUE
  2755 00002CD7 7403                <1> 	JZ	short J35		; IF ERROR, GO MARK IT
  2756 00002CD9 F8                  <1> 	CLC				; GOOD RETURN
  2757                              <1> J34:
  2758 00002CDA 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
  2759                              <1> CS_BACK:
  2760 00002CDB C3                  <1> 	RETn
  2761                              <1> J35:
  2762 00002CDC 800D[80DD0000]40    <1> 	OR	byte [DSKETTE_STATUS], BAD_SEEK
  2763 00002CE3 F9                  <1> 	STC				; ERROR RETURN CODE
  2764 00002CE4 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 00002CE6 FB                  <1> 	STI				; TURN ON INTERRUPTS, JUST IN CASE
  2783 00002CE7 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 00002CE8 B986450100          <1> 	mov 	ecx, WAIT_FDU_INT_LH	; 83334 (2.5 seconds)		
  2804                              <1> WFMS_CHECK_MEM:
  2805 00002CED F605[7DDD0000]80    <1> 	test	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  2806 00002CF4 7516                <1>         jnz     short J37
  2807                              <1> WFMS_HI:
  2808 00002CF6 E461                <1> 	IN	AL,PORT_B  ; 061h	; SYS1, wait for lo to hi
  2809 00002CF8 A810                <1> 	TEST	AL,010H			; transition on memory
  2810 00002CFA 75FA                <1> 	JNZ	SHORT WFMS_HI		; refresh.
  2811                              <1> WFMS_LO:
  2812 00002CFC E461                <1> 	IN	AL,PORT_B		;SYS1
  2813 00002CFE A810                <1> 	TEST	AL,010H
  2814 00002D00 74FA                <1> 	JZ	SHORT WFMS_LO
  2815 00002D02 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 00002D04 800D[80DD0000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; NOTHING HAPPENED
  2839 00002D0B F9                  <1> 	STC				; ERROR RETURN
  2840                              <1> J37:
  2841 00002D0C 9C                  <1> 	PUSHF				; SAVE CURRENT CARRY
  2842 00002D0D 8025[7DDD0000]7F    <1> 	AND	byte [SEEK_STATUS], ~INT_FLAG ; TURN OFF INTERRUPT FLAG
  2843 00002D14 9D                  <1> 	POPF				; RECOVER CARRY
  2844 00002D15 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 00002D16 57                  <1> 	PUSH	eDI
  2856 00002D17 BF[81DD0000]        <1> 	MOV	eDI, NEC_STATUS		; POINTER TO DATA AREA
  2857 00002D1C B307                <1> 	MOV	BL,7			; MAX STATUS BYTES
  2858 00002D1E 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 00002D22 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 00002D27 EC                  <1> 	IN	AL,DX			; GET STATUS
  2880 00002D28 24C0                <1> 	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  2881 00002D2A 3CC0                <1> 	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  2882 00002D2C 7418                <1> 	JZ	short J42		; STATUS AND DIRECTION OK
  2883                              <1> WFPSR_HI:
  2884 00002D2E E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  2885 00002D30 A810                <1> 	TEST	AL,010H			; transition on memory
  2886 00002D32 75FA                <1> 	JNZ	SHORT WFPSR_HI		; refresh.
  2887                              <1> WFPSR_LO:
  2888 00002D34 E461                <1> 	IN	AL, PORT_B		; SYS1
  2889 00002D36 A810                <1> 	TEST	AL,010H
  2890 00002D38 74FA                <1> 	JZ	SHORT WFPSR_LO
  2891 00002D3A 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 00002D3C 800D[80DD0000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  2912 00002D43 F9                  <1> 	STC				; SET ERROR RETURN
  2913 00002D44 EB29                <1> 	JMP	SHORT POPRES		; POP REGISTERS AND RETURN
  2914                              <1> 
  2915                              <1> ;-----	READ IN THE STATUS
  2916                              <1> 
  2917                              <1> J42:
  2918 00002D46 EB00                <1> 	JMP	$+2			; I/O DELAY
  2919 00002D48 6642                <1> 	INC	DX			; POINT AT DATA PORT
  2920 00002D4A EC                  <1> 	IN	AL,DX			; GET THE DATA
  2921                              <1> 	; 16/12/2014
  2922                              <1> 	NEWIODELAY
  2922 00002D4B E6EB                <2>  out 0ebh,al
  2923 00002D4D 8807                <1>         MOV     [eDI],AL                ; STORE THE BYTE
  2924 00002D4F 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 00002D50 B903000000          <1> 	MOV	eCX,3			; MINIMUM 24 MICROSECONDS FOR NEC
  2934 00002D55 E8D0ECFFFF          <1> 	CALL	WAITF			; WAIT 30 TO 45 MICROSECONDS
  2935 00002D5A 664A                <1> 	DEC	DX			; POINT AT STATUS PORT
  2936 00002D5C EC                  <1> 	IN	AL,DX			; GET STATUS
  2937                              <1> 	; 16/12/2014
  2938                              <1> 	NEWIODELAY
  2938 00002D5D E6EB                <2>  out 0ebh,al
  2939                              <1> 	;
  2940 00002D5F A810                <1> 	TEST	AL,00010000B		; TEST FOR NEC STILL BUSY
  2941 00002D61 740C                <1> 	JZ	short POPRES		; RESULTS DONE ?
  2942                              <1> 
  2943 00002D63 FECB                <1> 	DEC	BL			; DECREMENT THE STATUS COUNTER
  2944 00002D65 75BB                <1>         JNZ     short _R10              ; GO BACK FOR MORE
  2945 00002D67 800D[80DD0000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; TOO MANY STATUS BYTES
  2946 00002D6E F9                  <1> 	STC				; SET ERROR FLAG
  2947                              <1> 
  2948                              <1> ;-----	RESULT OPERATION IS DONE
  2949                              <1> POPRES:
  2950 00002D6F 5F                  <1> 	POP	eDI
  2951 00002D70 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 00002D71 E8A2FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON THE MOTOR IF OFF
  2966 00002D76 66BAF703            <1> 	MOV	DX,03F7H		; ADDRESS DIGITAL INPUT REGISTER
  2967 00002D7A EC                  <1> 	IN	AL,DX			; INPUT DIGITAL INPUT REGISTER
  2968 00002D7B A880                <1> 	TEST	AL,DSK_CHG		; CHECK FOR DISK CHANGE LINE ACTIVE
  2969 00002D7D 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 00002D7E E895FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON MOTOR IF NOT ALREADY ON
  2979 00002D83 E80AFFFFFF          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  2980 00002D88 7251                <1> 	JC	short DD_BAC		; ASSUME NO DRIVE PRESENT
  2981 00002D8A B530                <1> 	MOV	CH,TRK_SLAP		; SEEK TO TRACK 48
  2982 00002D8C E882FEFFFF          <1> 	CALL	SEEK
  2983 00002D91 7248                <1> 	JC	short DD_BAC		; ERROR NO DRIVE
  2984 00002D93 B50B                <1> 	MOV	CH,QUIET_SEEK+1		; SEEK TO TRACK 10
  2985                              <1> SK_GIN:
  2986 00002D95 FECD                <1> 	DEC	CH			; DECREMENT TO NEXT TRACK
  2987 00002D97 6651                <1> 	PUSH	CX			; SAVE TRACK
  2988 00002D99 E875FEFFFF          <1> 	CALL	SEEK
  2989 00002D9E 723C                <1> 	JC	short POP_BAC		; POP AND RETURN
  2990 00002DA0 B8[DC2D0000]        <1> 	MOV	eAX, POP_BAC		; LOAD NEC OUTPUT ERROR ADDRESS
  2991 00002DA5 50                  <1> 	PUSH	eAX
  2992 00002DA6 B404                <1> 	MOV	AH,SENSE_DRV_ST		; SENSE DRIVE STATUS COMMAND BYTE
  2993 00002DA8 E82CFEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  2994 00002DAD 6689F8              <1> 	MOV	AX,DI			; AL = DRIVE
  2995 00002DB0 88C4                <1> 	MOV	AH,AL			; AH = DRIVE
  2996 00002DB2 E822FEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  2997 00002DB7 E85AFFFFFF          <1> 	CALL	RESULTS			; GO GET STATUS
  2998 00002DBC 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  2999 00002DBD 6659                <1> 	POP	CX			; RESTORE TRACK
  3000 00002DBF F605[81DD0000]10    <1> 	TEST	byte [NEC_STATUS], HOME	; TRACK 0 ?
  3001 00002DC6 74CD                <1> 	JZ	short SK_GIN		; GO TILL TRACK 0
  3002 00002DC8 08ED                <1> 	OR	CH,CH			; IS HOME AT TRACK 0
  3003 00002DCA 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 00002DCC 808F[8DDD0000]94    <1> 	OR	byte [DSK_STATE+eDI], DRV_DET+MED_DET+RATE_250
  3009 00002DD3 C3                  <1> 	RETn				; ALL INFORMATION SET
  3010                              <1> IS_80:
  3011 00002DD4 808F[8DDD0000]01    <1> 	OR	byte [DSK_STATE+eDI], TRK_CAPA ; SETUP 80 TRACK CAPABILITY
  3012                              <1> DD_BAC:
  3013 00002DDB C3                  <1> 	RETn
  3014                              <1> POP_BAC:
  3015 00002DDC 6659                <1> 	POP	CX			; THROW AWAY
  3016 00002DDE 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 00002DDF 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER
  3032 00002DE1 1E                  <1> 	push	ds
  3033 00002DE2 66B81000            <1> 	mov	ax, KDATA
  3034 00002DE6 8ED8                <1> 	mov 	ds, ax
  3035 00002DE8 800D[7DDD0000]80    <1>         OR      byte [SEEK_STATUS], INT_FLAG ; TURN ON INTERRUPT OCCURRED
  3036 00002DEF B020                <1> 	MOV     AL,EOI                  ; END OF INTERRUPT MARKER
  3037 00002DF1 E620                <1> 	OUT	INTA00,AL		; INTERRUPT CONTROL PORT
  3038 00002DF3 1F                  <1> 	pop	ds
  3039 00002DF4 6658                <1> 	POP	AX			; RECOVER REGISTER
  3040 00002DF6 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 00002DF7 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 00002DF8 31FF                <1> 	XOR	eDI,eDI			; INITIALIZE DRIVE POINTER
  3063 00002DFA 66C705[8DDD0000]00- <1> 	MOV	WORD [DSK_STATE],0	; INITIALIZE STATES
  3063 00002E02 00                  <1>
  3064 00002E03 8025[88DD0000]33    <1> 	AND	byte [LASTRATE],~(STRT_MSK+SEND_MSK) ; CLEAR START & SEND
  3065 00002E0A 800D[88DD0000]C0    <1> 	OR	byte [LASTRATE],SEND_MSK ; INITIALIZE SENT TO IMPOSSIBLE
  3066 00002E11 C605[7DDD0000]00    <1> 	MOV	byte [SEEK_STATUS],0	; INDICATE RECALIBRATE NEEDED
  3067 00002E18 C605[7FDD0000]00    <1> 	MOV	byte [MOTOR_COUNT],0	; INITIALIZE MOTOR COUNT
  3068 00002E1F C605[7EDD0000]00    <1> 	MOV	byte [MOTOR_STATUS],0	; INITIALIZE DRIVES TO OFF STATE
  3069 00002E26 C605[80DD0000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; NO ERRORS
  3070                              <1> 	;
  3071                              <1> 	; 28/02/2015
  3072                              <1> 	;mov	word [cfd], 100h 
  3073 00002E2D E848F2FFFF          <1> 	call	DSK_RESET
  3074 00002E32 5A                  <1> 	pop	edx
  3075 00002E33 F8                  <1> 	clc	; 29/05/2016
  3076 00002E34 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 00002E35 9C                  <1> 	pushfd
  3109 00002E36 0E                  <1> 	push 	cs
  3110 00002E37 E841010000          <1> 	call 	DISK_IO
  3111 00002E3C 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 00002E3D 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 00002E3E C705[98DD0000]0000- <1> 	mov 	dword [HDPM_TBL_VEC], (DPT_SEGM*16)+HD0_DPT
  3464 00002E46 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 00002E48 C705[9CDD0000]2000- <1> 	mov 	dword [HDPS_TBL_VEC], (DPT_SEGM*16)+HD1_DPT
  3467 00002E50 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 00002E52 C705[A0DD0000]4000- <1> 	mov 	dword [HDSM_TBL_VEC], (DPT_SEGM*16)+HD2_DPT
  3470 00002E5A 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 00002E5C C705[A4DD0000]6000- <1> 	mov 	dword [HDSS_TBL_VEC], (DPT_SEGM*16)+HD3_DPT
  3473 00002E64 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 00002E66 BE[0CD80000]        <1> 	mov	esi, hd0_type
  3500                              <1> 	;mov	cx, 4
  3501 00002E6B B904000000          <1> 	mov	ecx, 4
  3502                              <1> hde_l:
  3503 00002E70 AC                  <1> 	lodsb
  3504 00002E71 3C80                <1> 	cmp	al, 80h			; 8?h = existing
  3505 00002E73 7206                <1> 	jb	short _L4
  3506 00002E75 FE05[94DD0000]      <1> 	inc	byte [HF_NUM]		; + 1 hard (fixed) disk drives
  3507                              <1> _L4: ; 26/02/2015
  3508 00002E7B 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 00002E7D 8A0D[94DD0000]      <1> 	mov	cl, [HF_NUM]
  3531 00002E83 20C9                <1> 	and	cl, cl
  3532 00002E85 740E                <1> 	jz	short POD_DONE
  3533                              <1> 	;
  3534 00002E87 B27F                <1> 	mov	dl, 7Fh
  3535                              <1> hdc_reset1:
  3536 00002E89 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 00002E8B B40D                <1> 	mov	ah, 0Dh ; ALTERNATE RESET
  3557                              <1> 	;int	13h
  3558 00002E8D E8A3FFFFFF          <1> 	call	int13h
  3559 00002E92 E2F5                <1> 	loop	hdc_reset1
  3560 00002E94 F8                  <1> 	clc 	; 29/05/2016
  3561                              <1> POD_DONE:
  3562 00002E95 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 00002E96 80642408FE          <1> 	and	byte [esp+8], 11111110b  ; clear carry bit of eflags register
  3693                              <1> 	; 16/05/2016
  3694 00002E9B 1E                  <1> 	push	ds
  3695 00002E9C 53                  <1> 	push	ebx ; user's buffer address (virtual)
  3696 00002E9D 66BB1000            <1> 	mov	bx, KDATA ; System (Kernel's) data segment
  3697 00002EA1 8EDB                <1> 	mov	ds, bx
  3698 00002EA3 8F05[78EA0000]      <1> 	pop	dword [user_buffer] ; 01/06/2016
  3699 00002EA9 C605[BEE30000]00    <1> 	mov	byte [scount], 0 ; sector count for transfer
  3700 00002EB0 80FC03              <1> 	cmp	ah, 03h ; chs write
  3701 00002EB3 7743                <1> 	ja	short int33h_2
  3702 00002EB5 7407                <1> 	je	short int33h_0
  3703 00002EB7 80FC02              <1> 	cmp	ah, 02h ; chs read
  3704 00002EBA 7269                <1> 	jb	short int33h_5
  3705 00002EBC EB62                <1> 	jmp	short int33h_4
  3706                              <1> int33h_0:
  3707                              <1> 	; transfer user's buffer content to sector buffer
  3708 00002EBE 51                  <1> 	push	ecx
  3709 00002EBF 0FB6C8              <1> 	movzx	ecx, al
  3710                              <1> int33h_1:
  3711 00002EC2 56                  <1> 	push	esi
  3712 00002EC3 8B35[78EA0000]      <1> 	mov	esi, [user_buffer]
  3713                              <1> 	; esi = user's buffer address (virtual, ebx)
  3714 00002EC9 57                  <1> 	push	edi
  3715 00002ECA 06                  <1> 	push	es
  3716 00002ECB 50                  <1> 	push	eax
  3717 00002ECC 66B81000            <1> 	mov	ax, KDATA
  3718 00002ED0 8EC0                <1> 	mov	es, ax
  3719 00002ED2 BF00000700          <1> 	mov	edi, Cluster_Buffer
  3720 00002ED7 C1E109              <1> 	shl	ecx, 9 ; * 512
  3721 00002EDA E800950000          <1> 	call	transfer_from_user_buffer
  3722 00002EDF 58                  <1> 	pop	eax
  3723 00002EE0 07                  <1> 	pop	es
  3724 00002EE1 5F                  <1> 	pop	edi
  3725 00002EE2 5E                  <1> 	pop	esi
  3726 00002EE3 59                  <1> 	pop	ecx
  3727 00002EE4 733F                <1> 	jnc	short int33h_5
  3728 00002EE6 8B1D[78EA0000]      <1> 	mov	ebx, [user_buffer] ; 01/06/2016
  3729 00002EEC 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 00002EED 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 00002EF2 B8FF000000          <1> 	mov	eax, 0FFh ; Unknown error !?
  3742 00002EF7 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 00002EF8 80FC05              <1> 	cmp	ah, 05h ; format track
  3765 00002EFB 770A                <1> 	ja	short int33h_3
  3766 00002EFD 7226                <1> 	jb	short int33h_5
  3767 00002EFF 51                  <1> 	push	ecx
  3768 00002F00 B901000000          <1> 	mov	ecx, 1
  3769 00002F05 EBBB                <1> 	jmp	short int33h_1
  3770                              <1> int33h_3:
  3771 00002F07 80FC1C              <1> 	cmp	ah, 1Ch ; LBA write
  3772 00002F0A 7719                <1> 	ja	short int33h_5
  3773 00002F0C 74B0                <1> 	je	short int33h_0
  3774 00002F0E 80FC1B              <1> 	cmp	ah, 1Bh ; LBA read
  3775 00002F11 740D                <1> 	je	short int33h_4
  3776 00002F13 80FC08              <1> 	cmp	ah, 08h ; get disk parameters
  3777 00002F16 750D                <1> 	jne	short int33h_5
  3778                              <1> 	; 01/06/2016
  3779 00002F18 8B1D[78EA0000]      <1> 	mov	ebx, [user_buffer] ; user's buffer address
  3780 00002F1E EB0A                <1> 	jmp	short int33h_6
  3781                              <1> int33h_4:
  3782 00002F20 A2[BEE30000]        <1> 	mov	byte [scount], al ; <= 128 sectors
  3783                              <1> int33h_5:
  3784 00002F25 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 00002F2A 1F                  <1> 	pop	ds
  3789 00002F2B 9C                  <1> 	pushfd
  3790 00002F2C 0E                  <1> 	push 	cs
  3791 00002F2D E84B000000          <1> 	call 	DISK_IO
  3792 00002F32 2E8B1D[78EA0000]    <1> 	mov	ebx, [CS:user_buffer] ; 01/06/2016
  3793 00002F39 723C                <1> 	jc	short int33h_9
  3794                              <1> 	;
  3795 00002F3B 2E803D[BEE30000]00  <1> 	cmp	byte [CS:scount], 0
  3796 00002F43 762C                <1> 	jna	short int33h_7
  3797                              <1> 	; transfer sector buffer content to user's buffer
  3798 00002F45 06                  <1> 	push	es
  3799 00002F46 1E                  <1> 	push	ds
  3800 00002F47 50                  <1> 	push	eax
  3801 00002F48 66B81000            <1> 	mov	ax, KDATA
  3802 00002F4C 8ED8                <1> 	mov	ds, ax
  3803 00002F4E 8EC0                <1> 	mov	es, ax
  3804 00002F50 51                  <1> 	push	ecx
  3805 00002F51 56                  <1> 	push	esi
  3806 00002F52 57                  <1> 	push	edi
  3807 00002F53 0FB60D[BEE30000]    <1> 	movzx	ecx, byte [scount]
  3808 00002F5A C1E109              <1> 	shl	ecx, 9 ; * 512 bytes
  3809 00002F5D 89DF                <1> 	mov	edi, ebx ; user's buffer address
  3810 00002F5F BE00000700          <1> 	mov	esi, Cluster_Buffer
  3811 00002F64 E82C940000          <1> 	call	transfer_to_user_buffer
  3812 00002F69 5F                  <1> 	pop	edi
  3813 00002F6A 5E                  <1> 	pop	esi
  3814 00002F6B 59                  <1> 	pop	ecx
  3815 00002F6C 58                  <1> 	pop	eax
  3816 00002F6D 1F                  <1> 	pop	ds
  3817 00002F6E 07                  <1> 	pop	es
  3818 00002F6F 7201                <1> 	jc	short int33h_8
  3819                              <1> int33h_7:
  3820                              <1> 	; cf = 0  ; use eflags which is in stack
  3821 00002F71 CF                  <1> 	iretd	
  3822                              <1> int33h_8:
  3823 00002F72 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 00002F77 804C240801          <1> 	or	byte [esp+8], 1  ; set carry bit of eflags register
  3837 00002F7C 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 00002F7D 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 00002F80 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 00002F86 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 00002F87 80FA83              <1> 	CMP	DL,(80H + S_MAX_FILE - 1)
  3859                              <1> 	;JA	short RET_2
  3860 00002F8A 7616                <1> 	jna	short _A0
  3861                              <1> 	; 29/05/2016
  3862 00002F8C 1E                  <1> 	push	ds
  3863 00002F8D 6650                <1> 	push	ax
  3864 00002F8F 66B81000            <1> 	mov	ax, KDATA
  3865 00002F93 8ED8                <1> 	mov	ds, ax
  3866 00002F95 6658                <1> 	pop	ax
  3867 00002F97 B4AA                <1>         mov     ah, 0AAh        ; Hard disk drive not ready !
  3868                              <1> 				; (Programmer's guide to AMIBIOS, 1992)
  3869 00002F99 8825[93DD0000]      <1> 	mov     byte [DISK_STATUS1], ah
  3870 00002F9F 1F                  <1> 	pop	ds
  3871 00002FA0 EB38                <1> 	jmp	short RET_2
  3872                              <1> _A0:
  3873                              <1> 	; 18/01/2015
  3874 00002FA2 08E4                <1> 	or	ah,ah
  3875 00002FA4 743A                <1> 	jz	short A4
  3876 00002FA6 80FC0D              <1> 	cmp	ah, 0Dh	; Alternate reset
  3877 00002FA9 7504                <1> 	jne	short A2
  3878 00002FAB 28E4                <1> 	sub	ah,ah	; Reset
  3879 00002FAD EB31                <1> 	jmp	short A4
  3880                              <1> A2:
  3881 00002FAF 80FC08              <1> 	CMP	AH,08H			; GET PARAMETERS IS A SPECIAL CASE
  3882                              <1> 	;JNZ	short A3
  3883                              <1>         ;JMP    GET_PARM_N
  3884 00002FB2 0F8431030000        <1> 	je	GET_PARM_N
  3885 00002FB8 80FC15              <1> A3:	CMP	AH,15H			; READ DASD TYPE IS ALSO
  3886                              <1> 	;JNZ	short A4
  3887                              <1>         ;JMP    READ_DASD_TYPE
  3888 00002FBB 0F84DA020000        <1>         je      READ_DASD_TYPE
  3889                              <1> 	; 02/02/2015
  3890 00002FC1 80FC1D              <1> 	cmp	ah, 1Dh			;(Temporary for Retro UNIX 386 v1)
  3891                              <1> 	; 12/01/2015
  3892 00002FC4 F5                  <1> 	cmc
  3893 00002FC5 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 00002FC7 1E                  <1> 	push	ds
  3899 00002FC8 6650                <1> 	push	ax
  3900 00002FCA 66B81000            <1> 	mov	ax, KDATA
  3901 00002FCE 8ED8                <1> 	mov	ds, ax
  3902 00002FD0 6658                <1> 	pop	ax
  3903 00002FD2 B401                <1> 	mov	ah, BAD_CMD
  3904 00002FD4 8825[93DD0000]      <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 00002FDA 804C240801          <1> 	or	byte [esp+8], 1 ; set carry bit of eflags register
  3910 00002FDF CF                  <1> 	iretd
  3911                              <1> A4:					; SAVE REGISTERS DURING OPERATION
  3912 00002FE0 C8080000            <1> 	ENTER	8,0			; SAVE (BP) AND MAKE ROOM FOR @CMD_BLOCK
  3913 00002FE4 53                  <1> 	PUSH	eBX			;  IN THE STACK, THE COMMAND BLOCK IS:
  3914 00002FE5 51                  <1> 	PUSH	eCX			;   @CMD_BLOCK == BYTE PTR [BP]-8
  3915 00002FE6 52                  <1> 	PUSH	eDX
  3916 00002FE7 1E                  <1> 	PUSH	DS
  3917 00002FE8 06                  <1> 	PUSH	ES
  3918 00002FE9 56                  <1> 	PUSH	eSI
  3919 00002FEA 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 00002FEB 6650                <1> 	push	ax
  3929 00002FED 66B81000            <1> 	mov	ax, KDATA
  3930 00002FF1 8ED8                <1> 	mov	ds, ax
  3931 00002FF3 8EC0                <1> 	mov	es, ax	
  3932 00002FF5 6658                <1> 	pop	ax
  3933 00002FF7 E88D000000          <1> 	CALL	DISK_IO_CONT		; PERFORM THE OPERATION
  3934                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  3935 00002FFC 8A25[93DD0000]      <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 00003002 5F                  <1> 	POP	eDI			; RESTORE REGISTERS
  3939 00003003 5E                  <1> 	POP	eSI
  3940 00003004 07                  <1>         POP     ES
  3941 00003005 1F                  <1>         POP     DS
  3942 00003006 5A                  <1> 	POP	eDX
  3943 00003007 59                  <1> 	POP	eCX
  3944 00003008 5B                  <1> 	POP	eBX
  3945 00003009 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 0000300A 80FC01              <1> 	cmp	ah, 1
  3950 0000300D 7205                <1> 	jc	short _A5 
  3951 0000300F 804C240801          <1> 	or	byte [esp+8], 1 ; set carry bit of eflags register
  3952                              <1> _A5:
  3953 00003014 CF                  <1> 	iretd
  3954                              <1> 
  3955                              <1> ; 21/02/2015
  3956                              <1> ;       dw --> dd
  3957                              <1> D1:					; FUNCTION TRANSFER TABLE
  3958 00003015 [D7310000]          <1> 	dd	DISK_RESET		; 000H
  3959 00003019 [4E320000]          <1> 	dd	RETURN_STATUS		; 001H
  3960 0000301D [5B320000]          <1> 	dd	DISK_READ		; 002H
  3961 00003021 [64320000]          <1> 	dd	DISK_WRITE		; 003H
  3962 00003025 [6D320000]          <1> 	dd	DISK_VERF		; 004H
  3963 00003029 [85320000]          <1> 	dd	FMT_TRK 		; 005H
  3964 0000302D [CD310000]          <1> 	dd	BAD_COMMAND		; 006H	FORMAT BAD SECTORS
  3965 00003031 [CD310000]          <1> 	dd	BAD_COMMAND		; 007H	FORMAT DRIVE
  3966 00003035 [CD310000]          <1> 	dd	BAD_COMMAND		; 008H	RETURN PARAMETERS
  3967 00003039 [70330000]          <1> 	dd	INIT_DRV		; 009H
  3968 0000303D [CF330000]          <1> 	dd	RD_LONG 		; 00AH
  3969 00003041 [D8330000]          <1> 	dd	WR_LONG 		; 00BH
  3970 00003045 [E1330000]          <1> 	dd	DISK_SEEK		; 00CH
  3971 00003049 [D7310000]          <1> 	dd	DISK_RESET		; 00DH
  3972 0000304D [CD310000]          <1> 	dd	BAD_COMMAND		; 00EH	READ BUFFER
  3973 00003051 [CD310000]          <1> 	dd	BAD_COMMAND		; 00FH	WRITE BUFFER
  3974 00003055 [09340000]          <1> 	dd	TST_RDY 		; 010H
  3975 00003059 [2D340000]          <1> 	dd	HDISK_RECAL		; 011H
  3976 0000305D [CD310000]          <1> 	dd	BAD_COMMAND		; 012H	MEMORY DIAGNOSTIC
  3977 00003061 [CD310000]          <1> 	dd	BAD_COMMAND		; 013H	DRIVE DIAGNOSTIC
  3978 00003065 [63340000]          <1> 	dd	CTLR_DIAGNOSTIC 	; 014H	CONTROLLER DIAGNOSTIC
  3979                              <1> 	; 02/02/2015 (Temporary - Retro UNIX 386 v1 - DISK I/O test)
  3980 00003069 [CD310000]          <1> 	dd	BAD_COMMAND		; 015h
  3981 0000306D [CD310000]          <1> 	dd	BAD_COMMAND		; 016h
  3982 00003071 [CD310000]          <1> 	dd	BAD_COMMAND		; 017h
  3983 00003075 [CD310000]          <1> 	dd	BAD_COMMAND		; 018h
  3984 00003079 [CD310000]          <1> 	dd	BAD_COMMAND		; 019h
  3985 0000307D [CD310000]          <1> 	dd	BAD_COMMAND		; 01Ah
  3986 00003081 [5B320000]          <1> 	dd	DISK_READ		; 01Bh ; LBA read
  3987 00003085 [64320000]          <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 00003089 80FC01              <1> 	CMP	AH,01H			; RETURN STATUS
  3993                              <1> 	;;JNZ	short SU0
  3994                              <1>         ;;JMP    RETURN_STATUS
  3995 0000308C 0F84BC010000        <1> 	je	RETURN_STATUS
  3996                              <1> SU0:
  3997 00003092 C605[93DD0000]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 00003099 89DE                <1> 	mov	esi, ebx ; 21/02/2015
  4001 0000309B 8A1D[94DD0000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  4002                              <1> 	;; 04/01/2015
  4003                              <1> 	;;PUSH	AX
  4004 000030A1 80E27F              <1> 	AND	DL,7FH			; GET DRIVE AS 0 OR 1
  4005                              <1> 					; (get drive number as 0 to 3)
  4006 000030A4 38D3                <1> 	CMP	BL,DL
  4007                              <1>         ;;JBE   BAD_COMMAND_POP         ; INVALID DRIVE
  4008 000030A6 0F8621010000        <1>         jbe     BAD_COMMAND ;; 14/02/2015
  4009                              <1>         ;
  4010                              <1> 	;;03/01/2015
  4011 000030AC 29DB                <1> 	sub	ebx, ebx
  4012 000030AE 88D3                <1> 	mov	bl, dl
  4013                              <1> 	;sub	bh, bh
  4014 000030B0 883D[A8DD0000]      <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 000030B6 6650                <1> 	push	ax ; ***
  4023                              <1> 	;PUSH	ES ; **
  4024 000030B8 6652                <1> 	PUSH	DX ; *
  4025 000030BA 6650                <1> 	push	ax
  4026 000030BC 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 000030C1 668B4310            <1> 	mov	ax, [ebx+16]
  4030 000030C5 66A3[00D80000]      <1> 	mov	[HF_PORT], ax
  4031                              <1> 	;mov	dx, [ES:BX+18] ; control port address (3F6h, 376h)
  4032 000030CB 668B5312            <1> 	mov	dx, [ebx+18]
  4033 000030CF 668915[02D80000]    <1> 	mov	[HF_REG_PORT], dx
  4034                              <1> 	;mov	al, [ES:BX+20] ; head register upper nibble (A0h,B0h,E0h,F0h)
  4035 000030D6 8A4314              <1> 	mov	al, [ebx+20]
  4036                              <1> 	; 23/02/2015
  4037 000030D9 A840                <1> 	test	al, 40h	 ; LBA bit (bit 6)
  4038 000030DB 7406                <1> 	jz 	short su1
  4039 000030DD FE05[A8DD0000]      <1> 	inc	byte [LBAMode] ; 1 
  4040                              <1> su1: 	 
  4041 000030E3 C0E804              <1> 	shr 	al, 4
  4042 000030E6 2401                <1> 	and	al, 1			
  4043 000030E8 A2[04D80000]        <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 000030ED 8A4308              <1> 	mov	al, [ebx+8]
  4048                              <1> 	;MOV	DX,[HF_REG_PORT]	; Device Control register	
  4049 000030F0 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 000030F1 8A25[95DD0000]      <1> 	MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  4059 000030F7 80E4C0              <1> 	AND	AH,0C0H 		; CONTROL BYTE
  4060 000030FA 08C4                <1> 	OR	AH,AL
  4061 000030FC 8825[95DD0000]      <1> 	MOV	[CONTROL_BYTE],AH	
  4062                              <1> 	; 04/01/2015
  4063 00003102 6658                <1> 	pop	ax
  4064 00003104 665A                <1> 	pop	dx ; * ;; 14/02/2015
  4065 00003106 20E4                <1> 	and	ah, ah	; Reset function ?
  4066 00003108 7507                <1> 	jnz	short su2
  4067                              <1> 	;;pop	dx ; * ;; 14/02/2015
  4068                              <1> 	;pop	es ; **
  4069 0000310A 6658                <1> 	pop	ax ; ***
  4070                              <1> 	;;pop	bx
  4071 0000310C E9C6000000          <1>         jmp     DISK_RESET
  4072                              <1> su2:
  4073 00003111 803D[A8DD0000]00    <1> 	cmp	byte [LBAMode], 0
  4074 00003118 7661                <1> 	jna	short su3
  4075                              <1> 	;
  4076                              <1> 	; 02/02/2015 (LBA read/write function calls)
  4077 0000311A 80FC1B              <1> 	cmp	ah, 1Bh
  4078 0000311D 720B                <1> 	jb	short lbarw1
  4079 0000311F 80FC1C              <1> 	cmp	ah, 1Ch
  4080 00003122 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 00003124 89C8                <1> 	mov	eax, ecx ; LBA address (21/02/2015)
  4084                              <1> 	;; 14/02/2015
  4085 00003126 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 00003128 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 0000312A 6652                <1> 	push	dx ; * ;; 14/02/2015
  4098                              <1> 	;xor	dh, dh
  4099 0000312C 31D2                <1> 	xor	edx, edx
  4100                              <1> 	;mov	dl, [ES:BX+14]	; sectors per track (logical)
  4101 0000312E 8A530E              <1> 	mov	dl, [ebx+14]
  4102                              <1> 	;xor	ah, ah
  4103 00003131 31C0                <1> 	xor	eax, eax
  4104                              <1> 	;mov	al, [ES:BX+2]	; heads (logical) 	
  4105 00003133 8A4302              <1> 	mov	al, [ebx+2]
  4106 00003136 FEC8                <1> 	dec	al
  4107 00003138 6640                <1> 	inc	ax		; 0 =  256
  4108 0000313A 66F7E2              <1> 	mul 	dx
  4109                              <1> 		; AX = # of Heads" * Sectors/Track
  4110 0000313D 6689CA              <1> 	mov	dx, cx
  4111                              <1> 	;and	cx, 3Fh	 ; sector  (1 to 63)
  4112 00003140 83E13F              <1> 	and	ecx, 3fh
  4113 00003143 86D6                <1> 	xchg	dl, dh
  4114 00003145 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 00003148 F7E2                <1> 	mul	edx
  4119 0000314A 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 0000314C 01C8                <1> 	add	eax, ecx
  4124 0000314E 6659                <1> 	pop	cx ; * ; ch = head, cl = drive number (zero based)
  4125                              <1> 	;push	dx
  4126                              <1> 	;push	ax
  4127 00003150 50                  <1> 	push	eax
  4128                              <1> 	;mov	al, [ES:BX+14]	; sectors per track (logical)	
  4129 00003151 8A430E              <1> 	mov	al, [ebx+14]
  4130 00003154 F6E5                <1> 	mul	ch
  4131                              <1> 		;  AX = Head * Sectors/Track
  4132 00003156 6699                <1>         cwd
  4133                              <1> 	;pop	dx
  4134 00003158 5A                  <1> 	pop	edx
  4135                              <1> 	;add	ax, dx
  4136                              <1> 	;pop	dx
  4137                              <1> 	;adc	dx, 0 ; add carry bit
  4138 00003159 01D0                <1> 	add	eax, edx
  4139                              <1> lbarw2:
  4140 0000315B 29D2                <1> 	sub	edx, edx ; 21/02/2015
  4141 0000315D 88CA                <1> 	mov	dl, cl ; 21/02/2015
  4142 0000315F 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 00003163 8A0D[04D80000]      <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 00003169 80C90E              <1> 	or	cl, 0Eh ; 1110b
  4156                              <1> 	;and	dh, 0Fh		; LBA byte 4 (bits 24 to 27)
  4157 0000316C 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh
  4158 00003171 C1E11C              <1> 	shl	ecx, 28 ; 21/02/2015
  4159                              <1> 	;or	dh, ch
  4160 00003174 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 00003176 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 00003179 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 0000317B 80FC14              <1> 	cmp 	ah, 14h
  4180 0000317E 7604                <1> 	jna 	short chsfnc
  4181                              <1> invldfnc:
  4182                              <1>         ; 14/02/2015  
  4183                              <1> 	;pop	es ; **
  4184 00003180 6658                <1>         pop     ax ; ***
  4185                              <1>         ;jmp     short BAD_COMMAND_POP
  4186 00003182 EB49                <1>         jmp     short BAD_COMMAND
  4187                              <1> chsfnc:	
  4188                              <1> 	;MOV	AX,[ES:BX+5]		; GET WRITE PRE-COMPENSATION CYLINDER
  4189 00003184 668B4305            <1> 	mov	ax, [ebx+5]
  4190 00003188 66C1E802            <1> 	SHR	AX,2
  4191 0000318C 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 0000318F 88C8                <1> 	MOV	AL,CL			; GET SECTOR NUMBER
  4204 00003191 243F                <1> 	AND	AL,3FH
  4205 00003193 8845FA              <1> 	MOV	[CMD_BLOCK+2],AL
  4206 00003196 886DFB              <1> 	MOV	[CMD_BLOCK+3],CH 	; GET CYLINDER NUMBER
  4207 00003199 88C8                <1> 	MOV	AL,CL
  4208 0000319B C0E806              <1> 	SHR	AL,6
  4209 0000319E 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 000031A1 A0[04D80000]        <1> 	mov	al, [hf_m_s]
  4213 000031A6 C0E004              <1> 	SHL	AL,4
  4214 000031A9 80E60F              <1> 	AND	DH,0FH			; HEAD NUMBER
  4215 000031AC 08F0                <1> 	OR	AL,DH
  4216                              <1> 	;OR	AL,80H or 20H
  4217 000031AE 0CA0                <1> 	OR	AL,80h+20h		; ECC AND 512 BYTE SECTORS
  4218 000031B0 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 000031B3 6658                <1>         pop     ax ; ***
  4229 000031B5 8845F9              <1>         mov     [CMD_BLOCK+1], al
  4230 000031B8 29DB                <1>         sub	ebx, ebx
  4231 000031BA 88E3                <1> 	mov     bl, ah
  4232                              <1>         ;xor     bh, bh
  4233                              <1>         ;sal     bx, 1
  4234 000031BC 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 000031C0 83FB74              <1> 	cmp	ebx, D1L
  4240 000031C3 7308                <1> 	jnb	short BAD_COMMAND
  4241                              <1>         ;xchg    bx, si
  4242 000031C5 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 000031C7 FFA6[15300000]      <1> 	jmp	dword [esi+D1]
  4259                              <1> ;;BAD_COMMAND_POP:
  4260                              <1> ;;	POP	AX
  4261                              <1> ;;	POP	BX
  4262                              <1> BAD_COMMAND:
  4263 000031CD C605[93DD0000]01    <1>         MOV     byte [DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  4264 000031D4 B000                <1> 	MOV	AL,0
  4265 000031D6 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 000031D7 FA                  <1> 	CLI
  4275 000031D8 E4A1                <1> 	IN	AL,INTB01		; GET THE MASK REGISTER
  4276                              <1> 	;JMP	$+2
  4277                              <1> 	IODELAY
  4277 000031DA EB00                <2>  jmp short $+2
  4277 000031DC EB00                <2>  jmp short $+2
  4278                              <1> 	;AND	AL,0BFH 		; ENABLE FIXED DISK INTERRUPT
  4279 000031DE 243F                <1> 	and	al,3Fh			; 22/12/2014 (IRQ 14 & IRQ 15)
  4280 000031E0 E6A1                <1> 	OUT	INTB01,AL
  4281 000031E2 FB                  <1> 	STI				; START INTERRUPTS
  4282                              <1> 	; 14/02/2015
  4283 000031E3 6689D7              <1> 	mov	di, dx	
  4284                              <1> 	; 04/01/2015
  4285                              <1> 	;xor	di,di
  4286                              <1> drst0:
  4287 000031E6 B004                <1> 	MOV	AL,04H  ; bit 2 - SRST 
  4288                              <1> 	;MOV	DX,HF_REG_PORT
  4289 000031E8 668B15[02D80000]    <1> 	MOV	DX,[HF_REG_PORT]
  4290 000031EF 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 000031F0 B902000000          <1>         mov	ecx, 2 ; 21/02/2015
  4296 000031F5 E830E8FFFF          <1> 	call    WAITF                   ; (Award Bios 1999 - WAIT_REFRESH,
  4297                              <1>                                         ; 40 micro seconds)
  4298 000031FA A0[95DD0000]        <1> 	mov	al,[CONTROL_BYTE]
  4299 000031FF 240F                <1> 	AND	AL,0FH			; SET HEAD OPTION
  4300 00003201 EE                  <1> 	OUT	DX,AL			; TURN RESET OFF
  4301 00003202 E838040000          <1> 	CALL	NOT_BUSY
  4302 00003207 7515                <1> 	JNZ	short DRERR		; TIME OUT ON RESET
  4303 00003209 668B15[00D80000]    <1> 	MOV	DX,[HF_PORT]
  4304 00003210 FEC2                <1> 	inc	dl  ; HF_PORT+1
  4305                              <1> 	; 02/01/2015 - Award BIOS 1999 - AHDSK.ASM
  4306                              <1>         ;mov     cl, 10
  4307 00003212 B90A000000          <1>         mov     ecx, 10 ; 21/02/2015 
  4308                              <1> drst1:
  4309 00003217 EC                  <1> 	IN	AL,DX			; GET RESET STATUS
  4310 00003218 3C01                <1> 	CMP	AL,1
  4311                              <1> 	; 04/01/2015
  4312 0000321A 740A                <1> 	jz	short drst2
  4313                              <1> 	;JNZ	short DRERR		; BAD RESET STATUS
  4314                              <1>         	; Drive/Head Register - bit 4
  4315 0000321C E2F9                <1> 	loop	drst1
  4316                              <1> DRERR:	
  4317 0000321E C605[93DD0000]05    <1> 	MOV	byte [DISK_STATUS1],BAD_RESET ; CARD FAILED
  4318 00003225 C3                  <1> 	RETn
  4319                              <1> drst2:
  4320                              <1> 	; 14/02/2015
  4321 00003226 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 00003229 A0[04D80000]        <1> 	mov	al, [hf_m_s] ; 18/01/2015
  4346 0000322E A801                <1> 	test	al,1
  4347                              <1> ;	jnz	short drst6
  4348 00003230 7516                <1>         jnz     short drst4
  4349 00003232 8065FDEF            <1> 	AND     byte [CMD_BLOCK+5],0EFH ; SET TO DRIVE 0
  4350                              <1> ;drst5:
  4351                              <1> drst3:
  4352 00003236 E835010000          <1> 	CALL	INIT_DRV		; SET MAX HEADS
  4353                              <1> 	;mov	dx,di
  4354 0000323B 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 00003240 C605[93DD0000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; IGNORE ANY SET UP ERRORS
  4362 00003247 C3                  <1> 	RETn
  4363                              <1> ;drst6:
  4364                              <1> drst4:		; Drive/Head Register - bit 4
  4365 00003248 804DFD10            <1> 	OR      byte [CMD_BLOCK+5],010H ; SET TO DRIVE 1     
  4366                              <1>         ;jmp    short drst5
  4367 0000324C 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 0000324E A0[93DD0000]        <1> 	MOV	AL,[DISK_STATUS1]	; OBTAIN PREVIOUS STATUS
  4375 00003253 C605[93DD0000]00    <1>         MOV     byte [DISK_STATUS1],0   ; RESET STATUS
  4376 0000325A C3                  <1> 	RETn
  4377                              <1> 
  4378                              <1> ;----------------------------------------
  4379                              <1> ;	DISK READ ROUTINE    (AH = 02H) :
  4380                              <1> ;----------------------------------------
  4381                              <1> 
  4382                              <1> DISK_READ:
  4383 0000325B C645FE20            <1> 	MOV	byte [CMD_BLOCK+6],READ_CMD
  4384 0000325F E954020000          <1>         JMP     COMMANDI
  4385                              <1> 
  4386                              <1> ;----------------------------------------
  4387                              <1> ;	DISK WRITE ROUTINE   (AH = 03H) :
  4388                              <1> ;----------------------------------------
  4389                              <1> 
  4390                              <1> DISK_WRITE:
  4391 00003264 C645FE30            <1> 	MOV	byte [CMD_BLOCK+6],WRITE_CMD
  4392 00003268 E9A6020000          <1>         JMP     COMMANDO
  4393                              <1> 
  4394                              <1> ;----------------------------------------
  4395                              <1> ;	DISK VERIFY	     (AH = 04H) :
  4396                              <1> ;----------------------------------------
  4397                              <1> 
  4398                              <1> DISK_VERF:
  4399 0000326D C645FE40            <1> 	MOV	byte [CMD_BLOCK+6],VERIFY_CMD
  4400 00003271 E814030000          <1> 	CALL	COMMAND
  4401 00003276 750C                <1> 	JNZ	short VERF_EXIT		; CONTROLLER STILL BUSY
  4402 00003278 E886030000          <1> 	CALL	_WAIT			; (Original: CALL WAIT)	
  4403 0000327D 7505                <1> 	JNZ	short VERF_EXIT		; TIME OUT
  4404 0000327F E813040000          <1> 	CALL	CHECK_STATUS
  4405                              <1> VERF_EXIT:
  4406 00003284 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 00003285 C645FE50            <1> 	MOV	byte [CMD_BLOCK+6],FMTTRK_CMD
  4414                              <1> 	;PUSH	ES
  4415                              <1> 	;PUSH	BX
  4416 00003289 53                  <1> 	push	ebx
  4417 0000328A E8BA040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS ADDRESS
  4418                              <1> 	;MOV	AL,[ES:BX+14]		; GET SECTORS/TRACK
  4419 0000328F 8A430E              <1> 	mov	al, [ebx+14]
  4420 00003292 8845F9              <1> 	MOV	[CMD_BLOCK+1],AL 	; SET SECTOR COUNT IN COMMAND
  4421 00003295 5B                  <1> 	pop	ebx
  4422                              <1> 	;POP	BX
  4423                              <1> 	;POP	ES
  4424 00003296 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 0000329B 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  4433                              <1> 	;PUSH	ES
  4434 0000329C 53                  <1> 	PUSH	eBX
  4435                              <1> 	;CALL	DDS			; ESTABLISH ADDRESSING
  4436                              <1> 	;push	cs
  4437                              <1> 	;pop	ds
  4438 0000329D 66BB1000            <1>         mov	bx, KDATA
  4439 000032A1 8EDB                <1> 	mov	ds, bx
  4440                              <1> 	;mov	es, bx
  4441 000032A3 C605[93DD0000]00    <1> 	MOV     byte [DISK_STATUS1],0
  4442 000032AA 8A1D[94DD0000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  4443 000032B0 80E27F              <1> 	AND	DL,7FH			; GET DRIVE NUMBER
  4444 000032B3 38D3                <1> 	CMP	BL,DL
  4445 000032B5 7627                <1> 	JBE	short RDT_NOT_PRESENT 	; RETURN DRIVE NOT PRESENT
  4446 000032B7 E88D040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETER ADDRESS
  4447                              <1> 	;MOV	AL,[ES:BX+2]		; HEADS
  4448 000032BC 8A4302              <1> 	mov	al, [ebx+2]
  4449                              <1> 	;MOV	CL,[ES:BX+14]
  4450 000032BF 8A4B0E              <1> 	mov	cl, [ebx+14]
  4451 000032C2 F6E9                <1> 	IMUL	CL			; * NUMBER OF SECTORS
  4452                              <1> 	;MOV	CX,[ES:BX]		; MAX NUMBER OF CYLINDERS
  4453 000032C4 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 000032C7 6649                <1> 	DEC	CX			; LEAVE ONE FOR DIAGNOSTICS
  4459                              <1> 	;
  4460 000032C9 66F7E9              <1> 	IMUL	CX			; NUMBER OF SECTORS
  4461 000032CC 6689D1              <1> 	MOV	CX,DX			; HIGH ORDER HALF
  4462 000032CF 6689C2              <1> 	MOV	DX,AX			; LOW ORDER HALF
  4463                              <1> 	;SUB	AX,AX
  4464 000032D2 28C0                <1> 	sub	al, al
  4465 000032D4 B403                <1> 	MOV	AH,03H			; INDICATE FIXED DISK
  4466 000032D6 5B                  <1> RDT2:	POP	eBX			; RESTORE REGISTERS
  4467                              <1> 	;POP	ES
  4468 000032D7 1F                  <1> 	POP	DS
  4469                              <1> 	; (*) CLC			; CLEAR CARRY
  4470                              <1> 	;RETf	2
  4471                              <1> 	; (*) 29/05/2016
  4472                              <1> 	; (*) retf 4
  4473 000032D8 80642408FE          <1> 	and	byte [esp+8], 0FEh ; clear carry bit of eflags register
  4474 000032DD CF                  <1> 	iretd
  4475                              <1> 
  4476                              <1> RDT_NOT_PRESENT:
  4477 000032DE 6629C0              <1> 	SUB	AX,AX			; DRIVE NOT PRESENT RETURN
  4478 000032E1 6689C1              <1> 	MOV	CX,AX			; ZERO BLOCK COUNT
  4479 000032E4 6689C2              <1> 	MOV	DX,AX
  4480 000032E7 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 000032E9 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  4493 000032EA 06                  <1> 	PUSH	ES
  4494 000032EB 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 000032EC 66BB1000            <1> 	mov	bx, KDATA
  4508 000032F0 8EDB                <1> 	mov	ds, bx
  4509 000032F2 8EC3                <1> 	mov	es, bx	; 27/05/2016
  4510                              <1> 	;
  4511 000032F4 80EA80              <1> 	SUB	DL,80H
  4512 000032F7 80FA04              <1> 	CMP	DL,MAX_FILE		; TEST WITHIN RANGE
  4513 000032FA 7361                <1> 	JAE	short G4
  4514                              <1> 	;
  4515 000032FC 31DB                <1> 	xor	ebx, ebx ; 21/02/2015
  4516                              <1> 	; 22/12/2014
  4517 000032FE 88D3                <1> 	mov	bl, dl
  4518                              <1> 	;xor	bh, bh  
  4519 00003300 C0E302              <1> 	shl	bl, 2			; convert index to offset
  4520                              <1> 	;add	bx, HF_TBL_VEC
  4521 00003303 81C3[98DD0000]      <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 00003309 8B1B                <1> 	mov	ebx, [ebx] ; 32 bit offset	
  4526                              <1> 
  4527 0000330B C605[93DD0000]00    <1> 	MOV	byte [DISK_STATUS1],0
  4528                              <1>         ;MOV     AX,[ES:BX]             ; MAX NUMBER OF CYLINDERS
  4529 00003312 668B03              <1> 	mov	ax, [ebx]
  4530                              <1> 	;;SUB	AX,2			; ADJUST FOR 0-N
  4531 00003315 6648                <1> 	dec	ax			; max. cylinder number
  4532 00003317 88C5                <1> 	MOV	CH,AL
  4533 00003319 66250003            <1> 	AND	AX,0300H		; HIGH TWO BITS OF CYLINDER
  4534 0000331D 66D1E8              <1> 	SHR	AX,1
  4535 00003320 66D1E8              <1> 	SHR	AX,1
  4536                              <1> 	;OR	AL,[ES:BX+14]		; SECTORS
  4537 00003323 0A430E              <1> 	or	al, [ebx+14]
  4538 00003326 88C1                <1> 	MOV	CL,AL
  4539                              <1> 	;MOV	DH,[ES:BX+2]		; HEADS
  4540 00003328 8A7302              <1> 	mov	dh, [ebx+2]
  4541 0000332B FECE                <1> 	DEC	DH			; 0-N RANGE
  4542 0000332D 8A15[94DD0000]      <1> 	MOV	DL,[HF_NUM]		; DRIVE COUNT
  4543 00003333 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 00003336 873C24              <1> 	xchg	edi, [esp]		; ebx (input)-> edi, edi -> [esp]
  4552 00003339 56                  <1> 	push	esi
  4553 0000333A 89DE                <1> 	mov	esi, ebx		; hard disk parameter table (32 bytes)	
  4554 0000333C 89FB                <1> 	mov	ebx, edi		; ebx = user's buffer address
  4555 0000333E 51                  <1> 	push	ecx
  4556 0000333F 50                  <1> 	push	eax
  4557 00003340 B920000000          <1> 	mov	ecx, 32 ; 32 bytes
  4558 00003345 E84B900000          <1> 	call	transfer_to_user_buffer ; trdosk6.s (16/05/2016)
  4559 0000334A 58                  <1> 	pop	eax
  4560 0000334B 59                  <1> 	pop	ecx
  4561 0000334C 5E                  <1> 	pop	esi
  4562 0000334D 5F                  <1> 	pop	edi
  4563 0000334E 730A                <1> 	jnc	short G5
  4564                              <1> 	; 29/05/2016 (*)
  4565 00003350 B8FF000000          <1> 	mov	eax, 0FFh ; unknown error !
  4566                              <1> _G6:
  4567 00003355 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 0000335A 07                  <1> 	POP	ES
  4572 0000335B 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 0000335C CF                  <1> 	iretd
  4578                              <1> G4:
  4579 0000335D C605[93DD0000]07    <1> 	MOV     byte [DISK_STATUS1],INIT_FAIL ; OPERATION FAILED
  4580 00003364 B407                <1> 	MOV	AH,INIT_FAIL
  4581 00003366 28C0                <1> 	SUB	AL,AL
  4582 00003368 6629D2              <1> 	SUB	DX,DX
  4583 0000336B 6629C9              <1> 	SUB	CX,CX
  4584                              <1> 	; 29/05/2016 (*)
  4585                              <1> 	;STC				; SET ERROR FLAG
  4586                              <1> 	;JMP	short G5
  4587 0000336E 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 00003370 31C0                <1> 	xor	eax, eax ; 21/02/2015
  4630 00003372 B00B                <1> 	mov	al,11 ; Physical heads from translated HDPT
  4631 00003374 3825[A8DD0000]      <1>         cmp     [LBAMode], ah   ; 0
  4632 0000337A 7702                <1> 	ja	short idrv0
  4633 0000337C B002                <1> 	mov	al,2  ; Physical heads from standard HDPT
  4634                              <1> idrv0:
  4635                              <1> 	; DL = drive number (0 based)
  4636 0000337E E8C6030000          <1> 	call	GET_VEC
  4637                              <1> 	;push	bx
  4638 00003383 53                  <1> 	push	ebx ; 21/02/2015
  4639                              <1> 	;add	bx,ax
  4640 00003384 01C3                <1> 	add	ebx, eax
  4641                              <1> 	;; 05/01/2015
  4642 00003386 8A25[04D80000]      <1> 	mov	ah, [hf_m_s] ; drive number (0= master, 1= slave)
  4643                              <1> 	;;and 	ah,1 
  4644 0000338C C0E404              <1> 	shl	ah,4
  4645 0000338F 80CCA0              <1> 	or	ah,0A0h  ; Drive/Head register - 10100000b (A0h)	
  4646                              <1> 	;mov	al,[es:bx]
  4647 00003392 8A03                <1> 	mov	al, [ebx] ; 21/02/2015
  4648 00003394 FEC8                <1> 	dec	al	 ; last head number 
  4649                              <1> 	;and	al,0Fh
  4650 00003396 08E0                <1> 	or	al,ah	 ; lower 4 bits for head number
  4651                              <1> 	;
  4652 00003398 C645FE91            <1> 	mov	byte [CMD_BLOCK+6],SET_PARM_CMD
  4653 0000339C 8845FD              <1> 	mov	[CMD_BLOCK+5],al
  4654                              <1> 	;pop	bx
  4655 0000339F 5B                  <1> 	pop	ebx
  4656 000033A0 29C0                <1> 	sub	eax, eax ; 21/02/2015
  4657 000033A2 B004                <1> 	mov	al,4 ; Physical sec per track from translated HDPT
  4658 000033A4 803D[A8DD0000]00    <1> 	cmp	byte [LBAMode], 0
  4659 000033AB 7702                <1> 	ja	short idrv1
  4660 000033AD 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 000033AF 01C3                <1> 	add	ebx, eax ; 21/02/2015
  4665                              <1> 	;mov	al,[es:bx]
  4666                              <1> 			; sector number
  4667 000033B1 8A03                <1> 	mov	al, [ebx]
  4668 000033B3 8845F9              <1> 	mov	[CMD_BLOCK+1],al
  4669 000033B6 28C0                <1> 	sub	al,al
  4670 000033B8 8845FB              <1> 	mov	[CMD_BLOCK+3],al  ; ZERO FLAGS
  4671 000033BB E8CA010000          <1> 	call	COMMAND 	  ; TELL CONTROLLER
  4672 000033C0 750C                <1> 	jnz	short INIT_EXIT	  ; CONTROLLER BUSY ERROR
  4673 000033C2 E878020000          <1> 	call	NOT_BUSY	  ; WAIT FOR IT TO BE DONE
  4674 000033C7 7505                <1> 	jnz	short INIT_EXIT	  ; TIME OUT
  4675 000033C9 E8C9020000          <1> 	call	CHECK_STATUS
  4676                              <1> INIT_EXIT:
  4677 000033CE 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 000033CF C645FE22            <1>         mov     byte [CMD_BLOCK+6],READ_CMD + ECC_MODE 
  4686 000033D3 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 000033D8 C645FE32            <1>         MOV     byte [CMD_BLOCK+6],WRITE_CMD + ECC_MODE
  4695 000033DC E932010000          <1>         JMP     COMMANDO
  4696                              <1> 
  4697                              <1> ;----------------------------------------
  4698                              <1> ;	SEEK		     (AH = 0CH) :
  4699                              <1> ;----------------------------------------
  4700                              <1> 
  4701                              <1> DISK_SEEK:
  4702 000033E1 C645FE70            <1>         MOV     byte [CMD_BLOCK+6],SEEK_CMD
  4703 000033E5 E8A0010000          <1> 	CALL	COMMAND
  4704 000033EA 751C                <1> 	JNZ	short DS_EXIT 		; CONTROLLER BUSY ERROR
  4705 000033EC E812020000          <1> 	CALL	_WAIT
  4706 000033F1 7515                <1>         JNZ     DS_EXIT                 ; TIME OUT ON SEEK
  4707 000033F3 E89F020000          <1> 	CALL	CHECK_STATUS
  4708 000033F8 803D[93DD0000]40    <1>         CMP     byte [DISK_STATUS1],BAD_SEEK
  4709 000033FF 7507                <1> 	JNE	short DS_EXIT
  4710 00003401 C605[93DD0000]00    <1>         MOV     byte [DISK_STATUS1],0
  4711                              <1> DS_EXIT:
  4712 00003408 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 00003409 E831020000          <1> 	CALL	NOT_BUSY
  4720 0000340E 751C                <1> 	JNZ	short TR_EX
  4721 00003410 8A45FD              <1> 	MOV	AL,[CMD_BLOCK+5] 	; SELECT DRIVE
  4722 00003413 668B15[00D80000]    <1> 	MOV	DX,[HF_PORT]
  4723 0000341A 80C206              <1> 	add	dl,6
  4724 0000341D EE                  <1> 	OUT	DX,AL
  4725 0000341E E88C020000          <1> 	CALL	CHECK_ST		; CHECK STATUS ONLY
  4726 00003423 7507                <1> 	JNZ	short TR_EX
  4727 00003425 C605[93DD0000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; WIPE OUT DATA CORRECTED ERROR
  4728                              <1> TR_EX:	
  4729 0000342C C3                  <1> 	RETn
  4730                              <1> 
  4731                              <1> ;----------------------------------------
  4732                              <1> ;	RECALIBRATE	     (AH = 11H) :
  4733                              <1> ;----------------------------------------
  4734                              <1> 
  4735                              <1> HDISK_RECAL:
  4736 0000342D C645FE10            <1>         MOV     byte [CMD_BLOCK+6],RECAL_CMD ; 10h, 16
  4737 00003431 E854010000          <1> 	CALL	COMMAND 		; START THE OPERATION
  4738 00003436 7523                <1> 	JNZ	short RECAL_EXIT	; ERROR
  4739 00003438 E8C6010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION
  4740 0000343D 7407                <1> 	JZ	short RECAL_X 		; TIME OUT ONE OK ?
  4741 0000343F E8BF010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION LONGER
  4742 00003444 7515                <1> 	JNZ	short RECAL_EXIT	; TIME OUT TWO TIMES IS ERROR
  4743                              <1> RECAL_X:
  4744 00003446 E84C020000          <1> 	CALL	CHECK_STATUS
  4745 0000344B 803D[93DD0000]40    <1> 	CMP	byte [DISK_STATUS1],BAD_SEEK ; SEEK NOT COMPLETE
  4746 00003452 7507                <1> 	JNE	short RECAL_EXIT	; IS OK
  4747 00003454 C605[93DD0000]00    <1> 	MOV	byte [DISK_STATUS1],0
  4748                              <1> RECAL_EXIT:
  4749 0000345B 803D[93DD0000]00    <1>         CMP     byte [DISK_STATUS1],0
  4750 00003462 C3                  <1> 	RETn
  4751                              <1> 
  4752                              <1> ;----------------------------------------
  4753                              <1> ;      CONTROLLER DIAGNOSTIC (AH = 14H) :
  4754                              <1> ;----------------------------------------
  4755                              <1> 
  4756                              <1> CTLR_DIAGNOSTIC:
  4757 00003463 FA                  <1>         CLI                             ; DISABLE INTERRUPTS WHILE CHANGING MASK
  4758 00003464 E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  4759                              <1> 	;AND	AL,0BFH
  4760 00003466 243F                <1> 	and	al, 3Fh			; enable IRQ 14 & IRQ 15
  4761                              <1> 	;JMP	$+2
  4762                              <1> 	IODELAY
  4762 00003468 EB00                <2>  jmp short $+2
  4762 0000346A EB00                <2>  jmp short $+2
  4763 0000346C E6A1                <1> 	OUT	INTB01,AL
  4764                              <1> 	IODELAY
  4764 0000346E EB00                <2>  jmp short $+2
  4764 00003470 EB00                <2>  jmp short $+2
  4765 00003472 E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  4766 00003474 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  4767                              <1> 	;JMP	$+2
  4768                              <1> 	IODELAY
  4768 00003476 EB00                <2>  jmp short $+2
  4768 00003478 EB00                <2>  jmp short $+2
  4769 0000347A E621                <1> 	OUT	INTA01,AL
  4770 0000347C FB                  <1> 	STI
  4771 0000347D E8BD010000          <1> 	CALL	NOT_BUSY		; WAIT FOR CARD
  4772 00003482 752B                <1> 	JNZ	short CD_ERR		; BAD CARD
  4773                              <1> 	;MOV	DX, HF_PORT+7
  4774 00003484 668B15[00D80000]    <1> 	mov	dx, [HF_PORT]
  4775 0000348B 80C207              <1> 	add	dl, 7
  4776 0000348E B090                <1> 	MOV	AL,DIAG_CMD		; START DIAGNOSE
  4777 00003490 EE                  <1> 	OUT	DX,AL
  4778 00003491 E8A9010000          <1> 	CALL	NOT_BUSY		; WAIT FOR IT TO COMPLETE
  4779 00003496 B480                <1> 	MOV	AH,TIME_OUT
  4780 00003498 7517                <1> 	JNZ	short CD_EXIT 		; TIME OUT ON DIAGNOSTIC
  4781                              <1> 	;MOV	DX,HF_PORT+1		; GET ERROR REGISTER
  4782 0000349A 668B15[00D80000]    <1> 	mov	dx, [HF_PORT]
  4783 000034A1 FEC2                <1> 	inc	dl
  4784 000034A3 EC                  <1> 	IN	AL,DX
  4785 000034A4 A2[8ADD0000]        <1> 	MOV	[HF_ERROR],AL		; SAVE IT
  4786 000034A9 B400                <1> 	MOV	AH,0
  4787 000034AB 3C01                <1> 	CMP	AL,1			; CHECK FOR ALL OK
  4788 000034AD 7402                <1> 	JE	SHORT CD_EXIT
  4789 000034AF B420                <1> CD_ERR: MOV	AH,BAD_CNTLR
  4790                              <1> CD_EXIT:
  4791 000034B1 8825[93DD0000]      <1> 	MOV	[DISK_STATUS1],AH
  4792 000034B7 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 000034B8 E862020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  4801 000034BD 7253                <1> 	JC	short CMD_ABORT
  4802                              <1> 	;MOV	DI,BX
  4803 000034BF 89DF                <1> 	mov	edi, ebx ; 21/02/2015
  4804 000034C1 E8C4000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  4805 000034C6 754A                <1> 	JNZ	short CMD_ABORT
  4806                              <1> CMD_I1:
  4807 000034C8 E836010000          <1> 	CALL	_WAIT			; WAIT FOR DATA REQUEST INTERRUPT
  4808 000034CD 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 000034CF B900010000          <1> 	mov	ecx, 256 ; 21/02/2015	
  4812                              <1> 	;MOV	DX,HF_PORT
  4813 000034D4 668B15[00D80000]    <1> 	mov	dx,[HF_PORT]
  4814 000034DB FA                  <1> 	CLI
  4815 000034DC FC                  <1> 	CLD
  4816 000034DD F3666D              <1> 	REP	INSW			; GET THE SECTOR
  4817 000034E0 FB                  <1> 	STI
  4818 000034E1 F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL INPUT
  4819 000034E5 7419                <1> 	JZ	short CMD_I3
  4820 000034E7 E880010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4821 000034EC 7224                <1> 	JC	short TM_OUT
  4822                              <1> 	;MOV	DX,HF_PORT
  4823 000034EE 668B15[00D80000]    <1> 	mov	dx,[HF_PORT]
  4824                              <1> 	;MOV	CX,4			; GET ECC BYTES
  4825 000034F5 B904000000          <1> 	mov 	ecx, 4 ; mov cx, 4 
  4826 000034FA EC                  <1> CMD_I2: IN	AL,DX
  4827                              <1> 	;MOV	[ES:DI],AL		; GO SLOW FOR BOARD
  4828 000034FB 8807                <1> 	mov 	[edi], al ; 21/02/2015
  4829 000034FD 47                  <1> 	INC	eDI
  4830 000034FE E2FA                <1> 	LOOP	CMD_I2
  4831                              <1> CMD_I3: 
  4832                              <1> 	; wait for 400 ns
  4833 00003500 80C207              <1> 	add 	dl, 7
  4834 00003503 EC                  <1> 	in	al, dx
  4835 00003504 EC                  <1> 	in	al, dx
  4836 00003505 EC                  <1> 	in	al, dx
  4837                              <1> 	;
  4838 00003506 E88C010000          <1> 	CALL	CHECK_STATUS
  4839 0000350B 7505                <1> 	JNZ	short CMD_ABORT		; ERROR RETURNED
  4840 0000350D FE4DF9              <1> 	DEC	byte [CMD_BLOCK+1]	; CHECK FOR MORE
  4841                              <1> 	;JNZ	SHORT CMD_I1
  4842 00003510 75BD                <1> 	jnz	short cmd_i1x ; 18/02/2016
  4843                              <1> CMD_ABORT:
  4844 00003512 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 00003513 E807020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  4853 00003518 72F8                <1> 	JC	short CMD_ABORT
  4854 0000351A 89DE                <1> CMD_OF: MOV	eSI,eBX ; 21/02/2015
  4855 0000351C E869000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  4856 00003521 75EF                <1> 	JNZ	short CMD_ABORT
  4857 00003523 E844010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4858 00003528 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 0000352A 668B15[00D80000]    <1> 	mov	dx, [HF_PORT]
  4866                              <1> 	;push	es
  4867                              <1> 	;pop	ds
  4868                              <1> 	;mov	cx, 256
  4869 00003531 B900010000          <1> 	mov	ecx, 256 ; 21/02/2015
  4870 00003536 FA                  <1> 	CLI
  4871 00003537 FC                  <1> 	CLD
  4872 00003538 F3666F              <1> 	REP	OUTSW
  4873 0000353B FB                  <1> 	STI
  4874                              <1> 	;POP	DS			; RESTORE DS
  4875 0000353C F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL OUTPUT
  4876 00003540 7419                <1> 	JZ	short CMD_O3
  4877 00003542 E825010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4878 00003547 72C9                <1> 	JC	short TM_OUT
  4879                              <1> 	;MOV	DX,HF_PORT
  4880 00003549 668B15[00D80000]    <1> 	mov	dx, [HF_PORT]
  4881                              <1> 	;MOV	CX,4			; OUTPUT THE ECC BYTES
  4882 00003550 B904000000          <1> 	mov	ecx, 4  ; mov cx, 4
  4883                              <1> CMD_O2: ;MOV	AL,[ES:SI]
  4884 00003555 8A06                <1> 	mov	al, [esi]
  4885 00003557 EE                  <1> 	OUT	DX,AL
  4886 00003558 46                  <1> 	INC	eSI
  4887 00003559 E2FA                <1> 	LOOP	CMD_O2
  4888                              <1> CMD_O3:
  4889 0000355B E8A3000000          <1> 	CALL	_WAIT			; WAIT FOR SECTOR COMPLETE INTERRUPT
  4890 00003560 75B0                <1> 	JNZ	short TM_OUT		; ERROR RETURNED
  4891 00003562 E830010000          <1> 	CALL	CHECK_STATUS
  4892 00003567 75A9                <1> 	JNZ	short CMD_ABORT
  4893 00003569 F605[89DD0000]08    <1> 	TEST	byte [HF_STATUS],ST_DRQ	; CHECK FOR MORE
  4894 00003570 75B8                <1> 	JNZ	SHORT CMD_O1
  4895                              <1> 	;MOV	DX,HF_PORT+2		; CHECK RESIDUAL SECTOR COUNT
  4896 00003572 668B15[00D80000]    <1> 	mov	dx, [HF_PORT]
  4897                              <1> 	;add	dl, 2
  4898 00003579 FEC2                <1> 	inc	dl
  4899 0000357B FEC2                <1> 	inc	dl
  4900 0000357D EC                  <1> 	IN	AL,DX			;
  4901 0000357E A8FF                <1> 	TEST	AL,0FFH 		;
  4902 00003580 7407                <1> 	JZ	short CMD_O4			; COUNT = 0  OK
  4903 00003582 C605[93DD0000]BB    <1> 	MOV	byte [DISK_STATUS1],UNDEF_ERR 
  4904                              <1> 					; OPERATION ABORTED - PARTIAL TRANSFER
  4905                              <1> CMD_O4:
  4906 00003589 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 0000358A 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 0000358B E879FEFFFF          <1> 	CALL	TST_RDY 		; CHECK DRIVE READY
  4922                              <1> 	;;POP	CX
  4923 00003590 7419                <1> 	JZ	short COMMAND2		; DRIVE IS READY
  4924 00003592 803D[93DD0000]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 00003599 7507                <1> 	jne	short COMMAND4
  4929                              <1> CMD_TIMEOUT:
  4930 0000359B C605[93DD0000]20    <1> 	MOV	byte [DISK_STATUS1],BAD_CNTLR
  4931                              <1> COMMAND4:
  4932 000035A2 5B                  <1> 	POP	eBX
  4933 000035A3 803D[93DD0000]00    <1>         CMP     byte [DISK_STATUS1],0   ; SET CONDITION CODE FOR CALLER
  4934 000035AA C3                  <1> 	RETn
  4935                              <1> COMMAND2:
  4936 000035AB 5B                  <1> 	POP	eBX
  4937 000035AC 57                  <1> 	PUSH	eDI
  4938 000035AD C605[8BDD0000]00    <1> 	MOV	byte [HF_INT_FLAG],0	; RESET INTERRUPT FLAG
  4939 000035B4 FA                  <1> 	CLI				; INHIBIT INTERRUPTS WHILE CHANGING MASK
  4940 000035B5 E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  4941                              <1> 	;AND	AL,0BFH
  4942 000035B7 243F                <1> 	and	al, 3Fh			; Enable IRQ 14 & 15
  4943                              <1> 	;JMP	$+2
  4944                              <1> 	IODELAY
  4944 000035B9 EB00                <2>  jmp short $+2
  4944 000035BB EB00                <2>  jmp short $+2
  4945 000035BD E6A1                <1> 	OUT	INTB01,AL
  4946 000035BF E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  4947 000035C1 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  4948                              <1> 	;JMP	$+2
  4949                              <1> 	IODELAY
  4949 000035C3 EB00                <2>  jmp short $+2
  4949 000035C5 EB00                <2>  jmp short $+2
  4950 000035C7 E621                <1> 	OUT	INTA01,AL
  4951 000035C9 FB                  <1> 	STI
  4952 000035CA 31FF                <1> 	XOR	eDI,eDI			; INDEX THE COMMAND TABLE
  4953                              <1> 	;MOV	DX,HF_PORT+1		; DISK ADDRESS
  4954 000035CC 668B15[00D80000]    <1> 	mov	dx, [HF_PORT]
  4955 000035D3 FEC2                <1> 	inc	dl
  4956 000035D5 F605[95DD0000]C0    <1> 	TEST	byte [CONTROL_BYTE],0C0H ; CHECK FOR RETRY SUPPRESSION
  4957 000035DC 7411                <1> 	JZ	short COMMAND3
  4958 000035DE 8A45FE              <1> 	MOV	AL, [CMD_BLOCK+6] 	; YES-GET OPERATION CODE
  4959 000035E1 24F0                <1> 	AND	AL,0F0H 		; GET RID OF MODIFIERS
  4960 000035E3 3C20                <1> 	CMP	AL,20H			; 20H-40H IS READ, WRITE, VERIFY
  4961 000035E5 7208                <1> 	JB	short COMMAND3
  4962 000035E7 3C40                <1> 	CMP	AL,40H
  4963 000035E9 7704                <1> 	JA	short COMMAND3
  4964 000035EB 804DFE01            <1> 	OR	byte [CMD_BLOCK+6],NO_RETRIES 
  4965                              <1> 					; VALID OPERATION FOR RETRY SUPPRESS
  4966                              <1> COMMAND3:
  4967 000035EF 8A443DF8            <1> 	MOV	AL,[CMD_BLOCK+eDI]	; GET THE COMMAND STRING BYTE
  4968 000035F3 EE                  <1> 	OUT	DX,AL			; GIVE IT TO CONTROLLER
  4969                              <1> 	IODELAY
  4969 000035F4 EB00                <2>  jmp short $+2
  4969 000035F6 EB00                <2>  jmp short $+2
  4970 000035F8 47                  <1> 	INC	eDI			; NEXT BYTE IN COMMAND BLOCK
  4971 000035F9 6642                <1> 	INC	DX			; NEXT DISK ADAPTER REGISTER
  4972 000035FB 6683FF07            <1> 	cmp	di, 7	; 1/1/2015	; ALL DONE?
  4973 000035FF 75EE                <1> 	JNZ	short COMMAND3		; NO--GO DO NEXT ONE
  4974 00003601 5F                  <1> 	POP	eDI
  4975 00003602 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 00003603 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 00003604 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 00003609 F605[8BDD0000]C0    <1> 	test 	byte [HF_INT_FLAG],0C0h
  5008                              <1> 	;LOOPZ	WT1
  5009 00003610 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 00003612 E461                <1> 	in	al, SYS1 ; 61h (PORT_B)	; wait for lo to hi
  5015 00003614 A810                <1> 	test	al, 10h			; transition on memory
  5016 00003616 75FA                <1> 	jnz	short WT1_hi		; refresh.
  5017                              <1> WT1_lo:
  5018 00003618 E461                <1> 	in	al, SYS1 		; 061h (PORT_B)	
  5019 0000361A A810                <1> 	test	al, 10h			
  5020 0000361C 74FA                <1> 	jz	short WT1_lo
  5021 0000361E 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 00003620 C605[93DD0000]80    <1> WT2:	MOV	byte [DISK_STATUS1],TIME_OUT ; REPORT TIME OUT ERROR
  5030 00003627 EB0E                <1> 	JMP	SHORT WT4
  5031 00003629 C605[93DD0000]00    <1> WT3:	MOV	byte [DISK_STATUS1],0
  5032 00003630 C605[8BDD0000]00    <1> 	MOV	byte [HF_INT_FLAG],0
  5033 00003637 803D[93DD0000]00    <1> WT4:	CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  5034 0000363E C3                  <1> 	RETn
  5035                              <1> 
  5036                              <1> ;----------------------------------------
  5037                              <1> ;	WAIT FOR CONTROLLER NOT BUSY	:
  5038                              <1> ;----------------------------------------
  5039                              <1> NOT_BUSY:
  5040 0000363F FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  5041                              <1> 	;PUSH	eBX
  5042                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  5043 00003640 668B15[00D80000]    <1> 	mov	DX, [HF_PORT]
  5044 00003647 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 0000364A 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 0000364F EC                  <1> 	IN	AL,DX			; CHECK STATUS
  5055                              <1> 	;TEST	AL,ST_BUSY
  5056 00003650 2480                <1> 	and	al, ST_BUSY
  5057                              <1> 	;LOOPNZ	NB1
  5058 00003652 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 00003654 E461                <1> NB1_hi: IN	AL,SYS1			; wait for hi to lo
  5063 00003656 A810                <1> 	TEST	AL,010H			; transition on memory
  5064 00003658 75FA                <1> 	JNZ	SHORT NB1_hi		; refresh.
  5065 0000365A E461                <1> NB1_lo: IN	AL,SYS1
  5066 0000365C A810                <1> 	TEST	AL,010H
  5067 0000365E 74FA                <1> 	JZ	short NB1_lo
  5068 00003660 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 00003662 B080                <1> 	mov	al, TIME_OUT
  5078                              <1> NB2:	
  5079                              <1> 	;MOV	byte [DISK_STATUS1],0
  5080                              <1> ;NB3:	
  5081                              <1> 	;POP	eBX
  5082 00003664 A2[93DD0000]        <1> 	mov	[DISK_STATUS1], al	;;; will be set after return
  5083                              <1> 	;CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  5084 00003669 08C0                <1> 	or	al, al			; (zf = 0 --> timeout)
  5085 0000366B 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 0000366C 668B15[00D80000]    <1> 	mov	dx, [HF_PORT]
  5094 00003673 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 00003676 B9E8030000          <1> 	mov 	ecx, WAIT_HDU_DRQ_LH ; 21/02/2015 
  5101 0000367B EC                  <1> WQ_1:	IN	AL,DX			; GET STATUS
  5102 0000367C A808                <1> 	TEST	AL,ST_DRQ		; WAIT FOR DRQ
  5103 0000367E 7516                <1> 	JNZ	short WQ_OK
  5104                              <1> 	;LOOP	WQ_1			; KEEP TRYING FOR A SHORT WHILE
  5105                              <1> WQ_hi:	
  5106 00003680 E461                <1> 	IN	AL,SYS1			; wait for hi to lo
  5107 00003682 A810                <1> 	TEST	AL,010H			; transition on memory
  5108 00003684 75FA                <1> 	JNZ	SHORT WQ_hi		; refresh.
  5109 00003686 E461                <1> WQ_lo:  IN      AL,SYS1
  5110 00003688 A810                <1> 	TEST	AL,010H
  5111 0000368A 74FA                <1> 	JZ	SHORT WQ_lo
  5112 0000368C E2ED                <1> 	LOOP	WQ_1
  5113                              <1> 
  5114 0000368E C605[93DD0000]80    <1>         MOV     byte [DISK_STATUS1],TIME_OUT ; ERROR
  5115 00003695 F9                  <1> 	STC
  5116                              <1> WQ_OK:
  5117 00003696 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 00003697 E813000000          <1> 	CALL	CHECK_ST		; CHECK THE STATUS BYTE
  5126 0000369C 7509                <1> 	JNZ	short CHECK_S1		; AN ERROR WAS FOUND
  5127 0000369E A801                <1> 	TEST	AL,ST_ERROR		; WERE THERE ANY OTHER ERRORS
  5128 000036A0 7405                <1> 	JZ	short CHECK_S1		; NO ERROR REPORTED
  5129 000036A2 E849000000          <1> 	CALL	CHECK_ER		; ERROR REPORTED
  5130                              <1> CHECK_S1:
  5131 000036A7 803D[93DD0000]00    <1> 	CMP	byte [DISK_STATUS1],0 	; SET STATUS FOR CALLER
  5132 000036AE 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 000036AF 668B15[00D80000]    <1> 	mov	dx, [HF_PORT]
  5140 000036B6 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 000036B9 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 000036BA E6EB                <2>  out 0ebh,al
  5150                              <1> 	;
  5151 000036BC A2[89DD0000]        <1> 	MOV	[HF_STATUS],AL
  5152 000036C1 B400                <1> 	MOV	AH,0
  5153 000036C3 A880                <1> 	TEST	AL,ST_BUSY		; IF STILL BUSY
  5154 000036C5 751A                <1> 	JNZ	short CKST_EXIT		;  REPORT OK
  5155 000036C7 B4CC                <1> 	MOV	AH,WRITE_FAULT
  5156 000036C9 A820                <1> 	TEST	AL,ST_WRT_FLT		; CHECK FOR WRITE FAULT
  5157 000036CB 7514                <1> 	JNZ	short CKST_EXIT
  5158 000036CD B4AA                <1> 	MOV	AH,NOT_RDY
  5159 000036CF A840                <1> 	TEST	AL,ST_READY		; CHECK FOR NOT READY
  5160 000036D1 740E                <1> 	JZ	short CKST_EXIT
  5161 000036D3 B440                <1> 	MOV	AH,BAD_SEEK
  5162 000036D5 A810                <1> 	TEST	AL,ST_SEEK_COMPL	; CHECK FOR SEEK NOT COMPLETE
  5163 000036D7 7408                <1> 	JZ	short CKST_EXIT
  5164 000036D9 B411                <1> 	MOV	AH,DATA_CORRECTED
  5165 000036DB A804                <1> 	TEST	AL,ST_CORRCTD		; CHECK FOR CORRECTED ECC
  5166 000036DD 7502                <1> 	JNZ	short CKST_EXIT
  5167 000036DF B400                <1> 	MOV	AH,0
  5168                              <1> CKST_EXIT:
  5169 000036E1 8825[93DD0000]      <1> 	MOV	[DISK_STATUS1],AH	; SET ERROR FLAG
  5170 000036E7 80FC11              <1> 	CMP	AH,DATA_CORRECTED	; KEEP GOING WITH DATA CORRECTED
  5171 000036EA 7403                <1> 	JZ	short CKST_EX1
  5172 000036EC 80FC00              <1> 	CMP	AH,0
  5173                              <1> CKST_EX1:
  5174 000036EF 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 000036F0 668B15[00D80000]    <1> 	mov	dx, [HF_PORT]		;
  5182 000036F7 FEC2                <1> 	inc	dl
  5183 000036F9 EC                  <1> 	IN	AL,DX
  5184 000036FA A2[8ADD0000]        <1> 	MOV	[HF_ERROR],AL
  5185 000036FF 53                  <1> 	PUSH	eBX ; 21/02/2015
  5186 00003700 B908000000          <1> 	MOV	eCX,8			; TEST ALL 8 BITS
  5187 00003705 D0E0                <1> CK1:	SHL	AL,1			; MOVE NEXT ERROR BIT TO CARRY
  5188 00003707 7202                <1> 	JC	short CK2		; FOUND THE ERROR
  5189 00003709 E2FA                <1> 	LOOP	CK1			; KEEP TRYING
  5190 0000370B BB[F4D70000]        <1> CK2:	MOV	eBX, ERR_TBL		; COMPUTE ADDRESS OF
  5191 00003710 01CB                <1> 	ADD	eBX,eCX			; ERROR CODE
  5192                              <1> 	;;MOV	AH,BYTE [CS:BX]		; GET ERROR CODE
  5193                              <1> 	;mov	ah, [bx]
  5194 00003712 8A23                <1> 	mov	ah, [ebx] ; 21/02/2015	
  5195 00003714 8825[93DD0000]      <1> CKEX:	MOV	[DISK_STATUS1],AH	; SAVE ERROR CODE
  5196 0000371A 5B                  <1> 	POP	eBX
  5197 0000371B 80FC00              <1> 	CMP	AH,0
  5198 0000371E 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 0000371F 6650                <1> 	PUSH	AX			; SAVE REGISTERS
  5211 00003721 66B80080            <1> 	MOV	AX,8000H		; AH = MAX # SECTORS AL = MAX OFFSET
  5212 00003725 F645FE02            <1>         TEST    byte [CMD_BLOCK+6],ECC_MODE
  5213 00003729 7404                <1> 	JZ	short CKD1
  5214 0000372B 66B8047F            <1> 	MOV	AX,7F04H		; ECC IS 4 MORE BYTES
  5215 0000372F 3A65F9              <1> CKD1:	CMP	AH, [CMD_BLOCK+1] 	; NUMBER OF SECTORS
  5216 00003732 7706                <1> 	JA	short CKDOK		; IT WILL FIT
  5217 00003734 7208                <1> 	JB	short CKDERR		; TOO MANY
  5218 00003736 38D8                <1> 	CMP	AL,BL			; CHECK OFFSET ON MAX SECTORS
  5219 00003738 7204                <1> 	JB	short CKDERR		; ERROR
  5220 0000373A F8                  <1> CKDOK:	CLC				; CLEAR CARRY
  5221 0000373B 6658                <1> 	POP	AX
  5222 0000373D C3                  <1> 	RETn				; NORMAL RETURN
  5223 0000373E F9                  <1> CKDERR: STC				; INDICATE ERROR
  5224 0000373F C605[93DD0000]09    <1>         MOV     byte [DISK_STATUS1],DMA_BOUNDARY
  5225 00003746 6658                <1> 	POP	AX
  5226 00003748 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 00003749 31DB                <1> 	xor	ebx, ebx
  5247 0000374B 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 0000374D C0E302              <1> 	shl	bl, 2	;;
  5253                              <1> 	;add	bx, HF_TBL_VEC		; Disk parameter table pointer
  5254 00003750 81C3[98DD0000]      <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 00003756 8B1B                <1> 	mov	ebx, [ebx]		
  5259                              <1> ;GV_EXIT:
  5260 00003758 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 00003759 6650                <1> 	PUSH	AX
  5278 0000375B 1E                  <1> 	PUSH	DS
  5279                              <1> 	;CALL	DDS
  5280                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  5281 0000375C 66B81000            <1> 	mov	ax, KDATA
  5282 00003760 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 00003762 C605[8BDD0000]FF    <1> 	mov	byte [HF_INT_FLAG], 0FFh
  5287                              <1> 	;
  5288 00003769 6652                <1> 	push	dx
  5289 0000376B 66BAF701            <1> 	mov	dx, HDC1_BASEPORT+7	; Status Register (1F7h)
  5290                              <1> 					; Clear Controller
  5291                              <1> Clear_IRQ1415:				; (Award BIOS - 1999)
  5292 0000376F EC                  <1> 	in	al, dx			;
  5293 00003770 665A                <1> 	pop	dx
  5294                              <1> 	NEWIODELAY
  5294 00003772 E6EB                <2>  out 0ebh,al
  5295                              <1> 	;
  5296 00003774 B020                <1> 	MOV	AL,EOI			; NON-SPECIFIC END OF INTERRUPT
  5297 00003776 E6A0                <1> 	OUT	INTB00,AL		; FOR CONTROLLER #2
  5298                              <1> 	;JMP	$+2			; WAIT
  5299                              <1> 	NEWIODELAY
  5299 00003778 E6EB                <2>  out 0ebh,al
  5300 0000377A E620                <1> 	OUT	INTA00,AL		; FOR CONTROLLER #1
  5301 0000377C 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 0000377D 6658                <1> 	POP	AX
  5307 0000377F 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 00003780 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 00003782 B00B                <1> 	mov	al, 0Bh  ; In-Service Register
  5322 00003784 E6A0                <1> 	out	0A0h, al
  5323 00003786 EB00                <1>         jmp short $+2
  5324 00003788 EB00                <1> 	jmp short $+2
  5325 0000378A E4A0                <1> 	in	al, 0A0h
  5326 0000378C 2480                <1> 	and 	al, 80h ; bit 7 (is it real IRQ 15 or fake?)
  5327 0000378E 74ED                <1> 	jz	short irq15_iret ; Fake (spurious)IRQ, do not send EOI)
  5328                              <1> 	;
  5329 00003790 1E                  <1> 	PUSH	DS
  5330                              <1> 	;CALL	DDS
  5331                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  5332 00003791 66B81000            <1> 	mov	ax, KDATA
  5333 00003795 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 00003797 800D[8BDD0000]C0    <1> 	or	byte [HF_INT_FLAG], 0C0h
  5338                              <1> 	;
  5339 0000379E 6652                <1> 	push	dx
  5340 000037A0 66BA7701            <1> 	mov	dx, HDC2_BASEPORT+7	; Status Register (177h)
  5341                              <1> 					; Clear Controller (Award BIOS 1999)
  5342 000037A4 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 000037A6 A1[00DD0000]        <1> 	mov	eax, [free_pages]
   328 000037AB 21C0                <1> 	and	eax, eax
   329 000037AD 7438                <1> 	jz	short out_of_memory
   330                              <1> 	;
   331 000037AF 53                  <1> 	push	ebx
   332 000037B0 51                  <1> 	push	ecx
   333                              <1> 	;
   334 000037B1 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table offset
   335 000037B6 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 000037B8 031D[04DD0000]      <1> 	add	ebx, [next_page] ; Free page searching starts from here
   343                              <1> 				 ; next_free_page >> 5
   344 000037BE 030D[08DD0000]      <1> 	add	ecx, [last_page] ; Free page searching ends here
   345                              <1> 				 ; (total_pages - 1) >> 5
   346                              <1> al_p_scan:
   347 000037C4 39CB                <1> 	cmp	ebx, ecx
   348 000037C6 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 000037C8 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 000037CB 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 000037CD 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 000037D0 EBF2                <1>         jmp     short al_p_scan
   382                              <1> 	;
   383                              <1> al_p_notfound:
   384 000037D2 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
   385 000037D8 890D[04DD0000]      <1> 	mov	[next_page], ecx ; next/first free page = last page 
   386                              <1> 				 ; (deallocate_page procedure will change it)
   387 000037DE 31C0                <1> 	xor	eax, eax
   388 000037E0 A3[00DD0000]        <1> 	mov	[free_pages], eax ; 0
   389 000037E5 59                  <1> 	pop	ecx
   390 000037E6 5B                  <1> 	pop	ebx
   391                              <1> 	;
   392                              <1> out_of_memory:
   393 000037E7 E855040000          <1> 	call	swap_out
   394 000037EC 7325                <1> 	jnc	short al_p_ok  ; [free_pages] = 0, re-allocation by swap_out
   395                              <1> 	;
   396 000037EE 29C0                <1> 	sub 	eax, eax ; 0
   397 000037F0 F9                  <1> 	stc
   398 000037F1 C3                  <1> 	retn
   399                              <1> 
   400                              <1> al_p_found:
   401 000037F2 89D9                <1> 	mov	ecx, ebx
   402 000037F4 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
   403 000037FA 890D[04DD0000]      <1> 	mov	[next_page], ecx ; Set first free page searching start
   404                              <1> 				 ; address/offset (to the next)
   405 00003800 FF0D[00DD0000]      <1>         dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
   406                              <1> 	;
   407 00003806 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 00003809 C1E103              <1> 	shl	ecx, 3		 ; (page block offset * 32) + page index
   415 0000380C 01C8                <1> 	add	eax, ecx	 ; = page number
   416 0000380E 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 00003811 59                  <1> 	pop	ecx
   422 00003812 5B                  <1> 	pop	ebx
   423                              <1> al_p_ok:
   424 00003813 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 00003814 E88DFFFFFF          <1> 	call	allocate_page
   446 00003819 7216                <1> 	jc	short mkpd_error
   447                              <1> 	;
   448 0000381B A3[31F20000]        <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 00003820 57                  <1> 	push	edi
   462 00003821 51                  <1> 	push	ecx
   463 00003822 50                  <1> 	push	eax
   464 00003823 B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
   465 00003828 89C7                <1> 	mov	edi, eax
   466 0000382A 31C0                <1> 	xor	eax, eax
   467 0000382C F3AB                <1> 	rep	stosd
   468 0000382E 58                  <1> 	pop	eax
   469 0000382F 59                  <1> 	pop	ecx
   470 00003830 5F                  <1> 	pop	edi
   471                              <1> mkpd_error:
   472                              <1> mkpt_error:
   473 00003831 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 00003832 E86FFFFFFF          <1> 	call	allocate_page
   497 00003837 72F8                <1> 	jc	short mkpt_error
   498 00003839 E811000000          <1> 	call	set_pde	
   499 0000383E 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 00003840 E861FFFFFF          <1> 	call	allocate_page
   520 00003845 7207                <1> 	jc	short mkp_err
   521 00003847 E821000000          <1> 	call	set_pte	
   522 0000384C 73D2                <1> 	jnc	short clear_page ; 18/04/2015
   523                              <1> mkp_err:
   524 0000384E 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 0000384F 89DA                <1> 	mov	edx, ebx
   550 00003851 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22
   551 00003854 C1E202              <1> 	shl	edx, 2 ; offset to page directory (1024*4)
   552 00003857 0315[31F20000]      <1> 	add	edx, [u.pgdir]
   553                              <1> 	;
   554 0000385D 21C0                <1> 	and	eax, eax
   555 0000385F 7506                <1> 	jnz	short spde_1
   556                              <1> 	;
   557 00003861 8B02                <1> 	mov	eax, [edx]  ; old PDE value
   558                              <1> 	;test	al, 1
   559                              <1> 	;jz	short spde_2
   560 00003863 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h  ; clear lower 12 bits
   561                              <1> spde_1:
   562                              <1> 	;and	cx, 0FFFh
   563 00003867 8902                <1> 	mov	[edx], eax
   564 00003869 66090A              <1> 	or	[edx], cx
   565 0000386C 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 0000386D 50                  <1> 	push	eax
   596 0000386E A1[31F20000]        <1> 	mov	eax, [u.pgdir] ; 20/07/2015
   597 00003873 E837000000          <1> 	call 	get_pde
   598                              <1> 		; EDX = PDE address
   599                              <1> 		; EAX = PDE value
   600 00003878 5A                  <1> 	pop	edx ; physical page address
   601 00003879 722A                <1> 	jc	short spte_err ; PDE not present
   602                              <1> 	;
   603 0000387B 53                  <1> 	push	ebx ; 24/07/2015
   604 0000387C 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
   605                              <1> 			    ; EDX = PT address (physical)	
   606 00003880 C1EB0C              <1> 	shr	ebx, PAGE_SHIFT ; 12
   607 00003883 81E3FF030000        <1> 	and	ebx, PTE_MASK	; 03FFh
   608                              <1> 			 ; clear higher 10 bits (PD bits)
   609 00003889 C1E302              <1> 	shl	ebx, 2   ; offset to page table (1024*4)
   610 0000388C 01C3                <1> 	add	ebx, eax
   611                              <1> 	;
   612 0000388E 8B03                <1> 	mov	eax, [ebx] ; Old PTE value
   613 00003890 A801                <1> 	test	al, 1
   614 00003892 740C                <1> 	jz	short spte_0
   615 00003894 09D2                <1> 	or	edx, edx
   616 00003896 750F                <1> 	jnz	short spte_1
   617 00003898 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 bits
   618 0000389C 89C2                <1> 	mov	edx, eax
   619 0000389E 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 000038A0 21C0                <1> 	and	eax, eax
   625 000038A2 7403                <1> 	jz	short spte_1
   626                              <1> 	; 24/07/2015
   627                              <1> 	; swapped page ! (on disk)
   628 000038A4 5B                  <1> 	pop	ebx
   629                              <1> spte_err:
   630 000038A5 F9                  <1> 	stc
   631 000038A6 C3                  <1> 	retn
   632                              <1> spte_1: 
   633 000038A7 89D0                <1> 	mov	eax, edx
   634                              <1> spte_2:
   635 000038A9 09CA                <1> 	or	edx, ecx
   636                              <1> 	; 23/06/2015
   637 000038AB 8913                <1> 	mov	[ebx], edx ; PTE value in EDX
   638                              <1> 	; 24/07/2015
   639 000038AD 5B                  <1> 	pop	ebx
   640 000038AE 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 000038AF 89DA                <1> 	mov	edx, ebx
   658 000038B1 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22  (12+10)
   659 000038B4 C1E202              <1> 	shl 	edx, 2 ; offset to page directory (1024*4)
   660 000038B7 01C2                <1> 	add	edx, eax ; page directory address (physical)
   661 000038B9 8B02                <1> 	mov	eax, [edx]
   662 000038BB A801                <1> 	test	al, PDE_A_PRESENT ; page table is present or not !
   663 000038BD 751F                <1> 	jnz	short gpte_retn
   664 000038BF F9                  <1> 	stc
   665                              <1> gpde_retn:	
   666 000038C0 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 000038C1 E8E9FFFFFF          <1> 	call 	get_pde
   688 000038C6 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 000038C8 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
   693 000038CC 89DA                <1> 	mov	edx, ebx
   694 000038CE C1EA0C              <1> 	shr	edx, PAGE_SHIFT ; 12
   695 000038D1 81E2FF030000        <1> 	and	edx, PTE_MASK	; 03FFh
   696                              <1> 			 ; clear higher 10 bits (PD bits)
   697 000038D7 C1E202              <1> 	shl	edx, 2 ; offset from start of page table (1024*4)
   698 000038DA 01C2                <1> 	add	edx, eax
   699 000038DC 8B02                <1> 	mov	eax, [edx]
   700                              <1> gpte_retn:
   701 000038DE 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 000038DF 56                  <1> 	push	esi
   724 000038E0 51                  <1> 	push	ecx
   725 000038E1 50                  <1> 	push	eax
   726 000038E2 89C6                <1> 	mov	esi, eax 
   727 000038E4 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 000038E6 890E                <1> 	mov	[esi], ecx ; 0 ; clear PDE 0
   731                              <1> dapd_0:
   732 000038E8 AD                  <1> 	lodsd
   733 000038E9 A801                <1> 	test	al, PDE_A_PRESENT ; bit 0, present flag (must be 1)
   734 000038EB 7409                <1> 	jz	short dapd_1	
   735 000038ED 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
   736 000038F1 E812000000          <1> 	call	deallocate_page_table			
   737                              <1> dapd_1:
   738 000038F6 41                  <1> 	inc	ecx ; page directory entry index
   739 000038F7 81F900040000        <1> 	cmp	ecx, PAGE_SIZE / 4 ; 1024
   740 000038FD 72E9                <1> 	jb	short dapd_0
   741                              <1> dapd_2:
   742 000038FF 58                  <1> 	pop	eax
   743 00003900 E879000000          <1> 	call	deallocate_page	; deallocate the page dir's itself
   744 00003905 59                  <1> 	pop	ecx
   745 00003906 5E                  <1> 	pop	esi
   746 00003907 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 00003908 56                  <1> 	push	esi
   770 00003909 57                  <1> 	push	edi
   771 0000390A 52                  <1> 	push	edx
   772 0000390B 50                  <1> 	push	eax ; *
   773 0000390C 89C6                <1> 	mov	esi, eax 
   774 0000390E 31FF                <1> 	xor	edi, edi ; 0
   775                              <1> dapt_0:
   776 00003910 AD                  <1> 	lodsd
   777 00003911 A801                <1> 	test	al, PTE_A_PRESENT ; bit 0, present flag (must be 1)
   778 00003913 7441                <1> 	jz	short dapt_1
   779                              <1> 	;
   780 00003915 A802                <1> 	test	al, PTE_A_WRITE   ; bit 1, writable (r/w) flag
   781                              <1> 				  ; (must be 1)
   782 00003917 754C                <1> 	jnz	short dapt_3
   783                              <1> 	; Read only -duplicated- page (belongs to a parent or a child)
   784 00003919 66A90002            <1>         test    ax, PTE_DUPLICATED ; Was this page duplicated 
   785                              <1> 				   ; as child's page ?
   786 0000391D 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 0000391F 53                  <1> 	push	ebx
   790 00003920 51                  <1> 	push	ecx
   791 00003921 66C1E102            <1> 	shl	cx, 2 ; *4 
   792 00003925 01CB                <1> 	add	ebx, ecx ; PDE offset (for the parent)
   793 00003927 8B0B                <1> 	mov	ecx, [ebx]
   794 00003929 F6C101              <1> 	test	cl, PDE_A_PRESENT ; present (valid) or not ?
   795 0000392C 7435                <1> 	jz	short dapt_2	; parent process does not use this page
   796 0000392E 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
   797                              <1> 	; EDI = page table entry index (0-1023)
   798 00003933 89FA                <1> 	mov	edx, edi 
   799 00003935 66C1E202            <1> 	shl	dx, 2 ; *4 
   800 00003939 01CA                <1> 	add	edx, ecx ; PTE offset (for the parent)
   801 0000393B 8B1A                <1> 	mov	ebx, [edx]
   802 0000393D F6C301              <1> 	test	bl, PTE_A_PRESENT ; present or not ?
   803 00003940 7421                <1> 	jz	short dapt_2	; parent process does not use this page
   804 00003942 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; Clear attribute bits 
   805 00003946 6681E300F0          <1> 	and	bx, PTE_A_CLEAR ; 0F000h ; Clear attribute bits
   806 0000394B 39D8                <1> 	cmp	eax, ebx	; parent's and child's pages are same ?
   807 0000394D 7514                <1> 	jne	short dapt_2	; not same page
   808                              <1> 				; deallocate the child's page
   809 0000394F 800A02              <1>         or      byte [edx], PTE_A_WRITE ; convert to writable page (parent)
   810 00003952 59                  <1> 	pop	ecx
   811 00003953 5B                  <1> 	pop	ebx
   812 00003954 EB14                <1> 	jmp	short dapt_4
   813                              <1> dapt_1:
   814 00003956 09C0                <1> 	or	eax, eax	; swapped page ?
   815 00003958 7417                <1> 	jz	short dapt_5	; no
   816                              <1> 				; yes
   817 0000395A D1E8                <1> 	shr	eax, 1
   818 0000395C E8C7040000          <1> 	call	unlink_swap_block ; Deallocate swapped page block
   819                              <1> 				  ; on the swap disk (or in file)
   820 00003961 EB0E                <1> 	jmp	short dapt_5
   821                              <1> dapt_2:
   822 00003963 59                  <1> 	pop	ecx
   823 00003964 5B                  <1> 	pop	ebx
   824                              <1> dapt_3:	
   825                              <1> 	;and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
   826 00003965 E814000000          <1> 	call	deallocate_page
   827                              <1> dapt_4:
   828 0000396A C746FC00000000      <1> 	mov	dword [esi-4], 0 ; clear/reset PTE (child, dupl. as parent)
   829                              <1> dapt_5:
   830 00003971 47                  <1> 	inc	edi ; page table entry index
   831 00003972 81FF00040000        <1> 	cmp	edi, PAGE_SIZE / 4 ; 1024
   832 00003978 7296                <1> 	jb	short dapt_0
   833                              <1> 	;
   834 0000397A 58                  <1> 	pop	eax ; *
   835 0000397B 5A                  <1> 	pop	edx
   836 0000397C 5F                  <1> 	pop	edi	
   837 0000397D 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 0000397E 53                  <1> 	push	ebx
   860 0000397F 52                  <1> 	push	edx
   861                              <1> 	;
   862 00003980 C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; shift physical address to 
   863                              <1> 				     ; 12 bits right
   864                              <1> 				     ; to get page number
   865 00003983 89C2                <1> 	mov	edx, eax
   866                              <1> 	; 15/09/2015
   867 00003985 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 00003988 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
   871                              <1> 				     ; (to get 32 bit position)			
   872                              <1> 	;
   873 0000398B BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address
   874 00003990 01D3                <1> 	add	ebx, edx
   875 00003992 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
   876                              <1> 				     ; (allocation bit position)	 
   877 00003995 3B15[04DD0000]      <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 0000399B 7306                <1> 	jnb	short dap_1	     ; no	
   881 0000399D 8915[04DD0000]      <1> 	mov	[next_page], edx     ; yes
   882                              <1> dap_1:
   883 000039A3 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 000039A6 FF05[00DD0000]      <1>         inc     dword [free_pages]
   891                              <1> dap_2:
   892 000039AC 5A                  <1> 	pop	edx
   893 000039AD 5B                  <1> 	pop	ebx
   894 000039AE 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 000039AF E8F2FDFFFF          <1> 	call	allocate_page
   978 000039B4 723E                <1> 	jc	short dpd_err
   979                              <1> 	;
   980 000039B6 55                  <1> 	push	ebp ; 20/07/2015
   981 000039B7 56                  <1> 	push	esi
   982 000039B8 57                  <1> 	push	edi
   983 000039B9 53                  <1> 	push	ebx
   984 000039BA 51                  <1> 	push	ecx
   985 000039BB 8B35[31F20000]      <1> 	mov	esi, [u.pgdir]
   986 000039C1 89C7                <1> 	mov	edi, eax
   987 000039C3 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 000039C4 A5                  <1> 	movsd
   992 000039C5 BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
   993 000039CA B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
   994                              <1> dpd_0:	
   995 000039CF AD                  <1> 	lodsd
   996                              <1> 	;or	eax, eax
   997                              <1>         ;jnz     short dpd_1
   998 000039D0 A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
   999 000039D2 7508                <1> 	jnz	short dpd_1
  1000                              <1>  	; 20/07/2015 (virtual address at the end of the page table)	
  1001 000039D4 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
  1002 000039DA EB0F                <1> 	jmp	short dpd_2
  1003                              <1> dpd_1:	
  1004 000039DC 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
  1005 000039E0 89C3                <1> 	mov	ebx, eax
  1006                              <1> 	; EBX = Parent's page table address
  1007 000039E2 E81F000000          <1> 	call	duplicate_page_table
  1008 000039E7 720C                <1> 	jc	short dpd_p_err
  1009                              <1> 	; EAX = Child's page table address
  1010 000039E9 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 000039EB AB                  <1> 	stosd
  1015 000039EC E2E1                <1> 	loop	dpd_0
  1016                              <1> 	;
  1017 000039EE 58                  <1> 	pop	eax  ; restore child's page directory address
  1018                              <1> dpd_3:
  1019 000039EF 59                  <1> 	pop	ecx
  1020 000039F0 5B                  <1> 	pop	ebx
  1021 000039F1 5F                  <1> 	pop	edi
  1022 000039F2 5E                  <1> 	pop	esi
  1023 000039F3 5D                  <1> 	pop	ebp ; 20/07/2015
  1024                              <1> dpd_err:
  1025 000039F4 C3                  <1> 	retn
  1026                              <1> dpd_p_err:
  1027                              <1> 	; release the allocated pages missing (recover free space)
  1028 000039F5 58                  <1> 	pop	eax  ; the new page directory address (physical)
  1029 000039F6 8B1D[31F20000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
  1030 000039FC E8DEFEFFFF          <1> 	call 	deallocate_page_dir
  1031 00003A01 29C0                <1> 	sub	eax, eax ; 0
  1032 00003A03 F9                  <1> 	stc
  1033 00003A04 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 00003A06 E89BFDFFFF          <1> 	call	allocate_page
  1057 00003A0B 726A                <1> 	jc	short dpt_err
  1058                              <1> 	;
  1059 00003A0D 50                  <1> 	push	eax ; *
  1060 00003A0E 56                  <1> 	push	esi
  1061 00003A0F 57                  <1> 	push	edi
  1062 00003A10 52                  <1> 	push	edx
  1063 00003A11 51                  <1> 	push	ecx
  1064                              <1> 	;
  1065 00003A12 89DE                <1> 	mov	esi, ebx
  1066 00003A14 89C7                <1> 	mov	edi, eax
  1067 00003A16 89C2                <1> 	mov	edx, eax
  1068 00003A18 81C200100000        <1> 	add	edx, PAGE_SIZE 	
  1069                              <1> dpt_0:
  1070 00003A1E AD                  <1> 	lodsd
  1071 00003A1F 21C0                <1> 	and	eax, eax
  1072 00003A21 7444                <1> 	jz	short dpt_3
  1073 00003A23 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
  1074 00003A25 7507                <1> 	jnz	short dpt_1
  1075                              <1> 	; 20/07/2015
  1076                              <1> 	; ebp = virtual (linear) address of the memory page
  1077 00003A27 E806050000          <1> 	call	reload_page ; 28/04/2015
  1078 00003A2C 7244                <1> 	jc	short dpt_p_err
  1079                              <1> dpt_1:
  1080                              <1> 	; 21/09/2015
  1081 00003A2E 89C1                <1> 	mov	ecx, eax
  1082 00003A30 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  1083 00003A34 F6C102              <1> 	test	cl, PTE_A_WRITE ; writable page ?
  1084 00003A37 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 00003A39 E868FDFFFF          <1> 	call	allocate_page
  1089 00003A3E 7232                <1> 	jc	short dpt_p_err
  1090 00003A40 57                  <1> 	push	edi
  1091 00003A41 56                  <1> 	push	esi
  1092 00003A42 89CE                <1> 	mov	esi, ecx
  1093 00003A44 89C7                <1> 	mov	edi, eax
  1094 00003A46 B900040000          <1> 	mov	ecx, PAGE_SIZE/4
  1095 00003A4B F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
  1096 00003A4D 5E                  <1> 	pop	esi
  1097 00003A4E 5F                  <1> 	pop	edi
  1098                              <1> 	; 
  1099 00003A4F 53                  <1> 	push	ebx
  1100 00003A50 50                  <1> 	push	eax
  1101                              <1> 	; 20/07/2015
  1102 00003A51 89EB                <1> 	mov	ebx, ebp
  1103                              <1> 	; ebx = virtual address of the memory page
  1104 00003A53 E88A030000          <1> 	call	add_to_swap_queue
  1105 00003A58 58                  <1> 	pop	eax
  1106 00003A59 5B                  <1> 	pop	ebx
  1107                              <1> 	; 21/09/2015
  1108 00003A5A 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
  1109                              <1> 		; user + writable + present page
  1110 00003A5C EB09                <1> 	jmp	short dpt_3
  1111                              <1> dpt_2:
  1112                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
  1113 00003A5E 0C05                <1> 	or	al, PTE_A_USER+PTE_A_PRESENT 
  1114                              <1> 		    ; (read only page!)
  1115 00003A60 8946FC              <1> 	mov	[esi-4], eax ; update parent's PTE
  1116 00003A63 660D0002            <1> 	or      ax, PTE_DUPLICATED  ; (read only page & duplicated PTE!)
  1117                              <1> dpt_3:
  1118 00003A67 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
  1119                              <1> 	;
  1120 00003A68 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
  1121                              <1> 	;
  1122 00003A6E 39D7                <1> 	cmp	edi, edx
  1123 00003A70 72AC                <1> 	jb	short dpt_0
  1124                              <1> dpt_p_err:
  1125 00003A72 59                  <1> 	pop	ecx
  1126 00003A73 5A                  <1> 	pop	edx
  1127 00003A74 5F                  <1> 	pop	edi
  1128 00003A75 5E                  <1> 	pop	esi
  1129 00003A76 58                  <1> 	pop	eax ; *
  1130                              <1> dpt_err:
  1131 00003A77 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 00003A78 53                  <1> 	push	ebx
  1274 00003A79 52                  <1> 	push	edx
  1275 00003A7A 51                  <1> 	push	ecx
  1276                              <1> 	;
  1277                              <1> 	; 21/09/2015 (debugging)
  1278 00003A7B FF05[41F20000]      <1> 	inc	dword [u.pfcount] ; page fault count for running process
  1279 00003A81 FF05[BCFF0000]      <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 00003A87 8A15[B4FF0000]      <1> 	mov	dl, [error_code]
  1283                              <1> 	;
  1284 00003A8D F6C201              <1> 	test	dl, 1	; page fault was caused by a non-present page
  1285                              <1> 			; sign
  1286 00003A90 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 00003A92 F6C202              <1> 	test	dl, 2	; page fault was caused by a page write
  1309                              <1> 			; sign
  1310 00003A95 0F84AB000000        <1>         jz      pfh_p_err
  1311                              <1> 	; 31/08/2015
  1312 00003A9B 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 00003A9E 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 00003AA4 0F20D3              <1> 	mov	ebx, cr2 ; CR2 contains the linear address 
  1320                              <1> 			 ; which has caused to page fault
  1321 00003AA7 E8A2000000          <1> 	call 	copy_page
  1322 00003AAC 0F828D000000        <1>         jc      pfh_im_err ; insufficient memory
  1323                              <1> 	;
  1324 00003AB2 EB7D                <1>         jmp     pfh_cpp_ok
  1325                              <1> 	;
  1326                              <1> pfh_alloc_np:
  1327 00003AB4 E8EDFCFFFF          <1> 	call	allocate_page	; (allocate a new page)
  1328 00003AB9 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 00003ABF 80E204              <1> 	and	dl, 4	; CPL = 3 ?
  1334 00003AC2 7505                <1> 	jnz	short pfh_um
  1335                              <1> 			; Page fault handler for kernel/system mode (CPL=0)		
  1336 00003AC4 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 00003AC7 EB06                <1> 	jmp	short pfh_get_pde
  1341                              <1> 	;
  1342                              <1> pfh_um:			; Page fault handler for user/appl. mode (CPL=3)
  1343 00003AC9 8B1D[31F20000]      <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 00003ACF 80CA03              <1> 	or	dl, 3	; USER + WRITE + PRESENT or SYSTEM + WRITE + PRESENT
  1348 00003AD2 0F20D1              <1> 	mov	ecx, cr2 ; CR2 contains the virtual address 
  1349                              <1> 			 ; which has been caused to page fault
  1350                              <1> 			 ;
  1351 00003AD5 C1E914              <1> 	shr	ecx, 20	 ; shift 20 bits right
  1352 00003AD8 80E1FC              <1> 	and	cl, 0FCh ; mask lower 2 bits to get PDE offset		
  1353                              <1> 	;
  1354 00003ADB 01CB                <1> 	add	ebx, ecx ; now, EBX points to the relevant page dir entry 
  1355 00003ADD 8B0B                <1> 	mov	ecx, [ebx] ; physical (base) address of the page table 	
  1356 00003ADF F6C101              <1> 	test	cl, 1	 ; check bit 0 is set (1) or not (0).
  1357 00003AE2 740B                <1> 	jz	short pfh_set_pde ; Page directory entry is not valid,
  1358                              <1> 			  	  ; set/validate page directory entry
  1359 00003AE4 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
  1360 00003AE9 89CB                <1> 	mov	ebx, ecx ; Physical address of the page table
  1361 00003AEB 89C1                <1> 	mov	ecx, eax ; new page address (physical) 	
  1362 00003AED 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 00003AEF 08D0                <1> 	or	al, dl	 ; lower 3 bits are used as U/S, R/W, P flags
  1368 00003AF1 8903                <1> 	mov	[ebx], eax ; Let's put the new page directory entry here !
  1369 00003AF3 30C0                <1> 	xor	al, al	 ; clear lower (3..8) bits
  1370 00003AF5 89C3                <1> 	mov	ebx, eax
  1371 00003AF7 E8AAFCFFFF          <1> 	call	allocate_page	 ; (allocate a new page)
  1372 00003AFC 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 00003AFE 89C1                <1> 	mov	ecx, eax
  1376 00003B00 E81BFDFFFF          <1> 	call	clear_page ; Clear page content
  1377                              <1> pfh_get_pte:
  1378 00003B05 0F20D0              <1> 	mov	eax, cr2 ; virtual address
  1379                              <1> 			 ; which has been caused to page fault
  1380 00003B08 89C7                <1> 	mov	edi, eax ; 20/07/2015
  1381 00003B0A C1E80C              <1> 	shr	eax, 12	 ; shift 12 bit right to get 
  1382                              <1> 			 ; higher 20 bits of the page fault address 
  1383 00003B0D 25FF030000          <1> 	and	eax, 3FFh ; mask PDE# bits, the result is PTE# (0 to 1023)
  1384 00003B12 C1E002              <1> 	shl	eax, 2	; shift 2 bits left to get PTE offset
  1385 00003B15 01C3                <1> 	add	ebx, eax ; now, EBX points to the relevant page table entry 
  1386 00003B17 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 00003B19 21C0                <1> 	and	eax, eax
  1389 00003B1B 7410                <1> 	jz	short pfh_gpte_1
  1390                              <1> 	; 20/07/2015
  1391 00003B1D 87D9                <1> 	xchg	ebx, ecx ; new page address (physical)
  1392 00003B1F 55                  <1> 	push	ebp ; 20/07/2015
  1393 00003B20 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 00003B23 E8B7000000          <1> 	call	swap_in
  1399 00003B28 5D                  <1> 	pop	ebp
  1400 00003B29 7210                <1> 	jc      short pfh_err_retn
  1401 00003B2B 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 00003B2D 08D1                <1> 	or	cl, dl	; lower 3 bits are used as U/S, R/W, P flags
  1406 00003B2F 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 00003B31 0F20D3              <1> 	mov	ebx, cr2
  1410 00003B34 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 00003B39 31C0                <1> 	xor	eax, eax  ; 0
  1419                              <1> 	;
  1420                              <1> pfh_err_retn:
  1421 00003B3B 59                  <1> 	pop	ecx
  1422 00003B3C 5A                  <1> 	pop	edx
  1423 00003B3D 5B                  <1> 	pop	ebx
  1424 00003B3E C3                  <1> 	retn 
  1425                              <1> 	
  1426                              <1> pfh_im_err:
  1427 00003B3F 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 00003B44 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 00003B46 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 00003B4B F9                  <1> 	stc
  1440 00003B4C 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 00003B4E 56                  <1> 	push	esi
  1470 00003B4F 57                  <1> 	push	edi
  1471                              <1> 	;push	ebx
  1472                              <1> 	;push	ecx
  1473 00003B50 31F6                <1> 	xor 	esi, esi
  1474 00003B52 C1EB0C              <1> 	shr	ebx, 12 ; shift 12 bits right to get PDE & PTE numbers
  1475 00003B55 89D9                <1> 	mov	ecx, ebx ; save page fault address (as 12 bit shifted)
  1476 00003B57 C1EB08              <1> 	shr	ebx, 8	 ; shift 8 bits right and then
  1477 00003B5A 80E3FC              <1> 	and	bl, 0FCh ; mask lower 2 bits to get PDE offset	
  1478 00003B5D 89DF                <1> 	mov 	edi, ebx ; save it for the parent of current process
  1479 00003B5F 031D[31F20000]      <1> 	add	ebx, [u.pgdir] ; EBX points to the relevant page dir entry 
  1480 00003B65 8B03                <1> 	mov	eax, [ebx] ; physical (base) address of the page table
  1481 00003B67 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits 	
  1482 00003B6B 89CB                <1> 	mov	ebx, ecx   ; (restore higher 20 bits of page fault address)
  1483 00003B6D 81E3FF030000        <1> 	and	ebx, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
  1484 00003B73 66C1E302            <1> 	shl	bx, 2	   ; shift 2 bits left to get PTE offset
  1485 00003B77 01C3                <1> 	add	ebx, eax   ; EBX points to the relevant page table entry 
  1486                              <1> 	; 07/09/2015
  1487 00003B79 66F7030002          <1>         test    word [ebx], PTE_DUPLICATED ; (Does current process share this
  1488                              <1> 				     ; read only page as a child process?)	
  1489 00003B7E 7509                <1> 	jnz	short cpp_0 ; yes
  1490 00003B80 8B0B                <1> 	mov	ecx, [ebx] ; PTE value
  1491 00003B82 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h  ; clear page attributes
  1492 00003B87 EB32                <1> 	jmp	short cpp_1
  1493                              <1> cpp_0:
  1494 00003B89 89FE                <1> 	mov	esi, edi
  1495 00003B8B 0335[35F20000]      <1> 	add	esi, [u.ppgdir] ; the parent's page directory entry
  1496 00003B91 8B06                <1> 	mov	eax, [esi] ; physical (base) address of the page table
  1497 00003B93 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  1498 00003B97 89CE                <1> 	mov	esi, ecx   ; (restore higher 20 bits of page fault address)	
  1499 00003B99 81E6FF030000        <1> 	and	esi, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
  1500 00003B9F 66C1E602            <1> 	shl	si, 2	   ; shift 2 bits left to get PTE offset
  1501 00003BA3 01C6                <1> 	add	esi, eax   ; EDX points to the relevant page table entry  	
  1502 00003BA5 8B0E                <1> 	mov	ecx, [esi] ; PTE value of the parent process
  1503                              <1> 	; 21/09/2015
  1504 00003BA7 8B03                <1> 	mov	eax, [ebx] ; PTE value of the child process
  1505 00003BA9 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear page attributes	
  1506                              <1> 	;
  1507 00003BAD F6C101              <1> 	test	cl, PTE_A_PRESENT ; is it a present/valid page ?
  1508 00003BB0 7424                <1> 	jz	short cpp_3 ; the parent's page is not same page  	
  1509                              <1> 	;
  1510 00003BB2 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h ; clear page attributes
  1511 00003BB7 39C8                <1> 	cmp	eax, ecx   ; Same page?	
  1512 00003BB9 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 00003BBB E8E6FBFFFF          <1> 	call	allocate_page
  1516 00003BC0 721A                <1> 	jc	short cpp_4 ; 'insufficient memory' error
  1517 00003BC2 21F6                <1> 	and	esi, esi    ; check ESI is valid or not
  1518 00003BC4 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 00003BC6 890E                <1> 	mov	[esi], ecx
  1524 00003BC8 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 00003BCB 89C7                <1> 	mov	edi, eax ; new page address of the child process
  1528                              <1> 	; 07/09/2015
  1529 00003BCD 89CE                <1> 	mov	esi, ecx ; the page address of the parent process
  1530 00003BCF B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
  1531 00003BD4 F3A5                <1> 	rep	movsd ; 31/08/2015
  1532                              <1> cpp_3:		
  1533 00003BD6 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER ; 1+2+4 = 7
  1534 00003BD8 8903                <1> 	mov	[ebx], eax ; Update PTE
  1535 00003BDA 28C0                <1> 	sub	al, al ; clear attributes
  1536                              <1> cpp_4:
  1537                              <1> 	;pop	ecx
  1538                              <1> 	;pop	ebx
  1539 00003BDC 5F                  <1> 	pop	edi
  1540 00003BDD 5E                  <1> 	pop	esi
  1541 00003BDE 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 00003BDF 833D[9EFF0000]00    <1>         cmp     dword [swp_drv], 0
  1731 00003BE6 7646                <1> 	jna	short swpin_dnp_err
  1732                              <1> 
  1733 00003BE8 3B05[A2FF0000]      <1> 	cmp	eax, [swpd_size]
  1734 00003BEE 734A                <1> 	jnb	short swpin_snp_err
  1735                              <1> 
  1736 00003BF0 56                  <1> 	push	esi
  1737 00003BF1 53                  <1> 	push	ebx
  1738 00003BF2 51                  <1> 	push	ecx
  1739 00003BF3 8B35[9EFF0000]      <1> 	mov	esi, [swp_drv]	
  1740 00003BF9 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 00003BFE 50                  <1> 	push	eax
  1751 00003BFF E8B2020000          <1> 	call	logical_disk_read
  1752 00003C04 58                  <1> 	pop	eax
  1753 00003C05 730C                <1> 	jnc	short swpin_read_ok
  1754                              <1> 	;
  1755 00003C07 B804000000          <1> 	mov	eax, SWP_DISK_READ_ERR ; drive not ready or read error
  1756 00003C0C A3[2DF20000]        <1> 	mov	[u.error], eax
  1757 00003C11 EB17                <1> 	jmp	short swpin_retn
  1758                              <1> 	;
  1759                              <1> swpin_read_ok:
  1760                              <1> 	; EAX = Offset address (logical sector number)
  1761 00003C13 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 00003C18 89EB                <1> 	mov	ebx, ebp ; virtual address (page fault address)
  1766 00003C1A 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
  1767 00003C1F 8A1D[27F20000]      <1> 	mov	bl, [u.uno] ; current process number
  1768                              <1> 	; EBX = Virtual address & process number combination
  1769 00003C25 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 00003C2A 59                  <1> 	pop	ecx
  1775 00003C2B 5B                  <1> 	pop	ebx
  1776 00003C2C 5E                  <1> 	pop	esi
  1777 00003C2D C3                  <1> 	retn
  1778                              <1> 
  1779                              <1> swpin_dnp_err:
  1780 00003C2E B805000000          <1> 	mov	eax, SWP_DISK_NOT_PRESENT_ERR
  1781                              <1> swpin_err_retn:
  1782 00003C33 A3[2DF20000]        <1> 	mov	[u.error], eax
  1783 00003C38 F9                  <1> 	stc
  1784 00003C39 C3                  <1> 	retn
  1785                              <1> 
  1786                              <1> swpin_snp_err:
  1787 00003C3A B806000000          <1> 	mov	eax, SWP_SECTOR_NOT_PRESENT_ERR
  1788 00003C3F 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 00003C41 66833D[9CFF0000]01  <1> 	cmp 	word [swpq_count], 1
  1813 00003C49 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 00003C4F 833D[A6FF0000]01    <1>         cmp     dword [swpd_free], 1
  1819 00003C56 0F828F000000        <1>         jc      swpout_nfspc_err ; 'no free space on swap disk'
  1820                              <1> 
  1821 00003C5C 53                  <1> 	push	ebx ; *
  1822                              <1> swpout_1:
  1823                              <1> 	; 10/06/2016
  1824 00003C5D 31DB                <1> 	xor	ebx, ebx ; shift the queue and return a PTE value
  1825 00003C5F E8A1000000          <1> 	call	swap_queue_shift
  1826 00003C64 21C0                <1> 	and	eax, eax	; 0 = empty queue (improper entries)
  1827 00003C66 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 00003C6C 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 00003C70 52                  <1> 	push	edx ; **
  1839                              <1> 
  1840                              <1> 	; 07/06/2016
  1841 00003C71 803D[7FEA0000]00    <1> 	cmp	byte [timer_events], 0 
  1842 00003C78 762F                <1> 	jna	short swpout_2
  1843                              <1> 	;
  1844 00003C7A 8A15[7FEA0000]      <1> 	mov	dl, [timer_events]
  1845                              <1> 
  1846 00003C80 51                  <1> 	push	ecx ; ***
  1847 00003C81 53                  <1> 	push	ebx ; ****
  1848 00003C82 BB[9CFE0000]        <1> 	mov	ebx, timer_set ; beginning address of timer event
  1849                              <1> 			       ; structures 
  1850                              <1> swpout_timer_page_1:
  1851 00003C87 8A0B                <1> 	mov	cl, [ebx]
  1852 00003C89 08C9                <1> 	or	cl, cl ; 0 = free, >0 = process number
  1853 00003C8B 7415                <1> 	jz	short swpout_timer_page_3
  1854 00003C8D 8B4B0C              <1> 	mov	ecx, [ebx+12] ; response (signal return) address
  1855 00003C90 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 00003C95 39C8                <1> 	cmp	eax, ecx
  1859 00003C97 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 00003C99 5B                  <1> 	pop	ebx ; ****
  1871 00003C9A 59                  <1> 	pop	ecx ; ***
  1872 00003C9B 5A                  <1> 	pop	edx ; **
  1873 00003C9C 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 00003C9E FECA                <1> 	dec	dl
  1878 00003CA0 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 00003CA2 83C310              <1> 	add	ebx, 16
  1883 00003CA5 EBE0                <1> 	jmp	short swpout_timer_page_1	
  1884                              <1> 
  1885                              <1> swpout_timer_page_4:
  1886 00003CA7 5B                  <1> 	pop	ebx ; ****
  1887 00003CA8 59                  <1> 	pop	ecx ; ***
  1888                              <1> swpout_2:
  1889 00003CA9 89DA                <1> 	mov	edx, ebx	       ; Page table entry address	
  1890 00003CAB 89C3                <1> 	mov	ebx, eax	       ; Buffer (Page) Address				
  1891                              <1> 	;
  1892 00003CAD E8A9010000          <1> 	call	link_swap_block
  1893 00003CB2 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 00003CB4 5A                  <1> 	pop	edx ; **
  1897 00003CB5 5B                  <1> 	pop	ebx ; *
  1898 00003CB6 EB33                <1> 	jmp	short swpout_nfspc_err 
  1899                              <1> swpout_3:
  1900 00003CB8 A900000080          <1> 	test	eax, 80000000h ; test bit 31 (this may not be needed!)
  1901 00003CBD 752C                <1> 	jnz	short swpout_nfspc_err  ; 10/06/2016 (bit 31 = 1 !)
  1902                              <1> 	;	
  1903 00003CBF 56                  <1> 	push	esi ; **
  1904 00003CC0 51                  <1> 	push	ecx ; ***
  1905 00003CC1 50                  <1> 	push	eax ; sector address ; (31 bit !, bit 31 = 0)
  1906 00003CC2 8B35[9EFF0000]      <1> 	mov	esi, [swp_drv]	
  1907 00003CC8 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 00003CCD E8E5010000          <1> 	call	logical_disk_write
  1919                              <1> 	; edx = PTE address
  1920 00003CD2 59                  <1> 	pop	ecx ; sector address	
  1921 00003CD3 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 00003CD5 B808000000          <1> 	mov	eax, SWP_DISK_WRITE_ERR ; drive not ready or write error
  1926 00003CDA A3[2DF20000]        <1> 	mov	[u.error], eax
  1927 00003CDF 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 00003CE1 D1E1                <1> 	shl 	ecx, 1  ; 31 bit sector address from bit 1 to bit 31 
  1934 00003CE3 890A                <1> 	mov 	[edx], ecx 
  1935                              <1> 		; bit 0 = 0 (swapped page)
  1936 00003CE5 89D8                <1> 	mov	eax, ebx
  1937                              <1> swpout_retn:
  1938 00003CE7 59                  <1> 	pop	ecx ; ***
  1939 00003CE8 5E                  <1> 	pop	esi ; **
  1940 00003CE9 5B                  <1> 	pop	ebx ; *
  1941 00003CEA 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 00003CEB B807000000          <1> 	mov	eax, SWP_NO_FREE_SPACE_ERR ; no free space
  1948                              <1> swpout_err_retn:
  1949 00003CF0 A3[2DF20000]        <1> 	mov	[u.error], eax
  1950                              <1> 	;stc
  1951 00003CF5 C3                  <1> 	retn
  1952                              <1> swpout_npts_err:
  1953 00003CF6 B809000000          <1> 	mov	eax, SWP_NO_PAGE_TO_SWAP_ERR
  1954 00003CFB 5B                  <1> 	pop	ebx
  1955 00003CFC EBF2                <1> 	jmp	short swpout_err_retn
  1956                              <1> swpout_im_err:
  1957 00003CFE B801000000          <1> 	mov	eax, ERR_MINOR_IM ; insufficient (out of) memory
  1958 00003D03 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 00003D05 0FB705[9CFF0000]    <1> 	movzx   eax, word [swpq_count]  ; Max. 1024
  2011 00003D0C 6621C0              <1> 	and	ax, ax
  2012 00003D0F 7433                <1> 	jz	short swpqs_retn
  2013 00003D11 57                  <1> 	push	edi
  2014 00003D12 56                  <1> 	push	esi
  2015 00003D13 51                  <1> 	push	ecx
  2016 00003D14 53                  <1> 	push	ebx
  2017 00003D15 BE00E00800          <1> 	mov	esi, swap_queue
  2018 00003D1A 89C1                <1> 	mov	ecx, eax
  2019 00003D1C 09DB                <1> 	or	ebx, ebx
  2020 00003D1E 7425                <1> 	jz	short swpqs_7
  2021                              <1> swpqs_1:
  2022 00003D20 AD                  <1> 	lodsd
  2023 00003D21 39D8                <1> 	cmp	eax, ebx
  2024 00003D23 7406                <1> 	je	short swpqs_2
  2025 00003D25 E2F9                <1> 	loop	swpqs_1
  2026                              <1> 	; 10/06/2016
  2027 00003D27 29C0                <1> 	sub	eax, eax 
  2028 00003D29 EB15                <1> 	jmp	short swpqs_6
  2029                              <1> swpqs_2:
  2030 00003D2B 89F7                <1> 	mov	edi, esi
  2031 00003D2D 83EF04              <1> 	sub 	edi, 4
  2032                              <1> swpqs_3:
  2033 00003D30 66FF0D[9CFF0000]    <1> 	dec	word [swpq_count]
  2034 00003D37 7403                <1> 	jz	short swpqs_5
  2035                              <1> swpqs_4:
  2036 00003D39 49                  <1> 	dec 	ecx
  2037 00003D3A F3A5                <1> 	rep	movsd	; shift up (to the head)
  2038                              <1> swpqs_5:
  2039 00003D3C 31C0                <1> 	xor	eax, eax
  2040 00003D3E 8907                <1> 	mov	[edi], eax
  2041                              <1> swpqs_6:
  2042 00003D40 5B                  <1> 	pop	ebx
  2043                              <1> swpqs_14:
  2044 00003D41 59                  <1> 	pop	ecx
  2045 00003D42 5E                  <1> 	pop	esi
  2046 00003D43 5F                  <1> 	pop	edi
  2047                              <1> swpqs_retn:
  2048 00003D44 C3                  <1> 	retn		
  2049                              <1> swpqs_7:
  2050 00003D45 89F7                <1> 	mov	edi, esi ; head
  2051 00003D47 AD                  <1> 	lodsd
  2052                              <1> 	; 20/07/2015
  2053 00003D48 89C3                <1> 	mov	ebx, eax
  2054 00003D4A 81E300F0FFFF        <1> 	and	ebx, ~PAGE_OFF ; ~0FFFh 
  2055                              <1> 		      ; ebx = virtual address (at page boundary)	
  2056 00003D50 25FF0F0000          <1> 	and	eax, PAGE_OFF ; 0FFFh
  2057                              <1> 		      ; ax = process number (1 to 4095)
  2058 00003D55 3A05[27F20000]      <1> 	cmp	al, [u.uno]
  2059                              <1> 		; Max. 16 (nproc) processes for Retro UNIX 386 v1
  2060 00003D5B 7507                <1> 	jne	short swpqs_8
  2061 00003D5D A1[31F20000]        <1> 	mov	eax, [u.pgdir]
  2062 00003D62 EB28                <1> 	jmp	short swpqs_9
  2063                              <1> swpqs_8:
  2064                              <1> 	; 09/06/2016
  2065 00003D64 80B8[49EF0000]00    <1> 	cmp	byte [eax+p.stat-1], 0
  2066 00003D6B 76C3                <1> 	jna	short swpqs_3     ; free (or terminated) process
  2067 00003D6D 80B8[49EF0000]02    <1> 	cmp	byte [eax+p.stat-1], 2 ; waiting
  2068 00003D74 77BA                <1> 	ja	short swpqs_3 	  ; zombie (3) or undefined ?	
  2069                              <1> 
  2070                              <1> 	;shl	ax, 2
  2071 00003D76 C0E002              <1> 	shl	al, 2
  2072 00003D79 8B80[56EF0000]      <1> 	mov 	eax, [eax+p.upage-4]
  2073 00003D7F 09C0                <1> 	or	eax, eax
  2074 00003D81 74AD                <1> 	jz	short swpqs_3 ; invalid upage
  2075 00003D83 83C061              <1> 	add	eax, u.pgdir - user
  2076                              <1> 			 ; u.pgdir value for the process
  2077                              <1> 			 ; is in [eax]
  2078 00003D86 8B00                <1> 	mov	eax, [eax]
  2079 00003D88 21C0                <1> 	and	eax, eax
  2080 00003D8A 74A4                <1> 	jz	short swpqs_3 ; invalid page directory
  2081                              <1> swpqs_9:
  2082 00003D8C 52                  <1> 	push	edx
  2083                              <1> 	; eax = page directory
  2084                              <1> 	; ebx = virtual address
  2085 00003D8D E82FFBFFFF          <1> 	call	get_pte
  2086 00003D92 89D3                <1> 	mov	ebx, edx	; PTE address
  2087 00003D94 5A                  <1> 	pop	edx
  2088                              <1> 	; 10/06/2016
  2089 00003D95 723B                <1> 	jc	short swpqs_13 ; empty PDE
  2090                              <1> 	; EAX = PTE value
  2091 00003D97 A801                <1> 	test	al, PTE_A_PRESENT ; bit 0 = 1
  2092 00003D99 7437                <1> 	jz	short swpqs_13  ; Drop non-present page
  2093                              <1> 			        ; from the queue (head)
  2094 00003D9B A802                <1> 	test	al, PTE_A_WRITE	; bit 1 = 0 (read only)
  2095 00003D9D 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 00003D9F 0FBAF005            <1>         btr     eax, PTE_A_ACCESS_BIT ; reset 'accessed' bit
  2101 00003DA3 7211                <1> 	jc	short swpqs_11  ; accessed page
  2102                              <1> 
  2103 00003DA5 49                  <1> 	dec	ecx
  2104 00003DA6 66890D[9CFF0000]    <1> 	mov	[swpq_count], cx
  2105 00003DAD 7402                <1>         jz      short swpqs_10
  2106                              <1> 		; esi = head + 4
  2107                              <1> 		; edi = head
  2108 00003DAF F3A5                <1> 	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
  2109                              <1> swpqs_10:
  2110 00003DB1 890F                <1> 	mov	[edi], ecx ; 0
  2111 00003DB3 59                  <1> 	pop	ecx       	;  EBX (input) in stack
  2112                              <1> 				;  EBX = PTE address	
  2113 00003DB4 EB8B                <1> 	jmp	short swpqs_14 
  2114                              <1> 
  2115                              <1> swpqs_11:
  2116 00003DB6 8903                <1> 	mov	[ebx], eax     ; save changed attribute
  2117                              <1> 	; Rotation (head -> tail)
  2118 00003DB8 49                  <1> 	dec	ecx     ; entry count -> last entry number		
  2119 00003DB9 74F6                <1> 	jz	short swpqs_10
  2120                              <1> 		; esi = head + 4
  2121                              <1> 		; edi = head
  2122 00003DBB 8B07                <1> 	mov	eax, [edi] ; 20/07/2015
  2123 00003DBD F3A5                <1> 	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
  2124 00003DBF 8907                <1> 	mov	[edi], eax ; head -> tail ; [k] = [1]
  2125                              <1> 
  2126 00003DC1 668B0D[9CFF0000]    <1> 	mov	cx, [swpq_count]
  2127                              <1> 
  2128                              <1> swpqs_12:
  2129 00003DC8 BE00E00800          <1> 	mov	esi, swap_queue ; head
  2130 00003DCD E973FFFFFF          <1>         jmp     swpqs_7
  2131                              <1> 
  2132                              <1> swpqs_13:
  2133 00003DD2 49                  <1> 	dec	ecx
  2134 00003DD3 66890D[9CFF0000]    <1> 	mov	[swpq_count], cx
  2135 00003DDA 0F845CFFFFFF        <1>         jz      swpqs_5
  2136 00003DE0 EBE6                <1> 	jmp	short swpqs_12
  2137                              <1> 
  2138                              <1> add_to_swap_queue:
  2139                              <1> ; temporary - 16/09/2015
  2140 00003DE2 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 00003DE3 53                  <1> 	push	ebx
  2160 00003DE4 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
  2161 00003DE9 8A1D[27F20000]      <1> 	mov	bl, [u.uno] ; current process number
  2162 00003DEF 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 00003DF4 0FB705[9CFF0000]    <1> 	movzx	eax, word [swpq_count]
  2166 00003DFB 663D0004            <1> 	cmp	ax, 1024
  2167 00003DFF 7205                <1> 	jb	short atsq_1
  2168 00003E01 6629C0              <1> 	sub	ax, ax
  2169 00003E04 5B                  <1> 	pop	ebx
  2170 00003E05 C3                  <1> 	retn
  2171                              <1> atsq_1:
  2172 00003E06 56                  <1> 	push	esi
  2173 00003E07 BE00E00800          <1> 	mov	esi, swap_queue
  2174 00003E0C 6621C0              <1> 	and	ax, ax
  2175 00003E0F 740A                <1> 	jz	short atsq_2
  2176 00003E11 66C1E002            <1> 	shl	ax, 2	; convert to offset
  2177 00003E15 01C6                <1> 	add	esi, eax
  2178 00003E17 66C1E802            <1> 	shr	ax, 2
  2179                              <1> atsq_2:
  2180 00003E1B 6640                <1> 	inc	ax
  2181 00003E1D 891E                <1> 	mov	[esi], ebx ; Virtual address + [u.uno] combination
  2182 00003E1F 66A3[9CFF0000]      <1> 	mov	[swpq_count], ax
  2183 00003E25 5E                  <1> 	pop	esi
  2184 00003E26 5B                  <1> 	pop	ebx
  2185 00003E27 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 00003E28 53                  <1> 	push	ebx
  2203 00003E29 52                  <1> 	push	edx
  2204                              <1> 	;
  2205 00003E2A 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 00003E2D 89C2                <1> 	mov	edx, eax
  2209                              <1> 	; 15/09/2015
  2210 00003E2F 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 00003E32 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2214                              <1> 				     ; (to get 32 bit position)			
  2215                              <1> 	;
  2216 00003E35 BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table address
  2217 00003E3A 01D3                <1> 	add	ebx, edx
  2218 00003E3C 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
  2219                              <1> 				     ; (allocation bit position)	 
  2220 00003E3F 3B05[AAFF0000]      <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 00003E45 7305                <1> 	jnb	short uswpbl_1	     ; no	
  2224 00003E47 A3[AAFF0000]        <1> 	mov	[swpd_next], eax     ; yes	
  2225                              <1> uswpbl_1:
  2226 00003E4C 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 00003E4F F5                  <1> 	cmc			     ; complement carry flag	
  2230 00003E50 7206                <1> 	jc	short uswpbl_2	     ; do not increase swfd_free count
  2231                              <1> 				     ; if the block is already deallocated
  2232                              <1> 				     ; before.	
  2233 00003E52 FF05[A6FF0000]      <1>         inc     dword [swpd_free]
  2234                              <1> uswpbl_2:
  2235 00003E58 5A                  <1> 	pop	edx
  2236 00003E59 5B                  <1> 	pop	ebx
  2237 00003E5A 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 00003E5B 53                  <1> 	push	ebx
  2262 00003E5C 51                  <1> 	push	ecx
  2263                              <1> 	;
  2264 00003E5D BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table offset
  2265 00003E62 89D9                <1> 	mov	ecx, ebx
  2266 00003E64 031D[AAFF0000]      <1> 	add	ebx, [swpd_next] ; Free block searching starts from here
  2267                              <1> 				 ; next_free_swap_block >> 5
  2268 00003E6A 030D[AEFF0000]      <1> 	add	ecx, [swpd_last] ; Free block searching ends here
  2269                              <1> 				 ; (total_swap_blocks - 1) >> 5
  2270                              <1> lswbl_scan:
  2271 00003E70 39CB                <1> 	cmp	ebx, ecx
  2272 00003E72 770A                <1> 	ja	short lswbl_notfound
  2273                              <1> 	;
  2274 00003E74 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 00003E77 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 00003E79 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 00003E7C EBF2                <1> 	jmp    	short lswbl_scan
  2291                              <1> 	;
  2292                              <1> lswbl_notfound:	
  2293 00003E7E 81E900000D00        <1> 	sub	ecx, swap_alloc_table
  2294 00003E84 890D[AAFF0000]      <1> 	mov	[swpd_next], ecx ; next/first free page = last page 
  2295                              <1> 				 ; (unlink_swap_block procedure will change it)
  2296 00003E8A 31C0                <1> 	xor	eax, eax
  2297 00003E8C A3[A6FF0000]        <1> 	mov	[swpd_free], eax
  2298 00003E91 F9                  <1> 	stc
  2299                              <1> lswbl_ok:
  2300 00003E92 59                  <1> 	pop	ecx
  2301 00003E93 5B                  <1> 	pop	ebx
  2302 00003E94 C3                  <1> 	retn
  2303                              <1> 	;
  2304                              <1> ;out_of_swpspc:
  2305                              <1> ;	stc
  2306                              <1> ;	retn
  2307                              <1> 
  2308                              <1> lswbl_found:
  2309 00003E95 89D9                <1> 	mov	ecx, ebx
  2310 00003E97 81E900000D00        <1> 	sub	ecx, swap_alloc_table
  2311 00003E9D 890D[AAFF0000]      <1> 	mov	[swpd_next], ecx ; Set first free block searching start
  2312                              <1> 				 ; address/offset (to the next)
  2313 00003EA3 FF0D[A6FF0000]      <1>         dec     dword [swpd_free] ; 1 block has been allocated (X = X-1) 
  2314                              <1> 	;
  2315 00003EA9 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 00003EAC C1E105              <1> 	shl	ecx, 5		 ; (block offset * 32) + block index
  2322 00003EAF 01C8                <1> 	add	eax, ecx	 ; = block number
  2323 00003EB1 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 00003EB4 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 00003EB6 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 00003EB7 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 00003EB8 81C300004000        <1> 	add	ebx, CORE ; 18/10/2015
  2388                              <1> get_physical_addr_x: ; 27/05/2016
  2389 00003EBE A1[31F20000]        <1> 	mov	eax, [u.pgdir]
  2390 00003EC3 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 00003EC8 731C                <1> 	jnc	short gpa_1
  2397                              <1> 	;
  2398 00003ECA E8D7F8FFFF          <1> 	call	allocate_page
  2399 00003ECF 725B                <1> 	jc	short gpa_im_err  ; 'insufficient memory' error
  2400                              <1> gpa_0:
  2401 00003ED1 E84AF9FFFF          <1> 	call 	clear_page
  2402                              <1> 	; EAX = Physical (base) address of the allocated (new) page
  2403 00003ED6 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 00003ED8 8902                <1> 	mov	[edx], eax ; Let's put the new page directory entry here !
  2407 00003EDA A1[31F20000]        <1> 	mov	eax, [u.pgdir]	
  2408 00003EDF E8DDF9FFFF          <1> 	call	get_pte
  2409 00003EE4 7246                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
  2410                              <1> gpa_1:
  2411                              <1> 	; EAX = PTE value, EDX = PTE address
  2412 00003EE6 A801                <1> 	test 	al, PTE_A_PRESENT
  2413 00003EE8 751A                <1> 	jnz	short gpa_3
  2414 00003EEA 09C0                <1> 	or	eax, eax
  2415 00003EEC 7430                <1> 	jz	short gpa_4  ; Allocate a new page
  2416                              <1> 	; 20/07/2015
  2417 00003EEE 55                  <1> 	push	ebp
  2418 00003EEF 89DD                <1> 	mov	ebp, ebx ; virtual (linear) address
  2419                              <1> 	; reload swapped page
  2420 00003EF1 E83C000000          <1> 	call	reload_page ; 28/04/2015
  2421 00003EF6 5D                  <1> 	pop	ebp
  2422 00003EF7 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 00003EF9 50                  <1> 	push	eax 
  2428                              <1> 	; EBX = virtual address
  2429 00003EFA E8E3FEFFFF          <1> 	call 	add_to_swap_queue
  2430 00003EFF 58                  <1> 	pop	eax
  2431                              <1> 		; PTE address in EDX
  2432                              <1> 		; virtual address in EBX
  2433                              <1> 	; EAX = memory page address
  2434 00003F00 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 00003F02 8902                <1> 	mov	[edx], eax  ; Update PTE value
  2439                              <1> gpa_3:
  2440                              <1> 	; 18/10/2015
  2441 00003F04 89D9                <1> 	mov	ecx, ebx
  2442 00003F06 81E1FF0F0000        <1> 	and	ecx, PAGE_OFF
  2443 00003F0C 89C2                <1> 	mov 	edx, eax
  2444 00003F0E 662500F0            <1> 	and	ax, PTE_A_CLEAR
  2445 00003F12 01C8                <1> 	add	eax, ecx
  2446 00003F14 F7D9                <1> 	neg	ecx ; 1 -> -1 (0FFFFFFFFh), 4095 (0FFFh) -> -4095
  2447 00003F16 81C100100000        <1> 	add	ecx, PAGE_SIZE
  2448 00003F1C F8                  <1> 	clc
  2449                              <1> gpa_retn:
  2450 00003F1D C3                  <1> 	retn	
  2451                              <1> gpa_4:	
  2452 00003F1E E883F8FFFF          <1> 	call	allocate_page
  2453 00003F23 7207                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
  2454 00003F25 E8F6F8FFFF          <1> 	call	clear_page
  2455 00003F2A EBCD                <1> 	jmp	short gpa_2
  2456                              <1> 
  2457                              <1> gpa_im_err:	
  2458 00003F2C B801000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
  2459                              <1> 				  ; Major error = 0 (No protection fault)	
  2460 00003F31 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 00003F32 D1E8                <1> 	shr	eax, 1   ; Convert PTE value to swap disk address 
  2480 00003F34 53                  <1> 	push	ebx      ;
  2481 00003F35 89C3                <1> 	mov	ebx, eax ; Swap disk (offset) address	
  2482 00003F37 E86AF8FFFF          <1> 	call	allocate_page
  2483 00003F3C 720C                <1> 	jc	short rlp_im_err
  2484 00003F3E 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 00003F3F E89BFCFFFF          <1> 	call	swap_in
  2489 00003F44 720B                <1> 	jc	short rlp_swp_err  ; (swap disk/file read error)
  2490 00003F46 89D8                <1> 	mov	eax, ebx	
  2491                              <1> rlp_retn:
  2492 00003F48 5B                  <1> 	pop	ebx
  2493 00003F49 C3                  <1> 	retn
  2494                              <1> 	
  2495                              <1> rlp_im_err:	
  2496 00003F4A B801000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
  2497                              <1> 				  ; Major error = 0 (No protection fault)	
  2498 00003F4F EBF7                <1> 	jmp	short rlp_retn
  2499                              <1> 
  2500                              <1> rlp_swp_err:
  2501 00003F51 B804000000          <1> 	mov 	eax, SWP_DISK_READ_ERR ; Swap disk read error !
  2502 00003F56 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 00003F58 E849F8FFFF          <1> 	call	allocate_page
  2524 00003F5D 723E                <1> 	jc	short cpd_err
  2525                              <1> 	;
  2526 00003F5F 55                  <1> 	push	ebp ; 20/07/2015
  2527 00003F60 56                  <1> 	push	esi
  2528 00003F61 57                  <1> 	push	edi
  2529 00003F62 53                  <1> 	push	ebx
  2530 00003F63 51                  <1> 	push	ecx
  2531 00003F64 8B35[31F20000]      <1> 	mov	esi, [u.pgdir]
  2532 00003F6A 89C7                <1> 	mov	edi, eax
  2533 00003F6C 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 00003F6D A5                  <1> 	movsd
  2537 00003F6E BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
  2538 00003F73 B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
  2539                              <1> cpd_0:	
  2540 00003F78 AD                  <1> 	lodsd
  2541                              <1> 	;or	eax, eax
  2542                              <1>         ;jnz     short cpd_1
  2543 00003F79 A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
  2544 00003F7B 7508                <1> 	jnz	short cpd_1
  2545                              <1>  	; (virtual address at the end of the page table)	
  2546 00003F7D 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
  2547 00003F83 EB0F                <1> 	jmp	short cpd_2
  2548                              <1> cpd_1:	
  2549 00003F85 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
  2550 00003F89 89C3                <1> 	mov	ebx, eax
  2551                              <1> 	; EBX = Parent's page table address
  2552 00003F8B E81F000000          <1> 	call	copy_page_table
  2553 00003F90 720C                <1> 	jc	short cpd_p_err
  2554                              <1> 	; EAX = Child's page table address
  2555 00003F92 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 00003F94 AB                  <1> 	stosd
  2560 00003F95 E2E1                <1> 	loop	cpd_0
  2561                              <1> 	;
  2562 00003F97 58                  <1> 	pop	eax  ; restore child's page directory address
  2563                              <1> cpd_3:
  2564 00003F98 59                  <1> 	pop	ecx
  2565 00003F99 5B                  <1> 	pop	ebx
  2566 00003F9A 5F                  <1> 	pop	edi
  2567 00003F9B 5E                  <1> 	pop	esi
  2568 00003F9C 5D                  <1> 	pop	ebp
  2569                              <1> cpd_err:
  2570 00003F9D C3                  <1> 	retn
  2571                              <1> cpd_p_err:
  2572                              <1> 	; release the allocated pages missing (recover free space)
  2573 00003F9E 58                  <1> 	pop	eax  ; the new page directory address (physical)
  2574 00003F9F 8B1D[31F20000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
  2575 00003FA5 E835F9FFFF          <1> 	call 	deallocate_page_dir
  2576 00003FAA 29C0                <1> 	sub	eax, eax ; 0
  2577 00003FAC F9                  <1> 	stc
  2578 00003FAD 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 00003FAF E8F2F7FFFF          <1> 	call	allocate_page
  2596 00003FB4 725A                <1> 	jc	short cpt_err
  2597                              <1> 	;
  2598 00003FB6 50                  <1> 	push	eax ; *
  2599                              <1> 	;push 	ebx
  2600 00003FB7 56                  <1> 	push	esi
  2601 00003FB8 57                  <1> 	push	edi
  2602 00003FB9 52                  <1> 	push	edx
  2603 00003FBA 51                  <1> 	push	ecx
  2604                              <1> 	;
  2605 00003FBB 89DE                <1> 	mov	esi, ebx
  2606 00003FBD 89C7                <1> 	mov	edi, eax
  2607 00003FBF 89C2                <1> 	mov	edx, eax
  2608 00003FC1 81C200100000        <1> 	add	edx, PAGE_SIZE 	
  2609                              <1> cpt_0:
  2610 00003FC7 AD                  <1> 	lodsd
  2611 00003FC8 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
  2612 00003FCA 750B                <1> 	jnz	short cpt_1
  2613 00003FCC 21C0                <1> 	and	eax, eax
  2614 00003FCE 7430                <1> 	jz	short cpt_2
  2615                              <1> 	; ebp = virtual (linear) address of the memory page
  2616 00003FD0 E85DFFFFFF          <1> 	call	reload_page ; 28/04/2015
  2617 00003FD5 7234                <1> 	jc	short cpt_p_err
  2618                              <1> cpt_1:
  2619 00003FD7 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  2620 00003FDB 89C1                <1> 	mov	ecx, eax
  2621                              <1> 	; Allocate a new page for the child process
  2622 00003FDD E8C4F7FFFF          <1> 	call	allocate_page
  2623 00003FE2 7227                <1> 	jc	short cpt_p_err
  2624 00003FE4 57                  <1> 	push	edi
  2625 00003FE5 56                  <1> 	push	esi
  2626 00003FE6 89CE                <1> 	mov	esi, ecx
  2627 00003FE8 89C7                <1> 	mov	edi, eax
  2628 00003FEA B900040000          <1> 	mov	ecx, PAGE_SIZE/4
  2629 00003FEF F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
  2630 00003FF1 5E                  <1> 	pop	esi
  2631 00003FF2 5F                  <1> 	pop	edi
  2632                              <1> 	; 
  2633 00003FF3 53                  <1> 	push	ebx
  2634 00003FF4 50                  <1> 	push	eax
  2635 00003FF5 89EB                <1> 	mov	ebx, ebp
  2636                              <1> 	; ebx = virtual address of the memory page
  2637 00003FF7 E8E6FDFFFF          <1> 	call	add_to_swap_queue
  2638 00003FFC 58                  <1> 	pop	eax
  2639 00003FFD 5B                  <1> 	pop	ebx
  2640                              <1> 	;
  2641                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
  2642 00003FFE 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
  2643                              <1> cpt_2:
  2644 00004000 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
  2645                              <1> 	;
  2646 00004001 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
  2647                              <1> 	;
  2648 00004007 39D7                <1> 	cmp	edi, edx
  2649 00004009 72BC                <1> 	jb	short cpt_0
  2650                              <1> cpt_p_err:
  2651 0000400B 59                  <1> 	pop	ecx
  2652 0000400C 5A                  <1> 	pop	edx
  2653 0000400D 5F                  <1> 	pop	edi
  2654 0000400E 5E                  <1> 	pop	esi
  2655                              <1> 	;pop	ebx
  2656 0000400F 58                  <1> 	pop	eax ; *
  2657                              <1> cpt_err:
  2658 00004010 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 00004011 52                  <1> 	push	edx ; *
  2702 00004012 BAFF0F0000          <1> 	mov	edx, PAGE_SIZE - 1   ; 4095
  2703 00004017 01D1                <1> 	add	ecx, edx
  2704 00004019 01D0                <1> 	add	eax, edx
  2705 0000401B C1E90C              <1> 	shr	ecx, PAGE_SHIFT	     ; 12
  2706                              <1> 
  2707                              <1> 	; ECX = number of contiguous pages to be allocated
  2708 0000401E 8B15[00DD0000]      <1> 	mov	edx, [free_pages]
  2709 00004024 39D1                <1> 	cmp	ecx, edx
  2710 00004026 7775                <1> 	ja	short amb_6
  2711                              <1> 
  2712 00004028 C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; 12
  2713                              <1> 
  2714 0000402B 89C2                <1> 	mov	edx, eax 	     ; page number
  2715 0000402D 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 00004030 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2719                              <1> 				     ; (to get 32 bit position)	
  2720 00004033 53                  <1> 	push	ebx ; **
  2721                              <1> amb_0:
  2722 00004034 890D[B4E90000]      <1> 	mov	[mem_ipg_count], ecx ; initial (reset) value of page count
  2723 0000403A 890D[B8E90000]      <1> 	mov	[mem_pg_count], ecx
  2724 00004040 31C9                <1> 	xor	ecx, ecx ; 0
  2725 00004042 890D[BCE90000]      <1> 	mov	[mem_aperture], ecx ; 0
  2726 00004048 890D[C0E90000]      <1> 	mov	[mem_max_aperture], ecx ; 0
  2727                              <1> 	
  2728 0000404E BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address.
  2729 00004053 3B15[04DD0000]      <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 00004059 7208                <1> 	jb	short amb_1
  2733 0000405B 3B15[08DD0000]      <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 00004061 7606                <1> 	jna	short amb_2	     ; no	
  2737                              <1> amb_1:
  2738 00004063 8B15[04DD0000]      <1> 	mov	edx, [next_page]     ; yes (reset to the first page of user space)
  2739                              <1> amb_2:
  2740 00004069 01D3                <1> 	add	ebx, edx
  2741                              <1> 
  2742 0000406B A3[C4E90000]        <1> 	mov	[mem_pg_pos], eax    ; beginning page no (for curr. mem. aperture)
  2743 00004070 A3[C8E90000]        <1>  	mov	[mem_max_pg_pos], eax ; beginning page no for max. mem. aperture
  2744                              <1> 
  2745 00004075 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only (0 to 31)
  2746                              <1> 				     ; (allocation bit position)	 
  2747 00004078 744B                <1> 	jz	short amb_10	     ; 0	
  2748                              <1> amb_3:
  2749 0000407A 8B13                <1> 	mov	edx, [ebx]
  2750 0000407C 88C1                <1> 	mov	cl, al ; 1 to 31
  2751 0000407E D3EA                <1> 	shr	edx, cl
  2752 00004080 89D0                <1> 	mov	eax, edx
  2753                              <1> amb_4:
  2754 00004082 D1E8                <1> 	shr	eax, 1 ; (***)
  2755 00004084 7321                <1> 	jnc	short amb_7
  2756 00004086 FF05[BCE90000]      <1> 	inc	dword [mem_aperture]
  2757 0000408C FF0D[B8E90000]      <1> 	dec	dword [mem_pg_count]
  2758 00004092 747B                <1> 	jz	short amb_15
  2759                              <1> amb_5:
  2760 00004094 80F91F              <1> 	cmp	cl, 31
  2761 00004097 7317                <1> 	jnb	short amb_8
  2762 00004099 FEC1                <1> 	inc	cl
  2763 0000409B EBE5                <1> 	jmp	short amb_4
  2764                              <1> 
  2765                              <1> amb_6:	; out_of_memory
  2766 0000409D 31C0                <1> 	xor	eax, eax ; 0
  2767 0000409F 89D1                <1> 	mov	ecx, edx ; free pages
  2768 000040A1 C1E10C              <1> 	shl	ecx, PAGE_SHIFT
  2769 000040A4 5A                  <1> 	pop	edx ; *
  2770 000040A5 F9                  <1> 	stc
  2771 000040A6 C3                  <1> 	retn
  2772                              <1> amb_7:
  2773 000040A7 50                  <1> 	push	eax ; (***) allocation bits (in shifted status)
  2774 000040A8 E819010000          <1> 	call	amb_26 ; set maximum memory aperture (free memory block size)
  2775 000040AD 58                  <1> 	pop	eax ; (***)
  2776 000040AE EBE4                <1> 	jmp	short amb_5
  2777                              <1> amb_8:
  2778 000040B0 28C9                <1> 	sub	cl, cl ; 0
  2779                              <1> amb_9:
  2780 000040B2 89DA                <1> 	mov	edx, ebx
  2781 000040B4 81EA00001000        <1> 	sub	edx, MEM_ALLOC_TBL
  2782 000040BA 3B15[08DD0000]      <1> 	cmp	edx, [last_page]
  2783 000040C0 7336                <1> 	jnb	short amb_14 ; contiguous pages not enough
  2784 000040C2 83C304              <1> 	add	ebx, 4
  2785                              <1> amb_10:
  2786 000040C5 8B03                <1> 	mov	eax, [ebx]
  2787 000040C7 21C0                <1> 	and 	eax, eax
  2788 000040C9 7406                <1>         jz      short amb_11 ; there is not a free page bit in this alloc dword
  2789 000040CB 40                  <1> 	inc	eax ; 0FFFFFFFFh -> 0
  2790 000040CC 740A                <1> 	jz	short amb_12 ; all of bits are set (32 free pages)
  2791 000040CE 48                  <1> 	dec	eax
  2792 000040CF EBB1                <1> 	jmp	short amb_4
  2793                              <1> amb_11:
  2794 000040D1 E8F0000000          <1> 	call	amb_26 ; set maximum memory aperture (free memory block size)
  2795 000040D6 EBDA                <1> 	jmp	short amb_9	
  2796                              <1> amb_12:
  2797 000040D8 B120                <1> 	mov	cl, 32
  2798 000040DA 390D[B8E90000]      <1> 	cmp	[mem_pg_count], ecx ; 32
  2799 000040E0 7306                <1> 	jnb	short amb_13
  2800 000040E2 8B0D[B8E90000]      <1> 	mov	ecx, [mem_pg_count]
  2801                              <1> amb_13:
  2802 000040E8 010D[BCE90000]      <1> 	add	[mem_aperture], ecx
  2803 000040EE 290D[B8E90000]      <1> 	sub	[mem_pg_count], ecx
  2804 000040F4 7619                <1> 	jna	short amb_15
  2805 000040F6 EBB8                <1> 	jmp	short amb_8
  2806                              <1> amb_14:
  2807 000040F8 A1[C8E90000]        <1> 	mov	eax, [mem_max_pg_pos] ; begin address of max. mem aperture	
  2808 000040FD 8B0D[C0E90000]      <1> 	mov	ecx, [mem_max_aperture] ; max. (largest) memory aperture
  2809 00004103 C1E00C              <1> 	shl	eax, PAGE_SHIFT	     ; convert to phy. address in bytes
  2810 00004106 C1E10C              <1> 	shl	ecx, PAGE_SHIFT	     ; convert to byte counts
  2811 00004109 F9                  <1> 	stc
  2812 0000410A E9AC000000          <1>         jmp     amb_25
  2813                              <1> 
  2814                              <1> amb_15: ; OK !
  2815 0000410F A1[C4E90000]        <1> 	mov	eax, [mem_pg_pos]    ; Beginning address as page number
  2816 00004114 8B0D[BCE90000]      <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 0000411A 89C2                <1> 	mov	edx, eax
  2820 0000411C C1EA05              <1> 	shr	edx, 5 ; 32 pages in one allocation dword (32 bits)
  2821 0000411F BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL
  2822 00004124 01D3                <1> 	add	ebx, edx
  2823 00004126 83E01F              <1> 	and	eax, 1Fh ; 31
  2824                              <1> 	; 03/04/2016
  2825 00004129 BA20000000          <1> 	mov	edx, 32
  2826 0000412E 28C2                <1> 	sub	dl, al
  2827 00004130 39CA                <1> 	cmp	edx, ecx
  2828 00004132 7602                <1> 	jna	short amb_17
  2829 00004134 89CA                <1> 	mov	edx, ecx
  2830                              <1> amb_17:
  2831 00004136 29D1                <1> 	sub	ecx, edx
  2832 00004138 51                  <1> 	push	ecx ; ***
  2833 00004139 89D1                <1> 	mov	ecx, edx
  2834                              <1> amb_18:		
  2835 0000413B 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 0000413E FF0D[00DD0000]      <1> 	dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
  2839 00004144 49                  <1> 	dec	ecx
  2840 00004145 7404                <1> 	jz	short amb_19
  2841 00004147 FEC0                <1> 	inc	al
  2842 00004149 EBF0                <1> 	jmp	short amb_18
  2843                              <1> amb_19:	
  2844 0000414B 59                  <1> 	pop	ecx ; ***
  2845 0000414C 21C9                <1> 	and	ecx, ecx ; 0 ?
  2846 0000414E 741E                <1> 	jz	short amb_22	
  2847                              <1> 	; 01/04/2016
  2848 00004150 B020                <1> 	mov	al, 32
  2849                              <1> amb_20:
  2850 00004152 83C304              <1> 	add	ebx, 4
  2851 00004155 39C1                <1> 	cmp	ecx, eax ; 32
  2852 00004157 7305                <1> 	jnb	short amb_21
  2853                              <1> 	; ECX < 32
  2854 00004159 28C0                <1> 	sub	al, al ; 0
  2855 0000415B 50                  <1> 	push	eax ; 0 ***
  2856 0000415C EBDD                <1> 	jmp	short amb_18
  2857                              <1> amb_21:
  2858 0000415E 2905[00DD0000]      <1> 	sub	[free_pages], eax ; [free_pages] = [free_pages] - 32
  2859 00004164 C70300000000        <1> 	mov	dword [ebx], 0 ; reset 32 bits
  2860 0000416A 29C1                <1> 	sub	ecx, eax ; 32
  2861 0000416C 75E4                <1> 	jnz	short amb_20
  2862                              <1> amb_22:
  2863 0000416E A1[C4E90000]        <1> 	mov	eax, [mem_pg_pos]   ; Beginning address as page number
  2864 00004173 8B0D[BCE90000]      <1> 	mov	ecx, [mem_aperture] ; Free contiguous page count
  2865                              <1> 	; [next_page] update
  2866 00004179 89C2                <1> 	mov	edx, eax
  2867                              <1> 	; 03/04/2016
  2868 0000417B 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 0000417E 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2872                              <1> 				     ; (to get 32 bit position)	
  2873 00004181 3B15[04DD0000]      <1> 	cmp	edx, [next_page] ; first free page pointer offset
  2874 00004187 7732                <1> 	ja	short amb_25
  2875 00004189 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL
  2876 0000418E 833C1300            <1> 	cmp	dword [ebx+edx], 0
  2877 00004192 7721                <1> 	ja	short amb_24
  2878 00004194 89C2                <1> 	mov	edx, eax
  2879 00004196 01CA                <1> 	add	edx, ecx
  2880 00004198 C1EA03              <1> 	shr	edx, 3
  2881 0000419B 80E2FC              <1> 	and	dl, 0FCh
  2882                              <1> amb_23:
  2883 0000419E 833C1300            <1> 	cmp	dword [ebx+edx], 0
  2884 000041A2 7711                <1> 	ja	short amb_24
  2885 000041A4 83C204              <1> 	add	edx, 4
  2886 000041A7 3B15[08DD0000]      <1> 	cmp	edx, [last_page]    ; last page pointer offset
  2887 000041AD 76EF                <1> 	jna	short amb_23
  2888 000041AF 8B15[0CDD0000]      <1> 	mov	edx, [first_page]   ; (for) beginning of user's space
  2889                              <1> amb_24:
  2890 000041B5 8915[04DD0000]      <1> 	mov	[next_page], edx
  2891                              <1> amb_25:
  2892 000041BB 9C                  <1> 	pushf
  2893 000041BC C1E00C              <1> 	shl	eax, PAGE_SHIFT	     ; convert to phy. address in bytes
  2894 000041BF C1E10C              <1> 	shl	ecx, PAGE_SHIFT	     ; convert to byte counts
  2895 000041C2 9D                  <1> 	popf
  2896 000041C3 5B                  <1> 	pop	ebx ; **
  2897 000041C4 5A                  <1> 	pop	edx ; *
  2898 000041C5 C3                  <1> 	retn
  2899                              <1> 
  2900                              <1> amb_26:	; set maximum free memory aperture (free memory block size) 
  2901 000041C6 89DA                <1> 	mov	edx, ebx ; current address
  2902 000041C8 81EA00001000        <1> 	sub	edx, MEM_ALLOC_TBL ; MAT beginning address
  2903                              <1> 	; 02/04/2016 
  2904 000041CE C1E203              <1> 	shl	edx, 3 ; MAT byte offset * 8 = page number base
  2905 000041D1 01CA                <1> 	add	edx, ecx ; current page number (ecx =  0 to 31)
  2906                              <1> 	;
  2907 000041D3 A1[BCE90000]        <1> 	mov	eax, [mem_aperture]
  2908 000041D8 21C0                <1> 	and	eax, eax
  2909 000041DA 7424                <1>         jz      short amb_27
  2910 000041DC C705[BCE90000]0000- <1>         mov     dword [mem_aperture], 0
  2910 000041E4 0000                <1>
  2911 000041E6 3B05[C0E90000]      <1> 	cmp	eax, [mem_max_aperture]
  2912 000041EC 7612                <1> 	jna	short amb_27
  2913 000041EE A3[C0E90000]        <1> 	mov	[mem_max_aperture], eax
  2914                              <1> 	;
  2915 000041F3 89D0                <1> 	mov	eax, edx
  2916 000041F5 2B05[C0E90000]      <1> 	sub	eax, [mem_max_aperture] ; the last aperture size in pages
  2917                              <1> 	; EAX = Beginning page number of the max. aperture 
  2918 000041FB A3[C8E90000]        <1> 	mov	[mem_max_pg_pos], eax
  2919                              <1> amb_27: 
  2920 00004200 42                  <1> 	inc	edx	
  2921 00004201 8915[C4E90000]      <1> 	mov	[mem_pg_pos], edx ; next page
  2922                              <1> 
  2923 00004207 A1[B4E90000]        <1> 	mov	eax, [mem_ipg_count] ; initial (reset) value of page count
  2924 0000420C A3[B8E90000]        <1> 	mov	[mem_pg_count], eax
  2925                              <1> 
  2926 00004211 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 00004212 52                  <1> 	push	edx ; *
  2948 00004213 53                  <1> 	push	ebx ; **
  2949                              <1> 
  2950 00004214 C1E80C              <1> 	shr	eax, PAGE_SHIFT	     ; 12
  2951 00004217 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 0000421A 89C2                <1> 	mov	edx, eax
  2958 0000421C 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 0000421F 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2962                              <1> 				     ; (to get 32 bit position)	
  2963 00004222 3B15[04DD0000]      <1> 	cmp	edx, [next_page] ; next free page
  2964 00004228 7306                <1> 	jnb	short damb_1
  2965 0000422A 8915[04DD0000]      <1> 	mov	[next_page], edx
  2966                              <1> damb_1:
  2967 00004230 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL
  2968 00004235 01D3                <1> 	add	ebx, edx
  2969 00004237 83E01F              <1> 	and	eax, 1Fh ; 31
  2970                              <1> 
  2971                              <1> 	; 03/04/2016
  2972 0000423A BA20000000          <1> 	mov	edx, 32
  2973 0000423F 28C2                <1> 	sub	dl, al
  2974 00004241 39CA                <1> 	cmp	edx, ecx
  2975 00004243 7602                <1> 	jna	short damb_2
  2976 00004245 89CA                <1> 	mov	edx, ecx
  2977                              <1> damb_2:
  2978 00004247 29D1                <1> 	sub	ecx, edx
  2979 00004249 51                  <1> 	push	ecx ; ***
  2980 0000424A 89D1                <1> 	mov	ecx, edx
  2981                              <1> damb_3:		
  2982 0000424C 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 0000424F FF05[00DD0000]      <1> 	inc     dword [free_pages]   ; 1 page has been deallocated (X = X+1) 
  2986 00004255 49                  <1> 	dec	ecx
  2987 00004256 7404                <1> 	jz	short damb_4
  2988 00004258 FEC0                <1> 	inc	al
  2989 0000425A EBF0                <1> 	jmp	short damb_3
  2990                              <1> damb_4:	
  2991 0000425C 59                  <1> 	pop	ecx ; ***
  2992 0000425D 21C9                <1> 	and	ecx, ecx ; 0 ?
  2993 0000425F 741E                <1> 	jz	short damb_7
  2994                              <1> 	; 03/04/2016
  2995 00004261 B020                <1> 	mov	al, 32
  2996                              <1> damb_5:
  2997 00004263 83C304              <1> 	add	ebx, 4
  2998 00004266 39C1                <1> 	cmp	ecx, eax ; 32
  2999 00004268 7305                <1> 	jnb	short damb_6
  3000                              <1> 	; ECX < 32
  3001 0000426A 28C0                <1> 	sub	al, al ; 0
  3002 0000426C 50                  <1> 	push	eax ; 0 ***
  3003 0000426D EBDD                <1> 	jmp	short damb_3
  3004                              <1> damb_6:
  3005 0000426F 0105[00DD0000]      <1> 	add	[free_pages], eax ; [free_pages] = [free_pages] + 32
  3006 00004275 C703FFFFFFFF        <1> 	mov	dword [ebx], 0FFFFFFFFh ; set 32 bits
  3007 0000427B 29C1                <1> 	sub	ecx, eax ; 32
  3008 0000427D 75E4                <1> 	jnz	short damb_5
  3009                              <1> damb_7:
  3010 0000427F 5B                  <1> 	pop	ebx ; **
  3011 00004280 5A                  <1> 	pop	edx ; *
  3012 00004281 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 00004282 9C                  <1> 	pushfd
    30 00004283 0E                  <1> 	push 	cs
    31 00004284 E801000000          <1> 	call 	TIME_OF_DAY_1
    32 00004289 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 0000428A FB                  <1> 	sti				; INTERRUPTS BACK ON
   107                              <1> 	; 29/05/2016
   108 0000428B 80642408FE          <1> 	and	byte [esp+8], 11111110b	; clear carry bit of eflags register
   109                              <1> 	;
   110 00004290 80FC08              <1> 	cmp	ah, (RTC_TBE-RTC_TB)/4	; CHECK IF COMMAND IN VALID RANGE (0-7)
   111 00004293 F5                  <1> 	cmc				; COMPLEMENT CARRY FOR ERROR EXIT
   112                              <1> 	; (*) jc short TIME_9		; EXIT WITH CARRY = 1 IF NOT VALID
   113 00004294 721C                <1> 	jc	short _TIME_9 ; 29/05/2016
   114                              <1> 
   115 00004296 1E                  <1> 	push	ds
   116 00004297 56                  <1> 	push	esi
   117 00004298 66BE1000            <1> 	mov	si, KDATA		; kernel data segment
   118 0000429C 8EDE                <1> 	mov	ds, si
   119 0000429E C0E402              <1> 	shl	ah, 2			; convert function to dword offset
   120 000042A1 0FB6F4              <1> 	movzx	esi, ah			; PLACE INTO ADDRESSING REGISTER
   121 000042A4 FA                  <1> 	cli				; NO INTERRUPTS DURING TIME FUNCTIONS
   122 000042A5 FF96[B8420000]      <1> 	call	[esi+RTC_TB]		; VECTOR TO FUNCTION REQUESTED WITH CY=0
   123                              <1> 					; RETURN WITH CARRY FLAG SET FOR RESULT
   124 000042AB FB                  <1> 	sti				; INTERRUPTS BACK ON
   125 000042AC B400                <1> 	mov	ah, 0			; CLEAR (AH) TO ZERO
   126 000042AE 5E                  <1> 	pop	esi			; RECOVER USERS REGISTER
   127 000042AF 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 000042B0 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 000042B2 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 000042B7 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 000042B8 [D8420000]          <1> 	dd	RTC_00			; 0 = READ CURRENT CLOCK COUNT
   165 000042BC [EB420000]          <1> 	dd	RTC_10			; 1 = SET CLOCK COUNT
   166 000042C0 [F9420000]          <1> 	dd	RTC_20			; 2 = READ THE REAL TIME CLOCK TIME
   167 000042C4 [28430000]          <1> 	dd	RTC_30			; 3 = SET REAL TIME CLOCK TIME
   168 000042C8 [6A430000]          <1> 	dd	RTC_40			; 4 = READ THE REAL TIME CLOCK DATE
   169 000042CC [97430000]          <1> 	dd	RTC_50			; 5 = SET REAL TIME CLOCK DATE
   170 000042D0 [E4430000]          <1> 	dd	RTC_60			; 6 = SET THE REAL TIME CLOCK ALARM
   171 000042D4 [37440000]          <1> 	dd	RTC_70			; 7 = RESET ALARM
   172                              <1> 
   173                              <1> RTC_TBE	equ	$
   174                              <1> 
   175                              <1> RTC_00:				; READ TIME COUNT
   176 000042D8 A0[7CDD0000]        <1> 	mov	al, [TIMER_OFL]		; GET THE OVERFLOW FLAG
   177 000042DD C605[7CDD0000]00    <1> 	mov	byte [TIMER_OFL], 0	; AND THEN RESET THE OVERFLOW FLAG
   178 000042E4 8B0D[78DD0000]      <1>         mov     ecx, [TIMER_LH]         ; GET COUNT OF TIME
   179 000042EA C3                  <1> 	retn
   180                              <1> 
   181                              <1> RTC_10:				; SET TIME COUNT
   182 000042EB 890D[78DD0000]      <1>         mov     [TIMER_LH], ecx         ; SET TIME COUNT
   183 000042F1 C605[7CDD0000]00    <1> 	mov	byte [TIMER_OFL], 0	; RESET OVERFLOW FLAG
   184 000042F8 C3                  <1> 	retn				; RETURN WITH NO CARRY
   185                              <1> 
   186                              <1> RTC_20:				; GET RTC TIME
   187 000042F9 E8EB010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   188 000042FE 7227                <1> 	jc	short RTC_29		; EXIT IF ERROR (CY= 1)
   189                              <1> 
   190 00004300 B000                <1> 	mov	al, CMOS_SECONDS	; SET ADDRESS OF SECONDS
   191 00004302 E8FD010000          <1> 	call	CMOS_READ		; GET SECONDS
   192 00004307 88C6                <1> 	mov	dh, al			; SAVE
   193 00004309 B00B                <1> 	mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   194 0000430B E8F4010000          <1> 	call	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
   195 00004310 2401                <1> 	and	al, 00000001b		; MASK FOR VALID DSE BIT
   196 00004312 88C2                <1> 	mov	dl, al			; SET [DL] TO ZERO FOR NO DSE BIT
   197 00004314 B002                <1> 	mov	al, CMOS_MINUTES	; SET ADDRESS OF MINUTES
   198 00004316 E8E9010000          <1> 	call	CMOS_READ		; GET MINUTES
   199 0000431B 88C1                <1> 	mov	cl, al			; SAVE
   200 0000431D B004                <1>         mov     al, CMOS_HOURS          ; SET ADDRESS OF HOURS
   201 0000431F E8E0010000          <1> 	call	CMOS_READ		; GET HOURS
   202 00004324 88C5                <1> 	mov	ch, al			; SAVE
   203 00004326 F8                  <1> 	clc				; SET CY= 0
   204                              <1> RTC_29:
   205 00004327 C3                  <1> 	retn				; RETURN WITH RESULT IN CARRY FLAG
   206                              <1> 
   207                              <1> RTC_30:				; SET RTC TIME
   208 00004328 E8BC010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   209 0000432D 7305                <1> 	jnc	short RTC_35		; GO AROUND IF CLOCK OPERATING
   210 0000432F E817010000          <1> 	call	RTC_STA			; ELSE TRY INITIALIZING CLOCK
   211                              <1> RTC_35:
   212 00004334 88F4                <1> 	mov	ah, dh			; GET TIME BYTE - SECONDS
   213 00004336 B000                <1> 	mov	al, CMOS_SECONDS	; ADDRESS SECONDS
   214 00004338 E8E0010000          <1> 	call	CMOS_WRITE		; UPDATE SECONDS
   215 0000433D 88CC                <1> 	mov	ah, cl			; GET TIME BYTE - MINUTES
   216 0000433F B002                <1> 	mov	al, CMOS_MINUTES	; ADDRESS MINUTES
   217 00004341 E8D7010000          <1> 	call	CMOS_WRITE		; UPDATE MINUTES
   218 00004346 88EC                <1> 	mov	ah, ch			; GET TIME BYTE - HOURS
   219 00004348 B004                <1> 	mov	al, CMOS_HOURS		; ADDRESS HOURS
   220 0000434A E8CE010000          <1> 	call	CMOS_WRITE		; UPDATE ADDRESS
   221                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   222                              <1> 	;mov	ah, al
   223 0000434F 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   224 00004353 E8AC010000          <1> 	call	CMOS_READ		; READ CURRENT TIME
   225 00004358 2462                <1> 	and	al, 01100010b		; MASK FOR VALID BIT POSITIONS
   226 0000435A 0C02                <1> 	or	al, 00000010b		; TURN ON 24 HOUR MODE
   227 0000435C 80E201              <1> 	and	dl, 00000001b		; USE ONLY THE DSE BIT
   228 0000435F 08D0                <1> 	or	al, dl			; GET DAY LIGHT SAVINGS TIME BIT (OSE)
   229 00004361 86E0                <1> 	xchg	ah, al			; PLACE IN WORK REGISTER AND GET ADDRESS
   230 00004363 E8B5010000          <1> 	call	CMOS_WRITE		; SET NEW ALARM SITS
   231 00004368 F8                  <1> 	clc				; SET CY= 0
   232 00004369 C3                  <1> 	retn				; RETURN WITH CY= 0
   233                              <1> 
   234                              <1> RTC_40:				; GET RTC DATE
   235 0000436A E87A010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   236 0000436F 7225                <1> 	jc	short RTC_49		; EXIT IF ERROR (CY= 1)
   237                              <1> 
   238 00004371 B007                <1> 	mov	al, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH
   239 00004373 E88C010000          <1> 	call	CMOS_READ		; READ DAY OF MONTH
   240 00004378 88C2                <1> 	mov	dl, al			; SAVE
   241 0000437A B008                <1> 	mov	al, CMOS_MONTH		; ADDRESS MONTH
   242 0000437C E883010000          <1> 	call	CMOS_READ		; READ MONTH
   243 00004381 88C6                <1> 	mov	dh, al			; SAVE
   244 00004383 B009                <1> 	mov	al, CMOS_YEAR		; ADDRESS YEAR
   245 00004385 E87A010000          <1> 	call	CMOS_READ		; READ YEAR
   246 0000438A 88C1                <1> 	mov	cl, al			; SAVE
   247 0000438C B032                <1> 	mov	al, CMOS_CENTURY	; ADDRESS CENTURY LOCATION
   248 0000438E E871010000          <1> 	call	CMOS_READ		; GET CENTURY BYTE
   249 00004393 88C5                <1> 	mov	ch, al			; SAVE
   250 00004395 F8                  <1> 	clc				; SET CY=0
   251                              <1> RTC_49:
   252 00004396 C3                  <1> 	retn				; RETURN WITH RESULTS IN CARRY FLAG
   253                              <1> 
   254                              <1> RTC_50:				; SET RTC DATE
   255 00004397 E84D010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   256 0000439C 7305                <1> 	jnc	short RTC_55		; GO AROUND IF NO ERROR
   257 0000439E E8A8000000          <1> 	call	RTC_STA			; ELSE INITIALIZE CLOCK
   258                              <1> RTC_55:
   259 000043A3 66B80600            <1> 	mov	ax, CMOS_DAY_WEEK	; ADDRESS OF DAY OF WEEK BYTE
   260 000043A7 E871010000          <1> 	call	CMOS_WRITE		; LOAD ZEROS TO DAY OF WEEK
   261 000043AC 88D4                <1> 	mov	ah, dl			; GET DAY OF MONTH BYTE
   262 000043AE B007                <1> 	mov	al, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH BYTE
   263 000043B0 E868010000          <1> 	call	CMOS_WRITE		; WRITE OF DAY OF MONTH REGISTER
   264 000043B5 88F4                <1> 	mov	ah, dh			; GET MONTH
   265 000043B7 B008                <1> 	mov	al, CMOS_MONTH		; ADDRESS MONTH BYTE
   266 000043B9 E85F010000          <1> 	call	CMOS_WRITE		; WRITE MONTH REGISTER
   267 000043BE 88CC                <1> 	mov	ah, cl			; GET YEAR BYTE
   268 000043C0 B009                <1> 	mov	al, CMOS_YEAR		; ADDRESS YEAR REGISTER
   269 000043C2 E856010000          <1> 	call	CMOS_WRITE		; WRITE YEAR REGISTER
   270 000043C7 88EC                <1> 	mov	ah, ch			; GET CENTURY BYTE
   271 000043C9 B032                <1> 	mov	al, CMOS_CENTURY	; ADDRESS CENTURY BYTE
   272 000043CB E84D010000          <1> 	call	CMOS_WRITE		; WRITE CENTURY LOCATION
   273                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   274                              <1> 	;mov	ah, al
   275 000043D0 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   276 000043D4 E82B010000          <1> 	call	CMOS_READ		; READ WIRRENT SETTINGS
   277 000043D9 247F                <1> 	and	al, 07Fh		; CLEAR 'SET BIT'
   278 000043DB 86E0                <1> 	xchg	ah, al			; MOVE TO WORK REGISTER
   279 000043DD E83B010000          <1> 	call	CMOS_WRITE		; AND START CLOCK UPDATING
   280 000043E2 F8                  <1> 	clc				; SET CY= 0
   281 000043E3 C3                  <1> 	retn				; RETURN CY=0
   282                              <1> 
   283                              <1> RTC_60:				; SET RTC ALARM
   284 000043E4 B00B                <1> 	mov	al, CMOS_REG_B		; ADDRESS ALARM
   285 000043E6 E819010000          <1> 	call	CMOS_READ		; READ ALARM REGISTER
   286 000043EB A820                <1> 	test	al, 20h			; CHECK FOR ALARM ALREADY ENABLED
   287 000043ED F9                  <1> 	stc				; SET CARRY IN CASE OF ERROR
   288 000043EE 7542                <1> 	jnz	short RTC_69		; ERROR EXIT IF ALARM SET
   289 000043F0 E8F4000000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   290 000043F5 7305                <1> 	jnc	short RTC_65		; SKIP INITIALIZATION IF NO ERROR
   291 000043F7 E84F000000          <1> 	call	RTC_STA			; ELSE INITIALIZE CLOCK
   292                              <1> RTC_65:	
   293 000043FC 88F4                <1> 	mov	ah, dh			; GET SECONDS BYTE
   294 000043FE B001                <1> 	mov	al, CMOS_SEC_ALARM	; ADDRESS THE SECONDS ALARM REGISTER
   295 00004400 E818010000          <1> 	call	CMOS_WRITE		; INSERT SECONDS
   296 00004405 88CC                <1> 	mov	ah, cl			; GET MINUTES PARAMETER
   297 00004407 B003                <1> 	mov	al, CMOS_MIN_ALARM	; ADDRESS MINUTES ALARM REGISTER
   298 00004409 E80F010000          <1> 	call	CMOS_WRITE		; INSERT MINUTES
   299 0000440E 88EC                <1> 	mov	ah, ch			; GET HOURS PARAMETER
   300 00004410 B005                <1> 	mov	al, CMOS_HR_ALARM	; ADDRESS HOUR ALARM REGISTER
   301 00004412 E806010000          <1> 	call	CMOS_WRITE		; INSERT HOURS
   302 00004417 E4A1                <1> 	in	al, INTB01		; READ SECOND INTERRUPT MASK REGISTER
   303 00004419 24FE                <1> 	and	al, 0FEh		; ENABLE ALARM TIMER BIT (CY= 0)
   304 0000441B E6A1                <1> 	out	INTB01, al		; WRITE UPDATED MASK
   305                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   306                              <1> 	;mov	ah, al
   307 0000441D 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   308 00004421 E8DE000000          <1> 	call	CMOS_READ		; READ CURRENT ALARM REGISTER
   309 00004426 247F                <1> 	and	al, 07Fh		; ENSURE SET BIT TURNED OFF
   310 00004428 0C20                <1> 	or	al, 20h			; TURN ON ALARM ENABLE
   311 0000442A 86E0                <1> 	xchg	ah, al			; MOVE MASK TO OUTPUT REGISTER
   312 0000442C E8EC000000          <1> 	call	CMOS_WRITE		; WRITE NEW ALARM MASK
   313 00004431 F8                  <1> 	clc				; SET CY= 0
   314                              <1> RTC_69:
   315 00004432 66B80000            <1> 	mov	ax, 0			; CLEAR AX REGISTER
   316 00004436 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 00004437 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257	; ADDRESS ALARM REGISTER (TO BOTH AH,AL)
   322 0000443B E8C4000000          <1> 	call	CMOS_READ		; READ ALARM REGISTER
   323 00004440 2457                <1> 	and	al, 57h			; TURN OFF ALARM ENABLE
   324 00004442 86E0                <1> 	xchg	ah, al			; SAVE DATA AND RECOVER ADDRESS
   325 00004444 E8D4000000          <1> 	call	CMOS_WRITE		; RESTORE NEW VALUE
   326 00004449 F8                  <1> 	clc				; SET CY= 0
   327 0000444A 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 0000444B 66B80A26            <1> 	mov	ax, (26h*100h)+CMOS_REG_A
   333 0000444F 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 00004454 66B80B82            <1> 	mov	ax, (82h*100h)+CMOS_REG_B
   337 00004458 E8C0000000          <1> 	call	CMOS_WRITE		; AND 24 HOUR MODE TO REGISTER B
   338 0000445D B00C                <1> 	mov	al, CMOS_REG_C		; ADDRESS REGISTER C
   339 0000445F E8A0000000          <1> 	call	CMOS_READ		; READ REGISTER C TO INITIALIZE
   340 00004464 B00D                <1> 	mov	al, CMOS_REG_D		; ADDRESS REGISTER D
   341 00004466 E899000000          <1> 	call	CMOS_READ		; READ REGISTER D TO INITIALIZE
   342 0000446B 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 0000446C 1E                  <1> 	push	ds			; LEAVE INTERRUPTS DISABLED
   363 0000446D 50                  <1> 	push	eax			; SAVE REGISTERS
   364 0000446E 57                  <1> 	push	edi
   365                              <1> RTC_I_1:				; CHECK FOR SECOND INTERRUPT
   366 0000446F 66B88C8B            <1> 	mov	ax, 256*(CMOS_REG_B+NMI)+CMOS_REG_C+NMI ; ALARM AND STATUS
   367 00004473 E670                <1> 	out	CMOS_PORT, al		; WRITE ALARM FLAG MASK ADDRESS
   368 00004475 90                  <1> 	nop				; I/O DELAY
   369 00004476 EB00                <1> 	jmp	short $+2
   370 00004478 E471                <1> 	in	al, CMOS_DATA		; READ AND RESET INTERRUPT REQUEST FLAGS
   371 0000447A A860                <1> 	test	al, 01100000b		; CHECK FOR EITHER INTERRUPT PENDING
   372 0000447C 745D                <1> 	jz	short	RTC_I_9		; EXIT IF NOT A VALID RTC INTERRUPT
   373                              <1> 
   374 0000447E 86E0                <1> 	xchg	ah, al			; SAVE FLAGS AND GET ENABLE ADDRESS
   375 00004480 E670                <1> 	out	CMOS_PORT, al		; WRITE ALARM ENABLE MASK ADDRESS
   376 00004482 90                  <1> 	nop				; I/O DELAY
   377 00004483 EB00                <1> 	jmp	short $+2	
   378 00004485 E471                <1> 	in	al, CMOS_DATA		; READ CURRENT ALARM ENABLE MASK
   379 00004487 20E0                <1> 	and	al, ah			; ALLOW ONLY SOURCES THAT ARE ENABLED
   380 00004489 A840                <1> 	test	al, 01000000b		; CHECK FOR PERIODIC INTERRUPT
   381 0000448B 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 0000448D 66BF1000            <1> 	mov	di, KDATA		; kernel data segment
   386 00004491 8EDF                <1> 	mov	ds, di
   387                              <1> 	
   388 00004493 812D[70DD0000]D003- <1> 	sub	dword [RTC_LH], 976	; DECREMENT COUNT BY 1/1024
   388 0000449B 0000                <1>
   389 0000449D 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 0000449F 6650                <1> 	push	ax			; SAVE INTERRUPT FLAG MASK
   394 000044A1 66B88B8B            <1> 	mov	ax, 257*(CMOS_REG_B+NMI) ; INTERRUPT ENABLE REGISTER
   395 000044A5 E670                <1> 	out	CMOS_PORT, al		; WRITE ADDRESS TO CMOS CLOCK
   396 000044A7 90                  <1> 	nop				; I/O DELAY
   397 000044A8 EB00                <1> 	jmp	short $+2
   398 000044AA E471                <1> 	in	al, CMOS_DATA		; READ CURRENT ENABLES
   399 000044AC 24BF                <1> 	and	al, 0BFh		; TURN OFF PIE
   400 000044AE 86C4                <1> 	xchg	al, ah			; GET CMOS ADDRESS AND SAVE VALUE
   401 000044B0 E670                <1> 	out	CMOS_PORT, al		; ADDRESS REGISTER B
   402 000044B2 86C4                <1> 	xchg	al, ah			; GET NEW INTERRUPT ENABLE MASK
   403 000044B4 E671                <1> 	out	CMOS_DATA, al		; SET MASK IN INTERRUPT ENABLE REGISTER
   404 000044B6 C605[74DD0000]00    <1> 	mov	byte [RTC_WAIT_FLAG], 0	; SET FUNCTION ACTIVE FLAG OFF
   405 000044BD 8B3D[75DD0000]      <1> 	mov	edi, [USER_FLAG]	; SET UP (DS:DI) TO POINT TO USER FLAG
   406 000044C3 C60780              <1> 	mov	byte [edi], 80h		; TURN ON USERS FLAG
   407 000044C6 6658                <1> 	pop	ax			; GET INTERRUPT SOURCE BACK
   408                              <1> RTC_I_5:
   409 000044C8 A820                <1> 	test	al, 00100000b		; TEST FOR ALARM INTERRUPT
   410 000044CA 740D                <1> 	jz	short RTC_I_7		; SKIP USER INTERRUPT CALL IF NOT ALARM
   411                              <1> 
   412 000044CC B00D                <1> 	mov	al, CMOS_REG_D		; POINT TO DEFAULT READ ONLY REGISTER
   413 000044CE E670                <1> 	out	CMOS_PORT, al		; ENABLE NMI AND CMOS ADDRESS TO DEFAULT
   414 000044D0 FB                  <1> 	sti				; INTERRUPTS BACK ON NOW
   415 000044D1 52                  <1> 	push	edx
   416 000044D2 E82B810000          <1> 	call	INT4Ah			; TRANSFER TO USER ROUTINE
   417 000044D7 5A                  <1> 	pop	edx
   418 000044D8 FA                  <1> 	cli				; BLOCK INTERRUPT FOR RETRY
   419                              <1> RTC_I_7:				; RESTART ROUTINE TO HANDLE DELAYED
   420 000044D9 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 000044DB B00D                <1> 	mov	al, CMOS_REG_D		; POINT TO DEFAULT READ ONLY REGISTER
   424 000044DD E670                <1> 	out	CMOS_PORT, al		; ENABLE NMI AND CMOS ADDRESS TO DEFAULT
   425 000044DF B020                <1> 	mov	al, EOI			; END OF INTERRUPT MASK TO 8259 - 2
   426 000044E1 E6A0                <1> 	out	INTB00, al		; TO 8259 - 2
   427 000044E3 E620                <1> 	out	INTA00,	al		; TO 8259 - 1
   428 000044E5 5F                  <1> 	pop	edi			; RESTORE REGISTERS
   429 000044E6 58                  <1> 	pop	eax
   430 000044E7 1F                  <1> 	pop	ds
   431 000044E8 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 000044E9 51                  <1> 	push	ecx
   439                              <1> 
   440                              <1> 	; 29/05/2016
   441 000044EA 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 000044EF B00A                <1> 	mov	al, CMOS_REG_A		; ADDRESS STATUS REGISTER A
   450 000044F1 FA                  <1> 	cli				; NO TIMER INTERRUPTS DURING UPDATES
   451 000044F2 E80D000000          <1> 	call	CMOS_READ		; READ UPDATE IN PROCESS FLAG
   452 000044F7 A880                <1> 	test	al, 80h			; IF UIP BIT IS ON ( CANNOT READ TIME )
   453 000044F9 7406                <1> 	jz	short UPD_90		; EXIT WITH CY= 0 IF CAN READ CLOCK NOW
   454 000044FB FB                  <1> 	sti				; ALLOW INTERRUPTS WHILE WAITING
   455 000044FC E2F1                <1> 	loop	UPD_10			; LOOP TILL READY OR TIMEOUT
   456 000044FE 31C0                <1> 	xor	eax, eax		; CLEAR RESULTS IF ERROR
   457                              <1> 		; xor ax, ax
   458 00004500 F9                  <1> 	stc				; SET CARRY FOR ERROR
   459                              <1> UPD_90:
   460 00004501 59                  <1> 	pop	ecx			; RESTORE CALLERS REGISTER
   461 00004502 FA                  <1> 	cli				; INTERRUPTS OFF DURING SET
   462 00004503 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 00004504 9C                  <1> 	pushf				; SAVE INTERRUPT ENABLE STATUS AND FLAGS
   486 00004505 D0C0                <1> 	rol	al, 1			; MOVE NMI BIT TO LOW POSITION
   487 00004507 F9                  <1> 	stc				; FORCE NMI BIT ON IN CARRY FLAG
   488 00004508 D0D8                <1> 	rcr	al, 1			; HIGH BIT ON TO DISABLE NMI - OLD IN CY
   489 0000450A FA                  <1> 	cli				; DISABLE INTERRUPTS
   490 0000450B E670                <1> 	out	CMOS_PORT, al		; ADDRESS LOCATION AND DISABLE NMI
   491                              <1> 	; 29/05/2016
   492                              <1> 	;nop				; I/O DELAY
   493 0000450D E6EB                <1> 	out	0ebh,al	; NEWIODELAY ; AWARD BIOS 1999, ATIME.ASM
   494                              <1> 	;
   495 0000450F E471                <1> 	in	al, CMOS_DATA		; READ THE REQUESTED CMOS LOCATION
   496 00004511 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 00004513 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 00004515 D0D8                <1> 	rcr	al, 1			; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
   502 00004517 E670                <1> 	out	CMOS_PORT, al		; SET DEFAULT TO READ ONLY REGISTER
   503 00004519 6658                <1> 	pop	ax			; RESTORE (AH) AND (AL), CMOS BYTE
   504 0000451B 9D                  <1> 	popf	
   505 0000451C 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 0000451D 9C                  <1> 	pushf				; SAVE INTERRUPT ENABLE STATUS AND FLAGS
   527 0000451E 6650                <1> 	push	ax			; SAVE WORK REGISTER VALUES
   528 00004520 D0C0                <1> 	rol	al, 1			; MOVE NMI BIT TO LOW POSITION
   529 00004522 F9                  <1> 	stc				; FORCE NMI BIT ON IN CARRY FLAG
   530 00004523 D0D8                <1> 	rcr	al, 1			; HIGH BIT ON TO DISABLE NMI - OLD IN CY
   531 00004525 FA                  <1> 	cli				; DISABLE INTERRUPTS
   532 00004526 E670                <1> 	out	CMOS_PORT, al		; ADDRESS LOCATION AND DISABLE NMI
   533 00004528 88E0                <1> 	mov	al, ah			; GET THE DATA BYTE TO WRITE
   534 0000452A E671                <1> 	out	CMOS_DATA, al		; PLACE IN REQUESTED CMOS LOCATION
   535 0000452C 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 0000452E D0D8                <1> 	rcr	al, 1			; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
   538 00004530 E670                <1> 	out	CMOS_PORT, al		; SET DEFAULT TO READ ONLY REGISTER
   539 00004532 90                  <1> 	nop				; I/O DELAY
   540 00004533 E471                <1> 	in	al, CMOS_DATA		; OPEN STANDBY LATCH
   541 00004535 6658                <1> 	pop	ax			; RESTORE WORK REGISTERS
   542 00004537 9D                  <1> 	popf
   543 00004538 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 00004539 31C0                <1> 	xor	eax, eax
    30 0000453B BF00010900          <1> 	mov	edi, Logical_DOSDisks
    31 00004540 B980060000          <1> 	mov	ecx, 6656/4 ; 26*256 = 6656 bytes
    32 00004545 F3AB                <1> 	rep	stosd ; 1664 times 4 bytes
    33                              <1> 
    34 00004547 B83F3A2F00          <1> 	mov	eax, '?:/'
    35 0000454C A3[BFDD0000]        <1> 	mov	[Current_Dir_Drv], eax
    36                              <1> 
    37                              <1> 	; Logical DRV INIT (only for hard disks)
    38 00004551 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 00004556 BE00010900          <1> 	mov 	esi, Logical_DOSDisks
    45 0000455B B001                <1> 	mov 	al, 1 ; Initialization sign (invalid_fd_parameter)
    46 0000455D 83C67E              <1> 	add 	esi, LD_MediaChanged ; Media Change Status = 1 (init needed)
    47 00004560 8806                <1> 	mov 	[esi], al ; A:
    48 00004562 81C600010000        <1> 	add 	esi, 100h 
    49 00004568 8806                <1> 	mov 	[esi], al ; B: 
    50                              <1>            
    51                              <1> _current_drive_bootdisk:
    52 0000456A 8A15[06D80000]      <1> 	mov 	dl, [boot_drv] ; physical drive number
    53 00004570 80FAFF              <1> 	cmp 	dl, 0FFh
    54 00004573 740A                <1> 	je 	short _last_dos_diskno_check
    55                              <1> _boot_drive_check:
    56 00004575 80FA80              <1> 	cmp 	dl, 80h
    57 00004578 7218                <1> 	jb 	short _current_drive_a
    58 0000457A 80EA7E              <1> 	sub 	dl, 7Eh ; C = 2 , D = 3
    59 0000457D EB13                <1> 	jmp 	short _current_drive_a 
    60                              <1> 
    61                              <1> _last_dos_diskno_check:
    62 0000457F 8A15[28C80000]      <1> 	mov 	dl, [Last_DOS_DiskNo]
    63 00004585 80FA02              <1> 	cmp 	dl, 2
    64 00004588 7706                <1> 	ja 	short _current_drive_c
    65 0000458A 7406                <1> 	je 	short _current_drive_a
    66 0000458C 30D2                <1> 	xor 	dl, dl ; A:
    67 0000458E EB02                <1> 	jmp 	short _current_drive_a
    68                              <1> 
    69                              <1> _current_drive_c:
    70 00004590 B202                <1> 	mov 	dl, 2 ; C:
    71                              <1> 
    72                              <1> _current_drive_a:
    73 00004592 8815[07D80000]      <1> 	mov	[drv], dl
    74 00004598 BE[2AC80000]        <1>         mov     esi, msg_CRLF_temp
    75 0000459D E89E000000          <1> 	call 	print_msg
    76                              <1> 
    77 000045A2 8A15[07D80000]      <1> 	mov	dl, [drv]
    78 000045A8 E898090000          <1> 	call 	change_current_drive
    79 000045AD 730C                <1> 	jnc 	short _start_mainprog
    80                              <1> 
    81                              <1> _drv_not_ready_error: 
    82 000045AF BE[EECA0000]        <1> 	mov 	esi, msgl_drv_not_ready
    83 000045B4 E887000000          <1> 	call 	print_msg
    84 000045B9 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 000045BB 66B80100            <1> 	mov	ax, 1
    96 000045BF A2[27F20000]        <1> 	mov	[u.uno], al
    97 000045C4 66A3[C0F10000]      <1> 	mov	[mpid], ax
    98 000045CA 66A3[BAEE0000]      <1> 	mov	[p.pid], ax
    99 000045D0 A2[4AEF0000]        <1> 	mov	[p.stat], al
   100 000045D5 B004                <1> 	mov	al, time_count
   101 000045D7 A2[1AF20000]        <1> 	mov	[u.quant], al
   102                              <1> 	;
   103 000045DC A1[F8DC0000]        <1> 	mov	eax, [k_page_dir]
   104 000045E1 A3[31F20000]        <1> 	mov	[u.pgdir], eax ; reset
   105                              <1> 	;
   106 000045E6 E8BBF1FFFF          <1> 	call	allocate_page
   107 000045EB 0F82A3000000        <1> 	jc	panic
   108 000045F1 A3[28F20000]        <1> 	mov	[u.upage], eax ; user structure page	
   109 000045F6 A3[5AEF0000]        <1> 	mov	[p.upage], eax
   110 000045FB E820F2FFFF          <1> 	call	clear_page
   111                              <1> 	;
   112                              <1> 	; 24/08/2015
   113 00004600 FE0D[CDF10000]      <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 00004606 BF00300900          <1> 	mov	edi, Env_Page ; 93000h
   118 0000460B B980000000          <1> 	mov	ecx, Env_Page_Size / 4 	; 512/4  (4096/4)				 	  		 	  
   119 00004610 31C0                <1> 	xor	eax, eax
   120 00004612 F3AB                <1> 	rep	stosd
   121                              <1> 
   122                              <1> 	; 14/04/2016
   123 00004614 E8BF320000          <1>  	call	mainprog_startup_configuration
   124                              <1> 
   125 00004619 E8630A0000          <1>         call    dos_prompt
   126                              <1>               
   127                              <1> _end_of_mainprog:
   128 0000461E BE[2AC80000]        <1>         mov     esi, msg_CRLF_temp
   129 00004623 E818000000          <1> 	call 	print_msg
   130 00004628 BE[30C80000]        <1> 	mov 	esi, mainprog_Version
   131 0000462D E80E000000          <1> 	call 	print_msg
   132                              <1> 	; 24/01/2016
   133 00004632 28E4                <1> 	sub	ah, ah
   134 00004634 E87DC4FFFF          <1> 	call	int16h ; call getch
   135 00004639 E954C9FFFF          <1> 	jmp	cpu_reset
   136                              <1> 
   137 0000463E 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 00004640 8A3D[26DD0000]      <1> 	mov	bh, [ACTIVE_PAGE] ; 04/01/2016 (ptty)
   148                              <1> 	;mov	bl, 07h ; Black background, light gray forecolor
   149                              <1> 
   150 00004646 AC                  <1> 	lodsb
   151                              <1> pmsg1:
   152 00004647 56                  <1> 	push 	esi
   153                              <1> 	;mov	bh, [ACTIVE_PAGE] ; 04/01/2016 (ptty)
   154 00004648 B307                <1> 	mov	bl, 07h ; Black background, light gray forecolor
   155 0000464A E8A0D2FFFF          <1> 	call 	_write_tty
   156 0000464F 5E                  <1> 	pop	esi
   157 00004650 AC                  <1> 	lodsb
   158 00004651 20C0                <1> 	and 	al, al
   159 00004653 75F2                <1> 	jnz 	short pmsg1
   160 00004655 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 00004656 0FB61D[26DD0000]    <1> 	movzx	ebx, byte [ACTIVE_PAGE] ; video page number (0 to 7)
   168 0000465D 8AA3[7AD30000]      <1> 	mov 	ah, [ebx+vmode] ; default = 03h (80x25 text)
   169 00004663 80FC04              <1> 	cmp	ah, 4
   170 00004666 7205                <1> 	jb	short cls1
   171 00004668 80FC07              <1> 	cmp	ah, 7
   172 0000466B 7526                <1> 	jne	short vga_clear
   173                              <1> cls1:
   174                              <1> 	;mov	bh, bl
   175                              <1> 	;mov	bl, 7
   176 0000466D 3A25[26D30000]      <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 00004673 0F8580D2FFFF        <1> 	jne	set_mode_3
   182                              <1> cls2:
   183 00004679 88DF                <1> 	mov	bh, bl ; video page (0 to 7)
   184 0000467B B307                <1> 	mov	bl, 07h ; attribute to be used on blanked line
   185 0000467D 28C0                <1> 	sub 	al, al ; 0 =  entire window
   186 0000467F 6631C9              <1> 	xor 	cx, cx
   187 00004682 66BA4F18            <1> 	mov 	dx, 184Fh
   188 00004686 E82FD0FFFF          <1> 	call	_scroll_up ; 24/01/2016
   189                              <1> 	;
   190                              <1> 	;mov	bh, [ACTIVE_PAGE] ; video page number (0 to 7)
   191 0000468B 6631D2              <1> 	xor 	dx, dx
   192 0000468E E8F2D2FFFF          <1> 	call	_set_cpos ; 24/01/2016 
   193                              <1> 	;retn
   194                              <1> vga_clear:
   195 00004693 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 00004694 BE[9FD90000]        <1> 	mov 	esi, panic_msg
   202 00004699 E8A2FFFFFF          <1> 	call 	print_msg
   203                              <1> key_to_reboot:
   204                              <1>         ; 24/01/2016
   205 0000469E 28E4                <1>         sub     ah, ah
   206 000046A0 E811C4FFFF          <1>         call    int16h ; call   getch
   207                              <1>         ; wait for a character from the current tty
   208                              <1> 	;
   209 000046A5 B00A                <1> 	mov	al, 0Ah
   210 000046A7 8A3D[26DD0000]      <1> 	mov	bh, [ptty] ; [ACTIVE_PAGE]
   211 000046AD B307                <1> 	mov	bl, 07h ; Black background, 
   212                              <1> 			; light gray forecolor
   213 000046AF E83BD2FFFF          <1> 	call 	_write_tty
   214 000046B4 E9D9C8FFFF          <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 000046B9 66833D[1CF20000]00  <1> 	cmp 	word [u.intr], 0
   226 000046C1 7645                <1> 	jna 	short cbrk4
   227                              <1> cbrk0:
   228                              <1> 	; 12/11/2015
   229                              <1> 	; 06/12/2013
   230 000046C3 66833D[1EF20000]00  <1> 	cmp 	word [u.quit], 0
   231 000046CB 743B                <1> 	jz	short cbrk4
   232                              <1> 	;
   233                              <1> 	; 20/09/2013	
   234 000046CD 6650                <1> 	push 	ax
   235 000046CF A0[26DD0000]        <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 000046D4 3C08                <1> 	cmp	al, 8 ; serial port tty nums > 7
   244 000046D6 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 000046D8 52                  <1> 	push	edx
   256 000046D9 0FB615[27F20000]    <1> 	movzx	edx, byte [u.uno]
   257 000046E0 3A82[19EF0000]      <1> 	cmp     al, [edx+p.ttyc-1] ; console tty (rw)
   258 000046E6 5A                  <1> 	pop	edx
   259 000046E7 7412                <1> 	je	short cbrk2
   260                              <1> cbrk1:
   261 000046E9 FEC0                <1> 	inc 	al  ; [u.ttyp] : 1 based tty number
   262                              <1> 	; 06/12/2013
   263 000046EB 3A05[08F20000]      <1> 	cmp	al, [u.ttyp] ; recent open tty (r)
   264 000046F1 7408                <1> 	je	short cbrk2	
   265 000046F3 3A05[09F20000]      <1>         cmp     al, [u.ttyp+1] ; recent open tty (w)
   266 000046F9 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 000046FB 6631C0              <1> 	xor	ax, ax ; 0
   274 000046FE 6648                <1> 	dec	ax
   275                              <1> 	; 0FFFFh = 'ctrl+brk' keystroke
   276 00004700 66A3[1EF20000]      <1> 	mov	[u.quit], ax
   277                              <1> cbrk3:
   278 00004706 6658                <1> 	pop	ax
   279                              <1> cbrk4:
   280 00004708 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 00004709 0FB60D[94DD0000]    <1> 	movzx	ecx, byte [HF_NUM] ; number of fixed disks
    25 00004710 80F901              <1> 	cmp	cl, 1
    26 00004713 7301                <1> 	jnb	short load_hd_partition_tables
    27                              <1> 	; No hard disks
    28 00004715 C3                  <1> 	retn
    29                              <1> load_hd_partition_tables:
    30 00004716 8B35[98DD0000]      <1> 	mov	esi, [HDPM_TBL_VEC] ; primary master disk FDPT
    31 0000471C BF[BEE10000]        <1> 	mov 	edi, PTable_hd0
    32 00004721 B280                <1> 	mov 	dl, 80h
    33                              <1> load_next_hd_partition_table:
    34 00004723 51                  <1> 	push	ecx
    35 00004724 57                  <1> 	push	edi
    36 00004725 56                  <1> 	push	esi ; FDPT (+ DPTE) address
    37 00004726 8A4614              <1> 	mov	al, [esi+20] ; DPTE offset 4
    38 00004729 2440                <1> 	and	al, 40h ;  LBA bit (bit 6)
    39                              <1> 	;shr	al, 6
    40 0000472B A2[BFE30000]        <1> 	mov 	[HD_LBA_yes], al
    41 00004730 E81C040000          <1> 	call	load_masterboot
    42 00004735 7275                <1> 	jc	short pass_pt_this_hard_disk
    43                              <1> 
    44 00004737 BE[7CE10000]        <1> 	mov	esi, PartitionTable
    45 0000473C 89F3                <1> 	mov	ebx, esi
    46                              <1> 	;mov	ecx, 16
    47 0000473E B110                <1> 	mov	cl, 16
    48 00004740 F3A5                <1> 	rep 	movsd
    49 00004742 89DE                <1> 	mov 	esi, ebx 
    50 00004744 C605[09D80000]04    <1> 	mov 	byte [hdc], 4 ; 4 - partition index
    51                              <1> loc_validate_hdp_partition:
    52 0000474B 807E0400            <1> 	cmp 	byte [esi+ptFileSystemID], 0
    53 0000474F 7641                <1> 	jna	short loc_validate_next_hdp_partition2
    54 00004751 56                  <1> 	push	esi ; Masterboot partition table offset
    55 00004752 52                  <1> 	push	edx ; dl = Physical drive number 
    56 00004753 FE05[C0E30000]      <1> 	inc	byte [PP_Counter]
    57 00004759 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 0000475B E879010000          <1> 	call 	validate_hd_fat_partition
    63 00004760 730A                <1> 	jnc 	short loc_set_valid_hdp_partition_entry
    64                              <1> 	;pop	edx
    65                              <1> 	;push	edx
    66 00004762 8B1424              <1> 	mov	edx, [esp] 
    67 00004765 E8C5020000          <1> 	call	validate_hd_fs_partition
    68 0000476A 7224                <1> 	jc	short loc_validate_next_hdp_partition1
    69                              <1> loc_set_valid_hdp_partition_entry:
    70 0000476C 8A0D[28C80000]      <1> 	mov 	cl, [Last_DOS_DiskNo] 
    71 00004772 80C141              <1> 	add 	cl, 'A'
    72                              <1> 	; ESI = Logical dos drive description table address
    73 00004775 880E                <1> 	mov	[esi+LD_Name], cl
    74 00004777 8A6602              <1> 	mov	ah, [esi+LD_PhyDrvNo]
    75 0000477A 88E0                <1> 	mov	al, ah ; Physical drive number
    76 0000477C 2C80                <1> 	sub	al, 80h
    77 0000477E C0E002              <1> 	shl	al, 2
    78 00004781 0404                <1> 	add	al, 4 ; 0 Based
    79 00004783 2A05[09D80000]      <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 00004789 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 0000478C 6689467C            <1> 	mov 	[esi+LD_PartitionEntry], ax
    89                              <1> loc_validate_next_hdp_partition1:
    90 00004790 5A                  <1> 	pop 	edx ; dl = Physical drive number 
    91 00004791 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 00004792 FE0D[09D80000]      <1> 	dec	byte [hdc] ; 4 - partition index
    96 00004798 7412                <1> 	jz	short pass_pt_this_hard_disk
    97 0000479A 83C610              <1> 	add	esi, 16 ; 10h
    98 0000479D EBAC                <1> 	jmp	short loc_validate_hdp_partition
    99                              <1> loc_next_hd_partition_table:
   100 0000479F FEC2                <1> 	inc	dl
   101 000047A1 83C620              <1> 	add	esi, 32 ; next FDPT address
   102 000047A4 83C740              <1> 	add	edi, 64 ; next partition table destination
   103 000047A7 E977FFFFFF          <1>         jmp     load_next_hd_partition_table
   104                              <1> pass_pt_this_hard_disk:
   105 000047AC 5E                  <1> 	pop	esi ; FDPT (+ DPTE) address
   106 000047AD 5F                  <1> 	pop	edi ; Ptable_hd?
   107 000047AE 59                  <1> 	pop	ecx
   108 000047AF E2EE                <1> 	loop	loc_next_hd_partition_table
   109 000047B1 803D[C0E30000]01    <1> 	cmp	byte [PP_Counter], 1
   110 000047B8 7301                <1> 	jnb	short load_extended_dos_partitions
   111                              <1> 	; Empty partition table
   112 000047BA C3                  <1> 	retn 
   113                              <1> load_extended_dos_partitions:
   114 000047BB BE[BEE10000]        <1> 	mov	esi, PTable_hd0
   115 000047C0 BF[BEE20000]        <1> 	mov	edi, PTable_ep0
   116 000047C5 C605[09D80000]80    <1> 	mov	byte [hdc], 80h
   117                              <1> next_hd_extd_partition:
   118 000047CC 56                  <1> 	push	esi ; PTable_hd? offset
   119 000047CD 57                  <1> 	push	edi ; PTable_ep?
   120                              <1> 	;mov	ecx, 4
   121 000047CE B104                <1> 	mov	cl, 4
   122 000047D0 8A15[09D80000]      <1> 	mov	dl, byte [hdc]
   123                              <1> hd_check_fs_id_05h:
   124 000047D6 8A4604              <1> 	mov	al, [esi+ptFileSystemID]
   125 000047D9 3C05                <1> 	cmp	al, 05h ; Is it an extended dos partition ?
   126 000047DB 7404                <1> 	je	short loc_set_ep_start_sector
   127 000047DD 3C0F                <1> 	cmp	al, 0Fh ; Is it an extended win4 (LBA mode) partition ?
   128 000047DF 7546                <1> 	jne	short continue_to_check_ep
   129                              <1> loc_set_ep_start_sector:
   130 000047E1 FE05[C1E30000]      <1> 	inc	byte [EP_Counter]
   131 000047E7 88D4                <1> 	mov	ah, dl ; byte [hdc]
   132 000047E9 86E0                <1> 	xchg	ah, al ; al = Drv Number, ah = Partition Identifier
   133 000047EB 50                  <1> 	push	eax 
   134 000047EC 30E4                <1> 	xor	ah, ah  
   135 000047EE 2C80                <1> 	sub	al, 80h
   136 000047F0 50                  <1> 	push	eax
   137 000047F1 C0E002              <1> 	shl	al, 2 ; al = al * 4
   138 000047F4 0FB6D8              <1> 	movzx	ebx, al
   139 000047F7 81C3[C2E30000]      <1> 	add	ebx, EP_StartSector
   140 000047FD 8B4608              <1> 	mov	eax, [esi+ptStartSector]
   141                              <1>         ; EAX = Extended partition's start sector
   142 00004800 8903                <1>         mov	[ebx], eax
   143 00004802 58                  <1> 	pop	eax ; AL = Drv number - 80h, AH = 0 
   144 00004803 5A                  <1> 	pop	edx ; DL = Drv number, DH = Partition ID
   145 00004804 BB[BEDF0000]        <1> 	mov	ebx, MasterBootBuff
   146 00004809 803D[BFE30000]01    <1> 	cmp	byte [HD_LBA_yes], 1 ; LBA ready = Yes
   147 00004810 7240                <1> 	jb	short loc_hd_load_ep_05h
   148 00004812 80FE05              <1> 	cmp	dh, 05h
   149 00004815 743B                <1> 	je	short loc_hd_load_ep_05h
   150                              <1> loc_hd_load_ep_0Fh:
   151                              <1> 	; 04/01/2016
   152 00004817 51                  <1> 	push	ecx
   153 00004818 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 0000481B B41B                <1> 	mov	ah, 1Bh ; LBA read
   159 0000481D B001                <1> 	mov	al, 1 ; sector count
   160 0000481F E811E6FFFF          <1> 	call	int13h
   161 00004824 59                  <1> 	pop	ecx
   162 00004825 733F                <1> 	jnc	short loc_hd_move_ep_table
   163                              <1> continue_to_check_ep:
   164 00004827 83C610              <1> 	add	esi, 16
   165 0000482A E2AA                <1> 	loop	hd_check_fs_id_05h
   166                              <1> continue_check_ep_next_disk:
   167 0000482C 5F                  <1> 	pop	edi ; PTable_ep?
   168 0000482D 5E                  <1> 	pop	esi ; PTable_hd?
   169 0000482E A0[94DD0000]        <1> 	mov	al, [HF_NUM] ; number of hard disks
   170 00004833 047F                <1> 	add	al, 7Fh
   171 00004835 3805[09D80000]      <1> 	cmp	[hdc], al
   172 0000483B 0F8392000000        <1> 	jnb	loc_validating_hd_partitions_ok
   173 00004841 83C640              <1> 	add	esi, 64
   174 00004844 83C740              <1> 	add	edi, 64
   175 00004847 FE05[09D80000]      <1> 	inc	byte [hdc]
   176 0000484D E97AFFFFFF          <1> 	jmp	next_hd_extd_partition
   177                              <1> loc_hd_load_ep_05h:
   178 00004852 51                  <1> 	push	ecx 
   179 00004853 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   180 00004856 668B4E02            <1>         mov     cx, word [esi+ptBeginSector]
   181 0000485A 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   182                              <1> 	;mov	ebx, MasterBootBuff
   183 0000485E E8D2E5FFFF          <1> 	call	int13h
   184 00004863 59                  <1> 	pop	ecx  
   185 00004864 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 00004866 8B3C24              <1> 	mov	edi, [esp]        
   190 00004869 BE[7CE10000]        <1>         mov	esi, PartitionTable ; Extended
   191 0000486E 89F3                <1> 	mov	ebx, esi
   192                              <1> 	;mov	ecx, 16
   193 00004870 B110                <1> 	mov	cl, 16
   194 00004872 F3A5                <1>        	rep	movsd
   195 00004874 89DE                <1> 	mov	esi, ebx 
   196                              <1> loc_set_hde_sub_partition_count:
   197 00004876 C605[C0E30000]04    <1> 	mov	byte [PP_Counter], 4
   198                              <1> loc_validate_hde_partition:
   199 0000487D 807E0400            <1> 	cmp	byte [esi+ptFileSystemID], 0
   200 00004881 763F                <1> 	jna	short loc_validate_next_hde_partition2
   201 00004883 56                  <1> 	push	esi ; Extended partition table offset
   202 00004884 8A15[09D80000]      <1> 	mov	dl, byte [hdc]
   203 0000488A 0FB6C2              <1> 	movzx	eax, dl
   204 0000488D 2C80                <1> 	sub	al, 80h
   205 0000488F 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 00004892 88C1                <1> 	mov	cl, al
   211 00004894 80C104              <1> 	add	cl, 4
   212 00004897 2A0D[C0E30000]      <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 0000489D 88D5                <1>       	mov	ch, dl   
   217 0000489F 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 000048A2 51                  <1> 	push	ecx ; *
   222 000048A3 BF[C2E30000]        <1> 	mov	edi, EP_StartSector
   223 000048A8 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 000048AA E82A000000          <1> 	call	validate_hd_fat_partition
   228 000048AF 59                  <1> 	pop	ecx ; *
   229 000048B0 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 000048B2 66894E7C            <1> 	mov	[esi+LD_PartitionEntry], cx 
   236                              <1> 	;
   237 000048B6 8A0D[28C80000]      <1> 	mov	cl, [Last_DOS_DiskNo] 
   238 000048BC 80C141              <1> 	add	cl, 'A'
   239 000048BF 880E                <1> 	mov	[esi+LD_Name], cl
   240                              <1> loc_validate_next_hde_partition1:
   241 000048C1 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 000048C2 FE0D[C0E30000]      <1> 	dec	byte [PP_Counter]
   246 000048C8 0F845EFFFFFF        <1> 	jz	continue_check_ep_next_disk
   247 000048CE 83C610              <1> 	add 	esi, 16 ; 10h
   248 000048D1 EBAA                <1> 	jmp	short loc_validate_hde_partition
   249                              <1> loc_validating_hd_partitions_ok:
   250 000048D3 A0[28C80000]        <1> 	mov	al, [Last_DOS_DiskNo]
   251                              <1> loc_drv_init_retn:
   252 000048D8 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 000048D9 8A6604              <1> 	mov 	ah, [esi+ptFileSystemID]
   275 000048DC 80FC06              <1> 	cmp 	ah, 06h ; FAT16 CHS partition
   276                              <1> 	; 12/02/2016
   277                              <1> 	;jb	short loc_not_a_valid_fat_partition2
   278 000048DF 7305                <1>  	jnb	short vhdp_FAT16_32
   279                              <1> 	;
   280 000048E1 80FC04              <1> 	cmp	ah, 04h ; FAT16 CHS partition (< 32MB)		
   281 000048E4 7519                <1> 	jne	short loc_not_a_valid_fat_partition1
   282                              <1> vhdp_FAT16_32:
   283 000048E6 B002                <1> 	mov	al, 2
   284 000048E8 7417                <1> 	je	short loc_set_valid_hd_partition_params
   285 000048EA 80FC0E              <1> 	cmp	ah, 0Eh ; FAT16 LBA partition
   286 000048ED 7710                <1> 	ja	short loc_not_a_valid_fat_partition1
   287 000048EF 7410                <1> 	je	short loc_set_valid_hd_partition_params
   288                              <1> 
   289 000048F1 FEC0                <1> 	inc	al ; 3
   290 000048F3 80FC0B              <1> 	cmp	ah, 0Bh ; FAT32 CHS partition 
   291 000048F6 7409                <1> 	je	short loc_set_valid_hd_partition_params
   292 000048F8 7206                <1> 	jb	short loc_not_a_valid_fat_partition2
   293 000048FA 80FC0C              <1> 	cmp	ah, 0Ch ; FAT32 LBA partition
   294 000048FD 7402                <1> 	je	short loc_set_valid_hd_partition_params
   295                              <1> loc_not_a_valid_fat_partition1:
   296 000048FF F9                  <1> 	stc
   297                              <1> loc_not_a_valid_fat_partition2:
   298 00004900 C3                  <1> 	retn
   299                              <1> 
   300                              <1> loc_set_valid_hd_partition_params:
   301 00004901 FE05[28C80000]      <1> 	inc 	byte [Last_DOS_DiskNo] ; > 1
   302                              <1> 	;
   303 00004907 31DB                <1> 	xor	ebx, ebx
   304 00004909 8A3D[28C80000]      <1> 	mov	bh, [Last_DOS_DiskNo] ; * 256	
   305 0000490F 81C300010900        <1> 	add	ebx, Logical_DOSDisks
   306                              <1> 	;
   307 00004915 C6430102            <1> 	mov	byte [ebx+LD_DiskType], 2
   308 00004919 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 0000491C 66894303            <1> 	mov	word [ebx+LD_FATType], ax
   312                              <1> 	;
   313 00004920 8B4E08              <1> 	mov	ecx, [esi+ptStartSector]
   314 00004923 09FF                <1> 	or	edi, edi 
   315 00004925 7402                <1> 	jz	short pass_hd_FAT_ep_start_sector_adding
   316                              <1> loc_add_hd_FAT_ep_start_sector:
   317 00004927 030F                <1> 	add	ecx, [edi]
   318                              <1> pass_hd_FAT_ep_start_sector_adding:
   319 00004929 894B6C              <1> 	mov	[ebx+LD_StartSector], ecx
   320                              <1> loc_hd_FAT_logical_drv_init:
   321 0000492C 89DD                <1> 	mov	ebp, ebx
   322                              <1> 	;mov	dl, [ebx+LD_PhyDrvNo]
   323 0000492E A0[BFE30000]        <1> 	mov	al, [HD_LBA_yes] ; 07/01/2016
   324 00004933 884305              <1> 	mov	[ebx+LD_LBAYes], al
   325 00004936 BB[D2E30000]        <1> 	mov	ebx, DOSBootSectorBuff ; buffer address
   326 0000493B 08C0                <1> 	or	al, al
   327 0000493D 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 0000493F B41B                <1> 	mov	ah, 1Bh ; LBA read
   336 00004941 B001                <1> 	mov	al, 1 ; sector count
   337 00004943 E8EDE4FFFF          <1> 	call	int13h
   338 00004948 7313                <1> 	jnc	short loc_hd_drv_FAT_boot_validation
   339                              <1> loc_not_a_valid_fat_partition3:
   340 0000494A C3                  <1> 	retn
   341                              <1> loc_hd_FAT_drv_init_load_bs_chs:
   342 0000494B 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   343 0000494E 668B4E02            <1> 	mov	cx, [esi+ptBeginSector]
   344 00004952 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   345                              <1> 	;mov	ebx, DOSBootSectorBuff
   346 00004956 E8DAE4FFFF          <1> 	call	int13h
   347 0000495B 72ED                <1> 	jc	short loc_not_a_valid_fat_partition3
   348                              <1> loc_hd_drv_FAT_boot_validation:
   349                              <1> 	;mov	esi, DOSBootSectorBuff
   350 0000495D 89DE                <1> 	mov	esi, ebx
   351 0000495F 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
   352 00004968 751A                <1> 	jne	short loc_not_a_valid_fat_partition4
   353 0000496A 807E15F8            <1> 	cmp	byte [esi+BPB_Media], 0F8h
   354 0000496E 7514                <1> 	jne	short loc_not_a_valid_fat_partition4
   355 00004970 66837E1600          <1> 	cmp	word [esi+BPB_FATSz16], 0
   356 00004975 770F                <1> 	ja	short loc_hd_FAT16_BPB
   357 00004977 807E4229            <1> 	cmp	byte [esi+BS_FAT32_BootSig], 29h
   358 0000497B 7507                <1> 	jne	short loc_not_a_valid_fat_partition4
   359                              <1> loc_hd_FAT32_BPB:
   360 0000497D B92D000000          <1> 	mov	ecx, 45
   361 00004982 EB0D                <1> 	jmp	short loc_hd_move_FAT_BPB
   362                              <1> 	;
   363                              <1> loc_not_a_valid_fat_partition4:
   364 00004984 F9                  <1> 	stc
   365 00004985 C3                  <1> 	retn
   366                              <1> 	;
   367                              <1> loc_hd_FAT16_BPB:
   368 00004986 807E2629            <1> 	cmp	byte [esi+BS_BootSig], 29h
   369 0000498A 75F8                <1> 	jne	short loc_not_a_valid_fat_partition4
   370 0000498C B920000000          <1> 	mov	ecx, 32
   371                              <1> loc_hd_move_FAT_BPB:
   372 00004991 89EF                <1> 	mov 	edi, ebp
   373                              <1> 	;mov	esi, ebx ; Boot sector
   374 00004993 57                  <1> 	push	edi
   375 00004994 83C706              <1> 	add	edi, LD_BPB
   376 00004997 F366A5              <1> 	rep	movsw 
   377 0000499A 5E                  <1> 	pop	esi
   378 0000499B 0FB74614            <1> 	movzx	eax, word [esi+LD_BPB+BPB_RsvdSecCnt]
   379 0000499F 03466C              <1> 	add	eax, [esi+LD_StartSector]
   380 000049A2 894660              <1> 	mov	[esi+LD_FATBegin], eax
   381 000049A5 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3
   382 000049A9 7224                <1> 	jb	short loc_set_FAT16_RootDirLoc
   383                              <1> loc_set_FAT32_RootDirLoc:
   384 000049AB 8B462A              <1> 	mov	eax, [esi+LD_BPB+BPB_FATSz32]
   385 000049AE 0FB65E16            <1>         movzx	ebx, byte [esi+LD_BPB+BPB_NumFATs]
   386 000049B2 F7E3                <1> 	mul	ebx
   387 000049B4 034660              <1> 	add	eax, [esi+LD_FATBegin]
   388                              <1> loc_set_FAT32_data_begin:
   389 000049B7 894668              <1> 	mov	[esi+LD_DATABegin], eax
   390 000049BA 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 000049BD 8B4632              <1> 	mov	eax, [esi+LD_BPB+BPB_RootClus]
   395 000049C0 83E802              <1> 	sub	eax, 2
   396 000049C3 7442                <1> 	jz	short short loc_set_32bit_FAT_total_sectors  
   397                              <1> 	;movzx	ebx, byte [esi+LD_BPB+BPB_SecPerClust]
   398 000049C5 8A5E13              <1> 	mov	bl, byte [esi+LD_BPB+BPB_SecPerClust] 
   399 000049C8 F7E3                <1> 	mul	ebx
   400 000049CA 014664              <1> 	add	[esi+LD_ROOTBegin], eax
   401 000049CD EB38                <1> 	jmp	short loc_set_32bit_FAT_total_sectors
   402                              <1> 	;
   403                              <1> loc_set_FAT16_RootDirLoc:
   404 000049CF 0FB64616            <1> 	movzx	eax, byte [esi+LD_BPB+BPB_NumFATs]
   405 000049D3 0FB7561C            <1> 	movzx	edx, word [esi+LD_BPB+BPB_FATSz16]
   406 000049D7 F7E2                <1> 	mul	edx
   407 000049D9 034660              <1> 	add	eax, [esi+LD_FATBegin]  
   408 000049DC 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
   409                              <1> loc_set_FAT16_data_begin:
   410 000049DF 894668              <1> 	mov	[esi+LD_DATABegin], eax 
   411 000049E2 B820000000          <1> 	mov	eax, 20h  ; Size of a directory entry
   412                              <1> 	;movzx	edx, word [esi+LD_BPB+BPB_RootEntCnt]
   413 000049E7 668B5617            <1>         mov     dx, [esi+LD_BPB+BPB_RootEntCnt]
   414 000049EB F7E2                <1>         mul	edx
   415                              <1> 	;mov	ecx, 511
   416 000049ED 66B9FF01            <1> 	mov	cx, 511
   417 000049F1 01C8                <1> 	add	eax, ecx
   418 000049F3 41                  <1> 	inc	ecx ; 512
   419 000049F4 F7F1                <1> 	div	ecx
   420 000049F6 014668              <1> 	add	[esi+LD_DATABegin], eax
   421 000049F9 0FB74619            <1> 	movzx	eax, word [esi+LD_BPB+BPB_TotalSec16]
   422 000049FD 6685C0              <1> 	test	ax, ax
   423 00004A00 7405                <1> 	jz	short loc_set_32bit_FAT_total_sectors
   424                              <1> loc_set_16bit_FAT_total_sectors:
   425 00004A02 894670              <1> 	mov	[esi+LD_TotalSectors], eax
   426 00004A05 EB06                <1> 	jmp	short loc_set_hd_FAT_cluster_count
   427                              <1> loc_set_32bit_FAT_total_sectors:
   428 00004A07 8B4626              <1> 	mov	eax, [esi+LD_BPB+BPB_TotalSec32]
   429 00004A0A 894670              <1> 	mov	[esi+LD_TotalSectors], eax
   430                              <1> loc_set_hd_FAT_cluster_count:
   431 00004A0D 8B5668              <1> 	mov	edx, [esi+LD_DATABegin]
   432 00004A10 2B566C              <1> 	sub	edx, [esi+LD_StartSector]
   433 00004A13 29D0                <1> 	sub	eax, edx
   434 00004A15 31D2                <1> 	xor	edx, edx ; 0
   435 00004A17 0FB64E13            <1>         movzx   ecx, byte [esi+LD_BPB+BPB_SecPerClust]
   436 00004A1B F7F1                <1>         div	ecx 
   437 00004A1D 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 00004A20 E859010000          <1> 	call	get_free_FAT_sectors
   443 00004A25 7207                <1> 	jc	short loc_validate_hd_FAT_partition_retn
   444 00004A27 894674              <1> 	mov	[esi+LD_FreeSectors], eax
   445 00004A2A 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 00004A2E 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 00004A2F 8A6604              <1> 	mov	ah, [esi+ptFileSystemID]
   472 00004A32 80FCA1              <1> 	cmp	ah, 0A1h ; SINGLIX FS1 (trfs1) partition
   473 00004A35 7549                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   474                              <1> loc_set_valid_hd_fs_partition_params:
   475 00004A37 FE05[28C80000]      <1> 	inc	byte [Last_DOS_DiskNo] ; > 1
   476 00004A3D 30C0                <1> 	xor	al, al ; mov al, 0
   477                              <1> 	;mov	[drv], dl
   478 00004A3F 29DB                <1> 	sub	ebx, ebx ; 0
   479 00004A41 8A3D[28C80000]      <1> 	mov	bh, [Last_DOS_DiskNo] 
   480 00004A47 81C300010900        <1> 	add	ebx, Logical_DOSDisks
   481 00004A4D C6430102            <1> 	mov	byte [ebx+LD_DiskType], 2
   482 00004A51 885302              <1> 	mov	[ebx+LD_PhyDrvNo], dl
   483                              <1> 	;mov	[ebx+LD_FATType], al ; 0
   484                              <1> 	;mov	[ebx+LD_FSType], ah
   485 00004A54 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 00004A58 89DD                <1> 	mov	ebp, ebx ; 10/01/2016
   490                              <1> 	;mov	dl, [ebx+LD_PhyDrvNo]
   491 00004A5A A0[BFE30000]        <1> 	mov	al, [HD_LBA_yes] ; 10/01/2016
   492 00004A5F 884305              <1> 	mov	[ebx+LD_LBAYes], al
   493 00004A62 89DE                <1> 	mov	esi, ebx
   494 00004A64 BB[D2E30000]        <1> 	mov	ebx, DOSBootSectorBuff ; buffer addressh
   495 00004A69 08C0                <1> 	or	al, al
   496 00004A6B 7515                <1> 	jnz	short loc_hd_fs_drv_init_load_bs_lba
   497                              <1> loc_hd_fs_drv_init_load_bs_chs:
   498 00004A6D 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   499 00004A70 668B4E02            <1> 	mov	cx, [esi+ptBeginSector]
   500 00004A74 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   501                              <1> 	;mov	ebx, DOSBootSectorBuff
   502 00004A78 E8B8E3FFFF          <1> 	call	int13h
   503 00004A7D 7311                <1> 	jnc	short loc_hd_drv_fs_boot_validation
   504                              <1> loc_validate_hd_fs_partition_err_retn:
   505 00004A7F C3                  <1> 	retn
   506                              <1> loc_validate_hd_fs_partition_stc_retn:
   507 00004A80 F9                  <1> 	stc
   508 00004A81 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 00004A82 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 00004A85 B41B                <1> 	mov	ah, 1Bh ; LBA read
   518 00004A87 B001                <1> 	mov	al, 1 ; sector count
   519 00004A89 E8A7E3FFFF          <1> 	call	int13h
   520 00004A8E 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 00004A90 89DE                <1> 	mov	esi, ebx ; Boot sector buffer
   524 00004A92 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
   525 00004A9B 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 00004A9D 66817E035346        <1> 	cmp	word [esi+bs_FS_Identifier], 'SF'
   529 00004AA3 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 00004AA5 807E09A1            <1> 	cmp	byte [esi+bs_FS_PartitionID], 0A1h
   533 00004AA9 75D5                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   534                              <1> 	;
   535 00004AAB 89EF                <1> 	mov	edi, ebp ; 10/01/2016
   536                              <1> 	;
   537 00004AAD 8A462D              <1> 	mov	al, byte [esi+bs_FS_LBA_Ready]
   538 00004AB0 884705              <1> 	mov	[edi+LD_FS_LBAYes], al
   539                              <1> 	;
   540                              <1> 	; 03/01/2010 CHS -> DOS FAT/BPB compatibility fix
   541 00004AB3 8A4608              <1> 	mov	al, [esi+bs_FS_MediaAttrib]
   542 00004AB6 884706              <1> 	mov	byte [edi+LD_FS_MediaAttrib], al
   543                              <1> 	;
   544 00004AB9 8A460A              <1> 	mov	al, [esi+bs_FS_VersionMaj]
   545 00004ABC 884707              <1> 	mov	[edi+LD_FS_VersionMajor], al
   546                              <1> 	;
   547 00004ABF 668B4606            <1> 	mov	ax, [esi+bs_FS_BytesPerSec]
   548 00004AC3 66894711            <1> 	mov	[edi+LD_FS_BytesPerSec], ax
   549 00004AC7 8A462E              <1> 	mov	al, [esi+bs_FS_SecPerTrack]
   550 00004ACA 6698                <1> 	cbw
   551 00004ACC 6689471E            <1> 	mov	[edi+LD_FS_SecPerTrack], ax
   552 00004AD0 8A462F              <1> 	mov	al, [esi+bs_FS_Heads]
   553                              <1> 	;cbw
   554 00004AD3 66894720            <1> 	mov	[edi+LD_FS_NumHeads], ax
   555                              <1> 	;
   556 00004AD7 8B4628              <1> 	mov	eax, [esi+bs_FS_UnDelDirD]
   557 00004ADA 894722              <1> 	mov	[edi+LD_FS_UnDelDirD], eax
   558 00004ADD 8B5618              <1> 	mov	edx, [esi+bs_FS_MATLocation]
   559 00004AE0 89570C              <1> 	mov	[edi+LD_FS_MATLocation], edx
   560 00004AE3 8B461C              <1> 	mov	eax, [esi+bs_FS_RootDirD]
   561 00004AE6 894708              <1> 	mov	[edi+LD_FS_RootDirD], eax
   562 00004AE9 8B460C              <1> 	mov	eax, [esi+bs_FS_BeginSector]
   563 00004AEC 89476C              <1> 	mov	[edi+LD_FS_BeginSector], eax
   564 00004AEF 8B4710              <1> 	mov	eax, [edi+bs_FS_VolumeSize]
   565 00004AF2 894770              <1> 	mov	[edi+LD_FS_VolumeSize], eax
   566                              <1> 	;
   567 00004AF5 89D0                <1> 	mov	eax, edx ; [edi+LD_FS_MATLocation]
   568 00004AF7 03476C              <1> 	add	eax, [edi+LD_FS_BeginSector]
   569 00004AFA 89FE                <1> 	mov	esi, edi
   570                              <1> mread_hd_fs_MAT_sector:
   571                              <1>        ;mov	ebx, DOSBootSectorBuff
   572 00004AFC B901000000          <1> 	mov	ecx, 1
   573 00004B01 E837790000          <1> 	call	disk_read
   574 00004B06 7248                <1> 	jc	short loc_validate_hd_fs_partition_retn
   575                              <1> 	; EDI will not be changed
   576 00004B08 89DE                <1> 	mov	esi, ebx
   577                              <1> use_hdfs_mat_sector_params:
   578 00004B0A 8B460C              <1> 	mov	eax, [esi+FS_MAT_DATLocation]
   579 00004B0D 894714              <1> 	mov	[edi+LD_FS_DATLocation], eax
   580 00004B10 8B4610              <1> 	mov	eax, [esi+FS_MAT_DATScount]
   581 00004B13 894718              <1> 	mov	[edi+LD_FS_DATSectors], eax
   582 00004B16 8B4614              <1> 	mov	eax, [esi+FS_MAT_FreeSectors]
   583 00004B19 894774              <1>         mov     [edi+LD_FS_FreeSectors], eax
   584 00004B1C 8B4618              <1> 	mov	eax, [esi+FS_MAT_FirstFreeSector]
   585 00004B1F 894778              <1> 	mov	[edi+LD_FS_FirstFreeSector], eax
   586 00004B22 8B4708              <1> 	mov	eax, [edi+LD_FS_RootDirD]
   587 00004B25 03476C              <1> 	add	eax, [edi+LD_FS_BeginSector]
   588 00004B28 89FE                <1> 	mov	esi, edi   
   589                              <1> read_hd_fs_RDT_sector:
   590 00004B2A BB[D2E30000]        <1> 	mov	ebx, DOSBootSectorBuff
   591                              <1> 	;mov	ecx, 1
   592 00004B2F B101                <1> 	mov	cl, 1
   593 00004B31 E807790000          <1> 	call	disk_read
   594 00004B36 7218                <1> 	jc	short loc_validate_hd_fs_partition_retn
   595                              <1> 	; EDI will not be changed
   596 00004B38 89DE                <1> 	mov	esi, ebx
   597                              <1> use_hdfs_RDT_sector_params:
   598 00004B3A 8B461C              <1> 	mov	eax, [esi+FS_RDT_VolumeSerialNo]
   599 00004B3D 894728              <1> 	mov	[edi+LD_FS_VolumeSerial], eax
   600 00004B40 57                  <1> 	push	edi
   601                              <1> 	;mov	ecx, 16
   602 00004B41 B110                <1> 	mov	cl, 16
   603 00004B43 83C640              <1> 	add	esi, FS_RDT_VolumeName
   604 00004B46 83C72C              <1> 	add	edi, LD_FS_VolumeName
   605 00004B49 F3A5                <1> 	rep	movsd ; 64 bytes
   606 00004B4B 5E                  <1> 	pop	esi
   607                              <1> 		; Volume Name Reset
   608 00004B4C 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 00004B50 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 00004B51 B40D                <1> 	mov	ah, 0Dh ; Alternate disk reset
   622 00004B53 E8DDE2FFFF          <1> 	call	int13h
   623 00004B58 7301                <1> 	jnc	short pass_reset_error
   624                              <1> harddisk_error:
   625 00004B5A C3                  <1>   	retn
   626                              <1> pass_reset_error:
   627 00004B5B BB[BEDF0000]        <1> 	mov	ebx, MasterBootBuff
   628 00004B60 66B80102            <1> 	mov	ax, 0201h
   629 00004B64 66B90100            <1> 	mov	cx, 1
   630 00004B68 30F6                <1> 	xor	dh, dh
   631 00004B6A E8C6E2FFFF          <1>  	call	int13h
   632 00004B6F 72E9                <1> 	jc	short harddisk_error
   633                              <1> 	;
   634 00004B71 66813D[BCE10000]55- <1> 	cmp	word [MBIDCode], 0AA55h
   634 00004B79 AA                  <1>
   635 00004B7A 7401                <1> 	je	short load_masterboot_ok
   636 00004B7C F9                  <1> 	stc
   637                              <1> load_masterboot_ok:
   638 00004B7D 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 00004B7E 31C0                <1> 	xor	eax, eax
   653                              <1> 	;mov	[esi+LD_FreeSectors], eax ; Reset
   654                              <1> 	
   655 00004B80 807E0302            <1>         cmp     byte [esi+LD_FATType], 2
   656 00004B84 7650                <1> 	jna	short loc_gfc_get_fat_free_clusters
   657                              <1> 
   658                              <1> 	; 29/02/2016
   659 00004B86 48                  <1> 	dec	eax ; 0FFFFFFFFh
   660 00004B87 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count (reset)
   661 00004B8A 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; First Free Cluster (reset)
   662 00004B8D 40                  <1> 	inc	eax ; 0
   663                              <1> 	;
   664 00004B8E 668B4636            <1> 	mov	ax, [esi+LD_BPB+BPB_FSInfo]
   665 00004B92 03466C              <1> 	add	eax, [esi+LD_StartSector]
   666                              <1> 
   667 00004B95 BB[D2E30000]        <1> 	mov	ebx, DOSBootSectorBuff
   668 00004B9A B901000000          <1> 	mov	ecx, 1
   669 00004B9F E899780000          <1>  	call	disk_read
   670 00004BA4 7301                <1> 	jnc	short loc_gfc_check_fsinfo_signs
   671                              <1> retn_gfc_get_fsinfo_sec:
   672 00004BA6 C3                  <1> 	retn
   673                              <1> 
   674                              <1> loc_gfc_check_fsinfo_signs:
   675 00004BA7 BB[D2E30000]        <1> 	mov 	ebx, DOSBootSectorBuff ; 13/02/2016
   676 00004BAC 813B52526141        <1>         cmp     dword [ebx], 41615252h
   677 00004BB2 7520                <1> 	jne	short retn_gfc_get_fsinfo_stc
   678                              <1> 	;add	ebx, 484
   679                              <1> 	;cmp	dword [ebx], 61417272h
   680 00004BB4 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
   680 00004BBD 61                  <1>
   681 00004BBE 7514                <1> 	jne	short retn_gfc_get_fsinfo_stc
   682                              <1> 	;add	ebx, 4
   683                              <1> 	;mov	eax, [ebx]
   684 00004BC0 8B83E8010000        <1> 	mov	eax, [ebx+488]
   685                              <1> 	; 29/02/2016
   686 00004BC6 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count
   687 00004BC9 8B93EC010000        <1> 	mov	edx,  [ebx+492] 
   688 00004BCF 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; First Free Cluster
   689                              <1> 	;
   690 00004BD2 EB12                <1> 	jmp	short retn_from_get_free_fat32_clusters
   691                              <1> 
   692                              <1> retn_gfc_get_fsinfo_stc:
   693 00004BD4 F9                  <1> 	stc
   694 00004BD5 C3                  <1> 	retn
   695                              <1> 
   696                              <1> loc_gfc_get_fat_free_clusters:
   697                              <1> 	;mov	eax, 2
   698 00004BD6 B002                <1> 	mov	al, 2
   699                              <1> 	;mov	[FAT_CurrentCluster], eax
   700                              <1> loc_gfc_loop_get_next_cluster:
   701 00004BD8 E805500000          <1> 	call	get_next_cluster
   702 00004BDD 730E                <1> 	jnc	short loc_gfc_free_fat_clusters_cont
   703 00004BDF 21C0                <1> 	and	eax, eax
   704 00004BE1 7411                <1> 	jz	short loc_gfc_pass_inc_free_cluster_count
   705                              <1>  
   706                              <1> retn_from_get_free_fat_clusters:
   707 00004BE3 8B4674              <1> 	mov	eax, [esi+LD_FreeSectors] ; Free clusters !
   708                              <1> retn_from_get_free_fat32_clusters:
   709 00004BE6 0FB65E13            <1>         movzx	ebx, byte [esi+LD_BPB+BPB_SecPerClust]
   710 00004BEA F7E3                <1>       	mul	ebx
   711                              <1> 	;mov	[esi+LD_FreeSectors], eax ; Free sectors
   712                              <1> retn_get_free_sectors_calc:
   713 00004BEC C3                  <1> 	retn
   714                              <1> 
   715                              <1> loc_gfc_free_fat_clusters_cont:
   716 00004BED 09C0                <1> 	or	eax, eax
   717 00004BEF 7503                <1> 	jnz	short loc_gfc_pass_inc_free_cluster_count
   718 00004BF1 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 00004BF4 89C8                <1> 	mov	eax, ecx ; [FAT_CurrentCluster]
   723 00004BF6 3B4678              <1> 	cmp	eax, [esi+LD_Clusters]
   724 00004BF9 77E8                <1> 	ja	short retn_from_get_free_fat_clusters
   725 00004BFB 40                  <1> 	inc	eax
   726                              <1> 	;mov	[FAT_CurrentCluster], eax
   727 00004BFC 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 00004BFE BE[0AD80000]        <1> 	mov	esi, fd0_type ; 10/01/2016
   742 00004C03 BF00010900          <1> 	mov	edi, Logical_DOSDisks
   743 00004C08 08D2                <1> 	or	dl, dl
   744 00004C0A 7407                <1> 	jz	short loc_drv_init_fd0_fd1
   745 00004C0C 81C700010000        <1> 	add	edi, 100h
   746 00004C12 46                  <1> 	inc	esi ; fd1_type ; 10/01/2016
   747                              <1> loc_drv_init_fd0_fd1:
   748 00004C13 C6477E00            <1> 	mov	byte [edi+LD_MediaChanged], 0
   749 00004C17 803E01              <1> 	cmp	byte [esi], 1 ; type (>0 if it is existing) 
   750                              <1> 		; 4 = 1.44 MB, 80 track, 3 1/2"
   751 00004C1A 7221                <1> 	jb	short read_fd_boot_sector_retn
   752 00004C1C 885702              <1> 	mov	[edi+LD_PhyDrvNo], dl
   753                              <1> read_fd_boot_sector:
   754 00004C1F 30F6                <1> 	xor	dh, dh
   755 00004C21 B904000000          <1> 	mov	ecx, 4 ; Retry Count
   756                              <1> read_fd_boot_sector_again:
   757 00004C26 51                  <1> 	push 	ecx
   758                              <1> 	;mov	cx, 1
   759 00004C27 B101                <1> 	mov	cl, 1
   760 00004C29 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   761 00004C2D BB[D2E30000]        <1> 	mov	ebx, DOSBootSectorBuff
   762 00004C32 E8FEE1FFFF          <1> 	call	int13h
   763 00004C37 59                  <1> 	pop	ecx
   764 00004C38 7304                <1> 	jnc	short use_fd_boot_sector_params
   765 00004C3A E2EA                <1> 	loop	read_fd_boot_sector_again
   766                              <1> 
   767                              <1> read_fd_boot_sector_stc_retn:
   768 00004C3C F9                  <1> 	stc
   769                              <1> read_fd_boot_sector_retn:
   770 00004C3D C3                  <1> 	retn
   771                              <1> 
   772                              <1> use_fd_boot_sector_params:
   773                              <1> 	;mov	esi, DOSBootSectorBuff
   774 00004C3E 89DE                <1> 	mov	esi, ebx
   775 00004C40 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
   776 00004C49 75F1                <1> 	jne	short read_fd_boot_sector_stc_retn
   777 00004C4B 66817E035346        <1>         cmp     word [esi+bs_FS_Identifier], 'SF'
   778 00004C51 0F85A2000000        <1>         jne     use_fd_fatfs_boot_sector_params
   779                              <1> 	;
   780 00004C57 8A462D              <1> 	mov	al, [esi+bs_FS_LBA_Ready]
   781 00004C5A 884705              <1> 	mov	[edi+LD_FS_LBAYes], al
   782                              <1> 	;
   783                              <1> 	; 03/01/2010 CHS -> DOS FAT/BPB compatibility fix
   784 00004C5D 8A4608              <1> 	mov	al, [esi+bs_FS_MediaAttrib]
   785 00004C60 884706              <1> 	mov	[edi+LD_FS_MediaAttrib], al
   786                              <1> 	;
   787 00004C63 8A460A              <1>         mov	al, [esi+bs_FS_VersionMaj]
   788 00004C66 884707              <1> 	mov	byte [edi+LD_FS_VersionMajor], al
   789 00004C69 668B4606            <1> 	mov	ax, [esi+bs_FS_BytesPerSec]
   790 00004C6D 66894711            <1> 	mov	[edi+LD_FS_BytesPerSec], ax
   791 00004C71 8A462E              <1> 	mov	al, [esi+bs_FS_SecPerTrack]
   792 00004C74 6698                <1> 	cbw
   793 00004C76 6689471E            <1> 	mov	[edi+LD_FS_SecPerTrack], ax
   794 00004C7A 8A462F              <1> 	mov	al, [esi+bs_FS_Heads]
   795                              <1> 	;cbw
   796 00004C7D 66894720            <1> 	mov	[edi+LD_FS_NumHeads], ax
   797                              <1> 	;
   798 00004C81 8B4628              <1> 	mov	eax, [esi+bs_FS_UnDelDirD]
   799 00004C84 894722              <1> 	mov	[edi+LD_FS_UnDelDirD], eax
   800 00004C87 8B4618              <1> 	mov	eax, [esi+bs_FS_MATLocation]
   801 00004C8A 89470C              <1> 	mov	[edi+LD_FS_MATLocation], eax
   802 00004C8D 8B461C              <1> 	mov	eax, [esi+bs_FS_RootDirD]
   803 00004C90 894708              <1> 	mov	[edi+LD_FS_RootDirD], eax
   804 00004C93 8B460C              <1> 	mov	eax, [esi+bs_FS_BeginSector]
   805 00004C96 89476C              <1> 	mov	[edi+LD_FS_BeginSector], eax
   806 00004C99 8B4610              <1> 	mov	eax, [esi+bs_FS_VolumeSize]
   807 00004C9C 894770              <1> 	mov	[edi+LD_FS_VolumeSize], eax
   808                              <1> 	;		
   809 00004C9F 89FE                <1> 	mov	esi, edi
   810 00004CA1 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 00004CA4 B101                <1> 	mov	cl, 1
   816 00004CA6 E898770000          <1> 	call	chs_read
   817 00004CAB 89DE                <1> 	mov	esi, ebx
   818 00004CAD 7301                <1> 	jnc	short use_fdfs_mat_sector_params
   819                              <1> 	;jmp	short read_fd_boot_sector_retn
   820 00004CAF C3                  <1> 	retn
   821                              <1> use_fdfs_mat_sector_params:
   822 00004CB0 8B460C              <1> 	mov	eax, [esi+FS_MAT_DATLocation]
   823 00004CB3 894714              <1> 	mov	[edi+LD_FS_DATLocation], eax
   824 00004CB6 8B4610              <1> 	mov	eax, [esi+FS_MAT_DATScount]
   825 00004CB9 894718              <1> 	mov	[edi+LD_FS_DATSectors], eax
   826 00004CBC 8B4714              <1> 	mov	eax, [edi+FS_MAT_FreeSectors]
   827 00004CBF 894774              <1> 	mov	[edi+LD_FS_FreeSectors], eax
   828 00004CC2 8B4618              <1> 	mov	eax, [esi+FS_MAT_FirstFreeSector]
   829 00004CC5 894778              <1> 	mov	[edi+LD_FS_FirstFreeSector], eax
   830                              <1> 	;
   831 00004CC8 89FE                <1> 	mov	esi, edi
   832 00004CCA 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 00004CCD B101                <1> 	mov	cl, 1
   837 00004CCF E86F770000          <1> 	call	chs_read
   838 00004CD4 89DE                <1> 	mov	esi, ebx
   839 00004CD6 7220                <1> 	jc	short read_fd_RDT_sector_retn
   840                              <1> use_fdfs_RDT_sector_params:
   841 00004CD8 8B461C              <1> 	mov	eax, [esi+FS_RDT_VolumeSerialNo]
   842 00004CDB 894728              <1> 	mov	[edi+LD_FS_VolumeSerial], eax
   843 00004CDE 57                  <1> 	push	edi
   844                              <1> 	;mov	ecx, 16
   845 00004CDF B110                <1> 	mov	cl, 16	
   846 00004CE1 83C640              <1> 	add	esi, FS_RDT_VolumeName
   847 00004CE4 83C72C              <1> 	add	edi, LD_FS_VolumeName
   848 00004CE7 F3A5                <1> 	rep	movsd ; 64 bytes
   849 00004CE9 5E                  <1> 	pop	esi
   850 00004CEA C6460300            <1> 	mov	byte [esi+LD_FATType], 0
   851 00004CEE C64604A1            <1> 	mov	byte [esi+LD_FSType], 0A1h  
   852 00004CF2 E9AA000000          <1>         jmp     loc_cont_use_fd_boot_sector_params
   853                              <1> 
   854                              <1> read_fd_RDT_sector_stc_retn:
   855 00004CF7 F9                  <1> 	stc
   856                              <1> read_fd_RDT_sector_retn:
   857 00004CF8 C3                  <1> 	retn
   858                              <1> 
   859                              <1> use_fd_fatfs_boot_sector_params:
   860 00004CF9 807E2629            <1> 	cmp	byte [esi+BS_BootSig], 29h
   861 00004CFD 75F8                <1> 	jne	short read_fd_RDT_sector_stc_retn
   862 00004CFF 807E15F0            <1> 	cmp	byte [esi+BPB_Media], 0F0h
   863 00004D03 72F3                <1> 	jb	short read_fd_RDT_sector_retn
   864 00004D05 57                  <1> 	push	edi
   865 00004D06 83C706              <1> 	add	edi, LD_BPB
   866                              <1> 	;mov	ecx, 16
   867 00004D09 B110                <1> 	mov	cl, 16
   868 00004D0B F3A5                <1> 	rep	movsd ; 64 bytes 
   869 00004D0D 5E                  <1> 	pop	esi
   870 00004D0E 31C0                <1> 	xor	eax, eax
   871 00004D10 89466C              <1> 	mov	[esi+LD_StartSector], eax ; 0
   872 00004D13 668B461C            <1> 	mov	ax, [esi+LD_BPB+BPB_FATSz16]
   873 00004D17 8A4E16              <1> 	mov	cl, [esi+LD_BPB+BPB_NumFATs] 
   874 00004D1A F7E1                <1>   	mul	ecx
   875                              <1> 	; edx = 0 !
   876 00004D1C 668B5614            <1> 	mov	dx, [esi+LD_BPB+BPB_RsvdSecCnt]
   877 00004D20 66895660            <1> 	mov	[esi+LD_FATBegin], dx
   878                              <1> 	;add	eax, edx
   879 00004D24 6601D0              <1> 	add	ax, dx
   880 00004D27 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
   881 00004D2A 894668              <1> 	mov	[esi+LD_DATABegin], eax 
   882 00004D2D 668B5617            <1> 	mov	dx, [esi+LD_BPB+BPB_RootEntCnt]
   883                              <1> 	;shl	edx, 5 ; * 32 (Size of a directory entry)
   884 00004D31 66C1E205            <1> 	shl	dx, 5
   885                              <1> 	;add	edx, 511
   886 00004D35 6681C2FF01          <1> 	add	dx, 511
   887                              <1> 	;shr	edx, 9 ; edx = ((edx*32)+511) / 512
   888 00004D3A 66C1EA09            <1> 	shr	dx, 9
   889 00004D3E 015668              <1> 	add 	[esi+LD_DATABegin], edx
   890                              <1> 	;movzx	eax, word [esi+LD_BPB+BPB_TotalSec16]
   891 00004D41 668B4619            <1> 	mov	ax, [esi+LD_BPB+BPB_TotalSec16]
   892 00004D45 894670              <1> 	mov	[esi+LD_TotalSectors], eax
   893 00004D48 2B4668              <1> 	sub	eax, [esi+LD_DATABegin]
   894                              <1>   	;movzx	ecx, byte [esi+LD_BPB+BPB_SecPerClust]
   895 00004D4B 8A4E13              <1> 	mov	cl, [esi+LD_BPB+BPB_SecPerClust]  
   896 00004D4E 80F901              <1> 	cmp	cl, 1
   897 00004D51 7605                <1> 	jna	short save_fd_fatfs_cluster_count
   898                              <1> 	;sub	edx, edx
   899 00004D53 6629D2              <1> 	sub	dx, dx ; 0
   900 00004D56 F7F1                <1> 	div	ecx
   901                              <1> save_fd_fatfs_cluster_count:
   902 00004D58 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 00004D5B 29C0                <1> 	sub	eax, eax ; 0  
   909 00004D5D A2[D6E50000]        <1> 	mov	[FAT_BuffValidData], al ; 0
   910 00004D62 A2[D7E50000]        <1> 	mov	[FAT_BuffDrvName], al ; 0
   911 00004D67 A3[DAE50000]        <1> 	mov	[FAT_BuffSector], eax ; 0
   912                              <1> 
   913                              <1> read_fd_FAT_sectors:
   914 00004D6C BB001C0900          <1>   	mov	ebx, FAT_Buffer
   915 00004D71 668B4614            <1> 	mov	ax, [esi+LD_BPB+BPB_RsvdSecCnt]
   916                              <1> 	;mov	ecx, 3
   917 00004D75 B103                <1> 	mov	cl, 3 ; 3 sectors
   918 00004D77 E8C7760000          <1> 	call	chs_read
   919 00004D7C 7240                <1> 	jc	short read_fd_FAT_sectors_retn
   920                              <1> use_fd_FAT_sectors:
   921 00004D7E 8A4602              <1> 	mov	al, [esi+LD_PhyDrvNo]
   922 00004D81 0441                <1> 	add	al, 'A' 
   923 00004D83 A2[D7E50000]        <1> 	mov	[FAT_BuffDrvName], al 
   924 00004D88 C605[D6E50000]01    <1>  	mov	byte [FAT_BuffValidData], 1
   925 00004D8F E82B000000          <1> 	call	fd_init_calculate_free_clusters
   926 00004D94 7228                <1> 	jc	short read_fd_FAT_sectors_retn
   927                              <1>   
   928                              <1> loc_use_fd_boot_sector_params_FAT:
   929 00004D96 C6460301            <1> 	mov	byte [esi+LD_FATType], 1 ; FAT 12
   930 00004D9A C6460401            <1> 	mov	byte [esi+LD_FSType], 1
   931 00004D9E 8B462D              <1>         mov     eax, [esi+LD_BPB+VolumeID]
   932                              <1> loc_cont_use_fd_boot_sector_params:
   933 00004DA1 8A7E02              <1> 	mov	bh, [esi+LD_PhyDrvNo]
   934 00004DA4 887E7D              <1> 	mov	[esi+LD_DParamEntry], bh
   935 00004DA7 88FB                <1> 	mov	bl, bh
   936 00004DA9 80C341              <1> 	add	bl, 'A'
   937 00004DAC 881E                <1> 	mov	byte [esi+LD_Name], bl
   938 00004DAE C6460101            <1> 	mov	byte [esi+LD_DiskType], 1
   939 00004DB2 C6460500            <1> 	mov	byte [esi+LD_LBAYes], 0
   940 00004DB6 C6467C00            <1> 	mov	byte [esi+LD_PartitionEntry], 0
   941 00004DBA C6467E06            <1> 	mov	byte [esi+LD_MediaChanged], 6 ; Volume Name Reset
   942                              <1> 
   943                              <1> read_fd_FAT_sectors_retn:
   944 00004DBE 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 00004DBF 29C0                <1> 	sub	eax, eax
   955 00004DC1 894674              <1> 	mov	[esi+LD_FreeSectors], eax ; 0
   956 00004DC4 B002                <1> 	mov	al, 2 ; eax = 2
   957                              <1> 
   958                              <1> fd_init_loop_get_next_cluster:
   959 00004DC6 E830000000          <1> 	call	fd_init_get_next_cluster
   960 00004DCB 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 00004DCD 6621C0              <1> 	and	ax, ax
   968 00004DD0 7504                <1> 	jnz	short fd_init_pass_inc_free_cluster_count
   969                              <1> 	;inc	dword [esi+LD_FreeSectors]
   970 00004DD2 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 00004DD6 66A1[D2E50000]      <1> 	mov	ax, [FAT_CurrentCluster]
   975                              <1> 	;cmp	eax, [esi+LD_Clusters]
   976 00004DDC 663B4678            <1> 	cmp	ax, [esi+LD_Clusters]
   977 00004DE0 7704                <1> 	ja	short short retn_from_fd_init_calculate_free_clusters
   978                              <1> 	;inc	eax
   979 00004DE2 6640                <1> 	inc	ax
   980 00004DE4 EBE0                <1> 	jmp	short fd_init_loop_get_next_cluster
   981                              <1> 
   982                              <1> retn_from_fd_init_calculate_free_clusters:
   983 00004DE6 8A4613              <1>   	mov	al, [esi+LD_BPB+BPB_SecPerClust]
   984 00004DE9 3C01                <1>   	cmp	al, 1
   985 00004DEB 760D                <1> 	jna	short fd_init_calculate_free_clusters_retn
   986                              <1> 	;movzx	eax, al
   987 00004DED 6698                <1> 	cbw
   988                              <1> 	;mov	ecx, [esi+LD_FreeSectors]
   989 00004DEF 668B4E74            <1> 	mov	cx, [esi+LD_FreeSectors] ; Count of free clusters
   990                              <1>   	;mul	ecx
   991 00004DF3 66F7E1              <1> 	mul	cx
   992                              <1> 	;mov	[esi+LD_FreeSectors], eax
   993 00004DF6 66894674            <1> 	mov	[esi+LD_FreeSectors], ax
   994                              <1> fd_init_calculate_free_clusters_retn:
   995 00004DFA 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 00004DFB A3[D2E50000]        <1> 	mov	[FAT_CurrentCluster], eax
  1010                              <1> fd_init_get_next_cluster_readnext:
  1011 00004E00 29D2                <1> 	sub	edx, edx ; 0
  1012 00004E02 BB00040000          <1>   	mov	ebx, 1024 ; 400h
  1013 00004E07 F7F3                <1>   	div	ebx
  1014                              <1>   	; EAX = Count of 3 FAT sectors
  1015                              <1>   	; EDX = Buffer entry index
  1016 00004E09 89C1                <1> 	mov	ecx, eax
  1017                              <1> 	;mov	eax, 3
  1018 00004E0B B003                <1> 	mov	al, 3
  1019 00004E0D F7E2                <1> 	mul	edx ; Multiply by 3
  1020 00004E0F 66D1E8              <1> 	shr	ax, 1 ; Divide by 2
  1021 00004E12 89C3                <1> 	mov	ebx, eax ; Buffer byte offset
  1022 00004E14 81C3001C0900        <1> 	add	ebx, FAT_Buffer
  1023 00004E1A 89C8                <1> 	mov	eax, ecx
  1024                              <1> 	;mov	edx, 3
  1025 00004E1C 66BA0300            <1> 	mov	dx, 3
  1026 00004E20 F7E2                <1> 	mul	edx 
  1027                              <1>   	; EAX = FAT Beginning Sector
  1028                              <1> 	; EDX = 0
  1029 00004E22 8A0E                <1> 	mov	cl, [esi+LD_Name]
  1030                              <1> 	;cmp	byte [FAT_BuffValidData], 0
  1031                              <1> 	;jna	short fd_init_load_FAT_sectors0
  1032 00004E24 3A0D[D7E50000]      <1> 	cmp	cl, [FAT_BuffDrvName]
  1033 00004E2A 751E                <1> 	jne	short fd_init_load_FAT_sectors0
  1034 00004E2C 3B05[DAE50000]      <1> 	cmp	eax, [FAT_BuffSector]
  1035 00004E32 751C                <1> 	jne	short fd_init_load_FAT_sectors1
  1036                              <1> 	;mov	eax, [FAT_CurrentCluster]
  1037 00004E34 A0[D2E50000]        <1> 	mov	al, [FAT_CurrentCluster]
  1038                              <1> 	;shr	eax, 1
  1039 00004E39 D0E8                <1> 	shr	al, 1
  1040 00004E3B 668B03              <1> 	mov	ax, [ebx]
  1041 00004E3E 7306                <1>   	jnc	short fd_init_gnc_even
  1042 00004E40 66C1E804            <1> 	shr	ax, 4
  1043                              <1> fd_init_gnc_clc_retn:
  1044 00004E44 F8                  <1> 	clc
  1045 00004E45 C3                  <1> 	retn
  1046                              <1> 
  1047                              <1> fd_init_gnc_even:
  1048 00004E46 80E40F              <1> 	and	ah, 0Fh
  1049 00004E49 C3                  <1> 	retn
  1050                              <1> 
  1051                              <1> fd_init_load_FAT_sectors0:
  1052 00004E4A 880D[D7E50000]      <1> 	mov 	[FAT_BuffDrvName], cl
  1053                              <1> fd_init_load_FAT_sectors1:
  1054 00004E50 C605[D6E50000]00    <1> 	mov	byte [FAT_BuffValidData], 0
  1055 00004E57 A3[DAE50000]        <1> 	mov	[FAT_BuffSector], eax
  1056 00004E5C 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1057 00004E5F BB001C0900          <1>  	mov	ebx, FAT_Buffer
  1058                              <1> 	;movzx	ecx, word [esi+LD_BPB+BPB_FATSz16]
  1059 00004E64 668B4E1C            <1> 	mov	cx, [esi+LD_BPB+BPB_FATSz16]
  1060 00004E68 662B0D[DAE50000]    <1> 	sub	cx, [FAT_BuffSector]
  1061                              <1>         ;cmp	ecx, 3
  1062 00004E6F 6683F903            <1> 	cmp	cx, 3
  1063 00004E73 7605                <1> 	jna	short fdinit_pass_fix_sector_count_3
  1064                              <1> 	;mov	ecx, 3
  1065 00004E75 B903000000          <1> 	mov	ecx, 3
  1066                              <1> fdinit_pass_fix_sector_count_3:  
  1067 00004E7A E8C4750000          <1> 	call	chs_read
  1068 00004E7F 730D                <1> 	jnc	short fd_init_FAT_sectors_no_load_error
  1069 00004E81 C605[D6E50000]00    <1> 	mov	byte [FAT_BuffValidData], 0
  1070                              <1> 		; Drv not ready or read Error !
  1071 00004E88 B80F000000          <1> 	mov	eax, ERR_DRV_NOT_RDY ; 15
  1072                              <1> 	;xor	edx, edx
  1073 00004E8D C3                  <1> 	retn
  1074                              <1> 
  1075                              <1> fd_init_FAT_sectors_no_load_error:
  1076 00004E8E C605[D6E50000]01    <1> 	mov	byte [FAT_BuffValidData], 1
  1077 00004E95 A1[D2E50000]        <1> 	mov	eax, [FAT_CurrentCluster]
  1078 00004E9A 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 00004E9F 89DE                <1> 	mov	esi, ebx
  1096 00004EA1 81E600FF0000        <1> 	and	esi, 0FF00h ; esi = bh
  1097 00004EA7 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1098 00004EAD 8A06                <1> 	mov     al, [esi+LD_Name]
  1099 00004EAF 8A6603              <1> 	mov     ah, [esi+LD_FATType]
  1100 00004EB2 80FC01              <1> 	cmp     ah, 1
  1101 00004EB5 7210                <1> 	jb    	short loc_gfvn_dir_load_err
  1102 00004EB7 3C41                <1> 	cmp 	al, 'A'
  1103 00004EB9 720C                <1> 	jb      short loc_gfvn_dir_load_err
  1104 00004EBB 80FC02              <1> 	cmp 	ah, 2 
  1105 00004EBE 7708                <1> 	ja      short get_FAT32_root_cluster
  1106                              <1> 	
  1107 00004EC0 E8784E0000          <1> 	call    load_FAT_root_directory
  1108 00004EC5 730B                <1> 	jnc     short loc_get_volume_name
  1109                              <1> 
  1110                              <1> loc_gfvn_dir_load_err:
  1111 00004EC7 C3                  <1> 	retn
  1112                              <1> 
  1113                              <1> get_FAT32_root_cluster:
  1114 00004EC8 8B4632              <1> 	mov	eax, [esi+LD_BPB+BPB_RootClus]
  1115 00004ECB E8F84E0000          <1> 	call    load_FAT_sub_directory
  1116 00004ED0 7224                <1> 	jc	short loc_get_volume_name_retn
  1117                              <1> 
  1118                              <1> loc_get_volume_name:
  1119 00004ED2 BE00000800          <1>         mov     esi, Directory_Buffer
  1120 00004ED7 6631C9              <1> 	xor	cx, cx ; 0
  1121                              <1> check_root_volume_name:
  1122 00004EDA 8A06                <1> 	mov	al, [esi]
  1123 00004EDC 08C0                <1> 	or      al, al
  1124 00004EDE 7416                <1> 	jz      short loc_get_volume_name_retn
  1125 00004EE0 807E0B08            <1> 	cmp     byte [esi+0Bh], 08h
  1126 00004EE4 7410                <1> 	je      short loc_get_volume_name_retn
  1127 00004EE6 663B0D[EBE50000]    <1> 	cmp     cx, [DirBuff_LastEntry]
  1128 00004EED 7308                <1> 	jnb     short pass_check_root_volume_name
  1129 00004EEF 6641                <1> 	inc     cx
  1130 00004EF1 83C620              <1> 	add     esi, 32
  1131 00004EF4 EBE4                <1> 	jmp     short check_root_volume_name
  1132                              <1> 
  1133                              <1> loc_get_volume_name_retn:
  1134 00004EF6 C3                  <1> 	retn
  1135                              <1>     
  1136                              <1> pass_check_root_volume_name:
  1137 00004EF7 803D[E7E50000]03    <1> 	cmp	byte [DirBuff_FATType], 3
  1138 00004EFE 7230                <1> 	jb	short loc_get_volume_name_retn_xor
  1139                              <1> 
  1140 00004F00 BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1141 00004F05 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1142 00004F0A 31C0                <1> 	xor	eax, eax
  1143 00004F0C 8A25[E6E50000]      <1> 	mov	ah, [DirBuff_DRV]
  1144 00004F12 80EC41              <1> 	sub	ah, 'A' 
  1145 00004F15 01C6                <1> 	add	esi, eax
  1146 00004F17 A1[EDE50000]        <1> 	mov	eax, [DirBuff_Cluster]
  1147 00004F1C E8C14C0000          <1> 	call	get_next_cluster
  1148 00004F21 7305                <1> 	jnc 	short loc_gfvn_load_FAT32_dir_cluster
  1149                              <1>   	
  1150 00004F23 83F801              <1> 	cmp     eax, 1
  1151 00004F26 F5                  <1> 	cmc
  1152 00004F27 C3                  <1> 	retn
  1153                              <1>   
  1154                              <1> loc_gfvn_load_FAT32_dir_cluster:
  1155 00004F28 E89B4E0000          <1> 	call	load_FAT_sub_directory
  1156 00004F2D 73A3                <1> 	jnc	short loc_get_volume_name
  1157 00004F2F C3                  <1> 	retn
  1158                              <1> 
  1159                              <1> loc_get_volume_name_retn_xor:
  1160 00004F30 31C0                <1> 	xor 	eax, eax
  1161 00004F32 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 00004F33 B416                <1> 	mov	ah, 16h
  1173 00004F35 E8FBDEFFFF          <1>   	call	int13h
  1174 00004F3A 80FC06              <1> 	cmp	ah, 06h
  1175 00004F3D 7405                <1> 	je	short loc_gmc_status_retn
  1176 00004F3F 08E4                <1> 	or	ah, ah
  1177 00004F41 7401                <1> 	jz	short loc_gmc_status_retn
  1178                              <1> loc_gmc_status_stc_retn:    
  1179 00004F43 F9                  <1> 	stc
  1180                              <1> loc_gmc_status_retn:
  1181 00004F44 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 00004F45 31DB                <1> 	xor	ebx, ebx
    33 00004F47 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 00004F49 BE00010900          <1> 	mov	esi, Logical_DOSDisks
    42 00004F4E 01DE                <1> 	add	esi, ebx
    43                              <1> loc_ccdrv_dos_drive_name_check:
    44 00004F50 80FA02              <1> 	cmp	dl, 2
    45 00004F53 720F                <1> 	jb	short loc_ccdrv_dos_drive_name_check_ok
    46                              <1> 
    47 00004F55 8A06                <1> 	mov	al, [esi+LD_Name]
    48 00004F57 2C41                <1> 	sub	al, 'A'
    49 00004F59 38D0                <1> 	cmp	al, dl
    50 00004F5B 7407                <1> 	je	short loc_ccdrv_dos_drive_name_check_ok
    51                              <1> 
    52                              <1> loc_ccdrv_drive_not_ready_err:
    53 00004F5D B815000000          <1> 	mov	eax, 15h ; Drive not ready
    54                              <1> loc_change_current_drive_stc_retn:
    55 00004F62 F9                  <1> 	stc
    56 00004F63 C3                  <1> 	retn  
    57                              <1> 
    58                              <1> loc_ccdrv_dos_drive_name_check_ok:
    59 00004F64 8A667E              <1> 	mov	ah, [esi+LD_MediaChanged]
    60 00004F67 80FC06              <1> 	cmp	ah, 6  ; VOLUME NAME CHECK/MOVE SIGN
    61 00004F6A 7450                <1> 	je	short loc_ccdrv_get_FAT_volume_name_0
    62                              <1> 
    63 00004F6C 80FA01              <1> 	cmp	dl, 1
    64 00004F6F 7778                <1> 	ja	short loc_gmcs_init_drv_hd
    65                              <1> 
    66                              <1> loc_gmcs_init_drv_fd:
    67 00004F71 08E4                <1> 	or	ah, ah 
    68                              <1> 	; AH = 1 is initialization sign (invalid_fd_parameter)
    69 00004F73 7517                <1> 	jnz	short loc_ccdrv_call_fd_init
    70                              <1> 
    71 00004F75 E8B9FFFFFF          <1> 	call	get_media_change_status
    72 00004F7A 72E1                <1> 	jc	short loc_ccdrv_drive_not_ready_err
    73                              <1> 
    74 00004F7C 20E4                <1> 	and	ah, ah
    75 00004F7E 7471                <1> 	jz	short loc_change_current_drv3
    76                              <1> 
    77 00004F80 80F406              <1> 	xor	ah, 6
    78 00004F83 75D8                <1> 	jnz	short loc_ccdrv_drive_not_ready_err
    79                              <1> 
    80                              <1> loc_ccdrv_call_fd_init_check_vol_id:
    81 00004F85 E8440A0000          <1> 	call	get_volume_serial_number
    82 00004F8A 7308                <1> 	jnc	short loc_ccdrv_check_vol_serial
    83                              <1> 
    84                              <1> loc_ccdrv_call_fd_init:
    85 00004F8C E86DFCFFFF          <1> 	call	floppy_drv_init
    86 00004F91 7315                <1> 	jnc	short loc_reset_drv_fd_current_dir
    87                              <1> 
    88                              <1> loc_ccdrv_fdinit_fail_retn:
    89 00004F93 C3                  <1> 	retn
    90                              <1> 
    91                              <1> loc_ccdrv_check_vol_serial:
    92 00004F94 A3[B4DD0000]        <1> 	mov	[Current_VolSerial], eax
    93                              <1> 	;mov	dl, bh
    94 00004F99 E860FCFFFF          <1> 	call	floppy_drv_init
    95 00004F9E 72F3                <1> 	jc	short loc_ccdrv_fdinit_fail_retn
    96                              <1> 
    97 00004FA0 3B05[B4DD0000]      <1> 	cmp	eax, [Current_VolSerial]
    98 00004FA6 7445                <1> 	je	short loc_change_current_drv2
    99                              <1> 
   100                              <1> loc_reset_drv_fd_current_dir:
   101 00004FA8 31C0                <1> 	xor	eax, eax              
   102 00004FAA 88467F              <1>         mov	[esi+LD_CDirLevel], al
   103 00004FAD 89F7                <1> 	mov	edi, esi
   104 00004FAF 81C780000000        <1> 	add	edi, LD_CurrentDirectory
   105 00004FB5 B920000000          <1> 	mov	ecx, 32
   106 00004FBA F3AB                <1> 	rep	stosd   
   107                              <1>  
   108                              <1> loc_ccdrv_get_FAT_volume_name_0:
   109 00004FBC 8A4603              <1> 	mov	al, [esi+LD_FATType]
   110 00004FBF 08C0                <1> 	or	al, al
   111 00004FC1 742A                <1> 	jz	short loc_change_current_drv2
   112                              <1> 
   113 00004FC3 56                  <1> 	push	esi 
   114 00004FC4 3C02                <1> 	cmp	al, 2
   115 00004FC6 7705                <1> 	ja	short loc_ccdrv_get_FAT32_vol_name
   116                              <1>              
   117                              <1> loc_ccdrv_get_FAT2_16_vol_name:
   118 00004FC8 83C631              <1> 	add	esi, LD_BPB + VolumeLabel
   119 00004FCB EB03                <1> 	jmp	short loc_ccdrv_get_FAT_volume_name_1
   120                              <1> 
   121                              <1> loc_ccdrv_get_FAT32_vol_name:
   122 00004FCD 83C64D              <1> 	add	esi, LD_BPB + FAT32_VolLab
   123                              <1> loc_ccdrv_get_FAT_volume_name_1:
   124 00004FD0 53                  <1> 	push	ebx
   125 00004FD1 56                  <1> 	push	esi
   126 00004FD2 E8C8FEFFFF          <1> 	call	get_FAT_volume_name
   127 00004FD7 5F                  <1> 	pop	edi
   128 00004FD8 5B                  <1> 	pop	ebx
   129                              <1> 	; BL = 0
   130 00004FD9 720B                <1> 	jc	short loc_change_current_drv1
   131 00004FDB 20C0                <1> 	and	al, al
   132 00004FDD 7407                <1> 	jz	short loc_change_current_drv1
   133                              <1> 
   134                              <1> loc_ccdrv_move_FAT_volume_name:
   135 00004FDF B90B000000          <1> 	mov	ecx, 11
   136 00004FE4 F3A4                <1> 	rep	movsb
   137                              <1> 
   138                              <1> loc_change_current_drv1:
   139 00004FE6 5E                  <1> 	pop	esi
   140 00004FE7 EB04                <1> 	jmp	short loc_change_current_drv2
   141                              <1> 
   142                              <1> loc_gmcs_init_drv_hd:
   143 00004FE9 08E4                <1> 	or	ah, ah
   144 00004FEB 7404                <1> 	jz	short loc_change_current_drv3
   145                              <1> 	; BL = 0, BH = Logical DOS drive number
   146                              <1> loc_change_current_drv2:
   147 00004FED C6467E00            <1> 	mov	byte [esi+LD_MediaChanged], 0
   148                              <1> loc_change_current_drv3:
   149 00004FF1 883D[BEDD0000]      <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 00004FF7 8A4603              <1> 	mov	al, [esi+LD_FATType]
   168 00004FFA A2[BDDD0000]        <1> 	mov	[Current_FATType], al
   169                              <1> 
   170 00004FFF 8A26                <1> 	mov	ah, [esi+LD_Name] 
   171 00005001 8825[BFDD0000]      <1> 	mov	[Current_Dir_Drv], ah
   172                              <1> 
   173 00005007 20C0                <1> 	and	al, al
   174 00005009 741D                <1> 	jz	short loc_restore_FS_current_directory
   175                              <1> 
   176                              <1> loc_restore_FAT_current_directory:
   177 0000500B 8A667F              <1> 	mov	ah, [esi+LD_CDirLevel]
   178 0000500E 8825[BCDD0000]      <1> 	mov	[Current_Dir_Level], ah
   179 00005014 08E4                <1> 	or	ah, ah
   180 00005016 7416                <1>         jz	short loc_ccdrv_reset_cdir_FAT_12_16_32_fcluster
   181                              <1> 
   182 00005018 0FB6D4              <1> 	movzx	edx, ah
   183 0000501B C0E204              <1> 	shl	dl, 4 ; * 16
   184 0000501E 01F2                <1>         add	edx, esi
   185 00005020 8B828C000000        <1> 	mov	eax, [edx+LD_CurrentDirectory+12]
   186 00005026 EB2C                <1> 	jmp	short loc_ccdrv_reset_cdir_FAT_fcluster
   187                              <1> 
   188                              <1> loc_restore_FS_current_directory:
   189 00005028 E8D64D0000          <1> 	call	load_current_FS_directory 
   190 0000502D C3                  <1> 	retn 
   191                              <1> 
   192                              <1> loc_ccdrv_reset_cdir_FAT_12_16_32_fcluster:
   193 0000502E 3C03                <1> 	cmp	al, 3
   194 00005030 7205                <1> 	jb	short loc_ccdrv_reset_cdir_FAT_12_16_fcluster
   195                              <1> loc_ccdrv_reset_cdir_FAT32_fcluster:
   196 00005032 8B4632              <1> 	mov	eax, [esi+LD_BPB+FAT32_RootFClust]
   197 00005035 EB04                <1> 	jmp	short loc_ccdrv_check_rootdir_sign
   198                              <1> loc_ccdrv_reset_cdir_FAT_12_16_fcluster:   
   199 00005037 30C0                <1> 	xor	al, al  ; xor eax, eax
   200 00005039 31D2                <1> 	xor	edx, edx
   201                              <1> loc_ccdrv_check_rootdir_sign:
   202 0000503B 80BE8000000000      <1> 	cmp	byte [esi+LD_CurrentDirectory], 0
   203 00005042 7510                <1> 	jne	short loc_ccdrv_reset_cdir_FAT_fcluster
   204                              <1> loc_ccdrv_set_rootdir_FAT_fcluster:
   205 00005044 89868C000000        <1>         mov     [esi+LD_CurrentDirectory+12], eax
   206 0000504A C78680000000524F4F- <1> 	mov	dword [esi+LD_CurrentDirectory], 'ROOT'
   206 00005053 54                  <1>
   207                              <1> 
   208                              <1> loc_ccdrv_reset_cdir_FAT_fcluster:
   209 00005054 A3[B8DD0000]        <1> 	mov	[Current_Dir_FCluster], eax
   210                              <1> 
   211 00005059 BF[1FE60000]        <1> 	mov	edi, PATH_Array
   212 0000505E 89F2                <1> 	mov	edx, esi
   213 00005060 81C680000000        <1> 	add	esi, LD_CurrentDirectory
   214 00005066 B920000000          <1> 	mov	ecx, 32
   215 0000506B F3A5                <1> 	rep	movsd
   216                              <1> 
   217 0000506D E8852D0000          <1> 	call	change_prompt_dir_string
   218                              <1> 	
   219 00005072 89D6                <1> 	mov	esi, edx
   220                              <1> 	
   221 00005074 29C0                <1>         sub	eax, eax
   222                              <1>        ;sub	edx, edx
   223 00005076 BF[BFDD0000]        <1> 	mov	edi, Current_Dir_Drv
   224                              <1> 
   225 0000507B A2[29C80000]        <1> 	mov	[Restore_CDIR], al ; 0
   226 00005080 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 00005081 C705[6CEA0000]-     <1> 	mov	dword [mainprog_return_addr], return_from_command_intepreter
   238 00005087 [35510000]          <1>
   239                              <1> 
   240                              <1> loc_TRDOS_prompt:
   241 0000508B BF[BEDE0000]        <1> 	mov	edi, TextBuffer
   242 00005090 C6075B              <1> 	mov	byte [edi], "["
   243 00005093 47                  <1> 	inc	edi
   244 00005094 BE[7CC80000]        <1> 	mov	esi, TRDOSPromptLabel
   245                              <1> get_next_prompt_label_char:
   246 00005099 803E20              <1> 	cmp	byte [esi], 20h
   247 0000509C 7203                <1> 	jb	short pass_prompt_label
   248 0000509E A4                  <1> 	movsb
   249 0000509F EBF8                <1> 	jmp	short get_next_prompt_label_char
   250                              <1> pass_prompt_label:
   251 000050A1 C6075D              <1> 	mov	byte [edi], "]"
   252 000050A4 47                  <1> 	inc	edi
   253 000050A5 C60720              <1> 	mov	byte [edi], 20h
   254 000050A8 47                  <1> 	inc	edi
   255 000050A9 BE[BFDD0000]        <1> 	mov	esi, Current_Dir_Drv
   256 000050AE 66A5                <1> 	movsw
   257 000050B0 A4                  <1> 	movsb 
   258                              <1> loc_prompt_current_directory:
   259 000050B1 803E20              <1> 	cmp	byte [esi], 20h
   260 000050B4 7203                <1> 	jb	short pass_prompt_current_directory
   261 000050B6 A4                  <1> 	movsb
   262 000050B7 EBF8                <1> 	jmp	short loc_prompt_current_directory  
   263                              <1> pass_prompt_current_directory:
   264 000050B9 C6073E              <1> 	mov	byte [edi], '>'
   265 000050BC 47                  <1> 	inc	edi
   266 000050BD C60700              <1> 	mov	byte [edi], 0  
   267 000050C0 BE[BEDE0000]        <1> 	mov	esi, TextBuffer
   268 000050C5 E876F5FFFF          <1> 	call	print_msg
   269                              <1>         
   270                              <1> 	;sub	bh, bh ; video page = 0
   271                              <1> 	;call	get_cpos ; get cursor position
   272 000050CA 668B15[16DD0000]    <1> 	mov	dx, [CURSOR_POSN] ; video page 0
   273 000050D1 8815[1EDE0000]      <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 000050D7 E899000000          <1> 	call	rw_char
   293                              <1> loc_move_command:
   294 000050DC BE[6EDE0000]        <1> 	mov	esi, CommandBuffer
   295 000050E1 89F7                <1> 	mov	edi, esi
   296 000050E3 31C9                <1> 	xor	ecx, ecx
   297                              <1> first_command_char:
   298 000050E5 AC                  <1> 	lodsb
   299 000050E6 3C20                <1> 	cmp	al, 20h
   300 000050E8 772E                <1> 	ja	short pass_space_control
   301 000050EA 7241                <1> 	jb	short loc_move_cmd_arguments_ok
   302 000050EC 81FE[BDDE0000]      <1> 	cmp	esi, CommandBuffer + 79
   303 000050F2 72F1                <1> 	jb	short first_command_char
   304 000050F4 EB37                <1> 	jmp	short loc_move_cmd_arguments_ok
   305                              <1> 
   306                              <1> next_command_char:
   307 000050F6 AC                  <1> 	lodsb
   308 000050F7 3C20                <1> 	cmp	al, 20h
   309 000050F9 771D                <1> 	ja	short pass_space_control
   310 000050FB 7230                <1> 	jb	short loc_move_cmd_arguments_ok
   311                              <1> 
   312                              <1> loc_1st_cmd_arg: ; 30/01/2016
   313 000050FD AC                  <1> 	lodsb
   314 000050FE 3C20                <1> 	cmp	al, 20h
   315 00005100 74FB                <1> 	je	short loc_1st_cmd_arg
   316 00005102 7229                <1> 	jb	short loc_move_cmd_arguments_ok
   317                              <1> 	
   318 00005104 C60700              <1>         mov     byte [edi], 0
   319 00005107 47                  <1> 	inc	edi
   320                              <1> 
   321                              <1> loc_move_cmd_arguments:
   322 00005108 AA                  <1> 	stosb
   323 00005109 81FE[BDDE0000]      <1> 	cmp	esi, CommandBuffer + 79
   324 0000510F 731C                <1> 	jnb	short loc_move_cmd_arguments_ok
   325 00005111 AC                  <1>         lodsb
   326 00005112 3C20                <1> 	cmp	al, 20h
   327 00005114 73F2                <1> 	jnb	short loc_move_cmd_arguments
   328 00005116 EB15                <1> 	jmp	short loc_move_cmd_arguments_ok
   329                              <1> 
   330                              <1> pass_space_control:
   331 00005118 3C61                <1> 	cmp	al, 61h
   332 0000511A 7206                <1> 	jb	short pass_capitalize
   333 0000511C 3C7A                <1> 	cmp	al, 7Ah
   334 0000511E 7702                <1> 	ja	short pass_capitalize
   335 00005120 24DF                <1> 	and	al, 0DFh
   336                              <1> pass_capitalize:
   337 00005122 AA                  <1> 	stosb   
   338 00005123 FEC1                <1> 	inc     cl
   339 00005125 81FE[BDDE0000]      <1>         cmp     esi, CommandBuffer + 79
   340 0000512B 72C9                <1> 	jb      short next_command_char 
   341                              <1> 
   342                              <1> loc_move_cmd_arguments_ok:
   343 0000512D C60700              <1>         mov     byte [edi], 0
   344                              <1>        
   345                              <1> call_command_intepreter:
   346 00005130 E8D4080000          <1> 	call    command_interpreter
   347                              <1> 
   348                              <1> return_from_command_intepreter:
   349 00005135 B950000000          <1>         mov	ecx, 80
   350                              <1> 	;mov	cx, 80
   351 0000513A BF[6EDE0000]        <1> 	mov	edi, CommandBuffer
   352 0000513F 30C0                <1> 	xor	al, al
   353 00005141 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 00005143 803D[26D30000]03    <1> 	cmp	byte [CRT_MODE], 3 ; 80*25 color
   359 0000514A 741D                <1> 	je	short pass_set_txt_mode
   360                              <1> 
   361 0000514C E890C2FFFF          <1> 	call	set_txt_mode ; set vide mode to 03h
   362                              <1> 
   363                              <1> loc_check_active_page:
   364 00005151 30C0                <1> 	xor	al, al
   365 00005153 3805[26DD0000]      <1> 	cmp	[ACTIVE_PAGE], al ; 0
   366 00005159 0F842CFFFFFF        <1>         je      loc_TRDOS_prompt 
   367                              <1> 	; AL = 0 = video page 0
   368 0000515F E8D8C4FFFF          <1> 	call	set_active_page
   369 00005164 E922FFFFFF          <1>         jmp     loc_TRDOS_prompt ; infinitive loop
   370                              <1> 
   371                              <1> pass_set_txt_mode: 
   372 00005169 BE[9CD90000]        <1> 	mov	esi, nextline
   373 0000516E E8CDF4FFFF          <1> 	call	print_msg
   374 00005173 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 00005175 30E4                <1> 	xor     ah, ah
   390 00005177 E83AB9FFFF          <1> 	call	int16h
   391 0000517C 20C0                <1> 	and	al, al
   392 0000517E 7434                <1> 	jz	short loc_arrow    
   393 00005180 3CE0                <1> 	cmp	al, 0E0h          
   394 00005182 7430                <1> 	je	short loc_arrow
   395 00005184 3C08                <1> 	cmp	al, 08h             
   396 00005186 7544                <1> 	jne	short char_return
   397                              <1> loc_back:
   398 00005188 3A15[1EDE0000]      <1> 	cmp	dl, [CursorColumn]
   399 0000518E 76E5                <1> 	jna     short readnextchar
   400                              <1> prev_column:
   401 00005190 FECA                <1> 	dec	dl
   402                              <1> set_cursor_pos:
   403 00005192 6652                <1> 	push	dx
   404                              <1> 	;xor	bh, bh ; 0 = video page 0
   405                              <1> 	; DH = Row, DL = Column
   406 00005194 E8ECC7FFFF          <1> 	call	_set_cpos ; 17/01/2016
   407 00005199 665A                <1>         pop	dx
   408                              <1> 	;movzx	ebx, dl
   409 0000519B 88D3                <1> 	mov	bl, dl
   410 0000519D 2A1D[1EDE0000]      <1> 	sub	bl, [CursorColumn] 
   411 000051A3 B020                <1> 	mov	al, 20h
   412 000051A5 8883[6EDE0000]      <1> 	mov	[CommandBuffer+ebx], al
   413                              <1> 	;sub	bh, bh ; video page 0
   414                              <1> 	;mov	cx, 1
   415 000051AB B307                <1> 	mov	bl, 7 ; color attribute
   416 000051AD E8D7C6FFFF          <1> 	call	_write_c_current ; 17/01/2016
   417                              <1> 	;mov	dx, [CURSOR_POSN]
   418 000051B2 EBC1                <1> 	jmp	short readnextchar
   419                              <1> loc_arrow:    
   420 000051B4 80FC4B              <1> 	cmp	ah, 4Bh
   421 000051B7 74CF                <1> 	je	short loc_back
   422 000051B9 80FC53              <1> 	cmp	ah, 53h
   423 000051BC 74CA                <1> 	je      short loc_back
   424 000051BE 80FC4D              <1> 	cmp	ah, 4Dh
   425 000051C1 75B2                <1> 	jne	short readnextchar
   426 000051C3 80FA4F              <1> 	cmp	dl, 79
   427 000051C6 73AD                <1> 	jnb	short readnextchar
   428 000051C8 FEC2                <1> 	inc	dl
   429 000051CA EBC6                <1> 	jmp	short set_cursor_pos
   430                              <1> char_return:
   431 000051CC 0FB6DA              <1> 	movzx	ebx, dl
   432 000051CF 2A1D[1EDE0000]      <1> 	sub	bl, [CursorColumn] 
   433 000051D5 3C20                <1> 	cmp	al, 20h
   434 000051D7 7220                <1> 	jb	short loc_escape
   435 000051D9 8883[6EDE0000]      <1> 	mov	[CommandBuffer+ebx], al
   436 000051DF 80FA4F              <1> 	cmp	dl, 79
   437 000051E2 7391                <1> 	jnb	short readnextchar
   438 000051E4 66BB0700            <1> 	mov	bx, 7 ; color attribute
   439 000051E8 E802C7FFFF          <1> 	call	_write_tty
   440 000051ED 668B15[16DD0000]    <1> 	mov	dx, [CURSOR_POSN] ; video page 0
   441 000051F4 E97CFFFFFF          <1>         jmp     readnextchar
   442                              <1> loc_escape:
   443 000051F9 3C1B                <1> 	cmp	al, 1Bh
   444 000051FB 7418                <1> 	je	short rw_char_retn
   445                              <1> 	;
   446 000051FD 3C0D                <1> 	cmp	al, 0Dh ; CR
   447 000051FF 0F8570FFFFFF        <1>         jne     readnextchar
   448                              <1> 	; 13/05/2016
   449 00005205 66BB0700            <1> 	mov	bx, 7 ; attribute/color (bl)
   450                              <1> 		      ; video page 0 (bh=0)	
   451 00005209 E8E1C6FFFF          <1> 	call	_write_tty
   452                              <1> 	;mov	bx, 7  ; attribute/color
   453                              <1> 		      ; video page 0 (bh=0)
   454 0000520E B00A                <1> 	mov	al, 0Ah ; LF
   455 00005210 E8DAC6FFFF          <1> 	call	_write_tty
   456                              <1> rw_char_retn:
   457 00005215 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 00005216 E84FF1FFFF          <1> 	call	RTC_40	; GET RTC DATE
   466                              <1> 
   467 0000521B 88D0                <1> 	mov	al, dl
   468 0000521D E88BB8FFFF          <1>   	call	bcd_to_ascii
   469 00005222 66A3[71C90000]      <1> 	mov	[Day], ax
   470                              <1> 
   471 00005228 88F0                <1> 	mov	al, dh
   472 0000522A E87EB8FFFF          <1>   	call	bcd_to_ascii
   473 0000522F 66A3[74C90000]      <1> 	mov	[Month], ax
   474                              <1> 
   475 00005235 88E8                <1> 	mov	al, ch
   476 00005237 E871B8FFFF          <1>   	call	bcd_to_ascii
   477 0000523C 66A3[77C90000]      <1> 	mov	[Century], ax
   478                              <1> 
   479 00005242 88C8                <1> 	mov	al, cl
   480 00005244 E864B8FFFF          <1>   	call	bcd_to_ascii
   481 00005249 66A3[79C90000]      <1> 	mov	word [Year], ax
   482                              <1> 
   483 0000524F BE[61C90000]        <1> 	mov	esi, Msg_Show_Date
   484 00005254 E8E7F3FFFF          <1> 	call	print_msg
   485                              <1> 
   486 00005259 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 0000525A BE[45C90000]        <1> 	mov	esi, Msg_Enter_Date
   494 0000525F E8DCF3FFFF          <1> 	call	print_msg
   495                              <1> 
   496                              <1> loc_enter_day_1:
   497 00005264 30E4                <1> 	xor     ah, ah
   498 00005266 E84BB8FFFF          <1> 	call	int16h
   499                              <1> 	; AL = ASCII Code of the Character
   500 0000526B 3C0D                <1> 	cmp	al, 13
   501 0000526D 0F84B7010000        <1> 	je	loc_set_date_retn
   502 00005273 3C1B                <1> 	cmp	al, 27
   503 00005275 0F84AF010000        <1> 	je	loc_set_date_retn
   504 0000527B A2[71C90000]        <1> 	mov	[Day], al
   505 00005280 3C30                <1> 	cmp	al, '0'
   506 00005282 0F82AD010000        <1> 	jb	loc_set_date_stc_0
   507 00005288 3C33                <1> 	cmp	al, '3'
   508 0000528A 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 00005290 B307                <1> 	mov	bl, 7
   513 00005292 E858C6FFFF          <1> 	call	_write_tty
   514                              <1> loc_enter_day_2:
   515 00005297 30E4                <1> 	xor     ah, ah
   516 00005299 E818B8FFFF          <1> 	call	int16h
   517                              <1> 	; AL = ASCII Code of the Character
   518 0000529E 3C1B                <1> 	cmp	al, 27
   519 000052A0 0F8484010000        <1>         je      loc_set_date_retn
   520 000052A6 A2[72C90000]        <1> 	mov	[Day+1], al
   521 000052AB 3C30                <1> 	cmp	al, '0'
   522 000052AD 0F828C010000        <1>         jb      loc_set_date_stc_1
   523 000052B3 3C39                <1> 	cmp	al, '9'
   524 000052B5 0F8784010000        <1>         ja      loc_set_date_stc_1
   525 000052BB 803D[71C90000]33    <1> 	cmp	byte [Day], '3'
   526 000052C2 7208                <1> 	jb	short pass_set_day_31
   527 000052C4 3C31                <1> 	cmp	al, '1'
   528 000052C6 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 000052CC B307                <1> 	mov	bl, 7
   534 000052CE E81CC6FFFF          <1> 	call	_write_tty
   535                              <1> loc_enter_separator_1:
   536 000052D3 28E4                <1> 	sub     ah, ah ; 0
   537 000052D5 E8DCB7FFFF          <1> 	call	int16h
   538                              <1> 	; AL = ASCII Code of the Character
   539 000052DA 3C1B                <1> 	cmp	al, 27
   540 000052DC 0F8448010000        <1>         je      loc_set_date_retn
   541 000052E2 3C2D                <1> 	cmp	al, '-'
   542 000052E4 7408                <1> 	je	short pass_set_date_separator_1
   543 000052E6 3C2F                <1> 	cmp	al, '/'
   544 000052E8 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 000052EE B307                <1> 	mov	bl, 7	
   550 000052F0 E8FAC5FFFF          <1> 	call	_write_tty
   551                              <1> loc_enter_month_1:
   552 000052F5 30E4                <1> 	xor     ah, ah ; 0
   553 000052F7 E8BAB7FFFF          <1> 	call	int16h
   554                              <1> 	; AL = ASCII Code of the Character
   555 000052FC 3C1B                <1> 	cmp	al, 27
   556 000052FE 0F8426010000        <1>         je      loc_set_date_retn
   557 00005304 A2[74C90000]        <1> 	mov	[Month], al
   558 00005309 3C30                <1> 	cmp	al, '0'
   559 0000530B 0F8264010000        <1>         jb      loc_set_date_stc_3
   560 00005311 3C31                <1> 	cmp	al, '1'
   561 00005313 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 00005319 B307                <1> 	mov	bl, 7
   566 0000531B E8CFC5FFFF          <1> 	call	_write_tty
   567                              <1> loc_enter_month_2:
   568 00005320 30E4                <1> 	xor     ah, ah
   569 00005322 E88FB7FFFF          <1> 	call	int16h
   570                              <1> 	; AL = ASCII Code of the Character
   571 00005327 3C1B                <1> 	cmp	al, 27
   572 00005329 0F84FB000000        <1>         je      loc_set_date_retn
   573 0000532F A2[75C90000]        <1> 	mov	[Month+1], al
   574 00005334 3C30                <1> 	cmp	al, '0'
   575 00005336 0F8254010000        <1>         jb      loc_set_date_stc_4
   576 0000533C 3C39                <1> 	cmp	al, '9'
   577 0000533E 0F874C010000        <1>         ja      loc_set_date_stc_4
   578 00005344 803D[74C90000]31    <1> 	cmp	byte [Month], '1'
   579 0000534B 7208                <1> 	jb	short pass_set_month_12
   580 0000534D 3C32                <1> 	cmp	al, '2'
   581 0000534F 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 00005355 B307                <1> 	mov	bl, 7	
   587 00005357 E893C5FFFF          <1> 	call	_write_tty
   588                              <1> loc_enter_separator_2:
   589 0000535C 28E4                <1> 	sub     ah, ah
   590 0000535E E853B7FFFF          <1> 	call	int16h
   591                              <1> 	; AL = ASCII Code of the Character
   592 00005363 3C1B                <1> 	cmp	al, 27
   593 00005365 0F84BF000000        <1>         je      loc_set_date_retn
   594 0000536B 3C2D                <1> 	cmp	al, '-'
   595 0000536D 7408                <1> 	je	short pass_set_date_separator_2
   596 0000536F 3C2F                <1> 	cmp	al, '/'
   597 00005371 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 00005377 B307                <1> 	mov	bl, 7
   603 00005379 E871C5FFFF          <1> 	call	_write_tty
   604                              <1> loc_enter_year_1:
   605 0000537E 30E4                <1> 	xor    ah, ah
   606 00005380 E831B7FFFF          <1> 	call	int16h
   607                              <1> 	; AL = ASCII Code of the Character
   608 00005385 3C1B                <1> 	cmp	al, 27
   609 00005387 0F849D000000        <1>         je      loc_set_date_retn
   610 0000538D A2[79C90000]        <1> 	mov	[Year], al
   611 00005392 3C30                <1> 	cmp	al, '0'
   612 00005394 0F822C010000        <1>         jb      loc_set_date_stc_6
   613 0000539A 3C39                <1> 	cmp	al, '9'
   614 0000539C 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 000053A2 B307                <1> 	mov	bl, 7	
   619 000053A4 E846C5FFFF          <1> 	call	_write_tty
   620                              <1> loc_enter_year_2:
   621 000053A9 30E4                <1> 	xor	ah, ah
   622 000053AB E806B7FFFF          <1> 	call	int16h
   623                              <1> 	; AL = ASCII Code of the Character
   624 000053B0 3C1B                <1> 	cmp	al, 27
   625 000053B2 7476                <1> 	je	short loc_set_date_retn
   626 000053B4 A2[7AC90000]        <1> 	mov	byte [Year+1], al
   627 000053B9 3C30                <1> 	cmp	al, '0'
   628 000053BB 0F8220010000        <1>         jb      loc_set_date_stc_7
   629 000053C1 3C39                <1> 	cmp	al, '9'
   630 000053C3 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 000053C9 B307                <1> 	mov	bl, 7	
   635 000053CB E81FC5FFFF          <1> 	call	_write_tty
   636                              <1> loc_set_date_get_lchar_again:
   637 000053D0 28E4                <1> 	sub	ah, ah ; 0
   638 000053D2 E8DFB6FFFF          <1> 	call	int16h
   639                              <1> 	; AL = ASCII Code of the Character
   640 000053D7 3C0D                <1> 	cmp	al, 13 ; ENTER key
   641 000053D9 7412                <1> 	je	short loc_set_date_progress
   642 000053DB 3C1B                <1> 	cmp	al, 27 ; ESC key
   643 000053DD 744B                <1> 	je	short loc_set_date_retn
   644                              <1> 	;
   645 000053DF E82A010000          <1> 	call	check_for_backspace
   646 000053E4 75EA                <1> 	jne	short loc_set_date_get_lchar_again
   647                              <1> 
   648                              <1> loc_set_date_bs_8:
   649 000053E6 E811010000          <1> 	call	write_backspace
   650 000053EB 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 000053ED E878EFFFFF          <1> 	call	RTC_40	; GET RTC DATE
   657                              <1> 	; CH = century (in BCD)
   658                              <1> 
   659 000053F2 66A1[79C90000]      <1> 	mov	ax, [Year]
   660 000053F8 662D3030            <1> 	sub	ax, '00'
   661 000053FC C0E004              <1> 	shl	al, 4 ; * 16
   662 000053FF 88C1                <1> 	mov	cl, al
   663 00005401 00E1                <1> 	add	cl, ah
   664 00005403 66A1[74C90000]      <1> 	mov	ax, [Month]
   665 00005409 662D3030            <1> 	sub	ax, '00'
   666 0000540D C0E004              <1> 	shl	al, 4 ; * 16
   667 00005410 88C6                <1> 	mov	dh, al
   668 00005412 00E6                <1> 	add	dh, ah
   669 00005414 66A1[71C90000]      <1> 	mov	ax, [Day]
   670 0000541A 662D3030            <1> 	sub	ax, '00'
   671 0000541E C0E004              <1> 	shl	al, 4 ; * 16
   672 00005421 88C2                <1> 	mov	dl, al
   673 00005423 00E2                <1> 	add	dl, ah
   674                              <1> 
   675                              <1> 	;mov	ah, 05h
   676                              <1> 	;call	int1Ah
   677 00005425 E86DEFFFFF          <1> 	call	RTC_50	; SET RTC DATE
   678                              <1> 
   679                              <1> loc_set_date_retn:
   680 0000542A BE[9CD90000]        <1> 	mov	esi, nextline
   681 0000542F E80CF2FFFF          <1> 	call	print_msg
   682 00005434 C3                  <1> 	retn
   683                              <1> 
   684                              <1> loc_set_date_stc_0:
   685                              <1> 	;xor	bh, bh ; video page 0
   686 00005435 E895C5FFFF          <1> 	call	beeper ; BEEP !
   687 0000543A E925FEFFFF          <1>         jmp     loc_enter_day_1
   688                              <1> loc_set_date_stc_1:
   689 0000543F E8CA000000          <1> 	call	check_for_backspace
   690 00005444 740A                <1> 	je	short loc_set_date_bs_1
   691                              <1> 	;xor	bh, bh ; video page 0
   692 00005446 E884C5FFFF          <1> 	call	beeper ; BEEP !
   693 0000544B E947FEFFFF          <1>         jmp     loc_enter_day_2
   694                              <1> loc_set_date_bs_1:
   695 00005450 E8A7000000          <1> 	call	write_backspace
   696 00005455 E90AFEFFFF          <1>         jmp     loc_enter_day_1
   697                              <1> loc_set_date_stc_2:
   698 0000545A E8AF000000          <1> 	call	check_for_backspace
   699 0000545F 740A                <1> 	je	short loc_set_date_bs_2
   700                              <1> 	;xor	bh, bh ; video page 0
   701 00005461 E869C5FFFF          <1> 	call	beeper ; BEEP !
   702 00005466 E968FEFFFF          <1>         jmp     loc_enter_separator_1
   703                              <1> loc_set_date_bs_2:
   704 0000546B E88C000000          <1> 	call	write_backspace
   705 00005470 E922FEFFFF          <1>         jmp     loc_enter_day_2
   706                              <1> loc_set_date_stc_3:
   707 00005475 E894000000          <1> 	call	check_for_backspace	
   708 0000547A 740A                <1> 	je short loc_set_date_bs_3
   709                              <1> 	;xor	bh, bh ; video page 0
   710 0000547C E84EC5FFFF          <1> 	call	beeper ; BEEP !
   711 00005481 E96FFEFFFF          <1>         jmp     loc_enter_month_1
   712                              <1> loc_set_date_bs_3:
   713 00005486 E871000000          <1> 	call	write_backspace
   714 0000548B E943FEFFFF          <1>         jmp     loc_enter_separator_1
   715                              <1> loc_set_date_stc_4:
   716 00005490 E879000000          <1> 	call	check_for_backspace	
   717 00005495 740A                <1> 	je	short loc_set_date_bs_4
   718                              <1> 	;xor	bh, bh ; video page 0
   719 00005497 E833C5FFFF          <1> 	call	beeper ; BEEP !
   720 0000549C E97FFEFFFF          <1>         jmp     loc_enter_month_2
   721                              <1> loc_set_date_bs_4:
   722 000054A1 E856000000          <1> 	call	write_backspace
   723 000054A6 E94AFEFFFF          <1>         jmp     loc_enter_month_1
   724                              <1> loc_set_date_stc_5:
   725 000054AB E85E000000          <1> 	call	check_for_backspace
   726 000054B0 740A                <1> 	je	short loc_set_date_bs_5
   727                              <1> 	;xor	bh, bh ; video page 0
   728 000054B2 E818C5FFFF          <1> 	call	beeper ; BEEP !
   729 000054B7 E9A0FEFFFF          <1>         jmp     loc_enter_separator_2
   730                              <1> loc_set_date_bs_5:
   731 000054BC E83B000000          <1> 	call	write_backspace
   732 000054C1 E95AFEFFFF          <1>         jmp     loc_enter_month_2
   733                              <1> loc_set_date_stc_6:
   734 000054C6 E843000000          <1> 	call	check_for_backspace
   735 000054CB 740A                <1>         je      short  loc_set_date_bs_6
   736                              <1> 	;xor	bh, bh ; video page 0
   737 000054CD E8FDC4FFFF          <1> 	call	beeper ; BEEP !
   738 000054D2 E9A7FEFFFF          <1>         jmp     loc_enter_year_1
   739                              <1> loc_set_date_bs_6:
   740 000054D7 E820000000          <1> 	call	write_backspace
   741 000054DC E97BFEFFFF          <1>         jmp     loc_enter_separator_2
   742                              <1> loc_set_date_stc_7:
   743 000054E1 E828000000          <1> 	call	check_for_backspace
   744 000054E6 740A                <1> 	je	short loc_set_date_bs_7
   745                              <1> 	;xor	bh, bh ; video page 0
   746 000054E8 E8E2C4FFFF          <1> 	call	beeper ; BEEP !
   747 000054ED E9B7FEFFFF          <1>         jmp     loc_enter_year_2
   748                              <1> loc_set_date_bs_7:
   749 000054F2 E805000000          <1> 	call	write_backspace
   750 000054F7 E982FEFFFF          <1>         jmp     loc_enter_year_1
   751                              <1> 
   752                              <1> write_backspace:
   753                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   754 000054FC B008                <1> 	mov	al, 08h ; BACKSPACE
   755                              <1> 	; 13/05/2016
   756 000054FE 66BB0700            <1> 	mov	bx, 7 ; bl = attribute/color
   757                              <1> 		      ; bh = video page = 0	
   758 00005502 E8E8C3FFFF          <1> 	call	_write_tty
   759 00005507 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 00005509 E97BC3FFFF          <1> 	jmp	_write_c_current
   764                              <1> 
   765                              <1> check_for_backspace:
   766                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   767 0000550E 663D080E            <1> 	cmp	ax, 0E08h
   768 00005512 7410                <1> 	je	short cfbs_retn
   769 00005514 663DE04B            <1> 	cmp	ax, 4BE0h
   770 00005518 740A                <1> 	je	short cfbs_retn
   771 0000551A 663D004B            <1> 	cmp	ax, 4B00h
   772 0000551E 7404                <1> 	je	short cfbs_retn
   773 00005520 663DE053            <1> 	cmp	ax, 53E0h
   774                              <1> cfbs_retn:
   775 00005524 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 00005525 E8CFEDFFFF          <1> 	call	RTC_20	; GET RTC TIME
   784                              <1> 	
   785 0000552A 88E8                <1> 	mov	al, ch
   786 0000552C E87CB5FFFF          <1> 	call	bcd_to_ascii
   787 00005531 66A3[9FC90000]      <1> 	mov	[Hour], ax
   788                              <1> 
   789 00005537 88C8                <1> 	mov	al, cl
   790 00005539 E86FB5FFFF          <1> 	call	bcd_to_ascii
   791 0000553E 66A3[A2C90000]      <1> 	mov	[Minute], ax
   792                              <1> 
   793 00005544 88F0                <1> 	mov	al, dh
   794 00005546 E862B5FFFF          <1> 	call	bcd_to_ascii
   795 0000554B 66A3[A5C90000]      <1> 	mov	[Second], ax
   796                              <1> 
   797 00005551 BE[8FC90000]        <1> 	mov	esi, Msg_Show_Time
   798 00005556 E8E5F0FFFF          <1> 	call	print_msg
   799 0000555B 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 0000555C BE[7EC90000]        <1> 	mov 	esi, Msg_Enter_Time
   807 00005561 E8DAF0FFFF          <1> 	call	print_msg
   808                              <1> 
   809                              <1> loc_enter_hour_1:
   810 00005566 30E4                <1> 	xor     ah, ah
   811 00005568 E849B5FFFF          <1> 	call	int16h
   812                              <1> 	; AL = ASCII Code of the Character
   813 0000556D 3C0D                <1> 	cmp	al, 13 ; ENTER key
   814 0000556F 0F84AE010000        <1>         je      loc_set_time_retn
   815 00005575 3C1B                <1> 	cmp	al, 27 ; ESC key
   816 00005577 0F84A6010000        <1>         je      loc_set_time_retn
   817 0000557D A2[9FC90000]        <1> 	mov	[Hour], al
   818 00005582 3C30                <1> 	cmp	al, '0'
   819 00005584 0F82A4010000        <1>         jb      loc_set_time_stc_0
   820 0000558A 3C32                <1> 	cmp	al, '2'
   821 0000558C 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 00005592 B307                <1> 	mov	bl, 7	
   826 00005594 E856C3FFFF          <1> 	call	_write_tty
   827                              <1> loc_enter_hour_2:
   828 00005599 30E4                <1> 	xor     ah, ah
   829 0000559B E816B5FFFF          <1> 	call	int16h
   830                              <1> 	; AL = ASCII Code of the Character
   831 000055A0 3C1B                <1> 	cmp	al, 27
   832 000055A2 0F847B010000        <1>         je      loc_set_time_retn
   833 000055A8 A2[A0C90000]        <1> 	mov	[Hour+1], al
   834 000055AD 3C30                <1> 	cmp	al, '0'
   835 000055AF 0F8283010000        <1>         jb      loc_set_time_stc_1
   836 000055B5 3C39                <1> 	cmp	al, '9'
   837 000055B7 0F877B010000        <1> 	ja	loc_set_time_stc_1
   838 000055BD 803D[9FC90000]32    <1>         cmp     byte [Hour], '2'
   839 000055C4 7208                <1> 	jb	short pass_set_time_24
   840 000055C6 3C34                <1> 	cmp	al, '4'
   841 000055C8 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 000055CE B307                <1> 	mov	bl, 7	
   847 000055D0 E81AC3FFFF          <1> 	call	_write_tty
   848                              <1> loc_enter_time_separator_1:
   849 000055D5 28E4                <1> 	sub    ah, ah ; 0
   850 000055D7 E8DAB4FFFF          <1> 	call	int16h
   851                              <1> 	; AL = ASCII Code of the Character
   852 000055DC 3C1B                <1> 	cmp	al, 27
   853 000055DE 0F843F010000        <1>         je      loc_set_time_retn
   854 000055E4 3C3A                <1> 	cmp	al, ':'
   855 000055E6 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 000055EC B307                <1> 	mov	bl, 7	
   860 000055EE E8FCC2FFFF          <1> 	call	_write_tty
   861                              <1> loc_enter_minute_1:
   862 000055F3 30E4                <1> 	xor     ah, ah
   863 000055F5 E8BCB4FFFF          <1> 	call	int16h
   864                              <1> 	; AL = ASCII Code of the Character
   865 000055FA 3C1B                <1> 	cmp	al, 27
   866 000055FC 0F8421010000        <1>         je      loc_set_time_retn
   867 00005602 A2[A2C90000]        <1> 	mov	[Minute], al
   868 00005607 3C30                <1> 	cmp	al, '0'
   869 00005609 0F825F010000        <1>         jb      loc_set_time_stc_3
   870 0000560F 3C35                <1> 	cmp	al, '5'
   871 00005611 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 00005617 B307                <1> 	mov	bl, 7	
   876 00005619 E8D1C2FFFF          <1> 	call	_write_tty
   877                              <1> loc_enter_minute_2:
   878 0000561E 30E4                <1> 	xor     ah, ah
   879 00005620 E891B4FFFF          <1> 	call	int16h
   880                              <1> 	; AL = ASCII Code of the Character
   881 00005625 3C1B                <1> 	cmp	al, 27
   882 00005627 0F84F6000000        <1>         je      loc_set_time_retn
   883 0000562D A2[A3C90000]        <1> 	mov	[Minute+1], al
   884 00005632 3C30                <1> 	cmp	al, '0'
   885 00005634 0F824F010000        <1>         jb      loc_set_time_stc_4
   886 0000563A 3C39                <1> 	cmp	al, '9'
   887 0000563C 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 00005642 B307                <1> 	mov	bl, 7	
   892 00005644 E8A6C2FFFF          <1> 	call	_write_tty
   893                              <1> loc_enter_time_separator_2:
   894 00005649 66C705[A5C90000]30- <1> 	mov	word [Second], 3030h
   894 00005651 30                  <1>
   895 00005652 28E4                <1> 	sub     ah, ah
   896 00005654 E85DB4FFFF          <1> 	call	int16h
   897                              <1> 	; AL = ASCII Code of the Character
   898 00005659 3C0D                <1> 	cmp	al, 13
   899 0000565B 0F8485000000        <1>         je      loc_set_time_progress
   900 00005661 3C1B                <1> 	cmp	al, 27
   901 00005663 0F84BA000000        <1>         je      loc_set_time_retn
   902 00005669 3C3A                <1> 	cmp	al, ':'
   903 0000566B 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 00005671 B307                <1> 	mov	bl, 7	
   908 00005673 E877C2FFFF          <1> 	call	_write_tty
   909                              <1> loc_enter_second_1:
   910 00005678 30E4                <1> 	xor     ah, ah
   911 0000567A E837B4FFFF          <1> 	call	int16h
   912                              <1> 	; AL = ASCII Code of the Character
   913 0000567F 3C0D                <1> 	cmp	al, 13
   914 00005681 7463                <1> 	je	short loc_set_time_progress
   915 00005683 3C1B                <1> 	cmp	al, 27
   916 00005685 0F8498000000        <1>         je      loc_set_time_retn
   917 0000568B A2[A5C90000]        <1> 	mov	[Second], al
   918 00005690 3C30                <1> 	cmp	al, '0'
   919 00005692 0F8227010000        <1>         jb      loc_set_time_stc_6
   920 00005698 3C35                <1> 	cmp	al, '5'
   921 0000569A 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 000056A0 B307                <1> 	mov	bl, 7	
   926 000056A2 E848C2FFFF          <1> 	call	_write_tty
   927                              <1> loc_enter_second_2:
   928 000056A7 30E4                <1> 	xor     ah, ah
   929 000056A9 E808B4FFFF          <1> 	call	int16h
   930                              <1> 	; AL = ASCII Code of the Character
   931 000056AE 3C1B                <1> 	cmp	al, 27
   932 000056B0 7471                <1> 	je	short loc_set_time_retn
   933 000056B2 3C30                <1> 	cmp	al, '0'
   934 000056B4 0F8229010000        <1>         jb      loc_set_time_stc_7
   935 000056BA 3C39                <1> 	cmp	al, '9'
   936 000056BC 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 000056C2 B307                <1> 	mov	bl, 7	
   941 000056C4 E826C2FFFF          <1> 	call	_write_tty
   942                              <1> loc_set_time_get_lchar_again:
   943 000056C9 28E4                <1> 	sub	ah, ah ; 0
   944 000056CB E8E6B3FFFF          <1> 	call	int16h
   945                              <1> 	; AL = ASCII Code of the Character
   946 000056D0 3C0D                <1> 	cmp	al, 13
   947 000056D2 7412                <1> 	je	short loc_set_time_progress
   948 000056D4 3C1B                <1> 	cmp	al, 27
   949 000056D6 744B                <1> 	je	short loc_set_time_retn
   950                              <1> 	;
   951 000056D8 E831FEFFFF          <1> 	call	check_for_backspace
   952 000056DD 75EA                <1> 	jne	short loc_set_time_get_lchar_again
   953                              <1> 
   954                              <1> loc_set_time_bs_8:
   955 000056DF E818FEFFFF          <1> 	call	write_backspace
   956 000056E4 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 000056E6 E80EECFFFF          <1> 	call	RTC_20	; GET RTC TIME
   963                              <1> 	;DL = Daylight Savings Enable option (0-1)	
   964                              <1> 
   965 000056EB 66A1[9FC90000]      <1> 	mov	ax, [Hour]
   966 000056F1 662D3030            <1> 	sub	ax, '00'
   967 000056F5 C0E004              <1> 	shl	al, 4 ; * 16
   968 000056F8 88C5                <1> 	mov	ch, al
   969 000056FA 00E5                <1> 	add	ch, ah
   970 000056FC 66A1[A2C90000]      <1> 	mov	ax, [Minute]
   971 00005702 662D3030            <1> 	sub	ax, '00'
   972 00005706 C0E004              <1> 	shl	al, 4 ; * 16
   973 00005709 88C1                <1> 	mov	cl, al
   974 0000570B 00E1                <1> 	add	cl, ah
   975 0000570D 66A1[A5C90000]      <1> 	mov	ax, [Second]
   976 00005713 662D3030            <1> 	sub	ax, '00'
   977 00005717 C0E004              <1> 	shl	al, 4 ; * 16
   978 0000571A 88C6                <1> 	mov	dh, al
   979 0000571C 00E6                <1> 	add	dh, ah
   980                              <1> 	
   981                              <1> 	;mov	ah, 03h
   982                              <1> 	;call	int1Ah
   983 0000571E E805ECFFFF          <1> 	call	RTC_30	; SET RTC TIME
   984                              <1> 
   985                              <1> loc_set_time_retn:
   986 00005723 BE[9CD90000]        <1> 	mov 	esi, nextline
   987 00005728 E813EFFFFF          <1> 	call	print_msg
   988 0000572D C3                  <1> 	retn
   989                              <1> 
   990                              <1> loc_set_time_stc_0:
   991                              <1> 	;xor	bh, bh ; video page 0
   992 0000572E E89CC2FFFF          <1> 	call	beeper ; BEEP !
   993 00005733 E92EFEFFFF          <1>         jmp     loc_enter_hour_1
   994                              <1> loc_set_time_stc_1:
   995 00005738 E8D1FDFFFF          <1> 	call	check_for_backspace
   996 0000573D 740A                <1> 	je	short loc_set_time_bs_1
   997                              <1> 	;xor	bh, bh ; video page 0
   998 0000573F E88BC2FFFF          <1> 	call	beeper ; BEEP !
   999 00005744 E950FEFFFF          <1>         jmp     loc_enter_hour_2
  1000                              <1> loc_set_time_bs_1:
  1001 00005749 E8AEFDFFFF          <1> 	call	write_backspace
  1002 0000574E E913FEFFFF          <1>         jmp     loc_enter_hour_1
  1003                              <1> loc_set_time_stc_2:
  1004 00005753 E8B6FDFFFF          <1> 	call	check_for_backspace
  1005 00005758 740A                <1> 	je	short loc_set_time_bs_2
  1006                              <1> 	;xor	bh, bh ; video page 0
  1007 0000575A E870C2FFFF          <1> 	call	beeper ; BEEP !
  1008 0000575F E971FEFFFF          <1>         jmp     loc_enter_time_separator_1
  1009                              <1> loc_set_time_bs_2:
  1010 00005764 E893FDFFFF          <1> 	call	write_backspace
  1011 00005769 E92BFEFFFF          <1>         jmp     loc_enter_hour_2
  1012                              <1> loc_set_time_stc_3:
  1013 0000576E E89BFDFFFF          <1> 	call	check_for_backspace
  1014 00005773 740A                <1> 	je	short loc_set_time_bs_3
  1015                              <1> 	;xor	bh, bh ; video page 0
  1016 00005775 E855C2FFFF          <1> 	call	beeper ; BEEP !6
  1017 0000577A E974FEFFFF          <1>         jmp     loc_enter_minute_1
  1018                              <1> loc_set_time_bs_3:
  1019 0000577F E878FDFFFF          <1> 	call	write_backspace
  1020 00005784 E94CFEFFFF          <1>         jmp     loc_enter_time_separator_1
  1021                              <1> loc_set_time_stc_4:
  1022 00005789 E880FDFFFF          <1> 	call	check_for_backspace
  1023 0000578E 740A                <1> 	je	short loc_set_time_bs_4
  1024                              <1> 	;xor	bh, bh ; video page 0
  1025 00005790 E83AC2FFFF          <1> 	call	beeper ; BEEP !
  1026 00005795 E984FEFFFF          <1>         jmp     loc_enter_minute_2
  1027                              <1> loc_set_time_bs_4:
  1028 0000579A E85DFDFFFF          <1> 	call	write_backspace
  1029 0000579F E94FFEFFFF          <1>         jmp     loc_enter_minute_1
  1030                              <1> loc_set_time_stc_5:
  1031 000057A4 E865FDFFFF          <1> 	call	check_for_backspace
  1032 000057A9 740A                <1> 	je	short loc_set_time_bs_5
  1033                              <1> 	;xor	bh, bh ; video page 0
  1034 000057AB E81FC2FFFF          <1> 	call	beeper ; BEEP !
  1035 000057B0 E994FEFFFF          <1>         jmp     loc_enter_time_separator_2
  1036                              <1> loc_set_time_bs_5:
  1037 000057B5 E842FDFFFF          <1> 	call	write_backspace
  1038 000057BA E95FFEFFFF          <1>         jmp     loc_enter_minute_2
  1039                              <1> loc_set_time_stc_6:
  1040 000057BF E84AFDFFFF          <1> 	call	check_for_backspace
  1041 000057C4 7413                <1> 	je	short loc_set_time_bs_6
  1042                              <1> 	;xor	bh, bh ; video page 0
  1043 000057C6 E804C2FFFF          <1> 	call	beeper ; BEEP !
  1044 000057CB 66C705[A5C90000]30- <1> 	mov	word [Second], 3030h
  1044 000057D3 30                  <1>
  1045 000057D4 E99FFEFFFF          <1>         jmp     loc_enter_second_1
  1046                              <1> loc_set_time_bs_6:
  1047 000057D9 E81EFDFFFF          <1> 	call	write_backspace
  1048 000057DE E966FEFFFF          <1>         jmp     loc_enter_time_separator_2
  1049                              <1> loc_set_time_stc_7:
  1050 000057E3 E826FDFFFF          <1> 	call	check_for_backspace
  1051 000057E8 740A                <1> 	je	short loc_set_time_bs_7
  1052                              <1> 	;xor	bh, bh ; video page 0
  1053 000057EA E8E0C1FFFF          <1> 	call	beeper ; BEEP !
  1054 000057EF E9B3FEFFFF          <1>         jmp     loc_enter_second_2
  1055                              <1> loc_set_time_bs_7:
  1056 000057F4 E803FDFFFF          <1> 	call	write_backspace
  1057 000057F9 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 000057FE 88C4                <1> 	mov	ah, al
  1076 00005800 28C0                <1> 	sub	al, al
  1077 00005802 0FB7F0              <1> 	movzx	esi, ax	
  1078 00005805 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1079 0000580B 8A06                <1> 	mov	al, [esi]
  1080 0000580D 3C41                <1> 	cmp	al, 'A'  
  1081 0000580F 7304                <1> 	jnb	short loc_pvi_set_vol_name
  1082 00005811 8A6604              <1> 	mov	ah, [esi+LD_FSType]
  1083 00005814 C3                  <1> 	retn
  1084                              <1> 
  1085                              <1> loc_pvi_set_vol_name:
  1086 00005815 A2[D9C90000]        <1> 	mov	[Vol_Drv_Name], al
  1087 0000581A 56                  <1> 	push	esi
  1088 0000581B E858010000          <1> 	call	move_volume_name_and_serial_no ;;;
  1089 00005820 7302                <1> 	jnc	short loc_pvi_mvn_ok
  1090 00005822 5E                  <1> 	pop	esi
  1091 00005823 C3                  <1> 	retn
  1092                              <1> 
  1093                              <1> loc_pvi_mvn_ok:
  1094 00005824 8B3424              <1> 	mov	esi, [esp]
  1095 00005827 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  1096 0000582B 7509                <1> 	jne	short loc_pvi_fat_vol_size
  1097 0000582D 8B4670              <1> 	mov	eax, [esi+LD_FS_VolumeSize]
  1098 00005830 0FB75E11            <1> 	movzx	ebx, word [esi+LD_FS_BytesPerSec]
  1099 00005834 EB07                <1> 	jmp	short loc_vol_size_mul32
  1100                              <1> loc_pvi_fat_vol_size:
  1101 00005836 8B4670              <1> 	mov	eax, [esi+LD_TotalSectors]
  1102 00005839 0FB75E11            <1> 	movzx	ebx, word [esi+LD_BPB+BPB_BytsPerSec]
  1103                              <1> loc_vol_size_mul32:
  1104 0000583D F7E3                <1> 	mul	ebx
  1105 0000583F 09D2                <1> 	or	edx, edx
  1106 00005841 7507                <1> 	jnz	short loc_vol_size_in_kbytes
  1107                              <1> loc_vol_size_in_bytes:
  1108 00005843 B9[B7C90000]        <1> 	mov	ecx, VolSize_Bytes
  1109 00005848 EB0D                <1> 	jmp	short loc_write_vol_size_str
  1110                              <1> loc_vol_size_in_kbytes:
  1111 0000584A 66BB0004            <1> 	mov	bx, 1024
  1112 0000584E F7F3                <1> 	div	ebx
  1113 00005850 B9[AAC90000]        <1> 	mov 	ecx, VolSize_KiloBytes
  1114 00005855 31D2                <1> 	xor	edx, edx ; 0
  1115                              <1> loc_write_vol_size_str:
  1116 00005857 890D[F7E50000]      <1> 	mov	[VolSize_Unit1], ecx
  1117                              <1> 	; 
  1118 0000585D BF[0DE60000]        <1> 	mov	edi, Vol_Tot_Sec_Str_End
  1119                              <1>         ;mov	byte [edi], 0
  1120 00005862 B90A000000          <1> 	mov	ecx, 10
  1121                              <1> loc_write_vol_size_chr:
  1122 00005867 F7F1                <1> 	div	ecx
  1123 00005869 80C230              <1> 	add	dl, '0'
  1124 0000586C 4F                  <1> 	dec	edi	
  1125 0000586D 8817                <1> 	mov	[edi], dl
  1126 0000586F 85C0                <1> 	test	eax, eax
  1127 00005871 7404                <1> 	jz	short loc_write_vol_size_str_ok
  1128 00005873 28D2                <1> 	sub	dl, dl ; 0
  1129 00005875 EBF0                <1> 	jmp	short loc_write_vol_size_chr
  1130                              <1> 
  1131                              <1> loc_write_vol_size_str_ok:
  1132 00005877 893D[FFE50000]      <1> 	mov	[Vol_Tot_Sec_Str_Start], edi
  1133                              <1> 	;
  1134 0000587D BF[C2C90000]        <1> 	mov	edi, Vol_FS_Name
  1135 00005882 8A4E03              <1> 	mov	cl, [esi+LD_FATType]
  1136 00005885 20C9                <1> 	and	cl, cl ; 0 ?
  1137 00005887 7515                <1> 	jnz	short loc_write_vol_FAT_str_1
  1138 00005889 66C7075452          <1> 	mov	word [edi], 'TR'
  1139 0000588E C7470420465331      <1> 	mov	dword [edi+4], ' FS1'
  1140                              <1> 	;movzx	ebx, word [esi+LD_FS_BytesPerSec]
  1141 00005895 668B5E11            <1> 	mov	bx, [esi+LD_FS_BytesPerSec]
  1142 00005899 8B4674              <1> 	mov	eax, [esi+LD_FS_FreeSectors]
  1143 0000589C EB36                <1> 	jmp	short loc_vol_freespace_mul32
  1144                              <1> 
  1145                              <1> loc_write_vol_FAT_str_1:
  1146 0000589E 66B83332            <1> 	mov	ax, '32' ; FAT32
  1147 000058A2 80F902              <1> 	cmp	cl, 2 ; [esi+LD_FATType]
  1148 000058A5 7708                <1> 	ja	short loc_write_vol_FAT_str_2
  1149 000058A7 66B83132            <1> 	mov	ax, '12' ; FAT12
  1150 000058AB 7202                <1> 	jb	short loc_write_vol_FAT_str_2
  1151 000058AD B436                <1> 	mov	ah, '6'  ; FAT16
  1152                              <1> loc_write_vol_FAT_str_2:
  1153 000058AF C70746415420        <1> 	mov	dword [edi], 'FAT '
  1154 000058B5 66894704            <1> 	mov	word [edi+4], ax
  1155                              <1> 	;
  1156                              <1> 	;movzx	ebx, word [esi+LD_BPB+BPB_BytsPerSec]
  1157 000058B9 668B5E11            <1> 	mov	bx, [esi+LD_BPB+BPB_BytsPerSec]
  1158 000058BD 8B4674              <1> 	mov	eax, [esi+LD_FreeSectors]
  1159                              <1> 
  1160                              <1> loc_vol_freespace_recalc0:
  1161                              <1> 	; 01/03/2016
  1162 000058C0 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh
  1163 000058C3 720F                <1> 	jb	short loc_vol_freespace_mul32
  1164                              <1> 	;inc	eax ; 0
  1165 000058C5 20C9                <1> 	and	cl, cl ; byte [esi+LD_FATType]
  1166 000058C7 740B                <1> 	jz	short loc_vol_freespace_mul32 	
  1167 000058C9 53                  <1> 	push	ebx
  1168 000058CA 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free sectors
  1169 000058CE E88B490000          <1> 	call	calculate_fat_freespace
  1170 000058D3 5B                  <1> 	pop	ebx
  1171                              <1> 
  1172                              <1> loc_vol_freespace_mul32:
  1173 000058D4 F7E3                <1> 	mul	ebx
  1174 000058D6 09D2                <1> 	or	edx, edx
  1175 000058D8 7507                <1> 	jnz	short loc_vol_fspace_in_kbytes
  1176                              <1> loc_vol_fspace_in_bytes:
  1177 000058DA B9[B7C90000]        <1> 	mov	ecx, VolSize_Bytes
  1178 000058DF EB0D                <1> 	jmp	short loc_write_vol_fspace_str
  1179                              <1> loc_vol_fspace_in_kbytes:
  1180 000058E1 66BB0004            <1> 	mov	bx, 1024
  1181 000058E5 F7F3                <1> 	div	ebx
  1182 000058E7 B9[AAC90000]        <1> 	mov 	ecx, VolSize_KiloBytes
  1183 000058EC 31D2                <1> 	xor	edx, edx ; 0
  1184                              <1> loc_write_vol_fspace_str:
  1185 000058EE 890D[FBE50000]      <1> 	mov	[VolSize_Unit2], ecx
  1186                              <1> 	;	
  1187 000058F4 BF[1DE60000]        <1> 	mov	edi, Vol_Free_Sectors_Str_End
  1188                              <1>         ;mov	byte [edi], 0
  1189 000058F9 B90A000000          <1> 	mov	ecx, 10
  1190                              <1> loc_write_vol_fspace_chr:
  1191 000058FE F7F1                <1> 	div	ecx
  1192 00005900 80C230              <1> 	add	dl, '0'
  1193 00005903 4F                  <1> 	dec	edi	
  1194 00005904 8817                <1> 	mov	[edi], dl
  1195 00005906 85C0                <1> 	test	eax, eax
  1196 00005908 7404                <1> 	jz	short loc_write_vol_fspace_str_ok
  1197 0000590A 28D2                <1> 	sub	dl, dl ; 0
  1198 0000590C EBF0                <1> 	jmp	short loc_write_vol_fspace_chr
  1199                              <1> 
  1200                              <1> loc_write_vol_fspace_str_ok:
  1201 0000590E 893D[0FE60000]      <1> 	mov	[Vol_Free_Sectors_Str_Start], edi
  1202                              <1> 	;
  1203 00005914 BE[C0C90000]        <1> 	mov	esi, Volume_in_drive
  1204 00005919 E822EDFFFF          <1> 	call	print_msg
  1205 0000591E BE[00CA0000]        <1> 	mov	esi, Vol_Name
  1206 00005923 E818EDFFFF          <1> 	call	print_msg
  1207 00005928 BE[9CD90000]        <1> 	mov	esi, nextline
  1208 0000592D E80EEDFFFF          <1> 	call	print_msg
  1209                              <1> 	;
  1210 00005932 BE[61CA0000]        <1> 	mov	esi, Vol_Total_Sector_Header
  1211 00005937 E804EDFFFF          <1> 	call	print_msg
  1212 0000593C 8B35[FFE50000]      <1> 	mov	esi, [Vol_Tot_Sec_Str_Start]
  1213 00005942 E8F9ECFFFF          <1> 	call	print_msg
  1214 00005947 8B35[F7E50000]      <1> 	mov	esi, [VolSize_Unit1]
  1215 0000594D E8EEECFFFF          <1> 	call	print_msg
  1216                              <1> 	;
  1217 00005952 BE[72CA0000]        <1> 	mov	esi, Vol_Free_Sectors_Header
  1218 00005957 E8E4ECFFFF          <1> 	call	print_msg
  1219 0000595C 8B35[0FE60000]      <1> 	mov	esi, [Vol_Free_Sectors_Str_Start]
  1220 00005962 E8D9ECFFFF          <1> 	call	print_msg
  1221 00005967 8B35[FBE50000]      <1> 	mov	esi, [VolSize_Unit2]
  1222 0000596D E8CEECFFFF          <1> 	call	print_msg
  1223                              <1> 	;
  1224 00005972 5E                  <1> 	pop	esi
  1225                              <1> 	
  1226                              <1> 	;mov	ah, [esi+LD_FSType]
  1227                              <1> 	;mov	al, [esi+LD_FATType]
  1228 00005973 668B4603            <1> 	mov	ax, [esi+LD_FATType]
  1229                              <1> 
  1230 00005977 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 00005978 BF[00CA0000]        <1> 	mov 	edi, Vol_Name
  1248                              <1> 
  1249                              <1> 	;mov	ah, [esi+LD_FSType]
  1250                              <1> 	;mov	al, [esi+LD_FATType]
  1251 0000597D 668B4603            <1> 	mov	ax, [esi+LD_FATType]
  1252 00005981 80FCA1              <1> 	cmp	ah, 0A1h
  1253 00005984 7418                <1> 	je	short mvn_2
  1254 00005986 08E4                <1> 	or	ah, ah
  1255 00005988 7404                <1> 	jz	short mvn_0
  1256 0000598A 08C0                <1> 	or	al, al
  1257 0000598C 7504                <1> 	jnz	short mvn_1
  1258                              <1> mvn_0:
  1259 0000598E 8A06                <1> 	mov	al, [esi]
  1260 00005990 F9                  <1> 	stc
  1261 00005991 C3                  <1> 	retn
  1262                              <1> mvn_1:
  1263 00005992 3C02                <1> 	cmp	al, 2
  1264 00005994 7717                <1> 	ja	short mvn_3 
  1265                              <1> 	;or	al, al
  1266                              <1> 	;jz	short mvn_2
  1267 00005996 8B462D              <1> 	mov	eax, [esi+LD_BPB+VolumeID]
  1268 00005999 83C631              <1> 	add	esi, LD_BPB+VolumeLabel
  1269 0000599C EB15                <1> 	jmp	short mvn_4
  1270                              <1> mvn_2:
  1271 0000599E 8B4628              <1> 	mov	eax, [esi+LD_FS_VolumeSerial]
  1272 000059A1 83C62C              <1> 	add	esi, LD_FS_VolumeName
  1273 000059A4 B910000000          <1> 	mov	ecx, 16
  1274 000059A9 F3A5                <1> 	rep	movsd
  1275 000059AB EB10                <1> 	jmp	short mvn_5
  1276                              <1> mvn_3:
  1277 000059AD 8B4649              <1> 	mov	eax, [esi+LD_BPB+FAT32_VolID]
  1278 000059B0 83C64D              <1> 	add	esi, LD_BPB+FAT32_VolLab
  1279                              <1> mvn_4:
  1280 000059B3 B90B000000          <1> 	mov	ecx, 11
  1281 000059B8 F3A4                <1> 	rep	movsb
  1282 000059BA C60700              <1> 	mov	byte [edi], 0
  1283                              <1> mvn_5:
  1284                              <1> 	;mov	[Current_VolSerial], eax  
  1285 000059BD E876C5FFFF          <1> 	call	dwordtohex
  1286 000059C2 8915[55CA0000]      <1> 	mov	[Vol_Serial1], edx
  1287 000059C8 A3[5ACA0000]        <1> 	mov	[Vol_Serial2], eax
  1288                              <1> 	; ecx = 0
  1289 000059CD 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 000059CE 31DB                <1> 	xor	ebx, ebx
  1302 000059D0 88D7                <1> 	mov	bh, dl
  1303 000059D2 3815[28C80000]      <1> 	cmp	[Last_DOS_DiskNo], dl
  1304 000059D8 7304                <1> 	jnb	short loc_gvsn_start
  1305                              <1> loc_gvsn_stc_retn:
  1306 000059DA 31C0                <1> 	xor	eax, eax
  1307 000059DC F9                  <1> 	stc 
  1308 000059DD C3                  <1>         retn 
  1309                              <1> loc_gvsn_start:
  1310 000059DE 56                  <1> 	push	esi
  1311 000059DF BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1312 000059E4 01DE                <1> 	add	esi, ebx
  1313 000059E6 8A5E03              <1> 	mov	bl, [esi+LD_FATType]
  1314 000059E9 20DB                <1> 	and	bl, bl
  1315 000059EB 740F                <1> 	jz	short loc_gvsn_fs
  1316 000059ED 80FB02              <1> 	cmp	bl, 2
  1317 000059F0 7705                <1> 	ja	short loc_gvsn_fat32
  1318                              <1> loc_gvsn_fat:
  1319 000059F2 83C62D              <1> 	add	esi, LD_BPB + VolumeID
  1320 000059F5 EB0E                <1> 	jmp	short loc_gvsn_return
  1321                              <1> loc_gvsn_fat32: 
  1322 000059F7 83C649              <1> 	add	esi, LD_BPB + FAT32_VolID
  1323 000059FA EB09                <1> 	jmp	short loc_gvsn_return 
  1324                              <1> loc_gvsn_fs:
  1325 000059FC 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  1326 00005A00 75D8                <1> 	jne	short loc_gvsn_stc_retn 
  1327 00005A02 83C628              <1> 	add	esi, LD_FS_VolumeSerial
  1328                              <1> loc_gvsn_return:
  1329 00005A05 8B06                <1> 	mov	eax, [esi]
  1330 00005A07 5E                  <1> 	pop	esi
  1331 00005A08 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 00005A09 C605[B0E60000]00    <1> 	mov	byte [Program_Exit],0
  1352 00005A10 80F904              <1> 	cmp	cl, 4
  1353 00005A13 0F87AE020000        <1>         ja      c_6
  1354 00005A19 0F822E010000        <1>         jb      c_2
  1355                              <1> c_4:
  1356                              <1> 
  1357                              <1> cmp_cmd_exit:
  1358 00005A1F BF[96C80000]        <1> 	mov	edi, Cmd_Exit
  1359 00005A24 E8C9030000          <1> 	call	cmp_cmd	
  1360 00005A29 7208                <1> 	jc	short cmp_cmd_date
  1361                              <1> 
  1362 00005A2B C605[B0E60000]01    <1>         mov     byte [Program_Exit], 1
  1363 00005A32 C3                  <1>         retn
  1364                              <1> 
  1365                              <1> cmp_cmd_date:
  1366 00005A33 B104                <1> 	mov	cl, 4
  1367 00005A35 BF[B2C80000]        <1> 	mov	edi, Cmd_Date
  1368 00005A3A E8B3030000          <1> 	call	cmp_cmd	
  1369 00005A3F 720B                <1>         jc	short cmp_cmd_time
  1370                              <1> 	
  1371 00005A41 E8D0F7FFFF          <1> 	call	show_date
  1372 00005A46 E80FF8FFFF          <1> 	call	set_date
  1373 00005A4B C3                  <1> 	retn
  1374                              <1> 
  1375                              <1> cmp_cmd_time:
  1376 00005A4C B104                <1> 	mov	cl, 4
  1377 00005A4E BF[B7C80000]        <1> 	mov	edi, Cmd_Time
  1378 00005A53 E89A030000          <1>    	call	cmp_cmd	
  1379 00005A58 720B                <1> 	jc	short cmp_cmd_show
  1380                              <1> 
  1381 00005A5A E8C6FAFFFF          <1> 	call	show_time
  1382 00005A5F E8F8FAFFFF          <1> 	call	set_time
  1383 00005A64 C3                  <1> 	retn
  1384                              <1> 
  1385                              <1> cmp_cmd_show:
  1386 00005A65 B104                <1> 	mov	cl, 4
  1387 00005A67 BF[C8C80000]        <1> 	mov	edi, Cmd_Show
  1388 00005A6C E881030000          <1>    	call	cmp_cmd	
  1389 00005A71 0F83F6090000        <1>         jnc     show_file
  1390                              <1> 
  1391                              <1> cmp_cmd_echo:
  1392 00005A77 B104                <1> 	mov	cl, 4
  1393 00005A79 BF[0DC90000]        <1> 	mov	edi, Cmd_Echo
  1394 00005A7E E86F030000          <1>    	call	cmp_cmd	
  1395 00005A83 721B                <1> 	jc	short cmp_cmd_copy
  1396                              <1> 
  1397                              <1> 	; 14/04/2016
  1398 00005A85 56                  <1> 	push	esi
  1399                              <1> cmd_echo_asciiz:
  1400 00005A86 46                  <1>         inc	esi
  1401 00005A87 8A06                <1> 	mov	al, [esi]
  1402 00005A89 3C20                <1> 	cmp	al, 20h
  1403 00005A8B 73F9                <1> 	jnb	short cmd_echo_asciiz
  1404 00005A8D C60600              <1> 	mov	byte [esi], 0                 
  1405 00005A90 5E                  <1> 	pop	esi  
  1406 00005A91 E8AAEBFFFF          <1> 	call	print_msg
  1407 00005A96 BE[0DDA0000]        <1> 	mov	esi, NextLine
  1408                              <1> 	;call	print_msg   
  1409                              <1> 	;retn
  1410 00005A9B E9A0EBFFFF          <1> 	jmp	print_msg
  1411                              <1> 
  1412                              <1> cmp_cmd_copy:
  1413 00005AA0 B104                <1> 	mov	cl, 4
  1414 00005AA2 BF[EBC80000]        <1> 	mov	edi, Cmd_Copy
  1415 00005AA7 E846030000          <1>    	call	cmp_cmd	
  1416 00005AAC 0F8301180000        <1> 	jnc	copy_file
  1417                              <1> 
  1418                              <1> cmp_cmd_move:
  1419 00005AB2 B104                <1> 	mov	cl, 4
  1420 00005AB4 BF[F0C80000]        <1> 	mov	edi, Cmd_Move
  1421 00005AB9 E834030000          <1>    	call	cmp_cmd	
  1422 00005ABE 0F8395160000        <1> 	jnc	move_file
  1423                              <1> 
  1424                              <1> cmp_cmd_path:
  1425 00005AC4 B104                <1> 	mov	cl, 4
  1426 00005AC6 BF[F5C80000]        <1> 	mov	edi, Cmd_Path
  1427 00005ACB E822030000          <1>    	call	cmp_cmd	
  1428 00005AD0 0F83351A0000        <1> 	jnc	set_get_path
  1429                              <1> 
  1430                              <1> cmp_cmd_beep:
  1431 00005AD6 B104                <1> 	mov	cl, 4
  1432 00005AD8 BF[2BC90000]        <1> 	mov	edi, Cmd_Beep
  1433 00005ADD E810030000          <1>    	call	cmp_cmd	
  1434 00005AE2 720B                <1> 	jc	short cmp_cmd_find
  1435                              <1> 	; 13/05/2016
  1436 00005AE4 8A3D[26DD0000]      <1> 	mov	bh, [ptty] ; [ACTIVE_PAGE]
  1437 00005AEA E9E0BEFFFF          <1> 	jmp	beeper
  1438                              <1> 
  1439                              <1> cmp_cmd_find:
  1440 00005AEF B104                <1> 	mov	cl, 4
  1441 00005AF1 BF[FFC80000]        <1> 	mov	edi, Cmd_Find
  1442 00005AF6 E8F7020000          <1>    	call	cmp_cmd	
  1443 00005AFB 0F82D4020000        <1>         jc      cmp_cmd_external
  1444                              <1> 
  1445                              <1> 	;call	find_and_list_files
  1446 00005B01 E9EC220000          <1> 	jmp	find_and_list_files
  1447                              <1> 	;retn
  1448                              <1> 
  1449                              <1> c_1:
  1450 00005B06 AD                  <1> 	lodsd
  1451                              <1> cmp_cmd_help:
  1452 00005B07 3C3F                <1> 	cmp	al, '?'
  1453 00005B09 751D                <1>         jne     short cmp_cmd_remark
  1454                              <1> 
  1455 00005B0B BE[88C80000]        <1> 	mov	esi, Command_List
  1456                              <1> cmd_help_next_w:
  1457 00005B10 E82BEBFFFF          <1> 	call	print_msg
  1458                              <1> 
  1459 00005B15 803E20              <1> 	cmp	byte [esi], 20h ; 0
  1460 00005B18 7232                <1> 	jb	short cmd_help_retn
  1461                              <1> 	
  1462 00005B1A 56                  <1> 	push	esi
  1463 00005B1B BE[9CD90000]        <1> 	mov	esi, nextline
  1464 00005B20 E81BEBFFFF          <1> 	call	print_msg
  1465 00005B25 5E                  <1> 	pop	esi
  1466 00005B26 EBE8                <1> 	jmp	short cmd_help_next_w	
  1467                              <1> 
  1468                              <1> cmp_cmd_remark:
  1469 00005B28 3C2A                <1> 	cmp	al, '*'
  1470 00005B2A 0F85A5020000        <1>         jne     cmp_cmd_external
  1471 00005B30 46                  <1> 	inc	esi
  1472 00005B31 BF[20DE0000]        <1> 	mov	edi, Remark
  1473 00005B36 8A06                <1> 	mov	al, [esi]
  1474 00005B38 3C20                <1> 	cmp	al, 20h
  1475 00005B3A 7707                <1> 	ja	short cmd_remark_write
  1476 00005B3C 89FE                <1> 	mov	esi, edi ; Remark
  1477 00005B3E E9FDEAFFFF          <1> 	jmp	print_msg
  1478                              <1> 
  1479                              <1> cmd_remark_write:
  1480 00005B43 AA                  <1> 	stosb
  1481 00005B44 AC                  <1> 	lodsb
  1482 00005B45 3C20                <1> 	cmp	al, 20h
  1483 00005B47 73FA                <1> 	jnb	short cmd_remark_write
  1484 00005B49 C60700              <1> 	mov	byte [edi], 0
  1485                              <1> 
  1486                              <1> cmd_help_retn:
  1487                              <1> cmd_remark_retn:
  1488                              <1> cd_retn:
  1489 00005B4C C3                  <1> 	retn
  1490                              <1> 
  1491                              <1> c_2:
  1492 00005B4D 80F902              <1> 	cmp	cl, 2
  1493 00005B50 0F87B1000000        <1>         ja      c_3
  1494 00005B56 BE[6EDE0000]        <1> 	mov	esi, CommandBuffer
  1495 00005B5B 72A9                <1> 	jb	short c_1
  1496                              <1> 
  1497                              <1> cmp_cmd_cd:
  1498 00005B5D 66AD                <1> 	lodsw
  1499 00005B5F 663D4344            <1> 	cmp	ax, 'CD'
  1500 00005B63 7553                <1> 	jne	short cmp_cmd_drive
  1501 00005B65 46                  <1>         inc	esi
  1502                              <1> cd_0:
  1503 00005B66 668B06              <1> 	mov	ax, [esi]	
  1504 00005B69 3C20                <1> 	cmp	al, 20h
  1505 00005B6B 76DF                <1> 	jna	short cd_retn
  1506                              <1> 	; 10/02/2016
  1507 00005B6D 80FC3A              <1> 	cmp	ah, ':'
  1508 00005B70 7504                <1> 	jne	short cd_1
  1509 00005B72 46                  <1> 	inc	esi
  1510 00005B73 46                  <1> 	inc	esi
  1511 00005B74 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 00005B76 B4CD                <1> 	mov	ah, 0CDh ; mov byte [CD_COMMAND], 0CDh 
  1521                              <1> 
  1522 00005B78 E85A230000          <1> 	call	change_current_directory
  1523 00005B7D 0F8374220000        <1>         jnc     change_prompt_dir_string
  1524                              <1> 
  1525                              <1> cd_error_messages:
  1526 00005B83 3C03                <1> 	cmp	al, 3
  1527 00005B85 740C                <1> 	je	short cd_path_not_found
  1528 00005B87 3C15                <1> 	cmp	al, 15h 
  1529 00005B89 745B                <1> 	je	short cd_drive_not_ready
  1530 00005B8B 3C18                <1> 	cmp	al, 18h ; Bad request structure length 
  1531 00005B8D 746C                <1> 	je	short cd_command_failed
  1532 00005B8F 3C1A                <1> 	cmp	al, 1Ah ; Unknown media type, non-DOS disk
  1533 00005B91 7468                <1>         je      short cd_command_failed
  1534                              <1> 
  1535                              <1> cd_path_not_found:
  1536 00005B93 6650                <1> 	push	ax	
  1537 00005B95 BE[34CB0000]        <1> 	mov	esi, Msg_Dir_Not_Found
  1538 00005B9A E8A1EAFFFF          <1> 	call	print_msg
  1539 00005B9F 6658                <1> 	pop	ax
  1540 00005BA1 3A25[BCDD0000]      <1> 	cmp	ah, [Current_Dir_Level]
  1541 00005BA7 0F834A220000        <1>         jnb     change_prompt_dir_string
  1542 00005BAD 8825[BCDD0000]      <1> 	mov	[Current_Dir_Level], ah
  1543 00005BB3 E93F220000          <1>         jmp     change_prompt_dir_string   
  1544                              <1> 
  1545                              <1> cmp_cmd_drive: ; change current drive
  1546                              <1> 	; C:, D:, E: etc.
  1547 00005BB8 80FC3A              <1> 	cmp	ah, ':'
  1548 00005BBB 0F8514020000        <1>         jne     cmp_cmd_external
  1549                              <1> 
  1550                              <1> cd_2:	; 'CD C:', 'CD D:' ...
  1551 00005BC1 803E20              <1> 	cmp	byte [esi], 20h
  1552 00005BC4 0F8715020000        <1>         ja      loc_cmd_failed
  1553                              <1> 
  1554 00005BCA 24DF                <1> 	and	al, 0DFh
  1555 00005BCC 2C41                <1> 	sub	al, 'A'
  1556 00005BCE 0F820B020000        <1>         jc      loc_cmd_failed
  1557                              <1> 
  1558 00005BD4 3A05[28C80000]      <1>         cmp     al, [Last_DOS_DiskNo]
  1559 00005BDA 770A                <1>         ja	short cd_drive_not_ready
  1560                              <1> 	
  1561 00005BDC 88C2                <1> 	mov	dl, al
  1562 00005BDE E862F3FFFF          <1> 	call 	change_current_drive
  1563 00005BE3 7201                <1> 	jc	short cd_drive_not_ready	
  1564 00005BE5 C3                  <1> 	retn
  1565                              <1> 
  1566                              <1> cd_drive_not_ready:
  1567 00005BE6 BE[F1CA0000]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1568 00005BEB E850EAFFFF          <1> 	call	print_msg
  1569                              <1> 
  1570                              <1> cd_fail_drive_restart:
  1571 00005BF0 8A15[BEDD0000]      <1> 	mov	dl, [Current_Drv]
  1572                              <1> 	;call 	change_current_drive
  1573 00005BF6 E94AF3FFFF          <1>         jmp     change_current_drive
  1574                              <1> 	;retn
  1575                              <1> 
  1576                              <1> cd_command_failed:
  1577 00005BFB BE[D2CA0000]        <1> 	mov	esi, Msg_Bad_Command
  1578 00005C00 E83BEAFFFF          <1> 	call	print_msg
  1579 00005C05 EBE9                <1> 	jmp	short cd_fail_drive_restart
  1580                              <1> 
  1581                              <1> c_3:
  1582                              <1> cmp_cmd_dir:
  1583 00005C07 BF[88C80000]        <1> 	mov	edi, Cmd_Dir
  1584 00005C0C E8E1010000          <1> 	call	cmp_cmd	
  1585 00005C11 0F8380020000        <1> 	jnc	print_directory_list
  1586                              <1> 
  1587                              <1> cmp_cmd_cls:
  1588 00005C17 B103                <1> 	mov	cl, 3
  1589 00005C19 BF[C4C80000]        <1> 	mov	edi, Cmd_Cls
  1590 00005C1E E8CF010000          <1> 	call	cmp_cmd	
  1591 00005C23 0F832DEAFFFF        <1>         jnc	clear_screen
  1592                              <1> 
  1593                              <1> cmp_cmd_ver:
  1594 00005C29 B103                <1> 	mov	cl, 3
  1595 00005C2B BF[92C80000]        <1> 	mov	edi, Cmd_Ver
  1596 00005C30 E8BD010000          <1> 	call	cmp_cmd	
  1597 00005C35 720A                <1> 	jc	short cmp_cmd_mem
  1598                              <1> 
  1599 00005C37 BE[30C80000]        <1> 	mov	esi, mainprog_Version
  1600                              <1> 	;call	print_msg
  1601 00005C3C E9FFE9FFFF          <1> 	jmp	print_msg
  1602                              <1> 	;retn
  1603                              <1> 
  1604                              <1> cmp_cmd_mem:
  1605 00005C41 B103                <1> 	mov	cl, 3
  1606 00005C43 BF[FAC80000]        <1> 	mov	edi, Cmd_Mem
  1607 00005C48 E8A5010000          <1> 	call	cmp_cmd	
  1608 00005C4D 0F8330C2FFFF        <1> 	jnc	memory_info
  1609                              <1> 
  1610                              <1> cmp_cmd_del:
  1611 00005C53 B103                <1> 	mov	cl, 3
  1612 00005C55 BF[CDC80000]        <1> 	mov	edi, Cmd_Del
  1613 00005C5A E893010000          <1> 	call	cmp_cmd	
  1614 00005C5F 0F83340F0000        <1>         jnc     delete_file
  1615                              <1> 
  1616                              <1> cmp_cmd_set:
  1617 00005C65 B103                <1> 	mov	cl, 3
  1618 00005C67 BF[C0C80000]        <1> 	mov	edi, Cmd_Set
  1619 00005C6C E881010000          <1> 	call	cmp_cmd	
  1620 00005C71 0F830C180000        <1>         jnc     set_get_env
  1621                              <1> 
  1622                              <1> cmp_cmd_run:
  1623 00005C77 B103                <1> 	mov	cl, 3
  1624 00005C79 BF[BCC80000]        <1> 	mov	edi, Cmd_Run
  1625 00005C7E E86F010000          <1> 	call	cmp_cmd	
  1626                              <1> 	; 07/05/2016
  1627 00005C83 0F824C010000        <1>         jc      cmp_cmd_external
  1628 00005C89 E9431E0000          <1> 	jmp	load_and_execute_file
  1629                              <1> c_5:
  1630                              <1> cmp_cmd_mkdir:
  1631 00005C8E BF[E5C80000]        <1> 	mov	edi, Cmd_Mkdir
  1632 00005C93 E85A010000          <1> 	call	cmp_cmd	
  1633 00005C98 0F83930A0000        <1>         jnc     make_directory
  1634                              <1> 
  1635                              <1> cmp_cmd_rmdir:
  1636 00005C9E B105                <1> 	mov	cl, 5
  1637 00005CA0 BF[DFC80000]        <1> 	mov	edi, Cmd_Rmdir
  1638 00005CA5 E848010000          <1> 	call	cmp_cmd	
  1639 00005CAA 0F83A00B0000        <1>         jnc     delete_directory
  1640                              <1> 
  1641                              <1> cmp_cmd_chdir:
  1642 00005CB0 B105                <1> 	mov	cl, 5
  1643 00005CB2 BF[25C90000]        <1> 	mov	edi, Cmd_Chdir
  1644 00005CB7 E836010000          <1> 	call	cmp_cmd	
  1645 00005CBC 0F8213010000        <1>         jc      cmp_cmd_external
  1646                              <1> 
  1647 00005CC2 E99FFEFFFF          <1> 	jmp	cd_0
  1648                              <1> 
  1649                              <1> c_6:
  1650 00005CC7 80F906              <1> 	cmp	cl, 6
  1651 00005CCA 0F87DF000000        <1>         ja      c_8
  1652 00005CD0 72BC                <1> 	jb	short c_5
  1653                              <1> cmp_cmd_prompt:
  1654 00005CD2 BF[9BC80000]        <1> 	mov	edi, Cmd_Prompt
  1655 00005CD7 E816010000          <1> 	call	cmp_cmd	
  1656 00005CDC 722E                <1>         jc	short cmp_cmd_volume
  1657                              <1> get_prompt_name_fchar:
  1658 00005CDE AC                  <1> 	lodsb
  1659 00005CDF 3C20                <1> 	cmp	al, 20h
  1660 00005CE1 74FB                <1> 	je	short get_prompt_name_fchar
  1661 00005CE3 7712                <1> 	ja	short loc_change_prompt_label
  1662 00005CE5 BE[7CC80000]        <1> 	mov	esi, TRDOSPromptLabel
  1663 00005CEA C7065452444F        <1> 	mov	dword [esi], "TRDO"
  1664 00005CF0 66C746045300        <1>        	mov	word [esi+4], "S" 
  1665                              <1> loc_cmd_prompt_return:
  1666 00005CF6 C3                  <1> 	retn
  1667                              <1> loc_change_prompt_label:
  1668 00005CF7 66B90B00            <1> 	mov	cx, 11
  1669 00005CFB BF[7CC80000]        <1> 	mov	edi, TRDOSPromptLabel
  1670                              <1> put_char_new_prompt_label:
  1671 00005D00 AA                  <1> 	stosb
  1672 00005D01 AC                  <1> 	lodsb
  1673 00005D02 3C20                <1> 	cmp	al, 20h
  1674 00005D04 7202                <1> 	jb	short pass_put_new_prompt_label
  1675 00005D06 E2F8                <1> 	loop	put_char_new_prompt_label
  1676                              <1> pass_put_new_prompt_label:
  1677 00005D08 C60700              <1> 	mov	byte [edi], 0
  1678 00005D0B C3                  <1> 	retn
  1679                              <1> 
  1680                              <1> cmp_cmd_volume:
  1681 00005D0C B106                <1> 	mov	cl, 6
  1682 00005D0E BF[A2C80000]        <1> 	mov	edi, Cmd_Volume
  1683 00005D13 E8DA000000          <1> 	call	cmp_cmd	
  1684 00005D18 7255                <1>         jc	short cmp_cmd_attrib
  1685                              <1> 
  1686                              <1> cmd_vol1:
  1687 00005D1A AC                  <1> 	lodsb
  1688 00005D1B 3C20                <1> 	cmp	al, 20h
  1689 00005D1D 7707                <1> 	ja	short cmd_vol2
  1690 00005D1F A0[BEDD0000]        <1> 	mov	al, [Current_Drv]
  1691 00005D24 EB3D                <1> 	jmp	short cmd_vol4
  1692                              <1> cmd_vol2:
  1693 00005D26 3C41                <1> 	cmp	al, 'A'
  1694 00005D28 0F82B1000000        <1>         jb      loc_cmd_failed
  1695 00005D2E 3C7A                <1> 	cmp	al, 'z'
  1696 00005D30 0F87A9000000        <1>         ja      loc_cmd_failed
  1697 00005D36 3C5A                <1> 	cmp	al, 'Z'
  1698 00005D38 760A                <1> 	jna	short cmd_vol3
  1699 00005D3A 3C61                <1> 	cmp	al, 'a'
  1700 00005D3C 0F829D000000        <1>         jb      loc_cmd_failed
  1701 00005D42 24DF                <1> 	and	al, 0DFh
  1702                              <1> cmd_vol3:
  1703 00005D44 8A26                <1> 	mov	ah, [esi]
  1704 00005D46 80FC3A              <1> 	cmp	ah, ':'
  1705 00005D49 0F8590000000        <1>         jne     loc_cmd_failed
  1706 00005D4F 2C41                <1> 	sub	al, 'A'
  1707 00005D51 3A05[28C80000]      <1>         cmp     al, [Last_DOS_DiskNo]
  1708 00005D57 760A                <1> 	jna	short cmd_vol4
  1709                              <1> 
  1710 00005D59 BE[F1CA0000]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1711 00005D5E E9DDE8FFFF          <1> 	jmp	print_msg
  1712                              <1> 	
  1713                              <1> cmd_vol4:
  1714 00005D63 E896FAFFFF          <1> 	call	print_volume_info
  1715 00005D68 0F8278FEFFFF        <1>         jc      cd_drive_not_ready
  1716 00005D6E C3                  <1> 	retn
  1717                              <1> 
  1718                              <1> cmp_cmd_attrib:
  1719 00005D6F B106                <1> 	mov	cl, 6
  1720 00005D71 BF[D1C80000]        <1> 	mov	edi, Cmd_Attrib
  1721 00005D76 E877000000          <1> 	call	cmp_cmd	
  1722 00005D7B 0F83380F0000        <1>         jnc     set_file_attributes
  1723                              <1> 
  1724                              <1> cmp_cmd_rename:
  1725 00005D81 B106                <1> 	mov	cl, 6
  1726 00005D83 BF[D8C80000]        <1> 	mov	edi, Cmd_Rename
  1727 00005D88 E865000000          <1> 	call	cmp_cmd	
  1728 00005D8D 0F836E110000        <1>         jnc     rename_file
  1729                              <1> 
  1730                              <1> cmp_cmd_device:
  1731 00005D93 B106                <1> 	mov	cl, 6
  1732 00005D95 BF[16C90000]        <1> 	mov	edi, Cmd_Device
  1733 00005D9A E853000000          <1> 	call	cmp_cmd	
  1734 00005D9F 7234                <1>         jc	short cmp_cmd_external
  1735                              <1> 
  1736 00005DA1 C3                  <1> 	retn
  1737                              <1> 
  1738                              <1> c_7:
  1739                              <1> cmp_cmd_devlist:
  1740 00005DA2 BF[1DC90000]        <1> 	mov	edi, Cmd_DevList
  1741 00005DA7 E846000000          <1> 	call	cmp_cmd	
  1742 00005DAC 7227                <1>         jc	short cmp_cmd_external
  1743                              <1> 
  1744 00005DAE C3                  <1> 	retn
  1745                              <1> 
  1746                              <1> c_8:
  1747 00005DAF 80F908              <1>         cmp	cl, 8
  1748 00005DB2 7721                <1> 	ja	short cmp_cmd_external
  1749 00005DB4 72EC                <1> 	jb	short c_7
  1750                              <1> 
  1751                              <1> cmp_cmd_longname:
  1752 00005DB6 BF[A9C80000]        <1> 	mov	edi, Cmd_LongName
  1753 00005DBB E832000000          <1> 	call	cmp_cmd	
  1754 00005DC0 0F8351060000        <1>         jnc     get_and_print_longname
  1755                              <1> 
  1756                              <1> cmp_cmd_readfile:
  1757 00005DC6 B108                <1> 	mov	cl, 8
  1758 00005DC8 BF[04C90000]        <1> 	mov	edi, Cmd_ReadFile
  1759 00005DCD E820000000          <1> 	call	cmp_cmd	
  1760 00005DD2 7201                <1>         jc	short cmp_cmd_external
  1761                              <1> 
  1762                              <1> loc_cmd_return:
  1763 00005DD4 C3                  <1> 	retn
  1764                              <1> 
  1765                              <1> cmp_cmd_external:
  1766                              <1> 	; 07/05/2016
  1767                              <1> 	; 22/04/2016
  1768 00005DD5 BE[6EDE0000]        <1> 	mov	esi, CommandBuffer
  1769 00005DDA E9F21C0000          <1> 	jmp	loc_run_check_filename 
  1770                              <1> 
  1771                              <1> loc_cmd_failed:
  1772 00005DDF 803D[6EDE0000]20    <1> 	cmp	byte [CommandBuffer], 20h
  1773 00005DE6 76EC                <1> 	jna	short loc_cmd_return
  1774 00005DE8 BE[D2CA0000]        <1> 	mov	esi, Msg_Bad_Command
  1775                              <1> ;	call	print_msg
  1776                              <1> ;loc_cmd_return:
  1777                              <1> ;	retn
  1778 00005DED E94EE8FFFF          <1> 	jmp	print_msg
  1779                              <1> 
  1780                              <1> cmp_cmd:
  1781                              <1> 	 ; 29/01/2016 (TRDOS 386 = TRDOS v2.0)
  1782 00005DF2 BE[6EDE0000]        <1>          mov	esi, CommandBuffer
  1783                              <1>          ; edi = internal command word (ASCIIZ)
  1784                              <1> 	 ; ecx = command length (<=8)
  1785                              <1> cmp_cmd_1:
  1786 00005DF7 AC                  <1> 	lodsb
  1787 00005DF8 AE                  <1> 	scasb
  1788 00005DF9 750D                <1> 	jne	short cmp_cmd_3
  1789 00005DFB E2FA                <1> 	loop	cmp_cmd_1
  1790 00005DFD AC                  <1>  	lodsb
  1791 00005DFE 3C20                <1> 	cmp	al, 20h
  1792 00005E00 7703                <1> 	ja	short cmp_cmd_2
  1793 00005E02 30C0                <1> 	xor	al, al
  1794                              <1> 	; ZF = 1 -> internal command word matches
  1795 00005E04 C3                  <1> 	retn
  1796                              <1> cmp_cmd_2:
  1797                              <1> 	; ZF = 0 (CF = 0) -> external command word 	
  1798 00005E05 58                  <1> 	pop	eax ; no return to the caller from here 
  1799 00005E06 EBCD                <1> 	jmp	cmp_cmd_external	
  1800                              <1> cmp_cmd_3:
  1801 00005E08 F9                  <1> 	stc
  1802                              <1> 	; CF = 1 -> internal command word does not match
  1803 00005E09 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 00005E0A 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 00005E0F 3C01                <1> 	cmp	al, 1
  1817 00005E11 74CC                <1> 	je	loc_cmd_failed
  1818                              <1> loc_run_dir_not_found:
  1819 00005E13 3C03                <1> 	cmp	al, 3
  1820 00005E15 750A                <1> 	jne	short loc_run_file_notfound_msg
  1821                              <1> 	; Path not found (MS-DOS Error Code = 3)
  1822 00005E17 BE[34CB0000]        <1> 	mov	esi, Msg_Dir_Not_Found
  1823 00005E1C E91FE8FFFF          <1> 	jmp	print_msg
  1824                              <1> 
  1825                              <1> loc_run_file_notfound_msg:
  1826 00005E21 3C02                <1> 	cmp	al, 2 ; File not found
  1827 00005E23 750A                <1> 	jne	short loc_run_file_drv_read_err
  1828                              <1> 
  1829                              <1> loc_print_file_notfound_msg: 
  1830 00005E25 BE[4BCB0000]        <1>         mov     esi, Msg_File_Not_Found
  1831                              <1> 	;call	proc_printmsg
  1832                              <1> 	;retn
  1833 00005E2A E911E8FFFF          <1> 	jmp	print_msg
  1834                              <1> 
  1835                              <1> loc_run_file_drv_read_err:
  1836                              <1> 	; Err: 1Eh (Read fault)
  1837 00005E2F 3C1E                <1> 	cmp	al, 1Eh ; Drive not ready or read error
  1838 00005E31 7404                <1> 	je	short loc_run_file_print_drv_read_err
  1839                              <1> 	;
  1840 00005E33 3C15                <1> 	cmp	al, 15h ; Drive not ready (or read error)
  1841 00005E35 750A                <1> 	jne	short loc_run_file_toobig
  1842                              <1> 
  1843                              <1> loc_run_file_print_drv_read_err:
  1844 00005E37 BE[F1CA0000]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1845 00005E3C E9FFE7FFFF          <1> 	jmp	print_msg
  1846                              <1> 
  1847                              <1> loc_run_file_toobig:
  1848 00005E41 3C08                <1> 	cmp	al, 8 ; Not enough free memory to load&run file
  1849 00005E43 750A                <1> 	jne	short loc_run_misc_error
  1850 00005E45 BE[93CB0000]        <1> 	mov	esi, Msg_Insufficient_Memory
  1851 00005E4A 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 00005E4F E8A4C0FFFF          <1> 	call	bytetohex
  1858 00005E54 66A3[C7CB0000]      <1>         mov     [error_code_hex], ax
  1859                              <1> 	
  1860 00005E5A BE[AACB0000]        <1> 	mov	esi, Msg_Error_Code 
  1861                              <1> 	;call	print_msg 
  1862                              <1> 	;retn
  1863                              <1> 
  1864 00005E5F 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 00005E64 50                  <1> 	push	eax
  1869 00005E65 8A3D[1EE60000]      <1> 	mov	bh, [RUN_CDRV] ; it is set at the beginning
  1870                              <1> 				; of the 'run' command.
  1871 00005E6B 3A3D[BEDD0000]      <1> 	cmp	bh, [Current_Drv]
  1872 00005E71 7409                <1> 	je	short loc_run_restore_cdir
  1873 00005E73 88FA                <1> 	mov	dl, bh
  1874 00005E75 E8CBF0FFFF          <1> 	call	change_current_drive 
  1875 00005E7A EB19                <1> 	jmp	short loc_run_err_pass_restore_cdir
  1876                              <1> 
  1877                              <1> loc_run_restore_cdir:
  1878 00005E7C 803D[29C80000]00    <1> 	cmp	byte [Restore_CDIR], 0
  1879 00005E83 7610                <1> 	jna	short loc_run_err_pass_restore_cdir
  1880 00005E85 30DB                <1> 	xor	bl, bl
  1881 00005E87 0FB7F3              <1> 	movzx	esi, bx
  1882 00005E8A 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1883 00005E90 E862F1FFFF          <1> 	call	restore_current_directory
  1884                              <1> 
  1885                              <1> loc_run_err_pass_restore_cdir:
  1886 00005E95 58                  <1> 	pop	eax
  1887 00005E96 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 00005E97 66C705[60E70000]00- <1> 	mov	word [AttributesMask], 0800h ; ..except volume names..
  1894 00005E9F 08                  <1>
  1895 00005EA0 A0[BEDD0000]        <1> 	mov	al, [Current_Drv]
  1896 00005EA5 A2[1EE60000]        <1> 	mov	[RUN_CDRV], al
  1897                              <1> get_dfname_fchar:
  1898 00005EAA AC                  <1> 	lodsb
  1899 00005EAB 3C20                <1> 	cmp	al, 20h
  1900 00005EAD 74FB                <1> 	je	short get_dfname_fchar
  1901 00005EAF 0F82A4000000        <1>         jb      loc_print_dir_call_all
  1902 00005EB5 3C2D                <1> 	cmp	al, '-'
  1903 00005EB7 7542                <1> 	jne	short loc_print_dir_call_flt
  1904                              <1> get_next_attr_char:
  1905 00005EB9 AC                  <1> 	lodsb
  1906 00005EBA 3C20                <1> 	cmp	al, 20h
  1907 00005EBC 74FB                <1> 	je	short get_next_attr_char
  1908 00005EBE 0F821BFFFFFF        <1>         jb      loc_cmd_failed
  1909 00005EC4 24DF                <1> 	and	al, 0DFh
  1910 00005EC6 3C44                <1> 	cmp	al, 'D' ; directories only ?
  1911 00005EC8 7512                <1> 	jne	short pass_only_directories
  1912 00005ECA AC                  <1> 	lodsb
  1913 00005ECB 3C20                <1> 	cmp	al, 20h
  1914 00005ECD 0F870CFFFFFF        <1>         ja      loc_cmd_failed
  1915 00005ED3 800D[60E70000]10    <1> 	or	byte [AttributesMask], 10h ; ..directory..
  1916 00005EDA EB18                <1> 	jmp	short get_dfname_fchar_attr
  1917                              <1> pass_only_directories:
  1918 00005EDC 3C46                <1> 	cmp	al, 'F'	; files only ?
  1919 00005EDE 0F85B0000000        <1>         jne     check_attr_s
  1920 00005EE4 AC                  <1> 	lodsb
  1921 00005EE5 3C20                <1> 	cmp	al, 20h
  1922 00005EE7 0F87F2FEFFFF        <1>         ja      loc_cmd_failed
  1923 00005EED 800D[61E70000]10    <1> 	or	byte [AttributesMask+1], 10h ; ..except directories..
  1924                              <1> get_dfname_fchar_attr:
  1925 00005EF4 AC                  <1> 	lodsb
  1926 00005EF5 3C20                <1> 	cmp	al, 20h
  1927 00005EF7 74FB                <1> 	je	short get_dfname_fchar_attr
  1928 00005EF9 725E                <1> 	jb	short loc_print_dir_call_all
  1929                              <1> 
  1930                              <1> loc_print_dir_call_flt:
  1931 00005EFB 4E                  <1> 	dec	esi
  1932 00005EFC BF[62E70000]        <1> 	mov	edi, FindFile_Drv
  1933 00005F01 E8E5250000          <1> 	call	parse_path_name
  1934 00005F06 7308                <1>  	jnc	short loc_print_dir_change_drv_1
  1935 00005F08 3C01                <1> 	cmp	al, 1
  1936 00005F0A 0F87FAFEFFFF        <1>         ja      loc_run_cmd_failed
  1937                              <1> 
  1938                              <1> loc_print_dir_change_drv_1:
  1939 00005F10 8A15[62E70000]      <1> 	mov	dl, [FindFile_Drv]
  1940                              <1> loc_print_dir_change_drv_2:
  1941 00005F16 3A15[1EE60000]      <1> 	cmp	dl, [RUN_CDRV]
  1942 00005F1C 740B                <1> 	je	short loc_print_dir_change_directory 
  1943 00005F1E E822F0FFFF          <1> 	call	change_current_drive
  1944 00005F23 0F82E1FEFFFF        <1>         jc      loc_run_cmd_failed
  1945                              <1> loc_print_dir_change_directory:
  1946 00005F29 803D[63E70000]20    <1> 	cmp	byte [FindFile_Directory], 20h ; 0 or 20h ?
  1947 00005F30 761D                <1> 	jna	short pass_print_dir_change_directory
  1948                              <1> 
  1949 00005F32 FE05[29C80000]      <1> 	inc	byte [Restore_CDIR]
  1950 00005F38 BE[63E70000]        <1> 	mov	esi, FindFile_Directory
  1951 00005F3D 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  1952 00005F3F E8931F0000          <1> 	call	change_current_directory
  1953 00005F44 0F82C0FEFFFF        <1>         jc      loc_run_cmd_failed
  1954                              <1> 
  1955                              <1> loc_print_dir_change_prompt_dir_string:
  1956 00005F4A E8A81E0000          <1> 	call	change_prompt_dir_string
  1957                              <1> 
  1958                              <1> pass_print_dir_change_directory:
  1959 00005F4F BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  1960 00005F54 803E20              <1> 	cmp	byte [esi], 20h ; ; 0 or 20h ?
  1961 00005F57 7706                <1> 	ja	short loc_print_dir_call
  1962                              <1> 
  1963                              <1> loc_print_dir_call_all:
  1964 00005F59 C7062A2E2A00        <1> 	mov	dword [esi], '*.*'
  1965                              <1> loc_print_dir_call:
  1966 00005F5F E87E000000          <1> 	call	print_directory
  1967                              <1> 
  1968 00005F64 8A15[1EE60000]      <1> 	mov	dl, [RUN_CDRV]  ; it is set at the beginning
  1969 00005F6A 3A15[BEDD0000]      <1> 	cmp	dl, [Current_Drv]
  1970 00005F70 7406                <1> 	je	short loc_print_dir_call_restore_cdir_retn
  1971 00005F72 E8CEEFFFFF          <1> 	call	change_current_drive 
  1972 00005F77 C3                  <1> 	retn
  1973                              <1> 
  1974                              <1> loc_print_dir_call_restore_cdir_retn:
  1975 00005F78 803D[29C80000]00    <1> 	cmp	byte [Restore_CDIR], 0
  1976 00005F7F 7610                <1> 	jna	short pass_print_dir_call_restore_cdir_retn
  1977                              <1> 
  1978 00005F81 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1979 00005F86 31C0                <1> 	xor	eax, eax
  1980 00005F88 88D4                <1> 	mov	ah, dl
  1981 00005F8A 01C6                <1> 	add	esi, eax
  1982                              <1> 
  1983 00005F8C E866F0FFFF          <1> 	call	restore_current_directory
  1984                              <1> 
  1985                              <1> pass_print_dir_call_restore_cdir_retn:
  1986 00005F91 C3                  <1> 	retn
  1987                              <1> 
  1988                              <1> check_attr_s_cap:
  1989 00005F92 24DF                <1> 	and	al, 0DFh
  1990                              <1> check_attr_s:
  1991 00005F94 3C53                <1> 	cmp	al, 'S'
  1992 00005F96 7514                <1> 	jne	short pass_attr_s
  1993 00005F98 800D[60E70000]04    <1> 	or	byte [AttributesMask], 4 ; system
  1994 00005F9F AC                  <1> 	lodsb
  1995 00005FA0 3C20                <1> 	cmp	al, 20h
  1996 00005FA2 0F844CFFFFFF        <1>         je      get_dfname_fchar_attr
  1997 00005FA8 72AF                <1> 	jb	short loc_print_dir_call_all
  1998 00005FAA 24DF                <1> 	and	al, 0DFh
  1999                              <1> pass_attr_s:
  2000 00005FAC 3C48                <1> 	cmp	al, 'H'
  2001 00005FAE 7514                <1> 	jne	short pass_attr_h
  2002 00005FB0 800D[60E70000]02    <1> 	or	byte [AttributesMask], 2 ; hidden
  2003                              <1> pass_attr_shr:
  2004 00005FB7 AC                  <1> 	lodsb
  2005 00005FB8 3C20                <1> 	cmp	al, 20h
  2006 00005FBA 0F8434FFFFFF        <1>         je      get_dfname_fchar_attr
  2007 00005FC0 7297                <1> 	jb	short loc_print_dir_call_all
  2008 00005FC2 EBCE                <1> 	jmp	short check_attr_s_cap
  2009                              <1> 
  2010                              <1> pass_attr_h:
  2011 00005FC4 3C52                <1> 	cmp	al, 'R'
  2012 00005FC6 7509                <1> 	jne	short pass_attr_r
  2013 00005FC8 800D[60E70000]01    <1> 	or	byte [AttributesMask], 1 ; read only
  2014 00005FCF EBE6                <1> 	jmp	short pass_attr_shr
  2015                              <1> 
  2016                              <1> pass_attr_r:
  2017 00005FD1 3C41                <1> 	cmp	al, 'A'
  2018 00005FD3 0F8506FEFFFF        <1>         jne     loc_cmd_failed
  2019 00005FD9 800D[60E70000]20    <1> 	or	byte [AttributesMask], 20h ; archive
  2020 00005FE0 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 00005FE2 56                  <1> 	push	esi
  2034                              <1> 
  2035 00005FE3 29C0                <1> 	sub	eax, eax
  2036                              <1> 
  2037 00005FE5 66A3[ECE70000]      <1> 	mov	word [Dir_Count], ax ; 0
  2038 00005FEB 66A3[EAE70000]      <1> 	mov 	word [File_Count], ax ; 0
  2039 00005FF1 A3[EEE70000]        <1> 	mov 	dword [Total_FSize], eax ; 0
  2040                              <1> 
  2041 00005FF6 E85BE6FFFF          <1> 	call    clear_screen
  2042                              <1> 	
  2043 00005FFB 31C9                <1> 	xor	ecx, ecx	
  2044 00005FFD 8A2D[BEDD0000]      <1> 	mov     ch, [Current_Drv] ; DirBuff_Drv - 'A'
  2045 00006003 A0[BFDD0000]        <1> 	mov     al, [Current_Dir_Drv] 
  2046 00006008 A2[EFC90000]        <1> 	mov     [Dir_Drive_Name], al
  2047 0000600D BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2048 00006012 01CE                <1> 	add	esi, ecx
  2049                              <1> 
  2050 00006014 E85FF9FFFF          <1> 	call	move_volume_name_and_serial_no
  2051 00006019 730C                <1> 	jnc	short print_dir_strlen_check
  2052                              <1> 
  2053 0000601B 5E                  <1> 	pop	esi
  2054 0000601C 8A3D[26DD0000]      <1> 	mov	bh, [ptty] ; [ACTIVE_PAGE]
  2055                              <1> 	;call	beeper
  2056                              <1> 	;retn
  2057 00006022 E9A8B9FFFF          <1> 	jmp	beeper  ; beep ! and return
  2058                              <1> 
  2059                              <1> print_dir_strlen_check:
  2060 00006027 BE[C1DD0000]        <1> 	mov	esi, Current_Dir_Root
  2061 0000602C BF[8CCA0000]        <1> 	mov	edi, Dir_Str_Root
  2062                              <1> 	
  2063                              <1> 	;xor	ecx, ecx
  2064 00006031 8A0D[1DDE0000]      <1>         mov     cl, [Current_Dir_StrLen]
  2065 00006037 FEC1                <1> 	inc	cl
  2066 00006039 80F940              <1> 	cmp	cl, 64
  2067 0000603C 760D                <1> 	jna	short pass_print_dir_strlen_shorting
  2068 0000603E 46                  <1> 	inc	esi
  2069 0000603F 01CE                <1> 	add	esi, ecx
  2070 00006041 83EE40              <1> 	sub	esi, 64 
  2071 00006044 47                  <1> 	inc	edi
  2072 00006045 B82E2E2E20          <1> 	mov	eax, '... ' 
  2073 0000604A AB                  <1> 	stosd
  2074                              <1>  
  2075                              <1> pass_print_dir_strlen_shorting:
  2076 0000604B F3A4                <1> 	rep	movsb
  2077                              <1> 
  2078 0000604D BE[E2C90000]        <1> 	mov	esi, Dir_Drive_Str
  2079 00006052 E8E9E5FFFF          <1> 	call	print_msg
  2080                              <1> 
  2081 00006057 BE[41CA0000]        <1> 	mov	esi, Vol_Serial_Header
  2082 0000605C E8DFE5FFFF          <1> 	call	print_msg
  2083                              <1> 
  2084 00006061 BE[81CA0000]        <1> 	mov	esi, Dir_Str_Header
  2085 00006066 E8D5E5FFFF          <1> 	call	print_msg
  2086                              <1> 	
  2087 0000606B BE[9AD90000]        <1> 	mov	esi, next2line
  2088 00006070 E8CBE5FFFF          <1> 	call	print_msg
  2089                              <1> 
  2090                              <1> loc_print_dir_first_file:
  2091 00006075 C605[01E80000]10    <1> 	mov	byte [PrintDir_RowCounter], 16
  2092 0000607C 66A1[60E70000]      <1> 	mov	ax, [AttributesMask]
  2093 00006082 5E                  <1> 	pop	esi
  2094                              <1> 
  2095 00006083 E859020000          <1> 	call	find_first_file
  2096 00006088 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 0000608E F6C310              <1> 	test	bl, 10h  ; Is it a directory?
  2101 00006091 741B                <1> 	jz	short loc_not_dir
  2102                              <1> 
  2103 00006093 66FF05[ECE70000]    <1> 	inc	word [Dir_Count]
  2104 0000609A 89F2                <1> 	mov	edx, esi 	; FindFile_DirEntry address
  2105 0000609C BE[CECB0000]        <1>  	mov	esi, Type_Dir	; '<DIR>     '
  2106 000060A1 BF[E5CB0000]        <1> 	mov	edi, Dir_Or_FileSize
  2107                              <1> 	; move 10 bytes
  2108 000060A6 A5                  <1> 	movsd
  2109 000060A7 A5                  <1> 	movsd
  2110 000060A8 66A5                <1> 	movsw	    	
  2111 000060AA 89D6                <1> 	mov	esi, edx
  2112 000060AC EB36                <1> 	jmp     short loc_dir_attribute
  2113                              <1> 
  2114                              <1> loc_not_dir:
  2115 000060AE 66FF05[EAE70000]    <1> 	inc	word [File_Count]
  2116 000060B5 0105[EEE70000]      <1> 	add	[Total_FSize], eax
  2117                              <1> 
  2118 000060BB B90A000000          <1> 	mov	ecx, 10  ; 32 bit divisor
  2119 000060C0 89CF                <1> 	mov	edi, ecx
  2120 000060C2 81C7[E5CB0000]      <1> 	add	edi, Dir_Or_FileSize
  2121                              <1> loc_dir_rdivide:
  2122 000060C8 29D2                <1> 	sub	edx, edx
  2123 000060CA F7F1                <1> 	div	ecx 	 ; remainder in dl (< 10)
  2124 000060CC 80C230              <1> 	add     dl, '0'	 ; to make visible (ascii)
  2125 000060CF 4F                  <1> 	dec	edi
  2126 000060D0 8817                <1> 	mov     [edi], dl
  2127 000060D2 21C0                <1> 	and	eax, eax
  2128 000060D4 75F2                <1> 	jnz	short loc_dir_rdivide
  2129                              <1> 
  2130                              <1> loc_dir_fill_space:
  2131 000060D6 81FF[E5CB0000]      <1> 	cmp     edi, Dir_Or_FileSize
  2132 000060DC 7606                <1> 	jna     short loc_dir_attribute
  2133 000060DE 4F                  <1> 	dec     edi
  2134 000060DF C60720              <1> 	mov     byte [edi], 20h
  2135 000060E2 EBF2                <1> 	jmp     short loc_dir_fill_space
  2136                              <1> 
  2137                              <1> loc_dir_attribute:
  2138 000060E4 C705[F0CB0000]2020- <1> 	mov	dword [File_Attribute], 20202020h
  2138 000060EC 2020                <1>
  2139                              <1> 
  2140 000060EE 80FB20              <1> 	cmp	bl, 20h  ; Is it an archive file?
  2141 000060F1 7207                <1> 	jb	short loc_dir_pass_arch
  2142 000060F3 C605[F3CB0000]41    <1> 	mov	byte [File_Attribute+3], 'A'
  2143                              <1> 
  2144                              <1> loc_dir_pass_arch:
  2145 000060FA 80E307              <1> 	and	bl, 7
  2146 000060FD 7428                <1> 	jz	short loc_dir_file_name
  2147 000060FF 88DF                <1> 	mov	bh, bl
  2148 00006101 80E303              <1> 	and	bl, 3
  2149 00006104 38DF                <1> 	cmp	bh, bl
  2150 00006106 7607                <1> 	jna	short loc_dir_pass_s
  2151 00006108 C605[F0CB0000]53    <1> 	mov	byte [File_Attribute], 'S'
  2152                              <1> 
  2153                              <1> loc_dir_pass_s:
  2154 0000610F 80E302              <1> 	and     bl,2
  2155 00006112 7407                <1> 	jz      short loc_dir_pass_h
  2156 00006114 C605[F1CB0000]48    <1> 	mov     byte [File_Attribute+1], 'H'
  2157                              <1> loc_dir_pass_h:
  2158 0000611B 80E701              <1> 	and     bh,1
  2159 0000611E 7407                <1> 	jz      short loc_dir_file_name
  2160 00006120 C605[F2CB0000]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 00006127 8B5E16              <1> 	mov	ebx, [esi+16h]
  2165 0000612A 89F1                <1> 	mov	ecx, esi ; FindFile_DirEntry address
  2166 0000612C BF[D8CB0000]        <1> 	mov     edi, File_Name
  2167                              <1> 	; move 8 bytes
  2168 00006131 A5                  <1> 	movsd
  2169 00006132 A5                  <1> 	movsd
  2170 00006133 C60720              <1> 	mov	byte [edi], 20h
  2171 00006136 47                  <1> 	inc	edi
  2172                              <1> 	; move 3 bytes
  2173 00006137 66A5                <1> 	movsw
  2174 00006139 A4                  <1> 	movsb
  2175 0000613A 89CE                <1> 	mov	esi, ecx
  2176                              <1> 
  2177                              <1> Dir_Time_start:
  2178                              <1> 	;mov	ax, dx		; Time
  2179 0000613C 6689D8              <1> 	mov	ax, bx
  2180 0000613F 66C1E805            <1> 	shr	ax, 5		; shift right 5 times
  2181 00006143 6683E03F            <1> 	and	ax, 0000111111b	; Minute Mask
  2182 00006147 D40A                <1> 	aam			; Q([AL]/10)->AH
  2183                              <1> 				; R([AL]/10)->AL
  2184                              <1> 				; [AL]+[AH]= Minute as BCD
  2185 00006149 660D3030            <1> 	or	ax, '00'	; Convert to ASCII
  2186 0000614D 86E0                <1> 	xchg	ah, al
  2187 0000614F 66A3[03CC0000]      <1> 	mov	[File_Minute], ax
  2188                              <1> 
  2189                              <1> 	;mov	al, dh
  2190 00006155 88F8                <1> 	mov	al, bh
  2191 00006157 C0E803              <1> 	shr	al, 3		; shift right 3 times
  2192 0000615A D40A                <1> 	aam			; [AL]+[AH]= Hours as BCD
  2193 0000615C 660D3030            <1> 	or	ax, '00'
  2194 00006160 86E0                <1> 	xchg	ah, al
  2195 00006162 66A3[00CC0000]      <1> 	mov     [File_Hour], ax
  2196                              <1> 
  2197 00006168 C1EB10              <1> 	shr	ebx, 16		; BX = Date
  2198                              <1> 	
  2199                              <1> Dir_Date_start:
  2200 0000616B 6689D8              <1> 	mov	ax, bx		; Date
  2201 0000616E 6683E01F            <1> 	and	ax, 00011111b	; Day Mask
  2202 00006172 D40A                <1> 	aam			; Q([AL]/10)->AH
  2203                              <1> 				; R([AL]/10)->AL
  2204                              <1> 				; [AL]+[AH]= Day as BCD
  2205 00006174 660D3030            <1> 	or	ax, '00'	; Convert to ASCII
  2206 00006178 86C4                <1> 	xchg	al, ah
  2207                              <1> 
  2208 0000617A 66A3[F5CB0000]      <1> 	mov	[File_Day], ax
  2209                              <1> 
  2210 00006180 6689D8              <1> 	mov	ax, bx
  2211 00006183 66C1E805            <1> 	shr	ax, 5		; shift right 5 times
  2212 00006187 6683E00F            <1> 	and	ax, 00001111b	; Month Mask
  2213 0000618B D40A                <1> 	aam
  2214 0000618D 660D3030            <1> 	or	ax, '00'
  2215 00006191 86E0                <1> 	xchg	ah, al
  2216 00006193 66A3[F8CB0000]      <1> 	mov	[File_Month], ax
  2217                              <1> 
  2218 00006199 6689D8              <1> 	mov	ax, bx
  2219 0000619C 66C1E809            <1> 	shr     ax, 9
  2220 000061A0 6683E07F            <1> 	and	ax, 01111111b	; Result = Year - 1980
  2221 000061A4 6605BC07            <1> 	add	ax, 1980
  2222                              <1> 
  2223 000061A8 B10A                <1> 	mov	cl, 10
  2224 000061AA F6F1                <1> 	div	cl		; Q -> AL, R -> AH 
  2225 000061AC 80CC30              <1> 	or	ah, '0'
  2226 000061AF 8825[FECB0000]      <1> 	mov	[File_Year+3], ah
  2227 000061B5 D40A                <1> 	aam
  2228 000061B7 86E0                <1> 	xchg	ah, al
  2229 000061B9 80CC30              <1> 	or	ah, '0'	  ; Convert to ASCII
  2230 000061BC 8825[FDCB0000]      <1> 	mov	[File_Year+2], ah
  2231 000061C2 D40A                <1> 	aam
  2232 000061C4 86C4                <1> 	xchg	al, ah
  2233 000061C6 660D3030            <1> 	or	ax, '00'
  2234 000061CA 66A3[FBCB0000]      <1> 	mov	[File_Year], ax
  2235                              <1> 
  2236                              <1> loc_show_line:
  2237 000061D0 56                  <1> 	push	esi
  2238 000061D1 BE[D8CB0000]        <1> 	mov     esi, File_Name
  2239 000061D6 E865E4FFFF          <1> 	call	print_msg
  2240 000061DB BE[9CD90000]        <1> 	mov	esi, nextline
  2241 000061E0 E85BE4FFFF          <1> 	call	print_msg
  2242 000061E5 5E                  <1> 	pop	esi
  2243                              <1> 
  2244 000061E6 FE0D[01E80000]      <1> 	dec	byte [PrintDir_RowCounter]
  2245 000061EC 0F84D4000000        <1>         jz      pause_dir_scroll
  2246                              <1> 
  2247                              <1> loc_next_entry:
  2248 000061F2 E899010000          <1> 	call	find_next_file
  2249 000061F7 0F8391FEFFFF        <1>         jnc     loc_dfname_use_this
  2250                              <1> 
  2251                              <1> loc_dir_ok:
  2252 000061FD B90A000000          <1> 	mov     ecx, 10
  2253 00006202 66A1[ECE70000]      <1> 	mov	ax, [Dir_Count]
  2254 00006208 BF[19CC0000]        <1> 	mov	edi, Decimal_Dir_Count
  2255 0000620D 6639C8              <1> 	cmp	ax, cx ; 10
  2256 00006210 7216                <1> 	jb	short pass_ddc
  2257 00006212 47                  <1> 	inc	edi
  2258 00006213 6683F864            <1> 	cmp	ax, 100
  2259 00006217 720F                <1> 	jb	short pass_ddc
  2260 00006219 47                  <1> 	inc	edi
  2261 0000621A 663DE803            <1> 	cmp	ax, 1000
  2262 0000621E 7208                <1> 	jb	short pass_ddc
  2263 00006220 47                  <1> 	inc	edi
  2264 00006221 663D1027            <1> 	cmp	ax, 10000
  2265 00006225 7201                <1> 	jb	short pass_ddc
  2266 00006227 47                  <1> 	inc	edi
  2267                              <1> pass_ddc:
  2268 00006228 886F01              <1> 	mov     [edi+1], ch ; 0
  2269                              <1> loc_ddc_rediv:
  2270 0000622B 31D2                <1> 	xor     edx, edx
  2271 0000622D 66F7F1              <1> 	div     cx	; 10
  2272 00006230 80C230              <1> 	add     dl, '0'
  2273 00006233 8817                <1> 	mov     [edi], dl
  2274 00006235 4F                  <1> 	dec     edi
  2275 00006236 6609C0              <1> 	or	ax, ax
  2276 00006239 75F0                <1> 	jnz	short loc_ddc_rediv
  2277                              <1> 
  2278 0000623B 66A1[EAE70000]      <1> 	mov     ax, [File_Count]
  2279 00006241 BF[08CC0000]        <1> 	mov     edi, Decimal_File_Count
  2280 00006246 6639C8              <1> 	cmp     ax, cx ; 10
  2281 00006249 7216                <1> 	jb      short pass_dfc
  2282 0000624B 47                  <1> 	inc     edi
  2283 0000624C 6683F864            <1> 	cmp     ax, 100
  2284 00006250 720F                <1> 	jb      short pass_dfc
  2285 00006252 47                  <1> 	inc     edi
  2286 00006253 663DE803            <1> 	cmp     ax, 1000
  2287 00006257 7208                <1> 	jb      short pass_dfc
  2288 00006259 47                  <1> 	inc     edi
  2289 0000625A 663D1027            <1> 	cmp     ax, 10000
  2290 0000625E 7201                <1> 	jb      short pass_dfc
  2291 00006260 47                  <1> 	inc     edi
  2292                              <1> pass_dfc:
  2293                              <1> 	;mov    cx, 10
  2294 00006261 886F01              <1> 	mov     [edi+1], ch ; 00
  2295                              <1> loc_dfc_rediv:
  2296                              <1> 	;xor	dx, dx
  2297 00006264 30D2                <1> 	xor	dl, dl
  2298 00006266 66F7F1              <1> 	div	cx
  2299 00006269 80C230              <1> 	add	dl, '0'
  2300 0000626C 8817                <1> 	mov	[edi], dl
  2301 0000626E 4F                  <1> 	dec	edi
  2302 0000626F 6609C0              <1> 	or	ax, ax
  2303 00006272 75F0                <1> 	jnz	short loc_dfc_rediv
  2304                              <1> 
  2305 00006274 BF[00E80000]        <1> 	mov     edi, TFS_Dec_End
  2306                              <1>         ;mov    byte [edi], 0
  2307 00006279 A1[EEE70000]        <1> 	mov     eax, [Total_FSize]
  2308                              <1> 	;mov    ecx, 10
  2309                              <1> rediv_tfs_hex:
  2310                              <1> 	;sub	edx, edx
  2311 0000627E 28D2                <1> 	sub	dl, dl
  2312 00006280 F7F1                <1> 	div	ecx
  2313 00006282 80C230              <1> 	add	dl, '0'
  2314 00006285 4F                  <1> 	dec     edi
  2315 00006286 8817                <1> 	mov     [edi], dl
  2316 00006288 21C0                <1> 	and	eax, eax
  2317 0000628A 75F2                <1> 	jnz	short rediv_tfs_hex
  2318                              <1> 	
  2319 0000628C 893D[F2E70000]      <1> 	mov	[TFS_Dec_Begin], edi
  2320 00006292 BE[06CC0000]        <1> 	mov	esi, Decimal_File_Count_Header
  2321 00006297 E8A4E3FFFF          <1> 	call	print_msg
  2322 0000629C BE[0ECC0000]        <1> 	mov	esi, str_files
  2323 000062A1 E89AE3FFFF          <1> 	call	print_msg
  2324 000062A6 BE[1FCC0000]        <1> 	mov	esi, str_dirs
  2325 000062AB E890E3FFFF          <1> 	call	print_msg
  2326 000062B0 8B35[F2E70000]      <1> 	mov	esi, [TFS_Dec_Begin]
  2327 000062B6 E885E3FFFF          <1> 	call	print_msg
  2328 000062BB BE[30CC0000]        <1> 	mov	esi, str_bytes
  2329 000062C0 E87BE3FFFF          <1> 	call	print_msg
  2330                              <1> 
  2331 000062C5 C3                  <1> 	retn
  2332                              <1> 
  2333                              <1> pause_dir_scroll:
  2334 000062C6 28E4                <1> 	sub	ah, ah           
  2335 000062C8 E8E9A7FFFF          <1> 	call	int16h
  2336 000062CD 3C1B                <1> 	cmp	al, 1Bh
  2337 000062CF 0F8428FFFFFF        <1>         je      loc_dir_ok
  2338 000062D5 C605[01E80000]10    <1> 	mov	byte [PrintDir_RowCounter], 16 ; Reset counter
  2339 000062DC 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 000062E1 66A3[B2E70000]      <1> 	mov	[FindFile_AttributesMask], ax
  2374 000062E7 BF[B4E70000]        <1> 	mov	edi, FindFile_DirEntry ; TR-DOS Fullfilename formatted buffer
  2375 000062EC 31C0                <1> 	xor	eax, eax
  2376 000062EE B90B000000          <1> 	mov	ecx, 11
  2377 000062F3 F3AB                <1> 	rep	stosd	; 44 bytes
  2378                              <1> 	;stosw		; +2 bytes 
  2379                              <1> 	    
  2380 000062F5 BF[A4E70000]        <1> 	mov	edi, FindFile_Name ; FFF structure, offset 66
  2381 000062FA 39FE                <1> 	cmp	esi, edi
  2382 000062FC 7408                <1> 	je	short loc_fff_mfn_ok
  2383 000062FE 89FA                <1> 	mov	edx, edi 
  2384                              <1> 	 ; move 13 bytes
  2385 00006300 A5                  <1> 	movsd
  2386 00006301 A5                  <1> 	movsd
  2387 00006302 A5                  <1> 	movsd
  2388 00006303 AA                  <1> 	stosb
  2389 00006304 89D6                <1> 	mov	esi, edx
  2390                              <1> loc_fff_mfn_ok:
  2391 00006306 BF[53E70000]        <1> 	mov	edi, Dir_Entry_Name ; Dir Entry Format File Name
  2392 0000630B E810210000          <1> 	call	convert_file_name
  2393 00006310 89FE                <1> 	mov	esi, edi ; offset Dir_Entry_Name
  2394                              <1> 
  2395 00006312 66A1[B2E70000]      <1> 	mov	ax, [FindFile_AttributesMask]
  2396                              <1> 	;xor	ecx, ecx
  2397 00006318 30C9                <1> 	xor	cl, cl  
  2398 0000631A E80C1E0000          <1> 	call	locate_current_dir_file
  2399 0000631F 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 00006321 30ED                <1> 	xor	ch, ch 
  2405 00006323 80F60F              <1> 	xor	dh, 0Fh
  2406 00006326 7408                <1> 	jz	short loc_fff_longname_yes
  2407 00006328 882D[B1E70000]      <1> 	mov	[FindFile_LongNameYes], ch ; 0
  2408 0000632E EB0C                <1> 	jmp	short loc_fff_longname_no
  2409                              <1> 
  2410                              <1> loc_fff_longname_yes:
  2411                              <1> 	;inc	byte [FindFile_LongNameYes]
  2412 00006330 8A0D[BEE60000]      <1> 	mov	cl, [LFN_EntryLength]  
  2413 00006336 880D[B1E70000]      <1> 	mov	[FindFile_LongNameEntryLength], cl ; FindFile_LongNameYes
  2414                              <1> 
  2415                              <1> loc_fff_longname_no:
  2416                              <1> 	;mov	bx, [DirBuff_CurrentEntry]
  2417 0000633C 66891D[DCE70000]    <1> 	mov	[FindFile_DirEntryNumber], bx
  2418 00006343 6689C2              <1> 	mov	dx, ax ; Ambigouos Filename chars used sign > 0
  2419                              <1> 
  2420 00006346 A0[BEDD0000]        <1> 	mov	al, [Current_Drv]
  2421 0000634B A2[62E70000]        <1> 	mov	[FindFile_Drv], al 
  2422                              <1> 
  2423 00006350 A1[B8DD0000]        <1> 	mov	eax, [Current_Dir_FCluster]
  2424 00006355 A3[D4E70000]        <1> 	mov	[FindFile_DirFirstCluster], eax
  2425                              <1> 
  2426 0000635A A1[EDE50000]        <1> 	mov	eax, [DirBuff_Cluster]
  2427 0000635F A3[D8E70000]        <1> 	mov	[FindFile_DirCluster], eax
  2428                              <1> 
  2429 00006364 66FF05[DEE70000]    <1> 	inc	word [FindFile_MatchCounter]
  2430                              <1> 
  2431 0000636B 89FB                <1> 	mov	ebx, edi
  2432 0000636D 89FE                <1> 	mov	esi, edi
  2433 0000636F BF[B4E70000]        <1> 	mov	edi, FindFile_DirEntry
  2434 00006374 89F8                <1> 	mov	eax, edi
  2435 00006376 B108                <1> 	mov	cl, 8
  2436 00006378 F3A5                <1> 	rep	movsd
  2437 0000637A 89C6                <1> 	mov	esi, eax
  2438 0000637C 89DF                <1> 	mov	edi, ebx
  2439                              <1> 
  2440 0000637E A1[D0E70000]        <1> 	mov	eax, [FindFile_DirEntry+28] ; File Size
  2441                              <1> 
  2442 00006383 8A1D[BFE70000]      <1> 	mov	bl, [FindFile_DirEntry+11] ; File Attributes 
  2443 00006389 8A3D[B1E70000]      <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 0000638F 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 00006390 66833D[DEE70000]00  <1> 	cmp	word [FindFile_MatchCounter], 0
  2474 00006398 7707                <1> 	ja	short loc_start_search_next_file
  2475                              <1> 
  2476                              <1> loc_fnf_stc_retn:
  2477 0000639A F9                  <1> 	stc
  2478                              <1> loc_fnf_ax12h_retn:
  2479 0000639B B812000000          <1> 	mov	eax, 12h ; 18, No More files
  2480                              <1> ;loc_fnf_retn:
  2481 000063A0 C3                  <1> 	retn
  2482                              <1> 
  2483                              <1> loc_start_search_next_file:
  2484 000063A1 668B1D[DCE70000]    <1> 	mov	bx, [FindFile_DirEntryNumber]
  2485 000063A8 6643                <1> 	inc	bx
  2486 000063AA 663B1D[EBE50000]    <1> 	cmp	bx, [DirBuff_LastEntry]
  2487 000063B1 7719                <1> 	ja	short loc_cont_search_next_file
  2488                              <1> 
  2489                              <1> loc_fnf_search:
  2490 000063B3 BE[53E70000]        <1> 	mov	esi, Dir_Entry_Name
  2491 000063B8 66A1[B2E70000]      <1> 	mov	ax, [FindFile_AttributesMask]
  2492 000063BE 6631C9              <1> 	xor	cx, cx
  2493 000063C1 E8671E0000          <1> 	call	find_directory_entry
  2494 000063C6 0F8355FFFFFF        <1>         jnc     loc_fff_fnf_ln_check
  2495                              <1> 
  2496                              <1> loc_cont_search_next_file:
  2497 000063CC 31DB                <1> 	xor	ebx, ebx
  2498 000063CE 8A3D[BEDD0000]      <1> 	mov	bh, [Current_Drv]
  2499 000063D4 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2500 000063D9 01DE                <1> 	add	esi, ebx
  2501                              <1> 
  2502 000063DB 803D[BCDD0000]00    <1> 	cmp	byte [Current_Dir_Level], 0
  2503 000063E2 7608                <1> 	jna	short loc_fnf_check_FAT_type
  2504 000063E4 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  2505 000063E8 72B1                <1> 	jb	short loc_fnf_ax12h_retn
  2506 000063EA EB06                <1> 	jmp	short loc_fnf_check_next_cluster
  2507                              <1>  
  2508                              <1> loc_fnf_check_FAT_type:
  2509 000063EC 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3
  2510 000063F0 72A9                <1> 	jb	short loc_fnf_ax12h_retn
  2511                              <1> 
  2512                              <1> loc_fnf_check_next_cluster:
  2513 000063F2 A1[EDE50000]        <1> 	mov	eax, [DirBuff_Cluster]
  2514 000063F7 E8E6370000          <1> 	call	get_next_cluster
  2515 000063FC 7306                <1> 	jnc	short loc_fnf_load_next_dir_cluster
  2516 000063FE 09C0                <1> 	or	eax, eax
  2517 00006400 7498                <1> 	jz	short loc_fnf_stc_retn
  2518                              <1> 	;mov	eax, 15h ;Drive not ready or read error
  2519 00006402 F5                  <1>  	cmc	;stc
  2520                              <1> loc_fnf_retn:
  2521 00006403 C3                  <1> 	retn
  2522                              <1> 
  2523                              <1> loc_fnf_load_next_dir_cluster:
  2524 00006404 E8BF390000          <1> 	call	load_FAT_sub_directory
  2525 00006409 72F8                <1> 	jc	short loc_fnf_retn
  2526 0000640B 6631DB              <1> 	xor	bx, bx
  2527 0000640E 66891D[DCE70000]    <1> 	mov	[FindFile_DirEntryNumber], bx
  2528 00006415 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 00006417 803E20              <1> 	cmp	byte [esi], 20h
  2536 0000641A 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 0000641C C3                  <1> 	retn
  2542                              <1> loc_find_longname:
  2543 0000641D E872210000          <1> 	call	find_longname
  2544 00006422 7320                <1> 	jnc	short loc_print_longname
  2545                              <1> 	
  2546 00006424 08C0                <1> 	or	al, al
  2547 00006426 7412                <1> 	jz	short loc_longname_not_found
  2548                              <1> 	  
  2549 00006428 3C15                <1> 	cmp	al, 15h
  2550 0000642A 0F84B6F7FFFF        <1> 	je	cd_drive_not_ready
  2551                              <1> 
  2552                              <1> loc_ln_file_dir_not_found:
  2553 00006430 BE[5DCB0000]        <1> 	mov	esi, Msg_File_Directory_Not_Found
  2554                              <1> 	;call	print_msg	
  2555                              <1>         ;retn
  2556 00006435 E906E2FFFF          <1> 	jmp	print_msg
  2557                              <1> 
  2558                              <1> loc_longname_not_found:
  2559 0000643A BE[7CCB0000]        <1>         mov     esi, Msg_LongName_Not_Found
  2560                              <1> 	;call	print_msg	
  2561                              <1>         ;retn
  2562 0000643F E9FCE1FFFF          <1> 	jmp	print_msg
  2563                              <1> 
  2564                              <1> loc_print_longname:
  2565                              <1> 	;mov	esi, LongFileName
  2566 00006444 BF[BEDE0000]        <1> 	mov	edi, TextBuffer
  2567 00006449 57                  <1> 	push	edi 
  2568 0000644A 3C00                <1> 	cmp	al, 0
  2569 0000644C 7708                <1> 	ja	short loc_print_longname_1
  2570                              <1> loc_print_FS_longname: ; Singlix FS (64 byte ASCIIZ file name)
  2571 0000644E AC                  <1> 	lodsb
  2572 0000644F AA                  <1> 	stosb  
  2573 00006450 08C0                <1> 	or	al, al
  2574 00006452 75FA                <1> 	jnz	short loc_print_FS_longname
  2575 00006454 EB07                <1> 	jmp	short loc_print_longname_2
  2576                              <1> 	;
  2577                              <1> loc_print_longname_1: ; MS Windows long name (UNICODE chars)
  2578 00006456 66AD                <1> 	lodsw
  2579 00006458 AA                  <1> 	stosb  
  2580 00006459 08C0                <1> 	or	al, al
  2581 0000645B 75F9                <1> 	jnz	short loc_print_longname_1
  2582                              <1> 	;
  2583                              <1> loc_print_longname_2:	
  2584 0000645D 5E                  <1> 	pop	esi
  2585 0000645E E8DDE1FFFF          <1> 	call	print_msg
  2586 00006463 BE[9CD90000]        <1>   	mov	esi, nextline
  2587                              <1> 	;call	print_msg
  2588                              <1> 	;retn
  2589 00006468 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 0000646D BF[62E70000]        <1> 	mov	edi, FindFile_Drv
  2600 00006472 E874200000          <1> 	call	parse_path_name
  2601 00006477 0F8262F9FFFF        <1> 	jc	loc_cmd_failed
  2602                              <1> 
  2603                              <1> loc_show_check_filename_exists:
  2604 0000647D BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  2605 00006482 803E20              <1> 	cmp	byte [esi], 20h
  2606 00006485 0F8654F9FFFF        <1> 	jna	loc_cmd_failed
  2607                              <1> 
  2608                              <1> 	; 15/02/2016 (invalid file name check)
  2609 0000648B E809020000          <1> 	call	check_filename 	
  2610 00006490 730A                <1> 	jnc	short loc_show_change_drv
  2611                              <1> 
  2612 00006492 BE[46CC0000]        <1> 	mov	esi, Msg_invalid_name_chars
  2613 00006497 E9A4E1FFFF          <1> 	jmp	print_msg
  2614                              <1>    
  2615                              <1> loc_show_change_drv:
  2616 0000649C 8A35[BEDD0000]      <1> 	mov	dh, [Current_Drv]
  2617 000064A2 8835[1EE60000]      <1> 	mov	[RUN_CDRV], dh
  2618 000064A8 8A15[62E70000]      <1> 	mov	dl, [FindFile_Drv]
  2619 000064AE 38F2                <1> 	cmp	dl, dh
  2620 000064B0 740B                <1> 	je	short loc_show_change_directory
  2621 000064B2 E88EEAFFFF          <1> 	call	change_current_drive
  2622                              <1> 	;jc	loc_file_rw_cmd_failed
  2623 000064B7 0F824DF9FFFF        <1> 	jc	loc_run_cmd_failed
  2624                              <1> 
  2625                              <1> loc_show_change_directory:
  2626 000064BD 803D[63E70000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  2627 000064C4 7618                <1> 	jna	short loc_findload_showfile
  2628                              <1> 
  2629 000064C6 FE05[29C80000]      <1> 	inc	byte [Restore_CDIR]
  2630 000064CC BE[63E70000]        <1> 	mov	esi, FindFile_Directory
  2631 000064D1 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2632 000064D3 E8FF190000          <1> 	call	change_current_directory
  2633                              <1> 	;jc	loc_file_rw_cmd_failed
  2634 000064D8 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 000064DE BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  2642 000064E3 BF[53E70000]        <1> 	mov	edi, Dir_Entry_Name ; Dir Entry Format File Name
  2643 000064E8 E8331F0000          <1> 	call	convert_file_name
  2644 000064ED 89FE                <1> 	mov	esi, edi ; offset Dir_Entry_Name
  2645                              <1> 
  2646 000064EF 28C0                <1> 	sub	al, al	; Attrib AND mask = 0
  2647                              <1> 	; Directory attribute : 10h
  2648                              <1> 	; Volume name attribute: 8h
  2649 000064F1 B418                <1> 	mov	ah, 00011000b ; 18h (Attrib NAND, AND --> zero mask)
  2650                              <1> 	;
  2651 000064F3 6631C9              <1> 	xor	cx, cx  
  2652 000064F6 E8301C0000          <1> 	call	locate_current_dir_file
  2653                              <1> 	;jc	loc_file_rw_cmd_failed
  2654 000064FB 0F8209F9FFFF        <1> 	jc	loc_run_cmd_failed
  2655                              <1> 
  2656                              <1> loc_show_load_file:
  2657                              <1> 	; EDI = Directory Entry
  2658 00006501 668B4714            <1> 	mov	ax, [edi+DirEntry_FstClusHI] ; First Cluster High Word
  2659 00006505 C1E010              <1> 	shl	eax, 16
  2660 00006508 668B471A            <1> 	mov	ax, [edi+DirEntry_FstClusLO] ; First Cluster Low Word
  2661 0000650C A3[0CE80000]        <1> 	mov	[Show_Cluster], eax
  2662 00006511 8B471C              <1> 	mov	eax, [edi+DirEntry_FileSize] ; File Size
  2663 00006514 21C0                <1> 	and	eax, eax ; Empty file !
  2664 00006516 0F8491000000        <1>         jz      end_of_show_file 
  2665 0000651C A3[10E80000]        <1> 	mov	[Show_FileSize], eax
  2666 00006521 31C0                <1> 	xor	eax, eax
  2667 00006523 A3[14E80000]        <1> 	mov	[Show_FilePointer], eax ; 0
  2668 00006528 66A3[18E80000]      <1> 	mov	[Show_ClusterPointer], ax ; 0
  2669 0000652E 29DB                <1> 	sub	ebx, ebx
  2670 00006530 8A3D[BEDD0000]      <1> 	mov	bh, [Current_Drv]
  2671 00006536 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2672 0000653B 01DE                <1> 	add	esi, ebx
  2673 0000653D 8935[08E80000]      <1> 	mov	[Show_LDDDT], esi ; Logical DOS Drv Description Table addr
  2674                              <1> 
  2675 00006543 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0	
  2676 00006547 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 00006549 8B15[0CE80000]      <1> 	mov	edx, [Show_Cluster] ; Compatibility dir. buffer value (FDT)	
  2680 0000654F 8915[04E80000]      <1> 	mov	[Show_FDT], edx
  2681 00006555 31C0                <1> 	xor	eax, eax
  2682 00006557 A3[0CE80000]        <1> 	mov	[Show_Cluster], eax ; Sector index  = 0
  2683                              <1> 				    ; (next time it will be 1)			
  2684                              <1> loc_show_calculate_cluster_size:
  2685 0000655C 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 00006560 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 00006563 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 00006565 66A3[1AE80000]      <1> 	mov	[Show_ClusterSize], ax
  2694                              <1> 
  2695                              <1> loc_start_show_file:
  2696 0000656B BE[9CD90000]        <1> 	mov	esi, nextline
  2697 00006570 E8CBE0FFFF          <1> 	call	print_msg
  2698                              <1> 
  2699 00006575 A1[0CE80000]        <1> 	mov	eax, [Show_Cluster]
  2700 0000657A C605[1CE80000]17    <1> 	mov	byte [Show_RowCount], 23
  2701                              <1> 
  2702                              <1> 	; 17/02/2016
  2703 00006581 8B35[08E80000]      <1> 	mov	esi, [Show_LDDDT]
  2704                              <1> 
  2705                              <1> loc_show_next_cluster:
  2706                              <1> 	; 15/02/2016
  2707 00006587 BB00000700          <1> 	mov	ebx, Cluster_Buffer ; 70000h (for current TRDOS 386 version)
  2708                              <1> 	; ESI = Logical DOS drv description table address
  2709 0000658C E875380000          <1> 	call	read_cluster
  2710                              <1> 	;jc	loc_file_rw_cmd_failed
  2711 00006591 0F8273F8FFFF        <1> 	jc	loc_run_cmd_failed
  2712                              <1> 
  2713 00006597 31DB                <1> 	xor 	ebx, ebx
  2714                              <1> loc_show_next_byte:
  2715 00006599 803D[1CE80000]00    <1> 	cmp	byte [Show_RowCount], 0
  2716 000065A0 7521                <1> 	jne	short pass_show_wait_for_key
  2717 000065A2 30E4                <1> 	xor	ah, ah
  2718 000065A4 E80DA5FFFF          <1> 	call	int16h
  2719 000065A9 3C1B                <1> 	cmp	al, 1Bh
  2720 000065AB 750F                <1> 	jne	short pass_exit_show
  2721                              <1> end_of_show_file:
  2722                              <1> pass_show_file:
  2723 000065AD BE[9CD90000]        <1> 	mov	esi, nextline
  2724 000065B2 E889E0FFFF          <1> 	call	print_msg
  2725 000065B7 E94D010000          <1> 	jmp	loc_file_rw_restore_retn
  2726                              <1> 
  2727                              <1> pass_exit_show:
  2728 000065BC C605[1CE80000]14    <1> 	mov	byte [Show_RowCount], 20
  2729                              <1> pass_show_wait_for_key:
  2730 000065C3 81C300000700        <1> 	add	ebx, Cluster_Buffer
  2731 000065C9 8A03                <1> 	mov	al, [ebx]
  2732 000065CB 3C0D                <1> 	cmp	al, 0Dh
  2733 000065CD 0F8590000000        <1>         jne     loc_show_check_tab_space
  2734 000065D3 FE0D[1CE80000]      <1> 	dec	byte [Show_RowCount]
  2735                              <1> pass_show_dec_rowcount:
  2736 000065D9 B307                <1> 	mov	bl, 7 ; (light gray character color, black background)
  2737 000065DB 8A3D[26DD0000]      <1> 	mov	bh, [ACTIVE_PAGE] ; [ptty]
  2738 000065E1 E809B3FFFF          <1> 	call	_write_tty
  2739                              <1> loc_show_check_eof:
  2740 000065E6 FF05[14E80000]      <1> 	inc	dword [Show_FilePointer]
  2741 000065EC A1[14E80000]        <1> 	mov	eax, [Show_FilePointer]
  2742 000065F1 3B05[10E80000]      <1> 	cmp	eax, [Show_FileSize]
  2743 000065F7 73B4                <1> 	jnb	short end_of_show_file
  2744 000065F9 66FF05[18E80000]    <1> 	inc	word [Show_ClusterPointer]
  2745 00006600 0FB71D[18E80000]    <1> 	movzx	ebx, word [Show_ClusterPointer]
  2746                              <1> 
  2747                              <1> 	; 17/02/2016
  2748                              <1> 	; (sector boundary -9 bits- check, 512 = 0)
  2749 00006607 66F7C3FF01          <1>         test    bx, 1FFh ;  1 to 511
  2750 0000660C 758B                <1> 	jnz	short loc_show_next_byte
  2751                              <1> 
  2752                              <1> 	; 16/02/2016
  2753 0000660E 8B35[08E80000]      <1> 	mov	esi, [Show_LDDDT]
  2754                              <1> 	;
  2755 00006614 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  2756 00006618 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 0000661A A1[0CE80000]        <1> 	mov	eax, [Show_Cluster]
  2761 0000661F 40                  <1> 	inc	eax
  2762 00006620 A3[0CE80000]        <1> 	mov	[Show_Cluster], eax
  2763                              <1> 
  2764 00006625 6621DB              <1> 	and	bx, bx ; 65536 -> 0
  2765 00006628 0F856BFFFFFF        <1>         jnz	loc_show_next_byte
  2766 0000662E E954FFFFFF          <1> 	jmp     loc_show_next_cluster
  2767                              <1> 	 
  2768                              <1> loc_show_check_fat_cluster_size:
  2769                              <1> 	; 17/02/2016
  2770 00006633 663B1D[1AE80000]    <1> 	cmp	bx, [Show_ClusterSize] ; cluster size in bytes
  2771 0000663A 0F8259FFFFFF        <1>         jb	loc_show_next_byte
  2772 00006640 66C705[18E80000]00- <1> 	mov	word [Show_ClusterPointer], 0
  2772 00006648 00                  <1>
  2773                              <1> 
  2774 00006649 A1[0CE80000]        <1> 	mov	eax, [Show_Cluster]
  2775                              <1> 	;mov	esi, [Show_LDDDT]
  2776                              <1> loc_show_get_next_cluster:
  2777 0000664E E88F350000          <1> 	call	get_next_cluster
  2778                              <1> 	;jc	loc_file_rw_cmd_failed
  2779 00006653 0F82B1F7FFFF        <1> 	jc	loc_run_cmd_failed
  2780                              <1> loc_show_update_ccluster:
  2781 00006659 A3[0CE80000]        <1> 	mov	[Show_Cluster], eax			
  2782 0000665E E924FFFFFF          <1>         jmp     loc_show_next_cluster
  2783                              <1> 
  2784                              <1> loc_show_check_tab_space:
  2785 00006663 3C09                <1> 	cmp	al, 09h
  2786 00006665 0F856EFFFFFF        <1>         jne     pass_show_dec_rowcount
  2787                              <1> loc_show_put_tab_space:
  2788 0000666B 8A3D[26DD0000]      <1> 	mov	bh, [ACTIVE_PAGE] ; [ptty]
  2789 00006671 E8AFAFFFFF          <1> 	call	get_cpos
  2790                              <1> 	; dl = cursor column
  2791 00006676 80E207              <1> 	and	dl, 7 ; 18/02/2016
  2792                              <1> 	;shr	bh, 1 ; [ACTIVE_PAGE]
  2793 00006679 8A3D[26DD0000]      <1> 	mov	bh, [ACTIVE_PAGE]
  2794 0000667F B307                <1> 	mov	bl, 7 ; color attribute
  2795                              <1> loc_show_put_space_chars:
  2796 00006681 B020                <1> 	mov	al, 20h ; space
  2797                              <1> 	;mov	bh, [ACTIVE_PAGE] ; [ptty]
  2798                              <1> 	;mov	bl, 7 ; color attribute
  2799 00006683 6652                <1> 	push	dx
  2800 00006685 E865B2FFFF          <1> 	call	_write_tty
  2801 0000668A 665A                <1> 	pop	dx
  2802                              <1> 	; 18/02/2016
  2803 0000668C 80FA07              <1> 	cmp	dl, 7
  2804 0000668F 0F8351FFFFFF        <1> 	jnb	loc_show_check_eof
  2805 00006695 FEC2                <1> 	inc	dl
  2806 00006697 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 00006699 56                  <1> 	push	esi
  2840                              <1> 
  2841 0000669A BF[31C90000]        <1>         mov     edi, invalid_fname_chars
  2842 0000669F AC                  <1> 	lodsb
  2843                              <1> check_filename_next_char:
  2844 000066A0 B914000000          <1> 	mov	ecx, sizeInvFnChars
  2845 000066A5 BF[31C90000]        <1> 	mov	edi, invalid_fname_chars
  2846                              <1> loc_scan_invalid_filename_char:
  2847 000066AA AE                  <1> 	scasb 
  2848 000066AB 741F                <1> 	je	short loc_invalid_filename_stc 
  2849 000066AD E2FB                <1> 	loop	loc_scan_invalid_filename_char
  2850 000066AF AC                  <1> 	lodsb
  2851 000066B0 3C1F                <1> 	cmp	al, 1Fh  ; 20h and above 
  2852 000066B2 77EC                <1> 	ja	short check_filename_next_char
  2853                              <1> 
  2854                              <1> check_filename_dot:
  2855 000066B4 8B3424              <1> 	mov	esi, [esp]
  2856                              <1> 
  2857 000066B7 B421                <1> 	mov	ah, 21h
  2858 000066B9 B908000000          <1> 	mov	ecx, 8
  2859                              <1> loc_check_filename_next_char:
  2860 000066BE AC                  <1> 	lodsb
  2861 000066BF 3C2E                <1> 	cmp	al, 2Eh
  2862 000066C1 7511                <1> 	jne	short pass_check_fn_dot_check
  2863                              <1> loc_check_filename_ext_0:
  2864 000066C3 AC                  <1> 	lodsb
  2865 000066C4 38E0                <1> 	cmp	al, ah ; 21h
  2866 000066C6 7205                <1> 	jb	short loc_invalid_filename
  2867 000066C8 3C2E                <1> 	cmp	al, 2Eh
  2868 000066CA 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 000066CC F9                  <1> 	stc
  2873                              <1> loc_invalid_filename:
  2874 000066CD B80B000000          <1> 	mov	eax, 0Bh ; Invalid format
  2875                              <1> 	; Invalid file name chars
  2876                              <1> loc_check_fn_rtn:
  2877 000066D2 5E                  <1> 	pop	esi
  2878 000066D3 C3                  <1> 	retn
  2879                              <1> 
  2880                              <1> pass_check_fn_dot_check:
  2881 000066D4 38E0                <1> 	cmp	al, ah ; 21h
  2882 000066D6 7224                <1> 	jb	short loc_check_fn_clc_rtn
  2883 000066D8 E2E4                <1> 	loop	loc_check_filename_next_char
  2884 000066DA AC                  <1> 	lodsb
  2885 000066DB 38E0                <1> 	cmp	al, ah ; 21h
  2886 000066DD 721D                <1> 	jb	short loc_check_fn_clc_rtn
  2887 000066DF 3C2E                <1> 	cmp	al, 2Eh
  2888 000066E1 75E9                <1> 	jne	short loc_check_fn_stc_rtn
  2889 000066E3 EBDE                <1> 	jmp	short loc_check_filename_ext_0
  2890                              <1> 
  2891                              <1> loc_check_filename_ext_1:
  2892 000066E5 AC                  <1> 	lodsb
  2893 000066E6 38E0                <1> 	cmp	al, ah ; 21h
  2894 000066E8 7212                <1> 	jb	short loc_check_fn_clc_rtn
  2895 000066EA 3C2E                <1> 	cmp	al, 2Eh
  2896 000066EC 74DE                <1> 	je	short loc_check_fn_stc_rtn
  2897 000066EE AC                  <1> 	lodsb
  2898 000066EF 38E0                <1> 	cmp	al, ah ; 21h
  2899 000066F1 7209                <1> 	jb	short loc_check_fn_clc_rtn
  2900 000066F3 3C2E                <1> 	cmp	al, 2Eh
  2901 000066F5 74D5                <1> 	je	short loc_check_fn_stc_rtn
  2902 000066F7 AC                  <1> 	lodsb
  2903 000066F8 38E0                <1> 	cmp	al, ah ; 21h
  2904 000066FA 73D0                <1> 	jnb	short loc_check_fn_stc_rtn
  2905                              <1> 
  2906                              <1> loc_check_fn_clc_rtn:
  2907 000066FC 5E                  <1> 	pop	esi
  2908 000066FD F8                  <1> 	clc
  2909 000066FE C3                  <1> 	retn
  2910                              <1> 
  2911                              <1> loc_print_deleted_message:
  2912 000066FF BE[1BCD0000]        <1> 	mov	esi, Msg_Deleted
  2913 00006704 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 00006709 9C                  <1> 	pushf 
  2922 0000670A E855F7FFFF          <1> 	call	restore_cdir_after_cmd_fail	
  2923 0000670F 9D                  <1> 	popf
  2924 00006710 720D                <1> 	jc	short loc_file_rw_check_write_fault
  2925 00006712 C3                  <1> 	retn
  2926                              <1> 
  2927                              <1> loc_permission_denied:
  2928                              <1> 	; 27/02/2016
  2929 00006713 BE[28CD0000]        <1> 	mov	esi, Msg_Permission_Denied
  2930 00006718 E823DFFFFF          <1> 	call	print_msg
  2931 0000671D EBEA                <1> 	jmp	short loc_file_rw_restore_retn
  2932                              <1> 
  2933                              <1> loc_file_rw_check_write_fault:
  2934 0000671F 3C1D                <1> 	cmp	al, 1Dh ; Write Fault
  2935 00006721 0F85E8F6FFFF        <1>         jne     loc_run_cmd_failed_cmp_al
  2936 00006727 BE[12CB0000]        <1> 	mov	esi, Msg_Not_Ready_Write_Err
  2937                              <1> 	;call	print_msg
  2938                              <1> 	;retn
  2939 0000672C 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 00006731 803E20              <1> 	cmp	byte [esi], 20h
  2951 00006734 7701                <1>         ja	short loc_mkdir_parse_path_name
  2952                              <1> 
  2953                              <1> loc_mkdir_nodirname_retn:
  2954 00006736 C3                  <1> 	retn
  2955                              <1> 
  2956                              <1> loc_mkdir_parse_path_name:
  2957 00006737 BF[62E70000]        <1> 	mov	edi, FindFile_Drv
  2958 0000673C E8AA1D0000          <1>         call    parse_path_name
  2959 00006741 0F8298F6FFFF        <1> 	jc	loc_cmd_failed
  2960                              <1> 
  2961                              <1> loc_mkdir_check_dirname_exists:
  2962 00006747 BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  2963 0000674C 803E20              <1> 	cmp	byte [esi], 20h
  2964 0000674F 0F868AF6FFFF        <1> 	jna	loc_cmd_failed
  2965 00006755 8935[20E80000]      <1> 	mov	[DelFile_FNPointer], esi
  2966 0000675B E839FFFFFF          <1> 	call	check_filename
  2967 00006760 7259                <1> 	jc	short loc_mkdir_invalid_dir_name_chars
  2968                              <1> 
  2969                              <1> loc_mkdir_drv:
  2970 00006762 8A35[BEDD0000]      <1> 	mov	dh, [Current_Drv]
  2971 00006768 8835[1EE60000]      <1> 	mov	[RUN_CDRV], dh
  2972                              <1> 	
  2973 0000676E 8A15[62E70000]      <1> 	mov	dl, [FindFile_Drv]
  2974 00006774 38F2                <1> 	cmp	dl, dh
  2975 00006776 7407                <1> 	je	short loc_mkdir_change_directory
  2976                              <1> 
  2977 00006778 E8C8E7FFFF          <1> 	call	change_current_drive
  2978 0000677D 728A                <1> 	jc	loc_file_rw_cmd_failed
  2979                              <1> 
  2980                              <1> loc_mkdir_change_directory:
  2981 0000677F 803D[63E70000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  2982 00006786 7614                <1> 	jna	short loc_mkdir_find_directory
  2983                              <1> 
  2984 00006788 FE05[29C80000]      <1> 	inc	byte [Restore_CDIR]
  2985 0000678E BE[63E70000]        <1> 	mov	esi, FindFile_Directory
  2986 00006793 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2987 00006795 E83D170000          <1> 	call	change_current_directory
  2988 0000679A 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 0000679C 8B35[20E80000]      <1> 	mov	esi, [DelFile_FNPointer]
  2996                              <1> 	;xor	eax, eax
  2997 000067A2 6631C0              <1> 	xor	ax, ax ; any name (dir, file, volume)
  2998 000067A5 E837FBFFFF          <1> 	call	find_first_file
  2999 000067AA 721E                <1> 	jc	short loc_mkdir_check_error_code
  3000                              <1> 
  3001                              <1> loc_mkdir_directory_found:
  3002 000067AC BE[73CC0000]        <1> 	mov	esi, Msg_Name_Exists
  3003 000067B1 E88ADEFFFF          <1> 	call	print_msg
  3004                              <1> 
  3005 000067B6 E94EFFFFFF          <1>         jmp     loc_file_rw_restore_retn
  3006                              <1> 
  3007                              <1> loc_mkdir_invalid_dir_name_chars:
  3008 000067BB BE[46CC0000]        <1> 	mov	esi, Msg_invalid_name_chars
  3009 000067C0 E87BDEFFFF          <1> 	call	print_msg
  3010                              <1> 
  3011 000067C5 E93FFFFFFF          <1>         jmp     loc_file_rw_restore_retn
  3012                              <1> 
  3013                              <1> loc_mkdir_check_error_code:
  3014 000067CA 3C02                <1> 	cmp	al, 2
  3015                              <1> 	;je	short loc_mkdir_directory_not_found
  3016 000067CC 7406                <1> 	je	short loc_mkdir_ask_for_yes_no
  3017 000067CE F9                  <1> 	stc
  3018 000067CF 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 000067D4 BE[94CC0000]        <1> 	mov	esi, Msg_DoYouWantMkdir
  3023 000067D9 E862DEFFFF          <1> 	call	print_msg
  3024 000067DE 8B35[20E80000]      <1> 	mov	esi, [DelFile_FNPointer]
  3025 000067E4 E857DEFFFF          <1> 	call	print_msg
  3026 000067E9 BE[B3CC0000]        <1> 	mov	esi, Msg_YesNo
  3027 000067EE E84DDEFFFF          <1> 	call	print_msg
  3028                              <1> 
  3029 000067F3 C605[BDCC0000]20    <1> 	mov	byte [Y_N_nextline], 20h
  3030                              <1> 
  3031                              <1> loc_mkdir_ask_again:
  3032 000067FA 30E4                <1> 	xor	ah, ah
  3033 000067FC E8B5A2FFFF          <1> 	call	int16h
  3034 00006801 3C1B                <1> 	cmp	al, 1Bh
  3035                              <1> 	;je	short loc_do_not_make_directory
  3036 00006803 7447                <1> 	je	short loc_mkdir_y_n_escape
  3037 00006805 24DF                <1> 	and	al, 0DFh ; y -> Y, n -> N
  3038 00006807 3C59                <1> 	cmp	al, 'Y' ; 'yes'
  3039 00006809 7404                <1> 	je	short loc_mkdir_yes_make_directory
  3040 0000680B 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3041 0000680D 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 0000680F A2[BDCC0000]        <1> 	mov	[Y_N_nextline], al
  3046 00006814 6650                <1> 	push	ax
  3047 00006816 BE[BDCC0000]        <1> 	mov	esi, Y_N_nextline
  3048 0000681B E820DEFFFF          <1> 	call	print_msg
  3049 00006820 6658                <1> 	pop	ax
  3050                              <1> 	;cmp	al, 'Y' ; 'yes'
  3051                              <1> 	;cmc
  3052                              <1>         ;jnc	loc_file_rw_restore_retn
  3053 00006822 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3054 00006824 0F84DFFEFFFF        <1>         je	loc_file_rw_restore_retn  
  3055                              <1> 
  3056                              <1> loc_mkdir_call_make_sub_directory:
  3057 0000682A 8B35[20E80000]      <1> 	mov	esi, [DelFile_FNPointer]
  3058 00006830 B110                <1> 	mov	cl, 10h ; Directory attributes 
  3059 00006832 E8B31D0000          <1> 	call	make_sub_directory
  3060                              <1> loc_rename_file_ok: ; 06/03/2016
  3061 00006837 0F82CCFEFFFF        <1>         jc	loc_file_rw_cmd_failed
  3062                              <1> move_source_file_to_destination_OK:
  3063 0000683D BE[C1CC0000]        <1> 	mov	esi, Msg_OK
  3064 00006842 E8F9DDFFFF          <1> 	call	print_msg
  3065 00006847 E9BDFEFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3066                              <1> 
  3067                              <1> loc_mkdir_y_n_escape:
  3068 0000684C B04E                <1> 	mov	al, 'N' ; 'no'
  3069 0000684E 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 00006850 803E20              <1> 	cmp	byte [esi], 20h
  3084 00006853 7701                <1>         ja	short loc_rmdir_parse_path_name
  3085                              <1> 
  3086                              <1> loc_rmdir_nodirname_retn:
  3087 00006855 C3                  <1> 	retn
  3088                              <1> 
  3089                              <1> loc_rmdir_parse_path_name:
  3090 00006856 BF[62E70000]        <1> 	mov	edi, FindFile_Drv
  3091 0000685B E88B1C0000          <1> 	call	parse_path_name
  3092 00006860 0F8279F5FFFF        <1> 	jc	loc_cmd_failed
  3093                              <1> 
  3094                              <1> loc_rmdir_check_dirname_exists:
  3095 00006866 BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  3096 0000686B 803E20              <1> 	cmp	byte [esi], 20h
  3097 0000686E 0F866BF5FFFF        <1> 	jna	loc_cmd_failed
  3098 00006874 8935[20E80000]      <1> 	mov	[DelFile_FNPointer], esi 
  3099                              <1> 
  3100                              <1> loc_rmdir_drv:
  3101 0000687A 8A35[BEDD0000]      <1> 	mov	dh, [Current_Drv]
  3102 00006880 8835[1EE60000]      <1> 	mov	[RUN_CDRV], dh
  3103                              <1> 
  3104 00006886 8A15[62E70000]      <1> 	mov	dl, [FindFile_Drv]
  3105 0000688C 38F2                <1> 	cmp	dl, dh
  3106 0000688E 740B                <1> 	je	short loc_rmdir_change_directory
  3107                              <1> 
  3108 00006890 E8B0E6FFFF          <1> 	call	change_current_drive
  3109 00006895 0F826EFEFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3110                              <1> 
  3111                              <1> loc_rmdir_change_directory:
  3112 0000689B 803D[63E70000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3113 000068A2 7614                <1> 	jna	short loc_rmdir_find_directory
  3114                              <1> 
  3115 000068A4 FE05[29C80000]      <1> 	inc	byte [Restore_CDIR]
  3116 000068AA BE[63E70000]        <1> 	mov	esi, FindFile_Directory
  3117 000068AF 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3118 000068B1 E821160000          <1> 	call	change_current_directory
  3119 000068B6 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 000068B8 8B35[20E80000]      <1> 	mov	esi, [DelFile_FNPointer]
  3127 000068BE 66B81008            <1> 	mov	ax, 0810h ; Only directories
  3128 000068C2 E81AFAFFFF          <1> 	call	find_first_file
  3129 000068C7 730A                <1> 	jnc	short loc_rmdir_ambgfn_check
  3130                              <1> 
  3131                              <1> loc_rmdir_check_error_code:
  3132 000068C9 3C02                <1> 	cmp	al, 2
  3133 000068CB 740B                <1> 	je	short loc_rmdir_directory_not_found
  3134 000068CD F9                  <1> 	stc
  3135 000068CE E936FEFFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3136                              <1> 
  3137                              <1> loc_rmdir_ambgfn_check:
  3138 000068D3 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3139 000068D6 740F                <1> 	jz	short loc_rmdir_directory_found
  3140                              <1> 
  3141                              <1> loc_rmdir_directory_not_found:
  3142 000068D8 BE[34CB0000]        <1> 	mov	esi, Msg_Dir_Not_Found
  3143 000068DD E85EDDFFFF          <1> 	call	print_msg
  3144                              <1> 
  3145 000068E2 E922FEFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3146                              <1> 
  3147                              <1> loc_rmdir_directory_found:
  3148 000068E7 80E307              <1> 	and	bl, 07h ; Attributes
  3149 000068EA 0F8523FEFFFF        <1> 	jnz	loc_permission_denied
  3150                              <1> 
  3151                              <1> loc_rmdir_save_lnel: ; 28/02/2016
  3152                              <1>        ;mov	bh, [LongName_EntryLength]
  3153 000068F0 883D[2AE80000]      <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 000068F6 57                  <1> 	push	edi ; * (29/02/2016)
  3166                              <1> 
  3167 000068F7 BE[C7CC0000]        <1> 	mov	esi, Msg_DoYouWantRmDir
  3168 000068FC E83FDDFFFF          <1> 	call	print_msg
  3169 00006901 8B35[20E80000]      <1> 	mov	esi, [DelFile_FNPointer]
  3170 00006907 E834DDFFFF          <1> 	call	print_msg
  3171 0000690C BE[B3CC0000]        <1> 	mov	esi, Msg_YesNo
  3172 00006911 E82ADDFFFF          <1> 	call	print_msg
  3173                              <1> 
  3174                              <1> loc_rmdir_ask_again:
  3175 00006916 30E4                <1> 	xor	ah, ah
  3176 00006918 E899A1FFFF          <1> 	call	int16h
  3177 0000691D 3C1B                <1> 	cmp	al, 1Bh
  3178                              <1> 	;je	short loc_do_not_delete_directory
  3179 0000691F 0F8498000000        <1>         je      loc_rmdir_y_n_escape ; 06/03/2016
  3180 00006925 24DF                <1> 	and	al, 0DFh
  3181 00006927 A2[BDCC0000]        <1> 	mov	[Y_N_nextline], al
  3182 0000692C 3C59                <1> 	cmp	al, 'Y'
  3183 0000692E 7404                <1> 	je	short loc_rmdir_yes_delete_directory
  3184 00006930 3C4E                <1> 	cmp	al, 'N'
  3185 00006932 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 00006934 A2[BDCC0000]        <1> 	mov	[Y_N_nextline], al
  3190 00006939 6650                <1> 	push	ax
  3191 0000693B BE[BDCC0000]        <1> 	mov	esi, Y_N_nextline
  3192 00006940 E8FBDCFFFF          <1> 	call	print_msg
  3193 00006945 6658                <1> 	pop	ax
  3194 00006947 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 00006948 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3199 0000694A 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 00006950 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  3204 00006954 C1E010              <1>         shl	eax, 16
  3205 00006957 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  3206                              <1> 
  3207 0000695B A3[24E80000]        <1> 	mov 	[DelFile_FCluster], eax
  3208                              <1> 
  3209                              <1> 	;mov	bx, [DirBuff_EntryCounter]
  3210 00006960 668B1D[DCE70000]    <1> 	mov	bx, [FindFile_DirEntryNumber] ; 27/02/2016
  3211 00006967 66891D[28E80000]    <1> 	mov	[DelFile_EntryCounter], bx
  3212                              <1> 
  3213 0000696E 29DB                <1>     	sub	ebx, ebx
  3214 00006970 8A3D[62E70000]      <1> 	mov	bh, [FindFile_Drv]
  3215 00006976 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3216 0000697B 01DE                <1> 	add	esi, ebx
  3217                              <1> 
  3218 0000697D 66817F0CA101        <1> 	cmp	word [edi+DirEntry_NTRes], 01A1h
  3219 00006983 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 00006985 8B15[EDE50000]      <1> 	mov	edx, [DirBuff_Cluster]
  3228 0000698B 8915[54E80000]      <1> 	mov	[RmDir_ParentDirCluster], edx
  3229                              <1> 
  3230 00006991 893D[50E80000]      <1> 	mov	[RmDir_DirEntryOffset], edi
  3231                              <1> 
  3232                              <1> 	; 01/03/2016
  3233 00006997 C705[DEE50000]0000- <1> 	mov	dword [FAT_ClusterCounter], 0 ; Reset
  3233 0000699F 0000                <1>
  3234                              <1> 
  3235                              <1> loc_rmdir_get_last_cluster:
  3236 000069A1 E8373A0000          <1> 	call	get_last_cluster
  3237 000069A6 0F82B8000000        <1>         jc      loc_rmdir_cmd_failed
  3238                              <1> 	
  3239 000069AC 3B05[24E80000]      <1> 	cmp	eax, [DelFile_FCluster]
  3240 000069B2 752F                <1> 	jne	short loc_rmdir_multi_dir_clusters
  3241                              <1> 
  3242 000069B4 C605[4FE80000]00    <1> 	mov	byte [RmDir_MultiClusters], 0
  3243 000069BB EB2D                <1> 	jmp	short pass_rmdir_multi_dir_clusters
  3244                              <1> 
  3245                              <1> loc_rmdir_y_n_escape:
  3246 000069BD B04E                <1> 	mov	al, 'N' ; 'no'
  3247 000069BF E970FFFFFF          <1>         jmp     loc_do_not_delete_directory
  3248                              <1> 
  3249                              <1> loc_rmdir_delete_fs_directory:
  3250 000069C4 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  3251 000069C8 0F8545FDFFFF        <1> 	jne	loc_permission_denied
  3252                              <1> 
  3253 000069CE E821140000          <1> 	call	delete_fs_directory
  3254 000069D3 0F8326FDFFFF        <1> 	jnc	loc_print_deleted_message
  3255                              <1> 
  3256 000069D9 09C0                <1> 	or	eax, eax
  3257 000069DB 745D                <1> 	jz	loc_rmdir_directory_not_empty_2         
  3258 000069DD F9                  <1> 	stc
  3259 000069DE E926FDFFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3260                              <1>  
  3261                              <1> loc_rmdir_multi_dir_clusters:
  3262 000069E3 C605[4FE80000]01    <1> 	mov	byte [RmDir_MultiClusters], 1
  3263                              <1> 
  3264                              <1> pass_rmdir_multi_dir_clusters:
  3265 000069EA A3[58E80000]        <1> 	mov 	[RmDir_DirLastCluster], eax
  3266 000069EF 890D[5CE80000]      <1> 	mov	[RmDir_PreviousCluster], ecx
  3267                              <1> 
  3268                              <1> loc_rmdir_load_fat_sub_directory:
  3269 000069F5 E8CE330000          <1> 	call	load_FAT_sub_directory
  3270 000069FA 7268                <1> 	jc	loc_rmdir_cmd_failed
  3271                              <1> 
  3272                              <1> loc_rmdir_find_last_dir_entry:
  3273 000069FC 56                  <1> 	push	esi
  3274 000069FD BE[46E70000]        <1> 	mov	esi, Dir_File_Name
  3275 00006A02 C6062A              <1> 	mov	byte [esi], '*'
  3276 00006A05 C646082A            <1> 	mov	byte [esi+8], '*'
  3277 00006A09 31DB                <1> 	xor	ebx, ebx ; Entry offset  = 0
  3278                              <1> loc_rmdir_find_last_dir_entry_next:
  3279 00006A0B 66B80008            <1> 	mov	ax, 0800h ; Except volume/long names
  3280 00006A0F 6631C9              <1> 	xor	cx, cx ; 0 = Find a valid file or dir name
  3281 00006A12 E816180000          <1> 	call	find_directory_entry
  3282 00006A17 7271                <1> 	jc	short loc_rmdir_empty_dir_cluster
  3283 00006A19 83FB01              <1> 	cmp	ebx, 1
  3284 00006A1C 771B                <1> 	ja	short loc_rmdir_directory_not_empty_1
  3285                              <1> loc_rmdir_dot_entry_check:
  3286 00006A1E 80FD2E              <1> 	cmp	ch, '.' ; The first char of the dir entry
  3287 00006A21 7516                <1> 	jne	short loc_rmdir_directory_not_empty_1
  3288 00006A23 08DB                <1> 	or	bl, bl
  3289 00006A25 7506                <1> 	jnz	short loc_rmdir_dotdot_entry_check
  3290 00006A27 807F0120            <1> 	cmp	byte [edi+1], 20h
  3291 00006A2B EB06                <1> 	jmp	short pass_rmdir_dot_entry_check
  3292                              <1> 
  3293                              <1> loc_rmdir_dotdot_entry_check:
  3294 00006A2D 66817F012E20        <1> 	cmp	word [edi+1], '. '
  3295                              <1> pass_rmdir_dot_entry_check:	
  3296 00006A33 7504                <1> 	jne	short loc_rmdir_directory_not_empty_1 
  3297 00006A35 FEC3                <1> 	inc	bl
  3298 00006A37 EBD2                <1> 	jmp	short loc_rmdir_find_last_dir_entry_next 
  3299                              <1> 
  3300                              <1> 
  3301                              <1> loc_rmdir_directory_not_empty_1:
  3302 00006A39 58                  <1> 	pop	eax ; pushed esi 
  3303                              <1> 
  3304                              <1> loc_rmdir_directory_not_empty_2:
  3305 00006A3A BE[E8CC0000]        <1> 	mov	esi, Msg_Dir_Not_Empty
  3306 00006A3F E8FCDBFFFF          <1> 	call	print_msg
  3307                              <1> 	; 01/03/2016
  3308 00006A44 A1[DEE50000]        <1> 	mov	eax, [FAT_ClusterCounter]
  3309 00006A49 09C0                <1> 	or	eax, eax ; 0 ?
  3310 00006A4B 0F84B8FCFFFF        <1> 	jz	loc_file_rw_restore_retn
  3311                              <1> 	; ESI = Logical DOS Drive Description Table address	
  3312                              <1> 
  3313 00006A51 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> use ESI for Drive parameters
  3314                              <1> 	           ; BL = 1 -> add free clusters
  3315 00006A55 E804380000          <1> 	call	calculate_fat_freespace
  3316 00006A5A 09C9                <1> 	or	ecx, ecx
  3317 00006A5C 0F84A7FCFFFF        <1>         jz      loc_file_rw_restore_retn ; ecx = 0 -> OK
  3318                              <1> 	; ecx > 0 -> Error (Recalculation is neeeded)
  3319 00006A62 EB0E                <1> 	jmp	short loc_rmdir_cmd_return
  3320                              <1> 
  3321                              <1> 
  3322                              <1> loc_rmdir_cmd_failed:
  3323 00006A64 833D[DEE50000]01    <1> 	cmp	dword [FAT_ClusterCounter], 1
  3324 00006A6B 0F8298FCFFFF        <1> 	jb	loc_file_rw_cmd_failed	
  3325 00006A71 F9                  <1> 	stc
  3326                              <1> loc_rmdir_cmd_return:
  3327                              <1> 	; 01/03/2016
  3328 00006A72 9C                  <1> 	pushf
  3329                              <1> 	; ESI = Logical DOS Drive Description Table address	
  3330 00006A73 66BB00FF            <1> 	mov	bx, 0FF00h ; BH = FFh -> use ESI for Drive parameters
  3331                              <1> 	           ; BL = 0 -> Recalculate free cluster count
  3332 00006A77 50                  <1> 	push	eax
  3333 00006A78 E8E1370000          <1> 	call	calculate_fat_freespace	
  3334 00006A7D 58                  <1> 	pop	eax
  3335 00006A7E 9D                  <1> 	popf
  3336 00006A7F 0F8284FCFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3337 00006A85 E97FFCFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3338                              <1> 
  3339                              <1> 
  3340                              <1> loc_rmdir_empty_dir_cluster:
  3341 00006A8A 5E                  <1> 	pop	esi
  3342                              <1> 
  3343                              <1> loc_rmdir_set_prev_cluster_dir_last_cluster:
  3344 00006A8B 803D[4FE80000]00    <1> 	cmp	byte [RmDir_MultiClusters], 0
  3345 00006A92 761D                <1> 	jna	short loc_rmdir_unlink_dir_last_cluster
  3346                              <1> 
  3347 00006A94 A1[5CE80000]        <1> 	mov	eax, [RmDir_PreviousCluster]
  3348                              <1> 	;xor	ecx, ecx
  3349 00006A99 49                  <1> 	dec	ecx ; FFFFFFFFh
  3350 00006A9A E86D340000          <1> 	call	update_cluster
  3351 00006A9F 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 00006AA1 83F801              <1> 	cmp	eax, 1  ; eax = 0 -> end of cluster chain
  3356 00006AA4 F5                  <1> 	cmc 
  3357 00006AA5 72BD                <1> 	jc	short loc_rmdir_cmd_failed
  3358 00006AA7 EB1D                <1> 	jmp	short loc_rmdir_save_fat_buffer 
  3359                              <1> 	
  3360                              <1> loc_rmdir_unlink_stc_retn_0Bh:
  3361 00006AA9 B80B000000          <1> 	mov	eax, 0Bh ; Invalid format
  3362 00006AAE F9                  <1> 	stc
  3363 00006AAF EBB3                <1> 	jmp	short loc_rmdir_cmd_failed
  3364                              <1>  
  3365                              <1> loc_rmdir_unlink_dir_last_cluster:
  3366 00006AB1 A1[58E80000]        <1> 	mov	eax, [RmDir_DirLastCluster]
  3367 00006AB6 31C9                <1> 	xor	ecx, ecx ; 0
  3368 00006AB8 E84F340000          <1> 	call	update_cluster
  3369 00006ABD 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 00006ABF 09C0                <1> 	or	eax, eax
  3373 00006AC1 7403                <1> 	jz	short loc_rmdir_save_fat_buffer ; eocc	
  3374 00006AC3 F9                  <1> 	stc
  3375 00006AC4 EB9E                <1>         jmp     short loc_rmdir_cmd_failed
  3376                              <1> 	 
  3377                              <1> loc_rmdir_save_fat_buffer:
  3378 00006AC6 803D[D6E50000]02    <1> 	cmp	byte [FAT_BuffValidData], 2
  3379 00006ACD 7525                <1> 	jne	short loc_rmdir_calculate_FAT_freespace
  3380 00006ACF E8F5360000          <1> 	call	save_fat_buffer
  3381 00006AD4 728E                <1> 	jc	short loc_rmdir_cmd_failed
  3382                              <1> 
  3383                              <1> 	; 01/03/2016
  3384 00006AD6 803D[4FE80000]00    <1> 	cmp	byte [RmDir_MultiClusters], 0
  3385 00006ADD 7615                <1> 	jna	short loc_rmdir_calculate_FAT_freespace
  3386                              <1> 
  3387 00006ADF A1[24E80000]        <1> 	mov	eax, [DelFile_FCluster]
  3388 00006AE4 E9B8FEFFFF          <1>         jmp     loc_rmdir_get_last_cluster
  3389                              <1> 
  3390                              <1> loc_rmdir_delete_short_name_invalid_data:
  3391 00006AE9 B80D000000          <1> 	mov	eax, 0Dh ; Invalid data
  3392 00006AEE F9                  <1> 	stc
  3393 00006AEF E970FFFFFF          <1>         jmp     loc_rmdir_cmd_failed
  3394                              <1> 
  3395                              <1> loc_rmdir_calculate_FAT_freespace:
  3396 00006AF4 A1[DEE50000]        <1> 	mov	eax, [FAT_ClusterCounter]
  3397 00006AF9 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 00006AFD E85C370000          <1> 	call	calculate_fat_freespace
  3402                              <1> 
  3403 00006B02 21C9                <1> 	and	ecx, ecx ; ecx = 0 -> valid free sector count
  3404 00006B04 7409                <1> 	jz 	short loc_rmdir_delete_short_name_continue
  3405                              <1> 
  3406                              <1> loc_rmdir_recalculate_FAT_freespace:
  3407 00006B06 66BB00FF            <1>         mov     bx, 0FF00h ; BL = 0 -> Recalculate free space
  3408 00006B0A E84F370000          <1> 	call	calculate_fat_freespace
  3409                              <1> 	          
  3410                              <1> loc_rmdir_delete_short_name_continue:
  3411 00006B0F A1[54E80000]        <1> 	mov	eax, [RmDir_ParentDirCluster]
  3412 00006B14 83F802              <1> 	cmp	eax, 2
  3413 00006B17 730D                <1> 	jnb	short loc_rmdir_del_short_name_load_sub_dir
  3414 00006B19 E81F320000          <1> 	call	load_FAT_root_directory
  3415 00006B1E 0F82E5FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3416 00006B24 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 00006B26 E89D320000          <1> 	call	load_FAT_sub_directory
  3420 00006B2B 0F82D8FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3421                              <1> 
  3422                              <1> loc_rmdir_del_short_name_ld_chk_fclust:
  3423 00006B31 0FB73D[50E80000]    <1> 	movzx	edi, word [RmDir_DirEntryOffset]
  3424 00006B38 81C700000800        <1> 	add	edi, Directory_Buffer
  3425                              <1> 
  3426 00006B3E 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  3427 00006B42 C1E010              <1> 	shl	eax, 16
  3428 00006B45 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  3429                              <1>         ; Not necessary... 
  3430 00006B49 3B05[24E80000]      <1> 	cmp	eax, [DelFile_FCluster]
  3431 00006B4F 7598                <1> 	jne	short loc_rmdir_delete_short_name_invalid_data
  3432                              <1> 	;
  3433 00006B51 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 00006B54 C605[E8E50000]02    <1>   	mov	byte [DirBuff_ValidData], 2 ; change sign
  3439                              <1> 	;
  3440 00006B5B E8EF1D0000          <1> 	call	save_directory_buffer
  3441 00006B60 0F82A3FBFFFF        <1> 	jc	loc_file_rw_cmd_failed 
  3442                              <1> 
  3443                              <1> loc_rmdir_del_long_name:
  3444 00006B66 0FB615[2AE80000]    <1> 	movzx	edx, byte [DelFile_LNEL]
  3445 00006B6D 08D2                <1> 	or	dl, dl
  3446 00006B6F 7414                <1> 	jz	short loc_rmdir_update_parent_dir_lmdt
  3447                              <1>              
  3448 00006B71 0FB705[28E80000]    <1> 	movzx	eax, word [DelFile_EntryCounter]
  3449 00006B78 29D0                <1> 	sub	eax, edx
  3450 00006B7A 0F8289FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3451                              <1>  
  3452                              <1>  	; EAX = Directory Entry Number of the long name last entry
  3453 00006B80 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 00006B85 E8601E0000          <1> 	call	update_parent_dir_lmdt
  3458                              <1> 	;jc	short loc_file_rw_cmd_failed
  3459                              <1> 
  3460                              <1> loc_rmdir_ok:
  3461 00006B8A BE[C1CC0000]        <1> 	mov	esi, Msg_OK
  3462 00006B8F E8ACDAFFFF          <1> 	call	print_msg
  3463 00006B94 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 00006B99 803E20              <1> 	cmp	byte [esi], 20h
  3475 00006B9C 7701                <1>         ja	short loc_delfile_parse_path_name
  3476                              <1> 
  3477                              <1> loc_delfile_nofilename_retn:
  3478 00006B9E C3                  <1> 	retn
  3479                              <1> 
  3480                              <1> loc_delfile_parse_path_name:
  3481 00006B9F BF[62E70000]        <1> 	mov	edi, FindFile_Drv
  3482 00006BA4 E842190000          <1> 	call	parse_path_name
  3483 00006BA9 0F8230F2FFFF        <1> 	jc	loc_cmd_failed
  3484                              <1> 
  3485                              <1> loc_delfile_check_filename_exists:
  3486 00006BAF BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  3487 00006BB4 803E20              <1> 	cmp	byte [esi], 20h
  3488 00006BB7 0F8622F2FFFF        <1> 	jna	loc_cmd_failed
  3489 00006BBD 8935[20E80000]      <1> 	mov	[DelFile_FNPointer], esi 
  3490                              <1> 
  3491                              <1> loc_delfile_drv:
  3492 00006BC3 8A15[62E70000]      <1> 	mov	dl, [FindFile_Drv]
  3493 00006BC9 8A35[BEDD0000]      <1> 	mov	dh, [Current_Drv]
  3494 00006BCF 8835[1EE60000]      <1> 	mov	[RUN_CDRV], dh
  3495 00006BD5 38F2                <1> 	cmp	dl, dh
  3496 00006BD7 740B                <1> 	je	short loc_delfile_change_directory
  3497                              <1> 
  3498 00006BD9 E867E3FFFF          <1> 	call	change_current_drive
  3499 00006BDE 0F8225FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3500                              <1> 
  3501                              <1> loc_delfile_change_directory:
  3502 00006BE4 803D[63E70000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3503 00006BEB 7618                <1> 	jna	short loc_delfile_find
  3504                              <1> 
  3505 00006BED FE05[29C80000]      <1> 	inc	byte [Restore_CDIR]
  3506 00006BF3 BE[63E70000]        <1> 	mov	esi, FindFile_Directory
  3507 00006BF8 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3508 00006BFA E8D8120000          <1> 	call	change_current_directory
  3509 00006BFF 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 00006C05 8B35[20E80000]      <1> 	mov	esi, [DelFile_FNPointer]
  3517 00006C0B 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  3518 00006C0F E8CDF6FFFF          <1> 	call	find_first_file
  3519 00006C14 0F82EFFAFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3520                              <1> 
  3521                              <1> loc_delfile_ambgfn_check:
  3522 00006C1A 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3523 00006C1D 740B                <1> 	jz	short loc_delfile_found
  3524                              <1> 
  3525                              <1> loc_file_not_found:
  3526 00006C1F B802000000          <1> 	mov	eax, 2 ; File not found sign
  3527 00006C24 F9                  <1> 	stc
  3528 00006C25 E9DFFAFFFF          <1> 	jmp	loc_file_rw_cmd_failed   
  3529                              <1> 
  3530                              <1> loc_delfile_found:
  3531 00006C2A 80E307              <1> 	and	bl, 07h ; Attributes
  3532 00006C2D 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 00006C33 57                  <1> 	push	edi ; * (29/02/2016)
  3539                              <1> 
  3540 00006C34 BE[FFCC0000]        <1> 	mov	esi, Msg_DoYouWantDelete
  3541 00006C39 E802DAFFFF          <1> 	call	print_msg
  3542 00006C3E 8B35[20E80000]      <1> 	mov	esi, [DelFile_FNPointer]
  3543 00006C44 E8F7D9FFFF          <1> 	call	print_msg
  3544 00006C49 BE[B3CC0000]        <1> 	mov	esi, Msg_YesNo
  3545 00006C4E E8EDD9FFFF          <1> 	call	print_msg
  3546                              <1> 
  3547                              <1> loc_delfile_ask_again:
  3548 00006C53 30E4                <1> 	xor	ah, ah
  3549 00006C55 E85C9EFFFF          <1> 	call	int16h
  3550 00006C5A 3C1B                <1> 	cmp	al, 1Bh
  3551                              <1> 	;je	short loc_do_not_delete_file
  3552 00006C5C 7457                <1> 	je	short loc_delfile_y_n_escape ; 06/03/2016
  3553 00006C5E 24DF                <1> 	and	al, 0DFh
  3554 00006C60 A2[BDCC0000]        <1> 	mov	[Y_N_nextline], al
  3555 00006C65 3C59                <1> 	cmp	al, 'Y'
  3556 00006C67 7404                <1> 	je	short loc_yes_delete_file
  3557 00006C69 3C4E                <1> 	cmp	al, 'N'
  3558 00006C6B 75E6                <1> 	jne	short loc_delfile_ask_again
  3559                              <1> 
  3560                              <1> loc_do_not_delete_file:
  3561                              <1> loc_yes_delete_file:
  3562 00006C6D A2[BDCC0000]        <1> 	mov	[Y_N_nextline], al
  3563 00006C72 6650                <1> 	push	ax
  3564 00006C74 BE[BDCC0000]        <1> 	mov	esi, Y_N_nextline
  3565 00006C79 E8C2D9FFFF          <1> 	call	print_msg
  3566 00006C7E 6658                <1> 	pop	ax
  3567 00006C80 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 00006C81 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3572 00006C83 0F8480FAFFFF        <1>         je	loc_file_rw_restore_retn  
  3573                              <1> 
  3574                              <1> loc_delete_file:
  3575 00006C89 8A3D[62E70000]      <1> 	mov	bh, [FindFile_Drv]
  3576                              <1> 	;mov	bl, [DelFile_LNEL]
  3577 00006C8F 8A1D[B1E70000]      <1> 	mov	bl, [FindFile_LongNameEntryLength]
  3578                              <1> 	;mov	cx, [DirBuff_EntryCounter]
  3579 00006C95 668B0D[DCE70000]    <1> 	mov	cx, [FindFile_DirEntryNumber]
  3580                              <1> 	; (*) EDI = Directory buffer entry offset/address 
  3581 00006C9C E8F81F0000          <1> 	call	remove_file ; (FILE.ASM, 'proc_delete_file')
  3582 00006CA1 0F8358FAFFFF        <1> 	jnc	loc_print_deleted_message
  3583                              <1> 
  3584 00006CA7 3C05                <1> 	cmp	al, 05h
  3585 00006CA9 0F8464FAFFFF        <1> 	je	loc_permission_denied
  3586 00006CAF F9                  <1> 	stc
  3587 00006CB0 E954FAFFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3588                              <1> 
  3589                              <1> loc_delfile_y_n_escape:
  3590 00006CB5 B04E                <1> 	mov	al, 'N' ; 'no'
  3591 00006CB7 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 00006CB9 6631C0              <1> 	xor	ax, ax
  3602 00006CBC 66A3[50CD0000]      <1> 	mov	[Attr_Chars], ax
  3603 00006CC2 A2[78E80000]        <1> 	mov	[Attributes], al
  3604                              <1> 
  3605                              <1> get_attrib_fchar:
  3606                              <1> 	; esi = file name
  3607 00006CC7 8A06                <1> 	mov	al, [esi]
  3608 00006CC9 3C20                <1> 	cmp	al, 20h
  3609 00006CCB 7623                <1> 	jna	short loc_attr_file_nofilename_retn
  3610                              <1> 
  3611                              <1> loc_scan_attrib_params:
  3612 00006CCD 3C2D                <1> 	cmp	al, '-'
  3613 00006CCF 0F871C010000        <1> 	ja	loc_attr_file_parse_path_name
  3614 00006CD5 7408                <1> 	je	short loc_attr_space
  3615                              <1> 
  3616 00006CD7 3C2B                <1> 	cmp	al, '+'
  3617 00006CD9 0F8500F1FFFF        <1> 	jne	loc_cmd_failed
  3618                              <1> 
  3619                              <1> loc_attr_space:
  3620 00006CDF 8A6601              <1> 	mov	ah, [esi+1]
  3621 00006CE2 80FC20              <1>  	cmp	ah, 20h
  3622 00006CE5 770A                <1> 	ja	short pass_attr_space
  3623 00006CE7 0F82F2F0FFFF        <1> 	jb	loc_cmd_failed
  3624 00006CED 46                  <1> 	inc	esi
  3625 00006CEE EBEF                <1> 	jmp	short loc_attr_space
  3626                              <1> 
  3627                              <1> loc_attr_file_nofilename_retn:
  3628 00006CF0 C3                  <1> 	retn
  3629                              <1> 
  3630                              <1> pass_attr_space:
  3631 00006CF1 80E4DF              <1> 	and	ah, 0DFh
  3632 00006CF4 80FC53              <1> 	cmp	ah, 'S'
  3633 00006CF7 0F87E2F0FFFF        <1> 	ja	loc_cmd_failed
  3634 00006CFD 7204                <1> 	jb	short pass_attr_system
  3635 00006CFF B404                <1> 	mov	ah, 04h   ; System
  3636 00006D01 EB21                <1> 	jmp	short pass_attr_archive
  3637                              <1> 
  3638                              <1> pass_attr_system:
  3639 00006D03 80FC48              <1> 	cmp	ah, 'H'
  3640 00006D06 7706                <1> 	ja	short pass_attr_hidden
  3641 00006D08 7213                <1> 	jb	short pass_attr_read_only
  3642 00006D0A B402                <1> 	mov	ah, 02h    ; Hidden
  3643 00006D0C EB16                <1> 	jmp	short pass_attr_archive
  3644                              <1> 
  3645                              <1> pass_attr_hidden:
  3646 00006D0E 80FC52              <1> 	cmp	ah, 'R'
  3647 00006D11 0F87C8F0FFFF        <1> 	ja	loc_cmd_failed
  3648 00006D17 7204                <1> 	jb	short pass_attr_read_only ; Read only
  3649 00006D19 B401                <1> 	mov	ah, 01h
  3650 00006D1B EB07                <1> 	jmp	short pass_attr_archive
  3651                              <1> 
  3652                              <1> pass_attr_read_only:
  3653 00006D1D 80FC41              <1> 	cmp	ah, 'A'
  3654 00006D20 753B                <1> 	jne	short loc_chk_attr_enter
  3655 00006D22 B420                <1> 	mov	ah, 20h    ; Archive
  3656                              <1> 
  3657                              <1> pass_attr_archive:
  3658 00006D24 3C2D                <1> 	cmp	al, '-'
  3659 00006D26 7508                <1> 	jne	short pass_reducing_attributes
  3660 00006D28 0825[50CD0000]      <1> 	or	[Attr_Chars], ah
  3661 00006D2E EB06                <1> 	jmp	short loc_change_attributes_inc
  3662                              <1> 
  3663                              <1> pass_reducing_attributes:
  3664 00006D30 0825[51CD0000]      <1> 	or	[Attr_Chars+1], ah
  3665                              <1> 
  3666                              <1> loc_change_attributes_inc:
  3667 00006D36 46                  <1> 	inc	esi
  3668 00006D37 8A6601              <1> 	mov	ah, [esi+1]
  3669 00006D3A 80FC20              <1> 	cmp	ah, 20h
  3670 00006D3D 7227                <1> 	jb	short pass_change_attr
  3671 00006D3F 74F5                <1> 	je	short loc_change_attributes_inc
  3672 00006D41 80FC2D              <1> 	cmp	ah, '-'
  3673 00006D44 770D                <1> 	ja	short loc_chk_next_attr_char1
  3674 00006D46 7405                <1> 	je	short loc_chk_next_attr_char0
  3675 00006D48 80FC2B              <1> 	cmp	ah, '+'
  3676 00006D4B 7506                <1> 	jne	short loc_chk_next_attr_char1
  3677                              <1> 
  3678                              <1> loc_chk_next_attr_char0:
  3679 00006D4D 46                  <1> 	inc	esi
  3680 00006D4E 668B06              <1> 	mov	ax, [esi]
  3681 00006D51 EB9E                <1> 	jmp	short pass_attr_space
  3682                              <1> 
  3683                              <1> loc_chk_next_attr_char1:
  3684 00006D53 803E2D              <1> 	cmp	byte [esi], '-'
  3685 00006D56 7799                <1> 	ja	short pass_attr_space
  3686 00006D58 E988000000          <1>         jmp     loc_attr_file_check_fname_fchar
  3687                              <1> 
  3688                              <1> loc_chk_attr_enter:
  3689 00006D5D 80FC0D              <1> 	cmp	ah, 0Dh
  3690 00006D60 0F8579F0FFFF        <1> 	jne	loc_cmd_failed
  3691                              <1> 
  3692                              <1> pass_change_attr:
  3693 00006D66 A0[50CD0000]        <1> 	mov	al, [Attr_Chars]
  3694 00006D6B F6D0                <1> 	not	al
  3695 00006D6D 2005[78E80000]      <1> 	and	[Attributes], al
  3696 00006D73 A0[51CD0000]        <1> 	mov	al, [Attr_Chars+1]
  3697 00006D78 0805[78E80000]      <1> 	or	[Attributes], al
  3698                              <1> 
  3699                              <1> loc_show_attributes:
  3700 00006D7E BE[9CD90000]        <1> 	mov	esi, nextline
  3701 00006D83 E8B8D8FFFF          <1> 	call	print_msg
  3702                              <1> 
  3703                              <1> loc_show_attributes_no_nextline:
  3704 00006D88 C705[50CD0000]4E4F- <1> 	mov	dword [Attr_Chars], 'NORM'
  3704 00006D90 524D                <1>
  3705 00006D92 66C705[54CD0000]41- <1> 	mov	word [Attr_Chars+4], 'AL'
  3705 00006D9A 4C                  <1>
  3706 00006D9B BE[50CD0000]        <1> 	mov	esi, Attr_Chars
  3707 00006DA0 A0[78E80000]        <1> 	mov	al, [Attributes]
  3708 00006DA5 A804                <1> 	test	al, 04h
  3709 00006DA7 7406                <1> 	jz	short pass_put_attr_s
  3710 00006DA9 66C7065300          <1> 	mov	word [esi], 0053h     ; S
  3711 00006DAE 46                  <1> 	inc	esi
  3712                              <1> 
  3713                              <1> pass_put_attr_s:
  3714 00006DAF A802                <1> 	test	al, 02h
  3715 00006DB1 7406                <1> 	jz	short pass_put_attr_h
  3716 00006DB3 66C7064800          <1> 	mov	word [esi], 0048h     ; H
  3717 00006DB8 46                  <1> 	inc	esi
  3718                              <1> 
  3719                              <1> pass_put_attr_h:
  3720 00006DB9 A801                <1> 	test	al, 01h
  3721 00006DBB 7406                <1> 	jz	short pass_put_attr_r
  3722 00006DBD 66C7065200          <1> 	mov	word [esi], 0052h     ; R
  3723 00006DC2 46                  <1> 	inc	esi
  3724                              <1> 
  3725                              <1> pass_put_attr_r:
  3726 00006DC3 3C20                <1> 	cmp	al, 20h
  3727 00006DC5 7205                <1> 	jb	short pass_put_attr_a
  3728 00006DC7 66C7064100          <1> 	mov	word [esi], 0041h     ; A
  3729                              <1> 
  3730                              <1> pass_put_attr_a:
  3731 00006DCC BE[43CD0000]        <1> 	mov	esi, Str_Attributes
  3732 00006DD1 E86AD8FFFF          <1> 	call	print_msg
  3733 00006DD6 BE[9CD90000]        <1> 	mov	esi, nextline
  3734 00006DDB E860D8FFFF          <1> 	call	print_msg
  3735 00006DE0 E924F9FFFF          <1> 	jmp	loc_file_rw_restore_retn 
  3736                              <1> 
  3737                              <1> loc_attr_file_check_fname_fchar:
  3738 00006DE5 46                  <1> 	inc	esi
  3739 00006DE6 803E20              <1> 	cmp	byte [esi], 20h
  3740 00006DE9 74FA                <1> 	je	short loc_attr_file_check_fname_fchar
  3741 00006DEB 0F8275FFFFFF        <1>         jb      pass_change_attr
  3742                              <1> 		   
  3743                              <1> loc_attr_file_parse_path_name:
  3744 00006DF1 BF[62E70000]        <1> 	mov	edi, FindFile_Drv
  3745 00006DF6 E8F0160000          <1> 	call	parse_path_name
  3746 00006DFB 0F82DEEFFFFF        <1> 	jc	loc_cmd_failed
  3747                              <1> 
  3748                              <1> loc_attr_file_check_filename_exists:
  3749 00006E01 BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  3750 00006E06 803E20              <1> 	cmp	byte [esi], 20h
  3751 00006E09 0F86D0EFFFFF        <1> 	jna	loc_cmd_failed
  3752 00006E0F 8935[20E80000]      <1> 	mov	[DelFile_FNPointer], esi 
  3753                              <1> 
  3754                              <1> loc_attr_file_drv:
  3755 00006E15 8A35[BEDD0000]      <1> 	mov	dh, [Current_Drv]
  3756 00006E1B 8835[1EE60000]      <1> 	mov	[RUN_CDRV], dh
  3757                              <1> 
  3758 00006E21 8A15[62E70000]      <1> 	mov	dl, [FindFile_Drv]
  3759 00006E27 38F2                <1> 	cmp	dl, dh
  3760 00006E29 740B                <1> 	je	short loc_attr_file_change_directory
  3761                              <1> 
  3762 00006E2B E815E1FFFF          <1> 	call	change_current_drive
  3763 00006E30 0F82D3F8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3764                              <1> 
  3765                              <1> loc_attr_file_change_directory:
  3766 00006E36 803D[63E70000]20    <1>         cmp     byte [FindFile_Directory], 20h
  3767 00006E3D 7618                <1> 	jna	short loc_attr_file_find
  3768                              <1> 
  3769 00006E3F FE05[29C80000]      <1> 	inc	byte [Restore_CDIR]
  3770                              <1> 	
  3771 00006E45 BE[63E70000]        <1> 	mov	esi, FindFile_Directory
  3772 00006E4A 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3773 00006E4C E886100000          <1> 	call	change_current_directory
  3774 00006E51 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 00006E57 8B35[20E80000]      <1> 	mov	esi, [DelFile_FNPointer]
  3782 00006E5D 66B80008            <1> 	mov	ax, 0800h ; Except volume labels
  3783 00006E61 E87BF4FFFF          <1> 	call	find_first_file
  3784 00006E66 0F829DF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3785                              <1> 
  3786                              <1> loc_attr_file_ambgfn_check:
  3787 00006E6C 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 00006E6F 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 00006E75 66833D[50CD0000]00  <1> 	cmp	word [Attr_Chars], 0
  3803 00006E7D 770B                <1> 	ja	short loc_attr_file_change_attributes
  3804 00006E7F 881D[78E80000]      <1> 	mov	[Attributes], bl
  3805 00006E85 E9F4FEFFFF          <1> 	jmp	loc_show_attributes
  3806                              <1> 
  3807                              <1> loc_attr_file_change_attributes:
  3808 00006E8A A0[50CD0000]        <1> 	mov	al, [Attr_Chars]
  3809 00006E8F F6D0                <1> 	not	al
  3810 00006E91 20C3                <1> 	and	bl, al
  3811 00006E93 A0[51CD0000]        <1> 	mov	al, [Attr_Chars+1]
  3812 00006E98 08C3                <1> 	or	bl, al
  3813                              <1> 
  3814 00006E9A 66817F0CA101        <1> 	cmp	word [edi+DirEntry_NTRes], 01A1h ; Singlix FS
  3815 00006EA0 741D                <1> 	je	short loc_attr_file_fs_check
  3816                              <1> 
  3817 00006EA2 881D[78E80000]      <1> 	mov	[Attributes], bl
  3818 00006EA8 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 00006EAB C605[E8E50000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  3826                              <1> 
  3827 00006EB2 E8981A0000          <1> 	call 	save_directory_buffer
  3828 00006EB7 0F824CF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3829                              <1> 
  3830 00006EBD EB33                <1> 	jmp	short loc_print_attr_changed_message
  3831                              <1> 
  3832                              <1> loc_attr_file_fs_check:
  3833 00006EBF 29C0                <1> 	sub	eax, eax
  3834 00006EC1 8A25[E6E50000]      <1>         mov     ah, [DirBuff_DRV]
  3835 00006EC7 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3836 00006ECC 01C6                <1>         add     esi, eax
  3837 00006ECE 807E04A1            <1>         cmp     byte [esi+LD_FSType], 0A1h
  3838 00006ED2 7309                <1> 	jnc	short loc_attr_file_change_fs_file_attributes
  3839 00006ED4 66B80D00            <1> 	mov	ax, 0Dh ; Invalid Data
  3840 00006ED8 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 00006EDD 88D8                <1> 	mov	al, bl ; File/Directory Attributes
  3845 00006EDF 30E4                <1> 	xor	ah, ah ; Attributes in MS-DOS format sign	  
  3846 00006EE1 E89C050000          <1> 	call	change_fs_file_attributes
  3847 00006EE6 0F821DF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3848                              <1> 
  3849 00006EEC 881D[78E80000]      <1> 	mov	[Attributes], bl 
  3850                              <1> 
  3851                              <1> loc_print_attr_changed_message:
  3852 00006EF2 BE[3ECD0000]        <1> 	mov	esi, Msg_New
  3853 00006EF7 E844D7FFFF          <1> 	call	print_msg
  3854 00006EFC 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 00006F01 803E20              <1> 	cmp	byte [esi], 20h
  3865 00006F04 7614                <1>         jna	short loc_rename_nofilename_retn
  3866                              <1> 
  3867 00006F06 8935[9CE80000]      <1> 	mov	[SourceFilePath], esi
  3868                              <1> 
  3869                              <1> rename_scan_source_file:
  3870 00006F0C 46                  <1> 	inc	esi
  3871 00006F0D 803E20              <1> 	cmp	byte [esi], 20h
  3872 00006F10 7409                <1> 	je	short rename_scan_destination_file_1
  3873                              <1> 	;jb	short loc_rename_nofilename_retn
  3874 00006F12 0F82C7EEFFFF        <1> 	jb	loc_cmd_failed
  3875 00006F18 EBF2                <1> 	jmp	short rename_scan_source_file
  3876                              <1> 
  3877                              <1> loc_rename_nofilename_retn: ; 08/03/2016
  3878 00006F1A C3                  <1> 	retn
  3879                              <1> 
  3880                              <1> rename_scan_destination_file_1:
  3881 00006F1B C60600              <1> 	mov	byte [esi], 0
  3882                              <1> 
  3883                              <1> rename_scan_destination_file_2:
  3884 00006F1E 46                  <1> 	inc	esi  
  3885 00006F1F 803E20              <1> 	cmp	byte [esi], 20h
  3886 00006F22 74FA                <1> 	je	short rename_scan_destination_file_2
  3887                              <1> 	;jb	short loc_rename_nofilename_retn
  3888 00006F24 0F82B5EEFFFF        <1> 	jb	loc_cmd_failed
  3889                              <1> 
  3890 00006F2A 8935[A0E80000]      <1> 	mov	[DestinationFilePath], esi
  3891                              <1> 
  3892                              <1> rename_scan_destination_file_3:
  3893 00006F30 46                  <1> 	inc	esi  
  3894 00006F31 803E20              <1> 	cmp	byte [esi], 20h
  3895 00006F34 77FA                <1> 	ja	short rename_scan_destination_file_3
  3896                              <1> 
  3897 00006F36 C60600              <1> 	mov	byte [esi], 0
  3898                              <1> 
  3899                              <1> loc_rename_save_current_drive:
  3900 00006F39 8A35[BEDD0000]      <1> 	mov	dh, [Current_Drv]
  3901 00006F3F 8835[1EE60000]      <1> 	mov	byte [RUN_CDRV], dh
  3902                              <1> 
  3903                              <1> loc_rename_sf_parse_path_name:
  3904 00006F45 8B35[9CE80000]      <1> 	mov	esi, [SourceFilePath] 
  3905 00006F4B BF[62E70000]        <1> 	mov	edi, FindFile_Drv
  3906 00006F50 E896150000          <1> 	call	parse_path_name
  3907 00006F55 0F8284EEFFFF        <1> 	jc	loc_cmd_failed
  3908                              <1> 
  3909                              <1> loc_rename_sf_check_filename_exists:
  3910 00006F5B BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  3911 00006F60 803E20              <1> 	cmp	byte [esi], 20h
  3912 00006F63 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 00006F69 8A15[62E70000]      <1> 	mov	dl, [FindFile_Drv]
  3921 00006F6F 38F2                <1> 	cmp	dl, dh ; dh = [Current_Drv]
  3922 00006F71 740B                <1> 	je	short rename_sf_change_directory
  3923                              <1> 
  3924 00006F73 E8CDDFFFFF          <1> 	call	change_current_drive
  3925 00006F78 0F828BF7FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3926                              <1> 
  3927                              <1> rename_sf_change_directory:
  3928 00006F7E 803D[63E70000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3929 00006F85 7618                <1> 	jna	short rename_sf_find
  3930                              <1> 
  3931 00006F87 FE05[29C80000]      <1> 	inc	byte [Restore_CDIR]
  3932 00006F8D BE[63E70000]        <1> 	mov	esi, FindFile_Directory
  3933 00006F92 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3934 00006F94 E83E0F0000          <1> 	call	change_current_directory
  3935 00006F99 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 00006F9F BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  3943                              <1> 
  3944 00006FA4 66B80008            <1> 	mov	ax, 0800h ; Except volume labels
  3945 00006FA8 E834F3FFFF          <1> 	call	find_first_file
  3946 00006FAD 0F8256F7FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3947                              <1> 
  3948                              <1> loc_rename_sf_ambgfn_check:
  3949 00006FB3 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 00006FB6 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 00006FBC F6C307              <1> 	test	bl, 07h ; Attributes, S-H-R
  3965 00006FBF 0F854EF7FFFF        <1> 	jnz	loc_permission_denied
  3966                              <1> 	
  3967 00006FC5 BE[62E70000]        <1>         mov     esi, FindFile_Drv
  3968 00006FCA BF[A4E80000]        <1>         mov     edi, SourceFile_Drv
  3969 00006FCF B920000000          <1> 	mov	ecx, 32
  3970 00006FD4 F3A5                <1> 	rep	movsd
  3971                              <1> 
  3972                              <1> loc_rename_df_parse_path_name:
  3973 00006FD6 8B35[A0E80000]      <1> 	mov	esi, [DestinationFilePath]
  3974 00006FDC BF[62E70000]        <1> 	mov	edi, FindFile_Drv
  3975 00006FE1 E805150000          <1> 	call	parse_path_name
  3976 00006FE6 7219                <1> 	jc	short loc_rename_df_cmd_failed
  3977                              <1> 
  3978                              <1> 	;mov	dh, [RUN_CDRV]
  3979 00006FE8 8A35[BEDD0000]      <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 00006FEE 8A15[62E70000]      <1> 	mov	dl, [FindFile_Drv]
  3985 00006FF4 38F2                <1> 	cmp	dl, dh ; are source and destination drives different ?!
  3986 00006FF6 7509                <1> 	jne	short loc_rename_df_cmd_failed ; yes! 
  3987                              <1> 
  3988                              <1> rename_df_check_dirname_exists:
  3989 00006FF8 803D[63E70000]00    <1> 	cmp	byte [FindFile_Directory], 0
  3990 00006FFF 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 00007001 B801000000          <1> 	mov	eax, 1 ; TRDOS 'Bad command or file name' error
  3996 00007006 F9                  <1> 	stc
  3997 00007007 E9FDF6FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3998                              <1> 	  
  3999                              <1> rename_df_check_filename_exists:
  4000 0000700C BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  4001 00007011 E883F6FFFF          <1> 	call	check_filename
  4002 00007016 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 0000701C 0FB6F6              <1> 	movzx	esi, dh
  4012                              <1> 	;movzx	esi, byte [Current_Drv]
  4013 0000701F 81C600010900        <1> 	add	esi, Logical_DOSDisks
  4014                              <1> 
  4015 00007025 88F2                <1> 	mov	dl, dh ; dl = [Current_Drv]
  4016 00007027 8A7601              <1> 	mov	dh, [esi+LD_DiskType]
  4017                              <1> 
  4018 0000702A 80FE01              <1> 	cmp	dh, 1 ; 0 = Invalid
  4019 0000702D 7310                <1> 	jnb	short rename_df_compare_sf_df_name
  4020                              <1> 
  4021 0000702F B813000000          <1> 	mov	eax, 13h ; MSDOS err => Disk write-protected
  4022 00007034 8B1D[A0E80000]      <1> 	mov	ebx, [DestinationFilePath] 
  4023 0000703A E9CAF6FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  4024                              <1> 
  4025                              <1> rename_df_compare_sf_df_name:
  4026 0000703F BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  4027 00007044 BF[E6E80000]        <1> 	mov	edi, SourceFile_Name
  4028 00007049 B90C000000          <1> 	mov	ecx, 12
  4029                              <1> rename_df_compare_sf_df_name_next: 
  4030 0000704E AC                  <1> 	lodsb
  4031 0000704F AE                  <1> 	scasb
  4032 00007050 7506                <1> 	jne	short loc_rename_df_find
  4033 00007052 08C0                <1> 	or	al, al
  4034 00007054 74AB                <1> 	jz	short loc_rename_df_cmd_failed
  4035 00007056 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 00007058 BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  4040                              <1> 
  4041 0000705D 6631C0              <1> 	xor	ax, ax ; Any
  4042 00007060 E87CF2FFFF          <1> 	call	find_first_file
  4043 00007065 739A                <1> 	jnc	short loc_rename_df_found
  4044                              <1> 
  4045                              <1> loc_rename_df_check_error_code:
  4046                              <1> 	;cmp	eax, 2
  4047 00007067 3C02                <1> 	cmp	al, 2 ; Not found error
  4048 00007069 7406                <1> 	je	short rename_df_move_find_struct_to_dest
  4049 0000706B F9                  <1> 	stc
  4050 0000706C 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 00007071 BE[62E70000]        <1>         mov     esi, FindFile_Drv
  4059 00007076 BF[24E90000]        <1>         mov     edi, DestinationFile_Drv
  4060 0000707B B920000000          <1> 	mov	ecx, 32
  4061 00007080 F3A5                <1> 	rep	movsd
  4062                              <1> 
  4063                              <1> loc_rename_df_process_q_sf:
  4064                              <1> 	;mov	ecx, 12
  4065 00007082 B10C                <1> 	mov	cl, 12
  4066 00007084 BE[E6E80000]        <1>  	mov	esi, SourceFile_Name
  4067 00007089 BF[7FCD0000]        <1> 	mov	edi, Rename_OldName
  4068                              <1> rename_df_process_q_nml_1_sf:
  4069 0000708E AC                  <1> 	lodsb
  4070 0000708F 3C20                <1>         cmp	al, 20h
  4071 00007091 7603                <1>         jna	short rename_df_process_q_nml_2_sf
  4072 00007093 AA                  <1> 	stosb
  4073 00007094 E2F8                <1> 	loop	rename_df_process_q_nml_1_sf
  4074                              <1> 
  4075                              <1> rename_df_process_q_nml_2_sf:
  4076 00007096 C60700              <1> 	mov	byte [edi], 0
  4077                              <1> 
  4078                              <1> loc_rename_df_process_q_df:
  4079                              <1> 	;mov	ecx, 12
  4080 00007099 B10C                <1> 	mov	cl, 12
  4081 0000709B BE[66E90000]        <1> 	mov	esi, DestinationFile_Name
  4082 000070A0 BF[90CD0000]        <1> 	mov	edi, Rename_NewName
  4083                              <1> rename_df_process_q_nml_1_df:
  4084 000070A5 AC                  <1> 	lodsb
  4085 000070A6 3C20                <1> 	cmp	al, 20h
  4086 000070A8 7603                <1> 	jna	short loc_rename_df_process_q_nml_2_df
  4087 000070AA AA                  <1> 	stosb
  4088 000070AB E2F8                <1> 	loop	rename_df_process_q_nml_1_df
  4089                              <1> 
  4090                              <1> loc_rename_df_process_q_nml_2_df:
  4091 000070AD C60700              <1> 	mov	byte [edi], 0
  4092                              <1> 
  4093                              <1> loc_rename_confirmation_question:
  4094 000070B0 BE[57CD0000]        <1> 	mov	esi, Msg_DoYouWantRename
  4095 000070B5 E886D5FFFF          <1> 	call	print_msg
  4096                              <1> 
  4097 000070BA A0[01E90000]        <1> 	mov	al, [SourceFile_DirEntry+11] ; Attributes
  4098 000070BF 2410                <1> 	and	al, 10h
  4099 000070C1 750C                <1> 	jnz	short rename_confirmation_question_dir
  4100                              <1> 
  4101                              <1> rename_confirmation_question_file:
  4102 000070C3 BE[6ECD0000]        <1> 	mov	esi, Rename_File
  4103 000070C8 E873D5FFFF          <1> 	call	print_msg 
  4104 000070CD EB0A                <1> 	jmp	short rename_confirmation_question_as 
  4105                              <1> 
  4106                              <1> rename_confirmation_question_dir:
  4107 000070CF BE[74CD0000]        <1> 	mov	esi, Rename_Directory
  4108 000070D4 E867D5FFFF          <1> 	call	print_msg
  4109                              <1> 
  4110                              <1> rename_confirmation_question_as:
  4111 000070D9 BE[7FCD0000]        <1> 	mov	esi, Rename_OldName
  4112 000070DE E85DD5FFFF          <1> 	call	print_msg
  4113 000070E3 BE[8CCD0000]        <1> 	mov	esi, Msg_File_rename_as
  4114 000070E8 E853D5FFFF          <1> 	call	print_msg
  4115 000070ED BE[B3CC0000]        <1> 	mov	esi, Msg_YesNo
  4116 000070F2 E849D5FFFF          <1> 	call	print_msg
  4117                              <1> 
  4118                              <1> loc_rename_ask_again:
  4119 000070F7 30E4                <1> 	xor	ah, ah
  4120 000070F9 E8B899FFFF          <1> 	call	int16h
  4121 000070FE 3C1B                <1> 	cmp	al, 1Bh
  4122 00007100 740F                <1> 	je	short loc_do_not_rename_file
  4123 00007102 24DF                <1> 	and	al, 0DFh
  4124 00007104 A2[BDCC0000]        <1> 	mov	[Y_N_nextline], al
  4125 00007109 3C59                <1> 	cmp	al, 'Y'
  4126 0000710B 7404                <1> 	je	short loc_yes_rename_file
  4127 0000710D 3C4E                <1> 	cmp	al, 'N'
  4128 0000710F 75E6                <1> 	jne	short loc_rename_ask_again
  4129                              <1> 
  4130                              <1> loc_do_not_rename_file:
  4131                              <1> loc_yes_rename_file:
  4132 00007111 A2[BDCC0000]        <1> 	mov	[Y_N_nextline], al
  4133 00007116 6650                <1> 	push	ax
  4134 00007118 BE[BDCC0000]        <1> 	mov	esi, Y_N_nextline
  4135 0000711D E81ED5FFFF          <1> 	call	print_msg
  4136 00007122 6658                <1> 	pop	ax
  4137                              <1> 	;cmp	al, 'Y' ; 'yes'
  4138                              <1> 	;cmc
  4139                              <1>         ;jnc	loc_file_rw_restore_retn
  4140 00007124 3C4E                <1> 	cmp	al, 'N' ; 'no'
  4141 00007126 0F84DDF5FFFF        <1>         je	loc_file_rw_restore_retn  
  4142                              <1> 
  4143 0000712C BE[90CD0000]        <1> 	mov	esi, Rename_NewName
  4144 00007131 668B0D[1EE90000]    <1> 	mov	cx, [SourceFile_DirEntryNumber] 
  4145 00007138 66A1[0AE90000]      <1> 	mov	ax, [SourceFile_DirEntry+20] ; First Cluster, HW 
  4146 0000713E 66C1E010            <1> 	shl	ax, 16
  4147 00007142 66A1[10E90000]      <1> 	mov	ax, [SourceFile_DirEntry+26] ; First Cluster, LW 
  4148                              <1> 
  4149 00007148 0FB61D[F3E80000]    <1>   	movzx	ebx, byte [SourceFile_LongNameEntryLength]  
  4150 0000714F E8E11B0000          <1>    	call	rename_directory_entry
  4151 00007154 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 00007159 803E20              <1> 	cmp	byte [esi], 20h
  4168 0000715C 7614                <1>         jna	short loc_move_nofilename_retn
  4169                              <1> 
  4170 0000715E 8935[9CE80000]      <1> 	mov	[SourceFilePath], esi
  4171                              <1> 
  4172                              <1> move_scan_source_file:
  4173 00007164 46                  <1> 	inc	esi
  4174 00007165 803E20              <1> 	cmp	byte [esi], 20h
  4175 00007168 7409                <1>         je      short move_scan_destination_1
  4176                              <1> 	;jb	short loc_move_nofilename_retn
  4177 0000716A 0F826FECFFFF        <1> 	jb	loc_cmd_failed
  4178 00007170 EBF2                <1> 	jmp	short move_scan_source_file
  4179                              <1> 
  4180                              <1> loc_move_nofilename_retn:
  4181 00007172 C3                  <1> 	retn
  4182                              <1> 
  4183                              <1> move_scan_destination_1:
  4184 00007173 C60600              <1> 	mov	byte [esi], 0
  4185                              <1> 
  4186                              <1> move_scan_destination_2:
  4187 00007176 46                  <1> 	inc	esi  
  4188 00007177 803E20              <1> 	cmp	byte [esi], 20h
  4189 0000717A 74FA                <1> 	je	short move_scan_destination_2
  4190                              <1> 	;jb	short loc_move_nofilename_retn
  4191 0000717C 0F825DECFFFF        <1> 	jb	loc_cmd_failed
  4192                              <1> 
  4193 00007182 8935[A0E80000]      <1> 	mov	[DestinationFilePath], esi
  4194                              <1> 
  4195                              <1> move_scan_destination_3:
  4196 00007188 46                  <1> 	inc	esi  
  4197 00007189 803E20              <1> 	cmp	byte [esi], 20h
  4198 0000718C 77FA                <1> 	ja	short move_scan_destination_3
  4199 0000718E C60600              <1> 	mov	byte [esi], 0
  4200                              <1> 
  4201                              <1> loc_move_scan_destination_OK:
  4202 00007191 8B35[9CE80000]      <1> 	mov	esi, [SourceFilePath]
  4203 00007197 8B3D[A0E80000]      <1> 	mov	edi, [DestinationFilePath]
  4204                              <1> 
  4205 0000719D B001                <1> 	mov	al, 1  ; move procedure Phase 1
  4206 0000719F E80E1C0000          <1> 	call	move_source_file_to_destination_file
  4207 000071A4 7328                <1> 	jnc	short move_source_file_to_destination_question
  4208                              <1> 
  4209                              <1> loc_move_cmd_failed_1:
  4210 000071A6 08C0                <1> 	or	al, al
  4211 000071A8 0F8431ECFFFF        <1> 	jz	loc_cmd_failed 
  4212 000071AE 3C11                <1> 	cmp	al, 11h
  4213 000071B0 740D                <1> 	je	short loc_msg_not_same_device   
  4214 000071B2 3C05                <1> 	cmp	al, 05h
  4215 000071B4 0F8550ECFFFF        <1> 	jne	loc_run_cmd_failed
  4216                              <1> 
  4217 000071BA 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 000071BF BE[9DCD0000]        <1> 	mov	esi, msg_not_same_drv 
  4225 000071C4 E877D4FFFF          <1> 	call	print_msg
  4226 000071C9 E93BF5FFFF          <1> 	jmp	loc_file_rw_restore_retn
  4227                              <1> 
  4228                              <1> move_source_file_to_destination_question:
  4229 000071CE A0[A4E80000]        <1>         mov     al, [SourceFile_Drv]
  4230 000071D3 0441                <1> 	add	al, 'A'
  4231 000071D5 A2[FFCD0000]        <1> 	mov	[msg_source_file_drv], al
  4232 000071DA A0[24E90000]        <1>         mov     al, [DestinationFile_Drv]
  4233 000071DF 0441                <1> 	add	al, 'A'
  4234 000071E1 A2[1ECE0000]        <1> 	mov	[msg_destination_file_drv], al
  4235                              <1> 
  4236 000071E6 57                  <1> 	push	edi ; *
  4237                              <1> 
  4238 000071E7 BE[E3CD0000]        <1> 	mov	esi, msg_source_file
  4239 000071EC E84FD4FFFF          <1> 	call	print_msg
  4240 000071F1 BE[A5E80000]        <1> 	mov	esi, SourceFile_Directory
  4241 000071F6 803E20              <1> 	cmp	byte [esi], 20h
  4242 000071F9 7605                <1> 	jna	short msftdfq_sfn
  4243 000071FB E840D4FFFF          <1> 	call	print_msg
  4244                              <1> msftdfq_sfn:
  4245 00007200 BE[E6E80000]        <1> 	mov	esi, SourceFile_Name
  4246 00007205 E836D4FFFF          <1> 	call	print_msg
  4247 0000720A BE[02CE0000]        <1> 	mov	esi, msg_destination_file
  4248 0000720F E82CD4FFFF          <1> 	call	print_msg
  4249 00007214 BE[25E90000]        <1> 	mov	esi, DestinationFile_Directory
  4250 00007219 803E20              <1> 	cmp	byte [esi], 20h
  4251 0000721C 7605                <1> 	jna	short msftdfq_dfn
  4252 0000721E E81DD4FFFF          <1> 	call	print_msg
  4253                              <1> msftdfq_dfn:
  4254 00007223 BE[66E90000]        <1> 	mov	esi, DestinationFile_Name
  4255 00007228 E813D4FFFF          <1> 	call	print_msg
  4256 0000722D BE[21CE0000]        <1> 	mov	esi, msg_copy_nextline
  4257 00007232 E809D4FFFF          <1> 	call	print_msg
  4258 00007237 BE[21CE0000]        <1> 	mov	esi, msg_copy_nextline
  4259 0000723C E8FFD3FFFF          <1> 	call	print_msg
  4260                              <1> 
  4261                              <1> loc_move_ask_for_new_file_yes_no:
  4262 00007241 BE[AFCD0000]        <1> 	mov	esi, Msg_DoYouWantMoveFile
  4263 00007246 E8F5D3FFFF          <1> 	call	print_msg
  4264 0000724B BE[B3CC0000]        <1> 	mov	esi, Msg_YesNo
  4265 00007250 E8EBD3FFFF          <1> 	call	print_msg
  4266                              <1> loc_move_ask_for_new_file_again:
  4267 00007255 30E4                <1> 	xor	ah, ah
  4268 00007257 E85A98FFFF          <1> 	call	int16h
  4269 0000725C 3C1B                <1> 	cmp	al, 1Bh
  4270                              <1> 	;je	short loc_do_not_move_file
  4271 0000725E 744F                <1> 	je	short loc_move_y_n_escape
  4272 00007260 24DF                <1> 	and	al, 0DFh
  4273 00007262 A2[BDCC0000]        <1>         mov     [Y_N_nextline], al
  4274 00007267 3C59                <1> 	cmp	al, 'Y'
  4275 00007269 7404                <1> 	je	short loc_yes_move_file
  4276 0000726B 3C4E                <1> 	cmp	al, 'N'
  4277 0000726D 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 0000726F A2[BDCC0000]        <1> 	mov	[Y_N_nextline], al
  4282 00007274 6650                <1> 	push	ax
  4283 00007276 BE[BDCC0000]        <1> 	mov	esi, Y_N_nextline
  4284 0000727B E8C0D3FFFF          <1> 	call	print_msg
  4285 00007280 6658                <1> 	pop	ax
  4286 00007282 5F                  <1> 	pop	edi ; *
  4287                              <1> 	;cmp	al, 'Y' ; 'yes'
  4288                              <1> 	;cmc
  4289                              <1>         ;jnc	loc_file_rw_restore_retn
  4290 00007283 3C4E                <1> 	cmp	al, 'N' ; 'no'
  4291 00007285 0F847EF4FFFF        <1>         je	loc_file_rw_restore_retn
  4292                              <1> 
  4293                              <1> loc_move_yes_move_file:
  4294 0000728B B002                <1> 	mov	al, 2 ; move procedure Phase 2
  4295 0000728D E8201B0000          <1> 	call	move_source_file_to_destination_file
  4296                              <1> 	;jc	short loc_move_cmd_failed_2
  4297 00007292 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 00007298 3C27                <1> 	cmp	al, 27h
  4306 0000729A 0F856AEBFFFF        <1> 	jne	loc_run_cmd_failed
  4307                              <1> 
  4308 000072A0 BE[C8CD0000]        <1> 	mov	esi, msg_insufficient_disk_space
  4309 000072A5 E896D3FFFF          <1> 	call	print_msg
  4310                              <1> 
  4311 000072AA E95AF4FFFF          <1> 	jmp	loc_file_rw_restore_retn
  4312                              <1> 
  4313                              <1> loc_move_y_n_escape:
  4314 000072AF B04E                <1> 	mov	al, 'N' ; 'no'
  4315 000072B1 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 000072B3 803E20              <1> 	cmp	byte [esi], 20h
  4327 000072B6 7614                <1>         jna     short loc_copy_nofilename_retn
  4328                              <1> 
  4329 000072B8 8935[9CE80000]      <1> 	mov	[SourceFilePath], esi
  4330                              <1> 
  4331                              <1> copy_scan_source_file:
  4332 000072BE 46                  <1> 	inc	esi  
  4333 000072BF 803E20              <1> 	cmp	byte [esi], 20h
  4334 000072C2 7409                <1> 	je	short copy_scan_destination_1
  4335                              <1> 	;jb	short loc_copy_nofilename_retn
  4336 000072C4 0F8215EBFFFF        <1> 	jb	loc_cmd_failed
  4337 000072CA EBF2                <1> 	jmp	short copy_scan_source_file
  4338                              <1> 
  4339                              <1> loc_copy_nofilename_retn:
  4340 000072CC C3                  <1> 	retn
  4341                              <1> 
  4342                              <1> copy_scan_destination_1:
  4343 000072CD C60600              <1> 	mov	byte [esi], 0
  4344                              <1> 
  4345                              <1> copy_scan_destination_2:
  4346 000072D0 46                  <1> 	inc	esi  
  4347 000072D1 803E20              <1> 	cmp	byte [esi], 20h
  4348 000072D4 74FA                <1> 	je	short copy_scan_destination_2
  4349                              <1> 	;jb	short loc_copy_nofilename_retn
  4350 000072D6 0F8203EBFFFF        <1> 	jb	loc_cmd_failed
  4351                              <1> 
  4352 000072DC 8935[A0E80000]      <1> 	mov	[DestinationFilePath], esi
  4353                              <1> 
  4354                              <1> copy_scan_destination_3:
  4355 000072E2 46                  <1> 	inc	esi  
  4356 000072E3 803E20              <1> 	cmp	byte [esi], 20h
  4357 000072E6 77FA                <1> 	ja	short copy_scan_destination_3
  4358 000072E8 C60600              <1> 	mov	byte [esi], 0
  4359                              <1> 
  4360                              <1> loc_copy_save_current_drive:
  4361 000072EB 8A35[BEDD0000]      <1> 	mov	dh, [Current_Drv]
  4362 000072F1 8835[1EE60000]      <1> 	mov	[RUN_CDRV], dh
  4363                              <1> 
  4364                              <1> copy_source_file_to_destination_phase_1:
  4365 000072F7 8B35[9CE80000]      <1> 	mov	esi, [SourceFilePath]
  4366 000072FD 8B3D[A0E80000]      <1> 	mov	edi, [DestinationFilePath]
  4367                              <1> 
  4368 00007303 B001                <1> 	mov	al, 1  ; copy procedure Phase 1
  4369 00007305 E8331D0000          <1> 	call	copy_source_file_to_destination_file
  4370 0000730A 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 0000730C 08C0                <1> 	or	al, al
  4375 0000730E 7507                <1> 	jnz	short loc_copy_cmd_failed_2
  4376                              <1> 
  4377 00007310 FEC0                <1>         inc     al ; mov al, 1 ; Bad command or file name !
  4378 00007312 E9F3EAFFFF          <1> 	jmp	loc_run_cmd_failed
  4379                              <1> 
  4380                              <1> loc_copy_cmd_failed_2:
  4381 00007317 3C27                <1> 	cmp	al, 27h ; Insufficient disk space 
  4382 00007319 740D                <1> 	je	short loc_file_write_insuff_disk_space_msg
  4383                              <1>  
  4384 0000731B 3C05                <1> 	cmp	al, 05h
  4385 0000731D 0F85E7EAFFFF        <1> 	jne	loc_run_cmd_failed
  4386                              <1> 	
  4387 00007323 E9EBF3FFFF          <1> 	jmp	loc_permission_denied
  4388                              <1> 
  4389                              <1> loc_file_write_insuff_disk_space_msg:
  4390 00007328 BE[C8CD0000]        <1> 	mov	esi, msg_insufficient_disk_space
  4391 0000732D E80ED3FFFF          <1> 	call	print_msg
  4392 00007332 E9D2F3FFFF          <1>         jmp     loc_file_rw_restore_retn 
  4393                              <1> 
  4394                              <1> copy_source_file_to_destination_question:
  4395 00007337 57                  <1> 	push	edi ; *
  4396                              <1> 
  4397                              <1> 	; dh = source file attributes
  4398                              <1> 	; dl > 0 -> destination file found
  4399 00007338 20D2                <1> 	and	dl, dl            
  4400 0000733A 7449                <1> 	jz	short copy_source_file_to_destination_pass_owrq
  4401                              <1> 
  4402                              <1> loc_copy_ask_for_owr_yes_no:
  4403 0000733C BE[24CE0000]        <1> 	mov	esi, Msg_DoYouWantOverWriteFile
  4404 00007341 E8FAD2FFFF          <1> 	call	print_msg
  4405 00007346 BE[66E90000]        <1> 	mov	esi, DestinationFile_Name
  4406 0000734B E8F0D2FFFF          <1> 	call	print_msg
  4407 00007350 BE[B3CC0000]        <1> 	mov	esi, Msg_YesNo
  4408 00007355 E8E6D2FFFF          <1> 	call	print_msg
  4409                              <1> 
  4410                              <1> loc_copy_ask_for_owr_again:
  4411 0000735A 30E4                <1> 	xor	ah, ah
  4412 0000735C E85597FFFF          <1> 	call	int16h
  4413 00007361 3C1B                <1> 	cmp	al, 1Bh
  4414                              <1>         ;je     loc_do_not_copy_file
  4415 00007363 7419                <1>         je      short loc_copy_y_n_escape
  4416 00007365 24DF                <1> 	and	al, 0DFh
  4417 00007367 A2[BDCC0000]        <1>         mov     [Y_N_nextline], al
  4418 0000736C 3C59                <1> 	cmp	al, 'Y'
  4419 0000736E 0F84B1000000        <1>         je      loc_yes_copy_file
  4420 00007374 3C4E                <1> 	cmp	al, 'N'
  4421 00007376 0F84A9000000        <1>         je      loc_do_not_copy_file
  4422 0000737C EBDC                <1> 	jmp	short loc_copy_ask_for_owr_again
  4423                              <1> 
  4424                              <1> loc_copy_y_n_escape:
  4425 0000737E B04E                <1> 	mov	al, 'N' ; 'no'
  4426 00007380 E9A0000000          <1>         jmp     loc_do_not_copy_file
  4427                              <1> 
  4428                              <1> copy_source_file_to_destination_pass_owrq:
  4429 00007385 A0[A4E80000]        <1> 	mov     al, [SourceFile_Drv]
  4430 0000738A 0441                <1> 	add	al, 'A'
  4431 0000738C A2[FFCD0000]        <1> 	mov	[msg_source_file_drv], al
  4432 00007391 A0[24E90000]        <1>         mov     al, [DestinationFile_Drv]
  4433 00007396 0441                <1> 	add	al, 'A'
  4434 00007398 A2[1ECE0000]        <1> 	mov	[msg_destination_file_drv], al
  4435                              <1> 
  4436 0000739D BE[E3CD0000]        <1> 	mov	esi, msg_source_file
  4437 000073A2 E899D2FFFF          <1> 	call	print_msg
  4438 000073A7 BE[A5E80000]        <1> 	mov	esi, SourceFile_Directory
  4439 000073AC 803E20              <1> 	cmp	byte [esi], 20h
  4440 000073AF 7605                <1> 	jna	short csftdfq_sfn
  4441 000073B1 E88AD2FFFF          <1> 	call	print_msg
  4442                              <1> csftdfq_sfn:
  4443 000073B6 BE[E6E80000]        <1> 	mov	esi, SourceFile_Name
  4444 000073BB E880D2FFFF          <1> 	call	print_msg
  4445 000073C0 BE[02CE0000]        <1> 	mov	esi, msg_destination_file
  4446 000073C5 E876D2FFFF          <1> 	call	print_msg
  4447 000073CA BE[25E90000]        <1> 	mov	esi, DestinationFile_Directory
  4448 000073CF 803E20              <1> 	cmp	byte [esi], 20h
  4449 000073D2 7605                <1> 	jna	short csftdfq_dfn
  4450 000073D4 E867D2FFFF          <1> 	call	print_msg
  4451                              <1> csftdfq_dfn:
  4452 000073D9 BE[66E90000]        <1> 	mov	esi, DestinationFile_Name
  4453 000073DE E85DD2FFFF          <1> 	call	print_msg
  4454 000073E3 BE[21CE0000]        <1> 	mov	esi, msg_copy_nextline
  4455 000073E8 E853D2FFFF          <1> 	call	print_msg
  4456 000073ED BE[21CE0000]        <1> 	mov	esi, msg_copy_nextline
  4457 000073F2 E849D2FFFF          <1> 	call	print_msg
  4458                              <1> 
  4459                              <1> loc_copy_ask_for_new_file_yes_no:
  4460 000073F7 BE[43CE0000]        <1> 	mov	esi, Msg_DoYouWantCopyFile
  4461 000073FC E83FD2FFFF          <1> 	call	print_msg
  4462 00007401 BE[B3CC0000]        <1> 	mov	esi, Msg_YesNo
  4463 00007406 E835D2FFFF          <1> 	call	print_msg
  4464                              <1> 
  4465                              <1> loc_copy_ask_for_new_file_again:
  4466 0000740B 30E4                <1> 	xor	ah, ah
  4467 0000740D E8A496FFFF          <1> 	call	int16h
  4468 00007412 3C1B                <1> 	cmp	al, 1Bh
  4469 00007414 740F                <1> 	je	short loc_do_not_copy_file
  4470 00007416 24DF                <1> 	and	al, 0DFh
  4471 00007418 A2[BDCC0000]        <1>         mov     [Y_N_nextline], al
  4472 0000741D 3C59                <1> 	cmp	al, 'Y'
  4473 0000741F 7404                <1> 	je	short loc_yes_copy_file
  4474 00007421 3C4E                <1> 	cmp	al, 'N'
  4475 00007423 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 00007425 A2[BDCC0000]        <1> 	mov	[Y_N_nextline], al
  4480 0000742A 6650                <1> 	push	ax
  4481 0000742C BE[BDCC0000]        <1> 	mov	esi, Y_N_nextline
  4482 00007431 E80AD2FFFF          <1> 	call	print_msg
  4483 00007436 6658                <1> 	pop	ax
  4484 00007438 5F                  <1> 	pop	edi ; *
  4485                              <1> 	;cmp	al, 'Y' ; 'yes'
  4486                              <1> 	;cmc
  4487                              <1>         ;jnc	loc_file_rw_restore_retn
  4488 00007439 3C4E                <1> 	cmp	al, 'N' ; 'no'
  4489 0000743B 0F84C8F2FFFF        <1>         je	loc_file_rw_restore_retn
  4490                              <1> 
  4491                              <1> copy_source_file_to_destination_pass_q:
  4492 00007441 B002                <1> 	mov	al, 2  ; copy procedure Phase 2
  4493 00007443 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 00007448 6651                <1> 	push	cx
  4498 0000744A BE[21CE0000]        <1> 	mov	esi, msg_copy_nextline
  4499 0000744F E8ECD1FFFF          <1> 	call	print_msg
  4500                              <1> 	;pop	cx
  4501 00007454 6658                <1> 	pop	ax
  4502                              <1> 
  4503                              <1> 	;or	cl, cl
  4504 00007456 08C0                <1> 	or	al, al
  4505 00007458 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 0000745A 3C1D                <1> 	cmp	al, 1Dh
  4510 0000745C 7506                <1> 	jne	short copy_source_file_to_destination_not_OK
  4511                              <1> 	;
  4512                              <1> 	;mov	al, cl ; error number (write fault!)
  4513 0000745E F9                  <1> 	stc
  4514 0000745F E9A5F2FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  4515                              <1> 
  4516                              <1> copy_source_file_to_destination_not_OK:
  4517 00007464 BE[5CCE0000]        <1> 	mov	esi, Msg_read_file_error_before_EOF
  4518 00007469 E8D2D1FFFF          <1> 	call	print_msg
  4519 0000746E E996F2FFFF          <1> 	jmp	loc_file_rw_restore_retn	      
  4520                              <1>  
  4521                              <1> copy_source_file_to_destination_OK:
  4522 00007473 BE[C1CC0000]        <1> 	mov	esi, Msg_OK
  4523 00007478 E8C3D1FFFF          <1> 	call	print_msg
  4524                              <1> 
  4525 0000747D 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 00007482 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 00007483 8A06                <1> 	mov	al, [esi]
  4553 00007485 3C20                <1> 	cmp	al, 20h
  4554 00007487 771E                <1> 	ja	short loc_find_env
  4555                              <1> 
  4556 00007489 BE00300900          <1> 	mov	esi, Env_Page
  4557                              <1> loc_print_setline:
  4558 0000748E 803E00              <1> 	cmp	byte [esi], 0
  4559 00007491 7613                <1> 	jna	short loc_setenv_retn
  4560 00007493 E8A8D1FFFF          <1> 	call	print_msg
  4561 00007498 56                  <1> 	push	esi
  4562 00007499 BE[9CD90000]        <1> 	mov	esi, nextline
  4563 0000749E E89DD1FFFF          <1> 	call	print_msg 
  4564 000074A3 5E                  <1> 	pop	esi
  4565 000074A4 EBE8                <1> 	jmp	short loc_print_setline   
  4566                              <1> 
  4567                              <1> loc_setenv_retn: 
  4568 000074A6 C3                  <1> 	retn
  4569                              <1> 
  4570                              <1> loc_find_env:
  4571 000074A7 3C3D                <1> 	cmp	al, '='
  4572 000074A9 0F8430E9FFFF        <1> 	je	loc_cmd_failed
  4573                              <1> 
  4574 000074AF 56                  <1> 	push	esi
  4575                              <1> loc_repeat_env_equal_check:
  4576 000074B0 46                  <1> 	inc	esi
  4577 000074B1 803E3D              <1> 	cmp	byte [esi], '='
  4578 000074B4 7431                <1> 	je	short pass_env_equal_check
  4579 000074B6 803E20              <1> 	cmp	byte [esi], 20h
  4580 000074B9 73F5                <1> 	jnb	short loc_repeat_env_equal_check
  4581 000074BB C60600              <1> 	mov	byte [esi], 0 
  4582 000074BE 5E                  <1> 	pop	esi
  4583 000074BF BF[BEDE0000]        <1> 	mov	edi, TextBuffer ; out buffer
  4584 000074C4 B9FF000000          <1> 	mov	ecx, 255 ; maximum size (limit)
  4585 000074C9 30C0                <1> 	xor	al, al ; 0 -> use [ESI]
  4586 000074CB E89E000000          <1> 	call	get_environment_string
  4587 000074D0 72D4                <1> 	jc	short loc_setenv_retn
  4588                              <1> 
  4589 000074D2 BE[BEDE0000]        <1> 	mov	esi, TextBuffer
  4590 000074D7 E864D1FFFF          <1> 	call	print_msg
  4591 000074DC BE[9CD90000]        <1> 	mov	esi, nextline
  4592 000074E1 E85AD1FFFF          <1> 	call	print_msg
  4593                              <1> 
  4594 000074E6 C3                  <1> 	retn 
  4595                              <1>               
  4596                              <1> pass_env_equal_check:
  4597 000074E7 46                  <1> 	inc	esi
  4598 000074E8 803E20              <1> 	cmp	byte [esi], 20h
  4599 000074EB 73FA                <1> 	jnb	short pass_env_equal_check
  4600 000074ED C60600              <1> 	mov	byte [esi], 0	
  4601                              <1> 
  4602                              <1> loc_call_set_env_string:
  4603 000074F0 5E                  <1> 	pop	esi
  4604 000074F1 E83B010000          <1> 	call	set_environment_string
  4605 000074F6 73AE                <1> 	jnc	short loc_setenv_retn
  4606                              <1> 
  4607                              <1> loc_set_cmd_failed:
  4608 000074F8 3C08                <1> 	cmp	al, 08h
  4609 000074FA 0F85DFE8FFFF        <1> 	jne	loc_cmd_failed
  4610                              <1> 
  4611 00007500 BE[9CCE0000]        <1> 	mov	esi, Msg_No_Set_Space
  4612 00007505 E836D1FFFF          <1> 	call	print_msg
  4613                              <1> 
  4614 0000750A 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 0000750B 803E20              <1> 	cmp	byte [esi], 20h
  4623 0000750E 7737                <1> 	ja	short loc_set_path
  4624                              <1> 
  4625 00007510 BE00300900          <1> 	mov	esi, Env_Page
  4626                              <1> loc_print_path:
  4627 00007515 803E00              <1> 	cmp	byte [esi], 0
  4628 00007518 762C                <1> 	jna	short loc_path_retn
  4629                              <1> 
  4630 0000751A BE[F5C80000]        <1> 	mov	esi, Cmd_Path ; 'PATH' address
  4631 0000751F BF[BEDE0000]        <1> 	mov	edi, TextBuffer ; oout buffer
  4632 00007524 30C0                <1> 	xor	al, al  ; use [ESI]
  4633 00007526 B9FF000000          <1> 	mov	ecx, 255 ; maximum size (limit)
  4634 0000752B E83E000000          <1> 	call	get_environment_string
  4635 00007530 7214                <1> 	jc	short loc_path_retn
  4636                              <1> 
  4637 00007532 BE[BEDE0000]        <1> 	mov	esi, TextBuffer
  4638 00007537 E804D1FFFF          <1> 	call	print_msg
  4639 0000753C BE[9CD90000]        <1> 	mov	esi, nextline
  4640 00007541 E8FAD0FFFF          <1> 	call	print_msg   
  4641                              <1> 
  4642                              <1> loc_path_retn: 
  4643 00007546 C3                  <1> 	retn
  4644                              <1> 
  4645                              <1> loc_set_path:
  4646 00007547 56                  <1> 	push	esi 
  4647                              <1> loc_set_path_find_end:
  4648 00007548 46                  <1> 	inc	esi
  4649 00007549 803E20              <1> 	cmp	byte [esi], 20h
  4650 0000754C 73FA                <1> 	jnb	short loc_set_path_find_end
  4651 0000754E C60600              <1> 	mov	byte [esi], 0 
  4652                              <1> loc_set_path_header: 
  4653 00007551 5E                  <1> 	pop	esi	  
  4654 00007552 4E                  <1> 	dec	esi
  4655 00007553 C6063D              <1> 	mov	byte [esi], '='
  4656 00007556 4E                  <1> 	dec	esi
  4657 00007557 C60648              <1> 	mov	byte [esi], 'H'
  4658 0000755A 4E                  <1> 	dec	esi
  4659 0000755B C60654              <1> 	mov	byte [esi], 'T'
  4660 0000755E 4E                  <1> 	dec	esi
  4661 0000755F C60641              <1> 	mov	byte [esi], 'A'
  4662 00007562 4E                  <1> 	dec	esi
  4663 00007563 C60650              <1> 	mov	byte [esi], 'P'   
  4664                              <1> 
  4665                              <1> loc_path_call_set_env_string:
  4666 00007566 E8C6000000          <1> 	call	set_environment_string
  4667 0000756B 728B                <1>         jc	short loc_set_cmd_failed
  4668                              <1> 
  4669 0000756D 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 0000756E BA00300900          <1> 	mov	edx, Env_Page
  4694 00007573 803A00              <1> 	cmp	byte [edx], 0
  4695 00007576 7474                <1> 	jz	short get_env_string_with_word_stc_retn
  4696                              <1> 
  4697 00007578 66890D[28EA0000]    <1> 	mov	[env_var_length], cx
  4698                              <1> 
  4699 0000757F 51                  <1> 	push	ecx ; *
  4700 00007580 56                  <1> 	push	esi ; **
  4701                              <1> 
  4702 00007581 08C0                <1> 	or	al, al
  4703 00007583 7449                <1> 	jz	short get_env_string_with_word
  4704                              <1> 
  4705                              <1> get_env_string_with_seq_number:
  4706 00007585 B101                <1> 	mov	cl, 1
  4707 00007587 88C5                <1> 	mov	ch, al
  4708 00007589 31C0                <1> 	xor	eax, eax
  4709 0000758B 89D6                <1> 	mov	esi, edx ; Env_Page
  4710                              <1> 
  4711                              <1> get_env_string_seq_number_check:
  4712 0000758D 38CD                <1> 	cmp	ch, cl
  4713 0000758F 7726                <1> 	ja	short get_env_string_seq_number_next
  4714                              <1> 
  4715                              <1> get_env_string_move_to_buff:
  4716 00007591 57                  <1> 	push	edi ; ***
  4717                              <1> 
  4718 00007592 29D2                <1> 	sub	edx, edx
  4719                              <1> 
  4720                              <1> get_env_string_seq_number_repeat1:
  4721 00007594 42                  <1> 	inc	edx
  4722 00007595 AC                  <1> 	lodsb
  4723 00007596 AA                  <1> 	stosb
  4724                              <1> 
  4725 00007597 66FF0D[28EA0000]    <1> 	dec	word [env_var_length]
  4726 0000759E 7508                <1> 	jnz	short get_env_string_seq_number_repeat3
  4727                              <1> 
  4728                              <1> get_env_string_seq_number_repeat2:
  4729 000075A0 20C0                <1> 	and	al, al
  4730 000075A2 7408                <1> 	jz	short get_env_string_seq_number_ok
  4731 000075A4 42                  <1> 	inc	edx
  4732 000075A5 AC                  <1> 	lodsb
  4733 000075A6 EBF8                <1> 	jmp	short get_env_string_seq_number_repeat2
  4734                              <1> 
  4735                              <1> get_env_string_seq_number_repeat3:
  4736 000075A8 08C0                <1> 	or	al, al
  4737 000075AA 75E8                <1> 	jnz	short get_env_string_seq_number_repeat1
  4738                              <1> 
  4739                              <1> get_env_string_seq_number_ok:
  4740 000075AC 5F                  <1> 	pop	edi ; ***
  4741 000075AD 89D0                <1> 	mov	eax, edx ; Length of the environment string
  4742                              <1> 			 ; (ASCIIZ, includes ZERO tail)
  4743 000075AF BA00300900          <1> 	mov	edx, Env_Page
  4744                              <1> 
  4745                              <1> get_env_string_stc_retn:
  4746 000075B4 5E                  <1> 	pop	esi ; **
  4747 000075B5 59                  <1> 	pop	ecx ; *
  4748 000075B6 C3                  <1> 	retn   
  4749                              <1> 	
  4750                              <1> get_env_string_seq_number_next:
  4751 000075B7 AC                  <1> 	lodsb
  4752 000075B8 08C0                <1> 	or	al, al
  4753 000075BA 75FB                <1> 	jnz	short get_env_string_seq_number_next
  4754                              <1> 
  4755 000075BC 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size ; +512 (+4096)
  4756 000075C2 F5                  <1> 	cmc
  4757 000075C3 72EF                <1> 	jc	short get_env_string_stc_retn
  4758                              <1> 
  4759 000075C5 AC                  <1> 	lodsb
  4760 000075C6 3C01                <1> 	cmp	al, 1
  4761 000075C8 72EA                <1> 	jb	short get_env_string_stc_retn
  4762 000075CA FEC1                <1> 	inc	cl
  4763 000075CC EBBF                <1> 	jmp	short get_env_string_seq_number_check
  4764                              <1> 
  4765                              <1> get_env_string_with_word:
  4766 000075CE 31C9                <1> 	xor	ecx, ecx
  4767                              <1> 
  4768                              <1> get_env_string_calc_word_length:
  4769 000075D0 AC                  <1> 	lodsb 
  4770 000075D1 3C20                <1> 	cmp	al, 20h
  4771 000075D3 7211                <1> 	jb	short get_env_string_calc_word_length_ok
  4772                              <1> 	;inc	cx
  4773 000075D5 FEC1                <1> 	inc	cl
  4774                              <1> 
  4775 000075D7 3C61                <1> 	cmp	al, 'a'
  4776 000075D9 72F5                <1> 	jb	short get_env_string_calc_word_length
  4777 000075DB 3C7A                <1> 	cmp	al, 'z'
  4778 000075DD 77F1                <1> 	ja	short get_env_string_calc_word_length
  4779 000075DF 24DF                <1> 	and	al, 0DFh
  4780 000075E1 8846FF              <1> 	mov	[esi-1], al
  4781 000075E4 EBEA                <1> 	jmp	short get_env_string_calc_word_length
  4782                              <1> 	
  4783                              <1> get_env_string_calc_word_length_ok:
  4784 000075E6 08C9                <1> 	or	cl, cl
  4785 000075E8 7506                <1> 	jnz	short get_env_string_calc_word_length_save
  4786                              <1>      
  4787 000075EA 5E                  <1> 	pop	esi ; **
  4788                              <1> 
  4789                              <1> get_env_string_stc_retn1:
  4790 000075EB 59                  <1> 	pop	ecx ; *
  4791                              <1>         
  4792                              <1> get_env_string_with_word_stc_retn:
  4793 000075EC 31C0                <1> 	xor	eax, eax  
  4794 000075EE F9                  <1> 	stc
  4795 000075EF C3                  <1> 	retn
  4796                              <1>   
  4797                              <1> get_env_string_calc_word_length_save:
  4798 000075F0 871C24              <1> 	xchg	ebx, [esp] ; **
  4799 000075F3 89DE                <1> 	mov	esi, ebx 
  4800                              <1> 		; Start of the env string (to be searched)
  4801                              <1> 
  4802 000075F5 57                  <1> 	push	edi ; ***
  4803 000075F6 89D7                <1> 	mov	edi, edx ; Env_Page
  4804                              <1> 
  4805                              <1> get_env_string_compare:
  4806 000075F8 57                  <1> 	push	edi ; ****
  4807 000075F9 51                  <1> 	push	ecx ; ***** ; Variable name length
  4808                              <1> 
  4809                              <1> get_env_string_compare_rep:
  4810 000075FA AC                  <1> 	lodsb
  4811 000075FB AE                  <1> 	scasb
  4812 000075FC 7511                <1> 	jne	short get_env_string_compare_next1
  4813 000075FE E2FA                <1> 	loop	get_env_string_compare_rep
  4814                              <1> 	
  4815 00007600 803F3D              <1> 	cmp	byte [edi], '='
  4816 00007603 750A                <1> 	jne	short get_env_string_compare_next1
  4817                              <1>  
  4818 00007605 59                  <1> 	pop	ecx ; *****
  4819 00007606 5F                  <1> 	pop	edi ; ****
  4820 00007607 89FE                <1> 	mov	esi, edi
  4821 00007609 5F                  <1> 	pop	edi ; ***
  4822 0000760A 871C24              <1> 	xchg	ebx, [esp] ; **
  4823 0000760D EB82                <1> 	jmp	short get_env_string_move_to_buff
  4824                              <1> 
  4825                              <1> get_env_string_compare_next1:
  4826 0000760F 89FE                <1> 	mov	esi, edi
  4827 00007611 59                  <1> 	pop	ecx ; *****
  4828 00007612 5F                  <1> 	pop	edi ; ****
  4829                              <1> get_env_string_compare_next2:
  4830 00007613 81FEFF310900        <1> 	cmp	esi, Env_Page + Env_Page_Size - 1 ; +511 (+4095)
  4831 00007619 7310                <1> 	jnb	short get_env_string_compare_not_ok
  4832 0000761B 20C0                <1> 	and	al, al
  4833 0000761D AC                  <1> 	lodsb
  4834 0000761E 75F3                <1> 	jnz	short get_env_string_compare_next2
  4835 00007620 08C0                <1> 	or	al, al
  4836 00007622 7407                <1> 	jz	short get_env_string_compare_not_ok
  4837 00007624 4E                  <1> 	dec	esi ; 12/04/2016
  4838 00007625 89F7                <1> 	mov	edi, esi
  4839 00007627 89DE                <1> 	mov	esi, ebx
  4840 00007629 EBCD                <1> 	jmp	short get_env_string_compare
  4841                              <1> 
  4842                              <1> get_env_string_compare_not_ok:
  4843 0000762B 5F                  <1> 	pop	edi ; ***
  4844 0000762C 89DE                <1> 	mov	esi, ebx
  4845 0000762E 5B                  <1> 	pop	ebx ; **
  4846 0000762F 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 00007631 56                  <1> 	push 	esi ; *
  4870                              <1> 
  4871 00007632 31C0                <1> 	xor	eax, eax
  4872                              <1> 
  4873                              <1> set_env_chk_validation1:
  4874 00007634 FEC4                <1> 	inc	ah ; variable (string) length
  4875 00007636 AC                  <1> 	lodsb
  4876 00007637 3C3D                <1> 	cmp	al, '='
  4877 00007639 7415                <1> 	je	short set_env_chk_validation2
  4878 0000763B 3C20                <1> 	cmp	al, 20h
  4879 0000763D 720F                <1> 	jb	short set_env_string_stc
  4880                              <1> 
  4881                              <1> 	; 06/04/2016
  4882 0000763F 3C61                <1> 	cmp	al, 'a'
  4883 00007641 72F1                <1> 	jb	short set_env_chk_validation1
  4884 00007643 3C7A                <1> 	cmp	al, 'z'
  4885 00007645 77ED                <1> 	ja	short set_env_chk_validation1
  4886 00007647 2C20                <1> 	sub	al, 'a'-'A'
  4887 00007649 8846FF              <1> 	mov	[esi-1], al
  4888 0000764C EBE6                <1> 	jmp	short set_env_chk_validation1
  4889                              <1> 
  4890                              <1> set_env_string_stc:
  4891 0000764E 5E                  <1> 	pop	esi ; *
  4892                              <1> 	;stc
  4893 0000764F C3                  <1> 	retn 
  4894                              <1> 	   
  4895                              <1> set_env_chk_validation2:
  4896 00007650 51                  <1> 	push	ecx ; **
  4897 00007651 53                  <1> 	push	ebx ; *** 
  4898 00007652 57                  <1> 	push	edi ; ****
  4899                              <1> 
  4900                              <1> 	; 12/04/2016
  4901 00007653 8B5C240C            <1> 	mov	ebx, [esp+12]
  4902                              <1> 
  4903                              <1> set_env_chk_validation2w:
  4904 00007657 89F7                <1> 	mov	edi, esi
  4905 00007659 4F                  <1> 	dec	edi
  4906                              <1> 
  4907 0000765A 807FFF20            <1> 	cmp	byte [edi-1], 20h
  4908 0000765E 771A                <1> 	ja	short set_env_chk_validation2z
  4909                              <1> 	
  4910 00007660 56                  <1> 	push	esi
  4911 00007661 89FE                <1> 	mov	esi, edi
  4912 00007663 4E                  <1> 	dec	esi
  4913                              <1> 
  4914                              <1> set_env_chk_validation2x:
  4915 00007664 4E                  <1> 	dec	esi
  4916                              <1> 
  4917 00007665 39DE                <1> 	cmp	esi, ebx
  4918 00007667 7207                <1> 	jb	short set_env_chk_validation2y
  4919                              <1> 
  4920 00007669 4F                  <1> 	dec	edi
  4921                              <1> 
  4922 0000766A 8A06                <1> 	mov	al, [esi]
  4923 0000766C 8807                <1> 	mov	[edi], al
  4924                              <1> 
  4925 0000766E EBF4                <1> 	jmp	short set_env_chk_validation2x
  4926                              <1> 
  4927                              <1> set_env_chk_validation2y:
  4928 00007670 5E                  <1> 	pop	esi
  4929                              <1> 
  4930                              <1> 	;mov	byte [ebx], 20h
  4931                              <1> 	
  4932 00007671 43                  <1> 	inc 	ebx
  4933 00007672 895C240C            <1> 	mov	[esp+12], ebx
  4934                              <1> 
  4935 00007676 FECC                <1> 	dec 	ah ; 13/04/2016
  4936                              <1> 
  4937 00007678 EBDD                <1> 	jmp	short set_env_chk_validation2w
  4938                              <1> 	
  4939                              <1> set_env_chk_validation2z:	
  4940 0000767A BA00300900          <1> 	mov	edx, Env_Page
  4941 0000767F 89D7                <1> 	mov	edi, edx
  4942                              <1> 
  4943                              <1> set_env_chk_validation3:
  4944 00007681 AC                  <1> 	lodsb
  4945 00007682 3C20                <1> 	cmp	al, 20h
  4946 00007684 74FB                <1> 	je	short set_env_chk_validation3
  4947                              <1> 
  4948 00007686 9C                  <1> 	pushf
  4949                              <1> 
  4950                              <1> 	; 12/04/2016
  4951                              <1> set_env_chk_validation3n:
  4952 00007687 3C61                <1> 	cmp	al, 'a'
  4953 00007689 720C                <1> 	jb	short set_env_chk_validation3c
  4954 0000768B 3C7A                <1> 	cmp	al, 'z'
  4955 0000768D 7705                <1> 	ja	short set_env_chk_validation3x
  4956 0000768F 2C20                <1> 	sub	al, 'a'-'A'
  4957 00007691 8846FF              <1> 	mov	[esi-1], al
  4958                              <1> 
  4959                              <1> set_env_chk_validation3x:
  4960 00007694 AC                  <1> 	lodsb
  4961 00007695 EBF0                <1> 	jmp	short set_env_chk_validation3n
  4962                              <1> 
  4963                              <1> set_env_chk_validation3c:
  4964 00007697 3C20                <1> 	cmp	al, 20h
  4965 00007699 73F9                <1> 	jnb	short set_env_chk_validation3x
  4966                              <1> 		
  4967 0000769B 803F00              <1> 	cmp	byte [edi], 0
  4968 0000769E 7731                <1> 	ja	short set_env_chk_validation4
  4969                              <1> 
  4970 000076A0 9D                  <1> 	popf
  4971 000076A1 7228                <1> 	jb	short set_env_string_nothing
  4972                              <1> 
  4973 000076A3 B900020000          <1> 	mov	ecx, Env_Page_Size ; 512 (4096)
  4974                              <1> 
  4975 000076A8 89DE                <1> 	mov	esi, ebx ; 12/04/2016
  4976                              <1> 
  4977                              <1> set_env_string_copy_to_envb:
  4978 000076AA AC                  <1> 	lodsb
  4979 000076AB 3C20                <1> 	cmp	al, 20h
  4980 000076AD 720A                <1> 	jb	short set_env_string_copy_to_envb_z
  4981 000076AF AA                  <1> 	stosb
  4982 000076B0 E2F8                <1> 	loop	set_env_string_copy_to_envb
  4983                              <1> 
  4984                              <1> 	; 11/04/2016
  4985 000076B2 89D7                <1> 	mov	edi, edx ; Env_Page
  4986 000076B4 B900020000          <1> 	mov	ecx, Env_Page_Size 
  4987                              <1> 
  4988                              <1> set_env_string_copy_to_envb_z:
  4989 000076B9 52                  <1> 	push	edx  ; Start address of the variable
  4990 000076BA BA00020000          <1> 	mov	edx, Env_Page_Size
  4991 000076BF 29CA                <1> 	sub	edx, ecx ; variable (string) length
  4992                              <1> 
  4993 000076C1 28C0                <1> 	sub	al, al ; 0
  4994 000076C3 F3AA                <1>  	rep	stosb ; clear remain bytes of the env page
  4995                              <1> 
  4996 000076C5 58                  <1> 	pop	eax  ; Start address of the variable
  4997                              <1> 
  4998                              <1> set_env_string_allocate_envb_retn:  ; stc or clc return
  4999 000076C6 5F                  <1> 	pop	edi ; ****
  5000 000076C7 5B                  <1> 	pop	ebx ; ***
  5001 000076C8 59                  <1> 	pop	ecx ; **
  5002 000076C9 5E                  <1> 	pop	esi ; *	
  5003 000076CA C3                  <1> 	retn
  5004                              <1> 
  5005                              <1> set_env_string_nothing:
  5006 000076CB 31C0                <1> 	xor	eax, eax
  5007 000076CD 31D2                <1> 	xor	edx, edx ; 11/04/2016
  5008 000076CF EBF5                <1> 	jmp	short set_env_string_allocate_envb_retn
  5009                              <1> 
  5010                              <1> set_env_chk_validation4:
  5011                              <1> 	; 11/04/2016
  5012 000076D1 9D                  <1> 	popf
  5013                              <1> 
  5014 000076D2 89D6                <1> 	mov	esi, edx  ; Env_Page
  5015                              <1> 
  5016                              <1> set_env_chk_validation5:	
  5017 000076D4 89DF                <1> 	mov	edi, ebx  ; ASCIIZ environment string address	
  5018 000076D6 0FB6CC              <1> 	movzx	ecx, ah ; Variable (string) length (with '=')
  5019                              <1> 
  5020                              <1> set_env_chk_validation5_loop:
  5021 000076D9 AC                  <1> 	lodsb
  5022 000076DA AE                  <1> 	scasb
  5023 000076DB 750A                <1> 	jne	short set_env_chk_validation6
  5024 000076DD E2FA                <1> 	loop	set_env_chk_validation5_loop
  5025                              <1> 
  5026 000076DF 3C3D                <1> 	cmp	al, '='
  5027 000076E1 0F8483000000        <1>         je      set_env_change_variable
  5028                              <1> 
  5029                              <1> set_env_chk_validation6:
  5030 000076E7 08C0                <1> 	or	al, al ; 0
  5031 000076E9 7403                <1> 	jz	short set_env_chk_validation7
  5032                              <1> 
  5033 000076EB AC                  <1> 	lodsb
  5034 000076EC EBF9                <1> 	jmp	short set_env_chk_validation6
  5035                              <1> 
  5036                              <1> set_env_chk_validation7:
  5037 000076EE 88E1                <1> 	mov	cl, ah
  5038 000076F0 01F1                <1> 	add	ecx, esi
  5039 000076F2 81F9FF310900        <1> 	cmp	ecx, Env_Page + Env_Page_Size - 1 
  5040                              <1> 		; 511 (4095) 
  5041                              <1> 		; strlen + '=' + 0
  5042 000076F8 72DA                <1> 	jb	short set_env_chk_validation5
  5043                              <1> 
  5044                              <1> set_env_chk_validation8: ; variable not found
  5045 000076FA 0FB6F4              <1> 	movzx	esi, ah  ; variable name length (with '=') 
  5046 000076FD 01DE                <1> 	add	esi, ebx ; position just after of the '='
  5047                              <1> 
  5048                              <1> set_env_chk_validation8_loop:
  5049 000076FF AC                  <1> 	lodsb
  5050 00007700 3C20                <1> 	cmp	al, 20h
  5051 00007702 74FB                <1> 	je	short set_env_chk_validation8_loop	
  5052 00007704 72C5                <1> 	jb	short set_env_string_nothing
  5053                              <1> 
  5054                              <1> set_env_chk_validation9:
  5055 00007706 AC                  <1> 	lodsb
  5056 00007707 3C20                <1> 	cmp	al, 20h
  5057 00007709 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 0000770B 29DE                <1> 	sub	esi, ebx ; variable+definition length
  5063                              <1> 	
  5064 0000770D 56                  <1> 	push	esi ; *****
  5065                              <1> 
  5066 0000770E 89D6                <1> 	mov	esi, edx ; Environment page address
  5067                              <1> 
  5068 00007710 B900020000          <1> 	mov	ecx, Env_Page_Size ; 512 (4096)	
  5069                              <1> 
  5070                              <1> set_env_add_variable_loop:
  5071 00007715 AC                  <1> 	lodsb
  5072 00007716 20C0                <1> 	and	al, al		
  5073 00007718 7406                <1> 	jz	short set_env_add_variable_chk1 ; 0
  5074 0000771A E2F9                <1> 	loop	set_env_add_variable_loop
  5075                              <1> 
  5076                              <1> 	; 11/04/2016
  5077 0000771C 884EFF              <1> 	mov	[esi-1], cl ; 0
  5078 0000771F 41                  <1> 	inc	ecx
  5079                              <1> 	
  5080                              <1> set_env_add_variable_chk1: 
  5081 00007720 49                  <1> 	dec	ecx
  5082 00007721 7408                <1> 	jz	short set_env_add_variable_nspc
  5083 00007723 AC                  <1> 	lodsb
  5084 00007724 08C0                <1> 	or 	al, al
  5085 00007726 740C                <1> 	jz	short set_env_add_variable_chk2 ; 00
  5086 00007728 49                  <1> 	dec	ecx
  5087 00007729 75EA                <1> 	jnz	short set_env_add_variable_loop
  5088                              <1> 
  5089                              <1> set_env_add_variable_nspc: ; no space on environment page
  5090 0000772B 58                  <1> 	pop	eax ; *****
  5091 0000772C B808000000          <1> 	mov	eax, 08h ; No space for new environment string
  5092 00007731 F9                  <1> 	stc
  5093 00007732 EB92                <1>         jmp     short set_env_string_allocate_envb_retn
  5094                              <1> 
  5095                              <1> set_env_add_variable_chk2:
  5096 00007734 8B0C24              <1> 	mov	ecx, [esp] ; *****
  5097 00007737 4E                  <1> 	dec	esi ; beginning address of the new variable
  5098 00007738 89F0                <1> 	mov	eax, esi
  5099 0000773A 01C8                <1> 	add	eax, ecx ; string length (with CR)
  5100 0000773C 81C200020000        <1> 	add	edx, Env_Page_Size ; 512 (4096)
  5101 00007742 39D0                <1> 	cmp	eax, edx 
  5102 00007744 77E5                <1> 	ja	short set_env_add_variable_nspc
  5103 00007746 49                  <1> 	dec	ecx ; except CR at the end
  5104 00007747 89CA                <1> 	mov	edx, ecx ; 12/04/2016
  5105 00007749 89F7                <1> 	mov	edi, esi
  5106 0000774B 893C24              <1> 	mov	[esp], edi ; ***** ; Start address of new variable
  5107 0000774E 89DE                <1> 	mov	esi, ebx ; ASCIIZ environment string address
  5108 00007750 F3A4                <1> 	rep	movsb
  5109 00007752 28C0                <1> 	sub	al, al
  5110 00007754 AA                  <1> 	stosb
  5111 00007755 58                  <1> 	pop	eax ; ***** ; Beginning address of new variable			
  5112 00007756 81FF00320900        <1>         cmp     edi, Env_Page + Env_Page_Size ; 12/04/2016
  5113 0000775C 0F8364FFFFFF        <1>         jnb     set_env_string_allocate_envb_retn ; OK !
  5114 00007762 880F                <1> 	mov	[edi], cl ; 0
  5115 00007764 F8                  <1> 	clc	; 13/04/2016
  5116 00007765 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 0000776A 8825[28EA0000]      <1> 	mov	[env_var_length], ah
  5125                              <1> 
  5126 00007770 28C9                <1> 	sub	cl, cl ; ecx = 0
  5127                              <1> 
  5128 00007772 57                  <1> 	push	edi ; *****
  5129                              <1> 
  5130 00007773 89F7                <1> 	mov	edi, esi ; 11/04/2016
  5131                              <1> 
  5132                              <1> set_env_change_variable_calc1:
  5133 00007775 AC                  <1> 	lodsb
  5134 00007776 08C0                <1> 	or	al, al
  5135 00007778 7403                <1> 	jz	short set_env_change_variable_calc2
  5136                              <1> 
  5137 0000777A 41                  <1> 	inc	ecx ; length of environment string (after the '=')
  5138                              <1> 
  5139 0000777B EBF8                <1> 	jmp	short set_env_change_variable_calc1	
  5140                              <1> 
  5141                              <1> set_env_change_variable_calc2:
  5142 0000777D 8B3424              <1> 	mov	esi, [esp] ; ASCIIZ environment string address
  5143                              <1> 	
  5144 00007780 29D2                <1> 	sub	edx, edx
  5145                              <1> 
  5146                              <1> set_env_change_variable_calc3:
  5147 00007782 AC                  <1> 	lodsb
  5148 00007783 3C20                <1> 	cmp	al, 20h
  5149 00007785 7203                <1> 	jb	short set_env_change_variable_calc4
  5150                              <1> 
  5151 00007787 42                  <1> 	inc	edx ; length of ASCIIZ string (after the '=')
  5152                              <1> 	
  5153 00007788 EBF8                <1> 	jmp	short set_env_change_variable_calc3
  5154                              <1> 	
  5155                              <1> set_env_change_variable_calc4:
  5156 0000778A C646FF00            <1> 	mov	byte [esi-1], 0  ; put ZERO instead of CR
  5157                              <1> 	
  5158 0000778E 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 0000778F 39CA                <1> 	cmp	edx, ecx
  5164 00007791 7717                <1> 	ja	short set_env_change_variable_calc5 ; longer
  5165 00007793 0F828F000000        <1>         jb      set_env_change_variable_calc9 ; shorter
  5166                              <1> 	
  5167                              <1> 	;same length (simple copy)
  5168 00007799 0FB6C4              <1> 	movzx	eax, ah
  5169 0000779C 01C2                <1> 	add	edx, eax
  5170 0000779E F7D8                <1> 	neg	eax
  5171 000077A0 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 000077A2 F3A4                <1> 	rep	movsb
  5176 000077A4 F8                  <1> 	clc	; 13/04/2016
  5177 000077A5 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 000077AA 52                  <1> 	push	edx ; *****
  5182 000077AB 29CA                <1> 	sub	edx, ecx ; difference ; (the new string is longer)
  5183 000077AD 89F3                <1> 	mov 	ebx, esi
  5184 000077AF 89FE                <1> 	mov	esi, edi
  5185                              <1> 
  5186                              <1> set_env_change_variable_calc6:
  5187 000077B1 AC                  <1> 	lodsb 
  5188 000077B2 20C0                <1> 	and	al, al
  5189 000077B4 75FB                <1> 	jnz	short set_env_change_variable_calc6
  5190                              <1> 
  5191 000077B6 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size ; 512 (4096)
  5192 000077BC 0F8369FFFFFF        <1>         jnb     set_env_add_variable_nspc
  5193                              <1> 
  5194 000077C2 89F9                <1> 	mov	ecx, edi  ; current (old) variable's address
  5195 000077C4 89F7                <1> 	mov	edi, esi  ; next variable's address 
  5196                              <1> 
  5197 000077C6 AC                  <1> 	lodsb
  5198 000077C7 08C0                <1> 	or	al, al
  5199 000077C9 7416                <1> 	jz	short set_env_change_variable_calc8 ; 00
  5200                              <1> 
  5201                              <1> set_env_change_variable_calc7:
  5202 000077CB AC                  <1> 	lodsb
  5203 000077CC 20C0                <1> 	and	al, al
  5204 000077CE 75FB                <1> 	jnz	short set_env_change_variable_calc7
  5205                              <1> 
  5206 000077D0 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size ; 512 (4096)
  5207 000077D6 0F834FFFFFFF        <1>         jnb     set_env_add_variable_nspc
  5208                              <1> 
  5209 000077DC AC                  <1> 	lodsb
  5210 000077DD 08C0                <1> 	or	al, al
  5211 000077DF 75EA                <1> 	jnz	short set_env_change_variable_calc7
  5212                              <1> 
  5213                              <1> set_env_change_variable_calc8:
  5214 000077E1 4E                  <1> 	dec	esi ; address of the second (last) 0 of the 00
  5215                              <1> 
  5216 000077E2 01F2                <1> 	add	edx, esi ; final position of the last 0
  5217                              <1> 
  5218 000077E4 81FA00320900        <1> 	cmp	edx, Env_Page + Env_Page_Size ; 512 (4096)
  5219 000077EA 0F833BFFFFFF        <1>         jnb     set_env_add_variable_nspc
  5220                              <1> 
  5221 000077F0 89C8                <1> 	mov	eax, ecx ; old variable's address (after '=')
  5222                              <1> 
  5223 000077F2 89F1                <1> 	mov	ecx, esi 
  5224 000077F4 29F9                <1> 	sub	ecx, edi ; count of bytes to move forward
  5225                              <1> 
  5226                              <1> 	; 13/04/2016
  5227 000077F6 C60200              <1> 	mov	byte [edx], 0
  5228 000077F9 89D7                <1> 	mov	edi, edx
  5229 000077FB 29F2                <1> 	sub	edx, esi ; difference (additional byte count)
  5230 000077FD 4F                  <1> 	dec	edi ; the last zero address (first byte of the 00)
  5231 000077FE 89FE                <1> 	mov	esi, edi
  5232 00007800 29D6                <1> 	sub	esi, edx ; - displacement
  5233                              <1> 	
  5234 00007802 FA                  <1> 	cli	; disable interrupts
  5235 00007803 FD                  <1> 	std	; backward
  5236                              <1> 
  5237 00007804 F3A4                <1> 	rep	movsb ; move ECX bytes from DS:ESI to ES:EDI
  5238                              <1> 
  5239 00007806 FC                  <1> 	cld	; forward (default)
  5240 00007807 FB                  <1> 	sti	; enable interrupts
  5241                              <1> 	
  5242 00007808 89C7                <1> 	mov	edi, eax
  5243 0000780A 59                  <1> 	pop	ecx ; ***** ; byte count (after '=')
  5244 0000780B 89CA                <1> 	mov	edx, ecx
  5245 0000780D 89DE                <1> 	mov	esi, ebx ; ASCIIZ string address (after '=')
  5246 0000780F 89FB                <1> 	mov	ebx, edi
  5247                              <1> 
  5248 00007811 F3A4                <1> 	rep	movsb
  5249                              <1> 
  5250 00007813 880F                <1> 	mov	[edi], cl ; 0 ; end of variable
  5251                              <1> 
  5252 00007815 0FB605[28EA0000]    <1> 	movzx	eax, byte [env_var_length]
  5253 0000781C 01C2                <1> 	add	edx, eax ; variable length (total)
  5254 0000781E F7D8                <1> 	neg	eax
  5255 00007820 01D8                <1> 	add	eax, ebx ; start address of the variable
  5256 00007822 F8                  <1> 	clc	; 13/04/2016
  5257 00007823 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 00007828 21D2                <1> 	and	edx, edx ; is empty ?
  5262 0000782A 753B                <1> 	jnz	short set_env_change_variable_calc15
  5263                              <1> 	
  5264 0000782C 0FB6DC              <1> 	movzx	ebx, ah
  5265 0000782F F7DB                <1> 	neg	ebx
  5266 00007831 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 00007833 89FE                <1> 	mov	esi, edi
  5272                              <1> 
  5273                              <1> set_env_change_variable_calc10:
  5274 00007835 AC                  <1> 	lodsb
  5275 00007836 08C0                <1> 	or	al, al
  5276 00007838 75FB                <1> 	jnz	short set_env_change_variable_calc10
  5277                              <1> 
  5278 0000783A B9FF310900          <1> 	mov	ecx, Env_Page + Env_Page_Size - 1
  5279                              <1> 
  5280 0000783F 39CE                <1> 	cmp	esi, ecx ; +511 (+4095)
  5281 00007841 7604                <1> 	jna	short set_env_change_variable_calc11
  5282                              <1> 
  5283 00007843 89CE                <1> 	mov	esi, ecx
  5284 00007845 8806                <1> 	mov	[esi], al ; 0
  5285                              <1> 
  5286                              <1> set_env_change_variable_calc11:
  5287 00007847 89DF                <1> 	mov	edi, ebx ; old variable's start address
  5288                              <1> 
  5289                              <1> set_env_change_variable_calc12:
  5290 00007849 AC                  <1> 	lodsb
  5291 0000784A AA                  <1> 	stosb
  5292 0000784B 20C0                <1> 	and	al, al
  5293 0000784D 75FA                <1> 	jnz	short set_env_change_variable_calc12
  5294 0000784F 39CE                <1> 	cmp	esi, ecx
  5295 00007851 7706                <1> 	ja	short set_env_change_variable_calc13
  5296 00007853 AC                  <1> 	lodsb
  5297 00007854 AA                  <1> 	stosb
  5298 00007855 20C0                <1> 	and	al, al
  5299 00007857 75F0                <1> 	jnz	short set_env_change_variable_calc12	
  5300                              <1> 
  5301                              <1> set_env_change_variable_calc13:
  5302 00007859 29F9                <1> 	sub	ecx, edi
  5303 0000785B 7203                <1> 	jb	short set_env_change_variable_calc14
  5304 0000785D 41                  <1> 	inc	ecx ; 1-512 (1-4096)
  5305 0000785E F3AA                <1> 	rep	stosb ; al = 0	
  5306                              <1> 
  5307                              <1> set_env_change_variable_calc14:
  5308 00007860 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 00007862 E95FFEFFFF          <1>         jmp     set_env_string_allocate_envb_retn ; OK !
  5313                              <1> 	    
  5314                              <1> set_env_change_variable_calc15:	
  5315 00007867 52                  <1> 	push	edx ; *****
  5316 00007868 F7DA                <1> 	neg	edx
  5317 0000786A 01CA                <1> 	add	edx, ecx ; difference (the old string is longer)
  5318 0000786C 89F3                <1> 	mov 	ebx, esi
  5319 0000786E 89FE                <1> 	mov	esi, edi
  5320                              <1> 
  5321                              <1> set_env_change_variable_calc16:
  5322 00007870 AC                  <1> 	lodsb 
  5323 00007871 20C0                <1> 	and	al, al
  5324 00007873 75FB                <1> 	jnz	short set_env_change_variable_calc16
  5325                              <1> 
  5326 00007875 B900320900          <1> 	mov	ecx, Env_Page + Env_Page_Size
  5327                              <1> 
  5328 0000787A 39CE                <1> 	cmp	esi, ecx ; +512 (+4096)
  5329 0000787C 7605                <1> 	jna	short set_env_change_variable_calc17
  5330                              <1> 
  5331 0000787E 89CE                <1> 	mov	esi, ecx
  5332 00007880 8846FF              <1> 	mov	[esi-1], al ; 0
  5333                              <1> 
  5334                              <1> set_env_change_variable_calc17:
  5335 00007883 89F9                <1> 	mov	ecx, edi  ; current (old) variable's address
  5336 00007885 89F7                <1> 	mov	edi, esi  ; next variable's address 
  5337                              <1> 
  5338 00007887 AC                  <1> 	lodsb
  5339 00007888 08C0                <1> 	or	al, al
  5340 0000788A 741D                <1> 	jz	short set_env_change_variable_calc20
  5341                              <1> 
  5342                              <1> set_env_change_variable_calc18:
  5343 0000788C AC                  <1> 	lodsb
  5344 0000788D 20C0                <1> 	and	al, al
  5345 0000788F 75FB                <1> 	jnz	short set_env_change_variable_calc18
  5346                              <1> 
  5347 00007891 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size
  5348 00007897 720B                <1> 	jb	short set_env_change_variable_calc19
  5349 00007899 740E                <1> 	je	short set_env_change_variable_calc20
  5350                              <1> 
  5351 0000789B BEFF310900          <1> 	mov	esi, Env_Page + Env_Page_Size - 1
  5352 000078A0 8806                <1> 	mov	[esi], al ; 0
  5353 000078A2 EB06                <1> 	jmp	short set_env_change_variable_calc21
  5354                              <1> 
  5355                              <1> set_env_change_variable_calc19:
  5356 000078A4 AC                  <1> 	lodsb
  5357 000078A5 08C0                <1> 	or	al, al
  5358 000078A7 75E3                <1> 	jnz	short set_env_change_variable_calc18
  5359                              <1> 
  5360                              <1> set_env_change_variable_calc20:
  5361 000078A9 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 000078AA 89C8                <1> 	mov	eax, ecx ; old variable's address (after '=')
  5367                              <1> 
  5368 000078AC 89F1                <1> 	mov	ecx, esi 
  5369 000078AE 29F9                <1> 	sub	ecx, edi ; count of bytes to move backward
  5370                              <1> 
  5371 000078B0 89FE                <1> 	mov	esi, edi ; next variable's address
  5372 000078B2 29D7                <1> 	sub	edi, edx ; (displacement)
  5373                              <1> 	
  5374 000078B4 F3A4                <1> 	rep	movsb
  5375                              <1> 
  5376 000078B6 880F                <1> 	mov	[edi], cl ; 0 ; 00 ; end of environment variables
  5377                              <1> 
  5378 000078B8 89C7                <1> 	mov	edi, eax
  5379 000078BA 5A                  <1> 	pop	edx ; ***** ; byte count (after '=')
  5380 000078BB 89D1                <1> 	mov	ecx, edx
  5381 000078BD 89DE                <1> 	mov	esi, ebx ; ASCIIZ string address (after '=')
  5382 000078BF 89FB                <1> 	mov	ebx, edi
  5383                              <1> 	
  5384 000078C1 F3A4                <1> 	rep	movsb
  5385                              <1> 
  5386 000078C3 880F                <1> 	mov	[edi], cl ; 0 ; end of variable
  5387                              <1> 
  5388 000078C5 0FB605[28EA0000]    <1> 	movzx	eax, byte [env_var_length]
  5389 000078CC 01C2                <1> 	add	edx, eax ; variable length (total)
  5390 000078CE F7D8                <1> 	neg	eax
  5391 000078D0 01D8                <1> 	add	eax, ebx ; start address of the variable
  5392 000078D2 F8                  <1> 	clc	; 13/04/2016
  5393 000078D3 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 000078D8 BE[6FC80000]        <1> 	mov	esi, MainProgCfgFile
  5402 000078DD 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  5403 000078E1 E8FBE9FFFF          <1> 	call	find_first_file
  5404 000078E6 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 000078E8 A3[ACDD0000]        <1> 	mov	[MainProgCfg_FileSize], eax
  5414                              <1> 
  5415 000078ED 668B5614            <1> 	mov	dx, [esi+DirEntry_FstClusHI]
  5416 000078F1 C1E210              <1> 	shl	edx, 16
  5417 000078F4 668B561A            <1> 	mov	dx, [esi+DirEntry_FstClusLO]
  5418 000078F8 8915[DCE90000]      <1> 	mov	[csftdf_sf_cluster], edx
  5419                              <1> 
  5420 000078FE 89C1                <1> 	mov	ecx, eax
  5421 00007900 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 00007902 E80AC7FFFF          <1> 	call	allocate_memory_block
  5430 00007907 7235                <1> 	jc	short loc_load_mainprog_cfg_exit
  5431                              <1> 
  5432 00007909 A3[D4E90000]        <1> 	mov	[csftdf_sf_mem_addr], eax ; loading address
  5433 0000790E 890D[D8E90000]      <1> 	mov	[csftdf_sf_mem_bsize], ecx ; block size
  5434                              <1> 
  5435 00007914 31DB                <1> 	xor	ebx, ebx
  5436                              <1> 	;mov	[csftdf_sf_rbytes], ebx ; 0, reset
  5437                              <1> 
  5438 00007916 8A3D[BEDD0000]      <1> 	mov	bh, [Current_Drv] ; [FindFile_Drv]
  5439 0000791C BE00010900          <1> 	mov	esi, Logical_DOSDisks
  5440 00007921 01DE                <1> 	add	esi, ebx
  5441                              <1> 
  5442 00007923 8B1D[D4E90000]      <1> 	mov	ebx, [csftdf_sf_mem_addr] ; memory block address
  5443                              <1> 
  5444 00007929 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5445 0000792D 7710                <1>         ja	short loc_mcfg_load_fat_file
  5446                              <1> 
  5447 0000792F C705[E4E90000]0000- <1> 	mov	dword [csftdf_r_size], 65536
  5447 00007937 0100                <1>
  5448 00007939 E992010000          <1>         jmp     loc_mcfg_load_fs_file
  5449                              <1> 
  5450                              <1> loc_load_mainprog_cfg_exit:
  5451 0000793E C3                  <1> 	retn 
  5452                              <1> 
  5453                              <1> loc_mcfg_load_fat_file:
  5454 0000793F 0FB74611            <1> 	movzx	eax, word [esi+LD_BPB+BytesPerSec]
  5455 00007943 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  5456 00007947 F7E1                <1> 	mul	ecx
  5457 00007949 A3[E4E90000]        <1> 	mov	[csftdf_r_size], eax
  5458                              <1> 
  5459                              <1> loc_mcfg_load_fat_file_next:
  5460 0000794E E813010000          <1> 	call	mcfg_read_fat_file_sectors
  5461 00007953 0F82F7000000        <1>         jc      mcfg_deallocate_mem
  5462                              <1> 
  5463 00007959 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  5464 0000795B 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 0000795D C705[6CEA0000]-     <1> 	mov	dword [mainprog_return_addr], loc_mcfg_ci_return_addr 
  5468 00007963 [117A0000]          <1>
  5469                              <1> 	;
  5470 00007967 8B35[D4E90000]      <1> 	mov	esi, [csftdf_sf_mem_addr]
  5471 0000796D 8935[B0DD0000]      <1> 	mov	[MainProgCfg_LineOffset], esi
  5472                              <1> 	
  5473 00007973 A1[ACDD0000]        <1> 	mov	eax, [MainProgCfg_FileSize]
  5474 00007978 89C2                <1> 	mov	edx, eax
  5475 0000797A 01F2                <1> 	add	edx, esi
  5476                              <1> 
  5477                              <1> loc_mcfg_process_next_line_check:
  5478 0000797C 89C1                <1> 	mov	ecx, eax
  5479                              <1> 
  5480 0000797E 803E2A              <1> 	cmp	byte [esi], "*" ; Remark sign
  5481 00007981 7503                <1> 	jne	short loc_mcfg_process_next_line
  5482 00007983 46                  <1> 	inc	esi
  5483 00007984 EB17                <1> 	jmp	short loc_move_mainprog_cfg_nl1
  5484                              <1> 
  5485                              <1> loc_mcfg_process_next_line:
  5486 00007986 83F94F              <1> 	cmp	ecx, 79
  5487 00007989 7605                <1> 	jna	short loc_start_mainprog_cfg_process
  5488                              <1> 	
  5489 0000798B B94F000000          <1> 	mov	ecx, 79 
  5490                              <1> 
  5491                              <1> loc_start_mainprog_cfg_process:
  5492 00007990 BF[6EDE0000]        <1> 	mov	edi, CommandBuffer
  5493                              <1> 
  5494                              <1> loc_move_mainprog_cfg_line:
  5495 00007995 AC                  <1> 	lodsb
  5496 00007996 3C20                <1> 	cmp	al, 20h
  5497 00007998 720C                <1> 	jb	short loc_move_mainprog_cfg_nl2
  5498 0000799A AA                  <1> 	stosb
  5499 0000799B E2F8                <1> 	loop	loc_move_mainprog_cfg_line
  5500                              <1> 
  5501                              <1> loc_move_mainprog_cfg_nl1:
  5502 0000799D 39D6                <1> 	cmp	esi, edx ; + configuration file size
  5503 0000799F 7312                <1> 	jnb	short loc_end_of_mainprog_cfg_line
  5504 000079A1 AC                  <1> 	lodsb
  5505 000079A2 3C20                <1> 	cmp	al, 20h
  5506 000079A4 73F7                <1> 	jnb	short loc_move_mainprog_cfg_nl1
  5507                              <1> 
  5508                              <1> loc_move_mainprog_cfg_nl2:
  5509 000079A6 39D6                <1> 	cmp	esi, edx
  5510 000079A8 7309                <1> 	jnb	short loc_end_of_mainprog_cfg_line
  5511 000079AA 8A06                <1> 	mov	al, [esi]
  5512 000079AC 3C20                <1> 	cmp	al, 20h
  5513 000079AE 7703                <1>  	ja	short loc_end_of_mainprog_cfg_line
  5514 000079B0 46                  <1> 	inc	esi
  5515 000079B1 EBF3                <1> 	jmp	short loc_move_mainprog_cfg_nl2	               
  5516                              <1> 
  5517                              <1> loc_end_of_mainprog_cfg_line:
  5518 000079B3 C60700              <1> 	mov	byte [edi], 0
  5519                              <1> 
  5520 000079B6 8935[B0DD0000]      <1> 	mov	[MainProgCfg_LineOffset], esi
  5521                              <1> 	
  5522                              <1> loc_move_mainprog_cfg_command:
  5523 000079BC BE[6EDE0000]        <1> 	mov	esi, CommandBuffer
  5524 000079C1 89F7                <1> 	mov	edi, esi
  5525 000079C3 31DB                <1> 	xor	ebx, ebx
  5526                              <1> 	;xor	ecx, ecx
  5527 000079C5 30C9                <1> 	xor	cl, cl
  5528                              <1> 
  5529                              <1> loc_move_mcfg_first_cmd_char:
  5530 000079C7 8A041E              <1> 	mov	al, [esi+ebx]
  5531 000079CA FEC3                <1> 	inc	bl 
  5532 000079CC 3C20                <1> 	cmp	al, 20h
  5533 000079CE 7712                <1> 	ja	short loc_move_mcfg_cmd_capitalizing
  5534 000079D0 7237                <1> 	jb	short loc_move_mcfg_cmd_arguments_ok
  5535 000079D2 80FB4F              <1> 	cmp	bl, 79
  5536 000079D5 72F0                <1> 	jb	short loc_move_mcfg_first_cmd_char
  5537 000079D7 EB30                <1> 	jmp	short loc_move_mcfg_cmd_arguments_ok
  5538                              <1> 
  5539                              <1> loc_move_mcfg_next_cmd_char:
  5540 000079D9 8A041E              <1> 	mov	al, [esi+ebx]
  5541 000079DC FEC3                <1> 	inc	bl
  5542 000079DE 3C20                <1> 	cmp	al, 20h
  5543 000079E0 7614                <1> 	jna	short loc_move_mcfg_cmd_ok
  5544                              <1> 
  5545                              <1> loc_move_mcfg_cmd_capitalizing:
  5546 000079E2 3C61                <1> 	cmp	al, 61h ; 'a'
  5547 000079E4 7206                <1> 	jb	short loc_move_mcfg_cmd_caps_ok
  5548 000079E6 3C7A                <1> 	cmp	al, 7Ah ; 'z'
  5549 000079E8 7702                <1> 	ja	short loc_move_mcfg_cmd_caps_ok
  5550 000079EA 24DF                <1> 	and	al, 0DFh ; sub	al, 'a'-'A'
  5551                              <1> 
  5552                              <1> loc_move_mcfg_cmd_caps_ok:
  5553 000079EC AA                  <1> 	stosb 
  5554 000079ED FEC1                <1> 	inc	cl
  5555 000079EF 80FB4F              <1> 	cmp	bl, 79
  5556 000079F2 72E5                <1> 	jb	short loc_move_mcfg_next_cmd_char
  5557 000079F4 EB13                <1> 	jmp	short loc_move_mcfg_cmd_arguments_ok
  5558                              <1> 
  5559                              <1> loc_move_mcfg_cmd_ok:
  5560 000079F6 30C0                <1> 	xor	al, al ; 0
  5561                              <1> 
  5562                              <1> loc_move_mcfg_cmd_arguments:
  5563 000079F8 8807                <1> 	mov	[edi], al
  5564 000079FA 47                  <1> 	inc	edi
  5565 000079FB 80FB4F              <1> 	cmp	bl, 79
  5566 000079FE 7309                <1> 	jnb	short loc_move_mcfg_cmd_arguments_ok
  5567 00007A00 8A041E              <1> 	mov	al, [esi+ebx]
  5568 00007A03 FEC3                <1> 	inc	bl
  5569 00007A05 3C20                <1> 	cmp	al, 20h
  5570 00007A07 73EF                <1> 	jnb	short loc_move_mcfg_cmd_arguments
  5571                              <1> 	
  5572                              <1> loc_move_mcfg_cmd_arguments_ok:
  5573 00007A09 C60700              <1> 	mov	byte [edi], 0
  5574                              <1>        
  5575                              <1> loc_mcfg_process_cmd_interpreter:
  5576 00007A0C E8F8DFFFFF          <1> 	call    command_interpreter
  5577                              <1> 
  5578                              <1> loc_mcfg_ci_return_addr: 
  5579 00007A11 A1[ACDD0000]        <1> 	mov	eax, [MainProgCfg_FileSize]
  5580 00007A16 89C2                <1> 	mov	edx, eax
  5581 00007A18 8B35[B0DD0000]      <1> 	mov	esi, [MainProgCfg_LineOffset]
  5582 00007A1E 01F2                <1> 	add	edx, esi
  5583 00007A20 0305[D4E90000]      <1> 	add	eax, [csftdf_sf_mem_addr]
  5584 00007A26 29F0                <1> 	sub	eax, esi
  5585 00007A28 0F874EFFFFFF        <1>         ja      loc_mcfg_process_next_line_check
  5586                              <1> 
  5587 00007A2E E81D000000          <1> 	call	mcfg_deallocate_mem
  5588                              <1>  
  5589 00007A33 B94F000000          <1>  	mov	ecx, 79 ; 80 ?
  5590 00007A38 BF[6EDE0000]        <1> 	mov	edi, CommandBuffer
  5591 00007A3D 30C0                <1> 	xor	al, al
  5592 00007A3F F3AA                <1> 	rep	stosb
  5593                              <1> 
  5594                              <1> 	; 06/05/2016
  5595 00007A41 BE[9CD90000]        <1> 	mov	esi, nextline
  5596 00007A46 E8F5CBFFFF          <1> 	call	print_msg
  5597 00007A4B E931D6FFFF          <1> 	jmp	dos_prompt
  5598                              <1> 
  5599                              <1> mcfg_deallocate_mem:
  5600 00007A50 A1[D4E90000]        <1> 	mov	eax, [csftdf_sf_mem_addr] ; start address
  5601 00007A55 8B0D[D8E90000]      <1> 	mov	ecx, [csftdf_sf_mem_bsize] ; block size	
  5602                              <1> 	;call	deallocate_memory_block
  5603                              <1> 	;retn
  5604 00007A5B E9B2C7FFFF          <1> 	jmp	deallocate_memory_block
  5605                              <1> 
  5606                              <1> mcfg_read_file_sectors:
  5607                              <1> 	; 14/04/2016
  5608 00007A60 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5609 00007A64 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 00007A66 8B15[ACDD0000]      <1> 	mov	edx, [MainProgCfg_FileSize]
  5619 00007A6C 2B15[ECE90000]      <1> 	sub	edx, [csftdf_sf_rbytes]
  5620 00007A72 3B15[E4E90000]      <1> 	cmp	edx, [csftdf_r_size]	
  5621 00007A78 7306                <1> 	jnb	short mcfg_read_fat_file_secs_1
  5622 00007A7A 8915[E4E90000]      <1> 	mov	[csftdf_r_size], edx
  5623                              <1> 		
  5624                              <1> mcfg_read_fat_file_secs_1:
  5625 00007A80 A1[E4E90000]        <1> 	mov	eax, [csftdf_r_size]
  5626 00007A85 29D2                <1> 	sub	edx, edx
  5627 00007A87 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec]
  5628 00007A8B 01C8                <1> 	add	eax, ecx
  5629 00007A8D 48                  <1> 	dec	eax
  5630 00007A8E F7F1                <1> 	div	ecx
  5631 00007A90 89C1                <1> 	mov	ecx, eax ; sector count
  5632 00007A92 A1[DCE90000]        <1> 	mov	eax, [csftdf_sf_cluster]
  5633                              <1> 
  5634                              <1> 	; EBX = memory block address (current)
  5635                              <1> 	
  5636 00007A97 E874230000          <1> 	call	read_fat_file_sectors
  5637 00007A9C 7230                <1> 	jc	short mcfg_read_fat_file_secs_3
  5638                              <1> 
  5639                              <1> 	; EBX = next memory address
  5640                              <1> 
  5641 00007A9E A1[ECE90000]        <1> 	mov	eax, [csftdf_sf_rbytes]
  5642 00007AA3 0305[E4E90000]      <1> 	add	eax, [csftdf_r_size]
  5643 00007AA9 8B15[ACDD0000]      <1> 	mov	edx, [MainProgCfg_FileSize]
  5644 00007AAF 39D0                <1> 	cmp	eax, edx
  5645 00007AB1 731B                <1> 	jnb	short mcfg_read_fat_file_secs_3 ; edx > 0
  5646 00007AB3 A3[ECE90000]        <1> 	mov	[csftdf_sf_rbytes], eax
  5647                              <1> 
  5648 00007AB8 53                  <1> 	push	ebx ; *
  5649                              <1> 	; get next cluster (csftdf_r_size! bytes)
  5650 00007AB9 A1[DCE90000]        <1> 	mov	eax, [csftdf_sf_cluster]
  5651 00007ABE E81F210000          <1> 	call	get_next_cluster
  5652 00007AC3 5B                  <1> 	pop	ebx ; *
  5653 00007AC4 7301                <1> 	jnc	short mcfg_read_fat_file_secs_2
  5654                              <1> 
  5655                              <1> 	;mov	eax, 15h ; Read error !
  5656 00007AC6 C3                  <1> 	retn
  5657                              <1> 
  5658                              <1> mcfg_read_fat_file_secs_2:
  5659 00007AC7 29D2                <1> 	sub	edx, edx ; 0
  5660 00007AC9 A3[DCE90000]        <1> 	mov	[csftdf_sf_cluster], eax ; next cluster
  5661                              <1> 
  5662                              <1> mcfg_read_fat_file_secs_3:
  5663 00007ACE C3                  <1> 	retn
  5664                              <1> 
  5665                              <1> mcfg_read_fs_file_sectors:
  5666 00007ACF C3                  <1> 	retn
  5667                              <1> 
  5668                              <1> loc_mcfg_load_fs_file:
  5669 00007AD0 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 00007AD1 803E20              <1> 	cmp	byte [esi], 20h
  5692 00007AD4 0F8205E3FFFF        <1> 	jb	loc_cmd_failed
  5693 00007ADA 7703                <1> 	ja	short loc_run_check_filename_ok
  5694 00007ADC 46                  <1> 	inc	esi
  5695 00007ADD EBF2                <1> 	jmp	short loc_run_check_filename
  5696                              <1> 
  5697                              <1> loc_run_check_filename_ok:
  5698 00007ADF C605[1FDE0000]00    <1> 	mov	byte [CmdArgStart], 0 ; reset
  5699 00007AE6 56                  <1> 	push	esi ; *
  5700                              <1> loc_run_get_first_arg_pos:
  5701 00007AE7 46                  <1> 	inc	esi
  5702 00007AE8 8A06                <1> 	mov	al, [esi]
  5703 00007AEA 3C20                <1> 	cmp	al, 20h
  5704 00007AEC 77F9                <1> 	ja	short loc_run_get_first_arg_pos
  5705 00007AEE C60600              <1> 	mov	byte [esi], 0
  5706                              <1> loc_run_get_external_arg_pos:
  5707                              <1> 	; 11/05/2016
  5708 00007AF1 46                  <1> 	inc	esi
  5709 00007AF2 8A06                <1> 	mov	al, [esi]
  5710 00007AF4 3C20                <1> 	cmp	al, 20h
  5711 00007AF6 760C                <1> 	jna	short loc_run_parse_path_name
  5712 00007AF8 89F0                <1> 	mov	eax, esi
  5713 00007AFA 2D[6EDE0000]        <1> 	sub	eax, CommandBuffer
  5714 00007AFF A2[1FDE0000]        <1> 	mov	byte [CmdArgStart], al
  5715                              <1> loc_run_parse_path_name:
  5716 00007B04 5E                  <1> 	pop	esi ; *
  5717 00007B05 BF[62E70000]        <1> 	mov	edi, FindFile_Drv
  5718 00007B0A E8DC090000          <1> 	call	parse_path_name
  5719 00007B0F 0F82CAE2FFFF        <1> 	jc	loc_cmd_failed
  5720                              <1> 
  5721                              <1> loc_run_check_filename_exists:
  5722 00007B15 BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  5723 00007B1A 803E20              <1> 	cmp	byte [esi], 20h
  5724 00007B1D 0F86BCE2FFFF        <1> 	jna	loc_cmd_failed
  5725                              <1> 
  5726                              <1> loc_run_check_exe_filename_ext:
  5727 00007B23 E897020000          <1> 	call	check_prg_filename_ext
  5728 00007B28 0F82B1E2FFFF        <1> 	jc	loc_cmd_failed
  5729                              <1> 	
  5730                              <1> loc_run_check_exe_filename_ext_ok:
  5731 00007B2E 66A3[6AEA0000]      <1> 	mov	word [EXE_ID], ax
  5732                              <1> 
  5733                              <1> loc_run_drv:
  5734 00007B34 C605[69EA0000]00    <1> 	mov	byte [Run_Manual_Path], 0
  5735 00007B3B A1[B8DD0000]        <1> 	mov	eax, [Current_Dir_FCluster]
  5736 00007B40 A3[64EA0000]        <1>         mov     [Run_CDirFC], eax
  5737                              <1> 	;
  5738 00007B45 8A35[BEDD0000]      <1> 	mov	dh, [Current_Drv]
  5739 00007B4B 8835[1EE60000]      <1> 	mov	[RUN_CDRV], dh
  5740                              <1> 
  5741 00007B51 8A15[62E70000]      <1> 	mov	dl, [FindFile_Drv]
  5742 00007B57 38F2                <1> 	cmp	dl, dh
  5743 00007B59 7412                <1> 	je	short loc_run_change_directory
  5744                              <1>                
  5745 00007B5B 8005[69EA0000]02    <1> 	add	byte [Run_Manual_Path], 2
  5746                              <1> 
  5747 00007B62 E8DED3FFFF          <1> 	call	change_current_drive
  5748 00007B67 0F829DE2FFFF        <1> 	jc	loc_run_cmd_failed
  5749                              <1> 
  5750                              <1> loc_run_change_directory:
  5751 00007B6D 803D[63E70000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  5752 00007B74 7623                <1> 	jna	short loc_run_find_executable_file
  5753                              <1> 
  5754 00007B76 FE05[69EA0000]      <1> 	inc	byte [Run_Manual_Path]
  5755                              <1>      
  5756 00007B7C FE05[29C80000]      <1> 	inc	byte [Restore_CDIR]
  5757                              <1> 
  5758 00007B82 BE[63E70000]        <1> 	mov	esi, FindFile_Directory
  5759 00007B87 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  5760 00007B89 E849030000          <1> 	call	change_current_directory
  5761 00007B8E 0F8276E2FFFF        <1> 	jc	loc_run_cmd_failed
  5762                              <1> 
  5763                              <1> loc_run_change_prompt_dir_string:
  5764 00007B94 E85E020000          <1> 	call	change_prompt_dir_string
  5765                              <1> 
  5766                              <1> loc_run_find_executable_file:
  5767 00007B99 66C705[68EA0000]00- <1> 	mov	word [Run_Auto_Path], 0
  5767 00007BA1 00                  <1>
  5768                              <1> 
  5769                              <1> loc_run_find_executable_file_next:
  5770 00007BA2 BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  5771                              <1> loc_run_find_program_file_next:
  5772 00007BA7 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  5773 00007BAB 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 00007BB0 0F835C010000        <1> 	jnc	loc_load_and_run_file
  5778                              <1> 	 
  5779 00007BB6 3C02                <1> 	cmp	al, 2 ; file not found
  5780 00007BB8 0F854CE2FFFF        <1> 	jne	loc_run_cmd_failed
  5781                              <1> 
  5782 00007BBE 66A1[6AEA0000]      <1> 	mov	ax, word [EXE_ID]
  5783 00007BC4 80FC2E              <1> 	cmp	ah, '.' ; File name has extension sign
  5784 00007BC7 7424                <1> 	je	short loc_run_check_auto_path
  5785                              <1> 
  5786 00007BC9 08C0                <1> 	or	al, al
  5787 00007BCB 7520                <1> 	jnz	short loc_run_check_auto_path
  5788                              <1> 
  5789 00007BCD 80FC08              <1> 	cmp	ah, 8 ; count of file name chars
  5790 00007BD0 771B                <1> 	ja	short loc_run_check_auto_path
  5791                              <1> 
  5792                              <1> loc_run_change_file_ext_to_prg:
  5793 00007BD2 0FB6DC              <1> 	movzx	ebx, ah ; count of file name chars
  5794 00007BD5 BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  5795 00007BDA 01F3                <1> 	add	ebx, esi	
  5796                              <1> 	; 07/05/2016
  5797 00007BDC C7032E505247        <1> 	mov	dword [ebx],  '.PRG'
  5798 00007BE2 66C705[6AEA0000]50- <1> 	mov	word [EXE_ID], 'P.'
  5798 00007BEA 2E                  <1>
  5799 00007BEB 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 00007BED A0[69EA0000]        <1> 	mov	al, [Run_Manual_Path]
  5810 00007BF2 08C0                <1> 	or	al, al
  5811 00007BF4 0F85E5E1FFFF        <1> 	jnz	loc_cmd_failed
  5812                              <1> 
  5813                              <1> loc_run_check_auto_path_again:
  5814 00007BFA 66833D[68EA0000]FF  <1> 	cmp	word [Run_Auto_Path], 0FFFFh		 
  5815                              <1> 		; 0FFFFh = Not a valid run path (in ENV block) 
  5816 00007C02 0F83D7E1FFFF        <1> 	jnb	loc_cmd_failed
  5817                              <1> 	; xor	al, al 
  5818 00007C08 BE[F5C80000]        <1> 	mov	esi, Cmd_Path ; 'PATH'
  5819 00007C0D BF[BEDE0000]        <1> 	mov	edi, TextBuffer
  5820 00007C12 E857F9FFFF          <1> 	call	get_environment_string
  5821 00007C17 730E                <1> 	jnc	short loc_run_chk_filename_ext_again
  5822 00007C19 66C705[68EA0000]FF- <1> 	mov	word [Run_Auto_Path], 0FFFFh ; invalid
  5822 00007C21 FF                  <1>
  5823 00007C22 E9B8E1FFFF          <1> 	jmp	loc_cmd_failed
  5824                              <1> 
  5825                              <1> loc_run_chk_filename_ext_again:
  5826 00007C27 89C1                <1> 	mov	ecx, eax ; string length (with zero tail)
  5827 00007C29 49                  <1> 	dec	ecx ; without zero tail
  5828 00007C2A 66A1[6AEA0000]      <1> 	mov	ax, [EXE_ID]
  5829 00007C30 80FC2E              <1> 	cmp	ah, '.'
  5830 00007C33 740E                <1> 	je	short loc_run_chk_auto_path_pos
  5831                              <1> 	 
  5832                              <1> loc_run_change_file_ext_to_noext_again:
  5833 00007C35 0FB6DC              <1> 	movzx	ebx, ah
  5834 00007C38 BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  5835 00007C3D 01F3                <1> 	add 	ebx, esi
  5836 00007C3F 29C0                <1> 	sub	eax, eax
  5837 00007C41 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 00007C43 66A1[68EA0000]      <1> 	mov	ax, [Run_Auto_Path]
  5842 00007C49 39C8                <1> 	cmp	eax, ecx ; ecx = string length (except zero tail)
  5843 00007C4B 0F838EE1FFFF        <1> 	jnb	loc_cmd_failed
  5844                              <1> 	;or	eax, eax
  5845 00007C51 6609C0              <1> 	or	ax, ax
  5846 00007C54 7502                <1> 	jnz	short loc_run_auto_path_pos_move
  5847 00007C56 B005                <1> 	mov	al, 5
  5848                              <1> 
  5849                              <1> loc_run_auto_path_pos_move:
  5850 00007C58 89FE                <1> 	mov	esi, edi ; offset TextBuffer
  5851 00007C5A 01C6                <1> 	add	esi, eax
  5852                              <1> 
  5853                              <1> loc_run_auto_path_pos_space_loop:
  5854 00007C5C AC                  <1> 	lodsb
  5855 00007C5D 3C20                <1> 	cmp	al, 20h 
  5856 00007C5F 74FB                <1> 	je	short loc_run_auto_path_pos_space_loop
  5857 00007C61 0F8278E1FFFF        <1> 	jb	loc_cmd_failed 
  5858 00007C67 AA                  <1> 	stosb
  5859                              <1> loc_run_auto_path_pos_move_next: 
  5860 00007C68 AC                  <1> 	lodsb
  5861 00007C69 3C3B                <1> 	cmp	al, ';'
  5862 00007C6B 7414                <1> 	je	short loc_run_auto_path_pos_move_last_byte
  5863 00007C6D 3C20                <1> 	cmp	al, 20h
  5864 00007C6F 74F7                <1> 	je	short loc_run_auto_path_pos_move_next
  5865 00007C71 7203                <1> 	jb	short loc_byte_ptr_end_of_path
  5866 00007C73 AA                  <1> 	stosb
  5867 00007C74 EBF2                <1> 	jmp	short loc_run_auto_path_pos_move_next 
  5868                              <1> 
  5869                              <1> loc_byte_ptr_end_of_path: 
  5870 00007C76 66C705[68EA0000]FF- <1> 	mov	word [Run_Auto_Path], 0FFFFh ; end of path
  5870 00007C7E FF                  <1>
  5871 00007C7F EB0D                <1> 	jmp	short loc_run_auto_path_move_ok 
  5872                              <1> 
  5873                              <1> loc_run_auto_path_pos_move_last_byte:
  5874 00007C81 89F0                <1> 	mov	eax, esi
  5875 00007C83 2D[BEDE0000]        <1> 	sub	eax, TextBuffer 
  5876 00007C88 66A3[68EA0000]      <1> 	mov	[Run_Auto_Path], ax ; next path position
  5877                              <1> 
  5878                              <1> loc_run_auto_path_move_ok:
  5879 00007C8E 4F                  <1> 	dec	edi
  5880 00007C8F B02F                <1> 	mov	al, '/'
  5881 00007C91 3807                <1> 	cmp	[edi], al
  5882 00007C93 7403                <1> 	je	short loc_run_auto_path_move_file_name
  5883 00007C95 47                  <1> 	inc	edi
  5884 00007C96 8807                <1> 	mov	[edi], al
  5885                              <1> 
  5886                              <1> loc_run_auto_path_move_file_name:
  5887 00007C98 47                  <1> 	inc	edi   
  5888 00007C99 BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  5889                              <1> 
  5890                              <1> loc_run_auto_path_move_fn_loop:
  5891 00007C9E AC                  <1> 	lodsb
  5892 00007C9F AA                  <1> 	stosb
  5893 00007CA0 08C0                <1> 	or	al, al
  5894 00007CA2 75FA                <1> 	jnz	short loc_run_auto_path_move_fn_loop
  5895                              <1> 
  5896 00007CA4 BE[BEDE0000]        <1> 	mov	esi, TextBuffer
  5897 00007CA9 BF[62E70000]        <1> 	mov	edi, FindFile_Drv
  5898 00007CAE E838080000          <1> 	call	parse_path_name
  5899 00007CB3 0F8226E1FFFF        <1> 	jc	loc_cmd_failed
  5900                              <1> 
  5901 00007CB9 8A35[BEDD0000]      <1> 	mov	dh, [Current_Drv]
  5902 00007CBF 8A15[62E70000]      <1> 	mov	dl, [FindFile_Drv]
  5903 00007CC5 38F2                <1> 	cmp	dl, dh
  5904 00007CC7 740B                <1> 	je	short loc_run_change_directory_again
  5905                              <1>                
  5906 00007CC9 E877D2FFFF          <1> 	call	change_current_drive
  5907 00007CCE 0F8236E1FFFF        <1> 	jc	loc_run_cmd_failed
  5908                              <1> 
  5909                              <1> loc_run_change_directory_again:
  5910 00007CD4 803D[63E70000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  5911 00007CDB 761D                <1> 	jna	short loc_load_executable_cdir_chk_again
  5912                              <1> 
  5913 00007CDD FE05[29C80000]      <1> 	inc	byte [Restore_CDIR]
  5914 00007CE3 BE[63E70000]        <1> 	mov	esi, FindFile_Directory
  5915 00007CE8 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  5916 00007CEA E8E8010000          <1> 	call	change_current_directory
  5917 00007CEF 0F8215E1FFFF        <1> 	jc	loc_run_cmd_failed
  5918                              <1> 
  5919                              <1> loc_run_chg_prompt_dir_str_again:
  5920 00007CF5 E8FD000000          <1> 	call	change_prompt_dir_string
  5921                              <1> 
  5922                              <1> loc_load_executable_cdir_chk_again:
  5923 00007CFA A1[B8DD0000]        <1> 	mov	eax, [Current_Dir_FCluster]
  5924 00007CFF 3B05[64EA0000]      <1> 	cmp	eax, [Run_CDirFC]
  5925 00007D05 0F8597FEFFFF        <1> 	jne	loc_run_find_executable_file_next
  5926 00007D0B 30C0                <1> 	xor	al, al ; 0
  5927 00007D0D E9E8FEFFFF          <1> 	jmp	loc_run_check_auto_path_again
  5928                              <1> 
  5929                              <1> loc_load_and_run_file:
  5930                              <1> 	; 23/04/2016
  5931 00007D12 BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  5932 00007D17 BF[BEDE0000]        <1> 	mov	edi, TextBuffer
  5933                              <1> 
  5934                              <1>  	; 24/04/2016
  5935 00007D1C 31D2                <1> 	xor	edx, edx
  5936 00007D1E 668915[56F20000]    <1> 	mov	word [argc], dx ; 0
  5937 00007D25 8915[00F20000]      <1> 	mov	dword [u.nread], edx ; 0
  5938                              <1> 
  5939                              <1> loc_load_and_run_file_1:
  5940 00007D2B AC                  <1> 	lodsb	
  5941 00007D2C AA                  <1> 	stosb
  5942 00007D2D FF05[00F20000]      <1> 	inc	dword [u.nread]
  5943 00007D33 20C0                <1> 	and	al, al
  5944 00007D35 75F4                <1> 	jnz 	short loc_load_and_run_file_1
  5945                              <1> 	
  5946 00007D37 A0[1FDE0000]        <1> 	mov	al, [CmdArgStart]
  5947 00007D3C 20C0                <1> 	and	al, al
  5948 00007D3E 7445                <1> 	jz	short loc_load_and_run_file_7
  5949                              <1> 
  5950 00007D40 0FB6F0              <1> 	movzx	esi, al ; 11/05/2016
  5951 00007D43 B950000000          <1> 	mov	ecx, 80
  5952 00007D48 29F1                <1> 	sub	ecx, esi
  5953 00007D4A 81C6[6EDE0000]      <1> 	add	esi, CommandBuffer
  5954                              <1> 
  5955 00007D50 66FF05[56F20000]    <1> 	inc	word [argc] ; 11/05/2016
  5956                              <1> 
  5957                              <1> loc_load_and_run_file_2:
  5958 00007D57 AC                  <1> 	lodsb
  5959 00007D58 3C20                <1> 	cmp	al, 20h
  5960 00007D5A 7717                <1> 	ja	short loc_load_and_run_file_5	
  5961 00007D5C 721E                <1> 	jb	short loc_load_and_run_file_6
  5962                              <1> 
  5963                              <1> loc_load_and_run_file_3:
  5964 00007D5E 803E20              <1> 	cmp	byte [esi], 20h
  5965 00007D61 7707                <1> 	ja	short loc_load_and_run_file_4
  5966 00007D63 7217                <1> 	jb	short loc_load_and_run_file_6
  5967 00007D65 46                  <1> 	inc	esi
  5968 00007D66 E2F6                <1> 	loop	loc_load_and_run_file_3
  5969 00007D68 EB12                <1> 	jmp	short loc_load_and_run_file_6
  5970                              <1> 
  5971                              <1> loc_load_and_run_file_4:
  5972 00007D6A 28C0                <1> 	sub	al, al ; 0
  5973 00007D6C 66FF05[56F20000]    <1> 	inc	word [argc]
  5974                              <1> loc_load_and_run_file_5:
  5975 00007D73 AA                  <1> 	stosb
  5976 00007D74 FF05[00F20000]      <1> 	inc	dword [u.nread]
  5977 00007D7A E2DB                <1> 	loop	loc_load_and_run_file_2
  5978                              <1> 			
  5979                              <1> loc_load_and_run_file_6:
  5980 00007D7C 30C0                <1> 	xor	al, al ; 0
  5981 00007D7E AA                  <1> 	stosb
  5982 00007D7F FF05[00F20000]      <1> 	inc	dword [u.nread]
  5983                              <1> loc_load_and_run_file_7:
  5984 00007D85 8807                <1> 	mov 	[edi], al ; 0
  5985 00007D87 66FF05[56F20000]    <1> 	inc	word [argc] ; 24/04/2016
  5986 00007D8E FF05[00F20000]      <1> 	inc	dword [u.nread] ; 24/04/2016
  5987 00007D94 BE[BEDE0000]        <1> 	mov	esi, TextBuffer
  5988 00007D99 8B15[D0E70000]      <1> 	mov	edx, [FindFile_DirEntry+DirEntry_FileSize]
  5989 00007D9F 66A1[C8E70000]      <1> 	mov	ax, [FindFile_DirEntry+DirEntry_FstClusHI]
  5990 00007DA5 66C1E010            <1> 	shl	ax, 16
  5991 00007DA9 66A1[CEE70000]      <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 00007DAF E8F63D0000          <1> 	call	load_and_run_file ; trdosk6.s
  5998 00007DB4 0F8250E0FFFF        <1>         jc      loc_run_cmd_failed
  5999                              <1> loc_load_and_run_file_8: ; 06/05/2016
  6000 00007DBA 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 00007DBF 30E4                <1> 	xor	ah, ah
  6020                              <1> loc_run_check_filename_ext:	
  6021 00007DC1 AC                  <1> 	lodsb
  6022 00007DC2 3C21                <1> 	cmp	al, 21h
  6023 00007DC4 7229                <1> 	jb	short loc_check_exe_fn_retn 
  6024 00007DC6 FEC4                <1> 	inc	ah
  6025 00007DC8 3C2E                <1> 	cmp	al, '.'
  6026 00007DCA 75F5                <1> 	jne	short loc_run_check_filename_ext	
  6027                              <1> 		 
  6028                              <1> loc_run_check_filename_ext_dot:
  6029 00007DCC 80FC02              <1> 	cmp	ah, 2 ; .??? is not valid
  6030 00007DCF 88C4                <1> 	mov	ah, al ; '.' 
  6031 00007DD1 7219                <1> 	jb	short loc_check_prg_fn_retn
  6032                              <1> 
  6033                              <1> loc_run_check_filename_ext_dot_ok:
  6034 00007DD3 AC                  <1> 	lodsb
  6035 00007DD4 24DF                <1> 	and	al, 0DFh 
  6036                              <1> 
  6037                              <1> loc_run_check_filename_ext_prg:
  6038 00007DD6 3C50                <1> 	cmp	al, 'P'
  6039 00007DD8 7212                <1> 	jb	short loc_check_prg_fn_retn
  6040 00007DDA 7711                <1> 	ja	short loc_check_prg_fn_stc
  6041 00007DDC AC                  <1> 	lodsb
  6042 00007DDD 24DF                <1> 	and	al, 0DFh 
  6043 00007DDF 3C52                <1> 	cmp	al, 'R'
  6044 00007DE1 750A                <1> 	jne	short loc_check_prg_fn_stc
  6045 00007DE3 AC                  <1> 	lodsb
  6046 00007DE4 24DF                <1> 	and	al, 0DFh
  6047 00007DE6 3C47                <1> 	cmp	al, 'G'
  6048 00007DE8 7503                <1> 	jne	short loc_check_prg_fn_stc
  6049                              <1> 
  6050 00007DEA B050                <1> 	mov	al, 'P'
  6051                              <1> loc_check_prg_fn_retn:
  6052 00007DEC C3                  <1> 	retn
  6053                              <1> 
  6054                              <1> loc_check_prg_fn_stc:
  6055 00007DED F9                  <1> 	stc
  6056 00007DEE C3                  <1> 	retn
  6057                              <1>  
  6058                              <1> loc_check_exe_fn_retn:
  6059 00007DEF 28C0                <1> 	sub	al, al ; 0
  6060 00007DF1 C3                  <1> 	retn
  6061                              <1>               
  6062                              <1> find_and_list_files:
  6063 00007DF2 C3                  <1> 	retn
  6064                              <1> set_exec_arguments:
  6065 00007DF3 C3                  <1> 	retn
  6066                              <1> delete_fs_directory:
  6067 00007DF4 31C0                <1> 	xor eax, eax
  6068 00007DF6 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 00007DF7 BF[C2DD0000]        <1> 	mov	edi, Current_Directory
    27 00007DFC 8A25[BCDD0000]      <1> 	mov	ah, [Current_Dir_Level]
    28 00007E02 BE[1FE60000]        <1> 	mov	esi, PATH_Array
    29 00007E07 E807000000          <1> 	call	set_current_directory_string
    30 00007E0C 880D[1DDE0000]      <1> 	mov	[Current_Dir_StrLen], cl
    31                              <1> 
    32 00007E12 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 00007E13 57                  <1> 	push    edi
    47 00007E14 80FC00              <1> 	cmp     ah, 0
    48 00007E17 7652                <1> 	jna	short pass_write_path
    49 00007E19 83C610              <1> 	add	esi, 16
    50 00007E1C 89F3                <1> 	mov	ebx, esi
    51                              <1> loc_write_path:
    52 00007E1E B908000000          <1> 	mov	ecx, 8
    53                              <1> path_write_dirname1:
    54 00007E23 AC                  <1> 	lodsb
    55 00007E24 3C20                <1> 	cmp	al, 20h
    56 00007E26 7612                <1> 	jna	short pass_write_dirname1
    57 00007E28 AA                  <1> 	stosb
    58 00007E29 81FF[1CDE0000]      <1> 	cmp	edi, End_Of_Current_Dir_Str
    59 00007E2F 733A                <1> 	jnb	short pass_write_path
    60 00007E31 E2F0                <1> 	loop	path_write_dirname1
    61 00007E33 803E20              <1> 	cmp	byte [esi], 20h
    62 00007E36 7624                <1> 	jna	short pass_write_dirname2
    63 00007E38 EB0A                <1> 	jmp     short loc_put_dot_cont_ext
    64                              <1> pass_write_dirname1:
    65 00007E3A 89DE                <1> 	mov	esi, ebx
    66 00007E3C 83C608              <1> 	add	esi, 8
    67 00007E3F 803E20              <1> 	cmp	byte [esi], 20h
    68 00007E42 7618                <1> 	jna	short pass_write_dirname2
    69                              <1> loc_put_dot_cont_ext:
    70 00007E44 C6072E              <1> 	mov	byte [edi], "."
    71                              <1> 	;mov	ecx, 3
    72 00007E47 B103                <1> 	mov	cl, 3
    73                              <1> loc_check_dir_name_ext:
    74 00007E49 AC                  <1> 	lodsb
    75 00007E4A 47                  <1> 	inc	edi
    76 00007E4B 3C20                <1> 	cmp	al, 20h
    77 00007E4D 760D                <1> 	jna	short pass_write_dirname2
    78 00007E4F 8807                <1> 	mov	[edi], al
    79 00007E51 81FF[1CDE0000]      <1> 	cmp	edi, End_Of_Current_Dir_Str
    80 00007E57 7312                <1> 	jnb	short pass_write_path
    81 00007E59 E2EE                <1> 	loop    loc_check_dir_name_ext
    82 00007E5B 47                  <1> 	inc	edi
    83                              <1> pass_write_dirname2:
    84 00007E5C FECC                <1> 	dec	ah
    85 00007E5E 740B                <1> 	jz      short pass_write_path
    86 00007E60 83C310              <1> 	add	ebx, 16
    87 00007E63 89DE                <1> 	mov	esi, ebx
    88 00007E65 C6072F              <1> 	mov	byte [edi],"/"
    89 00007E68 47                  <1> 	inc	edi
    90 00007E69 EBB3                <1> 	jmp	short loc_write_path
    91                              <1> pass_write_path:
    92 00007E6B C60700              <1> 	mov	byte [edi], 0
    93 00007E6E 47                  <1> 	inc	edi
    94 00007E6F 89F9                <1> 	mov	ecx, edi
    95 00007E71 5F                  <1> 	pop	edi
    96 00007E72 29F9                <1> 	sub	ecx, edi
    97                              <1> 	; ECX = Current Directory String Length
    98 00007E74 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 00007E75 80FA00              <1> 	cmp	dl, 0
   122 00007E78 7708                <1> 	ja	short loc_get_current_drive_1
   123 00007E7A 8A15[BEDD0000]      <1> 	mov	dl, [Current_Drv]
   124 00007E80 EB17                <1> 	jmp	short loc_get_current_drive_2
   125                              <1> loc_get_current_drive_1:
   126 00007E82 FECA                <1> 	dec 	dl
   127 00007E84 3A15[28C80000]      <1> 	cmp	dl, [Last_DOS_DiskNo]
   128 00007E8A 760D                <1> 	jna	short loc_get_current_drive_2
   129 00007E8C B80F000000          <1> 	mov	eax, 0Fh ; Invalid drive
   130 00007E91 F5                  <1> 	cmc 	; stc
   131 00007E92 C3                  <1> 	retn
   132                              <1> 
   133                              <1> loc_get_current_drive_not_ready_retn:
   134 00007E93 5E                  <1> 	pop	esi
   135                              <1> 	;mov	eax, 15h
   136 00007E94 66B81500            <1> 	mov	ax, 15h ; Drive not ready
   137 00007E98 C3                  <1> 	retn  
   138                              <1>  
   139                              <1> loc_get_current_drive_2:
   140 00007E99 31C0                <1> 	xor	eax, eax
   141 00007E9B 88D4                <1> 	mov	ah, dl
   142 00007E9D 56                  <1> 	push	esi
   143 00007E9E BE00010900          <1> 	mov	esi, Logical_DOSDisks
   144 00007EA3 01C6                <1> 	add	esi, eax
   145 00007EA5 8A06                <1> 	mov	al, [esi+LD_Name] 
   146 00007EA7 3C41                <1> 	cmp	al, 'A'
   147 00007EA9 72E8                <1> 	jb	short loc_get_current_drive_not_ready_retn
   148                              <1> 
   149 00007EAB 8A667F              <1> 	mov	ah, [esi+LD_CDirLevel]
   150 00007EAE 08E4                <1> 	or	ah, ah
   151 00007EB0 7506                <1> 	jnz	short loc_get_current_drive_3
   152                              <1> 
   153                              <1> 	;xor	ah, ah ; mov ah, 0
   154 00007EB2 8826                <1> 	mov	[esi], ah
   155 00007EB4 31C9                <1> 	xor	ecx, ecx
   156 00007EB6 EB1C                <1> 	jmp	short loc_get_current_drive_4
   157                              <1> 
   158                              <1> loc_get_current_drive_3:
   159 00007EB8 BF[1FE60000]        <1>         mov     edi, PATH_Array
   160 00007EBD 57                  <1> 	push	edi
   161 00007EBE 81C680000000        <1> 	add	esi, LD_CurrentDirectory
   162 00007EC4 B920000000          <1> 	mov	ecx, 32
   163 00007EC9 F3A5                <1> 	rep	movsd
   164 00007ECB 5E                  <1> 	pop	esi ; Path Array Address
   165 00007ECC 5F                  <1> 	pop	edi ; pushed esi (current dir buffer offset) 
   166                              <1> 	;
   167 00007ECD E841FFFFFF          <1> 	call	set_current_directory_string
   168 00007ED2 89FE                <1> 	mov	esi, edi
   169                              <1> 
   170                              <1> loc_get_current_drive_4:
   171 00007ED4 30C0                <1> 	xor	al, al
   172 00007ED6 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 00007ED7 8825[ADE60000]      <1> 	mov	[CD_COMMAND], ah
   197 00007EDD 803E2F              <1> 	cmp	byte [esi], '/'
   198 00007EE0 7505                <1> 	jne	short loc_ccd_cdir_level
   199 00007EE2 46                  <1> 	inc	esi
   200 00007EE3 30C0                <1> 	xor	al, al
   201 00007EE5 EB05                <1> 	jmp	short loc_ccd_parse_path_name
   202                              <1> loc_ccd_cdir_level:
   203 00007EE7 A0[BCDD0000]        <1> 	mov	al, [Current_Dir_Level]
   204                              <1> loc_ccd_parse_path_name:
   205 00007EEC 88C4                <1> 	mov	ah, al
   206 00007EEE BF[1FE60000]        <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 00007EF3 0FB6C8              <1> 	movzx	ecx, al
   218 00007EF6 FEC1                <1> 	inc	cl
   219 00007EF8 C0E104              <1> 	shl	cl, 4
   220 00007EFB 01CF                <1> 	add	edi, ecx
   221 00007EFD B107                <1> 	mov	cl, 7
   222 00007EFF 28C1                <1> 	sub	cl, al
   223 00007F01 C0E102              <1> 	shl	cl, 2
   224 00007F04 89C3                <1> 	mov	ebx, eax
   225 00007F06 31C0                <1> 	xor	eax, eax ; 0
   226 00007F08 F3AB                <1> 	rep	stosd
   227 00007F0A 89D8                <1> 	mov	eax, ebx
   228                              <1> 
   229 00007F0C BF[1FE60000]        <1> 	mov	edi, PATH_Array
   230                              <1> 
   231 00007F11 803E20              <1> 	cmp	byte [esi], 20h
   232 00007F14 F5                  <1> 	cmc
   233 00007F15 7305                <1> 	jnc	short pass_ccd_parse_dir_name
   234                              <1> 
   235                              <1> 		; ESI = Path name
   236                              <1> 		; AL = CCD_Level
   237 00007F17 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 00007F1C 9C                  <1> 	pushf
   244                              <1> 
   245                              <1> 	;mov	[CCD_Level], al
   246                              <1>         ;mov	[Last_Dir_Level], ah
   247 00007F1D 66A3[A3E60000]      <1> 	mov	[CCD_Level], ax
   248                              <1> 
   249 00007F23 31DB                <1> 	xor	ebx, ebx
   250 00007F25 8A3D[BEDD0000]      <1> 	mov	bh, [Current_Drv]
   251 00007F2B BE00010900          <1> 	mov	esi, Logical_DOSDisks
   252 00007F30 01DE                <1> 	add	esi, ebx
   253                              <1> 
   254 00007F32 9D                  <1> 	popf 
   255 00007F33 720A                <1> 	jc	short loc_ccd_bad_path_name_retn
   256                              <1> 
   257 00007F35 8935[9FE60000]      <1> 	mov	[CCD_DriveDT], esi
   258                              <1> 
   259 00007F3B 3C07                <1> 	cmp	al, 7
   260 00007F3D 7209                <1> 	jb	short loc_ccd_load_child_dir
   261                              <1> 
   262                              <1> loc_ccd_bad_path_name_retn:
   263 00007F3F 87F7                <1> 	xchg	esi, edi
   264                              <1> 	; DOS Error Code 
   265 00007F41 B818000000          <1> 	mov	eax, 18h ; Bad request structure length 
   266 00007F46 F9                  <1> 	stc
   267                              <1> loc_ccd_retn_p:
   268 00007F47 C3                  <1> 	retn
   269                              <1> 
   270                              <1> loc_ccd_load_child_dir:
   271                              <1> 	; AL = CCD_Level
   272 00007F48 08C0                <1> 	or	al, al
   273 00007F4A 7468                <1> 	jz	short loc_ccd_load_root_dir
   274                              <1> 
   275 00007F4C 6689C1              <1> 	mov	cx, ax
   276 00007F4F C0E004              <1> 	shl	al, 4
   277 00007F52 0FB6F0              <1> 	movzx	esi, al
   278 00007F55 01FE                <1>      	add	esi, edi  ; offset PATH_Array
   279                              <1> 
   280 00007F57 8B460C              <1> 	mov	eax, [esi+12]
   281 00007F5A 38E9                <1> 	cmp	cl, ch
   282 00007F5C 0F84FA000000        <1>         je      loc_ccd_load_sub_directory
   283 00007F62 A3[B8DD0000]        <1> 	mov	[Current_Dir_FCluster], eax
   284                              <1> 
   285                              <1> loc_ccd_load_child_dir_next:
   286 00007F67 83C610              <1> 	add	esi, 16 ; DOS DirEntry Format FileName Address
   287                              <1> 
   288                              <1>  	; Directory attribute : 10h
   289 00007F6A B010                <1> 	mov	al, 00010000b ; 10h (Attrib AND mask)
   290                              <1> 	;mov	ah, 11001000b ; C8h
   291                              <1> 	; Volume name attribute: 8h
   292 00007F6C B408                <1> 	mov	ah, 00001000b ; 08h (Attrib NAND, AND --> zero mask)
   293                              <1> 
   294 00007F6E 6631C9              <1> 	xor	cx, cx  
   295 00007F71 E8B5010000          <1> 	call	locate_current_dir_file
   296 00007F76 7353                <1> 	jnc	short loc_ccd_set_dir_cluster_ptr
   297                              <1> 
   298                              <1> 	 ; 19/02/2016
   299                              <1> 	;mov	edi, [CCD_DriveDT]
   300 00007F78 8A25[A3E60000]      <1> 	mov	ah, [CCD_Level]
   301 00007F7E 803D[ADE60000]CD    <1> 	cmp	byte [CD_COMMAND], 0CDh ;'CD' command or another
   302 00007F85 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 00007F87 88E1                <1> 	mov	cl, ah
   308 00007F89 50                  <1> 	push	eax
   309 00007F8A E8E3000000          <1> 	call	loc_ccd_save_current_dir
   310 00007F8F 58                  <1> 	pop	eax
   311                              <1> loc_ccd_load_child_dir_err:            
   312 00007F90 3C03                <1> 	cmp	al, 3	; AL = 2 => File not found error
   313 00007F92 7202                <1> 	jb	short loc_ccd_path_not_found_retn
   314 00007F94 F9                  <1> 	stc
   315 00007F95 C3                  <1> 	retn
   316                              <1> 
   317                              <1> loc_ccd_path_not_found_retn:
   318 00007F96 B003                <1> 	mov	al, 3	; Path not found
   319 00007F98 C3                  <1> 	retn
   320                              <1> 
   321                              <1> loc_ccd_load_FAT_root_dir:
   322 00007F99 803D[BDDD0000]02    <1> 	cmp	byte [Current_FATType], 2
   323 00007FA0 776B                <1> 	ja	short loc_ccd_load_FAT32_root_dir
   324                              <1> 
   325                              <1> 	;mov	esi, [CCD_DriveDT]
   326                              <1> 	;push	esi
   327 00007FA2 E8961D0000          <1> 	call	load_FAT_root_directory
   328                              <1> 	;pop	edi ; Dos Drv Description Table
   329                              <1> 
   330 00007FA7 89F7                <1> 	mov	edi, esi
   331 00007FA9 BE[1FE60000]        <1> 	mov	esi, PATH_Array
   332 00007FAE 7297                <1> 	jc	short loc_ccd_retn_p
   333                              <1> 
   334 00007FB0 31C0                <1> 	xor	eax, eax
   335 00007FB2 EB78                <1>         jmp	short loc_ccd_set_cdfc
   336                              <1> 
   337                              <1> loc_ccd_load_root_dir:
   338 00007FB4 803D[BDDD0000]01    <1> 	cmp	byte [Current_FATType], 1
   339 00007FBB 73DC                <1> 	jnb	short loc_ccd_load_FAT_root_dir
   340                              <1> 
   341                              <1> loc_ccd_load_FS_root_dir:
   342 00007FBD E8421E0000          <1> 	call	load_FS_root_directory
   343 00007FC2 EB5C                <1> 	jmp	short pass_ccd_load_FAT_sub_directory
   344                              <1> 
   345                              <1> loc_ccd_load_FS_sub_directory_next:
   346 00007FC4 E83C1E0000          <1> 	call	load_FS_sub_directory
   347 00007FC9 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 00007FCB 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
   352 00007FCF C1E010              <1> 	shl	eax, 16
   353 00007FD2 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
   354                              <1> 
   355 00007FD6 8B35[9FE60000]      <1> 	mov	esi, [CCD_DriveDT]
   356 00007FDC 803D[BDDD0000]01    <1> 	cmp	byte [Current_FATType], 1
   357 00007FE3 72DF                <1> 	jb	short loc_ccd_load_FS_sub_directory_next
   358                              <1> 	;push	esi
   359 00007FE5 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 00007FEA BE[1FE60000]        <1> 	mov	esi, PATH_Array
   365 00007FEF 7264                <1> 	jc	short loc_ccd_retn_c
   366                              <1> 
   367 00007FF1 A1[EDE50000]        <1> 	mov	eax, [DirBuff_Cluster]
   368                              <1> 
   369 00007FF6 FE05[A3E60000]      <1> 	inc	byte [CCD_Level]
   370 00007FFC 0FB61D[A3E60000]    <1> 	movzx	ebx, byte [CCD_Level]
   371 00008003 C0E304              <1> 	shl	bl, 4 ; * 16 (<= 128)   
   372 00008006 01DE                <1> 	add	esi, ebx ; 19/02/2016
   373 00008008 89460C              <1> 	mov	[esi+12], eax
   374 0000800B EB1F                <1> 	jmp	short loc_ccd_set_cdfc
   375                              <1> 
   376                              <1> loc_ccd_load_FAT32_root_dir:
   377 0000800D BE[1FE60000]        <1> 	mov	esi, PATH_Array
   378 00008012 8B460C              <1> 	mov	eax, [esi+12]
   379 00008015 8B35[9FE60000]      <1> 	mov	esi, [CCD_DriveDT]
   380                              <1>  
   381                              <1> loc_ccd_load_FAT_sub_directory:
   382                              <1> 	;push	esi
   383 0000801B 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 00008020 BE[1FE60000]        <1> 	mov	esi, PATH_Array
   389 00008025 722E                <1> 	jc	short loc_ccd_retn_c
   390                              <1> 
   391 00008027 A1[EDE50000]        <1> 	mov	eax, [DirBuff_Cluster]
   392                              <1> 
   393                              <1> loc_ccd_set_cdfc:
   394 0000802C 8A0D[A3E60000]      <1> 	mov	cl, [CCD_Level]
   395 00008032 880D[BCDD0000]      <1> 	mov	[Current_Dir_Level], cl
   396 00008038 A3[B8DD0000]        <1> 	mov	[Current_Dir_FCluster], eax
   397                              <1> 
   398 0000803D 8A2D[A4E60000]      <1> 	mov	ch, [Last_Dir_Level]
   399 00008043 38E9                <1> 	cmp	cl, ch 
   400 00008045 0F821CFFFFFF        <1> 	jb	loc_ccd_load_child_dir_next
   401                              <1> 	
   402 0000804B 803D[ADE60000]CD    <1> 	cmp	byte [CD_COMMAND], 0CDh ;'CD' command or another
   403 00008052 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 00008054 F8                  <1> 	clc
   409                              <1> 
   410                              <1> loc_ccd_retn_c:
   411 00008055 8B3D[9FE60000]      <1> 	mov	edi, [CCD_DriveDT]
   412 0000805B C3                  <1> 	retn
   413                              <1> 
   414                              <1> loc_ccd_load_sub_directory:
   415 0000805C 8B35[9FE60000]      <1> 	mov	esi, [CCD_DriveDT]
   416 00008062 803D[BDDD0000]01    <1> 	cmp	byte [Current_FATType], 1
   417 00008069 73B0                <1> 	jnb	short loc_ccd_load_FAT_sub_directory 
   418 0000806B E8951D0000          <1> 	call	load_FS_sub_directory
   419 00008070 EBAE                <1> 	jmp	short pass_ccd_load_FAT_sub_directory 
   420                              <1> 
   421                              <1> loc_ccd_save_current_dir:
   422 00008072 BE[1FE60000]        <1> 	mov	esi, PATH_Array ; 19/02/2016
   423 00008077 8B3D[9FE60000]      <1> 	mov	edi, [CCD_DriveDT]
   424 0000807D 57                  <1> 	push	edi
   425 0000807E 83C77F              <1>         add     edi, LD_CDirLevel
   426 00008081 880F                <1> 	mov	[edi], cl
   427 00008083 47                  <1> 	inc	edi ; LD_CurrentDirectory 
   428 00008084 56                  <1> 	push	esi
   429                              <1> 	;mov	ecx, 32  ; always < 65536 (in this procedure)
   430 00008085 66B92000            <1> 	mov	cx, 32
   431 00008089 F3A5                <1> 	rep	movsd
   432                              <1> 	; Current directory has been saved to 
   433                              <1> 	; the DOS drive description table, cdir area !
   434 0000808B 5E                  <1> 	pop	esi  ; PATH_Array
   435 0000808C 5F                  <1> 	pop	edi  ; Dos Drv Description Table
   436                              <1> 
   437 0000808D 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 0000808E 88C4                <1> 	mov	ah, al
   460 00008090 66A3[44E70000]      <1> 	mov	[PATH_CDLevel], ax
   461                              <1> repeat_ppdn_check_slash:
   462 00008096 AC                  <1> 	lodsb
   463 00008097 3C2F                <1> 	cmp	al, '/'
   464 00008099 74FB                <1> 	je	short repeat_ppdn_check_slash
   465 0000809B 3C21                <1> 	cmp	al, 21h
   466 0000809D 7219                <1> 	jb	short loc_ppdn_retn
   467 0000809F 57                  <1> 	push	edi
   468                              <1> loc_ppdn_get_dir_name:
   469 000080A0 B90C000000          <1> 	mov	ecx, 12
   470 000080A5 BF[46E70000]        <1> 	mov	edi, Dir_File_Name
   471                              <1> repeat_ppdn_get_dir_name:
   472 000080AA AA                  <1> 	stosb
   473 000080AB AC                  <1> 	lodsb
   474 000080AC 3C2F                <1> 	cmp	al, '/'
   475 000080AE 740A                <1> 	je	short loc_check_level_dot_conv_dir_name
   476 000080B0 3C20                <1> 	cmp	al, 20h
   477 000080B2 7605                <1> 	jna	short loc_ppdn_end_of_path_scan
   478 000080B4 E2F4                <1> 	loop	repeat_ppdn_get_dir_name
   479 000080B6 5F                  <1> 	pop	edi
   480 000080B7 F9                  <1> 	stc
   481                              <1> loc_ppdn_retn:
   482 000080B8 C3                  <1> 	retn
   483                              <1> 
   484                              <1> loc_ppdn_end_of_path_scan:
   485 000080B9 4E                  <1> 	dec	esi
   486                              <1> loc_check_level_dot_conv_dir_name:
   487 000080BA 31C0                <1> 	xor	eax, eax
   488 000080BC AA                  <1> 	stosb
   489 000080BD 89F3                <1> 	mov	ebx, esi
   490 000080BF BE[46E70000]        <1> 	mov	esi, Dir_File_Name
   491 000080C4 AC                  <1> 	lodsb
   492                              <1> repeat_ppdn_name_check_dot:
   493 000080C5 3C2E                <1> 	cmp	al, '.'
   494 000080C7 7509                <1> 	jne	short loc_ppdn_convert_sub_dir_name
   495                              <1> repeat_ppdn_name_dot_dot:
   496 000080C9 AC                  <1> 	lodsb
   497 000080CA 3C2E                <1> 	cmp	al, '.'
   498 000080CC 743E                <1> 	je	short loc_ppdn_dot_dot
   499 000080CE 3C21                <1> 	cmp	al, 21h
   500 000080D0 7226                <1> 	jb	short pass_ppdn_convert_sub_dir_name
   501                              <1> loc_ppdn_convert_sub_dir_name:
   502 000080D2 8A25[45E70000]      <1> 	mov	ah, [PATH_Level]
   503 000080D8 80FC07              <1> 	cmp	ah, 7
   504 000080DB 731B                <1> 	jnb	short pass_ppdn_convert_sub_dir_name
   505 000080DD FEC4                <1> 	inc	ah  
   506 000080DF 8825[45E70000]      <1> 	mov	[PATH_Level], ah
   507 000080E5 BE[46E70000]        <1> 	mov	esi, Dir_File_Name
   508                              <1> 	;mov	edi, [PATH_Array_Ptr]
   509 000080EA B010                <1> 	mov	al, 16
   510 000080EC F6E4                <1> 	mul	ah
   511 000080EE 8B3C24              <1> 	mov	edi, [esp]
   512                              <1> 	;push	edi 
   513 000080F1 01C7                <1> 	add	edi, eax
   514 000080F3 E828030000          <1> 	call	convert_file_name
   515                              <1> 	;pop	edi
   516                              <1> pass_ppdn_convert_sub_dir_name:
   517 000080F8 89DE                <1> 	mov	esi, ebx
   518                              <1> repeat_ppdn_check_last_slash:
   519 000080FA AC                  <1> 	lodsb
   520 000080FB 3C2F                <1> 	cmp	al, '/'
   521 000080FD 74FB                <1> 	je	short repeat_ppdn_check_last_slash
   522 000080FF 3C21                <1> 	cmp	al, 21h
   523 00008101 739D                <1> 	jnb	short loc_ppdn_get_dir_name
   524                              <1> end_of_parse_dir_name:
   525 00008103 5F                  <1> 	pop	edi
   526 00008104 F5                  <1> 	cmc  
   527                              <1> 	;mov	al, [PATH_CDLevel]
   528                              <1> 	;mov	ah, [PATH_Level]
   529 00008105 66A1[44E70000]      <1> 	mov	ax, [PATH_CDLevel]
   530 0000810B C3                  <1> 	retn
   531                              <1> 
   532                              <1> loc_ppdn_dot_dot:
   533 0000810C AC                  <1> 	lodsb
   534 0000810D 3C21                <1> 	cmp	al, 21h
   535 0000810F 73F2                <1> 	jnb	short end_of_parse_dir_name 
   536                              <1> loc_ppdn_dot_dot_prev_level:
   537 00008111 66A1[44E70000]      <1> 	mov	ax, [PATH_CDLevel]
   538 00008117 80EC01              <1> 	sub	ah, 1
   539 0000811A 80D400              <1> 	adc	ah, 0
   540 0000811D 38E0                <1> 	cmp	al, ah
   541 0000811F 7602                <1> 	jna	short pass_ppdn_set_al_to_ah
   542 00008121 88E0                <1> 	mov	al, ah
   543                              <1> pass_ppdn_set_al_to_ah:
   544 00008123 66A3[44E70000]      <1> 	mov	[PATH_CDLevel], ax
   545 00008129 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 0000812B 8935[A7E60000]      <1> 	mov	[CDLF_FNAddress], esi
   590 00008131 66A3[A5E60000]      <1> 	mov	[CDLF_AttributesMask], ax
   591 00008137 66890D[ABE60000]    <1> 	mov	[CDLF_DEType], cx
   592                              <1> 
   593 0000813E 31DB                <1> 	xor	ebx, ebx
   594 00008140 881D[BCE60000]      <1> 	mov	[PreviousAttr], bl ; 0  ; 13/02/2016
   595                              <1> 
   596 00008146 8A3D[BEDD0000]      <1> 	mov	bh, [Current_Drv]
   597 0000814C 381D[E8E50000]      <1> 	cmp	byte [DirBuff_ValidData], bl ; 0
   598 00008152 761D                <1> 	jna	short loc_lcdf_reload_current_dir2
   599 00008154 8A1D[E6E50000]      <1>         mov     bl, [DirBuff_DRV]
   600 0000815A 80EB41              <1> 	sub	bl, 'A'
   601 0000815D 38DF                <1> 	cmp	bh, bl
   602 0000815F 750E                <1> 	jne	short loc_lcdf_reload_current_dir1
   603 00008161 8B15[EDE50000]      <1> 	mov	edx, [DirBuff_Cluster]
   604 00008167 3B15[B8DD0000]      <1> 	cmp	edx, [Current_Dir_FCluster]
   605 0000816D 7412                <1> 	je	short loc_cdir_locatefile_search
   606                              <1> 
   607                              <1> loc_lcdf_reload_current_dir1:
   608 0000816F 30DB                <1> 	xor	bl, bl
   609                              <1> loc_lcdf_reload_current_dir2:
   610 00008171 89DE                <1> 	mov	esi, ebx
   611 00008173 81C600010900        <1>         add     esi, Logical_DOSDisks
   612 00008179 E872000000          <1> 	call	reload_current_directory 
   613 0000817E 735B                <1> 	jnc	short loc_locatefile_search_again 
   614 00008180 C3                  <1> 	retn  
   615                              <1> 
   616                              <1> loc_cdir_locatefile_search:
   617 00008181 31DB                <1> 	xor	ebx, ebx
   618 00008183 E8A5000000          <1> 	call	find_directory_entry
   619 00008188 7349                <1> 	jnc	short loc_cdir_locate_file_retn
   620                              <1> 
   621                              <1> loc_locatefile_check_stc_reason:
   622 0000818A 08ED                <1> 	or	ch, ch
   623 0000818C 7444                <1> 	jz	short loc_cdir_locate_file_stc_retn
   624                              <1> 
   625                              <1> loc_locatefile_check_next_entryblock:
   626 0000818E 8A3D[BEDD0000]      <1> 	mov	bh, [Current_Drv]
   627 00008194 28DB                <1> 	sub	bl, bl
   628 00008196 0FB7F3              <1> 	movzx	esi, bx
   629 00008199 81C600010900        <1>         add     esi, Logical_DOSDisks
   630                              <1> 
   631 0000819F 803D[BCDD0000]00    <1> 	cmp	byte [Current_Dir_Level], 0
   632 000081A6 760A                <1> 	jna	short loc_locatefile_check_FAT_type
   633                              <1>             
   634 000081A8 803D[BDDD0000]01    <1> 	cmp	byte [Current_FATType], 1
   635 000081AF 730A                <1> 	jnb	short loc_locatefile_load_subdir_cluster
   636 000081B1 C3                  <1> 	retn  
   637                              <1> 
   638                              <1> loc_locatefile_check_FAT_type:
   639 000081B2 803D[BDDD0000]03    <1> 	cmp	byte [Current_FATType], 3
   640 000081B9 7218                <1> 	jb	short loc_cdir_locate_file_retn
   641                              <1> 
   642                              <1> loc_locatefile_load_subdir_cluster:
   643 000081BB A1[EDE50000]        <1> 	mov	eax, [DirBuff_Cluster]
   644 000081C0 E81D1A0000          <1> 	call	get_next_cluster
   645 000081C5 730D                <1> 	jnc	short loc_locatefile_next_cluster
   646 000081C7 09C0                <1> 	or	eax, eax
   647 000081C9 7507                <1> 	jnz	short loc_locatefile_drive_not_ready_read_err
   648 000081CB F9                  <1> 	stc
   649                              <1> loc_locatefile_file_notfound:
   650 000081CC B802000000          <1> 	mov	eax, 2 ; File/Directory/VolName not found
   651 000081D1 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 000081D2 F5                  <1> 	cmc ;stc
   657                              <1> loc_cdir_locate_file_retn:
   658 000081D3 C3                  <1> 	retn
   659                              <1> 
   660                              <1> loc_locatefile_next_cluster:
   661 000081D4 E8EF1B0000          <1> 	call	load_FAT_sub_directory
   662                              <1> 	;jc	short loc_locatefile_drive_not_ready_read_err
   663 000081D9 72F8                <1> 	jc	short loc_cdir_locate_file_retn 
   664                              <1> 
   665                              <1> loc_locatefile_search_again:
   666 000081DB 8B35[A7E60000]      <1> 	mov	esi, [CDLF_FNAddress] 
   667 000081E1 66A1[A5E60000]      <1> 	mov	ax, [CDLF_AttributesMask]
   668 000081E7 668B0D[ABE60000]    <1> 	mov	cx, [CDLF_DEType] 
   669 000081EE 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 000081F0 A0[BDDD0000]        <1> 	mov	al, [Current_FATType]
   681 000081F5 3C02                <1> 	cmp	al, 2
   682 000081F7 7729                <1> 	ja	short loc_reload_FAT_sub_directory
   683 000081F9 8A25[BCDD0000]      <1> 	mov	ah, [Current_Dir_Level]
   684 000081FF 08C0                <1> 	or	al, al
   685 00008201 740A                <1> 	jz	short loc_reload_FS_directory
   686 00008203 08E4                <1> 	or	ah, ah
   687 00008205 751B                <1> 	jnz	short loc_reload_FAT_sub_directory
   688                              <1> loc_reload_FAT_12_16_root_directory:
   689 00008207 E8311B0000          <1> 	call	load_FAT_root_directory
   690 0000820C C3                  <1> 	retn
   691                              <1> loc_reload_FS_directory:
   692 0000820D 20E4                <1> 	and	ah, ah
   693 0000820F 7506                <1> 	jnz	short loc_reload_FS_sub_directory 
   694                              <1> loc_reload_FS_root_directory: 
   695 00008211 E8EE1B0000          <1> 	call	load_FS_root_directory
   696 00008216 C3                  <1> 	retn
   697                              <1> loc_reload_FS_sub_directory:
   698 00008217 A1[B8DD0000]        <1> 	mov	eax, [Current_Dir_FCluster]
   699 0000821C E8E41B0000          <1> 	call	load_FS_sub_directory
   700 00008221 C3                  <1> 	retn 
   701                              <1> loc_reload_FAT_sub_directory:
   702 00008222 A1[B8DD0000]        <1> 	mov	eax, [Current_Dir_FCluster]
   703 00008227 E89C1B0000          <1> 	call	load_FAT_sub_directory
   704 0000822C 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 0000822D 663B1D[EBE50000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   750 00008234 0F8739010000        <1>         ja      loc_ffde_stc_retn_255
   751                              <1> 
   752                              <1> 	;mov    [DirBuff_CurrentEntry], bx  
   753                              <1> 
   754 0000823A BF00000800          <1>   	mov	edi, Directory_Buffer
   755 0000823F 66A3[B8E60000]      <1> 	mov	[FDE_AttrMask], ax
   756                              <1> 
   757 00008245 29C0                <1> 	sub	eax, eax
   758                              <1>             
   759                              <1> 	;;mov	[PreviousAttr], al ; 0 ;; 13/02/2016
   760 00008247 66A3[BAE60000]      <1> 	mov	[AmbiguousFileName], ax ; 0
   761                              <1> 
   762 0000824D 6689D8              <1> 	mov	ax, bx
   763 00008250 66C1E005            <1> 	shl	ax, 5 ; ; * 32 ; Directory entry size
   764 00008254 01C7                <1> 	add     edi, eax
   765                              <1> 
   766 00008256 08ED                <1> 	or	ch, ch
   767 00008258 0F852C010000        <1>         jnz     loc_find_free_deleted_entry_0
   768                              <1> 
   769 0000825E 08C9                <1> 	or      cl, cl
   770 00008260 0F850D010000        <1>         jnz     loc_ffde_stc_retn_255
   771                              <1>  
   772                              <1> check_find_dir_entry:
   773 00008266 66A1[B8E60000]      <1> 	mov	ax, [FDE_AttrMask]
   774 0000826C 8A2F                <1> 	mov	ch, [edi]
   775 0000826E 80FD00              <1> 	cmp     ch, 0 ; Is it never used entry?
   776 00008271 0F86FF000000        <1> 	jna	loc_find_direntry_stc_retn 
   777 00008277 56                  <1> 	push	esi
   778 00008278 8A570B              <1> 	mov	dl, [edi+0Bh] ; File attributes
   779 0000827B 80FDE5              <1> 	cmp	ch, 0E5h ; Is it a deleted file?
   780 0000827E 746D                <1> 	je	short loc_find_dir_next_entry_prevdeleted
   781                              <1> 
   782 00008280 80FA0F              <1> 	cmp     dl, 0Fh ; longname sub component check
   783 00008283 7505                <1> 	jne     short loc_check_attributes_mask
   784 00008285 E8ED010000          <1> 	call	save_longname_sub_component
   785                              <1> 
   786                              <1> loc_check_attributes_mask:
   787 0000828A 88C6                <1> 	mov	dh, al
   788 0000828C 20D6                <1> 	and	dh, dl    
   789 0000828E 38F0                <1> 	cmp	al, dh
   790 00008290 0F85BA000000        <1>         jne     loc_find_dir_next_entry
   791 00008296 20D4                <1> 	and	ah, dl
   792 00008298 0F85B2000000        <1>         jnz     loc_find_dir_next_entry
   793 0000829E 80FA0F              <1> 	cmp	dl, 0Fh
   794 000082A1 751A                <1> 	jne	short pass_direntry_attr_check
   795                              <1> 
   796 000082A3 3C0F                <1> 	cmp	al, 0Fh ; AL = 0Fh -> find long name
   797 000082A5 0F85A5000000        <1>         jne     loc_find_dir_next_entry
   798                              <1> 
   799 000082AB 5E                  <1> 	pop	esi
   800 000082AC 6631C0              <1> 	xor	ax, ax
   801 000082AF 8A35[BCE60000]      <1> 	mov	dh, [PreviousAttr]
   802 000082B5 66891D[E9E50000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   803 000082BC C3                  <1> 	retn
   804                              <1> 
   805                              <1> pass_direntry_attr_check:
   806 000082BD 89FD                <1> 	mov	ebp, edi ; 14/02/2016
   807 000082BF B908000000          <1> 	mov	ecx, 8
   808                              <1> loc_lodsb_find_dir:
   809 000082C4 AC                  <1> 	lodsb
   810 000082C5 3C2A                <1> 	cmp	al, '*'
   811 000082C7 7508                <1> 	jne	short pass_fde_ambiguous1_check
   812 000082C9 FE05[BBE60000]      <1>         inc     byte [AmbiguousFileName+1]
   813 000082CF EB28                <1> 	jmp	short loc_check_direntry_extension
   814                              <1> 
   815                              <1> pass_fde_ambiguous1_check:
   816 000082D1 3C3F                <1> 	cmp	al, '?'
   817 000082D3 750D                <1> 	jne	short pass_fde_ambiguous2_check
   818 000082D5 FE05[BAE60000]      <1> 	inc	byte [AmbiguousFileName]
   819 000082DB 803F20              <1> 	cmp	byte [edi], 20h
   820 000082DE 764E                <1> 	jna	short loc_find_dir_next_entry_ebp
   821 000082E0 EB14                <1> 	jmp	short loc_scasb_find_dir_inc_di
   822                              <1> 
   823                              <1> pass_fde_ambiguous2_check:
   824 000082E2 3C20                <1> 	cmp	al, 20h
   825 000082E4 750C                <1> 	jne	short loc_scasb_find_dir
   826 000082E6 803F20              <1> 	cmp	byte [edi], 20h
   827 000082E9 7543                <1> 	jne	short loc_find_dir_next_entry_ebp
   828 000082EB EB0C                <1> 	jmp	short loc_check_direntry_extension
   829                              <1> 
   830                              <1> loc_find_dir_next_entry_prevdeleted:
   831 000082ED 80CA80              <1> 	or	dl, 80h  ; Bit 7 -> deleted entry sign
   832 000082F0 EB5E                <1> 	jmp	short loc_find_dir_next_entry
   833                              <1> 
   834                              <1> loc_scasb_find_dir:
   835 000082F2 3A07                <1> 	cmp	al, [edi]
   836 000082F4 7538                <1> 	jne	short loc_find_dir_next_entry_ebp
   837                              <1> loc_scasb_find_dir_inc_di:
   838 000082F6 47                  <1> 	inc	edi
   839 000082F7 E2CB                <1> 	loop	loc_lodsb_find_dir
   840                              <1> 
   841                              <1> loc_check_direntry_extension:
   842 000082F9 BE08000000          <1> 	mov	esi, 8
   843 000082FE 89F7                <1> 	mov	edi, esi ; 8
   844 00008300 033424              <1> 	add	esi, [esp] ; Sub Dir or File Name Address
   845 00008303 01EF                <1> 	add	edi, ebp
   846 00008305 B103                <1> 	mov	cl, 3
   847                              <1> loc_lodsb_find_dir_ext:
   848 00008307 AC                  <1> 	lodsb
   849 00008308 3C2A                <1> 	cmp	al, '*'
   850 0000830A 7508                <1> 	jne	short pass_fde_ambiguous3_check
   851 0000830C FE05[BBE60000]      <1> 	inc	byte [AmbiguousFileName+1]
   852 00008312 EB1E                <1> 	jmp	short loc_find_dir_proper_direntry
   853                              <1> 
   854                              <1> pass_fde_ambiguous3_check:
   855 00008314 3C3F                <1> 	cmp	al, '?'
   856 00008316 750D                <1> 	jne	short pass_fde_ambiguous4_check
   857 00008318 FE05[BAE60000]      <1> 	inc	byte [AmbiguousFileName]
   858 0000831E 803F20              <1> 	cmp	byte [edi], 20h
   859 00008321 760B                <1> 	jna	short loc_find_dir_next_entry_ebp
   860 00008323 EB49                <1> 	jmp	short loc_scasb_find_dir_ext_inc_di
   861                              <1> 
   862                              <1> pass_fde_ambiguous4_check:
   863 00008325 3C20                <1> 	cmp	al, 20h
   864 00008327 7541                <1> 	jne	short loc_scasb_find_dir_ext
   865 00008329 803F20              <1> 	cmp	byte [edi], 20h
   866 0000832C 7404                <1> 	je	short loc_find_dir_proper_direntry
   867                              <1> 
   868                              <1> loc_find_dir_next_entry_ebp:
   869 0000832E 89EF                <1> 	mov	edi, ebp ; 14/02/2016
   870 00008330 EB1E                <1> 	jmp	short loc_find_dir_next_entry
   871                              <1> 
   872                              <1> loc_find_dir_proper_direntry:
   873 00008332 30C9                <1> 	xor	cl, cl
   874                              <1> loc_find_dir_proper_direntry_1:
   875 00008334 5E                  <1> 	pop	esi
   876 00008335 89EF                <1>         mov     edi, ebp
   877 00008337 8A2F                <1> 	mov	ch, [edi]
   878 00008339 8A570B              <1> 	mov     dl, [edi+0Bh] ; Dir entry attributes
   879 0000833C 66A1[BAE60000]      <1> 	mov	ax, [AmbiguousFileName]
   880                              <1> loc_find_dir_proper_direntry_2:
   881 00008342 8A35[BCE60000]      <1> 	mov     dh, [PreviousAttr]
   882 00008348 66891D[E9E50000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   883 0000834F C3                  <1> 	retn
   884                              <1> 
   885                              <1> loc_find_dir_next_entry:
   886 00008350 8815[BCE60000]      <1> 	mov	byte [PreviousAttr], dl ; LongName check
   887                              <1> loc_find_dir_next_entry_1:
   888 00008356 5E                  <1> 	pop	esi
   889 00008357 83C720              <1> 	add	edi, 32
   890                              <1> 	;inc	word [DirBuff_EntryCounter]
   891 0000835A 6643                <1> 	inc	bx
   892 0000835C 663B1D[EBE50000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   893 00008363 770E                <1> 	ja	short loc_ffde_stc_retn_255
   894 00008365 E9FCFEFFFF          <1>         jmp     check_find_dir_entry 
   895                              <1> 
   896                              <1> loc_scasb_find_dir_ext:
   897 0000836A 3A07                <1> 	cmp	al, [edi]
   898 0000836C 75C0                <1> 	jne	short loc_find_dir_next_entry_ebp
   899                              <1> loc_scasb_find_dir_ext_inc_di:
   900 0000836E 47                  <1> 	inc	edi
   901 0000836F E296                <1> 	loop    loc_lodsb_find_dir_ext
   902 00008371 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 00008373 31C9                <1> 	xor	ecx, ecx
   907 00008375 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 00008376 B802000000          <1> 	mov	eax, 2 ; File Not Found
   913 0000837B 8A35[BCE60000]      <1> 	mov	dh, [PreviousAttr]
   914 00008381 66891D[E9E50000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   915 00008388 F9                  <1> 	stc
   916 00008389 C3                  <1> 	retn
   917                              <1> 
   918                              <1> loc_find_free_deleted_entry_0:
   919 0000838A 66A1[B8E60000]      <1> 	mov	ax, [FDE_AttrMask]
   920 00008390 8A2F                <1> 	mov	ch, [edi]
   921 00008392 8A570B              <1> 	mov	dl, [edi+0Bh] ; File attributes
   922 00008395 08C9                <1> 	or	cl, cl 
   923 00008397 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 00008399 80F9FF              <1> 	cmp	cl, 0FFh
   927 0000839C 7432                <1> 	je	short loc_find_free_deleted_entry_1
   928 0000839E EB4D                <1> 	jmp	short pass_loc_check_ffde_0_err
   929                              <1> 
   930                              <1> loc_check_ffde_0_repeat:
   931 000083A0 08ED                <1> 	or	ch, ch
   932 000083A2 7511                <1> 	jnz	short loc_check_ffde_0_next
   933                              <1> 
   934                              <1> loc_check_ffde_retn_2:
   935 000083A4 6629C0              <1> 	sub	ax, ax
   936 000083A7 8A35[BCE60000]      <1> 	mov	dh, [PreviousAttr]
   937 000083AD 66891D[E9E50000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   938 000083B4 C3                  <1> 	retn
   939                              <1>  
   940                              <1> loc_check_ffde_0_next:
   941 000083B5 6643                <1> 	inc	bx
   942 000083B7 83C720              <1> 	add	edi, 32
   943                              <1> 	;inc	word [DirBuff_EntryCounter]
   944                              <1> 	 
   945 000083BA 663B1D[EBE50000]    <1>         cmp	bx, [DirBuff_LastEntry]
   946 000083C1 77B0                <1> 	ja	short loc_ffde_stc_retn_255
   947 000083C3 8815[BCE60000]      <1> 	mov	[PreviousAttr], dl
   948 000083C9 8A2F                <1> 	mov	ch, [edi]
   949 000083CB 8A570B              <1> 	mov	dl, [edi+0Bh] ; file attributes
   950 000083CE EBD0                <1> 	jmp	short loc_check_ffde_0_repeat
   951                              <1> 
   952                              <1> loc_find_free_deleted_entry_1:
   953 000083D0 28D2                <1> 	sub	dl, dl      
   954                              <1> loc_find_free_deleted_entry_2:
   955 000083D2 20ED                <1> 	and	ch, ch  
   956 000083D4 74CE                <1> 	jz	short loc_check_ffde_retn_2
   957 000083D6 80FDE5              <1> 	cmp	ch, 0E5h
   958 000083D9 74C9                <1> 	je	short loc_check_ffde_retn_2
   959 000083DB 6643                <1> 	inc	bx
   960 000083DD 83C720              <1> 	add	edi, 32
   961 000083E0 663B1D[EBE50000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   962 000083E7 778A                <1> 	ja	short loc_ffde_stc_retn_255
   963 000083E9 8A2F                <1> 	mov	ch, [edi]
   964 000083EB EBE5                <1> 	jmp	short loc_find_free_deleted_entry_2
   965                              <1> 
   966                              <1> pass_loc_check_ffde_0_err:
   967 000083ED 38CD                <1> 	cmp	ch, cl
   968 000083EF 741F                <1> 	je	short loc_check_ffde_attrib 
   969                              <1> 
   970 000083F1 6643                <1> 	inc	bx
   971 000083F3 83C720              <1> 	add	edi, 32
   972 000083F6 663B1D[EBE50000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   973 000083FD 0F8770FFFFFF        <1>         ja      loc_ffde_stc_retn_255
   974 00008403 8815[BCE60000]      <1> 	mov	[PreviousAttr], dl
   975 00008409 8A2F                <1> 	mov	ch, [edi]
   976 0000840B 8A570B              <1> 	mov	dl, [edi+0Bh]
   977 0000840E EBDD                <1> 	jmp	short pass_loc_check_ffde_0_err
   978                              <1> 
   979                              <1> loc_check_ffde_attrib:
   980 00008410 88C6                <1> 	mov	dh, al
   981 00008412 20D6                <1> 	and	dh, dl    
   982 00008414 38F0                <1> 	cmp	al, dh
   983 00008416 759D                <1> 	jne	short loc_check_ffde_0_next
   984 00008418 20D4                <1> 	and	ah, dl
   985 0000841A 7599                <1> 	jnz	short loc_check_ffde_0_next
   986 0000841C 30C9                <1> 	xor	cl, cl 
   987 0000841E 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 00008420 56                  <1> 	push	esi  
  1006 00008421 57                  <1> 	push	edi
  1007                              <1> 
  1008 00008422 B90B000000          <1> 	mov	ecx, 11
  1009 00008427 B020                <1> 	mov	al, 20h
  1010 00008429 F3AA                <1> 	rep	stosb
  1011                              <1> 
  1012 0000842B 8B3C24              <1> 	mov	edi, [esp]
  1013                              <1> 
  1014 0000842E 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 00008430 B50B                <1> 	mov	ch, 11 ; directory entry's name length
  1024                              <1> loc_check_first_dot:
  1025 00008432 8A06                <1> 	mov	al, [esi]
  1026 00008434 3C2E                <1> 	cmp	al, 2Eh
  1027 00008436 750C                <1> 	jne	short pass_check_first_dot
  1028 00008438 8807                <1> 	mov	[edi], al
  1029 0000843A 47                  <1> 	inc	edi
  1030 0000843B 46                  <1> 	inc	esi
  1031 0000843C FEC9                <1> 	dec	cl
  1032 0000843E 75F2                <1> 	jnz	short loc_check_first_dot
  1033                              <1> 	;;(ecx <= 12)
  1034                              <1> 	;;loop	loc_check_first_dot 
  1035 00008440 EB30                <1> 	jmp	short stop_convert_file
  1036                              <1> 
  1037                              <1> loc_get_fchar:
  1038 00008442 8A06                <1> 	mov	al, [esi]
  1039                              <1> pass_check_first_dot:
  1040 00008444 3C61                <1> 	cmp	al, 61h ; 'a'
  1041 00008446 7208                <1> 	jb	short pass_name_capitalize
  1042 00008448 3C7A                <1> 	cmp	al, 7Ah ; 'z'
  1043 0000844A 7704                <1> 	ja	short pass_name_capitalize
  1044 0000844C 24DF                <1> 	and	al, 0DFh
  1045 0000844E 8806                <1> 	mov	[esi], al
  1046                              <1> pass_name_capitalize:
  1047 00008450 3C21                <1> 	cmp	al, 21h
  1048 00008452 721E                <1> 	jb	short stop_convert_file
  1049 00008454 3C2E                <1> 	cmp	al, 2Eh ; '.'
  1050 00008456 750C                <1> 	jne	short pass_dot_space
  1051                              <1> add_dot_space: 
  1052 00008458 80F904              <1> 	cmp	cl, 4
  1053 0000845B 760E                <1> 	jna	short inc_and_loop
  1054 0000845D 47                  <1> 	inc	edi
  1055 0000845E FECD                <1> 	dec	ch ; 06/03/2016
  1056 00008460 FEC9                <1> 	dec	cl
  1057 00008462 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 00008464 8807                <1> 	mov	[edi], al
  1069                              <1> loc_after_double_dot:
  1070                              <1> 	; 06/03/2016
  1071 00008466 FECD                <1> 	dec	ch ; count down for 11 bytes dir entry limit
  1072 00008468 740A                <1> 	jz	short stop_convert_file_x
  1073 0000846A 47                  <1> 	inc	edi
  1074                              <1> inc_and_loop:
  1075 0000846B FEC9                <1> 	dec	cl ; count down for 12 bytes filename limit 
  1076 0000846D 7403                <1> 	jz	short stop_convert_file	
  1077 0000846F 46                  <1> 	inc	esi
  1078                              <1> 	;;(ecx <= 12)
  1079                              <1> 	;;loop	loc_get_fchar
  1080 00008470 EBD0                <1> 	jmp	short loc_get_fchar
  1081                              <1> 
  1082                              <1> stop_convert_file:
  1083                              <1> 	; 06/03/2016
  1084 00008472 30ED                <1> 	xor	ch, ch
  1085                              <1> 	; ECX < 256 ; 'find_first_file' -> xor cl, cl
  1086                              <1> stop_convert_file_x:
  1087 00008474 5F                  <1> 	pop	edi
  1088 00008475 5E                  <1> 	pop	esi
  1089 00008476 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 00008477 57                  <1> 	push	edi
  1109 00008478 56                  <1> 	push	esi
  1110                              <1> 	;push	ebx
  1111                              <1> 	;push	ecx
  1112                              <1> 	;push	edx
  1113 00008479 50                  <1> 	push	eax
  1114                              <1>            
  1115 0000847A 29C9                <1> 	sub	ecx, ecx
  1116                              <1> 	;sub	eax, eax
  1117 0000847C B11A                <1> 	mov	cl, 26
  1118                              <1> 
  1119 0000847E 0FB607              <1> 	movzx	eax, byte [edi] ; LDIR_Order
  1120 00008481 3C41                <1> 	cmp	al, 41h  ; 40h (last long entry sign) + 1
  1121 00008483 722B                <1> 	jb	short pass_pslnsc_last_long_entry
  1122                              <1> 
  1123 00008485 88C4                <1> 	mov	ah, al
  1124 00008487 80EC40              <1> 	sub	ah, 40h
  1125 0000848A 8825[BEE60000]      <1> 	mov	[LFN_EntryLength], ah
  1126                              <1> 	
  1127 00008490 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 00008492 7753                <1> 	ja	short loc_pslnsc_retn
  1131                              <1> 
  1132 00008494 2407                <1> 	and	al, 07h ; 0Fh
  1133 00008496 A2[BDE60000]        <1> 	mov	[LongNameFound], al
  1134                              <1> 
  1135 0000849B FEC8                <1> 	dec	al
  1136                              <1> 	;mov	cl, 26
  1137 0000849D F6E1                <1> 	mul	cl
  1138                              <1> 
  1139 0000849F 89C6                <1> 	mov	esi, eax
  1140 000084A1 01CE                <1> 	add	esi, ecx
  1141                              <1> 		; to make is an ASCIZZ string
  1142                              <1> 		; with ax+26 bytes length
  1143 000084A3 81C6[C0E60000]      <1> 	add	esi, LongFileName
  1144 000084A9 66C7060000          <1> 	mov	word [esi], 0   
  1145 000084AE EB16                <1> 	jmp	short loc_pslsc_move_ldir_name2 
  1146                              <1> 
  1147                              <1> pass_pslnsc_last_long_entry:
  1148 000084B0 3C04                <1> 	cmp	al, 04h
  1149 000084B2 7733                <1> 	ja	short loc_pslnsc_retn
  1150 000084B4 FE0D[BDE60000]      <1> 	dec	byte [LongNameFound]
  1151 000084BA 3A05[BDE60000]      <1> 	cmp	al, [LongNameFound]
  1152 000084C0 7525                <1> 	jne	short loc_pslnsc_retn
  1153                              <1> 
  1154                              <1> loc_pslsc_move_ldir_name1:
  1155 000084C2 FEC8                <1> 	dec	al
  1156                              <1> 	;mov	cl, 26
  1157 000084C4 F6E1                <1> 	mul	cl
  1158                              <1> 
  1159                              <1> loc_pslsc_move_ldir_name2:
  1160 000084C6 8A4F0D              <1> 	mov	cl, [edi+0Dh] ; long name checksum
  1161 000084C9 880D[BFE60000]      <1> 	mov	[LFN_CheckSum], cl 
  1162 000084CF 89FE                <1> 	mov	esi, edi ; LDIR_Order
  1163 000084D1 BF[C0E60000]        <1> 	mov	edi, LongFileName
  1164 000084D6 01C7                <1> 	add	edi, eax
  1165 000084D8 46                  <1> 	inc	esi
  1166 000084D9 B105                <1> 	mov	cl, 5 ; chars 1 to 5
  1167 000084DB F366A5              <1> 	rep	movsw
  1168 000084DE 83C603              <1> 	add	esi, 3
  1169 000084E1 A5                  <1> 	movsd	; char 6 & 7 
  1170 000084E2 A5                  <1> 	movsd	; char 8 & 9
  1171 000084E3 A5                  <1> 	movsd	; char 10 & 11
  1172 000084E4 46                  <1> 	inc	esi
  1173 000084E5 46                  <1> 	inc	esi 
  1174 000084E6 A5                  <1> 	movsd   ; char 12 & 13 
  1175                              <1> 
  1176                              <1> loc_pslnsc_retn:
  1177 000084E7 58                  <1>  	pop	eax
  1178                              <1> 	;pop	edx
  1179                              <1> 	;pop	ecx
  1180                              <1> 	;pop	ebx
  1181 000084E8 5E                  <1> 	pop	esi  
  1182 000084E9 5F                  <1> 	pop	edi
  1183                              <1>  
  1184 000084EA 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 000084EB 57                  <1> 	push	edi
  1205 000084EC B914000000          <1> 	mov	ecx, 20  ; 80 bytes
  1206 000084F1 31C0                <1> 	xor	eax, eax
  1207 000084F3 F3AB                <1> 	rep	stosd 
  1208 000084F5 5F                  <1> 	pop	edi
  1209                              <1> 
  1210 000084F6 668B06              <1> 	mov	ax, [esi]
  1211 000084F9 80FC3A              <1> 	cmp	ah, ':'
  1212 000084FC 741C                <1> 	je	short loc_ppn_change_drive
  1213 000084FE A0[BEDD0000]        <1> 	mov	al, [Current_Drv]
  1214 00008503 EB33                <1> 	jmp	short pass_ppn_change_drive
  1215                              <1> 
  1216                              <1> pass_ppn_cdir:
  1217 00008505 8B35[E2E70000]      <1> 	mov	esi, [First_Path_Pos]
  1218 0000850B AC                  <1> 	lodsb
  1219                              <1> loc_ppn_get_filename:
  1220 0000850C 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 0000850F B10C                <1> 	mov	cl, 12
  1224                              <1> loc_ppn_get_fnchar_next:
  1225 00008511 AA                  <1> 	stosb
  1226 00008512 AC                  <1> 	lodsb
  1227 00008513 3C21                <1> 	cmp	al, 21h
  1228 00008515 7274                <1> 	jb	short loc_ppn_clc_return 
  1229 00008517 E2F8                <1>         loop    loc_ppn_get_fnchar_next
  1230                              <1> loc_ppn_return:
  1231 00008519 C3                  <1> 	retn
  1232                              <1> 
  1233                              <1> loc_ppn_change_drive:
  1234 0000851A 24DF                <1> 	and	al, 0DFh
  1235 0000851C 2C41                <1> 	sub	al, 'A'; A:
  1236 0000851E 726F                <1> 	jc	short loc_ppn_invalid_drive
  1237 00008520 3805[28C80000]      <1> 	cmp	[Last_DOS_DiskNo], al
  1238 00008526 7267                <1> 	jb	short loc_ppn_invalid_drive
  1239                              <1> 
  1240 00008528 46                  <1> 	inc	esi
  1241 00008529 46                  <1> 	inc	esi
  1242 0000852A 8A26                <1> 	mov	ah, [esi]
  1243 0000852C 80FC21              <1> 	cmp	ah, 21h
  1244 0000852F 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 00008531 8807                <1> 	mov	[edi], al ; Drv 
  1249 00008533 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 00008537 C3                  <1> 	retn
  1255                              <1> 
  1256                              <1> pass_ppn_change_drive:
  1257 00008538 8935[E2E70000]      <1> 	mov	[First_Path_Pos], esi
  1258 0000853E C705[E6E70000]0000- <1> 	mov	dword [Last_Slash_Pos], 0
  1258 00008546 0000                <1>
  1259 00008548 AA                  <1> 	stosb
  1260 00008549 8A06                <1> 	mov	al, [esi]
  1261                              <1> loc_scan_ppn_dslash:
  1262 0000854B 3C2F                <1> 	cmp	al, '/'
  1263 0000854D 7506                <1>   	jne	short loc_scan_next_slash_pos
  1264 0000854F 8935[E6E70000]      <1> 	mov	[Last_Slash_Pos], esi
  1265                              <1> loc_scan_next_slash_pos:
  1266 00008555 46                  <1> 	inc	esi
  1267 00008556 8A06                <1> 	mov	al, [esi]
  1268 00008558 3C20                <1> 	cmp	al, 20h
  1269 0000855A 77EF                <1> 	ja	short loc_scan_ppn_dslash
  1270 0000855C 833D[E6E70000]00    <1> 	cmp	dword [Last_Slash_Pos], 0
  1271 00008563 76A0                <1> 	jna	short pass_ppn_cdir
  1272                              <1> 	
  1273 00008565 8B0D[E6E70000]      <1> 	mov	ecx, [Last_Slash_Pos]
  1274 0000856B 8B35[E2E70000]      <1> 	mov	esi, [First_Path_Pos]
  1275 00008571 29F1                <1> 	sub	ecx, esi
  1276 00008573 41                  <1> 	inc	ecx
  1277                              <1> 	;cmp	ecx, 64
  1278 00008574 80F940              <1> 	cmp	cl, 64
  1279 00008577 7715                <1> 	ja	short loc_ppn_invalid_drive_stc
  1280                              <1> 
  1281 00008579 89F8                <1> 	mov	eax, edi ; Dest Dir String Location (65 byte)
  1282 0000857B F3A4                <1> 	rep	movsb
  1283                              <1> 	;mov	[edi], cl ; 0, End of Dir String
  1284 0000857D 8B35[E6E70000]      <1> 	mov	esi, [Last_Slash_Pos]
  1285 00008583 46                  <1> 	inc	esi
  1286 00008584 89C7                <1> 	mov	edi, eax
  1287 00008586 AC                  <1> 	lodsb
  1288 00008587 3C21                <1> 	cmp	al, 21h
  1289 00008589 7381                <1> 	jnb	short loc_ppn_get_filename
  1290                              <1> loc_ppn_clc_return:
  1291                              <1> 	;clc
  1292 0000858B 31C0                <1> 	xor	eax, eax
  1293 0000858D C3                  <1> 	retn
  1294                              <1> 
  1295                              <1> loc_ppn_invalid_drive_stc:
  1296 0000858E F5                  <1> 	cmc	 ; stc
  1297                              <1> loc_ppn_invalid_drive:
  1298                              <1> 	; cf = 1
  1299                              <1> 	; The Drive Letter/Char < "A" or > "Z"
  1300 0000858F 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 00008593 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 00008594 66B80008            <1> 	mov	ax, 0800h 
  1338                              <1> 		; it must not be volume name or longname
  1339 00008598 E844DDFFFF          <1> 	call	find_first_file
  1340 0000859D 7216                <1> 	jc	short loc_fln_retn
  1341                              <1>  
  1342                              <1> loc_fln_check_FAT_Type:
  1343 0000859F 803D[BDDD0000]01    <1> 	cmp	byte [Current_FATType], 1
  1344 000085A6 7306                <1> 	jnb	short loc_fln_check_longname_yes_sign
  1345                              <1> 
  1346 000085A8 E839000000          <1> 	call	get_fs_longname
  1347 000085AD C3                  <1> 	retn
  1348                              <1> 
  1349                              <1> loc_fln_check_longname_yes_sign:
  1350 000085AE 08FF                <1> 	or	bh, bh
  1351 000085B0 7504                <1> 	jnz	short loc_fln_check_longnamefound_number
  1352                              <1> loc_fln_longname_not_found_retn:
  1353 000085B2 31C0                <1> 	xor	eax, eax 
  1354                              <1> 	; cf = 1 & al = 0 -> longname not found
  1355 000085B4 F9                  <1> 	stc
  1356                              <1> loc_fln_retn:
  1357 000085B5 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 000085B6 803D[BDE60000]01    <1>         cmp     byte [LongNameFound], 1
  1368 000085BD 75F3                <1> 	jne	short loc_fln_longname_not_found_retn
  1369                              <1>              
  1370                              <1> loc_fln_calculate_checksum: 
  1371 000085BF 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 000085C4 3805[BFE60000]      <1> 	cmp	[LFN_CheckSum], al
  1382 000085CA 75E6                <1> 	jne	short loc_fln_longname_not_found_retn
  1383                              <1> 
  1384 000085CC BE[C0E60000]        <1> 	mov	esi, LongFileName
  1385 000085D1 A0[BDDD0000]        <1> 	mov	al, [Current_FATType]
  1386 000085D6 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 000085D7 30C0                <1> 	xor	al, al
  1411 000085D9 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 000085DE D0C8                <1> 	ror	al, 1 ; 17/10/2009  
  1420 000085E0 0206                <1> 	add	al, [esi]
  1421 000085E2 46                  <1> 	inc	esi
  1422                              <1> 	;add	al, ah
  1423 000085E3 E2F9                <1> 	loop	loc_next_sum
  1424 000085E5 C3                  <1> 	retn
  1425                              <1> 
  1426                              <1> get_fs_longname:
  1427                              <1> 	; temporary (13/02/2016)
  1428 000085E6 31C0                <1> 	xor eax, eax
  1429 000085E8 F9                  <1> 	stc
  1430 000085E9 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 000085EA 80E107              <1> 	and	cl, 07h
  1454 000085ED 880D[3CE80000]      <1> 	mov	byte [mkdir_attrib], cl
  1455                              <1> 
  1456 000085F3 56                  <1> 	push	esi
  1457 000085F4 31DB                <1> 	xor	ebx, ebx
  1458 000085F6 8A3D[BEDD0000]      <1> 	mov	bh, [Current_Drv]
  1459 000085FC BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1460 00008601 01DE                <1> 	add	esi, ebx
  1461 00008603 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 00008604 807E0101            <1> 	cmp	byte [esi+LD_DiskType], 1 ; 0 = Invalid
  1466 00008608 730B                <1> 	jnb	short loc_mkdir_check_file_sytem
  1467 0000860A B813000000          <1> 	mov	eax, 13h ; MSDOS err => Disk write-protected 
  1468 0000860F 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 00008614 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 00008615 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  1480 00008619 730B                <1> 	jnb	short loc_mkdir_check_free_sectors
  1481                              <1> 
  1482                              <1> loc_make_fs_directory:
  1483 0000861B A1[B8DD0000]        <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 00008620 E8B8150000          <1> 	call	make_fs_directory
  1488 00008625 C3                  <1> 	retn
  1489                              <1> 
  1490                              <1> loc_mkdir_check_free_sectors:
  1491 00008626 0FB64613            <1>         movzx   eax, byte [esi+LD_BPB+SecPerClust]
  1492 0000862A 8B4E74              <1> 	mov	ecx, [esi+LD_FreeSectors]
  1493 0000862D 39C1                <1> 	cmp	ecx, eax
  1494 0000862F 7255                <1> 	jb	short loc_mkdir_insufficient_disk_space
  1495                              <1> 
  1496                              <1> loc_make_fat_directory:
  1497 00008631 891D[2CE80000]      <1> 	mov	[mkdir_DirName_Offset], ebx
  1498 00008637 890D[38E80000]      <1> 	mov	[mkdir_FreeSectors], ecx
  1499                              <1> 
  1500                              <1> 	;mov	al, [esi+LD_BPB+SecPerClust]
  1501 0000863D A2[3EE80000]        <1> 	mov	byte [mkdir_SecPerClust], al
  1502                              <1> 
  1503                              <1> loc_mkdir_gffc_1:
  1504 00008642 E8F2170000          <1> 	call	get_first_free_cluster
  1505 00008647 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 00008649 A3[30E80000]        <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 0000864E 31C0                <1> 	xor	eax, eax
  1522 00008650 89C1                <1>         mov	ecx, eax
  1523 00008652 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 00008654 E8D2FAFFFF          <1> 	call	locate_current_dir_file
  1528 00008659 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 0000865B 83F802              <1> 	cmp	eax, 2  ; cmp al, 2 ; File/Dir not found !
  1532 0000865E 752B                <1> 	jne	short loc_mkdir_stc_return
  1533                              <1> 
  1534                              <1> loc_mkdir_add_new_cluster:
  1535 00008660 3805[BDDD0000]      <1> 	cmp	byte [Current_FATType], al ; 2
  1536                              <1> 	;cmp	byte ptr [esi+LD_FATType], 2
  1537 00008666 770C                <1> 	ja	short loc_mkdir_add_new_cluster_check_fsc
  1538 00008668 803D[BCDD0000]01    <1> 	cmp	byte [Current_Dir_Level], 1
  1539                              <1> 	;cmp	byte [esi+LD_CDirLevel], 1
  1540 0000866F 7303                <1> 	jnb	short loc_mkdir_add_new_cluster_check_fsc
  1541                              <1> 
  1542 00008671 B00C                <1> 	mov	al, 12 ; No more files 
  1543                              <1> loc_mkdir_gffc_retn:
  1544 00008673 C3                  <1> 	retn
  1545                              <1> 
  1546                              <1> loc_mkdir_add_new_cluster_check_fsc:
  1547 00008674 8B0D[38E80000]      <1> 	mov	ecx, [mkdir_FreeSectors]
  1548                              <1> 	;movzx	eax, byte [mkdir_SecPerClust]
  1549 0000867A A0[3EE80000]        <1> 	mov	al, [mkdir_SecPerClust]
  1550 0000867F 66D1E0              <1> 	shl	ax, 1 ; AX = 2 * AX
  1551 00008682 39C1                <1> 	cmp	ecx, eax
  1552 00008684 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 00008686 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 0000868A C3                  <1> 	retn
  1563                              <1> 
  1564                              <1> loc_mkdir_stc_return:
  1565 0000868B F9                  <1> 	stc
  1566 0000868C C3                  <1> 	retn 
  1567                              <1> 
  1568                              <1> loc_mkdir_gffc_2:
  1569 0000868D E8A7170000          <1> 	call	get_first_free_cluster
  1570 00008692 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 00008694 A3[30E80000]        <1> 	mov	[mkdir_FFCluster], eax
  1578                              <1> 
  1579 00008699 A1[34E80000]        <1> 	mov	eax, [mkdir_LastDirCluster]
  1580                              <1> 
  1581 0000869E E825170000          <1> 	call	load_FAT_sub_directory 
  1582 000086A3 72CE                <1> 	jc	short loc_mkdir_gffc_retn
  1583                              <1> 
  1584 000086A5 31FF                <1> 	xor	edi, edi
  1585                              <1> loc_mkdir_set_ff_dir_entry_1:
  1586                              <1> 	; 27/02/2016
  1587 000086A7 56                  <1> 	push	esi ; Logical DOS Drv Desc. Tbl. address
  1588                              <1> 	; EDI = Directory Entry Address
  1589 000086A8 8B35[2CE80000]      <1> 	mov	esi, [mkdir_DirName_Offset]
  1590 000086AE A1[30E80000]        <1> 	mov	eax, [mkdir_FFCluster]
  1591                              <1> 
  1592 000086B3 66B91000            <1> 	mov	cx, 10h	; CL = Directory attribute
  1593                              <1> 			; CH = 0 -> File size is 0
  1594 000086B7 0A0D[3CE80000]      <1> 	or	cl, [mkdir_attrib] ; S, H, R  
  1595 000086BD E8B0010000          <1> 	call	make_directory_entry
  1596                              <1> 
  1597 000086C2 5E                  <1> 	pop	esi
  1598                              <1> 
  1599 000086C3 C605[E8E50000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1600 000086CA E880020000          <1> 	call	save_directory_buffer
  1601 000086CF 0F83DA000000        <1>         jnc     loc_mkdir_set_ff_dir_entry_2
  1602                              <1> 
  1603                              <1> loc_mkdir_return:
  1604 000086D5 C3                  <1> 	retn
  1605                              <1> 
  1606                              <1> loc_mkdir_add_new_subdir_cluster:
  1607 000086D6 8B15[EDE50000]      <1> 	mov	edx, [DirBuff_Cluster]
  1608 000086DC 8915[34E80000]      <1> 	mov	[mkdir_LastDirCluster], edx       
  1609                              <1> 
  1610 000086E2 A1[30E80000]        <1> 	mov	eax, [mkdir_FFCluster]
  1611 000086E7 E8DC160000          <1> 	call	load_FAT_sub_directory 
  1612 000086EC 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 000086EE 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 000086F0 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec] ; 512
  1623 000086F4 66C1E802            <1> 	shr	ax, 2 ; 'byte count / 4' for 'stosd'
  1624 000086F8 66F7E1              <1> 	mul	cx ; max = 128*(512/4) -> 16384 (stosd)
  1625 000086FB 6689C1              <1> 	mov	cx, ax
  1626 000086FE 6629C0              <1> 	sub	ax, ax ; 0
  1627 00008701 F3AB                <1> 	rep	stosd ; clear directory buffer
  1628                              <1> 
  1629 00008703 C605[E8E50000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1630 0000870A E840020000          <1> 	call	save_directory_buffer 
  1631 0000870F 72C4                <1> 	jc	short loc_mkdir_return
  1632                              <1> 
  1633                              <1> loc_mkdir_save_added_cluster:
  1634 00008711 A1[34E80000]        <1> 	mov	eax, [mkdir_LastDirCluster]
  1635 00008716 8B0D[30E80000]      <1> 	mov	ecx, [mkdir_FFCluster]
  1636                              <1> 	; 01/03/2016
  1637 0000871C 31D2                <1> 	xor	edx, edx
  1638 0000871E 8915[DEE50000]      <1> 	mov	[FAT_ClusterCounter], edx ; 0 ; reset
  1639 00008724 E8E3170000          <1> 	call	update_cluster
  1640 00008729 7304                <1> 	jnc	short loc_mkdir_save_fat_buffer_0
  1641 0000872B 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  1642 0000872D 7518                <1> 	jnz	short loc_mkdir_save_fat_buffer_stc_retn
  1643                              <1> 
  1644                              <1> loc_mkdir_save_fat_buffer_0:
  1645 0000872F A1[30E80000]        <1> 	mov	eax, [mkdir_FFCluster]
  1646 00008734 A3[34E80000]        <1> 	mov	[mkdir_LastDirCluster], eax
  1647                              <1> 
  1648 00008739 31C9                <1> 	xor	ecx, ecx
  1649 0000873B 49                  <1> 	dec	ecx ; FFFFFFFFh
  1650                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1651 0000873C E8CB170000          <1> 	call	update_cluster
  1652 00008741 731A                <1> 	jnc	short loc_mkdir_save_fat_buffer_1
  1653 00008743 09C0                <1> 	or	eax, eax
  1654 00008745 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 00008747 803D[DEE50000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1659 0000874E 720C                <1> 	jb	short loc_mkdir_save_fat_buffer_retn
  1660                              <1> 
  1661 00008750 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free space (BL = 0)
  1662                              <1> 			   ; (BH = FFh -> Use ESI as Drv Param. Tbl.)
  1663 00008754 50                  <1> 	push	eax
  1664 00008755 E8041B0000          <1> 	call	calculate_fat_freespace
  1665 0000875A 58                  <1> 	pop	eax
  1666 0000875B F9                  <1> 	stc
  1667                              <1> loc_mkdir_save_fat_buffer_retn:
  1668 0000875C C3                  <1> 	retn
  1669                              <1> 
  1670                              <1> loc_mkdir_save_fat_buffer_1:
  1671                              <1> 	; byte [FAT_BuffValidData] = 2 
  1672 0000875D E8671A0000          <1> 	call	save_fat_buffer
  1673 00008762 72E3                <1> 	jc	short loc_mkdir_save_fat_buffer_stc_retn
  1674                              <1> 
  1675                              <1> 	; 01/03/2016
  1676 00008764 803D[DEE50000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1677 0000876B 721B                <1> 	jb	short loc_mkdir_save_fat_buffer_2
  1678                              <1> 
  1679                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1680 0000876D A1[DEE50000]        <1> 	mov	eax, [FAT_ClusterCounter]
  1681 00008772 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  1682 00008776 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 0000877B 09C9                <1> 	or	ecx, ecx 
  1689 0000877D 7409                <1> 	jz	short loc_mkdir_save_fat_buffer_2
  1690                              <1> 
  1691 0000877F 66BB00FF            <1> 	mov	bx, 0FF00h ; ; recalculate free space
  1692 00008783 E8D61A0000          <1> 	call	calculate_fat_freespace
  1693                              <1> 
  1694                              <1> loc_mkdir_save_fat_buffer_2:
  1695 00008788 C605[3FE80000]01    <1> 	mov	byte [mkdir_add_new_cluster], 1
  1696 0000878F E9C4000000          <1> 	jmp	loc_mkdir_upd_parent_dir_lmdt
  1697                              <1> 
  1698                              <1> loc_mkdir_update_sub_dir_cluster:
  1699 00008794 A1[30E80000]        <1> 	mov	eax, [mkdir_FFCluster]
  1700 00008799 29C9                <1> 	sub	ecx, ecx ; 0
  1701                              <1> 	; 01/03/2016
  1702 0000879B 890D[DEE50000]      <1> 	mov	[FAT_ClusterCounter], ecx ; 0 ; Reset
  1703 000087A1 49                  <1> 	dec	ecx ; 0FFFFFFFFh
  1704                              <1> 
  1705                              <1> 	; ESI = Logical DOS Drive Descisption Table address  
  1706 000087A2 E865170000          <1> 	call	update_cluster
  1707 000087A7 7379                <1> 	jnc	short loc_mkdir_save_fat_buffer_3
  1708 000087A9 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  1709 000087AB 7475                <1> 	jz	short loc_mkdir_save_fat_buffer_3
  1710                              <1> 	; 01/03/2016
  1711 000087AD 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 000087AF A1[30E80000]        <1> 	mov	eax, [mkdir_FFCluster]
  1716                              <1> 	; Load disk sectors as a directory cluster
  1717 000087B4 E80F160000          <1> 	call	load_FAT_sub_directory 
  1718 000087B9 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 000087BB BF40000800          <1> 	mov	edi, Directory_Buffer + 64 ; 26/02/2016
  1724                              <1> 
  1725                              <1> 	; 02/03/2016
  1726 000087C0 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec] ; 512
  1727 000087C4 66C1E802            <1> 	shr	ax, 2 ; 'byte count / 4' for 'stosd'
  1728 000087C8 F7E1                <1> 	mul 	ecx
  1729 000087CA 89C1                <1> 	mov	ecx, eax
  1730 000087CC 6629C0              <1> 	sub	ax, ax
  1731 000087CF 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 000087D1 BF00000800          <1> 	mov	edi, Directory_Buffer ; 26/02/2016
  1742                              <1> 	
  1743 000087D6 56                  <1> 	push	esi
  1744                              <1> 
  1745 000087D7 BE[40E80000]        <1> 	mov	esi, mkdir_Name
  1746 000087DC 66C7062E00          <1> 	mov	word [esi], 2Eh ; db '.', '0'
  1747                              <1> 
  1748 000087E1 A1[30E80000]        <1> 	mov	eax, [mkdir_FFCluster]
  1749 000087E6 66B91000            <1> 	mov	cx, 10h ; CL = Directory attribute
  1750                              <1> 			; CH = 0 -> File size is 0
  1751 000087EA E883000000          <1> 	call	make_directory_entry
  1752                              <1> 
  1753 000087EF 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 000087F4 29C0                <1> 	sub	eax, eax
  1769 000087F6 3805[BCDD0000]      <1> 	cmp	byte [Current_Dir_Level], al ; 0
  1770 000087FC 7605                <1> 	jna	short loc_mkdir_set_ff_dir_entry_3
  1771 000087FE A1[B8DD0000]        <1> 	mov	eax, [Current_Dir_FCluster] ; parent dir
  1772                              <1> loc_mkdir_set_ff_dir_entry_3:
  1773 00008803 66C746012E00        <1> 	mov	word [esi+1], 2Eh ; db '.', '0'
  1774                              <1> 
  1775                              <1> 	;mov	cx, 10h
  1776 00008809 E864000000          <1> 	call	make_directory_entry
  1777                              <1> 
  1778 0000880E 5E                  <1> 	pop	esi
  1779                              <1> 
  1780 0000880F C605[E8E50000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1781 00008816 E834010000          <1> 	call	save_directory_buffer
  1782 0000881B 0F8373FFFFFF        <1>         jnc     loc_mkdir_update_sub_dir_cluster
  1783                              <1>  
  1784                              <1> retn_make_fat_directory:
  1785 00008821 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 00008822 E8A2190000          <1> 	call	save_fat_buffer
  1791 00008827 0F821AFFFFFF        <1>         jc      loc_mkdir_save_fat_buffer_stc_retn
  1792                              <1> 
  1793 0000882D 803D[DEE50000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1794 00008834 721B                <1> 	jb	short loc_mkdir_save_fat_buffer_4
  1795                              <1> 
  1796                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1797 00008836 A1[DEE50000]        <1> 	mov	eax, [FAT_ClusterCounter]
  1798 0000883B 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  1799 0000883F 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 00008844 09C9                <1> 	or	ecx, ecx 
  1806 00008846 7409                <1>         jz      short loc_mkdir_save_fat_buffer_4
  1807                              <1> 
  1808 00008848 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free space
  1809 0000884C E80D1A0000          <1> 	call	calculate_fat_freespace
  1810                              <1> 
  1811                              <1> loc_mkdir_save_fat_buffer_4:	
  1812 00008851 C605[3FE80000]00    <1> 	mov	byte [mkdir_add_new_cluster], 0
  1813                              <1> 
  1814                              <1> loc_mkdir_upd_parent_dir_lmdt:
  1815 00008858 E88D010000          <1> 	call	update_parent_dir_lmdt
  1816                              <1> 
  1817                              <1> 	; 01/03/2016
  1818 0000885D 803D[3FE80000]00    <1> 	cmp	byte [mkdir_add_new_cluster], 0
  1819 00008864 0F8723FEFFFF        <1>         ja      loc_mkdir_gffc_2
  1820                              <1> 
  1821                              <1> loc_mkdir_retn_new_dir_cluster:
  1822 0000886A A1[30E80000]        <1> 	mov	eax, [mkdir_FFCluster]
  1823 0000886F 31D2                <1> 	xor	edx, edx
  1824                              <1> loc_mkdir_retn:
  1825 00008871 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 00008872 51                  <1> 	push	ecx
  1850                              <1> 
  1851 00008873 884F0B              <1> 	mov	[edi+11], cl ; Attributes
  1852 00008876 6689471A            <1> 	mov	[edi+26], ax ; FClusterLw, 26
  1853 0000887A C1E810              <1> 	shr	eax, 16
  1854 0000887D 66894714            <1> 	mov	[edi+20], ax ; FClusterHw, 20
  1855 00008881 6631C0              <1> 	xor	ax, ax 
  1856 00008884 6689470C            <1> 	mov	[edi+12], ax ; NTReserved, 12
  1857                              <1> 			     ; CrtTimeTenth, 13
  1858 00008888 08ED                <1> 	or	ch, ch
  1859 0000888A 7402                <1> 	jz	short loc_make_direntry_set_filesize
  1860                              <1> 
  1861 0000888C 8B03                <1> 	mov	eax, [ebx]
  1862                              <1>         
  1863                              <1> loc_make_direntry_set_filesize:
  1864 0000888E 89471C              <1> 	mov	[edi+28], eax ; FileSize, 28
  1865                              <1> 	
  1866 00008891 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 00008896 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 0000889B 6689470E            <1> 	mov	[edi+14], ax ; CrtTime, 14
  1874 0000889F 66895710            <1> 	mov	[edi+16], dx ; CrtDate, 16
  1875 000088A3 66895712            <1> 	mov	[edi+18], dx ; LastAccDate, 18
  1876 000088A7 66894716            <1> 	mov	[edi+22], ax ; WrtTime, 14
  1877 000088AB 66895718            <1> 	mov	[edi+24], dx ; WrtDate, 16
  1878 000088AF 59                  <1> 	pop	ecx
  1879                              <1> 
  1880 000088B0 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 000088B1 B404                <1> 	mov	ah, 04h ; Return Current Date
  1891 000088B3 E8CAB9FFFF          <1> 	call	int1Ah 
  1892                              <1> 
  1893 000088B8 88E8                <1> 	mov	al, ch ; <- century BCD
  1894 000088BA 240F                <1> 	and	al, 0Fh
  1895 000088BC 88EC                <1> 	mov	ah, ch
  1896 000088BE C0EC04              <1> 	shr	ah, 4
  1897 000088C1 D50A                <1> 	aad
  1898 000088C3 88C5                <1> 	mov	ch, al ; -> century 
  1899                              <1> 
  1900 000088C5 88C8                <1> 	mov	al, cl ; <- year BCD
  1901 000088C7 240F                <1> 	and	al, 0Fh
  1902 000088C9 88CC                <1> 	mov	ah, cl
  1903 000088CB C0EC04              <1> 	shr	ah, 4
  1904 000088CE D50A                <1> 	aad
  1905 000088D0 88C1                <1> 	mov	cl, al ; -> year
  1906                              <1> 
  1907 000088D2 88E8                <1> 	mov	al, ch
  1908 000088D4 B464                <1> 	mov	ah, 100
  1909 000088D6 F6E4                <1> 	mul	ah
  1910 000088D8 30ED                <1> 	xor	ch, ch
  1911 000088DA 6601C8              <1> 	add	ax, cx
  1912 000088DD 662DBC07            <1> 	sub	ax, 1980 ; ms-dos epoch
  1913 000088E1 6689C1              <1> 	mov	cx, ax
  1914                              <1> 
  1915 000088E4 88F0                <1> 	mov	al, dh ; <- month in bcd
  1916 000088E6 240F                <1> 	and	al, 0Fh
  1917 000088E8 88F4                <1> 	mov	ah, dh
  1918 000088EA C0EC04              <1> 	shr	ah, 4
  1919 000088ED D50A                <1> 	aad
  1920 000088EF 88C6                <1> 	mov	dh, al ; -> month
  1921                              <1> 
  1922 000088F1 88D0                <1> 	mov	al, dl ; <- day BCD
  1923 000088F3 240F                <1> 	and	al, 0Fh
  1924 000088F5 88D4                <1> 	mov	ah, dl
  1925 000088F7 C0EC04              <1> 	shr	ah, 4
  1926 000088FA D50A                <1> 	aad
  1927 000088FC 88C2                <1> 	mov	dl, al ; -> day
  1928                              <1> 
  1929 000088FE 88C8                <1> 	mov	al, cl ; count of years from 1980
  1930 00008900 66C1E004            <1> 	shl	ax, 4
  1931 00008904 08F0                <1> 	or	al, dh ; month of year, 1 to 12
  1932 00008906 66C1E005            <1> 	shl	ax, 5
  1933 0000890A 08D0                <1> 	or	al, dl ; day of year, 1 to 31
  1934                              <1> 	
  1935 0000890C 6650                <1> 	push	ax ; push date
  1936                              <1> 
  1937 0000890E B402                <1> 	mov	ah, 02h ; Return Current Time
  1938 00008910 E86DB9FFFF          <1> 	call	int1Ah
  1939                              <1> 
  1940 00008915 88E8                <1> 	mov	al, ch ; <- hours BCD
  1941 00008917 240F                <1> 	and	al, 0Fh
  1942 00008919 88EC                <1> 	mov	ah, ch
  1943 0000891B C0EC04              <1> 	shr	ah, 4
  1944 0000891E D50A                <1> 	aad
  1945 00008920 88C5                <1> 	mov	ch, al ; -> hours
  1946                              <1> 
  1947 00008922 88C8                <1> 	mov	al, cl ; <- minutes BCD
  1948 00008924 240F                <1> 	and	al, 0Fh
  1949 00008926 88CC                <1> 	mov	ah, cl
  1950 00008928 C0EC04              <1> 	shr	ah, 4
  1951 0000892B D50A                <1> 	aad
  1952 0000892D 88C1                <1> 	mov	cl, al ; -> minutes
  1953                              <1> 
  1954 0000892F 88F0                <1> 	mov	al, dh ; <- seconds BCD
  1955 00008931 240F                <1> 	and	al, 0Fh
  1956 00008933 88F4                <1> 	mov	ah, dh
  1957 00008935 C0EC04              <1> 	shr	ah, 4
  1958 00008938 D50A                <1> 	aad
  1959 0000893A 88C6                <1> 	mov	dh, al ; -> seconds
  1960                              <1> 
  1961 0000893C 88E8                <1> 	mov	al, ch ; hours
  1962 0000893E 66C1E006            <1> 	shl	ax, 6
  1963 00008942 08C8                <1> 	or	al, cl ; minutes
  1964 00008944 66C1E005            <1> 	shl	ax, 5
  1965 00008948 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 0000894A 08F0                <1> 	or	al, dh ; seconds
  1969                              <1> 
  1970 0000894C 665A                <1> 	pop	dx ; pop date
  1971                              <1> 	
  1972 0000894E 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 0000894F BB00000800          <1> 	mov	ebx, Directory_Buffer
  1991 00008954 803D[E8E50000]02    <1> 	cmp	byte [DirBuff_ValidData], 2
  1992 0000895B 7403                <1> 	je	short loc_save_dir_buffer
  1993 0000895D 31C0                <1> 	xor	eax, eax
  1994 0000895F C3                  <1> 	retn            
  1995                              <1> 
  1996                              <1> loc_save_dir_buffer:
  1997 00008960 56                  <1> 	push	esi
  1998 00008961 31DB                <1> 	xor	ebx, ebx 
  1999 00008963 8A3D[E6E50000]      <1>         mov     bh, [DirBuff_DRV]
  2000 00008969 80EF41              <1> 	sub	bh, 'A'
  2001 0000896C BE00010900          <1>         mov     esi, Logical_DOSDisks
  2002 00008971 01DE                <1> 	add	esi, ebx
  2003 00008973 668B4E03            <1>         mov     cx, [esi+LD_FATType]
  2004                              <1> 	; CH = FS Type (A1h for FS)
  2005                              <1> 	; CL = FAT Type (0 for FS)
  2006 00008977 08C9                <1> 	or	cl, cl
  2007 00008979 7433                <1> 	jz	short loc_save_dir_buff_stc_retn
  2008                              <1> 
  2009                              <1> loc_save_dir_buffer_check_cluster_no:    
  2010 0000897B A1[EDE50000]        <1> 	mov	eax, [DirBuff_Cluster]
  2011 00008980 28FF                <1> 	sub	bh, bh ; ebx = 0
  2012 00008982 09C0                <1> 	or	eax, eax
  2013 00008984 7540                <1> 	jnz	short loc_save_sub_dir_buffer
  2014 00008986 8A25[E7E50000]      <1> 	mov	ah, [DirBuff_FATType]
  2015 0000898C FEC3                <1> 	inc	bl ;  bl = 1
  2016 0000898E 38DC                <1> 	cmp	ah, bl
  2017 00008990 721D                <1> 	jb	short loc_save_dir_buff_inv_data_retn
  2018 00008992 FEC3                <1> 	inc	bl ; bl = 2
  2019 00008994 38E3                <1> 	cmp	bl, ah
  2020 00008996 7217                <1> 	jb	short loc_save_dir_buff_inv_data_retn
  2021                              <1> 
  2022                              <1> loc_save_root_dir_buffer:
  2023 00008998 668B5E17            <1> 	mov	bx, [esi+LD_BPB+RootDirEnts]
  2024 0000899C 6683C30F            <1> 	add	bx, 15
  2025 000089A0 66C1EB04            <1> 	shr	bx, 4 ; 16 dir entries per sector
  2026 000089A4 6609DB              <1> 	or	bx, bx
  2027 000089A7 7405                <1> 	jz	short loc_save_dir_buff_stc_retn
  2028                              <1> 	;mov	ecx, ebx 
  2029 000089A9 8B4664              <1> 	mov	eax, [esi+LD_ROOTBegin] ; 26/02/2016
  2030 000089AC EB23                <1> 	jmp	short loc_write_directory_to_disk
  2031                              <1> 
  2032                              <1> loc_save_dir_buff_stc_retn:
  2033 000089AE F9                  <1> 	stc
  2034                              <1> loc_save_dir_buff_inv_data_retn:
  2035 000089AF B00D                <1> 	mov	al, 0Dh ; Invalid data !
  2036 000089B1 C605[E8E50000]00    <1> 	mov	byte [DirBuff_ValidData], 0
  2037 000089B8 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 000089BA B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error 
  2042                              <1> 
  2043                              <1> loc_save_dir_buff_retn:
  2044 000089BF BB00000800          <1> 	mov	ebx, Directory_Buffer
  2045 000089C4 5E                  <1> 	pop	esi
  2046 000089C5 C3                  <1> 	retn
  2047                              <1>  
  2048                              <1> loc_save_sub_dir_buffer:
  2049                              <1> 	; ebx  = 0
  2050 000089C6 83E802              <1> 	sub	eax, 2
  2051 000089C9 8A5E13              <1> 	mov	bl, [esi+LD_BPB+SecPerClust]
  2052 000089CC F7E3                <1> 	mul	ebx
  2053 000089CE 034668              <1>         add     eax, [esi+LD_DATABegin]
  2054                              <1>  	;mov	ecx, ebx
  2055                              <1> 
  2056                              <1> loc_write_directory_to_disk:
  2057 000089D1 89D9                <1>  	mov	ecx, ebx
  2058 000089D3 BB00000800          <1> 	mov	ebx, Directory_Buffer
  2059 000089D8 E8513A0000          <1> 	call	disk_write
  2060 000089DD 72DB                <1> 	jc	short loc_write_directory_to_disk_err
  2061                              <1> 
  2062                              <1> loc_save_dir_buff_validate_retn:
  2063 000089DF C605[E8E50000]01    <1> 	mov	byte [DirBuff_ValidData], 1
  2064 000089E6 31C0                <1> 	xor	eax, eax
  2065                              <1> 	; 26/02/2016
  2066 000089E8 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 000089EA 29C0                <1> 	sub	eax, eax
  2082 000089EC 8A25[BCDD0000]      <1> 	mov	ah, [Current_Dir_Level]
  2083 000089F2 A0[BDDD0000]        <1> 	mov	al, [Current_FATType]
  2084 000089F7 3C01                <1> 	cmp	al, 1
  2085 000089F9 723A                <1> 	jb	short loc_UPDLMDT_proc_retn
  2086                              <1>     
  2087                              <1> loc_update_parent_dir_lm_date_time:
  2088 000089FB 08E4                <1> 	or	ah, ah
  2089 000089FD 7436                <1> 	jz	short loc_UPDLMDT_proc_retn
  2090                              <1> 
  2091 000089FF 56                  <1> 	push	esi ; *
  2092 00008A00 8825[60E80000]      <1> 	mov	[UPDLMDT_CDirLevel], ah
  2093 00008A06 8B15[B8DD0000]      <1> 	mov	edx, [Current_Dir_FCluster]
  2094 00008A0C 8915[61E80000]      <1> 	mov	[UPDLMDT_CDirFCluster], edx
  2095                              <1> 
  2096 00008A12 FECC                <1> 	dec	ah
  2097 00008A14 B90C000000          <1> 	mov	ecx, 12
  2098 00008A19 BE[1FE60000]        <1>         mov     esi, PATH_Array
  2099                              <1> 
  2100 00008A1E 8825[BCDD0000]      <1> 	mov	[Current_Dir_Level], ah
  2101 00008A24 08E4                <1> 	or	ah, ah
  2102 00008A26 750E                <1> 	jnz	short loc_update_parent_dir_lmdt_load_sub_dir_1
  2103 00008A28 803D[BDDD0000]02    <1> 	cmp	byte [Current_FATType], 2
  2104 00008A2F 770B                <1> 	ja	short loc_update_parent_dir_lmdt_load_sub_dir_2
  2105 00008A31 28C0                <1> 	sub	al, al ; eax = 0
  2106 00008A33 EB0A                <1> 	jmp	short loc_update_parent_dir_lmdt_load_sub_dir_3
  2107                              <1> 
  2108                              <1> loc_UPDLMDT_proc_retn:
  2109 00008A35 C3                  <1> 	retn
  2110                              <1>          
  2111                              <1> loc_update_parent_dir_lmdt_load_sub_dir_1:
  2112 00008A36 B010                <1> 	mov	al, 16
  2113 00008A38 F6E4                <1> 	mul	ah 
  2114 00008A3A 01C6                <1> 	add	esi, eax
  2115                              <1> 
  2116                              <1> loc_update_parent_dir_lmdt_load_sub_dir_2:  
  2117 00008A3C 8B460C              <1> 	mov	eax, [esi+12] ; Parent Dir First Cluster
  2118                              <1> 
  2119                              <1> loc_update_parent_dir_lmdt_load_sub_dir_3:
  2120 00008A3F A3[B8DD0000]        <1> 	mov	[Current_Dir_FCluster], eax
  2121                              <1> 
  2122 00008A44 83C610              <1> 	add	esi, 16
  2123 00008A47 66BF[46E7]          <1> 	mov	di, Dir_File_Name  
  2124 00008A4B F3A4                <1> 	rep	movsb
  2125                              <1> 	
  2126 00008A4D BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2127 00008A52 29DB                <1> 	sub	ebx, ebx
  2128 00008A54 8A3D[BEDD0000]      <1> 	mov	bh, [Current_Drv]
  2129 00008A5A 01DE                <1> 	add	esi, ebx
  2130 00008A5C E88FF7FFFF          <1> 	call	reload_current_directory
  2131 00008A61 7232                <1> 	jc	short loc_update_parent_dir_lmdt_restore_cdirlevel
  2132                              <1> 
  2133                              <1> loc_update_parent_dir_lmdt_locate_dir: 
  2134 00008A63 BE[46E70000]        <1> 	mov	esi, Dir_File_Name        
  2135 00008A68 6631C9              <1> 	xor	cx, cx
  2136 00008A6B 66B81008            <1> 	mov	ax, 0810h ; Only directories
  2137 00008A6F E8B7F6FFFF          <1>         call    locate_current_dir_file
  2138                              <1> 	; EDI = DirBuff Directory Entry Address
  2139 00008A74 721F                <1> 	jc short loc_update_parent_dir_lmdt_restore_cdirlevel
  2140                              <1> 
  2141 00008A76 E836FEFFFF          <1> 	call	convert_current_date_time
  2142 00008A7B 66895712            <1> 	mov	[edi+18], dx ; Last Access Date
  2143 00008A7F 66895718            <1> 	mov	[edi+24], dx ; Last Write Date
  2144 00008A83 66894716            <1> 	mov	[edi+22], ax ; Last Write Time
  2145                              <1> 
  2146 00008A87 C605[E8E50000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  2147 00008A8E E8BCFEFFFF          <1> 	call	save_directory_buffer
  2148 00008A93 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 00008A95 8A25[60E80000]      <1> 	mov	ah, [UPDLMDT_CDirLevel]
  2153 00008A9B 8825[BCDD0000]      <1> 	mov	[Current_Dir_Level], ah
  2154 00008AA1 8B15[61E80000]      <1>         mov     edx, [UPDLMDT_CDirFCluster]
  2155 00008AA7 8915[B8DD0000]      <1> 	mov	[Current_Dir_FCluster], edx
  2156                              <1> 
  2157 00008AAD 5E                  <1> 	pop	esi ; *
  2158 00008AAE 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 00008AAF 66A3[8CE80000]      <1> 	mov	[DLN_EntryNumber], ax
  2173 00008AB5 C605[8EE80000]40    <1>         mov     byte [DLN_40h], 40h
  2174                              <1> 
  2175 00008ABC E858000000          <1> 	call	locate_current_dir_entry
  2176 00008AC1 7308                <1> 	jnc	short loc_dln_check_attributes
  2177 00008AC3 C3                  <1> 	retn
  2178                              <1> 
  2179                              <1> loc_dln_longname_not_found:
  2180 00008AC4 B802000000          <1> 	mov	eax, 2
  2181 00008AC9 F9                  <1> 	stc
  2182 00008ACA C3                  <1> 	retn
  2183                              <1> 
  2184                              <1> loc_dln_check_attributes:
  2185 00008ACB B00F                <1> 	mov	al, 0Fh  ; long name
  2186 00008ACD 8A670B              <1> 	mov	ah, [edi+0Bh] ; dir entry attributes
  2187 00008AD0 38C4                <1> 	cmp	ah, al
  2188 00008AD2 75F0                <1> 	jne	short loc_dln_longname_not_found
  2189 00008AD4 8A27                <1> 	mov	ah, [edi]
  2190 00008AD6 2A25[8EE80000]      <1> 	sub	ah, [DLN_40h]
  2191 00008ADC 76E6                <1> 	jna	short loc_dln_longname_not_found         
  2192 00008ADE 80FC14              <1> 	cmp	ah, 14h ; 84-64=20 -> 20*13=260 bytes
  2193 00008AE1 77E1                <1> 	ja	short loc_dln_longname_not_found
  2194                              <1>              
  2195 00008AE3 C607E5              <1> 	mov	byte [edi], 0E5h  ; deleted sign
  2196 00008AE6 C605[E8E50000]02    <1> 	mov	byte [DirBuff_ValidData], 2 ; changed/write sign
  2197 00008AED C605[8EE80000]00    <1> 	mov	byte [DLN_40h], 0 ; 40h -> 0
  2198                              <1> 	  
  2199                              <1> loc_dln_delete_next_ln_entry:
  2200 00008AF4 80FC01              <1> 	cmp	ah, 1
  2201 00008AF7 7616                <1> 	jna	short loc_dln_longname_retn
  2202                              <1> loc_dln_delete_next_ln_entry_0:
  2203 00008AF9 66FF05[8CE80000]    <1> 	inc	word [DLN_EntryNumber]
  2204 00008B00 0FB705[8CE80000]    <1> 	movzx	eax, word [DLN_EntryNumber] 
  2205 00008B07 E80D000000          <1> 	call	locate_current_dir_entry
  2206 00008B0C 73BD                <1> 	jnc	short loc_dln_check_attributes
  2207                              <1> 
  2208                              <1> loc_dln_longname_stc_retn:
  2209 00008B0E 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 00008B0F E83BFEFFFF          <1> 	call	save_directory_buffer
  2215 00008B14 72F8                <1> 	jc	short loc_dln_longname_stc_retn
  2216                              <1> 
  2217                              <1> loc_dln_longname_retn_xor_eax:
  2218 00008B16 31C0                <1> 	xor	eax, eax
  2219 00008B18 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 00008B19 56                  <1> 	push	esi
  2244 00008B1A 89C1                <1> 	mov	ecx, eax
  2245 00008B1C BA20000000          <1> 	mov	edx, 32
  2246 00008B21 F7E2                <1> 	mul	edx 
  2247 00008B23 A3[98E80000]        <1> 	mov	[LCDE_ByteOffset], eax
  2248 00008B28 31DB                <1> 	xor	ebx, ebx
  2249 00008B2A 8A3D[BEDD0000]      <1> 	mov	bh, [Current_Drv]
  2250 00008B30 A0[E6E50000]        <1>         mov     al, [DirBuff_DRV]
  2251 00008B35 2C41                <1> 	sub	al, 'A'
  2252 00008B37 BE00010900          <1>         mov     esi, Logical_DOSDisks
  2253 00008B3C 01DE                <1> 	add	esi, ebx
  2254 00008B3E 38C7                <1> 	cmp	bh, al
  2255 00008B40 0F8592000000        <1>         jne     loc_lcde_reload_current_directory
  2256                              <1> loc_lcde_cdl_check:
  2257 00008B46 803D[BCDD0000]00    <1> 	cmp	byte [Current_Dir_Level], 0
  2258 00008B4D 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 00008B4F 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3  ; FAT32
  2263 00008B53 7324                <1> 	jnb	short loc_lcde_calc_dirbuff_cluster_offset
  2264                              <1> 
  2265                              <1> loc_lcde_cdl_check_FAT12_16:
  2266 00008B55 668B4617            <1> 	mov	ax, [esi+LD_BPB+RootDirEnts]
  2267 00008B59 6648                <1> 	dec	ax
  2268                              <1> 	;xor	dx, dx  
  2269 00008B5B 6639C8              <1> 	cmp	ax, cx ; cx = Directory Entry (Index) Number
  2270 00008B5E 720E                <1> 	jb	short loc_lcde_stc_12h_retn
  2271 00008B60 66890D[90E80000]    <1> 	mov	[LCDE_EntryIndex], cx
  2272 00008B67 31C0                <1> 	xor	eax, eax
  2273 00008B69 E993000000          <1>         jmp     loc_lcde_check_dir_buffer_cluster
  2274                              <1> 
  2275                              <1> loc_lcde_stc_12h_retn:
  2276 00008B6E 5E                  <1> 	pop	esi
  2277 00008B6F 89CB                <1> 	mov	ebx, ecx
  2278 00008B71 89D1                <1> 	mov	ecx, edx
  2279 00008B73 B812000000          <1> 	mov	eax, 12h ; No more files
  2280 00008B78 C3                  <1> 	retn 
  2281                              <1> 
  2282                              <1> loc_lcde_calc_dirbuff_cluster_offset:
  2283 00008B79 8A5E13              <1> 	mov	bl, [esi+LD_BPB+SecPerClust]
  2284 00008B7C 30FF                <1> 	xor	bh, bh
  2285 00008B7E 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec]
  2286 00008B82 66F7E3              <1> 	mul	bx
  2287 00008B85 6609D2              <1>  	or	dx, dx ; If bytes per cluster > 32KB it is invalid
  2288 00008B88 755D                <1> 	jnz	short loc_lcde_invalid_format
  2289                              <1> 	;mov	ecx, eax
  2290 00008B8A 6689C1              <1> 	mov	cx, ax ; BYTES PER CLUSTER
  2291 00008B8D A1[98E80000]        <1> 	mov	eax, [LCDE_ByteOffset]
  2292                              <1> 	;sub	edx, edx
  2293 00008B92 F7F1                <1> 	div	ecx
  2294 00008B94 3DFFFF0000          <1> 	cmp	eax, 65535
  2295 00008B99 774C                <1> 	ja	short loc_lcde_invalid_format
  2296                              <1> 
  2297                              <1> 	; cluster sequence number of directory (< 65536)
  2298 00008B9B 66A3[92E80000]      <1> 	mov	[LCDE_ClusterSN], ax 
  2299                              <1> 
  2300 00008BA1 6689D0              <1> 	mov	ax, dx ; byte offset in cluster (directory buffer)
  2301 00008BA4 66BB2000            <1> 	mov	bx, 32 ; ; 1 dir entry = 32 bytes
  2302 00008BA8 6629D2              <1>         sub     dx, dx  ; 0
  2303 00008BAB 66F7F3              <1> 	div	bx 
  2304 00008BAE 66A3[90E80000]      <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 00008BB4 A1[B8DD0000]        <1> 	mov	eax, [Current_Dir_FCluster]
  2308                              <1> 
  2309                              <1> loc_lcde_get_next_cluster:
  2310 00008BB9 66833D[92E80000]00  <1> 	cmp	word [LCDE_ClusterSN], 0
  2311 00008BC1 763E                <1> 	jna	short loc_lcde_check_dir_buffer_cluster
  2312 00008BC3 A3[94E80000]        <1> 	mov	[LCDE_Cluster], eax
  2313 00008BC8 E815100000          <1> 	call	get_next_cluster
  2314 00008BCD 7220                <1> 	jc	short loc_lcde_check_gnc_error
  2315 00008BCF 66FF0D[92E80000]    <1>   	dec	word [LCDE_ClusterSN]
  2316 00008BD6 EBE1                <1> 	jmp	short loc_lcde_get_next_cluster
  2317                              <1> 
  2318                              <1> loc_lcde_reload_current_directory:
  2319 00008BD8 51                  <1> 	push	ecx
  2320 00008BD9 E812F6FFFF          <1> 	call	reload_current_directory
  2321 00008BDE 59                  <1> 	pop	ecx
  2322 00008BDF 0F8361FFFFFF        <1>         jnc     loc_lcde_cdl_check
  2323 00008BE5 5E                  <1> 	pop	esi
  2324 00008BE6 C3                  <1> 	retn
  2325                              <1> 
  2326                              <1> loc_lcde_invalid_format:
  2327 00008BE7 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 00008BEC F9                  <1> 	stc
  2331 00008BED 5E                  <1> 	pop	esi 
  2332 00008BEE C3                  <1> 	retn  
  2333                              <1> 
  2334                              <1> loc_lcde_check_gnc_error:
  2335 00008BEF 09C0                <1> 	or	eax, eax
  2336 00008BF1 75F9                <1> 	jnz	short loc_lcde_drive_not_ready_read_err
  2337 00008BF3 66FF0D[92E80000]    <1> 	dec	word [LCDE_ClusterSN]
  2338 00008BFA 75EB                <1> 	jnz	short loc_lcde_invalid_format 
  2339 00008BFC A1[94E80000]        <1> 	mov	eax, [LCDE_Cluster]
  2340                              <1> 
  2341                              <1> loc_lcde_check_dir_buffer_cluster:
  2342 00008C01 3B05[EDE50000]      <1> 	cmp	eax, [DirBuff_Cluster]
  2343 00008C07 755C                <1> 	jne	short loc_lcde_load_dir_cluster
  2344 00008C09 803D[E8E50000]00    <1> 	cmp	byte [DirBuff_ValidData], 0
  2345 00008C10 7727                <1> 	ja	short lcde_check_dir_buffer_cluster_next
  2346 00008C12 803D[BCDD0000]00    <1> 	cmp	byte [Current_Dir_Level], 0    
  2347 00008C19 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 00008C1B 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3  ; FAT32
  2351 00008C1F 7359                <1> 	jnb	short loc_lcde_load_dir_cluster_0
  2352                              <1> 	;
  2353 00008C21 0FB74E17            <1> 	movzx	ecx, word [esi+LD_BPB+RootDirEnts]
  2354 00008C25 6683C10F            <1> 	add	cx, 15 ; round up (16 entries per sector)
  2355 00008C29 66C1E904            <1> 	shr	cx, 4 ; 1 sector contains 16 dir entries	
  2356                              <1> 
  2357 00008C2D 8B4664              <1>         mov     eax, [esi+LD_ROOTBegin]
  2358 00008C30 EB54                <1> 	jmp	short loc_lcde_load_dir_cluster_1 
  2359                              <1> 
  2360                              <1> loc_lcde_validate_dirBuff:
  2361 00008C32 C605[E8E50000]01    <1> 	mov	byte [DirBuff_ValidData], 1
  2362                              <1> 
  2363                              <1> lcde_check_dir_buffer_cluster_next:
  2364 00008C39 0FB71D[90E80000]    <1> 	movzx	ebx, word [LCDE_EntryIndex]
  2365 00008C40 663B1D[EBE50000]    <1> 	cmp	bx, [DirBuff_LastEntry]
  2366 00008C47 779E                <1> 	ja	short loc_lcde_invalid_format 
  2367 00008C49 B820000000          <1> 	mov	eax, 32
  2368 00008C4E F7E3                <1> 	mul	ebx
  2369                              <1> 	;or	edx, edx
  2370                              <1> 	;jnz	short loc_lcde_invalid_format
  2371                              <1> 
  2372 00008C50 BF00000800          <1> 	mov	edi, Directory_Buffer  
  2373 00008C55 01C7                <1> 	add	edi, eax ; add entry offset to buffer address
  2374                              <1> 
  2375                              <1> loc_lcde_dir_buffer_last_check:
  2376 00008C57 A1[EDE50000]        <1> 	mov	eax, [DirBuff_Cluster]
  2377 00008C5C 0FB60D[E8E50000]    <1> 	movzx	ecx, byte [DirBuff_ValidData]
  2378                              <1> 
  2379                              <1> loc_lcde_retn:
  2380 00008C63 5E                  <1> 	pop	esi
  2381 00008C64 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 00008C65 50                  <1> 	push	eax
  2387 00008C66 E8E4FCFFFF          <1> 	call	save_directory_buffer
  2388 00008C6B 58                  <1> 	pop	eax
  2389 00008C6C 72F5                <1> 	jc	short loc_lcde_retn
  2390                              <1> 
  2391                              <1> loc_lcde_load_dir_cluster_n2:
  2392 00008C6E C605[E8E50000]00    <1> 	mov	byte [DirBuff_ValidData], 0
  2393 00008C75 A3[EDE50000]        <1> 	mov	[DirBuff_Cluster], eax
  2394                              <1> 
  2395                              <1> loc_lcde_load_dir_cluster_0:
  2396 00008C7A 83E802              <1> 	sub	eax, 2
  2397 00008C7D 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  2398 00008C81 F7E1                <1> 	mul	ecx
  2399 00008C83 034668              <1>         add     eax, [esi+LD_DATABegin]
  2400                              <1> 
  2401                              <1> loc_lcde_load_dir_cluster_1:
  2402 00008C86 BB00000800          <1> 	mov	ebx, Directory_Buffer
  2403                              <1> 	; ecx = sector count
  2404 00008C8B E8AD370000          <1> 	call	disk_read
  2405 00008C90 73A0                <1> 	jnc	short loc_lcde_validate_dirBuff
  2406                              <1> 
  2407                              <1> 	; 23/03/2016
  2408 00008C92 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error !
  2409 00008C97 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 00008C99 29C0                <1> 	sub	eax, eax
  2423 00008C9B 88FC                <1> 	mov	ah, bh
  2424 00008C9D BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2425 00008CA2 01C6                <1> 	add	esi, eax
  2426                              <1> 
  2427 00008CA4 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  2428 00008CA8 7312                <1> 	jnb	short loc_del_fat_file 
  2429                              <1>               
  2430 00008CAA 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  2431 00008CAE 7406                <1> 	je	short loc_del_fs_file
  2432                              <1> 
  2433                              <1> loc_del_file_invalid_format:
  2434 00008CB0 30E4                <1> 	xor	ah, ah
  2435 00008CB2 B00B                <1> 	mov	al, 0Bh ; Invalid Format
  2436 00008CB4 F9                  <1> 	stc 
  2437 00008CB5 C3                  <1> 	retn
  2438                              <1> 
  2439                              <1> loc_del_fs_file:
  2440 00008CB6 E8200F0000          <1> 	call	delete_fs_file
  2441 00008CBB C3                  <1> 	retn
  2442                              <1> 
  2443                              <1> loc_del_fat_file:
  2444 00008CBC E808000000          <1> 	call	delete_directory_entry
  2445 00008CC1 7205                <1> 	jc	short loc_del_file_err_retn 
  2446                              <1> 
  2447                              <1> loc_delfile_unlink_cluster_chain:
  2448 00008CC3 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 00008CC8 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 00008CC9 881D[2AE80000]      <1> 	mov	[DelFile_LNEL], bl
  2474 00008CCF 66890D[28E80000]    <1> 	mov	[DelFile_EntryCounter], cx
  2475                              <1> 
  2476 00008CD6 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  2477 00008CDA C1E010              <1> 	shl	eax, 16
  2478 00008CDD 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  2479                              <1> 
  2480 00008CE1 A3[24E80000]        <1> 	mov	[DelFile_FCluster], eax
  2481                              <1> 
  2482                              <1> loc_del_short_name:
  2483 00008CE6 C607E5              <1> 	mov	byte [edi], 0E5h  ; Deleted sign
  2484                              <1> 
  2485 00008CE9 C605[E8E50000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  2486 00008CF0 E85AFCFFFF          <1> 	call	save_directory_buffer
  2487 00008CF5 723D                <1> 	jc	short loc_delete_direntry_err_return
  2488                              <1>  
  2489                              <1> loc_del_long_name:
  2490 00008CF7 0FB615[2AE80000]    <1> 	movzx	edx, byte [DelFile_LNEL]
  2491 00008CFE 08D2                <1> 	or	dl, dl
  2492 00008D00 7416                <1> 	jz	short loc_del_dir_entry_update_parent_dir_lm_date
  2493                              <1> 
  2494 00008D02 8835[2AE80000]      <1> 	mov	byte [DelFile_LNEL], dh ; 0              
  2495                              <1>   
  2496 00008D08 0FB705[28E80000]    <1> 	movzx	eax,  word [DelFile_EntryCounter]
  2497 00008D0F 29D0                <1> 	sub	eax, edx
  2498                              <1> 	;jnc	short loc_del_long_name_continue
  2499 00008D11 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 00008D13 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 00008D18 801D[2AE80000]00    <1> 	sbb	byte [DelFile_LNEL], 0 ; 0FFh if cf = 1
  2512                              <1> 
  2513 00008D1F E8C6FCFFFF          <1> 	call	update_parent_dir_lmdt
  2514 00008D24 B700                <1> 	mov	bh, 0
  2515 00008D26 80D700              <1> 	adc	bh, 0
  2516                              <1> 
  2517 00008D29 8A1D[2AE80000]      <1> 	mov	bl, byte [DelFile_LNEL]
  2518                              <1>  
  2519                              <1> loc_delete_direntry_return:
  2520 00008D2F A1[24E80000]        <1> 	mov	eax, [DelFile_FCluster]
  2521                              <1> loc_delete_direntry_err_return:
  2522 00008D34 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 00008D35 803D[BDDD0000]00    <1> 	cmp	byte [Current_FATType], 0
  2541 00008D3C 7706                <1> 	ja	short loc_rename_directory_entry
  2542                              <1> 
  2543 00008D3E E8990E0000          <1> 	call	rename_fs_file_or_directory
  2544 00008D43 C3                  <1> 	retn 
  2545                              <1> 	
  2546                              <1> loc_rename_directory_entry:
  2547 00008D44 881D[2AE80000]      <1> 	mov	[DelFile_LNEL], bl
  2548 00008D4A 66890D[28E80000]    <1> 	mov	[DelFile_EntryCounter], cx
  2549 00008D51 A3[24E80000]        <1> 	mov	[DelFile_FCluster], eax
  2550                              <1> 
  2551 00008D56 0FB7C1              <1> 	movzx	eax, cx
  2552 00008D59 E8BBFDFFFF          <1> 	call	locate_current_dir_entry
  2553 00008D5E 7308                <1> 	jnc	short loc_rename_direntry_check_fcluster
  2554                              <1> 
  2555                              <1> loc_rename_direntry_pop_retn:
  2556 00008D60 C3                  <1> 	retn
  2557                              <1> 
  2558                              <1> loc_rename_direntry_pop_invd_retn:
  2559 00008D61 F9                  <1> 	stc
  2560                              <1> loc_rename_direntry_invd_retn:
  2561 00008D62 B80D000000          <1> 	mov	eax, 0Dh ; Invalid data
  2562                              <1> loc_rename_retn:
  2563 00008D67 C3                  <1> 	retn 
  2564                              <1> 
  2565                              <1> loc_rename_direntry_check_fcluster:
  2566 00008D68 668B5714            <1> 	mov	dx, [edi+20] ; First Cluster HW
  2567 00008D6C 66C1E210            <1> 	shl	dx, 16
  2568 00008D70 668B571A            <1> 	mov	dx, [edi+26] ; First Cluster LW
  2569 00008D74 3B15[24E80000]      <1> 	cmp	edx, [DelFile_FCluster]
  2570 00008D7A 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 00008D7C E89FF6FFFF          <1> 	call	convert_file_name
  2581                              <1> 
  2582 00008D81 C605[E8E50000]02    <1>         mov     byte [DirBuff_ValidData], 2
  2583 00008D88 E8C2FBFFFF          <1> 	call	save_directory_buffer
  2584 00008D8D 72D8                <1> 	jc	short loc_rename_retn
  2585                              <1> 
  2586                              <1> loc_rename_direntry_del_ln:
  2587 00008D8F 0FB615[2AE80000]    <1> 	movzx	edx, byte [DelFile_LNEL]
  2588 00008D96 08D2                <1> 	or	dl, dl
  2589 00008D98 7410                <1> 	jz	short loc_rename_direntry_update_parent_dir_lm_date
  2590                              <1> 
  2591 00008D9A 0FB705[28E80000]    <1> 	movzx	eax, word [DelFile_EntryCounter]
  2592 00008DA1 29D0                <1> 	sub	eax, edx
  2593 00008DA3 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 00008DA5 E805FDFFFF          <1> 	call	delete_longname
  2598                              <1> 
  2599                              <1> loc_rename_direntry_update_parent_dir_lm_date:
  2600 00008DAA E83BFCFFFF          <1> 	call	update_parent_dir_lmdt
  2601 00008DAF 31C0                <1> 	xor	eax, eax 
  2602 00008DB1 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 00008DB2 3C02                <1> 	cmp	al, 2
  2643 00008DB4 0F846D010000        <1> 	je	msftdf_df2_check_directory
  2644 00008DBA A2[A6E90000]        <1> 	mov	[move_cmd_phase], al
  2645                              <1> 
  2646                              <1> msftdf_parse_sf_path:
  2647                              <1> 	; ESI = ASCIIZ pathname (Source)
  2648 00008DBF 57                  <1> 	push	edi 
  2649 00008DC0 BF[A4E80000]        <1> 	mov	edi, SourceFile_Drv
  2650 00008DC5 E821F7FFFF          <1> 	call	parse_path_name
  2651 00008DCA 5E                  <1> 	pop	esi
  2652 00008DCB 7211                <1> 	jc	short msftdf_psf_retn
  2653                              <1> 
  2654                              <1> msftdf_parse_df_path:
  2655                              <1> 	; ESI = ASCIIZ pathname	(Destination)
  2656 00008DCD BF[24E90000]        <1> 	mov	edi, DestinationFile_Drv
  2657 00008DD2 E814F7FFFF          <1> 	call	parse_path_name
  2658 00008DD7 7306                <1> 	jnc	short msftdf_check_sf_drv
  2659                              <1> 
  2660 00008DD9 3C01                <1> 	cmp	al, 1 ; File or directory name is not existing
  2661 00008DDB 7602                <1> 	jna	short msftdf_check_sf_drv
  2662                              <1> 
  2663                              <1> msftdf_stc_retn:
  2664 00008DDD F9                  <1> 	stc
  2665                              <1> msftdf_psf_retn:
  2666 00008DDE C3                  <1> 	retn 
  2667                              <1> 
  2668                              <1> msftdf_check_sf_drv:
  2669 00008DDF A0[A4E80000]        <1> 	mov	al, [SourceFile_Drv]
  2670                              <1> 
  2671                              <1> msftdf_check_df_drv:
  2672 00008DE4 8A15[24E90000]      <1> 	mov	dl, [DestinationFile_Drv]
  2673                              <1> 
  2674                              <1> msftdf_compare_sf_df_drv:
  2675 00008DEA 29DB                <1> 	sub	ebx, ebx
  2676 00008DEC 8A3D[BEDD0000]      <1> 	mov	bh, [Current_Drv]
  2677 00008DF2 38C2                <1> 	cmp	dl, al
  2678 00008DF4 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 00008DF6 88C6                <1> 	mov	dh, al ; destination file's drive number
  2683 00008DF8 B811000000          <1> 	mov	eax, 11h ; Not the same drive
  2684 00008DFD F9                  <1> 	stc
  2685 00008DFE C3                  <1> 	retn 
  2686                              <1> 
  2687                              <1> msftdf_check_sf_df_drv_ok:
  2688 00008DFF 8815[A7E90000]      <1> 	mov	[msftdf_sf_df_drv], dl
  2689                              <1> 
  2690 00008E05 29C0                <1>         sub	eax, eax
  2691 00008E07 88D4                <1> 	mov	ah, dl
  2692 00008E09 0500010900          <1> 	add	eax, Logical_DOSDisks
  2693 00008E0E A3[A8E90000]        <1> 	mov	[msftdf_drv_offset], eax
  2694                              <1> 
  2695 00008E13 38FA                <1> 	cmp	dl, bh ; byte [Current_Drv]
  2696 00008E15 7407                <1> 	je	short msftdf_df_check_directory
  2697                              <1> 
  2698                              <1> msftdf_change_drv:
  2699 00008E17 E829C1FFFF          <1> 	call 	change_current_drive
  2700 00008E1C 725B                <1> 	jc	short msftdf_df_error_retn
  2701                              <1> 	  
  2702                              <1> msftdf_check_destination_file:
  2703                              <1> msftdf_df_check_directory:
  2704 00008E1E BE[25E90000]        <1> 	mov	esi, DestinationFile_Directory
  2705 00008E23 803E20              <1> 	cmp	byte [esi], 20h
  2706 00008E26 760F                <1> 	jna	short msftdf_df_find_1
  2707                              <1> 
  2708                              <1> msftdf_df_change_directory:
  2709 00008E28 FE05[29C80000]      <1> 	inc	byte [Restore_CDIR]
  2710 00008E2E 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2711 00008E30 E8A2F0FFFF          <1> 	call	change_current_directory
  2712 00008E35 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 00008E37 BE[66E90000]        <1>         mov     esi, DestinationFile_Name
  2719 00008E3C 803E20              <1> 	cmp	byte [esi], 20h
  2720 00008E3F 761F                <1> 	jna	short msftdf_df_copy_sf_name
  2721                              <1> 
  2722                              <1> msftdf_df_find_2:
  2723 00008E41 6631C0              <1> 	xor	ax, ax ; DestinationFile_AttributesMask -> any/zero
  2724 00008E44 E898D4FFFF          <1> 	call	find_first_file
  2725 00008E49 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 00008E4B 3C02                <1> 	cmp	al, 2
  2730 00008E4D 7529                <1> 	jne	short msftdf_df_stc_retn
  2731                              <1>               
  2732                              <1> msftdf_convert_df_direntry_name:
  2733 00008E4F BE[66E90000]        <1> 	mov	esi, DestinationFile_Name
  2734 00008E54 BF[76E90000]        <1> 	mov	edi, DestinationFile_DirEntry
  2735 00008E59 E8C2F5FFFF          <1> 	call	convert_file_name
  2736 00008E5E EB1A                <1>   	jmp	short msftdf_restore_current_dir_1
  2737                              <1> 
  2738                              <1> msftdf_df_copy_sf_name:
  2739 00008E60 89F7                <1> 	mov	edi, esi
  2740 00008E62 57                  <1> 	push	edi 
  2741 00008E63 BE[E6E80000]        <1>         mov     esi, SourceFile_Name
  2742 00008E68 B90C000000          <1> 	mov	ecx, 12
  2743                              <1> msftdf_df_copy_sf_name_loop:
  2744 00008E6D AC                  <1> 	lodsb
  2745 00008E6E AA                  <1>         stosb
  2746 00008E6F 08C0                <1> 	or	al, al
  2747 00008E71 7402                <1> 	jz	short msftdf_df_copy_sf_name_ok	
  2748 00008E73 E2F8                <1>         loop    msftdf_df_copy_sf_name_loop
  2749                              <1> msftdf_df_copy_sf_name_ok:	
  2750 00008E75 5E                  <1> 	pop	esi  
  2751 00008E76 EBC9                <1> 	jmp	short msftdf_df_find_2
  2752                              <1> 
  2753                              <1> msftdf_df_stc_retn:
  2754 00008E78 F9                  <1> 	stc
  2755                              <1> msftdf_restore_cdir_failed:
  2756                              <1> msftdf_df_error_retn:
  2757 00008E79 C3                  <1> 	retn
  2758                              <1> 
  2759                              <1> msftdf_restore_current_dir_1:
  2760 00008E7A 803D[29C80000]00    <1> 	cmp	byte [Restore_CDIR], 0
  2761 00008E81 760D                <1> 	jna	short msftdf_sf_check_directory
  2762 00008E83 8B35[A8E90000]      <1> 	mov	esi, [msftdf_drv_offset] 
  2763 00008E89 E869C1FFFF          <1> 	call	restore_current_directory
  2764 00008E8E 72E9                <1> 	jc	short msftdf_restore_cdir_failed
  2765                              <1> 
  2766                              <1> msftdf_sf_check_directory:
  2767 00008E90 BE[A5E80000]        <1> 	mov	esi, SourceFile_Directory
  2768 00008E95 803E20              <1> 	cmp	byte [esi], 20h
  2769 00008E98 760F                <1> 	jna	short msftdf_sf_find
  2770                              <1> msftdf_sf_change_directory:
  2771 00008E9A FE05[29C80000]      <1> 	inc	byte [Restore_CDIR]
  2772 00008EA0 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2773 00008EA2 E830F0FFFF          <1> 	call	change_current_directory
  2774 00008EA7 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 00008EA9 BE[E6E80000]        <1>         mov     esi, SourceFile_Name  ; Offset 66
  2781 00008EAE 66B80018            <1> 	mov	ax, 1800h ; Only files
  2782 00008EB2 E82AD4FFFF          <1> 	call	find_first_file
  2783 00008EB7 7217                <1> 	jc	short msftdf_return
  2784                              <1> 
  2785                              <1> msftdf_sf_ambgfn_check:
  2786 00008EB9 6609D2              <1> 	or	dx, dx ; Ambiguous filename chars used sign (DX>0)
  2787 00008EBC 7407                <1> 	jz	short msftdf_sf_found
  2788                              <1> 
  2789                              <1> msftdf_ambiguous_file_name_error:
  2790 00008EBE B802000000          <1> 	mov	eax, 2 ; File not found error
  2791 00008EC3 F9                  <1> 	stc
  2792 00008EC4 C3                  <1> 	retn
  2793                              <1> 
  2794                              <1> msftdf_sf_found:
  2795 00008EC5 80E31F              <1> 	and	bl, 1Fh ; Attributes, D-V-S-H-R
  2796 00008EC8 7416                <1> 	jz	short msftdf_save_sf_structure
  2797                              <1> 
  2798                              <1> msftdf_permission_denied_retn:
  2799 00008ECA B805000000          <1> 	mov	eax, 05h ; Access (Permission) denied !
  2800 00008ECF F9                  <1> 	stc
  2801                              <1> msftdf_rest_cdir_err_retn:
  2802                              <1> msftdf_return:
  2803 00008ED0 C3                  <1> 	retn
  2804                              <1> 
  2805                              <1> msftdf_phase_1_return:
  2806 00008ED1 31C0                <1> 	xor	eax, eax
  2807 00008ED3 A2[A6E90000]        <1> 	mov	[move_cmd_phase], al ; 0
  2808 00008ED8 FEC0                <1> 	inc	al ; mov al, 1
  2809 00008EDA BB[278F0000]        <1> 	mov	ebx, msftdf_df2_check_directory
  2810                              <1> 	;mov	edx, 0FFFFFFFFh 
  2811 00008EDF C3                  <1> 	retn
  2812                              <1> 
  2813                              <1> msftdf_save_sf_structure:
  2814 00008EE0 BE[B4E70000]        <1> 	mov	esi, FindFile_DirEntry
  2815 00008EE5 BF[F6E80000]        <1> 	mov	edi, SourceFile_DirEntry
  2816 00008EEA B908000000          <1> 	mov	ecx, 8
  2817 00008EEF F3A5                <1> 	rep	movsd
  2818                              <1> 
  2819                              <1> msftdf_df_copy_sf_parameters:
  2820 00008EF1 BE0B000000          <1> 	mov	esi, 11
  2821 00008EF6 89F7                <1> 	mov	edi, esi
  2822 00008EF8 81C6[F6E80000]      <1> 	add	esi, SourceFile_DirEntry
  2823 00008EFE 81C7[76E90000]      <1> 	add	edi, DestinationFile_DirEntry
  2824                              <1> 	;mov	ecx, 21
  2825 00008F04 B115                <1> 	mov	cl, 21
  2826 00008F06 F3A4                <1> 	rep	movsb
  2827                              <1> 
  2828                              <1> msftdf_restore_current_dir_2:
  2829 00008F08 803D[29C80000]00    <1> 	cmp	byte [Restore_CDIR], 0
  2830 00008F0F 760D                <1> 	jna	short msftdf_df2_check_move_cmd_phase
  2831 00008F11 8B35[A8E90000]      <1>  	mov	esi, [msftdf_drv_offset]
  2832 00008F17 E8DBC0FFFF          <1> 	call	restore_current_directory
  2833 00008F1C 72B2                <1> 	jc	short msftdf_rest_cdir_err_retn
  2834                              <1> 
  2835                              <1> msftdf_df2_check_move_cmd_phase:
  2836 00008F1E 803D[A6E90000]01    <1> 	cmp	byte [move_cmd_phase], 1
  2837 00008F25 74AA                <1> 	je	short msftdf_phase_1_return
  2838                              <1> 
  2839                              <1> msftdf_df2_check_directory:
  2840 00008F27 BE[25E90000]        <1> 	mov	esi, DestinationFile_Directory
  2841 00008F2C 803E20              <1> 	cmp	byte [esi], 20h
  2842 00008F2F 760F                <1> 	jna	short msftdf_make_dfde_locate_ffe_on_directory
  2843                              <1> msftdf_df2_change_directory:
  2844 00008F31 FE05[29C80000]      <1> 	inc	byte [Restore_CDIR]
  2845 00008F37 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2846 00008F39 E899EFFFFF          <1> 	call	change_current_directory
  2847 00008F3E 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 00008F40 31C0                <1> 	xor	eax, eax
  2859 00008F42 89C1                <1> 	mov	ecx, eax
  2860 00008F44 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 00008F46 E8E0F1FFFF          <1> 	call	locate_current_dir_file
  2865 00008F4B 733F                <1> 	jnc	msftdf_make_dfde_set_ff_dir_entry
  2866                              <1> 	
  2867                              <1> 	;cmp	eax, 2
  2868 00008F4D 3C02                <1>         cmp	al, 2
  2869 00008F4F 7537                <1> 	jne	short msftdf_error_retn
  2870                              <1> 
  2871                              <1> msftdf_add_new_dir_entry_check_fs:
  2872 00008F51 8B35[A8E90000]      <1> 	mov	esi, [msftdf_drv_offset]
  2873 00008F57 A1[EDE50000]        <1> 	mov 	eax, [DirBuff_Cluster]
  2874 00008F5C 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  2875 00008F60 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 00008F62 30ED                <1> 	xor	ch, ch ; cx = 0 --> add a new subdir section
  2881 00008F64 E8750C0000          <1> 	call	add_new_fs_section
  2882 00008F69 721E                <1>         jc	short msftdf_dsfde_error_retn
  2883                              <1> 	;mov	[createfile_LastDirCluster], eax
  2884                              <1> 
  2885 00008F6B E8950E0000          <1> 	call	load_FS_sub_directory 
  2886                              <1> 	;mov	ebx, Directory_Buffer 
  2887 00008F70 7318                <1> 	jnc	short msftdf_add_new_fs_subdir_section_ok
  2888 00008F72 C3                  <1> 	retn	 
  2889                              <1> 
  2890                              <1> msftdf_add_new_subdir_cluster:
  2891 00008F73 E863150000          <1> 	call	add_new_cluster
  2892 00008F78 720F                <1> 	jc	short msftdf_dsfde_error_retn
  2893                              <1> 	
  2894                              <1> 	;mov	[createfile_LastDirCluster], eax
  2895                              <1> 
  2896 00008F7A E8490E0000          <1> 	call	load_FAT_sub_directory
  2897 00008F7F 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 00008F81 50                  <1> 	push	eax
  2903 00008F82 E863FAFFFF          <1> 	call	update_parent_dir_lmdt
  2904 00008F87 58                  <1> 	pop	eax
  2905                              <1> 
  2906                              <1> msftdf_error_retn:
  2907 00008F88 F9                  <1> 	stc
  2908                              <1> msftdf_dsfde_restore_cdir_failed:
  2909                              <1> msftdf_dsfde_error_retn:
  2910 00008F89 C3                  <1> 	retn
  2911                              <1> 
  2912                              <1> msftdf_add_new_fs_subdir_section_ok:
  2913                              <1> msftdf_add_new_subdir_cluster_ok:
  2914 00008F8A 89DF                <1> 	mov	edi, ebx ; Directory buffer address
  2915                              <1> 
  2916                              <1> msftdf_make_dfde_set_ff_dir_entry:
  2917 00008F8C 8B15[B8DD0000]      <1> 	mov	edx, [Current_Dir_FCluster]
  2918 00008F92 8915[0CEA0000]      <1> 	mov	[createfile_FFCluster], edx
  2919                              <1> 	; EDI = Directory entry offset
  2920 00008F98 BE[76E90000]        <1> 	mov	esi, DestinationFile_DirEntry
  2921 00008F9D B908000000          <1> 	mov	ecx, 8
  2922 00008FA2 F3A5                <1> 	rep	movsd
  2923                              <1> 
  2924 00008FA4 C605[E8E50000]02    <1> 	mov	byte [DirBuff_ValidData], 2 
  2925 00008FAB E89FF9FFFF          <1> 	call	save_directory_buffer
  2926 00008FB0 72CF                <1> 	jc	short msftdf_make_dfde_err_upd_pdir_lmdt
  2927                              <1> 
  2928                              <1> msftdf_make_dfde_update_pdir_lmdt:
  2929 00008FB2 E833FAFFFF          <1> 	call	update_parent_dir_lmdt
  2930                              <1> 
  2931                              <1> msftdf_dsfde_restore_current_dir_1:
  2932 00008FB7 803D[29C80000]00    <1> 	cmp	byte [Restore_CDIR], 0
  2933 00008FBE 760D                <1> 	jna	short msftdf_dsfde_check_directory
  2934 00008FC0 8B35[A8E90000]      <1>  	mov	esi, [msftdf_drv_offset]
  2935 00008FC6 E82CC0FFFF          <1> 	call	restore_current_directory
  2936 00008FCB 72BC                <1> 	jc	short msftdf_dsfde_restore_cdir_failed
  2937                              <1> 
  2938                              <1> msftdf_dsfde_check_directory:
  2939 00008FCD BE[A5E80000]        <1> 	mov	esi, SourceFile_Directory
  2940 00008FD2 803E20              <1> 	cmp	byte [esi], 20h
  2941 00008FD5 760F                <1> 	jna	short msftdf_dsfde_find_file
  2942                              <1> 
  2943                              <1> msftdf_dsfde_change_directory:
  2944 00008FD7 FE05[29C80000]      <1> 	inc	byte [Restore_CDIR]
  2945 00008FDD 28E4                <1> 	sub	ah, ah ; CD_COMMAND sign -> 0 
  2946 00008FDF E8F3EEFFFF          <1> 	call	change_current_directory
  2947 00008FE4 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 00008FE6 BE[E6E80000]        <1> 	mov	esi, SourceFile_Name  ; Offset 66
  2954 00008FEB 668B460E            <1> 	mov	ax, [esi+14] ; 80 -> SourceFile_AttributesMask
  2955 00008FEF E8EDD2FFFF          <1> 	call	find_first_file
  2956 00008FF4 7293                <1> 	jc	short msftdf_dsfde_error_retn
  2957                              <1> 
  2958                              <1> msftdf_dsfde_delete_direntry:
  2959 00008FF6 8B35[A8E90000]      <1> 	mov	esi, [msftdf_drv_offset]
  2960                              <1> 	
  2961 00008FFC 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  2962 00009000 770A                <1> 	ja	short msftdf_delete_FAT_direntry
  2963                              <1> 	
  2964 00009002 30DB                <1> 	xor	bl, bl
  2965                              <1> 	; BL = 0 -> File
  2966                              <1> 	; EDI -> Directory buffer entry offset/address 
  2967 00009004 E8D60B0000          <1> 	call	delete_fs_directory_entry
  2968 00009009 7315                <1> 	jnc	short msftdf_dsfde_restore_current_dir_2
  2969 0000900B C3                  <1> 	retn
  2970                              <1> 
  2971                              <1> msftdf_delete_FAT_direntry:	
  2972 0000900C 8A1D[B1E70000]      <1> 	mov	bl, [FindFile_LongNameEntryLength]
  2973 00009012 668B0D[DCE70000]    <1> 	mov	cx, [FindFile_DirEntryNumber]
  2974                              <1> 	; ESI = Logical DOS drive description table address
  2975                              <1> 	; EDI = Directory buffer entry offset/address 
  2976 00009019 E8ABFCFFFF          <1> 	call	delete_directory_entry
  2977 0000901E 721C                <1> 	jc	short msftdf_retn
  2978                              <1> 
  2979                              <1> msftdf_dsfde_restore_current_dir_2:
  2980 00009020 803D[29C80000]00    <1> 	cmp	byte [Restore_CDIR], 0
  2981 00009027 7607                <1> 	jna	short msftdf_new_dir_fcluster_retn
  2982                              <1> 	;mov	esi, [msftdf_drv_offset]
  2983 00009029 E8C9BFFFFF          <1> 	call	restore_current_directory
  2984 0000902E 720C                <1> 	jc	short msftdf_retn
  2985                              <1> 
  2986                              <1> msftdf_new_dir_fcluster_retn:
  2987 00009030 31C9                <1> 	xor	ecx, ecx 
  2988 00009032 A1[0CEA0000]        <1> 	mov	eax, [createfile_FFCluster]
  2989 00009037 BB[24E90000]        <1> 	mov	ebx, DestinationFile_Drv
  2990                              <1> 
  2991                              <1> msftdf_retn:
  2992 0000903C 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 0000903D 3C02                <1> 	cmp	al, 2
  3053 0000903F 0F844C020000        <1> 	je	csftdf2_check_cdrv
  3054                              <1> 
  3055                              <1> ; Phase 1
  3056                              <1> 
  3057 00009045 A2[CCE90000]        <1> 	mov	byte [copy_cmd_phase], al
  3058                              <1> 
  3059 0000904A 57                  <1> 	push	edi ; *
  3060                              <1> 
  3061                              <1> csftdf_parse_sf_path:
  3062 0000904B BF[A4E80000]        <1> 	mov	edi, SourceFile_Drv
  3063 00009050 E896F4FFFF          <1> 	call	parse_path_name
  3064 00009055 721C                <1> 	jc	short csftdf_parse_sf_path_failed
  3065                              <1> 
  3066                              <1> csftdf_parse_df_path:	
  3067 00009057 5E                  <1> 	pop	esi ; * (pushed edi) 
  3068                              <1> 
  3069                              <1> csftdf_sf_check_filename_exists:
  3070 00009058 803D[E6E80000]21    <1> 	cmp	byte [SourceFile_Name], 21h
  3071 0000905F 7215                <1> 	jb	short csftdf_sf_file_not_found_error
  3072                              <1> 
  3073 00009061 BF[24E90000]        <1> 	mov	edi, DestinationFile_Drv
  3074 00009066 E880F4FFFF          <1> 	call	parse_path_name
  3075 0000906B 7310                <1> 	jnc	short csftdf_check_sf_cdrv
  3076                              <1> 	
  3077 0000906D 3C01                <1> 	cmp	al, 1 ; File or directory name is not existing
  3078 0000906F 760C                <1> 	jna	short csftdf_check_sf_cdrv
  3079                              <1> 
  3080                              <1> csftdf_parse_df_path_failed:
  3081 00009071 F9                  <1> 	stc 
  3082                              <1> csftdf_sf_error_retn: 
  3083 00009072 C3                  <1> 	retn
  3084                              <1> 
  3085                              <1> csftdf_parse_sf_path_failed:	
  3086 00009073 5F                  <1> 	pop	edi ; *
  3087 00009074 EBFC                <1> 	jmp	short csftdf_sf_error_retn
  3088                              <1> 
  3089                              <1> csftdf_sf_file_not_found_error:
  3090 00009076 B802000000          <1> 	mov	eax, 2 ; File not found 
  3091 0000907B EBF5                <1> 	jmp	short csftdf_sf_error_retn
  3092                              <1> 
  3093                              <1> csftdf_check_sf_cdrv:
  3094 0000907D 8A3D[BEDD0000]      <1> 	mov	bh, [Current_Drv]
  3095                              <1> 
  3096 00009083 883D[CFE90000]      <1> 	mov	[csftdf_cdrv], bh ; 23/03/2016
  3097                              <1> 
  3098 00009089 8A15[A4E80000]      <1> 	mov	dl, [SourceFile_Drv]
  3099 0000908F 38FA                <1> 	cmp	dl, bh ; byte [Current_Drv]
  3100 00009091 7407                <1> 	je	short csftdf_sf_check_directory
  3101                              <1> 
  3102 00009093 E8ADBEFFFF          <1> 	call	change_current_drive
  3103 00009098 72D8                <1> 	jc	short csftdf_sf_error_retn
  3104                              <1> 
  3105                              <1> csftdf_sf_check_directory:
  3106 0000909A BE[A5E80000]        <1> 	mov	esi, SourceFile_Directory
  3107 0000909F 803E20              <1> 	cmp	byte [esi], 20h
  3108 000090A2 760F                <1> 	jna	short csftdf_find_sf
  3109                              <1> 
  3110                              <1> csftdf_sf_change_directory:
  3111 000090A4 FE05[29C80000]      <1> 	inc	byte [Restore_CDIR]
  3112 000090AA 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3113 000090AC E826EEFFFF          <1> 	call	change_current_directory
  3114 000090B1 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 000090B3 BE[E6E80000]        <1> 	mov	esi, SourceFile_Name
  3121 000090B8 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  3122 000090BC E820D2FFFF          <1> 	call	find_first_file
  3123 000090C1 72AF                <1> 	jc	short csftdf_sf_error_retn
  3124                              <1> 
  3125                              <1> csftdf_sf_ambgfn_check:
  3126 000090C3 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3127 000090C6 7407                <1> 	jz	short csftdf_sf_found
  3128                              <1> 
  3129                              <1> csftdf_ambiguous_file_name_error:
  3130 000090C8 B802000000          <1> 	mov	eax, 2 ; File not found error
  3131 000090CD F9                  <1> 	stc
  3132 000090CE C3                  <1> 	retn
  3133                              <1> 
  3134                              <1> csftdf_sf_found:
  3135 000090CF A3[D0E90000]        <1> 	mov	[csftdf_filesize], eax
  3136                              <1> 
  3137 000090D4 09C0                <1> 	or	eax, eax
  3138 000090D6 7507                <1> 	jnz	short csftdf_set_source_file_direnry
  3139                              <1> 
  3140                              <1> csftdf_sf_file_size_zero:
  3141 000090D8 B80E000000          <1> 	mov	eax, 0Eh ; TRDOS zero length error
  3142 000090DD F9                  <1> 	stc
  3143 000090DE C3                  <1> 	retn
  3144                              <1> 
  3145                              <1> csftdf_set_source_file_direnry:
  3146 000090DF BE[B4E70000]        <1> 	mov	esi, FindFile_DirEntry
  3147 000090E4 BF[F6E80000]        <1> 	mov	edi, SourceFile_DirEntry
  3148 000090E9 B908000000          <1> 	mov	ecx, 8
  3149 000090EE F3A5                <1> 	rep	movsd
  3150                              <1> 
  3151                              <1> csftdf_sf_restore_cdrv:
  3152                              <1> 	; 22/03/2016
  3153 000090F0 8A15[CFE90000]      <1> 	mov	dl, [csftdf_cdrv]
  3154 000090F6 3A15[BEDD0000]      <1> 	cmp	dl, [Current_Drv]
  3155 000090FC 7407                <1> 	je	short csftdf_sf_restore_cdir
  3156 000090FE E842BEFFFF          <1> 	call	change_current_drive 
  3157 00009103 724F                <1> 	jc	short csftdf_df_error_retn ; 30/03/2016
  3158                              <1> 
  3159                              <1> csftdf_sf_restore_cdir:
  3160 00009105 803D[29C80000]00    <1> 	cmp	byte [Restore_CDIR], 0
  3161 0000910C 7612                <1> 	jna	short csftdf_df_check_filename_exists
  3162 0000910E 29C0                <1> 	sub	eax, eax
  3163 00009110 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3164 00009115 88D4                <1> 	mov	ah, dl ; byte [csftdf_cdrv]
  3165 00009117 01C6                <1> 	add	esi, eax
  3166 00009119 E8D9BEFFFF          <1> 	call	restore_current_directory
  3167 0000911E 7234                <1> 	jc	short csftdf_df_error_retn
  3168                              <1>   
  3169                              <1> csftdf_df_check_filename_exists:
  3170 00009120 803D[66E90000]20    <1> 	cmp	byte [DestinationFile_Name], 20h
  3171 00009127 7716                <1> 	ja	short csftdf_check_df_cdrv
  3172                              <1> 
  3173                              <1> csftdf_copy_sf_name:
  3174 00009129 BF[66E90000]        <1> 	mov	edi, DestinationFile_Name
  3175 0000912E BE[E6E80000]        <1> 	mov	esi, SourceFile_Name
  3176 00009133 B10C                <1> 	mov	cl, 12
  3177                              <1> 
  3178                              <1> csftdf_df_copy_sf_name_loop:
  3179 00009135 AC                  <1> 	lodsb
  3180 00009136 AA                  <1> 	stosb
  3181 00009137 08C0                <1> 	or	al, al
  3182 00009139 7404                <1> 	jz	short csftdf_check_df_cdrv             
  3183 0000913B FEC9                <1> 	dec	cl
  3184 0000913D 75F6                <1> 	jnz	csftdf_df_copy_sf_name_loop
  3185                              <1> 
  3186                              <1> csftdf_check_df_cdrv:
  3187 0000913F 8A15[24E90000]      <1> 	mov	dl, [DestinationFile_Drv]
  3188 00009145 3A15[BEDD0000]      <1> 	cmp	dl, [Current_Drv]
  3189 0000914B 7408                <1> 	je	short csftdf_df_check_directory
  3190                              <1> 
  3191 0000914D E8F3BDFFFF          <1> 	call	change_current_drive
  3192 00009152 7301                <1> 	jnc	short csftdf_df_check_directory
  3193                              <1> 
  3194                              <1> csftdf_df_error_retn:
  3195 00009154 C3                  <1> 	retn
  3196                              <1> 
  3197                              <1> csftdf_df_check_directory:
  3198 00009155 BE[25E90000]        <1> 	mov	esi, DestinationFile_Directory
  3199 0000915A 803E20              <1>         cmp     byte [esi], 20h
  3200 0000915D 760F                <1> 	jna	short csftdf_find_df
  3201                              <1> 
  3202                              <1> csftdf_df_change_directory:
  3203 0000915F FE05[29C80000]      <1> 	inc	byte [Restore_CDIR]
  3204 00009165 28E4                <1> 	sub	ah, ah ; CD_COMMAND sign -> 0 
  3205 00009167 E86BEDFFFF          <1> 	call	change_current_directory
  3206 0000916C 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 0000916E 29DB                <1> 	sub	ebx, ebx
  3214 00009170 8A3D[24E90000]      <1> 	mov	bh,  [DestinationFile_Drv]
  3215 00009176 81C300010900        <1> 	add	ebx, Logical_DOSDisks
  3216 0000917C 891D[FCE90000]      <1> 	mov	[csftdf_df_drv_dt], ebx
  3217                              <1> 
  3218 00009182 BE[66E90000]        <1> 	mov	esi, DestinationFile_Name
  3219 00009187 6631C0              <1> 	xor	ax, ax 
  3220                              <1> 		; DestinationFile_AttributesMask -> any/zero
  3221 0000918A E852D1FFFF          <1> 	call	find_first_file
  3222 0000918F 7218                <1> 	jc	short csftdf_df_check_error_code
  3223                              <1> 
  3224                              <1> csftdf_df_ambgfn_check:
  3225 00009191 6609D2              <1> 	or	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3226 00009194 7511                <1> 	jnz	short csftdf_df_error_stc_retn
  3227                              <1> 	
  3228                              <1> csftdf_df_found:
  3229 00009196 C605[CEE90000]01    <1> 	mov	byte [DestinationFileFound], 1
  3230 0000919D 80E11F              <1> 	and	cl, 1Fh ; Attributes, D-V-S-H-R
  3231 000091A0 7451                <1> 	jz	short csftdf_df_save_first_cluster
  3232                              <1> 
  3233                              <1> csftdf_df_permission_denied_retn:	 
  3234 000091A2 B805000000          <1> 	mov	eax, 05h ; Access/Permisson denied.
  3235                              <1> csftdf_df_error_stc_retn:
  3236 000091A7 F9                  <1> 	stc
  3237 000091A8 C3                  <1> 	retn
  3238                              <1> 
  3239                              <1> csftdf_df_check_error_code:
  3240                              <1> 	;cmp	eax, 2
  3241 000091A9 3C02                <1> 	cmp	al, 2
  3242 000091AB 75FA                <1> 	jne	short csftdf_df_error_stc_retn
  3243                              <1> 
  3244                              <1> 	; 21/03/2016
  3245                              <1> 	; (Capitalized file name)
  3246 000091AD BE[A4E70000]        <1> 	mov	esi, FindFile_Name
  3247 000091B2 BF[66E90000]        <1> 	mov	edi, DestinationFile_Name
  3248 000091B7 A5                  <1> 	movsd
  3249 000091B8 A5                  <1> 	movsd	
  3250 000091B9 A5                  <1> 	movsd
  3251                              <1> 	;movsb
  3252                              <1> 
  3253 000091BA C605[CEE90000]00    <1> 	mov	byte [DestinationFileFound], 0
  3254                              <1> 
  3255                              <1> csftdf_check_disk_free_size_0:
  3256 000091C1 A1[12E90000]        <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 000091C6 8B35[FCE90000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 23/03/2016
  3265                              <1> 
  3266 000091CC 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec] ; 17, LD_BPB + 0Bh
  3267 000091D0 01C8                <1> 	add	eax, ecx
  3268 000091D2 48                  <1> 	dec	eax  ; file size (additional bytes) + 511 (round up)
  3269                              <1> csftdf_check_disk_free_size_3: ; 16/03/2016
  3270 000091D3 29D2                <1> 	sub	edx, edx
  3271 000091D5 F7F1                <1> 	div	ecx ; bytes per sector
  3272                              <1> 
  3273                              <1> csftdf_check_disk_free_size:
  3274 000091D7 3B4674              <1> 	cmp	eax, [esi+LD_FreeSectors]
  3275 000091DA 0F8294000000        <1>         jb      csftdf_check_disk_free_size_ok
  3276 000091E0 770A                <1> 	ja	short csftdf_df_insufficient_disk_space
  3277                              <1> 
  3278 000091E2 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0 ; FS needs FDT sector also.
  3279 000091E6 0F8788000000        <1>         ja      csftdf_check_disk_free_size_ok 
  3280                              <1> 
  3281                              <1> csftdf_df_insufficient_disk_space:
  3282 000091EC B827000000          <1> 	mov	eax, 27h ; insufficient disk space
  3283 000091F1 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 000091F3 81EF00000800        <1> 	sub	edi, Directory_Buffer  ; (<65536)
  3291 000091F9 66C1EF05            <1> 	shr	di, 5 ; Convert entry offset to entry index/number
  3292 000091FD 66893D[9EE90000]    <1> 	mov	[DestinationFile_DirEntryNumber], di ; (<2048)
  3293                              <1> 
  3294                              <1> csftdf_df_check_sf_df_fcluster:
  3295 00009204 668B5614            <1> 	mov	dx, [esi+DirEntry_FstClusHI]
  3296 00009208 C1E210              <1> 	shl	edx, 16
  3297 0000920B 668B561A            <1> 	mov	dx, [esi+DirEntry_FstClusLO]
  3298 0000920F 8915[E0E90000]      <1> 	mov	[csftdf_df_cluster], edx
  3299                              <1> csftdf_df_check_sf_df_fcluster_1:
  3300 00009215 668B15[0AE90000]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusHI]
  3301 0000921C C1E210              <1> 	shl	edx, 16
  3302 0000921F 668B15[10E90000]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusLO]
  3303 00009226 3B15[E0E90000]      <1> 	cmp	edx, [csftdf_df_cluster]
  3304 0000922C 7512                <1> 	jne	short csftdf_df_check_sf_df_fcluster_ok
  3305                              <1> csftdf_df_check_sf_df_drv:
  3306 0000922E 8A15[A4E80000]      <1> 	mov	dl, [SourceFile_Drv]
  3307 00009234 3A15[24E90000]      <1> 	cmp	dl, [DestinationFile_Drv]
  3308 0000923A 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 0000923C 31C0                <1> 	xor	eax, eax ; mov eax, 0 -> Bad command or file name !
  3314 0000923E F9                  <1> 	stc
  3315 0000923F 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 00009240 BF[76E90000]        <1> 	mov	edi, DestinationFile_DirEntry
  3321 00009245 B908000000          <1> 	mov	ecx, 8
  3322 0000924A F3A5                <1> 	rep	movsd
  3323                              <1> 	
  3324                              <1> csftdf_check_disk_free_size_2:
  3325 0000924C 89C2                <1> 	mov	edx, eax ; Old destination file size
  3326                              <1> 
  3327                              <1> 	;mov	eax, [SourceFile_DirEntry+DirEntry_FileSize]
  3328 0000924E A1[D0E90000]        <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 00009253 8B35[FCE90000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 23/03/2016
  3338                              <1> 
  3339 00009259 668B4E11            <1> 	mov	cx, [esi+LD_BPB+BytesPerSec] ; 17, LD_BPB + 0Bh
  3340 0000925D 01CA                <1> 	add	edx, ecx ; + 512
  3341 0000925F 01C8                <1> 	add	eax, ecx ; + 512
  3342 00009261 4A                  <1> 	dec	edx ; old file size + 511 (round up)
  3343 00009262 48                  <1> 	dec	eax ; new file size + 511 (round up)
  3344 00009263 F7D9                <1> 	neg	ecx ; -512 ; 0FFFFFE00h
  3345 00009265 21CA                <1> 	and	edx, ecx ; = old sector count * 512 
  3346 00009267 21C8                <1> 	and	eax, ecx ; = new sector count * 512 
  3347                              <1> 
  3348 00009269 29D0                <1> 	sub	eax, edx ; new file size - old file size (on disk)
  3349 0000926B 7607                <1> 	jna	short csftdf_check_disk_free_size_ok
  3350                              <1> 
  3351 0000926D 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 0000926F 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 00009274 A0[CCE90000]        <1> 	mov	al, [copy_cmd_phase]
  3361 00009279 3C01                <1> 	cmp	al, 1
  3362 0000927B 7514                <1> 	jne	short csftdf2_check_cdrv
  3363                              <1> 	
  3364 0000927D 31C0                <1> 	xor	eax, eax
  3365 0000927F A2[CCE90000]        <1> 	mov	[copy_cmd_phase], al ; 0
  3366                              <1> 
  3367 00009284 8A15[CEE90000]      <1> 	mov	dl, [DestinationFileFound]            
  3368 0000928A 8A35[01E90000]      <1> 	mov	dh, [SourceFile_DirEntry+11] ; Attributes
  3369                              <1>  
  3370                              <1> csftdf_return:	
  3371 00009290 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 00009291 803D[CEE90000]00    <1> 	cmp	byte [DestinationFileFound], 0 
  3405 00009298 7739                <1> 	ja	short csftdf2_set_sf_percentage
  3406                              <1> 
  3407                              <1> csftdf2_create_file:
  3408 0000929A BE[66E90000]        <1> 	mov	esi, DestinationFile_Name
  3409 0000929F A1[D0E90000]        <1> 	mov	eax, [csftdf_filesize]
  3410 000092A4 30C9                <1> 	xor	cl, cl ; 0
  3411                              <1> 
  3412 000092A6 31DB                <1> 	xor	ebx, ebx ; 0
  3413 000092A8 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 000092A9 E8EC050000          <1> 	call	create_file
  3432                              <1> 	;pop	esi
  3433 000092AE 0F82A3050000        <1>         jc      csftdf2_rw_error
  3434                              <1> 
  3435                              <1> csftdf2_create_file_OK:
  3436 000092B4 A3[E0E90000]        <1> 	mov	[csftdf_df_cluster], eax
  3437                              <1> 	
  3438                              <1> 	; 24/03/2016
  3439 000092B9 668915[9EE90000]    <1> 	mov	[DestinationFile_DirEntryNumber], dx 
  3440                              <1> 
  3441                              <1> 	; 21/03/2016
  3442 000092C0 BE00000800          <1> 	mov	esi, Directory_Buffer
  3443 000092C5 C1E205              <1> 	shl	edx, 5 ; 32 * index number
  3444 000092C8 01D6                <1> 	add	esi, edx
  3445 000092CA BF[76E90000]        <1> 	mov	edi, DestinationFile_DirEntry	
  3446 000092CF B108                <1> 	mov	cl, 8 ; 32 bytes
  3447 000092D1 F3A5                <1> 	rep	movsd
  3448                              <1> 
  3449                              <1> csftdf2_set_sf_percentage:
  3450                              <1> 	; 17/03/2016
  3451 000092D3 31C0                <1> 	xor	eax, eax	
  3452 000092D5 A2[F4E90000]        <1> 	mov 	[csftdf_percentage], al ; 0, reset
  3453                              <1> 
  3454 000092DA A3[ECE90000]        <1> 	mov	[csftdf_sf_rbytes], eax ; 0, reset
  3455 000092DF A3[F0E90000]        <1> 	mov	[csftdf_df_wbytes], eax ; 0, reset
  3456                              <1> 
  3457 000092E4 8A25[A4E80000]      <1> 	mov	ah, [SourceFile_Drv]	
  3458 000092EA BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3459 000092EF 01C6                <1> 	add	esi, eax
  3460                              <1> 	
  3461 000092F1 8935[F8E90000]      <1> 	mov	[csftdf_sf_drv_dt], esi ; 23/03/2016
  3462                              <1> 
  3463 000092F7 668B15[0AE90000]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusHI]
  3464 000092FE C1E210              <1> 	shl	edx, 16
  3465 00009301 668B15[10E90000]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusLO]
  3466 00009308 8915[DCE90000]      <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 0000930E 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  3475 00009312 880D[22E90000]      <1> 	mov	[SourceFile_SecPerClust], cl
  3476                              <1> 
  3477                              <1> 	; 17/03/2016
  3478 00009318 386E03              <1> 	cmp	[esi+LD_FATType], ch ; 0
  3479 0000931B 7707                <1> 	ja	short csftdf2_set_sf_percent_rsize1
  3480                              <1> 
  3481 0000931D B800000100          <1> 	mov	eax, 65536 ; read/write buffer size for Singlix FS
  3482 00009322 EB06                <1> 	jmp	short csftdf2_set_sf_percent_rsize2	
  3483                              <1>  
  3484                              <1> csftdf2_set_sf_percent_rsize1:
  3485 00009324 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec]
  3486 00009328 F7E1                <1> 	mul	ecx
  3487                              <1> 	;sub	edx, edx
  3488                              <1> csftdf2_set_sf_percent_rsize2:
  3489 0000932A A3[E4E90000]        <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 0000932F 8B3D[FCE90000]      <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 00009335 8A4F13              <1> 	mov	cl, [edi+LD_BPB+SecPerClust]
  3508 00009338 880D[A2E90000]      <1> 	mov	[DestinationFile_SecPerClust], cl
  3509                              <1> 
  3510                              <1> 	; 17/03/2016
  3511 0000933E 386F03              <1> 	cmp	[edi+LD_FATType], ch ; 0
  3512 00009341 7707                <1> 	ja	short csftdf2_set_df_percent_wsize1
  3513                              <1> 	
  3514 00009343 B800000100          <1> 	mov	eax, 65536 ; read/write buffer size for Singlix FS
  3515 00009348 EB06                <1> 	jmp	short csftdf2_set_df_percent_wsize2	
  3516                              <1> 
  3517                              <1> csftdf2_set_df_percent_wsize1:
  3518 0000934A 0FB74711            <1> 	movzx	eax, word [edi+LD_BPB+BytesPerSec]
  3519 0000934E F7E1                <1> 	mul	ecx
  3520                              <1> 	;sub	edx, edx
  3521                              <1> csftdf2_set_df_percent_wsize2:
  3522 00009350 A3[E8E90000]        <1> 	mov	[csftdf_w_size], eax
  3523                              <1> 
  3524 00009355 A1[D0E90000]        <1> 	mov	eax, [csftdf_filesize]
  3525                              <1> 
  3526 0000935A 3D00000100          <1> 	cmp	eax, 65536 ; 64KB	; small file
  3527 0000935F 721F                <1> 	jb	short csftdf2_load_file ; do not display percentage
  3528                              <1> 	
  3529                              <1> csftdf2_reset_wf_percent_ptr_chk_64k:
  3530 00009361 B201                <1> 	mov	dl, 1 ; 25/03/2016
  3531                              <1> 
  3532 00009363 3D00000400          <1> 	cmp	eax, 65536*4 ; 256KB
  3533 00009368 7310                <1> 	jnb	short csftdf2_enable_percentage_display ; big file
  3534                              <1> 
  3535                              <1> 	; 64-128KB file size for floppy disks
  3536 0000936A 3815[A4E80000]      <1> 	cmp	byte [SourceFile_Drv], dl ; 1 ; read from floppy disk ?
  3537 00009370 7608                <1> 	jna	short csftdf2_enable_percentage_display
  3538                              <1> 
  3539 00009372 3815[24E90000]      <1> 	cmp	byte [DestinationFile_Drv], dl ; 1 ; write to floppy disk ?
  3540 00009378 7706                <1> 	ja	short csftdf2_load_file
  3541                              <1> 
  3542                              <1> csftdf2_enable_percentage_display:	
  3543 0000937A 8815[F4E90000]      <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 00009380 B40F                <1> 	mov	ah, 0Fh
  3551 00009382 E8AA7FFFFF          <1> 	call	_int10h
  3552                              <1> 	; 13/05/2016
  3553 00009387 883D[F5E90000]      <1> 	mov	[csftdf_videopage], bh ; active video page
  3554 0000938D B403                <1> 	mov	ah, 03h
  3555 0000938F E89D7FFFFF          <1> 	call	_int10h
  3556 00009394 668915[F6E90000]    <1> 	mov	[csftdf_cursorpos], dx
  3557                              <1> 
  3558 0000939B 29C0                <1> 	sub	eax, eax
  3559 0000939D A2[CDE90000]        <1> 	mov	[csftdf_rw_err], al ; 0 
  3560                              <1> 
  3561                              <1> ; ///
  3562                              <1> csftdf_sf_amb: ; 15/03/2016
  3563 000093A2 8B0D[D0E90000]      <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 000093A8 E864ACFFFF          <1> 	call	allocate_memory_block
  3576 000093AD 7304                <1> 	jnc	short loc_check_sf_save_loading_parms
  3577                              <1> 
  3578 000093AF 29C0                <1> 	sub	eax, eax
  3579 000093B1 29C9                <1> 	sub	ecx, ecx
  3580                              <1> 	
  3581                              <1> loc_check_sf_save_loading_parms:
  3582 000093B3 A3[D4E90000]        <1> 	mov	[csftdf_sf_mem_addr], eax ; loading address
  3583 000093B8 890D[D8E90000]      <1> 	mov	[csftdf_sf_mem_bsize], ecx ; block size
  3584                              <1> ; ///   
  3585                              <1> 	; 19/03/2016
  3586 000093BE 8B35[F8E90000]      <1> 	mov	esi, [csftdf_sf_drv_dt] ; logical dos drv desc. tbl.
  3587                              <1> 
  3588                              <1> 	; 17/03/2016
  3589 000093C4 09C0                <1> 	or	eax, eax ; contiguous free memory block address 
  3590 000093C6 0F845B010000        <1>         jz      csftdf2_read_sf_cluster
  3591                              <1> 
  3592                              <1> 	; 18/03/2016
  3593 000093CC 8B1D[D4E90000]      <1> 	mov	ebx, [csftdf_sf_mem_addr] ; memory block address
  3594                              <1> 
  3595 000093D2 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3596 000093D6 0F8605020000        <1>         jna     csftdf2_load_fs_file
  3597                              <1> 
  3598                              <1> csftdf2_load_fat_file:
  3599 000093DC 53                  <1> 	push	ebx ; *
  3600                              <1> 
  3601                              <1> csftdf2_load_fat_file_next:
  3602 000093DD BE[7FCE0000]        <1> 	mov	esi, msg_reading
  3603 000093E2 E859B2FFFF          <1> 	call	print_msg
  3604                              <1> 
  3605 000093E7 803D[F4E90000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3606 000093EE 7605                <1> 	jna	short csftdf2_load_fat_file_1
  3607                              <1> 	
  3608 000093F0 E87C000000          <1> 	call	csftdf2_print_percentage ; 19/03/2016
  3609                              <1> 
  3610                              <1> csftdf2_load_fat_file_1:
  3611 000093F5 8B35[F8E90000]      <1> 	mov	esi, [csftdf_sf_drv_dt]	
  3612 000093FB 5B                  <1> 	pop	ebx ; *
  3613                              <1> 
  3614                              <1> csftdf2_load_fat_file_2:
  3615 000093FC E8B8000000          <1> 	call	csftdf2_read_fat_file_sectors ; 19/03/2016
  3616 00009401 0F8250040000        <1>         jc      csftdf2_rw_error ; eocc! or disk error! 
  3617                              <1> 
  3618 00009407 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3619 00009409 7520                <1> 	jnz	short csftdf2_load_fat_file_ok
  3620                              <1> 
  3621 0000940B 803D[F4E90000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3622 00009412 76E8                <1> 	jna	short csftdf2_load_fat_file_2
  3623                              <1> 
  3624 00009414 53                  <1> 	push	ebx ; *	
  3625                              <1> 
  3626                              <1> 	; Set cursor position
  3627                              <1> 	; AH= 02h, BH= Page Number, DH= Row, DL= Column
  3628 00009415 8A3D[F5E90000]      <1> 	mov	bh, [csftdf_videopage]
  3629 0000941B 668B15[F6E90000]    <1> 	mov	dx, [csftdf_cursorpos]
  3630 00009422 B402                <1> 	mov	ah, 2
  3631 00009424 E8087FFFFF          <1> 	call	_int10h
  3632 00009429 EBB2                <1> 	jmp	short csftdf2_load_fat_file_next
  3633                              <1> 	
  3634                              <1> csftdf2_load_fat_file_ok:
  3635 0000942B 803D[F4E90000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3636 00009432 0F8651020000        <1>         jna     csftdf2_save_file ; 25/03/2016
  3637                              <1> 	
  3638                              <1> 	; "Reading... 100%"
  3639 00009438 BF[97CE0000]        <1> 	mov	edi, percentagestr
  3640 0000943D B031                <1> 	mov	al, '1'
  3641 0000943F AA                  <1> 	stosb
  3642 00009440 B030                <1> 	mov	al, '0'
  3643 00009442 AA                  <1> 	stosb
  3644 00009443 AA                  <1> 	stosb
  3645                              <1> 
  3646 00009444 8A3D[F5E90000]      <1> 	mov	bh, [csftdf_videopage]
  3647 0000944A 668B15[F6E90000]    <1> 	mov	dx, [csftdf_cursorpos]
  3648 00009451 B402                <1> 	mov	ah, 2
  3649 00009453 E8D97EFFFF          <1> 	call	_int10h
  3650                              <1> 
  3651 00009458 BE[7FCE0000]        <1> 	mov	esi, msg_reading
  3652 0000945D E8DEB1FFFF          <1> 	call	print_msg
  3653                              <1> 	
  3654 00009462 BE[97CE0000]        <1> 	mov	esi, percentagestr
  3655 00009467 E8D4B1FFFF          <1> 	call	print_msg
  3656                              <1> 
  3657 0000946C 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 00009471 B020                <1> 	mov	al, 20h
  3663 00009473 BF[97CE0000]        <1> 	mov	edi, percentagestr
  3664 00009478 AA                  <1> 	stosb
  3665 00009479 AA                  <1> 	stosb
  3666 0000947A A1[ECE90000]        <1> 	mov	eax, [csftdf_sf_rbytes]
  3667 0000947F BA64000000          <1> 	mov	edx, 100
  3668 00009484 F7E2                <1> 	mul	edx
  3669 00009486 8B0D[D0E90000]      <1> 	mov	ecx, [csftdf_filesize]	
  3670 0000948C F7F1                <1> 	div	ecx
  3671 0000948E B10A                <1> 	mov	cl, 10
  3672 00009490 F6F1                <1> 	div	cl
  3673 00009492 80C430              <1> 	add	ah, '0'
  3674 00009495 8827                <1> 	mov	[edi], ah
  3675 00009497 20C0                <1> 	and	al, al
  3676 00009499 740A                <1> 	jz	short csftdf2_print_percent_1
  3677 0000949B 4F                  <1> 	dec	edi
  3678 0000949C 6698                <1> 	cbw
  3679 0000949E F6F1                <1> 	div	cl
  3680 000094A0 80C430              <1> 	add	ah, '0'
  3681 000094A3 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 000094A5 BE[97CE0000]        <1> 	mov	esi, percentagestr
  3689                              <1> 	;call	print_msg
  3690                              <1> 	;retn
  3691 000094AA E991B1FFFF          <1> 	jmp	print_msg
  3692                              <1> 
  3693                              <1> csftdf2_read_file_sectors:
  3694                              <1> 	; 19/03/2016
  3695 000094AF 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3696 000094B3 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 000094B9 8B15[D0E90000]      <1> 	mov	edx, [csftdf_filesize]
  3708 000094BF 2B15[ECE90000]      <1> 	sub	edx, [csftdf_sf_rbytes]
  3709 000094C5 3B15[E4E90000]      <1> 	cmp	edx, [csftdf_r_size]	
  3710 000094CB 7306                <1> 	jnb	short csftdf2_read_fat_file_secs_1
  3711 000094CD 8915[E4E90000]      <1> 	mov	[csftdf_r_size], edx
  3712                              <1> 		
  3713                              <1> csftdf2_read_fat_file_secs_1:
  3714 000094D3 A1[E4E90000]        <1> 	mov	eax, [csftdf_r_size]
  3715 000094D8 29D2                <1> 	sub	edx, edx
  3716 000094DA 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec]
  3717 000094DE 01C8                <1> 	add	eax, ecx
  3718 000094E0 48                  <1> 	dec	eax
  3719 000094E1 F7F1                <1> 	div	ecx
  3720 000094E3 89C1                <1> 	mov	ecx, eax ; sector count
  3721 000094E5 A1[DCE90000]        <1> 	mov	eax, [csftdf_sf_cluster]
  3722                              <1> 
  3723                              <1> 	; EBX = memory block address (current)
  3724                              <1> 	
  3725 000094EA E821090000          <1> 	call	read_fat_file_sectors
  3726 000094EF 7235                <1> 	jc	short csftdf2_read_fat_file_secs_3
  3727                              <1> 
  3728                              <1> 	; EBX = next memory address
  3729                              <1> 
  3730 000094F1 A1[ECE90000]        <1> 	mov	eax, [csftdf_sf_rbytes]
  3731 000094F6 0305[E4E90000]      <1> 	add	eax, [csftdf_r_size]
  3732 000094FC 8B15[D0E90000]      <1> 	mov	edx, [csftdf_filesize]
  3733 00009502 39D0                <1> 	cmp	eax, edx
  3734 00009504 7320                <1> 	jnb	short csftdf2_read_fat_file_secs_3 ; edx > 0
  3735 00009506 A3[ECE90000]        <1> 	mov	[csftdf_sf_rbytes], eax
  3736                              <1> 
  3737 0000950B 53                  <1> 	push	ebx ; *
  3738                              <1> 	; get next cluster (csftdf_r_size! bytes)
  3739 0000950C A1[DCE90000]        <1> 	mov	eax, [csftdf_sf_cluster]
  3740 00009511 E8CC060000          <1> 	call	get_next_cluster
  3741 00009516 5B                  <1> 	pop	ebx ; *
  3742 00009517 7306                <1> 	jnc	short csftdf2_read_fat_file_secs_2
  3743                              <1> 
  3744 00009519 B815000000          <1> 	mov	eax, 15h ; Read error !
  3745 0000951E C3                  <1> 	retn
  3746                              <1> 
  3747                              <1> csftdf2_read_fat_file_secs_2:
  3748 0000951F 29D2                <1> 	sub	edx, edx ; 0
  3749 00009521 A3[DCE90000]        <1> 	mov	[csftdf_sf_cluster], eax ; next cluster
  3750                              <1> 
  3751                              <1> csftdf2_read_fat_file_secs_3:
  3752 00009526 C3                  <1> 	retn
  3753                              <1> 
  3754                              <1> csftdf2_read_sf_cluster:
  3755                              <1> 	; 19/03/2016
  3756 00009527 BB00000700          <1> 	mov	ebx, Cluster_Buffer ; buffer address (64KB)
  3757                              <1> 
  3758 0000952C 803D[F4E90000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3759 00009533 760D                <1> 	jna	short csftdf2_read_sf_clust_2
  3760                              <1> 
  3761 00009535 53                  <1> 	push	ebx ; *	
  3762                              <1> 
  3763                              <1> csftdf2_read_sf_clust_next:
  3764 00009536 E836FFFFFF          <1> 	call	csftdf2_print_percentage
  3765                              <1> 
  3766                              <1> csftdf2_read_sf_clust_0:
  3767 0000953B 8B35[F8E90000]      <1> 	mov	esi, [csftdf_sf_drv_dt]	
  3768                              <1> csftdf2_read_sf_clust_1:
  3769 00009541 5B                  <1> 	pop	ebx ; *
  3770                              <1> 
  3771                              <1> csftdf2_read_sf_clust_2:
  3772 00009542 89DA                <1> 	mov	edx, ebx
  3773 00009544 0315[E4E90000]      <1> 	add	edx, [csftdf_r_size]
  3774 0000954A 81FA00000800        <1> 	cmp	edx, Cluster_Buffer + 65536
  3775 00009550 772F                <1> 	ja	short csftdf2_write_df_cluster
  3776                              <1> 
  3777 00009552 E858FFFFFF          <1> 	call	csftdf2_read_file_sectors ; 19/03/2016
  3778 00009557 0F8280020000        <1>         jc      csftdf2_save_fat_file_err2 ; eocc! or disk error! 
  3779                              <1> 
  3780 0000955D 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3781 0000955F 7520                <1> 	jnz	short csftdf2_write_df_cluster
  3782                              <1> 
  3783 00009561 803D[F4E90000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3784 00009568 76D8                <1> 	jna	short csftdf2_read_sf_clust_2
  3785                              <1> 
  3786 0000956A 53                  <1> 	push	ebx ; *	
  3787                              <1> 
  3788                              <1> 	; Set cursor position
  3789                              <1> 	; AH= 02h, BH= Page Number, DH= Row, DL= Column
  3790 0000956B 8A3D[F5E90000]      <1> 	mov	bh, [csftdf_videopage]
  3791 00009571 668B15[F6E90000]    <1> 	mov	dx, [csftdf_cursorpos]
  3792 00009578 B402                <1> 	mov	ah, 2
  3793 0000957A E8B27DFFFF          <1> 	call	_int10h
  3794 0000957F EBB5                <1> 	jmp	short csftdf2_read_sf_clust_next
  3795                              <1> 
  3796                              <1> csftdf2_write_df_cluster:
  3797                              <1> 	; 19/03/2016
  3798 00009581 8B35[FCE90000]      <1> 	mov	esi, [csftdf_df_drv_dt]	
  3799 00009587 BB00000700          <1> 	mov	ebx, Cluster_Buffer ; buffer address (64KB)
  3800                              <1> 
  3801                              <1> csftdf2_write_df_clust_next:
  3802 0000958C E855000000          <1> 	call	csftdf2_write_file_sectors ; 19/03/2016
  3803 00009591 0F8246020000        <1>         jc      csftdf2_save_fat_file_err2 ; eocc! or disk error! 
  3804                              <1> 
  3805 00009597 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3806 00009599 750A                <1> 	jnz	short csftdf2_rw_f_clust_ok
  3807                              <1> 
  3808 0000959B 81FB00000800        <1> 	cmp	ebx, Cluster_Buffer + 65536
  3809 000095A1 72E9                <1> 	jb	short csftdf2_write_df_clust_next
  3810                              <1> 	
  3811 000095A3 EB82                <1> 	jmp	short csftdf2_read_sf_cluster
  3812                              <1>  
  3813                              <1> csftdf2_rw_f_clust_ok:
  3814 000095A5 803D[F4E90000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3815 000095AC 0F86B2010000        <1>         jna     csftdf2_save_fat_file_4 ; 25/03/2016
  3816                              <1> 
  3817                              <1> 	; "100%"
  3818 000095B2 BF[97CE0000]        <1> 	mov	edi, percentagestr
  3819 000095B7 B031                <1> 	mov	al, '1'
  3820 000095B9 AA                  <1> 	stosb
  3821 000095BA B030                <1> 	mov	al, '0'
  3822 000095BC AA                  <1> 	stosb
  3823 000095BD AA                  <1> 	stosb
  3824                              <1> 
  3825 000095BE 8A3D[F5E90000]      <1> 	mov	bh, [csftdf_videopage]
  3826 000095C4 668B15[F6E90000]    <1> 	mov	dx, [csftdf_cursorpos]
  3827 000095CB B402                <1> 	mov	ah, 2
  3828 000095CD E85F7DFFFF          <1> 	call	_int10h
  3829                              <1> 
  3830 000095D2 BE[97CE0000]        <1> 	mov	esi, percentagestr
  3831 000095D7 E864B0FFFF          <1> 	call	print_msg
  3832                              <1> 
  3833 000095DC E983010000          <1>         jmp     csftdf2_save_fat_file_4
  3834                              <1> 
  3835                              <1> csftdf2_load_fs_file:
  3836                              <1> 	; temporary - 18/03/2016
  3837 000095E1 E96F020000          <1>         jmp     csftdf2_read_error
  3838                              <1> 
  3839                              <1> csftdf2_write_file_sectors:
  3840                              <1> 	; 19/03/2016
  3841 000095E6 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3842 000095EA 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 000095F0 8B15[D0E90000]      <1> 	mov	edx, [csftdf_filesize]
  3854 000095F6 2B15[F0E90000]      <1> 	sub	edx, [csftdf_df_wbytes]
  3855 000095FC 3B15[E8E90000]      <1> 	cmp	edx, [csftdf_w_size]	
  3856 00009602 7306                <1> 	jnb	short csftdf2_write_fat_file_secs_1
  3857 00009604 8915[E8E90000]      <1> 	mov	[csftdf_w_size], edx		
  3858                              <1> 
  3859                              <1> csftdf2_write_fat_file_secs_1:
  3860 0000960A A1[E8E90000]        <1> 	mov	eax, [csftdf_w_size]
  3861 0000960F 29D2                <1> 	sub	edx, edx
  3862 00009611 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec]
  3863 00009615 01C8                <1> 	add	eax, ecx
  3864 00009617 48                  <1> 	dec	eax
  3865 00009618 F7F1                <1> 	div	ecx
  3866 0000961A 89C1                <1> 	mov	ecx, eax ; sector count
  3867 0000961C A1[E0E90000]        <1> 	mov	eax, [csftdf_df_cluster]
  3868                              <1> 
  3869                              <1> 	; EBX = memory block address (current)	
  3870                              <1> 
  3871 00009621 E8920F0000          <1> 	call	write_fat_file_sectors
  3872 00009626 7259                <1> 	jc	short csftdf2_write_fat_file_secs_4
  3873                              <1> 
  3874                              <1> 	; EBX = next memory address
  3875                              <1> 
  3876 00009628 A1[F0E90000]        <1> 	mov	eax, [csftdf_df_wbytes]
  3877 0000962D 0305[E8E90000]      <1> 	add	eax, [csftdf_w_size]
  3878 00009633 8B15[D0E90000]      <1> 	mov	edx, [csftdf_filesize]
  3879 00009639 39D0                <1> 	cmp	eax, edx
  3880 0000963B 7344                <1> 	jnb	short csftdf2_write_fat_file_secs_4
  3881 0000963D A3[F0E90000]        <1> 	mov	[csftdf_df_wbytes], eax
  3882                              <1> 	;
  3883 00009642 A3[92E90000]        <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], eax
  3884                              <1> 
  3885 00009647 53                  <1> 	push	ebx ; *
  3886                              <1> 
  3887 00009648 803D[CEE90000]01    <1> 	cmp	byte [DestinationFileFound], 1
  3888 0000964F 7210                <1> 	jb	short csftdf2_write_fat_file_secs_2
  3889                              <1> 
  3890                              <1> 	; get next cluster (csftdf_w_size! bytes)
  3891 00009651 A1[E0E90000]        <1> 	mov	eax, [csftdf_df_cluster]
  3892 00009656 E887050000          <1> 	call	get_next_cluster
  3893 0000965B 731C                <1> 	jnc	short csftdf2_write_fat_file_secs_3
  3894                              <1> 
  3895 0000965D 21C0                <1> 	and	eax, eax ; end of cluster chain!?
  3896 0000965F 7521                <1> 	jnz	short csftdf2_write_fat_file_secs_5 ; disk error !
  3897                              <1> 
  3898                              <1> csftdf2_write_fat_file_secs_2:
  3899 00009661 A1[E0E90000]        <1> 	mov	eax, [csftdf_df_cluster] ; last cluster
  3900 00009666 E8700E0000          <1> 	call	add_new_cluster		
  3901 0000966B 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 0000966D 8B15[E8E90000]      <1> 	mov	edx, [csftdf_w_size] ; bytes per cluster
  3909 00009673 0115[92E90000]      <1> 	add	[DestinationFile_DirEntry+DirEntry_FileSize], edx
  3910                              <1> 
  3911                              <1> csftdf2_write_fat_file_secs_3:
  3912 00009679 5B                  <1> 	pop	ebx ; *
  3913 0000967A 29D2                <1> 	sub	edx, edx ; 0
  3914 0000967C A3[E0E90000]        <1> 	mov	[csftdf_df_cluster], eax ; next cluster
  3915                              <1> 
  3916                              <1> csftdf2_write_fat_file_secs_4:
  3917 00009681 C3                  <1> 	retn
  3918                              <1> 
  3919                              <1> csftdf2_write_fat_file_secs_5:
  3920 00009682 5B                  <1> 	pop	ebx ; *
  3921 00009683 B81D000000          <1> 	mov	eax, 1Dh ; Write error !
  3922 00009688 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 00009689 8B35[FCE90000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; logical dos drv desc. tbl.
  3929                              <1> 
  3930 0000968F 8B1D[D4E90000]      <1> 	mov	ebx, [csftdf_sf_mem_addr] ; memory block address
  3931                              <1> 
  3932 00009695 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3933 00009699 0F86F4010000        <1>         jna     csftdf2_save_fs_file
  3934                              <1> 
  3935                              <1> csftdf2_save_fat_file:
  3936 0000969F 53                  <1> 	push	ebx; *
  3937                              <1> 
  3938 000096A0 803D[F4E90000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3939 000096A7 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 000096A9 8A3D[F5E90000]      <1> 	mov	bh, [csftdf_videopage]
  3944 000096AF 668B15[F6E90000]    <1> 	mov	dx, [csftdf_cursorpos]
  3945 000096B6 B402                <1> 	mov	ah, 2
  3946 000096B8 E8747CFFFF          <1> 	call	_int10h
  3947                              <1> 	
  3948 000096BD BE[8BCE0000]        <1> 	mov	esi, msg_writing
  3949 000096C2 E879AFFFFF          <1> 	call	print_msg
  3950                              <1> 
  3951                              <1> csftdf2_save_fat_file_next:
  3952 000096C7 8B35[FCE90000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 25/03/2016
  3953                              <1> 
  3954                              <1> csftdf2_save_fat_file_0:
  3955 000096CD 5B                  <1> 	pop	ebx ; *
  3956                              <1> 
  3957                              <1> csftdf2_save_fat_file_1:
  3958 000096CE E813FFFFFF          <1> 	call	csftdf2_write_file_sectors ; 19/03/2016	
  3959 000096D3 0F827E010000        <1>         jc      csftdf2_rw_error ; eocc! or disk error! 
  3960                              <1> 
  3961 000096D9 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3962 000096DB 756D                <1>         jnz     short csftdf2_save_fat_file_3 ; 25/03/2016
  3963                              <1> 
  3964 000096DD 803D[F4E90000]00    <1> 	cmp	byte [csftdf_percentage], 0
  3965 000096E4 76E8                <1> 	jna	short csftdf2_save_fat_file_1
  3966                              <1> 
  3967 000096E6 B020                <1> 	mov	al, 20h
  3968 000096E8 BF[97CE0000]        <1> 	mov	edi, percentagestr
  3969 000096ED AA                  <1> 	stosb
  3970 000096EE AA                  <1> 	stosb
  3971 000096EF A1[F0E90000]        <1> 	mov	eax, [csftdf_df_wbytes]
  3972 000096F4 BA64000000          <1> 	mov	edx, 100
  3973 000096F9 F7E2                <1> 	mul	edx
  3974 000096FB 8B0D[D0E90000]      <1> 	mov	ecx, [csftdf_filesize]	
  3975 00009701 F7F1                <1> 	div	ecx
  3976 00009703 B10A                <1> 	mov	cl, 10
  3977 00009705 F6F1                <1> 	div	cl
  3978 00009707 80C430              <1> 	add	ah, '0'
  3979 0000970A 8827                <1> 	mov	[edi], ah
  3980 0000970C 20C0                <1> 	and	al, al
  3981 0000970E 740A                <1> 	jz	short csftdf2_save_fat_file_2
  3982 00009710 4F                  <1> 	dec	edi
  3983 00009711 6698                <1> 	cbw
  3984 00009713 F6F1                <1> 	div	cl
  3985 00009715 80C430              <1> 	add	ah, '0'
  3986 00009718 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 0000971A 53                  <1> 	push	ebx ; *
  3994                              <1> 
  3995 0000971B E802000000          <1> 	call	csftdf2_print_wr_percentage ; 25/03/2016
  3996                              <1> 
  3997 00009720 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 00009722 8A3D[F5E90000]      <1> 	mov	bh, [csftdf_videopage]
  4003 00009728 668B15[F6E90000]    <1> 	mov	dx, [csftdf_cursorpos]
  4004 0000972F B402                <1> 	mov	ah, 2
  4005 00009731 E8FB7BFFFF          <1> 	call	_int10h
  4006                              <1> 
  4007 00009736 BE[8BCE0000]        <1> 	mov	esi, msg_writing
  4008 0000973B E800AFFFFF          <1> 	call	print_msg
  4009                              <1> 
  4010 00009740 BE[97CE0000]        <1> 	mov	esi, percentagestr
  4011                              <1> 	;call	print_msg
  4012                              <1> 	;retn
  4013 00009745 E9F6AEFFFF          <1> 	jmp	print_msg
  4014                              <1> 
  4015                              <1> csftdf2_save_fat_file_3:
  4016 0000974A 803D[F4E90000]00    <1> 	cmp	byte [csftdf_percentage], 0
  4017 00009751 7611                <1>         jna     csftdf2_save_fat_file_4 ; 25/03/2016
  4018                              <1> 
  4019                              <1> 	; "100%"
  4020 00009753 BF[97CE0000]        <1> 	mov	edi, percentagestr
  4021 00009758 B031                <1> 	mov	al, '1'
  4022 0000975A AA                  <1> 	stosb
  4023 0000975B B030                <1> 	mov	al, '0'
  4024 0000975D AA                  <1> 	stosb
  4025 0000975E AA                  <1> 	stosb
  4026                              <1> 
  4027 0000975F E8BEFFFFFF          <1> 	call	csftdf2_print_wr_percentage
  4028                              <1> 
  4029                              <1> csftdf2_save_fat_file_4:
  4030 00009764 803D[CEE90000]00    <1> 	cmp	byte [DestinationFileFound], 0
  4031 0000976B 7647                <1> 	jna	short csftdf2_save_fat_file_6
  4032                              <1> 
  4033 0000976D 8B35[FCE90000]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 31/03/2016	
  4034                              <1> 
  4035 00009773 A1[E0E90000]        <1> 	mov	eax, [csftdf_df_cluster] ; last cluster
  4036 00009778 E865040000          <1> 	call	get_next_cluster
  4037 0000977D 7235                <1> 	jc	short csftdf2_save_fat_file_6 ; eocc! or disk error!
  4038                              <1> 
  4039 0000977F A1[E0E90000]        <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 00009784 B9FFFFFF0F          <1> 	mov	ecx, 0FFFFFFFh
  4045 00009789 E87E070000          <1> 	call	update_cluster
  4046 0000978E 7224                <1> 	jc	short csftdf2_save_fat_file_6 ; really last cluster!?
  4047                              <1> 
  4048 00009790 A3[E0E90000]        <1> 	mov	[csftdf_df_cluster], eax ; next cluster
  4049                              <1> 	
  4050                              <1> 	; byte [FAT_BuffValidData] = 2 
  4051 00009795 E82F0A0000          <1> 	call	save_fat_buffer
  4052 0000979A 730E                <1> 	jnc	short csftdf2_save_fat_file_5
  4053                              <1> 	
  4054 0000979C 8B15[D0E90000]      <1> 	mov	edx, [csftdf_filesize]
  4055 000097A2 8915[92E90000]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], edx
  4056 000097A8 EB58                <1> 	jmp	short csftdf2_save_fat_file_err3
  4057                              <1> 
  4058                              <1> csftdf2_save_fat_file_5:
  4059 000097AA A1[E0E90000]        <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 000097AF E8480C0000          <1> 	call	truncate_cluster_chain
  4064                              <1> 
  4065                              <1> csftdf2_save_fat_file_6:
  4066                              <1> 	; 28/03/2016
  4067 000097B4 BE[01E90000]        <1> 	mov	esi, SourceFile_DirEntry+DirEntry_Attr ; +11 to + 18
  4068 000097B9 BF[81E90000]        <1> 	mov	edi, DestinationFile_DirEntry+DirEntry_Attr ; +11 to + 18
  4069 000097BE A4                  <1> 	movsb ; +11
  4070 000097BF A5                  <1> 	movsd ; +12 .. +15
  4071 000097C0 66A5                <1> 	movsw ; +16 .. +17
  4072                              <1> 		; + 18
  4073 000097C2 83C604              <1> 	add	esi, 4
  4074 000097C5 83C704              <1> 	add	edi, 4
  4075 000097C8 A5                  <1> 	movsd	; DirEntry_WrtTime ; +22 .. +25
  4076                              <1> 
  4077 000097C9 8B15[D0E90000]      <1> 	mov	edx, [csftdf_filesize]
  4078 000097CF 8915[92E90000]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], edx
  4079                              <1> 
  4080 000097D5 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 000097DA EB4D                <1> 	jmp	short csftdf2_save_fat_file_7
  4084                              <1> 
  4085                              <1> csftdf2_save_fat_file_err1:
  4086 000097DC 5B                  <1> 	pop	ebx ; *	
  4087                              <1> csftdf2_save_fat_file_err2:
  4088 000097DD A1[F0E90000]        <1> 	mov	eax, [csftdf_df_wbytes]
  4089 000097E2 8B15[92E90000]      <1> 	mov	edx, [DestinationFile_DirEntry+DirEntry_FileSize]
  4090 000097E8 39C2                <1> 	cmp	edx, eax
  4091 000097EA 7616                <1> 	jna	short csftdf2_save_fat_file_err3
  4092 000097EC A1[E0E90000]        <1> 	mov	eax, [csftdf_df_cluster] ; last (empty) cluster
  4093                              <1> 	; ESI = Logical dos drive description table address
  4094 000097F1 E8060C0000          <1> 	call	truncate_cluster_chain
  4095 000097F6 720A                <1> 	jc	short csftdf2_save_fat_file_err3
  4096 000097F8 A1[F0E90000]        <1> 	mov	eax, [csftdf_df_wbytes]	
  4097 000097FD A3[92E90000]        <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], eax
  4098                              <1> csftdf2_save_fat_file_err3:
  4099 00009802 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 00009807 C605[83E90000]00    <1> 	mov	byte [DestinationFile_DirEntry+DirEntry_CrtTimeTenth], 0
  4103 0000980E 66A3[84E90000]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_CrtTime], ax
  4104 00009814 668915[86E90000]    <1> 	mov	[DestinationFile_DirEntry+DirEntry_CrtDate], dx		
  4105 0000981B 66A3[8CE90000]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_WrtTime], ax
  4106 00009821 668915[8EE90000]    <1> 	mov	[DestinationFile_DirEntry+DirEntry_WrtDate], dx
  4107 00009828 F9                  <1> 	stc
  4108                              <1> csftdf2_save_fat_file_7:
  4109 00009829 9C                  <1> 	pushf
  4110 0000982A 668915[88E90000]    <1> 	mov	[DestinationFile_DirEntry+DirEntry_LastAccDate], dx
  4111 00009831 BE[76E90000]        <1> 	mov	esi, DestinationFile_DirEntry
  4112 00009836 BF00000800          <1> 	mov	edi, Directory_Buffer
  4113 0000983B 0FB70D[9EE90000]    <1> 	movzx	ecx, word [DestinationFile_DirEntryNumber] ; (<2048)
  4114 00009842 66C1E105            <1> 	shl	cx, 5 ; 32 * directory entry number
  4115 00009846 01CF                <1> 	add	edi, ecx
  4116                              <1> 	;mov	ecx, 8
  4117 00009848 66B90800            <1> 	mov	cx, 8
  4118 0000984C F3A5                <1> 	rep	movsd
  4119 0000984E 9D                  <1> 	popf
  4120 0000984F 730B                <1> 	jnc	short csftdf2_write_file_OK
  4121                              <1> 	 		
  4122                              <1> csftdf2_write_error:
  4123                              <1> 	; 18/03/2016
  4124 00009851 B01D                <1> 	mov	al, 1Dh ; write error
  4125 00009853 EB02                <1> 	jmp	short csftdf2_rw_error
  4126                              <1> 
  4127                              <1> 	; 16/03/2016
  4128                              <1> csftdf2_read_error:
  4129 00009855 B015                <1> 	mov	al, 15h ; ; Drive not ready or read error!
  4130                              <1> csftdf2_rw_error:
  4131 00009857 A2[CDE90000]        <1> 	mov	[csftdf_rw_err], al 
  4132                              <1> 
  4133                              <1> csftdf2_write_file_OK:
  4134                              <1> 	; 18/03/2016
  4135 0000985C C605[E8E50000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  4136 00009863 E8E7F0FFFF          <1> 	call	save_directory_buffer
  4137                              <1> 
  4138                              <1>  	; Update last modification date&time of destination
  4139                              <1> 	; file's (parent) directory
  4140 00009868 E87DF1FFFF          <1> 	call	update_parent_dir_lmdt
  4141                              <1> 	;
  4142 0000986D A1[D4E90000]        <1> 	mov	eax, [csftdf_sf_mem_addr] ; start address
  4143                              <1> 
  4144 00009872 21C0                <1> 	and	eax, eax
  4145 00009874 750E                <1> 	jnz	short csftdf2_dealloc_mblock
  4146                              <1> 
  4147 00009876 88C5                <1> 	mov	ch, al ; 0 (Cluster r/w, not full loading)
  4148                              <1> csftdf2_dealloc_retn:
  4149 00009878 8A0D[CDE90000]      <1> 	mov	cl, [csftdf_rw_err]
  4150 0000987E A1[E0E90000]        <1> 	mov	eax, [csftdf_df_cluster]
  4151 00009883 C3                  <1> 	retn
  4152                              <1> 
  4153                              <1> csftdf2_dealloc_mblock:
  4154 00009884 8B0D[D8E90000]      <1> 	mov	ecx, [csftdf_sf_mem_bsize] ; block size	
  4155 0000988A E883A9FFFF          <1> 	call	deallocate_memory_block
  4156 0000988F B5FF                <1>         mov     ch, 0FFh ; (File was full loaded at memory)
  4157 00009891 EBE5                <1> 	jmp	short csftdf2_dealloc_retn
  4158                              <1> 
  4159                              <1> csftdf2_save_fs_file:
  4160                              <1> 	; temporary - (21/03/2016)
  4161 00009893 B81D000000          <1> 	mov	eax, 1Dh ; write error
  4162 00009898 F9                  <1> 	stc
  4163 00009899 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 0000989A 80E107              <1> 	and	cl, 07h ; S, H, R
  4193 0000989D 880D[1CEA0000]      <1>         mov     [createfile_attrib], cl 
  4194                              <1> 
  4195 000098A3 89D9                <1> 	mov	ecx, ebx
  4196 000098A5 89F3                <1> 	mov	ebx, esi ; ASCIIZ File Name address
  4197 000098A7 29D2                <1> 	sub	edx, edx
  4198 000098A9 8A35[BEDD0000]      <1>         mov     dh, [Current_Drv]
  4199 000098AF BE00010900          <1>         mov     esi, Logical_DOSDisks
  4200 000098B4 01D6                <1> 	add	esi, edx
  4201                              <1> 
  4202 000098B6 8815[27EA0000]      <1> 	mov	[createfile_UpdatePDir], dl ; 0 ; 31/03/2016 
  4203                              <1> 
  4204                              <1> 	; LD_DiskType = 0 for write protection (read only) 
  4205 000098BC 807E0101            <1> 	cmp	byte [esi+LD_DiskType], 1 ; 0 = Invalid
  4206 000098C0 730A                <1> 	jnb	short loc_createfile_check_file_sytem
  4207 000098C2 B813000000          <1> 	mov	eax, 13h ; MSDOS err => Disk write-protected 
  4208 000098C7 66BA0000            <1> 	mov	dx, 0
  4209                              <1> 	; err retn: EDX = 0, EBX = File name offset
  4210                              <1> 	; ESI -> Dos drive description table address	
  4211 000098CB 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 000098CC 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  4220 000098D0 730A                <1> 	jnb	short loc_createfile_chk_empty_FAT_file_sign1
  4221                              <1> 
  4222 000098D2 A3[08EA0000]        <1> 	mov	[createfile_size], eax
  4223                              <1> 	; ESI = Logical Dos Drive Description Table address
  4224                              <1> 	; EBX = ASCIIZ File Name address
  4225 000098D7 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 000098DC 41                  <1> 	inc	ecx
  4230 000098DD 7506                <1> 	jnz	short loc_createfile_chk_empty_FAT_file_sign2
  4231 000098DF 890D[08EA0000]      <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 000098E5 668B4E11            <1> 	mov	cx, [esi+LD_BPB+BytesPerSec]
  4236 000098E9 66890D[24EA0000]    <1> 	mov	[createfile_BytesPerSec], cx
  4237                              <1> 	
  4238                              <1> 	; EBX = ASCIIZ File Name address
  4239 000098F0 0FB65613            <1> 	movzx	edx, byte [esi+LD_BPB+SecPerClust]
  4240 000098F4 8815[1DEA0000]      <1> 	mov	[createfile_SecPerClust], dl
  4241 000098FA 8B4E74              <1> 	mov	ecx, [esi+LD_FreeSectors]
  4242 000098FD 39D1                <1> 	cmp	ecx, edx ; byte [createfile_SecPerClust]
  4243 000098FF 7306                <1> 	jnb	short loc_create_fat_file
  4244                              <1> 	  
  4245                              <1> loc_createfile_insufficient_disk_space:
  4246 00009901 B827000000          <1> 	mov	eax, 27h
  4247                              <1> loc_createfile_gffc_retn:
  4248 00009906 C3                  <1> 	retn
  4249                              <1> 
  4250                              <1> loc_create_fat_file:
  4251 00009907 891D[00EA0000]      <1> 	mov	[createfile_Name_Offset], ebx
  4252 0000990D 890D[04EA0000]      <1> 	mov	[createfile_FreeSectors], ecx
  4253                              <1> 
  4254                              <1> loc_createfile_gffc_1:
  4255 00009913 E821050000          <1> 	call	get_first_free_cluster
  4256 00009918 72EC                <1> 	jc	short loc_createfile_gffc_retn
  4257                              <1> 
  4258 0000991A A3[0CEA0000]        <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 0000991F 56                  <1> 	push	esi ; *
  4267 00009920 31C0                <1> 	xor	eax, eax
  4268                              <1> 
  4269 00009922 A3[DEE50000]        <1> 	mov	dword [FAT_ClusterCounter], eax ; 0
  4270                              <1> 	; 21/03/2016
  4271 00009927 A2[26EA0000]        <1> 	mov	byte [createfile_wfc], al ; 0 
  4272                              <1> 
  4273 0000992C 89C1                <1>  	mov	ecx, eax
  4274 0000992E 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 00009930 E8F6E7FFFF          <1> 	call	locate_current_dir_file
  4279 00009935 0F83EE000000        <1> 	jnc	loc_createfile_set_ff_dir_entry
  4280 0000993B 5E                  <1> 	pop	esi ; *
  4281                              <1> 	 ; ESI = Logical DOS Drv. Description Table Address 
  4282 0000993C 83F802              <1> 	cmp	eax, 2
  4283 0000993F 7402                <1> 	je	short loc_createfile_add_new_cluster
  4284                              <1> loc_createfile_locate_file_stc_retn:
  4285 00009941 F9                  <1> 	stc
  4286 00009942 C3                  <1> 	retn
  4287                              <1> 
  4288                              <1> loc_createfile_add_new_cluster:
  4289 00009943 803D[BDDD0000]02    <1> 	cmp	byte [Current_FATType], 2
  4290                              <1> 	;cmp	byte [esi+LD_FATType], 2
  4291 0000994A 770C                <1> 	ja	short loc_createfile_add_new_cluster_check_fsc
  4292 0000994C 803D[BCDD0000]01    <1> 	cmp	byte [Current_Dir_Level], 1
  4293                              <1> 	;cmp	byte [esi+LD_CDirLevel], 1
  4294 00009953 7303                <1> 	jnb	short loc_createfile_add_new_cluster_check_fsc
  4295                              <1> 	
  4296                              <1> 	;mov	eax, 12
  4297 00009955 B00C                <1> 	mov	al, 12 ; No more files 
  4298                              <1> 
  4299                              <1> loc_createfile_anc_retn:
  4300 00009957 C3                  <1> 	retn
  4301                              <1> 
  4302                              <1> loc_createfile_add_new_cluster_check_fsc:
  4303 00009958 8B0D[04EA0000]      <1> 	mov	ecx, [createfile_FreeSectors]
  4304 0000995E 0FB605[1DEA0000]    <1> 	movzx	eax, byte [createfile_SecPerClust]
  4305 00009965 66D1E0              <1> 	shl	ax, 1 ; AX = 2 * AX
  4306 00009968 39C1                <1> 	cmp	ecx, eax
  4307 0000996A 7295                <1>         jb	short loc_createfile_insufficient_disk_space
  4308                              <1> 
  4309                              <1> loc_createfile_add_new_subdir_cluster:
  4310 0000996C 8B15[EDE50000]      <1> 	mov	edx, [DirBuff_Cluster]
  4311 00009972 8915[10EA0000]      <1> 	mov	[createfile_LastDirCluster], edx	
  4312                              <1> 
  4313 00009978 A1[0CEA0000]        <1> 	mov	eax, [createfile_FFCluster]
  4314 0000997D E846040000          <1> 	call	load_FAT_sub_directory 
  4315 00009982 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 00009984 0FB705[24EA0000]    <1> 	movzx	eax, word [createfile_BytesPerSec] ; 23/03/2016
  4320 0000998B F7E1                <1> 	mul	ecx ; ecx = directory buffer sector count
  4321 0000998D 89C1                <1> 	mov	ecx, eax
  4322 0000998F C1E902              <1> 	shr	ecx, 2 ; dword count
  4323 00009992 29C0                <1> 	sub	eax, eax ; 0
  4324 00009994 F3AB                <1> 	rep	stosd 
  4325                              <1> 	;
  4326 00009996 C605[E8E50000]02    <1> 	mov	byte [DirBuff_ValidData], 2 
  4327 0000999D E8ADEFFFFF          <1> 	call	save_directory_buffer
  4328 000099A2 72B3                <1> 	jc	short loc_createfile_anc_retn
  4329                              <1> 
  4330                              <1> loc_createfile_save_added_subdir_cluster:
  4331 000099A4 A1[10EA0000]        <1> 	mov	eax, [createfile_LastDirCluster]
  4332 000099A9 8B0D[0CEA0000]      <1> 	mov	ecx, [createfile_FFCluster]
  4333 000099AF E858050000          <1> 	call	update_cluster
  4334 000099B4 7304                <1> 	jnc	short loc_createfile_save_fat_buffer_0
  4335 000099B6 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  4336 000099B8 751A                <1> 	jnz	short loc_createfile_save_fat_buffer_stc_retn
  4337                              <1> 
  4338                              <1> loc_createfile_save_fat_buffer_0:
  4339 000099BA A1[0CEA0000]        <1> 	mov	eax, [createfile_FFCluster]
  4340 000099BF A3[10EA0000]        <1> 	mov	[createfile_LastDirCluster], eax
  4341 000099C4 B9FFFFFF0F          <1> 	mov	ecx, 0FFFFFFFh ; 28 bit
  4342 000099C9 E83E050000          <1> 	call	update_cluster
  4343 000099CE 7306                <1> 	jnc	short loc_createfile_save_fat_buffer_1
  4344 000099D0 09C0                <1> 	or	eax, eax ; Was it free cluster
  4345 000099D2 7402                <1> 	jz	short loc_createfile_save_fat_buffer_1
  4346                              <1> 
  4347                              <1> loc_createfile_save_fat_buffer_stc_retn:
  4348 000099D4 F9                  <1> 	stc
  4349                              <1> loc_createfile_save_fat_buffer_retn:
  4350                              <1> loc_createfile_gffc_2_stc_retn:
  4351 000099D5 C3                  <1> 	retn
  4352                              <1> 
  4353                              <1> loc_createfile_save_fat_buffer_1:
  4354                              <1> 	; byte [FAT_BuffValidData] = 2 
  4355 000099D6 E8EE070000          <1> 	call	save_fat_buffer
  4356 000099DB 72F8                <1> 	jc	short loc_createfile_save_fat_buffer_retn
  4357                              <1> 
  4358 000099DD 803D[DEE50000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  4359 000099E4 7222                <1> 	jb	short loc_createfile_save_fat_buffer_2
  4360                              <1> 
  4361                              <1> 	; ESI = Logical DOS Drive Description Table address 
  4362 000099E6 A1[DEE50000]        <1> 	mov	eax, [FAT_ClusterCounter]
  4363                              <1> 
  4364 000099EB C605[DEE50000]00    <1> 	mov	byte [FAT_ClusterCounter], 0 ; 21/03/2016
  4365                              <1> 
  4366 000099F2 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  4367 000099F6 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 000099FB 09C9                <1> 	or	ecx, ecx 
  4374 000099FD 7409                <1> 	jz	short loc_createfile_save_fat_buffer_2
  4375                              <1> 
  4376 000099FF 66BB00FF            <1> 	mov	bx, 0FF00h ; ; recalculate free space
  4377 00009A03 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 00009A08 E82C040000          <1> 	call	get_first_free_cluster
  4384 00009A0D 72C6                <1> 	jc	short loc_createfile_gffc_2_stc_retn
  4385                              <1> 
  4386 00009A0F A3[0CEA0000]        <1> 	mov	[createfile_FFCluster], eax
  4387                              <1> 
  4388 00009A14 A1[10EA0000]        <1> 	mov	eax, [createfile_LastDirCluster]
  4389                              <1> 	
  4390 00009A19 E8AA030000          <1> 	call	load_FAT_sub_directory 
  4391 00009A1E 72B5                <1> 	jc	short loc_createfile_gffc_2_stc_retn
  4392                              <1> 
  4393 00009A20 BF00000800          <1> 	mov	edi, Directory_Buffer
  4394                              <1> 
  4395 00009A25 6629DB              <1> 	sub	bx, bx ; directory entry index/number = 0
  4396                              <1> 
  4397 00009A28 56                  <1> 	push	esi ; * ; 23/03/2016
  4398                              <1> 
  4399                              <1> loc_createfile_set_ff_dir_entry:
  4400 00009A29 66891D[1EEA0000]    <1> 	mov	[createfile_DirIndex], bx
  4401                              <1> 
  4402                              <1>         ; EDI = Directory entry address
  4403 00009A30 8B35[00EA0000]      <1> 	mov	esi, [createfile_Name_Offset]
  4404 00009A36 A1[0CEA0000]        <1> 	mov	eax, [createfile_FFCluster]
  4405 00009A3B A3[14EA0000]        <1> 	mov	[createfile_Cluster], eax ; 24/03/2016
  4406 00009A40 B5FF                <1> 	mov	ch, 0FFh
  4407 00009A42 8A0D[1CEA0000]      <1>         mov	cl, [createfile_attrib] ; file attributes
  4408                              <1> 	; CH > 0 -> File size is in EBX
  4409 00009A48 BB[08EA0000]        <1> 	mov	ebx, createfile_size
  4410                              <1>   
  4411 00009A4D E820EEFFFF          <1> 	call	make_directory_entry
  4412                              <1> 	
  4413 00009A52 5E                  <1> 	pop	esi ; * ; ESI = Logical Dos Drv Desc. Table address
  4414                              <1> 
  4415 00009A53 C605[E8E50000]02    <1> 	mov	byte [DirBuff_ValidData], 2 
  4416 00009A5A E8F0EEFFFF          <1> 	call	save_directory_buffer
  4417 00009A5F 7221                <1> 	jc	short loc_createfile_set_ff_dir_entry_retn
  4418                              <1> 
  4419 00009A61 C605[27EA0000]01    <1> 	mov	byte [createfile_UpdatePDir], 1 ; 31/03/2016 
  4420                              <1> 
  4421                              <1> loc_createfile_get_set_write_file_cluster:
  4422 00009A68 A1[08EA0000]        <1> 	mov	eax, [createfile_size]
  4423 00009A6D 09C0                <1> 	or	eax, eax
  4424 00009A6F 7570                <1> 	jnz	short loc_createfile_get_set_wfc_cont
  4425 00009A71 40                  <1> 	inc	eax
  4426                              <1> 	; 23/03/2016
  4427 00009A72 0FB61D[1DEA0000]    <1> 	movzx	ebx, byte [createfile_SecPerClust]
  4428                              <1> 	;movzx	ecx, word [esi+LD_BPB+BytesPerSec] ; 512
  4429 00009A79 0FB70D[24EA0000]    <1>         movzx   ecx, word [createfile_BytesPerSec] ; 512
  4430 00009A80 EB7C                <1> 	jmp	loc_createfile_set_cluster_count 
  4431                              <1> 
  4432                              <1> loc_createfile_set_ff_dir_entry_retn:
  4433 00009A82 C3                  <1> 	retn
  4434                              <1> 
  4435                              <1> loc_createfile_write_fcluster_to_disk:
  4436 00009A83 034668              <1> 	add	eax, [esi+LD_DATABegin] ; convert to physical address
  4437 00009A86 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 00009A8B E89E290000          <1> 	call	disk_write
  4443 00009A90 7211                <1> 	jc	short loc_createfile_dsk_wr_err
  4444                              <1> 
  4445                              <1> loc_createfile_update_fat_cluster:
  4446                              <1> 	; 21/03/2016	
  4447 00009A92 803D[26EA0000]00    <1> 	cmp	byte [createfile_wfc], 0 
  4448 00009A99 7712                <1> 	ja	short loc_createfile_update_fat_cluster_n1
  4449                              <1> 
  4450 00009A9B FE05[26EA0000]      <1> 	inc	byte [createfile_wfc] ; 1
  4451 00009AA1 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 00009AA3 B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error !
  4456 00009AA8 E9BD000000          <1> 	jmp	loc_createfile_stc_retn
  4457                              <1> 
  4458                              <1> loc_createfile_update_fat_cluster_n1:
  4459 00009AAD A1[18EA0000]        <1> 	mov	eax, [createfile_PCluster]
  4460 00009AB2 8B0D[14EA0000]      <1> 	mov	ecx, [createfile_Cluster]
  4461 00009AB8 E84F040000          <1> 	call	update_cluster
  4462 00009ABD 7308                <1> 	jnc	short loc_createfile_update_fat_cluster_n2
  4463 00009ABF 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  4464 00009AC1 0F85A3000000        <1> 	jnz	loc_createfile_stc_retn
  4465                              <1> 
  4466                              <1> loc_createfile_update_fat_cluster_n2:
  4467 00009AC7 A1[14EA0000]        <1>         mov	eax, [createfile_Cluster]
  4468 00009ACC B9FFFFFF0F          <1> 	mov	ecx, 0FFFFFFFh
  4469 00009AD1 E836040000          <1> 	call	update_cluster
  4470 00009AD6 734E                <1> 	jnc	short loc_createfile_save_fat_buffer_3
  4471 00009AD8 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  4472 00009ADA 744A                <1> 	jz	short loc_createfile_save_fat_buffer_3
  4473                              <1> 
  4474                              <1> loc_createfile_upd_fat_fcluster_stc_retn:
  4475 00009ADC 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 00009AE1 0FB70D[24EA0000]    <1> 	movzx	ecx, word [createfile_BytesPerSec] ; 512
  4480 00009AE8 01C8                <1> 	add	eax, ecx
  4481 00009AEA 48                  <1> 	dec	eax  ; add eax, 511
  4482 00009AEB 29D2                <1> 	sub	edx, edx
  4483 00009AED F7F1                <1> 	div	ecx
  4484 00009AEF 0FB61D[1DEA0000]    <1> 	movzx	ebx, byte [createfile_SecPerClust]
  4485 00009AF6 01D8                <1> 	add	eax, ebx
  4486 00009AF8 48                  <1> 	dec	eax  ; add eax, SecPerClust - 1
  4487 00009AF9 6631D2              <1> 	xor	dx, dx
  4488 00009AFC F7F3                <1> 	div	ebx
  4489                              <1> 
  4490                              <1> loc_createfile_set_cluster_count:
  4491 00009AFE A3[20EA0000]        <1> 	mov 	[createfile_CCount], eax
  4492                              <1> 	
  4493 00009B03 BF00000700          <1> 	mov	edi, Cluster_Buffer
  4494 00009B08 89C8                <1> 	mov	eax, ecx ; Bytes per Sector
  4495 00009B0A F7E3                <1> 	mul	ebx ; Sectors per Cluster 
  4496                              <1> 	; EAX = Bytes per Cluster
  4497 00009B0C 89C1                <1> 	mov	ecx, eax
  4498 00009B0E C1E902              <1> 	shr	ecx, 2 ; dword count
  4499 00009B11 31C0                <1> 	xor	eax, eax
  4500 00009B13 F3AB                <1> 	rep	stosd ; clear cluster buffer
  4501                              <1> 
  4502 00009B15 A1[14EA0000]        <1> 	mov	eax, [createfile_Cluster] ; 24/03/2016
  4503                              <1> 
  4504 00009B1A 89D9                <1> 	mov	ecx, ebx
  4505                              <1> 
  4506                              <1> loc_createfile_get_set_wf_fclust_cont:
  4507 00009B1C 83E802              <1> 	sub	eax, 2
  4508 00009B1F F7E1                <1> 	mul	ecx
  4509                              <1> 	; EAX = Logical DOS disk address (offset)
  4510 00009B21 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 00009B26 E89E060000          <1> 	call	save_fat_buffer
  4515 00009B2B 723D                <1> 	jc	loc_createfile_stc_retn
  4516                              <1> 
  4517                              <1> 	; 21/03/2016
  4518 00009B2D 803D[DEE50000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  4519 00009B34 721B                <1> 	jb	short loc_createfile_save_fat_buffer_4
  4520                              <1> 
  4521                              <1> 	; ESI = Logical DOS Drive Description Table address 
  4522 00009B36 A1[DEE50000]        <1> 	mov	eax, [FAT_ClusterCounter]
  4523 00009B3B 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  4524 00009B3F 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 00009B44 09C9                <1> 	or	ecx, ecx 
  4531 00009B46 7409                <1> 	jz	short loc_createfile_save_fat_buffer_4
  4532                              <1> 
  4533 00009B48 66BB00FF            <1> 	mov	bx, 0FF00h ; ; recalculate free space
  4534 00009B4C E80D070000          <1> 	call	calculate_fat_freespace
  4535                              <1> 
  4536                              <1> loc_createfile_save_fat_buffer_4:
  4537 00009B51 FF0D[20EA0000]      <1> 	dec	dword [createfile_CCount]
  4538                              <1> 	;jz	short loc_createfile_upd_dir_modif_date_time
  4539 00009B57 743F                <1> 	jz	short loc_createfile_stc_retn_cc ; 31/03/2016
  4540                              <1> 
  4541                              <1> loc_createfile_get_set_write_next_cluster:
  4542 00009B59 E8DB020000          <1> 	call	get_first_free_cluster
  4543 00009B5E 720A                <1> 	jc	short loc_createfile_stc_retn
  4544                              <1> 
  4545                              <1> loc_createfile_get_set_write_next_cluster_1:
  4546 00009B60 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh
  4547 00009B63 7213                <1> 	jb	short loc_createfile_get_set_write_next_cluster_2
  4548                              <1> 
  4549                              <1> loc_createfile_wnc_insufficient_disk_space:	
  4550 00009B65 B827000000          <1> 	mov	eax, 27h ; Insufficient disk space
  4551                              <1> 
  4552                              <1> loc_createfile_stc_retn:
  4553 00009B6A 803D[26EA0000]01    <1> 	cmp	byte [createfile_wfc], 1
  4554 00009B71 7324                <1> 	jnb	short loc_createfile_err_retn
  4555 00009B73 C3                  <1> 	retn
  4556                              <1> 
  4557                              <1> loc_createfile_wnc_inv_format_retn:
  4558                              <1> 	;mov	eax, 0Bh
  4559 00009B74 B00B                <1> 	mov	al, 0Bh ; Invalid format
  4560 00009B76 EBF2                <1> 	jmp	short loc_createfile_stc_retn
  4561                              <1> 	         
  4562                              <1> loc_createfile_get_set_write_next_cluster_2:
  4563 00009B78 83F802              <1> 	cmp	eax, 2
  4564 00009B7B 72F7                <1> 	jb	short loc_createfile_wnc_inv_format_retn
  4565                              <1> 
  4566                              <1> loc_createfile_get_set_write_next_cluster_3:
  4567 00009B7D 8B0D[14EA0000]      <1> 	mov	ecx, [createfile_Cluster]
  4568 00009B83 A3[14EA0000]        <1> 	mov	[createfile_Cluster], eax
  4569 00009B88 890D[18EA0000]      <1> 	mov	[createfile_PCluster], ecx
  4570 00009B8E 0FB60D[1DEA0000]    <1> 	movzx	ecx, byte [createfile_SecPerClust]
  4571 00009B95 EB85                <1> 	jmp	short loc_createfile_get_set_wf_fclust_cont
  4572                              <1> 
  4573                              <1> loc_createfile_err_retn:
  4574 00009B97 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 00009B98 9C                  <1> 	pushf	; cpu is here for an error return or completion 
  4579 00009B99 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 00009B9A A1[DEE50000]        <1> 	mov	eax, [FAT_ClusterCounter]
  4585 00009B9F 09C0                <1> 	or	eax, eax
  4586 00009BA1 741A                <1> 	jz	short loc_createfile_stc_retn_pop_eax
  4587 00009BA3 8A3D[BEDD0000]      <1> 	mov	bh, [Current_Drv]
  4588 00009BA9 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 00009BAB 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 00009BB0 21C9                <1> 	and	ecx, ecx ; cx = 0 -> valid free sector count
  4595 00009BB2 7409                <1> 	jz	short loc_createfile_stc_retn_pop_eax
  4596                              <1> 
  4597                              <1> loc_createfile_stc_retn_recalc_FAT_freespace:
  4598 00009BB4 66BB00FF            <1> 	mov	bx, 0FF00h ; bh = 0FFh -> 
  4599                              <1> 	; ESI = Logical DOS Drv DT Addr
  4600                              <1> 	; BL = 0 -> Recalculate 
  4601 00009BB8 E8A1060000          <1> 	call	calculate_fat_freespace
  4602                              <1> 
  4603                              <1> loc_createfile_stc_retn_pop_eax:
  4604 00009BBD 58                  <1> 	pop	eax
  4605 00009BBE 9D                  <1> 	popf
  4606 00009BBF 7218                <1> 	jc	short loc_createfile_retn
  4607                              <1> 
  4608                              <1> loc_createfile_retn_fcluster:
  4609 00009BC1 A1[0CEA0000]        <1> 	mov	eax, [createfile_FFCluster]
  4610 00009BC6 BB[08EA0000]        <1> 	mov	ebx, createfile_size
  4611                              <1> 	;movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  4612 00009BCB 0FB60D[1DEA0000]    <1> 	movzx	ecx, byte [createfile_SecPerClust] ; 23/03/2016
  4613 00009BD2 0FB715[1EEA0000]    <1> 	movzx	edx, word [createfile_DirIndex]
  4614                              <1> 
  4615                              <1> loc_createfile_retn:
  4616 00009BD9 C3                  <1> 	retn
  4617                              <1> 
  4618                              <1> create_fs_file:
  4619                              <1> 	; temporary (21/03/2016)
  4620 00009BDA C3                  <1> 	retn
  4621                              <1> 
  4622                              <1> delete_fs_file:
  4623                              <1> 	; temporary (28/02/2016)
  4624 00009BDB C3                  <1> 	retn
  4625                              <1> 
  4626                              <1> rename_fs_file_or_directory:
  4627 00009BDC C3                  <1> 	retn
  4628                              <1> 
  4629                              <1> make_fs_directory:
  4630                              <1> 	; temporary (21/02/2016)
  4631 00009BDD C3                  <1> 	retn
  4632                              <1> 
  4633                              <1> add_new_fs_section:
  4634                              <1> 	; temporary (11/03/2016)
  4635 00009BDE C3                  <1> 	retn
  4636                              <1> 
  4637                              <1> delete_fs_directory_entry:
  4638                              <1> 	; temporary (11/03/2016)
  4639 00009BDF C3                  <1> 	retn
  4640                              <1> 
  4641                              <1> csftdf2_read_fs_file_sectors:
  4642                              <1> 	; temporary (19/03/2016)
  4643 00009BE0 C3                  <1> 	retn
  4644                              <1> 
  4645                              <1> csftdf2_write_fs_file_sectors:
  4646                              <1> 	; temporary (19/03/2016)
  4647 00009BE1 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 00009BE2 A3[D2E50000]        <1> 	mov	[FAT_CurrentCluster], eax
    34                              <1> check_next_cluster_fat_type:
    35 00009BE7 29D2                <1> 	sub	edx, edx ; 0
    36 00009BE9 807E0302            <1>         cmp     byte [esi+LD_FATType], 2
    37 00009BED 7250                <1> 	jb	short get_FAT12_next_cluster
    38 00009BEF 0F87AF000000        <1>         ja      get_FAT32_next_cluster
    39                              <1> get_FAT16_next_cluster:
    40 00009BF5 BB00030000          <1> 	mov	ebx, 300h ;768
    41 00009BFA F7F3                <1> 	div	ebx
    42                              <1> 	; EAX = Count of 3 FAT sectors
    43                              <1> 	; EDX = Cluster Offset (< 768)
    44 00009BFC 66D1E2              <1> 	shl	dx, 1 ; Multiply by 2
    45 00009BFF 89D3                <1> 	mov	ebx, edx ; Byte Offset
    46 00009C01 81C3001C0900        <1> 	add	ebx, FAT_Buffer
    47 00009C07 66BA0300            <1> 	mov	dx, 3
    48 00009C0B F7E2                <1> 	mul	edx  
    49                              <1> 	; EAX = FAT Sector (<= 256)
    50                              <1> 	; EDX = 0
    51 00009C0D 8A0E                <1> 	mov	cl, [esi+LD_Name]
    52 00009C0F 803D[D6E50000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
    53 00009C16 0F86CC000000        <1>         jna     load_FAT_sectors0
    54 00009C1C 3A0D[D7E50000]      <1> 	cmp	cl, [FAT_BuffDrvName]
    55 00009C22 0F85C0000000        <1>         jne     load_FAT_sectors0
    56 00009C28 3B05[DAE50000]      <1> 	cmp	eax, [FAT_BuffSector]
    57 00009C2E 0F85BA000000        <1>         jne     load_FAT_sectors1
    58                              <1> 	;movzx	eax, word [ebx]
    59 00009C34 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 00009C37 6683F8F7            <1> 	cmp	ax, 0FFF7h
    69 00009C3B 725A                <1> 	jb	short loc_pass_gnc_FAT16_eoc_check
    70                              <1> 	; ax >= FFF7h (cluster 0002h to FFF6h is valid, in use)
    71 00009C3D EB56                <1> 	jmp	short loc_pass_gnc_FAT16_eoc_check_xor_eax
    72                              <1> 
    73                              <1> get_FAT12_next_cluster:
    74 00009C3F BB00040000          <1> 	mov	ebx, 400h ;1024
    75 00009C44 F7F3                <1> 	div	ebx
    76                              <1> 	; EAX = Count of 3 FAT sectors
    77                              <1> 	; EDX = Cluster Offset (< 1024)
    78 00009C46 6650                <1> 	push	ax
    79 00009C48 66B80300            <1> 	mov	ax, 3	
    80 00009C4C 66F7E2              <1> 	mul	dx    	; Multiply by 3
    81 00009C4F 66D1E8              <1> 	shr	ax, 1	; Divide by 2
    82 00009C52 6689C3              <1>         mov	bx, ax 	; Byte Offset
    83 00009C55 81C3001C0900        <1> 	add	ebx, FAT_Buffer
    84 00009C5B 6658                <1> 	pop	ax
    85 00009C5D 66BA0300            <1> 	mov	dx, 3
    86 00009C61 F7E2                <1> 	mul	edx 
    87                              <1> 	; EAX = FAT Sector (<= 12)
    88                              <1> 	; EDX = 0
    89 00009C63 8A0E                <1> 	mov	cl, [esi+LD_Name]
    90 00009C65 803D[D6E50000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
    91 00009C6C 767A                <1> 	jna	short load_FAT_sectors0
    92 00009C6E 3A0D[D7E50000]      <1> 	cmp	cl, [FAT_BuffDrvName]
    93 00009C74 7572                <1> 	jne	short load_FAT_sectors0
    94 00009C76 3B05[DAE50000]      <1> 	cmp	eax, [FAT_BuffSector]
    95 00009C7C 7570                <1> 	jne	short load_FAT_sectors1
    96 00009C7E A1[D2E50000]        <1> 	mov	eax, [FAT_CurrentCluster]
    97 00009C83 66D1E8              <1> 	shr	ax, 1
    98                              <1> 	;movzx	eax, word [ebx]
    99 00009C86 668B03              <1> 	mov	ax, [ebx]
   100 00009C89 7314                <1> 	jnc	short get_FAT12_nc_even
   101 00009C8B 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 00009C8F 663DF70F            <1> 	cmp	ax, 0FF7h
   108 00009C93 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 00009C95 31C0                <1> 	xor	eax, eax ; 0
   113                              <1> loc_pass_gnc_FAT16_eoc_check:
   114                              <1> loc_pass_gnc_FAT32_eoc_check:
   115 00009C97 8B0D[D2E50000]      <1> 	mov	ecx, [FAT_CurrentCluster]
   116 00009C9D F5                  <1> 	cmc
   117 00009C9E C3                  <1> 	retn
   118                              <1> 
   119                              <1> get_FAT12_nc_even:
   120 00009C9F 80E40F              <1> 	and	ah, 0Fh
   121 00009CA2 EBEB                <1> 	jmp	short loc_gnc_fat12_eoc_check
   122                              <1> 
   123                              <1> get_FAT32_next_cluster:
   124 00009CA4 BB80010000          <1> 	mov	ebx, 180h ;384
   125 00009CA9 F7F3                <1> 	div	ebx
   126                              <1> 	; EAX = Count of 3 FAT sectors
   127                              <1> 	; EDX = Cluster Offset (< 384)
   128 00009CAB 66C1E202            <1> 	shl	dx, 2	; Multiply by 4
   129 00009CAF 89D3                <1> 	mov	ebx, edx ; Byte Offset
   130 00009CB1 81C3001C0900        <1> 	add	ebx, FAT_Buffer
   131 00009CB7 66BA0300            <1> 	mov	dx, 3
   132 00009CBB 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 00009CBD 8A0E                <1> 	mov	cl, [esi+LD_Name]
   138 00009CBF 803D[D6E50000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
   139 00009CC6 7620                <1> 	jna	short load_FAT_sectors0
   140 00009CC8 3A0D[D7E50000]      <1> 	cmp	cl, [FAT_BuffDrvName]
   141 00009CCE 7518                <1> 	jne	short load_FAT_sectors0
   142 00009CD0 3B05[DAE50000]      <1> 	cmp	eax, [FAT_BuffSector] ; 0, 3, 6, 9 ...
   143 00009CD6 7516                <1> 	jne	short load_FAT_sectors1
   144 00009CD8 8B03                <1> 	mov	eax, [ebx]
   145 00009CDA 25FFFFFF0F          <1>  	and	eax, 0FFFFFFFh ; 28 bit Cluster
   146 00009CDF 3DF7FFFF0F          <1> 	cmp	eax, 0FFFFFF7h
   147 00009CE4 72B1                <1> 	jb	short loc_pass_gnc_FAT32_eoc_check
   148                              <1> 	; eax >= FFFFFF7h (cluster 0002h to FFFFFF6h is valid)
   149 00009CE6 EBAD                <1> 	jmp	short loc_pass_gnc_FAT16_eoc_check_xor_eax
   150                              <1> 
   151                              <1> load_FAT_sectors0:
   152 00009CE8 880D[D7E50000]      <1> 	mov	[FAT_BuffDrvName], cl
   153                              <1> load_FAT_sectors1:
   154 00009CEE A3[DAE50000]        <1> 	mov	[FAT_BuffSector], eax
   155 00009CF3 89C3                <1> 	mov	ebx, eax
   156 00009CF5 034660              <1>         add     eax, [esi+LD_FATBegin]
   157 00009CF8 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
   158 00009CFC 7706                <1>         ja      short load_FAT_sectors3
   159 00009CFE 0FB74E1C            <1> 	movzx	ecx, word [esi+LD_BPB+BPB_FATSz16]
   160 00009D02 EB03                <1> 	jmp	short load_FAT_sectors4
   161                              <1> load_FAT_sectors3:
   162 00009D04 8B4E2A              <1> 	mov	ecx, [esi+LD_BPB+BPB_FATSz32]
   163                              <1> load_FAT_sectors4:
   164 00009D07 29D9                <1> 	sub	ecx, ebx ; [FAT_BuffSector]
   165 00009D09 83F903              <1>         cmp     ecx, 3
   166 00009D0C 7605                <1>         jna     short load_FAT_sectors5
   167 00009D0E B903000000          <1> 	mov	ecx, 3
   168                              <1> load_FAT_sectors5:
   169 00009D13 BB001C0900          <1> 	mov	ebx, FAT_Buffer
   170 00009D18 E820270000          <1> 	call	disk_read
   171 00009D1D 730D                <1> 	jnc	short load_FAT_sectors_ok
   172                              <1> 	; 23/03/2016
   173 00009D1F B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error
   174 00009D24 C605[D6E50000]00    <1> 	mov	byte [FAT_BuffValidData], 0
   175 00009D2B C3                  <1> 	retn
   176                              <1> load_FAT_sectors_ok:
   177 00009D2C C605[D6E50000]01    <1> 	mov	byte [FAT_BuffValidData], 1
   178 00009D33 A1[D2E50000]        <1> 	mov	eax, [FAT_CurrentCluster]
   179 00009D38 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 00009D3D 8A1E                <1> 	mov	bl, [esi+LD_Name]
   204 00009D3F 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   205                              <1> 
   206                              <1> 	;mov	[DirBuff_DRV], bl
   207                              <1> 	;mov	[DirBuff_FATType], bh
   208 00009D42 66891D[E6E50000]    <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 00009D49 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 00009D4D 6681FA0002          <1> 	cmp	dx, 512 ; Number of Root Dir Entries
   219 00009D52 7414                <1> 	je	short lrd_mov_ecx_32
   220 00009D54 89D0                <1> 	mov	eax, edx
   221 00009D56 6683C00F            <1> 	add	ax, 15 ; round up 
   222 00009D5A 66C1E804            <1> 	shr	ax, 4  ; 16 entries per sector (512/32)
   223 00009D5E 89C1                <1> 	mov	ecx, eax ; Root directory size in sectors
   224 00009D60 66C1E009            <1> 	shl	ax, 9 ; Root directory size in bytes
   225 00009D64 664A                <1> 	dec	dx    ; Last entry number of root dir
   226                              <1> 	; cx = Dir Buffer sector count             
   227 00009D66 EB0B                <1> 	jmp	short lrd_check_dir_buffer
   228                              <1> 
   229                              <1> lrd_mov_ecx_32:
   230 00009D68 B920000000          <1> 	mov	ecx, 32
   231 00009D6D 664A                <1> 	dec	dx ; 511
   232 00009D6F 66B80040            <1> 	mov	ax, 32*512 
   233                              <1>  
   234                              <1> lrd_check_dir_buffer:
   235 00009D73 29DB                <1> 	sub	ebx, ebx ; 0
   236 00009D75 881D[E8E50000]      <1> 	mov	[DirBuff_ValidData], bl ; 0
   237 00009D7B 668915[EBE50000]    <1> 	mov	[DirBuff_LastEntry], dx
   238 00009D82 891D[EDE50000]      <1> 	mov	[DirBuff_Cluster], ebx ; 0
   239 00009D88 66A3[F1E50000]      <1> 	mov	[DirBuffer_Size], ax
   240                              <1> 
   241 00009D8E 8B4664              <1> 	mov	eax, [esi+LD_ROOTBegin]
   242                              <1> read_directory:
   243 00009D91 BB00000800          <1> 	mov	ebx, Directory_Buffer
   244 00009D96 51                  <1> 	push	ecx ; Directory buffer sector count
   245 00009D97 53                  <1> 	push	ebx
   246 00009D98 E8A0260000          <1> 	call	disk_read
   247 00009D9D 5B                  <1> 	pop	ebx
   248 00009D9E 720B                <1> 	jc	short load_DirBuff_error
   249                              <1> 
   250                              <1> validate_DirBuff_and_return:
   251 00009DA0 59                  <1> 	pop	ecx ; Number of loaded sectors
   252 00009DA1 C605[E8E50000]01    <1> 	mov	byte [DirBuff_ValidData], 1
   253 00009DA8 31C0                <1> 	xor	eax, eax ; 0 = no error
   254 00009DAA C3                  <1> 	retn
   255                              <1> 
   256                              <1> load_DirBuff_error:
   257 00009DAB 89C8                <1> 	mov	eax, ecx ; remaining sectors
   258 00009DAD 59                  <1> 	pop	ecx ; sector count
   259 00009DAE 29C1                <1> 	sub	ecx, eax ; Number of loaded sectors
   260 00009DB0 B815000000          <1> 	mov	eax, 15h ; DRV NOT READY OR READ ERROR !
   261 00009DB5 F9                  <1> 	stc
   262 00009DB6 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 00009DB7 8A1E                <1> 	mov	bl, [esi+LD_Name]
   281 00009DB9 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   282                              <1> 
   283                              <1> 	;mov	[DirBuff_DRV], bl
   284                              <1> 	;mov	[DirBuff_FATType], bh
   285 00009DBC 66891D[E6E50000]    <1> 	mov	[DirBuff_DRV], bx
   286                              <1> 
   287                              <1> load_FAT32_root_dir0:
   288 00009DC3 8B4632              <1> 	mov	eax, [esi+LD_BPB+FAT32_RootFClust]
   289 00009DC6 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 00009DC8 8A1E                <1> 	mov	bl, [esi+LD_Name]
   311 00009DCA 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   312                              <1> 
   313                              <1> 	;mov	[DirBuff_DRV], bl
   314                              <1> 	;mov	[DirBuff_FATType], bh
   315 00009DCD 66891D[E6E50000]    <1> 	mov	[DirBuff_DRV], bx
   316                              <1> 
   317                              <1> load_FAT_sub_dir0:
   318 00009DD4 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
   319                              <1> 
   320 00009DD8 882D[E8E50000]      <1> 	mov	[DirBuff_ValidData], ch ; 0
   321 00009DDE A3[EDE50000]        <1> 	mov	[DirBuff_Cluster], eax
   322                              <1> 
   323 00009DE3 0FB74611            <1> 	movzx	eax, word [esi+LD_BPB+BytesPerSec]
   324 00009DE7 F7E1                <1> 	mul	ecx
   325 00009DE9 C1E805              <1> 	shr	eax, 5 ; directory entry count (dir size / 32)
   326 00009DEC 6648                <1> 	dec	ax ; last entry
   327 00009DEE 66A3[EBE50000]      <1> 	mov	[DirBuff_LastEntry], ax
   328                              <1> 
   329 00009DF4 A1[EDE50000]        <1> 	mov	eax, [DirBuff_Cluster]
   330 00009DF9 83E802              <1> 	sub	eax, 2
   331 00009DFC F7E1                <1> 	mul	ecx
   332 00009DFE 034668              <1> 	add	eax, [esi+LD_DATABegin]
   333                              <1> 	; ecx = sector per cluster (dir buffer size = 32 sectors)
   334 00009E01 EB8E                <1> 	jmp	short read_directory
   335                              <1> 
   336                              <1> ; DRV_FS.ASM
   337                              <1> 
   338                              <1> load_current_FS_directory:
   339 00009E03 C3                  <1> 	retn
   340                              <1> load_FS_root_directory:
   341 00009E04 C3                  <1> 	retn
   342                              <1> load_FS_sub_directory:
   343 00009E05 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 00009E06 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 00009E0A 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
   369 00009E0E 761C                <1> 	jna	short read_fs_cluster
   370                              <1> 
   371                              <1> read_fat_file_sectors: ; 18/03/2016
   372 00009E10 83E802              <1> 	sub	eax, 2 ; Beginning cluster number is always 2
   373 00009E13 0FB65613            <1> 	movzx	edx, byte [esi+LD_BPB+BPB_SecPerClust] ; 18/03/2016 
   374 00009E17 F7E2                <1> 	mul	edx
   375 00009E19 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 00009E1C E81C260000          <1> 	call	disk_read
   384 00009E21 7306                <1> 	jnc	short rclust_retn
   385                              <1> 	
   386 00009E23 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error !
   387 00009E28 C3                  <1> 	retn
   388                              <1> 
   389                              <1> rclust_retn:
   390 00009E29 29C0                <1> 	sub	eax, eax ; 0
   391 00009E2B 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 00009E2C B980000000          <1> 	mov	ecx, 128 ; maximum count of sectors (before eof) 
   406 00009E31 E801000000          <1> 	call	read_fs_sectors
   407 00009E36 C3                  <1> 	retn
   408                              <1> 
   409                              <1> read_fs_sectors:
   410                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
   411 00009E37 F9                  <1> 	stc
   412 00009E38 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 00009E39 8B4678              <1> 	mov	eax, [esi+LD_Clusters]
   430 00009E3C 40                  <1> 	inc	eax ; add eax, 1
   431 00009E3D A3[70E80000]        <1> 	mov	[gffc_last_free_cluster], eax
   432                              <1> 
   433 00009E42 31DB                <1> 	xor	ebx, ebx ; 0 ; 02/03/2016
   434                              <1> 
   435 00009E44 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
   436 00009E48 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 00009E4A E834060000          <1> 	call	get_fat32_fsinfo_sector_parms
   441 00009E4F 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 00009E51 89D0                <1> 	mov	eax, edx ; FSI_Next_Free (First Free Cluster)
   453 00009E53 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh ; invalid (unknown) !
   454 00009E56 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 00009E58 B802000000          <1> 	mov	eax, 2
   459                              <1> 	;xor	edx, edx
   460                              <1> 
   461                              <1> loc_gffc_get_first_fat_free_cluster1:
   462 00009E5D 53                  <1> 	push	ebx ; 02/03/2016 
   463                              <1> 
   464                              <1> loc_gffc_get_first_fat_free_cluster2:   
   465 00009E5E A3[6CE80000]        <1> 	mov	[gffc_first_free_cluster], eax
   466 00009E63 A3[68E80000]        <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 00009E68 E875FDFFFF          <1> 	call	get_next_cluster
   474 00009E6D 7307                <1> 	jnc	short loc_gffc_get_first_fat_free_cluster4
   475 00009E6F 09C0                <1> 	or	eax, eax
   476 00009E71 740B                <1> 	jz	short loc_gffc_first_free_fat_cluster_next
   477 00009E73 5B                  <1> 	pop	ebx ; 02/03/2016
   478 00009E74 F5                  <1> 	cmc 	; stc
   479 00009E75 C3                  <1> 	retn
   480                              <1> 
   481                              <1> loc_gffc_get_first_fat_free_cluster4:
   482 00009E76 21C0                <1> 	and	eax, eax ; next cluster value
   483 00009E78 7504                <1> 	jnz	short loc_gffc_first_free_fat_cluster_next
   484 00009E7A 89C8                <1> 	mov	eax, ecx ; current (previous cluster) value
   485 00009E7C EB22                <1> 	jmp	short loc_gffc_check_for_set
   486                              <1>  
   487                              <1> loc_gffc_first_free_fat_cluster_next:
   488 00009E7E A1[68E80000]        <1> 	mov	eax, [gffc_next_free_cluster]
   489 00009E83 3B05[70E80000]      <1> 	cmp	eax, [gffc_last_free_cluster]
   490 00009E89 7308                <1> 	jnb	short retn_stc_from_get_first_free_cluster
   491                              <1> pass_gffc_last_cluster_eax_check:
   492 00009E8B 40                  <1> 	inc	eax ; add eax, 1
   493 00009E8C A3[68E80000]        <1> 	mov	[gffc_next_free_cluster], eax
   494 00009E91 EBD5                <1> 	jmp	short loc_gffc_get_first_fat_free_cluster3
   495                              <1> 
   496                              <1> retn_stc_from_get_first_free_cluster:
   497 00009E93 A1[6CE80000]        <1> 	mov	eax, [gffc_first_free_cluster]
   498 00009E98 83F802              <1> 	cmp	eax, 2
   499 00009E9B 7709                <1> 	ja	short loc_gffc_check_previous_clusters
   500 00009E9D 29C0                <1> 	sub	eax, eax
   501 00009E9F 48                  <1> 	dec	eax ; FFFFFFFFh
   502                              <1> 
   503                              <1> loc_gffc_check_for_set:
   504                              <1> 	; 02/03/2016
   505 00009EA0 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 00009EA1 09DB                <1> 	or	ebx, ebx
   512 00009EA3 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 00009EA5 C3                  <1> 	retn
   521                              <1> 
   522                              <1> loc_gffc_check_previous_clusters:
   523 00009EA6 48                  <1> 	dec	eax ; sub eax, 1
   524 00009EA7 A3[70E80000]        <1> 	mov	[gffc_last_free_cluster], eax 
   525 00009EAC B802000000          <1> 	mov	eax, 2
   526                              <1> 	;xor	edx, edx
   527 00009EB1 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 00009EB3 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 00009EB6 813B52526141        <1> 	cmp     dword [ebx], 41615252h
   565 00009EBC 7540                <1> 	jne	short loc_sffc_read_fsinfo_sector
   566 00009EBE 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
   566 00009EC7 61                  <1>
   567 00009EC8 7534                <1> 	jne	short loc_sffc_read_fsinfo_sector
   568                              <1> 
   569 00009ECA 3B83EC010000        <1> 	cmp	eax, [ebx+492]  ; FSI_Next_Free
   570 00009ED0 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 00009ED2 8983EC010000        <1> 	mov	[ebx+492], eax
   576 00009ED8 A1[80E80000]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC] 
   577 00009EDD B901000000          <1> 	mov	ecx, 1
   578 00009EE2 53                  <1> 	push	ebx
   579 00009EE3 E846250000          <1> 	call	disk_write
   580 00009EE8 7208                <1> 	jc      short loc_sffc_read_fsinfo_sector_err1
   581 00009EEA 5B                  <1> 	pop	ebx
   582                              <1> 
   583 00009EEB 8B83EC010000        <1> 	mov	eax, [ebx+492] ; First (Next) Free Cluster
   584                              <1> 
   585                              <1> loc_sffc_retn:
   586 00009EF1 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 00009EF2 BB00000000          <1> 	mov	ebx, 0
   594                              <1> 	; 23/03/2016
   595 00009EF7 B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error
   596                              <1> 
   597                              <1> loc_sffc_read_fsinfo_sector_err2:
   598 00009EFC 5A                  <1> 	pop	edx
   599 00009EFD C3                  <1> 	retn
   600                              <1> 	
   601                              <1> loc_sffc_read_fsinfo_sector:
   602 00009EFE 50                  <1> 	push	eax
   603                              <1> 
   604 00009EFF E87F050000          <1> 	call	get_fat32_fsinfo_sector_parms
   605 00009F04 72F6                <1> 	jc	short loc_sffc_read_fsinfo_sector_err2
   606                              <1> 
   607 00009F06 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 00009F07 39D0                <1> 	cmp	eax, edx ; First free Cluster (eax = new value) 
   612 00009F09 75C7                <1> 	jne	short loc_sffc_write_fsinfo_sector
   613                              <1> 
   614 00009F0B 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 00009F0C A3[D2E50000]        <1> 	mov	[FAT_CurrentCluster], eax
   648 00009F11 890D[74E80000]      <1> 	mov	[ClusterValue], ecx
   649                              <1> 
   650                              <1> loc_update_cluster_check_fat_buffer:
   651 00009F17 8A1E                <1> 	mov	bl, [esi+LD_Name]
   652 00009F19 381D[D7E50000]      <1> 	cmp	[FAT_BuffDrvName], bl
   653 00009F1F 741A                <1> 	je	short loc_update_cluster_check_fat_type
   654 00009F21 803D[D6E50000]02    <1> 	cmp	byte [FAT_BuffValidData], 2
   655 00009F28 0F84C2000000        <1>         je      loc_uc_save_fat_buffer
   656                              <1> 
   657                              <1> loc_uc_reset_fat_buffer_validation:
   658 00009F2E C605[D6E50000]00    <1> 	mov	byte [FAT_BuffValidData], 0
   659                              <1> 
   660                              <1> loc_uc_check_fat_type_reset_drvname:
   661 00009F35 881D[D7E50000]      <1> 	mov	[FAT_BuffDrvName], bl
   662                              <1> 
   663                              <1> loc_update_cluster_check_fat_type:
   664 00009F3B 29D2                <1> 	sub	edx, edx ; 26/02/2016
   665 00009F3D 8A5E03              <1> 	mov	bl, [esi+LD_FATType]
   666 00009F40 83F802              <1> 	cmp	eax, 2
   667 00009F43 0F82BE000000        <1>         jb      update_cluster_inv_data
   668 00009F49 80FB02              <1> 	cmp	bl, 2 
   669 00009F4C 0F877A010000        <1>         ja      update_fat32_cluster
   670                              <1> 	;cmp	bl, 1
   671                              <1> 	;jb	short update_cluster_inv_data
   672 00009F52 8B4E78              <1> 	mov	ecx, [esi+LD_Clusters]
   673 00009F55 41                  <1> 	inc	ecx  
   674 00009F56 890D[E2E50000]      <1> 	mov	[LastCluster], ecx
   675 00009F5C 39C8                <1> 	cmp	eax, ecx ; dword [LastCluster]
   676 00009F5E 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 00009F64 80FB01              <1> 	cmp	bl, 1 ; correct comparison is this !
   685 00009F67 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 00009F6D BB00030000          <1> 	mov	ebx, 300h ;768
   691 00009F72 F7F3                <1> 	div	ebx
   692                              <1> 	; EAX = Count of 3 FAT sectors
   693                              <1> 	; DX = Cluster offset in FAT buffer
   694 00009F74 6689D3              <1> 	mov	bx, dx  
   695 00009F77 66D1E3              <1> 	shl	bx, 1 ; Multiply by 2
   696 00009F7A 66BA0300            <1> 	mov	dx, 3
   697 00009F7E F7E2                <1> 	mul	edx  
   698                              <1> 	; EAX = FAT Sector
   699                              <1> 	; EDX = 0
   700                              <1> 	; EBX = Byte offset in FAT buffer
   701 00009F80 8A0D[D6E50000]      <1> 	mov	cl, [FAT_BuffValidData]
   702 00009F86 80F902              <1> 	cmp	cl, 2
   703 00009F89 750A                <1> 	jne	short loc_uc_check_fat16_buff_sector_load
   704                              <1> 
   705                              <1> loc_uc_check_fat16_buff_sector_save:
   706 00009F8B 3B05[DAE50000]      <1> 	cmp	eax, [FAT_BuffSector]
   707 00009F91 755D                <1> 	jne	short loc_uc_save_fat_buffer
   708 00009F93 EB15                <1> 	jmp	short loc_update_fat16_cell
   709                              <1> 
   710                              <1> loc_uc_check_fat16_buff_sector_load:
   711 00009F95 80F901              <1> 	cmp	cl, 1 ; byte [FAT_BuffValidData]
   712 00009F98 0F85FB010000        <1>         jne     loc_uc_load_fat_sectors
   713 00009F9E 3B05[DAE50000]      <1> 	cmp	eax, [FAT_BuffSector]
   714 00009FA4 0F85EF010000        <1>         jne     loc_uc_load_fat_sectors
   715                              <1> 
   716                              <1> loc_update_fat16_cell:
   717                              <1> loc_update_fat16_buffer:
   718 00009FAA 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   719                              <1> 	;movzx	eax, word [ebx]
   720 00009FB0 668B03              <1> 	mov	ax, [ebx]
   721                              <1> 	; 01/03/2016
   722 00009FB3 89C2                <1> 	mov	edx, eax ; old value of the cluster
   723 00009FB5 A3[D2E50000]        <1> 	mov	[FAT_CurrentCluster], eax
   724 00009FBA 8B0D[74E80000]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   725 00009FC0 66890B              <1> 	mov	[ebx], cx ; 16 bits !
   726                              <1> 
   727 00009FC3 C605[D6E50000]02    <1> 	mov	byte [FAT_BuffValidData], 2
   728                              <1> 	
   729 00009FCA 6683F802            <1> 	cmp	ax, 2
   730 00009FCE 723A                <1> 	jb	short return_uc_fat_stc
   731 00009FD0 3B05[E2E50000]      <1> 	cmp	eax, [LastCluster]
   732 00009FD6 7732                <1> 	ja	short return_uc_fat_stc
   733                              <1> 
   734                              <1> loc_fat_buffer_updated:
   735                              <1> 	; 01/03/2016
   736 00009FD8 F8                  <1> 	clc
   737                              <1> loc_fat_buffer_stc_1:
   738 00009FD9 9C                  <1> 	pushf
   739 00009FDA 21C9                <1> 	and	ecx, ecx
   740 00009FDC 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 00009FDE FF05[DEE50000]      <1> 	inc	dword [FAT_ClusterCounter]
   746                              <1> 
   747                              <1> loc_fat_buffer_updated_1: ; new value of the cluster > 0
   748 00009FE4 09D2                <1> 	or	edx, edx ; 02/03/2016
   749 00009FE6 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 00009FE8 FF0D[DEE50000]      <1> 	dec	dword [FAT_ClusterCounter] ; it may be negative number
   753                              <1> 
   754                              <1> loc_fat_buffer_updated_2:
   755 00009FEE 9D                  <1> 	popf
   756 00009FEF C3                  <1> 	retn
   757                              <1> 
   758                              <1> loc_uc_save_fat_buffer:
   759                              <1> 	; byte [FAT_BuffValidData] = 2 
   760 00009FF0 E8D4010000          <1> 	call	save_fat_buffer
   761 00009FF5 0F8297010000        <1>         jc      loc_fat_sectors_rw_error2
   762                              <1> 	;mov	byte [FAT_BuffValidData], 1
   763 00009FFB A1[D2E50000]        <1> 	mov	eax, [FAT_CurrentCluster]
   764                              <1> 	;mov	ecx, [ClusterValue]
   765                              <1> 	;jmp	short loc_update_cluster_check_fat_buffer
   766 0000A000 8A1E                <1> 	mov	bl, [esi+LD_Name] ; 01/03/2016
   767 0000A002 E927FFFFFF          <1>         jmp     loc_uc_reset_fat_buffer_validation
   768                              <1> 
   769                              <1> update_cluster_inv_data:
   770                              <1> 	;mov	eax, 0Dh
   771 0000A007 B00D                <1> 	mov	al, 0Dh  ; Invalid Data
   772 0000A009 C3                  <1> 	retn 
   773                              <1> 
   774                              <1> return_uc_fat_stc:
   775                              <1> 	; 01/03/2016
   776 0000A00A 31C0                <1> 	xor	eax, eax
   777 0000A00C F9                  <1> 	stc
   778 0000A00D 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 0000A00F BB00040000          <1> 	mov	ebx, 400h ;1024
   784 0000A014 F7F3                <1> 	div	ebx
   785                              <1> 	; EAX = Count of 3 FAT sectors
   786                              <1> 	; DX = Cluster offset in FAT buffer
   787 0000A016 66B90300            <1> 	mov	cx, 3
   788 0000A01A 6689C3              <1> 	mov	bx, ax
   789 0000A01D 6689C8              <1> 	mov	ax, cx ; 3
   790 0000A020 66F7E2              <1> 	mul	dx     ; Multiply by 3
   791 0000A023 66D1E8              <1> 	shr	ax, 1  ; Divide by 2
   792 0000A026 6693                <1> 	xchg	bx, ax
   793                              <1> 	; EAX = Count of 3 FAT sectors
   794                              <1> 	; EBX = Byte Offset in FAT buffer   
   795 0000A028 66F7E1              <1> 	mul	cx  ; 3 * AX
   796                              <1> 	; EAX = FAT Beginning Sector
   797                              <1> 	; EDX = 0
   798 0000A02B 8A0D[D6E50000]      <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 0000A031 80F902              <1> 	cmp	cl, 2 ; 2 = dirty buffer (must be written to disk)
   803 0000A034 750A                <1> 	jne	short loc_uc_check_fat12_buff_sector_load
   804                              <1> 
   805                              <1> loc_uc_check_fat12_buff_sector_save:
   806 0000A036 3B05[DAE50000]      <1> 	cmp	eax, [FAT_BuffSector]
   807 0000A03C 75B2                <1>         jne     short loc_uc_save_fat_buffer
   808 0000A03E EB15                <1> 	jmp	short loc_update_fat12_cell
   809                              <1> 
   810                              <1> loc_uc_check_fat12_buff_sector_load:
   811 0000A040 80F901              <1> 	cmp	cl, 1 ; byte ptr [FAT_BuffValidData]
   812 0000A043 0F8550010000        <1>         jne     loc_uc_load_fat_sectors
   813 0000A049 3B05[DAE50000]      <1> 	cmp	eax, [FAT_BuffSector]
   814 0000A04F 0F8544010000        <1>         jne     loc_uc_load_fat_sectors
   815                              <1> 
   816                              <1> loc_update_fat12_cell:
   817 0000A055 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   818 0000A05B 668B0D[D2E50000]    <1> 	mov	cx, [FAT_CurrentCluster]
   819 0000A062 66D1E9              <1> 	shr	cx, 1
   820 0000A065 668B03              <1> 	mov	ax, [ebx]
   821 0000A068 6689C2              <1> 	mov	dx, ax
   822 0000A06B 7344                <1> 	jnc	short uc_fat12_nc_even
   823                              <1> 
   824 0000A06D 6683E00F            <1> 	and	ax, 0Fh
   825 0000A071 8B0D[74E80000]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   826 0000A077 66C1E104            <1> 	shl	cx, 4
   827 0000A07B 6609C1              <1> 	or	cx, ax
   828 0000A07E 6689D0              <1> 	mov	ax, dx
   829 0000A081 66890B              <1> 	mov	[ebx], cx  ; 16 bits !
   830 0000A084 66C1E804            <1> 	shr	ax, 4 ; al(bit4..7)+ah(bit0..7)
   831                              <1> 
   832                              <1> update_fat12_buffer:
   833 0000A088 A3[D2E50000]        <1> 	mov	[FAT_CurrentCluster], eax
   834 0000A08D 89C2                <1> 	mov	edx, eax ; 01/03/2016
   835 0000A08F C605[D6E50000]02    <1> 	mov	byte [FAT_BuffValidData], 2
   836 0000A096 6683F802            <1> 	cmp	ax, 2
   837 0000A09A 0F826AFFFFFF        <1>         jb      return_uc_fat_stc
   838 0000A0A0 3B05[E2E50000]      <1> 	cmp	eax, [LastCluster]
   839 0000A0A6 0F875EFFFFFF        <1>         ja      return_uc_fat_stc
   840 0000A0AC E927FFFFFF          <1>         jmp     loc_fat_buffer_updated
   841                              <1> 
   842                              <1> uc_fat12_nc_even:
   843 0000A0B1 662500F0            <1> 	and	ax, 0F000h
   844 0000A0B5 8B0D[74E80000]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   845 0000A0BB 80E50F              <1> 	and	ch, 0Fh
   846 0000A0BE 6609C1              <1> 	or	cx, ax
   847 0000A0C1 6689D0              <1> 	mov	ax, dx
   848 0000A0C4 66890B              <1> 	mov	[ebx], cx ; 16 bits !
   849 0000A0C7 80E40F              <1> 	and	ah, 0Fh ; al(bit0..7)+ah(bit0..3)
   850 0000A0CA EBBC                <1> 	jmp	short update_fat12_buffer
   851                              <1> 
   852                              <1> update_fat32_cluster:
   853 0000A0CC 8B4E78              <1> 	mov	ecx, [esi+LD_Clusters]
   854 0000A0CF 41                  <1> 	inc	ecx
   855 0000A0D0 890D[E2E50000]      <1> 	mov	[LastCluster], ecx
   856                              <1> 
   857 0000A0D6 39C8                <1> 	cmp	eax, ecx
   858 0000A0D8 0F872CFFFFFF        <1>         ja      return_uc_fat_stc
   859                              <1> 
   860                              <1> pass_uc_fat32_errc:
   861                              <1> 	;sub	edx, edx
   862 0000A0DE BB80010000          <1> 	mov	ebx, 180h ;384
   863 0000A0E3 F7F3                <1> 	div	ebx
   864                              <1> 	; EAX = Count of 3 FAT sectors
   865                              <1> 	; DX = Cluster offset in FAT buffer
   866 0000A0E5 89D3                <1> 	mov	ebx, edx
   867 0000A0E7 C1E302              <1> 	shl	ebx, 2 ; Multiply by 4
   868 0000A0EA BA03000000          <1> 	mov	edx, 3	
   869 0000A0EF F7E2                <1> 	mul	edx
   870                              <1> 	; EBX = Cluster Offset in FAT buffer
   871                              <1> 	; EAX = FAT Sector
   872                              <1> 	; EDX = 0
   873 0000A0F1 8A0D[D6E50000]      <1> 	mov	cl, [FAT_BuffValidData]
   874 0000A0F7 80F902              <1> 	cmp	cl, 2
   875 0000A0FA 750E                <1> 	jne	short loc_uc_check_fat32_buff_sector_load
   876                              <1> 
   877                              <1> loc_uc_check_fat32_buff_sector_save:
   878 0000A0FC 3B05[DAE50000]      <1> 	cmp	eax, [FAT_BuffSector]
   879 0000A102 0F85E8FEFFFF        <1>         jne     loc_uc_save_fat_buffer
   880 0000A108 EB11                <1> 	jmp	short loc_update_fat32_cell
   881                              <1> 
   882                              <1> loc_uc_check_fat32_buff_sector_load:
   883 0000A10A 80F901              <1> 	cmp	cl, 1 ; byte [FAT_BuffValidData]
   884 0000A10D 0F8586000000        <1>         jne     loc_uc_load_fat_sectors
   885 0000A113 3B05[DAE50000]      <1> 	cmp	eax, [FAT_BuffSector]
   886 0000A119 757E                <1>         jne     loc_uc_load_fat_sectors
   887                              <1> 
   888                              <1> loc_update_fat32_cell:
   889                              <1> loc_update_fat32_buffer:
   890 0000A11B 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   891 0000A121 8B03                <1> 	mov	eax, [ebx]
   892 0000A123 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh ; 28 bit cluster value
   893                              <1> 	
   894 0000A128 8B15[D2E50000]      <1> 	mov	edx, [FAT_CurrentCluster] ; 01/03/2016
   895                              <1> 
   896 0000A12E A3[D2E50000]        <1> 	mov 	[FAT_CurrentCluster], eax
   897 0000A133 8B0D[74E80000]      <1> 	mov	ecx, [ClusterValue]
   898 0000A139 890B                <1> 	mov	[ebx], ecx ; 29/02/2016 
   899                              <1> 
   900 0000A13B C605[D6E50000]02    <1> 	mov	byte [FAT_BuffValidData], 2
   901                              <1> 
   902                              <1> 	; 01/03/2016
   903 0000A142 21C0                <1> 	and	eax, eax ; was it free cluster ?
   904 0000A144 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 0000A146 3B563E              <1> 	cmp	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free cluster
   910 0000A149 7520                <1> 	jne	short loc_upd_fat32_c3
   911                              <1> 
   912 0000A14B 3B15[E2E50000]      <1> 	cmp	edx, [LastCluster]
   913 0000A151 7207                <1> 	jb	short loc_upd_fat32_c0
   914                              <1> 
   915 0000A153 BA02000000          <1> 	mov	edx, 2 ; rewind !
   916 0000A158 EB0E                <1> 	jmp	short loc_upd_fat32_c2
   917                              <1> 
   918                              <1> loc_upd_fat32_c0:
   919 0000A15A FF463E              <1> 	inc	dword [esi+LD_BPB+BPB_Reserved+4] ; set it to next cluster		
   920 0000A15D EB0C                <1> 	jmp	short loc_upd_fat32_c3
   921                              <1> 
   922                              <1> loc_upd_fat32_c1:
   923 0000A15F 09C9                <1> 	or	ecx, ecx ; will it be free cluster ?
   924 0000A161 7508                <1> 	jnz	short loc_upd_fat32_c3
   925                              <1> 
   926 0000A163 3B563E              <1> 	cmp	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free cluster
   927 0000A166 7303                <1> 	jnb	short loc_upd_fat32_c3
   928                              <1> 
   929                              <1> loc_upd_fat32_c2:	
   930 0000A168 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx			
   931                              <1> 
   932                              <1> loc_upd_fat32_c3:
   933 0000A16B 89C2                <1> 	mov	edx, eax
   934                              <1> 
   935                              <1> loc_upd_fat32_c4:
   936 0000A16D 83F802              <1> 	cmp	eax, 2
   937 0000A170 0F8294FEFFFF        <1>         jb      return_uc_fat_stc
   938                              <1> 
   939                              <1> pass_uc_fat32_c_zero_check_2:
   940 0000A176 3B05[E2E50000]      <1> 	cmp	eax, [LastCluster]
   941 0000A17C 0F8788FEFFFF        <1>         ja      return_uc_fat_stc
   942                              <1> 	
   943 0000A182 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 0000A187 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error
   949 0000A18C 8825[D6E50000]      <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 0000A192 8B0D[74E80000]      <1> 	mov	ecx, [ClusterValue]
   955 0000A198 C3                  <1> 	retn
   956                              <1> 
   957                              <1> loc_uc_load_fat_sectors:
   958 0000A199 A3[DAE50000]        <1> 	mov	[FAT_BuffSector], eax
   959                              <1> 
   960                              <1> load_uc_fat_sectors_zero:
   961 0000A19E 034660              <1> 	add	eax, [esi+LD_FATBegin]
   962 0000A1A1 BB001C0900          <1> 	mov	ebx, FAT_Buffer
   963 0000A1A6 B903000000          <1> 	mov	ecx, 3
   964 0000A1AB E88D220000          <1> 	call	disk_read
   965 0000A1B0 72D5                <1> 	jc	short loc_fat_sectors_rw_error1
   966                              <1> 
   967 0000A1B2 C605[D6E50000]01    <1>         mov     byte [FAT_BuffValidData], 1
   968 0000A1B9 A1[D2E50000]        <1> 	mov 	eax, [FAT_CurrentCluster]
   969 0000A1BE 8B0D[74E80000]      <1> 	mov	ecx, [ClusterValue]
   970 0000A1C4 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 0000A1C9 31D2                <1> 	xor	edx, edx
   996 0000A1CB 8A35[D7E50000]      <1> 	mov	dh, [FAT_BuffDrvName]
   997 0000A1D1 80FE41              <1> 	cmp	dh, 'A'
   998 0000A1D4 722E                <1> 	jb	short loc_save_fat_buffer_inv_data_retn
   999 0000A1D6 80EE41              <1> 	sub	dh, 'A'
  1000 0000A1D9 56                  <1> 	push	esi ; *
  1001 0000A1DA BE00010900          <1>         mov     esi, Logical_DOSDisks
  1002 0000A1DF 01D6                <1> 	add	esi, edx
  1003                              <1> 	
  1004 0000A1E1 8A5603              <1> 	mov	dl, [esi+LD_FATType]
  1005 0000A1E4 20D2                <1> 	and	dl, dl
  1006 0000A1E6 741B                <1> 	jz	short loc_save_fat_buffer_inv_data_pop_retn 
  1007                              <1> 
  1008 0000A1E8 A1[DAE50000]        <1> 	mov	eax, [FAT_BuffSector]
  1009 0000A1ED 80FA02              <1> 	cmp	dl, 2
  1010 0000A1F0 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 0000A1F2 0FB74E1C            <1> 	movzx	ecx, word [esi+LD_BPB+FATSecs] 
  1019 0000A1F6 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 0000A1F8 7609                <1> 	jna	short loc_save_fat_buffer_inv_data_pop_retn ; correct addr.
  1023 0000A1FA EB15                <1> 	jmp	short loc_save_fat_buffer_check_rs3
  1024                              <1> 
  1025                              <1> loc_save_fat32_buff:
  1026 0000A1FC 8B4E2A              <1> 	mov	ecx, [esi+LD_BPB+FAT32_FAT_Size]
  1027 0000A1FF 29C1                <1> 	sub	ecx, eax
  1028 0000A201 770E                <1> 	ja	short loc_save_fat_buffer_check_rs3
  1029                              <1> 
  1030                              <1> loc_save_fat_buffer_inv_data_pop_retn:
  1031 0000A203 5E                  <1> 	pop	esi ; *
  1032                              <1> loc_save_fat_buffer_inv_data_retn:
  1033 0000A204 B80D000000          <1> 	mov	eax, 0Dh ; Invalid DATA
  1034 0000A209 C3                  <1> 	retn
  1035                              <1> 
  1036                              <1> loc_save_fat_buff_remain_sectors_3:
  1037 0000A20A B903000000          <1> 	mov	ecx, 3
  1038 0000A20F EB05                <1> 	jmp	short loc_save_fat_buff_continue
  1039                              <1> 
  1040                              <1> loc_save_fat_buffer_check_rs3:
  1041 0000A211 83F903              <1> 	cmp	ecx, 3
  1042 0000A214 77F4                <1> 	ja	short loc_save_fat_buff_remain_sectors_3
  1043                              <1> 
  1044                              <1> loc_save_fat_buff_continue:
  1045 0000A216 BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1046 0000A21B 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1047 0000A21E 51                  <1> 	push	ecx
  1048 0000A21F E80A220000          <1> 	call	disk_write
  1049 0000A224 59                  <1> 	pop	ecx
  1050 0000A225 722B                <1> 	jc	short loc_save_FAT_buff_write_err
  1051                              <1> 	
  1052 0000A227 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1053 0000A22B 7605                <1> 	jna	short loc_calc_2nd_fat12_16_addr
  1054                              <1> 
  1055                              <1> loc_calc_2nd_fat32_addr:
  1056 0000A22D 8B462A              <1> 	mov	eax, [esi+LD_BPB+FAT32_FAT_Size]
  1057 0000A230 EB04                <1> 	jmp	short loc_calc_2nd_fat_addr
  1058                              <1> 
  1059                              <1> loc_calc_2nd_fat12_16_addr:
  1060 0000A232 0FB7461C            <1> 	movzx	eax, word [esi+LD_BPB+FATSecs]
  1061                              <1> 
  1062                              <1> loc_calc_2nd_fat_addr:
  1063 0000A236 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1064 0000A239 0305[DAE50000]      <1> 	add	eax, [FAT_BuffSector]
  1065 0000A23F BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1066                              <1> 	; ecx = 1 to 3
  1067 0000A244 E8E5210000          <1> 	call	disk_write
  1068 0000A249 7207                <1> 	jc	short loc_save_FAT_buff_write_err
  1069                              <1>  	; Valid  buffer (1 = valid but do not save)
  1070 0000A24B C605[D6E50000]01    <1> 	mov	byte [FAT_BuffValidData], 1
  1071                              <1> 
  1072                              <1> loc_save_FAT_buff_write_err:
  1073 0000A252 5E                  <1> 	pop	esi ; *
  1074 0000A253 BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1075                              <1> 	; 23/03/2016
  1076 0000A258 B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error
  1077 0000A25D 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 0000A25E 66891D[7AE80000]    <1> 	mov	[CFS_OPType], bx
  1105 0000A265 A3[7CE80000]        <1> 	mov	[CFS_CC], eax
  1106                              <1> 	
  1107 0000A26A 80FFFF              <1> 	cmp	bh, 0FFh
  1108 0000A26D 740B                <1> 	je	short pass_calculate_freespace_get_drive_dt_offset
  1109                              <1> 
  1110                              <1> loc_calculate_freespace_get_drive_dt_offset:     
  1111 0000A26F 31C0                <1> 	xor	eax, eax
  1112 0000A271 88FC                <1>         mov     ah, bh
  1113 0000A273 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1114 0000A278 01C6                <1>         add     esi, eax
  1115                              <1> 
  1116                              <1> pass_calculate_freespace_get_drive_dt_offset:
  1117 0000A27A 08DB                <1> 	or	bl, bl
  1118 0000A27C 7435                <1> 	jz	short loc_reset_fcc
  1119                              <1> 	
  1120                              <1> loc_get_free_sectors:
  1121 0000A27E 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 0000A281 8B4E70              <1> 	mov	ecx, [esi+LD_TotalSectors]
  1130 0000A284 39C1                <1> 	cmp	ecx, eax ; Total sectors must be greater than Free sectors !
  1131 0000A286 7707                <1> 	ja	short loc_get_free_sectors_check_optype
  1132                              <1> 	
  1133 0000A288 31C0                <1> 	xor	eax, eax
  1134 0000A28A 48                  <1> 	dec	eax ; 0FFFFFFFFh  ; recalculation is needed!
  1135 0000A28B 894674              <1> 	mov	[esi+LD_FreeSectors], eax ; reset (for recalculation)
  1136                              <1> 		
  1137                              <1> loc_get_free_sectors_retn:
  1138 0000A28E C3                  <1> 	retn
  1139                              <1> 	
  1140                              <1> loc_get_free_sectors_check_optype:
  1141 0000A28F 80FB03              <1> 	cmp	bl, 3
  1142 0000A292 7203                <1> 	jb	short loc_set_fcc
  1143                              <1> 
  1144 0000A294 29C9                <1> 	sub	ecx, ecx ; 0
  1145                              <1> 
  1146 0000A296 C3                  <1> 	retn	
  1147                              <1> 
  1148                              <1> loc_set_fcc:
  1149 0000A297 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1150 0000A29B 0F87DF000000        <1>         ja      loc_update_FAT32_fs_info_fcc
  1151                              <1> 
  1152                              <1> 	;mov	eax, [esi+LD_FreeSectors]
  1153 0000A2A1 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  1154 0000A2A5 29D2                <1> 	sub	edx, edx
  1155 0000A2A7 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 0000A2A9 A3[F3E50000]        <1> 	mov	[FreeClusterCount], eax
  1163 0000A2AE E988000000          <1>         jmp     loc_set_free_sectors_FAT12_FAT16
  1164                              <1> 
  1165                              <1> loc_reset_fcc:
  1166 0000A2B3 31C0                <1> 	xor	eax, eax
  1167 0000A2B5 A3[F3E50000]        <1> 	mov	[FreeClusterCount], eax ; 0
  1168 0000A2BA 8B5678              <1> 	mov	edx, [esi+LD_Clusters]
  1169 0000A2BD 42                  <1> 	inc	edx
  1170 0000A2BE 8915[E2E50000]      <1> 	mov	[LastCluster], edx
  1171                              <1> 
  1172 0000A2C4 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1173 0000A2C8 7647                <1> 	jna	short loc_count_free_fat_clusters_0  
  1174                              <1> 
  1175 0000A2CA 48                  <1> 	dec	eax ; FFFFFFFFh
  1176 0000A2CB A3[84E80000]        <1> 	mov	[CFS_FAT32FC], eax
  1177                              <1> 
  1178                              <1> 	; 29/02/2016
  1179 0000A2D0 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; reset
  1180 0000A2D3 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; reset
  1181                              <1> 	
  1182 0000A2D6 B802000000          <1> 	mov 	eax, 2
  1183                              <1> 
  1184                              <1> loc_count_fc_next_cluster_0:
  1185 0000A2DB 50                  <1> 	push	eax
  1186 0000A2DC E801F9FFFF          <1> 	call	get_next_cluster
  1187 0000A2E1 7310                <1> 	jnc	short loc_check_fat32_ff_cluster
  1188 0000A2E3 09C0                <1> 	or	eax, eax
  1189 0000A2E5 741E                <1> 	jz	short pass_inc_cfs_fcc_0
  1190                              <1> 
  1191                              <1> loc_put_fcc_unknown_sign:
  1192 0000A2E7 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 0000A2E8 8B15[84E80000]      <1> 	mov	edx, [CFS_FAT32FC] ; First Free Cluster
  1200                              <1> 	; Save First Free Cluster value in FAT32 'BPB_Reserved+4' area
  1201 0000A2EE 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx
  1202                              <1> 	
  1203 0000A2F1 EB7D                <1>         jmp     loc_put_fcc_invalid_sign
  1204                              <1> 
  1205                              <1> loc_check_fat32_ff_cluster:
  1206 0000A2F3 09C0                <1> 	or	eax, eax
  1207 0000A2F5 750E                <1> 	jnz	short pass_inc_cfs_fcc_0
  1208 0000A2F7 58                  <1> 	pop	eax
  1209 0000A2F8 A3[84E80000]        <1> 	mov	[CFS_FAT32FC], eax
  1210                              <1> 	;mov	dword [FreeClusterCount], 1
  1211 0000A2FD FF05[F3E50000]      <1> 	inc	dword [FreeClusterCount]
  1212 0000A303 EB27                <1> 	jmp	short pass_inc_cfs_fcc_1
  1213                              <1> 
  1214                              <1> pass_inc_cfs_fcc_0:
  1215 0000A305 58                  <1> 	pop	eax
  1216                              <1> 
  1217                              <1> pass_inc_cfs_fcc_0c:
  1218 0000A306 40                  <1> 	inc	eax ; add eax, 1
  1219 0000A307 3B05[E2E50000]      <1> 	cmp	eax, [LastCluster]
  1220 0000A30D 76CC                <1> 	jna 	short loc_count_fc_next_cluster_0
  1221 0000A30F 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 0000A311 B002                <1> 	mov	al, 2
  1226                              <1> 
  1227                              <1> loc_count_fc_next_cluster:
  1228 0000A313 50                  <1> 	push	eax
  1229 0000A314 E8C9F8FFFF          <1> 	call	get_next_cluster
  1230 0000A319 720C                <1> 	jc	short loc_count_fcc_stc
  1231                              <1> 
  1232                              <1> loc_count_free_clusters_1:
  1233 0000A31B 21C0                <1> 	and	eax, eax
  1234 0000A31D 750C                <1> 	jnz	short pass_inc_cfs_fcc
  1235                              <1> 
  1236 0000A31F FF05[F3E50000]      <1> 	inc	dword [FreeClusterCount]
  1237 0000A325 EB04                <1> 	jmp	short pass_inc_cfs_fcc
  1238                              <1> 
  1239                              <1> loc_count_fcc_stc:
  1240 0000A327 09C0                <1> 	or	eax, eax
  1241 0000A329 75BC                <1> 	jnz	short loc_put_fcc_unknown_sign ; 29/02/2016
  1242                              <1> 
  1243                              <1> pass_inc_cfs_fcc:
  1244 0000A32B 58                  <1> 	pop	eax
  1245                              <1> 
  1246                              <1> pass_inc_cfs_fcc_1:
  1247 0000A32C 40                  <1> 	inc	eax ; add eax, 1
  1248 0000A32D 3B05[E2E50000]      <1> 	cmp	eax, [LastCluster]
  1249 0000A333 76DE                <1> 	jna	short loc_count_fc_next_cluster
  1250                              <1> 
  1251                              <1> loc_set_free_sectors:
  1252 0000A335 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1253 0000A339 7745                <1> 	ja	short loc_update_FAT32_fs_info_fcc
  1254                              <1> 
  1255                              <1> loc_set_free_sectors_FAT12_FAT16:
  1256 0000A33B 803D[7AE80000]00    <1> 	cmp	byte [CFS_OPType], 0
  1257 0000A342 761C                <1> 	jna	short pass_FAT_add_sub_fcc
  1258 0000A344 A1[7CE80000]        <1> 	mov	eax, [CFS_CC]
  1259 0000A349 803D[7AE80000]01    <1> 	cmp	byte [CFS_OPType], 1
  1260 0000A350 7708                <1> 	ja	short pass_FAT_add_fcc
  1261 0000A352 0105[F3E50000]      <1> 	add 	[FreeClusterCount], eax
  1262 0000A358 EB06                <1> 	jmp	short pass_FAT_add_sub_fcc
  1263                              <1> 
  1264                              <1> pass_FAT_add_fcc:
  1265 0000A35A 2905[F3E50000]      <1> 	sub	[FreeClusterCount], eax
  1266                              <1> 
  1267                              <1> pass_FAT_add_sub_fcc:
  1268 0000A360 0FB64613            <1> 	movzx	eax, byte [esi+LD_BPB+SecPerClust]
  1269 0000A364 8B15[F3E50000]      <1> 	mov	edx, [FreeClusterCount]
  1270 0000A36A F7E2                <1> 	mul	edx
  1271                              <1> 
  1272 0000A36C 31C9                <1> 	xor	ecx, ecx 
  1273 0000A36E EB05                <1> 	jmp	short loc_cfs_retn_params
  1274                              <1> 
  1275                              <1> loc_put_fcc_invalid_sign:
  1276 0000A370 29C0                <1>        	sub	eax, eax ; 0
  1277 0000A372 48                  <1> 	dec	eax ; FFFFFFFFh
  1278                              <1> loc_fat32_ffc_recalc_needed:
  1279 0000A373 89C1                <1> 	mov	ecx, eax
  1280                              <1> 
  1281                              <1> loc_cfs_retn_params:
  1282 0000A375 894674              <1> 	mov 	[esi+LD_FreeSectors], eax
  1283 0000A378 0FB71D[7AE80000]    <1> 	movzx	ebx, word [CFS_OPType]
  1284 0000A37F 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 0000A380 803D[7AE80000]01    <1> 	cmp	byte [CFS_OPType], 1
  1292 0000A387 7221                <1> 	jb	short loc_cfs_FAT32_get_rcalc_parms ; 0 = recalculated
  1293 0000A389 7406                <1> 	je	short loc_check_fcc_FSINFO_op1 ; 1 = add
  1294                              <1> loc_check_fcc_FSINFO_op2: ; subtract
  1295 0000A38B F71D[7CE80000]      <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 0000A391 31D2                <1> 	xor	edx, edx ; 0
  1299 0000A393 4A                  <1> 	dec	edx ; 0FFFFFFFFh
  1300 0000A394 8B463A              <1> 	mov	eax, [esi+LD_BPB+BPB_Reserved]
  1301 0000A397 39D0                <1> 	cmp	eax, edx
  1302 0000A399 73D5                <1> 	jnb	short loc_put_fcc_invalid_sign
  1303 0000A39B 0305[7CE80000]      <1>         add     eax, [CFS_CC] ; free cluster count on disk + current count
  1304 0000A3A1 72CD                <1> 	jc	short loc_put_fcc_invalid_sign
  1305                              <1> 	
  1306 0000A3A3 A3[F3E50000]        <1> 	mov	[FreeClusterCount], eax
  1307 0000A3A8 EB0E                <1> 	jmp	short loc_cfs_write_FSINFO_sector
  1308                              <1> 
  1309                              <1> loc_cfs_FAT32_get_rcalc_parms:
  1310 0000A3AA 8B15[84E80000]      <1> 	mov	edx, [CFS_FAT32FC]
  1311 0000A3B0 A1[F3E50000]        <1> 	mov	eax, [FreeClusterCount]
  1312 0000A3B5 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx ; First Free Cluster
  1313                              <1> loc_cfs_write_FSINFO_sector:
  1314 0000A3B8 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count
  1315                              <1> 	; 01/03/2016
  1316 0000A3BB E89A000000          <1> 	call	set_fat32_fsinfo_sector_parms
  1317 0000A3C0 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 0000A3C2 8B0D[F3E50000]      <1> 	mov	ecx, [FreeClusterCount]
  1327 0000A3C8 0FB64613            <1> 	movzx	eax, byte [esi+LD_BPB+SecPerClust]
  1328 0000A3CC F7E1                <1> 	mul	ecx
  1329                              <1> 	; 29/02/2016
  1330 0000A3CE 31C9                <1> 	xor	ecx, ecx ; 0
  1331 0000A3D0 09D2                <1> 	or	edx, edx ; 0 ?
  1332 0000A3D2 759C                <1>         jnz     loc_put_fcc_invalid_sign
  1333 0000A3D4 394670              <1> 	cmp	[esi+LD_TotalSectors], eax ; Volume size in sectors
  1334 0000A3D7 7697                <1>         jna     short loc_put_fcc_invalid_sign
  1335                              <1> 	;
  1336                              <1> loc_set_FAT32_free_sectors_ok:
  1337 0000A3D9 31D2                <1> 	xor	edx, edx ; 0
  1338 0000A3DB 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 0000A3DD 89C1                <1> 	mov	ecx, eax	
  1357                              <1> 
  1358                              <1> loc_glc_get_next_cluster_1:
  1359 0000A3DF 890D[88E80000]      <1> 	mov	[glc_prevcluster], ecx
  1360                              <1> 
  1361                              <1> loc_glc_get_next_cluster_2:
  1362 0000A3E5 E8F8F7FFFF          <1> 	call	get_next_cluster
  1363                              <1> 	; ecx = current/previous cluster 
  1364                              <1> 	; eax = next/last cluster
  1365 0000A3EA 73F3                <1> 	jnc	short loc_glc_get_next_cluster_1
  1366                              <1> 
  1367 0000A3EC 09C0                <1> 	or	eax, eax
  1368 0000A3EE 7509                <1> 	jnz	short loc_glc_stc_retn
  1369                              <1> 
  1370                              <1> 	; ecx = previous cluster
  1371 0000A3F0 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 0000A3F2 8B0D[88E80000]      <1> 	mov	ecx, [glc_prevcluster] 
  1378 0000A3F8 C3                  <1> 	retn
  1379                              <1> 
  1380                              <1> loc_glc_stc_retn:
  1381 0000A3F9 F5                  <1> 	cmc	;stc
  1382 0000A3FA 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 0000A3FC 31C9                <1> 	xor	ecx, ecx ; mov ecx, 0
  1402                              <1> 	;mov	byte [FAT_BuffValidData], 0
  1403 0000A3FE 890D[DEE50000]      <1> 	mov	[FAT_ClusterCounter], ecx ; 0 ; reset
  1404                              <1> 
  1405                              <1> loc_tcc_unlink_clusters:
  1406 0000A404 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 0000A409 73F9                <1> 	jnc short loc_tcc_unlink_clusters
  1413                              <1> 
  1414                              <1> pass_tcc_unlink_clusters:
  1415 0000A40B A2[8FE80000]        <1> 	mov	byte [TCC_FATErr], al
  1416 0000A410 803D[D6E50000]02    <1> 	cmp	byte [FAT_BuffValidData], 2
  1417 0000A417 750E                <1> 	jne	short loc_tcc_calculate_FAT_freespace
  1418 0000A419 E8ABFDFFFF          <1> 	call	save_fat_buffer
  1419 0000A41E 7307                <1> 	jnc	short loc_tcc_calculate_FAT_freespace
  1420 0000A420 A2[8FE80000]        <1> 	mov	byte [TCC_FATErr], al ; Error
  1421                              <1> 	;mov	byte [FAT_BuffValidData], 0
  1422                              <1> 
  1423                              <1> 	; 01/03/2016
  1424 0000A425 EB12                <1> 	jmp	short loc_tcc_recalculate_FAT_freespace
  1425                              <1> 
  1426                              <1> loc_tcc_calculate_FAT_freespace:
  1427 0000A427 A1[DEE50000]        <1> 	mov	eax, [FAT_ClusterCounter] ; signed (+-) number
  1428 0000A42C 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> ESI = Dos drv desc. table
  1429                              <1> 			   ; BL = 1 -> add cluster
  1430 0000A430 E829FEFFFF          <1> 	call	calculate_fat_freespace
  1431 0000A435 21C9                <1> 	and	ecx, ecx ; cx = 0 -> valid free sector count
  1432 0000A437 7409                <1> 	jz	short pass_truncate_cc_recalc_FAT_freespace
  1433                              <1> 
  1434                              <1> loc_tcc_recalculate_FAT_freespace:
  1435 0000A439 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate !
  1436 0000A43D 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 0000A442 8B0D[DEE50000]      <1> 	mov	ecx, [FAT_ClusterCounter]
  1441                              <1> 
  1442 0000A448 803D[8FE80000]00    <1> 	cmp	byte [TCC_FATErr], 0
  1443 0000A44F 7608                <1> 	jna	short loc_tcc_unlink_clusters_retn
  1444                              <1> 
  1445                              <1> loc_tcc_unlink_clusters_error:
  1446 0000A451 0FB605[8FE80000]    <1> 	movzx	eax, byte [TCC_FATErr]
  1447 0000A458 F9                  <1> 	stc
  1448                              <1> loc_tcc_unlink_clusters_retn:
  1449 0000A459 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 0000A45A E824000000          <1> 	call	get_fat32_fsinfo_sector_parms
  1466 0000A45F 7221                <1> 	jc	short update_fat32_fsinfo_sector_retn
  1467                              <1> 
  1468 0000A461 8B463A              <1> 	mov	eax, [esi+LD_BPB+BPB_Reserved] ; Free Cluster Count
  1469 0000A464 8B563E              <1> 	mov	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free Cluster	
  1470                              <1> 
  1471                              <1>         ;mov	ebx, DOSBootSectorBuff
  1472 0000A467 8983E8010000        <1> 	mov	[ebx+488], eax
  1473 0000A46D 8993EC010000        <1> 	mov	[ebx+492], edx	
  1474                              <1> 
  1475 0000A473 A1[80E80000]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC]
  1476 0000A478 B901000000          <1> 	mov	ecx, 1
  1477 0000A47D 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 0000A482 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 0000A483 0FB74636            <1> 	movzx	eax, word [esi+LD_BPB+FAT32_FSInfoSec]
  1507 0000A487 03466C              <1> 	add	eax, [esi+LD_StartSector]
  1508 0000A48A A3[80E80000]        <1> 	mov	[CFS_FAT32FSINFOSEC], eax
  1509                              <1> 	
  1510 0000A48F BB[D2E30000]        <1>         mov     ebx, DOSBootSectorBuff
  1511 0000A494 B901000000          <1> 	mov	ecx, 1
  1512 0000A499 E89F1F0000          <1> 	call	disk_read
  1513 0000A49E 7232                <1> 	jc	short loc_read_FAT32_fsinfo_sec_err
  1514                              <1> 
  1515 0000A4A0 BB[D2E30000]        <1> 	mov	ebx, DOSBootSectorBuff
  1516                              <1> 
  1517 0000A4A5 813B52526141        <1> 	cmp	dword [ebx], 41615252h
  1518 0000A4AB 751E                <1> 	jne	short loc_read_FAT32_fsinfo_sec_stc
  1519                              <1> 
  1520 0000A4AD 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
  1520 0000A4B6 61                  <1>
  1521 0000A4B7 7512                <1> 	jne	short loc_read_FAT32_fsinfo_sec_stc
  1522                              <1> 
  1523 0000A4B9 A1[80E80000]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC]
  1524 0000A4BE 8B8BE8010000        <1> 	mov	ecx, [ebx+488] ; free cluster count
  1525 0000A4C4 8B93EC010000        <1> 	mov	edx, [ebx+492] ; first (next) free cluster	
  1526                              <1> 
  1527 0000A4CA C3                  <1> 	retn
  1528                              <1> 
  1529                              <1> loc_read_FAT32_fsinfo_sec_stc:
  1530 0000A4CB B80B000000          <1> 	mov	eax, 0Bh ; Invalid format!
  1531 0000A4D0 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 0000A4D2 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error
  1536                              <1> 
  1537                              <1> loc_read_FAT32_fsinfo_sec_stc_retn:
  1538 0000A4D7 29DB                <1> 	sub	ebx, ebx ; 0
  1539 0000A4D9 F9                  <1> 	stc
  1540 0000A4DA 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 0000A4DB A3[ACE90000]        <1> 	mov	[FAT_anc_LCluster], eax
  1565                              <1> 	
  1566 0000A4E0 E854F9FFFF          <1> 	call	get_first_free_cluster
  1567 0000A4E5 720B                <1> 	jc	short loc_add_new_cluster_retn
  1568                              <1> 	; EAX >= 2 and EAX < FFFFFFFFh is valid
  1569                              <1> 
  1570 0000A4E7 89C2                <1> 	mov	edx, eax
  1571                              <1> 
  1572 0000A4E9 42                  <1> 	inc	edx
  1573                              <1> 	;jnz	short loc_add_new_cluster_check_ffc_eax
  1574 0000A4EA 7516                <1> 	jnz	short loc_add_new_cluster_save_fcc
  1575                              <1> 
  1576                              <1> loc_add_new_cluster_no_disk_space_retn:
  1577 0000A4EC B827000000          <1> 	mov	eax, 27h ; MSDOS err => insufficient disk space
  1578                              <1> loc_add_new_cluster_stc_retn:
  1579 0000A4F1 F9                  <1> 	stc
  1580                              <1> loc_add_new_cluster_retn:
  1581 0000A4F2 0FB65E13            <1> 	movzx	ebx, byte [esi+LD_BPB+SecPerClust]
  1582 0000A4F6 8B4E74              <1> 	mov	ecx, [esi+LD_FreeSectors]
  1583                              <1> 	;xor	edx, edx
  1584                              <1> 	;stc
  1585 0000A4F9 C3                  <1> 	retn
  1586                              <1> 
  1587                              <1> loc_anc_invalid_format_stc_retn:
  1588 0000A4FA F9                  <1> 	stc
  1589                              <1> loc_add_new_cluster_invalid_format_retn:
  1590 0000A4FB B80B000000          <1> 	mov	eax, 0Bh ; Invalid format
  1591 0000A500 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 0000A502 A3[B0E90000]        <1> 	mov	[FAT_anc_FFCluster], eax
  1599                              <1> 
  1600 0000A507 83E802              <1> 	sub	eax, 2
  1601 0000A50A 0FB65E13            <1>         movzx   ebx, byte [esi+LD_BPB+SecPerClust]
  1602 0000A50E F7E3                <1> 	mul	ebx
  1603 0000A510 09D2                <1> 	or	edx, edx
  1604 0000A512 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 0000A514 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 0000A515 BF00000700          <1> 	mov	edi, Cluster_Buffer ; 70000h (for current TRDOS 386 version)
  1621 0000A51A 89D9                <1> 	mov	ecx, ebx ; sector count
  1622 0000A51C C1E107              <1> 	shl	ecx, 7 ; 1 sector = 512 bytes -> 128 double words
  1623                              <1> 	;xor	eax, eax ; 0
  1624 0000A51F 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 0000A521 89D0                <1> 	mov	eax, edx
  1630 0000A523 034668              <1>         add     eax, [esi+LD_DATABegin]
  1631 0000A526 72D3                <1> 	jc	short loc_add_new_cluster_invalid_format_retn 
  1632                              <1> 		
  1633 0000A528 89D9                <1> 	mov	ecx, ebx ; ECX = sectors per cluster (<256)
  1634 0000A52A BB00000700          <1> 	mov	ebx, Cluster_Buffer
  1635 0000A52F E8FA1E0000          <1> 	call	disk_write
  1636 0000A534 7307                <1> 	jnc	short loc_add_new_cluster_update_fat_nlc
  1637                              <1> 	
  1638 0000A536 B81D000000          <1> 	mov	eax, 1Dh ; Write Error
  1639 0000A53B EBB4                <1> 	jmp	short loc_add_new_cluster_stc_retn
  1640                              <1> 
  1641                              <1> loc_add_new_cluster_update_fat_nlc:
  1642 0000A53D A1[B0E90000]        <1> 	mov	eax, [FAT_anc_FFCluster]
  1643 0000A542 31C9                <1> 	xor	ecx, ecx
  1644 0000A544 890D[DEE50000]      <1> 	mov	[FAT_ClusterCounter], ecx ; 0 ; reset
  1645 0000A54A 49                  <1> 	dec	ecx ; 0FFFFFFFFh
  1646 0000A54B E8BCF9FFFF          <1> 	call	update_cluster
  1647 0000A550 7304                <1> 	jnc	short loc_add_new_cluster_update_fat_plc
  1648 0000A552 09C0                <1> 	or	eax, eax ;EAX = 0 -> cluster value is 0 or eocc
  1649 0000A554 759B                <1> 	jnz	short loc_add_new_cluster_stc_retn
  1650                              <1> 
  1651                              <1> loc_add_new_cluster_update_fat_plc:
  1652 0000A556 A1[ACE90000]        <1> 	mov	eax, [FAT_anc_LCluster]
  1653 0000A55B 8B0D[B0E90000]      <1> 	mov	ecx, [FAT_anc_FFCluster]
  1654 0000A561 E8A6F9FFFF          <1> 	call	update_cluster
  1655 0000A566 7314                <1> 	jnc	short loc_add_new_cluster_save_fat_buffer
  1656 0000A568 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  1657 0000A56A 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 0000A56C 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free space (BL = 0)
  1664                              <1> 			   ; (BH = FFh -> Use ESI as Drv Param. Tbl.)
  1665 0000A570 50                  <1> 	push	eax
  1666 0000A571 E8E8FCFFFF          <1> 	call	calculate_fat_freespace
  1667 0000A576 58                  <1> 	pop	eax
  1668 0000A577 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 0000A57C E848FCFFFF          <1> 	call	save_fat_buffer
  1675 0000A581 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 0000A583 A1[DEE50000]        <1> 	mov	eax, [FAT_ClusterCounter]
  1680 0000A588 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> ESI -> Dos drv desc. table
  1681                              <1> 		; BL = 1 -> add cluster
  1682 0000A58C 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 0000A58E E8CBFCFFFF          <1>         call    calculate_fat_freespace
  1686                              <1> 	;ECX = 0 -> no error, ECX > 0 -> error or invalid return
  1687 0000A593 21C9                <1> 	and	ecx, ecx ; ECX = 0 -> valid free sector count
  1688 0000A595 7409                <1> 	jz	short loc_add_new_cluster_return_cluster_number
  1689                              <1> 
  1690                              <1> loc_add_new_cluster_recalc_FAT_freespace:
  1691 0000A597 66BB00FF            <1> 	mov	bx, 0FF00h  ; recalculate free space
  1692 0000A59B E8BEFCFFFF          <1>         call    calculate_fat_freespace
  1693                              <1> 	; cf = 0
  1694                              <1> loc_add_new_cluster_return_cluster_number:
  1695 0000A5A0 89C1                <1> 	mov	ecx, eax ; Free sector count
  1696 0000A5A2 A1[B0E90000]        <1> 	mov	eax, [FAT_anc_FFCluster]
  1697 0000A5A7 0FB65E13            <1> 	movzx	ebx, byte [esi+LD_BPB+SecPerClust]
  1698                              <1> 	;mov	edi, Cluster_Buffer
  1699 0000A5AB 31D2                <1> 	xor	edx, edx
  1700 0000A5AD 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 0000A5AE 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 0000A5B2 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  1723 0000A5B6 761C                <1> 	jna	short write_fs_cluster
  1724                              <1> 
  1725                              <1> write_fat_file_sectors: 
  1726 0000A5B8 83E802              <1> 	sub	eax, 2 ; Beginning cluster number is always 2
  1727 0000A5BB 0FB65613            <1> 	movzx	edx, byte [esi+LD_BPB+BPB_SecPerClust] ; 18/03/2016 
  1728 0000A5BF F7E2                <1> 	mul	edx
  1729 0000A5C1 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 0000A5C4 E8651E0000          <1> 	call	disk_write
  1738 0000A5C9 7306                <1> 	jnc	short wclust_retn
  1739                              <1> 	
  1740 0000A5CB B81D000000          <1> 	mov	eax, 1Dh ; Drive not ready or write error !
  1741 0000A5D0 C3                  <1> 	retn
  1742                              <1> 
  1743                              <1> wclust_retn:
  1744 0000A5D1 29C0                <1> 	sub	eax, eax ; 0
  1745 0000A5D3 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 0000A5D4 B980000000          <1> 	mov	ecx, 128 ; maximum count of sectors (before eof) 
  1760 0000A5D9 E801000000          <1> 	call	write_fs_sectors
  1761 0000A5DE C3                  <1> 	retn
  1762                              <1> 
  1763                              <1> write_fs_sectors:
  1764                              <1> 	; 21/03/2016 (TRDOS 386 =  TRDOS v2.0)
  1765 0000A5DF F9                  <1> 	stc
  1766 0000A5E0 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 0000A5E1 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  1783 0000A5E5 721E                <1>         jb      get_fs_section_by_index 
  1784                              <1> 
  1785 0000A5E7 3B4E78              <1> 	cmp	ecx, [esi+LD_Clusters]
  1786 0000A5EA 7207                <1> 	jb	short gcbi_1
  1787                              <1> gcbi_0:
  1788 0000A5EC F9                  <1> 	stc
  1789 0000A5ED B823000000          <1> 	mov	eax, 23h ; Cluster not available ! 
  1790                              <1> 			 ; MSDOS error code: FCB unavailable
  1791 0000A5F2 C3                  <1> 	retn
  1792                              <1> gcbi_1:
  1793 0000A5F3 51                  <1> 	push	ecx
  1794 0000A5F4 E8E9F5FFFF          <1> 	call	get_next_cluster
  1795 0000A5F9 59                  <1> 	pop	ecx
  1796 0000A5FA 7203                <1> 	jc	short gcbi_3
  1797 0000A5FC E2F5                <1> 	loop	gcbi_1
  1798                              <1> gcbi_2:
  1799 0000A5FE C3                  <1> 	retn
  1800                              <1> gcbi_3:
  1801 0000A5FF 09C0                <1> 	or	eax, eax
  1802 0000A601 74E9                <1> 	jz	short gcbi_0
  1803 0000A603 F5                  <1> 	cmc 	; stc
  1804 0000A604 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 0000A605 B8FFFFFFFF          <1> 	mov	eax, 0FFFFFFFFh
  1821 0000A60A 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 0000A60B 368925[D0F10000]    <1>         mov     [ss:u.sp], esp ; Kernel stack points to return address
    46                              <1> 	; save user registers
    47 0000A612 1E                  <1> 	push	ds
    48 0000A613 06                  <1> 	push	es
    49 0000A614 0FA0                <1> 	push	fs
    50 0000A616 0FA8                <1> 	push	gs
    51 0000A618 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 0000A619 50                  <1> 	push	eax ; 01/07/2015
    58 0000A61A 66B81000            <1> 	mov     ax, KDATA
    59 0000A61E 8ED8                <1>         mov     ds, ax
    60 0000A620 8EC0                <1>         mov     es, ax
    61 0000A622 8EE0                <1>         mov     fs, ax
    62 0000A624 8EE8                <1>         mov     gs, ax
    63 0000A626 A1[F8DC0000]        <1> 	mov	eax, [k_page_dir]
    64 0000A62B 0F22D8              <1> 	mov	cr3, eax
    65 0000A62E 58                  <1> 	pop	eax ; 01/07/2015
    66                              <1> 	; 19/10/2015
    67 0000A62F FC                  <1> 	cld
    68                              <1> 	;
    69 0000A630 FE05[CDF10000]      <1> 	inc	byte [sysflg]
    70                              <1> 		; incb sysflg / indicate a system routine is in progress
    71 0000A636 FB                  <1>         sti 	; 18/01/2014
    72 0000A637 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 0000A63D A3[D8F10000]        <1> 	mov	[u.r0], eax
    78 0000A642 8925[D4F10000]      <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 0000A648 C1E002              <1> 	shl	eax, 2
   100                              <1> 		; asl r0 / multiply by 2 to jump indirect in bytes
   101 0000A64B 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 0000A650 F5                  <1> 	cmc
   106 0000A651 9C                  <1> 	pushf	
   107 0000A652 50                  <1> 	push	eax
   108 0000A653 8B2D[D0F10000]      <1>  	mov 	ebp, [u.sp] ; Kernel stack at the beginning of sys call
   109 0000A659 B0FE                <1> 	mov	al, 0FEh ; 11111110b
   110 0000A65B 1400                <1> 	adc	al, 0 ; al = al + cf
   111 0000A65D 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 0000A660 5D                  <1> 	pop	ebp ; eax
   115 0000A661 9D                  <1> 	popf
   116 0000A662 0F8254010000        <1>         jc      badsys
   117 0000A668 A1[D8F10000]        <1> 	mov	eax, [u.r0]
   118                              <1> 	; system call registers: EAX, EDX, ECX, EBX, ESI, EDI
   119 0000A66D FFA5[73A60000]      <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 0000A673 [CAC20000]          <1> 	dd sysver	; 0 ; Get TRDOS 386 version number (v2.0)	
   132 0000A677 [1CA80000]          <1> 	dd sysexit 	; / 1
   133 0000A67B [86A90000]          <1> 	dd sysfork 	; / 2
   134 0000A67F [99AA0000]          <1> 	dd sysread 	; / 3
   135 0000A683 [B4AA0000]          <1> 	dd syswrite 	; / 4
   136 0000A687 [1EAB0000]          <1> 	dd sysopen 	; / 5
   137 0000A68B [58AC0000]          <1> 	dd sysclose 	; / 6
   138 0000A68F [08A90000]          <1> 	dd syswait 	; / 7
   139 0000A693 [CEAB0000]          <1> 	dd syscreat 	; / 8
   140 0000A697 [97B00000]          <1> 	dd syslink 	; / 9
   141 0000A69B [59B10000]          <1> 	dd sysunlink 	; / 10
   142 0000A69F [2CB20000]          <1> 	dd sysexec 	; / 11
   143 0000A6A3 [86B60000]          <1> 	dd syschdir 	; / 12
   144 0000A6A7 [6AB70000]          <1> 	dd systime 	; / 13
   145 0000A6AB [0FAC0000]          <1> 	dd sysmkdir 	; / 14
   146 0000A6AF [D8B60000]          <1> 	dd syschmod 	; / 15
   147 0000A6B3 [3AB70000]          <1> 	dd syschown 	; / 16
   148 0000A6B7 [9DB70000]          <1> 	dd sysbreak 	; / 17
   149 0000A6BB [F7B30000]          <1> 	dd sysstat 	; / 18
   150 0000A6BF [62B80000]          <1> 	dd sysseek 	; / 19
   151 0000A6C3 [74B80000]          <1> 	dd systell 	; / 20
   152 0000A6C7 [75B90000]          <1> 	dd sysmount 	; / 21
   153 0000A6CB [27BA0000]          <1> 	dd sysumount 	; / 22
   154 0000A6CF [F2B80000]          <1> 	dd syssetuid 	; / 23
   155 0000A6D3 [23B90000]          <1> 	dd sysgetuid 	; / 24
   156 0000A6D7 [79B70000]          <1> 	dd sysstime 	; / 25
   157 0000A6DB [E6B80000]          <1> 	dd sysquit 	; / 26
   158 0000A6DF [DAB80000]          <1> 	dd sysintr 	; / 27
   159 0000A6E3 [D3B30000]          <1> 	dd sysfstat 	; / 28
   160 0000A6E7 [74AC0000]          <1> 	dd sysemt 	; / 29
   161 0000A6EB [B9AD0000]          <1> 	dd sysmdate 	; / 30
   162                              <1> 	;dd sysstty	; / 31
   163 0000A6EF [04AE0000]          <1> 	dd sysvideo 	; 31 ; TRDOS 386 Video Functions (16/05/2016)
   164                              <1> 	;dd sysgtty	; / 32
   165 0000A6F3 [85B00000]          <1> 	dd sysaudio 	; 32 ; TRDOS 386 Audio Functions (16/05/2016)
   166                              <1> 	;dd sysilgins	; / 33
   167 0000A6F7 [8DAC0000]          <1> 	dd systimer 	; 33 ; TRDOS 386 Timer Functions (18/05/2016)
   168 0000A6FB [82BA0000]          <1> 	dd syssleep 	; 34 ; Retro UNIX 8086 v1 feature only !
   169                              <1> 			     ; 11/06/2014
   170 0000A6FF [B1BA0000]          <1> 	dd sysmsg	; 35 ; Retro UNIX 386 v1 feature only !
   171                              <1> 			     ; 01/07/2015
   172 0000A703 [87BB0000]          <1> 	dd sysgeterr	; 36 ; Retro UNIX 386 v1 feature only !
   173                              <1> 			     ; 21/09/2015 - get last error number
   174 0000A707 [D9C20000]          <1> 	dd sysreserved1 ; 37 ;; TRDOS 386 (19/05/2016)
   175 0000A70B [E8C20000]          <1> 	dd syspri 	; 38 ; change priority - TRDOS 386 (20/05/2016)
   176 0000A70F [86A70000]          <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 0000A713 8B2D[D0F10000]      <1> 	mov	ebp, [u.sp] ; interrupt (system call) return (iretd) address
   199 0000A719 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 0000A71D 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 0000A720 892D[D4F10000]      <1> 	mov	[u.usp], ebp
   209                              <1> ;err0:
   210                              <1> 	; 01/09/2015
   211 0000A726 8B25[D4F10000]      <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 0000A72C C605[3FF20000]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 0000A733 6631C0              <1> 	xor	ax, ax ; 04/05/2013
   257                              <1> sysret0: ; 29/07/2015 (eax = 0, jump from sysexec)
   258 0000A736 FEC0                <1> 	inc	al ; 04/05/2013
   259 0000A738 3805[26F20000]      <1> 	cmp	[u.bsys], al ; 1
   260                              <1> 		; tstb u.bsys / is a process about to be terminated because
   261 0000A73E 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 0000A744 FEC8                <1> 	dec 	al ; mov ax, 0
   266                              <1> 		; clr r1 / zero r1 to check last mentioned i-node
   267 0000A746 E8D01C0000          <1> 	call	iget
   268                              <1> 		; jsr r0,iget / if last mentioned i-node has been modified
   269                              <1> 		            ; / it is written out
   270 0000A74B 6631C0              <1> 	xor 	ax, ax ; 0
   271 0000A74E 3805[CBF10000]      <1> 	cmp	[smod], al ; 0
   272                              <1> 		; tstb	smod / has the super block been modified
   273 0000A754 7614                <1> 	jna	short sysret1
   274                              <1> 		; beq	1f / no, 1f
   275 0000A756 A2[CBF10000]        <1> 	mov	[smod], al ; 0
   276                              <1> 		; clrb smod / yes, clear smod
   277 0000A75B BB[85FA0000]        <1> 	mov	ebx, sb0 ;; 07/08//2013
   278 0000A760 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 0000A765 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 0000A76A 3805[CCF10000]      <1> 	cmp	[mmod], al ; 0
   289                              <1> 		; tstb	mmod / has the super block for the dismountable file
   290                              <1> 		           ; / system
   291 0000A770 7614                <1> 	jna	short sysrel0
   292                              <1> 		; beq 1f / been modified?  no, 1f
   293 0000A772 A2[CCF10000]        <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 0000A777 BB[8DFC0000]        <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 0000A77C 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 0000A781 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 0000A786 803D[1AF20000]00    <1> 	cmp	byte [u.quant], 0 ; 16/05/2013
   335                              <1> 		; tstb uquant / is the time quantum 0?
   336 0000A78D 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 0000A78F 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 0000A794 E8841C0000          <1> 	call	isintr
   357                              <1> 	; 20/10/2013
   358 0000A799 7405                <1> 	jz	short sysrel1
   359 0000A79B 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 0000A7A0 FA                  <1> 	cli ; 14/10/2015
   365 0000A7A1 FE0D[CDF10000]      <1> 	dec	byte [sysflg]
   366                              <1> 		; decb sysflg / turn system flag off
   367 0000A7A7 A1[31F20000]        <1> 	mov     eax, [u.pgdir]
   368 0000A7AC 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 0000A7AF 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 0000A7B0 A1[D8F10000]        <1> 	mov	eax, [u.r0]  ; ((return value in EAX))
   381 0000A7B5 0FA9                <1> 	pop	gs
   382 0000A7B7 0FA1                <1> 	pop	fs
   383 0000A7B9 07                  <1> 	pop	es
   384 0000A7BA 1F                  <1> 	pop	ds
   385 0000A7BB 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 0000A7BC FE05[26F20000]      <1> 	inc	byte [u.bsys]
   399                              <1> 	;
   400 0000A7C2 8B1D[D0F10000]      <1> 	mov	ebx, [u.sp] ; esp at the beginning of 'sysent'
   401 0000A7C8 8B03                <1> 	mov	eax, [ebx] ; EIP (return address, not 'INT 30h' address)
   402 0000A7CA 83E802              <1> 	sub	eax, 2 ; CDh, ##h
   403 0000A7CD E86677FFFF          <1> 	call	dwordtohex
   404 0000A7D2 8915[3DCF0000]      <1> 	mov	[eip_str], edx
   405 0000A7D8 A3[41CF0000]        <1> 	mov	[eip_str+4], eax
   406 0000A7DD A1[D8F10000]        <1> 	mov	eax, [u.r0]
   407 0000A7E2 E85177FFFF          <1> 	call	dwordtohex
   408 0000A7E7 8915[2CCF0000]      <1> 	mov	[eax_str], edx
   409 0000A7ED A3[30CF0000]        <1> 	mov	[eax_str+4], eax
   410                              <1> 
   411 0000A7F2 C605[21CF0000]40    <1> 	mov	byte [int_num_str], 40h
   412                              <1> 
   413 0000A7F9 BE[F3CE0000]        <1> 	mov	esi, ifc_msg ; "invalid funtion call !" msg (trdosk9.s)
   414 0000A7FE E83D9EFFFF          <1> 	call	print_msg
   415                              <1> 
   416 0000A803 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 0000A805 FB                  <1> 	sti
   434                              <1> 	; 07/12/2013	
   435 0000A806 66FF05[1EF20000]    <1> 	inc 	word [u.quit]
   436 0000A80D 7408                <1> 	jz	short intrct0 ; FFFFh -> 0
   437 0000A80F 66FF0D[1EF20000]    <1> 	dec	word [u.quit]
   438                              <1> 	; 16/04/2015
   439 0000A816 C3                  <1> 	retn
   440                              <1> intrct0:	
   441 0000A817 58                  <1> 	pop	eax ; call intract -> retn
   442                              <1> 	;
   443 0000A818 31C0                <1> 	xor 	eax, eax
   444 0000A81A 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 0000A81C 6648                <1> 	dec 	ax ; 0
   526 0000A81E 66A3[1CF20000]      <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 0000A824 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 0000A829 FEC0                <1> 	inc	al
   540                              <1> 		; inc r1 / increment file descriptor
   541                              <1> 	;cmp	ax, 10
   542 0000A82B 3C0A                <1> 	cmp	al, 10
   543                              <1> 		; cmp r1,$10. / end of u.fp list?
   544 0000A82D 72F5                <1> 	jb	short sysexit_1
   545                              <1> 		; blt 1b / no, go back
   546 0000A82F 0FB61D[27F20000]    <1> 	movzx	ebx, byte [u.uno]
   547                              <1> 		; movb	u.uno,r1 / yes, move dying process's number to r1
   548 0000A836 88A3[49EF0000]      <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 0000A83C D0E3                <1> 	shl	bl, 1
   552                              <1> 		; asl r1 / use r1 for index into the below tables
   553 0000A83E 668B8B[B8EE0000]    <1> 	mov	cx, [ebx+p.pid-2]
   554                              <1> 		; mov p.pid-2(r1),r3 / move dying process's name to r3
   555 0000A845 668B93[D8EE0000]    <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 0000A84C 30DB                <1> 	xor	bl, bl ; 0
   559                              <1> 		; clr r2
   560 0000A84E 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 0000A850 80C302              <1> 	add	bl, 2
   567                              <1> 		; add $2,r2 / search parent process table 
   568                              <1> 		          ; / for dying process's name
   569 0000A853 66398B[D8EE0000]    <1> 	cmp	[ebx+p.ppid-2], cx
   570                              <1> 		; cmp p.ppid-2(r2),r3 / found it?
   571 0000A85A 7513                <1> 	jne	short sysexit_4
   572                              <1> 		; bne 3f / no
   573                              <1> 	;shr	bx, 1
   574 0000A85C D0EB                <1> 	shr	bl, 1
   575                              <1> 		; asr r2 / yes, it is a parent
   576 0000A85E 80BB[49EF0000]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 0000A865 7506                <1> 	jne	short sysexit_3 
   580                              <1> 		; bne 2f / no
   581 0000A867 88A3[49EF0000]      <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 0000A86D 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 0000A86F 663993[B8EE0000]    <1> 	cmp	[ebx+p.pid-2], dx
   591                              <1> 		; cmp p.pid-2(r2),r4 / found it?
   592 0000A876 7502                <1> 	jne	short sysexit_5
   593                              <1> 		; bne 3f / no
   594 0000A878 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 0000A87A 80FB20              <1> 	cmp	bl, nproc + nproc
   600                              <1> 		; cmp r2,$nproc+nproc / has whole table been searched?
   601 0000A87D 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 0000A87F 21F6                <1> 	and	esi, esi ; r5=r1
   605 0000A881 7431                <1> 	jz	short sysexit_6
   606                              <1> 		; beq 2f / no parent has been found. 
   607                              <1> 		       ; / The process just dies
   608 0000A883 66D1EE              <1> 	shr	si, 1
   609                              <1> 		; asr r1 / set up index to p.stat
   610 0000A886 8A86[49EF0000]      <1> 	mov	al, [esi+p.stat-1]
   611                              <1> 		; movb p.stat-1(r1),r2 / move status of parent to r2
   612 0000A88C 20C0                <1> 	and	al, al
   613 0000A88E 7424                <1> 	jz	short sysexit_6
   614                              <1> 		; beq 2f / if its been freed, 2f
   615 0000A890 3C03                <1> 	cmp	al, 3
   616                              <1> 		; cmp r2,$3 / is parent a zombie?
   617 0000A892 7420                <1> 	je	short sysexit_6
   618                              <1> 		; beq 2f / yes, 2f
   619                              <1> 	; BH = 0
   620 0000A894 8A1D[27F20000]      <1> 	mov	bl, [u.uno]
   621                              <1> 		; movb u.uno,r3 / move dying process's number to r3
   622 0000A89A C683[49EF0000]03    <1> 	mov	byte [ebx+p.stat-1], 3  ; SZOMB
   623                              <1> 		; movb $3,p.stat-1(r3) / make the process a zombie
   624 0000A8A1 3C01                <1> 	cmp	al, 1 ; SRUN
   625 0000A8A3 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 0000A8A5 C686[49EF0000]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 0000A8AC 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 0000A8AF 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 0000A8B4 8A86[99EF0000]      <1> 	mov 	al, [esi+p.timer-1]
   650 0000A8BA 20C0                <1> 	and	al, al
   651 0000A8BC 743C                <1> 	jz	short sysexit_12 ; no timer events for this process
   652 0000A8BE C686[99EF0000]00    <1> 	mov	byte [esi+p.timer-1], 0 ; reset
   653 0000A8C5 A0[7FEA0000]        <1> 	mov	al, [timer_events]
   654                              <1> 	;or	al, al
   655                              <1>  	;jz	short sysexit_12 ; no timer events
   656 0000A8CA 88C1                <1> 	mov	cl, al
   657 0000A8CC 8A25[27F20000]      <1> 	mov	ah, [u.uno]
   658 0000A8D2 FA                  <1> 	cli	; disable interrupts 
   659 0000A8D3 B310                <1> 	mov	bl, 16
   660 0000A8D5 BE[9CFE0000]        <1> 	mov	esi, timer_set ; beginning address of timer events
   661                              <1> sysexit_7:
   662 0000A8DA 8A06                <1> 	mov	al, [esi] ; process number (of timer event)
   663 0000A8DC 38E0                <1> 	cmp	al, ah ; process number comparison
   664 0000A8DE 7411                <1> 	je	short sysexit_10
   665 0000A8E0 20C0                <1> 	and	al, al
   666 0000A8E2 7404                <1> 	jz	short sysexit_9
   667                              <1> sysexit_8:
   668 0000A8E4 FEC9                <1> 	dec	cl
   669 0000A8E6 7410                <1> 	jz	short sysexit_11
   670                              <1> sysexit_9:
   671 0000A8E8 FECB                <1> 	dec	bl
   672 0000A8EA 740C                <1> 	jz	short sysexit_11
   673 0000A8EC 83C610              <1> 	add	esi, 16
   674 0000A8EF EBE9                <1> 	jmp	short sysexit_7
   675                              <1> 
   676                              <1> sysexit_10:
   677                              <1> 	;mov	byte [esi], 0
   678 0000A8F1 66C7060000          <1> 	mov	word [esi], 0
   679                              <1> 	;mov	dword [esi+12], 0
   680 0000A8F6 EBEC                <1> 	jmp	short sysexit_8
   681                              <1> 
   682                              <1> sysexit_11:
   683 0000A8F8 30C0                <1> 	xor	al, al
   684                              <1> sysexit_12: ; 2:
   685 0000A8FA FB                  <1> 	sti	; enable interrupts 
   686                              <1> 	;
   687 0000A8FB A2[27F20000]        <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 0000A900 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 0000A905 F4                  <1> 	hlt
   698 0000A906 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 0000A908 0FB61D[27F20000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
   741                              <1> 		; movb u.uno,r1 / put parents process number in r1
   742 0000A90F D0E3                <1> 	shl	bl, 1
   743                              <1> 	;shl	bx, 1
   744                              <1> 		; asl r1 / x2 to get index into p.pid table
   745 0000A911 668B83[B8EE0000]    <1> 	mov	ax, [ebx+p.pid-2]
   746                              <1> 		; mov p.pid-2(r1),r1 / get the name of this process
   747 0000A918 31F6                <1> 	xor	esi, esi
   748                              <1> 		; clr r2
   749 0000A91A 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 0000A91C 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 0000A920 663B86[D8EE0000]    <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 0000A927 7535                <1> 	jne	short syswait_3
   761                              <1> 		;bne 3f / branch if no match of parent process name
   762                              <1> 	;inc	cx
   763 0000A929 FEC1                <1> 	inc	cl
   764                              <1> 		;inc r3 / yes, a match, r3 indicates number of children
   765 0000A92B 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 0000A92E 80BE[49EF0000]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 0000A935 7524                <1> 	jne	short syswait_2
   775                              <1> 		; bne 2f / no, skip it
   776 0000A937 88BE[49EF0000]      <1> 	mov	[esi+p.stat-1], bh ; 0
   777                              <1> 		; clrb p.stat-1(r2) / yes, free it
   778 0000A93D 66D1E6              <1> 	shl	si, 1
   779                              <1> 		; asl r2 / r2x2 to get index into p.pid table
   780 0000A940 0FB786[B8EE0000]    <1> 	movzx	eax, word [esi+p.pid-2]
   781 0000A947 A3[D8F10000]        <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 0000A94C 6629C0              <1> 	sub	ax, ax
   797 0000A94F 668986[D8EE0000]    <1> 	mov 	[esi+p.ppid-2], ax ; 0 ; 17/09/2015
   798 0000A956 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 0000A95B 66D1E6              <1> 	shl	si, 1
   804                              <1> 		; asl r2 / r2x2 to get index into p.ppid table
   805                              <1> syswait_3: ; 3:
   806 0000A95E 6683FE20            <1> 	cmp	si, nproc+nproc
   807                              <1> 		; cmp r2,$nproc+nproc / have all processes been checked?
   808 0000A962 72B8                <1> 	jb	short syswait_1
   809                              <1> 		; blt 1b / no, continue search
   810                              <1> 	;and	cx, cx
   811 0000A964 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 0000A966 750B                <1> 	jnz	short syswait_4
   816                              <1> 	;jz	error
   817                              <1> 		; beq error1 / there are no children, error
   818 0000A968 890D[D8F10000]      <1> 	mov	[u.r0], ecx ; 0
   819 0000A96E E9A0FDFFFF          <1> 	jmp	error
   820                              <1> syswait_4:
   821 0000A973 8A1D[27F20000]      <1> 	mov	bl, [u.uno]
   822                              <1> 		; movb u.uno,r1 / there are children so put 
   823                              <1> 			      ; / parent process number in r1
   824 0000A979 FE83[49EF0000]      <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 0000A97F E836180000          <1> 	call	swap
   829                              <1> 		; jsr r0,swap / swap it out, because it's waiting
   830 0000A984 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 0000A986 31F6                <1> 	xor 	esi, esi
   958                              <1> 		; clr r1
   959                              <1> sysfork_1: ; 1: / search p.stat table for unused process number
   960 0000A988 46                  <1> 	inc	esi
   961                              <1> 		; inc r1
   962 0000A989 80BE[49EF0000]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 0000A990 760B                <1> 	jna	short sysfork_2	
   965                              <1> 		; beq 1f / it's unused so branch
   966 0000A992 6683FE10            <1> 	cmp	si, nproc
   967                              <1> 		; cmp r1,$nproc / all processes checked
   968 0000A996 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 0000A998 E976FDFFFF          <1> 	jmp	error
   981                              <1> sysfork_2: ; 1:
   982 0000A99D E8048EFFFF          <1> 	call	allocate_page
   983 0000A9A2 0F826BFDFFFF        <1> 	jc	error
   984 0000A9A8 50                  <1> 	push	eax   ; UPAGE (user structure page) address
   985                              <1> 	; Retro UNIX 386 v1 modification!
   986 0000A9A9 E80190FFFF          <1> 	call	duplicate_page_dir
   987                              <1> 		; EAX = New page directory 
   988 0000A9AE 730B                <1> 	jnc	short sysfork_3
   989 0000A9B0 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
   990 0000A9B1 E8C88FFFFF          <1> 	call 	deallocate_page
   991 0000A9B6 E958FDFFFF          <1> 	jmp	error
   992                              <1> sysfork_3:
   993                              <1> 	; Retro UNIX 386 v1 modification !
   994 0000A9BB 56                  <1> 	push	esi
   995 0000A9BC E887180000          <1> 	call	wswap ; save current user (u) structure, user registers
   996                              <1> 		      ; and interrupt return components (for IRET)
   997 0000A9C1 8705[31F20000]      <1> 	xchg	eax, [u.pgdir] ; page directory of the child process
   998 0000A9C7 A3[35F20000]        <1> 	mov	[u.ppgdir], eax ; page directory of the parent process
   999 0000A9CC 5E                  <1> 	pop	esi
  1000 0000A9CD 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
  1001                              <1> 		; [u.usp] = esp
  1002 0000A9CE 89F7                <1> 	mov	edi, esi
  1003 0000A9D0 66C1E702            <1> 	shl	di, 2
  1004 0000A9D4 8987[56EF0000]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
  1005 0000A9DA A3[28F20000]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
  1006                              <1> 	; 28/08/2015
  1007 0000A9DF 0FB605[27F20000]    <1> 	movzx	eax, byte [u.uno] ; parent process number
  1008                              <1> 		; movb u.uno,-(sp) / save parent process number
  1009 0000A9E6 89C7                <1> 	mov	edi, eax
  1010 0000A9E8 50                  <1>         push	eax ; ** 
  1011 0000A9E9 8A87[19EF0000]      <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 0000A9EF 668986[19EF0000]    <1> 	mov     [esi+p.ttyc-1], ax ; al - set child's console tty
  1016                              <1> 				   ; ah - reset child's wait channel	
  1017 0000A9F6 89F0                <1> 	mov	eax, esi
  1018 0000A9F8 A2[27F20000]        <1> 	mov	[u.uno], al ; child process number
  1019                              <1> 		;movb r1,u.uno / set child process number to r1
  1020 0000A9FD FE86[49EF0000]      <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 0000AA03 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 0000AA04 E8A1180000          <1> 	call	putlu 
  1033                              <1>  		; jsr r0,putlu / put child process on lowest priority 
  1034                              <1> 			   ; / run queue
  1035 0000AA09 66D1E6              <1> 	shl	si, 1
  1036                              <1> 		; asl r1 / multiply r1 by 2 to get index 
  1037                              <1> 		       ; / into p.pid table
  1038 0000AA0C 66FF05[C0F10000]    <1> 	inc	word [mpid]
  1039                              <1> 		; inc mpid / increment m.pid; get a new process name
  1040 0000AA13 66A1[C0F10000]      <1> 	mov	ax, [mpid]
  1041 0000AA19 668986[B8EE0000]    <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 0000AA20 5A                  <1> 	pop	edx  ; * return address for the child process
  1045                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
  1046 0000AA21 5B                  <1>   	pop	ebx  ; **
  1047                              <1> 	;mov	ebx, [esp] ; ** parent process number
  1048                              <1> 		; movb (sp),r2 / put parent process number in r2
  1049 0000AA22 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 0000AA25 668B83[B8EE0000]    <1> 	mov	ax, [ebx+p.pid-2]
  1053                              <1> 		; mov p.pid-2(r2),r2 / get process name of parent
  1054                              <1> 				   ; / process
  1055 0000AA2C 668986[D8EE0000]    <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 0000AA33 A3[D8F10000]        <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 0000AA38 8B2D[D0F10000]      <1> 	mov 	ebp, [u.sp] ; points to return address (EIP for IRET)
  1062 0000AA3E 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 0000AA41 68[33A70000]        <1> 	push	sysret ; ***
  1071 0000AA46 8925[D4F10000]      <1> 	mov	[u.usp], esp ; points to 'sysret' address (***)
  1072                              <1> 			     ; (for child process)	
  1073 0000AA4C 31C0                <1> 	xor 	eax, eax
  1074 0000AA4E 66A3[08F20000]      <1> 	mov 	[u.ttyp], ax ; 0
  1075                              <1> 	;
  1076 0000AA54 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 0000AA59 58                  <1> 	pop	eax ; ***
  1083 0000AA5A 66D1E3              <1> 	shl	bx, 1
  1084 0000AA5D 8B83[56EF0000]      <1> 	mov     eax, [ebx+p.upage-4] ; UPAGE address ; 14/05/2015
  1085 0000AA63 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 0000AA68 0FB705[C0F10000]    <1>         movzx   eax, word [mpid]
  1089 0000AA6F A3[D8F10000]        <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 0000AA74 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 0000AA76 8A86[DEF10000]      <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 0000AA7C 08C0                <1> 	or	al, al
  1106 0000AA7E 740D                <1> 	jz	short sysfork_5	
  1107                              <1> 		; beq 2f / file has not been opened by parent, 
  1108                              <1> 		       ; / so branch
  1109 0000AA80 B40A                <1> 	mov	ah, 10 ; Retro UNIX 386 v1 fsp structure size = 10 bytes
  1110 0000AA82 F6E4                <1> 	mul	ah
  1111                              <1> 	;movzx	ebx, ax
  1112 0000AA84 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 0000AA87 FE83[A8EF0000]      <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 0000AA8D 46                  <1>         inc     esi
  1123                              <1> 		; inc r1 / get next open file
  1124 0000AA8E 6683FE0A            <1>         cmp     si, 10
  1125                              <1> 		; cmp r1,$10. / 10. files is the maximum number which
  1126                              <1> 			  ; / can be opened
  1127 0000AA92 72E2                <1> 	jb	short sysfork_4	
  1128                              <1> 		; blt 1b / check next entry
  1129 0000AA94 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 0000AA99 E83D000000          <1> 	call	rw1
  1164 0000AA9E 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 0000AAA4 F6C480              <1> 	test	ah, 80h
  1167                              <1> 		; tst r1 / negative i-number?
  1168 0000AAA7 0F8566FCFFFF        <1> 	jnz	error
  1169                              <1> 		; ble error1 / yes, error 1 to read
  1170                              <1> 			   ; / it should be positive
  1171 0000AAAD E813140000          <1> 	call	readi
  1172                              <1> 		; jsr r0,readi / read data into core
  1173 0000AAB2 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 0000AAB4 E822000000          <1> 	call	rw1
  1206 0000AAB9 0F8254FCFFFF        <1> 	jc	error ; 13/05/2015, ax < 1
  1207                              <1> 		; jsr r0,rw1 / get i-number in r1 of file to write
  1208 0000AABF F6C480              <1>         test	ah, 80h
  1209                              <1> 		; tst r1 / positive i-number ?
  1210 0000AAC2 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 0000AAC4 66F7D8              <1>         neg	ax
  1215                              <1> 		; neg r1 / make it positive
  1216 0000AAC7 E852190000          <1> 	call	writei
  1217                              <1>         	; jsr r0,writei / write data
  1218                              <1> rw0: ; 1:
  1219 0000AACC A1[00F20000]        <1>         mov	eax, [u.nread]
  1220 0000AAD1 A3[D8F10000]        <1> 	mov	[u.r0], eax
  1221                              <1> 		; mov u.nread,*u.r0 / put no. of bytes transferred
  1222                              <1> 				  ; / into (u.r0)
  1223 0000AAD6 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 0000AADB C705[D8F10000]0000- <1> 	mov	dword [u.r0], 0 ; r/w transfer count = 0 (reset)
  1241 0000AAE3 0000                <1>
  1242                              <1> 	;
  1243                              <1> 	;; call	getf
  1244                              <1>         ; eBX = File descriptor
  1245 0000AAE5 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 0000AAEA 6683F801            <1> 	cmp 	ax, 1
  1250 0000AAEE 7217                <1> 	jb	short rw2
  1251                              <1> 	;
  1252 0000AAF0 890D[F8F10000]      <1> 	mov	[u.base], ecx 	; buffer address/offset 
  1253                              <1> 				;(in the user's virtual memory space)
  1254 0000AAF6 8915[FCF10000]      <1> 	mov	[u.count], edx 
  1255                              <1> 	; 14/05/2015
  1256 0000AAFC C705[2DF20000]0000- <1>         mov     dword [u.error], 0 ; reset the last error code
  1256 0000AB04 0000                <1>
  1257 0000AB06 C3                  <1> 	retn
  1258                              <1>         	; rts r0
  1259                              <1> rw2:
  1260                              <1> 	; 13/05/2015
  1261 0000AB07 C705[2DF20000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
  1261 0000AB0F 0000                <1>
  1262 0000AB11 C3                  <1> 	retn
  1263                              <1> rw3: 
  1264                              <1> 	; 13/05/2015
  1265 0000AB12 C705[2DF20000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  1265 0000AB1A 0000                <1>
  1266 0000AB1C F9                  <1> 	stc
  1267 0000AB1D 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 0000AB1E 891D[F0F10000]      <1> 	mov	[u.namep], ebx
  1318 0000AB24 6651                <1> 	push	cx
  1319 0000AB26 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 0000AB2B 723B                <1> 	jc	short fnotfound ; 14/05/2015
  1324                              <1> 	;jc	error ; 27/05/2013
  1325                              <1> 		; br  error2 / file not found
  1326 0000AB2D 665A                <1>    	pop	dx ; mode
  1327 0000AB2F 6652                <1> 	push	dx
  1328                              <1> 	;or	dx, dx
  1329 0000AB31 08D2                <1> 	or	dl, dl
  1330                              <1> 		; tst (sp) / is mode = 0 (2nd arg of call; 
  1331                              <1> 		         ; / 0 means, open for read)
  1332 0000AB33 7403                <1> 	jz	short sysopen_0
  1333                              <1> 		; beq 1f / yes, leave i-number positive
  1334                              <1> syscreat_0: ; 27/12/2015
  1335 0000AB35 66F7D8              <1> 	neg	ax
  1336                              <1>         	; neg r1 / open for writing so make i-number negative
  1337                              <1> sysopen_0: ;1:
  1338 0000AB38 E8E2180000          <1> 	call	iopen
  1339                              <1> 		;jsr r0,iopen / open file whose i-number is in r1
  1340 0000AB3D 665A                <1> 	pop	dx
  1341                              <1> 	;and	dx, dx
  1342 0000AB3F 20D2                <1> 	and	dl, dl
  1343                              <1>         	; tst (sp)+ / pop the stack and test the mode
  1344 0000AB41 7403                <1> 	jz	short sysopen_2
  1345                              <1>         	; beq op1 / is open for read op1
  1346                              <1> sysopen_1: ;op0:
  1347 0000AB43 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 0000AB46 31F6                <1>         xor     esi, esi
  1354                              <1>         	; clr r2 / clear registers
  1355 0000AB48 31DB                <1>         xor     ebx, ebx
  1356                              <1> 		; clr r3
  1357                              <1> sysopen_3: ;1: / scan the list of entries in fsp table
  1358 0000AB4A 389E[DEF10000]      <1>         cmp     [esi+u.fp], bl ; 0
  1359                              <1> 		; tstb u.fp(r2) / test the entry in the u.fp list
  1360 0000AB50 7625                <1>         jna      short sysopen_4
  1361                              <1> 		; beq 1f / if byte in list is 0 branch
  1362 0000AB52 46                  <1>         inc     esi
  1363                              <1> 		; inc r2 / bump r2 so next byte can be checked
  1364 0000AB53 6683FE0A            <1>         cmp     si, 10
  1365                              <1> 		; cmp r2,$10. / reached end of list?
  1366 0000AB57 72F1                <1> 	jb	short sysopen_3
  1367                              <1> 		; blt 1b / no, go back
  1368                              <1> toomanyf:
  1369                              <1> 	; 14/05/2015
  1370 0000AB59 C705[2DF20000]0D00- <1> 	mov	dword [u.error], ERR_TOO_MANY_FILES ; too many open files !
  1370 0000AB61 0000                <1>
  1371 0000AB63 E9ABFBFFFF          <1> 	jmp	error
  1372                              <1>         	; br error2 / yes, error (no files open)
  1373                              <1> fnotfound: 
  1374                              <1> 	; 14/05/2015
  1375 0000AB68 C705[2DF20000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; file not found !
  1375 0000AB70 0000                <1>
  1376 0000AB72 E99CFBFFFF          <1> 	jmp	error
  1377                              <1> 
  1378                              <1> sysopen_4: ; 1:
  1379 0000AB77 6683BB[AAEF0000]00  <1>         cmp     word [ebx+fsp], 0
  1380                              <1> 		; tst fsp(r3) / scan fsp entries
  1381 0000AB7F 7610                <1>         jna     short sysopen_5
  1382                              <1> 		; beq 1f / if 0 branch
  1383                              <1> 	; 14/05/2015 - Retro UNIX 386 v1 modification !
  1384 0000AB81 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 0000AB85 6681FBF401          <1>         cmp     bx, nfiles*10
  1388                              <1> 		; cmp r3,$[nfiles*8.] / done scanning
  1389 0000AB8A 72EB                <1> 	jb	short sysopen_4
  1390                              <1>        		; blt 1b / no, back
  1391 0000AB8C 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 0000AB91 668983[AAEF0000]    <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 0000AB98 668B3D[B8F10000]    <1> 	mov	di, [cdev] ; word ? byte ?
  1398 0000AB9F 6689BB[ACEF0000]    <1>         mov     [ebx+fsp+2], di ; device number
  1399                              <1> 		; mov cdev,fsp+2(r3) / put # of device in next word
  1400 0000ABA6 31FF                <1>         xor	edi, edi
  1401 0000ABA8 89BB[AEEF0000]      <1>         mov     [ebx+fsp+4], edi ; offset pointer (0)
  1402                              <1> 		; clr fsp+4(r3)
  1403 0000ABAE 6689BB[B2EF0000]    <1>         mov     [ebx+fsp+8], di ; open count (0), deleted flag (0)
  1404                              <1>        		; clr fsp+6(r3) / clear the next two words
  1405 0000ABB5 89D8                <1>   	mov	eax, ebx
  1406 0000ABB7 B30A                <1> 	mov	bl, 10
  1407 0000ABB9 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 0000ABBB FEC0                <1> 	inc	al
  1412                              <1>         	; inc r3 / add 1 to get fsp entry number
  1413 0000ABBD 8886[DEF10000]      <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 0000ABC3 8935[D8F10000]      <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 0000ABC9 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 0000ABCE 891D[F0F10000]      <1> 	mov	[u.namep], ebx ; file name address
  1486 0000ABD4 6651                <1> 	push	cx ; mode
  1487 0000ABD6 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 0000ABDB 721E                <1> 	jc	short syscreat_1
  1492                              <1> 		; br  2f / if file doesn't exist 2f
  1493                              <1> 	; 27/12/2015
  1494 0000ABDD 6683F829            <1> 	cmp	ax, 41 ; device inode ?
  1495 0000ABE1 0F824EFFFFFF        <1>         jb      syscreat_0 ; yes
  1496                              <1> 	;
  1497 0000ABE7 66F7D8              <1> 	neg 	ax
  1498                              <1>         	; neg r1 / if file already exists make i-number 
  1499                              <1> 		       ; / negative (open for writing)
  1500 0000ABEA E830180000          <1> 	call	iopen
  1501                              <1>         	; jsr r0,iopen /
  1502 0000ABEF E82D180000          <1> 	call	itrunc
  1503                              <1>         	; jsr r0,itrunc / truncate to 0 length
  1504 0000ABF4 6659                <1> 	pop	cx ; pop mode (did not exist in original Unix v1 !?)
  1505 0000ABF6 E948FFFFFF          <1>         jmp     sysopen_1
  1506                              <1>         	; br op0
  1507                              <1> syscreat_1: ; 2: / file doesn't exist
  1508 0000ABFB 6658                <1> 	pop	ax
  1509                              <1>         	; mov (sp)+,r1 / put the mode in r1
  1510 0000ABFD 30E4                <1> 	xor	ah, ah	
  1511                              <1>         	; bic $!377,r1 / clear upper byte
  1512 0000ABFF E8DE0B0000          <1> 	call 	maknod
  1513                              <1>         	; jsr r0,maknod / make an i-node for this file
  1514 0000AC04 66A1[0AF20000]      <1> 	mov	ax, [u.dirbuf]
  1515                              <1>         	; mov u.dirbuf,r1 / put i-number 
  1516                              <1> 			        ; / for this new file in r1
  1517 0000AC0A 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 0000AC0F 891D[F0F10000]      <1> 	mov	[u.namep], ebx
  1559 0000AC15 6651                <1> 	push	cx ; mode
  1560 0000AC17 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 0000AC1C 731C                <1> 	jnc	short dir_exists ; 14/05/2015
  1566                              <1> 	;jnc	error	
  1567                              <1> 		; br  error2 / directory already exists (error)
  1568 0000AC1E 803D[24F20000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
  1569                              <1>         	;tstb u.uid / is user the super user
  1570 0000AC25 7622                <1> 	jna	short dir_access_err ; 14/05/2015
  1571                              <1> 	;jna	error
  1572                              <1>         	;bne error2 / no, not allowed
  1573 0000AC27 6658                <1> 	pop	ax
  1574                              <1>         	;mov (sp)+,r1 / put the mode in r1
  1575 0000AC29 6683E0CF            <1> 	and	ax, 0FFCFh ; 1111111111001111b
  1576                              <1>         	;bic $!317,r1 / all but su and ex
  1577                              <1> 	;or	ax , 4000h ; 1011111111111111b
  1578 0000AC2D 80CC40              <1> 	or	ah, 40h ; Set bit 14 to 1
  1579                              <1>         	;bis $40000,r1 / directory flag
  1580 0000AC30 E8AD0B0000          <1> 	call	maknod
  1581                              <1>         	;jsr r0,maknod / make the i-node for the directory
  1582 0000AC35 E9F9FAFFFF          <1> 	jmp	sysret
  1583                              <1>         	;br sysret2 /
  1584                              <1> dir_exists:
  1585                              <1> 	; 14/05/2015
  1586 0000AC3A C705[2DF20000]0E00- <1> 	mov	dword [u.error], ERR_DIR_EXISTS ; dir. already exists !
  1586 0000AC42 0000                <1>
  1587 0000AC44 E9CAFAFFFF          <1> 	jmp	error
  1588                              <1> dir_access_err:
  1589                              <1> 	; 14/05/2015
  1590 0000AC49 C705[2DF20000]0B00- <1> 	mov	dword [u.error], ERR_DIR_ACCESS ; permission denied !
  1590 0000AC51 0000                <1>
  1591 0000AC53 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 0000AC58 89D8                <1> 	mov 	eax, ebx
  1617 0000AC5A 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 0000AC5F 0F83CEFAFFFF        <1> 	jnc	sysret
  1624 0000AC65 C705[2DF20000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
  1624 0000AC6D 0000                <1>
  1625 0000AC6F 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 0000AC74 803D[24F20000]00    <1> 	cmp	byte [u.uid], 0 ; root ?
  1660                              <1> 	;ja	error
  1661 0000AC7B 0F873BFBFFFF        <1> 	ja	badsys ; 14/05/2015
  1662                              <1> 	;
  1663 0000AC81 FA                  <1> 	cli
  1664 0000AC82 881D[7EEA0000]      <1> 	mov	[multi_tasking], bl ; 0 to disable, >0 to enable
  1665 0000AC88 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 0000AC8D 80FF02              <1> 	cmp	bh, 2
  1746 0000AC90 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 0000AC92 774B                <1>         ja      short systimer_6 
  1750                              <1> 
  1751 0000AC94 20FF                <1> 	and	bh, bh
  1752 0000AC96 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 0000AC9C B00A                <1> 	mov	al, 10 ; (*)
  1757                              <1> 
  1758                              <1> systimer_0:
  1759 0000AC9E B710                <1> 	mov	bh, 16
  1760                              <1> 	;
  1761 0000ACA0 383D[7FEA0000]      <1> 	cmp	[timer_events], bh ; 16 ; 07/06/2016
  1762 0000ACA6 7319                <1> 	jnb 	short systimer_3  ; max. 16 timer events
  1763                              <1> 	;
  1764 0000ACA8 50                  <1> 	push	eax ; (*)
  1765                              <1> 
  1766 0000ACA9 BF[9CFE0000]        <1> 	mov	edi, timer_set  ; beginning address of timer events
  1767                              <1> 				; setting space
  1768 0000ACAE 30C0                <1> 	xor	al, al ; 0
  1769                              <1> systimer_1:
  1770 0000ACB0 FEC0                <1> 	inc	al
  1771 0000ACB2 803F00              <1> 	cmp	byte [edi], 0 	; is it free space ?
  1772 0000ACB5 7631                <1> 	jna	short systimer_7 ; yes
  1773 0000ACB7 FECF                <1> 	dec	bh
  1774 0000ACB9 7405                <1> 	jz	short systimer_2
  1775 0000ACBB 83C710              <1> 	add	edi, 16
  1776 0000ACBE EBF0                <1> 	jmp	short  systimer_1 ; next event space
  1777                              <1> 
  1778                              <1> systimer_2:
  1779 0000ACC0 58                  <1> 	pop	eax ; (*) discard
  1780                              <1> systimer_3:
  1781 0000ACC1 C605[D8F10000]00    <1> 	mov	byte [u.r0], 0
  1782                              <1> systimer_4:
  1783 0000ACC8 C705[2DF20000]1A00- <1>         mov     dword [u.error], ERR_MISC
  1783 0000ACD0 0000                <1>
  1784                              <1>                                 ; one of miscellaneous/other errors
  1785 0000ACD2 E93CFAFFFF          <1> 	jmp	error ; cf -> 1
  1786                              <1> 
  1787                              <1> systimer_5:
  1788 0000ACD7 883D[D8F10000]      <1> 	mov	[u.r0], bh ; Time count unit (=2 or >3)
  1789 0000ACDD EBE9                <1> 	jmp	short systimer_4 ; 07/06/2016
  1790                              <1> 
  1791                              <1> systimer_6:
  1792 0000ACDF 80FF03              <1> 	cmp	bh, 3
  1793 0000ACE2 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 0000ACE4 B0B6                <1> 	mov	al, 182 ; (*) ; 18.2 * 10
  1800 0000ACE6 EBB6                <1>         jmp     short systimer_0
  1801                              <1> 
  1802                              <1> systimer_7:
  1803 0000ACE8 A2[D8F10000]        <1> 	mov	[u.r0], al ; timer event number
  1804                              <1> 	;
  1805                              <1> 	; edi = address of empty timer event area
  1806 0000ACED A0[27F20000]        <1> 	mov	al, [u.uno]
  1807 0000ACF2 FA                  <1> 	cli 	; disable interrupts 
  1808 0000ACF3 AA                  <1> 	stosb	; process number
  1809 0000ACF4 D0E0                <1> 	shl	al, 1
  1810 0000ACF6 89C6                <1> 	mov	esi, eax
  1811 0000ACF8 28C0                <1> 	sub	al, al
  1812 0000ACFA AA                  <1> 	stosb 	; reserved (=0)
  1813 0000ACFB B001                <1> 	mov	al, 1 ; this is for real time clock interrupt
  1814 0000ACFD AA                  <1> 	stosb	; interrupt type
  1815 0000ACFE 88D8                <1> 	mov	al, bl ; Signal return (Response) value
  1816 0000AD00 AA                  <1> 	stosb  ; response byte
  1817 0000AD01 58                  <1> 	pop	eax ; (*) ; 10 or 182
  1818 0000AD02 89D3                <1> 	mov	ebx, edx ; virtual address for response/signal byte
  1819 0000AD04 F7E1                <1> 	mul	ecx
  1820                              <1> 	; (eax = 10 * count of 18.2 Hz timer ticks)
  1821                              <1> 	; (count down step = 10)
  1822 0000AD06 AB                  <1> 	stosd  ; count limit (reset value)
  1823 0000AD07 AB                  <1> 	stosd  ; current count value
  1824                              <1> 	; ebx = virtual address
  1825                              <1> 	; [u.pgdir] = page directory's physical address
  1826 0000AD08 E8AB91FFFF          <1> 	call	get_physical_addr
  1827 0000AD0D 720D                <1> 	jc	short systimer_8 ; 07/06/2016
  1828                              <1> 	; eax = physical address of the virtual address in user's space
  1829 0000AD0F AB                  <1> 	stosd	; response address (physical)
  1830 0000AD10 FE05[7FEA0000]      <1> 	inc	byte [timer_events] ; 07/06/201
  1831 0000AD16 FB                  <1> 	sti 	; enable interrupts
  1832 0000AD17 E917FAFFFF          <1> 	jmp	sysret
  1833                              <1> 
  1834                              <1> systimer_8:
  1835                              <1> 	; 10/06/2016
  1836                              <1> 	; 07/06/2016
  1837 0000AD1C 28C0                <1> 	sub	al, al ; 0
  1838 0000AD1E 8847F4              <1> 	mov	[edi-12], al ; clear process nummber (free timer event)
  1839                              <1> 	;mov	dword [edi], eax ; 0
  1840 0000AD21 FB                  <1> 	sti
  1841 0000AD22 A2[D8F10000]        <1> 	mov	[u.r0], al ; 0
  1842 0000AD27 E9E7F9FFFF          <1> 	jmp	error
  1843                              <1> 
  1844                              <1> systimer_9:
  1845                              <1> 	; 10/06/2016
  1846                              <1> 	; 07/06/2016
  1847 0000AD2C 28C0                <1> 	sub	al, al
  1848 0000AD2E A2[D8F10000]        <1> 	mov	byte [u.r0], al ; 0
  1849 0000AD33 3805[7FEA0000]      <1> 	cmp     byte [timer_events], al ;  0
  1850 0000AD39 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 0000AD3B BE[9CFE0000]        <1> 	mov	esi, timer_set  ; beginning address of timer events
  1856                              <1> 				; setting space	 
  1857 0000AD40 A0[27F20000]        <1> 	mov	al, [u.uno]
  1858                              <1> 	
  1859 0000AD45 B710                <1> 	mov	bh, 16
  1860                              <1> 
  1861 0000AD47 08DB                <1> 	or	bl, bl
  1862 0000AD49 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 0000AD4B FA                  <1> 	cli 	; disable interrupts
  1867                              <1> systimer_10:
  1868                              <1> 	; 10/06/2016
  1869                              <1> 	; 07/06/2016 	
  1870 0000AD4C 8A26                <1> 	mov	ah, [esi]
  1871 0000AD4E 08E4                <1> 	or	ah, ah ; 0 ?
  1872 0000AD50 7411                <1> 	jz	short systimer_11
  1873 0000AD52 38C4                <1> 	cmp	ah, al ; is the process ID (owner) same ?
  1874 0000AD54 750D                <1>         jne     short systimer_11 ; no
  1875                              <1> 
  1876                              <1> 	;mov	byte [esi], 0
  1877 0000AD56 66C7060000          <1> 	mov	word [esi], 0 ; clear
  1878                              <1> 	;mov	dword [esi+12], 0 ; clear
  1879                              <1> 
  1880 0000AD5B FE0D[7FEA0000]      <1> 	dec	byte [timer_events]
  1881 0000AD61 7409                <1> 	jz	short systimer_12
  1882                              <1> 
  1883                              <1> systimer_11:
  1884 0000AD63 FECF                <1> 	dec	bh
  1885 0000AD65 7405                <1> 	jz	short systimer_12
  1886 0000AD67 83C610              <1> 	add	esi, 16
  1887 0000AD6A EBE0                <1> 	jmp	short systimer_10
  1888                              <1> 
  1889                              <1> systimer_12:
  1890 0000AD6C 0FB635[27F20000]    <1> 	movzx	esi, byte [u.uno]
  1891 0000AD73 08DB                <1> 	or	bl, bl ; all timer events or one timer event ?
  1892 0000AD75 740C                <1> 	jz	short systimer_13
  1893 0000AD77 8A9E[99EF0000]      <1> 	mov	bl, [esi+p.timer-1]
  1894 0000AD7D 20DB                <1> 	and	bl, bl	; previous number of timer events for the process
  1895 0000AD7F 7408                <1> 	jz	short systimer_14
  1896 0000AD81 FECB                <1> 	dec	bl  ; previous number of timer events for the process - 1
  1897                              <1> systimer_13:
  1898 0000AD83 889E[99EF0000]      <1> 	mov	[esi+p.timer-1], bl ; 0 ; no timer events for process
  1899                              <1> systimer_14:
  1900 0000AD89 FB                  <1> 	sti	; enable interrupts
  1901 0000AD8A E9A4F9FFFF          <1> 	jmp	sysret
  1902                              <1> 
  1903                              <1> systimer_15:
  1904 0000AD8F 38FB                <1> 	cmp	bl, bh ; 16
  1905 0000AD91 0F8731FFFFFF        <1>         ja      systimer_4      ; max. 16 timer events !
  1906                              <1> 	;
  1907 0000AD97 88DA                <1> 	mov	dl, bl
  1908 0000AD99 FECA                <1> 	dec	dl  ; 16 -> 15 ... 1 -> 0 
  1909 0000AD9B C0E204              <1> 	shl	dl, 4 ; * 16
  1910 0000AD9E 0FB6FA              <1> 	movzx	edi, dl
  1911 0000ADA1 01F7                <1> 	add	edi, esi ; timer_set 
  1912                              <1> 	
  1913 0000ADA3 3A07                <1> 	cmp	al, [edi] ; process number
  1914 0000ADA5 0F851DFFFFFF        <1>         jne     systimer_4
  1915                              <1> 	
  1916                              <1> 	; same process ID
  1917 0000ADAB FA                  <1> 	cli	; disable interrupts
  1918                              <1>  	; 10/06/2016
  1919                              <1> 	;mov	byte [esi], 0 
  1920 0000ADAC 66C7060000          <1> 	mov	word [esi], 0 ; clear
  1921                              <1> 	;mov	dword [esi+12], 0 ; clear
  1922 0000ADB1 FE0D[7FEA0000]      <1> 	dec	byte [timer_events]
  1923 0000ADB7 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 0000ADB9 891D[F0F10000]      <1>         mov	[u.namep], ebx
  1954 0000ADBF E84B070000          <1> 	call	namei
  1955                              <1> 		; jsr r0,namei / get its i-number
  1956 0000ADC4 0F829EFDFFFF        <1>         jc	fnotfound ; file not found !
  1957                              <1> 	;jc	error       
  1958                              <1> 		; br error2 / no, such file
  1959 0000ADCA E84C160000          <1> 	call	iget
  1960                              <1> 		; jsr r0,iget / get i-node into core
  1961 0000ADCF A0[24F20000]        <1> 	mov	al, [u.uid]
  1962 0000ADD4 3A05[9DEE0000]      <1> 	cmp	al, [i.uid]
  1963                              <1>         	; cmpb u.uid,i.uid / is user same as owner
  1964 0000ADDA 7413                <1> 	je	short mdate_1
  1965                              <1>         	; beq 1f / yes
  1966 0000ADDC 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 0000ADDE 740F                <1> 	jz	short mdate_1
  1971 0000ADE0 C705[2DF20000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  1971 0000ADE8 0000                <1>
  1972 0000ADEA E924F9FFFF          <1> 	jmp	error
  1973                              <1> mdate_1: ;1:
  1974 0000ADEF E82E160000          <1> 	call	setimod
  1975                              <1>         	; jsr r0,setimod / fill in modification data,
  1976                              <1> 		               ; / time etc.
  1977 0000ADF4 BE[3CDD0000]        <1> 	mov	esi, p_time
  1978 0000ADF9 BF[B4EE0000]        <1> 	mov	edi, i.mtim
  1979 0000ADFE 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 0000ADFF 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 0000AE04 31C0                <1> 	xor	eax, eax
  2038 0000AE06 A3[D8F10000]        <1> 	mov	[u.r0], eax
  2039                              <1> 
  2040 0000AE0B 20FF                <1> 	and	bh, bh
  2041 0000AE0D 0F8520F9FFFF        <1> 	jnz	sysret
  2042                              <1> 	; Video mode 0, 80*25 text mode, CGA 16 colors  ; [CRT_MODE] = 3
  2043 0000AE13 88DF                <1> 	mov	bh, bl
  2044 0000AE15 C0EF02              <1> 	shr	bh, 2
  2045 0000AE18 20FF                <1> 	and	bh, bh
  2046 0000AE1A 0F8598000000        <1>         jnz     sysvideo_4
  2047 0000AE20 BF00800B00          <1> 	mov	edi, 0B8000h
  2048 0000AE25 20D2                <1> 	and	dl, dl
  2049 0000AE27 7413                <1> 	jz	short sysvideo_1
  2050 0000AE29 80FA07              <1> 	cmp	dl, 7
  2051 0000AE2C 0F8701F9FFFF        <1> 	ja	sysret
  2052                              <1> sysvideo_0:
  2053 0000AE32 81C7A00F0000        <1> 	add	edi, 80*25*2
  2054 0000AE38 FECA                <1> 	dec	dl
  2055 0000AE3A 75F6                <1> 	jnz	short sysvideo_0	
  2056                              <1> sysvideo_1:	
  2057 0000AE3C 80E303              <1> 	and	bl, 3
  2058 0000AE3F 7530                <1> 	jnz	short sysvideo_2
  2059 0000AE41 80F907              <1> 	cmp	cl, 7
  2060 0000AE44 0F87E9F8FFFF        <1> 	ja	sysret
  2061                              <1> 	; system to system video/display page transfer (mode 0)
  2062 0000AE4A BE00800B00          <1> 	mov	esi, 0B8000h
  2063 0000AE4F 0FB6C1              <1> 	movzx	eax, cl
  2064 0000AE52 BAA00F0000          <1> 	mov	edx, 80*25*2
  2065 0000AE57 F7E2                <1> 	mul	edx
  2066 0000AE59 01C6                <1> 	add	esi, eax
  2067 0000AE5B B9A00F0000          <1> 	mov	ecx, (80*25*2)
  2068 0000AE60 890D[D8F10000]      <1> 	mov	[u.r0], ecx
  2069 0000AE66 66C1E902            <1> 	shr	cx, 2 ; /4
  2070 0000AE6A F3A5                <1> 	rep	movsd
  2071 0000AE6C E9C2F8FFFF          <1> 	jmp	sysret	
  2072                              <1> sysvideo_2:  
  2073 0000AE71 80FB02              <1> 	cmp	bl, 2
  2074 0000AE74 0F87B9F8FFFF        <1>         ja      sysret
  2075 0000AE7A 721F                <1> 	jb	short sysvideo_3
  2076                              <1> 	; system to user video/display page transfer (mode 0)
  2077 0000AE7C 89FE                <1> 	mov	esi, edi
  2078 0000AE7E 89CF                <1> 	mov	edi, ecx ; user buffer
  2079 0000AE80 B9A00F0000          <1> 	mov	ecx, 80*25*2
  2080 0000AE85 E80B150000          <1> 	call	transfer_to_user_buffer ; fast transfer
  2081 0000AE8A 0F82A3F8FFFF        <1> 	jc	sysret
  2082 0000AE90 890D[D8F10000]      <1> 	mov	[u.r0], ecx
  2083 0000AE96 E998F8FFFF          <1> 	jmp	sysret 	
  2084                              <1> sysvideo_3: 
  2085                              <1> 	; user to system video/display page transfer (mode 0)	
  2086 0000AE9B 89CE                <1> 	mov	esi, ecx ; user buffer
  2087                              <1> 	; edi = video page address
  2088 0000AE9D B9A00F0000          <1> 	mov	ecx, 80*25*2
  2089 0000AEA2 E838150000          <1> 	call	transfer_from_user_buffer ; fast transfer
  2090 0000AEA7 0F8286F8FFFF        <1> 	jc	sysret
  2091 0000AEAD 890D[D8F10000]      <1> 	mov	[u.r0], ecx		
  2092 0000AEB3 E97BF8FFFF          <1> 	jmp	sysret
  2093                              <1> sysvideo_4:
  2094 0000AEB8 80E303              <1> 	and	bl, 3
  2095 0000AEBB 0F85F6000000        <1>         jnz     sysvideo_9
  2096 0000AEC1 80F907              <1> 	cmp	cl, 7
  2097 0000AEC4 0F8769F8FFFF        <1> 	ja	sysret
  2098                              <1> 	; system to system video/display page window transfer (mode 0)
  2099 0000AECA 81FE00800B00        <1> 	cmp	esi, 0B8000h
  2100 0000AED0 0F825DF8FFFF        <1> 	jb	sysret
  2101 0000AED6 81FE00FD0B00        <1> 	cmp	esi, 0B8000h+(80*25*2*8)
  2102 0000AEDC 0F8351F8FFFF        <1> 	jnb	sysret
  2103 0000AEE2 81FF00800B00        <1> 	cmp	edi, 0B8000h
  2104 0000AEE8 0F8245F8FFFF        <1> 	jb	sysret
  2105 0000AEEE 81FF00FD0B00        <1>         cmp     edi, 0B8000h+(80*25*2*8)
  2106 0000AEF4 0F8339F8FFFF        <1> 	jnb	sysret
  2107                              <1> 	;
  2108 0000AEFA 51                  <1> 	push	ecx
  2109 0000AEFB 52                  <1> 	push	edx
  2110 0000AEFC 0FB7C1              <1> 	movzx	eax, cx ; top left column
  2111 0000AEFF 50                  <1> 	push	eax
  2112 0000AF00 C1E910              <1> 	shr	ecx, 16 ; top row
  2113 0000AF03 66B8A000            <1> 	mov	ax, 80*2 ; 80 colums, 160 bytes per row
  2114 0000AF07 F7E1                <1> 	mul	ecx
  2115 0000AF09 01C6                <1> 	add	esi, eax
  2116 0000AF0B 01C7                <1> 	add	edi, eax
  2117 0000AF0D 58                  <1> 	pop	eax
  2118 0000AF0E 66D1E0              <1> 	shl	ax, 1 ; *2 	
  2119 0000AF11 01C6                <1> 	add	esi, eax
  2120 0000AF13 01C7                <1> 	add	edi, eax
  2121 0000AF15 5A                  <1> 	pop	edx
  2122 0000AF16 59                  <1> 	pop	ecx
  2123 0000AF17 B800FD0B00          <1> 	mov	eax, 0B8000h+(80*25*2*8)
  2124 0000AF1C 39C6                <1> 	cmp	esi, eax
  2125 0000AF1E 0F830FF8FFFF        <1> 	jnb	sysret
  2126 0000AF24 39C6                <1> 	cmp	esi, eax
  2127 0000AF26 0F8307F8FFFF        <1> 	jnb	sysret	
  2128                              <1> 
  2129 0000AF2C 56                  <1> 	push	esi ; ****
  2130 0000AF2D 57                  <1> 	push	edi ; ***
  2131 0000AF2E 52                  <1> 	push	edx ; **
  2132 0000AF2F 51                  <1> 	push	ecx ; *
  2133 0000AF30 C1E910              <1> 	shr	ecx, 16 ; top row
  2134 0000AF33 C1EA10              <1> 	shr	edx, 16 ; bottom row
  2135 0000AF36 83F918              <1> 	cmp	ecx, 24 ; max. 25 rows
  2136 0000AF39 7773                <1> 	ja	short sysvideo_6
  2137 0000AF3B 83FA18              <1> 	cmp	edx, 24 ; max. 25 rows
  2138 0000AF3E 776E                <1> 	ja	short sysvideo_6		
  2139 0000AF40 28CA                <1> 	sub	dl, cl
  2140 0000AF42 726A                <1> 	jc	short sysvideo_6
  2141 0000AF44 50                  <1> 	push	eax ; *****
  2142 0000AF45 89D3                <1> 	mov	ebx, edx ; row count - 1
  2143 0000AF47 B8A0000000          <1> 	mov	eax, 80*2
  2144 0000AF4C F7E0                <1> 	mul	eax
  2145 0000AF4E 01C6                <1> 	add	esi, eax
  2146 0000AF50 01C7                <1> 	add	edi, eax
  2147 0000AF52 58                  <1> 	pop	eax ; *****
  2148 0000AF53 39C6                <1> 	cmp	esi, eax
  2149 0000AF55 7757                <1> 	ja	short sysvideo_6
  2150 0000AF57 39C7                <1> 	cmp	edi, eax
  2151 0000AF59 7753                <1> 	ja	short sysvideo_6
  2152 0000AF5B 59                  <1> 	pop	ecx ; *
  2153 0000AF5C 5A                  <1> 	pop	edx ; **
  2154 0000AF5D 81E1FFFF0000        <1> 	and	ecx, 0FFFFh
  2155 0000AF63 81E2FFFF0000        <1> 	and	edx, 0FFFFh
  2156 0000AF69 83F94F              <1> 	cmp	ecx, 79 ; max. 80 columns
  2157 0000AF6C 7742                <1> 	ja	short sysvideo_7
  2158 0000AF6E 83FA4F              <1> 	cmp	edx, 79 ; max. 80 columns
  2159 0000AF71 773D                <1> 	ja	short sysvideo_7
  2160 0000AF73 28CA                <1> 	sub	dl, cl
  2161 0000AF75 7639                <1> 	jna	short sysvideo_7
  2162                              <1> 	; edx = column count (width) - 1
  2163 0000AF77 D0E2                <1> 	shl	dl, 1
  2164 0000AF79 01D6                <1> 	add	esi, edx
  2165 0000AF7B 01D7                <1> 	add	edi, edx
  2166 0000AF7D 39C6                <1> 	cmp	esi, eax
  2167 0000AF7F 772F                <1> 	ja	short sysvideo_7
  2168 0000AF81 39C7                <1> 	cmp	edi, eax
  2169 0000AF83 772B                <1> 	ja	short sysvideo_7
  2170 0000AF85 5F                  <1> 	pop	edi ; ***
  2171 0000AF86 5E                  <1> 	pop	esi ; ****
  2172 0000AF87 FEC3                <1> 	inc	bl
  2173 0000AF89 FEC2                <1> 	inc	dl ; column count
  2174 0000AF8B 88D7                <1> 	mov	bh, dl
  2175 0000AF8D D0E2                <1> 	shl	dl, 1
  2176 0000AF8F B8A0000000          <1> 	mov	eax, 80*2
  2177 0000AF94 28D0                <1> 	sub	al, dl ; (80 - columns) * 2
  2178                              <1> sysvideo_5:	
  2179 0000AF96 88F9                <1> 	mov	cl, bh
  2180 0000AF98 0115[D8F10000]      <1> 	add	[u.r0], edx
  2181 0000AF9E F366A5              <1> 	rep	movsw
  2182 0000AFA1 01C6                <1> 	add	esi, eax ; next row
  2183 0000AFA3 01C7                <1> 	add	edi, eax ; next row
  2184 0000AFA5 FECB                <1> 	dec	bl
  2185 0000AFA7 75ED                <1> 	jnz	short sysvideo_5
  2186 0000AFA9 E985F7FFFF          <1> 	jmp	sysret
  2187                              <1> 
  2188                              <1> sysvideo_6:
  2189 0000AFAE 59                  <1> 	pop	ecx ; *
  2190 0000AFAF 5A                  <1> 	pop	edx ; **
  2191                              <1> sysvideo_7:	
  2192 0000AFB0 5F                  <1> 	pop	edi ; ***
  2193 0000AFB1 5E                  <1> 	pop	esi ; ****
  2194 0000AFB2 E97CF7FFFF          <1> 	jmp	sysret
  2195                              <1> 
  2196                              <1> sysvideo_9:  
  2197 0000AFB7 80FB02              <1> 	cmp	bl, 2
  2198 0000AFBA 0F8773F7FFFF        <1>         ja      sysret
  2199                              <1> 
  2200 0000AFC0 56                  <1> 	push	esi ; ****
  2201 0000AFC1 57                  <1> 	push	edi ; ***
  2202 0000AFC2 52                  <1> 	push	edx ; **
  2203 0000AFC3 51                  <1> 	push	ecx ; *
  2204                              <1> 
  2205 0000AFC4 C1E910              <1> 	shr	ecx, 16 ; top row
  2206 0000AFC7 C1EA10              <1> 	shr	edx, 16 ; bottom row
  2207 0000AFCA 83F918              <1> 	cmp	ecx, 24 ; max. 25 rows
  2208 0000AFCD 77DF                <1> 	ja	short sysvideo_6
  2209 0000AFCF 83FA18              <1> 	cmp	edx, 24 ; max. 25 rows
  2210 0000AFD2 77DA                <1> 	ja	short sysvideo_6		
  2211 0000AFD4 28CA                <1> 	sub	dl, cl
  2212 0000AFD6 72D6                <1> 	jc	short sysvideo_6
  2213                              <1> 
  2214 0000AFD8 88CD                <1> 	mov	ch, cl ; top row
  2215 0000AFDA 8A0D[26DD0000]      <1> 	mov	cl, [ACTIVE_PAGE]
  2216 0000AFE0 BFA00F0000          <1> 	mov	edi, 80*25*2
  2217 0000AFE5 D3E7                <1> 	shl	edi, cl 
  2218 0000AFE7 81C760700B00        <1> 	add	edi, 0B8000h - 80*25*2
  2219                              <1> 
  2220 0000AFED 88D7                <1> 	mov	bh, dl ; row count - 1
  2221 0000AFEF 88EA                <1> 	mov	dl, ch ; top row
  2222 0000AFF1 B8A0000000          <1> 	mov	eax, 80*2
  2223 0000AFF6 F7E2                <1> 	mul	edx
  2224 0000AFF8 01C7                <1> 	add	edi, eax
  2225                              <1> 
  2226 0000AFFA 59                  <1> 	pop	ecx ; *
  2227 0000AFFB 5A                  <1> 	pop	edx ; **
  2228 0000AFFC 81E1FFFF0000        <1> 	and	ecx, 0FFFFh
  2229 0000B002 81E2FFFF0000        <1> 	and	edx, 0FFFFh
  2230 0000B008 83F94F              <1> 	cmp	ecx, 79 ; max. 80 columns
  2231 0000B00B 77A3                <1> 	ja	short sysvideo_7
  2232 0000B00D 83FA4F              <1> 	cmp	edx, 79 ; max. 80 columns
  2233 0000B010 779E                <1> 	ja	short sysvideo_7
  2234                              <1> 	
  2235 0000B012 28CA                <1> 	sub	dl, cl
  2236 0000B014 769A                <1> 	jna	short sysvideo_7
  2237                              <1> 	
  2238 0000B016 0FB6C1              <1> 	movzx	eax, cl ; left column
  2239 0000B019 D0E0                <1> 	shl	al, 1  ; column * 2
  2240 0000B01B 01C7                <1> 	add	edi, eax
  2241                              <1> 
  2242 0000B01D FEC2                <1> 	inc	dl ; column count
  2243 0000B01F D0E2                <1> 	shl	dl, 1
  2244 0000B021 88D1                <1> 	mov	cl, dl ; column count * 2
  2245 0000B023 B2A0                <1> 	mov	dl, 80*2
  2246 0000B025 58                  <1> 	pop	eax ; *** (swap address)
  2247 0000B026 5E                  <1> 	pop	esi ; ****
  2248 0000B027 FEC7                <1> 	inc	bh
  2249                              <1> 	
  2250                              <1> 	;mov	edx, 80*2
  2251 0000B029 B2A0                <1> 	mov	dl, 80*2
  2252                              <1> 	;
  2253 0000B02B 80FB01              <1> 	cmp	bl, 1
  2254 0000B02E 7735                <1> 	ja	short sysvideo_11
  2255                              <1> 
  2256                              <1> 	; user to system video/display page window transfer (mode 0)	
  2257 0000B030 21C0                <1> 	and	eax, eax ; swap address
  2258 0000B032 7413                <1> 	jz	short sysvideo_10 ; no window swap
  2259                              <1> 	; save previous window content in user's buffer (swap address)
  2260 0000B034 56                  <1> 	push	esi ; user buffer
  2261 0000B035 57                  <1> 	push	edi ; beginning address of the window
  2262 0000B036 89FE                <1> 	mov	esi, edi
  2263 0000B038 89C7                <1> 	mov	edi, eax
  2264 0000B03A E856130000          <1> 	call	transfer_to_user_buffer ; fast transfer
  2265 0000B03F 5F                  <1> 	pop	edi
  2266 0000B040 5E                  <1> 	pop	esi
  2267 0000B041 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 0000B047 E893130000          <1> 	call	transfer_from_user_buffer ; fast transfer
  2272 0000B04C 0F82E1F6FFFF        <1> 	jc	sysret
  2273 0000B052 010D[D8F10000]      <1> 	add	[u.r0], ecx
  2274 0000B058 01D7                <1> 	add	edi, edx ; next row
  2275 0000B05A 01CE                <1> 	add	esi, ecx
  2276 0000B05C FECF                <1> 	dec	bh
  2277 0000B05E 75E7                <1> 	jnz	short sysvideo_10
  2278 0000B060 E9CEF6FFFF          <1> 	jmp	sysret
  2279                              <1> 	
  2280                              <1> sysvideo_11:
  2281                              <1> 	; system to user video/display page window transfer (mode 0)
  2282 0000B065 87FE                <1> 	xchg	edi, esi
  2283                              <1> sysvideo_12:
  2284                              <1> 	; esi = beginning address of the window
  2285                              <1> 	; edi =	user buffer	
  2286 0000B067 E829130000          <1> 	call	transfer_to_user_buffer ; fast transfer
  2287 0000B06C 0F82C1F6FFFF        <1> 	jc	sysret
  2288 0000B072 010D[D8F10000]      <1> 	add	[u.r0], ecx
  2289 0000B078 01D6                <1> 	add	esi, edx ; next row
  2290 0000B07A 01CF                <1> 	add	edi, ecx
  2291 0000B07C FECF                <1> 	dec	bh
  2292 0000B07E 75E7                <1> 	jnz	short sysvideo_12
  2293 0000B080 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 0000B085 20FF                <1> 	and	bh, bh
  2309 0000B087 0F85A6F6FFFF        <1> 	jnz	sysret
  2310 0000B08D E84C69FFFF          <1> 	call	beep
  2311 0000B092 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 0000B097 891D[F0F10000]      <1> 	mov	[u.namep], ebx
  2342 0000B09D 51                  <1> 	push	ecx
  2343 0000B09E 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 0000B0A3 730F                <1> 	jnc	short syslink0
  2351                              <1> 	;pop 	ecx
  2352                              <1> 	; 'file not found !' error
  2353 0000B0A5 C705[2DF20000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  2353 0000B0AD 0000                <1>
  2354 0000B0AF E95FF6FFFF          <1> 	jmp	error
  2355                              <1> syslink0:
  2356 0000B0B4 E862130000          <1> 	call	iget
  2357                              <1> 		; jsr r0,iget / get the i-node into core
  2358 0000B0B9 8F05[F0F10000]      <1> 	pop	dword [u.namep] ; ecx
  2359                              <1> 		; mov (sp)+,u.namep / u.namep points to 2nd name
  2360 0000B0BF 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 0000B0C1 66FF35[B8F10000]    <1> 	push	word [cdev]
  2364                              <1> 		; mov cdev,-(sp) / put i-nodes device on the stack
  2365 0000B0C8 E855000000          <1> 	call	isdir
  2366                              <1> 		; jsr r0,isdir / is it a directory
  2367 0000B0CD 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 0000B0D2 720F                <1> 	jc	short syslink1
  2375                              <1> 	; pop ax
  2376                              <1> 	; pop ax
  2377                              <1> 	; 'file exists !' error
  2378 0000B0D4 C705[2DF20000]0E00- <1> 	mov	dword [u.error], ERR_FILE_EXISTS ; 14
  2378 0000B0DC 0000                <1>
  2379 0000B0DE E930F6FFFF          <1> 	jmp	error
  2380                              <1> syslink1:
  2381 0000B0E3 6659                <1> 	pop	cx
  2382                              <1> 	;cmp	cx, [cdev]
  2383 0000B0E5 3A0D[B8F10000]      <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 0000B0EB 740F                <1> 	je	short syslink2
  2389                              <1> 	; 'not same drive !' error
  2390 0000B0ED C705[2DF20000]1500- <1> 	mov	dword [u.error],  ERR_DRV_NOT_SAME ; 21
  2390 0000B0F5 0000                <1>
  2391 0000B0F7 E917F6FFFF          <1> 	jmp	error
  2392                              <1> syslink2:
  2393 0000B0FC 6658                <1> 	pop	ax
  2394 0000B0FE 6650                <1> 	push	ax
  2395 0000B100 66A3[0AF20000]      <1> 	mov	[u.dirbuf], ax
  2396                              <1> 		; mov (sp),u.dirbuf / i-number of name1 into u.dirbuf
  2397 0000B106 E8A8000000          <1> 	call	mkdir
  2398                              <1> 		; jsr r0,mkdir / make directory entry for name2 
  2399                              <1> 		 	     ; / in current directory
  2400 0000B10B 6658                <1> 	pop	ax
  2401                              <1> 		; mov (sp)+,r1 / r1 has i-number of name1
  2402 0000B10D E809130000          <1> 	call	iget
  2403                              <1> 		; jsr r0,iget / get i-node into core
  2404 0000B112 FE05[9CEE0000]      <1> 	inc	byte [i.nlks]
  2405                              <1> 		; incb i.nlks / add 1 to its number of links
  2406 0000B118 E805130000          <1> 	call	setimod
  2407                              <1> 		; jsr r0,setimod / set the i-node modified flag
  2408 0000B11D 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 0000B122 803D[24F20000]00    <1> 	cmp	byte [u.uid], 0 
  2437                              <1> 		; tstb u.uid / super user
  2438 0000B129 762D                <1> 	jna	short isdir1
  2439                              <1> 		; beq 1f / yes, don't care
  2440 0000B12B 66FF35[5DF20000]    <1> 	push	word [ii]
  2441                              <1> 		; mov ii,-(sp) / put current i-number on stack
  2442 0000B132 E8E4120000          <1> 	call	iget
  2443                              <1> 		; jsr r0,iget / get i-node into core (i-number in r1)
  2444 0000B137 66F705[9AEE0000]00- <1> 	test 	word [i.flgs], 4000h ; Bit 14 : Directory flag
  2444 0000B13F 40                  <1>
  2445                              <1> 		; bit $40000,i.flgs / is it a directory
  2446                              <1> 	;jnz	error
  2447                              <1> 		; bne error9 / yes, error
  2448 0000B140 740F                <1> 	jz	short isdir0
  2449 0000B142 C705[2DF20000]0B00- <1> 	mov 	dword [u.error], ERR_NOT_FILE  ; 11 ; ERR_DIR_ACCESS 
  2449 0000B14A 0000                <1>
  2450                              <1> 				; 'permission denied !' error
  2451                              <1> 	; pop	ax
  2452 0000B14C E9C2F5FFFF          <1> 	jmp	error	
  2453                              <1> isdir0:	
  2454 0000B151 6658                <1> 	pop	ax
  2455                              <1> 		; mov (sp)+,r1 / no, put current i-number in r1 (ii)
  2456 0000B153 E8C3120000          <1> 	call	iget
  2457                              <1> 		; jsr r0,iget / get it back in
  2458                              <1> isdir1: ; 1:
  2459 0000B158 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 0000B159 891D[F0F10000]      <1> 	mov	[u.namep], ebx
  2494                              <1> 		;jsr r0,arg; u.namep / u.namep points to name
  2495 0000B15F 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 0000B164 730F                <1> 	jnc	short sysunlink1
  2501                              <1> 	; 'file not found !' error
  2502 0000B166 C705[2DF20000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  2502 0000B16E 0000                <1>
  2503 0000B170 E99EF5FFFF          <1> 	jmp	error
  2504                              <1> sysunlink1:
  2505 0000B175 6650                <1> 	push	ax
  2506                              <1> 		; mov r1,-(sp) / put its i-number on the stack
  2507 0000B177 E8A6FFFFFF          <1> 	call	isdir
  2508                              <1> 		; jsr r0,isdir / is it a directory
  2509 0000B17C 6631C0              <1> 	xor 	ax, ax
  2510 0000B17F 66A3[0AF20000]      <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 0000B185 832D[F4F10000]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 0000B18C E86E000000          <1> 	call	wdir
  2517                              <1> 		; jsr r0,wdir / free the directory entry
  2518 0000B191 6658                <1> 	pop	ax
  2519                              <1> 		; mov (sp)+,r1 / get i-number back
  2520 0000B193 E883120000          <1> 	call	iget
  2521                              <1> 		; jsr r0,iget / get i-node
  2522 0000B198 E885120000          <1> 	call	setimod
  2523                              <1> 		; jsr r0,setimod / set modified flag
  2524 0000B19D FE0D[9CEE0000]      <1> 	dec	byte [i.nlks]
  2525                              <1> 		; decb i.nlks / decrement the number of links
  2526 0000B1A3 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 0000B1A9 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 0000B1AE 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 0000B1B3 31C0                <1> 	xor 	eax, eax
  2564 0000B1B5 BF[0CF20000]        <1> 	mov     edi, u.dirbuf+2
  2565 0000B1BA 89FE                <1> 	mov	esi, edi
  2566 0000B1BC AB                  <1> 	stosd
  2567 0000B1BD AB                  <1> 	stosd
  2568                              <1> 	; 04/12/2015 (14 byte directory names)
  2569 0000B1BE AB                  <1> 	stosd
  2570 0000B1BF 66AB                <1> 	stosw
  2571                              <1> 		; jsr r0,copyz; u.dirbuf+2; u.dirbuf+10. / clear this
  2572 0000B1C1 89F7                <1> 	mov	edi, esi ; offset to u.dirbuf
  2573                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
  2574                              <1> 	;mov 	ebp, [u.namep]
  2575 0000B1C3 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 0000B1C8 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 0000B1C9 AC                  <1> 	lodsb
  2587                              <1> 		; movb (r2)+,r1 / move character in name to r1
  2588 0000B1CA 20C0                <1> 	and 	al, al
  2589 0000B1CC 7427                <1> 	jz 	short mkdir_3 	  
  2590                              <1> 		; beq 1f / if null, done
  2591 0000B1CE 3C2F                <1> 	cmp	al, '/'
  2592                              <1> 		; cmp r1,$'/ / is it a "/"?
  2593 0000B1D0 7414                <1> 	je	short mkdir_err
  2594                              <1> 	;je	error
  2595                              <1> 		; beq error9 / yes, error
  2596                              <1> 	; 12/10/2015
  2597 0000B1D2 6649                <1> 	dec	cx
  2598 0000B1D4 7505                <1> 	jnz	short mkdir_2
  2599                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
  2600 0000B1D6 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 0000B1DB 81FF[1AF20000]      <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 0000B1E1 74E5                <1> 	je	short mkdir_1
  2609                              <1> 		; beq 1b / yes, go back
  2610 0000B1E3 AA                  <1> 	stosb
  2611                              <1> 		; movb r1,(r3)+ / no, put the char in the u.dirbuf
  2612 0000B1E4 EBE2                <1> 	jmp 	short mkdir_1
  2613                              <1> 		; br 1b / get next char
  2614                              <1> mkdir_err:
  2615                              <1> 	; 17/06/2015
  2616 0000B1E6 C705[2DF20000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
  2616 0000B1EE 0000                <1>
  2617 0000B1F0 E91EF5FFFF          <1> 	jmp	error
  2618                              <1> 
  2619                              <1> mkdir_3: ; 1:
  2620 0000B1F5 A1[ECF10000]        <1> 	mov	eax, [u.dirp]
  2621 0000B1FA A3[F4F10000]        <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 0000B1FF C705[F8F10000]-     <1>         mov     dword [u.base], u.dirbuf
  2625 0000B205 [0AF20000]          <1>
  2626                              <1> 		; mov $u.dirbuf,u.base / u.base points to created file name
  2627 0000B209 C705[FCF10000]1000- <1>         mov     dword [u.count], 16 ; 04/12/2015 (10 -> 16) 
  2627 0000B211 0000                <1>
  2628                              <1> 		; mov $10.,u.count / u.count = 10
  2629 0000B213 66A1[5DF20000]      <1> 	mov	ax, [ii] 
  2630                              <1> 		; mov ii,r1 / r1 has i-number of current directory
  2631 0000B219 B201                <1> 	mov	dl, 1 ; owner flag mask ; RETRO UNIX 8086 v1 modification !
  2632 0000B21B 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 0000B220 FE05[3FF20000]      <1> 	inc     byte [u.kcall] ; the caller is 'mkdir' sign	
  2638 0000B226 E8F3110000          <1> 	call	writei
  2639                              <1> 		; jsr r0,writei / write into directory
  2640 0000B22B 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 0000B22C 891D[F0F10000]      <1> 	mov	[u.namep], ebx ; argument 1
  2716                              <1>         ; 18/10/2015
  2717 0000B232 890D[58F20000]      <1> 	mov     [argv], ecx  ; * ; argument 2
  2718 0000B238 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 0000B23D 731E                <1> 	jnc	short sysexec_0
  2724                              <1> 	;
  2725                              <1> 	; 'file not found !' error
  2726 0000B23F C705[2DF20000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND
  2726 0000B247 0000                <1>
  2727 0000B249 E9C5F4FFFF          <1> 	jmp	error 
  2728                              <1> sysexec_not_exf:
  2729                              <1> 	; 'not executable file !' error
  2730 0000B24E C705[2DF20000]1600- <1> 	mov	dword [u.error], ERR_NOT_EXECUTABLE
  2730 0000B256 0000                <1>
  2731 0000B258 E9B6F4FFFF          <1> 	jmp	error 
  2732                              <1> sysexec_0:
  2733 0000B25D E8B9110000          <1> 	call	iget
  2734                              <1> 		; jsr r0,iget / get i-node for file to be executed
  2735 0000B262 66F705[9AEE0000]10- <1>         test    word [i.flgs], 10h
  2735 0000B26A 00                  <1>
  2736                              <1> 		; bit $20,i.flgs / is file executable
  2737 0000B26B 74E1                <1> 	jz	short sysexec_not_exf
  2738                              <1> 	;jz	error
  2739                              <1> 		; beq error9
  2740                              <1> 	;;
  2741 0000B26D 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 0000B272 66F705[9AEE0000]20- <1> 	test	word [i.flgs], 20h
  2745 0000B27A 00                  <1>
  2746                              <1> 		; bit $40,i.flgs / test user id on execution bit
  2747 0000B27B 7415                <1> 	jz	short sysexec_1
  2748                              <1> 		; beq 1f
  2749 0000B27D 803D[24F20000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013
  2750                              <1> 		; tstb u.uid / test user id
  2751 0000B284 760C                <1> 	jna	short sysexec_1
  2752                              <1> 		; beq 1f / super user
  2753 0000B286 8A0D[9DEE0000]      <1> 	mov	cl, [i.uid]
  2754 0000B28C 880D[24F20000]      <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 0000B292 89E5                <1> 	mov	ebp, esp ; (**)
  2770                              <1> 	; 18/10/2015
  2771 0000B294 89EF                <1> 	mov 	edi, ebp
  2772 0000B296 B900010000          <1> 	mov 	ecx, MAX_ARG_LEN ; 256
  2773                              <1> 	;sub	edi, MAX_ARG_LEN ; 256
  2774 0000B29B 29CF                <1> 	sub	edi, ecx
  2775 0000B29D 89FC                <1> 	mov	esp, edi
  2776 0000B29F 31C0                <1> 	xor	eax, eax
  2777 0000B2A1 A3[00F20000]        <1> 	mov 	[u.nread], eax ; 0
  2778 0000B2A6 49                  <1> 	dec	ecx ; 256 - 1
  2779 0000B2A7 890D[FCF10000]      <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 0000B2AD 8B35[58F20000]      <1> 	mov	esi, [argv] ; 18/10/2015 
  2783 0000B2B3 E866000000          <1> 	call	get_argp
  2784 0000B2B8 B904000000          <1> 	mov	ecx, 4 ; mov ecx, 4
  2785                              <1> sysexec_3:
  2786 0000B2BD 21C0                <1> 	and	eax, eax
  2787 0000B2BF 0F84C4090000        <1>         jz      sysexec_6
  2788                              <1> 	; 18/10/2015
  2789 0000B2C5 010D[58F20000]      <1> 	add	[argv], ecx ; 4
  2790 0000B2CB 66FF05[56F20000]    <1> 	inc	word [argc]
  2791                              <1> 	;
  2792 0000B2D2 A3[F8F10000]        <1> 	mov	[u.base], eax
  2793                              <1>  	; 23/10/2015
  2794 0000B2D7 66C705[3DF20000]00- <1> 	mov	word [u.pcount], 0
  2794 0000B2DF 00                  <1>
  2795                              <1> sysexec_4:
  2796 0000B2E0 E850100000          <1> 	call	cpass ; get a character from user's core memory
  2797 0000B2E5 750E                <1>         jnz      short sysexec_5
  2798                              <1> 		; (max. 255 chars + null)
  2799                              <1> 	; 18/10/2015
  2800 0000B2E7 28C0                <1> 	sub 	al, al
  2801 0000B2E9 AA                  <1> 	stosb
  2802 0000B2EA FF05[00F20000]      <1> 	inc	dword [u.nread]
  2803 0000B2F0 E994090000          <1> 	jmp	sysexec_6 ; 24/04/2016
  2804                              <1> sysexec_5:
  2805 0000B2F5 AA                  <1> 	stosb
  2806 0000B2F6 20C0                <1> 	and 	al, al
  2807 0000B2F8 75E6                <1> 	jnz	short sysexec_4
  2808 0000B2FA B904000000          <1> 	mov	ecx, 4
  2809 0000B2FF 390D[54F20000]      <1> 	cmp	[ncount], ecx ; 4
  2810 0000B305 72A6                <1> 	jb	short sysexec_2
  2811 0000B307 8B35[50F20000]      <1> 	mov	esi, [nbase]
  2812 0000B30D 010D[50F20000]      <1> 	add	[nbase], ecx ; 4	
  2813 0000B313 66290D[54F20000]    <1> 	sub	[ncount], cx 
  2814 0000B31A 8B06                <1> 	mov	eax, [esi]
  2815 0000B31C 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 0000B31E 833D[35F20000]00    <1>  	cmp     dword [u.ppgdir], 0 ; /etc/init ?
  2831                              <1> 				    ; (the caller is kernel)
  2832 0000B325 7667                <1>         jna     short get_argpk 
  2833                              <1> 	;
  2834 0000B327 89F3                <1>      	mov	ebx, esi
  2835 0000B329 E88A8BFFFF          <1> 	call	get_physical_addr ; get physical address
  2836 0000B32E 0F8289000000        <1>         jc      get_argp_err
  2837 0000B334 A3[50F20000]        <1> 	mov 	[nbase], eax ; physical address	
  2838 0000B339 66890D[54F20000]    <1> 	mov	[ncount], cx ; remain byte count in page (1-4096)
  2839 0000B340 B804000000          <1> 	mov	eax, 4 ; 21/07/2015
  2840 0000B345 6639C1              <1> 	cmp	cx, ax ; 4
  2841 0000B348 735D                <1> 	jnb	short get_argp2
  2842 0000B34A 89F3                <1> 	mov	ebx, esi
  2843 0000B34C 01CB                <1> 	add	ebx, ecx
  2844 0000B34E E8658BFFFF          <1> 	call	get_physical_addr ; get physical address
  2845 0000B353 7268                <1> 	jc	short get_argp_err
  2846                              <1> 	;push	esi
  2847 0000B355 89C6                <1> 	mov	esi, eax
  2848 0000B357 66870D[54F20000]    <1> 	xchg	cx, [ncount]
  2849 0000B35E 8735[50F20000]      <1> 	xchg	esi, [nbase]
  2850 0000B364 B504                <1> 	mov	ch, 4
  2851 0000B366 28CD                <1> 	sub	ch, cl
  2852                              <1> get_argp0:
  2853 0000B368 AC                  <1> 	lodsb
  2854 0000B369 6650                <1> 	push	ax
  2855 0000B36B FEC9                <1> 	dec	cl
  2856 0000B36D 75F9                <1>         jnz     short get_argp0
  2857 0000B36F 8B35[50F20000]      <1> 	mov	esi, [nbase]
  2858                              <1> 	; 21/07/2015
  2859 0000B375 0FB6C5              <1> 	movzx	eax, ch
  2860 0000B378 0105[50F20000]      <1> 	add	[nbase], eax
  2861 0000B37E 662905[54F20000]    <1> 	sub	[ncount], ax
  2862                              <1> get_argp1:
  2863 0000B385 AC                  <1> 	lodsb
  2864 0000B386 FECD                <1> 	dec	ch
  2865 0000B388 743D                <1>         jz      short get_argp3
  2866 0000B38A 6650                <1>         push	ax
  2867 0000B38C EBF7                <1> 	jmp     short get_argp1
  2868                              <1> get_argpk:
  2869                              <1> 	; Argument is in kernel's memory space
  2870 0000B38E 66C705[54F20000]00- <1> 	mov	word [ncount], PAGE_SIZE ; 4096
  2870 0000B396 10                  <1>
  2871 0000B397 8935[50F20000]      <1> 	mov	[nbase], esi
  2872 0000B39D 8305[50F20000]04    <1> 	add	dword [nbase], 4
  2873 0000B3A4 8B06                <1> 	mov	eax, [esi] ; virtual addr. = physcal addr.
  2874 0000B3A6 C3                  <1> 	retn
  2875                              <1> get_argp2:
  2876                              <1> 	; 21/07/2015
  2877                              <1> 	;mov	eax, 4
  2878 0000B3A7 8B15[50F20000]      <1> 	mov 	edx, [nbase] ; 18/10/2015
  2879 0000B3AD 0105[50F20000]      <1> 	add	[nbase], eax
  2880 0000B3B3 662905[54F20000]    <1> 	sub	[ncount], ax
  2881                              <1> 	;
  2882 0000B3BA 8B02                <1> 	mov	eax, [edx]
  2883 0000B3BC C3                  <1> 	retn
  2884                              <1> get_argp_err:
  2885 0000B3BD A3[2DF20000]        <1> 	mov	[u.error], eax
  2886 0000B3C2 E94CF3FFFF          <1> 	jmp	error
  2887                              <1> get_argp3:
  2888 0000B3C7 B103                <1> 	mov	cl, 3
  2889                              <1> get_argp4:
  2890 0000B3C9 C1E008              <1> 	shl	eax, 8
  2891 0000B3CC 665A                <1> 	pop	dx
  2892 0000B3CE 88D0                <1> 	mov 	al, dl
  2893 0000B3D0 E2F7                <1>         loop    get_argp4
  2894                              <1> 	;pop	esi
  2895 0000B3D2 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 0000B3D3 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 0000B3D4 E8FF000000          <1> 	call	getf1
  2931 0000B3D9 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 0000B3DC 750F                <1> 	jnz	short sysfstat1
  2936 0000B3DE C705[2DF20000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
  2936 0000B3E6 0000                <1>
  2937 0000B3E8 E926F3FFFF          <1> 	jmp	error
  2938                              <1> sysfstat1:
  2939 0000B3ED 80FC80              <1> 	cmp	ah, 80h
  2940 0000B3F0 7223                <1>         jb      short sysstat1
  2941                              <1> 		; bgt 1f / if i-number is negative (open for writing)
  2942 0000B3F2 66F7D8              <1> 	neg	ax
  2943                              <1> 		; neg r1 / make it positive, then branch
  2944 0000B3F5 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 0000B3F7 891D[F0F10000]      <1> 	mov	[u.namep], ebx
  2987 0000B3FD 51                  <1> 	push	ecx
  2988 0000B3FE 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 0000B403 7310                <1> 	jnc	short sysstat1
  2993                              <1> 	; pop 	ecx
  2994                              <1> sysstat_err0:
  2995                              <1> 	; 'file not found !' error
  2996 0000B405 C705[2DF20000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  2996 0000B40D 0000                <1>
  2997 0000B40F E9FFF2FFFF          <1> 	jmp	error
  2998                              <1> 
  2999 0000B414 00                  <1> statx: db 0
  3000                              <1> 
  3001                              <1> sysstat1: ; 1:
  3002 0000B415 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 0000B41A 8F05[F8F10000]      <1> 	pop	dword [u.base]
  3007                              <1> 		; mov (sp)+,r3 / move u.off to r3 (points to buffer)
  3008 0000B420 E858000000          <1> 	call	sysstat_gpa ; get physical address
  3009 0000B425 730A                <1> 	jnc 	short sysstat2
  3010                              <1> sysstat_err1:
  3011 0000B427 A3[2DF20000]        <1> 	mov	dword [u.error], eax ; error code
  3012 0000B42C E9E2F2FFFF          <1> 	jmp	error
  3013                              <1> sysstat2:
  3014 0000B431 A0[5DF20000]        <1> 	mov 	al, [ii] ; 07/10/2015 (result of 'iget' call, above)
  3015 0000B436 AA                  <1> 	stosb
  3016 0000B437 FF05[F8F10000]      <1> 	inc 	dword [u.base]
  3017 0000B43D 6649                <1> 	dec 	cx
  3018 0000B43F 7505                <1> 	jnz	short sysstat3
  3019 0000B441 E837000000          <1> 	call	sysstat_gpa
  3020                              <1> 	;jc	short sysstat_err1
  3021                              <1> sysstat3:
  3022 0000B446 A0[5EF20000]        <1> 	mov 	al, [ii+1] ; 07/10/2015 (result of 'iget' call, above)
  3023 0000B44B AA                  <1> 	stosb
  3024                              <1> 		; mov r1,(r3)+ / put i-number in 1st word of buffer
  3025 0000B44C FF05[F8F10000]      <1> 	inc 	dword [u.base]
  3026                              <1> 	;dec 	word [u.pcount]
  3027 0000B452 6649                <1> 	dec	cx
  3028 0000B454 7505                <1> 	jnz	short sysstat4
  3029 0000B456 E822000000          <1> 	call	sysstat_gpa
  3030                              <1> 	;jc	short sysstat_err1	
  3031                              <1> sysstat4:
  3032 0000B45B BE[9AEE0000]        <1> 	mov	esi, inode
  3033                              <1> 		; mov $inode,r2 / r2 points to i-node
  3034                              <1> sysstat5: ; 1:
  3035 0000B460 A4                  <1> 	movsb
  3036                              <1> 		; mov (r2)+,(r3)+ / move rest of i-node to buffer
  3037 0000B461 FF05[F8F10000]      <1> 	inc 	dword [u.base]
  3038                              <1> 	;dec 	word [u.pcount]
  3039 0000B467 6649                <1> 	dec	cx
  3040 0000B469 7505                <1> 	jnz	short sysstat6
  3041 0000B46B E80D000000          <1> 	call	sysstat_gpa
  3042                              <1> 	;jc	short sysstat_err1
  3043                              <1> sysstat6:		
  3044 0000B470 81FE[BAEE0000]      <1> 	cmp	esi, inode + 32
  3045                              <1> 		; cmp r2,$inode+32 / done?
  3046 0000B476 75E8                <1> 	jne	short sysstat5
  3047                              <1> 		; bne 1b / no, go back
  3048 0000B478 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 0000B47D 8B1D[F8F10000]      <1> 	mov 	ebx, [u.base]
  3054                              <1> 	; 07/10/2015
  3055 0000B483 E8308AFFFF          <1> 	call	get_physical_addr ; get physical address
  3056                              <1> 	;jc	short sysstat_gpa1
  3057 0000B488 729D                <1> 	jc	short sysstat_err1
  3058                              <1> 	; 18/10/2015
  3059 0000B48A 89C7                <1> 	mov	edi, eax ; physical address
  3060                              <1> 	;mov	[u.pcount], cx ; remain bytes in page
  3061                              <1> ;sysstat_gpa1:
  3062 0000B48C 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 0000B48D 0FB7D0              <1> 	movzx	edx, ax ; **
  3095 0000B490 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 0000B492 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 0000B497 6683F801            <1> 	cmp	ax, 1 ; r1
  3103                              <1> 		; tst r1 / is i-number 0?
  3104 0000B49B 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 0000B49D 89D3                <1> 	mov	ebx, edx ; **
  3108 0000B49F 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 0000B4A2 C683[DEF10000]00    <1> 	mov	byte [ebx+u.fp], 0
  3113                              <1> 		; clrb u.fp(r1) / clear that entry in the u.fp list
  3114 0000B4A9 8B1D[E8F10000]      <1> 	mov	ebx, [u.fofp]
  3115                              <1> 		; mov u.fofp,r1 / r1 points to 3rd word in fsp entry
  3116                              <1> fclose_0:
  3117 0000B4AF 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 0000B4B2 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 0000B4B4 6652                <1> 	push	dx ;*
  3124                              <1> 		; mov r2,-(sp) / put r2 on the stack (i-number)
  3125 0000B4B6 6631C0              <1> 	xor	ax, ax ; 0
  3126 0000B4B9 668943FC            <1> 	mov	[ebx-4], ax ; 0
  3127                              <1> 		; clr -4(r1) / clear 1st word of fsp entry
  3128 0000B4BD 8A4305              <1> 	mov	al, [ebx+5] ; 18/06/2015
  3129                              <1> 		; tstb	3(r1) / has this file been deleted
  3130 0000B4C0 20C0                <1> 	and	al, al
  3131 0000B4C2 7408                <1> 	jz	short fclose_1
  3132                              <1> 		; beq 2f / no, branch
  3133 0000B4C4 6689D0              <1> 	mov	ax, dx ; *
  3134                              <1> 		; mov r2,r1 / yes, put i-number back into r1
  3135                              <1> 	; AX = inode number
  3136 0000B4C7 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 0000B4CC 6658                <1> 	pop	ax ; *
  3141                              <1> 		; mov (sp)+,r1 / put i-number back into r1
  3142 0000B4CE 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 0000B4D3 6658                <1> 	pop	ax ; ***
  3146                              <1> 		; mov (sp)+,r1 / put index to u.fp back into r1
  3147 0000B4D5 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 0000B4D6 89C3                <1> 	mov	ebx, eax
  3156                              <1> getf1: ;; Calling point from 'rw1' (23/05/2013)
  3157 0000B4D8 83FB0A              <1> 	cmp	ebx, 10
  3158                              <1> 		; cmp r1,$10. / user limited to 10 open files
  3159 0000B4DB 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 0000B4DD 8A9B[DEF10000]      <1> 	mov	bl, [ebx+u.fp]
  3164                              <1> 		; movb	u.fp(r1),r1 / r1 contains number of entry 
  3165                              <1> 		                  ; / in fsp table
  3166 0000B4E3 08DB                <1> 	or	bl, bl
  3167 0000B4E5 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 0000B4E7 29C0                <1> 	sub	eax, eax
  3173 0000B4E9 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 0000B4EA B80A000000          <1> 	mov	eax, 10
  3193 0000B4EF F6E3                <1> 	mul	bl
  3194 0000B4F1 BB[A4EF0000]        <1> 	mov	ebx, fsp - 6 ; the 3rd word in the fsp entry
  3195 0000B4F6 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 0000B4F8 891D[E8F10000]      <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 0000B4FE 4B                  <1> 	dec	ebx
  3206 0000B4FF 4B                  <1> 	dec	ebx
  3207 0000B500 668B03              <1> 	mov	ax, [ebx]
  3208                              <1> 	;mov	[cdev], al ; ;;Retro UNIX 8086 v1 ! 
  3209 0000B503 66A3[B8F10000]      <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 0000B509 4B                  <1> 	dec	ebx
  3213 0000B50A 4B                  <1> 	dec	ebx
  3214 0000B50B 668B03              <1> 	mov	ax, [ebx]
  3215                              <1> 		; mov -(r1),r1 / and the i-number  r1
  3216                              <1> getf4:	; 1:
  3217 0000B50E 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 0000B50F 66A1[DCF10000]      <1> 	mov	ax, [u.cdir]
  3254                              <1> 		; mov u.cdir,r1 / put the i-number of current directory
  3255                              <1> 			      ; / in r1
  3256 0000B515 668B15[22F20000]    <1> 	mov	dx, [u.cdrv]
  3257 0000B51C 668915[B8F10000]    <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 0000B523 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 0000B528 803E2F              <1> 	cmp	byte [esi], '/'
  3269                              <1> 		; cmpb *u.namep,$'/ / is first char in file name a /
  3270 0000B52B 751E                <1> 	jne	short namei_1
  3271                              <1> 		; bne 1f
  3272 0000B52D FF05[F0F10000]      <1> 	inc	dword [u.namep]
  3273                              <1> 		; inc u.namep / go to next char
  3274 0000B533 6649                <1> 	dec	cx ; remain byte count in the page
  3275 0000B535 7506                <1> 	jnz	short namei_0
  3276                              <1> 	; 12/10/2015
  3277 0000B537 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 0000B53C 4E                  <1> 	dec	esi
  3281                              <1> namei_0:
  3282 0000B53D 46                  <1> 	inc 	esi  ; go to next char
  3283 0000B53E 66A1[C2F10000]      <1> 	mov	ax, [rootdir] ; 09/07/2013
  3284                              <1> 		; mov rootdir,r1 / put i-number of rootdirectory in r1
  3285 0000B544 C605[B8F10000]00    <1> 	mov	byte [cdev], 0
  3286                              <1> 		; clr cdev / clear device number
  3287                              <1> namei_1: ; 1:
  3288 0000B54B F606FF              <1> 	test	byte [esi], 0FFh
  3289 0000B54E 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 0000B550 8935[50F20000]      <1> 	mov 	[nbase], esi
  3297 0000B556 66890D[54F20000]    <1> 	mov 	[ncount], cx
  3298                              <1> 	;
  3299                              <1> 	;mov	dx, 2
  3300 0000B55D B202                <1> 	mov	dl, 2 ; user flag (read, non-owner)
  3301 0000B55F 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 0000B564 66F705[9AEE0000]00- <1> 	test 	word [i.flgs], 4000h
  3304 0000B56C 40                  <1>
  3305                              <1> 		; bit $40000,i.flgs / directory i-node?
  3306 0000B56D 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 0000B56F 31C0                <1> 	xor	eax, eax
  3310 0000B571 A3[F4F10000]        <1> 	mov	[u.off], eax ; 0
  3311 0000B576 66A1[61F20000]      <1> 	mov	ax, [i.size]
  3312 0000B57C A3[ECF10000]        <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 0000B581 C705[E8F10000]-     <1> 	mov	dword [u.fofp], u.off
  3315 0000B587 [F4F10000]          <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 0000B58B C705[F8F10000]-     <1> 	mov	dword [u.base], u.dirbuf
  3319 0000B591 [0AF20000]          <1>
  3320                              <1> 		; mov $u.dirbuf,u.base / u.dirbuf holds a file name 
  3321                              <1> 				    ; / copied from a directory
  3322 0000B595 C705[FCF10000]1000- <1> 	mov 	dword [u.count], 16 ; 04/12/2015 (10 -> 16) 	
  3322 0000B59D 0000                <1>
  3323                              <1>  		; mov $10.,u.count / u.count is byte count 
  3324                              <1> 				 ; / for reads and writes
  3325 0000B59F 66A1[5DF20000]      <1> 	mov 	ax, [ii]
  3326                              <1> 	; 31/07/2013 ('namei_r') - 16/06/2015 ('u.kcall')
  3327 0000B5A5 FE05[3FF20000]      <1>  	inc     byte [u.kcall] ; the caller is 'namei' sign	
  3328 0000B5AB 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 0000B5B0 8B0D[00F20000]      <1> 	mov 	ecx, [u.nread]
  3332 0000B5B6 09C9                <1> 	or 	ecx, ecx
  3333                              <1> 		; tst u.nread
  3334 0000B5B8 741B                <1> 	jz	short nib
  3335                              <1> 		; ble nib / gives error return
  3336                              <1> 	;
  3337 0000B5BA 668B1D[0AF20000]    <1> 	mov 	bx, [u.dirbuf]
  3338 0000B5C1 6621DB              <1> 	and 	bx, bx       
  3339                              <1> 		; tst u.dirbuf /
  3340 0000B5C4 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 0000B5C6 A1[F4F10000]        <1> 	mov	eax, [u.off]
  3344 0000B5CB 83E810              <1> 	sub	eax, 16 ; 04/12/2015 (10 -> 16) 
  3345 0000B5CE A3[ECF10000]        <1> 	mov	[u.dirp], eax
  3346                              <1> 		; mov u.off,u.dirp
  3347                              <1> 		; sub $10.,u.dirp
  3348 0000B5D3 EBB6                <1> 	jmp	short namei_3
  3349                              <1> 		; br 2b
  3350                              <1> 
  3351                              <1> 	; 18/07/2013
  3352                              <1> nib: 
  3353 0000B5D5 31C0                <1> 	xor	eax, eax  ; xor ax, ax ; ax = 0 -> file not found 
  3354 0000B5D7 F9                  <1> 	stc
  3355                              <1> nig:
  3356 0000B5D8 C3                  <1> 	retn
  3357                              <1> 
  3358                              <1> namei_err:
  3359                              <1> 	; 16/06/2015
  3360 0000B5D9 C705[2DF20000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a directory !' error
  3360 0000B5E1 0000                <1>
  3361 0000B5E3 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 0000B5E8 8B2D[F0F10000]      <1> 	mov	ebp, [u.namep]
  3369                              <1> 		; mov u.namep,r2 / u.namep points into a file name string
  3370 0000B5EE BF[0CF20000]        <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 0000B5F3 8B35[50F20000]      <1> 	mov	esi, [nbase]	
  3374 0000B5F9 668B0D[54F20000]    <1> 	mov	cx, [ncount]
  3375                              <1> 	;
  3376 0000B600 6621C9              <1> 	and	cx, cx
  3377 0000B603 7505                <1> 	jnz	short namei_5	
  3378                              <1> 	;
  3379 0000B605 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 0000B60A 45                  <1> 	inc	ebp ; 18/07/2015
  3384 0000B60B 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 0000B60C 08C0                <1> 	or 	al, al
  3387 0000B60E 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 0000B610 3C2F                <1> 	cmp	al, '/'
  3391                              <1> 		; cmp r4,$'/ / is char a </>
  3392 0000B612 7419                <1> 	je 	short namei_7
  3393                              <1> 		; beq 3f	
  3394                              <1> 	; 12/10/2015
  3395 0000B614 6649                <1> 	dec	cx ; remain byte count in the page
  3396 0000B616 7505                <1> 	jnz	short namei_6
  3397 0000B618 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 0000B61D 81FF[1AF20000]      <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 0000B623 74E5                <1> 	je	short namei_5
  3405                              <1> 		; beq 3b
  3406 0000B625 AE                  <1> 	scasb	
  3407                              <1> 		; cmpb (r3)+,r4 / compare char in u.namep string to file name 
  3408                              <1> 			      ; / char read from directory
  3409 0000B626 74E2                <1> 	je 	short namei_5
  3410                              <1> 		; beq 3b / branch if chars match
  3411                              <1> 
  3412 0000B628 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 0000B62D 81FF[1AF20000]      <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 0000B633 740A                <1> 	je	short namei_8
  3418                              <1> 		; beq 3f
  3419 0000B635 8A27                <1> 	mov 	ah, [edi]
  3420                              <1> 	;inc 	edi 
  3421 0000B637 20E4                <1> 	and 	ah, ah
  3422                              <1> 		; tstb (r3)+ /
  3423 0000B639 0F854CFFFFFF        <1>         jnz     namei_3
  3424                              <1> 		; bne 2b
  3425                              <1> namei_8: ; 3
  3426 0000B63F 892D[F0F10000]      <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 0000B645 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 0000B647 66A1[0AF20000]      <1> 	mov 	ax, [u.dirbuf] ; 17/06/2015
  3437 0000B64D 0F85FDFEFFFF        <1>         jnz     namei_2 
  3438                              <1> 		; bne 1b
  3439                              <1> 	; AX = i-number of the file
  3440                              <1> ;;nig:
  3441 0000B653 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 0000B654 8B2D[F0F10000]      <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 0000B65A 833D[35F20000]00    <1>         cmp     dword [u.ppgdir], 0  ; /etc/init ? (sysexec)
  3473 0000B661 7618                <1> 	jna	short trans_addr_nmk ; the caller is os kernel;
  3474                              <1> 				     ; it is already physical address
  3475 0000B663 50                  <1>    	push	eax	
  3476 0000B664 89EB                <1> 	mov	ebx, ebp ; [u.namep] ; pathname address (virtual)
  3477 0000B666 E84D88FFFF          <1>        	call	get_physical_addr ; get physical address
  3478 0000B66B 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 0000B66D 89C6                <1> 	mov	esi, eax ; 12/10/2015 (esi=[u.pnbase])
  3484 0000B66F 58                  <1> 	pop	eax 
  3485 0000B670 C3                  <1> 	retn
  3486                              <1> 
  3487                              <1> tr_addr_nm_err:
  3488 0000B671 A3[2DF20000]        <1> 	mov	[u.error], eax
  3489                              <1> 	;pop 	eax
  3490 0000B676 E998F0FFFF          <1> 	jmp	error
  3491                              <1> 
  3492                              <1> trans_addr_nmk:
  3493                              <1> 	; 12/10/2015
  3494                              <1> 	; 02/07/2015
  3495 0000B67B 8B35[F0F10000]      <1> 	mov	esi, [u.namep]  ; [u.pnbase]
  3496 0000B681 66B90010            <1> 	mov	cx, PAGE_SIZE ; 4096 ; [u.pncount]
  3497 0000B685 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 0000B686 891D[F0F10000]      <1> 	mov	[u.namep], ebx
  3524                              <1> 		;jsr r0,arg; u.namep / u.namep points to path name
  3525 0000B68C E87EFEFFFF          <1> 	call	namei
  3526                              <1> 		; jsr r0,namei / find its i-number
  3527                              <1> 	;jc	error
  3528                              <1> 		; br error3
  3529 0000B691 730F                <1> 	jnc	short syschdir0
  3530                              <1> 	; 'directory not found !' error
  3531 0000B693 C705[2DF20000]0C00- <1> 	mov	dword [u.error], ERR_DIR_NOT_FOUND ; 12
  3531 0000B69B 0000                <1>
  3532 0000B69D E971F0FFFF          <1> 	jmp	error
  3533                              <1> syschdir0:
  3534 0000B6A2 E87F0D0000          <1> 	call	access
  3535                              <1> 		; jsr r0,access; 2 / get i-node into core
  3536 0000B6A7 66F705[9AEE0000]00- <1> 	test	word [i.flgs], 4000h
  3536 0000B6AF 40                  <1>
  3537                              <1> 		; bit $40000,i.flgs / is it a directory?
  3538                              <1> 	;jz	error 
  3539                              <1> 		; beq error3 / no error
  3540 0000B6B0 750F                <1> 	jnz	short syschdir1
  3541 0000B6B2 C705[2DF20000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
  3541 0000B6BA 0000                <1>
  3542 0000B6BC E952F0FFFF          <1> 	jmp	error
  3543                              <1> syschdir1:
  3544 0000B6C1 66A3[DCF10000]      <1> 	mov	[u.cdir], ax
  3545                              <1> 		; mov r1,u.cdir / move i-number to users 
  3546                              <1> 			      ; / current directory
  3547 0000B6C7 66A1[B8F10000]      <1> 	mov	ax, [cdev]
  3548 0000B6CD 66A3[22F20000]      <1> 	mov	[u.cdrv], ax
  3549                              <1> 		; mov cdev,u.cdev / move its device to users 
  3550                              <1> 			        ; / current device
  3551 0000B6D3 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 0000B6D8 E814000000          <1> 	call	isown
  3593                              <1> 		;jsr r0,isown / get the i-node and check user status
  3594 0000B6DD 66F705[9AEE0000]00- <1> 	test	word [i.flgs], 4000h
  3594 0000B6E5 40                  <1>
  3595                              <1> 		; bit	$40000,i.flgs / directory?
  3596 0000B6E6 7402                <1> 	jz	short syschmod1
  3597                              <1> 		; beq 2f / no
  3598                              <1> 	; AL = (new) mode
  3599 0000B6E8 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 0000B6EA A2[9AEE0000]        <1> 	mov	[i.flgs], al	
  3604                              <1> 		; movb r2,i.flgs / move remaining mode to i.flgs
  3605 0000B6EF 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 0000B6F1 891D[F0F10000]      <1> 	mov	[u.namep], ebx ;; 1st argument
  3638 0000B6F7 51                  <1> 	push 	ecx ;; 2nd argument
  3639                              <1> 	;;
  3640 0000B6F8 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 0000B6FD 730F                <1> 	jnc	short isown0
  3649                              <1> 	; 'file not found !' error
  3650 0000B6FF C705[2DF20000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  3650 0000B707 0000                <1>
  3651 0000B709 E905F0FFFF          <1> 	jmp	error
  3652                              <1> isown0:
  3653 0000B70E E8080D0000          <1> 	call	iget
  3654                              <1> 		; jsr r0,iget / get i-node into core
  3655 0000B713 A0[24F20000]        <1> 	mov	al, [u.uid] ; 02/08/2013
  3656 0000B718 08C0                <1> 	or	al, al
  3657                              <1> 		; tstb u.uid / super user?
  3658 0000B71A 7417                <1> 	jz	short isown1
  3659                              <1> 		; beq 1f / yes, branch
  3660 0000B71C 3A05[9DEE0000]      <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 0000B722 740F                <1> 	je	short isown1
  3667                              <1> 
  3668 0000B724 C705[2DF20000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER  ; 11
  3668 0000B72C 0000                <1>
  3669                              <1> 			;  'permission denied !' error
  3670 0000B72E E9E0EFFFFF          <1> 	jmp	error
  3671                              <1> isown1: ; 1:
  3672 0000B733 E8EA0C0000          <1> 	call	setimod
  3673                              <1> 		; jsr r0,setimod / indicates 
  3674                              <1> 		;	       ; / i-node has been modified
  3675 0000B738 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 0000B739 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 0000B73A E8B2FFFFFF          <1> 	call	isown
  3767                              <1> 		; jsr r0,isown / get the i-node and check user status
  3768 0000B73F 803D[24F20000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013 
  3769                              <1> 		; tstb u.uid / super user
  3770 0000B746 7418                <1> 	jz	short syschown1
  3771                              <1> 		; beq 2f / yes, 2f
  3772 0000B748 F605[9AEE0000]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 0000B74F 740F                <1> 	jz	short syschown1
  3777                              <1> 	; 'permission denied !'
  3778 0000B751 C705[2DF20000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS  ; 11
  3778 0000B759 0000                <1>
  3779 0000B75B E9B3EFFFFF          <1> 	jmp	error
  3780                              <1> syschown1: ; 2:
  3781                              <1> 	; AL = owner (number/ID)
  3782 0000B760 A2[9DEE0000]        <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 0000B765 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 0000B76A E8B90C0000          <1> 	call 	epoch
  3815 0000B76F A3[D8F10000]        <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 0000B774 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 0000B779 803D[24F20000]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 0000B780 760F                <1> 	jna	short systime1
  3853                              <1> 	; 'permission denied !'
  3854 0000B782 C705[2DF20000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11 
  3854 0000B78A 0000                <1>
  3855 0000B78C 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 0000B791 89D8                <1> 	mov	eax, ebx
  3860 0000B793 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 0000B798 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 0000B79D 8B2D[04F20000]      <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 0000B7A3 8B15[D0F10000]      <1> 	mov	edx, [u.sp] ; kernel stack at the beginning of sys call
  3910 0000B7A9 83C20C              <1> 	add	edx, 12 ; EIP -4-> CS -4-> EFLAGS -4-> ESP (user) 
  3911                              <1> 	; 07/10/2015
  3912 0000B7AC 891D[04F20000]      <1> 	mov	[u.break], ebx ; virtual address !!!
  3913                              <1> 	;
  3914 0000B7B2 3B1A                <1> 	cmp	ebx, [edx] ; compare new break point with 
  3915                              <1> 			   ; with top of user's stack (virtual!)
  3916 0000B7B4 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 0000B7B6 89DE                <1> 	mov	esi, ebx
  3921 0000B7B8 29EE                <1> 	sub	esi, ebp ; new break point - old break point
  3922 0000B7BA 7621                <1> 	jna	short sysbreak_3 
  3923                              <1> 	;push	ebx
  3924                              <1> sysbreak_1:
  3925 0000B7BC 89EB                <1> 	mov	ebx, ebp  
  3926 0000B7BE E8F586FFFF          <1> 	call	get_physical_addr ; get physical address
  3927 0000B7C3 0F82A8FEFFFF        <1> 	jc	tr_addr_nm_err
  3928                              <1> 	; 18/10/2015
  3929 0000B7C9 89C7                <1> 	mov	edi, eax 
  3930 0000B7CB 29C0                <1> 	sub	eax, eax ; 0
  3931                              <1> 		 ; ECX = remain byte count in page (1-4096)
  3932 0000B7CD 39CE                <1> 	cmp	esi, ecx
  3933 0000B7CF 7302                <1> 	jnb	short sysbreak_2
  3934 0000B7D1 89F1                <1> 	mov	ecx, esi
  3935                              <1> sysbreak_2:
  3936 0000B7D3 29CE                <1> 	sub	esi, ecx
  3937 0000B7D5 01CD                <1> 	add	ebp, ecx
  3938 0000B7D7 F3AA                <1> 	rep 	stosb
  3939 0000B7D9 09F6                <1> 	or	esi, esi
  3940 0000B7DB 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 0000B7DD 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 0000B7E2 80CC80              <1> 	or 	ah, 80h  ; 10000000b
  3987                              <1> 		; bis	$100000,r1 / allocate flag set
  3988 0000B7E5 6650                <1> 	push	ax
  3989                              <1> 		; mov r1,-(sp) / put mode on stack
  3990                              <1> 	; 31/07/2013
  3991 0000B7E7 66A1[5DF20000]      <1> 	mov	ax, [ii] ; move current i-number to AX/r1
  3992                              <1> 		; mov ii,r1 / move current i-number to r1
  3993 0000B7ED B201                <1> 	mov	dl, 1 ; owner flag mask
  3994 0000B7EF E8320C0000          <1> 	call	access	
  3995                              <1> 		; jsr r0,access; 1 / get its i-node into core
  3996 0000B7F4 6650                <1> 	push	ax
  3997                              <1> 		; mov r1,-(sp) / put i-number on stack
  3998 0000B7F6 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 0000B7FA 6640                <1> 	inc	ax
  4002                              <1> 		; inc r1 / r1 = r1 + 1
  4003 0000B7FC 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 0000B801 8413                <1> 	test	[ebx], dl
  4012                              <1> 		; bitb mq,(r2) / is the i-node active
  4013 0000B803 75F5                <1> 	jnz	short maknod1
  4014                              <1> 		; bne 1b / yes, try the next one
  4015 0000B805 0813                <1> 	or	[ebx], dl
  4016                              <1> 		; bisb mq,(r2) / no, make it active 
  4017                              <1> 			     ; / (put a 1 in the bit map)
  4018 0000B807 E80F0C0000          <1> 	call	iget
  4019                              <1> 		; jsr r0,iget / get i-node into core
  4020 0000B80C 66F705[9AEE0000]00- <1> 	test	word [i.flgs], 8000h 
  4020 0000B814 80                  <1>
  4021                              <1> 		; tst i.flgs / is i-node already allocated
  4022 0000B815 75E3                <1> 	jnz	short maknod1	
  4023                              <1> 		; blt 1b / yes, look for another one
  4024 0000B817 66A3[0AF20000]      <1> 	mov	[u.dirbuf], ax
  4025                              <1> 		; mov r1,u.dirbuf / no, put i-number in u.dirbuf
  4026 0000B81D 6658                <1> 	pop	ax
  4027                              <1> 		; mov (sp)+,r1 / get current i-number back
  4028 0000B81F E8F70B0000          <1> 	call	iget
  4029                              <1> 		; jsr r0,iget / get i-node in core
  4030 0000B824 E88AF9FFFF          <1> 	call	mkdir
  4031                              <1> 		; jsr r0,mkdir / make a directory entry 
  4032                              <1> 			     ; / in current directory
  4033 0000B829 66A1[0AF20000]      <1> 	mov	ax, [u.dirbuf]
  4034                              <1> 		; mov u.dirbuf,r1 / r1 = new inode number
  4035 0000B82F 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 0000B834 B908000000          <1> 	mov	ecx, 8 
  4039 0000B839 31C0                <1> 	xor	eax, eax ; 0
  4040 0000B83B BF[9AEE0000]        <1> 	mov	edi, inode 
  4041 0000B840 F3AB                <1> 	rep	stosd
  4042                              <1> 	;
  4043 0000B842 668F05[9AEE0000]    <1> 	pop	word [i.flgs]
  4044                              <1> 		; mov (sp)+,i.flgs / fill flags
  4045 0000B849 8A0D[24F20000]      <1> 	mov 	cl, [u.uid] ; 02/08/2013
  4046 0000B84F 880D[9DEE0000]      <1> 	mov 	[i.uid], cl
  4047                              <1> 		; movb u.uid,i.uid / user id	
  4048 0000B855 C605[9CEE0000]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 0000B85C E8C10B0000          <1> 	call setimod
  4059                              <1> 		; jsr r0,setimod / set modified flag
  4060 0000B861 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 0000B862 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 0000B867 0305[F8F10000]      <1> 	add	eax, [u.base] ; add offset (u.base) to base
  4102 0000B86D 8903                <1> 	mov	[ebx], eax
  4103                              <1> 		; mov u.count,*u.fofp / put result into r/w pointer
  4104 0000B86F 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 0000B874 BA01000000          <1> 	mov	edx, 1 ; 05/08/2013
  4119                              <1> 	;call 	seektell
  4120 0000B879 E812000000          <1> 	call 	seektell0 ; 05/08/2013
  4121                              <1> 	;mov	ebx, [u.fofp]
  4122 0000B87E 8B03                <1> 	mov	eax, [ebx]
  4123 0000B880 A3[D8F10000]        <1> 	mov	[u.r0], eax
  4124 0000B885 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 0000B88A 890D[F8F10000]      <1> 	mov 	[u.base], ecx ; offset
  4155                              <1> 		; jsr r0,arg; u.base / puts offset in u.base
  4156                              <1> seektell0:
  4157 0000B890 8915[FCF10000]      <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 0000B896 E83DFCFFFF          <1> 	call	getf1
  4166 0000B89B 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 0000B89E 750F                <1> 	jnz	short seektell1
  4172 0000B8A0 C705[2DF20000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
  4172 0000B8A8 0000                <1>
  4173 0000B8AA E964EEFFFF          <1> 	jmp	error
  4174                              <1> seektell1:
  4175                              <1> 	;push	eax
  4176 0000B8AF 80FC80              <1> 	cmp	ah, 80h
  4177 0000B8B2 7203                <1> 	jb	short seektell2
  4178                              <1> 		; bgt .+4 / if its positive jump
  4179 0000B8B4 66F7D8              <1> 	neg	ax
  4180                              <1> 		; neg r1 / if not make it positive
  4181                              <1> seektell2:
  4182 0000B8B7 E85F0B0000          <1> 	call	iget
  4183                              <1> 		; jsr r0,iget / get its i-node into core
  4184 0000B8BC 8B1D[E8F10000]      <1>         mov     ebx, [u.fofp] ; 05/08/2013
  4185 0000B8C2 803D[FCF10000]01    <1> 	cmp	byte [u.count], 1
  4186                              <1> 		; cmp u.count,$1 / is ptr name =1
  4187 0000B8C9 7705                <1> 	ja	short seektell3
  4188                              <1> 		; blt 2f / no its zero
  4189 0000B8CB 740A                <1> 	je	short seektell_4
  4190                              <1> 		; beq 1f / yes its 1
  4191 0000B8CD 31C0                <1> 	xor	eax, eax
  4192                              <1> 	;jmp	short seektell_5
  4193 0000B8CF C3                  <1> 	retn
  4194                              <1> seektell3:
  4195                              <1> 	; 03/01/2016
  4196                              <1> 	;movzx	eax, word [i.size]
  4197 0000B8D0 66A1[61F20000]      <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 0000B8D6 C3                  <1> 	retn
  4203                              <1> seektell_4: ; 1: / ptrname =1
  4204                              <1> 	;mov	ebx, [u.fofp]
  4205 0000B8D7 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 0000B8D9 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 0000B8DA 66891D[1CF20000]    <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 0000B8E1 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 0000B8E6 66891D[1EF20000]    <1> 	mov	[u.quit], bx
  4277 0000B8ED 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 0000B8F2 3A1D[25F20000]      <1> 	cmp	bl, [u.ruid] 
  4309                              <1> 		; cmpb r1,u.ruid / is it equal to the real user 
  4310                              <1> 			       ; / id number
  4311 0000B8F8 741E                <1> 	je	short setuid1
  4312                              <1> 		; beq 1f / yes
  4313 0000B8FA 803D[24F20000]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 0000B901 760F                <1> 	jna	short setuid0
  4318 0000B903 C705[2DF20000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11
  4318 0000B90B 0000                <1>
  4319                              <1> 				;  'permission denied !' error
  4320 0000B90D E901EEFFFF          <1> 	jmp	error
  4321                              <1> setuid0:
  4322 0000B912 881D[25F20000]      <1> 	mov	[u.ruid], bl
  4323                              <1> setuid1: ; 1:
  4324 0000B918 881D[24F20000]      <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 0000B91E 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 0000B923 0FB605[25F20000]    <1> 	movzx 	eax, byte [u.ruid]
  4353 0000B92A A3[D8F10000]        <1> 	mov	[u.r0], eax
  4354                              <1> 		; movb	u.ruid,*u.r0 / move the real user id to (u.r0)
  4355 0000B92F 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 0000B934 BB[AAEF0000]        <1> 	mov	ebx, fsp
  4383                              <1> 		; mov $fsp,r2 / move start of fsp table to r2
  4384                              <1> anyi_1: ; 1:
  4385 0000B939 663B03              <1> 	cmp	ax, [ebx]
  4386                              <1> 		; cmp r1,(r2) / do i-numbers match?
  4387 0000B93C 7433                <1> 	je	short anyi_3
  4388                              <1> 		; beq 1f / yes, 1f
  4389 0000B93E 66F7D8              <1> 	neg	ax
  4390                              <1> 		; neg r1 / no complement r1
  4391 0000B941 663B03              <1> 	cmp	ax, [ebx]
  4392                              <1> 		; cmp r1,(r2) / do they match now?
  4393 0000B944 742B                <1> 	je	short anyi_3
  4394                              <1> 		; beq 1f / yes, transfer
  4395                              <1> 		; / i-numbers do not match
  4396 0000B946 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 0000B949 81FB[9EF10000]      <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 0000B94F 72E8                <1> 	jb	short anyi_1
  4403                              <1> 		; blt 1b / no, check next entries i-number
  4404                              <1> 	;cmp	ax, 32768
  4405 0000B951 80FC80              <1> 	cmp	ah, 80h ; negative number check
  4406                              <1> 		; tst r1 / yes, no match
  4407                              <1> 		; bge .+4
  4408 0000B954 7203                <1> 	jb	short anyi_2
  4409 0000B956 66F7D8              <1> 	neg	ax
  4410                              <1> 		; neg r1 / make i-number positive
  4411                              <1> anyi_2:	
  4412 0000B959 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 0000B95E F6D2                <1> 	not 	dl ;; 0 at calculated bit position, other bits are 1
  4419                              <1>         ;and	[ebx], dx
  4420 0000B960 2013                <1> 	and 	[ebx], dl 
  4421                              <1> 		; bicb mq,(r2) / clear bit for i-node in the imap
  4422 0000B962 E8BA0A0000          <1> 	call	itrunc
  4423                              <1> 		; jsr r0,itrunc / free all blocks related to i-node
  4424 0000B967 66C705[9AEE0000]00- <1>  	mov 	word [i.flgs], 0
  4424 0000B96F 00                  <1>
  4425                              <1> 		; clr i.flgs / clear all flags in the i-node
  4426 0000B970 C3                  <1> 	retn
  4427                              <1> 		;rts	r0 / return
  4428                              <1> anyi_3: ; 1: / i-numbers match
  4429 0000B971 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 0000B974 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 0000B975 891D[F0F10000]      <1> 	mov	[u.namep], ebx
  4479 0000B97B 51                  <1> 	push	ecx ; directory name
  4480 0000B97C 66833D[BEF10000]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 0000B984 0F87E9000000        <1> 	ja	sysmnt_err0
  4486                              <1> 	;
  4487 0000B98A E8CC000000          <1> 	call	getspl
  4488                              <1> 		; jsr r0,getspl / get special files device number in r1
  4489                              <1> 	; 13/10/2015
  4490 0000B98F 0FB7D8              <1> 	movzx	ebx, ax ; ; Retro UNIX 8086 v1 device number (0 to 5)
  4491 0000B992 F683[56D80000]80    <1>         test    byte [ebx+drv.status], 80h ; 24/10/2015 
  4492 0000B999 750F                <1> 	jnz	short sysmnt_1
  4493                              <1> sysmnt_err1:
  4494 0000B99B C705[2DF20000]0F00- <1>         mov     dword [u.error], ERR_DRV_NOT_RDY ; drive not ready !
  4494 0000B9A3 0000                <1>
  4495 0000B9A5 E969EDFFFF          <1> 	jmp	error
  4496                              <1> sysmnt_1:
  4497 0000B9AA 8F05[F0F10000]      <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 0000B9B0 53                  <1> 	push	ebx ; 13/10/2015
  4502                              <1> 		; mov r1,-(sp) / save the device number
  4503                              <1>         ;
  4504 0000B9B1 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 0000B9B6 730F                <1> 	jnc	short sysmnt_2
  4512                              <1> sysmnt_err2:
  4513 0000B9B8 C705[2DF20000]0C00- <1>         mov     dword [u.error], ERR_FILE_NOT_FOUND ; drive not ready !
  4513 0000B9C0 0000                <1>
  4514 0000B9C2 E94CEDFFFF          <1> 	jmp	error
  4515                              <1> sysmnt_2:	
  4516 0000B9C7 66A3[BEF10000]      <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 0000B9CD 58                  <1> 	pop	eax ; Retro UNIX 8086 v1 device number/ID (0 to 5)     
  4529 0000B9CE A2[BBF10000]        <1> 	mov	[mdev], al
  4530                              <1> 		; mov  (sp),mntd / no, put the device number in mntd
  4531 0000B9D3 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 0000B9D5 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 0000B9DA C7430401000000      <1> 	mov	dword [ebx+4], 1 ; physical block number = 1
  4541 0000B9E1 E8450A0000          <1> 	call 	diskio
  4542 0000B9E6 731C                <1> 	jnc	short sysmnt_5
  4543 0000B9E8 31C0                <1> 	xor 	eax, eax
  4544 0000B9EA 66A3[BEF10000]      <1> 	mov	[mnti], ax ; 0
  4545 0000B9F0 A2[BBF10000]        <1> 	mov	[mdev], al ; 0
  4546                              <1> 	;mov	[cdev], al ; 0
  4547                              <1> sysmnt_invd:
  4548                              <1> 	; 14/11/2015
  4549 0000B9F5 FEC8                <1> 	dec 	al
  4550 0000B9F7 8903                <1> 	mov	[ebx], eax ; 000000FFh
  4551 0000B9F9 FEC0                <1> 	inc	al
  4552 0000B9FB 48                  <1> 	dec	eax
  4553 0000B9FC 894304              <1> 	mov	[ebx+4], eax ; 0FFFFFFFFh
  4554 0000B9FF 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 0000BA04 0FB603              <1> 	movzx	eax, byte [ebx] ; device number
  4561 0000BA07 C0E002              <1> 	shl	al, 2 ; 4*index
  4562 0000BA0A 8B88[3AD80000]      <1> 	mov	ecx, [eax+drv.size] ; volume (fs) size
  4563 0000BA10 C1E103              <1> 	shl 	ecx, 3
  4564 0000BA13 0FB715[91FC0000]    <1> 	movzx	edx, word [sb1+4] ; the 1st data word
  4565 0000BA1A 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 0000BA1C 75D7                <1> 	jne	short sysmnt_invd ; invalid disk !
  4569                              <1> 			 ; (which has not got a valid super block)
  4570                              <1> 	;
  4571 0000BA1E 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 0000BA22 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 0000BA27 891D[F0F10000]      <1>         mov	[u.namep], ebx
  4614 0000BA2D E829000000          <1> 	call	getspl
  4615                              <1> 		; jsr r0,getspl / get the device number in r1
  4616 0000BA32 3A05[BBF10000]      <1> 	cmp	al, [mdev]
  4617                              <1> 		; cmp r1,mntd / is it equal to the last device mounted?
  4618 0000BA38 7539                <1> 	jne	short sysmnt_err0 ; 'permission denied !' error
  4619                              <1> 	;jne	error
  4620                              <1>         	; bne errora / no error
  4621 0000BA3A 30C0                <1> 	xor	al, al ; ah = 0
  4622                              <1> sysumnt_0: ;1:
  4623 0000BA3C 3805[8EFC0000]      <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 0000BA42 7607                <1> 	jna	short sysumnt_1		
  4627                              <1> 		; bne 1b / yes, wait
  4628 0000BA44 E8E3090000          <1> 	call	idle ; (wait for hardware interrupt)
  4629 0000BA49 EBF1                <1> 	jmp	short sysumnt_0
  4630                              <1> sysumnt_1:        
  4631 0000BA4B A2[BBF10000]        <1> 	mov	[mdev], al
  4632                              <1> 	     	; clr mntd / no, clear these
  4633 0000BA50 66A3[BEF10000]      <1>    	mov	[mnti], ax
  4634                              <1>         	; clr mnti
  4635 0000BA56 E9D8ECFFFF          <1>         jmp	sysret
  4636                              <1> 		; br sysreta / return
  4637                              <1> 
  4638                              <1> getspl: ; / get device number from a special file name
  4639 0000BA5B E8AFFAFFFF          <1> 	call	namei
  4640                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
  4641                              <1> 		       ; ax = 0 -> file not found 	
  4642 0000BA60 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 0000BA66 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 0000BA6A 7207                <1>         jc	short sysmnt_err0 ; 'permission denied !' error
  4651                              <1> 	;jc	error
  4652                              <1> 		; ble errora / less than 0?  yes, error
  4653 0000BA6C 6683F805            <1>         cmp	ax, 5 ;
  4654                              <1> 		; cmp  r1,$9. / greater than 9  tap 7
  4655 0000BA70 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 0000BA72 C3                  <1> 	retn
  4661                              <1> 		; rts    r0 / return with device number in r1
  4662                              <1> sysmnt_err0:
  4663 0000BA73 C705[2DF20000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  4663 0000BA7B 0000                <1>
  4664 0000BA7D 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 0000BA82 0FB61D[27F20000]    <1> 	movzx	ebx, byte [u.uno] ; process number
  4677 0000BA89 8AA3[19EF0000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
  4678 0000BA8F E899090000          <1> 	call	sleep
  4679 0000BA94 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 0000BA99 28C0                <1> 	sub	al, al
  4698                              <1> 	; al = 0 (clear video page)
  4699                              <1> 	; bh = video page ; 13/05/2016
  4700 0000BA9B B407                <1> 	mov	ah, 07h
  4701                              <1> 	; ah = 7 (attribute/color)
  4702 0000BA9D 6631C9              <1> 	xor 	cx, cx ; 0, left upper column (cl) & row (cl)
  4703 0000BAA0 66BA4F18            <1> 	mov	dx, 184Fh ; right lower column & row (dl=24, dh=79)
  4704 0000BAA4 E8115CFFFF          <1> 	call	_scroll_up
  4705                              <1> 	; bh = video page
  4706 0000BAA9 6631D2              <1> 	xor	dx, dx ; 0 (cursor position) 
  4707 0000BAAC E9D45EFFFF          <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 0000BAB1 81F9FF000000        <1> 	cmp	ecx, MAX_MSG_LEN ; 255
  4720 0000BAB7 0F8776ECFFFF        <1> 	ja	sysret ; nothing to do with big message size
  4721 0000BABD 08C9                <1> 	or	cl, cl
  4722 0000BABF 0F846EECFFFF        <1> 	jz	sysret
  4723 0000BAC5 20D2                <1> 	and	dl, dl
  4724 0000BAC7 7502                <1> 	jnz	short sysmsg0
  4725 0000BAC9 B207                <1> 	mov	dl, 07h ; default color
  4726                              <1> 		; (black background, light gray character) 
  4727                              <1> sysmsg0:
  4728 0000BACB 891D[F8F10000]      <1> 	mov	[u.base], ebx
  4729 0000BAD1 8815[27DD0000]      <1> 	mov	[ccolor], dl ; color attributes
  4730 0000BAD7 89E5                <1> 	mov	ebp, esp
  4731 0000BAD9 31DB                <1> 	xor	ebx, ebx ; 0
  4732 0000BADB 891D[00F20000]      <1> 	mov	[u.nread], ebx ; 0
  4733                              <1> 	;
  4734 0000BAE1 381D[3FF20000]      <1> 	cmp	[u.kcall], bl ; 0
  4735 0000BAE7 7769                <1> 	ja	short sysmsgk ; Temporary (01/07/2015)
  4736                              <1> 	;
  4737 0000BAE9 890D[FCF10000]      <1> 	mov	[u.count], ecx
  4738 0000BAEF 41                  <1> 	inc	ecx ; + 00h ; ASCIIZ
  4739 0000BAF0 29CC                <1> 	sub	esp, ecx
  4740 0000BAF2 89E7                <1> 	mov	edi, esp
  4741 0000BAF4 89E6                <1> 	mov	esi, esp
  4742 0000BAF6 66891D[3DF20000]    <1> 	mov	[u.pcount], bx ; reset page (phy. addr.) counter
  4743                              <1> 	; 11/11/2015
  4744 0000BAFD 8A25[08F20000]      <1> 	mov 	ah, [u.ttyp] ; recent open tty
  4745                              <1> 	; 0 = none
  4746 0000BB03 FECC                <1> 	dec	ah
  4747 0000BB05 790C                <1> 	jns	short sysmsg1 
  4748 0000BB07 8A1D[27F20000]      <1> 	mov	bl, [u.uno] ; process number	
  4749 0000BB0D 8AA3[19EF0000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; user's (process's) console tty
  4750                              <1> sysmsg1:
  4751 0000BB13 8825[2CF20000]      <1> 	mov	[u.ttyn], ah
  4752                              <1> sysmsg2:
  4753 0000BB19 E817080000          <1> 	call	cpass
  4754 0000BB1E 7416                <1> 	jz	short sysmsg5
  4755 0000BB20 AA                  <1> 	stosb
  4756 0000BB21 20C0                <1> 	and	al, al
  4757 0000BB23 75F4                <1> 	jnz	short sysmsg2
  4758                              <1> sysmsg3:
  4759 0000BB25 80FC07              <1> 	cmp	ah, 7 ; tty number
  4760 0000BB28 7711                <1> 	ja	short sysmsg6 ; serial port
  4761 0000BB2A E83E000000          <1> 	call	print_cmsg
  4762                              <1> sysmsg4:
  4763 0000BB2F 89EC                <1> 	mov	esp, ebp	
  4764 0000BB31 E9FDEBFFFF          <1> 	jmp	sysret
  4765                              <1> sysmsg5:
  4766 0000BB36 C60700              <1> 	mov	byte [edi], 0
  4767 0000BB39 EBEA                <1> 	jmp	short sysmsg3
  4768                              <1> sysmsg6:
  4769 0000BB3B 8A06                <1> 	mov	al, [esi]
  4770 0000BB3D E8E3080000          <1> 	call	sndc
  4771 0000BB42 72EB                <1> 	jc	short sysmsg4
  4772 0000BB44 803E00              <1> 	cmp	byte [esi], 0  ; 0 is stop character
  4773 0000BB47 76E6                <1> 	jna	short sysmsg4
  4774 0000BB49 46                  <1> 	inc 	esi
  4775 0000BB4A 8A25[2CF20000]      <1> 	mov	ah, [u.ttyn]
  4776 0000BB50 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 0000BB52 8B35[F8F10000]      <1> 	mov	esi, [u.base]
  4782 0000BB58 8A25[26DD0000]      <1> 	mov	ah, [ptty] ; present/current screen (video page)
  4783 0000BB5E 8825[2CF20000]      <1> 	mov	[u.ttyn], ah
  4784 0000BB64 C605[3FF20000]00    <1> 	mov	byte [u.kcall], 0
  4785 0000BB6B 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 0000BB6D 8A3D[2CF20000]      <1> 	mov	bh, [u.ttyn]
  4800                              <1> 	;mov	bh, ah
  4801                              <1> 
  4802 0000BB73 AC                  <1> 	lodsb
  4803                              <1> pcmsg1:
  4804 0000BB74 56                  <1> 	push 	esi
  4805 0000BB75 8A1D[27DD0000]      <1> 	mov	bl, [ccolor]
  4806                              <1> 	;mov	bh, [u.ttyn]
  4807 0000BB7B E86F5DFFFF          <1> 	call 	_write_tty
  4808 0000BB80 5E                  <1> 	pop	esi
  4809 0000BB81 AC                  <1> 	lodsb
  4810 0000BB82 20C0                <1> 	and 	al, al  ; 0
  4811 0000BB84 75EE                <1> 	jnz 	short pcmsg1
  4812 0000BB86 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 0000BB87 21DB                <1> 	and 	ebx, ebx
  4830 0000BB89 750B                <1> 	jnz	short glerr_2
  4831                              <1> glerr_0:
  4832 0000BB8B A1[2DF20000]        <1> 	mov	eax, [u.error]
  4833                              <1> glerr_1:
  4834 0000BB90 A3[D8F10000]        <1> 	mov	[u.r0], eax
  4835 0000BB95 C3                  <1>  	retn
  4836                              <1> glerr_2:
  4837 0000BB96 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0, FFFFFFFEh -> FFFFFFFFh
  4838 0000BB97 74FD                <1> 	jz	short glerr_2 ; page fault count for process
  4839 0000BB99 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0	
  4840 0000BB9A 75EF                <1> 	jnz	short glerr_0
  4841 0000BB9C A1[BCFF0000]        <1> 	mov	eax, [PF_Count] ; total page fault count
  4842 0000BBA1 EBED                <1>         jmp     short glerr_1
  4843                              <1> glerr_3:
  4844 0000BBA3 A1[41F20000]        <1> 	mov 	eax, [u.pfcount]
  4845 0000BBA8 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 0000BBAA 8935[58F20000]      <1> 	mov	[argv], esi
  4865 0000BBB0 8915[61F20000]      <1> 	mov	[i.size], edx
  4866 0000BBB6 A3[5DF20000]        <1> 	mov	[ii], eax
  4867                              <1> 
  4868                              <1> 	; 06/05/2016
  4869                              <1> 	; Set 'sysexit' return order to MainProg
  4870                              <1> 	;
  4871 0000BBBB 58                  <1> 	pop	eax ; * 'loc_load_and_run_file_8:' address
  4872 0000BBBC 8B25[94DC0000]      <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 0000BBC2 68[1E460000]        <1> 	push	_end_of_mainprog ; we must not return to here !
  4881 0000BBC7 FF35[6CEA0000]      <1> 	push	dword [mainprog_return_addr]
  4882 0000BBCD 89E5                <1> 	mov	ebp, esp ; **
  4883                              <1> 	;	
  4884 0000BBCF 9C                  <1> 	pushfd  ; EFLAGS      ; IRETD
  4885 0000BBD0 6A08                <1> 	push	KCODE ; cs    ; IRETD
  4886 0000BBD2 50                  <1> 	push	eax ; * (eip) ; IRETD
  4887 0000BBD3 8925[D0F10000]      <1> 	mov	[u.sp], esp
  4888 0000BBD9 1E                  <1> 	push	ds
  4889 0000BBDA 06                  <1> 	push	es
  4890 0000BBDB 0FA0                <1> 	push	fs
  4891 0000BBDD 0FA8                <1> 	push	gs	
  4892 0000BBDF 60                  <1> 	pushad
  4893 0000BBE0 68[33A70000]        <1> 	push	sysret
  4894 0000BBE5 8925[D4F10000]      <1> 	mov	[u.usp], esp
  4895                              <1> 	;
  4896 0000BBEB E858060000          <1> 	call	wswap ; Save MainProg (process 1) 'u' structure
  4897                              <1> 		      ; and registers for return (from program)	
  4898 0000BBF0 89EC                <1> 	mov	esp, ebp ; **
  4899 0000BBF2 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 0000BBF3 31F6                <1> 	xor 	esi, esi
  4904                              <1> cnpm_1: ; search p.stat table for unused process number
  4905 0000BBF5 46                  <1> 	inc	esi
  4906 0000BBF6 80BE[49EF0000]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE
  4907                              <1> 				; is process active, unused, dead
  4908 0000BBFD 760B                <1> 	jna	short cnpm_2	; it's unused so branch
  4909 0000BBFF 6683FE10            <1> 	cmp	si, nproc 	; all processes checked
  4910 0000BC03 72F0                <1> 	jb	short cnpm_1    ; no, branch back
  4911 0000BC05 E98A8AFFFF          <1> 	jmp	panic 
  4912                              <1> cnpm_2:
  4913 0000BC0A A1[31F20000]        <1> 	mov	eax, [u.pgdir] ; page directory of MainProg
  4914 0000BC0F A3[35F20000]        <1> 	mov	[u.ppgdir], eax ; parent's page directory
  4915 0000BC14 E88D7BFFFF          <1> 	call	allocate_page
  4916 0000BC19 0F82758AFFFF        <1> 	jc	panic
  4917                              <1> 	; EAX = UPAGE (user structure page) address
  4918 0000BC1F A3[28F20000]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
  4919 0000BC24 89F7                <1> 	mov	edi, esi
  4920 0000BC26 66C1E702            <1> 	shl	di, 2
  4921 0000BC2A 8987[56EF0000]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
  4922 0000BC30 E8EB7BFFFF          <1> 	call	clear_page ; 03/05/2016
  4923                              <1> 	;movzx	eax, byte [p.ttyc] ; console tty (for MainProg)
  4924 0000BC35 6629C0              <1> 	sub	ax, ax ; 0
  4925 0000BC38 668986[19EF0000]    <1> 	mov     [esi+p.ttyc-1], ax ; al - set child's console tty
  4926                              <1> 				   ; ah - reset child's wait channel	
  4927 0000BC3F 89F0                <1> 	mov	eax, esi
  4928 0000BC41 A2[27F20000]        <1> 	mov	[u.uno], al ; child process number
  4929 0000BC46 FE86[49EF0000]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN
  4930 0000BC4C 66D1E6              <1> 	shl	si, 1 ; multiply si by 2 to get index into p.pid table
  4931 0000BC4F 66FF05[C0F10000]    <1> 	inc	word [mpid] ; increment m.pid; get a new process name
  4932 0000BC56 66A1[C0F10000]      <1> 	mov	ax, [mpid]
  4933 0000BC5C 668986[B8EE0000]    <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 0000BC63 66B80100            <1> 	mov	ax, 1
  4937 0000BC67 668986[D8EE0000]    <1> 	mov	[esi+p.ppid-2], ax ; put parent process name 
  4938                              <1> 			           ; in parent process slot for child
  4939 0000BC6E 6648                <1> 	dec	ax ; 0
  4940 0000BC70 66A3[08F20000]      <1> 	mov 	[u.ttyp], ax ; 0
  4941                              <1> 	;;;
  4942 0000BC76 A1[5DF20000]        <1> 	mov 	eax,  [ii]
  4943                              <1> 	; Retro UNIX 386 v1, 'sysexec' (u2.s)
  4944 0000BC7B E89F070000          <1> 	call	iopen
  4945                              <1> 	; 06/06/2016
  4946 0000BC80 C605[1BF20000]01    <1> 	mov	byte [u.pri], 1 ; normal priority
  4947                              <1> 	;
  4948 0000BC87 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 0000BC89 A1[31F20000]        <1> 	mov	eax, [u.pgdir] ; physical address of page directory
  4959 0000BC8E E84C7CFFFF          <1> 	call	deallocate_page_dir
  4960                              <1> sysexec_7:
  4961 0000BC93 E87C7BFFFF          <1> 	call	make_page_dir
  4962 0000BC98 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 0000BC9E 8B15[F8DC0000]      <1> 	mov	edx, [k_page_dir] ; Kernel's page directory
  4970 0000BCA4 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 0000BCA6 8B15[31F20000]      <1> 	mov 	edx, [u.pgdir]
  4974 0000BCAC 8902                <1> 	mov	[edx], eax ; PDE 0 (1st 4MB)
  4975                              <1> 	;
  4976                              <1> 	; 20/07/2015
  4977 0000BCAE BB00004000          <1> 	mov	ebx, CORE ; start address = 0 (virtual) + CORE
  4978                              <1> 	; 18/10/2015
  4979 0000BCB3 BE[48F20000]        <1> 	mov	esi, pcore ; physical start address
  4980                              <1> sysexec_8:	
  4981 0000BCB8 B907000000          <1> 	mov	ecx, PDE_A_USER + PDE_A_WRITE + PDE_A_PRESENT
  4982 0000BCBD E8707BFFFF          <1> 	call	make_page_table
  4983 0000BCC2 0F82CC89FFFF        <1> 	jc	panic
  4984                              <1> 	;mov	ecx, PTE_A_USER + PTE_A_WRITE + PTE_A_PRESENT
  4985 0000BCC8 E8737BFFFF          <1> 	call	make_page ; make new page, clear and set the pte 
  4986 0000BCCD 0F82C189FFFF        <1> 	jc	panic
  4987                              <1> 	;
  4988 0000BCD3 8906                <1> 	mov	[esi], eax ; 24/06/2015
  4989                              <1> 	; ebx = virtual address (24/07/2015)
  4990 0000BCD5 E80881FFFF          <1> 	call 	add_to_swap_queue
  4991                              <1> 	; 18/10/2015
  4992 0000BCDA 81FE[4CF20000]      <1> 	cmp	esi, ecore ; user's stack (last) page ?
  4993 0000BCE0 740C                <1> 	je	short sysexec_9 ; yes
  4994 0000BCE2 BE[4CF20000]        <1> 	mov	esi, ecore  ; physical address of the last page 
  4995                              <1> 	; 20/07/2015
  4996 0000BCE7 BB00F0FFFF          <1> 	mov	ebx, (ECORE - PAGE_SIZE) + CORE
  4997                              <1> 	; ebx = virtual end address + segment base address - 4K
  4998 0000BCEC 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 0000BCEE 8B3D[4CF20000]      <1> 	mov	edi, [ecore]
  5009 0000BCF4 81C700100000        <1> 	add	edi, PAGE_SIZE
  5010 0000BCFA 0FB705[56F20000]    <1> 	movzx	eax, word [argc]
  5011 0000BD01 09C0                <1> 	or	eax, eax
  5012 0000BD03 7509                <1> 	jnz	short sysexec_10
  5013 0000BD05 89FB                <1> 	mov 	ebx, edi
  5014 0000BD07 83EB04              <1> 	sub	ebx, 4 
  5015 0000BD0A 8903                <1> 	mov	[ebx], eax ; 0
  5016 0000BD0C EB44                <1> 	jmp 	short sysexec_13
  5017                              <1> sysexec_10:
  5018 0000BD0E 8B0D[00F20000]      <1> 	mov	ecx, [u.nread]
  5019                              <1> 	;mov	esi, TextBuffer
  5020 0000BD14 8B35[58F20000]      <1> 	mov	esi, [argv] ; 24/04/2016 (TRDOS 386  = TRDOS v2.0)
  5021 0000BD1A 29CF                <1> 	sub	edi, ecx ; page end address - argument list length
  5022 0000BD1C 89C2                <1> 	mov	edx, eax
  5023 0000BD1E FEC2                <1> 	inc	dl ; argument count + 1 for argc value  
  5024 0000BD20 C0E202              <1> 	shl 	dl, 2  ; 4 * (argument count + 1)
  5025 0000BD23 89FB                <1> 	mov	ebx, edi
  5026 0000BD25 80E3FC              <1> 	and	bl, 0FCh ; 32 bit (dword) alignment
  5027 0000BD28 29D3                <1> 	sub 	ebx, edx
  5028 0000BD2A 89FA                <1> 	mov	edx, edi
  5029 0000BD2C F3A4                <1> 	rep	movsb
  5030 0000BD2E 89D6                <1> 	mov 	esi, edx
  5031 0000BD30 89DF                <1> 	mov 	edi, ebx
  5032 0000BD32 BA00F0BFFF          <1> 	mov	edx, ECORE - PAGE_SIZE ; virtual addr. of the last page
  5033 0000BD37 2B15[4CF20000]      <1> 	sub 	edx, [ecore] ; difference (virtual - physical) 
  5034 0000BD3D AB                  <1> 	stosd	; eax = argument count	
  5035                              <1> sysexec_11:
  5036 0000BD3E 89F0                <1> 	mov	eax, esi
  5037 0000BD40 01D0                <1> 	add	eax, edx
  5038 0000BD42 AB                  <1> 	stosd  ; eax = virtual address
  5039 0000BD43 FE0D[56F20000]      <1> 	dec	byte [argc]
  5040 0000BD49 7407                <1> 	jz	short sysexec_13
  5041                              <1> sysexec_12:
  5042 0000BD4B AC                  <1> 	lodsb
  5043 0000BD4C 20C0                <1> 	and	al, al
  5044 0000BD4E 75FB                <1> 	jnz	short sysexec_12
  5045 0000BD50 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 0000BD52 2B1D[4CF20000]      <1> 	sub 	ebx, [ecore]
  5055 0000BD58 81C300F0BFFF        <1> 	add     ebx, (ECORE - PAGE_SIZE)
  5056                              <1> 			; end of core - 4096 (last page)
  5057                              <1> 			; (virtual address)
  5058 0000BD5E 891D[58F20000]      <1> 	mov	[argv], ebx
  5059 0000BD64 891D[04F20000]      <1> 	mov	[u.break], ebx ; available user memory
  5060                              <1> 	;
  5061 0000BD6A 29C0                <1> 	sub	eax, eax
  5062 0000BD6C C705[FCF10000]2000- <1> 	mov	dword [u.count], 32 ; Executable file header size
  5062 0000BD74 0000                <1>
  5063 0000BD76 C705[E8F10000]-     <1> 	mov	dword [u.fofp], u.off
  5063 0000BD7C [F4F10000]          <1>
  5064 0000BD80 A3[F4F10000]        <1> 	mov	[u.off], eax ; 0
  5065 0000BD85 A3[F8F10000]        <1> 	mov	[u.base], eax ; 0, start of user's core (virtual)
  5066 0000BD8A A1[5DF20000]        <1> 	mov	eax, [ii] ; Fist Cluster of the Program (PRG) file
  5067                              <1> 	; EAX = First cluster of the executable file
  5068 0000BD8F E831010000          <1> 	call	readi
  5069                              <1> 
  5070 0000BD94 8B0D[04F20000]      <1> 	mov	ecx, [u.break] ; top of user's stack (physical addr.)
  5071 0000BD9A 890D[FCF10000]      <1> 	mov	[u.count], ecx ; save for overrun check
  5072                              <1> 	;
  5073 0000BDA0 8B0D[00F20000]      <1> 	mov	ecx, [u.nread]
  5074 0000BDA6 890D[04F20000]      <1> 	mov	[u.break], ecx ; virtual address (offset from start)
  5075 0000BDAC 80F920              <1> 	cmp	cl, 32
  5076 0000BDAF 7540                <1>         jne     short sysexec_15
  5077                              <1> 	;:
  5078                              <1> 	; Retro UNIX 386 v1 (32 bit) executable file header format
  5079 0000BDB1 8B35[48F20000]      <1> 	mov	esi, [pcore] ; start address of user's core memory 
  5080                              <1> 		             ; (phys. start addr. of the exec. file)
  5081 0000BDB7 AD                  <1> 	lodsd
  5082 0000BDB8 663DEB1E            <1> 	cmp	ax, 1EEBh ; EBH, 1Eh -> jump to +32
  5083 0000BDBC 7533                <1> 	jne	short sysexec_15
  5084 0000BDBE AD                  <1> 	lodsd
  5085 0000BDBF 89C1                <1> 	mov	ecx, eax ; text (code) section size
  5086 0000BDC1 AD                  <1> 	lodsd
  5087 0000BDC2 01C1                <1> 	add	ecx, eax ; + data section size (initialized data)
  5088 0000BDC4 89CB                <1> 	mov	ebx, ecx
  5089 0000BDC6 AD                  <1> 	lodsd	
  5090 0000BDC7 01C3                <1> 	add	ebx, eax ; + bss section size (for overrun checking)
  5091 0000BDC9 3B1D[FCF10000]      <1> 	cmp	ebx, [u.count]
  5092 0000BDCF 7711                <1> 	ja	short sysexec_14  ; program overruns stack !
  5093                              <1> 	;
  5094                              <1> 	; add bss section size to [u.break]
  5095 0000BDD1 0105[04F20000]      <1> 	add 	[u.break], eax
  5096                              <1> 	;
  5097 0000BDD7 83E920              <1> 	sub	ecx, 32  ; header size (already loaded)
  5098                              <1> 	;cmp	ecx, [u.count]
  5099                              <1> 	;jnb	short sysexec_16
  5100 0000BDDA 890D[FCF10000]      <1> 	mov	[u.count], ecx ; required read count
  5101 0000BDE0 EB29                <1> 	jmp	short sysexec_16
  5102                              <1> sysexec_14:
  5103                              <1> 	; insufficient (out of) memory
  5104 0000BDE2 C705[2DF20000]0100- <1> 	mov	dword [u.error], ERR_MINOR_IM ; 1
  5104 0000BDEA 0000                <1>
  5105 0000BDEC E922E9FFFF          <1> 	jmp	error
  5106                              <1> sysexec_15:
  5107 0000BDF1 8B15[61F20000]      <1>         mov	edx, [i.size] ; file size
  5108 0000BDF7 29CA                <1> 	sub	edx, ecx ; file size - loaded bytes
  5109 0000BDF9 7626                <1> 	jna	short sysexec_17 ; no need to next read
  5110 0000BDFB 01D1                <1> 	add	ecx, edx ; [i.size]
  5111 0000BDFD 3B0D[FCF10000]      <1> 	cmp	ecx, [u.count] ; overrun check (!)
  5112 0000BE03 77DD                <1> 	ja	short sysexec_14
  5113 0000BE05 8915[FCF10000]      <1> 	mov	[u.count], edx
  5114                              <1> sysexec_16:
  5115 0000BE0B A1[5DF20000]        <1> 	mov	eax, [ii] ; first cluster
  5116 0000BE10 E8B0000000          <1> 	call	readi
  5117 0000BE15 8B0D[00F20000]      <1> 	mov	ecx, [u.nread]
  5118 0000BE1B 010D[04F20000]      <1> 	add	[u.break], ecx
  5119                              <1> sysexec_17:
  5120 0000BE21 A1[5DF20000]        <1> 	mov	eax, [ii] ; first cluster
  5121 0000BE26 E8F5050000          <1> 	call	iclose
  5122 0000BE2B 31C0                <1> 	xor     eax, eax
  5123 0000BE2D FEC0                <1> 	inc	al
  5124 0000BE2F 66A3[1CF20000]      <1> 	mov	[u.intr], ax ; 1 (interrupt/time-out is enabled)
  5125 0000BE35 66A3[1EF20000]      <1> 	mov	[u.quit], ax ; 1 ('crtl+brk' signal is enabled) 
  5126 0000BE3B 833D[35F20000]00    <1>         cmp	dword [u.ppgdir], 0  ; is the caller MainProg (kernel) ?
  5127 0000BE42 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 0000BE44 8B15[F8DC0000]      <1> 	mov	edx, [k_page_dir] ; kernel's page directory
  5130 0000BE4A 8915[35F20000]      <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 0000BE50 8B2D[58F20000]      <1> 	mov	ebp, [argv] ; user's stack pointer must point to argument
  5138                              <1> 			    ; list pointers (argument count)
  5139 0000BE56 FA                  <1> 	cli
  5140 0000BE57 8B25[94DC0000]      <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 0000BE5D FEC8                <1> 	dec	al ; eax = 0
  5146 0000BE5F 66BA2300            <1> 	mov	dx, UDATA
  5147 0000BE63 6652                <1> 	push	dx  ; user's stack segment
  5148 0000BE65 55                  <1> 	push	ebp ; user's stack pointer
  5149                              <1> 		    ; (points to number of arguments)
  5150 0000BE66 FB                  <1> 	sti
  5151 0000BE67 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 0000BE68 6A1B                <1> 	push	UCODE
  5158                              <1> 	;push	0
  5159 0000BE6A 50                  <1> 	push	eax ; EIP (=0) - start address -	
  5160 0000BE6B 8925[D0F10000]      <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 0000BE71 8EC2                <1> 	mov 	es, dx ; UDATA
  5174 0000BE73 06                  <1> 	push 	es ; ds (UDATA)
  5175 0000BE74 06                  <1> 	push 	es ; es (UDATA)
  5176 0000BE75 06                  <1> 	push 	es ; fs (UDATA)
  5177 0000BE76 06                  <1> 	push	es ; gs (UDATA)
  5178 0000BE77 66BA1000            <1> 	mov	dx, KDATA
  5179 0000BE7B 8EC2                <1> 	mov	es, dx
  5180                              <1> 	;
  5181                              <1> 	;; pushad simulation
  5182 0000BE7D 89E5                <1> 	mov	ebp, esp ; esp before pushad
  5183 0000BE7F 50                  <1> 	push	eax ; eax (0)
  5184 0000BE80 50                  <1> 	push	eax ; ecx (0)
  5185 0000BE81 50                  <1> 	push	eax ; edx (0)
  5186 0000BE82 50                  <1> 	push	eax ; ebx (0)
  5187 0000BE83 55                  <1> 	push	ebp ; esp before pushad
  5188 0000BE84 50                  <1> 	push	eax ; ebp (0)
  5189 0000BE85 50                  <1> 	push	eax ; esi (0)		
  5190 0000BE86 50                  <1> 	push	eax ; edi (0)	
  5191                              <1> 	;
  5192 0000BE87 A3[D8F10000]        <1> 	mov	[u.r0], eax ; eax = 0
  5193 0000BE8C 8925[D4F10000]      <1> 	mov	[u.usp], esp
  5194                              <1> 
  5195                              <1> 	; 02/05/2016
  5196 0000BE92 FE05[CDF10000]      <1> 	inc	byte [sysflg] ; 0FFh -> 0
  5197 0000BE98 0FB61D[27F20000]    <1> 	movzx	ebx, byte [u.uno]	
  5198 0000BE9F 6683BB[D8EE0000]01  <1> 	cmp	word [ebx+p.ppid-2], 1 ; MainProg
  5199 0000BEA7 0F8789E8FFFF        <1> 	ja	sysret0 ; 03/05/2016
  5200 0000BEAD 68[33A70000]        <1> 	push	sysret ; * 
  5201 0000BEB2 8925[D4F10000]      <1> 	mov	[u.usp], esp
  5202 0000BEB8 E88B030000          <1> 	call	wswap ; save child process 'u' structure and
  5203                              <1> 		      ; registers
  5204 0000BEBD 8305[D4F10000]04    <1> 	add	dword [u.usp], 4 ; 03/05/2016 
  5205                              <1> sysexec_19: ; 02/05/2016
  5206 0000BEC4 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 0000BEC5 31D2                <1> 	xor	edx, edx ; 0
  5231 0000BEC7 8915[00F20000]      <1> 	mov 	[u.nread], edx ; 0
  5232 0000BECD 668915[3DF20000]    <1> 	mov	[u.pcount], dx ; 19/05/2015
  5233 0000BED4 3915[FCF10000]      <1> 	cmp 	[u.count], edx ; 0
  5234 0000BEDA 7701                <1> 	ja 	short readi_1
  5235 0000BEDC 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 0000BEDD 8B15[61F20000]      <1>         mov	edx, [i.size]
  5244 0000BEE3 8B1D[E8F10000]      <1> 	mov	ebx, [u.fofp]
  5245 0000BEE9 2B13                <1> 	sub	edx, [ebx]
  5246 0000BEEB 7647                <1> 	jna	short dskr_4
  5247                              <1> 	;
  5248 0000BEED 50                  <1> 	push	eax ; 01/05/2016
  5249 0000BEEE 3B15[FCF10000]      <1> 	cmp     edx, [u.count] 
  5250 0000BEF4 7306                <1> 	jnb	short dskr_1
  5251 0000BEF6 8915[FCF10000]      <1> 	mov	[u.count], edx
  5252                              <1> dskr_1:
  5253                              <1> 	; EAX = First Cluster
  5254                              <1> 	; [Current_Drv] = Physical drive number 
  5255 0000BEFC 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 0000BF01 BB[6DF20000]        <1> 	mov	ebx, readi_buffer
  5259 0000BF06 803D[3FF20000]00    <1> 	cmp	byte [u.kcall], 0 ; the caller is 'namei' sign (=1)
  5260 0000BF0D 770F                <1> 	ja	short dskr_3	  ; zf=0 -> the caller is 'namei'
  5261 0000BF0F 66833D[3DF20000]00  <1> 	cmp	word [u.pcount], 0
  5262 0000BF17 7705                <1> 	ja	short dskr_3
  5263                              <1> dskr_2:
  5264                              <1> 	; [u.base] = virtual address to transfer (as destination address)
  5265 0000BF19 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 0000BF1E E8F3010000          <1> 	call	sioreg
  5269 0000BF23 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 0000BF25 F3A4                <1> 	rep	movsb
  5274                              <1> 	; eax = remain bytes in buffer
  5275                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
  5276 0000BF27 09C0                <1> 	or	eax, eax
  5277 0000BF29 75EE                <1> 	jnz	short dskr_2 ; (page end before system buffer end!)		
  5278 0000BF2B 58                  <1> 	pop	eax  ; (first cluster number)
  5279 0000BF2C 390D[FCF10000]      <1> 	cmp	[u.count], ecx ; 0
  5280 0000BF32 77A9                <1> 	ja	short dskr_0
  5281                              <1> dskr_4:
  5282 0000BF34 C605[3FF20000]00    <1> 	mov	byte [u.kcall], 0
  5283 0000BF3B 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 0000BF3C 8B35[E8F10000]      <1> 	mov     esi, [u.fofp]
  5304 0000BF42 8B1E                <1> 	mov	ebx, [esi] ; u.off
  5305                              <1> 
  5306 0000BF44 29C9                <1> 	sub	ecx, ecx
  5307 0000BF46 8A2D[BEDD0000]      <1> 	mov	ch, [Current_Drv]
  5308                              <1> 
  5309 0000BF4C BE00010900          <1> 	mov	esi, Logical_DOSDisks
  5310 0000BF51 01CE                <1> 	add	esi, ecx
  5311                              <1> 
  5312 0000BF53 380D[2CEA0000]      <1> 	cmp	[readi.valid], cl ; 0
  5313 0000BF59 764B                <1> 	jna	short mget_r_0
  5314                              <1> 	
  5315 0000BF5B 3A2D[2DEA0000]      <1> 	cmp	ch, [readi.drv]
  5316 0000BF61 7543                <1> 	jne	short mget_r_0
  5317                              <1> 
  5318 0000BF63 3B05[40EA0000]      <1> 	cmp	eax, [readi.fclust]
  5319 0000BF69 7567                <1> 	jne	short mget_r_3
  5320                              <1> 	
  5321 0000BF6B 668B0D[34EA0000]    <1> 	mov	cx, [readi.bpc]
  5322 0000BF72 41                  <1> 	inc	ecx ; <= 65536
  5323 0000BF73 29D2                <1> 	sub	edx, edx
  5324 0000BF75 F7F1                <1> 	div	ecx
  5325                              <1> 
  5326 0000BF77 8B3D[3CEA0000]      <1> 	mov	edi, [readi.c_index] ; cluster index
  5327                              <1> 
  5328 0000BF7D 39F8                <1> 	cmp	eax, edi
  5329 0000BF7F 0F858B000000        <1>         jne     mget_r_5  ; (*)
  5330                              <1> 
  5331                              <1> 	; edx = byte offset in cluster (<= 65535)
  5332 0000BF85 668915[36EA0000]    <1> 	mov	[readi.offset], dx
  5333 0000BF8C 66C1EA09            <1> 	shr	dx, 9 ; / 512
  5334 0000BF90 8815[2FEA0000]      <1> 	mov	[readi.s_index], dl ; sector index in cluster (0 to spc -1)
  5335                              <1> 	
  5336 0000BF96 A1[38EA0000]        <1> 	mov	eax, [readi.cluster]
  5337 0000BF9B 8B15[44EA0000]      <1> 	mov	edx, [readi.fs_index]
  5338 0000BFA1 E9AF000000          <1>         jmp     mget_r_8
  5339                              <1> 	
  5340                              <1> mget_r_0:
  5341 0000BFA6 882D[2DEA0000]      <1> 	mov	[readi.drv], ch ; physical drive number
  5342 0000BFAC 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5343 0000BFB0 7707                <1> 	ja	short  mget_r_1
  5344 0000BFB2 8A4E12              <1> 	mov	cl, [esi+LD_FS_BytesPerSec+1]
  5345 0000BFB5 D0E9                <1> 	shr	cl, 1 ;  ; 1 for 512 bytes, 4 for 2048 bytes
  5346 0000BFB7 EB03                <1> 	jmp	short mget_r_2	
  5347                              <1> mget_r_1:
  5348 0000BFB9 8A4E13              <1> 	mov	cl, [esi+LD_BPB+BPB_SecPerClust]
  5349                              <1> mget_r_2:
  5350 0000BFBC 880D[2EEA0000]      <1> 	mov	[readi.spc], cl  ; sectors per cluster
  5351                              <1> 	; NOTE: readi bytes per sector value is always 512 ! 
  5352 0000BFC2 66C1E109            <1> 	shl	cx, 9 ; * 512
  5353 0000BFC6 6649                <1> 	dec	cx ; bytes per cluster - 1
  5354 0000BFC8 66890D[34EA0000]    <1> 	mov	[readi.bpc], cx
  5355 0000BFCF 6629C9              <1> 	sub	cx, cx
  5356                              <1> mget_r_3:
  5357 0000BFD2 A3[40EA0000]        <1> 	mov	[readi.fclust], eax ; first cluster (or FDT address)
  5358 0000BFD7 880D[2CEA0000]      <1> 	mov	[readi.valid], cl ; 0 
  5359 0000BFDD 880D[2FEA0000]      <1> 	mov	[readi.s_index], cl ; 0
  5360 0000BFE3 66890D[36EA0000]    <1> 	mov	[readi.offset], cx ; 0
  5361 0000BFEA 890D[3CEA0000]      <1> 	mov	[readi.c_index], ecx ; 0
  5362 0000BFF0 890D[38EA0000]      <1> 	mov	[readi.cluster], ecx ; 0
  5363 0000BFF6 890D[30EA0000]      <1> 	mov	[readi.sector], ecx ; 0
  5364                              <1> mget_r_4:	
  5365 0000BFFC 89D8                <1> 	mov	eax, ebx ; file offset
  5366 0000BFFE 668B0D[34EA0000]    <1> 	mov	cx, [readi.bpc]
  5367 0000C005 41                  <1> 	inc	ecx ; <= 65536
  5368 0000C006 29D2                <1> 	sub	edx, edx
  5369 0000C008 F7F1                <1> 	div	ecx
  5370 0000C00A 8B3D[3CEA0000]      <1> 	mov	edi, [readi.c_index] ; previous cluster index
  5371                              <1> mget_r_5:
  5372 0000C010 A3[3CEA0000]        <1> 	mov	[readi.c_index], eax ; cluster index
  5373                              <1> 	; edx = byte offset in cluster (<= 65535)
  5374 0000C015 668915[36EA0000]    <1> 	mov	[readi.offset], dx
  5375 0000C01C 66C1EA09            <1> 	shr	dx, 9 ; / 512
  5376 0000C020 8815[2FEA0000]      <1> 	mov	[readi.s_index], dl ; sector index in cluster (0 to spc -1)
  5377                              <1> 
  5378 0000C026 89C1                <1> 	mov	ecx, eax ; current cluster index
  5379 0000C028 A1[40EA0000]        <1> 	mov	eax, [readi.fclust]
  5380 0000C02D 09C9                <1> 	or	ecx, ecx ; cluster index
  5381 0000C02F 741F                <1> 	jz	short mget_r_7
  5382                              <1> 
  5383 0000C031 39CF                <1> 	cmp	edi, ecx
  5384 0000C033 7710                <1> 	ja	short mget_r_6 ; old cluster index is higher
  5385 0000C035 8B15[38EA0000]      <1> 	mov	edx, [readi.cluster]
  5386 0000C03B 21D2                <1> 	and	edx, edx
  5387 0000C03D 7406                <1> 	jz	short mget_r_6
  5388                              <1> 	; valid 'readi' parameters (*)
  5389 0000C03F 89D0                <1> 	mov	eax, edx
  5390 0000C041 29F9                <1> 	sub	ecx, edi
  5391 0000C043 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 0000C045 E897E5FFFF          <1> 	call	get_cluster_by_index
  5399 0000C04A 0F82C3E6FFFF        <1> 	jc	error
  5400                              <1> 	; EAX = Cluster number		
  5401                              <1> mget_r_7:
  5402 0000C050 A3[38EA0000]        <1> 	mov	[readi.cluster], eax ; FDT number for Singlix File System
  5403                              <1> mget_r_8:
  5404 0000C055 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5405 0000C059 764E                <1> 	jna	short  mget_r_13
  5406                              <1> 
  5407 0000C05B 83E802              <1> 	sub	eax, 2
  5408 0000C05E 0FB615[2EEA0000]    <1> 	movzx	edx, byte [readi.spc]
  5409 0000C065 F7E2                <1> 	mul	edx
  5410                              <1> 
  5411 0000C067 034668              <1> 	add	eax, [esi+LD_DATABegin]
  5412 0000C06A 8A15[2FEA0000]      <1> 	mov	dl, [readi.s_index]
  5413 0000C070 01D0                <1> 	add	eax, edx
  5414                              <1> msget_r_9:
  5415                              <1> 	; eax = logical sector number
  5416 0000C072 803D[2CEA0000]00    <1> 	cmp	byte [readi.valid], 0
  5417 0000C079 7608                <1> 	jna	short mget_r_10
  5418 0000C07B 3B05[30EA0000]      <1> 	cmp	eax, [readi.sector]
  5419 0000C081 7425                <1> 	je	short mget_r_12 ; sector is already in 'readi' buffer
  5420                              <1> mget_r_10:
  5421 0000C083 A3[30EA0000]        <1> 	mov	[readi.sector], eax
  5422 0000C088 BB[6DF20000]        <1> 	mov	ebx, readi_buffer ; buffer address
  5423 0000C08D 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 0000C092 E8A6030000          <1> 	call	disk_read
  5434 0000C097 730A                <1> 	jnc	short mget_r_11
  5435                              <1> 
  5436 0000C099 B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error !
  5437 0000C09E E970E6FFFF          <1> 	jmp	error
  5438                              <1> mget_r_11:
  5439 0000C0A3 A1[30EA0000]        <1> 	mov	eax, [readi.sector]
  5440                              <1> mget_r_12:
  5441 0000C0A8 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 0000C0A9 40                  <1> 	inc	eax ; the first data sector in FS disk section	
  5446 0000C0AA 8915[44EA0000]      <1> 	mov	[readi.fs_index], edx
  5447 0000C0B0 01D0                <1> 	add	eax, edx
  5448 0000C0B2 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 0000C0B4 31D2                <1> 	xor	edx, edx ; 0 (read access sign)
  5457 0000C0B6 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 0000C0B8 29D2                <1> 	sub	edx, edx
  5466 0000C0BA FEC2                <1> 	inc	dl ; 1 (write access sign)
  5467                              <1> trans_addr_rw:
  5468 0000C0BC 50                  <1> 	push	eax
  5469 0000C0BD 53                  <1> 	push	ebx
  5470 0000C0BE 52                  <1> 	push 	edx ; r/w sign (in DL)
  5471                              <1> 	;
  5472 0000C0BF 8B1D[F8F10000]      <1> 	mov	ebx, [u.base]
  5473 0000C0C5 E8EE7DFFFF          <1> 	call	get_physical_addr ; get physical address
  5474 0000C0CA 730A                <1> 	jnc	short passc_0
  5475 0000C0CC A3[2DF20000]        <1> 	mov	[u.error], eax
  5476                              <1> 	;pop	edx
  5477                              <1> 	;pop 	ebx
  5478                              <1> 	;pop	eax
  5479 0000C0D1 E93DE6FFFF          <1> 	jmp	error
  5480                              <1> passc_0:
  5481 0000C0D6 F6C202              <1> 	test	dl, PTE_A_WRITE ; writable page
  5482 0000C0D9 5A                  <1> 	pop	edx
  5483 0000C0DA 751C                <1> 	jnz	short passc_1
  5484                              <1> 	
  5485 0000C0DC 20D2                <1> 	and 	dl, dl
  5486 0000C0DE 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 0000C0E0 51                  <1> 	push 	ecx
  5490 0000C0E1 E8687AFFFF          <1> 	call 	copy_page
  5491 0000C0E6 59                  <1> 	pop	ecx
  5492 0000C0E7 721E                <1> 	jc	short passc_2
  5493 0000C0E9 50                  <1> 	push	eax ; physical address of the new/allocated page
  5494 0000C0EA E8F37CFFFF          <1> 	call	add_to_swap_queue	
  5495 0000C0EF 58                  <1> 	pop	eax
  5496 0000C0F0 81E3FF0F0000        <1> 	and 	ebx, PAGE_OFF ; 0FFFh
  5497                              <1> 	;mov 	ecx, PAGE_SIZE
  5498                              <1> 	;sub	ecx, ebx 
  5499 0000C0F6 01D8                <1> 	add	eax, ebx  
  5500                              <1> passc_1: 
  5501 0000C0F8 A3[39F20000]        <1> 	mov 	[u.pbase], eax ; physical address	
  5502 0000C0FD 66890D[3DF20000]    <1> 	mov	[u.pcount], cx ; remain byte count in page (1-4096)
  5503 0000C104 5B                  <1> 	pop	ebx
  5504 0000C105 58                  <1> 	pop	eax
  5505 0000C106 C3                  <1> 	retn
  5506                              <1> passc_2:
  5507 0000C107 C705[2DF20000]0100- <1> 	mov	dword [u.error], ERR_MINOR_IM ; "Insufficient memory !" error
  5507 0000C10F 0000                <1>
  5508                              <1> 	;pop 	ebx
  5509                              <1> 	;pop	eax
  5510 0000C111 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 0000C116 8B35[E8F10000]      <1>         mov     esi, [u.fofp]
  5533 0000C11C 8B3E                <1>         mov     edi, [esi]
  5534 0000C11E 89F9                <1> 	mov	ecx, edi
  5535 0000C120 81C900FEFFFF        <1> 	or	ecx, 0FFFFFE00h
  5536 0000C126 81E7FF010000        <1> 	and	edi, 1FFh
  5537 0000C12C 01DF                <1> 	add	edi, ebx ; EBX = system buffer (data) address
  5538 0000C12E F7D9                <1> 	neg	ecx
  5539 0000C130 3B0D[FCF10000]      <1> 	cmp	ecx, [u.count]
  5540 0000C136 7606                <1> 	jna	short sioreg_0
  5541 0000C138 8B0D[FCF10000]      <1> 	mov	ecx, [u.count]
  5542                              <1> sioreg_0:
  5543 0000C13E 803D[3FF20000]00    <1> 	cmp	byte [u.kcall], 0 
  5544 0000C145 7613                <1> 	jna	short sioreg_1
  5545                              <1> 	 ; the caller is 'mkdir' or 'namei'
  5546 0000C147 A1[F8F10000]        <1> 	mov	eax, [u.base]
  5547 0000C14C A3[39F20000]        <1> 	mov 	[u.pbase], eax ; physical address = virtual address
  5548 0000C151 66890D[3DF20000]    <1> 	mov	word [u.pcount], cx ; remain bytes in buffer (1 sector)
  5549 0000C158 EB0B                <1> 	jmp	short sioreg_2
  5550                              <1> sioreg_1:
  5551 0000C15A 0FB715[3DF20000]    <1> 	movzx	edx, word [u.pcount]
  5552 0000C161 39D1                <1> 	cmp	ecx, edx	
  5553 0000C163 772A                <1> 	ja	short sioreg_4 ; transfer count > [u.pcount]
  5554                              <1> sioreg_2: ; 2:
  5555 0000C165 31C0                <1> 	xor 	eax, eax
  5556                              <1> sioreg_3:
  5557 0000C167 010D[00F20000]      <1> 	add 	[u.nread], ecx
  5558 0000C16D 290D[FCF10000]      <1> 	sub 	[u.count], ecx
  5559 0000C173 010D[F8F10000]      <1> 	add 	[u.base], ecx
  5560 0000C179 010E                <1>         add 	[esi], ecx 
  5561 0000C17B 8B35[39F20000]      <1> 	mov	esi, [u.pbase]
  5562 0000C181 66290D[3DF20000]    <1> 	sub	[u.pcount], cx
  5563 0000C188 010D[39F20000]      <1> 	add	[u.pbase], ecx
  5564 0000C18E C3                  <1>         retn
  5565                              <1> sioreg_4:
  5566                              <1> 	; transfer count > [u.pcount] 
  5567                              <1> 	; (ecx > edx)
  5568 0000C18F 89C8                <1> 	mov	eax, ecx
  5569 0000C191 29D0                <1> 	sub	eax, edx ; remain bytes for 1 sector (block) transfer 
  5570 0000C193 89D1                <1> 	mov	ecx, edx ; current transfer count = [u.pcount]
  5571 0000C195 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 0000C197 803D[1BF20000]02    <1> 	cmp	byte [u.pri], 2	; high priority (run for event) ?
  5646 0000C19E 731A                <1> 	jnb	short swap      ; yes, do not add process to the run queue   
  5647                              <1> 	
  5648 0000C1A0 BB[C6F10000]        <1> 	mov	ebx, runq+2 	; 'runq_normal' ; normal/regular priority
  5649 0000C1A5 803D[1BF20000]00    <1> 	cmp	byte [u.pri], 0
  5650 0000C1AC 7702                <1> 	ja	short tswap_1	; normal priority
  5651                              <1> 
  5652 0000C1AE 43                  <1> 	inc	ebx
  5653 0000C1AF 43                  <1> 	inc	ebx		; runq+4, 'runq_background', low priority
  5654                              <1> tswap_1:
  5655 0000C1B0 A0[27F20000]        <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 0000C1B5 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 0000C1BA BE[C4F10000]        <1> 	mov	esi, runq ; 'runq_event' ; high priority, 'run for event'
  5727 0000C1BF C605[7CEA0000]03    <1> 	mov	byte [priority], 3 ; high priority + 1
  5728                              <1> swap_0: ; 1: / search runq table for highest priority process
  5729 0000C1C6 66AD                <1> 	lodsw  ; mov ax, [esi], add esi+2
  5730 0000C1C8 31DB                <1> 	xor	ebx, ebx ; 02/05/2016
  5731 0000C1CA 6621C0              <1> 	and 	ax, ax ; are there any processes to run in this Q entry
  5732 0000C1CD 750E                <1> 	jnz	short swap_2 
  5733                              <1> 	; 21/05/2026
  5734                              <1> 	; runq_normal = runq+2, runq_background = runq+4
  5735 0000C1CF FE0D[7CEA0000]      <1> 	dec	byte [priority] ; 3 -> 3, 2 -> 1, 1-> 0
  5736 0000C1D5 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 0000C1D7 FEC0                <1> 	inc	al ; mov al, 1  ; process number of MainProg
  5745 0000C1D9 FEC3                <1> 	inc	bl ; mov bl, al ; 1
  5746 0000C1DB EB1E                <1> 	jmp	short swap_4
  5747                              <1> swap_2:
  5748                              <1> 	; 21/05/2016
  5749 0000C1DD FE0D[7CEA0000]      <1> 	dec	byte [priority] ; priority level of present user/process
  5750                              <1> 			        ; 0, 1, 2	   
  5751 0000C1E3 4E                  <1> 	dec	esi
  5752 0000C1E4 4E                  <1>         dec     esi
  5753                              <1> 	;
  5754 0000C1E5 88C3                <1> 	mov	bl, al
  5755 0000C1E7 38E0                <1> 	cmp	al, ah ; is there only 1 process in the queue to be run
  5756 0000C1E9 740A                <1> 	je	short swap_3 ; yes
  5757 0000C1EB 8AA3[39EF0000]      <1> 	mov	ah, [ebx+p.link-1] 
  5758 0000C1F1 8826                <1>        	mov	[esi], ah ; move next process in line into run queue
  5759 0000C1F3 EB06                <1> 	jmp	short swap_4
  5760                              <1> swap_3: 
  5761 0000C1F5 6631D2              <1> 	xor	dx, dx
  5762 0000C1F8 668916              <1> 	mov	[esi], dx ; zero the entry; no processes on the Q
  5763                              <1> swap_4: 
  5764 0000C1FB 8A25[27F20000]      <1> 	mov 	ah, [u.uno]
  5765 0000C201 38C4                <1> 	cmp	ah, al ;is this process the same as the process in core?
  5766 0000C203 743B                <1>        	je	short swap_8 ; yes, don't have to swap
  5767 0000C205 08E4                <1> 	or	ah, ah  ; is the process # = 0
  5768 0000C207 740D                <1>        	jz	short swap_6 ; 'sysexit'
  5769 0000C209 8925[D4F10000]      <1> 	mov	[u.usp], esp ; return  address for 'syswait' & 'sleep'
  5770 0000C20F E834000000          <1> 	call	wswap   ; write out core to disk
  5771 0000C214 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 0000C216 53                  <1> 	push	ebx
  5778 0000C217 A1[31F20000]        <1> 	mov 	eax, [u.pgdir]  ; page directory of the process
  5779 0000C21C 8B1D[35F20000]      <1> 	mov	ebx, [u.ppgdir] ; page directory of the parent process
  5780 0000C222 E8B876FFFF          <1> 	call	deallocate_page_dir
  5781 0000C227 A1[28F20000]        <1> 	mov	eax, [u.upage] ; 'user' structure page of the process
  5782 0000C22C E84D77FFFF          <1> 	call	deallocate_page
  5783 0000C231 5B                  <1> 	pop	ebx
  5784                              <1> swap_7: 
  5785 0000C232 C0E302              <1> 	shl	bl, 2 ; * 4 
  5786 0000C235 8B83[56EF0000]      <1> 	mov	eax, [ebx+p.upage-4] ; the 'u' page of the new process
  5787 0000C23B E831000000          <1> 	call	rswap ; read new process into core
  5788                              <1> swap_8: 
  5789                              <1> 	; Retro UNIX  8086 v1 modification !
  5790 0000C240 C605[1AF20000]04    <1> 	mov	byte [u.quant], time_count 
  5791 0000C247 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 0000C248 8B3D[28F20000]      <1> 	mov	edi, [u.upage] ; process's user (u) structure page addr
  5843 0000C24E B91E000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
  5844 0000C253 BE[D0F10000]        <1> 	mov	esi, user ; active user (u) structure	
  5845 0000C258 F3A5                <1> 	rep	movsd
  5846                              <1> 	;
  5847 0000C25A 8B35[D4F10000]      <1> 	mov	esi, [u.usp] ; esp (system stack pointer, 
  5848                              <1> 			     ;      points to user registers)
  5849 0000C260 8B0D[D0F10000]      <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 0000C266 29F1                <1> 	sub	ecx, esi     ; required space for user registers
  5857 0000C268 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
  5858                              <1> 			     ; (for IRET) 	
  5859 0000C26B C1E902              <1> 	shr	ecx, 2	     		
  5860 0000C26E F3A5                <1> 	rep	movsd
  5861 0000C270 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 0000C271 89C6                <1> 	mov	esi, eax  ; process's user (u) structure page addr
  5917 0000C273 B91E000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
  5918 0000C278 BF[D0F10000]        <1> 	mov	edi, user ; active user (u) structure	
  5919 0000C27D F3A5                <1> 	rep	movsd
  5920 0000C27F 58                  <1> 	pop	eax	; 'rswap' return address
  5921                              <1> 	; 
  5922                              <1> 	;; 21/05/2016
  5923 0000C280 8A0D[7CEA0000]      <1> 	mov	cl, [priority]
  5924 0000C286 880D[1BF20000]      <1> 	mov	[u.pri], cl  ; running priority level 
  5925                              <1> 			     ; (specifies run queue which is 
  5926                              <1> 			     ; process comes from)
  5927                              <1> 	;cli
  5928 0000C28C 8B3D[D4F10000]      <1> 	mov	edi, [u.usp] ; esp (system stack pointer, 
  5929                              <1> 			     ;     points to user registers)
  5930 0000C292 8B0D[D0F10000]      <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 0000C298 29F9                <1> 	sub	ecx, edi     ; required space for user registers
  5938 0000C29A 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
  5939                              <1> 			     ; (for IRET) 	
  5940 0000C29D C1E902              <1> 	shr	ecx, 2	       		
  5941 0000C2A0 F3A5                <1> 	rep	movsd
  5942 0000C2A2 8B25[D4F10000]      <1> 	mov	esp, [u.usp] ; 15/09/2015
  5943                              <1> 	;sti
  5944 0000C2A8 50                  <1> 	push	eax	; 'rswap' return address
  5945 0000C2A9 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 0000C2AA 0FB613              <1> 	movzx  	edx, byte [ebx]
  5987 0000C2AD 43                  <1> 	inc	ebx
  5988 0000C2AE 20D2                <1> 	and	dl, dl
  5989                              <1> 		; tstb (r2)+ / is queue empty?
  5990 0000C2B0 740A                <1>        	jz	short putlu_1
  5991                              <1> 		; beq 1f / yes, branch
  5992 0000C2B2 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 0000C2B4 8882[39EF0000]      <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 0000C2BA EB03                <1> 	jmp	short putlu_2
  5999                              <1> 		; br 2f /
  6000                              <1> putlu_1: ; 1:
  6001 0000C2BC 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 0000C2BF 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 0000C2C1 88C2                <1> 	mov	dl, al
  6009 0000C2C3 88B2[39EF0000]      <1>         mov     [edx+p.link-1], dh ; 0
  6010                              <1> 		; dec r2 / restore r2
  6011 0000C2C9 C3                  <1>         retn
  6012                              <1> 		; rts r0
  6013                              <1> sysver:
  6014                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  6015 0000C2CA C705[D8F10000]0002- <1> 	mov	dword [u.r0], 200h ; AH = major version, AL = minor version 
  6015 0000C2D2 0000                <1>
  6016 0000C2D4 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 0000C2D9 C705[D8F10000]E007- <1> 	mov	dword [u.r0], 2016
  6021 0000C2E1 0000                <1>
  6022 0000C2E3 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 0000C2E8 29C0                <1> 	sub	eax, eax ; 0
  6071 0000C2EA A3[2DF20000]        <1> 	mov	[u.error], eax
  6072                              <1> 
  6073 0000C2EF A0[1BF20000]        <1> 	mov	al, [u.pri]
  6074 0000C2F4 A3[D8F10000]        <1> 	mov	[u.r0], eax
  6075                              <1> 
  6076 0000C2F9 FEC3                <1> 	inc	bl
  6077 0000C2FB 0F8432E4FFFF        <1> 	jz	sysret ; 0FFh -> 0, get priority level
  6078                              <1> 	
  6079 0000C301 3C02                <1> 	cmp	al, 2
  6080 0000C303 0F830AE4FFFF        <1> 	jnb	error ; CF = 1 & AL = 2 (& last error = 0)
  6081                              <1> 
  6082 0000C309 FECB                <1> 	dec	bl
  6083 0000C30B 80FB02              <1> 	cmp	bl, 2
  6084 0000C30E 7602                <1> 	jna	short syspri_1
  6085 0000C310 B302                <1> 	mov	bl, 2
  6086                              <1> syspri_1:
  6087 0000C312 881D[1BF20000]      <1> 	mov	[u.pri], bl
  6088 0000C318 80FB02              <1> 	cmp	bl, 2
  6089 0000C31B 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 0000C321 A0[27F20000]        <1> 	mov	al, [u.uno]
  6104 0000C326 BB[C6F10000]        <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 0000C32B E87AFFFFFF          <1> 	call	putlu
  6110 0000C330 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 0000C335 833D[FCF10000]00    <1> 	cmp 	dword [u.count], 0  ; have all the characters been transferred
  6127                              <1> 			    	    ; i.e., u.count, # of chars. left
  6128 0000C33C 763F                <1> 	jna	short cpass_3	    ; to be transferred = 0?) yes, branch
  6129 0000C33E FF0D[FCF10000]      <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 0000C344 66833D[3DF20000]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 0000C34C 770E                <1> 	ja	short cpass_1
  6137 0000C34E 833D[35F20000]00    <1> 	cmp     dword [u.ppgdir], 0  ; is the caller os kernel
  6138 0000C355 7427                <1>         je      short cpass_k       ; (sysexec, '/etc/init') ?  (MainProg)
  6139 0000C357 E858FDFFFF          <1> 	call	trans_addr_r
  6140                              <1> cpass_1:
  6141 0000C35C 66FF0D[3DF20000]    <1> 	dec	word [u.pcount]
  6142                              <1> cpass_2: 
  6143 0000C363 8B15[39F20000]      <1> 	mov	edx, [u.pbase]
  6144 0000C369 8A02                <1> 	mov	al, [edx]	; take the character pointed to 
  6145                              <1> 				; by u.base and put it in r1
  6146 0000C36B FF05[00F20000]      <1> 	inc	dword [u.nread] ; increment no. of bytes transferred
  6147 0000C371 FF05[F8F10000]      <1> 	inc	dword [u.base]  ; increment the buffer address to point to the
  6148                              <1> 			        ; next byte
  6149 0000C377 FF05[39F20000]      <1> 	inc	dword [u.pbase]
  6150                              <1> cpass_3:
  6151 0000C37D 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 0000C37E 8B1D[F8F10000]      <1> 	mov	ebx, [u.base]
  6157 0000C384 66C705[3DF20000]00- <1>         mov     word [u.pcount], PAGE_SIZE ; 4096
  6157 0000C38C 10                  <1>
  6158 0000C38D 891D[39F20000]      <1> 	mov	[u.pbase], ebx
  6159 0000C393 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 0000C395 21C9                <1> 	and	ecx, ecx
  6179 0000C397 743B                <1> 	jz	short ttub_4
  6180                              <1> 
  6181 0000C399 890D[FCF10000]      <1> 	mov	[u.count], ecx
  6182                              <1> 	
  6183 0000C39F 57                  <1> 	push	edi
  6184 0000C3A0 56                  <1> 	push	esi
  6185 0000C3A1 53                  <1> 	push	ebx
  6186 0000C3A2 52                  <1> 	push	edx
  6187 0000C3A3 51                  <1> 	push	ecx
  6188                              <1> 
  6189 0000C3A4 89FB                <1> 	mov	ebx, edi
  6190 0000C3A6 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 0000C3AC E80D7BFFFF          <1>        	call	get_physical_addr_x ; get physical address
  6195 0000C3B1 7222                <1> 	jc	short ttub_5
  6196                              <1> 	; eax = physical address 
  6197                              <1> 	; ecx = remain byte count in page (1-4096)
  6198 0000C3B3 89C7                <1> 	mov	edi, eax
  6199 0000C3B5 A1[FCF10000]        <1> 	mov	eax, [u.count]
  6200 0000C3BA 39C1                <1> 	cmp	ecx, eax
  6201 0000C3BC 7602                <1> 	jna	short ttub_2
  6202 0000C3BE 89C1                <1> 	mov	ecx, eax
  6203                              <1> ttub_2:	
  6204 0000C3C0 29C8                <1> 	sub	eax, ecx
  6205 0000C3C2 01CB                <1> 	add	ebx, ecx
  6206 0000C3C4 F3A4                <1> 	rep	movsb
  6207 0000C3C6 A3[FCF10000]        <1> 	mov	[u.count], eax
  6208 0000C3CB 09C0                <1> 	or	eax, eax
  6209 0000C3CD 75DD                <1> 	jnz	short ttub_1
  6210                              <1> ttub_retn:
  6211                              <1> tfub_retn:
  6212 0000C3CF 59                  <1> 	pop	ecx ; transfer count = actual transfer count
  6213                              <1> ttub_3:
  6214 0000C3D0 5A                  <1> 	pop	edx
  6215 0000C3D1 5B                  <1> 	pop	ebx
  6216 0000C3D2 5E                  <1> 	pop	esi
  6217 0000C3D3 5F                  <1> 	pop	edi
  6218                              <1> ttub_4:
  6219 0000C3D4 C3                  <1> 	retn
  6220                              <1> ttub_5:
  6221 0000C3D5 59                  <1> 	pop	ecx
  6222 0000C3D6 2B0D[FCF10000]      <1> 	sub	ecx, [u.count] ; actual transfer count
  6223 0000C3DC F9                  <1> 	stc
  6224 0000C3DD 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 0000C3DF 21C9                <1> 	and	ecx, ecx
  6244                              <1> 	;jz	short tfub_4
  6245 0000C3E1 74F1                <1> 	jz	short ttub_4
  6246                              <1> 
  6247 0000C3E3 890D[FCF10000]      <1> 	mov	[u.count], ecx
  6248                              <1> 	
  6249 0000C3E9 57                  <1> 	push	edi
  6250 0000C3EA 56                  <1> 	push	esi
  6251 0000C3EB 53                  <1> 	push	ebx
  6252 0000C3EC 52                  <1> 	push	edx
  6253 0000C3ED 51                  <1> 	push	ecx
  6254                              <1> 
  6255 0000C3EE 89F3                <1> 	mov	ebx, esi
  6256 0000C3F0 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 0000C3F6 E8C37AFFFF          <1>        	call	get_physical_addr_x ; get physical address
  6261                              <1> 	;jc	short tfub_5
  6262 0000C3FB 72D8                <1> 	jc	short ttub_5
  6263                              <1> 	; eax = physical address 
  6264                              <1> 	; ecx = remain byte count in page (1-4096)
  6265 0000C3FD 89C6                <1> 	mov	esi, eax
  6266 0000C3FF A1[FCF10000]        <1> 	mov	eax, [u.count]
  6267 0000C404 39C1                <1> 	cmp	ecx, eax
  6268 0000C406 7602                <1> 	jna	short tfub_2
  6269 0000C408 89C1                <1> 	mov	ecx, eax
  6270                              <1> tfub_2:	
  6271 0000C40A 29C8                <1> 	sub	eax, ecx
  6272 0000C40C 01CB                <1> 	add	ebx, ecx
  6273 0000C40E F3A4                <1> 	rep	movsb
  6274 0000C410 A3[FCF10000]        <1> 	mov	[u.count], eax
  6275 0000C415 09C0                <1> 	or	eax, eax
  6276 0000C417 75DD                <1> 	jnz	short tfub_1
  6277                              <1> 
  6278 0000C419 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 0000C41B C3                  <1> 	retn
  6299                              <1> poke:
  6300 0000C41C C3                  <1> 	retn
  6301                              <1> isintr:
  6302 0000C41D C3                  <1> 	retn
  6303                              <1> writei:
  6304 0000C41E C3                  <1> 	retn
  6305                              <1> iopen:
  6306 0000C41F C3                  <1> 	retn
  6307                              <1> iclose:
  6308 0000C420 C3                  <1> 	retn
  6309                              <1> itrunc:
  6310 0000C421 C3                  <1> 	retn
  6311                              <1> setimod:
  6312 0000C422 C3                  <1> 	retn
  6313                              <1> ottyp:
  6314 0000C423 C3                  <1> 	retn
  6315                              <1> cttyp:
  6316 0000C424 C3                  <1> 	retn
  6317                              <1> sndc:
  6318 0000C425 C3                  <1> 	retn
  6319                              <1> access:
  6320 0000C426 C3                  <1> 	retn
  6321                              <1> passc:
  6322 0000C427 C3                  <1> 	retn
  6323                              <1> epoch:
  6324 0000C428 C3                  <1> 	retn
  6325                              <1> set_date_time:
  6326 0000C429 C3                  <1> 	retn
  6327                              <1> imap:
  6328 0000C42A C3                  <1> 	retn
  6329                              <1> diskio:
  6330 0000C42B C3                  <1> 	retn
  6331                              <1> idle:
  6332 0000C42C C3                  <1> 	retn
  6333                              <1> sleep:
  6334 0000C42D 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 0000C42E 807E0500            <1> 	cmp	byte [esi+LD_LBAYes], 0
    20 0000C432 777B                <1>         ja      short lba_write
    21                              <1> 
    22                              <1> chs_write:
    23                              <1> 	; 25/02/2016
    24                              <1> 	; 23/02/2016
    25 0000C434 C605[B1E60000]03    <1> 	mov	byte [disk_rw_op], 3 ; CHS write
    26 0000C43B 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 0000C43D 807E0500            <1> 	cmp	byte [esi+LD_LBAYes], 0
    47 0000C441 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 0000C443 C605[B1E60000]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 0000C44A C605[B2E60000]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 0000C451 50                  <1> 	push	eax			; Linear sector #
    80 0000C452 51                  <1> 	push	ecx			; # of FAT/FILE/DIR sectors
    81                              <1>                 
    82 0000C453 0FB74E1E            <1> 	movzx	ecx, word [esi+LD_BPB+SecPerTrack]
    83                              <1> 	;movzx	ecx, byte [disk_rw_spt] ; 23/02/2016
    84 0000C457 29D2                <1> 	sub	edx, edx
    85 0000C459 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 0000C45B 6689D1              <1> 	mov	cx, dx			; Sector (zero based)
    90 0000C45E 6641                <1> 	inc	cx			; To make it 1 based
    91 0000C460 6651                <1> 	push	cx
    92 0000C462 668B4E20            <1> 	mov	cx, [esi+LD_BPB+Heads]
    93 0000C466 6629D2              <1> 	sub	dx, dx
    94 0000C469 F7F1                <1> 	div	ecx			; Convert track to head & cyl
    95                              <1> 	; eax (ax) = cylinder, dx (dl) = head (max. FFh)
    96 0000C46B 88D6                <1> 	mov	dh, dl
    97 0000C46D 6659                <1> 	pop	cx			; AX=Cyl, DH=Head, CX=Sector
    98 0000C46F 8A5602              <1> 	mov	dl, [esi+LD_PhyDrvNo]
    99                              <1> 
   100 0000C472 88C5                <1> 	mov	ch, al			; NOTE: max. 1023 cylinders !                   
   101 0000C474 C0CC02              <1> 	ror	ah, 2			; Rotate 2 bits right
   102 0000C477 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 0000C479 B001                <1> 	mov	al, 1 ; 25/02/2016
   113 0000C47B 8A25[B1E60000]      <1> 	mov	ah, [disk_rw_op]  ; 02h = chs read, 03h = chs write 
   114                              <1> 	;
   115 0000C481 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 0000C486 8825[B3E60000]      <1> 	mov	[disk_rw_err], ah
   122                              <1> 	
   123 0000C48C 59                  <1> 	pop	ecx
   124 0000C48D 58                  <1> 	pop	eax
   125 0000C48E 7314                <1> 	jnc	short chs_read_ok
   126                              <1> 
   127 0000C490 803D[B3E60000]09    <1> 	cmp	byte [disk_rw_err], 09h ; DMA crossed 64K segment boundary
   128 0000C497 7408                <1> 	je	short chs_read_error_retn
   129                              <1>              
   130 0000C499 FE0D[B2E60000]      <1> 	dec	byte [retry_count]
   131 0000C49F 75B0                <1> 	jnz	short chs_read_retry
   132                              <1> 
   133                              <1> chs_read_error_retn:
   134 0000C4A1 F9                  <1> 	stc
   135                              <1> 	;retn
   136 0000C4A2 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 0000C4A4 40                  <1> 	inc	eax ; next sector
   154 0000C4A5 81C300020000        <1> 	add	ebx, 512
   155 0000C4AB E29D                <1> 	loop	chs_read_next_sector
   156 0000C4AD EB5E                <1> 	jmp	short update_drv_error_byte
   157                              <1> 
   158                              <1> lba_write:
   159                              <1> 	; 23/02/2016
   160 0000C4AF C605[B1E60000]1C    <1> 	mov	byte [disk_rw_op], 1Ch ; LBA write
   161 0000C4B6 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 0000C4B8 C605[B1E60000]1B    <1> 	mov	byte [disk_rw_op], 1Bh ; LBA read
   185                              <1> 
   186                              <1> lba_rw:
   187                              <1> 	; 17/02/2016
   188 0000C4BF 57                  <1> 	push	edi
   189                              <1> 
   190 0000C4C0 890D[B4E60000]      <1> 	mov	[sector_count], ecx ; total sector (read) count
   191                              <1> 
   192 0000C4C6 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 0000C4C9 81F900010000        <1> 	cmp	ecx, 256
   197 0000C4CF 7605                <1> 	jna	short lba_read_rsc
   198 0000C4D1 B900010000          <1> 	mov	ecx, 256 ; 17/02/2016
   199                              <1> lba_read_rsc:
   200 0000C4D6 290D[B4E60000]      <1> 	sub	[sector_count], ecx ; remain sectors
   201                              <1> 
   202 0000C4DC 89CF                <1> 	mov	edi, ecx 
   203 0000C4DE 89C1                <1> 	mov	ecx, eax ; sector number/address
   204                              <1> 
   205 0000C4E0 C605[B2E60000]04    <1> 	mov	byte [retry_count], 4
   206                              <1> lba_read_retry:
   207 0000C4E7 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 0000C4E9 8A25[B1E60000]      <1> 	mov	ah, [disk_rw_op] ; 1Bh = LBA read, 1Ch = LBA write
   217 0000C4EF E84169FFFF          <1> 	call	int13h
   218                              <1> 	; al = ? (changed)
   219                              <1> 	; ah = error code
   220 0000C4F4 8825[B3E60000]      <1> 	mov	[disk_rw_err], ah
   221 0000C4FA 7334                <1> 	jnc	short lba_read_ok
   222 0000C4FC 80FC80              <1> 	cmp	ah, 80h ; time out?
   223 0000C4FF 740A                <1>         je      short lba_read_stc_retn
   224 0000C501 FE0D[B2E60000]      <1> 	dec	byte [retry_count]
   225 0000C507 7FDE                <1> 	jg	short lba_read_retry
   226 0000C509 743A                <1> 	jz	short lba_read_reset
   227                              <1> 	; sf =  1
   228                              <1> 
   229                              <1> lba_read_stc_retn:
   230 0000C50B F9                  <1> 	stc
   231                              <1> lba_read_retn:
   232 0000C50C 5F                  <1> 	pop	edi
   233                              <1> 
   234                              <1> update_drv_error_byte:
   235 0000C50D 9C                  <1> 	pushf
   236 0000C50E 53                  <1> 	push	ebx
   237 0000C50F 6651                <1> 	push	cx
   238                              <1> 	;or	ecx, ecx
   239                              <1> 	;jz	short udrv_errb0
   240 0000C511 8A0D[B3E60000]      <1> 	mov	cl, [disk_rw_err]
   241                              <1> udrv_errb0:
   242 0000C517 0FB65E02            <1> 	movzx	ebx, byte [esi+LD_PhyDrvNo]
   243 0000C51B 80FB02              <1> 	cmp	bl, 2
   244 0000C51E 7203                <1>         jb      short udrv_errb1
   245 0000C520 80EB7E              <1> 	sub	bl, 7Eh
   246                              <1> 	;cmp	bl, 5
   247                              <1> 	;ja	short udrv_errb2	
   248                              <1> udrv_errb1:
   249 0000C523 81C3[5DD80000]      <1>         add     ebx, drv.error ; 13/02/2016
   250 0000C529 880B                <1> 	mov	[ebx], cl ; error code
   251                              <1> udrv_errb2:
   252 0000C52B 6659                <1> 	pop	cx
   253 0000C52D 5B                  <1> 	pop	ebx
   254 0000C52E 9D                  <1> 	popf
   255 0000C52F C3                  <1> 	retn
   256                              <1> 
   257                              <1> lba_read_ok:
   258 0000C530 89C8                <1> 	mov	eax, ecx ; sector number
   259 0000C532 01F8                <1> 	add	eax, edi ; sector number (next)
   260 0000C534 C1E709              <1> 	shl	edi, 9 ; sector count * 512
   261 0000C537 01FB                <1> 	add	ebx, edi ; next buffer offset
   262                              <1> 
   263 0000C539 8B0D[B4E60000]      <1> 	mov	ecx, [sector_count] ; remaining sectors
   264 0000C53F 09C9                <1> 	or	ecx, ecx
   265 0000C541 7586                <1> 	jnz	short lba_read_next
   266 0000C543 EBC7                <1> 	jmp	short lba_read_retn
   267                              <1> 
   268                              <1> lba_read_reset:
   269 0000C545 B40D                <1> 	mov	ah, 0Dh ; Alternate reset
   270 0000C547 E8E968FFFF          <1>         call	int13h
   271                              <1> 	; al = ? (changed)
   272                              <1> 	; ah = error code
   273 0000C54C 7399                <1> 	jnc	short lba_read_retry
   274 0000C54E 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 0000C550 89C3                <1> 	mov	ebx, eax
   109 0000C552 31C0                <1> 	xor	eax, eax
   110 0000C554 BF[BAEE0000]        <1> 	mov	edi, p.pid
   111                              <1> srunseq_1:
   112 0000C559 3A05[27F20000]      <1>         cmp     al, [u.uno]     ; same process ?
   113 0000C55F 7514                <1> 	jne	short srunseq_4 ; no
   114                              <1> 
   115 0000C561 8A25[1BF20000]      <1> 	mov	ah, [u.pri] 	; present/current priority
   116 0000C567 80FC02              <1> 	cmp	ah, 2       	; 'run for event' priority level
   117 0000C56A 7229                <1> 	jb	short srunseq_8 ; no
   118                              <1> 
   119                              <1> srunseq_2:
   120                              <1> 	; there is nothing to do!
   121 0000C56C C3                  <1> 	retn
   122                              <1> 
   123                              <1> srunseq_3:
   124 0000C56D 3C10                <1>         cmp     al, nproc       ; number of processes = 16 
   125 0000C56F 7322                <1> 	jnb	short srunseq_7 ; 'p.pid' values do not match !!!???
   126                              <1> 
   127 0000C571 47                  <1> 	inc	edi
   128 0000C572 47                  <1> 	inc	edi
   129 0000C573 EBE4                <1> 	jmp	short srunseq_1
   130                              <1> 
   131                              <1> srunseq_4:
   132                              <1> 	; dl = priority
   133 0000C575 80FA02              <1> 	cmp	dl, 2 		; event queue
   134 0000C578 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 0000C57A 3A15[1BF20000]      <1> 	cmp	dl, [u.pri] 	; priority of present process
   142 0000C580 7606                <1> 	jna	short srunseq_5 ; is high, also
   143                              <1> 	;
   144                              <1> 	; present process will be swapped/switched out
   145 0000C582 FE05[7DEA0000]      <1> 	inc	byte [p_change] ; 1
   146                              <1> 
   147                              <1> srunseq_5:
   148                              <1> 	; add process to 'runq_event' queue for new event
   149 0000C588 BB[C4F10000]        <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 0000C58D E818FDFFFF          <1> 	call	putlu
   155 0000C592 C3                  <1> 	retn
   156                              <1> 
   157                              <1> srunseq_7:
   158 0000C593 F5                  <1> 	cmc
   159 0000C594 C3                  <1> 	retn
   160                              <1> 
   161                              <1> srunseq_8:
   162                              <1> 	; present priority of the process is not high
   163                              <1> 	
   164 0000C595 8815[1BF20000]      <1> 	mov	[u.pri], dl ; new priority 
   165                              <1> 			    ; (will be used by 'tswap')
   166                              <1> 
   167 0000C59B 80FA02              <1> 	cmp	dl, 2 		; high priority ?
   168 0000C59E 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 0000C5A0 BB[C6F10000]        <1> 	mov	ebx, runq_normal ; 'run as regular' queue
   176                              <1> 
   177 0000C5A5 20E4                <1> 	and	ah, ah  ;  previous value of [u.pri]
   178 0000C5A7 75E4                <1> 	jnz	short srunseq_6
   179                              <1> 
   180 0000C5A9 43                  <1> 	inc	ebx
   181 0000C5AA 43                  <1> 	inc	ebx
   182                              <1> 	; ebx = runq_background ; 'run on backgroud' queue 
   183                              <1> 
   184 0000C5AB 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 0000C5AD 803D[1AF20000]00    <1> 	cmp	byte [u.quant], 0
   195 0000C5B4 772C                <1> 	ja	short clk_1
   196                              <1> 	;
   197 0000C5B6 803D[27F20000]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 0000C5BD 7623                <1> 	jna	short clk_1 ; yes, do not swap out
   201                              <1> 	;
   202 0000C5BF 803D[CDF10000]FF    <1> 	cmp     byte [sysflg], 0FFh ; user or system space ?
   203 0000C5C6 7520                <1> 	jne	short clk_2 	    ; system space (sysflg <> 0FFh)
   204                              <1> 	;
   205 0000C5C8 66833D[1CF20000]00  <1> 	cmp	word [u.intr], 0
   206 0000C5D0 7616                <1> 	jna	short clk_2
   207                              <1> 	;
   208                              <1> 	; 23/05/2016
   209 0000C5D2 803D[7EEA0000]00    <1> 	cmp	byte [multi_tasking], 0
   210 0000C5D9 760D                <1> 	jna	short clk_2
   211                              <1> 	;
   212 0000C5DB FE05[7DEA0000]      <1> 	inc	byte [p_change] ; it is time to change running process	
   213 0000C5E1 C3                  <1> 	retn
   214                              <1> clk_1:
   215 0000C5E2 FE0D[1AF20000]      <1> 	dec	byte [u.quant]
   216                              <1> clk_2:
   217 0000C5E8 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 0000C5E9 FB                  <1> 	sti	; enable interrupts
   237 0000C5EA 80642408FE          <1> 	and	byte [esp+8], 11111110b	; clear carry bit of eflags register
   238 0000C5EF 80FC01              <1> 	cmp	ah, 1
   239 0000C5F2 7706                <1> 	ja	short int34h_3
   240 0000C5F4 7202                <1> 	jb	short int34h_2
   241                              <1> 	; AH = 1 -> write port
   242 0000C5F6 EE                  <1> 	out	dx, al
   243 0000C5F7 CF                  <1> 	iretd
   244                              <1> int34h_2:
   245                              <1> 	; AH = 0 -> read port
   246 0000C5F8 EC                  <1> 	in	al, dx	
   247 0000C5F9 CF                  <1> 	iretd
   248                              <1> int34h_3:
   249                              <1> 	; AH > 1 -> invalid function for now ; 20/06/2016
   250 0000C5FA 30C0                <1> 	xor	al, al ; 0
   251 0000C5FC 804C240801          <1> 	or	byte [esp+8], 1	; set carry bit of eflags register
   252 0000C601 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 0000C602 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 0000C603 890424              <1> 	mov 	[esp], eax ; overwrite call return address
   272                              <1> 	;push	eax
   273 0000C606 66B80900            <1> 	mov	ax, 9
   274 0000C60A EB07                <1> 	jmp	short comm_int
   275                              <1> com1_int:
   276                              <1> 	; 07/11/2015
   277                              <1> 	; 24/10/2015
   278 0000C60C 890424              <1> 	mov 	[esp], eax ; overwrite call return address
   279                              <1> 	; 23/10/2015
   280                              <1> 	;push	eax
   281 0000C60F 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 0000C613 53                  <1> 	push	ebx
   295 0000C614 56                  <1> 	push	esi
   296 0000C615 57                  <1> 	push	edi
   297 0000C616 1E                  <1> 	push 	ds
   298 0000C617 06                  <1> 	push 	es
   299                              <1> 	; 18/11/2015
   300 0000C618 0F20DB              <1> 	mov	ebx, cr3
   301 0000C61B 53                  <1> 	push	ebx ; ****
   302                              <1> 	;
   303 0000C61C 51                  <1> 	push	ecx ; ***
   304 0000C61D 52                  <1> 	push	edx ; **
   305                              <1> 	;
   306 0000C61E BB10000000          <1> 	mov	ebx, KDATA
   307 0000C623 8EDB                <1> 	mov	ds, bx
   308 0000C625 8EC3                <1> 	mov	es, bx
   309                              <1> 	;
   310 0000C627 8B0D[F8DC0000]      <1> 	mov	ecx, [k_page_dir]
   311 0000C62D 0F22D9              <1> 	mov	cr3, ecx
   312                              <1> 	; 20/11/2015
   313                              <1> 	; Interrupt identification register
   314 0000C630 66BAFA02            <1> 	mov	dx, 2FAh ; COM2
   315                              <1> 	;
   316 0000C634 3C08                <1> 	cmp 	al, 8 
   317 0000C636 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 0000C638 FEC6                <1> 	inc	dh ; 3FAh ; COM1 Interrupt id. register
   329                              <1> com_i0:
   330                              <1> 	;push	eax ; *
   331                              <1> 	; 07/11/2015
   332 0000C63A A2[62DD0000]        <1> 	mov 	byte [ccomport], al
   333                              <1> 	; 09/11/2015
   334 0000C63F 0FB7D8              <1> 	movzx	ebx, ax ; 8 or 9
   335                              <1> 	; 17/11/2015
   336                              <1>  	; reset request for response status
   337 0000C642 88A3[58DD0000]      <1> 	mov	[ebx+req_resp-8], ah ; 0
   338                              <1> 	;
   339                              <1> 	; 20/11/2015
   340 0000C648 EC                  <1> 	in	al, dx		; read interrupt id. register
   341 0000C649 EB00                <1> 	JMP	$+2	   	; I/O DELAY
   342 0000C64B 2404                <1> 	and	al, 4		; received data available?	
   343 0000C64D 7470                <1> 	jz	short com_eoi	; (transmit. holding reg. empty)
   344                              <1> 	;
   345                              <1> 	; 20/11/2015
   346 0000C64F 80EA02              <1> 	sub	dl, 3FAh-3F8h	; data register (3F8h, 2F8h)
   347 0000C652 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 0000C653 89DE                <1> 	mov	esi, ebx 
   352 0000C655 89DF                <1> 	mov	edi, ebx
   353 0000C657 81C6[5CDD0000]      <1> 	add 	esi, rchar - 8 ; points to last received char
   354 0000C65D 81C7[5EDD0000]      <1> 	add	edi, schar - 8 ; points to last sent char
   355 0000C663 8806                <1> 	mov	[esi], al ; received char (current char)
   356                              <1> 	; query
   357 0000C665 20C0                <1> 	and	al, al
   358 0000C667 7527                <1> 	jnz	short com_i2
   359                              <1>    	; response
   360                              <1> 	; 17/11/2015
   361                              <1> 	; set request for response status
   362 0000C669 FE83[58DD0000]      <1>         inc     byte [ebx+req_resp-8] ; 1 
   363                              <1> 	;
   364 0000C66F 6683C205            <1> 	add	dx, 3FDh-3F8h	; (3FDh, 2FDh)
   365 0000C673 EC                  <1> 	in	al, dx	   	; read line status register 
   366 0000C674 EB00                <1> 	JMP	$+2	   	; I/O DELAY
   367 0000C676 2420                <1> 	and	al, 20h	   	; transmitter holding reg. empty?
   368 0000C678 7445                <1> 	jz	short com_eoi 	; no
   369 0000C67A B0FF                <1> 	mov 	al, 0FFh   	; response			
   370 0000C67C 6683EA05            <1> 	sub	dx, 3FDh-3F8h 	; data port (3F8h, 2F8h)
   371 0000C680 EE                  <1> 	out	dx, al	   	; send on serial port
   372                              <1> 	; 17/11/2015
   373 0000C681 803F00              <1> 	cmp 	byte [edi], 0   ; query ? (schar)
   374 0000C684 7502                <1> 	jne 	short com_i1    ; no
   375 0000C686 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 0000C688 FE8B[58DD0000]      <1>         dec     byte [ebx+req_resp-8] ; 0 
   380 0000C68E EB2F                <1> 	jmp	short com_eoi
   381                              <1> com_i2:	
   382                              <1> 	; 08/11/2015
   383 0000C690 3CFF                <1> 	cmp 	al, 0FFh	; (response ?)
   384 0000C692 7417                <1> 	je	short com_i3	; (check for response signal)
   385                              <1> 	; 07/11/2015
   386 0000C694 3C04                <1> 	cmp	al, 04h	; EOT
   387 0000C696 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 0000C698 861D[26DD0000]      <1> 	xchg	bl, [ptty]  ; tty number (8 or 9)
   393 0000C69E E81680FFFF          <1> 	call 	ctrlbrk
   394 0000C6A3 861D[26DD0000]      <1> 	xchg	[ptty], bl ; (restore ptty value and BL value)
   395                              <1> 	;mov	al, 04h ; EOT
   396                              <1> 	; 08/11/2015
   397 0000C6A9 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 0000C6AB 803F00              <1>         cmp     byte [edi], 0 ; query ? (schar)
   404 0000C6AE 7704                <1> 	ja	short com_i4 ; no
   405                              <1> 	; reset query status (schar)
   406 0000C6B0 8807                <1> 	mov	[edi], al ; 0FFh
   407 0000C6B2 FEC0                <1> 	inc	al ; 0
   408                              <1> com_i4:
   409                              <1> 	; 27/07/2014
   410                              <1> 	; 09/07/2014
   411 0000C6B4 D0E3                <1> 	shl	bl, 1	
   412 0000C6B6 81C3[28DD0000]      <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 0000C6BC 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 0000C6BF A0[62DD0000]        <1> 	mov	al, byte [ccomport] ; current COM port
   426                              <1> 	 ; al = tty number (8 or 9)
   427 0000C6C4 E85E010000          <1>         call	wakeup
   428                              <1> com_iret:
   429                              <1> 	; 23/10/2015
   430 0000C6C9 5A                  <1> 	pop	edx ; **
   431 0000C6CA 59                  <1> 	pop	ecx ; ***
   432                              <1> 	; 18/11/2015
   433                              <1> 	;pop	eax ; ****
   434                              <1> 	;mov	cr3, eax
   435                              <1> 	;jmp	iiret
   436 0000C6CB E9ED42FFFF          <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 0000C6D0 BB[5EDD0000]        <1> 	mov	ebx, com1p		; COM1 parameters  
   502 0000C6D5 66BAF803            <1> 	mov	dx, 3F8h		; COM1
   503                              <1> 	 ; 29/10/2015
   504 0000C6D9 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
   505 0000C6DD E86F000000          <1> 	call	sp_i3	; call A4	
   506 0000C6E2 A880                <1> 	test	al, 80h
   507 0000C6E4 7410                <1> 	jz	short sp_i0 ; OK..
   508                              <1> 		; Error !
   509                              <1> 	;mov	dx, 3F8h
   510 0000C6E6 80EA05              <1> 	sub	dl, 5 ; 3FDh -> 3F8h
   511 0000C6E9 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
   512 0000C6ED E85F000000          <1> 	call	sp_i3	; call A4	
   513 0000C6F2 A880                <1> 	test	al, 80h
   514 0000C6F4 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 0000C6F6 C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
   520 0000C6F9 E8DC000000          <1> 	call	sp_i5 ; 29/06/2015
   521                              <1> sp_i1:
   522 0000C6FE 43                  <1> 	inc	ebx
   523 0000C6FF 66BAF802            <1> 	mov	dx, 2F8h		; COM2
   524                              <1> 	 ; 29/10/2015
   525 0000C703 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
   526 0000C707 E845000000          <1> 	call	sp_i3	; call A4	
   527 0000C70C A880                <1> 	test	al, 80h
   528 0000C70E 7410                <1> 	jz	short sp_i2 ; OK..
   529                              <1> 		; Error !
   530                              <1> 	;mov	dx, 2F8h
   531 0000C710 80EA05              <1> 	sub	dl, 5 ; 2FDh -> 2F8h
   532 0000C713 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
   533 0000C717 E835000000          <1> 	call	sp_i3	; call A4	
   534 0000C71C A880                <1> 	test	al, 80h
   535 0000C71E 7530                <1> 	jnz	short sp_i7
   536                              <1> sp_i2:
   537 0000C720 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 0000C723 9C                  <1> 	pushf
   543 0000C724 FA                  <1> 	cli
   544                              <1> 	;
   545 0000C725 66BAFC02            <1> 	mov	dx, 2FCh   		; modem control register
   546 0000C729 EC                  <1> 	in	al, dx 	   		; read register
   547 0000C72A EB00                <1> 	JMP	$+2	   		; I/O DELAY
   548 0000C72C 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
   549 0000C72E EE                  <1> 	out	dx, al     		; write back to register
   550 0000C72F EB00                <1> 	JMP	$+2	   		; I/O DELAY
   551 0000C731 66BAF902            <1> 	mov	dx, 2F9h   		; interrupt enable register
   552 0000C735 EC                  <1> 	in	al, dx     		; read register
   553 0000C736 EB00                <1> 	JMP	$+2	   		; I/O DELAY
   554                              <1> 	;or	al, 1      		; receiver data interrupt enable and
   555 0000C738 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
   556 0000C73A EE                  <1> 	out	dx, al 	   		; write back to register
   557 0000C73B EB00                <1> 	JMP	$+2        		; I/O DELAY
   558 0000C73D E421                <1> 	in	al, 21h    		; read interrupt mask register
   559 0000C73F EB00                <1> 	JMP	$+2	   		; I/O DELAY
   560 0000C741 24F7                <1> 	and	al, 0F7h   		; enable IRQ 3 (COM2)
   561 0000C743 E621                <1> 	out	21h, al    		; write back to register
   562                              <1> 	;
   563                              <1> 	; 23/10/2015
   564 0000C745 B8[03C60000]        <1> 	mov 	eax, com2_int
   565 0000C74A A3[22C80000]        <1> 	mov	[com2_irq3], eax
   566                              <1> 	; 26/10/2015
   567 0000C74F 9D                  <1> 	popf	
   568                              <1> sp_i7:
   569 0000C750 C3                  <1> 	retn
   570                              <1> 
   571                              <1> sp_i3:
   572                              <1> ;A4:  	;-----	INITIALIZE THE COMMUNICATIONS PORT
   573                              <1> 	; 28/10/2015
   574 0000C751 FEC2                <1> 	inc	dl	; 3F9h (2F9h)	; 3F9h, COM1 Interrupt enable register 
   575 0000C753 B000                <1> 	mov	al, 0
   576 0000C755 EE                  <1> 	out	dx, al			; disable serial port interrupt
   577 0000C756 EB00                <1> 	JMP	$+2			; I/O DELAY
   578 0000C758 80C202              <1> 	add	dl, 2 	; 3FBh (2FBh)	; COM1 Line control register (3FBh)
   579 0000C75B B080                <1> 	mov	al, 80h			
   580 0000C75D EE                  <1> 	out	dx, al			; SET DLAB=1 ; divisor latch access bit
   581                              <1> 	;-----	SET BAUD RATE DIVISOR
   582                              <1> 	; 26/10/2015
   583 0000C75E 80EA03              <1> 	sub 	dl, 3   ; 3F8h (2F8h)	; register for least significant byte
   584                              <1> 					; of the divisor value
   585 0000C761 88C8                <1> 	mov	al, cl	; 1
   586 0000C763 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 0000C764 EB00                <1> 	JMP	$+2			; I/O DELAY
   592 0000C766 28C0                <1> 	sub	al, al
   593 0000C768 FEC2                <1> 	inc	dl      ; 3F9h (2F9h)	; register for most significant byte
   594                              <1> 					; of the divisor value
   595 0000C76A EE                  <1> 	out	dx, al ; 0
   596 0000C76B EB00                <1> 	JMP	$+2			; I/O DELAY
   597                              <1> 	;	
   598 0000C76D 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 0000C76F 80C202              <1> 	add	dl, 2	; 3FBh (2FBh)	; Line control register
   601 0000C772 EE                  <1> 	out	dx, al			
   602 0000C773 EB00                <1> 	JMP	$+2			; I/O DELAY
   603                              <1> 	; 29/10/2015
   604 0000C775 FECA                <1> 	dec 	dl 	; 3FAh (2FAh)	; FIFO Control register (16550/16750)
   605 0000C777 30C0                <1> 	xor	al, al			; 0
   606 0000C779 EE                  <1> 	out	dx, al			; Disable FIFOs (reset to 8250 mode)
   607 0000C77A 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 0000C77C 80C204              <1> 	add	dl, 4	; 3FEh (2FEh)	; Modem status register
   612                              <1> sp_i4s:
   613 0000C77F EC                  <1> 	in	al, dx			; GET MODEM CONTROL STATUS
   614 0000C780 EB00                <1> 	JMP	$+2			; I/O DELAY
   615 0000C782 88C4                <1> 	mov	ah, al			; PUT IN (AH) FOR RETURN
   616 0000C784 FECA                <1> 	dec	dl	; 3FDh (2FDh)	; POINT TO LINE STATUS REGISTER
   617                              <1> 					; dx = 3FDh for COM1, 2FDh for COM2
   618 0000C786 EC                  <1> 	in	al, dx			; GET LINE CONTROL STATUS
   619                              <1> 	; AL = Line status, AH = Modem status
   620 0000C787 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 0000C788 66BAFE03            <1> 	mov	dx, 3FEh		; Modem status register (COM1)
   627 0000C78C 28C6                <1> 	sub	dh, al			; dh = 2 for COM2 (al = 1)
   628                              <1> 					; dx = 2FEh for COM2
   629 0000C78E 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 0000C790 66BAF803            <1> 	mov	dx, 3F8h
   674 0000C794 BB[5EDD0000]        <1> 	mov	ebx, com1p ; COM1 control byte offset
   675 0000C799 3C01                <1> 	cmp	al, 1
   676 0000C79B 776B                <1> 	ja 	short sp_invp_err
   677 0000C79D 7203                <1> 	jb	short sp_setp1 ;  COM1 (AL = 0)
   678 0000C79F FECE                <1> 	dec	dh ; 2F8h
   679 0000C7A1 43                  <1> 	inc	ebx ; COM2 control byte offset
   680                              <1> sp_setp1:
   681                              <1> 	; 29/10/2015
   682 0000C7A2 8823                <1> 	mov	[ebx], ah
   683 0000C7A4 0FB6CC              <1> 	movzx 	ecx, ah
   684 0000C7A7 C0E905              <1> 	shr	cl, 5 ; -> baud rate index
   685 0000C7AA 80E41F              <1> 	and	ah, 1Fh ; communication parameters except baud rate
   686 0000C7AD 8A81[17C80000]      <1> 	mov	al, [ecx+b_div_tbl]
   687 0000C7B3 6689C1              <1> 	mov	cx, ax
   688 0000C7B6 E896FFFFFF          <1> 	call	sp_i3
   689 0000C7BB 6689C1              <1> 	mov	cx, ax ; CL = Line status, CH = Modem status
   690 0000C7BE A880                <1> 	test	al, 80h
   691 0000C7C0 740F                <1> 	jz	short sp_setp2
   692 0000C7C2 C603E3              <1>         mov     byte [ebx], 0E3h ; Reset to initial value (11100011b)
   693                              <1> stp_dnr_err:
   694 0000C7C5 C705[2DF20000]0F00- <1> 	mov	dword [u.error], ERR_DEV_NOT_RDY ; 'device not ready !'
   694 0000C7CD 0000                <1>
   695                              <1> 	; CL = Line status, CH = Modem status
   696 0000C7CF F9                  <1> 	stc
   697 0000C7D0 C3                  <1> 	retn
   698                              <1> sp_setp2:
   699 0000C7D1 80FE02              <1> 	cmp	dh, 2 ; COM2 (2F?h)
   700 0000C7D4 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 0000C7DA 9C                  <1> 	pushf
   709 0000C7DB FA                  <1> 	cli
   710 0000C7DC 66BAFC03            <1> 	mov	dx, 3FCh   		; modem control register
   711 0000C7E0 EC                  <1> 	in	al, dx 	   		; read register
   712 0000C7E1 EB00                <1> 	JMP	$+2			; I/O DELAY
   713 0000C7E3 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
   714 0000C7E5 EE                  <1> 	out	dx, al     		; write back to register
   715 0000C7E6 EB00                <1> 	JMP	$+2			; I/O DELAY
   716 0000C7E8 66BAF903            <1> 	mov	dx, 3F9h   		; interrupt enable register
   717 0000C7EC EC                  <1> 	in	al, dx     		; read register
   718 0000C7ED EB00                <1> 	JMP	$+2			; I/O DELAY
   719                              <1> 	;or	al, 1      		; receiver data interrupt enable and
   720 0000C7EF 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
   721 0000C7F1 EE                  <1> 	out	dx, al 	   		; write back to register
   722 0000C7F2 EB00                <1> 	JMP	$+2        		; I/O DELAY
   723 0000C7F4 E421                <1> 	in	al, 21h    		; read interrupt mask register
   724 0000C7F6 EB00                <1> 	JMP	$+2			; I/O DELAY
   725 0000C7F8 24EF                <1> 	and	al, 0EFh   		; enable IRQ 4 (COM1)
   726 0000C7FA E621                <1> 	out	21h, al    		; write back to register
   727                              <1> 	;
   728                              <1> 	; 23/10/2015
   729 0000C7FC B8[0CC60000]        <1> 	mov 	eax, com1_int
   730 0000C801 A3[1EC80000]        <1> 	mov	[com1_irq4], eax
   731                              <1> 	; 26/10/2015
   732 0000C806 9D                  <1> 	popf
   733 0000C807 C3                  <1> 	retn
   734                              <1> 
   735                              <1> sp_invp_err:
   736 0000C808 C705[2DF20000]1700- <1> 	mov	dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
   736 0000C810 0000                <1>
   737 0000C812 31C9                <1> 	xor	ecx, ecx
   738 0000C814 49                  <1> 	dec	ecx ; 0FFFFh
   739 0000C815 F9                  <1> 	stc
   740 0000C816 C3                  <1> 	retn
   741                              <1> 
   742                              <1> ; 29/10/2015
   743                              <1> b_div_tbl: ; Baud rate divisor table (115200/divisor)
   744 0000C817 010C0603080401      <1> 	db 1, 12, 6, 3, 8, 4, 1
   745                              <1> 
   746                              <1> 
   747                              <1> ; 23/10/2015
   748                              <1> com1_irq4:
   749 0000C81E [26C80000]          <1> 	dd dummy_retn
   750                              <1> com2_irq3:
   751 0000C822 [26C80000]          <1> 	dd dummy_retn
   752                              <1> 
   753                              <1> dummy_retn:
   754 0000C826 C3                  <1> 	retn
   755                              <1> 
   756                              <1> wakeup:
   757                              <1> 	; 24/01/2016
   758 0000C827 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: 02/07/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 0000C828 01                  <1> 		db 1 ; A: = 0 & B: = 1
    22                              <1> 
    23                              <1> Restore_CDIR:	
    24 0000C829 FF                  <1> 		db 0FFh ; Initial value -> any number except 0
    25                              <1> 
    26                              <1> msg_CRLF_temp:  
    27 0000C82A 070D0A00            <1> 		db  07h, 0Dh, 0Ah, 0
    28                              <1> 
    29                              <1> Magic_Bytes:
    30 0000C82E 04                  <1> 		db 4
    31 0000C82F 01                  <1> 		db 1
    32                              <1> mainprog_Version:
    33 0000C830 07                  <1> 		db 7
    34 0000C831 5B5452444F535D204D- <1> 		db "[TRDOS] Main Program v2.0.020716"
    34 0000C83A 61696E2050726F6772- <1>
    34 0000C843 616D2076322E302E30- <1>
    34 0000C84C 3230373136          <1>
    35 0000C851 0D0A                <1> 		db 0Dh, 0Ah
    36 0000C853 286329204572646F67- <1> 		db "(c) Erdogan Tan 2005-2016"
    36 0000C85C 616E2054616E203230- <1>
    36 0000C865 30352D32303136      <1>
    37 0000C86C 0D0A00              <1> 		db 0Dh, 0Ah, 0
    38                              <1> 
    39                              <1> MainProgCfgFile: ; 14/04/2016
    40 0000C86F 4D41494E50524F472E- <1> 		db "MAINPROG.CFG", 0
    40 0000C878 43464700            <1>
    41                              <1> 
    42                              <1> TRDOSPromptLabel:
    43 0000C87C 5452444F53          <1> 		db "TRDOS"
    44 0000C881 00                  <1> 		db 0
    45 0000C882 00<rept>            <1>                 times 5 db 0
    46 0000C887 00                  <1> 		db 0
    47                              <1> 
    48                              <1> ; INTERNAL COMMANDS
    49                              <1> Command_List:
    50 0000C888 44495200            <1> Cmd_Dir:	db "DIR", 0
    51 0000C88C 434400              <1> Cmd_Cd:		db "CD", 0
    52 0000C88F 433A00              <1> Cmd_Drive:	db "C:", 0
    53 0000C892 56455200            <1> Cmd_Ver:	db "VER", 0
    54 0000C896 4558495400          <1> Cmd_Exit:	db "EXIT", 0
    55 0000C89B 50524F4D505400      <1> Cmd_Prompt:	db "PROMPT", 0
    56 0000C8A2 564F4C554D4500      <1> Cmd_Volume:	db "VOLUME", 0
    57 0000C8A9 4C4F4E474E414D4500  <1> Cmd_LongName:	db "LONGNAME", 0
    58 0000C8B2 4441544500          <1> Cmd_Date:	db "DATE", 0
    59 0000C8B7 54494D4500          <1> Cmd_Time:	db "TIME", 0
    60 0000C8BC 52554E00            <1> Cmd_Run:	db "RUN", 0
    61 0000C8C0 53455400            <1> Cmd_Set:	db "SET", 0 
    62 0000C8C4 434C5300            <1> Cmd_Cls:	db "CLS", 0
    63 0000C8C8 53484F5700          <1> Cmd_Show:	db "SHOW", 0
    64 0000C8CD 44454C00            <1> Cmd_Del:	db "DEL", 0
    65 0000C8D1 41545452494200      <1> Cmd_Attrib:	db "ATTRIB", 0
    66 0000C8D8 52454E414D4500      <1> Cmd_Rename:	db "RENAME", 0
    67 0000C8DF 524D44495200        <1> Cmd_Rmdir:	db "RMDIR", 0
    68 0000C8E5 4D4B44495200        <1> Cmd_Mkdir:	db "MKDIR", 0
    69 0000C8EB 434F505900          <1> Cmd_Copy:	db "COPY", 0
    70 0000C8F0 4D4F564500          <1> Cmd_Move:	db "MOVE", 0
    71 0000C8F5 5041544800          <1> Cmd_Path:	db "PATH", 0
    72 0000C8FA 4D454D00            <1> Cmd_Mem:	db "MEM", 0
    73 0000C8FE 00                  <1> 		db 0
    74 0000C8FF 46494E4400          <1> Cmd_Find:	db "FIND", 0
    75 0000C904 5245414446494C4500  <1> Cmd_ReadFile:	db "READFILE", 0
    76 0000C90D 4543484F00          <1> Cmd_Echo:	db "ECHO", 0
    77 0000C912 2A00                <1> Cmd_Remark:	db "*", 0
    78 0000C914 3F00                <1> Cmd_Help:	db "?", 0
    79 0000C916 44455649434500      <1> Cmd_Device:	db "DEVICE", 0
    80 0000C91D 4445564C49535400    <1> Cmd_DevList:	db "DEVLIST", 0
    81 0000C925 434844495200        <1> Cmd_Chdir:	db "CHDIR", 0
    82 0000C92B 4245455000          <1> Cmd_Beep:	db "BEEP", 0
    83                              <1> 		
    84 0000C930 00                  <1> 		db 0
    85                              <1> 
    86                              <1> ; 15/02/2016 (FILE.ASM, 09/10/2011)
    87                              <1> invalid_fname_chars:
    88 0000C931 222728292A2B2C2F    <1> 		db 22h, 27h, 28h, 29h, 2Ah, 2Bh, 2Ch, 2Fh
    89 0000C939 3A3B3C3D3E3F40      <1> 		db 3Ah, 3Bh, 3Ch, 3Dh, 3Eh, 3Fh, 40h
    90 0000C940 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 0000C945 456E746572206E6577- <1>                 db 'Enter new date (dd-mm-yy): '
    95 0000C94E 206461746520286464- <1>
    95 0000C957 2D6D6D2D7979293A20  <1>
    96 0000C960 00                  <1>                 db 0
    97                              <1> Msg_Show_Date:
    98 0000C961 43757272656E742064- <1>                 db   'Current date is '
    98 0000C96A 61746520697320      <1>
    99 0000C971 30                  <1> Day:            db   '0'
   100 0000C972 30                  <1> 		db   '0'
   101 0000C973 2F                  <1>                 db   '/'
   102 0000C974 30                  <1> Month:          db   '0'
   103 0000C975 30                  <1> 		db   '0'
   104 0000C976 2F                  <1>                 db   '/'
   105 0000C977 30                  <1> Century:        db   '0'
   106 0000C978 30                  <1>                 db   '0'
   107 0000C979 30                  <1> Year:           db   '0'
   108 0000C97A 30                  <1> 		db   '0'
   109 0000C97B 0D0A00              <1>                 db   0Dh, 0Ah, 0
   110                              <1> 
   111                              <1> Msg_Enter_Time:
   112 0000C97E 456E746572206E6577- <1> 		db 'Enter new time: '
   112 0000C987 2074696D653A20      <1>
   113 0000C98E 00                  <1> 		db 0
   114                              <1> Msg_Show_Time:
   115 0000C98F 43757272656E742074- <1> 		db   'Current time is '
   115 0000C998 696D6520697320      <1>
   116 0000C99F 30                  <1> Hour:           db   '0'
   117 0000C9A0 30                  <1> 		db   '0'
   118 0000C9A1 3A                  <1> 		db   ':'
   119 0000C9A2 30                  <1> Minute:         db   '0'
   120 0000C9A3 30                  <1> 		db   '0'
   121 0000C9A4 3A                  <1> 		db   ':'
   122 0000C9A5 30                  <1> Second:         db   '0'
   123 0000C9A6 30                  <1> 		db   '0'
   124 0000C9A7 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 0000C9AA 206B696C6F62797465- <1> 		db " kilobytes", 0Dh, 0Ah, 0
   130 0000C9B3 730D0A00            <1>
   131                              <1> VolSize_Bytes:
   132 0000C9B7 2062797465730D0A00  <1> 		db " bytes", 0Dh, 0Ah, 0
   133                              <1> Volume_in_drive:
   134 0000C9C0 0D0A                <1> 		db 0Dh, 0Ah
   135                              <1> Vol_FS_Name:
   136 0000C9C2 54522046533120      <1> 		db "TR FS1 "
   137 0000C9C9 566F6C756D6520696E- <1> 		db "Volume in drive "
   137 0000C9D2 20647269766520      <1>
   138 0000C9D9 30                  <1> Vol_Drv_Name:   db 30h
   139 0000C9DA 3A                  <1> 		db ":"
   140 0000C9DB 20697320            <1> 		db " is "
   141 0000C9DF 0D0A00              <1> 		db 0Dh, 0Ah, 0
   142                              <1> Dir_Drive_Str:
   143 0000C9E2 54522D444F53204472- <1>                 db "TR-DOS Drive "
   143 0000C9EB 69766520            <1>
   144                              <1> Dir_Drive_Name:
   145 0000C9EF 303A                <1>                 db "0:"
   146 0000C9F1 0D0A                <1>                 db  0Dh, 0Ah
   147                              <1> Vol_Str_Header:
   148 0000C9F3 566F6C756D65204E61- <1>                 db "Volume Name: "
   148 0000C9FC 6D653A20            <1>
   149                              <1> Vol_Name:
   150 0000CA00 00<rept>            <1> 		times 64 db 0
   151 0000CA40 00                  <1> 		db 0
   152                              <1> Vol_Serial_Header:
   153 0000CA41 0D0A                <1> 		db 0Dh, 0Ah
   154 0000CA43 566F6C756D65205365- <1> 		db "Volume Serial No: "
   154 0000CA4C 7269616C204E6F3A20  <1>
   155                              <1> Vol_Serial1:
   156 0000CA55 30303030            <1> 		db "0000"
   157 0000CA59 2D                  <1> 		db "-"
   158                              <1> Vol_Serial2:
   159 0000CA5A 30303030            <1> 		db "0000"
   160 0000CA5E 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 0000CA61 0D0A                <1> 		db 0Dh, 0Ah
   166 0000CA63 566F6C756D65205369- <1> 		db "Volume Size : ", 0
   166 0000CA6C 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 0000CA72 467265652053706163- <1> 		db "Free Space  : ", 0
   174 0000CA7B 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 0000CA81 4469726563746F7279- <1>                 db "Directory: "
   181 0000CA8A 3A20                <1>
   182 0000CA8C 2F                  <1> Dir_Str_Root:   db "/"
   183 0000CA8D 00<rept>            <1> Dir_Str:        times 64 db 0
   184 0000CACD 00000000            <1>                 dd 0
   185 0000CAD1 00                  <1>                 db 0
   186                              <1> 
   187                              <1> Msg_Bad_Command:
   188 0000CAD2 42616420636F6D6D61- <1>                 db "Bad command or file name!"
   188 0000CADB 6E64206F722066696C- <1>
   188 0000CAE4 65206E616D6521      <1>
   189 0000CAEB 0D0A00              <1>                 db 0Dh, 0Ah, 0
   190                              <1> 
   191                              <1> msgl_drv_not_ready: 
   192 0000CAEE 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 0000CAF1 4472697665206E6F74- <1>                 db "Drive not ready or read error!"
   197 0000CAFA 207265616479206F72- <1>
   197 0000CB03 207265616420657272- <1>
   197 0000CB0C 6F7221              <1>
   198 0000CB0F 0D0A00              <1>                 db 0Dh, 0Ah, 0
   199                              <1> 
   200                              <1> Msg_Not_Ready_Write_Err:
   201 0000CB12 4472697665206E6F74- <1>                 db "Drive not ready or write error!"
   201 0000CB1B 207265616479206F72- <1>
   201 0000CB24 207772697465206572- <1>
   201 0000CB2D 726F7221            <1>
   202 0000CB31 0D0A00              <1>                 db 0Dh, 0Ah, 0
   203                              <1> 
   204                              <1> Msg_Dir_Not_Found:
   205 0000CB34 4469726563746F7279- <1>                 db "Directory not found!"
   205 0000CB3D 206E6F7420666F756E- <1>
   205 0000CB46 6421                <1>
   206 0000CB48 0D0A00              <1>                 db 0Dh, 0Ah, 0
   207                              <1> 
   208                              <1> Msg_File_Not_Found:
   209 0000CB4B 46696C65206E6F7420- <1>                 db "File not found!"
   209 0000CB54 666F756E6421        <1>
   210 0000CB5A 0D0A00              <1>                 db 0Dh, 0Ah, 0
   211                              <1> 
   212                              <1> Msg_File_Directory_Not_Found:
   213 0000CB5D 46696C65206F722064- <1>                 db "File or directory not found!"
   213 0000CB66 69726563746F727920- <1>
   213 0000CB6F 6E6F7420666F756E64- <1>
   213 0000CB78 21                  <1>
   214 0000CB79 0D0A00              <1>                 db 0Dh, 0Ah, 0
   215                              <1> 
   216                              <1> Msg_LongName_Not_Found:
   217 0000CB7C 4C6F6E67206E616D65- <1>                 db "Long name not found!"
   217 0000CB85 206E6F7420666F756E- <1>
   217 0000CB8E 6421                <1>
   218 0000CB90 0D0A00              <1>                 db 0Dh, 0Ah, 0
   219                              <1> 
   220                              <1> Msg_Insufficient_Memory:
   221 0000CB93 496E73756666696369- <1>                 db "Insufficient memory!"
   221 0000CB9C 656E74206D656D6F72- <1>
   221 0000CBA5 7921                <1>
   222 0000CBA7 0D0A00              <1>                 db 0Dh, 0Ah, 0
   223                              <1> 
   224                              <1> Msg_Error_Code:
   225 0000CBAA 436F6D6D616E642066- <1>                 db 'Command failed! Error code : '
   225 0000CBB3 61696C656421204572- <1>
   225 0000CBBC 726F7220636F646520- <1>
   225 0000CBC5 3A20                <1>
   226 0000CBC7 303068              <1> error_code_hex: db '00h'
   227 0000CBCA 0A0A00              <1>                 db 0Ah, 0Ah, 0
   228                              <1> 
   229 0000CBCD 90                  <1> align 2
   230                              <1> 
   231                              <1> ; 10/02/2016
   232                              <1> ; DIR.ASM - 09/10/2011
   233                              <1> 
   234 0000CBCE 3C4449523E20202020- <1> Type_Dir:       db '<DIR>     ' ; 10 bytes
   234 0000CBD7 20                  <1>
   235                              <1> 
   236                              <1> File_Name:
   237 0000CBD8 20<rept>            <1>                 times 12 db 20h
   238 0000CBE4 20                  <1> 		db 20h
   239                              <1> Dir_Or_FileSize:
   240 0000CBE5 20<rept>            <1>                 times 10 db 20h
   241 0000CBEF 20                  <1> 		db 20h
   242                              <1> File_Attribute:
   243 0000CBF0 20202020            <1> 		dd 20202020h
   244 0000CBF4 20                  <1> 		db 20h
   245                              <1> File_Day:
   246 0000CBF5 3030                <1>                 db '0','0'
   247 0000CBF7 2F                  <1> 		db '/'
   248                              <1> File_Month:
   249 0000CBF8 3030                <1>                 db '0','0'
   250 0000CBFA 2F                  <1> 		db '/'
   251                              <1> File_Year:
   252 0000CBFB 30303030            <1>                 db '0','0','0','0'
   253 0000CBFF 20                  <1> 		db 20h
   254                              <1> File_Hour:
   255 0000CC00 3030                <1>                 db '0','0'
   256 0000CC02 3A                  <1> 		db ':'
   257                              <1> File_Minute:
   258 0000CC03 3030                <1>                 db '0','0'
   259 0000CC05 00                  <1> 		db 0
   260                              <1> 
   261                              <1> Decimal_File_Count_Header:
   262 0000CC06 0D0A                <1> 		db 0Dh, 0Ah
   263                              <1> Decimal_File_Count:
   264 0000CC08 00<rept>            <1> 		times 6 db 0
   265                              <1> 
   266 0000CC0E 2066696C6528732920- <1> str_files:	db " file(s) & "
   266 0000CC17 2620                <1>
   267                              <1> Decimal_Dir_Count: 
   268 0000CC19 00<rept>            <1> 		times 6 db 0
   269                              <1> str_dirs:       
   270 0000CC1F 206469726563746F72- <1> 		db " directory(s) "
   270 0000CC28 7928732920          <1>
   271 0000CC2D 0D0A00              <1> 		db 0Dh, 0Ah, 0
   272                              <1> 
   273 0000CC30 206279746528732920- <1> str_bytes:	db " byte(s) in file(s)"
   273 0000CC39 696E2066696C652873- <1>
   273 0000CC42 29                  <1>
   274 0000CC43 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 0000CC46 496E76616C69642066- <1>                 db "Invalid file or directory name characters!"
   279 0000CC4F 696C65206F72206469- <1>
   279 0000CC58 726563746F7279206E- <1>
   279 0000CC61 616D65206368617261- <1>
   279 0000CC6A 637465727321        <1>
   280 0000CC70 0D0A00              <1>         	db 0Dh, 0Ah, 0
   281                              <1> ; 21/02/2016
   282 0000CC73 46696C65206F722064- <1> Msg_Name_Exists: db "File or directory name exists!"
   282 0000CC7C 69726563746F727920- <1>
   282 0000CC85 6E616D652065786973- <1>
   282 0000CC8E 747321              <1>
   283 0000CC91 0D0A00              <1>                 db 0Dh, 0Ah, 0
   284                              <1> Msg_DoYouWantMkdir:
   285 0000CC94 446F20796F75207761- <1>                 db "Do you want to make directory ", 0
   285 0000CC9D 6E7420746F206D616B- <1>
   285 0000CCA6 65206469726563746F- <1>
   285 0000CCAF 72792000            <1>
   286 0000CCB3 2028592F4E29203F20- <1> Msg_YesNo:      db " (Y/N) ? ", 0  
   286 0000CCBC 00                  <1>
   287 0000CCBD 000D0A00            <1> Y_N_nextline:	db 0, 0Dh, 0Ah, 0 
   288 0000CCC1 4F4B2E0D0A00        <1> Msg_OK:		db "OK.", 0Dh, 0Ah, 0
   289                              <1> 
   290                              <1> ; 27/02/2016
   291                              <1> Msg_DoYouWantRmDir:
   292 0000CCC7 446F20796F75207761- <1>                 db "Do you want to delete directory ", 0
   292 0000CCD0 6E7420746F2064656C- <1>
   292 0000CCD9 657465206469726563- <1>
   292 0000CCE2 746F72792000        <1>
   293                              <1> Msg_Dir_Not_Empty:
   294 0000CCE8 4469726563746F7279- <1>                 db "Directory not empty!"
   294 0000CCF1 206E6F7420656D7074- <1>
   294 0000CCFA 7921                <1>
   295 0000CCFC 0D0A00              <1>                 db 0Dh, 0Ah, 0
   296                              <1> 
   297                              <1> Msg_DoYouWantDelete:
   298 0000CCFF 446F20796F75207761- <1>                 db "Do you want to delete file ",0
   298 0000CD08 6E7420746F2064656C- <1>
   298 0000CD11 6574652066696C6520- <1>
   298 0000CD1A 00                  <1>
   299                              <1> 
   300 0000CD1B 44656C657465642E2E- <1> Msg_Deleted:    db "Deleted...", 0Dh, 0Ah, 0
   300 0000CD24 2E0D0A00            <1>
   301                              <1> 
   302                              <1> Msg_Permission_Denied:
   303 0000CD28 07                  <1>                 db 7
   304 0000CD29 5065726D697373696F- <1>                 db "Permission denied!", 0Dh, 0Ah, 0
   304 0000CD32 6E2064656E69656421- <1>
   304 0000CD3B 0D0A00              <1>
   305                              <1> 
   306                              <1> ; 04/03/2016
   307 0000CD3E 4E657720            <1> Msg_New:        db "New "
   308 0000CD42 00                  <1>                 db 0
   309                              <1> Str_Attributes:
   310 0000CD43 417474726962757465- <1>                 db "Attributes : "
   310 0000CD4C 73203A20            <1>
   311 0000CD50 4E4F524D414C        <1> Attr_Chars:     db "NORMAL"
   312 0000CD56 00                  <1>                 db 0
   313                              <1> 
   314                              <1> ; 06/03/2016
   315                              <1> ; CMD_INTR.ASM - 16/11/2010 
   316                              <1> Msg_DoYouWantRename:
   317 0000CD57 446F20796F75207761- <1>                 db "Do you want to rename ", 0
   317 0000CD60 6E7420746F2072656E- <1>
   317 0000CD69 616D652000          <1>
   318 0000CD6E 66696C652000        <1> Rename_File:    db "file ", 0
   319 0000CD74 6469726563746F7279- <1> Rename_Directory: db "directory ", 0
   319 0000CD7D 2000                <1>
   320 0000CD7F 00<rept>            <1> Rename_OldName: times 13 db 0
   321 0000CD8C 20617320            <1> Msg_File_rename_as: db " as "
   322 0000CD90 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 0000CD9D 4E6F742073616D6520- <1>                 db "Not same drive!" 
   327 0000CDA6 647269766521        <1>
   328 0000CDAC 0D0A00              <1>                 db 0Dh, 0Ah, 0 
   329                              <1> 
   330                              <1> Msg_DoYouWantMoveFile:
   331 0000CDAF 446F20796F75207761- <1>                 db "Do you want to move file", 0
   331 0000CDB8 6E7420746F206D6F76- <1>
   331 0000CDC1 652066696C6500      <1>
   332                              <1> 
   333                              <1> msg_insufficient_disk_space:
   334 0000CDC8 496E73756666696369- <1>                 db "Insufficient disk space!" 
   334 0000CDD1 656E74206469736B20- <1>
   334 0000CDDA 737061636521        <1>
   335 0000CDE0 0D0A00              <1>                 db 0Dh, 0Ah, 0
   336                              <1> 
   337                              <1> ; 01/08/2010
   338                              <1> msg_source_file: 
   339 0000CDE3 0D0A536F7572636520- <1> 		db 0Dh, 0Ah, "Source file name      :   "
   339 0000CDEC 66696C65206E616D65- <1>
   339 0000CDF5 2020202020203A2020- <1>
   339 0000CDFE 20                  <1>
   340                              <1> msg_source_file_drv: 
   341 0000CDFF 203A00              <1> 		db " :", 0
   342                              <1> msg_destination_file: 
   343 0000CE02 0D0A44657374696E61- <1> 		db 0Dh, 0Ah, "Destination file name :   "
   343 0000CE0B 74696F6E2066696C65- <1>
   343 0000CE14 206E616D65203A2020- <1>
   343 0000CE1D 20                  <1>
   344                              <1> msg_destination_file_drv: 
   345 0000CE1E 203A00              <1> 		db " :", 0
   346                              <1> msg_copy_nextline: 
   347 0000CE21 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 0000CE24 446F20796F75207761- <1>                 db "Do you want to overwrite file ",0
   353 0000CE2D 6E7420746F206F7665- <1>
   353 0000CE36 727772697465206669- <1>
   353 0000CE3F 6C652000            <1>
   354                              <1>   
   355                              <1> Msg_DoYouWantCopyFile:
   356 0000CE43 446F20796F75207761- <1>                 db "Do you want to copy file",0
   356 0000CE4C 6E7420746F20636F70- <1>
   356 0000CE55 792066696C6500      <1>
   357                              <1> 
   358                              <1> Msg_read_file_error_before_EOF:
   359 0000CE5C 46696C652072656164- <1> 		db "File reading error! (before EOF)"
   359 0000CE65 696E67206572726F72- <1>
   359 0000CE6E 2120286265666F7265- <1>
   359 0000CE77 20454F4629          <1>
   360 0000CE7C 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 0000CE7F 52656164696E672E2E- <1> 		db "Reading... ", 0
   365 0000CE88 2E2000              <1>
   366                              <1> msg_writing:
   367 0000CE8B 57726974696E672E2E- <1> 		db "Writing... ", 0
   367 0000CE94 2E2000              <1>
   368                              <1> percentagestr:
   369 0000CE97 2020202500          <1> 		db "   %", 0  ; "  0%" .. "100%"
   370                              <1> ; 11/04/2016
   371                              <1> Msg_No_Set_Space:
   372 0000CE9C 496E73756666696369- <1>                 db "Insufficient environment space!"
   372 0000CEA5 656E7420656E766972- <1>
   372 0000CEAE 6F6E6D656E74207370- <1>
   372 0000CEB7 61636521            <1>
   373 0000CEBB 0D0A00              <1>                 db 0Dh, 0Ah, 0
   374                              <1> ; 18/04/2016
   375                              <1> isc_msg:	
   376 0000CEBE 0D0A                <1> 		db 0Dh, 0Ah
   377 0000CEC0 494E56414C49442053- <1> 		db "INVALID SYSTEM CALL", 0
   377 0000CEC9 595354454D2043414C- <1>
   377 0000CED2 4C00                <1>
   378                              <1> usi_msg:
   379 0000CED4 0D0A                <1> 		db 0Dh, 0Ah
   380 0000CED6 554E444546494E4544- <1> 		db "UNDEFINED SOFTWARE INTERRUPT", 0
   380 0000CEDF 20534F465457415245- <1>
   380 0000CEE8 20494E544552525550- <1>
   380 0000CEF1 5400                <1>
   381                              <1> ifc_msg:
   382 0000CEF3 0D0A                <1> 		db 0Dh, 0Ah
   383 0000CEF5 494E56414C49442046- <1> 		db "INVALID FUNCTION CALL"
   383 0000CEFE 554E4354494F4E2043- <1>
   383 0000CF07 414C4C              <1>
   384                              <1> inv_msg_for_trdos_v2:
   385 0000CF0A 20                  <1> 		db 20h
   386 0000CF0B 666F72205452444F53- <1> 		db "for TRDOS v2!"
   386 0000CF14 20763221            <1>
   387 0000CF18 07                  <1> 		db 07h
   388 0000CF19 0D0A                <1> 		db 0Dh, 0Ah
   389 0000CF1B 0D0A                <1> 		db 0Dh, 0Ah
   390 0000CF1D 494E5420            <1> 		db "INT "
   391 0000CF21 303068              <1> int_num_str:	db "00h"
   392 0000CF24 0D0A                <1> 		db 0Dh, 0Ah
   393 0000CF26 454158203A20        <1> 		db "EAX : "
   394 0000CF2C 303030303030303068- <1> eax_str:	db "00000000h", 0Dh, 0Ah
   394 0000CF35 0D0A                <1>
   395 0000CF37 454950203A20        <1> 		db "EIP : "
   396 0000CF3D 303030303030303068- <1> eip_str:	db "00000000h", 0Dh, 0Ah, 0
   396 0000CF46 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 0000CF49 8B1C24                  	mov	ebx, [esp] ; EIP (next)
  1928 0000CF4C 83EB02                  	sub	ebx, 2 ; EIP (CD ##h)
  1929                                  
  1930 0000CF4F 89C1                    	mov	ecx, eax
  1931 0000CF51 8A4301                  	mov	al, [ebx+1] ; CDh ##h
  1932                                  
  1933 0000CF54 66BA1000                	mov	dx, KDATA
  1934 0000CF58 8EDA                    	mov	ds, dx
  1935 0000CF5A 8EC2                    	mov	es, dx
  1936                                  
  1937 0000CF5C FC                      	cld
  1938 0000CF5D 8B15[F8DC0000]          	mov	edx, [k_page_dir]
  1939 0000CF63 0F22DA                  	mov	cr3, edx
  1940                                  
  1941 0000CF66 E88D4FFFFF              	call	bytetohex
  1942 0000CF6B 66A3[21CF0000]          	mov	[int_num_str], ax
  1943                                  
  1944 0000CF71 89D8                    	mov	eax, ebx ; EIP
  1945 0000CF73 E8C04FFFFF              	call	dwordtohex
  1946 0000CF78 8915[3DCF0000]          	mov	[eip_str], edx
  1947 0000CF7E A3[41CF0000]            	mov	[eip_str+4], eax
  1948                                  
  1949 0000CF83 89C8                    	mov	eax, ecx
  1950 0000CF85 E8AE4FFFFF              	call	dwordtohex
  1951 0000CF8A 8915[2CCF0000]          	mov	[eax_str], edx
  1952 0000CF90 A3[30CF0000]            	mov	[eax_str+4], eax 	
  1953                                  
  1954 0000CF95 43                      	inc	ebx
  1955 0000CF96 8A03                    	mov	al, [ebx] ; Interrupt number
  1956                                  
  1957                                  trdos_isc_handler:
  1958 0000CF98 80FE30                  	cmp	dh, 30h ; Retro UNIX, SINGLIX System calls
  1959 0000CF9B 7507                    	jne	short trdos_usi_handler
  1960 0000CF9D BE[BECE0000]            	mov	esi, isc_msg
  1961 0000CFA2 EB05                    	jmp	short loc_write_inv_system_call_msg
  1962                                  
  1963                                  trdos_usi_handler:
  1964 0000CFA4 BE[D4CE0000]            	mov	esi, usi_msg
  1965                                  
  1966                                  loc_write_inv_system_call_msg:
  1967 0000CFA9 E89276FFFF              	call	print_msg
  1968                                  	; 29/04/2016
  1969 0000CFAE BE[0ACF0000]            	mov	esi, inv_msg_for_trdos_v2
  1970 0000CFB3 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 0000CFB8 FE05[CDF10000]          	inc	byte [sysflg] ; 0FFh -> 0
  1978                                  
  1979 0000CFBE B801000000              	mov	eax, 1
  1980 0000CFC3 E954D8FFFF              	jmp	sysexit
  1981                                  
  1982                                  ; 07/03/2015
  1983                                  ; Temporary Code
  1984                                  display_disks:
  1985 0000CFC8 803D[0AD80000]00        	cmp 	byte [fd0_type], 0
  1986 0000CFCF 7605                    	jna 	short ddsks1
  1987 0000CFD1 E87D000000              	call	pdskm
  1988                                  ddsks1:
  1989 0000CFD6 803D[0BD80000]00        	cmp	byte [fd1_type], 0
  1990 0000CFDD 760C                    	jna	short ddsks2
  1991 0000CFDF C605[8BD90000]31        	mov	byte [dskx], '1'
  1992 0000CFE6 E868000000              	call	pdskm
  1993                                  ddsks2:
  1994 0000CFEB 803D[0CD80000]00        	cmp	byte [hd0_type], 0
  1995 0000CFF2 7654                    	jna	short ddsk6
  1996 0000CFF4 66C705[89D90000]68-     	mov	word [dsktype], 'hd'
  1996 0000CFFC 64                 
  1997 0000CFFD C605[8BD90000]30        	mov	byte [dskx], '0'
  1998 0000D004 E84A000000              	call	pdskm
  1999                                  ddsks3:
  2000 0000D009 803D[0DD80000]00        	cmp	byte [hd1_type], 0
  2001 0000D010 7636                    	jna	short ddsk6
  2002 0000D012 C605[8BD90000]31        	mov	byte [dskx], '1'
  2003 0000D019 E835000000              	call	pdskm
  2004                                  ddsks4:
  2005 0000D01E 803D[0ED80000]00        	cmp	byte [hd2_type], 0
  2006 0000D025 7621                    	jna	short ddsk6
  2007 0000D027 C605[8BD90000]32        	mov	byte [dskx], '2'
  2008 0000D02E E820000000              	call	pdskm
  2009                                  ddsks5:
  2010 0000D033 803D[0FD80000]00        	cmp	byte [hd3_type], 0
  2011 0000D03A 760C                    	jna	short ddsk6
  2012 0000D03C C605[8BD90000]33        	mov	byte [dskx], '3'
  2013 0000D043 E80B000000              	call	pdskm
  2014                                  ddsk6:
  2015 0000D048 BE[9CD90000]            	mov	esi, nextline
  2016 0000D04D E806000000              	call	pdskml
  2017                                  pdskm_ok:
  2018 0000D052 C3                      	retn
  2019                                  pdskm:
  2020 0000D053 BE[87D90000]            	mov	esi, dsk_ready_msg
  2021                                  pdskml:	
  2022 0000D058 AC                      	lodsb
  2023 0000D059 08C0                    	or	al, al
  2024 0000D05B 74F5                    	jz	short pdskm_ok
  2025 0000D05D 56                      	push	esi
  2026                                  	; 13/05/2016
  2027 0000D05E BB07000000                      mov     ebx, 7  ; Black background, 
  2028                                  			; light gray forecolor
  2029                                  			; Video page 0 (bh=0)
  2030 0000D063 E88748FFFF              	call	_write_tty
  2031 0000D068 5E                      	pop	esi
  2032 0000D069 EBED                    	jmp	short pdskml
  2033                                  
  2034 0000D06B 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 0000D070 0000000000000000        	dw 0, 0, 0, 0		; NULL descriptor
  2044                                  	; 18/08/2014
  2045                                  			; 8h kernel code segment, base = 00000000h		
  2046 0000D078 FFFF0000009ACF00        	dw 0FFFFh, 0, 9A00h, 00CFh	; KCODE
  2047                                  			; 10h kernel data segment, base = 00000000h	
  2048 0000D080 FFFF00000092CF00        	dw 0FFFFh, 0, 9200h, 00CFh	; KDATA
  2049                                  			; 1Bh user code segment, base address = 400000h ; CORE
  2050 0000D088 FFFB000040FACF00        	dw 0FBFFh, 0, 0FA40h, 00CFh	; UCODE 
  2051                                  			; 23h user data segment, base address = 400000h ; CORE
  2052 0000D090 FFFB000040F2CF00        	dw 0FBFFh, 0, 0F240h, 00CFh	; UDATA
  2053                                  			; Task State Segment
  2054 0000D098 6700                    	dw 0067h ; Limit = 103 ; (104-1, tss size = 104 byte, 
  2055                                  			       ;  no IO permission in ring 3)
  2056                                  gdt_tss0:
  2057 0000D09A 0000                    	dw 0  ; TSS base address, bits 0-15 
  2058                                  gdt_tss1:
  2059 0000D09C 00                      	db 0  ; TSS base address, bits 16-23 
  2060                                  	      		; 49h	
  2061 0000D09D E9                      	db 11101001b ; E9h => P=1/DPL=11/0/1/0/B/1 --> B = Task is busy (1)
  2062 0000D09E 00                      	db 0 ; G/0/0/AVL/LIMIT=0000 ; (Limit bits 16-19 = 0000) (G=0, 1 byte)
  2063                                  gdt_tss2:
  2064 0000D09F 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 0000D0A0 2F00                            dw gdt_end - gdt - 1    ; Limit (size)
  2099 0000D0A2 [70D00000]                      dd gdt			; Address of the GDT
  2100                                  
  2101                                  	; 20/08/2014
  2102                                  idtd:
  2103 0000D0A6 7F02                            dw idt_end - idt - 1    ; Limit (size)
  2104 0000D0A8 [10DA0000]                      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 0000D0AC [35080000]              	dd	exc0	; 0h,  Divide-by-zero Error
  2117 0000D0B0 [3C080000]              	dd	exc1	
  2118 0000D0B4 [43080000]              	dd 	exc2	
  2119 0000D0B8 [4A080000]              	dd	exc3	
  2120 0000D0BC [4E080000]              	dd	exc4	
  2121 0000D0C0 [52080000]              	dd	exc5	
  2122 0000D0C4 [56080000]              	dd 	exc6	; 06h,  Invalid Opcode
  2123 0000D0C8 [5A080000]              	dd	exc7	
  2124 0000D0CC [5E080000]              	dd	exc8	
  2125 0000D0D0 [62080000]              	dd	exc9	
  2126 0000D0D4 [66080000]              	dd 	exc10	
  2127 0000D0D8 [6A080000]              	dd	exc11
  2128 0000D0DC [6E080000]              	dd	exc12
  2129 0000D0E0 [72080000]              	dd	exc13	; 0Dh, General Protection Fault
  2130 0000D0E4 [76080000]              	dd 	exc14	; 0Eh, Page Fault
  2131 0000D0E8 [7A080000]              	dd	exc15
  2132 0000D0EC [7E080000]              	dd	exc16
  2133 0000D0F0 [82080000]              	dd	exc17
  2134 0000D0F4 [86080000]              	dd 	exc18
  2135 0000D0F8 [8A080000]              	dd	exc19
  2136 0000D0FC [8E080000]              	dd 	exc20
  2137 0000D100 [92080000]              	dd	exc21
  2138 0000D104 [96080000]              	dd	exc22
  2139 0000D108 [9A080000]              	dd	exc23
  2140 0000D10C [9E080000]              	dd 	exc24
  2141 0000D110 [A2080000]              	dd	exc25
  2142 0000D114 [A6080000]              	dd	exc26
  2143 0000D118 [AA080000]              	dd	exc27
  2144 0000D11C [AE080000]              	dd 	exc28
  2145 0000D120 [B2080000]              	dd	exc29
  2146 0000D124 [B6080000]              	dd 	exc30
  2147 0000D128 [BA080000]              	dd	exc31
  2148                                  	; Interrupt list
  2149 0000D12C [2A060000]              	dd	timer_int	; INT 20h
  2150                                  		;dd	irq0	
  2151 0000D130 [960C0000]              	dd	kb_int		; 24/01/2016
  2152                                  		;dd	irq1
  2153 0000D134 [8B070000]              	dd	irq2
  2154                                  		; COM2 int
  2155 0000D138 [8F070000]              	dd	irq3
  2156                                  		; COM1 int
  2157 0000D13C [9A070000]              	dd	irq4
  2158 0000D140 [A5070000]              	dd	irq5
  2159                                  ;DISKETTE_INT: ;06/02/2015
  2160 0000D144 [DF2D0000]              	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 0000D148 [960A0000]              	dd	default_irq7	; 25/02/2015
  2165                                  		;dd	irq7
  2166                                  ; Real Time Clock Interrupt
  2167 0000D14C [07070000]              	dd	rtc_int		; 23/02/2015, IRQ 8 handler
  2168                                  		;dd	irq8	; INT 28h
  2169 0000D150 [B5070000]              	dd	irq9
  2170 0000D154 [B9070000]              	dd	irq10
  2171 0000D158 [BD070000]              	dd	irq11
  2172 0000D15C [C1070000]              	dd	irq12
  2173 0000D160 [C5070000]              	dd	irq13
  2174                                  ;HDISK_INT1:  ;06/02/2015 	
  2175 0000D164 [59370000]              	dd	hdc1_int 	; 21/02/2015, IRQ 14 handler		
  2176                                  		;dd	irq14
  2177                                  ;HDISK_INT2:  ;06/02/2015
  2178 0000D168 [80370000]              	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 0000D16C [49CF0000]              	dd	int30h		; Reserved for
  2187                                  				; !!! Retro UNIX (RUNIX) !!!
  2188                                  				; !!! SINGLIX !!! System Calls
  2189 0000D170 [89130000]              	dd	int31h		; Video BIOS (IBM PC/AT, Int 10h)
  2190 0000D174 [BE0A0000]              	dd	int32h		; Keyboard Functions (IBM PC/AT, Int 16h)
  2191 0000D178 [962E0000]              	dd	int33h		; DISK I/O (IBM PC/AT, Int 13h)
  2192 0000D17C [E9C50000]              	dd	int34h		; #IOCTL# (I/O port access support for ring 3)
  2193 0000D180 [8A420000]              	dd	int35h		; Time/Date Functions (IBM PC/AT, Int 1Ah)
  2194 0000D184 [8B090000]              	dd	ignore_int	; INT 36h : Timer Functions	
  2195 0000D188 [8B090000]              	dd	ignore_int	; INT 37h	
  2196 0000D18C [8B090000]              	dd	ignore_int	; INT 38h
  2197 0000D190 [8B090000]              	dd	ignore_int	; INT 39h
  2198 0000D194 [8B090000]              	dd	ignore_int	; INT 3Ah	
  2199 0000D198 [8B090000]              	dd	ignore_int	; INT 3Bh
  2200 0000D19C [8B090000]              	dd	ignore_int	; INT 3Ch
  2201 0000D1A0 [8B090000]              	dd	ignore_int	; INT 3Dh	
  2202 0000D1A4 [8B090000]              	dd	ignore_int	; INT 3Eh
  2203 0000D1A8 [8B090000]              	dd	ignore_int	; INT 3Fh
  2204 0000D1AC [0BA60000]              	dd	sysent		; INT 40h : !!! TRDOS 386 System Calls !!!
  2205                                  	;dd	ignore_int
  2206 0000D1B0 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 0000D1B4 524F50514B          <1> K30:	db	82,79,80,81,75
    36 0000D1B9 4C4D474849          <1> 	db	76,77,71,72,73		; 10 NUMBER ON KEYPAD
    37                              <1> ;-----	SUPER-SHIFT-TABLE 
    38 0000D1BE 101112131415        <1> 	db	16,17,18,19,20,21	; A-Z TYPEWRITER CHARS
    39 0000D1C4 161718191E1F        <1> 	db	22,23,24,25,30,31
    40 0000D1CA 202122232425        <1> 	db	32,33,34,35,36,37
    41 0000D1D0 262C2D2E2F30        <1> 	db	38,44,45,46,47,48
    42 0000D1D6 3132                <1> 	db	49,50
    43                              <1> 
    44                              <1> ;-----	TABLE OF SHIFT KEYS AND MASK VALUES
    45                              <1> ;-----	KEY_TABLE 
    46 0000D1D8 52                  <1> _K6:    db      INS_KEY                 ; INSERT KEY
    47 0000D1D9 3A4546381D          <1> 	db	CAPS_KEY,NUM_KEY,SCROLL_KEY,ALT_KEY,CTL_KEY
    48 0000D1DE 2A36                <1>         db      LEFT_KEY,RIGHT_KEY
    49                              <1> _K6L    equ     $-_K6
    50                              <1> 
    51                              <1> ;-----	MASK_TABLE
    52 0000D1E0 80                  <1> _K7:    db      INS_SHIFT               ; INSERT MODE SHIFT
    53 0000D1E1 4020100804          <1> 	db	CAPS_SHIFT,NUM_SHIFT,SCROLL_SHIFT,ALT_SHIFT,CTL_SHIFT
    54 0000D1E6 0201                <1> 	db	LEFT_SHIFT,RIGHT_SHIFT
    55                              <1> 
    56                              <1> ;-----	TABLES FOR CTRL CASE		;---- CHARACTERS ------
    57 0000D1E8 1BFF00FFFFFF        <1> _K8:	db	27,-1,0,-1,-1,-1	; Esc, 1, 2, 3, 4, 5
    58 0000D1EE 1EFFFFFFFF1F        <1> 	db 	30,-1,-1,-1,-1,31	; 6, 7, 8, 9, 0, -
    59 0000D1F4 FF7FFF111705        <1> 	db	-1,127,-1,17,23,5	; =, Bksp, Tab, Q, W, E
    60 0000D1FA 12141915090F        <1> 	db	18,20,25,21,9,15	; R, T, Y, U, I, O
    61 0000D200 101B1D0AFF01        <1> 	db	16,27,29,10,-1,1	; P, [, ], Enter, Ctrl, A
    62 0000D206 13040607080A        <1> 	db	19,4,6,7,8,10		; S, D, F, G, H, J
    63 0000D20C 0B0CFFFFFFFF        <1> 	db	11,12,-1,-1,-1,-1	; K, L, :, ', `, LShift
    64 0000D212 1C1A18031602        <1> 	db	28,26,24,3,22,2		; Bkslash, Z, X, C, V, B
    65 0000D218 0E0DFFFFFFFF        <1> 	db	14,13,-1,-1,-1,-1	; N, M, ,, ., /, RShift
    66 0000D21E 96FF20FF            <1> 	db	150,-1,' ',-1		; *, ALT, Spc, CL
    67                              <1> 	;				;----- FUNCTIONS ------		
    68 0000D222 5E5F60616263        <1> 	db 	94,95,96,97,98,99	; F1 - F6
    69 0000D228 64656667FFFF        <1> 	db	100,101,102,103,-1,-1	; F7 - F10, NL, SL
    70 0000D22E 778D848E738F        <1> 	db	119,141,132,142,115,143	; Home, Up, PgUp, -, Left, Pad5
    71 0000D234 749075917692        <1> 	db 	116,144,117,145,118,146 ; Right, +, End, Down, PgDn, Ins
    72 0000D23A 93FFFFFF898A        <1> 	db	147,-1,-1,-1,137,138	; Del, SysReq, Undef, WT, F11, F12
    73                              <1> 
    74                              <1> ;-----	TABLES FOR LOWER CASE ----------
    75 0000D240 1B3132333435363738- <1> K10:	db 	27,'1234567890-=',8,9
    75 0000D249 39302D3D0809        <1>
    76 0000D24F 71776572747975696F- <1> 	db 	'qwertyuiop[]',13,-1,'asdfghjkl;',39
    76 0000D258 705B5D0DFF61736466- <1>
    76 0000D261 67686A6B6C3B27      <1>
    77 0000D268 60FF5C7A786376626E- <1> 	db	96,-1,92,'zxcvbnm,./',-1,'*',-1,' ',-1
    77 0000D271 6D2C2E2FFF2AFF20FF  <1>
    78                              <1> ;-----	LC TABLE SCAN
    79 0000D27A 3B3C3D3E3F          <1> 	db	59,60,61,62,63		; BASE STATE OF F1 - F10
    80 0000D27F 4041424344          <1> 	db	64,65,66,67,68
    81 0000D284 FFFF                <1> 	db	-1,-1			; NL, SL
    82                              <1> 
    83                              <1> ;-----	KEYPAD TABLE
    84 0000D286 474849FF4BFF        <1> K15:	db	71,72,73,-1,75,-1	; BASE STATE OF KEYPAD KEYS
    85 0000D28C 4DFF4F50515253      <1> 	db	77,-1,79,80,81,82,83
    86 0000D293 FFFF5C8586          <1> 	db	-1,-1,92,133,134	; SysRq, Undef, WT, F11, F12
    87                              <1> 
    88                              <1> ;-----	TABLES FOR UPPER CASE ----------
    89 0000D298 1B21402324255E262A- <1> K11:	db 	27,'!@#$%',94,'&*()_+',8,0
    89 0000D2A1 28295F2B0800        <1>
    90 0000D2A7 51574552545955494F- <1> 	db 	'QWERTYUIOP{}',13,-1,'ASDFGHJKL:"'
    90 0000D2B0 507B7D0DFF41534446- <1>
    90 0000D2B9 47484A4B4C3A22      <1>
    91 0000D2C0 7EFF7C5A584356424E- <1> 	db	126,-1,'|ZXCVBNM<>?',-1,'*',-1,' ',-1
    91 0000D2C9 4D3C3E3FFF2AFF20FF  <1>
    92                              <1> ;-----	UC TABLE SCAN
    93 0000D2D2 5455565758          <1> K12:	db	84,85,86,87,88		; SHIFTED STATE OF F1 - F10
    94 0000D2D7 595A5B5C5D          <1> 	db	89,90,91,92,93
    95 0000D2DC FFFF                <1> 	db	-1,-1			; NL, SL
    96                              <1> 
    97                              <1> ;-----	NUM STATE TABLE
    98 0000D2DE 3738392D3435362B31- <1> K14:	db 	'789-456+1230.'		; NUMLOCK STATE OF KEYPAD KEYS
    98 0000D2E7 3233302E            <1>
    99                              <1> 	;
   100 0000D2EB 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 0000D2F0 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 0000D2F1 00                  <1> KB_FLAG		db	0		; KEYBOARD SHIFT STATE AND STATUS FLAGS
   118 0000D2F2 00                  <1> KB_FLAG_1	db	0		; SECOND BYTE OF KEYBOARD STATUS
   119 0000D2F3 00                  <1> KB_FLAG_2	db	0		; KEYBOARD LED FLAGS
   120 0000D2F4 00                  <1> KB_FLAG_3	db	0		; KEYBOARD MODE STATE AND TYPE FLAGS
   121 0000D2F5 00                  <1> ALT_INPUT	db	0		; STORAGE FOR ALTERNATE KEY PAD ENTRY
   122 0000D2F6 [06D30000]          <1> BUFFER_START	dd	KB_BUFFER 	; OFFSET OF KEYBOARD BUFFER START
   123 0000D2FA [26D30000]          <1> BUFFER_END	dd	KB_BUFFER + 32	; OFFSET OF END OF BUFFER
   124 0000D2FE [06D30000]          <1> BUFFER_HEAD	dd	KB_BUFFER 	; POINTER TO HEAD OF KEYBOARD BUFFER
   125 0000D302 [06D30000]          <1> BUFFER_TAIL	dd	KB_BUFFER 	; POINTER TO TAIL OF KEYBOARD BUFFER
   126                              <1> ; ------	HEAD = TAIL	INDICATES THAT THE BUFFER IS EMPTY
   127 0000D306 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: 01/07/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> ;----------------------------------------
    26                              <1> ;	VIDEO DISPLAY DATA AREA		;
    27                              <1> ;----------------------------------------
    28 0000D326 03                  <1> CRT_MODE:	db	3	; CURRENT DISPLAY MODE (TYPE)
    29 0000D327 29                  <1> CRT_MODE_SET:	db	29h	; CURRENT SETTING OF THE 3X8 REGISTER
    30                              <1> 				; (29h default setting for video mode 3)
    31                              <1> 				; Mode Select register Bits
    32                              <1> 				;   BIT 0 - 80x25 (1), 40x25 (0)
    33                              <1> 				;   BIT 1 - ALPHA (0), 320x200 GRAPHICS (1)
    34                              <1> 				;   BIT 2 - COLOR (0), BW (1)
    35                              <1> 				;   BIT 3 - Video Sig. ENABLE (1), DISABLE (0)
    36                              <1> 				;   BIT 4 - 640x200 B&W Graphics Mode (1)
    37                              <1> 				;   BIT 5 - ALPHA mode BLINKING (1)
    38                              <1> 				;   BIT 6, 7 - Not Used
    39                              <1> 
    40                              <1> ; Mode 0 - 2Ch = 101100b	; 40x25 text, 16 gray colors
    41                              <1> ; Mode 1 - 28h = 101000b	; 40x25 text, 16 fore colors, 8 back colors
    42                              <1> ; Mode 2 - 2Dh = 101101b	; 80x25 text, 16 gray colors	
    43                              <1> ; Mode 3 - 29h = 101001b	; 80x25 text, 16 fore color, 8 back color
    44                              <1> ; Mode 4 - 2Ah = 101010b	; 320x200 graphics, 4 colors
    45                              <1> ; Mode 5 - 2Eh = 101110b	; 320x200 graphics, 4 gray colors
    46                              <1> ; Mode 6 - 1Eh = 011110b	; 640x200 graphics, 2 colors
    47                              <1> ; Mode 7 - 29h = 101001b	; 80x25 text, black & white colors
    48                              <1> ; Mode & 37h = Video signal OFF
    49                              <1> 
    50                              <1> ; 24/06/2016
    51 0000D328 50                  <1> CRT_COLS:	db	80	; Number of columns
    52                              <1> 
    53                              <1> ; 01/07/2016
    54 0000D329 00                  <1> CRT_PALETTE:	db 	0	; Current palette setting
    55                              <1> 			
    56                              <1> video_params:
    57                              <1> 	; 01/07/2016 - TRDOS 386 (TRDOS v2.0)
    58                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
    59                              <1> 	;ORGS.ASM ----- 06/10/85   COMPATIBILITY MODULE
    60                              <1> 
    61 0000D32A 38282D0A1F0619      <1> 	DB	38H,28H,2DH,0AH,1FH,6,19H	; SET UP FOR 40X25
    62 0000D331 1C02070607          <1> 	DB	1CH,2,7,6,7
    63 0000D336 00000000            <1> 	DB	0,0,0,0
    64                              <1> _M4	EQU	$-video_params
    65                              <1> 
    66 0000D33A 71505A0A1F0619      <1> 	DB	71H,50H,5AH,0AH,1FH,6,19H	; SET UP FOR 80X25
    67 0000D341 1C02070607          <1> 	DB	1CH,2,7,6,7
    68 0000D346 00000000            <1> 	DB	0,0,0,0
    69                              <1> 
    70 0000D34A 38282D0A7F0664      <1> 	DB	38H,28H,2DH,0AH,7FH,6,64H	; SETUP FOR GRAPHICS
    71 0000D351 7002010607          <1> 	DB	70H,2,1,6,7
    72 0000D356 00000000            <1> 	DB	0,0,0,0
    73                              <1> 
    74                              <1> 	;DB	61H,50H,52H,0FH,19H,6,19H	; SETUP FOR 80X25 B&W CARD
    75                              <1> 	;DB	19H,2,0DH,0BH,0CH
    76                              <1> 	;DB	0,0,0,0
    77                              <1> 
    78                              <1> ;-----	TABLE OF REGEN LENGTHS
    79                              <1> M5:
    80 0000D35A 0008                <1> 	dw	2048		; 40X25
    81 0000D35C 0010                <1> 	dw	4096		; 80X25
    82 0000D35E 0040                <1> 	dw	16384		; GRAPHICS
    83 0000D360 0040                <1> 	dw	16384
    84                              <1> 
    85                              <1> ;-----	COLUMNS
    86                              <1> M6:
    87 0000D362 2828505028285050    <1> 	db	40, 40, 80, 80, 40, 40, 80, 80
    88                              <1> 
    89                              <1> ;-----	C_REG_TAB
    90                              <1> M7:
    91 0000D36A 2C282D292A2E1E29    <1> 	db	2Ch, 28h, 2Dh, 29h, 2Ah, 2Eh, 1Eh, 29h	; TABLE OF MODE SETS
    92                              <1> 
    93                              <1> ; 16/01/2016
    94                              <1> chr_attrib:  ; Character color/attributes for viode pages (0 to 7)
    95 0000D372 0707070707070707    <1> 	db	07h, 07h, 07h, 07h, 07h, 07h, 07h, 07h
    96                              <1> ; 30/01/2016
    97                              <1> vmode:
    98 0000D37A 0303030303030303    <1> 	db	3,3,3,3,3,3,3,3 ; video modes for pseudo screens 
    99                              <1> 
   100                              <1> CURSOR_MODE: ; cursor start (ch) = 13, cursor end (cl) = 15
   101 0000D382 0E0D                <1> 	db	14, 13 ; 17/06/2016 - TRDOS 386 (TRDOS v2.0)
   102                              <1> 
   103                              <1> ; 01/07/2016 - TRDOS 386 (TRDOS v2.0)
   104                              <1> ; IBM PC/XT 286 BIOS - ORGS.ASM ----- 10/06/1985 COMPATIBILITY MODULE
   105                              <1> ;----------------------------------------------------------------------
   106                              <1> ; CHARACTER GENERATOR GRAPHICS FOR 320X200 AND 640X200 GRAPHICS       :
   107                              <1> ;----------------------------------------------------------------------
   108                              <1> 
   109                              <1> CRT_CHAR_GEN:
   110 0000D384 0000000000000000    <1> 	DB	000H,000H,000H,000H,000H,000H,000H,000H ; D_00	BLANK
   111 0000D38C 7E81A581BD99817E    <1> 	DB	07EH,081H,0A5H,081H,0BDH,099H,081H,07EH ; D_01	SMILING FACE
   112 0000D394 7EFFDBFFC3E7FF7E    <1> 	DB	07EH,0FFH,0DBH,0FFH,0C3H,0E7H,0FFH,07EH ; D_02	SMILING FACE N
   113 0000D39C 6CFEFEFE7C381000    <1> 	DB	06CH,0FEH,0FEH,0FEH,07CH,038H,010H,000H ; D_03	HEART
   114 0000D3A4 10387CFE7C381000    <1> 	DB	010H,038H,07CH,0FEH,07CH,038H,010H,000H ; D_04	DIAMOND
   115 0000D3AC 387C38FEFE7C387C    <1> 	DB	038H,07CH,038H,0FEH,0FEH,07CH,038H,07CH ; D_05	CLUB
   116 0000D3B4 1010387CFE7C387C    <1> 	DB	010H,010H,038H,07CH,0FEH,07CH,038H,07CH ; D_06	SPADE
   117 0000D3BC 0000183C3C180000    <1> 	DB	000H,000H,018H,03CH,03CH,018H,000H,000H ; D_07	BULLET
   118 0000D3C4 FFFFE7C3C3E7FFFF    <1> 	DB	0FFH,0FFH,0E7H,0C3H,0C3H,0E7H,0FFH,0FFH ; D_08	BULLET NEG
   119 0000D3CC 003C664242663C00    <1> 	DB	000H,03CH,066H,042H,042H,066H,03CH,000H ; D_09	CIRCLE
   120 0000D3D4 FFC399BDBD99C3FF    <1> 	DB	0FFH,0C3H,099H,0BDH,0BDH,099H,0C3H,0FFH ; D_0A	CIRCLE NEG
   121 0000D3DC 0F070F7DCCCCCC78    <1> 	DB	00FH,007H,00FH,07DH,0CCH,0CCH,0CCH,078H ; D_0B	MALE
   122 0000D3E4 3C6666663C187E18    <1> 	DB	03CH,066H,066H,066H,03CH,018H,07EH,018H ; D_0C	FEMALE
   123 0000D3EC 3F333F303070F0E0    <1> 	DB	03FH,033H,03FH,030H,030H,070H,0F0H,0E0H ; D_0D	EIGHTH NOTE
   124 0000D3F4 7F637F636367E6C0    <1> 	DB	07FH,063H,07FH,063H,063H,067H,0E6H,0C0H ; D_0E	TWO 1/16 NOTE
   125 0000D3FC 995A3CE7E73C5A99    <1> 	DB	099H,05AH,03CH,0E7H,0E7H,03CH,05AH,099H ; D_0F	SUN
   126                              <1> 
   127 0000D404 80E0F8FEF8E08000    <1> 	DB	080H,0E0H,0F8H,0FEH,0F8H,0E0H,080H,000H ; D_10	R ARROWHEAD
   128 0000D40C 020E3EFE3E0E0200    <1> 	DB	002H,00EH,03EH,0FEH,03EH,00EH,002H,000H ; D_11	L ARROWHEAD
   129 0000D414 183C7E18187E3C18    <1> 	DB	018H,03CH,07EH,018H,018H,07EH,03CH,018H ; D_12	ARROW 2 VERT
   130 0000D41C 6666666666006600    <1> 	DB	066H,066H,066H,066H,066H,000H,066H,000H ; D_13	2 EXCLAMATIONS
   131 0000D424 7FDBDB7B1B1B1B00    <1> 	DB	07FH,0DBH,0DBH,07BH,01BH,01BH,01BH,000H ; D_14	PARAGRAPH
   132 0000D42C 3E63386C6C38CC78    <1> 	DB	03EH,063H,038H,06CH,06CH,038H,0CCH,078H ; D_15	SECTION
   133 0000D434 000000007E7E7E00    <1> 	DB	000H,000H,000H,000H,07EH,07EH,07EH,000H ; D_16	RECTANGLE
   134 0000D43C 183C7E187E3C18FF    <1> 	DB	018H,03CH,07EH,018H,07EH,03CH,018H,0FFH ; D_17	ARROW 2 VRT UP
   135 0000D444 183C7E1818181800    <1> 	DB	018H,03CH,07EH,018H,018H,018H,018H,000H ; D_18	ARROW VRT UP
   136 0000D44C 181818187E3C1800    <1> 	DB	018H,018H,018H,018H,07EH,03CH,018H,000H ; D_19	ARROW VRT DOWN
   137 0000D454 00180CFE0C180000    <1> 	DB	000H,018H,00CH,0FEH,00CH,018H,000H,000H ; D_1A	ARROW RIGHT
   138 0000D45C 003060FE60300000    <1> 	DB	000H,030H,060H,0FEH,060H,030H,000H,000H ; D_1B	ARROW LEFT
   139 0000D464 0000C0C0C0FE0000    <1> 	DB	000H,000H,0C0H,0C0H,0C0H,0FEH,000H,000H ; D_1C	NOT INVERTED
   140 0000D46C 002466FF66240000    <1> 	DB	000H,024H,066H,0FFH,066H,024H,000H,000H ; D_1D	ARROW 2 HORZ
   141 0000D474 00183C7EFFFF0000    <1> 	DB	000H,018H,03CH,07EH,0FFH,0FFH,000H,000H ; D_1E	ARROWHEAD UP
   142 0000D47C 00FFFF7E3C180000    <1> 	DB	000H,0FFH,0FFH,07EH,03CH,018H,000H,000H ; D_1F	ARROWHEAD DOWN
   143                              <1> 
   144 0000D484 0000000000000000    <1> 	DB	000H,000H,000H,000H,000H,000H,000H,000H ; D_20	SPACE
   145 0000D48C 3078783030003000    <1> 	DB	030H,078H,078H,030H,030H,000H,030H,000H ; D_21 ! EXCLAMATION
   146 0000D494 6C6C6C0000000000    <1> 	DB	06CH,06CH,06CH,000H,000H,000H,000H,000H ; D_22 " QUOTATION
   147 0000D49C 6C6CFE6CFE6C6C00    <1> 	DB	06CH,06CH,0FEH,06CH,0FEH,06CH,06CH,000H ; D_23 # LB.
   148 0000D4A4 307CC0780CF83000    <1> 	DB	030H,07CH,0C0H,078H,00CH,0F8H,030H,000H ; D_24 $ DOLLAR SIGN
   149 0000D4AC 00C6CC183066C600    <1> 	DB	000H,0C6H,0CCH,018H,030H,066H,0C6H,000H ; D_25 % PERCENT
   150 0000D4B4 386C3876DCCC7600    <1> 	DB	038H,06CH,038H,076H,0DCH,0CCH,076H,000H ; D_26 & AMPERSAND
   151 0000D4BC 6060C00000000000    <1> 	DB	060H,060H,0C0H,000H,000H,000H,000H,000H ; D_27 ' APOSTROPHE
   152 0000D4C4 1830606060301800    <1> 	DB	018H,030H,060H,060H,060H,030H,018H,000H ; D_28 ( L. PARENTHESIS
   153 0000D4CC 6030181818306000    <1> 	DB	060H,030H,018H,018H,018H,030H,060H,000H ; D_29 ) R. PARENTHESIS
   154 0000D4D4 00663CFF3C660000    <1> 	DB	000H,066H,03CH,0FFH,03CH,066H,000H,000H ; D_2A * ASTERISK
   155 0000D4DC 003030FC30300000    <1> 	DB	000H,030H,030H,0FCH,030H,030H,000H,000H ; D_2B + PLUS
   156 0000D4E4 0000000000303060    <1> 	DB	000H,000H,000H,000H,000H,030H,030H,060H ; D_2C , COMMA
   157 0000D4EC 000000FC00000000    <1> 	DB	000H,000H,000H,0FCH,000H,000H,000H,000H ; D_2D - DASH
   158 0000D4F4 0000000000303000    <1> 	DB	000H,000H,000H,000H,000H,030H,030H,000H ; D_2E . PERIOD
   159 0000D4FC 060C183060C08000    <1> 	DB	006H,00CH,018H,030H,060H,0C0H,080H,000H ; D_2F / SLASH
   160                              <1> 
   161 0000D504 7CC6CEDEF6E67C00    <1> 	DB	07CH,0C6H,0CEH,0DEH,0F6H,0E6H,07CH,000H ; D_30 0
   162 0000D50C 307030303030FC00    <1> 	DB	030H,070H,030H,030H,030H,030H,0FCH,000H ; D_31 1
   163 0000D514 78CC0C3860CCFC00    <1> 	DB	078H,0CCH,00CH,038H,060H,0CCH,0FCH,000H ; D_32 2
   164 0000D51C 78CC0C380CCC7800    <1> 	DB	078H,0CCH,00CH,038H,00CH,0CCH,078H,000H ; D_33 3
   165 0000D524 1C3C6CCCFE0C1E00    <1> 	DB	01CH,03CH,06CH,0CCH,0FEH,00CH,01EH,000H ; D_34 4
   166 0000D52C FCC0F80C0CCC7800    <1> 	DB	0FCH,0C0H,0F8H,00CH,00CH,0CCH,078H,000H ; D_35 5
   167 0000D534 3860C0F8CCCC7800    <1> 	DB	038H,060H,0C0H,0F8H,0CCH,0CCH,078H,000H ; D_36 6
   168 0000D53C FCCC0C1830303000    <1> 	DB	0FCH,0CCH,00CH,018H,030H,030H,030H,000H ; D_37 7
   169 0000D544 78CCCC78CCCC7800    <1> 	DB	078H,0CCH,0CCH,078H,0CCH,0CCH,078H,000H ; D_38 8
   170 0000D54C 78CCCC7C0C187000    <1> 	DB	078H,0CCH,0CCH,07CH,00CH,018H,070H,000H ; D_39 9
   171 0000D554 0030300000303000    <1> 	DB	000H,030H,030H,000H,000H,030H,030H,000H ; D_3A : COLON
   172 0000D55C 0030300000303060    <1> 	DB	000H,030H,030H,000H,000H,030H,030H,060H ; D_3B ; SEMICOLON
   173 0000D564 183060C060301800    <1> 	DB	018H,030H,060H,0C0H,060H,030H,018H,000H ; D_3C < LESS THAN
   174 0000D56C 0000FC0000FC0000    <1> 	DB	000H,000H,0FCH,000H,000H,0FCH,000H,000H ; D_3D = EQUAL
   175 0000D574 6030180C18306000    <1> 	DB	060H,030H,018H,00CH,018H,030H,060H,000H ; D_3E > GREATER THAN
   176 0000D57C 78CC0C1830003000    <1> 	DB	078H,0CCH,00CH,018H,030H,000H,030H,000H ; D_3F ? QUESTION MARK
   177                              <1> 
   178 0000D584 7CC6DEDEDEC07800    <1> 	DB	07CH,0C6H,0DEH,0DEH,0DEH,0C0H,078H,000H ; D_40 @ AT
   179 0000D58C 3078CCCCFCCCCC00    <1> 	DB	030H,078H,0CCH,0CCH,0FCH,0CCH,0CCH,000H ; D_41 A
   180 0000D594 FC66667C6666FC00    <1> 	DB	0FCH,066H,066H,07CH,066H,066H,0FCH,000H ; D_42 B
   181 0000D59C 3C66C0C0C0663C00    <1> 	DB	03CH,066H,0C0H,0C0H,0C0H,066H,03CH,000H ; D_43 C
   182 0000D5A4 F86C6666666CF800    <1> 	DB	0F8H,06CH,066H,066H,066H,06CH,0F8H,000H ; D_44 D
   183 0000D5AC FE6268786862FE00    <1> 	DB	0FEH,062H,068H,078H,068H,062H,0FEH,000H ; D_45 E
   184 0000D5B4 FE6268786860F000    <1> 	DB	0FEH,062H,068H,078H,068H,060H,0F0H,000H ; D_46 F
   185 0000D5BC 3C66C0C0CE663E00    <1> 	DB	03CH,066H,0C0H,0C0H,0CEH,066H,03EH,000H ; D_47 G
   186 0000D5C4 CCCCCCFCCCCCCC00    <1> 	DB	0CCH,0CCH,0CCH,0FCH,0CCH,0CCH,0CCH,000H ; D_48 H
   187 0000D5CC 7830303030307800    <1> 	DB	078H,030H,030H,030H,030H,030H,078H,000H ; D_49 I
   188 0000D5D4 1E0C0C0CCCCC7800    <1> 	DB	01EH,00CH,00CH,00CH,0CCH,0CCH,078H,000H ; D_4A J
   189 0000D5DC E6666C786C66E600    <1> 	DB	0E6H,066H,06CH,078H,06CH,066H,0E6H,000H ; D_4B K
   190 0000D5E4 F06060606266FE00    <1> 	DB	0F0H,060H,060H,060H,062H,066H,0FEH,000H ; D_4C L
   191 0000D5EC C6EEFEFED6C6C600    <1> 	DB	0C6H,0EEH,0FEH,0FEH,0D6H,0C6H,0C6H,000H ; D_4D M
   192 0000D5F4 C6E6F6DECEC6C600    <1> 	DB	0C6H,0E6H,0F6H,0DEH,0CEH,0C6H,0C6H,000H ; D_4E N
   193 0000D5FC 386CC6C6C66C3800    <1> 	DB	038H,06CH,0C6H,0C6H,0C6H,06CH,038H,000H ; D_4F O
   194                              <1> 
   195 0000D604 FC66667C6060F000    <1> 	DB	0FCH,066H,066H,07CH,060H,060H,0F0H,000H ; D_50 P
   196 0000D60C 78CCCCCCDC781C00    <1> 	DB	078H,0CCH,0CCH,0CCH,0DCH,078H,01CH,000H ; D_51 Q
   197 0000D614 FC66667C6C66E600    <1> 	DB	0FCH,066H,066H,07CH,06CH,066H,0E6H,000H ; D_52 R
   198 0000D61C 78CCE0701CCC7800    <1> 	DB	078H,0CCH,0E0H,070H,01CH,0CCH,078H,000H ; D_53 S
   199 0000D624 FCB4303030307800    <1> 	DB	0FCH,0B4H,030H,030H,030H,030H,078H,000H ; D_54 T
   200 0000D62C CCCCCCCCCCCCFC00    <1> 	DB	0CCH,0CCH,0CCH,0CCH,0CCH,0CCH,0FCH,000H ; D_55 U
   201 0000D634 CCCCCCCCCC783000    <1> 	DB	0CCH,0CCH,0CCH,0CCH,0CCH,078H,030H,000H ; D_56 V
   202 0000D63C C6C6C6D6FEEEC600    <1> 	DB	0C6H,0C6H,0C6H,0D6H,0FEH,0EEH,0C6H,000H ; D_57 W
   203 0000D644 C6C66C38386CC600    <1> 	DB	0C6H,0C6H,06CH,038H,038H,06CH,0C6H,000H ; D_58 X
   204 0000D64C CCCCCC7830307800    <1> 	DB	0CCH,0CCH,0CCH,078H,030H,030H,078H,000H ; D_59 Y
   205 0000D654 FEC68C183266FE00    <1> 	DB	0FEH,0C6H,08CH,018H,032H,066H,0FEH,000H ; D_5A Z
   206 0000D65C 7860606060607800    <1> 	DB	078H,060H,060H,060H,060H,060H,078H,000H ; D_5B [ LEFT BRACKET
   207 0000D664 C06030180C060200    <1> 	DB	0C0H,060H,030H,018H,00CH,006H,002H,000H ; D_5C \ BACKSLASH
   208 0000D66C 7818181818187800    <1> 	DB	078H,018H,018H,018H,018H,018H,078H,000H ; D_5D ] RIGHT BRACKET
   209 0000D674 10386CC600000000    <1> 	DB	010H,038H,06CH,0C6H,000H,000H,000H,000H ; D_5E ^ CIRCUMFLEX
   210 0000D67C 00000000000000FF    <1> 	DB	000H,000H,000H,000H,000H,000H,000H,0FFH ; D_5F _ UNDERSCORE
   211                              <1> 
   212 0000D684 3030180000000000    <1> 	DB	030H,030H,018H,000H,000H,000H,000H,000H ; D_60 ` APOSTROPHE REV
   213 0000D68C 0000780C7CCC7600    <1> 	DB	000H,000H,078H,00CH,07CH,0CCH,076H,000H ; D_61 a
   214 0000D694 E060607C6666DC00    <1> 	DB	0E0H,060H,060H,07CH,066H,066H,0DCH,000H ; D_62 b
   215 0000D69C 000078CCC0CC7800    <1> 	DB	000H,000H,078H,0CCH,0C0H,0CCH,078H,000H ; D_63 c
   216 0000D6A4 1C0C0C7CCCCC7600    <1> 	DB	01CH,00CH,00CH,07CH,0CCH,0CCH,076H,000H ; D_64 d
   217 0000D6AC 000078CCFCC07800    <1> 	DB	000H,000H,078H,0CCH,0FCH,0C0H,078H,000H ; D_65 e
   218 0000D6B4 386C60F06060F000    <1> 	DB	038H,06CH,060H,0F0H,060H,060H,0F0H,000H ; D_66 f
   219 0000D6BC 000076CCCC7C0CF8    <1> 	DB	000H,000H,076H,0CCH,0CCH,07CH,00CH,0F8H ; D_67 g
   220 0000D6C4 E0606C766666E600    <1> 	DB	0E0H,060H,06CH,076H,066H,066H,0E6H,000H ; D_68 h
   221 0000D6CC 3000703030307800    <1> 	DB	030H,000H,070H,030H,030H,030H,078H,000H ; D_69 i
   222 0000D6D4 0C000C0C0CCCCC78    <1> 	DB	00CH,000H,00CH,00CH,00CH,0CCH,0CCH,078H ; D_6A j
   223 0000D6DC E060666C786CE600    <1> 	DB	0E0H,060H,066H,06CH,078H,06CH,0E6H,000H ; D_6B k
   224 0000D6E4 7030303030307800    <1> 	DB	070H,030H,030H,030H,030H,030H,078H,000H ; D_6C l
   225 0000D6EC 0000CCFEFED6C600    <1> 	DB	000H,000H,0CCH,0FEH,0FEH,0D6H,0C6H,000H ; D_6D m
   226 0000D6F4 0000F8CCCCCCCC00    <1> 	DB	000H,000H,0F8H,0CCH,0CCH,0CCH,0CCH,000H ; D_6E n
   227 0000D6FC 000078CCCCCC7800    <1> 	DB	000H,000H,078H,0CCH,0CCH,0CCH,078H,000H ; D_6F o
   228                              <1> 
   229 0000D704 0000DC66667C60F0    <1> 	DB	000H,000H,0DCH,066H,066H,07CH,060H,0F0H ; D_70 p
   230 0000D70C 000076CCCC7C0C1E    <1> 	DB	000H,000H,076H,0CCH,0CCH,07CH,00CH,01EH ; D_71 q
   231 0000D714 0000DC766660F000    <1> 	DB	000H,000H,0DCH,076H,066H,060H,0F0H,000H ; D_72 r
   232 0000D71C 00007CC0780CF800    <1> 	DB	000H,000H,07CH,0C0H,078H,00CH,0F8H,000H ; D_73 s
   233 0000D724 10307C3030341800    <1> 	DB	010H,030H,07CH,030H,030H,034H,018H,000H ; D_74 t
   234 0000D72C 0000CCCCCCCC7600    <1> 	DB	000H,000H,0CCH,0CCH,0CCH,0CCH,076H,000H ; D_75 u
   235 0000D734 0000CCCCCC783000    <1> 	DB	000H,000H,0CCH,0CCH,0CCH,078H,030H,000H ; D_76 v
   236 0000D73C 0000C6D6FEFE6C00    <1> 	DB	000H,000H,0C6H,0D6H,0FEH,0FEH,06CH,000H ; D_77 w
   237 0000D744 0000C66C386CC600    <1> 	DB	000H,000H,0C6H,06CH,038H,06CH,0C6H,000H ; D_78 x
   238 0000D74C 0000CCCCCC7C0CF8    <1> 	DB	000H,000H,0CCH,0CCH,0CCH,07CH,00CH,0F8H ; D_79 y
   239 0000D754 0000FC983064FC00    <1> 	DB	000H,000H,0FCH,098H,030H,064H,0FCH,000H ; D_7A z
   240 0000D75C 1C3030E030301C00    <1> 	DB	01CH,030H,030H,0E0H,030H,030H,01CH,000H ; D_7B { LEFT BRACE
   241 0000D764 1818180018181800    <1> 	DB	018H,018H,018H,000H,018H,018H,018H,000H ; D_7C | BROKEN STROKE
   242 0000D76C E030301C3030E000    <1> 	DB	0E0H,030H,030H,01CH,030H,030H,0E0H,000H ; D_7D } RIGHT BRACE
   243 0000D774 76DC000000000000    <1> 	DB	076H,0DCH,000H,000H,000H,000H,000H,000H ; D_7E ~ TILDE
   244 0000D77C 0010386CC6C6FE00    <1> 	DB	000H,010H,038H,06CH,0C6H,0C6H,0FEH,000H ; D_7F  DELTA
   245                              <1> 
   246                              <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 0000D784 [E7D70000]          <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 0000D788 01                  <1> 		DB	01		;DRIVE TYPE, MEDIA TABLE
   113                              <1>                 ;DW      MD_TBL1
   114 0000D789 [A6D70000]          <1> 		dd	MD_TBL1
   115 0000D78D 82                  <1> 		DB	02+BIT7ON
   116                              <1> 		;DW      MD_TBL2
   117 0000D78E [B3D70000]          <1>                 dd      MD_TBL2
   118 0000D792 02                  <1> DR_DEFAULT:	DB	02
   119                              <1>                 ;DW      MD_TBL3
   120 0000D793 [C0D70000]          <1> 		dd      MD_TBL3
   121 0000D797 03                  <1> 		DB	03
   122                              <1>                 ;DW      MD_TBL4
   123 0000D798 [CDD70000]          <1> 		dd      MD_TBL4
   124 0000D79C 84                  <1> 		DB	04+BIT7ON
   125                              <1>                 ;DW      MD_TBL5
   126 0000D79D [DAD70000]          <1> 		dd      MD_TBL5
   127 0000D7A1 04                  <1> 		DB	04
   128                              <1>                 ;DW      MD_TBL6
   129 0000D7A2 [E7D70000]          <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 0000D7A6 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   141 0000D7A7 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   142 0000D7A8 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   143 0000D7A9 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   144 0000D7AA 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   145 0000D7AB 2A                  <1> 	DB	02AH		; GAP LENGTH
   146 0000D7AC FF                  <1> 	DB	0FFH		; DTL
   147 0000D7AD 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   148 0000D7AE F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   149 0000D7AF 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   150 0000D7B0 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   151 0000D7B1 27                  <1> 	DB	39		; MAX. TRACK NUMBER
   152 0000D7B2 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 0000D7B3 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   158 0000D7B4 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   159 0000D7B5 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   160 0000D7B6 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   161 0000D7B7 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   162 0000D7B8 2A                  <1> 	DB	02AH		; GAP LENGTH
   163 0000D7B9 FF                  <1> 	DB	0FFH		; DTL
   164 0000D7BA 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   165 0000D7BB F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   166 0000D7BC 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   167 0000D7BD 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   168 0000D7BE 27                  <1> 	DB	39		; MAX. TRACK NUMBER
   169 0000D7BF 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 0000D7C0 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   175 0000D7C1 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   176 0000D7C2 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   177 0000D7C3 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   178 0000D7C4 0F                  <1> 	DB	15		; EOT (LAST SECTOR ON TRACK)
   179 0000D7C5 1B                  <1> 	DB	01BH		; GAP LENGTH
   180 0000D7C6 FF                  <1> 	DB	0FFH		; DTL
   181 0000D7C7 54                  <1> 	DB	054H		; GAP LENGTH FOR FORMAT
   182 0000D7C8 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   183 0000D7C9 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   184 0000D7CA 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   185 0000D7CB 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   186 0000D7CC 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 0000D7CD DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   192 0000D7CE 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   193 0000D7CF 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   194 0000D7D0 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   195 0000D7D1 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   196 0000D7D2 2A                  <1> 	DB	02AH		; GAP LENGTH
   197 0000D7D3 FF                  <1> 	DB	0FFH		; DTL
   198 0000D7D4 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   199 0000D7D5 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   200 0000D7D6 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   201 0000D7D7 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   202 0000D7D8 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   203 0000D7D9 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 0000D7DA DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   209 0000D7DB 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   210 0000D7DC 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   211 0000D7DD 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   212 0000D7DE 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   213 0000D7DF 2A                  <1> 	DB	02AH		; GAP LENGTH
   214 0000D7E0 FF                  <1> 	DB	0FFH		; DTL
   215 0000D7E1 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   216 0000D7E2 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   217 0000D7E3 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   218 0000D7E4 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   219 0000D7E5 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   220 0000D7E6 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 0000D7E7 AF                  <1> 	DB	10101111B	; SRT=A, HD UNLOAD=0F - 1ST SPECIFY BYTE
   226 0000D7E8 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   227 0000D7E9 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   228 0000D7EA 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   229 0000D7EB 12                  <1> 	DB	18		; EOT (LAST SECTOR ON TRACK)
   230 0000D7EC 1B                  <1> 	DB	01BH		; GAP LENGTH
   231 0000D7ED FF                  <1> 	DB	0FFH		; DTL
   232 0000D7EE 6C                  <1> 	DB	06CH		; GAP LENGTH FOR FORMAT
   233 0000D7EF F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   234 0000D7F0 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   235 0000D7F1 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   236 0000D7F2 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   237 0000D7F3 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 0000D7F4 E0                  <1> 	db	NO_ERR
   280 0000D7F5 024001BB            <1> 	db	BAD_ADDR_MARK,BAD_SEEK,BAD_CMD,UNDEF_ERR
   281 0000D7F9 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 0000D7FD 00                  <1> cfd:		db 0			; current floppy drive (for GET_PARM)
   286                              <1> ; 17/12/2014				; instead of 'DISK_POINTER'
   287 0000D7FE 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 0000D7FF 90                  <1> align 2
   293                              <1> 
   294 0000D800 F001                <1> HF_PORT:	dw 	1F0h  ; Default = 1F0h
   295                              <1> 			      ; (170h)
   296 0000D802 F603                <1> HF_REG_PORT:	dw	3F6h  ; HF_PORT + 206h
   297                              <1> 
   298                              <1> ; 05/01/2015 
   299 0000D804 00                  <1> hf_m_s:         db      0     ; (0 = Master, 1 = Slave)
   300                              <1> 
   301                              <1> ; *****************************************************************************
  2212                                  ;;;
  2213                                  
  2214 0000D805 90                      Align 2
  2215                                  
  2216                                  ; 12/11/2014 (Retro UNIX 386 v1)
  2217 0000D806 00                      boot_drv:    db 0 ; boot drive number (physical)
  2218                                  ; 24/11/2014
  2219 0000D807 00                      drv:	     db 0 
  2220 0000D808 00                      last_drv:    db 0 ; last hdd
  2221 0000D809 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 0000D80A 00                      fd0_type:    db 0  ; floppy drive type
  2227 0000D80B 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 0000D80C 00                      hd0_type:    db 0  ; EDD status for hd0 (bit 7 = present flag)
  2233 0000D80D 00                      hd1_type:    db 0  ; EDD status for hd1 (bit 7 = present flag)
  2234 0000D80E 00                      hd2_type:    db 0  ; EDD status for hd2 (bit 7 = present flag)
  2235 0000D80F 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 0000D810 000000000000000000-     drv.cylinders: dw 0,0,0,0,0,0,0
  2244 0000D819 0000000000         
  2245 0000D81E 000000000000000000-     drv.heads:     dw 0,0,0,0,0,0,0
  2245 0000D827 0000000000         
  2246 0000D82C 000000000000000000-     drv.spt:       dw 0,0,0,0,0,0,0
  2246 0000D835 0000000000         
  2247 0000D83A 000000000000000000-     drv.size:      dd 0,0,0,0,0,0,0
  2247 0000D843 000000000000000000-
  2247 0000D84C 000000000000000000-
  2247 0000D855 00                 
  2248 0000D856 00000000000000          drv.status:    db 0,0,0,0,0,0,0
  2249 0000D85D 00000000000000          drv.error:     db 0,0,0,0,0,0,0		
  2250                                  ;
  2251                                  
  2252                                  ; 27/08/2014
  2253                                  scr_row:
  2254 0000D864 E0810B00                	dd 0B8000h + 0A0h + 0A0h + 0A0h ; Row 3
  2255                                  scr_col:
  2256 0000D868 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 0000D86C 556E6B6E6F776E2069-     	db "Unknown interrupt ! ", 0
  2262 0000D875 6E7465727275707420-
  2262 0000D87E 212000             
  2263                                  
  2264 0000D881 90                      Align 2
  2265                                  	; 21/08/2014
  2266                                  exc_msg:
  2267 0000D882 435055206578636570-     	db "CPU exception ! "
  2267 0000D88B 74696F6E202120     
  2268                                  excnstr: 		; 25/08/2014
  2269 0000D892 3F3F68202045495020-     	db "??h", "  EIP : "
  2269 0000D89B 3A20               
  2270                                  EIPstr: ; 29/08/2014
  2271 0000D89D 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 0000D8A9 070D0A                  	db 	07h, 0Dh, 0Ah
  2282 0000D8AC 496E73756666696369-             db      'Insufficient memory ! (Minimum 2 MB memory is needed.)'
  2282 0000D8B5 656E74206D656D6F72-
  2282 0000D8BE 79202120284D696E69-
  2282 0000D8C7 6D756D2032204D4220-
  2282 0000D8D0 6D656D6F7279206973-
  2282 0000D8D9 206E65656465642E29 
  2283 0000D8E2 0D0A00                   	db	0Dh, 0Ah, 0
  2284                                  	;
  2285                                  setup_error_msg:
  2286 0000D8E5 0D0A                    	db 0Dh, 0Ah
  2287 0000D8E7 4469736B2053657475-     	db 'Disk Setup Error!' 
  2287 0000D8F0 70204572726F7221   
  2288 0000D8F8 0D0A00                  	db 0Dh, 0Ah,0
  2289                                  
  2290                                  ; 06/11/2014
  2291                                  ; Memory Information message
  2292                                  ; 14/08/2015
  2293                                  msg_memory_info:
  2294 0000D8FB 07                      	db	07h
  2295 0000D8FC 0D0A                    	db	0Dh, 0Ah
  2296                                  	;db 	"MEMORY ALLOCATION INFO", 0Dh, 0Ah, 0Dh, 0Ah
  2297 0000D8FE 546F74616C206D656D-     	db	"Total memory : "
  2297 0000D907 6F7279203A20       
  2298                                  mem_total_b_str: ; 10 digits
  2299 0000D90D 303030303030303030-     	db	"0000000000 bytes", 0Dh, 0Ah
  2299 0000D916 302062797465730D0A 
  2300 0000D91F 202020202020202020-     	db	"               ", 20h, 20h, 20h
  2300 0000D928 202020202020202020 
  2301                                  mem_total_p_str: ; 7 digits
  2302 0000D931 303030303030302070-     	db	"0000000 pages", 0Dh, 0Ah
  2302 0000D93A 616765730D0A       
  2303 0000D940 0D0A                    	db 	0Dh, 0Ah
  2304 0000D942 46726565206D656D6F-     	db	"Free memory  : "
  2304 0000D94B 727920203A20       
  2305                                  free_mem_b_str:  ; 10 digits
  2306 0000D951 3F3F3F3F3F3F3F3F3F-     	db	"?????????? bytes", 0Dh, 0Ah
  2306 0000D95A 3F2062797465730D0A 
  2307 0000D963 202020202020202020-     	db	"               ", 20h, 20h, 20h
  2307 0000D96C 202020202020202020 
  2308                                  free_mem_p_str:  ; 7 digits
  2309 0000D975 3F3F3F3F3F3F3F2070-     	db	"??????? pages", 0Dh, 0Ah
  2309 0000D97E 616765730D0A       
  2310 0000D984 0D0A00                  	db	0Dh, 0Ah, 0
  2311                                  
  2312                                  dsk_ready_msg:
  2313 0000D987 0D0A                    	db 	0Dh, 0Ah
  2314                                  dsktype:
  2315 0000D989 6664                    	db	'fd'
  2316                                  dskx:
  2317 0000D98B 30                      	db	'0'
  2318 0000D98C 20                      	db	20h
  2319 0000D98D 697320524541445920-     	db 	'is READY ...'
  2319 0000D996 2E2E2E             
  2320 0000D999 00                      	db 	0
  2321                                  
  2322                                  next2line: ; 08/02/2016
  2323 0000D99A 0D0A                    	db	0Dh, 0Ah
  2324                                  nextline:
  2325 0000D99C 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 - 02/07/2016 (v2.0.0)'
  2343                                  ;	db 0Dh, 0Ah, 0
  2344                                  
  2345                                  panic_msg:
  2346 0000D99F 0D0A07                  	db 0Dh, 0Ah, 07h
  2347 0000D9A2 4552524F523A204B65-     	db 'ERROR: Kernel Panic !'
  2347 0000D9AB 726E656C2050616E69-
  2347 0000D9B4 632021             
  2348 0000D9B7 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 0000D9BA B207                    year: 	dw 1970
  2358 0000D9BC 0100                    month: 	dw 1
  2359 0000D9BE 0100                    day: 	dw 1
  2360 0000D9C0 0000                    hour: 	dw 0
  2361 0000D9C2 0000                    minute: dw 0
  2362 0000D9C4 0000                    second: dw 0
  2363                                  
  2364                                  DMonth:
  2365 0000D9C6 0000                    	dw 0
  2366 0000D9C8 1F00                    	dw 31
  2367 0000D9CA 3B00                    	dw 59
  2368 0000D9CC 5A00                    	dw 90
  2369 0000D9CE 7800                    	dw 120
  2370 0000D9D0 9700                    	dw 151
  2371 0000D9D2 B500                    	dw 181
  2372 0000D9D4 D400                    	dw 212
  2373 0000D9D6 F300                    	dw 243
  2374 0000D9D8 1101                    	dw 273
  2375 0000D9DA 3001                    	dw 304
  2376 0000D9DC 4E01                    	dw 334
  2377                                  
  2378                                  ; 04/11/2014 (Retro UNIX 386 v1)
  2379 0000D9DE 0000                    mem_1m_1k:   dw 0  ; Number of contiguous KB between
  2380                                                       ; 1 and 16 MB, max. 3C00h = 15 MB.
  2381 0000D9E0 0000                    mem_16m_64k: dw 0  ; Number of contiguous 64 KB blocks
  2382                                  		   ; between 16 MB and 4 GB.
  2383                                  
  2384                                  starting_msg:
  2385 0000D9E2 5475726B6973682052-     	db "Turkish Rational DOS v2.0 [02/07/2016] ...", 0
  2385 0000D9EB 6174696F6E616C2044-
  2385 0000D9F4 4F532076322E30205B-
  2385 0000D9FD 30322F30372F323031-
  2385 0000DA06 365D202E2E2E00     
  2386                                  NextLine:
  2387 0000DA0D 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                                  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 0000DA10 <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 0000DC90 <res 00000002>          tss.link:   resw 1
  2417 0000DC92 <res 00000002>          	    resw 1
  2418                                  ; tss offset 4	
  2419 0000DC94 <res 00000004>          tss.esp0:   resd 1
  2420 0000DC98 <res 00000002>          tss.ss0:    resw 1
  2421 0000DC9A <res 00000002>          	    resw 1	
  2422 0000DC9C <res 00000004>          tss.esp1:   resd 1
  2423 0000DCA0 <res 00000002>          tss.ss1:    resw 1
  2424 0000DCA2 <res 00000002>          	    resw 1 	
  2425 0000DCA4 <res 00000004>          tss.esp2:   resd 1
  2426 0000DCA8 <res 00000002>          tss.ss2:    resw 1
  2427 0000DCAA <res 00000002>          	    resw 1
  2428                                  ; tss offset 28
  2429 0000DCAC <res 00000004>          tss.CR3:    resd 1
  2430 0000DCB0 <res 00000004>          tss.eip:    resd 1
  2431 0000DCB4 <res 00000004>          tss.eflags: resd 1
  2432                                  ; tss offset 40
  2433 0000DCB8 <res 00000004>          tss.eax:    resd 1		 		
  2434 0000DCBC <res 00000004>          tss.ecx:    resd 1
  2435 0000DCC0 <res 00000004>          tss.edx:    resd 1
  2436 0000DCC4 <res 00000004>          tss.ebx:    resd 1
  2437 0000DCC8 <res 00000004>          tss.esp:    resd 1
  2438 0000DCCC <res 00000004>          tss.ebp:    resd 1
  2439 0000DCD0 <res 00000004>          tss.esi:    resd 1
  2440 0000DCD4 <res 00000004>          tss.edi:    resd 1
  2441                                  ; tss offset 72
  2442 0000DCD8 <res 00000002>          tss.ES:     resw 1
  2443 0000DCDA <res 00000002>          	    resw 1	
  2444 0000DCDC <res 00000002>          tss.CS:	    resw 1
  2445 0000DCDE <res 00000002>          	    resw 1
  2446 0000DCE0 <res 00000002>          tss.SS:	    resw 1
  2447 0000DCE2 <res 00000002>          	    resw 1
  2448 0000DCE4 <res 00000002>          tss.DS:	    resw 1
  2449 0000DCE6 <res 00000002>          	    resw 1
  2450 0000DCE8 <res 00000002>          tss.FS:	    resw 1
  2451 0000DCEA <res 00000002>          	    resw 1
  2452 0000DCEC <res 00000002>          tss.GS:	    resw 1
  2453 0000DCEE <res 00000002>          	    resw 1		
  2454 0000DCF0 <res 00000002>          tss.LDTR:   resw 1
  2455 0000DCF2 <res 00000002>          	    resw 1
  2456                                  ; tss offset 100		
  2457 0000DCF4 <res 00000002>          	    resw 1		
  2458 0000DCF6 <res 00000002>          tss.IOPB:   resw 1
  2459                                  ; tss offset 104 
  2460                                  tss_end:
  2461                                  
  2462 0000DCF8 <res 00000004>          k_page_dir:  resd 1 ; Kernel's (System) Page Directory address
  2463                                  		    ; (Physical address = Virtual address)	 	
  2464 0000DCFC <res 00000004>          memory_size: resd 1 ; memory size in pages
  2465 0000DD00 <res 00000004>          free_pages:  resd 1 ; number of free pages		
  2466 0000DD04 <res 00000004>          next_page:   resd 1 ; offset value in M.A.T. for
  2467                                  		    ; first free page search
  2468 0000DD08 <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 0000DD0C <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 0000DD10 <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 0000DD14 <res 00000002>          CRT_START:   resw 1 	  ; starting address in regen buffer
  2479                                  			  ; NOTE: active page only	
  2480 0000DD16 <res 00000010>          CURSOR_POSN: resw 8 ; cursor positions for video pages
  2481                                  ACTIVE_PAGE: 
  2482 0000DD26 <res 00000001>          ptty: 	     resb 1 ; current tty
  2483                                  ; 01/07/2015 - 29/01/2016
  2484 0000DD27 <res 00000001>          ccolor:	     resb 1 ; current color attribute
  2485                                  ; 26/10/2015
  2486                                  ; 07/09/2014
  2487 0000DD28 <res 00000014>          ttychr:      resw ntty+2 ; Character buffer (multiscreen)
  2488                                  
  2489                                  ; 18/05/2015 (03/06/2013 - Retro UNIX 8086 v1 feature only!)
  2490 0000DD3C <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 0000DD40 <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 0000DD54 <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 0000DD5E <res 00000001>          com1p:       resb 1  ;;0E3h
  2505 0000DD5F <res 00000001>          com2p:       resb 1  ;;0E3h
  2506                                  
  2507                                  ; 17/11/2015
  2508                                  ; request for response (from the terminal)	
  2509 0000DD60 <res 00000002>          req_resp:    resw 1 			
  2510                                  ; 07/11/2015
  2511 0000DD62 <res 00000001>          ccomport:    resb 1 ; current COM (serial) port
  2512                                  		    ; (0= COM1, 1= COM2)
  2513                                  ; 09/11/2015
  2514 0000DD63 <res 00000001>          comqr:	     resb 1 ; 'query or response' sign (u9.s, 'sndc')
  2515                                  ; 07/11/2015
  2516 0000DD64 <res 00000002>          rchar:	     resw 1 ; last received char for COM 1 and COM 2		
  2517 0000DD66 <res 00000002>          schar:	     resw 1 ; last sent char for COM 1 and COM 2
  2518                                  
  2519                                  ; 22/08/2014 (RTC)
  2520                                  ; (Packed BCD)
  2521 0000DD68 <res 00000001>          time_seconds: resb 1
  2522 0000DD69 <res 00000001>          time_minutes: resb 1
  2523 0000DD6A <res 00000001>          time_hours:   resb 1
  2524 0000DD6B <res 00000001>          date_wday:    resb 1
  2525 0000DD6C <res 00000001>          date_day:     resb 1
  2526 0000DD6D <res 00000001>          date_month:   resb 1			
  2527 0000DD6E <res 00000001>          date_year:    resb 1
  2528 0000DD6F <res 00000001>          date_century: resb 1
  2529                                  
  2530                                  ; 24/01/2016
  2531 0000DD70 <res 00000004>          RTC_LH:	       resd 1
  2532 0000DD74 <res 00000001>          RTC_WAIT_FLAG: resb 1
  2533 0000DD75 <res 00000001>          USER_FLAG:     resb 1
  2534                                  ; 19/05/2016
  2535                                  ;RTC_second:
  2536 0000DD76 <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 0000DD77 <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 0000DD78 <res 00000002>      <1> TIMER_LOW:      resw	1               ; LOW WORD OF TIMER COUNT
    31 0000DD7A <res 00000002>      <1> TIMER_HIGH:     resw	1               ; HIGH WORD OF TIMER COUNT
    32 0000DD7C <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 0000DD7D <res 00000001>      <1> SEEK_STATUS:	resb	1
    39 0000DD7E <res 00000001>      <1> MOTOR_STATUS:	resb	1
    40 0000DD7F <res 00000001>      <1> MOTOR_COUNT:	resb	1
    41 0000DD80 <res 00000001>      <1> DSKETTE_STATUS:	resb	1
    42 0000DD81 <res 00000007>      <1> NEC_STATUS:	resb	7
    43                              <1> 
    44                              <1> ;----------------------------------------
    45                              <1> ;	ADDITIONAL MEDIA DATA		:
    46                              <1> ;----------------------------------------
    47                              <1> 
    48 0000DD88 <res 00000001>      <1> LASTRATE:	resb 	1
    49 0000DD89 <res 00000001>      <1> HF_STATUS:	resb 	1
    50 0000DD8A <res 00000001>      <1> HF_ERROR:	resb 	1
    51 0000DD8B <res 00000001>      <1> HF_INT_FLAG:	resb 	1
    52 0000DD8C <res 00000001>      <1> HF_CNTRL:	resb 	1
    53 0000DD8D <res 00000004>      <1> DSK_STATE:	resb 	4
    54 0000DD91 <res 00000002>      <1> DSK_TRK:	resb 	2
    55                              <1> 
    56                              <1> ;----------------------------------------
    57                              <1> ;	FIXED DISK DATA AREAS		:
    58                              <1> ;----------------------------------------
    59                              <1> 
    60 0000DD93 <res 00000001>      <1> DISK_STATUS1:	resb 	1		; FIXED DISK STATUS
    61 0000DD94 <res 00000001>      <1> HF_NUM:		resb 	1		; COUNT OF FIXED DISK DRIVES
    62 0000DD95 <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 0000DD96 <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 0000DD98 <res 00000004>      <1> HDPM_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
    73 0000DD9C <res 00000004>      <1> HDPS_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
    74 0000DDA0 <res 00000004>      <1> HDSM_TBL_VEC:	resd	1 		; Secondary master disk param. tbl. pointer
    75 0000DDA4 <res 00000004>      <1> HDSS_TBL_VEC:	resd	1		; Secondary slave disk param. tbl. pointer
    76                              <1> 
    77                              <1> ; 03/01/2015
    78 0000DDA8 <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: 01/07/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 0000DDA9 <res 00000003>      <1> alignb 4
    20                              <1> 
    21                              <1> ; MAINPROG.ASM
    22 0000DDAC <res 00000004>      <1> MainProgCfg_FileSize:   resd 1 ; 14/04/2016
    23 0000DDB0 <res 00000004>      <1> MainProgCfg_LineOffset: resd 1 ; 14/04/2016
    24                              <1> 
    25 0000DDB4 <res 00000004>      <1> Current_VolSerial: resd 1
    26                              <1> 
    27 0000DDB8 <res 00000004>      <1> Current_Dir_FCluster: resd 1
    28                              <1> 
    29 0000DDBC <res 00000001>      <1> Current_Dir_Level: resb 1
    30 0000DDBD <res 00000001>      <1> Current_FATType: resb 1
    31 0000DDBE <res 00000001>      <1> Current_Drv: resb 1
    32 0000DDBF <res 00000001>      <1> Current_Dir_Drv:   resb 1 ; '?'
    33 0000DDC0 <res 00000001>      <1>                    resb 1 ; ':'
    34 0000DDC1 <res 00000001>      <1> Current_Dir_Root:  resb 1 ; '/' 
    35 0000DDC2 <res 0000005A>      <1> Current_Directory: resb 90
    36 0000DE1C <res 00000001>      <1> End_Of_Current_Dir_Str: resb 1
    37 0000DE1D <res 00000001>      <1> Current_Dir_StrLen: resb 1   
    38                              <1> 
    39 0000DE1E <res 00000001>      <1> CursorColumn: 	resb 1
    40 0000DE1F <res 00000001>      <1> CmdArgStart:    resb 1
    41                              <1> 
    42                              <1> ; 03/02/2016
    43 0000DE20 <res 0000004E>      <1> Remark:		resb 78
    44                              <1> 
    45 0000DE6E <res 00000050>      <1> CommandBuffer: 	resb 80
    46                              <1> 
    47 0000DEBE <res 00000100>      <1> TextBuffer:	resb 256
    48                              <1> 
    49                              <1> MasterBootBuff:
    50 0000DFBE <res 000001BE>      <1> MasterBootCode: resb 1BEh
    51 0000E17C <res 00000040>      <1> PartitionTable: resb 64
    52 0000E1BC <res 00000002>      <1> MBIDCode: resw 1
    53                              <1> 
    54                              <1> PTable_Buffer:
    55 0000E1BE <res 00000040>      <1> PTable_hd0: resb 64
    56 0000E1FE <res 00000040>      <1> PTable_hd1: resb 64
    57 0000E23E <res 00000040>      <1> PTable_hd2: resb 64
    58 0000E27E <res 00000040>      <1> PTable_hd3: resb 64
    59 0000E2BE <res 00000040>      <1> PTable_ep0: resb 64
    60 0000E2FE <res 00000040>      <1> PTable_ep1: resb 64
    61 0000E33E <res 00000040>      <1> PTable_ep2: resb 64
    62 0000E37E <res 00000040>      <1> PTable_ep3: resb 64
    63                              <1> 
    64 0000E3BE <res 00000001>      <1> scount:	resb 1 ; 16/05/2016 (diskio.s, 'int33h:')	
    65 0000E3BF <res 00000001>      <1> HD_LBA_yes: resb 1
    66 0000E3C0 <res 00000001>      <1> PP_Counter: resb 1
    67 0000E3C1 <res 00000001>      <1> EP_Counter: resb 1
    68                              <1> 
    69 0000E3C2 <res 00000004>      <1> EP_StartSector: resd 1
    70 0000E3C6 <res 00000004>      <1>                 resd 1
    71 0000E3CA <res 00000004>      <1>                 resd 1
    72 0000E3CE <res 00000004>      <1>                 resd 1
    73                              <1> 
    74 0000E3D2 <res 00000200>      <1> DOSBootSectorBuff: resb 512
    75                              <1> 
    76                              <1> FAT_BuffDescriptor:
    77 0000E5D2 <res 00000004>      <1> FAT_CurrentCluster: resd 1
    78 0000E5D6 <res 00000001>      <1> FAT_BuffValidData: resb 1
    79 0000E5D7 <res 00000001>      <1> FAT_BuffDrvName: resb 1
    80 0000E5D8 <res 00000002>      <1> FAT_BuffOffset: resw 1
    81 0000E5DA <res 00000004>      <1> FAT_BuffSector: resd 1
    82                              <1> 
    83 0000E5DE <res 00000004>      <1> FAT_ClusterCounter: resd 1
    84 0000E5E2 <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 0000E5E6 <res 00000001>      <1> DirBuff_DRV: resb 1
    92 0000E5E7 <res 00000001>      <1> DirBuff_FATType: resb 1
    93 0000E5E8 <res 00000001>      <1> DirBuff_ValidData: resb 1
    94 0000E5E9 <res 00000002>      <1> DirBuff_CurrentEntry: resw 1
    95 0000E5EB <res 00000002>      <1> DirBuff_LastEntry: resw 1
    96 0000E5ED <res 00000004>      <1> DirBuff_Cluster: resd 1 
    97 0000E5F1 <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 0000E5F3 <res 00000004>      <1> FreeClusterCount: resd 1
   109                              <1> 
   110 0000E5F7 <res 00000004>      <1> VolSize_Unit1:   resd 1
   111 0000E5FB <res 00000004>      <1> VolSize_Unit2:   resd 1
   112                              <1> 
   113 0000E5FF <res 00000004>      <1> Vol_Tot_Sec_Str_Start:	    resd 1
   114 0000E603 <res 0000000A>      <1> Vol_Tot_Sec_Str: 	    resb 10
   115 0000E60D <res 00000001>      <1> Vol_Tot_Sec_Str_End:	    resb 1
   116 0000E60E <res 00000001>      <1> resb 1
   117 0000E60F <res 00000004>      <1> Vol_Free_Sectors_Str_Start: resd 1
   118 0000E613 <res 0000000A>      <1> Vol_Free_Sectors_Str:	    resb 10				
   119 0000E61D <res 00000001>      <1> Vol_Free_Sectors_Str_End:   resb 1
   120                              <1> 
   121                              <1> ; 10/02/2016
   122 0000E61E <res 00000001>      <1> RUN_CDRV: resb 1 ; CMD_INTR.ASM  ; 09/11/2011
   123                              <1> 
   124                              <1> ; 24/01/2016
   125 0000E61F <res 00000080>      <1> PATH_Array:     resb 128 ; DIR.ASM ; 09/10/2011
   126                              <1> ; 06/02/2016
   127 0000E69F <res 00000004>      <1> CCD_DriveDT:	resd 1 ; DIR.ASM ; (word)
   128 0000E6A3 <res 00000001>      <1> CCD_Level:	resb 1 ; DIR.ASM
   129 0000E6A4 <res 00000001>      <1> Last_Dir_Level:	resb 1 ; DIR.ASM
   130                              <1> ;
   131 0000E6A5 <res 00000002>      <1> CDLF_AttributesMask: resw 1 ; DIR.ASM
   132 0000E6A7 <res 00000004>      <1> CDLF_FNAddress:	resd 1 ; DIR.ASM (word)
   133 0000E6AB <res 00000002>      <1> CDLF_DEType:	resw 1 ; DIR.ASM
   134                              <1> ;
   135 0000E6AD <res 00000001>      <1> CD_COMMAND:	resb 1 ; DIR.ASM
   136                              <1> 
   137 0000E6AE <res 00000002>      <1> alignb 4
   138                              <1> 
   139                              <1> ; 29/01/2016
   140 0000E6B0 <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 0000E6B1 <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 0000E6B2 <res 00000001>      <1> retry_count: 	resb 1 ; DISK_IO.ASM ; 20/07/2011 (CHS_RetryCount)
   148 0000E6B3 <res 00000001>      <1> disk_rw_err: 	resb 1 ; DISK_IO.ASM ; (Disk_IO_err_code)
   149 0000E6B4 <res 00000004>      <1> sector_count:	resd 1 ; DISK_IO.ASM ; (Disk_RW_SectorCount)
   150                              <1> 
   151                              <1> ; 06/02/2016 (long name)
   152 0000E6B8 <res 00000002>      <1> FDE_AttrMask:	   resw 1 ; DIR.ASM
   153 0000E6BA <res 00000002>      <1> AmbiguousFileName: resw 1 ; DIR.ASM
   154 0000E6BC <res 00000001>      <1> PreviousAttr:	   resb 1 ; DIR.ASM
   155                              <1> ;	
   156 0000E6BD <res 00000001>      <1> LongNameFound:   resb 1	  ; DIR.ASM
   157 0000E6BE <res 00000001>      <1> LFN_EntryLength: resb 1   ; DIR.ASM
   158 0000E6BF <res 00000001>      <1> LFN_CheckSum:    resb 1   ; DIR.ASM
   159 0000E6C0 <res 00000084>      <1> LongFileName:    resb 132 ; DIR.ASM
   160                              <1> 
   161                              <1> ;PATH_Array_Ptr: resw 1 ; DIR.ASM
   162 0000E744 <res 00000001>      <1> PATH_CDLevel:	 resb 1 ; DIR.ASM
   163 0000E745 <res 00000001>      <1> PATH_Level:	 resb 1 ; DIR.ASM
   164                              <1> 
   165                              <1> ; 07/02/2016
   166 0000E746 <res 0000000D>      <1> Dir_File_Name:	resb 13 ; DIR.ASM ; 09/10/2011
   167                              <1> 
   168                              <1> ; 10/02/2016
   169 0000E753 <res 0000000D>      <1> Dir_Entry_Name:	resb 13 ; DIR.ASM
   170                              <1> 
   171                              <1> alignb 2
   172                              <1> 
   173 0000E760 <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 0000E762 <res 00000001>      <1> FindFile_Drv:		  resb 1
   179 0000E763 <res 00000041>      <1> FindFile_Directory:	  resb 65
   180 0000E7A4 <res 0000000D>      <1> FindFile_Name:		  resb 13
   181                              <1> FindFile_LongNameEntryLength:
   182 0000E7B1 <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 0000E7B2 <res 00000002>      <1> FindFile_AttributesMask:  resw 1
   186 0000E7B4 <res 00000020>      <1> FindFile_DirEntry:	  resb 32
   187 0000E7D4 <res 00000004>      <1> FindFile_DirFirstCluster: resd 1
   188 0000E7D8 <res 00000004>      <1> FindFile_DirCluster:	  resd 1
   189 0000E7DC <res 00000002>      <1> FindFile_DirEntryNumber:  resw 1
   190 0000E7DE <res 00000002>      <1> FindFile_MatchCounter:	  resw 1
   191 0000E7E0 <res 00000002>      <1> FindFile_Reserved:	  resw 1 ; 06/03/2016
   192                              <1> 
   193 0000E7E2 <res 00000004>      <1> First_Path_Pos: resd 1	; DIR.ASM ; 09/10/2011
   194 0000E7E6 <res 00000004>      <1> Last_Slash_Pos: resd 1	; DIR.ASM 
   195                              <1> 
   196                              <1> ; 10/02/2016
   197 0000E7EA <res 00000002>      <1> File_Count:     resw 1 	; DIR.ASM ; 09/10/2011
   198 0000E7EC <res 00000002>      <1> Dir_Count:      resw 1
   199 0000E7EE <res 00000004>      <1> Total_FSize:    resd 1
   200 0000E7F2 <res 00000004>      <1> TFS_Dec_Begin:  resd 1
   201 0000E7F6 <res 0000000A>      <1>                 resb 10
   202 0000E800 <res 00000001>      <1> TFS_Dec_End:    resb 1
   203                              <1> 
   204 0000E801 <res 00000001>      <1> PrintDir_RowCounter: resb 1
   205                              <1> 
   206 0000E802 <res 00000002>      <1> alignb 4
   207                              <1> ; 15/02/2015 ('show' command variables)
   208 0000E804 <res 00000004>      <1> Show_FDT:	resd 1
   209 0000E808 <res 00000004>      <1> Show_LDDDT:	resd 1
   210 0000E80C <res 00000004>      <1> Show_Cluster:	resd 1
   211 0000E810 <res 00000004>      <1> Show_FileSize:	resd 1
   212 0000E814 <res 00000004>      <1> Show_FilePointer: resd 1
   213 0000E818 <res 00000002>      <1> Show_ClusterPointer: resw 1
   214 0000E81A <res 00000002>      <1> Show_ClusterSize: resw 1
   215 0000E81C <res 00000001>      <1> Show_RowCount:	resb 1
   216                              <1> 
   217 0000E81D <res 00000003>      <1> alignb 4
   218                              <1> ; 21/02/2016
   219 0000E820 <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 0000E824 <res 00000004>      <1> DelFile_FCluster:	resd 1
   223 0000E828 <res 00000002>      <1> DelFile_EntryCounter:	resw 1
   224 0000E82A <res 00000001>      <1> DelFile_LNEL:		resb 1
   225 0000E82B <res 00000001>      <1> resb 1
   226                              <1> 
   227                              <1> ; DIR.ASM
   228 0000E82C <res 00000004>      <1> mkdir_DirName_Offset: 	resd 1
   229 0000E830 <res 00000004>      <1> mkdir_FFCluster:	resd 1
   230 0000E834 <res 00000004>      <1> mkdir_LastDirCluster:	resd 1
   231 0000E838 <res 00000004>      <1> mkdir_FreeSectors:	resd 1
   232 0000E83C <res 00000002>      <1> mkdir_attrib:		resw 1 
   233 0000E83E <res 00000001>      <1> mkdir_SecPerClust:	resb 1
   234 0000E83F <res 00000001>      <1> mkdir_add_new_cluster:	resb 1
   235 0000E840 <res 0000000D>      <1> mkdir_Name:		resb 13
   236 0000E84D <res 00000002>      <1> resw 1 ; 01/03/2016
   237                              <1> ; 27/02/2016
   238 0000E84F <res 00000001>      <1> RmDir_MultiClusters:	resb 1  
   239 0000E850 <res 00000004>      <1> RmDir_DirEntryOffset:	resd 1 ; 01/03/2016 (word -> dword)
   240 0000E854 <res 00000004>      <1> RmDir_ParentDirCluster: resd 1
   241 0000E858 <res 00000004>      <1> RmDir_DirLastCluster:   resd 1
   242 0000E85C <res 00000004>      <1> RmDir_PreviousCluster:  resd 1
   243                              <1> ; 22/02/2016
   244 0000E860 <res 00000001>      <1> UPDLMDT_CDirLevel:	resb 1
   245 0000E861 <res 00000004>      <1> UPDLMDT_CDirFCluster:	resd 1
   246                              <1> 	
   247 0000E865 <res 00000003>      <1> alignb 4
   248                              <1> ; DRV_FAT.ASM ; 21/08/2011
   249 0000E868 <res 00000004>      <1> gffc_next_free_cluster:  resd 1
   250 0000E86C <res 00000004>      <1> gffc_first_free_cluster: resd 1
   251 0000E870 <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 0000E874 <res 00000004>      <1> ClusterValue:	resd 1
   257                              <1> ; 04/03/2016
   258 0000E878 <res 00000001>      <1> Attributes:	resb 1 
   259                              <1> ;;CFS_error:  resb 1 ;; 01/03/2016
   260 0000E879 <res 00000001>      <1> resb 1
   261 0000E87A <res 00000001>      <1> CFS_OPType: resb 1
   262 0000E87B <res 00000001>      <1> CFS_Drv:    resb 1
   263 0000E87C <res 00000004>      <1> CFS_CC:	    resd 1
   264 0000E880 <res 00000004>      <1> CFS_FAT32FSINFOSEC: resd 1
   265 0000E884 <res 00000004>      <1> CFS_FAT32FC: resd 1
   266                              <1> 
   267                              <1> ; 27/02/2016
   268                              <1> ;alignb 4
   269 0000E888 <res 00000004>      <1> glc_prevcluster: resd 1 ; DRV_FAT.ASM (21/08/2011)
   270                              <1> 
   271                              <1> ; DIR.ASM
   272 0000E88C <res 00000002>      <1> DLN_EntryNumber: resw 1
   273 0000E88E <res 00000001>      <1> DLN_40h:	 resb 1
   274                              <1> ; 28/02/2016
   275 0000E88F <res 00000001>      <1> TCC_FATErr:	 resb 1 ; DRV_FAT.ASM
   276                              <1> 
   277                              <1> alignb 4
   278                              <1> ; DIR.ASM (09/10/2011)
   279 0000E890 <res 00000002>      <1> LCDE_EntryIndex: resw 1 ; LCDE_EntryOffset
   280 0000E892 <res 00000002>      <1> LCDE_ClusterSN:  resw 1
   281 0000E894 <res 00000004>      <1> LCDE_Cluster: 	 resd 1
   282 0000E898 <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 0000E89C <res 00000004>      <1> SourceFilePath:	     resd 1
   288 0000E8A0 <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 0000E8A4 <res 00000001>      <1> SourceFile_Drv:			resb 1
   295 0000E8A5 <res 00000041>      <1> SourceFile_Directory:		resb 65
   296 0000E8E6 <res 0000000D>      <1> SourceFile_Name:		resb 13
   297                              <1> SourceFile_LongNameEntryLength: 
   298 0000E8F3 <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 0000E8F4 <res 00000002>      <1> SourceFile_AttributesMask:	resw 1
   302 0000E8F6 <res 00000020>      <1> SourceFile_DirEntry:		resb 32
   303 0000E916 <res 00000004>      <1> SourceFile_DirFirstCluster:	resd 1
   304 0000E91A <res 00000004>      <1> SourceFile_DirCluster:		resd 1
   305 0000E91E <res 00000002>      <1> SourceFile_DirEntryNumber:	resw 1
   306 0000E920 <res 00000002>      <1> SourceFile_MatchCounter:	resw 1
   307                              <1> ; 16/03/2016
   308 0000E922 <res 00000001>      <1> SourceFile_SecPerClust:		resb 1
   309 0000E923 <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 0000E924 <res 00000001>      <1> DestinationFile_Drv:		resb 1
   314 0000E925 <res 00000041>      <1> DestinationFile_Directory: 	resb 65
   315 0000E966 <res 0000000D>      <1> DestinationFile_Name:		resb 13
   316                              <1> DestinationFile_LongNameEntryLength:
   317 0000E973 <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 0000E974 <res 00000002>      <1> DestinationFile_AttributesMask: resw 1
   321 0000E976 <res 00000020>      <1> DestinationFile_DirEntry:	resb 32
   322 0000E996 <res 00000004>      <1> DestinationFile_DirFirstCluster: resd 1
   323 0000E99A <res 00000004>      <1> DestinationFile_DirCluster:	resd 1
   324 0000E99E <res 00000002>      <1> DestinationFile_DirEntryNumber: resw 1
   325 0000E9A0 <res 00000002>      <1> DestinationFile_MatchCounter:	resw 1
   326                              <1> ; 16/03/2016
   327 0000E9A2 <res 00000001>      <1> DestinationFile_SecPerClust:	resb 1
   328 0000E9A3 <res 00000001>      <1> DestinationFile_Reserved:	resb 1
   329                              <1> ; Above is 128 bytes
   330                              <1> 
   331                              <1> ; 24/04/2016
   332 0000E9A4 <res 00000002>      <1> resw 1
   333                              <1> 
   334                              <1> ; 10/03/2016
   335                              <1> ; FILE.ASM
   336 0000E9A6 <res 00000001>      <1> move_cmd_phase:	   resb 1
   337 0000E9A7 <res 00000001>      <1> msftdf_sf_df_drv:  resb 1
   338 0000E9A8 <res 00000004>      <1> msftdf_drv_offset: resd 1
   339                              <1> 
   340                              <1> ; 11/03/2016
   341                              <1> ; DRV_FAT.ASM (21/08/2011)
   342 0000E9AC <res 00000004>      <1> FAT_anc_LCluster:  resd 1
   343 0000E9B0 <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 0000E9B4 <res 00000004>      <1> mem_ipg_count:	resd 1 ; page count (for contiguous allocation)
   351 0000E9B8 <res 00000004>      <1> mem_pg_count:	resd 1 ; page count (for count down)
   352 0000E9BC <res 00000004>      <1> mem_aperture:	resd 1 ; contiguous free pages (current)
   353 0000E9C0 <res 00000004>      <1> mem_max_aperture: resd 1 ; maximum value of contiguous free pages
   354 0000E9C4 <res 00000004>      <1> mem_pg_pos:	resd 1 ; mem. position (page #) of current aperture
   355 0000E9C8 <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 0000E9CC <res 00000001>      <1> copy_cmd_phase:       resb 1
   360 0000E9CD <res 00000001>      <1> csftdf_rw_err:	      resb 1
   361 0000E9CE <res 00000001>      <1> DestinationFileFound: resb 1
   362 0000E9CF <res 00000001>      <1> csftdf_cdrv: 	      resb 1
   363 0000E9D0 <res 00000004>      <1> csftdf_filesize:      resd 1
   364                              <1> ; TRDOS386 (TRDOS v2.0)
   365 0000E9D4 <res 00000004>      <1> csftdf_sf_mem_addr:   resd 1
   366 0000E9D8 <res 00000004>      <1> csftdf_sf_mem_bsize:  resd 1
   367                              <1> ;
   368                              <1> 
   369 0000E9DC <res 00000004>      <1> csftdf_sf_cluster:    resd 1 ; 16/03/2016
   370 0000E9E0 <res 00000004>      <1> csftdf_df_cluster:    resd 1
   371                              <1> ; 16/03/2016
   372 0000E9E4 <res 00000004>      <1> csftdf_r_size:        resd 1
   373 0000E9E8 <res 00000004>      <1> csftdf_w_size:        resd 1
   374 0000E9EC <res 00000004>      <1> csftdf_sf_rbytes:     resd 1
   375 0000E9F0 <res 00000004>      <1> csftdf_df_wbytes:     resd 1
   376 0000E9F4 <res 00000001>      <1> csftdf_percentage:    resb 1
   377                              <1> ; 17/03/2016
   378 0000E9F5 <res 00000001>      <1> csftdf_videopage:     resb 1
   379 0000E9F6 <res 00000002>      <1> csftdf_cursorpos:     resw 1
   380 0000E9F8 <res 00000004>      <1> csftdf_sf_drv_dt:     resd 1
   381 0000E9FC <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 0000EA00 <res 00000004>      <1> createfile_Name_Offset:  resd 1
   387 0000EA04 <res 00000004>      <1> createfile_FreeSectors:  resd 1 
   388 0000EA08 <res 00000004>      <1> createfile_size:         resd 1
   389 0000EA0C <res 00000004>      <1> createfile_FFCluster:    resd 1 ; 11/03/2016
   390 0000EA10 <res 00000004>      <1> createfile_LastDirCluster: resd 1
   391 0000EA14 <res 00000004>      <1> createfile_Cluster:      resd 1
   392 0000EA18 <res 00000004>      <1> createfile_PCluster:     resd 1
   393 0000EA1C <res 00000001>      <1> createfile_attrib:	 resb 1
   394 0000EA1D <res 00000001>      <1> createfile_SecPerClust:  resb 1
   395 0000EA1E <res 00000002>      <1> createfile_DirIndex:     resw 1
   396 0000EA20 <res 00000004>      <1> createfile_CCount:	 resd 1
   397 0000EA24 <res 00000002>      <1> createfile_BytesPerSec:	 resw 1 ; 23/03/2016
   398 0000EA26 <res 00000001>      <1> createfile_wfc:	         resb 1
   399 0000EA27 <res 00000001>      <1> createfile_UpdatePDir:	 resb 1 ; 31/03/2016
   400                              <1> 
   401                              <1> ;alignb 4
   402                              <1> 
   403                              <1> ; 11/04/2016
   404 0000EA28 <res 00000002>      <1> env_var_length:	   resw 1
   405                              <1> 
   406 0000EA2A <res 00000002>      <1> alignb 4
   407                              <1> 
   408                              <1> ; 25/04/2016
   409 0000EA2C <res 00000001>      <1> readi.valid:	resb 1 ; valid data (>0 = valid for readi)
   410 0000EA2D <res 00000001>      <1> readi.drv:	resb 1 ; drive number (0, 1,2,3,4..)
   411 0000EA2E <res 00000001>      <1> readi.spc:	resb 1 ; sectors per cluster for 'readi' drive
   412 0000EA2F <res 00000001>      <1> readi.s_index:  resb 1 ; sector index in current cluster (buffer)
   413 0000EA30 <res 00000004>      <1> readi.sector:	resd 1 ; current disk sector
   414 0000EA34 <res 00000002>      <1> readi.bpc:	resw 1 ; bytes per cluster - 1
   415 0000EA36 <res 00000002>      <1> readi.offset:	resw 1 ; byte offset in cluster buffer
   416 0000EA38 <res 00000004>      <1> readi.cluster:  resd 1 ; current cluster number
   417 0000EA3C <res 00000004>      <1> readi.c_index:	resd 1 ; cluster index of the current cluster (0,1,2,3..)
   418 0000EA40 <res 00000004>      <1> readi.fclust:	resd 1 ; first cluster of the current cluster
   419 0000EA44 <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 0000EA48 <res 00000001>      <1> writei.valid:	resb 1 ; valid data (>0 = valid for writei)
   423 0000EA49 <res 00000001>      <1> writei.drv:	resb 1 ; drive number (0, 1,2,3,4..)
   424 0000EA4A <res 00000001>      <1> writei.spc:	resb 1 ; sectors per cluster for 'writei' drive
   425 0000EA4B <res 00000001>      <1> writei.s_index: resb 1 ; sector index in current cluster (buffer)
   426 0000EA4C <res 00000004>      <1> writei.sector:	resd 1 ; current disk sector
   427 0000EA50 <res 00000002>      <1> writei.bpc:	resw 1 ; bytes per cluster - 1
   428 0000EA52 <res 00000002>      <1> writei.offset:	resw 1 ; byte offset in cluster buffer
   429 0000EA54 <res 00000004>      <1> writei.cluster: resd 1 ; current cluster number
   430 0000EA58 <res 00000004>      <1> writei.c_index:	resd 1 ; cluster index of the current cluster (0,1,2,3..)
   431 0000EA5C <res 00000004>      <1> writei.fclust:  resd 1 ; first cluster of the current cluster
   432 0000EA60 <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 0000EA64 <res 00000004>      <1> Run_CDirFC:	resd 1
   437 0000EA68 <res 00000001>      <1> Run_Auto_Path:	resb 1
   438 0000EA69 <res 00000001>      <1> Run_Manual_Path: resb 1 ; 0 -> auto path sequence needed
   439 0000EA6A <res 00000001>      <1> EXE_ID:		resb 1	
   440 0000EA6B <res 00000001>      <1> EXE_dot:	resb 1
   441                              <1> 
   442                              <1> ; 06/05/2016
   443 0000EA6C <res 00000004>      <1> mainprog_return_addr: resd 1
   444 0000EA70 <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 0000EA74 <res 00000004>      <1> video_eax:	resd 1  ; eax return value of video function
   449                              <1> 
   450                              <1> ; 01/06/2016
   451 0000EA78 <res 00000004>      <1> user_buffer:	resd 1  ; 'diskio.s' (INT 33h, Function 08h, floppy disk type)
   452                              <1> 
   453                              <1> ; 21/05/2016 - TRDOS 386 ('swap/switch', 'rswap', [u.pri])
   454 0000EA7C <res 00000001>      <1> priority:	resb 1  ; running priority level of process (0,1,2)
   455                              <1> 			; (run queue which is process comes from)
   456                              <1> ; 22/05/2016 - TRDOS 386 ('set_run_sequence', 'rtc_int', 'u_timer')
   457 0000EA7D <res 00000001>      <1> p_change:	resb 1  ; process change status (for timer events)
   458                              <1> ; 23/05/2016 - TRDOS 386 ('clock')
   459 0000EA7E <res 00000001>      <1> multi_tasking:	resb 1   ; Multi Tasking status (0 = disabled, >0 = enabled)
   460                              <1> 			; (EBX will return with user buffer addr or disk type)
   461                              <1> ; 07/06/2016
   462 0000EA7F <res 00000001>      <1> timer_events:	resb 1  ; number of (active) timer events, <= 16		
   463                              <1> 
   464                              <1> ; 29/05/2016
   465 0000EA80 <res 00000001>      <1> set_mode_clear:	resb 1  ; > 0 = clear video page (and reset it's cursor pos.)
   466                              <1> 			; 0 = clear all of regen buffer, reset all cursor pos.
   467                              <1> ; 24/06/2016
   468 0000EA81 <res 00000001>      <1> w_str_cmd:	resb 1	; WRITE_STRING command (0,1,2,3) ; video.s
   469 0000EA82 <res 00000001>      <1> p_crt_mode:	resb 1  ; previous video mode (=3 or 0), backup mark/sign
   470                              <1> ; 26/06/2016
   471 0000EA83 <res 00000001>      <1> p_crt_page:	resb 1  ; previous active page (for 'set_mode')
   472                              <1> alignb 2
   473 0000EA84 <res 00000002>      <1> CRT_LEN:	resw 1  ; length of regen buffer
   474 0000EA86 <res 00000010>      <1> cursor_pposn:	resw 8  ; cursor positions backup
   475                              <1> ; 01/07/2016
   476 0000EA96 <res 00000004>      <1> EXT_PTR:	resd 1	; pointer extended characters (for graphics modes)
   477                              <1> ;EXT_GFX_TBL:
   478 0000EA9A <res 00000400>      <1> 		resb 8*128 ; 128 graphics chacters, each one is 8 bytes	
  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                              <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 0000EE9A <res 00000002>      <1> 	i.flgs:	 resw 1
    37 0000EE9C <res 00000001>      <1> 	i.nlks:	 resb 1
    38 0000EE9D <res 00000001>      <1> 	i.uid:	 resb 1
    39                              <1>         ;i.size:  resw 1 ; size
    40 0000EE9E <res 00000002>      <1> 	resw 1 ; 29/04/2016
    41 0000EEA0 <res 00000010>      <1> 	i.dskp:	 resw 8 ; 16 bytes
    42 0000EEB0 <res 00000004>      <1> 	i.ctim:	 resd 1
    43 0000EEB4 <res 00000004>      <1> 	i.mtim:	 resd 1
    44 0000EEB8 <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 0000EEBA <res 00000020>      <1>         p.pid:   resw nproc
    57 0000EEDA <res 00000020>      <1>         p.ppid:  resw nproc
    58 0000EEFA <res 00000020>      <1>         p.break: resw nproc
    59 0000EF1A <res 00000010>      <1>         p.ttyc:  resb nproc ; console tty in Retro UNIX 8086 v1.
    60 0000EF2A <res 00000010>      <1> 	p.waitc: resb nproc ; waiting channel in Retro UNIX 8086 v1.
    61 0000EF3A <res 00000010>      <1> 	p.link:	 resb nproc
    62 0000EF4A <res 00000010>      <1> 	p.stat:	 resb nproc
    63                              <1> 
    64                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 feature only !) 
    65 0000EF5A <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 0000EF9A <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 0000EFAA <res 000001F4>      <1> fsp:	 resb nfiles * 10 ; 11/05/2015 (8 -> 10)
   104 0000F19E <res 00000018>      <1> bufp:	 resd (nbuf+2) ; will be initialized 
   105 0000F1B6 <res 00000002>      <1> idev:	 resw 1 ; device number is 1 byte in Retro UNIX 8086 v1 !
   106 0000F1B8 <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 0000F1BA <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 0000F1BB <res 00000001>      <1> mdev:	 resb 1 ; mounted device number ; Retro UNIX 8086 v1 feature only!
   122                              <1> ; 15/04/2015
   123 0000F1BC <res 00000001>      <1> active:	 resb 1 
   124 0000F1BD <res 00000001>      <1> 	 resb 1 ; 09/06/2015
   125 0000F1BE <res 00000002>      <1> mnti:	 resw 1
   126 0000F1C0 <res 00000002>      <1> mpid:	 resw 1
   127 0000F1C2 <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 0000F1C4 <res 00000002>      <1> runq_event:	 resw 1 ; high priority, 'run for event'            ; 2
   132 0000F1C6 <res 00000002>      <1> runq_normal:	 resw 1 ; normal/regular priority, 'run as reqular' ; 1
   133 0000F1C8 <res 00000002>      <1> runq_background: resw 1 ; low priority, 'run on background'         ; 0
   134                              <1> ;
   135 0000F1CA <res 00000001>      <1> imod:	 resb 1
   136 0000F1CB <res 00000001>      <1> smod:	 resb 1
   137 0000F1CC <res 00000001>      <1> mmod:	 resb 1
   138 0000F1CD <res 00000001>      <1> sysflg:	 resb 1
   139                              <1> 
   140 0000F1CE <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 0000F1D0 <res 00000004>      <1> 	u.sp:	  resd 1 ; esp (kernel stack at the beginning of 'sysent')
   160 0000F1D4 <res 00000004>      <1> 	u.usp:	  resd 1 ; esp (kernel stack points to user's registers)
   161 0000F1D8 <res 00000004>      <1> 	u.r0:	  resd 1 ; eax
   162 0000F1DC <res 00000002>      <1> 	u.cdir:	  resw 1
   163 0000F1DE <res 0000000A>      <1> 	u.fp:	  resb 10
   164 0000F1E8 <res 00000004>      <1> 	u.fofp:	  resd 1
   165 0000F1EC <res 00000004>      <1> 	u.dirp:	  resd 1
   166 0000F1F0 <res 00000004>      <1> 	u.namep:  resd 1
   167 0000F1F4 <res 00000004>      <1> 	u.off:	  resd 1
   168 0000F1F8 <res 00000004>      <1> 	u.base:	  resd 1
   169 0000F1FC <res 00000004>      <1> 	u.count:  resd 1
   170 0000F200 <res 00000004>      <1> 	u.nread:  resd 1
   171 0000F204 <res 00000004>      <1> 	u.break:  resd 1 ; break
   172 0000F208 <res 00000002>      <1> 	u.ttyp:	  resw 1 
   173 0000F20A <res 00000010>      <1> 	u.dirbuf: resb 16 ; 04/12/2015 (10 -> 16) 
   174                              <1> 	;u.pri:	  resw 1 ; 14/02/2014
   175 0000F21A <res 00000001>      <1> 	u.quant:  resb 1 ; Retro UNIX 8086 v1 Feature only ! (uquant)
   176 0000F21B <res 00000001>      <1> 	u.pri:	  resb 1 ; Modification: 21/05/2016 (priority levels: 0, 1, 2)
   177 0000F21C <res 00000002>      <1> 	u.intr:	  resw 1
   178 0000F21E <res 00000002>      <1> 	u.quit:	  resw 1
   179                              <1> 	;u.emt:	  resw 1 ; 10/10/2013
   180 0000F220 <res 00000002>      <1> 	u.ilgins: resw 1
   181 0000F222 <res 00000002>      <1> 	u.cdrv:	  resw 1 ; cdev
   182 0000F224 <res 00000001>      <1> 	u.uid:	  resb 1 ; uid
   183 0000F225 <res 00000001>      <1> 	u.ruid:	  resb 1
   184 0000F226 <res 00000001>      <1> 	u.bsys:	  resb 1
   185 0000F227 <res 00000001>      <1> 	u.uno:	  resb 1
   186 0000F228 <res 00000004>      <1>         u.upage:  resd 1 ; 16/04/2015 - Retro Unix 386 v1 feature only !
   187                              <1> 	; tty number (rtty, rcvt, wtty)
   188 0000F22C <res 00000001>      <1> 	u.ttyn:	  resb 1 ; 28/07/2013 - Retro Unix 8086 v1 feature only !
   189                              <1> 	; last error number
   190 0000F22D <res 00000004>      <1> 	u.error:  resd 1 ; 28/07/2013 - 09/03/2015 
   191                              <1> 		        ; Retro UNIX 8086/386 v1 feature only!
   192 0000F231 <res 00000004>      <1> 	u.pgdir:  resd 1 ; 09/03/2015 (page dir addr of process)
   193 0000F235 <res 00000004>      <1> 	u.ppgdir: resd 1 ; 06/05/2015 (page dir addr of the parent process)
   194 0000F239 <res 00000004>      <1> 	u.pbase:  resd 1 ; 20/05/2015 (physical base/transfer address)
   195 0000F23D <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 0000F23F <res 00000001>      <1> 	u.kcall:  resb 1 ; The caller is 'namei' (dskr) or 'mkdir' (dskw) sign		
   202 0000F240 <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 0000F241 <res 00000004>      <1> 	u.pfcount: resd 1 ; page fault count for (this) process (for sys geterr)
   212                              <1> 
   213 0000F245 <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 0000F248 <res 00000004>      <1> pcore:  resd 1 ; physical start address of user's memory space (for sys exec)
   219 0000F24C <res 00000004>      <1> ecore:  resd 1 ; physical start address of user's memory space (for sys exec)
   220 0000F250 <res 00000004>      <1> nbase:	resd 1	; physical base address for 'namei' & 'sysexec'
   221 0000F254 <res 00000002>      <1> ncount: resw 1	; remain byte count in page for 'namei' & 'sysexec'
   222 0000F256 <res 00000002>      <1> argc:	resw 1	; argument count for 'sysexec'
   223 0000F258 <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 0000F25C <res 00000001>      <1> rw: 	 resb 1 ;; Read/Write sign (iget)
   228                              <1> 
   229                              <1> ;alignb 4
   230                              <1> 
   231                              <1> ; 24/04/2016
   232 0000F25D <res 00000004>      <1> ii:		resd 1 ; first cluster of the program file
   233 0000F261 <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 0000F265 <res 00000008>      <1> 	resb	8 
   239                              <1> readi_buffer:
   240 0000F26D <res 00000200>      <1> 	resb 	512
   241 0000F46D <res 00000008>      <1> 	resb	8
   242                              <1> writei_buffer:
   243 0000F475 <res 00000200>      <1> 	resb	512	
   244 0000F675 <res 00000410>      <1> 	resb (nbuf-2) * 520
   245                              <1> 
   246 0000FA85 <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 0000FA8D <res 00000002>      <1> 	resw 1
   256 0000FA8F <res 00000168>      <1> 	resb 360 ; 2880 sectors ; original UNIX v1 value: 128
   257 0000FBF7 <res 00000002>      <1> 	resw 1
   258 0000FBF9 <res 00000020>      <1> 	resb 32	 ; 256+40 inodes ; original UNIX v1 value: 64
   259 0000FC19 <res 00000004>      <1> 	s.time:	 resd 1
   260 0000FC1D <res 00000004>      <1> 	s.syst:	 resd 1
   261 0000FC21 <res 00000004>      <1>         s.wait_: resd 1 ; wait
   262 0000FC25 <res 00000004>      <1> 	s.idlet: resd 1
   263 0000FC29 <res 00000004>      <1> 	s.chrgt: resd 1
   264 0000FC2D <res 00000002>      <1> 	s.drerr: resw 1
   265                              <1> 
   266                              <1> S_SIZE	equ $ - systm
   267                              <1> 
   268 0000FC2F <res 0000005E>      <1> 	resb 512-S_SIZE ; 03/06/2015	 
   269                              <1> 
   270 0000FC8D <res 00000008>      <1> sb1:	resd 2
   271                              <1> ; (mounted disk) super block buffer
   272                              <1> mount:	
   273 0000FC95 <res 00000200>      <1> 	resb 512  ; 03/06/2015
  2548                                  
  2549 0000FE95 <res 00000003>          alignb 4
  2550                                  
  2551                                  ; 23/05/2016 (TRDOS 386)
  2552                                  ; 14/10/2015 (Retro UNIX 386 v1, 'unix386.s')
  2553 0000FE98 <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 0000FE9C <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 0000FF9C <res 00000002>          swpq_count: resw 1 ; count of pages on the swap queue
  2573 0000FF9E <res 00000004>          swp_drv:    resd 1 ; logical drive description table address of the swap drive/disk
  2574 0000FFA2 <res 00000004>          swpd_size:  resd 1 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
  2575 0000FFA6 <res 00000004>          swpd_free:  resd 1 ; free page blocks (4096 bytes) on swap disk/drive (logical)
  2576 0000FFAA <res 00000004>          swpd_next:  resd 1 ; next free page block
  2577 0000FFAE <res 00000004>          swpd_last:  resd 1 ; last swap page block	
  2578                                  
  2579 0000FFB2 <res 00000002>          alignb 4
  2580                                  
  2581                                  ; 10/07/2015
  2582                                  ; 28/08/2014
  2583 0000FFB4 <res 00000004>          error_code:	resd 1
  2584                                  ; 29/08/2014
  2585 0000FFB8 <res 00000004>          FaultOffset: 	resd 1
  2586                                  ; 21/09/2015
  2587 0000FFBC <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
