     1                                  ; ****************************************************************************
     2                                  ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.3
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Last Update: 22/12/2020
     5                                  ; ----------------------------------------------------------------------------
     6                                  ; Beginning: 04/01/2016
     7                                  ; ----------------------------------------------------------------------------
     8                                  ; Assembler: NASM version 2.15 (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                                  ; nasm trdos386.s -l trdos386.txt -o TRDOS386.SYS
    22                                  
    23                                  
    24                                  KLOAD	equ 10000h ; Kernel loading address
    25                                  	; NOTE: Retro UNIX 8086 v1 /boot code loads kernel at 1000h:0000h 
    26                                  KCODE	equ 08h	; Code segment descriptor (ring 0)
    27                                  KDATA	equ 10h	; Data segment descriptor (ring 0)
    28                                  ; 19/03/2015
    29                                  UCODE	equ 1Bh ; 18h + 3h  (ring 3)
    30                                  UDATA	equ 23h ; 20h + 3h  (ring 3)
    31                                  ; 24/03/2015
    32                                  TSS	equ 28h	; Task state segment descriptor (ring 0)
    33                                  ; 19/03/2015
    34                                  CORE	equ 400000h  ; Start of USER's virtual/linear address space 
    35                                  		     ; (at the end of the 1st 4MB)
    36                                  ECORE	equ 0FFC00000h ; End of USER's virtual address space (4GB - 4MB)
    37                                  		     ; ULIMIT = (ECORE/4096) - 1 = 0FFBFFh (in GDT)
    38                                  
    39                                  ;; 27/12/2013
    40                                  ;KEND    equ KLOAD + 65536 ; (28/12/2013) (end of kernel space)
    41                                  ; 04/07/2016
    42                                  KEND    equ KERNELFSIZE + KLOAD
    43                                  
    44                                  
    45                                  ; IBM PC/AT BIOS ----- 10/06/85 (postequ.inc)
    46                                  ;--------- CMOS TABLE LOCATION ADDRESS'S -------------------------------------
    47                                  CMOS_SECONDS	EQU	00H		; SECONDS (BCD)
    48                                  CMOS_SEC_ALARM	EQU	01H		; SECONDS ALARM (BCD)
    49                                  CMOS_MINUTES	EQU	02H		; MINUTES (BCD)
    50                                  CMOS_MIN_ALARM	EQU	03H		; MINUTES ALARM (BCD) 	
    51                                  CMOS_HOURS	EQU	04H		; HOURS (BCD
    52                                  CMOS_HR_ALARM	EQU	005H		; HOURS ALARM   (BCD)
    53                                  CMOS_DAY_WEEK	EQU	06H		; DAY OF THE WEEK  (BCD)
    54                                  CMOS_DAY_MONTH	EQU	07H		; DAY OF THE MONTH (BCD) 
    55                                  CMOS_MONTH	EQU	08H		; MONTH (BCD)
    56                                  CMOS_YEAR	EQU	09H		; YEAR (TWO DIGITS) (BCD)
    57                                  CMOS_CENTURY	EQU	32H		; DATE CENTURY BYTE (BCD)
    58                                  CMOS_REG_A	EQU	0AH		; STATUS REGISTER A
    59                                  CMOS_REG_B	EQU	00BH		; STATUS REGISTER B  ALARM
    60                                  CMOS_REG_C	EQU	00CH		; STATUS REGISTER C  FLAGS
    61                                  CMOS_REG_D	EQU	0DH		; STATUS REGISTER D  BATTERY
    62                                  CMOS_SHUT_DOWN	EQU	0FH		; SHUTDOWN STATUS COMMAND BYTE
    63                                  ;----------------------------------------
    64                                  ;	CMOS EQUATES FOR THIS SYSTEM	;
    65                                  ;-----------------------------------------------------------------------------
    66                                  CMOS_PORT	EQU	070H		; I/O ADDRESS OF CMOS ADDRESS PORT
    67                                  CMOS_DATA	EQU	071H		; I/O ADDRESS OF CMOS DATA PORT
    68                                  NMI		EQU	10000000B	; DISABLE NMI INTERRUPTS MASK -
    69                                  					; HIGH BIT OF CMOS LOCATION ADDRESS
    70                                  
    71                                  ; Memory Allocation Table Address
    72                                  ; 05/11/2014
    73                                  ; 31/10/2014
    74                                  MEM_ALLOC_TBL	equ	100000h		; Memory Allocation Table at the end of
    75                                  					; the 1st 1 MB memory space.
    76                                  					; (This address must be aligned
    77                                  					;  on 128 KB boundary, if it will be
    78                                  					;  changed later.)
    79                                  					; ((lower 17 bits of 32 bit M.A.T.
    80                                  					;   address must be ZERO)).
    81                                  					; ((((Reason: 32 bit allocation 
    82                                  					;     instructions, dword steps)))
    83                                  					; (((byte >> 12 --> page >> 5)))  
    84                                  ;04/11/2014	
    85                                  PDE_A_PRESENT	equ	1		; Present flag for PDE
    86                                  PDE_A_WRITE	equ 	2		; Writable (write permission) flag
    87                                  PDE_A_USER	equ	4		; User (non-system/kernel) page flag
    88                                  ;
    89                                  PTE_A_PRESENT	equ	1		; Present flag for PTE (bit 0)
    90                                  PTE_A_WRITE	equ 	2		; Writable (write permission) flag (bit 1)
    91                                  PTE_A_USER	equ	4		; User (non-system/kernel) page flag (bit 2)
    92                                  PTE_A_ACCESS    equ	32		; Accessed flag (bit 5) ; 09/03/2015
    93                                  
    94                                  ; 17/02/2015 (unix386.s)
    95                                  ; 10/12/2014 - 30/12/2014 (0B000h -> 9000h) (dsectrm2.s)
    96                                  DPT_SEGM equ 09000h  ; FDPT segment (EDD v1.1, EDD v3)
    97                                  ;
    98                                  HD0_DPT	 equ 0	    ; Disk parameter table address for hd0
    99                                  HD1_DPT	 equ 32	    ; Disk parameter table address for hd1
   100                                  HD2_DPT	 equ 64	    ; Disk parameter table address for hd2
   101                                  HD3_DPT	 equ 96	    ; Disk parameter table address for hd3
   102                                  
   103                                  ; 15/11/2020
   104                                  VBE3INFOSEG equ 97E0h ; 512 bytes before Video_Pg_Backup
   105                                  ; 15/12/2020
   106                                  VBE3MODEINFOSEG equ 97C0h ; 512 bytes before VBE3INFOBLOCK 
   107                                  
   108                                  ; 29/11/2020
   109                                  VBE3INFOBLOCK equ 97E00h ; linear address (512 bytes)
   110                                  VBE3MODEINFOBLOCK equ 97C00h ; linear address (256 bytes)
   111                                  VBE3SAVERESTOREBLOCK equ 97600h ; linear address (2048 bytes)
   112                                  VBE3CRTCINFOBLOCK equ 97D00h ; linear address (64 bytes)
   113                                  VBE3BIOSDATABLOCK equ 97000h ; linear address (1536 bytes)
   114                                  VBE3STACKADDR equ 96000h ; linear address (1024 bytes)
   115                                  ; VBE3 32 bit Protected Mode Interface (16 bit) Selectors (in GDT)
   116                                  VBE3CS equ 30h ; _vbe3_CS:
   117                                  VBE3BDS equ 38h ; _vbe3_BDS:
   118                                  VBE3A000 equ 40h ; _A0000Sel:
   119                                  VBE3B000 equ 48h ; _B0000Sel:
   120                                  VBE3B800 equ 50h ; _B8000Sel:
   121                                  VBE3DS equ 58h ; _vbe3_DS:
   122                                  VBE3SS equ 60h ; _vbe3_SS:
   123                                  VBE3ES equ 68h ; _vbe3_ES:
   124                                  KCODE16 equ 70h ; _16bit_CS:
   125                                  ; 06/12/2020
   126                                  VBE3MODE3STATE equ 95800h	
   127                                  
   128                                  ; FDPT (Phoenix, Enhanced Disk Drive Specification v1.1, v3.0)
   129                                  ;      (HDPT: Programmer's Guide to the AMIBIOS, 1993)
   130                                  ;
   131                                  FDPT_CYLS	equ 0 ; 1 word, number of cylinders
   132                                  FDPT_HDS	equ 2 ; 1 byte, number of heads
   133                                  FDPT_TT		equ 3 ; 1 byte, A0h = translated FDPT with logical values
   134                                  		      ; otherwise it is standard FDPT with physical values 	
   135                                  FDPT_PCMP	equ 5 ; 1 word, starting write precompensation cylinder
   136                                  		      ; (obsolete for IDE/ATA drives)
   137                                  FDPT_CB		equ 8 ; 1 byte, drive control byte
   138                                  			; Bits 7-6 : Enable or disable retries (00h = enable)
   139                                  			; Bit 5	: 1 = Defect map is located at last cyl. + 1
   140                                  			; Bit 4 : Reserved. Always 0
   141                                  			; Bit 3 : Set to 1 if more than 8 heads
   142                                  			; Bit 2-0 : Reserved. Alsways 0
   143                                  FDPT_LZ		equ 12 ; 1 word, landing zone (obsolete for IDE/ATA drives)
   144                                  FDPT_SPT	equ 14 ; 1 byte, sectors per track
   145                                  
   146                                  ; Floppy Drive Parameters Table (Programmer's Guide to the AMIBIOS, 1993)
   147                                  ; (11 bytes long) will be used by diskette handler/bios
   148                                  ; which is derived from IBM PC-AT BIOS (DISKETTE.ASM, 21/04/1986).
   149                                  
   150                                  ; 01/02/2016
   151                                  Logical_DOSDisks equ 90000h + 100h ; 26*256 = 6656 bytes
   152                                  Directory_Buffer equ 80000h ; max = 64K Bytes
   153                                  FAT_Buffer	 equ 91C00h ; 1536 bytes (3 sectors)
   154                                  ; 15/02/2016
   155                                  Cluster_Buffer	 equ 70000h ; max = 64K Bytes ; buffer for file read & write
   156                                  ; 11/04/2016
   157                                  Env_Page:	 equ 93000h ; 512 bytes (4096 bytes)
   158                                  Env_Page_Size	 equ 512    ; (4096 bytes)
   159                                  ; 30/07/2016
   160                                  Video_Pg_Backup	 equ 98000h ; Mode 3h, video page backup (32K, 8 pages)
   161                                  
   162                                  ; 29/11/2020
   163                                  ; Free/Reserved memory blocks (in 1st 1MB): 93200h to 96000h (available)
   164                                  ; 06/12/2020
   165                                  ; Free/Reserved memory blocks (in 1st 1MB): 93200h to 95800h (available)
   166                                  
   167                                  ; 15/12/2020
   168                                  LFB_ADDR	equ LFB_Info+LFBINFO.LFB_addr
   169                                  LFB_SIZE	equ LFB_Info+LFBINFO.LFB_size
   170                                   
   171                                  [BITS 16]       ; We need 16-bit intructions for Real mode
   172                                  
   173                                  [ORG 0] 
   174                                  	; 12/11/2014
   175                                  	; Save boot drive number (that is default root drive)
   176 00000000 8816[CA67]              	mov	[boot_drv], dl ; physical drv number
   177                                  
   178                                  	; Determine installed memory
   179                                  	; 31/10/2014
   180                                  	;
   181 00000004 B801E8                  	mov	ax, 0E801h ; Get memory size 
   182 00000007 CD15                    	int	15h	   ; for large configurations
   183 00000009 7308                    	jnc	short chk_ms
   184 0000000B B488                    	mov	ah, 88h    ; Get extended memory size 
   185 0000000D CD15                    	int	15h
   186                                  	;	   
   187                                  	;mov	al, 17h	; Extended memory (1K blocks) low byte
   188                                  	;out	70h, al ; select CMOS register
   189                                  	;in	al, 71h ; read data (1 byte)
   190                                  	;mov	cl, al
   191                                  	;mov	al, 18h ; Extended memory (1K blocks) high byte
   192                                  	;out	70h, al ; select CMOS register
   193                                  	;in	al, 71h ; read data (1 byte)
   194                                  	;mov	ch, al
   195                                   	;      
   196 0000000F 89C1                    	mov	cx, ax
   197 00000011 31D2                    	xor	dx, dx
   198                                  chk_ms:
   199 00000013 890E[C667]              	mov	[mem_1m_1k], cx
   200 00000017 8916[C867]              	mov	[mem_16m_64k], dx
   201                                  	; 05/11/2014
   202                                  	;and	dx, dx
   203                                  	;jz	short L2
   204 0000001B 81F90004                        cmp     cx, 1024
   205                                  	;jnb	short L0
   206 0000001F 7351                    	jnb	short V0 ; 14/11/2020
   207                                  		 ; insufficient memory_error	
   208                                  		 ; Minimum 2 MB memory is needed... 
   209                                  	; 05/11/2014
   210                                  	; (real mode error printing)
   211 00000021 FB                      	sti
   212 00000022 BE[3600]                	mov	si, msg_out_of_memory
   213 00000025 BB0700                  	mov	bx, 7
   214 00000028 B40E                    	mov	ah, 0Eh	; write tty
   215                                  oom_1:
   216 0000002A AC                      	lodsb
   217 0000002B 08C0                    	or	al, al
   218 0000002D 7404                    	jz	short oom_2
   219 0000002F CD10                    	int	10h
   220 00000031 EBF7                    	jmp	short oom_1
   221                                  oom_2:
   222 00000033 F4                              hlt
   223 00000034 EBFD                    	jmp	short oom_2
   224                                  
   225                                  ; 20/02/2017
   226                                  ; 05/11/2014
   227                                  msg_out_of_memory:
   228 00000036 070D0A                  	db 	07h, 0Dh, 0Ah
   229 00000039 496E73756666696369-             db      'Insufficient memory !'
   229 00000042 656E74206D656D6F72-
   229 0000004B 792021             
   230 0000004E 0D0A                    	db	0Dh, 0Ah
   231                                  _int13h_48h_buffer: ; 07/07/2016
   232 00000050 284D696E696D756D20-     	db	'(Minimum 2MB memory is needed.)'
   232 00000059 324D42206D656D6F72-
   232 00000062 79206973206E656564-
   232 0000006B 65642E29           
   233 0000006F 0D0A00                   	db	0Dh, 0Ah, 0
   234                                  V0:
   235                                  	; 15/12/2020
   236 00000072 8B36[C867]              	mov	si, [mem_16m_64k]
   237 00000076 8936[D10E]              	mov	[real_mem_16m_64k], si
   238                                  	; 15/11/2020
   239                                  	; 14/11/2020 (TRDOS 386 v2.0.3)
   240                                  	; check VESA (VBE) VIDEO BIOS version
   241                                  
   242 0000007A B8034F                  	mov	ax, 4F03h  ; Return current VBE mode
   243 0000007D CD10                    	int	10h
   244 0000007F 83F84F                  	cmp	ax, 004Fh  ; successful (vbe) function call
   245 00000082 7554                    	jne	short L0   ; not a VESA VBE compatible bios	
   246                                  
   247                                  	;mov	ah, 3
   248                                  	;;jmp	short v1	
   249                                  	
   250                                  	; 15/11/2020
   251 00000084 BBE097                  	mov	bx, VBE3INFOSEG  ; 97E0h for current version 
   252 00000087 8EC3                    	mov	es, bx
   253 00000089 31FF                    	xor	di, di
   254 0000008B 2666C70556424532        	mov	dword [es:di], 'VBE2' ; request VESA VBE3 info
   255                                  		; es:di = buffer address (512 bytes)
   256                                  	;mov	ax, 4F00h ; Return VBE controller information
   257 00000093 86C4                    	xchg	al, ah
   258 00000095 CD10                    	int	10h
   259                                  	
   260                                  	; dx = cs
   261                                  	; es = VBE3INFOSEG (97E0h)
   262                                  	; di = 0
   263                                  	; ss = (endofkernelfile/16)+16
   264                                  	; sp = 0FFFEh
   265                                  
   266 00000097 83F84F                  	cmp	ax, 004Fh
   267 0000009A 753A                    	jne	short V1 ; old vga bios (not VESA compatible)
   268                                  
   269                                  	; 15/11/2020
   270 0000009C 2666813D56455341        	cmp	dword [es:di], 'VESA'
   271 000000A4 7530                    	jne	short V1
   272                                  	
   273                                  	;mov	ax, [es:di+4]
   274                                  	;	; ax = vbe version in BCD format (0200h or 0300h)
   275                                  	;mov	[vbe3], ah ; version number (major) 	
   276                                  
   277                                  	; 15/11/2020
   278 000000A6 268A4505                	mov	al, [es:di+5]
   279                                  		; al = high byte of VBE version number (02h or 03h)
   280                                  
   281 000000AA A2[4409]                	mov	[vbe3], al ; version number (major) 	
   282                                  			   ; 02h or 03h is expected
   283                                  	; 15/12/2020
   284                                  	; Get linear frame buffer info (for VESA VBE mode 118h)
   285 000000AD BEC097                  	mov	si, VBE3MODEINFOSEG  ; 97C0h for current version
   286 000000B0 8EC6                    	mov	es, si
   287                                   	; di = 0
   288 000000B2 B91841                  	mov	cx, 04118h  ; 1024*768, 24 bpp, LFB
   289 000000B5 B8014F                  	mov	ax, 4F01h ; Return VBE mode information
   290 000000B8 CD10                    	int	10h
   291                                  	;cmp	ax, 4Fh
   292                                  	;jne	short V1
   293                                  	; 19/12/2020
   294                                  	;mov	si, [es:di+MODEINFO.PhysBasePtr+2]
   295                                  			; hw of LFB base address
   296                                  	; MODEINFO structure starts from offset -2
   297 000000BA 268B752A                	mov	si, [es:di+MODEINFO.PhysBasePtr] ; hw of LFB addr
   298 000000BE 8936[D30E]              	mov	[def_LFB_addr], si ; k_LFB_size = 3145728 bytes
   299 000000C2 81EE0001                	sub	si, 256
   300                                  	
   301                                  	; 15/12/2020
   302                                  	; check memory and decrease it to 3.5 GB if it is 4GB
   303                                  	; (reserve upper memory for LFB)
   304 000000C6 8B3E[C867]              	mov	di, [mem_16m_64k]
   305 000000CA 893E[D10E]              	mov	[real_mem_16m_64k], di
   306                                  
   307 000000CE 39F7                    	cmp	di, si
   308 000000D0 7604                    	jna	short V1
   309                                  
   310 000000D2 8936[C867]              	mov	[mem_16m_64k], si
   311                                  
   312                                  	; VESA VBE3 video hardware 
   313                                  	; (example: NVIDIA GEFORCE FX550, 256 MB)
   314                                  	; uses upper memory from 0D0000000h to 0DFFFFFFFh
   315                                  	
   316                                  	;;cmp	di, 0CF00h ; 3328 MB - 16MB
   317                                  	;jna	short V1  ; <= 3328 MB memory, it is not required
   318                                  			  ; decrease
   319                                  	;cmp	al, 3 
   320                                  	;jb	short V2 
   321                                  	; VESA VBE 3
   322                                  	;mov	word [mem_16m_64k], 0CF00h ; 3328 MB - 16MB
   323                                  	;jmp	short V1 	
   324                                  ;V2:
   325                                  	; VESA VBE 2
   326                                  	; Check Bochs/Qemu/VirtualBox Emulator
   327                                  	; LFB base address: 0E0000000h
   328                                  	;sub	ax, ax ; 0
   329                                  	;mov	dx, 1CEh ; VBE_DISPI_IOPORT_INDEX
   330                                  	;out	dx, ax ; VBE_DISPI_INDEX_ID register
   331                                  	;inc	dx
   332                                  	;in	ax, dx
   333                                  	;and	al, 0F0h
   334                                  	;cmp	ax, 0B0C0h
   335                                  	;jne	short V1
   336                                  	;
   337                                  	; BOCHS/QEMU/VIRTUALBOX
   338                                  	;mov	word [mem_16m_64k], 0DF00h ; 3584 MB - 16MB	
   339                                  V1:
   340 000000D6 1E                      	push	ds
   341 000000D7 07                      	pop	es ; restore extra data segment	
   342                                  L0:
   343                                  
   344                                  %include 'diskinit.s' ; 07/03/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.2 - diskinit.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 29/08/2020
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.14 (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> 	; 29/08/2020
    27                              <1> 	; 17/07/2020
    28                              <1> 	; 14/07/2020 (TRDOS 386 v2.0.2)
    29                              <1> 	; 10/12/2014 - 02/02/2015 - dsectrm2.s
    30                              <1> ;L0:
    31                              <1> 	; 12/11/2014 (Retro UNIX 386 v1 - beginning)
    32                              <1> 	; Detecting disk drives... (by help of ROM-BIOS)
    33 000000D8 BA7F00              <1> 	mov	dx, 7Fh
    34                              <1> L1:	
    35 000000DB FEC2                <1> 	inc	dl
    36 000000DD B441                <1> 	mov	ah, 41h ; Check extensions present
    37                              <1> 			; Phoenix EDD v1.1 - EDD v3
    38 000000DF BBAA55              <1> 	mov	bx, 55AAh
    39 000000E2 CD13                <1> 	int 	13h
    40 000000E4 721A                <1> 	jc	short L2
    41                              <1> 
    42 000000E6 81FB55AA            <1> 	cmp	bx, 0AA55h
    43 000000EA 7514                <1> 	jne	short L2
    44 000000EC FE06[CD67]          <1> 	inc	byte [hdc]	; count of hard disks (EDD present)
    45 000000F0 8816[CC67]          <1>         mov     [last_drv], dl  ; last hard disk number
    46 000000F4 BB[5067]            <1> 	mov	bx, hd0_type - 80h
    47 000000F7 01D3                <1> 	add	bx, dx	 
    48 000000F9 880F                <1> 	mov	[bx], cl ; Interface support bit map in CX
    49                              <1> 			 ; Bit 0 - 1, Fixed disk access subset ready
    50                              <1> 			 ; Bit 1 - 1, Drv locking and ejecting ready
    51                              <1> 			 ; Bit 2 - 1, Enhanced Disk Drive Support
    52                              <1>                          ;            (EDD) ready (DPTE ready)
    53                              <1> 			 ; Bit 3 - 1, 64bit extensions are present
    54                              <1>                          ;            (EDD-3)
    55                              <1> 			 ; Bit 4 to 15 - 0, Reserved
    56 000000FB 80FA83              <1> 	cmp	dl, 83h	 ; drive number < 83h
    57 000000FE 72DB                <1> 	jb	short L1
    58                              <1> L2:
    59                              <1> 	; 23/11/2014
    60                              <1> 	; 19/11/2014
    61 00000100 30D2                <1> 	xor	dl, dl  ; 0
    62                              <1> 	; 04/02/2016 (esi -> si)
    63 00000102 BE[CE67]            <1> 	mov	si, fd0_type
    64                              <1> L3:
    65                              <1> 	; 14/01/2015
    66 00000105 8816[CB67]          <1> 	mov	[drv], dl
    67                              <1> 	;
    68 00000109 B408                <1> 	mov 	ah, 08h ; Return drive parameters
    69 0000010B CD13                <1> 	int	13h	
    70 0000010D 7210                <1> 	jc	short L4
    71                              <1> 		; BL = drive type (for floppy drives)
    72                              <1> 		; DL = number of floppy drives
    73                              <1> 		;		
    74                              <1> 		; ES:DI = Address of DPT from BIOS
    75                              <1> 		;
    76 0000010F 881C                <1> 	mov	[si], bl ;  Drive type
    77                              <1> 			; 4 = 1.44 MB, 80 track, 3 1/2"
    78                              <1> 	; 14/01/2015
    79 00000111 E8DE01              <1> 	call	set_disk_parms
    80                              <1> 	; 10/12/2014
    81 00000114 81FE[CE67]          <1> 	cmp	si, fd0_type
    82 00000118 7705                <1> 	ja	short L4
    83 0000011A 46                  <1> 	inc	si ; fd1_type
    84 0000011B B201                <1> 	mov	dl, 1
    85 0000011D EBE6                <1> 	jmp	short L3
    86                              <1> L4:
    87 0000011F B27F                <1> 	mov	dl, 7Fh
    88                              <1> 	; 24/12/2014
    89 00000121 803E[CD67]00        <1> 	cmp	byte [hdc], 0 ; EDD present or not ?	
    90 00000126 0F878700            <1>         ja      L10       ; yes, all fixed disk operations
    91                              <1> 			  ; will be performed according to
    92                              <1> 			  ; present EDD specification
    93                              <1> 
    94                              <1> 	; 17/07/2020
    95                              <1> 	; Note: Virtual CPU will not come here while 
    96                              <1> 	; running in QEMU, Bochs, VirtualBox emulators !!!
    97                              <1> 	
    98                              <1> 	; 17/07/2020
    99                              <1> 	; Older BIOS (INT 13h, AH = 48h is not available)
   100                              <1> L6:
   101 0000012A FEC2                <1> 	inc 	dl
   102 0000012C 8816[CB67]          <1>         mov     [drv], dl
   103 00000130 8816[CC67]          <1>         mov     [last_drv], dl ; 14/01/2015
   104 00000134 B408                <1> 	mov 	ah, 08h ; Return drive parameters
   105 00000136 CD13                <1> 	int	13h	; (conventional function)
   106 00000138 0F82A801            <1>         jc      L13	; fixed disk drive not ready
   107 0000013C 8816[CD67]          <1>         mov     [hdc], dl ; number of drives
   108                              <1> 	;; 14/01/2013
   109                              <1> 	;;push	cx
   110 00000140 E8AF01              <1> 	call	set_disk_parms
   111                              <1> 	;;pop	cx
   112                              <1> 	;
   113                              <1> 	;;and	cl, 3Fh	 ; sectors per track (bits 0-6)
   114 00000143 8A16[CB67]          <1>         mov     dl, [drv]
   115 00000147 BB0401              <1> 	mov	bx, 65*4 ; hd0 parameters table (INT 41h)	
   116 0000014A 80FA80              <1> 	cmp	dl, 80h
   117 0000014D 7603                <1> 	jna	short L7
   118 0000014F 83C314              <1> 	add	bx, 5*4	 ; hd1 parameters table (INT 46h)
   119                              <1> L7:	
   120 00000152 31C0                <1> 	xor	ax, ax
   121 00000154 8ED8                <1> 	mov	ds, ax
   122 00000156 8B37                <1>         mov     si, [bx]
   123 00000158 8B4702              <1>         mov     ax, [bx+2] 
   124 0000015B 8ED8                <1> 	mov	ds, ax
   125 0000015D 3A4C0E              <1>         cmp     cl, [si+FDPT_SPT] ; sectors per track 
   126 00000160 0F857C01            <1>         jne     L12 ; invalid FDPT
   127 00000164 BF0000              <1> 	mov	di, HD0_DPT
   128 00000167 80FA80              <1> 	cmp	dl, 80h
   129 0000016A 7603                <1> 	jna	short L8
   130 0000016C BF2000              <1> 	mov	di, HD1_DPT 
   131                              <1> L8:
   132                              <1> 	; 30/12/2014
   133 0000016F B80090              <1> 	mov	ax, DPT_SEGM
   134 00000172 8EC0                <1> 	mov	es, ax
   135                              <1> 	; 24/12/2014
   136 00000174 B90800              <1> 	mov	cx, 8
   137 00000177 F3A5                <1> 	rep	movsw  ; copy 16 bytes to the kernel's DPT location
   138 00000179 8CC8                <1> 	mov	ax, cs
   139 0000017B 8ED8                <1> 	mov	ds, ax
   140                              <1> 
   141                              <1> 	; 02/02/2015
   142                              <1> 	;mov	cl, [drv]
   143                              <1> 	;mov	bl, cl
   144                              <1> 	;mov	ax, 1F0h
   145                              <1> 	;and	bl, 1
   146                              <1> 	;jz	short L9
   147                              <1> 	;shl	bl, 4
   148                              <1> 	;sub	ax, 1F0h-170h
   149                              <1> 
   150                              <1> 	; 17/07/2020 
   151                              <1> 	; (Only 1F0h port address must be valid for old ROM BIOSes)
   152 0000017D B8F001              <1> 	mov	ax, 1F0h
   153 00000180 B3A0                <1> 	mov	bl, 0A0h
   154 00000182 80FA80              <1> 	cmp	dl, 80h
   155 00000185 7603                <1> 	jna	short L9
   156                              <1> 	; dl = 81h
   157 00000187 80C310              <1> 	add	bl, 10h  ; slave disk
   158                              <1> 	;sub	ax, 1F0h-170h
   159                              <1> L9:
   160 0000018A AB                  <1> 	stosw	; I/O PORT Base Address (1F0h, 170h)
   161 0000018B 050602              <1> 	add	ax, 206h
   162 0000018E AB                  <1> 	stosw	; CONTROL PORT Address (3F6h, 376h)	
   163 0000018F 88D8                <1> 	mov	al, bl  ; bit 4, master/slave disk bit
   164                              <1> 	;add	al, 0A0h ; 17/07/2020
   165 00000191 AA                  <1> 	stosb	; Device/Head Register upper nibble
   166                              <1> 	;
   167 00000192 FE06[CB67]          <1> 	inc	byte [drv]
   168 00000196 BB[5067]            <1> 	mov	bx, hd0_type - 80h
   169 00000199 01CB                <1> 	add	bx, cx
   170 0000019B 800F80              <1>         or      byte [bx], 80h  ; present sign (when lower nibble is 0)
   171 0000019E A0[CD67]            <1> 	mov	al, [hdc]
   172 000001A1 FEC8                <1> 	dec	al
   173 000001A3 0F843D01            <1>         jz      L13
   174 000001A7 80FA80              <1> 	cmp	dl, 80h
   175 000001AA 0F867CFF            <1>         jna	L6 ; Max. 2 hard disks  ; 17/07/2020 
   176 000001AE E93301              <1>         jmp     L13
   177                              <1> L10:
   178 000001B1 FEC2                <1> 	inc 	dl
   179                              <1> 	; 25/12/2014
   180 000001B3 8816[CB67]          <1> 	mov	[drv], dl
   181 000001B7 B408                <1> 	mov 	ah, 08h ; Return drive parameters
   182 000001B9 CD13                <1> 	int	13h	; (conventional function)
   183 000001BB 0F822501            <1>         jc      L13
   184                              <1> 	; 14/01/2015
   185 000001BF 8A16[CB67]          <1> 	mov	dl, [drv]
   186 000001C3 52                  <1> 	push	dx
   187 000001C4 51                  <1> 	push	cx
   188 000001C5 E82A01              <1> 	call	set_disk_parms
   189 000001C8 59                  <1> 	pop	cx
   190 000001C9 5A                  <1> 	pop	dx
   191                              <1> 	; 06/07/2016 (BugFix for >64K kernel files)
   192                              <1> 	; 04/02/2016 (esi -> si)
   193                              <1> 	;mov	si, _end ; 30 byte temporary buffer address 	
   194                              <1> 	;		 ; at the '_end' of kernel.
   195                              <1> 	;mov	word [si], 30
   196                              <1> 	; 06/07/2016
   197 000001CA BE[5000]            <1> 	mov	si, _int13h_48h_buffer
   198                              <1> 	; 09/07/2016
   199 000001CD B81E00              <1> 	mov	ax, 001Eh
   200 000001D0 8824                <1> 	mov	[si], ah ; 0
   201 000001D2 46                  <1> 	inc	si
   202 000001D3 8904                <1> 	mov	word [si], ax
   203                              <1>  	; word [si] = 30
   204                              <1> 	;
   205 000001D5 B448                <1> 	mov	ah, 48h	 ; Get drive parameters (EDD function)
   206 000001D7 CD13                <1> 	int	13h
   207 000001D9 0F820701            <1>         jc      L13
   208                              <1> 
   209                              <1> 	; 29/08/2020
   210                              <1> 	; 04/02/2016 (ebx -> bx)
   211                              <1> 	; 14/01/2015
   212 000001DD 28FF                <1> 	sub	bh, bh
   213 000001DF 88D3                <1> 	mov	bl, dl
   214                              <1> 	;sub	bl, 80h
   215                              <1> 	; 29/08/2020
   216 000001E1 81C3[5067]          <1> 	add	bx, (hd0_type - 80h)
   217                              <1> 	;mov 	al, [bx]
   218 000001E5 8A07                <1> 	mov	al, [bx]
   219 000001E7 0C80                <1> 	or	al, 80h
   220 000001E9 8807                <1> 	mov 	[bx], al	
   221 000001EB 81EB[CE67]          <1> 	sub	bx, hd0_type - 2 ; 15/01/2015
   222                              <1> 	;add	bx, drv.status
   223                              <1> 	;mov	[bx], al
   224                              <1> 	; 29/08/2020
   225 000001EF 8887[1A68]          <1> 	mov	[bx+drv.status], al
   226                              <1> 	; 04/02/2016 (eax -> ax)
   227                              <1> 	;mov	ax, [si+16]
   228                              <1> 	; 14/07/2020
   229                              <1> 	;mov	di, [si+18] 
   230                              <1> 	;;test	ax, [si+18]
   231                              <1> 	;test	ax, di ; 14/07/2020
   232                              <1> 	;jz	short L10_A0h ; (!) ; 17/07/2020
   233                              <1> 			; 'CHS only' disks on EDD system 
   234                              <1> 			;  are reported with ZERO disk size
   235                              <1> 			; (if so, we must not overwrite
   236                              <1> 			; calculated disk size in 'set_disk_parms')
   237                              <1> 	; 29/08/2020
   238 000001F3 8B4410              <1> 	mov	ax, [si+16]
   239 000001F6 8B7C12              <1> 	mov	di, [si+18]
   240 000001F9 09C0                <1> 	or	ax, ax
   241 000001FB 7504                <1> 	jnz	short L10_LBA
   242 000001FD 09FF                <1> 	or	di, di
   243 000001FF 740B                <1> 	jz	short L10_A0h
   244                              <1> L10_LBA:
   245                              <1> 	;sub	bx, drv.status
   246 00000201 C1E302              <1> 	shl	bx, 2
   247                              <1> 	;add	bx, drv.size ; disk size (in sectors)
   248                              <1> 	;mov	[bx], ax
   249                              <1> 	; 29/08/2020
   250 00000204 8987[FE67]          <1> 	mov	[bx+drv.size], ax
   251                              <1> 	;mov	ax, [si+18]
   252                              <1> 	;;mov	[bx], ax
   253                              <1> 	;mov	[bx+2], ax ; BugFix ; 15/07/2020
   254                              <1> 	; 14/07/2020
   255                              <1> 	;mov	[bx+2], di ; 15/07/2020
   256                              <1> 	; 29/08/2020
   257 00000208 89BF[0068]          <1> 	mov	[bx+drv.size+2], di
   258                              <1> L10_A0h: 
   259                              <1> 	; 17/07/2020
   260                              <1> 	; Note: Virtual CPU will jump here from above (!) test
   261                              <1> 	;	while running in QEMU
   262                              <1> 
   263                              <1> 	; Jump here to fix a ZERO (LBA) disk size problem 
   264                              <1> 	; for CHS disks (28/02/2015)
   265                              <1> 	
   266                              <1> 	; 30/12/2014
   267 0000020C BF0000              <1> 	mov	di, HD0_DPT
   268 0000020F 88D0                <1> 	mov	al, dl
   269 00000211 83E003              <1> 	and 	ax, 3
   270 00000214 C0E005              <1> 	shl	al, 5 ; * 32
   271 00000217 01C7                <1> 	add 	di, ax
   272 00000219 B80090              <1> 	mov	ax, DPT_SEGM
   273 0000021C 8EC0                <1> 	mov	es, ax
   274                              <1> 	;
   275 0000021E 88E8                <1> 	mov	al, ch	; max. cylinder number (bits 0-7)
   276 00000220 88CC                <1> 	mov	ah, cl	
   277 00000222 C0EC06              <1> 	shr	ah, 6	; max. cylinder number (bits 8-9)
   278 00000225 40                  <1>  	inc	ax	; logical cylinders (limit 1024)
   279 00000226 AB                  <1> 	stosw		
   280 00000227 88F0                <1> 	mov	al, dh	; max. head number
   281                              <1> 	;
   282 00000229 30F6                <1> 	xor	dh, dh  ; 29/08/2020 (dh = 0 is needed here)
   283                              <1> 	;
   284 0000022B FEC0                <1> 	inc	al
   285 0000022D AA                  <1> 	stosb		; logical heads (limits 256)
   286 0000022E B0A0                <1> 	mov	al, 0A0h ; Indicates translated table
   287 00000230 AA                  <1> 	stosb
   288 00000231 8A440C              <1> 	mov	al, [si+12]
   289 00000234 AA                  <1> 	stosb		 ; physical sectors per track
   290 00000235 31C0                <1>  	xor	ax, ax
   291                              <1> 	;dec	ax	 ; 02/01/2015 
   292 00000237 AB                  <1> 	stosw		 ; precompensation (obsolete)
   293                              <1> 	;xor	al, al	 ; 02/01/2015	
   294 00000238 AA                  <1> 	stosb		 ; reserved
   295 00000239 B008                <1> 	mov	al, 8	 ; drive control byte
   296                              <1> 		         ; (do not disable retries, 
   297                              <1> 			 ; more than 8 heads)
   298 0000023B AA                  <1> 	stosb
   299 0000023C 8B4404              <1> 	mov	ax, [si+4]
   300 0000023F AB                  <1> 	stosw		 ; physical number of cylinders	
   301                              <1> 	;push	ax	 ; 02/01/2015
   302 00000240 8A4408              <1> 	mov	al, [si+8]
   303 00000243 AA                  <1> 	stosb		 ; physical num. of heads (limit 16)
   304 00000244 29C0                <1> 	sub 	ax, ax
   305                              <1> 	;pop	ax	 ; 02/01/2015	
   306 00000246 AB                  <1> 	stosw		 ; landing zone (obsolete)
   307 00000247 88C8                <1> 	mov	al, cl	 ; logical sectors per track (limit 63)
   308 00000249 243F                <1> 	and 	al, 3Fh	
   309 0000024B AA                  <1> 	stosb
   310                              <1> 	;sub	al, al	 ; checksum
   311                              <1> 	;stosb
   312                              <1> 	;
   313 0000024C 83C61A              <1> 	add	si, 26   ; (BIOS) DPTE address pointer
   314 0000024F AD                  <1> 	lodsw
   315 00000250 50                  <1> 	push	ax ; *	 ; (BIOS) DPTE offset
   316 00000251 AD                  <1> 	lodsw
   317 00000252 50                  <1> 	push	ax ; **	 ; (BIOS) DPTE segment
   318                              <1> 	;
   319                              <1> 	; checksum calculation
   320 00000253 89FE                <1> 	mov	si, di
   321 00000255 06                  <1> 	push	es
   322 00000256 1F                  <1> 	pop	ds
   323                              <1> 	;mov	cx, 16
   324 00000257 B90F00              <1> 	mov 	cx, 15
   325 0000025A 29CE                <1> 	sub	si, cx
   326 0000025C 30E4                <1> 	xor	ah, ah
   327                              <1> 	;del	cl
   328                              <1> L11:		
   329 0000025E AC                  <1> 	lodsb
   330 0000025F 00C4                <1> 	add	ah, al
   331 00000261 E2FB                <1> 	loop	L11
   332                              <1> 	;
   333 00000263 88E0                <1> 	mov	al, ah
   334 00000265 F6D8                <1> 	neg	al	; -x+x = 0
   335 00000267 AA                  <1> 	stosb		; put checksum in byte 15 of the tbl
   336                              <1> 	;
   337 00000268 1F                  <1> 	pop	ds ; **	; (BIOS) DPTE segment
   338 00000269 5E                  <1> 	pop	si ; *	; (BIOS) DPTE offset	
   339                              <1> 	;
   340                              <1> 	; 14/07/2020
   341                              <1> 	; 0FFFFh:0FFFFh = invalid DPTE address
   342 0000026A 8B0C                <1> 	mov	cx, [si]
   343 0000026C 8B4402              <1> 	mov	ax, [si+2]
   344 0000026F 21C1                <1> 	and	cx, ax
   345 00000271 41                  <1> 	inc	cx 
   346 00000272 7404                <1> 	jz	short L11c ; 0FFFFh:0FFFFh
   347 00000274 0B04                <1> 	or	ax, [si]
   348 00000276 752A                <1> 	jnz	short L11e ; <> 0
   349                              <1> L11c:
   350                              <1> 	; 17/07/2020
   351                              <1> 	; TRDOS 386 v2 DRVINIT assumptions:
   352                              <1> 	; (also by regarding QEMU, Bochs and VirtualBox settings)
   353                              <1> 	;	Hard disk 0 port address: 1F0h
   354                              <1> 	;	Hard disk 1 port address: 1F0h
   355                              <1> 	;	Hard disk 2 port address: 170h
   356                              <1> 	;	Hard disk 3 port address: 170h
   357                              <1> 
   358                              <1> 	; in QEMU, hda=hd0 (1F0h) and hdb=hd1 (1F0h) -IRQ14-
   359                              <1> 	;      and hdc=hd2 (170h) and hdd=hd3 (170h) -IRQ15-
   360                              <1> 
   361 00000278 B8F001              <1> 	mov	ax, 1F0h
   362                              <1> 
   363                              <1> 	; 15/07/2020
   364                              <1> 	; 14/07/2020
   365                              <1> 	; Invalid DPTE address...
   366                              <1> 	; Default DPTE parms must be set for DISK_IO_CONT
   367                              <1> 	; (diskio.s)
   368                              <1> 	; 17/07/2020
   369                              <1> 
   370                              <1> 	;mov	bl, dl
   371                              <1> 	;and	bl, 1
   372                              <1> 	;jz	short L11d
   373                              <1> 
   374 0000027B B3A0                <1> 	mov	bl, 0A0h
   375                              <1> 
   376 0000027D F6C201              <1> 	test	dl, 1
   377 00000280 7403                <1> 	jz	short L11g  ; Master (as default, for 80h & 82h))
   378                              <1> 	;shl	bl, 4 ; bl = 16 (bit 4 = 1 -> slave)
   379 00000282 80C310              <1> 	add	bl, 10h  ; Slave (as default, for 81h & 83h)
   380                              <1> L11g:
   381                              <1> 	; 17/07/2020
   382 00000285 80FA82              <1> 	cmp	dl, 82h	; Hard disk 3 or 4 ?
   383 00000288 7203                <1> 	jb	short L11d ; Primary ATA channel (hd0, hd1)
   384                              <1> 			   ; (port address = 1F0h)
   385                              <1> 	
   386                              <1> 	; Secondary ATA channel (hd2, hd3)
   387                              <1> 	; (port address = 170h)
   388                              <1> 
   389 0000028A 2D8000              <1> 	sub	ax, 1F0h-170h
   390                              <1> L11d:
   391                              <1> 	; 14/07/2020
   392 0000028D AB                  <1> 	stosw	; I/O PORT Base Address (1F0h, 170h)
   393 0000028E 050602              <1> 	add	ax, 206h
   394 00000291 AB                  <1> 	stosw	; CONTROL PORT Address (3F6h, 376h)	
   395 00000292 88D8                <1> 	mov	al, bl  ; Master/Slave bit (0 = Master)
   396                              <1> 	; 17/07/2020
   397                              <1> 	;or	al, 0A0h ; CHS (LBA enable bit = 0)
   398                              <1> 			 ; (Bits 5&7, reserved bits  =  1)
   399 00000294 30E4                <1> 	xor	ah, ah
   400                              <1> 	;stosb	; Device/Head Register upper nibble
   401 00000296 AB                  <1> 	stosw
   402 00000297 30C0                <1> 	xor	al, al
   403 00000299 B90500              <1> 	mov	cx, 5
   404 0000029C F3AB                <1> 	rep	stosw ; clear remain part of the (fake) DPTE
   405 0000029E 0E                  <1> 	push	cs
   406 0000029F 1F                  <1> 	pop	ds
   407 000002A0 EB2E                <1> 	jmp	short L11f
   408                              <1> L11e:
   409                              <1> 	; 23/02/2015
   410 000002A2 57                  <1> 	push	di
   411                              <1> 	; ES:DI points to DPTE (FDPTE) location
   412                              <1> 	;;mov	cx, 8
   413                              <1> 	;mov	cl, 8
   414 000002A3 B90800              <1> 	mov	cx, 8 ; 14/07/2020
   415 000002A6 F3A5                <1> 	rep	movsw	
   416                              <1> 	;
   417                              <1> 	; 23/02/2015
   418                              <1> 	; (P)ATA drive and LBA validation
   419                              <1> 	; (invalidating SATA drives and setting
   420                              <1> 	; CHS type I/O for old type fixed disks)
   421 000002A8 5B                  <1> 	pop	bx
   422 000002A9 8CC8                <1> 	mov	ax, cs
   423 000002AB 8ED8                <1> 	mov	ds, ax
   424 000002AD 268B07              <1> 	mov	ax, [es:bx]
   425 000002B0 3DF001              <1> 	cmp	ax, 1F0h
   426 000002B3 7413                <1> 	je	short L11a
   427 000002B5 3D7001              <1> 	cmp	ax, 170h
   428 000002B8 740E                <1> 	je	short L11a
   429                              <1> 	; invalidation 
   430                              <1> 	; (because base port address is not 1F0h or 170h)
   431                              <1> 	;xor	bh, bh
   432                              <1> 	;mov	bl, dl
   433                              <1> 	; 29/08/2020
   434                              <1> 	;xor	dh, dh ; 0
   435 000002BA 89D3                <1> 	mov	bx, dx
   436                              <1> 	;sub	bl, 80h
   437                              <1> 	;mov	byte [bx+hd0_type], 0 ; not a valid disk drive !		
   438                              <1>         ;or	byte [bx+drv.status+2], 0F0h ; (failure sign)
   439                              <1> 	; 29/08/2020
   440 000002BC C687[5067]00        <1> 	mov	byte [bx+hd0_type-80h], 0
   441 000002C1 808F[9C67]F0        <1> 	or	byte [bx+drv.status-7Eh], 0F0h
   442 000002C6 EB0F                <1> 	jmp	short L11b
   443                              <1> L11a:	
   444                              <1> 	; LBA validation
   445 000002C8 268A4704            <1> 	mov	al, [es:bx+4] ; Head register upper nibble
   446 000002CC A840                <1> 	test	al, 40h ; LBA bit (bit 6)
   447 000002CE 7507                <1> 	jnz	short L11b ; LBA type I/O is OK! (E0h or F0h)
   448                              <1> L11f:
   449                              <1> 	; force CHS type I/O for this drive (A0h or B0h)
   450                              <1> 	;sub	bh, bh
   451                              <1> 	;mov	bl, dl
   452                              <1> 	; 29/08/2020
   453                              <1> 	;xor	dh, dh ; 0
   454 000002D0 89D3                <1> 	mov	bx, dx
   455                              <1> 	;sub	bl, 80h ; 26/02/2015
   456                              <1>         ;and	byte [bx+drv.status+2], 0FEh ; clear bit 0
   457                              <1> 				; bit 0 = LBA ready bit
   458                              <1> 	; 29/08/2020
   459 000002D2 80A7[9C67]FE        <1> 	and	byte [bx+drv.status-7Eh], 0FEh
   460                              <1> 	; 'diskio' procedure will check this bit !
   461                              <1> L11b:
   462 000002D7 3A16[CC67]          <1> 	cmp	dl, [last_drv] ; 25/12/2014
   463 000002DB 7307                <1>         jnb     short L13
   464 000002DD E9D1FE              <1>         jmp     L10
   465                              <1> 
   466                              <1> L12:
   467                              <1> 	; Restore data registers
   468 000002E0 8CC8                <1> 	mov	ax, cs
   469 000002E2 8ED8                <1> 	mov	ds, ax	
   470                              <1> L13:
   471                              <1> 	; 13/12/2014
   472 000002E4 0E                  <1> 	push	cs
   473 000002E5 07                  <1> 	pop	es
   474                              <1> L14:
   475                              <1> 	; clear keyboard buffer
   476 000002E6 B411                <1> 	mov 	ah, 11h
   477 000002E8 CD16                <1> 	int 	16h
   478 000002EA 744D                <1> 	jz 	short L16 ; no keys in keyboard buffer
   479 000002EC B010                <1> 	mov	al, 10h
   480 000002EE CD16                <1> 	int 	16h
   481 000002F0 EBF4                <1> 	jmp 	short L14
   482                              <1> 
   483                              <1> set_disk_parms:
   484                              <1> 	; 29/08/2020
   485                              <1> 	; 04/02/2016 (ebx -> bx)
   486                              <1> 	; 10/07/2015
   487                              <1> 	; 14/01/2015
   488                              <1> 	;push	bx
   489 000002F2 28FF                <1> 	sub	bh, bh
   490 000002F4 8A1E[CB67]          <1> 	mov	bl, [drv]
   491 000002F8 80FB80              <1> 	cmp	bl, 80h
   492 000002FB 7203                <1> 	jb	short sdp0
   493 000002FD 80EB7E              <1> 	sub	bl, 7Eh
   494                              <1> sdp0:	
   495                              <1> 	;add	bx, drv.status
   496                              <1>   	;mov	byte [bx], 80h ; 'Present' flag
   497                              <1> 	; 29/08/2020
   498 00000300 C687[1A68]80        <1> 	mov	byte [bx+drv.status], 80h
   499                              <1> 	;
   500 00000305 88E8                <1> 	mov	al, ch ; last cylinder (bits 0-7)
   501 00000307 88CC                <1> 	mov	ah, cl ; 
   502 00000309 C0EC06              <1> 	shr	ah, 6  ; last cylinder (bits 8-9)
   503                              <1> 	;sub	bx, drv.status
   504 0000030C D0E3                <1> 	shl	bl, 1
   505                              <1> 	;add	bx, drv.cylinders
   506 0000030E 40                  <1> 	inc	ax  ; convert max. cyl number to cyl count		
   507                              <1> 	;mov	[bx], ax
   508                              <1> 	; 29/08/2020
   509 0000030F 8987[D467]          <1> 	mov	[bx+drv.cylinders], ax
   510 00000313 50                  <1> 	push	ax ; ** cylinders
   511                              <1> 	;sub	bx, drv.cylinders
   512                              <1> 	;add	bx, drv.heads
   513 00000314 30E4                <1> 	xor	ah, ah
   514 00000316 88F0                <1> 	mov	al, dh ; heads
   515 00000318 40                  <1> 	inc	ax
   516                              <1> 	;mov	[bx], ax
   517                              <1> 	; 29/08/2020
   518 00000319 8987[E267]          <1>         mov	[bx+drv.heads], ax
   519                              <1> 	;sub     bx, drv.heads
   520                              <1>         ;add     bx, drv.spt
   521 0000031D 30ED                <1> 	xor	ch, ch
   522 0000031F 80E13F              <1> 	and	cl, 3Fh	; sectors (bits 0-6)
   523                              <1> 	;mov	[bx], cx
   524                              <1>         ; 29/08/2020
   525 00000322 898F[F067]          <1> 	mov	[bx+drv.spt], cx
   526                              <1> 	;sub	bx, drv.spt
   527 00000326 D1E3                <1> 	shl	bx, 1
   528                              <1> 	;add	bx, drv.size ; disk size (in sectors)
   529                              <1> 	; LBA size = cylinders * heads * secpertrack
   530 00000328 F7E1                <1> 	mul	cx 
   531 0000032A 89C2                <1> 	mov	dx, ax	; heads*spt					
   532 0000032C 58                  <1> 	pop	ax ; ** cylinders
   533 0000032D 48                  <1> 	dec	ax ; 1 cylinder reserved (!?)
   534 0000032E F7E2                <1> 	mul	dx ; cylinders * (heads*spt)		
   535                              <1> 	;mov	[bx], ax
   536                              <1> 	;mov	[bx+2], dx
   537                              <1> 	; 29/08/2020
   538 00000330 8987[FE67]          <1> 	mov	[bx+drv.size], ax
   539 00000334 8997[0068]          <1> 	mov	[bx+drv.size+2], dx
   540                              <1> 	;
   541                              <1> 	;pop	bx
   542 00000338 C3                  <1> 	retn
   543                              <1> 
   544                              <1> L16:	; 28/05/2016
   345                                  
   346                                  	; 10/11/2014
   347 00000339 FA                           	cli	; Disable interrupts (clear interrupt flag)
   348                                  		; Reset Interrupt MASK Registers (Master&Slave)
   349                                  	;mov	al, 0FFh	; mask off all interrupts
   350                                  	;out	21h, al		; on master PIC (8259)
   351                                  	;jmp 	$+2  ; (delay)
   352                                  	;out	0A1h, al	; on slave PIC (8259)
   353                                  	;
   354                                  	; Disable NMI 
   355 0000033A B080                    	mov   	al, 80h 
   356 0000033C E670                    	out   	70h, al		; set bit 7 to 1 for disabling NMI
   357                                  	;23/02/2015
   358                                  	;nop			;
   359                                  	;in	al, 71h		; read in 71h just after writing out to 70h
   360                                  				; for preventing unknown state (!?)
   361                                  	;
   362                                   	; 20/08/2014
   363                                  	; Moving the kernel 64 KB back (to physical address 0)
   364                                  	; DS = CS = 1000h
   365                                  	; 05/11/2014
   366 0000033E 31C0                    	xor	ax, ax
   367 00000340 8EC0                    	mov	es, ax ; ES = 0
   368                                  	;
   369                                  	; 04/07/2016 -  TRDOS 386 (64K - 128K kernel)
   370 00000342 31F6                          	xor	si, si
   371 00000344 31FF                    	xor	di, di
   372 00000346 B90040                  	mov	cx, 16384
   373 00000349 F366A5                  	rep	movsd
   374                                  	;
   375 0000034C 06                      	push	es ; 0
   376 0000034D 68[5103]                	push	L17
   377 00000350 CB                      	retf
   378                                  L17:
   379 00000351 B90010                  	mov	cx, 1000h
   380 00000354 8EC1                    	mov	es, cx  ; 1000h 
   381 00000356 01C9                    	add	cx, cx
   382 00000358 8ED9                    	mov	ds, cx  ; 2000h
   383 0000035A 29F6                    	sub	si, si
   384 0000035C 29FF                    	sub	di, di
   385 0000035E B90040                  	mov	cx, 16384
   386 00000361 F366A5                  	rep	movsd
   387                                  	
   388                                  	; Turn off the floppy drive motor
   389 00000364 BAF203                          mov     dx, 3F2h
   390 00000367 EE                              out     dx, al ; 0 ; 31/12/2013
   391                                  
   392                                  	; Enable access to memory above one megabyte
   393                                  L18:
   394 00000368 E464                    	in	al, 64h
   395 0000036A A802                    	test	al, 2
   396 0000036C 75FA                            jnz     short L18
   397 0000036E B0D1                    	mov	al, 0D1h	; Write output port
   398 00000370 E664                    	out	64h, al
   399                                  L19:
   400 00000372 E464                    	in	al, 64h
   401 00000374 A802                    	test	al, 2
   402 00000376 75FA                            jnz     short L19
   403 00000378 B0DF                    	mov	al, 0DFh	; Enable A20 line
   404 0000037A E660                    	out	60h, al
   405                                  ;L20:
   406                                  	;
   407                                  	; Load global descriptor table register
   408                                  
   409                                          ;mov     ax, cs
   410                                          ;mov     ds, ax
   411                                  
   412 0000037C 2E0F0116[3867]                  lgdt    [cs:gdtd]
   413                                  
   414 00000382 0F20C0                          mov     eax, cr0
   415                                  	; or 	eax, 1
   416 00000385 40                      	inc     ax
   417 00000386 0F22C0                  	mov     cr0, eax
   418                                  
   419                                  	; Jump to 32 bit code
   420                                  	
   421 00000389 66                      	db 66h 			; Prefix for 32-bit
   422 0000038A EA                      	db 0EAh 		; Opcode for far jump
   423 0000038B [91030000]              	dd StartPM 		; Offset to start, 32-bit
   424                                  				; (1000h:StartPM = StartPM + 10000h)
   425 0000038F 0800                    	dw KCODE		; This is the selector for CODE32_DESCRIPTOR,
   426                                  				; assuming that StartPM resides in code32
   427                                  
   428                                  ; 20/02/2017
   429                                  
   430                                  
   431                                  [BITS 32] 
   432                                  
   433                                  StartPM:
   434                                  	; Kernel Base Address = 0 ; 30/12/2013
   435 00000391 66B81000                	mov ax, KDATA           ; Save data segment identifier
   436 00000395 8ED8                            mov ds, ax              ; Move a valid data segment into DS register
   437 00000397 8EC0                           	mov es, ax              ; Move data segment into ES register
   438 00000399 8EE0                           	mov fs, ax              ; Move data segment into FS register
   439 0000039B 8EE8                          	mov gs, ax              ; Move data segment into GS register
   440 0000039D 8ED0                            mov ss, ax              ; Move data segment into SS register
   441 0000039F BC00000900                      mov esp, 90000h         ; Move the stack pointer to 090000h
   442                                  
   443                                  clear_bss: ; Clear uninitialized data area
   444                                  	; 11/03/2015
   445 000003A4 31C0                    	xor  eax, eax ; 0
   446 000003A6 B9456C0000              	mov  ecx, (bss_end - bss_start)/4
   447                                  	;shr  ecx, 2 ; bss section is already aligned for double words
   448 000003AB BF[EA600100]            	mov  edi, bss_start	
   449 000003B0 F3AB                    	rep  stosd  		
   450                                  
   451                                  memory_init:
   452                                  	; Initialize memory allocation table and page tables
   453                                  	; 16/11/2014
   454                                  	; 15/11/2014
   455                                  	; 07/11/2014
   456                                  	; 06/11/2014
   457                                  	; 05/11/2014
   458                                  	; 04/11/2014
   459                                  	; 31/10/2014 (Retro UNIX 386 v1 - Beginning) 
   460                                  	;
   461                                  ;	xor	eax, eax
   462                                  ;	xor 	ecx, ecx
   463 000003B2 B108                    	mov	cl, 8
   464 000003B4 BF00001000              	mov	edi, MEM_ALLOC_TBL	
   465 000003B9 F3AB                    	rep	stosd		   ; clear Memory Allocation Table
   466                                  				   ; for the first 1 MB memory
   467                                  	;
   468 000003BB 668B0D[C6670000]        	mov	cx, [mem_1m_1k]	   ; Number of contiguous KB between
   469                                  				   ; 1 and 16 MB, max. 3C00h = 15 MB.
   470 000003C2 66C1E902                	shr	cx, 2		   ; convert 1 KB count to 4 KB count
   471 000003C6 890D[E0630100]          	mov	[free_pages], ecx
   472 000003CC 668B15[C8670000]        	mov	dx, [mem_16m_64k]  ; Number of contiguous 64 KB blocks
   473                                  				   ; between 16 MB and 4 GB.	
   474 000003D3 6609D2                  	or	dx, dx
   475 000003D6 7413                    	jz	short mi_0
   476                                  	;
   477 000003D8 6689D0                  	mov	ax, dx
   478 000003DB C1E004                  	shl	eax, 4		   ; 64 KB -> 4 KB (page count)
   479 000003DE 0105[E0630100]          	add	[free_pages], eax
   480 000003E4 0500100000              	add	eax, 4096	   ; 16 MB = 4096 pages
   481 000003E9 EB07                    	jmp	short mi_1
   482                                  mi_0:
   483 000003EB 6689C8                  	mov	ax, cx
   484 000003EE 66050001                	add	ax, 256		   ; add 256 pages for the first 1 MB		 
   485                                  mi_1:
   486 000003F2 A3[DC630100]            	mov	[memory_size], eax ; Total available memory in pages
   487                                  				   ; 1 alloc. tbl. bit = 1 memory page
   488                                  				   ; 32 allocation bits = 32 mem. pages   
   489                                  	;
   490 000003F7 05FF7F0000              	add	eax, 32767	   ; 32768 memory pages per 1 M.A.T. page 	
   491 000003FC C1E80F                  	shr	eax, 15		   ; ((32768 * x) + y) pages (y < 32768)
   492                                  				   ;  --> x + 1 M.A.T. pages, if y > 0
   493                                  				   ;  --> x M.A.T. pages, if y = 0
   494 000003FF 66A3[F0630100]          	mov	[mat_size], ax	   ; Memory Alloc. Table Size in pages		
   495 00000405 C1E00C                  	shl	eax, 12		   ; 1 M.A.T. page = 4096 bytes
   496                                  	;			   ; Max. 32 M.A.T. pages (4 GB memory)
   497 00000408 89C3                    	mov	ebx, eax	   ; M.A.T. size in bytes
   498                                  	; Set/Calculate Kernel's Page Directory Address
   499 0000040A 81C300001000            	add	ebx, MEM_ALLOC_TBL
   500 00000410 891D[D8630100]          	mov	[k_page_dir], ebx  ; Kernel's Page Directory address
   501                                  				   ; just after the last M.A.T. page
   502                                  	;
   503 00000416 83E804                  	sub	eax, 4		   ; convert M.A.T. size to offset value
   504 00000419 A3[E8630100]            	mov	[last_page], eax   ; last page ofset in the M.A.T.
   505                                  	;			   ; (allocation status search must be 
   506                                  				   ; stopped after here)	
   507 0000041E 31C0                    	xor	eax, eax
   508 00000420 48                      	dec	eax		   ; FFFFFFFFh (set all bits to 1)	
   509 00000421 6651                    	push	cx
   510 00000423 C1E905                  	shr	ecx, 5		   ; convert 1 - 16 MB page count to 
   511                                  				   ; count of 32 allocation bits
   512 00000426 F3AB                    	rep	stosd
   513 00000428 6659                    	pop	cx
   514 0000042A 40                      	inc	eax		   ; 0	
   515 0000042B 80E11F                  	and	cl, 31		   ; remain bits
   516 0000042E 7412                    	jz	short mi_4
   517 00000430 8907                    	mov	[edi], eax	   ; reset	
   518                                  mi_2:
   519 00000432 0FAB07                  	bts	[edi], eax	   ; 06/11/2014		
   520 00000435 FEC9                    	dec	cl
   521 00000437 7404                    	jz	short mi_3
   522 00000439 FEC0                    	inc	al
   523 0000043B EBF5                    	jmp	short mi_2
   524                                  mi_3:
   525 0000043D 28C0                    	sub	al, al	   	   ; 0
   526 0000043F 83C704                  	add	edi, 4		   ; 15/11/2014
   527                                  mi_4:
   528 00000442 6609D2                  	or	dx, dx		  ; check 16M to 4G memory space	
   529 00000445 7421                    	jz	short mi_6	  ; max. 16 MB memory, no more...
   530                                  	;	
   531 00000447 B900021000              	mov	ecx, MEM_ALLOC_TBL + 512 ; End of first 16 MB memory
   532                                  	;	
   533 0000044C 29F9                    	sub	ecx, edi	  ; displacement (to end of 16 MB)
   534 0000044E 7406                    	jz	short mi_5	  ; jump if EDI points to 
   535                                  				  ;         end of first 16 MB	
   536 00000450 D1E9                    	shr	ecx, 1		  ; convert to dword count
   537 00000452 D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   538 00000454 F3AB                    	rep 	stosd		  ; reset all bits for reserved pages
   539                                  				  ; (memory hole under 16 MB)
   540                                  mi_5:
   541 00000456 6689D1                  	mov	cx, dx		  ; count of 64 KB memory blocks
   542 00000459 D1E9                    	shr	ecx, 1		  ; 1 alloc. dword per 128 KB memory
   543 0000045B 9C                      	pushf			  ; 16/11/2014		
   544 0000045C 48                      	dec	eax		  ; FFFFFFFFh (set all bits to 1)
   545 0000045D F3AB                    	rep	stosd
   546 0000045F 40                      	inc	eax		  ; 0
   547 00000460 9D                      	popf			  ; 16/11/2014
   548 00000461 7305                    	jnc	short mi_6
   549 00000463 6648                    	dec	ax		  ; eax = 0000FFFFh
   550 00000465 AB                      	stosd
   551 00000466 6640                    	inc	ax		  ; 0		
   552                                  mi_6:
   553 00000468 39DF                    	cmp	edi, ebx	  ; check if EDI points to 	
   554 0000046A 730A                    	jnb	short mi_7	  ; end of memory allocation table
   555                                  	;			  ; (>= MEM_ALLOC_TBL + 4906) 
   556 0000046C 89D9                    	mov	ecx, ebx	  ; end of memory allocation table
   557 0000046E 29F9                    	sub	ecx, edi	  ; convert displacement/offset
   558 00000470 D1E9                    	shr	ecx, 1		  ; to dword count 	 		
   559 00000472 D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   560 00000474 F3AB                    	rep 	stosd		  ; reset all remain M.A.T. bits
   561                                  mi_7:
   562                                  	; Reset M.A.T. bits in M.A.T. (allocate M.A.T. pages)
   563 00000476 BA00001000              	mov	edx, MEM_ALLOC_TBL
   564                                  	;sub	ebx, edx	  ; Mem. Alloc. Tbl. size in bytes
   565                                  	;shr	ebx, 12		  ; Mem. Alloc. Tbl. size in pages	
   566 0000047B 668B0D[F0630100]        	mov	cx, [mat_size]	  ; Mem. Alloc. Tbl. size in pages
   567 00000482 89D7                    	mov	edi, edx
   568 00000484 C1EF0F                  	shr	edi, 15		  ; convert M.A.T. address to
   569                                  				  ; byte offset in M.A.T.
   570                                  				  ; (1 M.A.T. byte points to 
   571                                  				  ;	      32768 bytes)
   572                                  				  ; Note: MEM_ALLOC_TBL address 
   573                                  				  ; must be aligned on 128 KB 
   574                                  				  ; boundary!
   575 00000487 01D7                    	add	edi, edx	  ; points to M.A.T.'s itself	
   576                                  	; eax = 0
   577 00000489 290D[E0630100]          	sub	[free_pages], ecx ; 07/11/2014
   578                                  mi_8:
   579 0000048F 0FB307                  	btr	[edi], eax	  ; clear bit 0 to bit x (1 to 31)
   580                                  	;dec	bl
   581 00000492 FEC9                    	dec	cl
   582 00000494 7404                    	jz	short mi_9
   583 00000496 FEC0                    	inc	al
   584 00000498 EBF5                    	jmp	short mi_8
   585                                  mi_9:
   586                                  	;
   587                                  	; Reset Kernel's Page Dir. and Page Table bits in M.A.T.
   588                                  	;		(allocate pages for system page tables)
   589                                  
   590                                  	; edx = MEM_ALLOC_TBL
   591 0000049A 8B0D[DC630100]          	mov	ecx, [memory_size] ; memory size in pages (PTEs)
   592 000004A0 81C1FF030000            	add	ecx, 1023	 ; round up (1024 PTEs per table)	 	
   593 000004A6 C1E90A                  	shr	ecx, 10		 ; convert memory page count to 
   594                                  				 ; page table count (PDE count)
   595                                  	;
   596 000004A9 51                      	push	ecx		 ; (**) PDE count (<= 1024)
   597                                  	;
   598 000004AA 41                      	inc	ecx		 ; +1 for kernel page directory	
   599                                  	;
   600 000004AB 290D[E0630100]          	sub	[free_pages], ecx ; 07/11/2014
   601                                  	;
   602 000004B1 8B35[D8630100]          	mov	esi, [k_page_dir] ; Kernel's Page Directory address
   603 000004B7 C1EE0C                  	shr	esi, 12		 ; convert to page number
   604                                  mi_10:
   605 000004BA 89F0                    	mov	eax, esi	 ; allocation bit offset		 
   606 000004BC 89C3                    	mov	ebx, eax
   607 000004BE C1EB03                  	shr	ebx, 3		 ; convert to alloc. byte offset
   608 000004C1 80E3FC                  	and	bl,  0FCh	 ; clear bit 0 and bit 1
   609                                  				 ;   to align on dword boundary
   610 000004C4 83E01F                  	and	eax, 31		 ; set allocation bit position 
   611                                  				 ;  (bit 0 to bit 31)
   612                                  	;
   613 000004C7 01D3                    	add	ebx, edx	 ; offset in M.A.T. + M.A.T. address 
   614                                  	;
   615 000004C9 0FB303                  	btr 	[ebx], eax	 ; reset relevant bit (0 to 31)
   616                                  	;
   617 000004CC 46                      	inc	esi		 ; next page table
   618 000004CD E2EB                    	loop	mi_10		 ; allocate next kernel page table 
   619                                  				 ; (ecx = page table count + 1)		
   620                                  	;
   621 000004CF 59                      	pop	ecx		 ; (**) PDE count (= pg. tbl. count)
   622                                  	;
   623                                  	; Initialize Kernel Page Directory and Kernel Page Tables
   624                                  	;
   625                                  	; Initialize Kernel's Page Directory
   626 000004D0 8B3D[D8630100]          	mov	edi, [k_page_dir]
   627 000004D6 89F8                    	mov	eax, edi
   628 000004D8 0C03                    	or	al, PDE_A_PRESENT + PDE_A_WRITE
   629                                  				; supervisor + read&write + present
   630 000004DA 89CA                    	mov	edx, ecx 	; (**) PDE count (= pg. tbl. count)	
   631                                  mi_11:
   632 000004DC 0500100000              	add	eax, 4096	; Add page size (PGSZ)
   633                                  			        ; EAX points to next page table
   634 000004E1 AB                      	stosd
   635 000004E2 E2F8                    	loop	mi_11
   636 000004E4 29C0                    	sub	eax, eax	; Empty PDE
   637 000004E6 66B90004                	mov	cx, 1024	; Entry count (PGSZ/4)
   638 000004EA 29D1                    	sub	ecx, edx
   639 000004EC 7402                    	jz	short mi_12
   640 000004EE F3AB                    	rep	stosd 		; clear remain (empty) PDEs
   641                                  	;
   642                                  	; Initialization of Kernel's Page Directory is OK, here.
   643                                  mi_12:
   644                                  	; Initialize Kernel's Page Tables
   645                                  	;
   646                                  	; (EDI points to address of page table 0)
   647                                  	; eax = 0
   648 000004F0 8B0D[DC630100]          	mov	ecx, [memory_size] ; memory size in pages
   649 000004F6 89CA                    	mov	edx, ecx	; (***)
   650 000004F8 B003                    	mov	al, PTE_A_PRESENT + PTE_A_WRITE
   651                                  			     ; supervisor + read&write + present 	
   652                                  mi_13:
   653 000004FA AB                      	stosd
   654 000004FB 0500100000              	add	eax, 4096	
   655 00000500 E2F8                    	loop	mi_13	
   656 00000502 6681E2FF03              	and	dx, 1023	; (***)
   657 00000507 740B                    	jz	short mi_14
   658 00000509 66B90004                	mov	cx, 1024	
   659 0000050D 6629D1                  	sub	cx, dx		; from dx (<= 1023) to 1024
   660 00000510 31C0                    	xor	eax, eax
   661 00000512 F3AB                    	rep	stosd		; clear remain (empty) PTEs 
   662                                  				; of the last page table
   663                                  mi_14:
   664                                  	;  Initialization of Kernel's Page Tables is OK, here.
   665                                  	;
   666 00000514 89F8                    	mov	eax, edi	; end of the last page table page
   667                                  			        ; (beginging of user space pages)
   668 00000516 C1E80F                  	shr	eax, 15		; convert to M.A.T. byte offset
   669 00000519 24FC                    	and	al, 0FCh	; clear bit 0 and bit 1 for
   670                                  				; aligning on dword boundary	
   671                                  	 
   672 0000051B A3[EC630100]            	mov	[first_page], eax
   673 00000520 A3[E4630100]            	mov	[next_page], eax ; The first free page pointer
   674                                  				 ; for user programs
   675                                  				 ; (Offset in Mem. Alloc. Tbl.)	
   676                                  	;
   677                                  	; Linear/FLAT (1 to 1) memory paging for the kernel is OK, here.
   678                                  	;
   679                                  	
   680                                  	; Enable paging
   681                                  	;
   682 00000525 A1[D8630100]                    mov     eax, [k_page_dir]
   683 0000052A 0F22D8                  	mov	cr3, eax
   684 0000052D 0F20C0                  	mov	eax, cr0
   685 00000530 0D00000080              	or	eax, 80000000h	; set paging bit (bit 31)
   686 00000535 0F22C0                  	mov	cr0, eax
   687                                          ;jmp    KCODE:StartPMP
   688                                  
   689 00000538 EA                      	db 0EAh 		; Opcode for far jump
   690 00000539 [3F050000]                      dd StartPMP		; 32 bit offset
   691 0000053D 0800                    	dw KCODE		; kernel code segment descriptor
   692                                  
   693                                  StartPMP:
   694                                  	; 06/11//2014
   695                                  	; Clear video page 0
   696                                  	;
   697                                  	; Temporary Code
   698                                  	;
   699 0000053F B9E8030000              	mov	ecx, 80*25/2
   700 00000544 BF00800B00              	mov	edi, 0B8000h
   701                                  	; 30/01/2016
   702                                  	;xor	eax, eax	; black background, black fore color
   703 00000549 B800070007              	mov	eax, 07000700h  ; black background, light gray fore color
   704 0000054E F3AB                    	rep	stosd
   705                                  	
   706                                  	; 19/08/2014
   707                                  	; Kernel Base Address = 0
   708                                  	; It is mapped to (physically) 0 in the page table.
   709                                  	; So, here is exactly 'StartPMP' address.
   710                                  
   711                                   	; 29/01/2016 (TRDOS 386 = TRDOS v2.0)
   712 00000550 BE[D6240100]            	mov	esi, starting_msg
   713                                  	;; 14/08/2015 (kernel version message will appear
   714                                  	;;	       when protected mode and paging is enabled)
   715 00000555 BF00800B00              	mov	edi, 0B8000h ; 27/08/2014
   716                                  	
   717                                  	; 30/11/2020
   718                                  	; 14/11/2020 (TRDOS 386 v2.0.3)
   719                                  	;cmp	byte [vbe3], 3 ; 03h
   720                                  	;jne	short pkv_1
   721                                  	;;mov	ah, 0Bh ; Black background, light cyan forecolor
   722                                  	;; Light red TRDOS 386 version text shows VBE3 is ready !
   723                                  	;mov	ah, 0Ch ; Black background, light red forecolor
   724                                  	;jmp	short pkv_2
   725                                  ;pkv_1:
   726 0000055A B40A                    	mov	ah, 0Ah ; Black background, light green forecolor
   727                                  ;pkv_2:
   728                                  	; 20/08/2014
   729 0000055C E8D9030000              	call	printk
   730                                  
   731                                  	; 'UNIX v7/x86' source code by Robert Nordier (1999)
   732                                  	; // Set IRQ offsets
   733                                  	;
   734                                  	;  Linux (v0.12) source code by Linus Torvalds (1991)
   735                                  	;
   736                                  					;; ICW1
   737 00000561 B011                    	mov	al, 11h			; Initialization sequence
   738 00000563 E620                    	out	20h, al			; 	8259A-1
   739                                  	; jmp 	$+2
   740 00000565 E6A0                    	out	0A0h, al		; 	8259A-2
   741                                  					;; ICW2
   742 00000567 B020                    	mov	al, 20h			; Start of hardware ints (20h)
   743 00000569 E621                    	out	21h, al			;	for 8259A-1
   744                                  	; jmp 	$+2
   745 0000056B B028                    	mov	al, 28h			; Start of hardware ints (28h)
   746 0000056D E6A1                    	out	0A1h, al		; 	for 8259A-2
   747                                  					;
   748 0000056F B004                    	mov	al, 04h			;; ICW3
   749 00000571 E621                    	out	21h, al			; 	IRQ2 of 8259A-1 (master)
   750                                  	; jmp 	$+2
   751 00000573 B002                    	mov	al, 02h			; 	is 8259A-2 (slave)
   752 00000575 E6A1                    	out	0A1h, al		;
   753                                  					;; ICW4
   754 00000577 B001                    	mov	al, 01h	 		;
   755 00000579 E621                    	out	21h, al			; 	8086 mode, normal EOI	
   756                                  	; jmp 	$+2
   757 0000057B E6A1                    	out	0A1h, al		;	for both chips.
   758                                  
   759                                  	;mov	al, 0FFh	; mask off all interrupts for now
   760                                  	;out	21h, al
   761                                  	;; jmp 	$+2
   762                                  	;out	0A1h, al
   763                                  
   764                                  	; 02/04/2015
   765                                  	; 26/03/2015 System call (INT 30h) modification
   766                                  	;  DPL = 3 (Interrupt service routine can be called from user mode)			
   767                                  	;
   768                                  	;; Linux (v0.12) source code by Linus Torvalds (1991)
   769                                  	;  setup_idt:
   770                                  	;
   771                                          ;; 16/02/2015
   772                                  	;;mov     dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
   773                                  	; 21/08/2014 (timer_int)
   774 0000057D BE[74210100]            	mov	esi, ilist
   775 00000582 8D3D[F0600100]          	lea	edi, [idt]
   776                                  	; 26/03/2015
   777 00000588 B930000000              	mov	ecx, 48		; 48 hardware interrupts (INT 0 to INT 2Fh)
   778                                  	; 02/04/2015
   779 0000058D BB00000800              	mov	ebx,  80000h
   780                                  rp_sidt1:
   781 00000592 AD                      	lodsd
   782 00000593 89C2                    	mov	edx, eax
   783 00000595 66BA008E                	mov	dx, 8E00h
   784 00000599 6689C3                  	mov	bx, ax
   785 0000059C 89D8                    	mov	eax, ebx	; /* selector = 0x0008 = cs */
   786                                         			        ; /* interrupt gate - dpl=0, present */
   787 0000059E AB                      	stosd	; selector & offset bits 0-15 	
   788 0000059F 89D0                    	mov	eax, edx
   789 000005A1 AB                      	stosd	; attributes & offset bits 16-23
   790 000005A2 E2EE                    	loop	rp_sidt1
   791                                  	; 15/04/2016
   792                                  	; TRDOS 386 (TRDOS v2.0) /// 32 sofware interrupts ///
   793                                  	;mov	cl, 16        ; 16 software interrupts (INT 30h to INT 3Fh)
   794 000005A4 B120                    	mov	cl, 32	      ; 32 software interrupts (INT 30h to INT 4Fh)	
   795                                  rp_sidt2:
   796 000005A6 AD                      	lodsd
   797 000005A7 21C0                    	and	eax, eax
   798 000005A9 7413                    	jz	short rp_sidt3
   799 000005AB 89C2                    	mov	edx, eax
   800 000005AD 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
   801 000005B1 6689C3                  	mov	bx, ax
   802 000005B4 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
   803 000005B6 AB                      	stosd
   804 000005B7 89D0                    	mov	eax, edx
   805 000005B9 AB                      	stosd
   806 000005BA E2EA                    	loop	rp_sidt2
   807 000005BC EB16                    	jmp	short sidt_OK
   808                                  rp_sidt3:
   809 000005BE B8[650D0000]            	mov	eax, ignore_int
   810 000005C3 89C2                    	mov	edx, eax
   811 000005C5 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
   812 000005C9 6689C3                  	mov	bx, ax
   813 000005CC 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
   814                                  rp_sidt4:
   815 000005CE AB                      	stosd
   816 000005CF 92                      	xchg	eax, edx
   817 000005D0 AB                      	stosd
   818 000005D1 92                      	xchg	edx, eax
   819 000005D2 E2FA                    	loop	rp_sidt4
   820                                  sidt_OK: 
   821 000005D4 0F011D[3E670000]        	lidt 	[idtd]
   822                                  	;
   823                                  	; TSS descriptor setup ; 24/03/2015
   824 000005DB B8[70630100]            	mov	eax, task_state_segment
   825 000005E0 66A3[EA660000]          	mov	[gdt_tss0], ax
   826 000005E6 C1C010                  	rol	eax, 16
   827 000005E9 A2[EC660000]            	mov	[gdt_tss1], al
   828 000005EE 8825[EF660000]          	mov	[gdt_tss2], ah
   829 000005F4 66C705[D6630100]68-     	mov	word [tss.IOPB], tss_end - task_state_segment
   829 000005FC 00                 
   830                                  		; 
   831                                  		; IO Map Base address (When this address points
   832                                  		; to end of the TSS, CPU does not use IO port 
   833                                  		; permission bit map for RING 3 IO permissions, 
   834                                  		; access to any IO ports in ring 3 will be forbidden.)
   835                                   		;
   836                                  	;mov	[tss.esp0], esp ; TSS offset 4
   837                                  	;mov	word [tss.ss0], KDATA ; TSS offset 8 (SS)
   838 000005FD 66B82800                   	mov	ax, TSS  ; It is needed when an interrupt 
   839                                  			 ; occurs (or a system call -software INT- is requested)
   840                                  			 ; while cpu running in ring 3 (in user mode).				
   841                                  			 ; (Kernel stack pointer and segment will be loaded
   842                                  			 ; from offset 4 and 8 of the TSS, by the CPU.)	 
   843 00000601 0F00D8                  	ltr	ax  ; Load task register
   844                                  	;
   845                                  esp0_set0:
   846                                  	; 30/07/2015
   847 00000604 8B0D[DC630100]          	mov 	ecx, [memory_size] ; memory size in pages
   848 0000060A C1E10C                  	shl 	ecx, 12 ; convert page count to byte count
   849 0000060D 81F900004000            	cmp	ecx, CORE ; beginning of user's memory space (400000h)
   850                                  			  ; (kernel mode virtual address)
   851 00000613 7605                    	jna	short esp0_set1
   852                                  	;
   853                                  	; If available memory > CORE (end of the 1st 4 MB)
   854                                  	; set stack pointer to CORE
   855                                  	;(Because, PDE 0 is reserved for kernel space in user's page directory)
   856                                  	;(PDE 0 points to page table of the 1st 4 MB virtual address space)
   857 00000615 B900004000              	mov	ecx, CORE
   858                                  esp0_set1:
   859 0000061A 89CC                    	mov	esp, ecx ; top of kernel stack (**tss.esp0**)
   860                                  esp0_set_ok:
   861                                  	; 30/07/2015 (**tss.esp0**) 
   862 0000061C 8925[74630100]          	mov	[tss.esp0], esp
   863 00000622 66C705[78630100]10-             mov     word [tss.ss0], KDATA
   863 0000062A 00                 
   864                                  	; 14/08/2015
   865                                  	; 10/11/2014 (Retro UNIX 386 v1 - Erdogan Tan)
   866                                  	;
   867                                  	;cli	; Disable interrupts (for CPU)
   868                                  	;    (CPU will not handle hardware interrupts, except NMI!)
   869                                  	;
   870 0000062B 30C0                    	xor	al, al		; Enable all hardware interrupts!
   871 0000062D E621                    	out	21h, al		; (IBM PC-AT compatibility)
   872 0000062F EB00                    	jmp 	$+2		; (All conventional PC-AT hardware
   873 00000631 E6A1                    	out	0A1h, al	;  interrupts will be in use.)	
   874                                  				; (Even if related hardware component
   875                                  				;  does not exist!)
   876                                  	; Enable NMI 
   877 00000633 B07F                    	mov	al, 7Fh		; Clear bit 7 to enable NMI (again)
   878 00000635 E670                    	out  	70h, al
   879                                  	; 23/02/2015
   880 00000637 90                      	nop
   881 00000638 E471                    	in	al, 71h		; read in 71h just after writing out to 70h
   882                                  				; for preventing unknown state (!?)
   883                                  	;
   884                                  	; Only a NMI can occur here... (Before a 'STI' instruction)
   885                                  	;
   886                                  	; 02/09/2014
   887 0000063A 6631DB                  	xor	bx, bx
   888 0000063D 66BA0002                	mov	dx, 0200h	; Row 2, column 0  ; 07/03/2015
   889 00000641 E8511C0000              	call	_set_cpos	; 24/01/2016
   890                                  
   891                                  	; 14/11/2020 (TRDOS 386 v2.0.3)
   892                                  	; Check VBE3 protected mode interface/feature(s)
   893                                  
   894                                  	;cmp	byte [vbe3], 3 ; 03h
   895                                  	;jne	short display_mem_info
   896                                  
   897                                  	; 20/11/2020
   898 00000646 803D[44090000]02        	cmp	byte [vbe3], 2 ; 02h
   899 0000064D 770B                    	ja	short vbe3_pmid_chk
   900                                  	;jb	short display_mem_info
   901 0000064F 0F82C5010000            	jb	display_mem_info ; 02/12/2020
   902 00000655 E9F9010000              	jmp	check_boch_plex86_vbe
   903                                  vbe3_pmid_chk:	
   904 0000065A B9EA7F0000              	mov	ecx, 32768 - (20+2) ; 32766 - PMInfoBlockSize
   905 0000065F BE02000C00              	mov	esi, 0C0002h ; 1st word of the video bios rom is 0AA55h
   906                                  	
   907                                  chk_pmi_sign:
   908                                  	;mov	eax, [esi] 
   909                                  	;cmp	eax, 'PMID'
   910                                  	; 30/11/2020
   911                                  	;cmp	al, 'P'
   912                                  	;jne	short chk_pmi_sign_next
   913 00000664 813E504D4944            	cmp	dword [esi], 'PMID'
   914                                  	;je	short display_vbios_product_name
   915 0000066A 740E                    	je	short verify_pmib_chksum ; 15/11/2020
   916                                  ;chk_pmi_sign_next:
   917 0000066C 46                      	inc	esi  ; inc si
   918 0000066D E2F5                    	loop	chk_pmi_sign
   919                                  
   920                                  not_valid_pmib:
   921 0000066F FE0D[44090000]          	dec	byte [vbe3] ; 2 = VBE2 compatible 
   922                                  			    ; (vbe3 feature is defective in this vbios)
   923                                  	;jmp	short display_mem_info
   924                                  	; 02/12/2020
   925 00000675 E9A0010000              	jmp	display_mem_info
   926                                  
   927                                  verify_pmib_chksum:
   928                                  	; 15/11/2020
   929 0000067A 31C0                    	xor	eax, eax
   930                                  	;mov	ecx, eax 
   931                                  	;mov	cl, 20
   932 0000067C 66B91400                	mov	cx, 20 ; 30/11/2020
   933 00000680 56                      	push	esi
   934                                  pmib_sum_bytes:
   935 00000681 AC                      	lodsb
   936 00000682 00C4                    	add	ah, al
   937 00000684 E2FB                    	loop	pmib_sum_bytes
   938 00000686 5E                      	pop	esi
   939 00000687 08E4                    	or	ah, ah
   940 00000689 75E4                    	jnz	short not_valid_pmib ; AH must be 0
   941                                  
   942                                  display_vbios_product_name: ; 14/11/2020
   943                                  
   944                                  	; ESI points to 'PMID' (0C0000h + 'PMID' offset)
   945                                  
   946                                  	; 15/11/2020
   947                                  	;mov	[pmid_addr], si	; PMInfoBlock offset
   948                                  	;		; (in VGA bios, 0C0000h + offset)
   949                                  	; 02/12/2020
   950                                  	;push	esi ; * pmid_addr
   951 0000068B 89F7                    	mov	edi, esi
   952                                  
   953                                  	;mov	esi, [VBE3INFOBLOCK+22] ; 097E00h + 16h
   954                                  	;		; OemVendorNamePtr (seg16:off16)
   955 0000068D 8B35067E0900            	mov	esi, [VBE3INFOBLOCK+6] ; 097E00h + 06h
   956                                  			; OemStringPtr (seg16:off16)
   957 00000693 30C0                    	xor	al, al  ; eax = 0
   958 00000695 6696                    	xchg	ax, si	; ax = offset, si = 0
   959 00000697 C1EE0C                  	shr	esi, 12 ; (to convert segment to base addr)
   960 0000069A 6601C6                  	add	si, ax  ; esi has an address < 1 MB limit
   961                                  			; (OemVendorName is in VBE3INFOBLOCK)
   962                                  			; Example: 
   963                                  			; TRDOS 386 v2.0.3 VESA VBE3 protected mode
   964                                  			; interface development reference is ...
   965                                  			; NVIDIA GeForce FX5500 VGA BIOS -C000h:029Ch-
   966                                  			; Version 4.34.20.54.00 -C000h:02EDh- 	  
   967                                  			; ((OemString is 'NVIDIA'))
   968                                  			; ((OemVendorName is 'NVIDIA Corporation'))
   969                                  			; ((OemProductName is 'NV34 Board - p162-1nz))
   970                                  
   971                                  	;mov	ah, 0Eh ; Black background, yellow forecolor
   972                                  	; 30/11/2020
   973 0000069D B40C                    	mov	ah, 0Ch ; Black background, light red forecolor
   974                                  
   975 0000069F E8C6350000              	call	print_kmsg
   976                                  
   977                                  	;mov	ah, 07h
   978                                  
   979 000006A4 BE[7E600100]            	mov	esi, vesa_vbe3_bios_msg
   980                                  	;call	print_kmsg
   981 000006A9 E8C2350000              	call	pkmsg_loop ; 30/11/2020
   982                                  
   983                                  	; 02/12/2020
   984                                  	;pop	edi ; * pmid_addr
   985                                  
   986                                  	; 30/11/2020
   987                                  	; 29/11/2020 - TRDOS 386 v2.0.3
   988                                  
   989                                  struc PMInfo  ;  VESA VBE3 PMInfoBlock ('PMID' block)
   990                                  
   991 00000000 <res 00000004>           .Signature:	resb 4  ; db 'PMID' ; PM Info Block Signature
   992 00000004 <res 00000002>           .EntryPoint:	resw 1	; Offset of PM entry point within BIOS
   993 00000006 <res 00000002>           .PMInitialize: resw 1	; Offset of PM initialization entry point
   994 00000008 <res 00000002>           .BIOSDataSel:	resw 1 	; Selector to BIOS data area emulation block
   995 0000000A <res 00000002>           .A0000Sel:	resw 1	; Selector to access A0000h physical mem
   996 0000000C <res 00000002>           .B0000Sel:	resw 1  ; Selector to access B0000h physical mem
   997 0000000E <res 00000002>           .B8000Sel:	resw 1	; Selector to access B8000h physical mem
   998 00000010 <res 00000002>           .CodeSegSel:	resw 1	; Selector to access code segment as data
   999 00000012 <res 00000001>           .InProtectMode: resb 1 ; Set to 1 when in protected mode
  1000 00000013 <res 00000001>           .Checksum:	resb 1	; Checksum byte for structure
  1001                                   .size:
  1002                                  
  1003                                  endstruc
  1004                                  
  1005                                  	; 29/11/2020
  1006                                  vbe3pminit:
  1007                                  	; 30/11/2020
  1008                                  	;cmp	byte [vbe3], 3 ; is VESA VBE3 PMI ready ?
  1009                                  	;jne	short di4
  1010                                  
  1011                                  	; Allocate 64KB contiguous (kernel) memory block
  1012 000006AE 31C0                    	xor	eax, eax
  1013 000006B0 B900000100              	mov	ecx, 65536
  1014 000006B5 E895570000              	call	allocate_memory_block
  1015                                  	;jc	short di4
  1016 000006BA 0F8253010000            	jc	di0 ; 30/11/2020
  1017                                  
  1018                                  	; of course this block must be in the 1st 16MB
  1019                                  	; because vbe3 pmi segments will be 16 bit segments
  1020                                  	; (80286 type segment descriptors in GDT)
  1021                                  
  1022 000006C0 A3[A0110300]            	mov	[vbe3bios_addr], eax
  1023                                  
  1024                                  	; set [pmid_addr] to the new location
  1025 000006C5 BE00000C00              	mov	esi, 0C0000h
  1026                                  
  1027                                  	; 30/11/2020
  1028 000006CA 29F7                    	sub	edi, esi ; izolate offset
  1029 000006CC 01C7                    	add	edi, eax ; new address
  1030 000006CE 893D[A4110300]          	mov	[pmid_addr], edi ; new 'PMID' location	
  1031                                  
  1032                                  	; Move VIDEO BIOS from 0C0000h to EAX
  1033 000006D4 B900400000              	mov	ecx, 65536/4
  1034 000006D9 89C7                    	mov	edi, eax ; 30/11/2020
  1035 000006DB F3A5                    	rep	movsd
  1036                                  
  1037                                  	; 02/12/2020
  1038                                  	; 30/11/2020
  1039                                  	; set vbe3 segment selectors
  1040                                  
  1041                                  	; VBE3CS (VESA VBE3 video bios code segment)
  1042 000006DD BF[F2660000]            	mov	edi, _vbe3_CS+2 ; base address bits 0..15
  1043 000006E2 66AB                    	stosw	; edi = _vbe3_CS+4
  1044 000006E4 C1C810                  	ror	eax, 16
  1045 000006E7 8807                    	mov	[edi], al ; base address, bits 16..23
  1046                                  
  1047                                  	; VBE3DS ('CodeSegSel' in PMInfoBlock)
  1048 000006E9 BF[1C670000]            	mov	edi, _vbe3_DS+4 ; base addr bits 16..23
  1049 000006EE 8807                    	mov	[edi], al 
  1050 000006F0 C1C010                  	rol	eax, 16
  1051 000006F3 668947FE                	mov	[edi-2], ax ; base address, bits 0..15
  1052                                  
  1053                                  	; VBE3BDS (BIOSDataSel in PMInfoBlock)
  1054 000006F7 BF[FA660000]            	mov	edi, _vbe3_BDS+2 ; base addr bits 0..15
  1055 000006FC B800700900              	mov	eax, VBE3BIOSDATABLOCK ; 1536 bytes
  1056 00000701 66AB                    	stosw	; edi = _vbe3_BDS+4
  1057 00000703 C1E810                  	shr	eax, 16
  1058 00000706 8807                    	mov	[edi], al ; base address, bits 16..23
  1059                                  
  1060                                  	; VBE3SS (1024 bytes)
  1061 00000708 BF[22670000]            	mov	edi, _vbe3_SS+2 ; base addr bits 0..15
  1062 0000070D B800600900              	mov	eax, VBE3STACKADDR ; size = 1024 bytes
  1063 00000712 66AB                    	stosw	; edi = _vbe3_SS+4
  1064 00000714 C1E810                  	shr	eax, 16
  1065 00000717 8807                    	mov	[edi], al ; base address, bits 16..23
  1066                                  
  1067                                  	; stack pointer (esp) will be set to 1020
  1068                                  	; (before VBE3 PMI call)
  1069                                  
  1070                                  	; VBE3ES (max: 2048 bytes)
  1071 00000719 BF[2A670000]            	mov	edi, _vbe3_ES+2 ; base addr bits 0..15
  1072 0000071E B800760900              	mov	eax, VBE3SAVERESTOREBLOCK
  1073 00000723 66AB                    	stosw	; edi = _vbe3_ES+4
  1074 00000725 C1E810                  	shr	eax, 16
  1075 00000728 8807                    	mov	[edi], al ; base address, bits 16..23 	
  1076                                  
  1077                                  	;Note: low word of _VBE3_ES base address will be
  1078                                  	;      set -again- by VBE3 PMI caller routine 
  1079                                  
  1080                                  	; 09/12/2020
  1081                                  	;; set pmi32 (as VBE3 PMI is ready)
  1082                                  	;inc	byte [pmi32] ; = 1 
  1083                                  
  1084                                  	; KCODE16 (set PMI far return segment)
  1085 0000072A BF[32670000]            	mov	edi, _16bit_CS+2 ; base addr bits 0..15
  1086 0000072F B8[B8070000]            	mov	eax, pminit_return_addr16
  1087 00000734 66AB                    	stosw	; edi = _16bit_CS+4
  1088 00000736 C1E810                  	shr	eax, 16
  1089 00000739 8807                    	mov	[edi], al ; base address, bits 16..23 
  1090                                  
  1091                                  	; 30/11/2020
  1092                                  	; clear mem from VBE3 BIOS data area emu block
  1093                                  	; to end of vbe3 buffers
  1094                                  
  1095                                  	; 01/12/2020
  1096 0000073B BF00700900              	mov	edi, VBE3BIOSDATABLOCK ; 97000h
  1097                                  	;mov	cx, (VBE3INFOBLOCK-VBE3BIOSDATABLOCK)/4
  1098                                  	;	; ecx = 3584/4 double words
  1099                                  	; 21/12/2020
  1100 00000740 66B90003                	mov	cx, (VBE3MODEINFOBLOCK-VBE3BIOSDATABLOCK)/4
  1101                                  		; ecx = 3072/4 double words
  1102                                  	;xor	eax, eax
  1103 00000744 30C0                    	xor	al, al
  1104 00000746 F3AB                    	rep	stosd
  1105                                  
  1106                                  	; Filling PMInfoBlock selector fields
  1107 00000748 8B3D[A4110300]          	mov	edi, [pmid_addr]
  1108 0000074E 66C747083800            	mov	word [edi+PMInfo.BIOSDataSel], VBE3BDS
  1109 00000754 66C7470A4000            	mov	word [edi+PMInfo.A0000Sel], VBE3A000
  1110 0000075A 66C7470C4800            	mov	word [edi+PMInfo.B0000Sel], VBE3B000
  1111 00000760 66C7470E5000            	mov	word [edi+PMInfo.B8000Sel], VBE3B800	
  1112 00000766 66C747105800            	mov	word [edi+PMInfo.CodeSegSel], VBE3DS
  1113 0000076C C6471201                	mov	byte [edi+PMInfo.InProtectMode], 1
  1114                                  
  1115                                  	; Calculate and write checksum byte
  1116 00000770 89FE                    	mov	esi, edi
  1117 00000772 B113                    	mov	cl, PMInfo.size - 1
  1118                                  	;xor	ah, ah
  1119                                  pmid_chksum:
  1120 00000774 AC                      	lodsb	
  1121 00000775 00C4                    	add	ah, al
  1122 00000777 E2FB                    	loop	pmid_chksum
  1123 00000779 F6DC                    	neg	ah ; 1 -> 255, 255 -> 1
  1124 0000077B 8826                    	mov	byte [esi], ah  ; checksum
  1125                                  
  1126                                  	; far call PM initialization
  1127                                  	; (VBE3 video bios will return via 'retf')
  1128                                  
  1129 0000077D 668B4706                	mov	ax, [edi+PMInfo.PMInitialize]
  1130                                  	; 30/11/2020
  1131 00000781 C1E010                  	shl	eax, 16 ; save entry address in hw
  1132                                  	; ax = 0 
  1133                                  
  1134                                  	; 02/12/2020
  1135 00000784 68[DC070000]            	push	pminit_ok ; normal, near return address
  1136                                  
  1137                                  	; 30/11/2020
  1138                                  _VBE3PMI_fcall:
  1139                                  	; ax = function, hw of eax = entry address
  1140 00000789 9C                      	pushf	; save 32 bit flags
  1141 0000078A 56                      	push	esi ; *
  1142 0000078B 55                      	push	ebp ; **
  1143                                  
  1144 0000078C 89E5                    	mov	ebp, esp ; save 32 bit stack pointer
  1145                                  	
  1146 0000078E 89C6                    	mov	esi, eax
  1147                                  
  1148 00000790 FA                      	cli
  1149                                  
  1150                                  	; Disable interrupts (clear interrupt flag)
  1151                                  	; Reset Interrupt MASK Registers (Master&Slave)
  1152 00000791 B0FF                    	mov	al, 0FFh	; mask off all interrupts
  1153 00000793 E621                    	out	21h, al		; on master PIC (8259)
  1154 00000795 EB00                    	jmp 	$+2  ; (delay)
  1155 00000797 E6A1                    	out	0A1h, al	; on slave PIC (8259)
  1156                                  
  1157                                  	; 02/12/2020
  1158 00000799 66B86000                	mov	ax, VBE3SS
  1159 0000079D 8ED0                    	mov	ss, ax
  1160                                  	
  1161 0000079F BCFC030000              	mov	esp, 1020 ; 30/11/2020
  1162                                  
  1163                                  	; 01/12/2020
  1164                                  	;lss	esp, [stack16]
  1165                                  
  1166 000007A4 C1E810                  	shr	eax, 16	; now, entry address is in lw
  1167                                  
  1168                                  	; 30/11/2020 - 16 bit pm selector test (OK)
  1169                                  	; (32 bit stack push/pop & retf with 32 bit code segment)
  1170                                  	; (16 bit stack push/pop with 16 bit code segment)
  1171                                  	
  1172                                  	; return
  1173                                  	;push	KCODE16
  1174                                  	;push	0 ; 30/11/2020 (pminit_return_addr16)
  1175                                  
  1176                                  	; 30/11/2020 (16 bit stack during retf from video bios)
  1177 000007A7 C7042400007000          	mov	dword [esp], KCODE16 << 16
  1178                                  				; ip = 0, cs = KCODE16 
  1179                                  	; 01/12/2020
  1180                                  	;mov	dword [VBE3STACKADDR+1020], KCODE16*65536
  1181                                  
  1182                                  	;mov	[jumpfar16], eax
  1183                                  
  1184                                  	; 02/12/2020
  1185                                  	; 30/11/2020 (32 bit stack during retf from kernel)
  1186                                  	; far jump/call via retf
  1187 000007AE 6A30                    	push	VBE3CS ; VBE3 video bios's code segment
  1188 000007B0 50                      	push	eax ; PMInitialize or EntryPoint
  1189                                  
  1190 000007B1 6689F0                  	mov	ax, si ; restore function
  1191                                  	
  1192                                  	; 02/12/2020
  1193 000007B4 31F6                    	xor	esi, esi ; (not necessary, it is not used)
  1194                                  	
  1195 000007B6 CB                      	retf 	; far return (to 16 bit code segment)
  1196                                  
  1197                                  	; 01/12/2020
  1198                                  	;db	0EAh  ; far jump to 16 bit code segment
  1199                                  ;jumpfar16:
  1200                                  	;dd	0		
  1201                                  	;dw	VBE3CS
  1202                                  
  1203                                  ;stack16:
  1204                                  	;dd	1020
  1205                                  	;dw	VBE3SS
  1206                                  
  1207 000007B7 90                      	align 2	
  1208                                  
  1209                                  pminit_return_addr16:
  1210                                  	; 02/12/2020
  1211                                  	; 30/11/2020
  1212                                  	;;db	66h 		     ; Prefix for 32-bit
  1213                                  	;db	0EAh 		     ; Opcode for far jump
  1214                                  	;dd	pminit_return_addr32 ; 32 bit Offset
  1215                                  	;dw	KCODE		     ; 32 bit code segment
  1216                                  	; 01/12/2020
  1217 000007B8 EA[BF070000]0800        	jmp	KCODE:pminit_return_addr32
  1218                                  
  1219                                  pminit_return_addr32:
  1220                                  	; restore 32 bit kernel selectors and 32 bit stack addr
  1221 000007BF BE10000000              	mov	esi, KDATA
  1222 000007C4 8EDE                    	mov	ds, si
  1223 000007C6 8EC6                    	mov	es, si
  1224 000007C8 8ED6                    	mov	ss, si
  1225 000007CA 89EC                    	mov	esp, ebp  ; top of stack = iretd return addr
  1226                                  
  1227 000007CC 5D                      	pop	ebp ; **
  1228 000007CD 5E                      	pop	esi ; *
  1229 000007CE 9D                      	popf	; restore 32 bit flags
  1230                                  
  1231                                  	; enable interrupts
  1232                                  
  1233 000007CF FA                      	cli
  1234                                  
  1235                                  	; 21/12/2020
  1236 000007D0 50                      	push	eax
  1237                                  
  1238 000007D1 30C0                    	xor	al, al	   ; Enable all hardware interrupts!
  1239 000007D3 E621                    	out	21h, al	   ; (IBM PC-AT compatibility)
  1240 000007D5 EB00                    	jmp 	$+2	   ; (All conventional PC-AT hardware
  1241 000007D7 E6A1                    	out	0A1h, al   ;  interrupts will be in use.)	
  1242                                  			   ; (Even if related hardware component
  1243                                  			   ;  does not exist!)
  1244 000007D9 58                      	pop	eax
  1245                                  	
  1246 000007DA FB                      	sti
  1247                                  
  1248                                  	; top of stack = return address 
  1249                                  	; ('pminit_ok' for PMinit)
  1250                                  
  1251 000007DB C3                      	retn
  1252                                  
  1253                                  pminit_ok:
  1254                                  	; 03/12/2020
  1255                                  	; (set [pmid_addr] to PMI entry point for next calls)
  1256 000007DC 8305[A4110300]04        	add	dword [pmid_addr], PMInfo.EntryPoint ; + 4
  1257                                  
  1258                                  	; 06/12/2020
  1259                                  	; Save video mode 03h regs/dac/bios state
  1260                                  	
  1261 000007E3 66B8044F                	mov	ax, 4F04h ; VESA VBE Function 04h
  1262                                  			  ; Save/Restore State
  1263 000007E7 28D2                    	sub	dl, dl	; 0 = return buffer size
  1264 000007E9 66B90F00                	mov	cx, 0Fh  ; ctrl/bios/dac/regs
  1265                                  	
  1266 000007ED E800120000              	call	int10h_32bit_pmi
  1267                                   	; bx = number of 64-byte blocks to hold the state buff
  1268                                  	
  1269 000007F2 66891D[A8110300]        	mov	[mode3stbufsize], bx
  1270                                  
  1271                                  	; 06/12/2020	
  1272                                  	; check 'mode3stbufsize' (it must be <= 32)
  1273                                  	
  1274 000007F9 6683FB20                	cmp	bx, 32
  1275 000007FD 771B                    	ja	short display_mem_info ; light red forecolor
  1276                                  
  1277                                  	; 30/11/2020
  1278                                  	; Change VESA VBE3 BIOS text color in order to give
  1279                                  	; "VBE3 PMI initialization has been successed" meaning 	
  1280                                  
  1281 000007FF BE40810B00              	mov	esi, 0B8000h + 160*2 ; row 2
  1282 00000804 89F7                    	mov	edi, esi
  1283                                  vbe3h_chcl:
  1284 00000806 66AD                    	lodsw
  1285 00000808 80FC0C                  	cmp	ah, 0Ch	; light red forecolor
  1286 0000080B 750D                    	jne	short display_mem_info
  1287 0000080D B40E                    	mov	ah, 0Eh ; yellow forecolor
  1288 0000080F 66AB                    	stosw
  1289 00000811 EBF3                    	jmp	short vbe3h_chcl
  1290                                  
  1291                                  di0:
  1292                                  	; 30/11/2020
  1293                                  	; Memory allocation error !
  1294 00000813 C605[44090000]00        	mov	byte [vbe3], 0 ; disable VBE3
  1295                                  
  1296                                  display_mem_info:
  1297                                  	; 19/12/2020
  1298                                  	; temporary
  1299 0000081A E867340000              	call	default_lfb_info
  1300                                  	;
  1301                                  	; 06/11/2014
  1302 0000081F E8ED330000              	call	memory_info
  1303                                  	; 14/08/2015
  1304                                  	;call getch ; 28/02/2015
  1305                                  drv_init:
  1306 00000824 FB                      	sti	; Enable Interrupts 
  1307                                  	; 06/02/2015
  1308 00000825 8B15[D0670000]          	mov	edx, [hd0_type] ; hd0, hd1, hd2, hd3
  1309 0000082B 668B1D[CE670000]        	mov	bx, [fd0_type] ; fd0, fd1
  1310                                  	; 22/02/2015
  1311 00000832 6621DB                  	and	bx, bx
  1312 00000835 756C                    	jnz	short di1
  1313                                  	;
  1314 00000837 09D2                    	or 	edx, edx
  1315 00000839 757A                    	jnz	short di2
  1316                                  	;
  1317                                  setup_error:
  1318 0000083B BE[7A240100]            	mov 	esi, setup_error_msg
  1319                                  psem:	
  1320 00000840 AC                      	lodsb
  1321 00000841 08C0                    	or	al, al
  1322                                  	;jz	short haltx ; 22/02/2015
  1323 00000843 747B                    	jz	short di3
  1324 00000845 56                      	push	esi
  1325                                  	; 13/05/2016
  1326 00000846 BB07000000              	mov	ebx, 7	; Black background, 
  1327                                  			; light gray forecolor
  1328                                  			; Video page 0 (BH=0)
  1329 0000084B E8AD190000              	call	_write_tty
  1330 00000850 5E                      	pop	esi
  1331 00000851 EBED                    	jmp	short psem
  1332                                  
  1333                                  check_boch_plex86_vbe:
  1334                                  	; 20/11/2020
  1335                                  	; check Bochs/Plex86 VGABios VBE extension
  1336                                  	; (check if TRDOS 386 v2 is running on emulators)
  1337                                  	; BOCHS/QEMU/VIRTUALBOX
  1338                                  	;
  1339                                  	; ref: vbe_display_api.txt
  1340                                  
  1341                                  	; bochs/plex86 VGAbios VBE source code
  1342                                  	;  by Jeroen Janssen (2002)
  1343                                  	;  and Volker Ruppert (2003-2020)
  1344                                  
  1345 00000853 29C0                    	sub	eax, eax ; 0
  1346 00000855 66BACE01                	mov	dx, 1CEh ; VBE_DISPI_IOPORT_INDEX
  1347 00000859 66EF                    	out	dx, ax ; VBE_DISPI_INDEX_ID register
  1348                                  	;mov	ax, 0B0C0h ; VBE_DISPI_ID0
  1349                                  	;mov	dx, 1CFh ; VBE_DISPI_IOPORT_DATA
  1350 0000085B 6642                    	inc	dx
  1351                                  	;out	dx, ax
  1352                                  	;nop
  1353 0000085D 66ED                    	in	ax, dx
  1354 0000085F 80FCB0                  	cmp	ah, 0B0h
  1355                                  	;jne	short not_boch_qemu_vbe
  1356 00000862 75B6                    	jne	short display_mem_info
  1357 00000864 3CC5                    	cmp	al, 0C5h ; it must be 0B0C4h or 0B0C5h ..
  1358                                  	;ja	short not_boch_qemu_vbe
  1359 00000866 77B2                    	ja	short display_mem_info
  1360 00000868 3CC0                    	cmp	al, 0C0h ; 0B0C0h to 0B0C5h .. ; Qemu
  1361                                  	;cmp	al, 0C4h ; 0BC04h or 0B0C5h is OK ; Bochs
  1362                                  	;jb	short not_boch_qemu_vbe
  1363 0000086A 72AE                    	jb	short display_mem_info
  1364                                  
  1365                                  	; save VESA VBE2 bios (bochs/qemu) signature
  1366                                  	; for enabling VBE2 functions in TRDOS 386 v2 kernel
  1367 0000086C A2[45090000]            	mov	[vbe2bios], al ; 0C4h or 0C5h (for BOCHS) 
  1368                                  			       ; (0C0h-0C5h for QEMU)
  1369 00000871 C605[87600100]32        	mov	byte [vbe_vnumber], "2"
  1370                                  	; 26/11/2020
  1371                                  	; "BOCHS/QEMU/VIRTUALBOX VBE2 Video BIOS ..".
  1372 00000878 BE[69600100]            	mov	esi, vbe2_bochs_vbios ; BOCH/QEMU vbios msg
  1373 0000087D B40E                    	mov	ah, 0Eh  ; Yellow font
  1374 0000087F E8E6330000              	call	print_kmsg
  1375                                  	
  1376                                  	; this is not necessary ! (20/11/2020)
  1377 00000884 803D[45090000]C4        	cmp	byte [vbe2bios], 0C4h 
  1378 0000088B 728D                    	jb	display_mem_info	; (QEMU) 
  1379                                  
  1380                                  	; Display kernel version message if 0E9h hack port
  1381                                  	; is enabled (bochs emulator feature)
  1382 0000088D 66BAE900                	mov	dx, 0E9h ; hack port for BOCHS
  1383 00000891 BE[C1600100]            	mov	esi, kernel_version_msg
  1384                                  kvmsg_next_char:
  1385 00000896 AC                      	lodsb	
  1386 00000897 08C0                    	or	al, al
  1387 00000899 7505                    	jnz	short put_kvmsg_in_hack_port
  1388                                  not_boch_qemu_vbe:
  1389 0000089B E97AFFFFFF               	jmp	display_mem_info
  1390                                  put_kvmsg_in_hack_port:	
  1391 000008A0 EE                      	out	dx, al
  1392 000008A1 EBF3                    	jmp	short kvmsg_next_char
  1393                                  
  1394                                  di1:
  1395                                  	; supress 'jmp short T6'
  1396                                  	;  (activate fdc motor control code)
  1397 000008A3 66C705[A6090000]90-     	mov	word [T5], 9090h ; nop
  1397 000008AB 90                 
  1398                                  	;
  1399                                  	;mov	ax, int_0Eh	; IRQ 6 handler
  1400                                  	;mov	di, 0Eh*4	; IRQ 6 vector
  1401                                  	;stosw
  1402                                  	;mov 	ax, cs
  1403                                  	;stosw
  1404                                  	;; 16/02/2015
  1405                                          ;;mov     dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
  1406                                  	;
  1407 000008AC E80B430000              	CALL	DSKETTE_SETUP	; Initialize Floppy Disks
  1408                                  	;
  1409 000008B1 09D2                    	or	edx, edx
  1410 000008B3 740B                            jz      short di3
  1411                                  di2:
  1412 000008B5 E84A430000              	call   	DISK_SETUP	; Initialize Fixed Disks
  1413 000008BA 0F827BFFFFFF                    jc      setup_error
  1414                                  di3:
  1415 000008C0 E820330000              	call	setup_rtc_int	; 22/05/2015 (dsectrpm.s)
  1416                                  	;
  1417 000008C5 E8461A0100              	call	display_disks ; 07/03/2015  (Temporary)
  1418                                  ;haltx:
  1419                                  	; 14/08/2015
  1420                                  	;call	getch ; 22/02/2015
  1421                                  	;sti	; Enable interrupts (for CPU)
  1422                                  ;	; 29/01/2016
  1423                                  ;	sub	ah, ah ;  read time count
  1424                                  ;	call	int1Ah
  1425                                  ;	mov	edx, ecx ; 18.2 * seconds
  1426                                  ;md_info_msg_wait1:
  1427                                  ;	; 29/01/2016
  1428                                  ;	mov	ah, 1
  1429                                  ;	call	int16h
  1430                                  ;	jz	short md_info_msg_wait2
  1431                                  ;	xor	ah, ah ; 0
  1432                                  ;       call    int16h
  1433                                  ;	jmp 	short md_info_msg_ok
  1434                                  ;md_info_msg_wait2:
  1435                                  ;	sub	ah, ah  ; read time count
  1436                                  ;	call	int1Ah
  1437                                  ;	cmp	edx, ecx ; ; 18.2 * seconds
  1438                                  ;	jna	short md_info_msg_wait3
  1439                                  ;	xchg 	edx, ecx	
  1440                                  ;md_info_msg_wait3:
  1441                                  ;	sub	ecx, edx
  1442                                  ;	cmp	ecx, 127 ; 7 seconds (18.2 * 7)
  1443                                  ;	jb	short md_info_msg_wait1		
  1444                                  ;md_info_msg_ok:
  1445                                  
  1446                                  	; 15/12/2020
  1447                                  	; set initial values of LFB parameters
  1448                                  
  1449 000008CA 803D[44090000]02        	cmp	byte [vbe3], 2
  1450 000008D1 7214                    	jb	short di4
  1451                                  
  1452                                  	;mov	ax, [def_LFB_addr]
  1453                                  	;shl	eax, 16
  1454                                  	;mov	[LFB_ADDR], eax
  1455                                  	;mov	eax, 1024*768*3
  1456                                  	;mov	[LFB_SIZE], eax
  1457                                  
  1458 000008D3 BEFE7B0900              	mov	esi, VBE3MODEINFOBLOCK - 2
  1459 000008D8 66C7061801              	mov	word [esi], 0118h ; default vbe mode
  1460                                  				  ; 1024*768, 24bpp
  1461 000008DD E8682F0000              	call	set_lfbinfo_table
  1462                                  
  1463 000008E2 E8BE5A0000              	call	allocate_lfb_pages_for_kernel
  1464                                  di4:
  1465                                  	; 08/09/2016
  1466 000008E7 0F20C0                  	mov	eax, cr0
  1467 000008EA A810                    	test	al, 10h  ; Bit 4, ET (Extension Type)
  1468 000008EC 7408                    	jz	short sysinit
  1469                                  	; 27/02/2017
  1470 000008EE FE05[94700100]          	inc	byte [fpready]
  1471                                  	; 80387 (FPU) is ready
  1472 000008F4 DBE3                    	fninit ; Initialize Floating-Point Unit
  1473                                  sysinit:
  1474                                  	; 30/06/2015
  1475 000008F6 E80B650000              	call	sys_init
  1476                                  	;
  1477                                  	;jmp 	cpu_reset ; 22/02/2015
  1478                                  hang:  
  1479                                  	; 23/02/2015
  1480                                  	;sti			; Enable interrupts
  1481 000008FB F4                      	hlt
  1482                                  	;
  1483                                  	;nop
  1484                                  	;; 03/12/2014
  1485                                  	;; 28/08/2014
  1486                                  	;mov	ah, 11h
  1487                                  	;call	getc
  1488                                  	;jz      _c8
  1489                                  	;
  1490                                  	; 23/02/2015
  1491                                  	; 06/02/2015
  1492                                  	; 07/09/2014
  1493 000008FC 31DB                    	xor	ebx, ebx
  1494 000008FE 8A1D[06640100]          	mov	bl, [ptty]	; active_page
  1495 00000904 89DE                    	mov	esi, ebx
  1496 00000906 66D1E6                  	shl 	si, 1
  1497 00000909 81C6[08640100]          	add	esi, ttychr
  1498 0000090F 668B06                  	mov	ax, [esi]
  1499 00000912 6621C0                  	and	ax, ax
  1500                                  	;jz	short _c8
  1501 00000915 74E4                    	jz	short hang
  1502 00000917 66C7060000              	mov	word [esi], 0
  1503 0000091C 80FB03                  	cmp	bl, 3		; Video page 3
  1504                                  	;jb	short _c8
  1505 0000091F 72DA                    	jb	short hang
  1506                                  	;	
  1507                                  	; 13/05/2016
  1508                                  	; 07/09/2014
  1509                                  nxtl:
  1510 00000921 6653                    	push	bx
  1511 00000923 66BB0E00                	mov	bx, 0Eh 	; Yellow character 
  1512                                  				; on black background
  1513                                  				; bh = 0 (video page 0)
  1514                                  				; Retro UNIX 386 v1 - Video Mode 0
  1515                                  				; (PC/AT Video Mode 3 - 80x25 Alpha.)
  1516 00000927 6650                    	push	ax
  1517 00000929 E8CF180000              	call 	_write_tty
  1518 0000092E 6658                    	pop	ax
  1519 00000930 665B                    	pop	bx
  1520 00000932 3C0D                    	cmp	al, 0Dh		; carriage return (enter)
  1521                                  	;jne	short _c8
  1522 00000934 75C5                    	jne	short hang
  1523 00000936 B00A                    	mov	al, 0Ah		; next line
  1524 00000938 EBE7                    	jmp	short nxtl
  1525                                  	
  1526                                  ;_c8:
  1527                                  ;	; 25/08/2014
  1528                                  ;	cli				; Disable interrupts
  1529                                  ;	mov	al, [scounter + 1]
  1530                                  ;	and	al, al
  1531                                  ;	jnz	hang
  1532                                  ;	call	rtc_p
  1533                                  ;	jmp     hang
  1534                                  
  1535                                  	; 27/08/2014
  1536                                  	; 20/08/2014
  1537                                  printk:
  1538                                          ;mov    edi, [scr_row]
  1539                                  pkl:
  1540 0000093A AC                      	lodsb
  1541 0000093B 08C0                    	or 	al, al
  1542 0000093D 7404                    	jz	short pkr
  1543 0000093F 66AB                    	stosw
  1544 00000941 EBF7                    	jmp	short pkl
  1545                                  pkr:
  1546 00000943 C3                      	retn
  1547                                  
  1548                                  ; 14/11/2020 (TRDOS 386 v2.0.3)
  1549 00000944 00                      vbe3:	db 0  ; VESA VBE version (must be 03h)
  1550                                  	      ; for using video bios calls in protected mode
  1551                                  vbe2bios:
  1552 00000945 B0                      	db 0B0h ; 
  1553                                  ;pmid_addr: 		
  1554                                  	;dw 0  ; > 0 if 'PMID' sign is found 
  1555                                  	;     ;	('pmid' offset addr in VGA bios seg, 0C000h)
  1556                                  	;; 02/12/2020
  1557                                  	;dw 0	; 32 bit address in pmid_addr
  1558                                  		
  1559                                  ; 28/02/2017
  1560                                  ; 22/01/2017
  1561                                  ; 15/01/2017
  1562                                  ; 14/01/2017
  1563                                  ; 02/01/2017
  1564                                  ; 25/12/2016
  1565                                  ; 19/12/2016
  1566                                  ; 10/12/2016 (callback)
  1567                                  ; 06/06/2016
  1568                                  ; 23/05/2016
  1569                                  ; 22/05/2016 - TRDOS 386 (TRDOS v2.0) Timer Event Modifications
  1570                                  ; 25/07/2015
  1571                                  ; 14/05/2015 (multi tasking -time sharing- 'clock', x_timer)
  1572                                  ; 17/02/2015
  1573                                  ; 06/02/2015 (unix386.s)
  1574                                  ; 11/12/2014 - 22/12/2014 (dsectrm2.s) 
  1575                                  ;
  1576                                  ; IBM PC-XT Model 286 Source Code - BIOS2.ASM (06/10/85)
  1577                                  ;
  1578                                  ;-- HARDWARE INT  08 H - ( IRQ LEVEL 0 ) ---------------------------------------
  1579                                  ;	THIS ROUTINE HANDLES THE TIMER INTERRUPT FROM FROM CHANNEL 0 OF        :
  1580                                  ;	THE 8254 TIMER.  INPUT FREQUENCY IS 1.19318 MHZ AND THE DIVISOR        :
  1581                                  ;	IS 65536, RESULTING IN APPROXIMATELY 18.2 INTERRUPTS EVERY SECOND.     :
  1582                                  ;									       :
  1583                                  ;	THE INTERRUPT HANDLER MAINTAINS A COUNT (40:6C) OF INTERRUPTS SINCE    :
  1584                                  ;	POWER ON TIME, WHICH MAY BE USED TO ESTABLISH TIME OF DAY.	       :
  1585                                  ;	THE INTERRUPT HANDLER ALSO DECREMENTS THE MOTOR CONTROL COUNT (40:40)  :
  1586                                  ;	OF THE DISKETTE, AND WHEN IT EXPIRES, WILL TURN OFF THE 	       :
  1587                                  ;	DISKETTE MOTOR(s), AND RESET THE MOTOR RUNNING FLAGS.		       :
  1588                                  ;	THE INTERRUPT HANDLER WILL ALSO INVOKE A USER ROUTINE THROUGH	       :
  1589                                  ;	INTERRUPT 1CH AT EVERY TIME TICK.  THE USER MUST CODE A 	       :
  1590                                  ;	ROUTINE AND PLACE THE CORRECT ADDRESS IN THE VECTOR TABLE.	       :
  1591                                  ;-------------------------------------------------------------------------------
  1592                                  ;
  1593                                  
  1594                                  timer_int:	; IRQ 0
  1595                                  ;int_08h:	; Timer
  1596                                  	; 14/10/2015
  1597                                  	; Here, we are simulating system call entry (for task switch)
  1598                                  	; (If multitasking is enabled, 
  1599                                  	; 'clock' procedure may jump to 'sysrelease')
  1600                                  
  1601 00000946 1E                      	push	ds
  1602 00000947 06                      	push	es
  1603 00000948 0FA0                    	push	fs
  1604 0000094A 0FA8                    	push	gs
  1605                                  
  1606 0000094C 60                      	pushad	; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
  1607 0000094D 66B91000                	mov     cx, KDATA
  1608 00000951 8ED9                            mov     ds, cx
  1609 00000953 8EC1                            mov     es, cx
  1610 00000955 8EE1                            mov     fs, cx
  1611 00000957 8EE9                            mov     gs, cx
  1612                                  
  1613 00000959 0F20D9                  	mov	ecx, cr3
  1614 0000095C 890D[5C040300]          	mov	[cr3reg], ecx ; save current cr3 register value/content
  1615                                  
  1616                                  	; 14/01/2017
  1617 00000962 3B0D[D8630100]          	cmp 	ecx, [k_page_dir]
  1618 00000968 7409                    	je	short T3
  1619                                  
  1620 0000096A 8B0D[D8630100]          	mov	ecx, [k_page_dir]
  1621 00000970 0F22D9                  	mov	cr3, ecx
  1622                                  T3:
  1623                                  	;sti				; INTERRUPTS BACK ON
  1624 00000973 66FF05[58640100]        	INC	word [TIMER_LOW]	; INCREMENT TIME
  1625 0000097A 7507                    	JNZ	short T4		; GO TO TEST_DAY
  1626 0000097C 66FF05[5A640100]        	INC	word [TIMER_HIGH]	; INCREMENT HIGH WORD OF TIME
  1627                                  T4:					; TEST_DAY
  1628 00000983 66833D[5A640100]18      	CMP	word [TIMER_HIGH],018H	; TEST FOR COUNT EQUALING 24 HOURS
  1629 0000098B 7519                    	JNZ	short T5		; GO TO DISKETTE_CTL
  1630 0000098D 66813D[58640100]B0-     	CMP	word [TIMER_LOW],0B0H
  1630 00000995 00                 
  1631 00000996 750E                    	JNZ	short T5		; GO TO DISKETTE_CTL
  1632                                  
  1633                                  ;-----	TIMER HAS GONE 24 HOURS
  1634                                  	;;SUB	AX,AX
  1635                                  	;MOV	[TIMER_HIGH],AX
  1636                                  	;MOV	[TIMER_LOW],AX
  1637 00000998 29C0                    	sub	eax, eax
  1638 0000099A A3[58640100]            	mov	[TIMER_LH], eax
  1639                                  	;	
  1640 0000099F C605[5C640100]01        	MOV	byte [TIMER_OFL],1
  1641                                  
  1642                                  ;-----	TEST FOR DISKETTE TIME OUT
  1643                                  
  1644                                  T5:
  1645                                  	; 23/12/2014
  1646 000009A6 EB1D                    	jmp	short T6		; will be replaced with nop, nop
  1647                                  					; (9090h) if a floppy disk
  1648                                  					; is detected.
  1649                                  	;mov	al,[CS:MOTOR_COUNT]
  1650 000009A8 A0[5F640100]            	mov	al, [MOTOR_COUNT]
  1651 000009AD FEC8                    	dec	al
  1652                                  	;mov	[CS:MOTOR_COUNT], al	; DECREMENT DISKETTE MOTOR CONTROL
  1653 000009AF A2[5F640100]            	mov	[MOTOR_COUNT], al
  1654                                  	;mov	[ORG_MOTOR_COUNT], al
  1655 000009B4 750F                    	JNZ	short T6		; RETURN IF COUNT NOT OUT
  1656 000009B6 B0F0                    	mov 	al,0F0h
  1657                                  	;AND	[CS:MOTOR_STATUS],al 	; TURN OFF MOTOR RUNNING BITS
  1658 000009B8 2005[5E640100]          	and	[MOTOR_STATUS], al
  1659                                  	;and	[ORG_MOTOR_STATUS], al
  1660 000009BE B00C                    	MOV	AL,0CH			; bit 3 = enable IRQ & DMA, 
  1661                                  					; bit 2 = enable controller
  1662                                  					;	1 = normal operation
  1663                                  					;	0 = reset	
  1664                                  					; bit 0, 1 = drive select
  1665                                  					; bit 4-7 = motor running bits 
  1666 000009C0 66BAF203                	MOV	DX,03F2H		; FDC CTL PORT
  1667 000009C4 EE                      	OUT	DX,AL			; TURN OFF THE MOTOR
  1668                                  T6:	
  1669                                  	;inc	word [CS:wait_count]	; 22/12/2014 (byte -> word)
  1670                                  					; TIMER TICK INTERRUPT
  1671                                  	;;inc	word [wait_count] ;;27/02/2015
  1672                                  	;INT	1CH			; TRANSFER CONTROL TO A USER ROUTINE
  1673                                  	;cli
  1674 000009C5 E857040000              	call 	u_timer			; TRANSFER CONTROL TO A USER ROUTINE
  1675                                  	; 23/05/2016
  1676 000009CA E880FA0000              	call	clock			; Multi Tasking control procedure
  1677                                  T7:
  1678                                  	; 14/10/2015
  1679 000009CF B020                    	MOV	AL,EOI			; GET END OF INTERRUPT MASK
  1680 000009D1 FA                      	CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
  1681 000009D2 E620                    	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
  1682                                  	;
  1683                                  rtc_int_2:
  1684                                  	; 26/12/2016
  1685                                  	;mov	ecx, [cr3reg]
  1686                                  	; 13/01/2017
  1687 000009D4 803D[D4030300]00        	cmp	byte [u.t_lock], 0  	; T_LOCK
  1688 000009DB 7730                    	ja	short timer_int_return  ; Timer Lock : 'sysrele' is needed !
  1689                                  	; 28/02/2017
  1690                                  	; We need to exit if the user's IRQ callback service is in progress!
  1691                                  	; (To prevent a conflict!)
  1692 000009DD 803D[D8030300]00        	cmp	byte [u.r_lock], 0	; R_LOCK, IRQ callback service lock !
  1693 000009E4 7727                    	ja	short timer_int_return  ; Timer Lock : 'sysrele' is needed !	
  1694                                  	; 15/01/2017
  1695 000009E6 803D[68700100]02        	cmp	byte [priority], 2
  1696 000009ED 733A                    	jnb	short T8  ; current process has a timer event (15/01/2017)
  1697                                  	; 22/05/2016
  1698 000009EF 803D[69700100]00        	cmp	byte [p_change], 0 ; in 'set_run_sequence', in 'rtc_p'
  1699 000009F6 7615                    	jna	short timer_int_return ; 23/05/2016
  1700                                  
  1701                                  	; 15/01/2017
  1702                                  	
  1703                                  	; present process must be changed with high priority process	
  1704                                  	;xor	al, al
  1705 000009F8 31C0                    	xor	eax, eax ; 26/12/2016
  1706 000009FA A2[69700100]            	mov	[p_change], al ; 0
  1707                                  	;mov	byte [priority], 2 ; 15/01/2017 (there is a timer event)
  1708                                  
  1709 000009FF 803D[5B030300]FF        	cmp     byte [sysflg], 0FFh ; user or system space ?
  1710 00000A06 7416                    	je	short rtc_int_3     ; user space ([sysflg]= 0FFh)
  1711                                  
  1712                                  	; system space, wait for 'sysret'
  1713                                  	; to change running process 	
  1714                                  	; with high priority (event) process
  1715                                  
  1716 00000A08 A2[A8030300]            	mov	[u.quant], al ; 0
  1717                                  
  1718                                  timer_int_return: ; 23/05/2016 - jump from 'rtc_int' ('rtc_int_2')
  1719 00000A0D 8B0D[5C040300]          	mov 	ecx, [cr3reg] 	; previous value/content of cr3 register
  1720 00000A13 0F22D9                   	mov	cr3, ecx	; restore cr3 register content
  1721                                  	;
  1722 00000A16 61                      	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
  1723                                  	;
  1724 00000A17 0FA9                    	pop	gs
  1725 00000A19 0FA1                    	pop	fs
  1726 00000A1B 07                      	pop	es
  1727 00000A1C 1F                      	pop	ds
  1728                                  	;
  1729 00000A1D CF                      	iretd	; return from interrupt
  1730                                  
  1731                                  rtc_int_3:
  1732 00000A1E FE05[5B030300]          	inc	byte [sysflg] 	; now, we are in system space
  1733                                  	;
  1734 00000A24 E9C3C80000                      jmp     sysrelease ; change running process immediatelly 
  1735                                  
  1736                                  T8:
  1737                                  	; 13/01/2017 (eax -> ebx)
  1738                                  	; callback checking... (19/12/2016)
  1739 00000A29 31DB                    	xor	ebx, ebx
  1740 00000A2B 871D[D0030300]          	xchg	ebx, [u.tcb] ; callback address (0 = normal return)
  1741 00000A31 09DB                    	or	ebx, ebx
  1742 00000A33 74D8                    	jz	short timer_int_return
  1743                                  
  1744                                  	; Set user's callback routine as return address from this interrupt
  1745                                  	; and set normal return address as return address from callback
  1746                                  	; routine!!! (19/12/2016)
  1747                                  	
  1748                                  	; 14/01/2017
  1749                                  	; 13/01/2017 - Timer Lock (T_LOCK)
  1750 00000A35 FE05[D4030300]          	inc	byte [u.t_lock]
  1751 00000A3B 8A0D[5B030300]          	mov	cl, [sysflg]
  1752 00000A41 880D[D5030300]          	mov	[u.t_mode], cl 
  1753                                  
  1754 00000A47 8B2D[74630100]          	mov	ebp, [tss.esp0] ; kernel stack address (for ring 0)
  1755 00000A4D 83ED14                  	sub	ebp, 20		; eip, cs, eflags, esp, ss
  1756 00000A50 892D[5C030300]           	mov	[u.sp], ebp
  1757 00000A56 8925[60030300]          	mov	[u.usp], esp
  1758                                  
  1759                                  	;or	word [ebp+8], 200h ; 22/01/2017, force enabling interrupts
  1760                                  
  1761 00000A5C 8B44241C                	mov	eax, [esp+28] ; pushed eax
  1762 00000A60 A3[64030300]            	mov	[u.r0], eax
  1763                                  
  1764 00000A65 E8DBE60000              	call	wswap ; save user's registers & status
  1765                                  
  1766                                  	; software int is in ring 0 but timer int must return to ring 3
  1767                                  	; so, ring 3 return address and stack registers
  1768                                  	; (eip, cs, eflags, esp, ss) 
  1769                                  	; must be copied to timer int return
  1770                                  	; eip will be replaced by callback service routine address
  1771                                  
  1772 00000A6A C605[5B030300]FF        	mov	byte [sysflg], 0FFh ; user mode
  1773                                  
  1774                                  	; system mode (system call)
  1775                                  	;mov	ebp, [u.sp] ; EIP (u), CS (UCODE), EFLAGS (u),
  1776                                  			    ; ESP (u), SS (UDATA)
  1777                                  
  1778 00000A71 8B4510                  	mov	eax, [ebp+16]	; SS (UDATA
  1779 00000A74 89E6                    	mov	esi, esp
  1780 00000A76 50                      	push	eax
  1781 00000A77 50                      	push	eax
  1782 00000A78 89E7                    	mov	edi, esp
  1783 00000A7A 893D[60030300]          	mov	[u.usp], edi
  1784 00000A80 B908000000              	mov	ecx, ((ESPACE/4) - 4) ; except DS, ES, FS, GS
  1785 00000A85 F3A5                    	rep	movsd
  1786 00000A87 B104                    	mov	cl, 4	
  1787 00000A89 F3AB                    	rep	stosd
  1788 00000A8B 893D[5C030300]          	mov	[u.sp], edi
  1789 00000A91 89EE                    	mov	esi, ebp
  1790 00000A93 B105                    	mov	cl, 5 ; EIP (u), CS (UCODE), EFLAGS (u), ESP (u), SS (UDATA)
  1791 00000A95 F3A5                    	rep	movsd
  1792                                  
  1793 00000A97 8B0D[B8030300]          	mov	ecx, [u.pgdir]
  1794 00000A9D 890D[5C040300]          	mov	[cr3reg], ecx
  1795                                  
  1796                                  	; 13/01/207 (eax -> ebx)
  1797                                  	; EBX = callback routine address (virtual, not physical address!)
  1798                                  
  1799                                  	; 09/01/2017
  1800                                  	; !!! CALLBACK ROUTINE MUST BE ENDED/RETURNED WITH 'sysrele'
  1801                                  	;     system call !!!	
  1802                                  	; 25/12/2016
  1803                                  	; Callback Note: (19/12/2016)
  1804                                  	; !!! CALLBACK ROUTINE MUST BE ENDED/RETURNED WITH 'RETN' !!!
  1805                                  	;	pushf ; save flags	
  1806                                  	; 	<callback service code>
  1807                                  	; 	popf  ; restore flags
  1808                                  	; 	retn ; return to normal running address
  1809                                  	;
  1810                                  
  1811                                  	; 15/01/2017
  1812                                  	; 14/01/2017
  1813                                  	; 13/01/2017 (eax -> ebx)
  1814                                  	; 10/01/2017
  1815                                  set_callback_addr:
  1816                                  	; 09/01/2017 (**)
  1817                                  	; 02/01/2017 (*)
  1818                                  	; 25/12/2016 (*)
  1819                                  	; 19/12/2016 (TRDOS 386 feature only!)
  1820                                  	;
  1821                                  	; This routine sets return address
  1822                                  	; to start of user's interrupt
  1823                                  	; service (callback) address
  1824                                  	;; and sets callback 'retn' address to normal
  1825                                  	;; return address of user's running code! 
  1826                                  	;
  1827                                  	; INPUT:
  1828                                  	;	EBX = callback routine/service address
  1829                                  	;	      (virtual, not physical address!)	
  1830                                  	;	[u.sp] = kernel stack, points to
  1831                                  	;		 user's EIP,CS,EFLAGS,ESP,SS
  1832                                  	;		 registers.
  1833                                  	; OUTPUT:
  1834                                  	;	EIP (user) = callback (service) address
  1835                                  	;	CS (user) = UCODE
  1836                                  	;	EFLAGS (user) = flags before callback 	 
  1837                                  	;       ESP (user) = ESP-4 (user, before callback) 
  1838                                  	;	[ESP](user) = EIP (user) before callback
  1839                                  	;
  1840                                  	; Note: If CPU was in user mode while entering 
  1841                                  	;	the timer interrupt service routine,
  1842                                  	;	'IRET' will get return to callback routine
  1843                                  	;	immediately. If CPU was in system/kernel mode  
  1844                                  	;	'iret' will get return to system call and
  1845                                  	;	then, callback routine will be return address
  1846                                  	;	from system call. (User's callback/service code
  1847                                  	;	will be able to return to normal return address
  1848                                  	;	via an 'retn' at the end.) 
  1849                                  	;
  1850                                  	; Note(**): User's callback service code must be ended
  1851                                  	;	with a 'sysrele' sytstem call ! (09/01/2017)
  1852                                  	;
  1853                                  	;	For example:
  1854                                  	;
  1855                                  	;	timer_callback:
  1856                                  	;	    ...	 
  1857                                    	;	    inc	dword [time_counter]
  1858                                  	;	    ...
  1859                                  	;	    mov eax, 39 ; 'sysrele'
  1860                                  	;	    int 40h ; TRDOS 386 system call (interrupt)		
  1861                                  	;
  1862                                  	;
  1863                                  	;; Note(*): User's callback service code must preserve cpu 
  1864                                  	;;	flags if it has any instructions which changes
  1865                                  	;;	flags in the service code. (25/12/2016)
  1866                                  	;;
  1867                                  	;;	For example:
  1868                                  	;;
  1869                                  	;;	timer_callback:
  1870                                  	;;	    pushf ; save flags
  1871                                  	;;	    ; this instruction changes zero flag
  1872                                    	;;	    inc	dword [time_counter]
  1873                                  	;;	    popf ; restore flags
  1874                                  	;;	    retn ; return to normal user code
  1875                                  	;;		  (which is interrupted by the 
  1876                                  	;;		   timer interput) 	
  1877                                  	;;
  1878                                  
  1879                                  	; 15/01/2017
  1880 00000AA3 8B2D[5C030300]          	mov	ebp, [u.sp]; kernel's stack, points to EIP (user)
  1881 00000AA9 895D00                  	mov	[ebp], ebx
  1882 00000AAC E95CFFFFFF              	jmp	timer_int_return
  1883                                  
  1884                                  	; 15/01/2017
  1885                                  	; 13/01/2017
  1886                                  	; 19/12/2016
  1887                                  	; 06/06/2016
  1888                                  	; 23/05/2016
  1889                                  	; 22/05/2016
  1890                                  	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
  1891                                  	; 26/02/2015
  1892                                  	; 07/09/2014
  1893                                  	; 25/08/2014
  1894                                  rtc_int:       ; Real Time Clock Interrupt (IRQ 8)
  1895                                  	; 22/05/2016
  1896 00000AB1 1E                      	push	ds ; ** ; 23/05/2016
  1897 00000AB2 50                      	push	eax ; *
  1898 00000AB3 66B81000                	mov	ax, KDATA
  1899 00000AB7 8ED8                    	mov	ds, ax
  1900                                  	;
  1901 00000AB9 8A25[56640100]          	mov	ah, [RTC_2Hz] ;  2 Hz interrupt to 1 Hz function
  1902 00000ABF 80F401                  	xor	ah, 1
  1903 00000AC2 8825[56640100]          	mov	[RTC_2Hz], ah ; 1 = 0.5 second, 0 = 1 second
  1904 00000AC8 753B                    	jnz	short rtc_int_return ; half second
  1905                                  	; 1 second
  1906                                  rtc_int_0:
  1907                                  	; 22/05/2016
  1908 00000ACA 58                      	pop	eax ; *
  1909                                  	;
  1910                                  	; 14/10/2015 ('timer_int')
  1911                                  	; Here, we are simulating system call entry (for task switch)
  1912                                  	; (If multitasking is enabled, 
  1913                                  	; 'clock' procedure may jump to 'sysrelease')
  1914                                  	;push	ds ; ** ; 23/05/2016
  1915 00000ACB 06                      	push	es
  1916 00000ACC 0FA0                    	push	fs
  1917 00000ACE 0FA8                    	push	gs
  1918 00000AD0 60                      	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
  1919 00000AD1 66B91000                	mov     cx, KDATA
  1920                                          ;mov    ds, cx ; 06/06/2016
  1921 00000AD5 8EC1                            mov     es, cx
  1922 00000AD7 8EE1                            mov     fs, cx
  1923 00000AD9 8EE9                            mov     gs, cx
  1924                                  	;
  1925 00000ADB 0F20D9                  	mov	ecx, cr3
  1926 00000ADE 890D[5C040300]          	mov	[cr3reg], ecx ; save current cr3 register value/content
  1927                                  	;
  1928 00000AE4 803D[D4030300]00        	cmp	byte [u.t_lock], 0 ; timer lock (callback) status ?
  1929 00000AEB 7711                    	ja	short rtc_int_1	   ; yes
  1930                                  
  1931                                  	; 15/01/2017
  1932 00000AED 3B0D[D8630100]          	cmp 	ecx, [k_page_dir]
  1933 00000AF3 7409                    	je	short rtc_int_1
  1934                                  
  1935 00000AF5 8B0D[D8630100]          	mov	ecx, [k_page_dir]
  1936 00000AFB 0F22D9                  	mov	cr3, ecx
  1937                                  rtc_int_1:
  1938                                  	; Timer event (kernel) functions must be performed with
  1939                                  	; 1 second intervals - TRDOS 386 (TRDOS v2.0) feature ! -
  1940                                   	;	
  1941                                  	; 25/08/2014
  1942 00000AFE E81A030000              	call	rtc_p  ; 19/05/2016 - major modification 
  1943                                  	
  1944                                  	; 23/05/2016
  1945 00000B03 28E4                    	sub	ah, ah ; 0
  1946                                  	; 22/05/2016 - TRDOS 386 timer event modifications
  1947                                  rtc_int_return: ; 19/05/2016
  1948                                  	; 22/02/2015 - dsectpm.s
  1949                                  	; [ source: http://wiki.osdev.org/RTC ]
  1950                                  	; read status register C to complete procedure
  1951                                  	;(it is needed to get a next IRQ 8) 
  1952 00000B05 B00C                    	mov	al, 0Ch ; 
  1953 00000B07 E670                    	out	70h, al ; select register C
  1954 00000B09 90                      	nop
  1955 00000B0A E471                    	in	al, 71h ; just throw away contents
  1956                                  	; 22/02/2015
  1957 00000B0C B020                    	MOV	AL,EOI		; END OF INTERRUPT
  1958                                  	;CLI			; DISABLE INTERRUPTS TILL STACK CLEARED
  1959 00000B0E E6A0                    	OUT	INTB00,AL	; FOR CONTROLLER #2
  1960                                  
  1961                                  	; 23/05/2016
  1962 00000B10 B020                    	MOV	AL,EOI		; GET END OF INTERRUPT MASK
  1963 00000B12 FA                      	CLI			; DISABLE INTERRUPTS TILL STACK CLEARED
  1964 00000B13 E620                    	OUT	INTA00,AL	; END OF INTERRUPT TO 8259 - 1	
  1965                                  	;
  1966                                  	; 23/05/2016
  1967 00000B15 20E4                    	and	ah, ah
  1968 00000B17 0F84B7FEFFFF                    jz      rtc_int_2
  1969                                  	
  1970                                  	; ah = 1 (half second)
  1971 00000B1D 58                      	pop	eax ; *
  1972 00000B1E 1F                      	pop	ds  ; **
  1973 00000B1F CF                      	iretd
  1974                                  
  1975                                  ; ////////////////
  1976                                  
  1977                                  	; 28/08/2014
  1978                                  irq0:
  1979 00000B20 6A00                            push 	dword 0
  1980 00000B22 EB48                    	jmp	short which_irq
  1981                                  irq1:
  1982 00000B24 6A01                            push 	dword 1
  1983 00000B26 EB44                    	jmp	short which_irq
  1984                                  irq2:
  1985 00000B28 6A02                            push 	dword 2
  1986 00000B2A EB40                    	jmp	short which_irq
  1987                                  irq3:
  1988                                  	; 20/11/2015
  1989                                  	; 24/10/2015
  1990 00000B2C 2EFF15[0D070100]        	call	dword [cs:com2_irq3]
  1991 00000B33 6A03                    	push 	dword 3
  1992 00000B35 EB35                    	jmp	short which_irq
  1993                                  irq4:
  1994                                  	; 20/11/2015
  1995                                  	; 24/10/2015
  1996 00000B37 2EFF15[09070100]        	call	dword [cs:com1_irq4]
  1997 00000B3E 6A04                            push 	dword 4
  1998 00000B40 EB2A                    	jmp	short which_irq
  1999                                  irq5:
  2000 00000B42 6A05                            push 	dword 5
  2001 00000B44 EB26                    	jmp	short which_irq
  2002                                  irq6:
  2003 00000B46 6A06                            push 	dword 6
  2004 00000B48 EB22                    	jmp	short which_irq
  2005                                  irq7:
  2006 00000B4A 6A07                            push 	dword 7
  2007 00000B4C EB1E                    	jmp	short which_irq
  2008                                  irq8:
  2009 00000B4E 6A08                            push 	dword 8
  2010 00000B50 EB1A                    	jmp	short which_irq
  2011                                  irq9:
  2012 00000B52 6A09                            push 	dword 9
  2013 00000B54 EB16                    	jmp	short which_irq
  2014                                  irq10:
  2015 00000B56 6A0A                            push 	dword 10
  2016 00000B58 EB12                    	jmp	short which_irq
  2017                                  irq11:
  2018 00000B5A 6A0B                            push 	dword 11
  2019 00000B5C EB0E                    	jmp	short which_irq
  2020                                  irq12:
  2021 00000B5E 6A0C                            push 	dword 12
  2022 00000B60 EB0A                    	jmp	short which_irq
  2023                                  irq13:
  2024 00000B62 6A0D                            push 	dword 13
  2025 00000B64 EB06                    	jmp	short which_irq
  2026                                  irq14:
  2027 00000B66 6A0E                            push 	dword 14
  2028 00000B68 EB02                    	jmp	short which_irq
  2029                                  irq15:
  2030 00000B6A 6A0F                            push 	dword 15
  2031                                  	;jmp	short which_irq
  2032                                  
  2033                                  	; 22/01/2017
  2034                                  	; 19/10/2015
  2035                                  	; 29/08/2014
  2036                                  	; 21/08/2014
  2037                                  which_irq:
  2038 00000B6C 870424                  	xchg	eax, [esp]  ; 28/08/2014
  2039 00000B6F 53                      	push	ebx
  2040 00000B70 56                      	push	esi
  2041 00000B71 57                      	push	edi
  2042 00000B72 1E                      	push 	ds
  2043 00000B73 06                      	push 	es
  2044                                  	;
  2045 00000B74 88C3                    	mov	bl, al
  2046                                  	;
  2047 00000B76 B810000000              	mov	eax, KDATA
  2048 00000B7B 8ED8                    	mov	ds, ax
  2049 00000B7D 8EC0                    	mov	es, ax
  2050                                  	; 19/10/2015
  2051 00000B7F FC                      	cld
  2052                                          ; 27/08/2014
  2053 00000B80 8105[6A210100]A000-             add     dword [scr_row], 0A0h
  2053 00000B88 0000               
  2054                                  	;
  2055 00000B8A B417                    	mov	ah, 17h	; blue (1) background, 
  2056                                  			; light gray (7) forecolor
  2057 00000B8C 8B3D[6A210100]                  mov     edi, [scr_row]
  2058 00000B92 B049                    	mov	al, 'I'
  2059 00000B94 66AB                    	stosw
  2060 00000B96 B052                    	mov	al, 'R'
  2061 00000B98 66AB                    	stosw
  2062 00000B9A B051                    	mov	al, 'Q'
  2063 00000B9C 66AB                    	stosw
  2064 00000B9E B020                    	mov	al, ' '
  2065 00000BA0 66AB                    	stosw
  2066 00000BA2 88D8                    	mov	al, bl
  2067 00000BA4 3C0A                    	cmp	al, 10
  2068 00000BA6 7208                    	jb	short ii1
  2069 00000BA8 B031                    	mov	al, '1'
  2070 00000BAA 66AB                    	stosw
  2071 00000BAC 88D8                    	mov	al, bl
  2072 00000BAE 2C0A                    	sub	al, 10
  2073                                  ii1:
  2074 00000BB0 0430                    	add	al, '0'
  2075 00000BB2 66AB                    	stosw
  2076 00000BB4 B020                    	mov	al, ' '
  2077 00000BB6 66AB                    	stosw
  2078 00000BB8 B021                    	mov	al, '!'
  2079 00000BBA 66AB                    	stosw
  2080 00000BBC B020                    	mov	al, ' '
  2081 00000BBE 66AB                    	stosw
  2082                                  	; 23/02/2015
  2083 00000BC0 80FB07                  	cmp	bl, 7 ; check for IRQ 8 to IRQ 15 
  2084 00000BC3 7604                    	jna	ii2
  2085                                  	; 22/01/2017
  2086 00000BC5 B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  2087 00000BC7 E6A0                    	out	0A0h, al ; the 2nd 8259
  2088                                  ii2:
  2089 00000BC9 B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  2090 00000BCB E620                    	out	20h, al ; the 2nd 8259
  2091 00000BCD E9CD010000              	jmp     iiret
  2092                                  	;
  2093                                  	; 22/08/2014
  2094                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  2095                                  	;out	20h, al	; 8259 PORT
  2096                                  	;
  2097                                  	;pop	es
  2098                                  	;pop	ds
  2099                                  	;pop	edi
  2100                                  	;pop	esi
  2101                                  	;pop	ebx
  2102                                  	;pop 	eax
  2103                                  	;iret
  2104                                  
  2105                                  	; 02/04/2015
  2106                                  	; 25/08/2014
  2107                                  exc0:
  2108 00000BD2 6A00                            push 	dword 0
  2109 00000BD4 E990000000                      jmp     cpu_except
  2110                                  exc1:
  2111 00000BD9 6A01                            push 	dword 1
  2112 00000BDB E989000000                      jmp     cpu_except
  2113                                  exc2:
  2114 00000BE0 6A02                            push 	dword 2
  2115 00000BE2 E982000000                      jmp     cpu_except
  2116                                  exc3:
  2117 00000BE7 6A03                            push 	dword 3
  2118 00000BE9 EB7E                            jmp     cpu_except
  2119                                  exc4:
  2120 00000BEB 6A04                            push 	dword 4
  2121 00000BED EB7A                            jmp     cpu_except
  2122                                  exc5:
  2123 00000BEF 6A05                            push 	dword 5
  2124 00000BF1 EB76                            jmp     cpu_except
  2125                                  exc6:
  2126 00000BF3 6A06                            push 	dword 6
  2127 00000BF5 EB72                            jmp     cpu_except
  2128                                  exc7:
  2129 00000BF7 6A07                            push 	dword 7
  2130 00000BF9 EB6E                            jmp     cpu_except
  2131                                  exc8:
  2132                                  	; [esp] = Error code
  2133 00000BFB 6A08                            push 	dword 8
  2134 00000BFD EB5C                            jmp     cpu_except_en
  2135                                  exc9:
  2136 00000BFF 6A09                            push 	dword 9
  2137 00000C01 EB66                            jmp     cpu_except
  2138                                  exc10:
  2139                                  	; [esp] = Error code
  2140 00000C03 6A0A                            push 	dword 10
  2141 00000C05 EB54                            jmp     cpu_except_en
  2142                                  exc11:
  2143                                  	; [esp] = Error code
  2144 00000C07 6A0B                            push 	dword 11
  2145 00000C09 EB50                            jmp     cpu_except_en
  2146                                  exc12:
  2147                                  	; [esp] = Error code
  2148 00000C0B 6A0C                            push 	dword 12
  2149 00000C0D EB4C                            jmp     cpu_except_en
  2150                                  exc13:
  2151                                  	; [esp] = Error code
  2152 00000C0F 6A0D                            push 	dword 13
  2153 00000C11 EB48                            jmp     cpu_except_en
  2154                                  exc14:
  2155                                  	; [esp] = Error code
  2156 00000C13 6A0E                            push 	dword 14
  2157 00000C15 EB44                    	jmp	short cpu_except_en
  2158                                  exc15:
  2159 00000C17 6A0F                            push 	dword 15
  2160 00000C19 EB4E                            jmp     cpu_except
  2161                                  exc16:
  2162 00000C1B 6A10                            push 	dword 16
  2163 00000C1D EB4A                            jmp     cpu_except
  2164                                  exc17:
  2165                                  	; [esp] = Error code
  2166 00000C1F 6A11                            push 	dword 17
  2167 00000C21 EB38                    	jmp	short cpu_except_en
  2168                                  exc18:
  2169 00000C23 6A12                            push 	dword 18
  2170 00000C25 EB42                    	jmp	short cpu_except
  2171                                  exc19:
  2172 00000C27 6A13                            push 	dword 19
  2173 00000C29 EB3E                    	jmp	short cpu_except
  2174                                  exc20:
  2175 00000C2B 6A14                            push 	dword 20
  2176 00000C2D EB3A                    	jmp	short cpu_except
  2177                                  exc21:
  2178 00000C2F 6A15                            push 	dword 21
  2179 00000C31 EB36                    	jmp	short cpu_except
  2180                                  exc22:
  2181 00000C33 6A16                            push 	dword 22
  2182 00000C35 EB32                    	jmp	short cpu_except
  2183                                  exc23:
  2184 00000C37 6A17                            push 	dword 23
  2185 00000C39 EB2E                    	jmp	short cpu_except
  2186                                  exc24:
  2187 00000C3B 6A18                            push 	dword 24
  2188 00000C3D EB2A                    	jmp	short cpu_except
  2189                                  exc25:
  2190 00000C3F 6A19                            push 	dword 25
  2191 00000C41 EB26                    	jmp	short cpu_except
  2192                                  exc26:
  2193 00000C43 6A1A                            push 	dword 26
  2194 00000C45 EB22                    	jmp	short cpu_except
  2195                                  exc27:
  2196 00000C47 6A1B                            push 	dword 27
  2197 00000C49 EB1E                    	jmp	short cpu_except
  2198                                  exc28:
  2199 00000C4B 6A1C                            push 	dword 28
  2200 00000C4D EB1A                    	jmp	short cpu_except
  2201                                  exc29:
  2202 00000C4F 6A1D                            push 	dword 29
  2203 00000C51 EB16                    	jmp	short cpu_except
  2204                                  exc30:
  2205 00000C53 6A1E                            push 	dword 30
  2206 00000C55 EB04                    	jmp	short cpu_except_en
  2207                                  exc31:
  2208 00000C57 6A1F                            push 	dword 31
  2209 00000C59 EB0E                            jmp     short cpu_except
  2210                                  
  2211                                  	; 19/10/2015
  2212                                  	; 19/09/2015
  2213                                  	; 01/09/2015
  2214                                  	; 28/08/2015
  2215                                  	; 28/08/2014
  2216                                  cpu_except_en:
  2217 00000C5B 87442404                	xchg	eax, [esp+4] ; Error code
  2218 00000C5F 36A3[78050300]          	mov	[ss:error_code], eax
  2219 00000C65 58                      	pop	eax  ; Exception number
  2220 00000C66 870424                  	xchg	eax, [esp]
  2221                                  		; eax = eax before exception
  2222                                  		; [esp] -> exception number
  2223                                  		; [esp+4] -> EIP to return
  2224                                  	; 22/01/2017
  2225                                  	; 19/10/2015
  2226                                  	; 19/09/2015
  2227                                  	; 01/09/2015
  2228                                  	; 28/08/2015
  2229                                  	; 29/08/2014
  2230                                  	; 28/08/2014
  2231                                  	; 25/08/2014
  2232                                  	; 21/08/2014
  2233                                  cpu_except:	; CPU Exceptions
  2234 00000C69 FC                      	cld
  2235 00000C6A 870424                  	xchg	eax, [esp] 
  2236                                  		; eax = Exception number
  2237                                  		; [esp] = eax (before exception)	
  2238 00000C6D 53                      	push	ebx
  2239 00000C6E 56                      	push	esi
  2240 00000C6F 57                      	push	edi
  2241 00000C70 1E                      	push 	ds
  2242 00000C71 06                      	push 	es
  2243                                  	; 28/08/2015
  2244 00000C72 66BB1000                	mov	bx, KDATA
  2245 00000C76 8EDB                    	mov	ds, bx
  2246 00000C78 8EC3                    	mov	es, bx
  2247 00000C7A 0F20DB                  	mov	ebx, cr3
  2248 00000C7D 53                      	push	ebx ; (*) page directory
  2249                                  	; 19/10/2015
  2250 00000C7E FC                      	cld
  2251                                  	; 25/03/2015
  2252 00000C7F 8B1D[D8630100]          	mov	ebx, [k_page_dir]
  2253 00000C85 0F22DB                  	mov	cr3, ebx
  2254                                  	; 28/08/2015
  2255 00000C88 83F80E                  	cmp	eax, 0Eh ; 14, PAGE FAULT	
  2256 00000C8B 750F                    	jne	short cpu_except_nfp
  2257 00000C8D E8EB4B0000              	call	page_fault_handler
  2258 00000C92 21C0                    	and 	eax, eax
  2259 00000C94 0F8401010000                    jz	iiretp ; 01/09/2015
  2260 00000C9A B00E                    	mov	al, 0Eh ; 14
  2261                                  cpu_except_nfp:
  2262                                  	; 23/08/2016
  2263 00000C9C 803D[9A690000]03        	cmp	byte [CRT_MODE], 3
  2264 00000CA3 7409                    	je	short cpu_except_mode_3
  2265 00000CA5 50                      	push	eax
  2266 00000CA6 B003                    	mov	al, 3
  2267 00000CA8 E8BB0D0000              	call	_set_mode
  2268 00000CAD 58                      	pop	eax
  2269                                  cpu_except_mode_3:
  2270                                  	; 02/04/2015
  2271 00000CAE BB[FB080000]            	mov	ebx, hang
  2272 00000CB3 875C241C                	xchg	ebx, [esp+28]
  2273                                  		; EIP (points to instruction which faults)
  2274                                  	  	; New EIP (hang)
  2275 00000CB7 891D[7C050300]          	mov	[FaultOffset], ebx
  2276 00000CBD C744242008000000        	mov	dword [esp+32], KCODE ; kernel's code segment
  2277 00000CC5 814C242400020000        	or	dword [esp+36], 200h ; enable interrupts (set IF)
  2278                                  	;
  2279 00000CCD 88C4                    	mov	ah, al
  2280 00000CCF 240F                    	and	al, 0Fh
  2281 00000CD1 3C09                    	cmp	al, 9
  2282 00000CD3 7602                    	jna	short h1ok
  2283 00000CD5 0407                    	add	al, 'A'-':'
  2284                                  h1ok:
  2285 00000CD7 C0EC04                  	shr	ah, 4
  2286 00000CDA 80FC09                  	cmp	ah, 9
  2287 00000CDD 7603                    	jna	short h2ok
  2288 00000CDF 80C407                  	add	ah, 'A'-':'
  2289                                  h2ok:	
  2290 00000CE2 86E0                    	xchg 	ah, al	
  2291 00000CE4 66053030                	add	ax, '00'
  2292 00000CE8 66A3[C4230100]          	mov	[excnstr], ax
  2293                                  	;
  2294                                  	; 29/08/2014
  2295 00000CEE A1[7C050300]            	mov	eax, [FaultOffset]
  2296 00000CF3 51                      	push	ecx
  2297 00000CF4 52                      	push	edx
  2298 00000CF5 89E3                    	mov	ebx, esp
  2299                                  	; 28/08/2015
  2300 00000CF7 B910000000              	mov	ecx, 16	  ; divisor value to convert binary number
  2301                                  			  ; to hexadecimal string
  2302                                  	;mov	ecx, 10	    ; divisor to convert	
  2303                                  			    ; binary number to decimal string
  2304                                  b2d1:
  2305 00000CFC 31D2                    	xor	edx, edx
  2306 00000CFE F7F1                    	div	ecx
  2307 00000D00 6652                    	push	dx
  2308 00000D02 39C8                    	cmp	eax, ecx
  2309 00000D04 73F6                    	jnb	short b2d1
  2310 00000D06 BF[CF230100]            	mov	edi, EIPstr ; EIP value
  2311                                  			    ; points to instruction which faults	
  2312                                  	; 28/08/2015
  2313 00000D0B 89C2                    	mov	edx, eax
  2314                                  b2d2:
  2315                                  	;add	al, '0'
  2316 00000D0D 8A82[F13C0000]          	mov	al, [edx+hexchrs]
  2317 00000D13 AA                      	stosb		    ; write hexadecimal digit to its place	
  2318 00000D14 39E3                    	cmp	ebx, esp
  2319 00000D16 7606                    	jna	short b2d3
  2320 00000D18 6658                    	pop	ax
  2321 00000D1A 88C2                    	mov	dl, al
  2322 00000D1C EBEF                    	jmp	short b2d2
  2323                                  b2d3:
  2324 00000D1E B068                    	mov 	al, 'h' ; 28/08/2015
  2325 00000D20 AA                      	stosb
  2326 00000D21 B020                    	mov	al, 20h	    ; space
  2327 00000D23 AA                      	stosb
  2328 00000D24 30C0                    	xor	al, al	    ; to do it an ASCIIZ string	
  2329 00000D26 AA                      	stosb
  2330                                  	;
  2331 00000D27 5A                      	pop	edx
  2332 00000D28 59                      	pop	ecx
  2333                                  	;
  2334 00000D29 B44F                    	mov	ah, 4Fh	; red (4) background, 
  2335                                  			; white (F) forecolor
  2336 00000D2B BE[B4230100]            	mov	esi, exc_msg ; message offset
  2337                                  	;
  2338                                  	; 20/01/2017 (!cpu exception!)
  2339                                  	;
  2340 00000D30 8105[6A210100]A000-             add    dword [scr_row], 0A0h
  2340 00000D38 0000               
  2341 00000D3A 8B3D[6A210100]                  mov    edi, [scr_row]
  2342                                  	;	
  2343 00000D40 C605[5B030300]00        	mov	byte [sysflg], 0  ; system mode
  2344 00000D47 FB                              sti
  2345                                  	;
  2346 00000D48 E8EDFBFFFF              	call 	printk
  2347                                  	;
  2348 00000D4D B410                    	mov	ah, 10h
  2349 00000D4F E881010000              	call	int16h ; getc
  2350                                  	;
  2351 00000D54 B003                    	mov	al, 3
  2352 00000D56 E80D0D0000              	call	_set_mode
  2353                                  	;
  2354 00000D5B B801000000              	mov	eax, 1
  2355 00000D60 E9EEC60000              	jmp	sysexit ; terminate process !!!
  2356                                  	
  2357                                  	; 22/01/2017
  2358                                  	; 18/04/2016
  2359                                  	; 28/08/2015
  2360                                  	; 23/02/2015
  2361                                  	; 20/08/2014
  2362                                  ignore_int:
  2363 00000D65 50                      	push	eax
  2364 00000D66 53                      	push	ebx ; 23/02/2015
  2365 00000D67 56                      	push	esi
  2366 00000D68 57                      	push	edi
  2367 00000D69 1E                      	push 	ds
  2368 00000D6A 06                      	push 	es
  2369                                  	; 18/04/2016
  2370 00000D6B 66B81000                	mov	ax, KDATA
  2371 00000D6F 8ED8                    	mov	ds, ax
  2372 00000D71 8EC0                    	mov	es, ax
  2373                                  	; 28/08/2015
  2374 00000D73 0F20D8                  	mov	eax, cr3
  2375 00000D76 50                      	push	eax ; (*) page directory
  2376                                  	;
  2377 00000D77 B467                    	mov	ah, 67h	; brown (6) background, 
  2378                                  			; light gray (7) forecolor
  2379 00000D79 BE[7C220100]            	mov	esi, int_msg ; message offset
  2380                                  piemsg:
  2381                                          ; 27/08/2014
  2382 00000D7E 8105[6A210100]A000-             add     dword [scr_row], 0A0h
  2382 00000D86 0000               
  2383 00000D88 8B3D[6A210100]                  mov     edi, [scr_row]
  2384                                          ;
  2385 00000D8E E8A7FBFFFF              	call 	printk
  2386                                  	;
  2387                                  	; 23/02/2015
  2388 00000D93 B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  2389 00000D95 E6A0                    	out	0A0h, al ; the 2nd 8259
  2390                                  	; 22/08/2014
  2391 00000D97 B020                    	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  2392 00000D99 E620                    	out	20h, al	; 8259 PORT
  2393                                  iiretp: 
  2394                                  	; 22/01/2017
  2395                                  	; 01/09/2015
  2396                                  	; 28/08/2015
  2397 00000D9B 58                      	pop	eax ; (*) page directory
  2398 00000D9C 0F22D8                  	mov	cr3, eax
  2399                                  iiret:
  2400 00000D9F 07                      	pop	es
  2401 00000DA0 1F                      	pop	ds
  2402 00000DA1 5F                      	pop	edi
  2403 00000DA2 5E                      	pop	esi
  2404 00000DA3 5B                      	pop	ebx ; 29/08/2014
  2405 00000DA4 58                      	pop 	eax
  2406 00000DA5 CF                      	iretd
  2407                                  
  2408                                  	; 23/05/2016
  2409                                  	; 22/08/2014
  2410                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios.asm)
  2411                                  	; (INT 1Ah)
  2412                                  	;; Linux (v0.12) source code (main.c) by Linus Torvalds (1991)
  2413                                  time_of_day:
  2414 00000DA6 E8C1580000              	call	UPD_IPR			; WAIT TILL UPDATE NOT IN PROGRESS
  2415 00000DAB 726F                            jc      short time_of_day_retn ; 23/05/2016
  2416 00000DAD B000                    	mov	al, CMOS_SECONDS
  2417 00000DAF E8D3580000              	call	CMOS_READ
  2418 00000DB4 A2[48640100]            	mov	[time_seconds], al 
  2419 00000DB9 B002                    	mov	al, CMOS_MINUTES
  2420 00000DBB E8C7580000              	call	CMOS_READ
  2421 00000DC0 A2[49640100]            	mov	[time_minutes], al 
  2422 00000DC5 B004                    	mov	al, CMOS_HOURS
  2423 00000DC7 E8BB580000              	call	CMOS_READ
  2424 00000DCC A2[4A640100]                    mov     [time_hours], al
  2425 00000DD1 B006                    	mov	al, CMOS_DAY_WEEK 
  2426 00000DD3 E8AF580000              	call	CMOS_READ
  2427 00000DD8 A2[4B640100]            	mov	[date_wday], al
  2428 00000DDD B007                     	mov	al, CMOS_DAY_MONTH
  2429 00000DDF E8A3580000              	call	CMOS_READ
  2430 00000DE4 A2[4C640100]            	mov	[date_day], al
  2431 00000DE9 B008                    	mov	al, CMOS_MONTH
  2432 00000DEB E897580000              	call	CMOS_READ
  2433 00000DF0 A2[4D640100]            	mov	[date_month], al
  2434 00000DF5 B009                    	mov	al, CMOS_YEAR
  2435 00000DF7 E88B580000              	call	CMOS_READ
  2436 00000DFC A2[4E640100]            	mov	[date_year], al
  2437 00000E01 B032                    	mov	al, CMOS_CENTURY
  2438 00000E03 E87F580000              	call	CMOS_READ
  2439 00000E08 A2[4F640100]            	mov	[date_century], al
  2440                                  	;
  2441 00000E0D B000                    	mov	al, CMOS_SECONDS
  2442 00000E0F E873580000              	call 	CMOS_READ
  2443 00000E14 3A05[48640100]          	cmp	al, [time_seconds]
  2444 00000E1A 758A                    	jne	short time_of_day
  2445                                  
  2446                                  time_of_day_retn:
  2447 00000E1C C3                      	retn
  2448                                  
  2449                                  	; 15/01/2017
  2450                                  	; 10/06/2016
  2451                                  	; 07/06/2016
  2452                                  	; 06/06/2016
  2453                                  	; 23/05/2016
  2454                                  rtc_p:
  2455 00000E1D B101                    	mov	cl, 1 ; 15/01/2017
  2456 00000E1F EB02                    	jmp	short rtc_p0
  2457                                  u_timer: 
  2458                                  	; Timer Events with 18.2 Hz Timer Ticks
  2459                                  	; (and also timer events with RTC seconds)
  2460 00000E21 28C9                    	sub	cl, cl ; mov cl, 0 ; 15/01/2017
  2461                                  rtc_p0:
  2462                                  	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
  2463                                  	; Major Modification:
  2464                                  	; Check and Perform Timer Events (for RTC)
  2465                                  	; 25/08/2014 - 07/09/2014
  2466                                  	; Retro UNIX 386 v1:
  2467                                   	; Print Real Time Clock content
  2468                                  	
  2469                                  	; 15/01/2017
  2470 00000E23 880D[68700100]          	mov	byte [priority], cl ; 0 or 1 (not 2)
  2471 00000E29 8A2D[6B700100]          	mov	ch, [timer_events]
  2472 00000E2F 20ED                    	and	ch, ch
  2473 00000E31 7420                    	jz	short rtc_p3
  2474                                  
  2475 00000E33 BE[60040300]            	mov	esi, timer_set  ; beginning address of
  2476                                  				; timer events space
  2477                                  rtc_p1:
  2478 00000E38 8B06                    	mov	eax, [esi]	
  2479 00000E3A 20C0                    	and	al, al ; 0 = free, >0 = process no.
  2480 00000E3C 7416                    	jz	short rtc_p4
  2481                                  	;
  2482 00000E3E C1C810                  	ror	eax, 16
  2483                                  	; ah = response value, al = interrupt type
  2484                                  	; 15/01/2017
  2485                                  	; cl = interrupt source
  2486                                  	;       1 = RTC, 0 = PIT  	 	
  2487 00000E41 38C8                    	cmp	al, cl 
  2488 00000E43 750A                    	jne	short rtc_p2 ; not as requested or undefined !
  2489 00000E45 3C01                    	cmp	al, 1 ; 1 ; RTC interrupt ?
  2490 00000E47 7410                    	je	short rtc_p5 ; yes, check for response
  2491                                  	; 06/06/2016 - 18.2 Hz Timer Ticks
  2492 00000E49 836E080A                	sub	dword [esi+8], 10 ; 1 tick = 10
  2493 00000E4D 7613                    	jna	short rtc_p6  ; continue for responding
  2494                                  rtc_p2:
  2495                                  	; 15/01/2017 (cl -> ch)
  2496                                  	; 07/06/2016
  2497 00000E4F FECD                    	dec	ch    ; remain count of timer events	
  2498 00000E51 7501                    	jnz	short rtc_p4
  2499                                  rtc_p3:	 
  2500 00000E53 C3                      	retn
  2501                                  rtc_p4:	
  2502                                  	;cmp	esi, timer_set + 240 ; 15*16 (last event)
  2503                                  	;jnb	short rtc_p3 ; end of timer event space
  2504 00000E54 83C610                  	add	esi, 16 ; next timer event
  2505 00000E57 EBDF                    	jmp	short rtc_p1
  2506                                  rtc_p5:	 
  2507                                  	; current timer count ; 06/06/2016 (182)
  2508 00000E59 816E08B6000000          	sub	dword [esi+8], 182 ; 1 second (10*18.2)
  2509 00000E60 77ED                    	ja	short rtc_p2  ; check for the next 
  2510                                  rtc_p6:	
  2511                                  	; it is the time of response! 
  2512 00000E62 8B5E04                  	mov	ebx, [esi+4] ; set (count limit) value
  2513 00000E65 895E08                  	mov	[esi+8], ebx ; reset count down value
  2514                                  			     ; to count limit
  2515                                  	; 19/12/2016
  2516                                  	; 10/12/2016 - timer callback modification
  2517 00000E68 8B7E0C                  	mov	edi, [esi+12] ; response (or callback) address	
  2518 00000E6B 807E0100                	cmp	byte [esi+1], 0 ; >0 = callback
  2519 00000E6F 762A                    	jna	short rtc_p8
  2520                                  
  2521                                  	; timer callback !
  2522 00000E71 0FB61E                  	movzx	ebx, byte [esi] ; process number (>0)
  2523 00000E74 89D8                    	mov	eax, ebx
  2524 00000E76 C0E302                  	shl	bl, 2 ; *4
  2525 00000E79 89BB[0C010300]          	mov	[ebx+p.tcb-4], edi ; user's callback service addr
  2526 00000E7F 3A05[B3030300]          	cmp	al, [u.uno]
  2527 00000E85 7521                    	jne	short rtc_p9
  2528 00000E87 893D[D0030300]          	mov	[u.tcb], edi
  2529                                  rtc_p7:
  2530                                  	; 15/01/2017
  2531 00000E8D B002                    	mov	al, 2
  2532 00000E8F A2[68700100]            	mov	[priority], al ; 2
  2533                                  	; 10/01/2017
  2534                                  	;mov	byte [u.pri], 2
  2535 00000E94 A2[A9030300]            	mov	[u.pri], al ; 2
  2536 00000E99 EBB4                    	jmp	short rtc_p2
  2537                                  rtc_p8:
  2538                                  	; response address is physical address of
  2539                                  	; the program's response (signal return) byte
  2540                                  	; 06/06/2016
  2541                                  	;mov	edi, [esi+12] ; response address
  2542 00000E9B 8827                    	mov	[edi], ah     ; response value 
  2543                                  	;
  2544 00000E9D C1C010                  	rol	eax, 16
  2545                                  	; 15/01/2017
  2546 00000EA0 3A05[B3030300]          	cmp	al, [u.uno] ; running process ?
  2547 00000EA6 74E5                    	je	short rtc_p7
  2548                                  rtc_p9:
  2549                                  	; al = process number  ; 10/06/2016
  2550 00000EA8 B202                    	mov	dl, 2 ; priority, 2 = event (high)	
  2551 00000EAA E854F50000              	call	set_run_sequence ; 19/05/2016
  2552 00000EAF EB9E                    	jmp	short rtc_p2 ; 10/06/2016
  2553                                  
  2554                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  2555                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  2556                                  default_irq7:
  2557 00000EB1 6650                    	push	ax
  2558 00000EB3 B00B                    	mov	al, 0Bh  ; In-Service register
  2559 00000EB5 E620                    	out	20h, al
  2560 00000EB7 EB00                            jmp short $+2
  2561 00000EB9 EB00                    	jmp short $+2
  2562 00000EBB E420                    	in	al, 20h
  2563 00000EBD 2480                    	and 	al, 80h ; bit 7 (is it real IRQ 7 or fake?)
  2564 00000EBF 7404                            jz      short irq7_iret ; Fake (spurious) IRQ, do not send EOI 
  2565 00000EC1 B020                            mov     al, 20h ; EOI
  2566 00000EC3 E620                    	out	20h, al 
  2567                                  irq7_iret:
  2568 00000EC5 6658                    	pop	ax
  2569 00000EC7 CF                      	iretd
  2570                                  	
  2571                                  bcd_to_ascii:
  2572                                  	; 25/08/2014
  2573                                  	; INPUT ->
  2574                                  	;	al = Packed BCD number
  2575                                  	; OUTPUT ->
  2576                                  	;	ax  = ASCII word/number
  2577                                  	;
  2578                                  	; Erdogan Tan - 1998 (proc_hex) - TRDOS.ASM (2004-2011)
  2579                                  	;
  2580 00000EC8 D410                    	db 0D4h,10h                     ; Undocumented inst. AAM
  2581                                  					; AH = AL / 10h
  2582                                  					; AL = AL MOD 10h
  2583 00000ECA 660D3030                	or ax,'00'                      ; Make it ASCII based
  2584                                  
  2585 00000ECE 86E0                            xchg ah, al 
  2586                                  	
  2587 00000ED0 C3                      	retn
  2588                                  
  2589                                  ; 15/12/2020
  2590                                  real_mem_16m_64k: 
  2591 00000ED1 0000                    	dw 0	; Real size of system memory (if > 16MB)
  2592                                  		; as number of 64K blocks - 256
  2593                                  		; (This is for saving real system memory
  2594                                  		; because if system memory is larger than
  2595                                  		; 3 GB and if a VESA VBE video bios
  2596                                  		; is detected, 'mem_16m_64K' may be
  2597                                  		; decreased to reserve LFB space 
  2598                                  		; at the end of system memory.)
  2599                                  		; Upper memory space from LFB base address
  2600                                  		; to 4GB will not be included by M.A.T.
  2601                                  def_LFB_addr:	
  2602 00000ED3 0000                    	dw 0 	; HW of default LFB addr (for mode 118h)	
  2603                                  	
  2604                                  
  2605                                  %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: 15/01/2017
     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 00000ED5 9C                  <1> 	pushfd	; 28/08/2014
    40 00000ED6 0E                  <1> 	push 	cs
    41 00000ED7 E801000000          <1> 	call 	KEYBOARD_IO_1 ; getc_int
    42 00000EDC 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> ; 15/01/2017
   136                              <1> ; 14/01/2017
   137                              <1> ; 02/01/2017
   138                              <1> ; 29/05/2016
   139                              <1> ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   140                              <1> int32h:  ; Keyboard BIOS
   141                              <1> 
   142                              <1> KEYBOARD_IO_1:	
   143                              <1> 	;sti				; INTERRUPTS BACK ON
   144                              <1> 	; 29/05/2016
   145 00000EDD 80642408BE          <1>         and     byte [esp+8], 10111110b ; clear zero flag and cary flag
   146                              <1> 	;
   147 00000EE2 1E                  <1> 	push	ds			; SAVE CURRENT DS
   148 00000EE3 53                  <1> 	push	ebx			; SAVE BX TEMPORARILY
   149                              <1> 	;push	ecx			; SAVE CX TEMPORARILY
   150 00000EE4 66BB1000            <1>         mov     bx, KDATA 
   151 00000EE8 8EDB                <1> 	mov	ds, bx			; PUT SEGMENT VALUE OF DATA AREA INTO DS
   152                              <1> 
   153                              <1> 	; 14/01/2017
   154 00000EEA 8B1C24              <1> 	mov	ebx, [esp]
   155                              <1> 	;; 15/01/2017
   156                              <1> 	; 02/01/2017
   157                              <1> 	;;mov	byte [intflg], 32h	; keyboard interrupt 
   158 00000EED FB                  <1> 	sti
   159                              <1> 	;
   160                              <1> 
   161 00000EEE 08E4                <1> 	or	ah, ah			; CHECK FOR (AH)= 00H
   162 00000EF0 743A                <1> 	jz	short _K1		; ASCII_READ
   163 00000EF2 FECC                <1> 	dec	ah                      ; CHECK FOR (AH)= 01H
   164 00000EF4 7453                <1>         jz      short _K2               ; ASCII_STATUS
   165 00000EF6 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 02H
   166 00000EF8 0F8494000000        <1>         jz      _K3                     ; SHIFT STATUS
   167 00000EFE FECC                <1> 	dec	ah			; CHECK FOR (AH)= 03H	
   168 00000F00 0F8493000000        <1>         jz      _K300                   ; SET TYPAMATIC RATE/DELAY
   169 00000F06 80EC02              <1> 	sub	ah, 2			; CHECK FOR (AH)= 05H	
   170 00000F09 0F84BC000000        <1>         jz      _K500                   ; KEYBOARD WRITE         
   171                              <1> _KIO1:	
   172 00000F0F 80EC0B              <1> 	sub	ah, 11			; AH =  10H
   173 00000F12 740C                <1> 	jz	short _K1E		; EXTENDED ASCII READ
   174 00000F14 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 11H
   175 00000F16 7422                <1> 	jz	short _K2E		; EXTENDED_ASCII_STATUS
   176 00000F18 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 12H
   177 00000F1A 7458                <1> 	jz	short _K3E		; EXTENDED_SHIFT_STATUS
   178                              <1> _KIO_EXIT:
   179                              <1> 	; 02/01/2017
   180 00000F1C FA                  <1> 	cli
   181                              <1> 	;;mov	byte [intflg], 0 ;; 15/01/2017
   182                              <1> 	;
   183                              <1> 	;pop	ecx			; RECOVER REGISTER
   184 00000F1D 5B                  <1> 	pop	ebx			; RECOVER REGISTER
   185 00000F1E 1F                  <1> 	pop	ds			; RECOVER SEGMENT
   186 00000F1F CF                  <1> 	iretd				; INVALID COMMAND, EXIT
   187                              <1> 
   188                              <1> 	;-----	ASCII CHARACTER
   189                              <1> _K1E:	
   190 00000F20 E8D3000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER (EXTENDED)
   191 00000F25 E848010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
   192 00000F2A EBF0                <1> 	jmp	short _KIO_EXIT         ; GIVE IT TO THE CALLER
   193                              <1> _K1:	
   194 00000F2C E8C7000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER
   195 00000F31 E847010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
   196 00000F36 72F4                <1> 	jc	short _K1		; CARRY SET MEANS TROW CODE AWAY
   197                              <1> _K1A:
   198 00000F38 EBE2                <1> 	jmp	short _KIO_EXIT         ; RETURN TO CALLER
   199                              <1> 
   200                              <1> 	;-----	ASCII STATUS
   201                              <1> _K2E:	
   202 00000F3A E804010000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER (EXTENDED)
   203 00000F3F 7420                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
   204 00000F41 9C                  <1> 	pushf				; SAVE ZF FROM TEST
   205 00000F42 E82B010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
   206 00000F47 EB17                <1> 	jmp	short _K2A	        ; GIVE IT TO THE CALLER
   207                              <1> _K2:	
   208 00000F49 E8F5000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER
   209 00000F4E 7411                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
   210 00000F50 9C                  <1> 	pushf				; SAVE ZF FROM TEST
   211 00000F51 E827010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
   212 00000F56 7308                <1> 	jnc	short _K2A	        ; CARRY CLEAR MEANS PASS VALID CODE
   213 00000F58 9D                  <1> 	popf				; INVALID CODE FOR THIS TYPE OF CALL
   214 00000F59 E89A000000          <1> 	call	_K1S			; THROW THE CHARACTER AWAY
   215 00000F5E EBE9                <1> 	jmp	short _K2		; GO LOOK FOR NEXT CHAR, IF ANY
   216                              <1> _K2A:
   217 00000F60 9D                  <1> 	popf				; RESTORE ZF FROM TEST
   218                              <1> _K2B:
   219                              <1> 	; 02/01/2017
   220 00000F61 FA                  <1> 	cli
   221                              <1> 	;; mov	byte [intflg], 0 ;; 15/01/2017
   222                              <1> 	;
   223                              <1> 	;pop	ecx			; RECOVER REGISTER
   224 00000F62 5B                  <1> 	pop	ebx			; RECOVER REGISTER
   225 00000F63 1F                  <1> 	pop	ds			; RECOVER SEGMENT
   226                              <1> 	; (*) 29/05/2016
   227                              <1> 	; (*) retf 4			; THROW AWAY (e)FLAGS
   228 00000F64 7208                <1> 	jc	short _k2d
   229 00000F66 7505                <1> 	jnz	short _k2c
   230 00000F68 804C240840          <1> 	or	byte [esp+8], 01000000b	; set zero flag bit of eflags register
   231                              <1> _k2c:
   232 00000F6D CF                  <1> 	iretd
   233                              <1> _k2d:
   234                              <1> 	; 29/05/2016 -set carry flag on stack-
   235                              <1> 	; [esp] = EIP
   236                              <1> 	; [esp+4] = CS
   237                              <1> 	; [esp+8] = E-FLAGS
   238 00000F6E 804C240801          <1> 	or	byte [esp+8], 1  ; set carry bit of eflags register
   239                              <1> 	; [esp+12] = ESP (user)
   240                              <1> 	; [esp+16] = SS (User)
   241 00000F73 CF                  <1> 	iretd
   242                              <1> 
   243                              <1> 	
   244                              <1> 	; (*) 29/05/2016 - 'ref 4' intruction causes to stack fault
   245                              <1> 	; (OUTER-PRIVILEGE-LEVEL)
   246                              <1> 	; INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986
   247                              <1> 	; // RETF instruction:
   248                              <1> 	;
   249                              <1> 	; IF OperandMode=32 THEN
   250                              <1>  	;    Load CS:EIP from stack;
   251                              <1>  	;    Set CS RPL to CPL;
   252                              <1>  	;    Increment eSP by 8 plus the immediate offset if it exists;
   253                              <1>  	;    Load SS:eSP from stack;
   254                              <1>  	; ELSE (* OperandMode=16 *)
   255                              <1>  	;    Load CS:IP from stack;
   256                              <1>  	;    Set CS RPL to CPL;
   257                              <1>  	;    Increment eSP by 4 plus the immediate offset if it exists;
   258                              <1> 	;    Load SS:eSP from stack;
   259                              <1>  	; FI;
   260                              <1> 	;
   261                              <1> 	; //
   262                              <1> 
   263                              <1> 	;-----	SHIFT STATUS
   264                              <1> _K3E:                                   ; GET THE EXTENDED SHIFT STATUS FLAGS
   265 00000F74 8A25[66690000]      <1> 	mov	ah, [KB_FLAG_1]		; GET SYSTEM SHIFT KEY STATUS
   266 00000F7A 80E404              <1> 	and	ah, SYS_SHIFT		; MASK ALL BUT SYS KEY BIT
   267                              <1> 	;mov	cl, 5			; SHIFT THEW SYSTEMKEY BIT OVER TO
   268                              <1> 	;shl	ah, cl			; BIT 7 POSITION
   269 00000F7D C0E405              <1>         shl	ah, 5
   270 00000F80 A0[66690000]        <1> 	mov	al, [KB_FLAG_1]		; GET SYSTEM SHIFT STATES BACK
   271 00000F85 2473                <1> 	and	al, 01110011b		; ELIMINATE SYS SHIFT, HOLD_STATE AND INS_SHIFT
   272 00000F87 08C4                <1> 	or	ah, al                  ; MERGE REMAINING BITS INTO AH
   273 00000F89 A0[68690000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT CTL AND ALT
   274 00000F8E 240C                <1> 	and	al, 00001100b		; ELIMINATE LC_E0 AND LC_E1
   275 00000F90 08C4                <1> 	or	ah, al			; OR THE SHIFT FLAGS TOGETHER
   276                              <1> _K3:
   277 00000F92 A0[65690000]        <1> 	mov	al, [KB_FLAG]		; GET THE SHIFT STATUS FLAGS
   278                              <1> 	;jmp	short _KIO_EXIT		; RETURN TO CALLER
   279 00000F97 EB83                <1> 	jmp	_KIO_EXIT
   280                              <1> 
   281                              <1> 	;-----	SET TYPAMATIC RATE AND DELAY
   282                              <1> _K300:
   283 00000F99 3C05                <1> 	cmp	al, 5			; CORRECT FUNCTION CALL?
   284                              <1> 	;jne	short _KIO_EXIT		; NO, RETURN
   285 00000F9B 0F857BFFFFFF        <1>      	jne	_KIO_EXIT
   286 00000FA1 F6C3E0              <1> 	test	bl, 0E0h		; TEST FOR OUT-OF-RANGE RATE
   287 00000FA4 0F8572FFFFFF        <1>         jnz     _KIO_EXIT               ; RETURN IF SO
   288 00000FAA F6C7FC              <1> 	test	BH, 0FCh		; TEST FOR OUT-OF-RANGE DELAY
   289 00000FAD 0F8569FFFFFF        <1>         jnz     _KIO_EXIT               ; RETURN IF SO
   290 00000FB3 B0F3                <1> 	mov	al, KB_TYPA_RD		; COMMAND FOR TYPAMATIC RATE/DELAY		
   291 00000FB5 E8DA060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
   292                              <1> 	;mov	cx, 5			; SHIFT COUNT
   293                              <1> 	;shl	bh, cl			; SHIFT DELAY OVER
   294 00000FBA C0E705              <1> 	shl	bh, 5
   295 00000FBD 88D8                <1> 	mov	al, bl			; PUT IN RATE
   296 00000FBF 08F8                <1> 	or	al, bh			; AND DELAY
   297 00000FC1 E8CE060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
   298 00000FC6 E951FFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER
   299                              <1> 
   300                              <1> 	;-----	WRITE TO KEYBOARD BUFFER
   301                              <1> _K500:
   302 00000FCB 56                  <1> 	push	esi			; SAVE SI (esi)
   303 00000FCC FA                  <1> 	cli				; 
   304 00000FCD 8B1D[76690000]      <1>      	mov	ebx, [BUFFER_TAIL]	; GET THE 'IN TO' POINTER TO THE BUFFER
   305 00000FD3 89DE                <1> 	mov	esi, ebx		; SAVE A COPY IN CASE BUFFER NOT FULL
   306 00000FD5 E8D3000000          <1> 	call	_K4			; BUMP THE POINTER TO SEE IF BUFFER IS FULL
   307 00000FDA 3B1D[72690000]      <1> 	cmp	ebx, [BUFFER_HEAD]	; WILL THE BUFFER OVERRUN IF WE STORE THIS?
   308 00000FE0 740D                <1> 	je	short _K502		; YES - INFORM CALLER OF ERROR		
   309 00000FE2 66890E              <1> 	mov	[esi], cx		; NO - PUT ASCII/SCAN CODE INTO BUFFER	
   310 00000FE5 891D[76690000]      <1> 	mov	[BUFFER_TAIL], ebx	; ADJUST 'IN TO' POINTER TO REFLECT CHANGE
   311 00000FEB 28C0                <1> 	sub	al, al			; TELL CALLER THAT OPERATION WAS SUCCESSFUL
   312 00000FED EB02                <1> 	jmp	short _K504		; SUB INSTRUCTION ALSO RESETS CARRY FLAG
   313                              <1> _K502:
   314 00000FEF B001                <1> 	mov	al, 01h			; BUFFER FULL INDICATION
   315                              <1> _K504:
   316 00000FF1 FB                  <1> 	sti				
   317 00000FF2 5E                  <1> 	pop	esi			; RECOVER SI (esi)
   318 00000FF3 E924FFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER WITH STATUS IN AL
   319                              <1> 
   320                              <1> 	;-----	READ THE KEY TO FIGURE OUT WHAT TO DO -----
   321                              <1> _K1S:
   322 00000FF8 FA                  <1> 	cli	; 03/12/2014
   323 00000FF9 8B1D[72690000]      <1>         mov     ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
   324 00000FFF 3B1D[76690000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
   325                              <1> 	;jne	short _K1U		; IF ANYTHING IN BUFFER SKIP INTERRUPT
   326 00001005 750F                <1> 	jne	short _k1x ; 03/12/2014
   327                              <1> 	;
   328                              <1> 	; 03/12/2014
   329                              <1> 	; 28/08/2014
   330                              <1> 	; PERFORM OTHER FUNCTION ?? here !
   331                              <1> 	;; MOV	AX, 9002h		; MOVE IN WAIT CODE & TYPE
   332                              <1> 	;; INT 	15H			; PERFORM OTHER FUNCTION
   333                              <1> _K1T:                                   ; ASCII READ
   334 00001007 FB                  <1> 	sti				; INTERRUPTS BACK ON DURING LOOP
   335 00001008 90                  <1> 	nop				; ALLOW AN INTERRUPT TO OCCUR
   336                              <1> _K1U:	
   337 00001009 FA                  <1> 	cli				; INTERRUPTS BACK OFF
   338 0000100A 8B1D[72690000]      <1>         mov    	ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
   339 00001010 3B1D[76690000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
   340                              <1> _k1x:
   341 00001016 53                  <1> 	push	ebx			; SAVE ADDRESS		
   342 00001017 9C                  <1> 	pushf				; SAVE FLAGS
   343 00001018 E82F070000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
   344 0000101D 8A1D[67690000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
   345 00001023 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
   346 00001025 80E307              <1> 	and	bl, 07h	; KB_LEDS	; ISOLATE INDICATOR BITS
   347 00001028 7406                <1> 	jz	short _K1V		; IF NO CHANGE BYPASS UPDATE
   348 0000102A E8C9060000          <1> 	call	SND_LED1
   349 0000102F FA                  <1> 	cli				; DISABLE INTERRUPTS
   350                              <1> _K1V:
   351 00001030 9D                  <1> 	popf				; RESTORE FLAGS
   352 00001031 5B                  <1> 	pop	ebx			; RESTORE ADDRESS
   353 00001032 74D3                <1>         je      short _K1T              ; LOOP UNTIL SOMETHING IN BUFFER
   354                              <1> 	;
   355 00001034 668B03              <1> 	mov	ax, [ebx] 		; GET SCAN CODE AND ASCII CODE
   356 00001037 E871000000          <1>         call    _K4                     ; MOVE POINTER TO NEXT POSITION
   357 0000103C 891D[72690000]      <1>         mov     [BUFFER_HEAD], ebx      ; STORE VALUE IN VARIABLE
   358 00001042 C3                  <1> 	retn				; RETURN
   359                              <1> 
   360                              <1> 	;-----	READ THE KEY TO SEE IF ONE IS PRESENT -----
   361                              <1> _K2S:
   362 00001043 FA                  <1> 	cli				; INTERRUPTS OFF
   363 00001044 8B1D[72690000]      <1>         mov     ebx, [BUFFER_HEAD]      ; GET HEAD POINTER
   364 0000104A 3B1D[76690000]      <1>         cmp     ebx, [BUFFER_TAIL]      ; IF EQUAL (Z=1) THEN NOTHING THERE
   365 00001050 668B03              <1> 	mov	ax, [ebx]
   366 00001053 9C                  <1> 	pushf				; SAVE FLAGS
   367 00001054 6650                <1> 	push	ax			; SAVE CODE
   368 00001056 E8F1060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
   369 0000105B 8A1D[67690000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
   370 00001061 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
   371 00001063 80E307              <1> 	and	bl, 07h ; KB_LEDS	; ISOLATE INDICATOR BITS
   372 00001066 7405                <1> 	jz	short _K2T		; IF NO CHANGE BYPASS UPDATE
   373 00001068 E874060000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
   374                              <1> _K2T:
   375 0000106D 6658                <1> 	pop	ax			; RESTORE CODE
   376 0000106F 9D                  <1> 	popf				; RESTORE FLAGS
   377 00001070 FB                  <1> 	sti				; INTERRUPTS BACK ON
   378 00001071 C3                  <1> 	retn				; RETURN
   379                              <1> 
   380                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR EXTENDED CALLS -----
   381                              <1> _KIO_E_XLAT:
   382 00001072 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
   383 00001074 7506                <1> 	jne	short _KIO_E_RET	; NO, PASS IT ON
   384 00001076 08E4                <1>         or 	ah, ah			; AH = 0 IS SPECIAL CASE
   385 00001078 7402                <1>         jz	short _KIO_E_RET        ; PASS THIS ON UNCHANGED
   386 0000107A 30C0                <1> 	xor	al, al			; OTHERWISE SET AL = 0
   387                              <1> _KIO_E_RET:				
   388 0000107C C3                  <1> 	retn				; GO BACK
   389                              <1> 
   390                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR STANDARD CALLS -----
   391                              <1> _KIO_S_XLAT:
   392 0000107D 80FCE0              <1> 	cmp	ah, 0E0h		; IS IT KEYPAD ENTER OR / ?
   393 00001080 750F                <1> 	jne	short _KIO_S2		; NO, CONTINUE
   394 00001082 3C0D                <1> 	cmp	al, 0Dh			; KEYPAD ENTER CODE?
   395 00001084 7408                <1>         je	short _KIO_S1		; YES, MASSAGE A BIT
   396 00001086 3C0A                <1> 	cmp	al, 0Ah			; CTRL KEYPAD ENTER CODE?
   397 00001088 7404                <1>         je	short _KIO_S1		; YES, MASSAGE THE SAME
   398 0000108A B435                <1> 	mov	ah, 35h			; NO, MUST BE KEYPAD /
   399                              <1> _kio_ret: ; 03/12/2014
   400 0000108C F8                  <1> 	clc
   401 0000108D C3                  <1> 	retn
   402                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
   403                              <1> _KIO_S1:				
   404 0000108E B41C                <1> 	mov	ah, 1Ch			; CONVERT TO COMPATIBLE OUTPUT
   405                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
   406 00001090 C3                  <1> 	retn
   407                              <1> _KIO_S2:		
   408 00001091 80FC84              <1> 	cmp	ah, 84h			; IS IT ONE OF EXTENDED ONES?
   409 00001094 7715                <1> 	ja	short _KIO_DIS		; YES, THROW AWAY AND GET ANOTHER CHAR
   410 00001096 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
   411 00001098 7506                <1>         jne	short _KIO_S3		; NO, TRY LAST TEST
   412 0000109A 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
   413 0000109C 740C                <1>         jz	short _KIO_USE		; PASS THIS ON UNCHANGED
   414 0000109E EB0B                <1> 	jmp	short _KIO_DIS		; THROW AWAY THE REST
   415                              <1> _KIO_S3:
   416 000010A0 3CE0                <1> 	cmp	al, 0E0h		; IS IT AN EXTENSION OF A PREVIOUS ONE?
   417                              <1> 	;jne	short _KIO_USE		; NO, MUST BE A STANDARD CODE
   418 000010A2 75E8                <1> 	jne	short _kio_ret
   419 000010A4 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
   420 000010A6 7402                <1>         jz	short _KIO_USE		; JUMP IF AH = 0
   421 000010A8 30C0                <1> 	xor	al, al			; CONVERT TO COMPATIBLE OUTPUT
   422                              <1> 	;jmp	short _KIO_USE		; PASS IT ON TO CALLER
   423                              <1> _KIO_USE:
   424                              <1> 	;clc				; CLEAR CARRY TO INDICATE GOOD CODE
   425 000010AA C3                  <1> 	retn				; RETURN	
   426                              <1> _KIO_DIS:
   427 000010AB F9                  <1> 	stc				; SET CARRY TO INDICATE DISCARD CODE
   428 000010AC C3                  <1> 	retn				; RETURN
   429                              <1> 
   430                              <1> 	;-----	INCREMENT BUFFER POINTER ROUTINE -----
   431                              <1> _K4:    
   432 000010AD 43                  <1> 	inc     ebx
   433 000010AE 43                  <1> 	inc	ebx			; MOVE TO NEXT WORD IN LIST
   434 000010AF 3B1D[6E690000]      <1>         cmp     ebx, [BUFFER_END] 	; AT END OF BUFFER?
   435                              <1>         ;jne    short _K5               ; NO, CONTINUE
   436 000010B5 7206                <1> 	jb	short _K5
   437 000010B7 8B1D[6A690000]      <1>         mov     ebx, [BUFFER_START]     ; YES, RESET TO BUFFER BEGINNING
   438                              <1> _K5:
   439 000010BD C3                  <1> 	retn
   440                              <1> 
   441                              <1> ; 20/02/2015
   442                              <1> ; 05/12/2014
   443                              <1> ; 26/08/2014
   444                              <1> ; KEYBOARD (HARDWARE) INTERRUPT -  IRQ LEVEL 1
   445                              <1> ; (INT_09h - Retro UNIX 8086 v1 - U9.ASM, 07/03/2014)
   446                              <1> ;
   447                              <1> ; Derived from "KB_INT_1" procedure of IBM "pc-at" 
   448                              <1> ; rombios source code (06/10/1985)
   449                              <1> ; 'keybd.asm', HARDWARE INT 09h - (IRQ Level 1)
   450                              <1> 
   451                              <1> ; EQUATES (IBM PC-XT-286 BIOS, 1986, 'POSQEQU.INC')
   452                              <1> 
   453                              <1> ;--------- 8042 COMMANDS -------------------------------------------------------
   454                              <1> ENA_KBD		equ	0AEh		; ENABLE KEYBOARD COMMAND
   455                              <1> DIS_KBD		equ	0ADh		; DISABLE KEYBOARD COMMAND
   456                              <1> SHUT_CMD	equ	0FEh		; CAUSE A SHUTDOWN COMMAND
   457                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
   458                              <1> STATUS_PORT	equ	064h		; 8042 STATUS PORT
   459                              <1> INPT_BUF_FULL	equ	00000010b 	; 1 = +INPUT BUFFER FULL
   460                              <1> PORT_A		equ	060h		; 8042 KEYBOARD SCAN CODE/CONTROL PORT
   461                              <1> ;---------- 8042 KEYBOARD RESPONSE ---------------------------------------------
   462                              <1> KB_ACK		equ	0FAh		; ACKNOWLEDGE PROM TRANSMISSION
   463                              <1> KB_RESEND	equ	0FEh		; RESEND REQUEST
   464                              <1> KB_OVER_RUN	equ	0FFh		; OVER RUN SCAN CODE
   465                              <1> ;---------- KEYBOARD/LED COMMANDS ----------------------------------------------
   466                              <1> KB_ENABLE	equ	0F4h		; KEYBOARD ENABLE
   467                              <1> LED_CMD		equ	0EDh		; LED WRITE COMMAND
   468                              <1> KB_TYPA_RD	equ	0F3h		; TYPAMATIC RATE/DELAY COMMAND
   469                              <1> ;---------- KEYBOARD SCAN CODES ------------------------------------------------
   470                              <1> NUM_KEY		equ	69		; SCAN CODE FOR	 NUMBER LOCK KEY
   471                              <1> SCROLL_KEY	equ	70		; SCAN CODE FOR	 SCROLL LOCK KEY
   472                              <1> ALT_KEY		equ	56		; SCAN CODE FOR	 ALTERNATE SHIFT KEY
   473                              <1> CTL_KEY		equ	29		; SCAN CODE FOR	 CONTROL KEY
   474                              <1> CAPS_KEY	equ	58		; SCAN CODE FOR	 SHIFT LOCK KEY
   475                              <1> DEL_KEY		equ	83		; SCAN CODE FOR	 DELETE KEY
   476                              <1> INS_KEY		equ	82		; SCAN CODE FOR	 INSERT KEY
   477                              <1> LEFT_KEY	equ	42		; SCAN CODE FOR	 LEFT SHIFT
   478                              <1> RIGHT_KEY	equ	54		; SCAN CODE FOR	 RIGHT SHIFT
   479                              <1> SYS_KEY		equ	84		; SCAN CODE FOR	 SYSTEM KEY
   480                              <1> ;---------- ENHANCED KEYBOARD SCAN CODES ---------------------------------------
   481                              <1> ID_1		equ	0ABh		; 1ST ID CHARACTER FOR KBX
   482                              <1> ID_2		equ	041h		; 2ND ID CHARACTER FOR KBX
   483                              <1> ID_2A		equ	054h		; ALTERNATE 2ND ID CHARACTER FOR KBX
   484                              <1> F11_M		equ	87		; F11 KEY MAKE
   485                              <1> F12_M		equ	88		; F12 KEY MAKE
   486                              <1> MC_E0		equ	224		; GENERAL MARKER CODE
   487                              <1> MC_E1		equ	225		; PAUSE KEY MARKER CODE
   488                              <1> ;---------- FLAG EQUATES WITHIN @KB_FLAG----------------------------------------
   489                              <1> RIGHT_SHIFT	equ	00000001b	; RIGHT SHIFT KEY DEPRESSED
   490                              <1> LEFT_SHIFT	equ	00000010b	; LEFT SHIFT KEY DEPRESSED
   491                              <1> CTL_SHIFT	equ	00000100b	; CONTROL SHIFT KEY DEPRESSED
   492                              <1> ALT_SHIFT	equ	00001000b	; ALTERNATE SHIFT KEY DEPRESSED
   493                              <1> SCROLL_STATE	equ	00010000b	; SCROLL LOCK STATE IS ACTIVE
   494                              <1> NUM_STATE	equ	00100000b	; NUM LOCK STATE IS ACTIVE
   495                              <1> CAPS_STATE	equ	01000000b	; CAPS LOCK STATE IS ACTIVE
   496                              <1> INS_STATE	equ	10000000b	; INSERT STATE IS ACTIVE
   497                              <1> ;---------- FLAG EQUATES WITHIN	@KB_FLAG_1 -------------------------------------
   498                              <1> L_CTL_SHIFT	equ	00000001b	; LEFT CTL KEY DOWN
   499                              <1> L_ALT_SHIFT	equ	00000010b	; LEFT ALT KEY DOWN
   500                              <1> SYS_SHIFT	equ	00000100b	; SYSTEM KEY DEPRESSED AND HELD
   501                              <1> HOLD_STATE	equ	00001000b	; SUSPEND KEY HAS BEEN TOGGLED
   502                              <1> SCROLL_SHIFT	equ	00010000b	; SCROLL LOCK KEY IS DEPRESSED
   503                              <1> NUM_SHIFT	equ	00100000b	; NUM LOCK KEY IS DEPRESSED
   504                              <1> CAPS_SHIFT	equ	01000000b	; CAPS LOCK KEY IS DEPRE55ED
   505                              <1> INS_SHIFT	equ	10000000b	; INSERT KEY IS DEPRESSED
   506                              <1> ;---------- FLAGS EQUATES WITHIN @KB_FLAG_2 -----------------------------------
   507                              <1> KB_LEDS		equ	00000111b	; KEYBOARD LED STATE BITS
   508                              <1> ;		equ	00000001b	; SCROLL LOCK INDICATOR
   509                              <1> ;		equ	00000010b	; NUM LOCK INDICATOR
   510                              <1> ;		equ	00000100b	; CAPS LOCK INDICATOR
   511                              <1> ;		equ	00001000b	; RESERVED (MUST BE ZERO)
   512                              <1> KB_FA		equ	00010000b	; ACKNOWLEDGMENT RECEIVED
   513                              <1> KB_FE		equ	00100000b	; RESEND RECEIVED FLAG
   514                              <1> KB_PR_LED	equ	01000000b	; MODE INDICATOR UPDATE
   515                              <1> KB_ERR		equ	10000000b	; KEYBOARD TRANSMIT ERROR FLAG
   516                              <1> ;----------- FLAGS EQUATES WITHIN @KB_FLAG_3 -----------------------------------
   517                              <1> LC_E1		equ	00000001b	; LAST CODE WAS THE E1 HIDDEN CODE
   518                              <1> LC_E0		equ	00000010b	; LAST CODE WAS THE E0 HIDDEN CODE
   519                              <1> R_CTL_SHIFT	equ	00000100b	; RIGHT CTL KEY DOWN
   520                              <1> R_ALT_SHIFT	equ	00001000b	; RIGHT ALT KEY DOWN
   521                              <1> GRAPH_ON	equ	00001000b	; ALT GRAPHICS KEY DOWN (WT ONLY)	
   522                              <1> KBX		equ	00010000b	; ENHANCED KEYBOARD INSTALLED
   523                              <1> SET_NUM_LK	equ	00100000b	; FORCE NUM LOCK IF READ ID AND KBX
   524                              <1> LC_AB		equ	01000000b	; LAST CHARACTER WAS FIRST ID CHARACTER
   525                              <1> RD_ID		equ	10000000b	; DOING A READ ID (MUST BE BIT0)
   526                              <1> ;
   527                              <1> ;----------- INTERRUPT EQUATES -------------------------------------------------
   528                              <1> EOI		equ	020h		; END OF INTERRUPT COMMAND TO 8259
   529                              <1> INTA00		equ	020h		; 8259 PORT
   530                              <1> 
   531                              <1> 
   532                              <1> kb_int:
   533                              <1> 
   534                              <1> ; 17/10/2015 ('ctrlbrk') 
   535                              <1> ; 05/12/2014
   536                              <1> ; 04/12/2014 (derived from pc-xt-286 bios source code -1986-)
   537                              <1> ; 26/08/2014
   538                              <1> ;
   539                              <1> ; 03/06/86  KEYBOARD BIOS
   540                              <1> ;
   541                              <1> ;--- HARDWARE INT 09H -- (IRQ LEVEL 1) ------------------------------------------
   542                              <1> ;										;
   543                              <1> ;	KEYBOARD INTERRUPT ROUTINE						;
   544                              <1> ;										;
   545                              <1> ;--------------------------------------------------------------------------------
   546                              <1> 
   547                              <1> KB_INT_1:
   548 000010BE FB                  <1> 	sti				; ENABLE INTERRUPTS
   549                              <1> 	;push	ebp
   550 000010BF 50                  <1> 	push	eax
   551 000010C0 53                  <1> 	push	ebx
   552 000010C1 51                  <1> 	push	ecx
   553 000010C2 52                  <1> 	push	edx
   554 000010C3 56                  <1> 	push	esi
   555 000010C4 57                  <1> 	push	edi
   556 000010C5 1E                  <1> 	push	ds
   557 000010C6 06                  <1> 	push	es
   558 000010C7 FC                  <1> 	cld				; FORWARD DIRECTION
   559 000010C8 66B81000            <1> 	mov	ax, KDATA
   560 000010CC 8ED8                <1> 	mov	ds, ax
   561 000010CE 8EC0                <1> 	mov	es, ax
   562                              <1> 	;
   563                              <1> 	;-----	WAIT FOR KEYBOARD DISABLE COMMAND TO BE ACCEPTED
   564 000010D0 B0AD                <1> 	mov	al, DIS_KBD		; DISABLE THE KEYBOARD COMMAND
   565 000010D2 E8A9050000          <1> 	call	SHIP_IT			; EXECUTE DISABLE
   566 000010D7 FA                  <1> 	cli				; DISABLE INTERRUPTS
   567 000010D8 B900000100          <1> 	mov	ecx, 10000h		; SET MAXIMUM TIMEOUT
   568                              <1> KB_INT_01:
   569 000010DD E464                <1> 	in	al, STATUS_PORT		; READ ADAPTER STATUS
   570 000010DF A802                <1> 	test	al, INPT_BUF_FULL	; CHECK INPUT BUFFER FULL STATUS BIT
   571 000010E1 E0FA                <1> 	loopnz	KB_INT_01		; WAIT FOR COMMAND TO BE ACCEPTED
   572                              <1> 	;
   573                              <1> 	;-----	READ CHARACTER FROM KEYBOARD INTERFACE
   574 000010E3 E460                <1> 	in	al, PORT_A		; READ IN THE CHARACTER
   575                              <1> 	;
   576                              <1> 	;-----	SYSTEM HOOK INT 15H - FUNCTION 4FH (ON HARDWARE INT LEVEL 9H) 	
   577                              <1> 	;MOV	AH, 04FH		; SYSTEM INTERCEPT - KEY CODE FUNCTION
   578                              <1> 	;STC				; SET CY=1 (IN CASE OF IRET)
   579                              <1> 	;INT	15H			; CASETTE CALL (AL)=KEY SCAN CODE
   580                              <1> 	;				; RETURNS CY=1 FOR INVALID FUNCTION
   581                              <1> 	;JC	KB_INT_02		; CONTINUE IF CARRY FLAG SET ((AL)=CODE)
   582                              <1> 	;JMP	K26			; EXIT IF SYSTEM HANDLES SCAN CODE
   583                              <1> 	;				; EXT HANDLES HARDWARE EOI AND ENABLE		
   584                              <1> 	;
   585                              <1> 	;-----	CHECK FOR A RESEND COMMAND TO KEYBOARD
   586                              <1> KB_INT_02:				; 	  (AL)= SCAN CODE
   587 000010E5 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
   588 000010E6 3CFE                <1> 	cmp	al, KB_RESEND		; IS THE INPUT A RESEND
   589 000010E8 7411                <1>         je      short KB_INT_4          ; GO IF RESEND
   590                              <1> 	;
   591                              <1> 	;-----	CHECK FOR RESPONSE TO A COMMAND TO KEYBOARD
   592 000010EA 3CFA                <1> 	cmp	al, KB_ACK		; IS THE INPUT AN ACKNOWLEDGE
   593 000010EC 751A                <1>         jne     short KB_INT_2          ; GO IF NOT
   594                              <1> 	;
   595                              <1> 	;-----	A COMMAND TO THE KEYBOARD WAS ISSUED
   596 000010EE FA                  <1> 	cli				; DISABLE INTERRUPTS
   597 000010EF 800D[67690000]10    <1> 	or	byte [KB_FLAG_2], KB_FA ; INDICATE ACK RECEIVED
   598 000010F6 E97A020000          <1>         jmp     K26                     ; RETURN IF NOT (ACK RETURNED FOR DATA)
   599                              <1> 	;
   600                              <1> 	;-----	RESEND THE LAST BYTE
   601                              <1> KB_INT_4:
   602 000010FB FA                  <1> 	cli				; DISABLE INTERRUPTS
   603 000010FC 800D[67690000]20    <1> 	or	byte [KB_FLAG_2], KB_FE ; INDICATE RESEND RECEIVED
   604 00001103 E96D020000          <1>         jmp     K26                     ; RETURN IF NOT ACK RETURNED FOR DATA)
   605                              <1> 	;
   606                              <1> ;-----	UPDATE MODE INDICATORS IF CHANGE IN STATE
   607                              <1> KB_INT_2:
   608 00001108 6650                <1> 	push 	ax			; SAVE DATA IN
   609 0000110A E83D060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
   610 0000110F 8A1D[67690000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
   611 00001115 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
   612 00001117 80E307              <1> 	and	bl, KB_LEDS		; ISOLATE INDICATOR BITS
   613 0000111A 7405                <1> 	jz	short UP0		; IF NO CHANGE BYPASS UPDATE
   614 0000111C E8C0050000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
   615                              <1> UP0:
   616 00001121 6658                <1> 	pop	ax			; RESTORE DATA IN
   617                              <1> ;------------------------------------------------------------------------
   618                              <1> ;	START OF KEY PROCESSING						;
   619                              <1> ;------------------------------------------------------------------------
   620 00001123 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE IN AH ALSO
   621                              <1> 	;
   622                              <1> 	;-----	TEST FOR OVERRUN SCAN CODE FROM KEYBOARD
   623 00001125 3CFF                <1> 	cmp	al, KB_OVER_RUN		; IS THIS AN OVERRUN CHAR
   624 00001127 0F843F050000        <1>         je      K62			; BUFFER_FULL_BEEP
   625                              <1> 	;
   626                              <1> K16:	
   627 0000112D 8A3D[68690000]      <1> 	mov	bh, [KB_FLAG_3]		; LOAD FLAGS FOR TESTING
   628                              <1> 	;
   629                              <1> 	;-----	TEST TO SEE IF A READ_ID IS IN PROGRESS
   630 00001133 F6C7C0              <1> 	test 	bh, RD_ID+LC_AB 	; ARE WE DOING A READ ID?
   631 00001136 7449                <1> 	jz	short NOT_ID		; CONTINUE IF NOT
   632 00001138 7917                <1> 	jns	short TST_ID_2		; IS THE RD_ID FLAG ON?
   633 0000113A 3CAB                <1> 	cmp	al, ID_1		; IS THIS THE 1ST ID CHARACTER?
   634 0000113C 7507                <1> 	jne	short RST_RD_ID
   635 0000113E 800D[68690000]40    <1> 	or	byte [KB_FLAG_3], LC_AB ; INDICATE 1ST ID WAS OK
   636                              <1> RST_RD_ID:
   637 00001145 8025[68690000]7F    <1> 	and	byte [KB_FLAG_3], ~RD_ID ; RESET THE READ ID FLAG
   638                              <1>         ;jmp    short ID_EX		; AND EXIT
   639 0000114C E924020000          <1> 	jmp	K26
   640                              <1> 	;
   641                              <1> TST_ID_2:
   642 00001151 8025[68690000]BF    <1> 	and	byte [KB_FLAG_3], ~LC_AB ; RESET FLAG
   643 00001158 3C54                <1> 	cmp	al, ID_2A		; IS THIS THE 2ND ID CHARACTER?
   644 0000115A 7419                <1>         je	short KX_BIT		; JUMP IF SO
   645 0000115C 3C41                <1> 	cmp	al, ID_2		; IS THIS THE 2ND ID CHARACTER?
   646                              <1>         ;jne	short ID_EX		; LEAVE IF NOT
   647 0000115E 0F8511020000        <1> 	jne	K26
   648                              <1> 	;
   649                              <1> 	;-----	A READ ID SAID THAT IT WAS ENHANCED KEYBOARD
   650 00001164 F6C720              <1> 	test	bh, SET_NUM_LK 		; SHOULD WE SET NUM LOCK?
   651 00001167 740C                <1>         jz      short KX_BIT		; EXIT IF NOT
   652 00001169 800D[65690000]20    <1> 	or	byte [KB_FLAG], NUM_STATE ; FORCE NUM LOCK ON
   653 00001170 E86C050000          <1> 	call	SND_LED			; GO SET THE NUM LOCK INDICATOR
   654                              <1> KX_BIT:
   655 00001175 800D[68690000]10    <1> 	or	byte [KB_FLAG_3], KBX	; INDICATE ENHANCED KEYBOARD WAS FOUND
   656 0000117C E9F4010000          <1> ID_EX:	jmp     K26			; EXIT
   657                              <1> 	;
   658                              <1> NOT_ID:
   659 00001181 3CE0                <1> 	cmp	al, MC_E0		; IS THIS THE GENERAL MARKER CODE?
   660 00001183 750C                <1> 	jne	short TEST_E1
   661 00001185 800D[68690000]12    <1> 	or	byte [KB_FLAG_3], LC_E0+KBX ; SET FLAG BIT, SET KBX, AND
   662                              <1> 	;jmp	short EXIT		; THROW AWAY THIS CODE
   663 0000118C E9EB010000          <1> 	jmp	K26A	
   664                              <1> TEST_E1:	
   665 00001191 3CE1                <1> 	cmp	al, MC_E1		; IS THIS THE PAUSE KEY?
   666 00001193 750C                <1> 	jne	short NOT_HC
   667 00001195 800D[68690000]11    <1> 	or	byte [KB_FLAG_3], LC_E1+KBX ; SET FLAG BIT, SET KBX, AND
   668 0000119C E9DB010000          <1> EXIT:	jmp	K26A			; THROW AWAY THIS CODE
   669                              <1> 	;
   670                              <1> NOT_HC:
   671 000011A1 247F                <1> 	and	al, 07Fh		; TURN OFF THE BREAK BIT
   672 000011A3 F6C702              <1> 	test	bh, LC_E0		; LAST CODE THE E0 MARKER CODE
   673 000011A6 7414                <1> 	jz	short NOT_LC_E0		; JUMP IF NOT
   674                              <1> 	;
   675 000011A8 BF[52680000]        <1> 	mov	edi, _K6+6		; IS THIS A SHIFT KEY?
   676 000011AD AE                  <1> 	scasb
   677 000011AE 0F84C1010000        <1>         je      K26 ; K16B              ; YES, THROW AWAY & RESET FLAG
   678 000011B4 AE                  <1> 	scasb
   679 000011B5 757C                <1> 	jne	short K16A		; NO, CONTINUE KEY PROCESSING
   680                              <1> 	;jmp	short K16B		; YES, THROW AWAY & RESET FLAG
   681 000011B7 E9B9010000          <1> 	jmp	K26
   682                              <1> 	;
   683                              <1> NOT_LC_E0:
   684 000011BC F6C701              <1> 	test	bh, LC_E1		; LAST CODE THE E1 MARKER CODE?
   685 000011BF 7435                <1> 	jz	short T_SYS_KEY		; JUMP IF NOT
   686 000011C1 B904000000          <1> 	mov	ecx, 4			; LENGHT OF SEARCH
   687 000011C6 BF[50680000]        <1> 	mov	edi, _K6+4		; IS THIS AN ALT, CTL, OR SHIFT?
   688 000011CB F2AE                <1> 	repne	scasb			; CHECK IT
   689                              <1> 	;je	short EXIT		; THROW AWAY IF SO
   690 000011CD 0F84A9010000        <1> 	je	K26A			
   691                              <1> 	;
   692 000011D3 3C45                <1> 	cmp	al, NUM_KEY		; IS IT THE PAUSE KEY?
   693                              <1> 	;jne	short K16B		; NO, THROW AWAY & RESET FLAG
   694 000011D5 0F859A010000        <1> 	jne	K26
   695 000011DB F6C480              <1> 	test	ah, 80h			; YES, IS IT THE BREAK OF THE KEY?
   696                              <1> 	;jnz	short K16B		; YES, THROW THIS AWAY, TOO	
   697 000011DE 0F8591010000        <1> 	jnz	K26
   698                              <1>         ; 20/02/2015 
   699 000011E4 F605[66690000]08    <1> 	test	byte [KB_FLAG_1],HOLD_STATE ;  NO, ARE WE PAUSED ALREADY?
   700                              <1> 	;jnz	short K16B		;  YES, THROW AWAY
   701 000011EB 0F8584010000        <1> 	jnz	K26
   702 000011F1 E9E1020000          <1> 	jmp     K39P                    ; NO, THIS IS THE REAL PAUSE STATE
   703                              <1> 	;
   704                              <1> 	;-----	TEST FOR SYSTEM KEY
   705                              <1> T_SYS_KEY:
   706 000011F6 3C54                <1> 	cmp	al, SYS_KEY		; IS IT THE SYSTEM KEY?
   707 000011F8 7539                <1> 	jnz	short K16A		; CONTINUE IF NOT
   708                              <1> 	;
   709 000011FA F6C480              <1> 	test	ah, 80h			; CHECK IF THIS A BREAK CODE
   710 000011FD 7524                <1> 	jnz	short K16C		; DO NOT TOUCH SYSTEM INDICATOR IF TRUE
   711                              <1> 	;
   712 000011FF F605[66690000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; SEE IF IN SYSTEM KEY HELD DOWN 
   713                              <1>         ;jnz	short K16B		; IF YES, DO NOT PROCESS SYSTEM INDICATOR	
   714 00001206 0F8569010000        <1> 	jnz     K26			
   715                              <1> 	;
   716 0000120C 800D[66690000]04    <1> 	or	byte [KB_FLAG_1], SYS_SHIFT ; INDICATE SYSTEM KEY DEPRESSED
   717 00001213 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
   718 00001215 E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
   719                              <1> 					; INTERRUPT-RETURN-NO-EOI
   720 00001217 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
   721 00001219 E862040000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
   722                              <1> 	; !!! SYSREQ !!! function/system call (INTERRUPT) must be here !!!
   723                              <1> 	;MOV	AL, 8500H		; FUNCTION VALUE FOR MAKE OF SYSTEM KEY
   724                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
   725                              <1> 	;INT	15H			; USER INTERRUPT	
   726 0000121E E965010000          <1>         jmp     K27A                    ; END PROCESSING
   727                              <1> 	;
   728                              <1> ;K16B:	jmp	K26			; IGNORE SYSTEM KEY
   729                              <1> 	;
   730                              <1> K16C:
   731 00001223 8025[66690000]FB    <1> 	and	byte [KB_FLAG_1], ~SYS_SHIFT ; TURN OFF SHIFT KEY HELD DOWN
   732 0000122A B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
   733 0000122C E620                <1> 	out	20h, al ;out INTA00, al ; SEND COMMAND TO INTERRUPT CONTROL PORT
   734                              <1> 					; INTERRUPT-RETURN-NO-EOI
   735                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
   736                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
   737                              <1> 	;
   738                              <1> 	;MOV	AX, 8501H		; FUNCTION VALUE FOR BREAK OF SYSTEM KEY
   739                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
   740                              <1> 	;INT	15H			; USER INTERRUPT
   741                              <1> 	;JMP	K27A			; INGONRE SYSTEM KEY				
   742                              <1> 	;
   743 0000122E E94E010000          <1> 	jmp     K27			; IGNORE SYSTEM KEY
   744                              <1> 	;
   745                              <1> 	;-----	TEST FOR SHIFT KEYS
   746                              <1> K16A:
   747 00001233 8A1D[65690000]      <1> 	mov	bl, [KB_FLAG]		; PUT STATE FLAGS IN BL
   748 00001239 BF[4C680000]        <1> 	mov	edi, _K6		; SHIFT KEY TABLE offset
   749 0000123E B908000000          <1> 	mov	ecx, _K6L		; LENGTH
   750 00001243 F2AE                <1> 	repne	scasb			; LOOK THROUGH THE TABLE FOR A MATCH
   751 00001245 88E0                <1> 	mov	al, ah			; RECOVER SCAN CODE
   752 00001247 0F8510010000        <1>         jne     K25                     ; IF NO MATCH, THEN SHIFT NOT FOUND
   753                              <1> 	;
   754                              <1> 	;------	SHIFT KEY FOUND
   755                              <1> K17:
   756 0000124D 81EF[4D680000]      <1>         sub     edi, _K6+1              ; ADJUST PTR TO SCAN CODE MATCH
   757 00001253 8AA7[54680000]      <1>        	mov     ah, [edi+_K7]       	; GET MASK INTO AH
   758 00001259 B102                <1> 	mov	cl, 2			; SETUP COUNT FOR FLAG SHIFTS
   759 0000125B A880                <1> 	test	al, 80h			; TEST FOR BREAK KEY
   760 0000125D 0F8596000000        <1>         jnz     K23                     ; JUMP OF BREAK
   761                              <1> 	;
   762                              <1> 	;-----	SHIFT MAKE FOUND, DETERMINE SET OR TOGGLE
   763                              <1> K17C:
   764 00001263 80FC10              <1> 	cmp	ah, SCROLL_SHIFT
   765 00001266 732B                <1> 	jae	short K18		; IF SCROLL SHIFT OR ABOVE, TOGGLE KEY
   766                              <1> 	;
   767                              <1> 	;-----	PLAIN SHIFT KEY, SET SHIFT ON
   768 00001268 0825[65690000]      <1> 	or	[KB_FLAG], ah		; TURN ON SHIFT BIT
   769 0000126E A80C                <1>         test	al, CTL_SHIFT+ALT_SHIFT ; IS IT ALT OR CTRL?
   770                              <1> 	;jnz	short K17D		; YES, MORE FLAGS TO SET
   771 00001270 0F84FF000000        <1> 	jz	K26			; NO, INTERRUPT RETURN
   772                              <1> K17D:
   773 00001276 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF NEW KEYS?
   774 00001279 740B                <1> 	jz 	short K17E		; NO, JUMP
   775 0000127B 0825[68690000]      <1> 	or	[KB_FLAG_3], ah		; SET BITS FOR RIGHT CTRL, ALT
   776 00001281 E9EF000000          <1> 	jmp	K26			; INTERRUPT RETURN
   777                              <1> K17E:
   778 00001286 D2EC                <1> 	shr	ah, cl			; MOVE FLAG BITS TWO POSITIONS
   779 00001288 0825[66690000]      <1> 	or	[KB_FLAG_1], ah		; SET BITS FOR LEFT CTRL, ALT
   780 0000128E E9E2000000          <1> 	jmp	K26
   781                              <1> 	;
   782                              <1> 	;-----	TOGGLED SHIFT KEY, TEST FOR 1ST MAKE OR NOT
   783                              <1> K18:					; SHIFT-TOGGLE
   784 00001293 F6C304              <1> 	test	bl, CTL_SHIFT 		; CHECK CTL SHIFT STATE
   785                              <1>         ;jz    	short K18A              ; JUMP IF NOT CTL STATE
   786 00001296 0F85C1000000        <1>         jnz     K25                     ; JUMP IF CTL STATE
   787                              <1> K18A:
   788 0000129C 3C52                <1> 	cmp	al, INS_KEY		; CHECK FOR INSERT KEY
   789 0000129E 7524                <1> 	jne	short K22		; JUMP IF NOT INSERT KEY
   790 000012A0 F6C308              <1> 	test	bl, ALT_SHIFT 		; CHECK FOR ALTERNATE SHIFT
   791                              <1>       	;jz	short K18B		; JUMP IF NOT ALTERNATE SHIFT	
   792 000012A3 0F85B4000000        <1>         jnz     K25                     ; JUMP IF ALTERNATE SHIFT
   793                              <1> K18B:
   794 000012A9 F6C702              <1> 	test	bh, LC_E0 ;20/02/2015	; IS THIS NEW INSERT KEY?
   795 000012AC 7516                <1> 	jnz	short K22		; YES, THIS ONE'S NEVER A '0'
   796                              <1> K19:	
   797 000012AE F6C320              <1> 	test	bl, NUM_STATE 		; CHECK FOR BASE STATE
   798 000012B1 750C                <1> 	jnz	short K21		; JUMP IF NUM LOCK IS ON
   799 000012B3 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST FOR SHIFT STATE
   800 000012B6 740C                <1> 	jz	short K22		; JUMP IF BASE STATE
   801                              <1> K20:					; NUMERIC ZERO, NOT INSERT KEY
   802 000012B8 88C4                <1> 	mov	ah, al			; PUT SCAN CODE BACK IN AH
   803 000012BA E99E000000          <1>         jmp     K25                     ; NUMERAL '0', STNDRD. PROCESSING
   804                              <1> K21:					; MIGHT BE NUMERIC
   805 000012BF F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT
   806 000012C2 74F4                <1> 	jz	short K20		; IS NUMERIC, STD. PROC.
   807                              <1> 	;
   808                              <1> K22:					; SHIFT TOGGLE KEY HIT; PROCESS IT
   809 000012C4 8425[66690000]      <1> 	test	ah, [KB_FLAG_1] 	; IS KEY ALREADY DEPRESSED
   810 000012CA 0F85A5000000        <1>         jnz     K26                     ; JUMP IF KEY ALREADY DEPRESSED
   811                              <1> K22A:
   812 000012D0 0825[66690000]      <1>         or      [KB_FLAG_1], ah 	; INDICATE THAT THE KEY IS DEPRESSED
   813 000012D6 3025[65690000]      <1> 	xor	[KB_FLAG], ah		; TOGGLE THE SHIFT STATE
   814                              <1> 	;
   815                              <1> 	;-----	TOGGLE LED IF CAPS, NUM  OR SCROLL KEY DEPRESSED
   816 000012DC F6C470              <1> 	test	ah, CAPS_SHIFT+NUM_SHIFT+SCROLL_SHIFT ; SHIFT TOGGLE?
   817 000012DF 7409                <1> 	jz	short K22B		; GO IF NOT
   818                              <1> 	;
   819 000012E1 6650                <1> 	push	ax			; SAVE SCAN CODE AND SHIFT MASK
   820 000012E3 E8F9030000          <1> 	call	SND_LED			; GO TURN MODE INDICATORS ON
   821 000012E8 6658                <1> 	pop	ax			; RESTORE SCAN CODE
   822                              <1> K22B:
   823 000012EA 3C52                <1> 	cmp	al, INS_KEY		; TEST FOR 1ST MAKE OF INSERT KEY
   824 000012EC 0F8583000000        <1>         jne     K26                     ; JUMP IF NOT INSERT KEY
   825 000012F2 88C4                <1> 	mov	ah, al		        ; SCAN CODE IN BOTH HALVES OF AX
   826 000012F4 E999000000          <1>         jmp     K28                     ; FLAGS UPDATED, PROC. FOR BUFFER
   827                              <1> 	;
   828                              <1> 	;-----	BREAK SHIFT FOUND
   829                              <1> K23:					; BREAK-SHIFT-FOUND
   830 000012F9 80FC10              <1> 	cmp	ah, SCROLL_SHIFT	; IS THIS A TOGGLE KEY
   831 000012FC F6D4                <1> 	not	ah			; INVERT MASK
   832 000012FE 7355                <1> 	jae	short K24		; YES, HANDLE BREAK TOGGLE
   833 00001300 2025[65690000]      <1> 	and	[KB_FLAG], ah		; TURN OFF SHIFT BIT
   834 00001306 80FCFB              <1> 	cmp	ah, ~CTL_SHIFT		; IS THIS ALT OR CTL?
   835 00001309 7730                <1> 	ja	short K23D		; NO, ALL DONE
   836                              <1> 	;
   837 0000130B F6C702              <1> 	test	bh, LC_E0		; 2ND ALT OR CTL?
   838 0000130E 7408                <1> 	jz	short K23A		; NO, HANSLE NORMALLY
   839 00001310 2025[68690000]      <1> 	and 	[KB_FLAG_3], ah		; RESET BIT FOR RIGHT ALT OR CTL
   840 00001316 EB08                <1> 	jmp	short K23B		; CONTINUE
   841                              <1> K23A:
   842 00001318 D2FC                <1> 	sar	ah, cl			; MOVE THE MASK BIT TWO POSITIONS
   843 0000131A 2025[66690000]      <1> 	and	[KB_FLAG_1], ah		; RESET BIT FOR LEFT ALT AND CTL
   844                              <1> K23B:
   845 00001320 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE
   846 00001322 A0[68690000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT ALT & CTRL FLAGS
   847 00001327 D2E8                <1> 	shr	al, cl			; MOVE TO BITS 1 & 0
   848 00001329 0A05[66690000]      <1> 	or	al, [KB_FLAG_1]		; PUT IN LEFT ALT & CTL FLAGS
   849 0000132F D2E0                <1> 	shl	al, cl			; MOVE BACK TO BITS 3 & 2
   850 00001331 240C                <1> 	and	al, ALT_SHIFT+CTL_SHIFT ; FILTER OUT OTHER GARBAGE
   851 00001333 0805[65690000]      <1> 	or	[KB_FLAG], al		; PUT RESULT IN THE REAL FLAGS	
   852 00001339 88E0                <1> 	mov	al, ah
   853                              <1> K23D:
   854 0000133B 3CB8                <1> 	cmp	al, ALT_KEY+80h		; IS THIS ALTERNATE SHIFT RELEASE
   855 0000133D 7536                <1> 	jne	short K26		; INTERRUPT RETURN
   856                              <1> 	;	
   857                              <1> 	;-----	ALTERNATE SHIFT KEY RELEASED, GET THE VALUE INTO BUFFER
   858 0000133F A0[69690000]        <1> 	mov	al, [ALT_INPUT]
   859 00001344 B400                <1> 	mov	ah, 0			; SCAN CODE OF 0
   860 00001346 8825[69690000]      <1> 	mov	[ALT_INPUT], ah 	; ZERO OUT THE FIELD
   861 0000134C 3C00                <1> 	cmp	al, 0			; WAS THE INPUT = 0?
   862 0000134E 7425                <1> 	je	short K26		; INTERRUPT_RETURN
   863                              <1>         ; 29/01/2016
   864                              <1> 	;jmp     K61                    ; IT WASN'T, SO PUT IN BUFFER
   865 00001350 E9D0020000          <1> 	jmp	_K60
   866                              <1> 	;
   867                              <1> K24:					; BREAK-TOGGLE
   868 00001355 2025[66690000]      <1> 	and	[KB_FLAG_1], ah 	; INDICATE NO LONGER DEPRESSED
   869 0000135B EB18                <1> 	jmp	short K26		; INTERRUPT_RETURN
   870                              <1> 	;
   871                              <1> 	;-----	TEST FOR HOLD STATE
   872                              <1> 					; AL, AH = SCAN CODE
   873                              <1> K25:					; NO-SHIFT-FOUND
   874 0000135D 3C80                <1> 	cmp	al, 80h			; TEST FOR BREAK KEY
   875 0000135F 7314                <1> 	jae	short K26		; NOTHING FOR BREAK CHARS FROM HERE ON
   876 00001361 F605[66690000]08    <1> 	test	byte [KB_FLAG_1], HOLD_STATE ; ARE WE IN HOLD STATE
   877 00001368 7428                <1> 	jz	short K28		; BRANCH AROUND TEST IF NOT
   878 0000136A 3C45                <1> 	cmp	al, NUM_KEY
   879 0000136C 7407                <1> 	je	short K26		; CAN'T END HOLD ON NUM_LOCK
   880 0000136E 8025[66690000]F7    <1> 	and	byte [KB_FLAG_1], ~HOLD_STATE ; TURN OFF THE HOLD STATE BIT
   881                              <1> 	;
   882                              <1> K26:
   883 00001375 8025[68690000]FC    <1> 	and	byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
   884                              <1> K26A:					; INTERRUPT-RETURN
   885 0000137C FA                  <1> 	cli				; TURN OFF INTERRUPTS
   886 0000137D B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
   887 0000137F E620                <1> 	out	20h, al	;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
   888                              <1> K27:					; INTERRUPT-RETURN-NO-EOI
   889 00001381 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
   890 00001383 E8F8020000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
   891                              <1> K27A:
   892 00001388 FA                  <1> 	cli				; DISABLE INTERRUPTS
   893                              <1> 	;;mov	byte [intflg], 0 ; 07/01/2017 ;; 15/01/2017
   894 00001389 07                  <1> 	pop	es			; RESTORE REGISTERS
   895 0000138A 1F                  <1> 	pop	ds
   896 0000138B 5F                  <1> 	pop	edi
   897 0000138C 5E                  <1> 	pop	esi
   898 0000138D 5A                  <1> 	pop	edx
   899 0000138E 59                  <1> 	pop	ecx
   900 0000138F 5B                  <1> 	pop	ebx
   901 00001390 58                  <1> 	pop	eax
   902                              <1> 	;pop	ebp
   903 00001391 CF                  <1> 	iretd				; RETURN
   904                              <1> 
   905                              <1> 	;-----	NOT IN	HOLD STATE
   906                              <1> K28:					; NO-HOLD-STATE
   907 00001392 3C58                <1> 	cmp	al, 88			; TEST FOR OUT-OF-RANGE SCAN CODES
   908 00001394 77DF                <1> 	ja	short K26		; IGNORE IF OUT-OF-RANGE	
   909                              <1> 	;
   910 00001396 F6C308              <1> 	test	bl, ALT_SHIFT 		; ARE WE IN ALTERNATE SHIFT
   911                              <1>         ;jz	short K28A		; IF NOT ALTERNATE
   912 00001399 0F84F1000000        <1>         jz      K38
   913                              <1> 	;
   914 0000139F F6C710              <1> 	test	bh, KBX			; IS THIS THE ENCHANCED KEYBOARD?
   915 000013A2 740D                <1> 	jz	short K29		; NO, ALT STATE IS REAL
   916                              <1> 	 ;28/02/2015
   917 000013A4 F605[66690000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; YES, IS SYSREQ KEY DOWN?
   918                              <1> 	;jz	short K29		;  NO, ALT STATE IS REAL
   919 000013AB 0F85DF000000        <1> 	jnz	K38			; YES, THIS IS PHONY ALT STATE 
   920                              <1>         ;				; DUE TO PRESSING SYSREQ	
   921                              <1> ;K28A:	jmp	short K38
   922                              <1> 	;
   923                              <1> 	;-----	TEST FOR RESET KEY SEQUENCE (CTL ALT DEL)
   924                              <1> K29:					; TEST-RESET
   925 000013B1 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT ALSO?
   926 000013B4 740B                <1> 	jz	short K31		; NO_RESET
   927 000013B6 3C53                <1> 	cmp	al, DEL_KEY		; CTL-ALT STATE, TEST FOR DELETE KEY
   928 000013B8 7507                <1> 	jne	short K31		; NO_RESET, IGNORE
   929                              <1> 	;
   930                              <1> 	;-----	CTL-ALT-DEL HAS BEEN FOUND
   931                              <1>  	; 26/08/2014
   932                              <1> cpu_reset:
   933                              <1> 	; IBM PC/AT ROM BIOS source code - 10/06/85 (TEST4.ASM - PROC_SHUTDOWN)
   934                              <1> 	; Send FEh (system reset command) to the keyboard controller.
   935 000013BA B0FE                <1> 	mov	al, SHUT_CMD		; SHUTDOWN COMMAND
   936 000013BC E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROL PORT
   937                              <1> khere:
   938 000013BE F4                  <1> 	hlt				; WAIT FOR 80286 RESET
   939 000013BF EBFD                <1> 	jmp 	short khere		; INSURE HALT
   940                              <1> 
   941                              <1> 	;
   942                              <1> 	;-----	IN ALTERNATE SHIFT, RESET NOT FOUND
   943                              <1> K31:					; NO-RESET
   944 000013C1 3C39                <1> 	cmp	al, 57			; TEST FOR SPACE KEY
   945 000013C3 7507                <1> 	jne	short K311		; NOT THERE
   946 000013C5 B020                <1> 	mov	al, ' '			; SET SPACE CHAR
   947 000013C7 E948020000          <1>         jmp     K57                     ; BUFFER_FILL
   948                              <1> K311:
   949 000013CC 3C0F                <1> 	cmp	al, 15			; TEST FOR TAB KEY
   950 000013CE 7509                <1> 	jne	short K312		; NOT THERE
   951 000013D0 66B800A5            <1> 	mov	ax, 0A500h		; SET SPECIAL CODE FOR ALT-TAB
   952 000013D4 E93B020000          <1>         jmp     K57                     ; BUFFER_FILL
   953                              <1> K312:
   954 000013D9 3C4A                <1> 	cmp	al, 74			; TEST FOR KEY PAD -
   955 000013DB 0F84A2000000        <1>         je      K37B                    ; GO PROCESS
   956 000013E1 3C4E                <1> 	cmp	al, 78			; TEST FOR KEY PAD +
   957 000013E3 0F849A000000        <1>         je      K37B                    ; GO PROCESS
   958                              <1> 	;
   959                              <1> 	;-----	LOOK FOR KEY PAD ENTRY
   960                              <1> K32:					; ALT-KEY-PAD
   961 000013E9 BF[28680000]        <1> 	mov	edi, K30		; ALT-INPUT-TABLE offset
   962 000013EE B90A000000          <1> 	mov	ecx, 10			; LOOK FOR ENTRY USING KEYPAD
   963 000013F3 F2AE                <1> 	repne	scasb			; LOOK FOR MATCH
   964 000013F5 7525                <1> 	jne	short K33		; NO_ALT_KEYPAD
   965 000013F7 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF THE NEW KEYS?
   966 000013FA 0F858A000000        <1>         jnz     K37C                    ; YES, JUMP, NOT NUMPAD KEY
   967 00001400 81EF[29680000]      <1> 	sub	edi, K30+1		; DI NOW HAS ENTRY VALUE
   968 00001406 A0[69690000]        <1> 	mov	al, [ALT_INPUT] 	; GET THE CURRENT BYTE
   969 0000140B B40A                <1> 	mov	ah, 10			; MULTIPLY BY 10
   970 0000140D F6E4                <1> 	mul	ah
   971 0000140F 6601F8              <1> 	add	ax, di			; ADD IN THE LATEST ENTRY
   972 00001412 A2[69690000]        <1> 	mov	[ALT_INPUT], al 	; STORE IT AWAY
   973                              <1> ;K32A:
   974 00001417 E959FFFFFF          <1>         jmp     K26                     ; THROW AWAY THAT KEYSTROKE
   975                              <1> 	;
   976                              <1> 	;-----	LOOK FOR SUPERSHIFT ENTRY
   977                              <1> K33:					; NO-ALT-KEYPAD
   978 0000141C C605[69690000]00    <1>         mov     byte [ALT_INPUT], 0     ; ZERO ANY PREVIOUS ENTRY INTO INPUT
   979 00001423 B91A000000          <1> 	mov	ecx, 26			; (DI),(ES) ALREADY POINTING
   980 00001428 F2AE                <1> 	repne	scasb			; LOOK FOR MATCH IN ALPHABET
   981 0000142A 7450                <1> 	je	short K37A		; MATCH FOUND, GO FILLL THE BUFFER
   982                              <1> 	;
   983                              <1> 	;-----	LOOK FOR TOP ROW OF ALTERNATE SHIFT
   984                              <1> K34:					; ALT-TOP-ROW
   985 0000142C 3C02                <1> 	cmp	al, 2			; KEY WITH '1' ON IT
   986 0000142E 7253                <1> 	jb	short K37B		; MUST BE ESCAPE
   987 00001430 3C0D                <1> 	cmp	al, 13			; IS IT IN THE REGION
   988 00001432 7705                <1> 	ja	short K35		; NO, ALT SOMETHING ELSE
   989 00001434 80C476              <1> 	add	ah, 118			; CONVERT PSEUDO SCAN CODE TO RANGE
   990 00001437 EB43                <1> 	jmp	short K37A		; GO FILL THE BUFFER
   991                              <1> 	;
   992                              <1> 	;-----	TRANSLATE ALTERNATE SHIFT PSEUDO SCAN CODES
   993                              <1> K35:					; ALT-FUNCTION
   994 00001439 3C57                <1> 	cmp	al, F11_M		; IS IT F11?	
   995 0000143B 7209                <1> 	jb	short K35A ; 20/02/2015	; NO, BRANCH
   996 0000143D 3C58                <1> 	cmp	al, F12_M		; IS IT F12?
   997 0000143F 7705                <1> 	ja	short K35A ; 20/02/2015	; NO, BRANCH
   998 00001441 80C434              <1> 	add	ah, 52			; CONVERT TO PSEUDO SCAN CODE
   999 00001444 EB36                <1> 	jmp	short K37A		; GO FILL THE BUFFER
  1000                              <1> K35A:
  1001 00001446 F6C702              <1> 	test	bh, LC_E0		; DO WE HAVE ONE OF THE NEW KEYS?
  1002 00001449 7422                <1> 	jz	short K37		; NO, JUMP
  1003 0000144B 3C1C                <1> 	cmp	al, 28			; TEST FOR KEYPAD ENTER
  1004 0000144D 7509                <1>         jne     short K35B              ; NOT THERE
  1005 0000144F 66B800A6            <1> 	mov	ax, 0A600h		; SPECIAL CODE
  1006 00001453 E9BC010000          <1> 	jmp	K57			; BUFFER FILL
  1007                              <1> K35B:
  1008 00001458 3C53                <1> 	cmp	al, 83			; TEST FOR DELETE KEY
  1009 0000145A 742E                <1> 	je	short K37C		; HANDLE WITH OTHER EDIT KEYS
  1010 0000145C 3C35                <1> 	cmp	al, 53			; TEST FOR KEYPAD /
  1011                              <1> 	;jne	short K32A		; NOT THERE, NO OTHER E0 SPECIALS	
  1012 0000145E 0F8511FFFFFF        <1>         jne     K26
  1013 00001464 66B800A4            <1> 	mov	ax, 0A400h		; SPECIAL CODE
  1014 00001468 E9A7010000          <1> 	jmp	K57			; BUFFER FILL
  1015                              <1> K37:
  1016 0000146D 3C3B                <1> 	cmp	al, 59			; TEST FOR FUNCTION KEYS (F1)
  1017 0000146F 7212                <1>         jb      short K37B		; NO FN, HANDLE W/OTHER EXTENDED
  1018 00001471 3C44                <1> 	cmp	al, 68			; IN KEYPAD REGION?
  1019                              <1>         ;ja	short K32A		; IF SO, IGNORE
  1020 00001473 0F87FCFEFFFF        <1>         ja      K26
  1021 00001479 80C42D              <1> 	add	ah, 45			; CONVERT TO PSEUDO SCAN CODE
  1022                              <1> K37A:
  1023 0000147C B000                <1> 	mov	al, 0			; ASCII CODE OF ZERO
  1024 0000147E E991010000          <1>         jmp     K57                     ; PUT IT IN THE BUFFER
  1025                              <1> K37B:
  1026 00001483 B0F0                <1> 	mov	al, 0F0h		; USE SPECIAL ASCII CODE
  1027 00001485 E98A010000          <1> 	jmp     K57                     ; PUT IT IN THE BUFFER
  1028                              <1> K37C:
  1029 0000148A 0450                <1> 	add	al, 80			; CONVERT SCAN CODE (EDIT KEYS)
  1030 0000148C 88C4                <1> 	mov	ah, al			; (SCAN CODE NOT IN AH FOR INSERT)
  1031 0000148E EBEC                <1> 	jmp     short K37A              ; PUT IT IN THE BUFFER
  1032                              <1> 	;
  1033                              <1> 	;-----	NOT IN ALTERNATE SHIFT
  1034                              <1> K38:					; NOT-ALT-SHIFT
  1035                              <1> 					; BL STILL HAS SHIFT FLAGS
  1036 00001490 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT?
  1037                              <1> 	;jnz	short K38A		; YES, START PROCESSING	
  1038 00001493 0F84B0000000        <1>         jz      K44                     ; NOT-CTL-SHIFT
  1039                              <1> 	;
  1040                              <1> 	;-----	CONTROL SHIFT, TEST SPECIAL CHARACTERS
  1041                              <1> 	;-----	TEST FOR BREAK
  1042                              <1> K38A:
  1043 00001499 3C46                <1> 	cmp	al, SCROLL_KEY		; TEST FOR BREAK
  1044 0000149B 7531                <1> 	jne	short K39		; JUMP, NO-BREAK
  1045 0000149D F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  1046 000014A0 7405                <1> 	jz	short K38B		; NO, BREAK IS VALID	
  1047 000014A2 F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  1048 000014A5 7427                <1> 	jz	short K39		; NO-BREAK, TEST FOR PAUSE	
  1049                              <1> K38B:
  1050 000014A7 8B1D[72690000]      <1> 	mov	ebx, [BUFFER_HEAD] 	; RESET BUFFER TO EMPTY
  1051 000014AD 891D[76690000]      <1> 	mov	[BUFFER_TAIL], ebx
  1052 000014B3 C605[64690000]80    <1> 	mov	byte [BIOS_BREAK], 80h  ; TURN ON BIOS_BREAK BIT
  1053                              <1> 	;
  1054                              <1> 	;-----	ENABLE KEYBOARD
  1055 000014BA B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  1056 000014BC E8BF010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  1057                              <1> 	;
  1058                              <1> 	; CTRL+BREAK code here !!!
  1059                              <1> 	;INT	1BH			; BREAK INTERRUPT VECTOR
  1060                              <1> 	; 17/10/2015	
  1061 000014C1 E8EA5A0000          <1> 	call	ctrlbrk ; control+break subroutine
  1062                              <1> 	;
  1063 000014C6 6629C0              <1> 	sub	ax, ax			; PUT OUT DUMMY CHARACTER
  1064 000014C9 E946010000          <1>         jmp     K57                     ; BUFFER_FILL
  1065                              <1> 	;
  1066                              <1> 	;-----	TEST FOR PAUSE
  1067                              <1> K39:					; NO_BREAK
  1068 000014CE F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  1069 000014D1 7537                <1> 	jnz	short K41		; YES, THEN THIS CAN'T BE PAUSE	
  1070 000014D3 3C45                <1> 	cmp	al, NUM_KEY		; LOOK FOR PAUSE KEY
  1071 000014D5 7533                <1> 	jne	short K41		; NO-PAUSE
  1072                              <1> K39P:
  1073 000014D7 800D[66690000]08    <1> 	or	byte [KB_FLAG_1], HOLD_STATE ; TURN ON THE HOLD FLAG
  1074                              <1> 	;
  1075                              <1> 	;-----	ENABLE KEYBOARD
  1076 000014DE B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  1077 000014E0 E89B010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  1078                              <1> K39A:
  1079 000014E5 B020                <1> 	mov	al, EOI			; END OF INTERRUPT TO CONTROL PORT
  1080 000014E7 E620                <1> 	out	20h, al ;out INTA00, al	; ALLOW FURTHER KEYSTROKE INTERRUPTS
  1081                              <1> 	;
  1082                              <1> 	;-----	DURING PAUSE INTERVAL, TURN COLOR CRT BACK ON
  1083 000014E9 803D[9A690000]07    <1>         cmp     byte [CRT_MODE], 7      ; IS THIS BLACK AND WHITE CARD
  1084 000014F0 740A                <1>         je      short K40              	; YES, NOTHING TO DO
  1085 000014F2 66BAD803            <1> 	mov	dx, 03D8h		; PORT FOR COLOR CARD
  1086 000014F6 A0[9B690000]        <1>         mov     al, [CRT_MODE_SET] 	; GET THE VALUE OF THE CURRENT MODE
  1087 000014FB EE                  <1> 	out	dx, al			; SET THE CRT MODE, SO THAT CRT IS ON
  1088                              <1> 	;
  1089                              <1> K40:					; PAUSE-LOOP
  1090 000014FC F605[66690000]08    <1>         test    byte [KB_FLAG_1], HOLD_STATE ; CHECK HOLD STATE FLAG
  1091 00001503 75F7                <1> 	jnz	short K40		; LOOP UNTIL FLAG TURNED OFF
  1092                              <1> 	;
  1093 00001505 E977FEFFFF          <1>         jmp     K27                     ; INTERRUPT_RETURN_NO_EOI
  1094                              <1>         ;
  1095                              <1> 	;-----	TEST SPECIAL CASE KEY 55
  1096                              <1> K41:					; NO-PAUSE
  1097 0000150A 3C37                <1> 	cmp	al, 55			; TEST FOR */PRTSC KEY
  1098 0000150C 7513                <1> 	jne	short K42		; NOT-KEY-55
  1099 0000150E F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  1100 00001511 7405                <1> 	jz	short K41A		; NO, CTL-PRTSC IS VALID	
  1101 00001513 F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  1102 00001516 7421                <1> 	jz	short K42B		; NO, TRANSLATE TO A FUNCTION
  1103                              <1> K41A:	
  1104 00001518 66B80072            <1> 	mov	ax, 114*256		; START/STOP PRINTING SWITCH
  1105 0000151C E9F3000000          <1>         jmp     K57                     ; BUFFER_FILL
  1106                              <1> 	;
  1107                              <1> 	;-----	SET UP TO TRANSLATE CONTROL SHIFT
  1108                              <1> K42:					; NOT-KEY-55
  1109 00001521 3C0F                <1> 	cmp	al, 15			; IS IT THE TAB KEY?
  1110 00001523 7414                <1> 	je	short K42B		; YES, XLATE TO FUNCTION CODE
  1111 00001525 3C35                <1> 	cmp	al, 53			; IS IT THE / KEY?
  1112 00001527 750E                <1> 	jne	short K42A		; NO, NO MORE SPECIAL CASES	
  1113 00001529 F6C702              <1> 	test	bh, LC_E0		; YES, IS IT FROM THE KEY PAD?
  1114 0000152C 7409                <1> 	jz	short K42A		; NO, JUST TRANSLATE
  1115 0000152E 66B80095            <1> 	mov	ax, 9500h		; YES, SPECIAL CODE FOR THIS ONE
  1116 00001532 E9DD000000          <1> 	jmp	K57			; BUFFER FILL	
  1117                              <1> K42A: 
  1118                              <1> 	;;mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  1119 00001537 3C3B                <1> 	cmp	al, 59			; IS IT IN CHARACTER TABLE?
  1120                              <1>         ;jb	short K45F              ; YES, GO TRANSLATE CHAR
  1121                              <1> 	;;jb	K56 ; 20/02/2015
  1122                              <1> 	;;jmp	K64 ; 20/02/2015
  1123                              <1> K42B:
  1124 00001539 BB[5C680000]        <1> 	mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  1125 0000153E 0F82AE000000        <1> 	jb	K56 ;; 20/02/2015	
  1126 00001544 E9B9000000          <1> 	jmp	K64	
  1127                              <1>         ;
  1128                              <1> 	;-----	NOT IN CONTROL SHIFT
  1129                              <1> K44:					; NOT-CTL-SHIFT
  1130 00001549 3C37                <1> 	cmp	al, 55			; PRINT SCREEN KEY?
  1131 0000154B 7528                <1> 	jne	short K45		; NOT PRINT SCREEN
  1132 0000154D F6C710              <1> 	test	bh, KBX			; IS THIS ENHANCED KEYBOARD?
  1133 00001550 7407                <1> 	jz	short K44A		; NO, TEST FOR SHIFT STATE	
  1134 00001552 F6C702              <1> 	test	bh, LC_E0		; YES, LAST CODE A MARKER?
  1135 00001555 7507                <1> 	jnz	short K44B		; YES, IS PRINT SCREEN
  1136 00001557 EB41                <1> 	jmp	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  1137                              <1> K44A:
  1138 00001559 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; NOT 101 KBD, SHIFT KEY DOWN?
  1139 0000155C 743C                <1> 	jz	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  1140                              <1> 	;
  1141                              <1> 	;-----	ISSUE INTERRUPT TO INDICATE PRINT SCREEN FUNCTION
  1142                              <1> K44B:
  1143 0000155E B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  1144 00001560 E81B010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  1145 00001565 B020                <1> 	mov	al, EOI			; END OF CURRENT INTERRUPT
  1146 00001567 E620                <1> 	out	20h, al ;out INTA00, al	; SO FURTHER THINGS CAN HAPPEN
  1147                              <1> 	; Print Screen !!!		; ISSUE PRINT SCREEN INTERRUPT (INT 05h)
  1148                              <1> 	;PUSH 	BP			; SAVE POINTER
  1149                              <1> 	;INT 	5H			; ISSUE PRINT SCREEN INTERRUPT
  1150                              <1> 	;POP	BP			; RESTORE POINTER
  1151 00001569 8025[68690000]FC    <1>         and     byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; ZERO OUT THESE FLAGS
  1152 00001570 E90CFEFFFF          <1>         jmp     K27                     ; GO BACK WITHOUT EOI OCCURRING
  1153                              <1> 	;
  1154                              <1> 	;-----	HANDLE IN-CORE KEYS
  1155                              <1> K45:					; NOT-PRINT-SCREEN
  1156 00001575 3C3A                <1> 	cmp	al, 58			; TEST FOR IN-CORE AREA
  1157 00001577 7734                <1> 	ja	short K46		; JUMP IF NOT
  1158 00001579 3C35                <1> 	cmp	al, 53			; IS THIS THE '/' KEY?
  1159 0000157B 7505                <1> 	jne	short K45A		; NO, JUMP
  1160 0000157D F6C702              <1> 	test	bh, LC_E0		; WAS THE LAST CODE THE MARKER?
  1161 00001580 7518                <1> 	jnz	short K45C		; YES, TRANSLATE TO CHARACTER
  1162                              <1> K45A:
  1163 00001582 B91A000000          <1> 	mov	ecx, 26			; LENGHT OF SEARCH
  1164 00001587 BF[32680000]        <1> 	mov	edi, K30+10		; POINT TO TABLE OF A-Z CHARS
  1165 0000158C F2AE                <1> 	repne	scasb			; IS THIS A LETTER KEY?
  1166                              <1> 		; 20/02/2015
  1167 0000158E 7505                <1> 	jne	short K45B              ; NO, SYMBOL KEY
  1168                              <1> 	;
  1169 00001590 F6C340              <1> 	test	bl, CAPS_STATE		; ARE WE IN CAPS_LOCK?
  1170 00001593 750C                <1> 	jnz	short K45D		; TEST FOR SURE
  1171                              <1> K45B:
  1172 00001595 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  1173 00001598 750C                <1> 	jnz	short K45E		; YES, UPPERCASE
  1174                              <1> 					; NO, LOWERCASE
  1175                              <1> K45C:
  1176 0000159A BB[B4680000]        <1> 	mov	ebx, K10		; TRANSLATE TO LOWERCASE LETTERS
  1177 0000159F EB51                <1> 	jmp	short K56	
  1178                              <1> K45D:					; ALMOST-CAPS-STATE
  1179 000015A1 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; CL ON. IS SHIFT ON, TOO?
  1180 000015A4 75F4                <1> 	jnz	short K45C		; SHIFTED TEMP OUT OF CAPS STATE
  1181                              <1> K45E:
  1182 000015A6 BB[0C690000]        <1> 	mov	ebx, K11		; TRANSLATE TO UPPER CASE LETTERS
  1183 000015AB EB45                <1> K45F:	jmp	short K56
  1184                              <1> 	;
  1185                              <1> 	;-----	TEST FOR KEYS F1 - F10
  1186                              <1> K46:					; NOT IN-CORE AREA
  1187 000015AD 3C44                <1> 	cmp	al, 68			; TEST FOR F1 - F10
  1188                              <1> 	;ja	short K47		; JUMP IF NOT
  1189                              <1> 	;jmp	short K53		; YES, GO DO FN KEY PROCESS			
  1190 000015AF 7635                <1> 	jna	short K53		
  1191                              <1> 	;
  1192                              <1> 	;-----	HANDLE THE NUMERIC PAD KEYS
  1193                              <1> K47:					; NOT F1 - F10
  1194 000015B1 3C53                <1> 	cmp	al, 83			; TEST NUMPAD KEYS
  1195 000015B3 772D                <1> 	ja	short K52		; JUMP IF NOT
  1196                              <1> 	;
  1197                              <1> 	;-----	KEYPAD KEYS, MUST TEST NUM LOCK FOR DETERMINATION
  1198                              <1> K48:
  1199 000015B5 3C4A                <1> 	cmp	al , 74			; SPECIAL CASE FOR MINUS
  1200 000015B7 74ED                <1> 	je	short K45E		; GO TRANSLATE
  1201 000015B9 3C4E                <1> 	cmp	al , 78			; SPECIAL CASE FOR PLUS
  1202 000015BB 74E9                <1> 	je	short K45E		; GO TRANSLATE
  1203 000015BD F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OFTHE NEW KEYS?
  1204 000015C0 750A                <1> 	jnz	short K49		; YES, TRANSLATE TO BASE STATE
  1205                              <1> 	;		
  1206 000015C2 F6C320              <1> 	test 	bl, NUM_STATE		; ARE WE IN NUM LOCK
  1207 000015C5 7514                <1> 	jnz	short K50		; TEST FOR SURE
  1208 000015C7 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  1209                              <1> 	;jnz	short K51		; IF SHIFTED, REALLY NUM STATE
  1210 000015CA 75DA                <1> 	jnz	short K45E
  1211                              <1> 	;
  1212                              <1> 	;-----	BASE CASE FOR KEYPAD
  1213                              <1> K49:					
  1214 000015CC 3C4C                <1> 	cmp	al, 76			; SPECIAL CASE FOR BASE STATE 5
  1215 000015CE 7504                <1> 	jne	short K49A		; CONTINUE IF NOT KEYPAD 5
  1216 000015D0 B0F0                <1> 	mov	al, 0F0h		; SPECIAL ASCII CODE	
  1217 000015D2 EB40                <1> 	jmp	short K57		; BUFFER FILL
  1218                              <1> K49A:
  1219 000015D4 BB[B4680000]        <1> 	mov	ebx, K10		; BASE CASE TABLE	
  1220 000015D9 EB27                <1> 	jmp	short K64		; CONVERT TO PSEUDO SCAN
  1221                              <1> 	;
  1222                              <1> 	;-----	MIGHT BE NUM LOCK, TEST SHIFT STATUS
  1223                              <1> K50:					; ALMOST-NUM-STATE
  1224 000015DB F6C303              <1>         test    bl, LEFT_SHIFT+RIGHT_SHIFT
  1225 000015DE 75EC                <1> 	jnz 	short K49		; SHIFTED TEMP OUT OF NUM STATE
  1226 000015E0 EBC4                <1> K51:	jmp	short K45E		; REALLY NUM STATE
  1227                              <1> 	;
  1228                              <1> 	;-----	TEST FOR THE NEW KEYS ON WT KEYBOARDS 
  1229                              <1> K52:					; NOT A NUMPAD KEY
  1230 000015E2 3C56                <1> 	cmp	al, 86			; IS IT THE NEW WT KEY?
  1231                              <1> 	;jne	short K53		; JUMP IF NOT
  1232                              <1> 	;jmp	short K45B		; HANDLE WITH REST OF LETTER KEYS
  1233 000015E4 74AF                <1> 	je	short K45B		
  1234                              <1> 	;
  1235                              <1> 	;-----	MUST BE F11 OR F12 
  1236                              <1> K53:					; F1 - F10 COME HERE, TOO
  1237 000015E6 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST SHIFT STATE
  1238 000015E9 74E1                <1> 	jz	short K49		; JUMP, LOWER CASE PSEUDO SC'S
  1239                              <1> 		; 20/02/2015 
  1240 000015EB BB[0C690000]        <1> 	mov	ebx, K11		; UPPER CASE PSEUDO SCAN CODES
  1241 000015F0 EB10                <1> 	jmp	short K64		; TRANSLATE SCAN
  1242                              <1> 	;
  1243                              <1> 	;-----	TRANSLATE THE CHARACTER
  1244                              <1> K56:					; TRANSLATE-CHAR
  1245 000015F2 FEC8                <1> 	dec	al			; CONVERT ORIGIN
  1246 000015F4 D7                  <1> 	xlat    			; CONVERT THE SCAN CODE TO ASCII
  1247 000015F5 F605[68690000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  1248 000015FC 7416                <1> 	jz	short K57		; NO, GO FILL BUFFER
  1249 000015FE B4E0                <1> 	mov	ah, MC_E0		; YES, PUT SPECIAL MARKER IN AH
  1250 00001600 EB12                <1> 	jmp	short K57		; PUT IT INTO THE BUFFER	
  1251                              <1> 	;
  1252                              <1> 	;-----	TRANSLATE SCAN FOR PSEUDO SCAN CODES
  1253                              <1> K64:					; TRANSLATE-SCAN-ORGD
  1254 00001602 FEC8                <1> 	dec	al			; CONVERT ORIGIN
  1255 00001604 D7                  <1>        	xlat    	                ; CTL TABLE SCAN
  1256 00001605 88C4                <1> 	mov	ah, al			; PUT VALUE INTO AH
  1257 00001607 B000                <1> 	mov	al, 0			; ZERO ASCII CODE
  1258 00001609 F605[68690000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  1259 00001610 7402                <1> 	jz	short K57		; NO, GO FILL BUFFER
  1260 00001612 B0E0                <1> 	mov	al, MC_E0		; YES, PUT SPECIAL MARKER IN AL
  1261                              <1> 	;
  1262                              <1> 	;-----	PUT CHARACTER INTO BUFFER
  1263                              <1> K57:					; BUFFER_FILL
  1264 00001614 3CFF                <1> 	cmp	al, -1			; IS THIS AN IGNORE CHAR
  1265                              <1>         ;je	short K59		; YES, DO NOTHING WITH IT
  1266 00001616 0F8459FDFFFF        <1> 	je      K26			; YES, DO NOTHING WITH IT
  1267 0000161C 80FCFF              <1> 	cmp	ah, -1			; LOOK FOR -1 PSEUDO SCAN
  1268                              <1>         ;jne	short K61		; NEAR_INTERRUPT_RETURN
  1269 0000161F 0F8450FDFFFF        <1> 	je      K26			; INTERRUPT_RETURN
  1270                              <1> ;K59:					; NEAR_INTERRUPT_RETURN
  1271                              <1> ;	jmp	K26			; INTERRUPT_RETURN
  1272                              <1> 
  1273                              <1> _K60: ; 29/01/2016
  1274 00001625 80FC68              <1> 	cmp	ah, 68h	; ALT + F1 key
  1275 00001628 721F                <1> 	jb	short K61
  1276 0000162A 80FC6F              <1> 	cmp	ah, 6Fh ; ALT + F8 key	
  1277 0000162D 771A                <1> 	ja	short K61
  1278                              <1> 	;
  1279 0000162F 8A1D[06640100]      <1> 	mov	bl, [ACTIVE_PAGE]
  1280 00001635 80C368              <1> 	add	bl, 68h
  1281 00001638 38E3                <1> 	cmp	bl, ah
  1282 0000163A 740D                <1> 	je	short K61
  1283 0000163C 6650                <1> 	push	ax
  1284 0000163E 88E0                <1> 	mov	al, ah
  1285 00001640 2C68                <1> 	sub	al, 68h
  1286 00001642 E868080000          <1> 	call	set_active_page
  1287 00001647 6658                <1> 	pop	ax
  1288                              <1> K61:					; NOT-CAPS-STATE
  1289 00001649 8B1D[76690000]      <1> 	mov	ebx, [BUFFER_TAIL] 	; GET THE END POINTER TO THE BUFFER
  1290 0000164F 89DE                <1> 	mov	esi, ebx		; SAVE THE VALUE
  1291 00001651 E857FAFFFF          <1> 	call	_K4			; ADVANCE THE TAIL
  1292 00001656 3B1D[72690000]      <1> 	cmp	ebx, [BUFFER_HEAD] 	; HAS THE BUFFER WRAPPED AROUND
  1293 0000165C 740E                <1> 	je	short K62		; BUFFER_FULL_BEEP
  1294 0000165E 668906              <1> 	mov	[esi], ax		; STORE THE VALUE
  1295 00001661 891D[76690000]      <1> 	mov	[BUFFER_TAIL], ebx 	; MOVE THE POINTER UP
  1296 00001667 E909FDFFFF          <1> 	jmp	K26
  1297                              <1> 	;;cli				; TURN OFF INTERRUPTS
  1298                              <1> 	;;mov	al, EOI			; END OF INTERRUPT COMMAND
  1299                              <1> 	;;out	INTA00, al		; SEND COMMAND TO INTERRUPT CONTROL PORT
  1300                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  1301                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
  1302                              <1> 	;MOV	AX, 9102H		; MOVE IN POST CODE & TYPE
  1303                              <1> 	;INT	15H			; PERFORM OTHER FUNCTION
  1304                              <1> 	;;and	byte [KB_FLAG_3],~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  1305                              <1> 	;JMP	K27A			; INTERRUPT_RETURN
  1306                              <1> 	;;jmp   K27                    
  1307                              <1> 	;
  1308                              <1> 	;-----	BUFFER IS FULL SOUND THE BEEPER
  1309                              <1> K62:
  1310 0000166C B020                <1> 	mov	al, EOI			; ENABLE INTERRUPT CONTROLLER CHIP
  1311 0000166E E620                <1> 	out	INTA00, al
  1312 00001670 66B9A602            <1> 	mov	cx, 678			; DIVISOR FOR 1760 HZ
  1313 00001674 B304                <1> 	mov	bl, 4			; SHORT BEEP COUNT (1/16 + 1/64 DELAY)
  1314 00001676 E8750C0000          <1> 	call	beep			; GO TO COMMON BEEP HANDLER
  1315 0000167B E901FDFFFF          <1> 	jmp     K27			; EXIT   
  1316                              <1> 
  1317                              <1> SHIP_IT:
  1318                              <1> 	;---------------------------------------------------------------------------------
  1319                              <1> 	; SHIP_IT
  1320                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  1321                              <1> 	;	TO THE KEYBOARD CONTROLLER.
  1322                              <1> 	;---------------------------------------------------------------------------------
  1323                              <1> 	;
  1324 00001680 6650                <1> 	push	ax			; SAVE DATA TO SEND
  1325                              <1> 
  1326                              <1> 	;-----	WAIT FOR COMMAND TO ACCEPTED
  1327 00001682 FA                  <1> 	cli				; DISABLE INTERRUPTS TILL DATA SENT
  1328                              <1> 	; xor	ecx, ecx		; CLEAR TIMEOUT COUNTER
  1329 00001683 B900000100          <1> 	mov	ecx, 10000h			
  1330                              <1> S10:
  1331 00001688 E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD CONTROLLER STATUS
  1332 0000168A A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ITS INPUT BUFFER BUSY
  1333 0000168C E0FA                <1> 	loopnz	S10			; WAIT FOR COMMAND TO BE ACCEPTED
  1334                              <1> 
  1335 0000168E 6658                <1> 	pop	ax			; GET DATA TO SEND
  1336 00001690 E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROLLER
  1337 00001692 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  1338 00001693 C3                  <1> 	retn				; RETURN TO CALLER
  1339                              <1> 
  1340                              <1> SND_DATA:
  1341                              <1> 	; ---------------------------------------------------------------------------------
  1342                              <1> 	; SND_DATA
  1343                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  1344                              <1> 	;	TO THE KEYBOARD AND RECEIPT OF ACKNOWLEDGEMENTS. IT ALSO
  1345                              <1> 	;	HANDLES ANY RETRIES IF REQUIRED
  1346                              <1> 	; ---------------------------------------------------------------------------------
  1347                              <1> 	;
  1348 00001694 6650                <1> 	push	ax			; SAVE REGISTERS
  1349 00001696 6653                <1> 	push	bx
  1350 00001698 51                  <1> 	push	ecx
  1351 00001699 88C7                <1> 	mov	bh, al			; SAVE TRANSMITTED BYTE FOR RETRIES
  1352 0000169B B303                <1> 	mov	bl, 3			; LOAD RETRY COUNT
  1353                              <1> SD0:
  1354 0000169D FA                  <1> 	cli				; DISABLE INTERRUPTS
  1355 0000169E 8025[67690000]CF    <1> 	and	byte [KB_FLAG_2], ~(KB_FE+KB_FA) ; CLEAR ACK AND RESEND FLAGS
  1356                              <1> 	;
  1357                              <1> 	;-----	WAIT FOR COMMAND TO BE ACCEPTED
  1358 000016A5 B900000100          <1> 	mov	ecx, 10000h		; MAXIMUM WAIT COUNT
  1359                              <1> SD5:
  1360 000016AA E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD PROCESSOR STATUS PORT
  1361 000016AC A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ANY PENDING COMMAND
  1362 000016AE E0FA                <1> 	loopnz	SD5			; WAIT FOR COMMAND TO BE ACCEPTED
  1363                              <1> 	;
  1364 000016B0 88F8                <1> 	mov	al, bh			; REESTABLISH BYTE TO TRANSMIT
  1365 000016B2 E660                <1> 	out	PORT_A, al		; SEND BYTE
  1366 000016B4 FB                  <1> 	sti				; ENABLE INTERRUPTS
  1367                              <1> 	;mov	cx, 01A00h		; LOAD COUNT FOR 10 ms+
  1368 000016B5 B9FFFF0000          <1> 	mov	ecx, 0FFFFh
  1369                              <1> SD1:
  1370 000016BA F605[67690000]30    <1> 	test	byte [KB_FLAG_2], KB_FE+KB_FA ; SEE IF EITHER BIT SET
  1371 000016C1 750F                <1> 	jnz	short SD3		; IF SET, SOMETHING RECEIVED GO PROCESS
  1372 000016C3 E2F5                <1> 	loop	SD1			; OTHERWISE WAIT
  1373                              <1> SD2:
  1374 000016C5 FECB                <1> 	dec	bl			; DECREMENT RETRY COUNT
  1375 000016C7 75D4                <1> 	jnz	short SD0		; RETRY TRANSMISSION
  1376 000016C9 800D[67690000]80    <1> 	or	byte [KB_FLAG_2], KB_ERR ; TURN ON TRANSMIT ERROR FLAG
  1377 000016D0 EB09                <1> 	jmp	short SD4		; RETRIES EXHAUSTED FORGET TRANSMISSION
  1378                              <1> SD3:
  1379 000016D2 F605[67690000]10    <1> 	test	byte [KB_FLAG_2], KB_FA ; SEE IF THIS IS AN ACKNOWLEDGE
  1380 000016D9 74EA                <1> 	jz	short SD2		; IF NOT, GO RESEND
  1381                              <1> SD4:	
  1382 000016DB 59                  <1> 	pop	ecx			; RESTORE REGISTERS
  1383 000016DC 665B                <1> 	pop	bx
  1384 000016DE 6658                <1> 	pop	ax
  1385 000016E0 C3                  <1> 	retn				; RETURN, GOOD TRANSMISSION
  1386                              <1> 
  1387                              <1> SND_LED:
  1388                              <1> 	; ---------------------------------------------------------------------------------
  1389                              <1> 	; SND_LED
  1390                              <1> 	;	THIS ROUTINES TURNS ON THE MODE INDICATORS.
  1391                              <1> 	;
  1392                              <1> 	;----------------------------------------------------------------------------------
  1393                              <1> 	;
  1394 000016E1 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1395 000016E2 F605[67690000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  1396 000016E9 755F                <1> 	jnz 	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  1397                              <1> 	;
  1398 000016EB 800D[67690000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  1399 000016F2 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  1400 000016F4 E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  1401 000016F6 EB11                <1> 	jmp	short SL0		; GO SEND MODE INDICATOR COMMAND
  1402                              <1> SND_LED1:
  1403 000016F8 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1404 000016F9 F605[67690000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  1405 00001700 7548                <1> 	jnz	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  1406                              <1> 	;
  1407 00001702 800D[67690000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  1408                              <1> SL0:
  1409 00001709 B0ED                <1> 	mov	al, LED_CMD		; LED CMD BYTE
  1410 0000170B E884FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  1411 00001710 FA                  <1> 	cli
  1412 00001711 E836000000          <1> 	call	MAKE_LED		; GO FORM INDICATOR DATA BYTE
  1413 00001716 8025[67690000]F8    <1> 	and	byte [KB_FLAG_2], 0F8h	; ~KB_LEDS ; CLEAR MODE INDICATOR BITS
  1414 0000171D 0805[67690000]      <1> 	or	[KB_FLAG_2], al 	; SAVE PRESENT INDICATORS FOR NEXT TIME
  1415 00001723 F605[67690000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  1416 0000172A 750F                <1> 	jnz	short SL2		; IF SO, BYPASS SECOND BYTE TRANSMISSION
  1417                              <1> 	;
  1418 0000172C E863FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  1419 00001731 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1420 00001732 F605[67690000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  1421 00001739 7408                <1> 	jz	short SL3		; IF NOT, DON'T SEND AN ENABLE COMMAND
  1422                              <1> SL2:
  1423 0000173B B0F4                <1> 	mov	al, KB_ENABLE		; GET KEYBOARD CSA ENABLE COMMAND
  1424 0000173D E852FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  1425 00001742 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1426                              <1> SL3:
  1427 00001743 8025[67690000]3F    <1> 	and	byte [KB_FLAG_2], ~(KB_PR_LED+KB_ERR) ; TURN OFF MODE INDICATOR
  1428                              <1> SL1:					; UPDATE AND TRANSMIT ERROR FLAG
  1429 0000174A FB                  <1> 	sti				; ENABLE INTERRUPTS
  1430 0000174B C3                  <1> 	retn				; RETURN TO CALLER
  1431                              <1> 
  1432                              <1> MAKE_LED:
  1433                              <1> 	;---------------------------------------------------------------------------------
  1434                              <1> 	; MAKE_LED
  1435                              <1> 	;	THIS ROUTINES FORMS THE DATA BYTE NECESSARY TO TURN ON/OFF
  1436                              <1> 	;	THE MODE INDICATORS.
  1437                              <1> 	;---------------------------------------------------------------------------------
  1438                              <1> 	;
  1439                              <1> 	;push 	cx			; SAVE CX
  1440 0000174C A0[65690000]        <1> 	mov	al, [KB_FLAG]		; GET CAPS & NUM LOCK INDICATORS
  1441 00001751 2470                <1> 	and	al, CAPS_STATE+NUM_STATE+SCROLL_STATE ; ISOLATE INDICATORS
  1442                              <1> 	;mov	cl, 4			; SHIFT COUNT
  1443                              <1> 	;rol	al, cl			; SHIFT BITS OVER TO TURN ON INDICATORS
  1444 00001753 C0C004              <1> 	rol	al, 4 ; 20/02/2015
  1445 00001756 2407                <1> 	and	al, 07h			; MAKE SURE ONLY MODE BITS ON
  1446                              <1> 	;pop	cx
  1447 00001758 C3                  <1> 	retn				; RETURN TO CALLER
  1448                              <1> 
  1449                              <1> ; % include 'kybdata.s'   ; KEYBOARD DATA
  1450                              <1> 
  1451                              <1> 
  1452                              <1> ; /// End Of KEYBOARD FUNCTIONS ///
  2606                                  
  2607                                  %include 'video.s' ; 07/03/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.3 - video.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 22/12/2020
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 16/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.15 (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 00001759 9C                  <1> 	pushfd
    35 0000175A 0E                  <1> 	push	cs
    36 0000175B E851000000          <1> 	call	VIDEO_IO_1
    37 00001760 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 00001761 [221A0000]          <1> M1:	dd	SET_MODE	; TABLE OF ROUTINES WITHIN VIDEO I/O
   191 00001765 [EF1D0000]          <1> 	dd	SET_CTYPE
   192 00001769 [231E0000]          <1> 	dd	SET_CPOS
   193 0000176D [4B1E0000]          <1> 	dd	READ_CURSOR
   194                              <1> 	;dd	VIDEO_RETURN	; READ_LPEN
   195 00001771 [201A0000]          <1> 	dd	set_mode_ncm	; Set mode without clearing video memory
   196 00001775 [911E0000]          <1> 	dd	ACT_DISP_PAGE
   197 00001779 [231F0000]          <1> 	dd	SCROLL_UP
   198 0000177D [4D200000]          <1> 	dd	SCROLL_DOWN
   199 00001781 [CD200000]          <1> 	dd	READ_AC_CURRENT
   200 00001785 [2A210000]          <1> 	dd	WRITE_AC_CURRENT
   201 00001789 [50210000]          <1> 	dd	WRITE_C_CURRENT
   202 0000178D [8B2A0000]          <1> 	dd	SET_COLOR
   203 00001791 [F62A0000]          <1> 	dd	WRITE_DOT
   204 00001795 [C12A0000]          <1> 	dd	READ_DOT
   205 00001799 [E0210000]          <1> 	dd	WRITE_TTY
   206 0000179D [081A0000]          <1> 	dd	VIDEO_STATE
   207 000017A1 [3F340000]          <1> 	dd	vga_pal_funcs	; 10/08/2016 (TRDOS 386)
   208 000017A5 [F72F0000]          <1> 	dd	font_setup	; 10/07/2016 (TRDOS 386)
   209 000017A9 [571A0000]          <1> 	dd	VIDEO_RETURN	; RESERVED
   210 000017AD [51230000]          <1> 	dd	WRITE_STRING	; 23/06/2016 (TRDOS 386)
   211                              <1> M1L	EQU	$ - M1
   212                              <1> 
   213                              <1> ; 06/12/2020
   214                              <1> ; 05/12/2020
   215                              <1> ; 03/12/2020
   216                              <1> ; 27/11/2020 - TRDOS 386 v2.0.3
   217                              <1> ; 14/01/2017
   218                              <1> ; 02/01/2017
   219                              <1> ; 04/07/2016
   220                              <1> ; 12/05/2016
   221                              <1> ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   222                              <1> int31h:  ; Video BIOS
   223                              <1> 
   224                              <1> ; BH = Video page number
   225                              <1> ; BL = Color/Attribute
   226                              <1> ; AH = Function number
   227                              <1> ; AL = Character
   228                              <1> 
   229                              <1> VIDEO_IO_1:
   230                              <1> 	;sti				; INTERRUPTS BACK ON
   231 000017B1 FC                  <1> 	cld				; SET DIRECTION FORWARD
   232                              <1> 	
   233                              <1> 	;cmp	ah, M1L/4		; TEST FOR WITHIN TABLE RANGE
   234                              <1> 	;jnb	short M4		; BRANCH TO EXIT IF NOT A VALID COMMAND
   235                              <1> 
   236                              <1> 	; 26/11/2020
   237 000017B2 80FC14              <1> 	cmp	ah, M1L/4
   238 000017B5 7205                <1> 	jb	short VGA_func
   239                              <1> 
   240 000017B7 80FC4F              <1> 	cmp	ah, 4Fh
   241 000017BA 7532                <1> 	jne	short M4 ; invalid !
   242                              <1> 
   243                              <1> VGA_func: ; 26/11/2020
   244 000017BC 06                  <1> 	push	es ; *
   245 000017BD 1E                  <1> 	push	ds ; **			; SAVE WORK AND PARAMETER REGISTERS
   246                              <1> 
   247                              <1> 	; 26/11/2020
   248 000017BE 50                  <1> 	push	eax ; -
   249                              <1> 	
   250 000017BF 66B81000            <1> 	mov	ax, KDATA 		; POINT DS: TO DATA SEGMENT
   251 000017C3 8ED8                <1> 	mov	ds, ax
   252 000017C5 8EC0                <1> 	mov	es, ax
   253                              <1> 
   254                              <1> 	; 26/11/2020
   255 000017C7 58                  <1> 	pop	eax ; +
   256                              <1> 	;
   257 000017C8 FB                  <1> 	sti
   258 000017C9 80FC4F              <1> 	cmp	ah, 4Fh
   259 000017CC 747A                <1> 	je	short VBE_func
   260                              <1> 
   261                              <1> 	; 04/12/2020
   262 000017CE A3[60700100]        <1> 	mov	[video_eax], eax
   263                              <1> 
   264                              <1> 	; 21/12/2020
   265 000017D3 803D[9A690000]FF    <1> 	cmp	byte [CRT_MODE], 0FFh	; Current mode is a VESA VBE mode ?
   266 000017DA 7213                <1> 	jb	short VGA_func_std
   267                              <1> 
   268 000017DC 08E4                <1> 	or	ah, ah			; set mode ?
   269 000017DE 750F                <1> 	jnz	short VGA_func_std	; no
   270                              <1> 
   271 000017E0 803D[44090000]03    <1> 	cmp	byte [vbe3], 3		; (real) VESA VBE 3 video bios ?
   272 000017E7 7506                <1> 	jne	short VGA_func_std	; no
   273                              <1> 
   274 000017E9 E981010000          <1> 	jmp	vesa_vbe3_pmi
   275                              <1> 
   276                              <1> 	; 21/12/2020
   277                              <1> M4:					; COMMAND NOT VALID
   278 000017EE CF                  <1> 	iretd				; DO NOTHING IF NOT IN VALID RANGE
   279                              <1> 
   280                              <1> VGA_func_std:
   281                              <1> 	; 06/12/2020
   282                              <1> 	; 03/12/2020
   283 000017EF 80FC0F              <1> 	cmp	ah, 0Fh
   284 000017F2 773D                <1> 	ja	short VGA_funcs_0	; only CGA funcs will be handled by	
   285                              <1> 	; 06/12/2020			; vga bios firmware
   286                              <1> 	; 03/12/2020			
   287                              <1> 	;test	ah, 7Fh ; set mode ?
   288                              <1> 	;;or	ah, ah			; only 'set mode' will be handled by
   289                              <1> 	;jnz	short VGA_funcs_0	; vga bios firmware	
   290                              <1> 	;jz	short vbe_pmi32_0
   291                              <1> 
   292                              <1> 	; 28/11/2020
   293 000017F4 803D[9C110300]00    <1> 	cmp	byte [pmi32], 0		; 32 bit protected mode interface for
   294 000017FB 7634                <1> 	jna	short VGA_funcs_0	; video hardware's vga bios firmware
   295                              <1> 					; ([pmi32] > 0 if it is activated)
   296                              <1> 					; note:
   297                              <1> 					; [vbe3] = 3 is required to activate
   298                              <1> 	; 07/12/2020
   299 000017FD 20E4                <1> 	and	ah, ah ; is this set mode ?
   300 000017FF 7413                <1> 	jz	short vbe_pmi32_2 ; yes
   301                              <1> 
   302 00001801 80FC04              <1> 	cmp	ah, 04h	 ; set mode ('no clear memory' option)
   303 00001804 742B                <1> 	je	short VGA_funcs_0
   304                              <1> 
   305                              <1> 	; 07/12/2020
   306 00001806 803D[9A690000]07    <1> 	cmp	byte [CRT_MODE], 7 ; current mode > 7 ?
   307 0000180D 7622                <1> 	jna	short VGA_funcs_0  ; no	
   308                              <1> 
   309                              <1> 	; when mode 3 is active, 
   310                              <1> 	; video bios functions are not redirected
   311                              <1> 	; to VESA VBE3 PMI except 'set mode' function
   312                              <1> 
   313                              <1> vbe_pmi32_0:
   314                              <1> 	; 06/12/2020
   315                              <1> 	;or	ah, ah
   316                              <1> 	;jnz	short vbe_pmi32_2
   317                              <1> 	; ah = 0 ; 'set mode'
   318                              <1> 	;cmp	al, 3 ; 80x25 text mode, 16 colors, default mode for MainProg
   319                              <1> 	;jne	short vbe_pmi32_1
   320                              <1> 	;cmp	byte [CRT_MODE], 3 ; If current video mode <> 3 and requested
   321                              <1> 	;			; video mode is 3, use internal 'set mode';
   322                              <1> 	;			; otherwise, use vesa vbe 3 bios's 'set mode'.
   323                              <1> 	;jne	short VGA_funcs_0
   324                              <1> vbe_pmi32_1:
   325 0000180F E95B010000          <1> 	jmp	vesa_vbe3_pmi
   326                              <1> ;vbe_pmi32_2:
   327                              <1> 	;cmp	ah, 04h ; set mode (no clear mem option)
   328                              <1> 	;jne	short vbe_pmi32_1
   329                              <1> 
   330                              <1> vbe_pmi32_2:
   331                              <1> 	; 07/12/2020
   332 00001814 803D[9A690000]07    <1> 	cmp	byte [CRT_MODE], 7 ; current mode > 7 ?
   333 0000181B 77F2                <1> 	ja	short vbe_pmi32_1  ; yes
   334                              <1> 
   335 0000181D 3C07                <1> 	cmp	al, 7	; requested mode > 7 ?
   336 0000181F 7610                <1> 	jna	short VGA_funcs_0  ; no (CGA)
   337                              <1> 
   338 00001821 3C13                <1> 	cmp	al, 13h
   339 00001823 76EA                <1> 	jna	short vbe_pmi32_1
   340                              <1> 
   341 00001825 A880                <1> 	test	al, 80h
   342 00001827 7408                <1> 	jz	short VGA_funcs_0  ; unknown or special
   343                              <1> 
   344 00001829 3C87                <1> 	cmp	al, 87h	; requested mode > 7 ? 
   345                              <1> 			; (with no clear mem ops)
   346 0000182B 7604                <1> 	jna	short VGA_funcs_0  ; no (CGA)
   347                              <1> 
   348 0000182D 3C93                <1> 	cmp	al, 93h
   349 0000182F 76DE                <1> 	jna	short vbe_pmi32_1
   350                              <1> 
   351                              <1> 	; > 13h video modes are unknown or special
   352                              <1>  	; they must be handled by kernel	
   353                              <1> 
   354                              <1> 	; CGA video modes will be handled by kernel		
   355                              <1> 
   356                              <1> VGA_funcs_0:
   357 00001831 52                  <1> 	push	edx ; ***
   358 00001832 51                  <1> 	push	ecx ; ****
   359 00001833 53                  <1> 	push	ebx ; *****
   360 00001834 56                  <1> 	push	esi ; ******
   361 00001835 57                  <1> 	push	edi ; *******
   362 00001836 55                  <1> 	push	ebp ; ********
   363                              <1> 
   364                              <1> 	;mov	[video_eax], eax ; 12/05/2016 
   365 00001837 BF00800B00          <1> 	mov	edi, 0B8000h		; GET offset FOR COLOR CARD
   366                              <1> 
   367                              <1> 	; 23/03/2016
   368 0000183C C0E402              <1> 	shl	ah, 2  ; dword		; TIMES 2 FOR WORD TABLE LOOKUP
   369 0000183F 0FB6F4              <1> 	movzx	esi, ah			; MOVE OFFSET INTO LOOK UP REGISTER (SI)
   370                              <1> 	;mov	ah, [CRT_MODE]		; MOVE CURRENT MODE INTO (AH) REGISTER
   371                              <1> 
   372                              <1> 	;;15/01/2017
   373                              <1> 	; 14/01/2017
   374                              <1> 	; 02/01/2017
   375                              <1> 	;;mov	byte [intflg], 31h  ; video interrupt
   376                              <1> 	;sti ; 26/11/2020
   377                              <1> 	;
   378                              <1> 
   379 00001842 FFA6[61170000]      <1> 	JMP	dword [esi+M1]		; GO TO SELECTED FUNCTION
   380                              <1> 
   381                              <1> VBE_func:
   382                              <1> 	; 26/11/2020
   383                              <1> 	;sti
   384 00001848 55                  <1> 	push	ebp ; *** ; 27/11/2020	
   385 00001849 56                  <1> 	push	esi ; **** 
   386                              <1> 	
   387                              <1> 	; Note:
   388                              <1> 	; ebx, ecx, edx, edi, ebp registers
   389                              <1> 	; must be saved by VBE functions and
   390                              <1> 	; eax register must be set
   391                              <1> 	; (according to VBE 3 standard)
   392                              <1> 	; before return from this interrupt
   393                              <1> 	; (every function must restore and set
   394                              <1> 	; registers except esp, esi, es, ds)
   395                              <1> 
   396 0000184A 803D[44090000]02    <1> 	cmp	byte [vbe3], 2
   397 00001851 773D                <1> 	ja	short VESA_VBE3_PMI_CALL ; VBE3 video bios ('PMID')
   398                              <1> 	;je	short VBE_func_0  ; Bochs/Qemu/VirtualBox emulator
   399 00001853 7262                <1> 	jb	short VBE_unknown ; invalid ([vbe3] = 0)
   400                              <1> 
   401                              <1> 	;jmp	VESA_VBE3_PMI_CALL
   402                              <1> 
   403                              <1> VBE_func_0:	
   404                              <1> 	; Bochs/Plex86 VGAbios VBE extension
   405                              <1> 	; (TRDOS 386 v2.0.3 can use VBE graphics modes on emulators)
   406                              <1> 	; BOCHS/QEMU/VIRTUALBOX
   407                              <1>  
   408 00001855 8A25[45090000]      <1> 	mov	ah, [vbe2bios]
   409 0000185B 80FCC0              <1> 	cmp	ah, 0C0h		
   410 0000185E 7257                <1> 	jb	short VBE_unknown 	
   411 00001860 80FCC5              <1> 	cmp	ah, 0C5h
   412 00001863 7752                <1> 	ja	short VBE_unknown
   413                              <1> 
   414                              <1> 	; TRDOS 386 is running on BOCHS or QEMU
   415 00001865 B44F                <1> 	mov	ah, 4Fh
   416                              <1> VBE_func_1:
   417 00001867 0FB6F0              <1> 	movzx	esi, al ; VESA VBE function number
   418 0000186A 66C1E602            <1> 	shl	si, 2 ; dword
   419 0000186E 6683FE10            <1> 	cmp	si, N1L
   420 00001872 7343                <1> 	jnb	short VBE_unknown
   421                              <1> 	;sti
   422                              <1> 	
   423 00001874 FF96[80180000]      <1> 	call	dword [esi+N1] ; call VBE function
   424                              <1> 		
   425                              <1> 	;jmp	short VBE_bios_return
   426                              <1> 
   427                              <1> VBE_bios_return:
   428 0000187A FA                  <1> 	cli
   429 0000187B 5E                  <1> 	pop	esi ; ****
   430 0000187C 5D                  <1> 	pop	ebp ; *** ; 27/11/2020
   431 0000187D 07                  <1> 	pop	es  ; **
   432 0000187E 1F                  <1> 	pop	ds  ; *
   433 0000187F CF                  <1> 	iretd
   434                              <1> 
   435                              <1> 	; 26/11/2020
   436                              <1> N1:
   437 00001880 [DB180000]          <1> 	dd	vbe_biosfn_return_ctrl_info
   438 00001884 [CB370000]          <1> 	dd	vbe_biosfn_return_mode_info
   439 00001888 [86380000]          <1> 	dd	vbe_biosfn_set_mode
   440 0000188C [56390000]          <1> 	dd	vbe_biosfn_return_current_mode
   441                              <1> 	;dd	vbe_biosfn_save_restore_state
   442                              <1> 	;dd	vbe_biosfn_display_window_ctrl
   443                              <1> 	;dd	vbe_biosfn_set_get_log_scanline
   444                              <1> 	;dd	vbe_biosfn_set_get_disp_start
   445                              <1> 	;dd	vbe_biosfn_set_get_dac_pal_frm
   446                              <1> 	;dd	vbe_biosfn_set_get_palette_data
   447                              <1> 	
   448                              <1> N1L	EQU	$ - N1
   449                              <1> 
   450                              <1> 
   451                              <1> VESA_VBE3_PMI_CALL: ; VESA VBE video bios (firmware) functions
   452                              <1> 		    ; by using VESA VBE3 Protected Mode Interface
   453                              <1> 	
   454                              <1> 	; 29/11/2020
   455                              <1> 	; 26/11/2020 - TRDOS 386 v2.0.3 video.s
   456                              <1> 
   457                              <1> 	; We are here because..
   458                              <1> 	; 'PMID' has been verified by TRDOS 386 v2.0.3 kernel.
   459                              <1> 	; (Otherwise bochs/plex86 compatible VBE functions and
   460                              <1> 	;  modes would be used on BOCHS/QEMU/VIRTUALBOX emulators
   461                              <1> 	;  or only standard/old VGA graphics modes would be used.)   	
   462                              <1> 
   463                              <1> 	; (TRDOS 386 v2.0.3 can use VESA VBE graphics modes if
   464                              <1> 	;  the video bios is full compatible with VBE3 standard) 
   465                              <1> 
   466                              <1> 	; 29/11/2020
   467                              <1> 
   468 00001890 0FB6F0              <1> 	movzx	esi, al ; VESA VBE 3 function number
   469 00001893 66C1E602            <1> 	shl	si, 2 ; dword
   470 00001897 6683FE10            <1> 	cmp	si, P1L
   471 0000189B 731A                <1> 	jnb	short VBE_unknown
   472                              <1> 	;sti
   473                              <1> 
   474 0000189D 57                  <1> 	push	edi ; *****
   475                              <1> 		
   476 0000189E FF96[A7180000]      <1> 	call	dword [esi+P1] ; call VBE 3 function
   477                              <1> 
   478 000018A4 5F                  <1> 	pop	edi ; *****
   479                              <1> 		
   480 000018A5 EBD3                <1> 	jmp	short VBE_bios_return
   481                              <1> 
   482                              <1> P1:
   483 000018A7 [BD180000]          <1> 	dd	vbe3_pmfn_return_ctrl_info
   484 000018AB [E1180000]          <1> 	dd	vbe3_pmfn_return_mode_info
   485 000018AF [1E190000]          <1> 	dd	vbe3_pmfn_set_mode
   486 000018B3 [19190000]          <1> 	dd	vbe3_pmfn_return_current_mode
   487                              <1> 	;dd	vbe3_pmfn_save_restore_state
   488                              <1> 	;dd	vbe3_pmfn_display_window_ctrl
   489                              <1> 	;dd	vbe3_pmfn_set_get_log_scanline
   490                              <1> 	;dd	vbe3_pmfn_set_get_disp_start
   491                              <1> 	;dd	vbe3_pmfn_set_get_dac_pal_frm
   492                              <1> 	;dd	vbe3_pmfn_set_get_palette_data
   493                              <1> 	;dd	vbe3_pmfn_return_pmi ; invalid for TRDOS 386 v2
   494                              <1> 	;dd	vbe3_pmfn_set_get_pixel_clock
   495                              <1> 	
   496                              <1> P1L	EQU	$ - P1
   497                              <1> 
   498                              <1> ;	; 29/11/2020
   499                              <1> ;	mov	edi, VBE3MODEINFOBLOCK >> 4 ; / 16
   500                              <1> ;	
   501                              <1> ;	cmp	al, 04h
   502                              <1> ;	jb	short vbe3_pm_f ; function: 4F00h to 4F03h
   503                              <1> ;	ja	short vbe3_pmi_f5B ; function: 4F05h to 4F0Bh
   504                              <1> ;
   505                              <1> ;	; check buffer length (must be <= 2048 bytes)
   506                              <1> ;
   507                              <1> ;	and	dl, dl ; 0
   508                              <1> ;	jz	short vbe3_pm_f 
   509                              <1> ;		       ; Return Save/Restore State buffer size
   510                              <1> ;
   511                              <1> ;	push	ebx  ; buffer address
   512                              <1> ;	push	edx  ; function: save (01h) or restore (02h)
   513                              <1> ;	call	
   514                              <1> ;
   515                              <1> ;vbe3_pm_f03:
   516                              <1> ;	cmp	al, 2
   517                              <1> ;	ja	short vbe3_pm_f ; function 4F03h
   518                              <1> ;	jb	short vbe3_pm_f1
   519                              <1> ;
   520                              <1> ;
   521                              <1> ;vbe3_pm_f1:
   522                              <1> ;	
   523                              <1> ;
   524                              <1> ;vbe3_pmi_f5B:
   525                              <1> ;	cmp	al, 09h
   526                              <1> ;	jna	short vbe3_pm_f ; funcs 05h to 09h are usable 
   527                              <1> ;	
   528                              <1> ;	cmp	al, 0Bh ; Get/Set pixel clock, last function
   529                              <1> ;	jne	short VBE_unknown 
   530                              <1> ;			; (do not use 'uncertain' functions
   531                              <1> ;			; because of system-user buff transfers) 	
   532                              <1> ;vbe3_pm_f:
   533                              <1> ;	mov	byte [vbe3_pm_fn], al	; set
   534                              <1> ;	; prepare 16 bit pm segments & registers for pmi call 
   535                              <1> ;	call	VESA_VBE3_PM_FUNCTION
   536                              <1> ;
   537                              <1> ;
   538                              <1> 
   539                              <1> 	; 26/11/2020
   540                              <1> VBE_unknown:
   541 000018B7 66B80001            <1> 	mov	ax, 0100h  ; ah = 1 : Function call failed	
   542                              <1> 			   ; al = 0 : Function is not supported	
   543                              <1> 	
   544 000018BB EBBD                <1> 	jmp	short VBE_bios_return
   545                              <1> 
   546                              <1> vbe3_pmfn_return_ctrl_info:
   547                              <1> 	; 12/12/2020
   548                              <1> 	;
   549                              <1> 	; VBE function 4F00h - Return VBE Controller Information
   550                              <1> 	;
   551                              <1> 	; Input:
   552                              <1> 	;      EDI = Pointer to buffer in which to place
   553                              <1> 	;	     VbeInfoBlock structure
   554                              <1> 	;
   555                              <1> 	;	AX = 4F00h
   556                              <1> 	; Output:
   557                              <1> 	;	AX = VBE return status
   558                              <1> 	;	     AX = 004Fh -> succeeded
   559                              <1> 	;	     AX <> 004Fh -> failed   
   560                              <1> 	; 
   561                              <1> 	; Modified registers: eax (+ edi for kernel's own call)
   562                              <1> 
   563                              <1> 	; NOTE: TRDOS 386 v2 (v2.0.3) kernel calls this function
   564                              <1> 	; during startup while cpu is in real mode
   565                              <1> 	; (by using int 10h, 4F02h) and saves VbeInfoBlock at
   566                              <1> 	; VBE3INFOBLOCK address (97E00h for TRDOS 386 v2.0.3).
   567                              <1> 	;	
   568                              <1> 	; So...
   569                              <1> 	; This VBE function is adjusted to return/move same info	
   570                              <1> 	; from VBE3INFOBLOCK to user's buffer in EDI.
   571                              <1> 
   572                              <1> 	; int 31h (int 10h) entrance
   573                              <1> 
   574 000018BD 21FF                <1> 	and	edi, edi
   575 000018BF 7424                <1> 	jz	short vbe3_func_fail ; invalid buffer address !
   576                              <1> 
   577                              <1> ;_vbe3_pmfn_return_ctrl_info:		
   578                              <1> 	;or	edi, edi
   579                              <1> 	;jnz	short _vbe_biosfn_return_ctrl_info
   580                              <1> 	;
   581                              <1> 	;; this option may not be necessary - 12/12/2020
   582                              <1> 	;
   583                              <1> 	;; edi = 0, kernel forces to get ctrl info again
   584                              <1> 	;;	   by using VESA VBE3 video bios's pmi
   585                              <1> 	;
   586                              <1> 	;;push	edi
   587                              <1> 	;; far call to VESA VBE3 PMI 
   588                              <1> 	;;mov	ax, 4F00h ; Return VBE Controller Info
   589                              <1> 	;mov	edi, VBE3INFOBLOCK-VBE3SAVERESTOREBLOCK
   590                              <1> 	;; ES selector base address = VBE3SAVERESTOREBLOCK 
   591                              <1> 	;call	int10h_32bit_pmi
   592                              <1> 	;;pop	edi
   593                              <1> 	;mov	edi, VBE3INFOBLOCK ; retn to the kernel sub
   594                              <1> 	;cmp	ax, 004Fh
   595                              <1> 	;je	short vbe_ctrl_info_retn
   596                              <1> 	;stc	
   597                              <1> 	;retn
   598                              <1> 
   599                              <1> _vbe_biosfn_return_ctrl_info:
   600 000018C1 57                  <1> 	push	edi
   601 000018C2 51                  <1> 	push	ecx
   602 000018C3 BE007E0900          <1> 	mov	esi, VBE3INFOBLOCK
   603 000018C8 B900020000          <1> 	mov	ecx, 512
   604 000018CD E8BFD90000          <1> 	call	transfer_to_user_buffer
   605 000018D2 59                  <1> 	pop	ecx
   606 000018D3 5F                  <1> 	pop	edi
   607 000018D4 720F                <1> 	jc	short vbe3_func_fail
   608                              <1> 
   609 000018D6 31C0                <1> 	xor	eax, eax
   610 000018D8 B04F                <1> 	mov	al, 4Fh ; successful
   611                              <1> ;vbe_ctrl_info_retn:
   612 000018DA C3                  <1> 	retn
   613                              <1> 
   614                              <1> vbe_biosfn_return_ctrl_info:
   615                              <1> 	; 12/12/2020
   616                              <1> 	;
   617                              <1> 	; VBE function 4F00h - Return VBE Controller Information
   618                              <1> 	;
   619                              <1> 	; Input:
   620                              <1> 	;      EDI = Pointer to buffer in which to place
   621                              <1> 	;	     VbeInfoBlock structure
   622                              <1> 	;
   623                              <1> 	;	AX = 4F00h
   624                              <1> 	; Output:
   625                              <1> 	;	AX = VBE return status
   626                              <1> 	;	     AX = 004Fh -> succeeded
   627                              <1> 	;	     AX <> 004Fh -> failed   
   628                              <1> 	; 
   629                              <1> 	; Modified registers: eax
   630                              <1> 
   631 000018DB 21FF                <1> 	and	edi, edi
   632 000018DD 7406                <1> 	jz	short vbe3_func_fail ; invalid buffer addr !
   633 000018DF EBE0                <1> 	jmp	short _vbe_biosfn_return_ctrl_info 
   634                              <1> 
   635                              <1> vbe3_pmfn_return_mode_info:
   636                              <1> 	; 21/12/2020
   637                              <1> 	; 12/12/2020
   638                              <1> 	;
   639                              <1> 	; VBE function 4F01h - Return VBE Mode Information
   640                              <1> 	;
   641                              <1> 	; Input:
   642                              <1> 	;	CX = Mode number (VESA VBE mode number)
   643                              <1> 	;      EDI = Pointer to ModeInfoBlock structure
   644                              <1> 	;	     (256 bytes) -User's buffer address-
   645                              <1> 	;      EDI = 0 -> kernel call
   646                              <1> 	;		  (do not transfer ModeInfoBlock
   647                              <1> 	;		  to user's buffer address)
   648                              <1> 	;	AX = 4F01h	
   649                              <1> 	; Output:
   650                              <1> 	;	AX = VBE return status
   651                              <1> 	;	     AX = 004Fh -> succeeded
   652                              <1> 	;	     AX <> 004Fh -> failed   
   653                              <1> 	; 
   654                              <1> 	; Modified registers: eax, esi, edi
   655                              <1> 
   656                              <1> 	; int 31h (int 10h) entrance
   657                              <1> 	
   658 000018E1 09FF                <1> 	or	edi, edi
   659 000018E3 7506                <1> 	jnz	short _vbe3_pmfn_return_mode_info
   660                              <1> 
   661                              <1> vbe3_func_fail:
   662 000018E5 B84F010000          <1> 	mov	eax, 014Fh ; ah = 1 : Function call failed	
   663                              <1> 			   ; al = 4Fh : Function is supported
   664 000018EA C3                  <1> 	retn
   665                              <1> 	
   666                              <1> 	; jump from '_vbe_biosfn_return_mode_info' 
   667                              <1> _vbe3_pmfn_return_mode_info:
   668 000018EB 57                  <1> 	push	edi
   669                              <1> 
   670                              <1> 	;; clear vbe3 'mode info block' buffer
   671                              <1> 	;push	ecx
   672                              <1> 	;xor	eax, eax
   673                              <1> 	;mov	ecx, 256/4
   674                              <1> 	;mov	edi, VBE3MODEINFOBLOCK
   675                              <1> 	;rep	stosd
   676                              <1> 	;pop	ecx
   677                              <1> 
   678                              <1> 	; far call to VESA VBE3 PMI 
   679                              <1> 	;mov	ax, 4F01h ; Return VBE Mode Information
   680 000018EC BF00060000          <1> 	mov	edi, VBE3MODEINFOBLOCK-VBE3SAVERESTOREBLOCK
   681                              <1> 	; ES selector base address = VBE3SAVERESTOREBLOCK 
   682 000018F1 E8FC000000          <1> 	call	int10h_32bit_pmi
   683                              <1> 
   684 000018F6 5F                  <1> 	pop	edi
   685                              <1> 
   686                              <1> 	;cmp	ax, 004Fh
   687                              <1> 	;jne	short vbe3_func_retn  ; failed !
   688                              <1> 
   689 000018F7 21FF                <1> 	and	edi, edi
   690                              <1> 	;jz	short vbe3_func_success
   691                              <1> 	; 21/12/2020
   692 000018F9 741D                <1> 	jz	short vbe3_func_retn
   693                              <1> 
   694 000018FB 6683F84F            <1> 	cmp	ax, 004Fh
   695 000018FF 7517                <1> 	jne	short vbe3_func_retn  ; failed !
   696                              <1> 
   697 00001901 51                  <1> 	push	ecx
   698 00001902 BE007C0900          <1> 	mov	esi, VBE3MODEINFOBLOCK		
   699 00001907 B900010000          <1> 	mov	ecx, 256
   700 0000190C E880D90000          <1> 	call	transfer_to_user_buffer
   701 00001911 59                  <1> 	pop	ecx
   702 00001912 72D1                <1> 	jc	short vbe3_func_fail
   703                              <1> 
   704 00001914 31C0                <1> 	xor	eax, eax
   705 00001916 B04F                <1> 	mov	al, 4Fh ; successful
   706                              <1> vbe3_func_success:
   707                              <1> vbe3_func_retn:	
   708 00001918 C3                  <1> 	retn
   709                              <1> 
   710                              <1> vbe3_pmfn_return_current_mode:
   711                              <1> 	; 12/12/2020
   712                              <1> 	;
   713                              <1> 	; VBE function 4F03h - Return Current VBE Mode
   714                              <1> 	;
   715                              <1> 	; Input:
   716                              <1> 	;	none (AX = 4F03h)
   717                              <1> 	; Output:
   718                              <1> 	;	AX = VBE return status
   719                              <1> 	;	     AX = 004Fh -> succeeded
   720                              <1> 	;	     AX <> 004Fh -> failed
   721                              <1> 	;	BX = Current VBE mode
   722                              <1> 	;	  bit 0-13 = Mode number
   723                              <1> 	;	  bit 14 = 0 Windowed frame buffer model
   724                              <1> 	;	         = 1 Linear frame buffer model
   725                              <1> 	;	  bit 15 
   726                              <1> 	;	      = 0 Memory cleared at last mode set
   727                              <1> 	;	      = 1 Memory not cleared at last mode set
   728                              <1> 	; 
   729                              <1> 	; Modified registers: eax, ebx
   730                              <1> 
   731                              <1> 	; int 31h (int 10h) entrance
   732                              <1> 	
   733                              <1> 	; far call to VESA VBE3 PMI 
   734                              <1> 
   735                              <1> 	;mov	eax, 4F03h ; Return Current VBE Mode
   736                              <1> vbe3_pmfn_far_call:
   737                              <1> 	; ES selector base address = VBE3SAVERESTOREBLOCK 
   738                              <1> 	;call	int10h_32bit_pmi
   739                              <1> 	;retn
   740 00001919 E9D4000000          <1> 	jmp	int10h_32bit_pmi
   741                              <1> 
   742                              <1> vbe3_pmfn_set_mode:
   743                              <1> 	; 22/12/2020
   744                              <1> 	; 21/12/2020
   745                              <1> 	; 12/12/2020
   746                              <1> 	;
   747                              <1> 	; VBE function 4F02h - Set VBE Mode
   748                              <1> 	;
   749                              <1> 	; Input:
   750                              <1> 	;	BX = Desired Mode to set
   751                              <1> 	;	  bit 0-13 = Mode number
   752                              <1> 	;	  bit 14 = 0 Windowed frame buffer model
   753                              <1> 	;	         = 1 Linear frame buffer model
   754                              <1> 	;	  bit 15 
   755                              <1> 	;	      = 0 Memory cleared at last mode set
   756                              <1> 	;	      = 1 Memory not cleared at last mode set
   757                              <1> 	; Output:
   758                              <1> 	;	AX = VBE return status
   759                              <1> 	;	     AX = 004Fh -> succeeded
   760                              <1> 	;	     AX <> 004Fh -> failed
   761                              <1> 	; 
   762                              <1> 	; Modified registers: eax, ebx, esi (21/12/2020)
   763                              <1> 
   764                              <1> 	; int 31h (int 10h) entrance
   765                              <1> 
   766                              <1> 	; 22/12/2020 (VESA VBE3 feature)
   767                              <1> 	; BX bit 11 is flag for
   768                              <1> 	;	user specified CRTC values for refresh rate
   769                              <1> 	; 'test bh, 8'
   770                              <1> 	; if bit 11 is set, EDI points to 'CRTCInfoBlock'
   771                              <1> 
   772                              <1> 	; 22/12/2020
   773                              <1> 	;; test bx for VBE video mode
   774                              <1> 	;test	bh, 1
   775                              <1> 	;jnz	short vbe3_sm_0
   776                              <1> 
   777                              <1> 	;; use internal VBE mode set procedure
   778                              <1> 	;; for non-vbe (std VGA/CGA) modes
   779                              <1> 	;
   780                              <1> 	;; (it is useful -as 4F02h function- 
   781                              <1> 	;;  to jump 'vbe_biosfn_set_mode'
   782                              <1> 	;;  instead of direct jump to '_set_mode')
   783                              <1> 	;; ((eliminates additional push-pops and settings))  
   784                              <1>  
   785                              <1> 	;jmp	vbe_biosfn_set_mode	
   786                              <1> 
   787                              <1> vbe3_sm_0: 
   788                              <1> 	;;push	ds  ; *
   789                              <1> 	;;push	es  ; **
   790                              <1> 	;;push	ebp ; ***
   791                              <1> 	;;push	esi ; **** 
   792                              <1> 	
   793                              <1> 	; Fit bx to VESA VBE2 type mode setting
   794                              <1> 	; (bx bit 11 is used for custom CRTC values in VBE3)
   795                              <1> 	; clear bit 9 to 11 (clear bh bit 1 to bit 3)
   796                              <1> 
   797                              <1> 	; 22/12/2020
   798 0000191E 57                  <1> 	push	edi ; *****
   799 0000191F F6C708              <1> 	test	bh, 8	; Use user specified CRTC values
   800 00001922 7530                <1> 	jnz	short vbe3_sm_3  ; for refresh rate
   801                              <1> vbe3_sm_4:
   802 00001924 80E7C1              <1> 	and	bh, 0C1h ; use bit 15, 14, 8 only (for bh)
   803                              <1> 	;mov	[vbe_mode_x], bh
   804                              <1> 
   805 00001927 803D[9A690000]03    <1> 	cmp	byte [CRT_MODE], 3 ; is current mode 03h ?
   806 0000192E 7509                <1> 	jne	short vbe3_sm_1    ; no
   807                              <1> 
   808                              <1> 	; save mode 03h video pages and cursor positions
   809 00001930 57                  <1> 	push	edi ; **!***	
   810 00001931 51                  <1> 	push	ecx ; ******
   811                              <1> 	;push	esi
   812                              <1> 	
   813 00001932 E8E6030000          <1> 	call	save_mode3_multiscreen
   814                              <1> 	
   815                              <1> 	;pop	esi
   816 00001937 59                  <1> 	pop	ecx ; ******
   817 00001938 5F                  <1> 	pop	edi ; **!***		
   818                              <1> vbe3_sm_1:
   819                              <1> 	; ax = 4F02h
   820                              <1> 	; bx = video mode number (vbe2 type)	
   821 00001939 E8B4000000          <1> 	call	int10h_32bit_pmi 
   822                              <1> 			; call to far call to VBE3 PMI
   823                              <1> 
   824 0000193E 6683F84F            <1> 	cmp	ax, 004Fh ; succeeded ?
   825 00001942 750E                <1> 	jne	short vbe3_sm_2
   826                              <1> 	; set current mode byte/sign to extended (SVGA) mode
   827 00001944 C605[9A690000]FF    <1> 	mov	byte [CRT_MODE], 0FFh ; VESA VBE mode
   828                              <1> 	; set current VBE mode word to bx input
   829 0000194B 66891D[9E110300]    <1> 	mov	[video_mode], bx
   830                              <1> vbe3_sm_2:
   831                              <1> 	; 22/12/2020
   832 00001952 5F                  <1> 	pop	edi ; ***** 
   833 00001953 C3                  <1> 	retn
   834                              <1> 
   835                              <1> vbe3_sm_3:
   836                              <1> 	; 22/12/2020
   837                              <1> 	; copy user's CRTCInfoBlock to the buffer
   838 00001954 51                  <1> 	push	ecx
   839 00001955 89FE                <1> 	mov	esi, edi
   840 00001957 BF007D0900          <1> 	mov	edi, VBE3CRTCINFOBLOCK
   841 0000195C B940000000          <1> 	mov	ecx, 64
   842 00001961 E875D90000          <1> 	call	transfer_from_user_buffer
   843 00001966 59                  <1> 	pop	ecx
   844                              <1> 	; set offset (es base addr is VBE3SAVERESTOREBLOCK) 
   845 00001967 81EF00760900        <1> 	sub	edi, VBE3SAVERESTOREBLOCK
   846 0000196D EBB5                <1> 	jmp	short vbe3_sm_4
   847                              <1> 	
   848                              <1> vesa_vbe3_pmi:
   849                              <1> 	; 12/12/2020
   850                              <1> 	; 08/12/2020
   851                              <1> 	; 07/12/2020
   852                              <1> 	; 05/12/2020, 06/12/2020
   853                              <1> 	; 03/12/2020, 04/12/2020
   854                              <1> 	; 28/11/2020 (TRDOS 386 v2.0.3)
   855                              <1> 	; VGA BIOS functions via
   856                              <1> 	; VESA VBE3 Protected Mode Inface
   857                              <1> 	; [vbe3] = 3 and [pmi32] > 0
   858                              <1> 
   859                              <1> 	; 04/12/2020
   860                              <1> 	; Only 'set mode' will be redirected to vbe3 video bios
   861                              <1> 	; (by setting mode 3 multiscreen paraters before and after) 
   862                              <1> 
   863                              <1> 	; 06/12/2020
   864 0000196F 20E4                <1> 	and	ah, ah	; 0 = set mode function
   865 00001971 7402                <1> 	jz	short vbe3_pmi_0
   866 00001973 EB76                <1> 	jmp	vbe3_pmi_9 
   867                              <1> 
   868                              <1> vbe3_pmi_0:
   869                              <1> 	; 07/12/2020
   870 00001975 88C4                <1> 	mov	ah, al
   871 00001977 80E480              <1> 	and	ah, 80h ; 0 or 80h
   872 0000197A 30E0                <1> 	xor	al, ah ; 8?h -> 0?h
   873                              <1> 
   874                              <1> 	;cmp	al, 13h ; mode number above 13h is returned
   875                              <1> 	;jna	short vbe3_pmi_1
   876                              <1> 	;		; back to default code due to uncertainty
   877                              <1> 	; 		; (>13h is not std for all svga bioses)
   878                              <1> 	;jmp	VGA_funcs_0
   879                              <1> vbe3_pmi_1:
   880                              <1> 	; 07/12/2020
   881                              <1> 	; Possible cases for VBE3 (PMI, ah=0) set mode:
   882                              <1> 	; current mode > 07h and requested mode: any 
   883                              <1> 	; current mode <= 07h and requested mode > 07h
   884                              <1> 
   885                              <1> 	; 06/12/2020
   886 0000197C 8825[6F700100]      <1> 	mov	byte [noclearmem], ah ; 0 or 80h
   887                              <1> 	; check current video mode if it is 03h
   888 00001982 803D[9A690000]03    <1> 	cmp	byte [CRT_MODE], 3 ; current mode
   889 00001989 750B                <1> 	jne	short vbe3_pmi_3
   890                              <1> 	; 07/12/2020
   891                              <1> 	; check new video mode if it is 03h also
   892                              <1> 	;cmp	al, 3
   893                              <1> 	;jne	short vbe3_pmi_2
   894                              <1> 	;mov	byte [p_crt_mode], 80h 	; clear video memory
   895                              <1> 	;jmp	short vbe3_pmi_5
   896                              <1> vbe3_pmi_2:
   897                              <1> 	; case 1:
   898                              <1> 	; Current mode is 03h and new mode is not 03h
   899                              <1> 
   900                              <1> 	; save video pages and cursor positions
   901 0000198B 56                  <1> 	push	esi
   902 0000198C 57                  <1> 	push	edi
   903 0000198D 51                  <1> 	push	ecx
   904                              <1> 
   905                              <1> 	; 12/12/2020
   906                              <1> 	;mov	esi, 0B8000h ; mode 3 video memory
   907                              <1> 	;mov	edi, 98000h  ; backup location
   908                              <1> 	;mov	ecx, (0B8000h-0B0000h)/4
   909                              <1> 	;rep	movsd
   910                              <1> 	;
   911                              <1> 	;mov	byte [p_crt_mode], 3 ; previous mode, backup sign
   912                              <1> 	;xchg	cl, [ACTIVE_PAGE]
   913                              <1> 	;mov	[p_crt_page], cl  ; save as previous active page	
   914                              <1> 	;
   915                              <1> 	;; save cursor positions
   916                              <1> 	;mov	esi, CURSOR_POSN
   917                              <1> 	;mov	edi, cursor_pposn ; cursor positions backup
   918                              <1> 	;mov	cl, 4
   919                              <1> 	;rep	movsd
   920                              <1> 
   921                              <1> 	; 12/12/2020
   922 0000198E E88A030000          <1> 	call	save_mode3_multiscreen
   923                              <1> 
   924 00001993 59                  <1> 	pop	ecx
   925 00001994 5F                  <1> 	pop	edi
   926 00001995 5E                  <1> 	pop	esi
   927                              <1> vbe3_pmi_3:
   928                              <1> 	; 08/12/2020
   929                              <1> 	; 07/12/2020
   930                              <1> 	; case 3 or case 4
   931 00001996 A2[9A690000]        <1> 	mov	[CRT_MODE], al
   932 0000199B 3C03                <1> 	cmp	al, 3
   933 0000199D 7407                <1> 	je	short vbe3_pmi_4
   934                              <1> 	; case 4:
   935                              <1> 	; Current mode is not 03h and also new mode is not 03h
   936 0000199F 800D[6D700100]80    <1> 	or	byte [p_crt_mode], 80h  ; 83h (case 1 -> case 4)
   937                              <1> 	;jmp	short vbe3_pmi_5
   938                              <1> vbe3_pmi_4:
   939                              <1> 	; case 3:
   940                              <1> 	;
   941                              <1> 	; Current mode is not 03h and new mode is 03h
   942                              <1> 
   943                              <1> ;vbe3_pmi_5:
   944                              <1> 	;mov	[CRT_MODE], al
   945                              <1> 
   946 000019A6 E847000000          <1> 	call	int10h_32bit_pmi	
   947                              <1> 
   948 000019AB 803D[9A690000]03    <1> 	cmp	byte [CRT_MODE], 3  ; new video mode
   949                              <1> 	;jne	vbe3_pmi_8	; video mode <> 03h
   950 000019B2 7532                <1> 	jne	short vbe3_pmi_8	
   951                              <1> 
   952                              <1> 	;push	eax ; 04/12/2020
   953 000019B4 53                  <1> 	push	ebx
   954 000019B5 51                  <1> 	push	ecx
   955 000019B6 52                  <1> 	push	edx
   956 000019B7 57                  <1> 	push	edi ; 03/12/2020
   957                              <1> 
   958                              <1> 	; 12/12/2020
   959 000019B8 56                  <1> 	push	esi
   960 000019B9 E892030000          <1> 	call	restore_mode3_multiscreen
   961 000019BE 5E                  <1> 	pop	esi
   962                              <1> 	; AL = active video page
   963                              <1> 
   964                              <1> 	; 12/12/2020
   965                              <1> 	;mov	al, [p_crt_page] ; previous mode 3 active page
   966                              <1> 	;
   967                              <1> 	;;test	byte [p_crt_mode], 7Fh ; 83h or 80h or 03h
   968                              <1> 	;;jz	short vbe3_pmi_6 ; do not restore video pages
   969                              <1> 	;			 ; clear current video page
   970                              <1> 	;; case 3
   971                              <1> 	;
   972                              <1> 	;; ([p_crt_mode] = 03h)
   973                              <1> 	;
   974                              <1> 	;; New video mode is 3 while current video mode is not 3
   975                              <1> 	;; (multi screen) video pages will be restored from 098000h
   976                              <1> 	;
   977                              <1> 	;; restore video pages and cursor positions
   978                              <1> 	;
   979                              <1> 	;mov	[ACTIVE_PAGE], al ; current mode 3 active page
   980                              <1> 	;
   981                              <1> 	;push	esi
   982                              <1> 	;
   983                              <1> 	;; restore video pages
   984                              <1> 	;mov	esi, 98000h
   985                              <1> 	;mov	edi, 0B8000h
   986                              <1> 	;;mov	ecx, 2000h
   987                              <1> 	;mov	cx, 2000h ; 8K dwords (32K)
   988                              <1> 	;rep	movsd
   989                              <1> 	;
   990                              <1> 	;mov	[p_crt_mode], cl ; reset ('case 3' end condition)
   991                              <1> 	;
   992                              <1> 	;; restore cursor positions
   993                              <1> 	;mov	esi, cursor_pposn
   994                              <1> 	;mov	edi, CURSOR_POSN
   995                              <1> 	;;mov	ecx, 4	; restore all cursor positions (16 bytes)
   996                              <1> 	;mov	cl, 4
   997                              <1> 	;rep 	movsd
   998                              <1> 	;
   999                              <1> 	;pop	esi
  1000                              <1> 	;
  1001                              <1> 	;; 07/12/2020
  1002                              <1> 	;; restore CRT_START according to ACTIVE_PAGE
  1003                              <1> 	;mov	[CRT_START], cx ; 0
  1004                              <1> 	;
  1005                              <1> 	;; check active page and set it again if it is not 0
  1006                              <1> 	;or	al, al
  1007                              <1> 	;jz	short vbe3_pmi_7
  1008                              <1> 	;
  1009                              <1> 	;mov	cl, al
  1010                              <1> ;vbe3_pmi_5:
  1011                              <1> 	;add	word [CRT_START], 4096
  1012                              <1> 	;dec	cl
  1013                              <1> 	;jnz	short vbe3_pmi_5
  1014                              <1> 
  1015 000019BF B405                <1> 	mov	ah, 05h ; set current video page
  1016                              <1> 	;al = video page
  1017 000019C1 E82C000000          <1> 	call	int10h_32bit_pmi
  1018                              <1> 	
  1019                              <1> 	; check current cursor position & set it again if not 0,0
  1020                              <1> 	;movzx	ebx, byte [ACTIVE_PAGE]
  1021 000019C6 0FB6D8              <1> 	movzx	ebx, al
  1022 000019C9 D0E3                <1> 	shl	bl, 1
  1023 000019CB 81C3[F6630100]      <1> 	add	ebx, CURSOR_POSN
  1024 000019D1 668B13              <1> 	mov	dx, [ebx]
  1025 000019D4 6621D2              <1> 	and	dx, dx		
  1026 000019D7 7409                <1> 	jz	short vbe3_pmi_7
  1027                              <1> 	
  1028                              <1> 	;dx = cursor position (dl = column, dh = row)
  1029                              <1> 	;mov	bh, [ACTIVE_PAGE] ; 06/12/2020
  1030 000019D9 88C7                <1> 	mov	bh, al
  1031 000019DB B402                <1> 	mov	ah, 02h ; set cursor position
  1032 000019DD E810000000          <1> 	call	int10h_32bit_pmi
  1033                              <1> 	
  1034                              <1> 	;jmp	short vbe3_pmi_7
  1035                              <1> 
  1036                              <1> ;vbe3_pmi_6:
  1037                              <1> ;	; 07/12/2020
  1038                              <1> ;	; case 1, previous mode is 03h, current mode is 03h
  1039                              <1> ;	; 03/12/2020
  1040                              <1> ;	cmp	byte [noclearmem], 0
  1041                              <1> ;	jna	short vbe3_pmi_7 ; do not clear memory
  1042                              <1> ;	; clear video page
  1043                              <1> ;	mov	ecx, 1024 ; 4096/4
  1044                              <1> ;	mov	eax, 07200720h
  1045                              <1> ;	mov	edi, 0B8000h ; [crt_base]
  1046                              <1> ;	add	di, [CRT_START]
  1047                              <1> ;	rep	stosd	; FILL THE REGEN BUFFER WITH BLANKS
  1048                              <1> 
  1049                              <1> vbe3_pmi_7:
  1050 000019E2 5F                  <1> 	pop	edi
  1051 000019E3 5A                  <1> 	pop	edx
  1052 000019E4 59                  <1> 	pop	ecx
  1053 000019E5 5B                  <1> 	pop	ebx
  1054                              <1> 	;pop	eax ; 04/12/2020
  1055                              <1> vbe3_pmi_8:
  1056                              <1> 	; 04/12/2020
  1057                              <1> 	;(TRDOS 386 v2.0.3, INT 31h, ah=0 return)
  1058 000019E6 31C0                <1> 	xor	eax, eax  ; eax = 0 -> succesful
  1059                              <1> vesa_vbe3_pmi_retn:
  1060 000019E8 07                  <1> 	pop	es  ; **
  1061 000019E9 1F                  <1> 	pop	ds  ; *
  1062 000019EA CF                  <1> 	iretd
  1063                              <1> 
  1064                              <1> vbe3_pmi_9:
  1065                              <1> 	; 06/12/2020 
  1066                              <1> 	;cmp	ah, 10h ; Set/Get Palette Registers
  1067                              <1> 	;jnb	short vbe3_pmi_10
  1068                              <1> 	; 05/12/2020
  1069 000019EB E802000000          <1> 	call	int10h_32bit_pmi
  1070 000019F0 EBF6                <1> 	jmp	short vesa_vbe3_pmi_retn
  1071                              <1> 
  1072                              <1> ;vbe3_pmi_10:
  1073                              <1> 	; 06/12/2020
  1074                              <1> 	;jmp	VGA_funcs_0
  1075                              <1> 
  1076                              <1> int10h_32bit_pmi:
  1077                              <1> 	; 03/12/2020
  1078                              <1> 	; 28/11/2020
  1079                              <1> 	; calling standard VGA Bios (INT 10h) functions
  1080                              <1> 	; by using 32 bit protected mode interface of
  1081                              <1> 	; VESA VBE3 Video Bios (with 'PMID' signature)
  1082                              <1> 
  1083                              <1> 	; 03/12/2020
  1084                              <1> 	; eax, ebx, ecx, edx, edi will be used by vbios pmi
  1085                              <1> 	; (esi and ebp will not be used) 
  1086                              <1> 
  1087                              <1> 	; 03/12/2020
  1088 000019F2 56                  <1> 	push	esi
  1089 000019F3 C1E010              <1> 	shl	eax, 16  ; move function number (ax) to hw
  1090 000019F6 8B35[A4110300]      <1> 	mov	esi, [pmid_addr] ; linear address of
  1091                              <1> 				 ; PMInfo.Entrypoint pointer
  1092                              <1> 	;mov	ax, [esi+PMInfo.EntryPoint]	
  1093 000019FC 668B06              <1> 	mov	ax, [esi]	 
  1094 000019FF C1C010              <1> 	rol	eax, 16 ; move PM entry address to hw
  1095                              <1> 			; and move function number to lw (ax)
  1096 00001A02 5E                  <1> 	pop	esi
  1097                              <1> 
  1098                              <1> 	; top of stack: ; (*)
  1099                              <1> 	; return (the caller) address of "int10h_32bit_pmi"
  1100                              <1> 
  1101 00001A03 E981EDFFFF          <1> 	jmp	_VBE3PMI_fcall ; will return to the caller (*)
  1102                              <1> 
  1103                              <1> VIDEO_STATE:
  1104                              <1> 	; 26/06/2016
  1105                              <1> 	; 12/05/2016
  1106                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  1107                              <1> 
  1108                              <1> ;---------------------------------------------------
  1109                              <1> ; VIDEO STATE
  1110                              <1> ;  RETURNS THE CURRENT VIDEO STATE IN AX
  1111                              <1> ;  AH = NUMBER OF COLUMNS ON THE SCREEN
  1112                              <1> ;  AL = CURRENT VIDEO MODE
  1113                              <1> ;  BH = CURRENT ACTIVE PAGE
  1114                              <1> ;---------------------------------------------------
  1115                              <1> 
  1116 00001A08 8A25[9C690000]      <1> 	mov	ah, [CRT_COLS]	; GET NUMBER OF COLUMNS
  1117 00001A0E A0[9A690000]        <1> 	mov	al, [CRT_MODE]	; CURRENT MODE
  1118                              <1> 	;movzx	esi, al
  1119                              <1> 	;mov	ah, [esi+M6] 
  1120                              <1> 	; BH = active page
  1121 00001A13 8A3D[06640100]      <1> 	mov	bh, [ACTIVE_PAGE] ; GET CURRENT ACTIVE PAGE
  1122 00001A19 FA                  <1> 	cli	; 02/01/2017
  1123 00001A1A 5D                  <1> 	pop	ebp		; RECOVER REGISTERS
  1124 00001A1B 5F                  <1> 	pop	edi
  1125 00001A1C 5E                  <1> 	pop	esi
  1126 00001A1D 59                  <1> 	pop	ecx		; DISCARD SAVED BX
  1127 00001A1E EB41                <1> 	jmp	short M15	; RETURN TO CALLER
  1128                              <1> 
  1129                              <1> set_mode_ncm:
  1130                              <1> 	; 17/11/2020 (TRDOS 386 v2.0.3)
  1131                              <1> 	; 04/07/2016 - TRDOS 386 (TRDOS v2.0)
  1132                              <1> 	; set mode without clearing the video memory
  1133                              <1> 	; (ony for graphics modes)
  1134                              <1> 
  1135                              <1> 	;cmp	al, 7 ; IBM PC CGA modes
  1136                              <1> 	;jna	short SET_MODE ; normal function (clear)
  1137                              <1> 	;; do not clear memory
  1138                              <1> 	;;mov	[noclearmem], al ; > 0
  1139                              <1> 	;mov	byte [noclearmem], 80h ; 17/11/2020
  1140                              <1> 	;call	_set_mode
  1141                              <1> 	;mov	byte [noclearmem], 0
  1142                              <1>         ;jmp     short VIDEO_RETURN
  1143                              <1> 
  1144                              <1> 	; 17/11/2020 (TRDOS v2.0.3)
  1145 00001A20 0C80                <1> 	or	al, 80h ; not clear memory option
  1146                              <1> 
  1147                              <1> 	; 05/12/2020
  1148                              <1> 	; 27/11/2020
  1149                              <1> 	; 17/11/2020
  1150                              <1> 	; 08/08/2016, 10/08/2016
  1151                              <1> 	; 29/07/2016, 30/07/2016
  1152                              <1> 	; 25/07/2016, 26/07/2016, 27/07/2016
  1153                              <1> 	; 02/07/2016, 18/07/2016, 23/07/2016
  1154                              <1> 	; 24/06/2016, 26/06/2016
  1155                              <1> 	; 29/05/2016 - TRDOS 386 (TRDOS v2.0)
  1156                              <1> SET_MODE:
  1157                              <1> 	; For 32 bit TRDOS and Retro UNIX 386:
  1158                              <1> 	;	valid video mode: 03h only!
  1159                              <1> 	;	(VGA modes will be selected with another routine)
  1160                              <1> 	;
  1161                              <1> 	; set_txt_mode ; 80*25 (16 fore colors, 8 back colors)
  1162                              <1> 
  1163                              <1> 	; 27/11/2020
  1164                              <1> 	
  1165                              <1> 	; Check if current mode is 
  1166                              <1> 	; Bochs/Plex86 VBE graphics mode
  1167 00001A22 803D[9A690000]FF    <1> 	cmp	byte [CRT_MODE], 0FFh ; VESA VBE graphics mode
  1168 00001A29 7220                <1> 	jb	short _set_mode_      ; signature  	
  1169                              <1> 				      ; VBE mode number is in	 
  1170                              <1> 				      ; [video_mode] bit 0to8
  1171 00001A2B 88C3                <1> 	mov	bl, al ; save video mode
  1172 00001A2D E86F1F0000          <1> 	call	dispi_get_enable
  1173 00001A32 50                  <1> 	push	eax ; save current VBE dispi status 
  1174                              <1> 	; Disable Bochs/Plex86 VBE dispi
  1175                              <1> 	;mov	ax, 0 ; VBE_DISPI_DISABLED 
  1176 00001A33 31C0                <1> 	xor	eax, eax ; 0 
  1177 00001A35 E83B1F0000          <1> 	call	dispi_set_enable
  1178 00001A3A 88D8                <1> 	mov	al, bl ; restore video mode
  1179 00001A3C E827000000          <1> 	call	_set_mode
  1180 00001A41 58                  <1> 	pop	eax ; restore current VBE dispi status 
  1181 00001A42 7313                <1> 	jnc	short VIDEO_RETURN
  1182                              <1> 	; ! unimplemented or invalid video mode number !
  1183                              <1> 	; VBE dispi must be enabled again
  1184                              <1> 	; (return to run on current VBE graphics mode)
  1185                              <1> 	;;mov	al, [video_mode+1] ; bit 8 to 15
  1186                              <1> 	;;and	al, 0C0h ; isolate bit 14 and bit 15 
  1187                              <1> 	;;or	al, 1 ; VBE_DISPI_ENABLED
  1188 00001A44 E82C1F0000          <1> 	call	dispi_set_enable
  1189 00001A49 EB07                <1> 	jmp	short _video_func_err
  1190                              <1> 
  1191                              <1> _set_mode_:
  1192                              <1> 	; VGA bios (non-VBE) 'setmode' procedure
  1193                              <1> 
  1194                              <1> 	; 26/11/2020 (TRDOS v2.0.3)
  1195                              <1> 	
  1196                              <1> ;------------------------------------------------------
  1197                              <1> ; SET MODE					      :
  1198                              <1> ;	THIS ROUTINE INITIALIZES THE ATTACHMENT TO    :
  1199                              <1> ;	THE SELECTED MODE, THE SCREEN IS BLANKED.     :
  1200                              <1> ; INPUT						      :
  1201                              <1> ;	(AL) - MODE SELECTED (RANGE 0-7)	      :
  1202                              <1> ; OUTPUT					      :
  1203                              <1> ;	NONE					      :
  1204                              <1> ;------------------------------------------------------
  1205                              <1> 
  1206 00001A4B E818000000          <1> 	call	_set_mode ; 24/06/2016 (set_txt_mode)
  1207                              <1> 	; 26/11/2020
  1208 00001A50 7305                <1> 	jnc	short VIDEO_RETURN
  1209                              <1> 
  1210                              <1> 	; 26/11/2020
  1211                              <1> _video_func_err:
  1212 00001A52 31C0                <1> 	xor	eax, eax ; function call failed
  1213 00001A54 48                  <1> 	dec	eax  ; 0FFFFFFFFh ; - 1	
  1214 00001A55 EB05                <1> 	jmp	short _video_return	
  1215                              <1> 
  1216                              <1> ; 12/05/2016
  1217                              <1> ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  1218                              <1> 
  1219                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
  1220                              <1> 
  1221                              <1> VIDEO_RETURN:
  1222 00001A57 A1[60700100]        <1> 	mov	eax, [video_eax] ; 12/05/2016
  1223                              <1> _video_return:
  1224 00001A5C FA                  <1> 	cli ; 02/01/2017
  1225 00001A5D 5D                  <1> 	pop	ebp ; ******** ; 26/11/2020
  1226 00001A5E 5F                  <1> 	pop	edi ; *******
  1227 00001A5F 5E                  <1> 	pop	esi ; ******
  1228 00001A60 5B                  <1> 	pop	ebx ; *****
  1229                              <1> M15:	; VIDEO_RETURN_C
  1230                              <1> 	;;15/01/2017
  1231                              <1> 	; 02/01/2017
  1232                              <1> 	;;mov	byte [intflg], 0
  1233                              <1> 	;
  1234 00001A61 59                  <1> 	pop	ecx ; **** ; 26/11/2020
  1235 00001A62 5A                  <1> 	pop	edx ; ***
  1236 00001A63 1F                  <1> 	pop	ds  ; **
  1237 00001A64 07                  <1> 	pop	es  ; *	; RECOVER SEGMENTS
  1238 00001A65 CF                  <1> 	iretd		; ALL DONE
  1239                              <1> 
  1240                              <1> set_txt_mode:
  1241                              <1> 	
  1242                              <1> 	; 29/07/2016
  1243                              <1> 	; 27/06/2016
  1244 00001A66 B003                <1> 	mov	al, 3 ; 26/11/2020 (bit 7 = 0)
  1245                              <1> 
  1246                              <1> 	; 17/11/2020 (TRDOS v2.0.3)
  1247                              <1> 	;mov	byte [noclearmem], 0
  1248                              <1> 
  1249                              <1> ; 10/08/2016
  1250                              <1> ; 08/08/2016
  1251                              <1> ; 30/07/2016
  1252                              <1> ; 29/07/2016
  1253                              <1> ; 25/07/2016, 26/07/2016, 27/07/2016
  1254                              <1> ; 07/07/2016, 18/07/2016, 23/07/2016
  1255                              <1> ; 02/07/2016, 03/07/2016, 04/07/2016
  1256                              <1> ; 26/06/2016
  1257                              <1> ; 24/06/2016 (set_txt_mode -> _set_mode)
  1258                              <1> ; 17/06/2016
  1259                              <1> ; 29/05/2016
  1260                              <1> ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  1261                              <1> 
  1262                              <1> _set_mode:
  1263                              <1> 	; 12/12/2020
  1264                              <1> 	; 26/11/2020
  1265                              <1> 	; call from 'biosfn_set_video_mode'
  1266                              <1> 	;	(bochs/plex86 video bios code)
  1267                              <1> 	; call from 'SET_MODE'
  1268                              <1> 	;	(TRDOS 386 v2 default, IBM PC/AT rom bios code)
  1269                              <1> 	; continue from 'set_txt_mode'	
  1270                              <1> 
  1271                              <1> 	; INPUT:
  1272                              <1> 	;	al = VGA video mode
  1273                              <1> 	; RETURN:
  1274                              <1> 	;	cf = 1 -> video mode not implemented
  1275                              <1> 	;	cf = 0 -> OK
  1276                              <1> 	;
  1277                              <1> 	; Modified registers: eax, bx, ecx, esi, edi, (ebp)
  1278                              <1> 
  1279                              <1> 	; 17/11/2020 (TRDOS v2.0.3)
  1280                              <1> 	; no clear memory option 
  1281                              <1> 	; (from mode number byte bit 7)
  1282 00001A68 88C4                <1> 	mov	ah, al
  1283 00001A6A 80E480              <1> 	and	ah, 80h
  1284                              <1> 	;mov	[noclearmem], al
  1285 00001A6D 8825[6F700100]      <1> 	mov	[noclearmem], ah
  1286                              <1> 	;and	al, 7Fh ; clear bit 7
  1287                              <1> 	;;xor	[noclearmem], al ; clear bit 0 to 6
  1288                              <1> 	; 26/11/2020
  1289 00001A73 30E0                <1> 	xor	al, ah ; and al, 7Fh
  1290                              <1> 
  1291                              <1> 	; 19/11/2020
  1292                              <1> 
  1293                              <1> 	; Video mode 03h action principle:
  1294                              <1> 	;
  1295                              <1> 	; for case 1:
  1296                              <1> 	; Current mode is 03h and next/requested mode is not 03h
  1297                              <1> 	;	- save mode (set mode 03h flag)
  1298                              <1> 	;	- save 8 video pages (which are will be restored)	
  1299                              <1> 	;	- save active page number (which will be reactivated)
  1300                              <1> 	;	- set active page to 0 always (no multi screen)
  1301                              <1> 	;	- save 8 cursor positions (which will be restored)
  1302                              <1> 	; 	- use 'noclearmem' option
  1303                              <1> 	;	[p_crt_mode] = 0 -> 03h 
  1304                              <1> 	;
  1305                              <1> 	; for case 2:
  1306                              <1> 	; Current mode is 03h and next/requested mode is also 03h
  1307                              <1> 	;	- clear active video page if 'noclearmem' is not set
  1308                              <1> 	;	[p_crt_mode] = 0 -> 80h -> 0
  1309                              <1> 	;
  1310                              <1> 	; for case 3:
  1311                              <1> 	; Current mode is not 03h and next/requested mode is 03h
  1312                              <1> 	;	- restore video pages (8 video pages were saved)	
  1313                              <1> 	;	- restore active page number (which were saved)
  1314                              <1> 	;	- restore 8 cursor positions (which were saved)
  1315                              <1> 	;	- reset/clear mode 03h flag
  1316                              <1> 	;	[p_crt_mode] = 03h -> 0
  1317                              <1> 	;
  1318                              <1> 	; for case 4:
  1319                              <1> 	; Current mode is not 03h and next/requested mode is not 03h
  1320                              <1> 	; 	- use 'noclearmem' option
  1321                              <1> 	;	- set active page to 0 always
  1322                              <1> 	;	[p_crt_mode] = 03h -> 83h -> 03h
  1323                              <1> 	;
  1324                              <1> 	; initial (boot time) values:
  1325                              <1> 	;	[p_crt_mode] = 0 ("there isn't a page backup, yet")
  1326                              <1> 	;	  [CRT_MODE] = 3 (kernel's starting mode)
  1327                              <1> 
  1328                              <1> 	; 26/11/2020
  1329 00001A75 3C03                <1> 	cmp	al, 03h	    ; mode 3, 80x25 text, 16 colors
  1330 00001A77 7515                <1> 	jne	short _sm_0 ; (default mode for TRDOS 386 mainprog) 	
  1331                              <1> 
  1332                              <1> 	; case 2 or case 3
  1333                              <1> 
  1334                              <1> 	; check current video mode if it is 03h
  1335 00001A79 08E4                <1> 	or	ah, ah ; 80h or 0 ('noclearmem' option)
  1336 00001A7B 7521                <1> 	jnz	short _sm_1 ; do not clear display page
  1337                              <1>  	
  1338                              <1> 	; 26/11/2020
  1339                              <1> 	; Note:
  1340                              <1> 	; [CRT_MODE] = 0FFh for VESA VBE video modes
  1341                              <1> 	; [video_mode] = standard VGA and VESA VBE video modes
  1342                              <1> 	
  1343 00001A7D 3805[9A690000]      <1> 	cmp	[CRT_MODE], al	; 03h
  1344 00001A83 7520                <1> 	jne	short _sm_2	; case 3 ([p_crt_mode] = 03h)
  1345                              <1> 
  1346                              <1> 	; case 2
  1347                              <1> 
  1348                              <1> 	; [p_crt_mode] = 0
  1349                              <1> 
  1350                              <1> 	; 19/11/2020
  1351                              <1> 	; If '_set_mode' procedure is called for video mode 3
  1352                              <1> 	;     while video mode is 3, video page will be cleared
  1353                              <1> 	;     and cursor position of video page will be reset.	 
  1354                              <1> 
  1355                              <1> 	; clear display page
  1356 00001A85 C605[6D700100]80    <1> 	mov	byte [p_crt_mode], 80h ; clear page sign
  1357 00001A8C EB1C                <1> 	jmp	short _sm_3	; bypass save video page routine
  1358                              <1> _sm_0:
  1359                              <1> 	; case 1 or case 4
  1360                              <1> 
  1361                              <1> 	; 05/12/2020
  1362 00001A8E 803D[9A690000]03    <1> 	cmp	byte [CRT_MODE], 3 ; is current mode 03h?
  1363 00001A95 7507                <1> 	jne	short _sm_1	; case 4 ; [p_crt_mode] = 03h
  1364                              <1> 	
  1365                              <1> 	; case 1
  1366                              <1> 	; [p_crt_mode] = 0
  1367                              <1> 
  1368                              <1> 	; 19/11/2020
  1369                              <1> 	; If '_set_mode' procedure is called for a video mode
  1370                              <1> 	;     except video mode 3 while current video mode
  1371                              <1> 	;     is 3, all video pages of mode 3 will be copied 
  1372                              <1> 	;     to 98000h address as backup, before mode change.	
  1373                              <1> 	
  1374                              <1> _sm_save_pm:
  1375                              <1> 	; 12/12/2020
  1376                              <1> 	;; 03/07/2016
  1377                              <1> 	;; save video pages
  1378                              <1> 	;mov	esi, 0B8000h
  1379                              <1> 	;mov	edi, 98000h ; 30/07/2016
  1380                              <1> 	;mov	ecx, (0B8000h-0B0000h)/4
  1381                              <1> 	;rep	movsd
  1382                              <1> 
  1383                              <1> 	;mov	byte [p_crt_mode], 3 ; previous mode, backup sign
  1384                              <1> 	;; 26/11/2020
  1385                              <1> 	;xchg	cl, [ACTIVE_PAGE]
  1386                              <1> 	;mov	[p_crt_page], cl  ; save as previous active page	
  1387                              <1> 	;
  1388                              <1> 	;; save cursor positions
  1389                              <1> 	;mov	esi, CURSOR_POSN
  1390                              <1> 	;mov	edi, cursor_pposn ; cursor positions backup
  1391                              <1> 	;mov	cl, 4
  1392                              <1> 	;rep	movsd
  1393                              <1> 
  1394                              <1> 	; 12/12/2020
  1395 00001A97 E881020000          <1> 	call	save_mode3_multiscreen
  1396                              <1> 
  1397                              <1> 	; 29/07/2016
  1398                              <1> 	;;mov	[ACTIVE_PAGE], cl ; 0
  1399                              <1> 	;xchg	cl, [ACTIVE_PAGE]
  1400                              <1> 	;mov	[p_crt_page], cl  ; previous page (for mode 3)	
  1401                              <1> 	
  1402                              <1> 	; [ACTIVE_PAGE] = 0 
  1403                              <1> 	
  1404 00001A9C EB07                <1> 	jmp	short _sm_2	; case 1 - 19/11/2020
  1405                              <1> _sm_1:
  1406                              <1> 	; 26/11/2020
  1407                              <1> 	; 19/11/2020
  1408                              <1> 	
  1409                              <1> 	; case 4
  1410 00001A9E 800D[6D700100]80    <1> 	or	byte [p_crt_mode], 80h 
  1411                              <1> 				; here [p_crt_mode] must be 83h
  1412                              <1> 				;	  (for case 4)
  1413                              <1> 				; (because video mode 03h
  1414                              <1> 				; was changed before as in case 1) 
  1415                              <1> 
  1416                              <1> _sm_2:	; case 4 (jump to _sm_2) - 19/11/2020 
  1417                              <1> 
  1418                              <1> 	; 19/11/2020
  1419                              <1> 	; case 3
  1420                              <1> 	; If '_set_mode' procedure is called for video mode 3
  1421                              <1> 	;     while video mode is not 3 and if there is video
  1422                              <1> 	;     page backup for video mode 3, all (of 8) mode 3
  1423                              <1> 	;     video pages will be restored from 98000h.
  1424                              <1> 
  1425 00001AA5 A2[9A690000]        <1> 	mov	[CRT_MODE], al  ; save mode in global variable
  1426                              <1> _sm_3:
  1427                              <1> 	; 30/07/2016
  1428                              <1> 	; 26/07/2016
  1429                              <1> 	; 25/07/2016
  1430                              <1> 	; set_mode_vga:
  1431                              <1> 	; 18/07/2016
  1432                              <1> 	; 14/07/2016
  1433                              <1> 	; 09/07/2016
  1434                              <1> 	; 04/07/2016
  1435                              <1> 	; 03/07/2016 (TRDOS 386 = TRDOS v2.0)
  1436                              <1> 	; /// video mode 13h ///
  1437                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  1438                              <1> 	; vgabios-0.7a (2011)
  1439                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  1440                              <1> 	; 'vgabios.c', 'vgatables.h'
  1441                              <1> 	;
  1442                              <1> 	; Oracle VirtualBox 5.0.24 VGABios Source Code
  1443                              <1> 	; ('vgabios.c', 'vgatables.h', 'vgafonts.h', 'vgarom.asm')
  1444                              <1> 	;
  1445 00001AAA 88C4                <1> 	mov	ah, al
  1446 00001AAC B910000000          <1> 	mov	ecx, vga_mode_count 	
  1447 00001AB1 BE[B6690000]        <1> 	mov	esi, vga_modes
  1448 00001AB6 31DB                <1> 	xor	ebx, ebx
  1449                              <1> _sm_4:
  1450 00001AB8 AC                  <1> 	lodsb
  1451 00001AB9 38C4                <1> 	cmp	ah, al
  1452 00001ABB 7406                <1> 	je	short _sm_5
  1453 00001ABD FEC3                <1> 	inc	bl
  1454 00001ABF E2F7                <1> 	loop	_sm_4
  1455                              <1> 
  1456                              <1> 	; UNIMPLEMENTED VIDEO MODE !
  1457                              <1> 	;xor	eax, eax
  1458                              <1>         ;mov	[video_eax], eax ; 0 
  1459                              <1> 
  1460                              <1> 	; 26/11/2020
  1461 00001AC1 F9                  <1> 	stc	; unimplemented video mode ! (cf=1)	
  1462                              <1> 
  1463 00001AC2 C3                  <1> 	retn
  1464                              <1> 
  1465                              <1> ;-----	eBX POINTS TO CORRECT ROW OF INITIALIZATION TABLE	
  1466                              <1> 
  1467                              <1> _sm_5: 	; 25/07/2016
  1468                              <1> 	;mov	esi, ebx
  1469                              <1> 	;add	esi, vga_memmodel
  1470                              <1> 	;mov	al, [esi]
  1471                              <1> 	; 19/11/2020
  1472 00001AC3 8A83[066A0000]      <1> 	mov	al, [ebx+vga_memmodel]
  1473 00001AC9 A2[86700100]        <1> 	mov	[VGA_MTYPE], al
  1474                              <1> 
  1475 00001ACE 89DF                <1> 	mov	edi, ebx
  1476 00001AD0 81C7[166A0000]      <1> 	add	edi, vga_dac_s 	
  1477 00001AD6 C0E302              <1> 	shl	bl, 2 ; byte -> dword
  1478 00001AD9 81C3[C6690000]      <1> 	add	ebx, vga_mode_tbl_ptr
  1479                              <1> 
  1480                              <1> 	;mov	dword [VGA_BASE], 0B8000h
  1481                              <1> 	;cmp	ah, 0Dh ; [CRT_MODE]
  1482                              <1> 	;jb	short M9 
  1483                              <1> 	;mov	dword [VGA_BASE], 0A0000h
  1484                              <1> ;M9:
  1485 00001ADF 8B33                <1> 	mov	esi, [ebx]
  1486 00001AE1 89F3                <1> 	mov	ebx, esi
  1487 00001AE3 83C614              <1> 	add	esi, vga_p_cm_pos ; ebx + 20
  1488 00001AE6 668B06              <1> 	mov	ax, [esi]       ; get the cursor mode from the table
  1489 00001AE9 66A3[B3690000]      <1> 	mov	[CURSOR_MODE], ax ; save cursor mode (initial value)
  1490                              <1> 	; al = 6, ah = 7
  1491                              <1> 	; al = 0Dh, ah = 0Eh ; 25/07/2016
  1492 00001AEF E8A8020000          <1> 	call	cursor_shape_fix
  1493                              <1> 	; al = 14, ah = 15 (If [CHAR_HEIGHT] = 16)
  1494 00001AF4 668906              <1> 	mov	[esi], ax
  1495                              <1> 
  1496 00001AF7 56                  <1> 	push	esi ; *	
  1497                              <1> 
  1498 00001AF8 8A25[A1690000]      <1> 	mov	ah, [VGA_MODESET_CTL]
  1499 00001AFE 80E408              <1> 	and	ah, 8 ; default palette loading ?
  1500 00001B01 7524                <1> 	jnz	short _sm_6
  1501 00001B03 66BAC603            <1> 	mov	dx, 3C6h ; VGAREG_PEL_MASK (DAC mask register)
  1502 00001B07 B0FF                <1> 	mov	al, 0FFh ; PEL mask
  1503 00001B09 EE                  <1> 	out	dx, al
  1504 00001B0A 8A27                <1> 	mov	ah, [edi] ; DAC model (selection number)
  1505 00001B0C E874100000          <1> 	call	load_dac_palette
  1506                              <1> 	; ecx = 0
  1507 00001B11 F605[A1690000]02    <1> 	test	byte [VGA_MODESET_CTL], 2 ; gray scale summing
  1508 00001B18 740D                <1> 	jz	short _sm_6
  1509 00001B1A 53                  <1> 	push	ebx
  1510 00001B1B 29DB                <1> 	sub	ebx, ebx ; sub bl, bl
  1511 00001B1D 66B90001            <1>         mov     cx, 256 
  1512 00001B21 E8B2100000          <1> 	call	gray_scale_summing
  1513 00001B26 5B                  <1> 	pop	ebx	
  1514                              <1> _sm_6:
  1515                              <1> 	; Reset Attribute Ctl flip-flop
  1516 00001B27 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  1517 00001B2B EC                  <1>  	in	al, dx
  1518                              <1> 	; Set Attribute Ctl
  1519 00001B2C 89DE                <1> 	mov	esi, ebx ; addr of params tbl for selected mode
  1520 00001B2E 83C623              <1> 	add	esi, 35  ; actl regs
  1521 00001B31 30E4                <1> 	xor	ah, ah ; 0
  1522 00001B33 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  1523                              <1> _sm_7:
  1524 00001B37 88E0                <1> 	mov	al, ah
  1525 00001B39 EE                  <1> 	out	dx, al ; index
  1526 00001B3A AC                  <1> 	lodsb
  1527                              <1> 	; DX = 3C0h = VGAREG_ACTL_WRITE_DATA
  1528 00001B3B EE                  <1> 	out	dx, al ; value
  1529 00001B3C FEC4                <1> 	inc	ah
  1530 00001B3E 80FC14              <1> 	cmp	ah, 20 ; number of actl registers
  1531 00001B41 72F4                <1> 	jb	short _sm_7
  1532                              <1> 	;
  1533 00001B43 88E0                <1> 	mov	al, ah ; 20
  1534 00001B45 EE                  <1> 	out	dx, al ; index
  1535 00001B46 28C0                <1> 	sub	al, al ; 0
  1536 00001B48 EE                  <1> 	out	dx, al ; value
  1537                              <1> 	;
  1538                              <1> 	; Set Sequencer Ctl
  1539 00001B49 89DE                <1> 	mov	esi, ebx ; addr of params tbl for selected mode
  1540 00001B4B 83C605              <1> 	add	esi, 5 ; sequ regs
  1541                              <1> 	;
  1542 00001B4E 66BAC403            <1> 	mov	dx, 3C4h  ; VGAREG_SEQU_ADDRESS
  1543 00001B52 EE                  <1> 	out	dx, al ; 0
  1544 00001B53 6642                <1> 	inc	dx ; 3C5h ; VGAREG_SEQU_DATA
  1545 00001B55 B003                <1> 	mov	al, 3
  1546 00001B57 EE                  <1> 	out	dx, al
  1547 00001B58 B401                <1> 	mov	ah, 1	
  1548                              <1> _sm_8:
  1549 00001B5A 88E0                <1> 	mov	al, ah
  1550                              <1> 	;mov	dx, 3C4h ; VGAREG_SEQU_ADDRESS
  1551 00001B5C 664A                <1> 	dec	dx
  1552 00001B5E EE                  <1> 	out	dx, al ; index
  1553 00001B5F AC                  <1> 	lodsb
  1554 00001B60 6642                <1> 	inc	dx ; 3C5h ; VGAREG_SEQU_DATA
  1555 00001B62 EE                  <1> 	out	dx, al
  1556 00001B63 80FC04              <1> 	cmp	ah, 4 ; number of sequ regs
  1557 00001B66 7304                <1> 	jnb	short _sm_9		
  1558 00001B68 FEC4                <1> 	inc	ah 
  1559 00001B6A EBEE                <1> 	jmp	short _sm_8
  1560                              <1> _sm_9:
  1561                              <1> 	; Set Grafx Ctl
  1562 00001B6C 89DE                <1> 	mov	esi, ebx ; addr of params tbl for selected mode
  1563 00001B6E 83C637              <1> 	add	esi, 55 ; grdc regs
  1564 00001B71 30E4                <1> 	xor	ah, ah ; 0
  1565                              <1> _sm_10:
  1566 00001B73 88E0                <1> 	mov	al, ah
  1567 00001B75 66BACE03            <1> 	mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  1568 00001B79 EE                  <1> 	out	dx, al	
  1569 00001B7A AC                  <1> 	lodsb
  1570 00001B7B 6642                <1> 	inc	dx ; 3CFh ; VGAREG_GRDC_DATA
  1571 00001B7D EE                  <1> 	out	dx, al
  1572 00001B7E FEC4                <1> 	inc	ah
  1573 00001B80 80FC09              <1> 	cmp	ah, 9 ; number of grdc regs
  1574 00001B83 72EE                <1> 	jb	short _sm_10
  1575                              <1> 	;
  1576                              <1> 	; Disable CRTC write protection
  1577 00001B85 66BAD403            <1> 	mov	dx, 3D4h  ; VGAREG_VGA_CRTC_ADDRESS
  1578                              <1> 	;mov	al, 11h
  1579                              <1> 	;our	dx, al
  1580                              <1> 	;inc	dx
  1581                              <1> 	;sub	al, al
  1582                              <1> 	;out	dx, al
  1583 00001B89 66B81100            <1> 	mov	ax, 11h
  1584 00001B8D 66EF                <1> 	out	dx, ax
  1585 00001B8F 89DE                <1> 	mov	esi, ebx ; addr of params tbl for selected mode
  1586 00001B91 83C60A              <1> 	add	esi, 10 ; crtc regs
  1587                              <1> 	; ah = 0
  1588                              <1> _sm_11:
  1589 00001B94 88E0                <1> 	mov	al, ah
  1590                              <1> 	; dx = 3D4h = VGAREG_VGA_CRTC_ADDRESS
  1591 00001B96 EE                  <1> 	out	dx, al ; index
  1592 00001B97 AC                  <1> 	lodsb
  1593 00001B98 6642                <1> 	inc	dx  ; VGAREG_VGA_CRTC_ADDRESS + 1
  1594 00001B9A EE                  <1> 	out	dx, al ; value
  1595 00001B9B 80FC18              <1> 	cmp	ah, 24 ; number of crtc registers - 1
  1596 00001B9E 7306                <1> 	jnb	short _sm_12
  1597 00001BA0 FEC4                <1> 	inc	ah
  1598 00001BA2 664A                <1> 	dec	dx ; 3D4h
  1599 00001BA4 EBEE                <1> 	jmp	short _sm_11
  1600                              <1> _sm_12:
  1601                              <1> 	; Set the misc register
  1602 00001BA6 66BACC03            <1> 	mov	dx, 3CCh ; VGAREG_READ_MISC_OUTPUT
  1603 00001BAA 8A4309              <1> 	mov	al, [ebx+9] ; misc reg
  1604 00001BAD EE                  <1> 	out	dx, al
  1605                              <1> 	;
  1606                              <1> 	; Enable video
  1607 00001BAE 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  1608 00001BB2 B020                <1> 	mov	al, 20h  
  1609 00001BB4 EE                  <1>         out     dx, al   ; set bit 5 to 1
  1610 00001BB5 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  1611 00001BB9 EC                  <1> 	in	al, dx
  1612                              <1> 	;
  1613                              <1> 	; 17/11/2020
  1614                              <1> 	;cmp	byte [noclearmem], 0
  1615                              <1>         ;ja	short _sm_15
  1616                              <1> 
  1617 00001BBA F605[6F700100]80    <1> 	test	byte [noclearmem], 80h
  1618 00001BC1 7540                <1> 	jnz	short _sm_15	
  1619                              <1> 
  1620                              <1> 	; 29/07/2016
  1621 00001BC3 31C0                <1> 	xor	eax, eax
  1622 00001BC5 B900400000          <1> 	mov	ecx, 4000h ; 16K words (32K)
  1623 00001BCA 803D[86700100]02    <1> 	cmp     byte [VGA_MTYPE], 2  ; CTEXT, MTEXT, CGA
  1624 00001BD1 7715                <1> 	ja	short _sm_14    ; no ? (0A0000h)
  1625 00001BD3 BF00800B00          <1> 	mov	edi, 0B8000h
  1626 00001BD8 7409                <1> 	je	short _sm_13	; CGA graphics mode
  1627                              <1> 	; 08/08/2016
  1628 00001BDA A3[82700100]        <1> 	mov	[VGA_INT43H], eax ; 0 ; default font 
  1629 00001BDF 66B82007            <1> 	mov	ax, 0720h	; CGA text mode
  1630                              <1> _sm_13:
  1631 00001BE3 F366AB              <1> 	rep	stosw
  1632 00001BE6 EB1B                <1> 	jmp	short _sm_15		
  1633                              <1> 
  1634                              <1> _sm_14:
  1635 00001BE8 BF00000A00          <1> 	mov	edi, 0A0000h
  1636                              <1> 	; ecx = 16384 dwords (64K)
  1637 00001BED 66BAC403            <1> 	mov	dx, 3C4h ; VGAREG_SEQU_ADDRESS
  1638 00001BF1 B002                <1> 	mov	al, 2
  1639 00001BF3 EE                  <1> 	out	dx, al
  1640                              <1> 	;mov	dx, 3C5h ; VGAREG_SEQU_DATA
  1641 00001BF4 6642                <1> 	inc	dx
  1642 00001BF6 EC                  <1> 	in	al, dx ; mmask
  1643 00001BF7 6650                <1> 	push	ax
  1644 00001BF9 B00F                <1> 	mov	al, 0Fh ; all planes
  1645 00001BFB EE                  <1> 	out	dx, al
  1646 00001BFC 30C0                <1> 	xor	al, al ; 0
  1647 00001BFE F3AB                <1> 	rep	stosd	; ecx = 163684 (64K)
  1648 00001C00 6658                <1> 	pop	ax
  1649 00001C02 EE                  <1> 	out	dx, al  ; mmask
  1650                              <1> _sm_15:
  1651                              <1> 	; ebx = addr of params tbl for selected mode
  1652                              <1> 	; 10/08/2016
  1653 00001C03 668B03              <1> 	mov	ax, [ebx] ; num of columns, 'twidth'
  1654 00001C06 A2[9C690000]        <1> 	mov	[CRT_COLS], al
  1655                              <1> 	;; 26/07/2016
  1656                              <1> 	;; CRTC_ADDRESS = 3D4h (always)
  1657                              <1> 	;mov	ah, [ebx+1] ; num of rows, 'theightm1'
  1658 00001C0B FEC4                <1> 	inc	ah ; 09/07/2016
  1659 00001C0D 8825[A2690000]      <1> 	mov	[VGA_ROWS], ah
  1660                              <1> 	; 10/08/2016
  1661 00001C13 8A4302              <1> 	mov	al, [ebx+2]
  1662 00001C16 A2[9E690000]        <1> 	mov	[CHAR_HEIGHT], al 
  1663                              <1> 	; 29/07/2016
  1664                              <1> 	; length of regen buffer in bytes
  1665 00001C1B 668B4B03            <1> 	mov	cx, [ebx+3] ; 'slength_l'
  1666 00001C1F 66890D[70700100]    <1> 	mov	[CRT_LEN], cx
  1667                              <1> 	;
  1668                              <1> 	; 27/07/2016
  1669 00001C26 30E4                <1> 	xor	ah, ah
  1670 00001C28 A0[06640100]        <1> 	mov	al, [ACTIVE_PAGE] ; may be > 0 for mode 3
  1671                              <1> 	;mul	word [CRT_LEN] ; 4096 for mode 3
  1672 00001C2D 66F7E1              <1> 	mul	cx ; 29/07/2016
  1673 00001C30 66A3[F4630100]      <1> 	mov	[CRT_START], ax
  1674                              <1> 	;
  1675 00001C36 B060                <1> 	mov	al, 60h
  1676                              <1> 	;cmp	byte [noclearmem], 0
  1677                              <1> 	;jna	short _sm_16
  1678                              <1> 	;add	al, 80h
  1679 00001C38 0A05[6F700100]      <1> 	or	al, [noclearmem] ; 17/11/2020
  1680                              <1> _sm_16:
  1681 00001C3E A2[9F690000]        <1> 	mov	[VGA_VIDEO_CTL], al
  1682 00001C43 C605[A0690000]F9    <1> 	mov	byte [VGA_SWITCHES], 0F9h
  1683 00001C4A 8025[A1690000]7F    <1> 	and	byte [VGA_MODESET_CTL], 7Fh
  1684                              <1> 
  1685 00001C51 5E                  <1> 	pop	esi ; *
  1686                              <1> 
  1687                              <1> 	; 26/07/2016
  1688                              <1> 	; 07/07/2016
  1689 00001C52 668B0D[B3690000]    <1> 	mov	cx, [CURSOR_MODE] ; restore cursor mode (initial value)
  1690 00001C59 66870E              <1> 	xchg	cx, [esi] ; cl = start line, ch = end line
  1691                              <1> 			  ; reset to initial value
  1692 00001C5C 86E9                <1> 	xchg 	ch, cl  ; ch = start line, cl = end line  
  1693 00001C5E 66890D[B3690000]    <1> 	mov	[CURSOR_MODE], cx ; save (fixed) cursor mode
  1694                              <1> 
  1695                              <1> 	; 27/07/2016
  1696 00001C65 803D[86700100]02    <1> 	cmp	byte [VGA_MTYPE], 2 ; CTEXT, MTEXT
  1697 00001C6C 7317                <1> 	jnb	short _sm_17
  1698                              <1> 
  1699                              <1> 	; Set cursor shape
  1700                              <1> 	;mov	cx, 0607h
  1701                              <1> 	;call	_set_ctype
  1702                              <1> 
  1703                              <1> 	; 29/07/2016
  1704 00001C6E B40A                <1> 	mov	ah, 10	; 6845 register for cursor set
  1705 00001C70 E84D060000          <1> 	call	m16	; output cx register
  1706                              <1> 	
  1707                              <1> 	; 25/07/2016
  1708 00001C75 803D[9A690000]03    <1>         cmp     byte [CRT_MODE], 03h
  1709 00001C7C 7507                <1> 	jne	short _sm_17
  1710                              <1> 	; 26/07/2016
  1711                              <1> 
  1712 00001C7E A0[06640100]        <1> 	mov	al, [ACTIVE_PAGE]
  1713 00001C83 EB0B                <1> 	jmp	short _sm_18
  1714                              <1> _sm_17:
  1715                              <1> 	; Set cursor pos for page 0..7
  1716                              <1> 	;sub	ax, ax ; eax = 0
  1717 00001C85 29C0                <1> 	sub	eax, eax ; 17/11/2020
  1718 00001C87 BF[F6630100]        <1> 	mov	edi, CURSOR_POSN
  1719 00001C8C AB                  <1> 	stosd	
  1720 00001C8D AB                  <1> 	stosd
  1721 00001C8E AB                  <1> 	stosd
  1722 00001C8F AB                  <1> 	stosd
  1723                              <1> 	;; Set active page 0
  1724                              <1> 	;mov	[ACTIVE_PAGE], al ; 0
  1725                              <1> _sm_18:
  1726                              <1> 	; 29/07/2016
  1727 00001C90 803D[86700100]02    <1> 	cmp	byte [VGA_MTYPE], 2 ; CTEXT, MTEXT
  1728 00001C97 737F                <1>         jnb	_sm_23
  1729                              <1> 
  1730                              <1> 	;cmp	byte [CHAR_HEIGHT], 16
  1731                              <1> 	;je	short _sm_19
  1732                              <1> 
  1733                              <1>  	;; copy and activate 8x16 font
  1734                              <1> 	
  1735                              <1> 	; 26/07/2016
  1736 00001C99 B004                <1> 	mov	al, 04h
  1737                              <1> 	;sub	bl, bl
  1738                              <1> 	; AX = 1104H ; Load ROM 8x16 Character Set
  1739                              <1> 	; (BL = font block to load (EGA: 0-3; VGA: 0-7))
  1740 00001C9B E8C9150000          <1> 	call	load_text_8_16_pat
  1741                              <1> 
  1742                              <1> 	; video_func_1103h:
  1743                              <1> 	; biosfn_set_text_block_specifier:
  1744                              <1> 	; BL = font block selector code	
  1745                              <1> 	; NOTE: TRDOS 386 only uses and sets font block 0
  1746                              <1> 	; (It is as BL = 0 for TRDOS 386)
  1747 00001CA0 66BAC403            <1> 	mov	dx, 3C4h ; VGAREG_SEQU_ADDRESS
  1748                              <1> 	;;mov	ah, bl
  1749                              <1> 	;sub	ah, ah ; 0
  1750                              <1> 	;mov	al, 03h
  1751                              <1> 	; 19/11/2020
  1752 00001CA4 66B80300            <1> 	mov	ax, 03h
  1753 00001CA8 66EF                <1> 	out	dx, ax
  1754                              <1> _sm_19:
  1755                              <1> 	; 29/07/2016
  1756                              <1> 	; 26/07/2016
  1757                              <1> 	; 24/06/2016
  1758                              <1> 	;mov	edi, 0B8000h
  1759                              <1> 	;mov	cx, 4000h ; 16K words (32K)
  1760                              <1> 	;
  1761 00001CAA 30C0                <1> 	xor	al, al
  1762 00001CAC 3805[6D700100]      <1>         cmp     [p_crt_mode], al ; 0 
  1763 00001CB2 7705                <1>         ja      short _sm_20 ; 03h, 80h or 83h
  1764                              <1> 
  1765                              <1> 	; case 1 - 19/11/2020
  1766                              <1> 	;
  1767                              <1> 	; If [pc_crt_mode] = 0, that means, previous mode is 03h
  1768                              <1> 	; and current mode is not 03h (case 1)
  1769                              <1> 
  1770                              <1> 	; 30/07/2016
  1771                              <1> 	; 24/06/2016
  1772                              <1> 	; TRDOS 386 (TRDOS v2) 'set mode' modification
  1773                              <1> 	; (for multiscreen feature):
  1774                              <1> 	; If '_set_mode' procedure is called for video mode 3
  1775                              <1> 	;     while video mode is 3, video page will be cleared
  1776                              <1> 	;     and cursor position of video page will be reset.	  
  1777                              <1> 	; If '_set_mode' procedure is called for a video mode
  1778                              <1> 	;     except video mode 3, while current video mode
  1779                              <1> 	;     is 3, all video pages of mode 3 will be copied 
  1780                              <1> 	;     to 98000h address as backup, before mode change.	 	
  1781                              <1> 	; If '_set_mode' procedure is called for video mode 3
  1782                              <1> 	;     while video mode is not 3 and if there is video
  1783                              <1> 	;     page backup for video mode 3, all (of 8) mode 3
  1784                              <1> 	;     video pages will be restored from 98000h.
  1785                              <1> 
  1786                              <1> 	; 19/11/2020
  1787                              <1> 	;mov	[ACTIVE_PAGE], al ; 0
  1788                              <1> 
  1789                              <1> 	; Here,
  1790                              <1> 	; video memory already cleared if [noclearmem] <> 80h
  1791                              <1> 	
  1792                              <1> 	;mov	ax, 0720h
  1793                              <1> 	;mov	cx, 4000h ; 16K words (32K)
  1794                              <1> 	;mov	edi, 0B8000h
  1795                              <1> 	;rep	stosw
  1796                              <1> 	;sub	al, al
  1797                              <1> 	
  1798                              <1> 	;jmp	short _sm_23
  1799                              <1> 
  1800                              <1> 	; Set hardware side for the new active video page
  1801                              <1>  
  1802 00001CB4 E9FB010000          <1> 	jmp	_set_active_page ; 19/11/2020	
  1803                              <1> 
  1804                              <1> _sm_20:
  1805                              <1> 	; 19/11/2020
  1806                              <1> 	; case 2 or case 3 or case 4 - 19/11/2020
  1807                              <1> 	
  1808                              <1> 	; 19/11/2020
  1809 00001CB9 803D[9A690000]03    <1> 	cmp	byte [CRT_MODE], 3  ; new video mode
  1810 00001CC0 754F                <1> 	jne	short _sm_22 ; al = 0 (& video mode <> 03h)
  1811                              <1> 			     ; case 4 - 19/11/2020
  1812                              <1> 			     ; ([p_crt_mode] = 83h) 		
  1813                              <1> 
  1814                              <1> 	; case 2 or case 3 - 19/11/2020	
  1815                              <1> 
  1816                              <1> 	;movzx	ebx, byte [ACTIVE_PAGE]
  1817                              <1> 	; 19/11/2020
  1818 00001CC2 A0[6E700100]        <1> 	mov	al, [p_crt_page] ; previous mode 3 active page
  1819                              <1> 	;movzx	ebx, al
  1820                              <1> 	;shl	bl, 1 ; * 2
  1821                              <1> 	;add	ebx, CURSOR_POSN
  1822                              <1> 
  1823                              <1> 	; 29/07/2016
  1824 00001CC7 F605[6D700100]7F    <1> 	test    byte [p_crt_mode], 7Fh ; 83h or 80h or 03h
  1825 00001CCE 740F                <1> 	jz	short _sm_21	; do not restore video pages
  1826                              <1> 				; case 2 - 19/11/2020 
  1827                              <1> 	; case 3 - 19/11/2020
  1828                              <1> 
  1829                              <1> 	; ([p_crt_mode] = 03h)
  1830                              <1> 
  1831                              <1> 	; New video mode is 3 while current video mode is not 3
  1832                              <1> 	; (multi screen) video pages will be restored from 098000h
  1833                              <1> 
  1834                              <1> 	; 19/11/2020
  1835 00001CD0 A2[06640100]        <1> 	mov	[ACTIVE_PAGE], al ; current mode 3 active page
  1836                              <1> 
  1837                              <1> 	; 12/12/2020
  1838                              <1> 	;; restore video pages
  1839                              <1> 	;mov	esi, 98000h ; 30/07/2016 
  1840                              <1> 	;mov	edi, 0B8000h
  1841                              <1> 	;mov	cx, 2000h ; 8K dwords (32K)
  1842                              <1> 	;rep	movsd
  1843                              <1> 	;
  1844                              <1> 	;; 19/11/2020
  1845                              <1> 	;mov	[p_crt_mode], cl ; reset ('case 3' end condition)
  1846                              <1> 	;
  1847                              <1> 	;; restore cursor positions
  1848                              <1> 	;mov	esi, cursor_pposn
  1849                              <1> 	;mov	edi, CURSOR_POSN
  1850                              <1> 	;;mov	ecx, 4	; restore all cursor positions (16 bytes)
  1851                              <1> 	;mov	cl, 4
  1852                              <1> 	;rep 	movsd
  1853                              <1> 	
  1854                              <1> 	; 12/12/2020
  1855 00001CD5 E89C000000          <1> 	call	_restore_mode3_multiscreen
  1856                              <1> 
  1857                              <1> 	;jmp	short _sm_23 ; do not clear current video pages
  1858                              <1> 
  1859                              <1> 	; 19/11/2020
  1860 00001CDA E9D5010000          <1> 	jmp	_set_active_page
  1861                              <1> 
  1862                              <1> _sm_21:
  1863                              <1> 	; 19/11/2020
  1864                              <1> 	; case 2 
  1865                              <1> 	;
  1866                              <1> 	; ([p_crt_mode] = 80h)
  1867                              <1> 	;
  1868                              <1> 	; User has requested to set video mode 3 again while
  1869                              <1> 	; current video mode is 3.. that means, set mode 03h
  1870                              <1> 	; parameters again and clear video page.
  1871                              <1> 	; ('noclearmem' option effects the result) 
  1872                              <1> 	
  1873                              <1> 	; 19/11/2020
  1874 00001CDF F605[6F700100]80    <1> 	test	byte [noclearmem], 80h
  1875 00001CE6 7529                <1> 	jnz	short _sm_22	; 'do not clear video memory'
  1876                              <1> 				; continue with current text
  1877                              <1> 				; (user's option/choice) 
  1878                              <1> 	; clear video page
  1879                              <1> 	;mov	cx, [CRT_LEN] ; 4096
  1880                              <1> 	;shr	cx, 1 ; 2048 ; 16/11/2020
  1881 00001CE8 66B82007            <1> 	mov	ax, 0720h
  1882                              <1> 	; 26/11/2020
  1883 00001CEC B900080000          <1> 	mov	ecx, 2048 ; 4096/2
  1884 00001CF1 BF00800B00          <1> 	mov	edi, 0B8000h ; [crt_base]
  1885 00001CF6 66033D[F4630100]    <1> 	add	di, [CRT_START]
  1886 00001CFD F366AB              <1> 	rep	stosw	; FILL THE REGEN BUFFER WITH BLANKS
  1887                              <1> 	;
  1888                              <1> 	; 19/11/2020
  1889 00001D00 A0[06640100]        <1> 	mov	al, [ACTIVE_PAGE] ; 0 to 7 (for video mode 3)
  1890 00001D05 0FB6D8              <1> 	movzx	ebx, al
  1891 00001D08 D0E3                <1> 	shl	bl, 1
  1892 00001D0A 66898B[F6630100]    <1> 	mov	[ebx+CURSOR_POSN], cx ; reset cursor position
  1893                              <1> _sm_22:
  1894                              <1> 	;mov	[p_crt_mode], al ; 0 ; reset
  1895                              <1> 	; 19/11/2020
  1896                              <1> 	;and	byte [p_crt_mode], 3 ; 83h -> 3, 80h -> 0  
  1897 00001D11 8025[6D700100]7F    <1> 	and	byte [p_crt_mode], 7Fh ; 83h -> 3, 80h -> 0  
  1898                              <1> _sm_23:
  1899                              <1> 	; al = video page number
  1900                              <1> 	; [CRT_LEN] = length of regen buffer in bytes
  1901                              <1> 	;call	_set_active_page
  1902                              <1> 	; 16/11/2020
  1903 00001D18 E997010000          <1> 	jmp	_set_active_page
  1904                              <1> 
  1905                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
  1906                              <1> 	;retn
  1907                              <1> 
  1908                              <1> save_mode3_multiscreen:
  1909                              <1> 	; 12/12/2020 (TRDOS v2.0.3)
  1910                              <1> 	; save mode 03h video pages and cursor positions
  1911                              <1> 	;
  1912                              <1> 	; Modified registers: ecx (=0), esi, edi
  1913                              <1> 	
  1914                              <1> 	; 12/12/2020
  1915                              <1> 	; moved here from '_set_mode'	
  1916                              <1> 	; 03/07/2016
  1917                              <1> 	; save video pages
  1918 00001D1D BE00800B00          <1> 	mov	esi, 0B8000h
  1919 00001D22 BF00800900          <1> 	mov	edi, 98000h ; 30/07/2016
  1920 00001D27 B900200000          <1> 	mov	ecx, (0B8000h-0B0000h)/4
  1921 00001D2C F3A5                <1> 	rep	movsd
  1922                              <1> 	
  1923 00001D2E C605[6D700100]03    <1> 	mov	byte [p_crt_mode], 3 ; previous mode, backup sign
  1924                              <1> 	; 26/11/2020
  1925 00001D35 860D[06640100]      <1> 	xchg	cl, [ACTIVE_PAGE]
  1926 00001D3B 880D[6E700100]      <1> 	mov	[p_crt_page], cl  ; save as previous active page	
  1927                              <1> 	
  1928                              <1> 	; save cursor positions
  1929 00001D41 BE[F6630100]        <1> 	mov	esi, CURSOR_POSN
  1930 00001D46 BF[72700100]        <1> 	mov	edi, cursor_pposn ; cursor positions backup
  1931 00001D4B B104                <1> 	mov	cl, 4
  1932 00001D4D F3A5                <1> 	rep	movsd
  1933 00001D4F C3                  <1> 	retn
  1934                              <1> 
  1935                              <1> restore_mode3_multiscreen:
  1936                              <1> 	; 12/12/2020 (TRDOS v2.0.3)
  1937                              <1> 	; restore mode 03h video pages and cursor positions
  1938                              <1> 	;
  1939                              <1> 	; Input:
  1940                              <1> 	;    settings from the last 'save_mode3_multiscreen'
  1941                              <1> 	;
  1942                              <1> 	; Output: 
  1943                              <1> 	;    AL = active video page = [ACTIVE_PAGE]
  1944                              <1> 	;
  1945                              <1> 	; Modified registers: al, ecx (=0), esi, edi
  1946                              <1> 
  1947 00001D50 A0[6E700100]        <1> 	mov	al, [p_crt_page] ; previous mode 3 active page
  1948 00001D55 A2[06640100]        <1> 	mov	[ACTIVE_PAGE], al ; current mode 3 active page
  1949                              <1> 
  1950                              <1> 	; 12/12/2020
  1951                              <1> 	; moved here from 'vesa_vbe3_pmi'	
  1952                              <1> 
  1953                              <1> 	; 07/12/2020
  1954                              <1> 	; restore CRT_START according to ACTIVE_PAGE
  1955                              <1> 	;mov	[CRT_START], cx ; 0
  1956                              <1> 	; 12/12/2020
  1957 00001D5A 66C705[F4630100]00- <1> 	mov	word [CRT_START], 0
  1957 00001D62 00                  <1>
  1958                              <1> 
  1959                              <1> 	; check active page and set it again if it is not 0
  1960 00001D63 08C0                <1> 	or	al, al
  1961                              <1> 	;;jz	short vbe3_pmi_7
  1962                              <1> 	;jz	short _restore_mode3_multiscreen
  1963 00001D65 740F                <1> 	jz	short r_m3_ms_1
  1964 00001D67 88C1                <1> 	mov	cl, al
  1965                              <1> ;vbe3_pmi_5:
  1966                              <1> r_m3_ms_0:
  1967 00001D69 668105[F4630100]00- <1> 	add	word [CRT_START], 4096
  1967 00001D71 10                  <1>
  1968 00001D72 FEC9                <1> 	dec	cl
  1969                              <1> 	;jnz	short vbe3_pmi_5
  1970 00001D74 75F3                <1> 	jnz	short r_m3_ms_0
  1971                              <1> r_m3_ms_1:
  1972                              <1> 	; 12/12/2020
  1973                              <1> 	; moved here from '_set_mode'	
  1974                              <1> _restore_mode3_multiscreen:
  1975                              <1> 	; Modified registers: ecx, esi, edi
  1976                              <1> 
  1977                              <1> 	; restore video pages
  1978 00001D76 BE00800900          <1> 	mov	esi, 98000h ; 30/07/2016 
  1979 00001D7B BF00800B00          <1> 	mov	edi, 0B8000h
  1980                              <1> 	;mov	cx, 2000h ; 8K dwords (32K)
  1981 00001D80 B900200000          <1> 	mov	ecx, 2000h
  1982 00001D85 F3A5                <1> 	rep	movsd
  1983                              <1> 
  1984                              <1> 	; 19/11/2020
  1985 00001D87 880D[6D700100]      <1> 	mov	[p_crt_mode], cl ; reset ('case 3' end condition)
  1986                              <1> 
  1987                              <1> 	; restore cursor positions
  1988 00001D8D BE[72700100]        <1> 	mov	esi, cursor_pposn
  1989 00001D92 BF[F6630100]        <1> 	mov	edi, CURSOR_POSN
  1990                              <1> 	;mov	ecx, 4	; restore all cursor positions (16 bytes)
  1991 00001D97 B104                <1> 	mov	cl, 4
  1992 00001D99 F3A5                <1> 	rep 	movsd
  1993 00001D9B C3                  <1> 	retn
  1994                              <1> 
  1995                              <1> cursor_shape_fix:
  1996                              <1> 	; 07/07/2016
  1997                              <1> 	; (Cursor start and cursor end line values -6,7-
  1998                              <1> 	; will be fixed depending on character height)
  1999                              <1> 	;
  2000                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  2001                              <1> 	; vgabios-0.7a (2011)
  2002                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  2003                              <1> 	; 'vgabios.c', ' biosfn_set_cursor_shape (CH,CL)'
  2004                              <1> 	;
  2005                              <1> 	; INPUT ->
  2006                              <1> 	;	AL = cursor start line (=6)
  2007                              <1> 	;	AH = cursor end line (=7)
  2008                              <1> 	; OUTPUT ->
  2009                              <1> 	;	AL = cursor start line (=14)
  2010                              <1> 	;	AH = cursor end line (=15)
  2011                              <1> 	;
  2012                              <1> 	;; if((modeset_ctl&0x01)&&(cheight>8)&&(CL<8)&&(CH<0x20))
  2013                              <1> 
  2014                              <1> 	;test	byte [VGA_MODESET_CTL], 1 ; VGA active
  2015                              <1> 	;jz	short csf_3
  2016 00001D9C 803D[9E690000]08    <1> 	cmp	byte [CHAR_HEIGHT], 8
  2017 00001DA3 7649                <1> 	jna	short csf_3
  2018 00001DA5 80FC08              <1> 	cmp	ah, 8
  2019 00001DA8 7344                <1> 	jnb	short csf_3
  2020 00001DAA 3C20                <1> 	cmp	al, 20h
  2021 00001DAC 7340                <1> 	jnb	short csf_3
  2022                              <1> 	;
  2023 00001DAE 6650                <1> 	push	ax
  2024                              <1> 	; {
  2025                              <1>    	; if(CL!=(CH+1))	
  2026 00001DB0 FEC0                <1> 	inc	al
  2027 00001DB2 38C4                <1> 	cmp	ah, al   ; ah != al + 1
  2028 00001DB4 740F                <1>         je      short csf_1
  2029                              <1> 	; CH = ((CH+1) * cheight / 8) -1;
  2030 00001DB6 8A25[9E690000]      <1> 	mov	ah, [CHAR_HEIGHT]
  2031 00001DBC F6E4                <1> 	mul	ah
  2032 00001DBE C0E803              <1> 	shr	al, 3 ; / 8
  2033 00001DC1 FEC8                <1> 	dec	al ; - 1
  2034 00001DC3 EB0E                <1> 	jmp	short csf_2 
  2035                              <1> csf_1: 	
  2036                              <1>  	; }
  2037                              <1>    	; else		; ah = al + 1
  2038                              <1>     	; {
  2039 00001DC5 FEC4                <1> 	inc	ah	; ah = ah + 1   
  2040                              <1> 	; CH = ((CL+1) * cheight / 8) - 2;
  2041 00001DC7 A0[9E690000]        <1> 	mov	al, [CHAR_HEIGHT]
  2042 00001DCC F6E4                <1> 	mul	ah
  2043 00001DCE C0E803              <1> 	shr	al, 3 ; / 8
  2044 00001DD1 2C02                <1> 	sub	al, 2 ; - 2
  2045                              <1> 	; al = 14 (if [CHAR_HEIGHT] = 16)
  2046                              <1> csf_2:
  2047 00001DD3 880424              <1> 	mov	[esp], al
  2048 00001DD6 8A642401            <1> 	mov	ah, [esp+1]
  2049                              <1> 	; CL = ((CL+1) * cheight / 8) - 1;
  2050 00001DDA FEC4                <1> 	inc	ah 
  2051 00001DDC A0[9E690000]        <1> 	mov	al, [CHAR_HEIGHT]
  2052 00001DE1 F6E4                <1> 	mul	ah
  2053 00001DE3 C0E803              <1> 	shr	al, 3 ; / 8
  2054 00001DE6 FEC8                <1> 	dec	al ; - 1
  2055 00001DE8 88442401            <1> 	mov	[esp+1], al
  2056                              <1> 	; ah = 15 (if [CHAR_HEIGHT] = 16)
  2057                              <1> 	;
  2058 00001DEC 6658                <1> 	pop	ax
  2059                              <1> csf_3:
  2060 00001DEE C3                  <1> 	retn
  2061                              <1> 
  2062                              <1> SET_CTYPE:
  2063                              <1> 	; 12/09/2016
  2064                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  2065 00001DEF 803D[9A690000]07    <1> 	cmp	byte [CRT_MODE], 7
  2066 00001DF6 0F875BFCFFFF        <1> 	ja	VIDEO_RETURN ; 12/09/2016
  2067 00001DFC E805000000          <1> 	call	_set_ctype
  2068 00001E01 E951FCFFFF          <1>         jmp     VIDEO_RETURN
  2069                              <1> 
  2070                              <1> _set_ctype:
  2071                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
  2072                              <1> 	;
  2073                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2074                              <1> 
  2075                              <1> 	; (CH) = BITS 4-0 = START LINE FOR CURSOR
  2076                              <1> 	;  ** HARDWARE WILL ALWAYS CAUSE BLINK
  2077                              <1> 	;  ** SETTING BIT 5 OR 6 WILL CAUSE ERRATIC BLINKING
  2078                              <1> 	;     OR NO CURSOR AT ALL
  2079                              <1> 	; (CL) = BITS 4-0 = END LINE FOR CURSOR
  2080                              <1> 
  2081                              <1> ;------------------------------------------------
  2082                              <1> ; SET_CTYPE
  2083                              <1> ;	THIS ROUTINE SETS THE CURSOR VALUE
  2084                              <1> ; INPUT
  2085                              <1> ;	(CX) HAS CURSOR VALUE CH-START LINE, CL-STOP LINE
  2086                              <1> ; OUTPUT	
  2087                              <1> ;	NONE
  2088                              <1> ;------------------------------------------------
  2089                              <1> 
  2090                              <1> 	; 07/07/2016
  2091                              <1> 	; Fixing cursor start and stop line depending on
  2092                              <1> 	; current character height (=16)
  2093                              <1> 	; (Note: Default/initial values are 6 and 7.
  2094                              <1> 	; If set values are 6 (start) & 7 (stop) and 
  2095                              <1> 	; [CHAR_HEIGHT] = 16 :
  2096                              <1> 	; After fixing, start line will be 14, stop line
  2097                              <1> 	; will be 15.)
  2098 00001E06 6689C8              <1> 	mov	ax, cx
  2099 00001E09 86C4                <1> 	xchg	al, ah
  2100                              <1> 	; AL = start line, AH = stop line
  2101 00001E0B E88CFFFFFF          <1> 	call	cursor_shape_fix
  2102                              <1> 	; AL = start line (fixed), AH = stop line (fixed)
  2103 00001E10 6689C1              <1> 	mov	cx, ax
  2104 00001E13 86E9                <1> 	xchg	ch, cl
  2105                              <1> 	; CH = start line (fixed), CL = stop line (fixed)
  2106                              <1> 	;
  2107 00001E15 B40A                <1> 	mov	ah, 10	; 6845 register for cursor set
  2108 00001E17 66890D[B3690000]    <1> 	mov	[CURSOR_MODE], cx ; save in data area
  2109                              <1> 	;call	m16	; output cx register
  2110                              <1> 	;retn
  2111 00001E1E E99F040000          <1>         jmp     m16
  2112                              <1> 
  2113                              <1> SET_CPOS:
  2114                              <1> 	; 12/09/2016
  2115                              <1> 	; 07/07/2016
  2116                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  2117 00001E23 80FF07              <1> 	cmp	bh, 7 ; video page > 7 ; 07/07/2016
  2118 00001E26 0F872BFCFFFF        <1> 	ja	VIDEO_RETURN
  2119                              <1> 	;
  2120 00001E2C 803D[9A690000]07    <1> 	cmp	byte [CRT_MODE], 7
  2121 00001E33 770A                <1> 	ja	short vga_set_cpos ; 12/09/2016	
  2122 00001E35 E85D040000          <1> 	call	_set_cpos
  2123 00001E3A E918FCFFFF          <1>         jmp     VIDEO_RETURN
  2124                              <1> 
  2125                              <1> vga_set_cpos:
  2126                              <1> 	; 12/09/2016
  2127                              <1> 	; 09/07/2016
  2128                              <1> 	; set cursor position
  2129                              <1> 	; NOTE: Hardware cursor position will not be set
  2130                              <1> 	;   in any VGA modes (>7)
  2131                              <1> 	;   But, cursor position will be saved into
  2132                              <1> 	;   [CURSOR_POSN].
  2133                              <1> 	;   TRDOS 386 (TRDOS v2.0) uses only one page
  2134                              <1> 	;   (page 0) for all graphics modes.
  2135                              <1> 
  2136 00001E3F 668915[F6630100]    <1> 	mov	[CURSOR_POSN], dx ; save cursor pos for pg 0
  2137                              <1> 	; 04/08/2016
  2138                              <1> 	;mov	bh, [ACTIVE_PAGE] ; = 0
  2139                              <1> 	;call	_set_cpos
  2140 00001E46 E90CFCFFFF          <1> 	jmp     VIDEO_RETURN
  2141                              <1> 
  2142                              <1> READ_CURSOR:
  2143                              <1> 	; 12/09/2016
  2144                              <1> 	; 07/07/2016
  2145                              <1> 	; 12/05/2016
  2146                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  2147                              <1> 	;
  2148                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2149                              <1> 
  2150                              <1> ;------------------------------------------------------
  2151                              <1> ; READ_CURSOR
  2152                              <1> ;	THIS ROUTINE READS THE CURRENT CURSOR VALUE FROM THE
  2153                              <1> ;	845, FORMATS IT, AND SENDS IT BACK TO THE CALLER
  2154                              <1> ; INPUT
  2155                              <1> ;	BH - PAGE OF CURSOR
  2156                              <1> ; OUTPUT
  2157                              <1> ;	DX - ROW, COLUMN OF THE CURRENT CURSOR POSITION
  2158                              <1> ;	CX - CURRENT CURSOR MODE
  2159                              <1> ;------------------------------------------------------
  2160                              <1> 
  2161                              <1> 	; BH = Video page number (0 to 7)
  2162                              <1> 
  2163                              <1> 	; 07/07/2016
  2164 00001E4B 80FF07              <1> 	cmp	bh, 7 ; video page > 7 (invalid)
  2165 00001E4E 7606                <1> 	jna	short read_cursor_1
  2166                              <1> 	; invalid video page (input) 
  2167 00001E50 31C9                <1> 	xor	ecx, ecx ; 0
  2168 00001E52 31D2                <1> 	xor	edx, edx ; 0
  2169 00001E54 EB15                <1> 	jmp	short read_cursor_2
  2170                              <1> read_cursor_1:
  2171                              <1> 	; 12/09/2016
  2172 00001E56 803D[9A690000]07    <1> 	cmp	byte [CRT_MODE], 7 ; vga mode
  2173 00001E5D 7727                <1> 	ja	short vga_get_cpos
  2174                              <1> 	;
  2175 00001E5F E815000000          <1> 	call	get_cpos
  2176 00001E64 0FB70D[B3690000]    <1> 	movzx	ecx, word [CURSOR_MODE]
  2177                              <1> read_cursor_2:
  2178 00001E6B 5D                  <1> 	pop	ebp
  2179 00001E6C 5F                  <1> 	pop	edi
  2180 00001E6D 5E                  <1> 	pop	esi
  2181 00001E6E 5B                  <1> 	pop	ebx
  2182 00001E6F 58                  <1> 	pop	eax  ; DISCARD SAVED CX AND DX
  2183 00001E70 58                  <1> 	pop	eax
  2184 00001E71 A1[60700100]        <1> 	mov	eax, [video_eax] ; 12/05/2016
  2185                              <1> 	;;15/01/2017
  2186                              <1> 	;;mov	byte [intflg], 0 ; 07/01/2017
  2187 00001E76 1F                  <1> 	pop	ds
  2188 00001E77 07                  <1> 	pop	es
  2189 00001E78 CF                  <1> 	iretd
  2190                              <1> 
  2191                              <1> get_cpos:
  2192                              <1> 	; 12/05/2016
  2193                              <1> 	; 16/01/2016
  2194                              <1> 	; BH = Video page number (0 to 7)
  2195                              <1> 	;
  2196 00001E79 D0E7                <1> 	shl	bh, 1 ; WORD OFFSET
  2197 00001E7B 0FB6F7              <1> 	movzx	esi, bh 
  2198 00001E7E 0FB796[F6630100]    <1> 	movzx	edx, word [esi+CURSOR_POSN]
  2199 00001E85 C3                  <1> 	retn
  2200                              <1> 
  2201                              <1> vga_get_cpos:
  2202                              <1> 	; 12/09/2016
  2203                              <1> 	; get cursor position (vga)
  2204 00001E86 0FB715[F6630100]    <1> 	movzx	edx, word [CURSOR_POSN] ; cursor pos for pg 0
  2205 00001E8D 31C9                <1> 	xor	ecx, ecx ; Cursor Mode = 0 (invalid)
  2206 00001E8F EBDA                <1> 	jmp     short read_cursor_2
  2207                              <1> 
  2208                              <1> ACT_DISP_PAGE:
  2209                              <1> 	; 07/07/2016
  2210                              <1> 	; 26/06/2016
  2211                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  2212                              <1> 	;
  2213                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2214                              <1> 	;
  2215                              <1> ;-----------------------------------------------------
  2216                              <1> ; ACT_DISP_PAGE
  2217                              <1> ;	THIS ROUTINE SETS THE ACTIVE DISPLAY PAGE, ALLOWING
  2218                              <1> ;	THE FULL USE OF THE MEMORY SET ASIDE FOR THE VIDEO ATTACHMENT
  2219                              <1> ; INPUT
  2220                              <1> ;	AL HAS THE NEW ACTIVE DISPLAY PAGE
  2221                              <1> ; OUTPUT
  2222                              <1> ;	THE 6845 IS RESET TO DISPLAY THAT PAGE
  2223                              <1> ;-----------------------------------------------------
  2224                              <1> 	; 07/07/2016
  2225 00001E91 3C07                <1> 	cmp	al, 7	; > 7 = invalid video page number
  2226                              <1> 	;ja	VIDEO_RETURN
  2227 00001E93 7715                <1>         ja	short adp_2 ; 18/11/2020
  2228                              <1> 	;cmp	byte [CRT_MODE], 3
  2229                              <1> 	;je	short adp_1
  2230                              <1> 	; 18/11/2020
  2231 00001E95 8A25[9A690000]      <1> 	mov	ah, [CRT_MODE]
  2232 00001E9B 80FC03              <1> 	cmp	ah, 3
  2233 00001E9E 7605                <1> 	jna	short adp_1 ; mode 01h, 00h (01h), 02h (03h), 03h
  2234 00001EA0 80FC07              <1> 	cmp	ah, 7	    ; mode 07h (03h)	
  2235 00001EA3 7505                <1> 	jne	short adp_2
  2236                              <1> 	;and 	al, al
  2237                              <1>         ;jnz	VIDEO_RETURN
  2238                              <1> 	;;sub	al, al ; 0 ; force to page 0
  2239                              <1> adp_1:	
  2240 00001EA5 E805000000          <1> 	call	set_active_page
  2241                              <1> adp_2:
  2242 00001EAA E9A8FBFFFF          <1>         jmp     VIDEO_RETURN
  2243                              <1> 
  2244                              <1> set_active_page:   ; tty_sw
  2245                              <1> 	; 09/12/2017
  2246                              <1> 	; 26/07/2016
  2247                              <1> 	; 26/06/2016
  2248                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  2249                              <1> 	; 30/06/2015
  2250                              <1> 	; 04/03/2014  (act_disp_page --> tty_sw)
  2251                              <1> 	; 10/12/2013
  2252                              <1> 	; 04/12/2013
  2253                              <1> 	;
  2254 00001EAF A2[06640100]        <1> 	mov	[ACTIVE_PAGE], al ; save active page value ; [ptty]
  2255                              <1> _set_active_page:
  2256                              <1> 	; 27/06/2015
  2257 00001EB4 0FB6D8              <1> 	movzx	ebx, al
  2258                              <1> 	;
  2259                              <1> 	;cbw	; 07/09/2014 (ah=0)
  2260 00001EB7 28E4                <1> 	sub	ah, ah ; 09/12/2017
  2261 00001EB9 66F725[70700100]    <1> 	mul	word [CRT_LEN]  ; get saved length of regen buffer
  2262                              <1> 				; display page times regen length
  2263                              <1> 	; 10/12/2013
  2264 00001EC0 66A3[F4630100]      <1> 	mov	[CRT_START], ax ; save start address for later
  2265 00001EC6 6689C1              <1> 	mov	cx, ax ; start address to cx
  2266                              <1> _M16:
  2267                              <1> 	;sar	cx, 1
  2268 00001EC9 66D1E9              <1> 	shr	cx, 1	; divide by 2 for 6845 handling
  2269 00001ECC B40C                <1> 	mov	ah, 12	; 6845 register for start address
  2270 00001ECE E8EF030000          <1> 	call	m16
  2271                              <1> 	;sal	bx, 1
  2272                              <1> 	; 01/09/2014
  2273 00001ED3 D0E3                <1> 	shl	bl, 1	; *2 for word offset
  2274 00001ED5 81C3[F6630100]      <1> 	add	ebx, CURSOR_POSN
  2275 00001EDB 668B13              <1> 	mov	dx, [ebx] ; get cursor for this page
  2276                              <1> 	; 16/01/2016
  2277                              <1> 	;call	m18
  2278                              <1> 	;retn
  2279 00001EDE E9CB030000          <1> 	jmp	m18
  2280                              <1> 
  2281                              <1> position:
  2282                              <1> 	; 24/06/2016
  2283                              <1> 	; 12/05/2016 - TRDOS 386 (TRDOS v2.0)
  2284                              <1> 	; 27/06/2015
  2285                              <1> 	; 02/09/2014
  2286                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  2287                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1)
  2288                              <1> 	;
  2289                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2290                              <1> 	;
  2291                              <1> ;-----------------------------------------
  2292                              <1> ; POSITION
  2293                              <1> ;	THIS SERVICE ROUTINE CALCULATES THE REGEN BUFFER ADDRESS
  2294                              <1> ;	OF A CHARACTER IN THE ALPHA MODE
  2295                              <1> ; INPUT
  2296                              <1> ;	AX = ROW, COLUMN POSITION
  2297                              <1> ; OUTPUT
  2298                              <1> ;	AX = OFFSET OF CHAR POSITION IN REGEN BUFFER
  2299                              <1> ;-----------------------------------------
  2300                              <1> 
  2301                              <1> 	; DX = ROW, COLUMN POSITION
  2302 00001EE3 0FB605[9C690000]    <1> 	movzx	eax, byte [CRT_COLS] ; 24/06/2016
  2303 00001EEA F6E6                <1> 	mul	dh	 ; row value
  2304 00001EEC 30F6                <1> 	xor	dh, dh   ; 0	
  2305 00001EEE 6601D0              <1> 	add	ax, dx	 ; add column value to the result
  2306 00001EF1 66D1E0              <1> 	shl	ax, 1	; * 2 for attribute bytes
  2307                              <1> 		; EAX = AX = OFFSET OF CHAR POSITION IN REGEN BUFFER 
  2308 00001EF4 C3                  <1> 	retn
  2309                              <1> 
  2310                              <1> find_position:
  2311                              <1> 	; 24/06/2016
  2312                              <1> 	; 12/05/2016 - TRDOS 386 (TRDOS v2.0)
  2313                              <1> 	; 27/06/2015
  2314                              <1> 	; 07/09/2014
  2315                              <1> 	; 02/09/2014
  2316                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  2317                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2318                              <1> 
  2319 00001EF5 0FB6CF              <1> 	movzx	ecx, bh ; video page number
  2320 00001EF8 89CE                <1> 	mov	esi, ecx
  2321 00001EFA 66D1E6              <1> 	shl	si, 1
  2322 00001EFD 668B96[F6630100]    <1> 	mov	dx, [esi+CURSOR_POSN]
  2323 00001F04 740C                <1> 	jz	short p21
  2324 00001F06 6631F6              <1> 	xor	si, si
  2325                              <1> p20:
  2326 00001F09 660335[70700100]    <1> 	add	si, [CRT_LEN] ; 24/06/2016
  2327                              <1> 	;add	si, 80*25*2 ; add length of buffer for one page		
  2328 00001F10 E2F7                <1> 	loop	p20
  2329                              <1> p21:
  2330 00001F12 6621D2              <1> 	and	dx, dx
  2331 00001F15 7407                <1> 	jz	short p22
  2332 00001F17 E8C7FFFFFF          <1> 	call 	position ; determine location in regen in page
  2333 00001F1C 01C6                <1> 	add	esi, eax ; add location to start of regen page
  2334                              <1> p22:	
  2335                              <1> 	;mov	dx, [addr_6845] ; get base address of active display			
  2336                              <1> 	;mov	dx, 03D4h ; I/O address of color card
  2337                              <1> 	;add	dx, 6	; point at status port
  2338 00001F1E 66BADA03            <1> 	mov	dx, 03DAh ; status port
  2339                              <1> 	; cx = 0
  2340 00001F22 C3                  <1> 	retn
  2341                              <1> 
  2342                              <1> SCROLL_UP:
  2343                              <1> 	; 07/07/2016
  2344                              <1> 	; 26/06/2016
  2345                              <1> 	; 12/05/2016
  2346                              <1> 	; 30/01/2016
  2347                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  2348                              <1> 	; 07/09/2014
  2349                              <1> 	; 02/09/2014
  2350                              <1> 	; 01/09/2014 (Retro UNIX 386 v1 - beginning)
  2351                              <1> 	; 04/04/2014
  2352                              <1> 	; 04/12/2013
  2353                              <1> 	;
  2354                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2355                              <1> 	;
  2356                              <1> ;----------------------------------------------
  2357                              <1> ; SCROLL UP
  2358                              <1> ;	THIS ROUTINE MOVES A BLOCK OF CHARACTERS UP
  2359                              <1> ;	ON THE SCREEN
  2360                              <1> ; INPUT
  2361                              <1> ;	(AH) = CURRENT CRT MODE
  2362                              <1> ;	(AL) = NUMBER OF ROWS TO SCROLL
  2363                              <1> ;	(CX) = ROW/COLUMN OF UPPER LEFT CORNER
  2364                              <1> ;	(DX) = ROW/COLUMN OF LOWER RIGHT CORNER
  2365                              <1> ;	(BH) = ATTRIBUTE TO BE USED ON BLANKED LINE
  2366                              <1> ;	(DS) = DATA SEGMENT
  2367                              <1> ;	(ES) = REGEN BUFFER SEGMENT
  2368                              <1> ; OUTPUT
  2369                              <1> ;	NONE -- THE REGEN BUFFER IS MODIFIED
  2370                              <1> ;--------------------------------------------
  2371                              <1> 
  2372                              <1> 	; 07/07/2016
  2373 00001F23 38F5                <1> 	cmp	ch, dh
  2374 00001F25 0F872CFBFFFF        <1> 	ja	VIDEO_RETURN
  2375 00001F2B 38D1                <1> 	cmp	cl, dl
  2376 00001F2D 0F8724FBFFFF        <1> 	ja	VIDEO_RETURN
  2377                              <1> 	;
  2378 00001F33 E805000000          <1> 	call	_scroll_up
  2379 00001F38 E91AFBFFFF          <1>         jmp     VIDEO_RETURN
  2380                              <1> 
  2381                              <1> _scroll_up:  ; from 'write_tty'
  2382                              <1> 	;
  2383                              <1> 	; cl = left upper column
  2384                              <1> 	; ch = left upper row
  2385                              <1> 	; dl = right lower column
  2386                              <1> 	; dh = right lower row
  2387                              <1> 	;
  2388                              <1> 	; al = line count 
  2389                              <1> 	; bl = attribute to be used on blanked line	
  2390                              <1> 	; bh = video page number (0 to 7)
  2391                              <1> 
  2392 00001F3D E89C000000          <1> 	call	test_line_count ; 16/01/2016
  2393                              <1> 
  2394 00001F42 8A25[9A690000]      <1> 	mov	ah, [CRT_MODE] ; current video mode	
  2395                              <1> 	;;cmp	byte [CRT_MODE], 4
  2396                              <1> 	;cmp	ah, 4 ; 07/07/2016
  2397                              <1> 	;jnb	GRAPHICS_UP ; 26/06/2016
  2398                              <1> 	; 18/11/2020
  2399 00001F48 80FC04              <1> 	cmp	ah, 4
  2400 00001F4B 720A                <1>  	jb	short n0	
  2401 00001F4D 80FC07              <1> 	cmp	ah, 7 ; TEST FOR BW CARD 
  2402                              <1> 		      ;	(80x25 text, mono)
  2403 00001F50 7405                <1> 	je	short n0 ; same with mode 3 for TRDOS 386
  2404 00001F52 E938050000          <1> 	jmp	GRAPHICS_UP
  2405                              <1> n0:
  2406                              <1> 	; 07/07/2016
  2407 00001F57 80FF07              <1> 	cmp	bh, 7 ; video page number
  2408 00001F5A 7606                <1> 	jna	short n1
  2409 00001F5C 8A3D[06640100]      <1> 	mov	bh, [ACTIVE_PAGE]
  2410                              <1> n1:
  2411 00001F62 88DC                <1> 	mov	ah, bl ; attribute
  2412 00001F64 6650                <1> 	push	ax ; *
  2413                              <1> 	;mov 	esi, [CRT_BASE]
  2414 00001F66 BE00800B00          <1>         mov     esi, 0B8000h  
  2415 00001F6B 3A3D[06640100]      <1>         cmp     bh, [ACTIVE_PAGE]
  2416 00001F71 750B                <1> 	jne	short n2
  2417                              <1> 	;
  2418 00001F73 66A1[F4630100]      <1>         mov     ax, [CRT_START]
  2419 00001F79 6601C6              <1>         add     si, ax
  2420 00001F7C EB11                <1>         jmp     short n4
  2421                              <1> n2:
  2422 00001F7E 20FF                <1>         and     bh, bh
  2423 00001F80 740D                <1> 	jz	short n4
  2424 00001F82 88F8                <1> 	mov	al, bh
  2425                              <1> n3:
  2426 00001F84 660335[70700100]    <1>         add	si, [CRT_LEN]
  2427 00001F8B FEC8                <1>         dec	al
  2428 00001F8D 75F5                <1> 	jnz	short n3
  2429                              <1> n4:	
  2430 00001F8F E85D000000          <1> 	call	scroll_position ; 16/01/2016
  2431 00001F94 7420                <1>         jz      short n6 
  2432                              <1> 
  2433 00001F96 01CE                <1>         add     esi, ecx ; from address for scroll
  2434 00001F98 88F5                <1> 	mov	ch, dh  ; #rows in block
  2435 00001F9A 28C5                <1> 	sub	ch, al	; #rows to be moved
  2436                              <1> n5:
  2437 00001F9C E894000000          <1> 	call	n10 ; 16/01/2016
  2438                              <1> 	
  2439 00001FA1 51                  <1>         push	ecx
  2440 00001FA2 0FB60D[9C690000]    <1> 	movzx	ecx, byte [CRT_COLS] 
  2441 00001FA9 00C9                <1> 	add	cl, cl
  2442 00001FAB 01CE                <1>         add	esi, ecx  ; next line
  2443 00001FAD 01CF                <1>         add	edi, ecx
  2444 00001FAF 59                  <1> 	pop	ecx
  2445                              <1> 
  2446 00001FB0 FECD                <1> 	dec	ch	 ; count of lines to move
  2447 00001FB2 75E8                <1> 	jnz	short n5 ; row loop
  2448                              <1> 	; ch = 0
  2449 00001FB4 88C6                <1> 	mov	dh, al	 ; #rows	
  2450                              <1> n6:
  2451                              <1> 	; attribute in ah
  2452 00001FB6 B020                <1> 	mov	al, ' '	 ; fill with blanks
  2453                              <1> n7:
  2454 00001FB8 E885000000          <1> 	call	n11 ; 16/01/2016
  2455                              <1> 
  2456 00001FBD 8A0D[9C690000]      <1> 	mov	cl, [CRT_COLS]
  2457 00001FC3 00C9                <1> 	add	cl, cl
  2458 00001FC5 01CF                <1>         add	edi, ecx
  2459                              <1> 
  2460 00001FC7 FECE                <1> 	dec	dh
  2461 00001FC9 75ED                <1> 	jnz	short n7
  2462                              <1> n16:
  2463 00001FCB 3A3D[06640100]      <1> 	cmp	bh, [ACTIVE_PAGE]
  2464 00001FD1 750A                <1> 	jne	short n8
  2465                              <1> 	
  2466                              <1> 	;cmp	byte [CRT_MODE], 7 ; is this the black and white card
  2467                              <1> 	;je	short n8	   ; if so, skip the mode reset
  2468                              <1> 
  2469 00001FD3 A0[9B690000]        <1> 	mov	al, [CRT_MODE_SET] ; get the value of mode set
  2470 00001FD8 66BAD803            <1> 	mov	dx, 03D8h ; always set color card port
  2471 00001FDC EE                  <1> 	out	dx, al
  2472                              <1> n8:
  2473 00001FDD C3                  <1> 	retn
  2474                              <1> 
  2475                              <1> test_line_count:
  2476                              <1> 	; 12/05/2016
  2477                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  2478                              <1> 	; 07/09/2014 (scroll_up)
  2479 00001FDE 08C0                <1> 	or	al, al
  2480 00001FE0 740E                <1> 	jz	short al_set2
  2481 00001FE2 6652                <1> 	push	dx
  2482 00001FE4 28EE                <1> 	sub	dh, ch  ; subtract upper row from lower row number
  2483 00001FE6 FEC6                <1> 	inc	dh	; adjust difference by 1
  2484 00001FE8 38C6                <1> 	cmp	dh, al 	; line count = amount of rows in window?
  2485 00001FEA 7502                <1> 	jne	short al_set1 ; if not the we're all set
  2486 00001FEC 30C0                <1> 	xor	al, al	; otherwise set al to zero
  2487                              <1> al_set1:
  2488 00001FEE 665A                <1> 	pop	dx
  2489                              <1> al_set2:
  2490 00001FF0 C3                  <1> 	retn
  2491                              <1> 
  2492                              <1> scroll_position:
  2493                              <1> 	; 26/06/2016
  2494                              <1> 	; 30/01/2016
  2495                              <1>         ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  2496                              <1> 	; 07/09/2014 (scroll_up)
  2497                              <1> 
  2498 00001FF1 6652                <1> 	push	dx
  2499 00001FF3 6689CA              <1> 	mov	dx, cx	; now, upper left position in DX
  2500 00001FF6 E8E8FEFFFF          <1> 	call	position
  2501 00001FFB 01C6                <1> 	add	esi, eax
  2502 00001FFD 89F7                <1> 	mov	edi, esi
  2503 00001FFF 665A                <1> 	pop	dx	; lower right position in DX
  2504 00002001 6629CA              <1> 	sub	dx, cx
  2505 00002004 FEC6                <1> 	inc	dh	; dh = #rows 
  2506 00002006 FEC2                <1> 	inc	dl	; dl = #cols in block
  2507 00002008 59                  <1> 	pop	ecx 	; return address
  2508 00002009 6658                <1> 	pop	ax	; * ; al = line count, ah = attribute
  2509 0000200B 51                  <1> 	push	ecx	; return address
  2510 0000200C 0FB7C8              <1> 	movzx	ecx, ax
  2511 0000200F 8A25[9C690000]      <1> 	mov	ah, [CRT_COLS]
  2512 00002015 F6E4                <1> 	mul	ah	; determine offset to from address
  2513 00002017 6601C0              <1> 	add	ax, ax  ; *2 for attribute byte
  2514                              <1> 	;
  2515 0000201A 6650                <1> 	push	ax	; offset 
  2516 0000201C 6652                <1> 	push	dx
  2517                              <1> 	;
  2518                              <1> 	; 04/04/2014
  2519 0000201E 66BADA03            <1> 	mov	dx, 3DAh ; guaranteed to be color card here	
  2520                              <1> n9:                      ; wait_display_enable
  2521 00002022 EC                  <1>         in      al, dx   ; get port
  2522 00002023 A808                <1> 	test	al, RVRT ; wait for vertical retrace	
  2523 00002025 74FB                <1> 	jz	short n9 ; wait_display_enable
  2524 00002027 B025                <1> 	mov	al, 25h
  2525 00002029 B2D8                <1> 	mov	dl, 0D8h ; address control port
  2526 0000202B EE                  <1> 	out	dx, al	; turn off video during vertical retrace
  2527 0000202C 665A                <1> 	pop	dx	; #rows, #cols
  2528 0000202E 6658                <1>        	pop	ax	; offset
  2529 00002030 6691                <1> 	xchg	ax, cx	; 
  2530                              <1> 	; ecx = offset, al = line count, ah = attribute
  2531                              <1> 	;
  2532 00002032 08C0                <1> 	or	al, al
  2533 00002034 C3                  <1> 	retn
  2534                              <1> n10:
  2535                              <1> 	; Move rows
  2536 00002035 88D1                <1> 	mov	cl, dl	; get # of cols to move
  2537 00002037 56                  <1> 	push	esi
  2538 00002038 57                  <1> 	push	edi	; save start address
  2539                              <1> n10r:
  2540 00002039 66A5                <1> 	movsw		; move that line on screen
  2541 0000203B FEC9                <1> 	dec	cl
  2542 0000203D 75FA                <1>         jnz     short n10r
  2543 0000203F 5F                  <1> 	pop	edi
  2544 00002040 5E                  <1> 	pop	esi	; recover addresses
  2545 00002041 C3                  <1> 	retn
  2546                              <1> n11:
  2547                              <1> 	; Clear rows
  2548                              <1>                 	; dh =  #rows
  2549 00002042 88D1                <1>         mov	cl, dl	; get # of cols to clear
  2550 00002044 57                  <1>         push    edi     ; save address
  2551                              <1> n11r:
  2552 00002045 66AB                <1>         stosw           ; store fill character
  2553 00002047 FEC9                <1> 	dec	cl
  2554 00002049 75FA                <1>         jnz     short n11r
  2555 0000204B 5F                  <1>         pop     edi     ; recover address
  2556 0000204C C3                  <1> 	retn
  2557                              <1> 
  2558                              <1> SCROLL_DOWN:
  2559                              <1> 	; 07/07/2016
  2560                              <1> 	; 27/06/2016
  2561                              <1> 	; 26/06/2016
  2562                              <1> 	; 12/05/2016
  2563                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  2564                              <1> 	;
  2565                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2566                              <1> 
  2567                              <1> ;------------------------------------------
  2568                              <1> ; SCROLL DOWN
  2569                              <1> ;	THIS ROUTINE MOVES THE CHARACTERS WITHIN A DEFINED
  2570                              <1> ;	BLOCK DOWN ON THE SCREEN, FILLING THE TOP LINES
  2571                              <1> ;	WITH A DEFINED CHARACTER
  2572                              <1> ; INPUT
  2573                              <1> ;	(AH) = CURRENT CRT MODE
  2574                              <1> ;	(AL) = NUMBER OF LINES TO SCROLL
  2575                              <1> ;	(CX) = UPPER LEFT CORNER OF RECION
  2576                              <1> ;	(DX) = LOWER RIGHT CORNER OF REGION
  2577                              <1> ;	(BH) = FILL CHARACTER
  2578                              <1> ;	(DS) = DATA SEGMENT
  2579                              <1> ;	(ES) = REGEN SEGMENT
  2580                              <1> ; OUTPUT
  2581                              <1> ;	NONE -- SCREEN IS SCROLLED
  2582                              <1> ;------------------------------------------
  2583                              <1> 
  2584                              <1> 	; 07/07/2016
  2585 0000204D 38F5                <1> 	cmp	ch, dh
  2586                              <1> 	;ja	VIDEO_RETURN
  2587 0000204F 7709                <1> 	ja	short _s_d_retn ; 18/11/2020
  2588 00002051 38D1                <1> 	cmp	cl, dl
  2589                              <1> 	;ja	VIDEO_RETURN
  2590 00002053 7705                <1> 	ja	short _s_d_retn ; 18/11/2020
  2591                              <1> 	;
  2592 00002055 E805000000          <1> 	call	_scroll_down
  2593                              <1> _s_d_retn:
  2594 0000205A E9F8F9FFFF          <1>         jmp     VIDEO_RETURN
  2595                              <1> 
  2596                              <1> _scroll_down: ; 27/06/2016
  2597                              <1> 
  2598                              <1> 	; cl = left upper column
  2599                              <1> 	; ch = left upper row
  2600                              <1> 	; dl = right lower column
  2601                              <1> 	; dh = right lower row
  2602                              <1> 	;
  2603                              <1> 	; al = line count 
  2604                              <1> 	; bl = attribute to be used on blanked line	
  2605                              <1> 	; bh = video page number (0 to 7)
  2606                              <1> 
  2607                              <1> 	; !!!!
  2608 0000205F FD                  <1> 	std		; DIRECTION FOR SCROLL DOWN
  2609                              <1> 	; !!!!
  2610 00002060 E879FFFFFF          <1> 	call	test_line_count ; 16/01/2016
  2611                              <1> 	
  2612 00002065 8A25[9A690000]      <1> 	mov	ah, [CRT_MODE] ; current video mode	
  2613                              <1> 	;;cmp	byte [CRT_MODE], 4
  2614                              <1> 	;cmp	ah, 4 ; 07/07/2016
  2615                              <1> 	;jnb	GRAPHICS_DOWN ; 26/06/2016
  2616                              <1> 	; 18/11/2020
  2617 0000206B 80FC04              <1> 	cmp	ah, 4
  2618 0000206E 720A                <1>  	jb	short _n0	
  2619 00002070 80FC07              <1> 	cmp	ah, 7 ; TEST FOR BW CARD 
  2620                              <1> 		      ;	(80x25 text, mono)
  2621 00002073 7405                <1> 	je	short _n0 ; same with mode 3 for TRDOS 386
  2622 00002075 E9F9070000          <1> 	jmp	GRAPHICS_DOWN
  2623                              <1> _n0:
  2624                              <1> 	; 07/07/2016
  2625 0000207A 80FF07              <1> 	cmp	bh, 7 ; video page number
  2626 0000207D 7606                <1> 	jna	short n12
  2627 0000207F 8A3D[06640100]      <1> 	mov	bh, [ACTIVE_PAGE]
  2628                              <1> 	;
  2629                              <1> n12:			; CONTINUE_DOWN
  2630 00002085 88DC                <1> 	mov	ah, bl
  2631 00002087 6650                <1> 	push	ax	; * ; save attribute in ah
  2632 00002089 6689D0              <1> 	mov	ax, dx	; LOWER RIGHT CORNER
  2633 0000208C E860FFFFFF          <1> 	call	scroll_position	; GET REGEN LOCATION
  2634 00002091 741F                <1> 	jz	short n14
  2635 00002093 29CE                <1> 	sub	esi, ecx  ; SI IS FROM ADDRESS
  2636 00002095 88F5                <1> 	mov	ch, dh  ; #rows in block
  2637 00002097 28C5                <1> 	sub	ch, al	; #rows to be moved
  2638                              <1> n13:
  2639 00002099 E897FFFFFF          <1> 	call	n10	; MOVE ONE ROW
  2640                              <1> 
  2641 0000209E 51                  <1> 	push	ecx
  2642 0000209F 8A0D[9C690000]      <1> 	mov	cl, [CRT_COLS] 
  2643 000020A5 00C9                <1> 	add	cl, cl
  2644 000020A7 29CE                <1>         sub	esi, ecx  ; next line
  2645 000020A9 29CF                <1>         sub	edi, ecx
  2646 000020AB 59                  <1>         pop	ecx
  2647                              <1> 	
  2648 000020AC FECD                <1> 	dec	ch	 ; count of lines to move
  2649 000020AE 75E9                <1> 	jnz	short n13 ; row loop
  2650                              <1> 	; ch = 0
  2651 000020B0 88C6                <1> 	mov	dh, al	 ; #rows
  2652                              <1> n14:
  2653                              <1> 	; attribute in ah
  2654 000020B2 B020                <1> 	mov	al, ' '	 ; fill with blanks
  2655                              <1> n15:
  2656 000020B4 E889FFFFFF          <1> 	call	n11 ; 16/01/2016
  2657                              <1> 
  2658 000020B9 8A0D[9C690000]      <1> 	mov	cl, [CRT_COLS]
  2659 000020BF 00C9                <1> 	add	cl, cl
  2660 000020C1 29CF                <1>         sub	edi, ecx
  2661                              <1>         
  2662 000020C3 FECE                <1> 	dec	dh
  2663 000020C5 75ED                <1> 	jnz	short n15
  2664                              <1> 	;
  2665                              <1> 	; 18/11/2020
  2666 000020C7 FC                  <1> 	cld	; clear direction flag	
  2667                              <1> 	;
  2668 000020C8 E9FEFEFFFF          <1> 	jmp	n16 ; 27/06/2016
  2669                              <1> 
  2670                              <1> ;	cmp	bh, [ACTIVE_PAGE]
  2671                              <1> ;	jne	short n16
  2672                              <1> ;
  2673                              <1> ;	;cmp	byte [CRT_MODE], 7	; is this the black and white card
  2674                              <1> ;	;je	short n16		; if so, skip the mode reset
  2675                              <1> ;
  2676                              <1> ;	mov	al, [CRT_MODE_SET] ; get the value of mode set
  2677                              <1> ;	mov	dx, 03D8h ; always set color card port
  2678                              <1> ;	out	dx, al
  2679                              <1> ;n16:
  2680                              <1> ;	; !!!!
  2681                              <1> ;	cld		; Clear direction flag !
  2682                              <1> ;	; !!!!
  2683                              <1> ;	retn
  2684                              <1> 
  2685                              <1> READ_AC_CURRENT:
  2686                              <1> 	; 08/07/2016
  2687                              <1> 	; 26/06/2016
  2688                              <1> 	; 12/05/2016
  2689                              <1> 	; 18/01/2016
  2690                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  2691                              <1> 	;
  2692                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2693                              <1> 	;
  2694                              <1> 	; 08/07/2016
  2695 000020CD 803D[9A690000]07    <1>         cmp     byte [CRT_MODE], 7 ; 6!?
  2696 000020D4 7607                <1> 	jna	short read_ac_c
  2697 000020D6 31C0                <1> 	xor	eax, eax
  2698 000020D8 E97FF9FFFF          <1>         jmp     _video_return 
  2699                              <1> read_ac_c:
  2700 000020DD E805000000          <1> 	call	_read_ac_current
  2701                              <1> 	; 12/05/2016
  2702                              <1>         ;jmp     VIDEO_RETURN
  2703 000020E2 E975F9FFFF          <1> 	jmp	_video_return
  2704                              <1> 
  2705                              <1> ;------------------------------------------------------------------------
  2706                              <1> ; READ_AC_CURRENT							:
  2707                              <1> ;	THIS ROUTINE READS THE ATTRIBUTE AND CHARACTER AT THE CURRENT	:
  2708                              <1> ;	CURSOR POSITION AND RETURNS THEM TO THE CALLER			:
  2709                              <1> ; INPUT									:
  2710                              <1> ;	(AH) = CURRENT CRT MODE						:
  2711                              <1> ;	(BH) = DISPLAY PAGE ( ALPHA MODES ONLY )			:
  2712                              <1> ;	(DS) = DATA SEGMENT						:
  2713                              <1> ;	(ES) = REGEN SEGMENT						:
  2714                              <1> ; OUTPUT								:
  2715                              <1> ;	(AL) = CHARACTER READ						:
  2716                              <1> ;	(AH) = ATTRIBUTE READ						:
  2717                              <1> ;------------------------------------------------------------------------
  2718                              <1> 
  2719                              <1> _read_ac_current:
  2720                              <1> 	; 26/06/2016
  2721                              <1> 	; 12/05/2016 
  2722                              <1> 	; 18/01/2016
  2723                              <1> 
  2724 000020E7 8A25[9A690000]      <1> 	mov	ah, [CRT_MODE] ; current video mode	
  2725 000020ED 80FC04              <1> 	cmp	ah, 4
  2726 000020F0 720A                <1>  	jb	short p10
  2727                              <1> 	; 18/11/2020
  2728                              <1> 	;cmp	byte [CRT_MODE], 4
  2729                              <1> 	;jnb	GRAPHICS_READ ; 26/06/2016
  2730                              <1> 
  2731 000020F2 80FC07              <1> 	cmp	ah, 7 ; TEST FOR BW CARD (80x25 monochrome text)
  2732 000020F5 7405                <1> 	je	short p10	 ; same with mode 3 in TRDOS 386
  2733 000020F7 E9CD080000          <1> 	jmp	GRAPHICS_READ
  2734                              <1> p10:
  2735 000020FC E8F4FDFFFF          <1> 	call	find_position	; GET REGEN LOCATION AND PORT ADDRESS
  2736                              <1> 	;
  2737                              <1> 	; esi = regen location
  2738                              <1> 	; dx = status port
  2739                              <1> 	;
  2740                              <1> 
  2741                              <1> 	; 18/11/2020
  2742                              <1> 	; convert display mode to a zero value 
  2743                              <1> 	; for 80 column color mode
  2744                              <1> 	;mov	ah, [CRT_MODE]	
  2745                              <1> 	;sub	ah, 2
  2746                              <1> 	;shr	ah, 1
  2747                              <1> 	;jnz	short p13
  2748                              <1> 
  2749                              <1> 	; 05/12/2020
  2750                              <1> 	; 18/11/2020 (TRDOS 386 v2.0.3)
  2751                              <1> 	;xor	bl, bl	; 0
  2752 00002101 803D[9A690000]03    <1> 	cmp	byte [CRT_MODE], 03h ; 80x25 color text
  2753                              <1> 	;je	short p11    ; Note: Only mode 03h and mode 01h are
  2754                              <1> 	;inc	bl	; 1  ;       in use by TRDOS 386 as text modes	
  2755                              <1> 	;jmp	short p14    ;       (07h, 00h and 02h are redirected)		
  2756 00002108 7516                <1> 	jne	short p13
  2757                              <1> 
  2758                              <1> 	; 05/12/2020
  2759 0000210A 3A3D[06640100]      <1> 	cmp     bh, [ACTIVE_PAGE]
  2760 00002110 750E                <1> 	jne	short p13 
  2761                              <1> 
  2762                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE IF COLOR 80
  2763                              <1> p11:
  2764 00002112 FB                  <1> 	sti		; enable interrupts first
  2765                              <1> 	; 05/12/2020
  2766 00002113 90                  <1> 	nop
  2767                              <1> 	; 18/11/2020
  2768                              <1> 	;or	bl, bl
  2769                              <1> 	;jnz	short p13 ; mode 01h (and mode 00h) - 40x25 color text
  2770 00002114 FA                  <1> 	cli 		; block interrupts for single loop
  2771 00002115 EC                  <1> 	in	al, dx	; get status from the adapter
  2772 00002116 A801                <1> 	test	al, RHRZ ; is horizontal retrace low
  2773 00002118 75F8                <1> 	jnz	short p11 ; wait until it is
  2774                              <1> p12:			;  wait for either retrace high
  2775 0000211A EC                  <1> 	in	al, dx ; get status again
  2776 0000211B A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
  2777 0000211D 74FB                <1> 	jz	short p12 ; wait until either retrace active
  2778                              <1> ;p14:
  2779 0000211F FB                  <1> 	sti
  2780                              <1> p13:
  2781 00002120 81C600800B00        <1> 	add	esi, 0B8000h 
  2782 00002126 668B06              <1> 	mov	ax, [esi]
  2783                              <1> 
  2784 00002129 C3                  <1> 	retn	; 18/01/2016
  2785                              <1> 
  2786                              <1> WRITE_AC_CURRENT:
  2787                              <1> 	; 08/07/2016
  2788                              <1> 	; 26/06/2016
  2789                              <1> 	; 24/06/2016
  2790                              <1> 	; 12/05/2016
  2791                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  2792                              <1> 	;
  2793                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2794                              <1> 	;
  2795                              <1> ;----------------------------------------------------------------
  2796                              <1> ; WRITE_AC_CURRENT						:
  2797                              <1> ;	THTS ROUTINE WRITES THE ATTRIBUTE AND CHARACTER		:
  2798                              <1> ;	AT THE CURRENT CURSOR POSITION				:
  2799                              <1> ; INPUT								:
  2800                              <1> ;	(AH) = CURRENT CRT MODE					:
  2801                              <1> ;	(BH) = DISPLAY PAGE					:
  2802                              <1> ;	(CX) = COUNT OF CHARACTERS TO WRITE			:
  2803                              <1> ;	(AL) = CHAR TO WRITE					:
  2804                              <1> ;	(BL) = ATTRIBUTE OF CHAR TO WRITE			:
  2805                              <1> ;	(DS) = DATA SEGMENT					:
  2806                              <1> ;	(ES) = REGEN SEGMENT					:
  2807                              <1> ; OUTPUT							:
  2808                              <1> ;	DISPLAY REGEN BUFFER UPDATED				:
  2809                              <1> ;----------------------------------------------------------------
  2810                              <1> 
  2811                              <1> 	; 08/07/2016
  2812 0000212A 803D[9A690000]07    <1> 	cmp	byte [CRT_MODE], 7 ; 6!?
  2813 00002131 760A                <1> 	jna	short write_ac_c
  2814                              <1> 
  2815 00002133 E8070B0000          <1> 	call	vga_write_char_attr
  2816 00002138 E91AF9FFFF          <1> 	jmp     VIDEO_RETURN	
  2817                              <1> 
  2818                              <1> write_ac_c:
  2819 0000213D E834000000          <1> 	call	_write_c_current
  2820                              <1> 
  2821 00002142 0FB6F7              <1> 	movzx	esi, bh ; video page number (0 to 7)	
  2822 00002145 889E[A3690000]      <1> 	mov	[esi+chr_attrib], bl ; color/attribute
  2823                              <1> 
  2824 0000214B E907F9FFFF          <1>         jmp     VIDEO_RETURN
  2825                              <1> 
  2826                              <1> WRITE_C_CURRENT:
  2827                              <1> 	; 08/07/2016
  2828                              <1> 	; 26/06/2016
  2829                              <1> 	; 12/05/2016
  2830                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  2831                              <1> 	;
  2832                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  2833                              <1> 	;
  2834                              <1> ;----------------------------------------------------------------
  2835                              <1> ; WRITE_C_CURRENT						:
  2836                              <1> ;	THIS ROUTINE WRITES THE CHARACTER AT			:
  2837                              <1> ;	THE CURRENT CURSOR POSITION, ATTRIBUTE UNCHANGED	:
  2838                              <1> ; INPUT								:
  2839                              <1> ;	(AH) = CURRENT CRT MODE					:
  2840                              <1> ;	(BH) = DISPLAY PAGE					:
  2841                              <1> ;	(CX) = COUNT OF CHARACTERS TO WRITE			:
  2842                              <1> ;	(AL) = CHAR TO WRITE					:
  2843                              <1> ;	(DS) = DATA SEGMENT					:
  2844                              <1> ;	(ES) = REGEN SEGMENT					:
  2845                              <1> ; OUTPUT							:
  2846                              <1> ;	DISPLAY REGEN BUFFER UPDATED				:
  2847                              <1> ;----------------------------------------------------------------
  2848                              <1> 
  2849                              <1> 	; 08/07/2016
  2850 00002150 803D[9A690000]07    <1> 	cmp	byte [CRT_MODE], 7 ; 6!?
  2851 00002157 760A                <1> 	jna	short write_c_c
  2852                              <1> 
  2853 00002159 E8E10A0000          <1> 	call	vga_write_char_only
  2854 0000215E E9F4F8FFFF          <1> 	jmp     VIDEO_RETURN	
  2855                              <1> 
  2856                              <1> write_c_c:
  2857                              <1> 	;and	bh, 7 ; video page number (<= 7)
  2858 00002163 0FB6F7              <1> 	movzx	esi, bh	
  2859 00002166 8A9E[A3690000]      <1> 	mov	bl, [esi+chr_attrib]
  2860                              <1> 
  2861 0000216C E805000000          <1> 	call	_write_c_current
  2862 00002171 E9E1F8FFFF          <1>         jmp     VIDEO_RETURN
  2863                              <1> 
  2864                              <1> _write_c_current:  ; from 'write_tty'
  2865                              <1> 	; 18/11/2020
  2866                              <1> 	; 26/06/2016
  2867                              <1> 	; 24/06/2016
  2868                              <1> 	; 12/05/2016
  2869                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  2870                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  2871                              <1> 	; 18/01/2014
  2872                              <1> 	; 04/12/2013
  2873                              <1> 	;
  2874                              <1> 	; VIDEO.ASM - 06/10/85 VIDEO DISPLAY BIOS
  2875                              <1> 
  2876                              <1> 	; 18/11/2020
  2877 00002176 8A25[9A690000]      <1> 	mov	ah, [CRT_MODE] ; current video mode	
  2878 0000217C 80FC04              <1> 	cmp	ah, 4
  2879 0000217F 720A                <1>  	jb	short p40
  2880                              <1> 	
  2881                              <1> 	;cmp	byte [CRT_MODE], 4
  2882                              <1>         ;jnb	GRAPHICS_WRITE ; 26/06/2016
  2883                              <1> 
  2884 00002181 80FC07              <1> 	cmp	ah, 7 ; TEST FOR BW CARD
  2885 00002184 7405                <1> 	je	short p40
  2886 00002186 E98E070000          <1> 	jmp	GRAPHICS_WRITE
  2887                              <1> p40:
  2888                              <1> 	; al = character
  2889                              <1> 	; bl = color/attribute
  2890                              <1> 	; bh = video page
  2891                              <1> 	; cx = count of characters to write
  2892 0000218B 6652                <1> 	push	dx
  2893 0000218D 88DC                <1> 	mov	ah, bl  ; color/attribute (12/05/2016)
  2894 0000218F 6650                <1> 	push	ax	; save character & attribute/color
  2895 00002191 6651                <1> 	push	cx
  2896 00002193 E85DFDFFFF          <1> 	call 	find_position  ; get regen location and port address
  2897 00002198 6659                <1> 	pop	cx
  2898                              <1> 	; esi = regen location
  2899                              <1> 	; dx = status port
  2900                              <1> 	;
  2901 0000219A 81C600800B00        <1> 	add	esi, 0B8000h ; 30/08/2014 (crt_base) 
  2902                              <1> 	;
  2903                              <1> 	; 18/11/2020
  2904                              <1> 	; convert display mode to a zero value 
  2905                              <1> 	; for 80 column color mode
  2906                              <1> 	;mov	ah, [CRT_MODE]	
  2907                              <1> 	;sub	ah, 2
  2908                              <1> 	;shr	ah, 1
  2909                              <1> 	;jnz	short p44    ; 26/06/2016
  2910                              <1> 
  2911                              <1> 	; 05/12/2020
  2912                              <1> 	; 18/11/2020 (TRDOS 386 v2.0.3)
  2913                              <1> 	;xor	bl, bl	; 0
  2914 000021A0 803D[9A690000]03    <1> 	cmp	byte [CRT_MODE], 03h ; 80x25 color text
  2915                              <1> 	;je	short p41    ; Note: Only mode 03h and mode 01h are
  2916                              <1> 	;inc	bl	; 1  ;       in use by TRDOS 386 as text modes	
  2917                              <1> 	;jmp	short p43    ;       (07h, 00h and 02h are redirected)			
  2918                              <1> 	; 05/12/2020
  2919 000021A7 751A                <1> 	jne	short p44
  2920                              <1> p46:
  2921                              <1> 	; 05/12/2020
  2922 000021A9 3A3D[06640100]      <1> 	cmp     bh, [ACTIVE_PAGE]
  2923 000021AF 7512                <1> 	jne	short p44
  2924                              <1> 
  2925                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE IF COLOR 80
  2926                              <1> p41:
  2927                              <1> 	; 05/12/2020
  2928 000021B1 FB                  <1> 	sti		; enable interrupts first
  2929 000021B2 90                  <1> 	nop
  2930                              <1> 	; 18/11/2020
  2931                              <1> 	;or	bl, bl
  2932                              <1> 	;jnz	short p44 ; mode 01h (and mode 00h) - 40x25 color text
  2933 000021B3 FA                  <1> 	cli 		; block interrupts for single loop
  2934 000021B4 EC                  <1> 	in	al, dx	; get status from the adapter
  2935 000021B5 A808                <1> 	test	al, RVRT ; check for vertical retrace first
  2936 000021B7 7509                <1> 	jnz	short p43 ; Do fast write now if vertical retrace
  2937 000021B9 A801                <1> 	test	al, RHRZ ; is horizontal retrace low
  2938 000021BB 75F4                <1> 	jnz	short p41 ; wait until it is
  2939                              <1> p42:			;  wait for either retrace high
  2940 000021BD EC                  <1> 	in	al, dx ; get status again
  2941 000021BE A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
  2942 000021C0 74FB                <1> 	jz	short p42 ; wait until either retrace active
  2943                              <1> p43:	
  2944 000021C2 FB                  <1> 	sti
  2945                              <1> p44:
  2946 000021C3 668B0424            <1> 	mov	ax, [esp] ; restore the character (al) & attribute (ah)
  2947 000021C7 668906              <1> 	mov	[esi], ax
  2948                              <1> 
  2949 000021CA 6649                <1> 	dec	cx
  2950 000021CC 740D                <1> 	jz	short p45
  2951                              <1> 
  2952 000021CE 46                  <1> 	inc	esi
  2953 000021CF 46                  <1> 	inc	esi
  2954                              <1> 
  2955                              <1> 	; 05/12/2020
  2956 000021D0 803D[9A690000]03    <1> 	cmp	byte [CRT_MODE], 03h
  2957 000021D7 75EA                <1> 	jne	short p44
  2958                              <1> 	;jmp	short p41
  2959 000021D9 EBCE                <1> 	jmp	short p46
  2960                              <1> p45:	
  2961 000021DB 6658                <1> 	pop	ax
  2962 000021DD 665A                <1> 	pop	dx
  2963 000021DF C3                  <1> 	retn
  2964                              <1> 
  2965                              <1> ; 09/07/2016
  2966                              <1> ; 26/06/2016
  2967                              <1> ; 24/06/2016
  2968                              <1> ; 12/05/2016
  2969                              <1> ; 18/01/2016
  2970                              <1> ; 16/01/2016 - TRDOS 386 (TRDOS v2.0)
  2971                              <1> ; 30/06/2015
  2972                              <1> ; 27/06/2015
  2973                              <1> ; 11/03/2015
  2974                              <1> ; 02/09/2014
  2975                              <1> ; 30/08/2014
  2976                              <1> ; VIDEO FUNCTIONS
  2977                              <1> ; (write_tty - Retro UNIX 8086 v1 - U9.ASM, 01/02/2014)
  2978                              <1> 
  2979                              <1> WRITE_TTY:
  2980                              <1> 	; 09/12/2017
  2981                              <1> 	; 09/07/2016
  2982                              <1> 	; 01/07/2016
  2983                              <1> 	; 26/06/2016
  2984                              <1> 	; 24/06/2016
  2985                              <1> 	; 13/05/2016
  2986                              <1> 	; 12/05/2016
  2987                              <1> 	; 30/01/2016
  2988                              <1> 	; 18/01/2016
  2989                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  2990                              <1> 	; 13/08/2015
  2991                              <1> 	; 02/09/2014
  2992                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  2993                              <1> 	; 01/02/2014 (Retro UNIX 8086 v1 - last update)
  2994                              <1> 	; 03/12/2013 (Retro UNIX 8086 v1 - beginning)	
  2995                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
  2996                              <1> 	;
  2997                              <1> 	; INPUT -> AL = Character to be written
  2998                              <1> 	;	   BL = Color (Forecolor, Backcolor)
  2999                              <1> 	;	   BH = Video Page (0 to 7)
  3000                              <1> 
  3001                              <1> 	; 09/07/2016
  3002 000021E0 803D[9A690000]07    <1>         cmp     byte [CRT_MODE], 7
  3003 000021E7 760A                <1> 	jna 	short write_tty_cga
  3004                              <1> 
  3005 000021E9 E8300D0000          <1> 	call	vga_write_teletype
  3006 000021EE E964F8FFFF          <1> 	jmp	VIDEO_RETURN
  3007                              <1> 
  3008                              <1> write_tty_cga:
  3009                              <1> 	; 13/05/2016
  3010                              <1> 	;call	_write_tty
  3011                              <1> 	; 01/07/2016
  3012 000021F3 E818000000          <1> 	call	_write_tty_m3
  3013 000021F8 E95AF8FFFF          <1> 	jmp	VIDEO_RETURN
  3014                              <1> 
  3015                              <1> RVRT	equ	00001000b	; VIDEO VERTICAL RETRACE BIT
  3016                              <1> RHRZ	equ	00000001b	; VIDEO HORIZONTAL RETRACE BIT
  3017                              <1> 
  3018                              <1> ; Derived from "WRITE_TTY" procedure of IBM "pc-at" rombios source code
  3019                              <1> ; (06/10/1985), 'video.asm', INT 10H, VIDEO_IO
  3020                              <1> ;
  3021                              <1> ; 06/10/85  VIDEO DISPLAY BIOS
  3022                              <1> ;
  3023                              <1> ;--- WRITE_TTY ------------------------------------------------------------------
  3024                              <1> ;										:
  3025                              <1> ;   THIS INTERFACE PROVIDES A TELETYPE LIKE INTERFACE TO THE			:
  3026                              <1> ;   VIDEO CARDS. THE INPUT CHARACTER IS WRITTEN TO THE CURRENT			:
  3027                              <1> ;   CURSOR POSITION, AND THE CURSOR IS MOVED TO THE NEXT POSITION.		:
  3028                              <1> ;   IF THE CURSOR LEAVES THE LAST COLUMN OF THE FIELD, THE COLUMN		:
  3029                              <1> ;   IS SET TO ZERO, AND THE ROW VALUE IS INCREMENTED. IF THE ROW		:
  3030                              <1> ;   ROW VALUE LEAVES THE FIELD, THE CURSOR IS PLACED ON THE LAST ROW,		:
  3031                              <1> ;   FIRST COLUMN, AND THE ENTIRE SCREEN IS SCROLLED UP ONE LINE.		:
  3032                              <1> ;   WHEN THE SCREEN IS SCROLLED UP, THE ATTRIBUTE FOR FILLING THE		:
  3033                              <1> ;   NEWLY BLANKED LINE IS READ FROM THE CURSOR POSITION ON THE PREVIOUS		:
  3034                              <1> ;   LINE BEFORE THE SCROLL, IN CHARACTER MODE. IN GRAPHICS MODE,		:
  3035                              <1> ;   THE 0 COLOR IS USED.							:
  3036                              <1> ;   ENTRY --									:
  3037                              <1> ;     (AH) = CURRENT CRT MODE							:
  3038                              <1> ;     (AL) = CHARACTER TO BE WRITTEN						:
  3039                              <1> ;	    NOTE THAT BACK SPACE, CARRIAGE RETURN, BELL AND LINE FEED ARE	:
  3040                              <1> ;	    HANDLED AS COMMANDS RATHER THAN AS DISPLAY GRAPHICS CHARACTERS	:
  3041                              <1> ;     (BL) = FOREGROUND COLOR FOR CHAR WRITE IF CURRENTLY IN A GRAPHICS MODE	:
  3042                              <1> ;   EXIT -- 									:
  3043                              <1> ;     ALL REGISTERS SAVED							:
  3044                              <1> ;--------------------------------------------------------------------------------
  3045                              <1> 
  3046                              <1> ; 18/11/2020 (TRDOS 386 v2.0.3)
  3047                              <1> ; 09/12/2017
  3048                              <1> ; 08/07/2016
  3049                              <1> ; 26/06/2016
  3050                              <1> ; 24/06/2016
  3051                              <1> _write_tty:
  3052                              <1> 	; 13/05/2016
  3053                              <1> 	; --- 18/11/2020 ---
  3054                              <1> 	; NOTE:
  3055                              <1> 	; Only kernel calls "_write_tty" procedure...
  3056                              <1> 	; TRDOS 386 v2 kernel uses video mode 3 for displaying
  3057                              <1> 	; (some error) messages and also mainprog command interpreter
  3058                              <1> 	; (in kernel) uses "_write_tty".
  3059                              <1> 	; So, here video mode must be set to 3 if it is not 3.
  3060                              <1>  
  3061 000021FD FA                  <1> 	cli	; disable interrupts
  3062                              <1> 	;
  3063                              <1> 	; 01/09/2014
  3064 000021FE 803D[9A690000]03    <1> 	cmp	byte [CRT_MODE], 3
  3065 00002205 7409                <1> 	je	short _write_tty_m3
  3066                              <1> 	;
  3067                              <1> set_mode_3:
  3068 00002207 53                  <1> 	push	ebx
  3069 00002208 50                  <1> 	push	eax
  3070                              <1> 	;call	_set_mode
  3071                              <1> 	; 18/11/2020 
  3072 00002209 E858F8FFFF          <1> 	call	set_txt_mode  ; set video mode to 03h 
  3073 0000220E 58                  <1> 	pop	eax
  3074 0000220F 5B                  <1> 	pop	ebx
  3075                              <1> 	;
  3076                              <1> _write_tty_m3: ; 24/06/2016 (m3 -> _write_tty_m3)
  3077 00002210 0FB6F7              <1> 	movzx 	esi, bh ; 12/05/2016
  3078 00002213 66D1E6              <1> 	shl	si, 1
  3079 00002216 81C6[F6630100]      <1> 	add	esi, CURSOR_POSN
  3080 0000221C 668B16              <1> 	mov	dx, [esi]
  3081                              <1> 	;
  3082                              <1> 	; dx now has the current cursor position
  3083                              <1> 	;
  3084 0000221F 3C0D                <1> 	cmp	al, 0Dh	; CR	; is it carriage return or control character
  3085 00002221 763E                <1> 	jbe	short u8
  3086                              <1> 	;
  3087                              <1> 	; write the char to the screen
  3088                              <1> u0:	
  3089                              <1> 	; al = character
  3090                              <1> 	; bl = attribute/color
  3091                              <1> 	; bh = video page number (0 to 7)
  3092                              <1> 	;
  3093 00002223 66B90100            <1> 	mov	cx, 1  ; 24/06/2016
  3094                              <1> 	; cx = count of characters to write
  3095                              <1> 	;
  3096 00002227 E84AFFFFFF          <1> 	call	_write_c_current ; 16/01/2015
  3097                              <1> 	;
  3098                              <1> 	; position the cursor for next char
  3099 0000222C FEC2                <1> 	inc	dl		; next column
  3100 0000222E 3A15[9C690000]      <1> 	cmp	dl, [CRT_COLS]  ; test for column overflow 
  3101 00002234 7561                <1>         jne     _set_cpos
  3102 00002236 B200                <1> 	mov	dl, 0		; column = 0
  3103                              <1> u10:				; (line feed found)
  3104 00002238 80FE18              <1> 	cmp	dh, 25-1 	; check for last row
  3105 0000223B 7220                <1> 	jb 	short u6
  3106                              <1> 	;
  3107                              <1> 	; scroll required
  3108                              <1> u1:	
  3109                              <1> 	; SET CURSOR POSITION (04/12/2013)
  3110 0000223D E855000000          <1> 	call	_set_cpos
  3111                              <1> 	;
  3112                              <1> 	; determine value to fill with during scroll
  3113                              <1> u2:
  3114                              <1> 	; bh = video page number
  3115                              <1> 	;
  3116 00002242 E8A0FEFFFF          <1> 	call	_read_ac_current ; 18/01/2016
  3117                              <1> 	;
  3118                              <1> 	; al = character, ah = attribute
  3119                              <1> 	; bh = video page number
  3120                              <1> 	; 18/11/2020
  3121 00002247 88E3                <1> 	mov	bl, ah ; color/attribute 	
  3122                              <1> u3:
  3123                              <1> 	;;mov	ax, 0601h 	; scroll one line
  3124                              <1> 	;;sub	cx, cx		; upper left corner
  3125                              <1> 	;;mov	dh, 25-1 	; lower right row
  3126                              <1> 	;;;mov	dl, [CRT_COLS]
  3127                              <1> 	;mov	dl, 80		; lower right column	
  3128                              <1> 	;;dec	dl
  3129                              <1> 	;;mov	dl, 79
  3130                              <1> 
  3131                              <1> 	;;call	scroll_up	; 04/12/2013
  3132                              <1> 	;;; 11/03/2015
  3133                              <1> 	; 02/09/2014
  3134                              <1> 	;;;mov	cx, [crt_ulc] ; Upper left corner  (0000h)
  3135                              <1> 	;;;mov	dx, [crt_lrc] ; Lower right corner (184Fh)
  3136                              <1> 	; 11/03/2015
  3137 00002249 6629C9              <1> 	sub	cx, cx
  3138                              <1> 	;mov	dx, 184Fh ; dl = 79 (column), dh = 24 (row)
  3139                              <1> 	; 18/11/2020
  3140 0000224C B618                <1> 	mov	dh, 25-1
  3141 0000224E 8A15[9C690000]      <1> 	mov	dl, [CRT_COLS]
  3142 00002254 FECA                <1> 	dec	dl
  3143                              <1> 	;
  3144 00002256 B001                <1> 	mov	al, 1		; scroll 1 line up
  3145                              <1> 		; ah = attribute
  3146                              <1> 	;mov	bl, al ; 12/05/2016
  3147 00002258 E9E0FCFFFF          <1> 	jmp	_scroll_up	; 16/01/2016
  3148                              <1> ;u4:
  3149                              <1> 	;;int	10h		; video-call return
  3150                              <1> 				; scroll up the screen
  3151                              <1> 				; tty return
  3152                              <1> ;u5:
  3153                              <1> 	;retn			; return to the caller
  3154                              <1> 
  3155                              <1> u6:				; set-cursor-inc
  3156 0000225D FEC6                <1> 	inc	dh		; next row
  3157                              <1> 				; set cursor
  3158                              <1> ;u7:					
  3159                              <1> 	;;mov	ah, 02h
  3160                              <1> 	;;jmp	short u4 	; establish the new cursor
  3161                              <1> 	;call	_set_cpos
  3162                              <1> 	;jmp 	short u5
  3163 0000225F EB36                <1> 	jmp     _set_cpos
  3164                              <1> 
  3165                              <1> 	; check for control characters
  3166                              <1> u8:
  3167 00002261 7432                <1> 	je	short u9
  3168 00002263 3C0A                <1> 	cmp	al, 0Ah		; is it a line feed (0Ah)
  3169 00002265 74D1                <1> 	je	short u10
  3170 00002267 3C07                <1> 	cmp	al, 07h 	; is it a bell
  3171 00002269 7476                <1> 	je	short u11
  3172 0000226B 3C08                <1> 	cmp	al, 08h		; is it a backspace
  3173                              <1> 	;jne	short u0
  3174 0000226D 741E                <1> 	je	short bs	; 12/12/2013
  3175                              <1> 	; 12/12/2013 (tab stop)
  3176 0000226F 3C09                <1> 	cmp	al, 09h		; is it a tab stop
  3177 00002271 75B0                <1> 	jne	short u0
  3178 00002273 88D0                <1> 	mov	al, dl
  3179                              <1> 	;cbw
  3180 00002275 30E4                <1> 	xor	ah, ah ; 09/12/2017
  3181 00002277 B108                <1> 	mov	cl, 8
  3182 00002279 F6F1                <1> 	div	cl
  3183 0000227B 28E1                <1> 	sub	cl, ah
  3184                              <1> ts:
  3185                              <1> 	; 02/09/2014
  3186                              <1> 	; 01/09/2014
  3187                              <1> 	;mov	al, 20h
  3188                              <1> tsloop:
  3189 0000227D 6651                <1> 	push	cx
  3190                              <1> 	; 18/11/2020
  3191                              <1> 	;push	ax
  3192                              <1> 	;;mov	bh, [ACTIVE_PAGE]
  3193                              <1> 	; 05/12/2020
  3194                              <1> 	;push	bx
  3195 0000227F B020                <1> 	mov	al, 20h ; al = space (blank) 
  3196                              <1> 			; bl = color/attribute
  3197 00002281 E88AFFFFFF          <1> 	call	_write_tty_m3 ; 24/06/2016 (m3 -> _write_tty_m3)
  3198                              <1> 	; 05/12/2020
  3199                              <1> 	; bx is preserved in '_write_tty_m3'
  3200                              <1> 	; 18/11/2020
  3201                              <1> 	;pop	bx  ; BL = color/attribute, Bh = video page 
  3202                              <1> 	;pop	ax  ; AL = character
  3203 00002286 6659                <1> 	pop	cx
  3204 00002288 FEC9                <1> 	dec	cl
  3205 0000228A 75F1                <1> 	jnz	short tsloop
  3206 0000228C C3                  <1> 	retn
  3207                              <1> bs:	
  3208                              <1> 	; back space found
  3209                              <1> 
  3210 0000228D 08D2                <1> 	or	dl, dl 		; is it already at start of line
  3211                              <1> 	;je	short u7 	; set_cursor
  3212 0000228F 7406                <1> 	jz	short _set_cpos
  3213 00002291 664A                <1> 	dec	dx     		; no -- just move it back
  3214                              <1> 	;jmp	short u7
  3215 00002293 EB02                <1> 	jmp	short _set_cpos
  3216                              <1> 
  3217                              <1> 	; carriage return found
  3218                              <1> u9:
  3219 00002295 B200                <1> 	mov	dl, 0 		; move to first column
  3220                              <1> 	;jmp	short u7
  3221                              <1> 	;jmp	short _set_cpos ; 30/01/2016
  3222                              <1> 
  3223                              <1> 	; line feed found
  3224                              <1> ;u10:
  3225                              <1> ;	cmp	dh, 25-1 	; bottom of screen
  3226                              <1> ;	jne	short u6 	; no, just set the cursor
  3227                              <1> ;       jmp     u1              ; yes, scroll the screen
  3228                              <1> 
  3229                              <1> _set_cpos:
  3230                              <1> 	; 12/05/2016 - TRDOS 386 (TRDOS v2.0)
  3231                              <1> 	; 27/06/2015
  3232                              <1> 	; 01/09/2014
  3233                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  3234                              <1> 	;
  3235                              <1> 	; 04/12/2013 - 12/12/2013 (Retro UNIX 8086 v1) 
  3236                              <1> 	;
  3237                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  3238                              <1> 	;
  3239                              <1> ;----------------------------------------------
  3240                              <1> ; SET_CPOS
  3241                              <1> ;	THIS ROUTINE SETS THE CURRENT CURSOR POSITION TO THE
  3242                              <1> ;	NEW X-Y VALUES PASSED
  3243                              <1> ; INPUT
  3244                              <1> ;	DX - ROW,COLUMN OF NEW CURSOR
  3245                              <1> ;	BH - DISPLAY PAGE OF CURSOR
  3246                              <1> ; OUTPUT
  3247                              <1> ;	CURSOR ID SET AT 6845 IF DISPLAY PAGE IS CURRENT DISPLAY
  3248                              <1> ;----------------------------------------------
  3249                              <1> 	;
  3250 00002297 BE[F6630100]        <1> 	mov	esi, CURSOR_POSN
  3251 0000229C 0FB6C7              <1>         movzx   eax, bh	; BH = video page number
  3252                              <1> ;	or	al, al
  3253                              <1> ;	jz	short _set_cpos_0
  3254 0000229F D0E0                <1>         shl     al, 1   ; word offset
  3255 000022A1 01C6                <1>         add     esi, eax
  3256                              <1> ;_set_cpos_0:
  3257 000022A3 668916              <1> 	mov	[esi], dx ; save the pointer
  3258 000022A6 383D[06640100]      <1> 	cmp	[ACTIVE_PAGE], bh
  3259 000022AC 7532                <1> 	jne	short m17
  3260                              <1> 	;call	m18	; CURSOR SET
  3261                              <1> ;m17:			; SET_CPOS_RETURN
  3262                              <1> 	; 01/09/2014
  3263                              <1> ;	retn
  3264                              <1> 		; DX  = row/column
  3265                              <1> m18:
  3266 000022AE E830FCFFFF          <1> 	call	position ; determine location in regen buffer	
  3267 000022B3 668B0D[F4630100]    <1> 	mov	cx, [CRT_START]
  3268 000022BA 6601C1              <1> 	add	cx, ax  ; add char position in regen buffer
  3269                              <1> 			; to the start address (offset) for this page
  3270 000022BD 66D1E9              <1> 	shr	cx, 1	; divide by 2 for char only count
  3271 000022C0 B40E                <1> 	mov	ah, 14	; register number for cursor
  3272                              <1> 	;call	m16	; output value to the 6845	
  3273                              <1> 	;retn
  3274                              <1> 
  3275                              <1> 	;-----	THIS ROUTINE OUTPUTS THE CX REGISTER
  3276                              <1> 	;	TO THE 6845 REGISTERS NAMED IN (AH)
  3277                              <1> m16:
  3278 000022C2 FA                  <1> 	cli
  3279                              <1> 	;mov	dx, [addr_6845] ; address register
  3280 000022C3 66BAD403            <1> 	mov 	dx, 03D4h ; I/O address of color card
  3281 000022C7 88E0                <1> 	mov	al, ah	; get value
  3282 000022C9 EE                  <1> 	out	dx, al	; register set
  3283 000022CA 6642                <1> 	inc	dx	; data register
  3284 000022CC EB00                <1> 	jmp	$+2	; i/o delay
  3285 000022CE 88E8                <1> 	mov	al, ch	; data
  3286 000022D0 EE                  <1> 	out	dx, al	
  3287 000022D1 664A                <1> 	dec	dx	
  3288 000022D3 88E0                <1> 	mov	al, ah
  3289 000022D5 FEC0                <1> 	inc	al	; point to other data register
  3290 000022D7 EE                  <1> 	out	dx, al	; set for second register
  3291 000022D8 6642                <1> 	inc	dx
  3292 000022DA EB00                <1> 	jmp	$+2	; i/o delay
  3293 000022DC 88C8                <1> 	mov	al, cl	; second data value
  3294 000022DE EE                  <1> 	out	dx, al
  3295 000022DF FB                  <1> 	sti
  3296                              <1> m17:
  3297 000022E0 C3                  <1> 	retn
  3298                              <1> 
  3299                              <1> beeper: 
  3300                              <1> 	; 04/08/2016
  3301                              <1> 	; 12/05/2016 - TRDOS 386 (TRDOS v2.0)
  3302                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  3303                              <1> 	; 18/01/2014
  3304                              <1> 	; 03/12/2013
  3305                              <1> 	; bell found
  3306                              <1> u11:
  3307 000022E1 FB                  <1> 	sti
  3308 000022E2 3A3D[06640100]      <1> 	cmp	bh, [ACTIVE_PAGE]
  3309 000022E8 7551                <1> 	jne	short u12	; Do not sound the beep 
  3310                              <1> 				; if it is not written on the active page
  3311                              <1> beeper_gfx: ; 04/08/2016
  3312 000022EA 66B93305            <1> 	mov	cx, 1331 	; divisor for 896 hz tone
  3313 000022EE B31F                <1> 	mov	bl, 31		; set count for 31/64 second for beep
  3314                              <1> 	;call	beep		; sound the pod bell
  3315                              <1> 	;jmp	short u5 	; tty_return
  3316                              <1> 	;retn
  3317                              <1> 	
  3318                              <1> TIMER	equ 	040h   		; 8254 TIMER - BASE ADDRESS
  3319                              <1> PORT_B	equ	061h		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  3320                              <1> GATE2	equ	00000001b	; TIMER 2 INPUT CATE CLOCK BIT
  3321                              <1> SPK2	equ	00000010b	; SPEAKER OUTPUT DATA ENABLE BIT
  3322                              <1> 
  3323                              <1> beep:
  3324                              <1> 	; 07/02/2015
  3325                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  3326                              <1> 	; 18/01/2014
  3327                              <1> 	; 03/12/2013
  3328                              <1> 	;
  3329                              <1> 	; TEST4.ASM - 06/10/85  POST AND BIOS UTILITY ROUTINES
  3330                              <1> 	;
  3331                              <1> 	; ROUTINE TO SOUND THE BEEPER USING TIMER 2 FOR TONE
  3332                              <1> 	;
  3333                              <1> 	; ENTRY:
  3334                              <1> 	;    (BL) = DURATION COUNTER ( 1 FOR 1/64 SECOND )
  3335                              <1> 	;    (CX) = FREQUENCY DIVISOR (1193180/FREQUENCY) (1331 FOR 886 HZ)
  3336                              <1> 	; EXIT:				:
  3337                              <1> 	;    (AX),(BL),(CX) MODIFIED.
  3338                              <1> 
  3339 000022F0 9C                  <1> 	pushf  ; 18/01/2014	; save interrupt status
  3340 000022F1 FA                  <1> 	cli			; block interrupts during update
  3341 000022F2 B0B6                <1> 	mov	al, 10110110b	; select timer 2, lsb, msb binary
  3342 000022F4 E643                <1> 	out	TIMER+3, al 	; write timer mode register
  3343 000022F6 EB00                <1> 	jmp	$+2		; I/O delay
  3344 000022F8 88C8                <1> 	mov	al, cl		; divisor for hz (low)
  3345 000022FA E642                <1> 	out	TIMER+2,AL	; write timer 2 count - lsb
  3346 000022FC EB00                <1> 	jmp	$+2		; I/O delay
  3347 000022FE 88E8                <1> 	mov	al, ch		; divisor for hz (high)
  3348 00002300 E642                <1> 	out	TIMER+2, al	; write timer 2 count - msb
  3349 00002302 E461                <1> 	in	al, PORT_B	; get current setting of port
  3350 00002304 88C4                <1> 	mov	ah, al		; save that setting
  3351 00002306 0C03                <1> 	or	al, GATE2+SPK2	; gate timer 2 and turn speaker on
  3352 00002308 E661                <1> 	out	PORT_B, al	; and restore interrupt status
  3353                              <1> 	;popf	; 18/01/2014
  3354 0000230A FB                  <1> 	sti
  3355                              <1> g7:				; 1/64 second per count (bl)
  3356 0000230B B90B040000          <1> 	mov	ecx, 1035	; delay count for 1/64 of a second	
  3357 00002310 E827000000          <1> 	call	waitf		; go to beep delay 1/64 count
  3358 00002315 FECB                <1> 	dec	bl		; (bl) length count expired?
  3359 00002317 75F2                <1> 	jnz	short g7	; no - continue beeping speaker
  3360                              <1> 	;
  3361                              <1> 	;pushf			; save interrupt status
  3362 00002319 FA                  <1> 	cli  	; 18/01/2014	; block interrupts during update
  3363 0000231A E461                <1> 	in	al, PORT_B	; get current port value
  3364                              <1>         ;or      al, not (GATE2+SPK2) ; isolate current speaker bits in case
  3365 0000231C 0CFC                <1>         or      al, ~(GATE2+SPK2)
  3366 0000231E 20C4                <1>         and	ah, al		; someone turned them off during beep
  3367 00002320 88E0                <1> 	mov	al, ah		; recover value of port
  3368                              <1>         ;or      al, not (GATE2+SPK2) ; force speaker data off
  3369 00002322 0CFC                <1> 	or 	al, ~(GATE2+SPK2) ; isolate current speaker bits in case
  3370 00002324 E661                <1> 	out	PORT_B, al	; and stop speaker timer
  3371                              <1> 	;popf			; restore interrupt flag state
  3372 00002326 FB                  <1> 	sti
  3373 00002327 B90B040000          <1> 	mov	ecx, 1035	; force 1/64 second delay (short)
  3374 0000232C E80B000000          <1> 	call	waitf		; minimum delay between all beeps
  3375                              <1> 	;pushf			; save interrupt status
  3376 00002331 FA                  <1> 	cli			; block interrupts during update
  3377 00002332 E461                <1> 	in	al, PORT_B	; get current port value in case	
  3378 00002334 2403                <1> 	and	al, GATE2+SPK2	; someone turned them on
  3379 00002336 08E0                <1> 	or	al, ah		; recover value of port_b
  3380 00002338 E661                <1> 	out	PORT_B, al	; restore speaker status
  3381 0000233A 9D                  <1> 	popf			; restore interrupt flag state
  3382                              <1> u12:	
  3383 0000233B C3                  <1> 	retn
  3384                              <1> 
  3385                              <1> REFRESH_BIT equ	00010000b 	; REFRESH TEST BIT
  3386                              <1> 
  3387                              <1> WAITF:
  3388                              <1> waitf:
  3389                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  3390                              <1> 	; 03/12/2013
  3391                              <1> 	;
  3392                              <1> ;	push ax			; save work register (ah)	
  3393                              <1> ;waitf1:
  3394                              <1> 				; use timer 1 output bits
  3395                              <1> ;	in	al, PORT_B	; read current counter output status
  3396                              <1> ;	and	al, REFRESH_BIT	; mask for refresh determine bit
  3397                              <1> ;	cmp	al, ah		; did it just change
  3398                              <1> ;	je	short waitf1	; wait for a change in output line
  3399                              <1> ;	;
  3400                              <1> ;	mov	ah, al		; save new lflag state
  3401                              <1> ;	loop	waitf1		; decrement half cycles till count end		
  3402                              <1> ;	;
  3403                              <1> ;	pop	ax		; restore (ah)
  3404                              <1> ;	retn			; return (cx)=0
  3405                              <1> 
  3406                              <1> ; 06/02/2015 (unix386.s <-- dsectrm2.s)
  3407                              <1> ; 17/12/2014 (dsectrm2.s)
  3408                              <1> ; WAITF
  3409                              <1> ; /// IBM PC-XT Model 286 System BIOS Source Code - Test 4 - 06/10/85 ///
  3410                              <1> ;
  3411                              <1> ;---WAITF-----------------------------------------------------------------------
  3412                              <1> ;	FIXED TIME WAIT ROUTINE (HARDWARE CONTROLLED - NOT PROCESSOR)
  3413                              <1> ; ENTRY:
  3414                              <1> ;	(CX) =	COUNT OF 15.085737 MICROSECOND INTERVALS TO WAIT
  3415                              <1> ;	      	MEMORY REFRESH TIMER 1 OUTPUT USED AS REFERENCE
  3416                              <1> ; EXIT:
  3417                              <1> ;	       	AFTER (CX) TIME COUNT (PLUS OR MINUS 16 MICROSECONDS)
  3418                              <1> ;	(CX) = 0	
  3419                              <1> ;-------------------------------------------------------------------------------
  3420                              <1> 
  3421                              <1> ; Refresh period: 30 micro seconds (15-80 us)
  3422                              <1> ; (16/12/2014 - AWARDBIOS 1999 - ATORGS.ASM, WAIT_REFRESH)
  3423                              <1> 
  3424                              <1> ;WAITF:					; DELAY FOR (CX)*15.085737 US
  3425 0000233C 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER (AH)
  3426                              <1> 	; 16/12/2014
  3427                              <1> 	;shr	cx, 1			; convert to count of 30 micro seconds
  3428 0000233E D1E9                <1> 	shr	ecx, 1	; 21/02/2015
  3429                              <1> ;17/12/2014	
  3430                              <1> ;WAITF1:
  3431                              <1> ;	IN	AL, PORT_B   ;061h	; READ CURRENT COUNTER OUTPUT STATUS
  3432                              <1> ;	AND	AL, REFRESH_BIT	;00010000b ; MASK FOR REFRESH DETERMINE BIT
  3433                              <1> ;	CMP	AL, AH			; DID IT JUST CHANGE
  3434                              <1> ;	JE	short WAITF1		; WAIT FOR A CHANGE IN OUTPUT LINE
  3435                              <1> ;	MOV	AH, AL			; SAVE NEW FLAG STATE
  3436                              <1> ;	LOOP	WAITF1			; DECREMENT HALF CYCLES TILL COUNT END		
  3437                              <1> 	;
  3438                              <1> 	; 17/12/2014
  3439                              <1> 	;
  3440                              <1> 	; Modification from 'WAIT_REFRESH' procedure of AWARD BIOS - 1999
  3441                              <1> 	;
  3442                              <1> ;WAIT_REFRESH:  Uses port 61, bit 4 to have CPU speed independent waiting.
  3443                              <1> ;   	INPUT:  CX = number of refresh periods to wait
  3444                              <1> ;     	       (refresh periods = 1 per 30 microseconds on most machines)
  3445                              <1> WR_STATE_0:
  3446 00002340 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  3447 00002342 A810                <1> 	TEST	AL,010H
  3448 00002344 74FA                <1> 	JZ	SHORT WR_STATE_0
  3449                              <1> WR_STATE_1:
  3450 00002346 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  3451 00002348 A810                <1> 	TEST	AL,010H
  3452 0000234A 75FA                <1> 	JNZ	SHORT WR_STATE_1
  3453 0000234C E2F2                <1>         LOOP    WR_STATE_0
  3454                              <1> 	;
  3455 0000234E 6658                <1> 	POP	AX			; RESTORE (AH)
  3456 00002350 C3                  <1> 	RETn				; (CX) = 0
  3457                              <1> 
  3458                              <1> ; 09/07/2016
  3459                              <1> ; 01/07/2016
  3460                              <1> ; 24/06/2016
  3461                              <1> ; 23/06/2016 - TRDOS 386 (TRDOS v2.0)
  3462                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  3463                              <1> ;-------------------------------------------------------------------------------
  3464                              <1> ; WRITE_STRING								       :
  3465                              <1> ;	THIS ROUTINE WRITES A STRING OF CHARACTERS TO THE CRT.		       :
  3466                              <1> ; INPUT 								       :
  3467                              <1> ;	(AL) = WRITE STRING COMMAND  0 - 3				       :
  3468                              <1> ;	(BH) = DISPLAY PAGE (ACTIVE PAGE)				       :
  3469                              <1> ;	(CX) = COUNT OF CHARACTERS TO WRITE, IF (CX) = 0 THEN RETURN	       :
  3470                              <1> ;	(DX) = CURSOR POSITION FOR START OF STRING WRITE		       :
  3471                              <1> ;	(BL) = ATTRIBUTE OF CHARACTER TO WRITE IF (AL) = 0  OR	(AL) = 1       :
  3472                              <1> ;	(eBP) = SOURCE STRING OFFSET					       :
  3473                              <1> ; OUTPUT								       :
  3474                              <1> ;	NONE								       :
  3475                              <1> ;-------------------------------------------------------------------------------
  3476                              <1> 
  3477                              <1> ; AL = 00h: Assign all characters the attribute in BL; do not update cursor
  3478                              <1> ; AL = 01h: Assign all characters the attribute in BL; update cursor
  3479                              <1> ; AL = 02h: Use attributes in string; do not update cursor
  3480                              <1> ; AL = 03h: Use attributes in string; update cursor
  3481                              <1> 
  3482                              <1> WRITE_STRING:
  3483                              <1> 	; 12/09/2016
  3484                              <1> 	; 09/07/2016
  3485                              <1> 	;cmp	byte [CRT_MODE], 7 ; 6?!
  3486                              <1> 	;ja	VIDEO_RETURN		; not a valid function for VGA modes
  3487                              <1> 	;
  3488 00002351 A2[6C700100]        <1> 	mov	[w_str_cmd], al		; save (AL) command
  3489 00002356 3C04                <1> 	CMP	AL, 4			; TEST FOR INVALID WRITE STRING OPTION
  3490 00002358 0F83F9F6FFFF        <1> 	JNB	VIDEO_RETURN		; IF OPTION INVALID THEN RETURN
  3491                              <1> 
  3492                              <1>         ;JCXZ   VIDEO_RETURN            ; IF ZERO LENGTH STRING THEN RETURN
  3493                              <1> 
  3494 0000235E 67E362              <1>         jcxz    P55			; 01/07/2016
  3495                              <1> 
  3496                              <1> 	; 01/07/2016
  3497                              <1> 	;and	ecx, 0FFFFh
  3498                              <1> 	; ECX = byte count
  3499                              <1> 	;push	ecx
  3500 00002361 89EE                <1> 	mov	esi, ebp ; user buffer
  3501 00002363 BF00000700          <1> 	mov	edi, Cluster_Buffer  ; system buffer
  3502 00002368 E86ECF0000          <1> 	call	transfer_from_user_buffer
  3503                              <1> 	;pop	ecx
  3504 0000236D 0F82E4F6FFFF        <1> 	jc	VIDEO_RETURN
  3505                              <1> 	; ecx = transfer (byte) count = character count
  3506 00002373 BD00000700          <1> 	mov	ebp, Cluster_Buffer
  3507                              <1> 	; 12/09/2016
  3508 00002378 803D[9A690000]07    <1> 	cmp	byte [CRT_MODE], 7 ; 6?!
  3509 0000237F 0F87A1000000        <1> 	ja	vga_write_string
  3510                              <1> 	;
  3511 00002385 0FB6F7              <1> 	movzx	esi, bh			; GET CURRENT CURSOR PAGE
  3512 00002388 66D1E6              <1> 	SAL	SI, 1			; CONVERT TO PAGE OFFSET  (SI= PAGE)
  3513                              <1> 	; *****
  3514 0000238B 66FFB6[F6630100]    <1> 	PUSH	word [eSI+CURSOR_POSN]	; SAVE CURRENT CURSOR POSITION IN STACK
  3515                              <1> 
  3516                              <1> 	;MOV	AX,0200H		; SET NEW CURSOR POSITION
  3517                              <1> 	;INT	10H
  3518                              <1> P50next:	
  3519 00002392 51                  <1> 	push	ecx ; ****
  3520 00002393 53                  <1> 	push	ebx ; *** ; 18/11/2020
  3521 00002394 56                  <1> 	push	esi ; **
  3522 00002395 52                  <1> 	push	edx ; *
  3523 00002396 E8FCFEFFFF          <1> 	call	_set_cpos
  3524                              <1> P50:
  3525 0000239B 8A4500              <1> 	MOV	AL, [eBP]		; GET CHARACTER FROM INPUT STRING
  3526 0000239E 45                  <1> 	INC	eBP			; BUMP POINTER TO CHARACTER
  3527                              <1> 
  3528                              <1> ;-----	TEST FOR SPECIAL CHARACTER'S
  3529                              <1> 
  3530 0000239F 3C08                <1> 	CMP	AL, 08H			; IS IT A BACKSPACE
  3531 000023A1 7410                <1> 	JE	short P51		; BACK_SPACE
  3532 000023A3 3C0D                <1> 	CMP	AL, 0Dh ; CR		; IS IT CARRIAGE RETURN
  3533 000023A5 740C                <1> 	JE	short P51		; CAR_RET
  3534 000023A7 3C0A                <1> 	CMP	AL, 0Ah ; LF		; IS IT A LINE FEED
  3535 000023A9 7408                <1> 	JE	short P51		; LINE_FEED
  3536                              <1> 	; 18/11/2020
  3537 000023AB 3C09                <1> 	cmp	al, 09h			; is it a tab stop
  3538 000023AD 7404                <1> 	je	short P51
  3539                              <1> 	;
  3540 000023AF 3C07                <1> 	CMP	AL, 07h			; IS IT A BELL
  3541 000023B1 7515                <1> 	JNE	short P52		; IF NOT THEN DO WRITE CHARACTER
  3542                              <1> P51:
  3543                              <1> 	;MOV	AH,0EH			; TTY_CHARACTER_WRITE
  3544                              <1> 	;INT	10H			; WRITE TTY CHARACTER TO THE CRT
  3545                              <1> 	
  3546 000023B3 E858FEFFFF          <1> 	call	_write_tty_m3
  3547                              <1> 
  3548 000023B8 5A                  <1> 	pop	edx ; *
  3549 000023B9 5E                  <1> 	pop	esi ; **
  3550                              <1> 
  3551 000023BA 668B96[F6630100]    <1> 	MOV	DX, [eSI+CURSOR_POSN]	; GET CURRENT CURSOR POSITION
  3552 000023C1 EB44                <1> 	JMP	SHORT P54		; SET CURSOR POSITION AND CONTINUE
  3553                              <1> P55:
  3554 000023C3 E98FF6FFFF          <1> 	JMP	VIDEO_RETURN
  3555                              <1> P52:
  3556 000023C8 66B90100            <1> 	MOV	CX, 1			; SET CHARACTER WRITE AMOUNT TO ONE
  3557 000023CC 803D[6C700100]02    <1> 	CMP	byte [w_str_cmd], 2	; IS THE ATTRIBUTE IN THE STRING
  3558 000023D3 7204                <1> 	JB	short P53		; IF NOT THEN SKIP
  3559 000023D5 8A5D00              <1> 	MOV	BL, [eBP]		; ELSE GET NEW ATTRIBUTE
  3560 000023D8 45                  <1> 	INC	eBP			; BUMP STRING POINTER
  3561                              <1> P53:
  3562                              <1> 	;MOV	AH,09H			; GOT_CHARACTER
  3563                              <1> 	;INT	10H			; WRITE CHARACTER TO THE CRT
  3564                              <1> 
  3565 000023D9 E898FDFFFF          <1> 	call	_write_c_current
  3566                              <1> 	
  3567 000023DE 5A                  <1> 	pop	edx ; *	
  3568                              <1> 
  3569                              <1> 	; 05/12/2020
  3570                              <1> 	; bx is preserved in '_write_c_current'
  3571                              <1> 	; 18/11/2020
  3572                              <1> 	;mov	ebx, [esp+4]	; ***
  3573                              <1> 
  3574 000023DF 0FB6F7              <1> 	movzx	esi, bh ; video page number (0 to 7)	
  3575 000023E2 889E[A3690000]      <1> 	mov	[esi+chr_attrib], bl ; color/attribute
  3576                              <1> 
  3577 000023E8 FEC2                <1> 	INC	DL			; INCREMENT COLUMN COUNTER
  3578 000023EA 3A15[9C690000]      <1> 	CMP	DL, [CRT_COLS]		; IF COLS ARE WITHIN RANGE FOR THIS MODE
  3579                              <1> 	;JB	short P54		;    THEN GO TO COLUMNS SET
  3580 000023F0 7214                <1> 	jb	short P56 ; 05/12/2020
  3581 000023F2 FEC6                <1> 	INC	DH			; BUMP ROW COUNTER BY ONE
  3582 000023F4 28D2                <1> 	SUB	DL, DL			; SET COLUMN COUNTER TO ZERO
  3583 000023F6 80FE19              <1> 	CMP	DH, 25			; IF ROWS ARE LESS THAN 25 THEN
  3584                              <1> 	;JB	short P54		; GO TO ROWS_COLUMNS_SET
  3585 000023F9 720B                <1> 	jb	short P56 ; 05/12/2020
  3586                              <1> 
  3587                              <1> 	; 18/11/2020
  3588                              <1> 	;MOV	AX,0E0AH		; ELSE SCROLL SCREEN
  3589                              <1> 	;INT	10H			; RESET ROW COUNTER TO 24
  3590                              <1> 
  3591                              <1> 	; 18/11/2020
  3592 000023FB B00A                <1> 	mov	al, 0Ah	; line feed
  3593                              <1> 
  3594 000023FD E80EFEFFFF          <1> 	call	_write_tty_m3
  3595                              <1> 	
  3596 00002402 66BA0018            <1> 	mov	dx, 1800h		; Column = 0, Row = 24
  3597                              <1> P56:	
  3598                              <1> 	; 05/12/2020
  3599                              <1> 	; 18/11/2020
  3600 00002406 5E                  <1> 	pop	esi ; **
  3601                              <1> P54:					; ROW_COLUMNS_SET
  3602                              <1> 	;MOV	AX,0200H		; SET NEW CURSOR POSITION COMMAND
  3603                              <1> 	;INT	10H			; ESTABLISH NEW CURSOR POSITION
  3604                              <1> 
  3605                              <1> 	; 18/11/2020
  3606 00002407 5B                  <1> 	pop	ebx ; ***
  3607 00002408 59                  <1> 	pop	ecx ; ****
  3608                              <1> 
  3609                              <1> 	;LOOP	P50			; DO IT ONCE MORE UNTIL (CX) = ZERO
  3610 00002409 6649                <1> 	dec	cx
  3611 0000240B 7585                <1> 	jnz	short P50next
  3612                              <1> 
  3613 0000240D 665A                <1> 	POP	DX  ; *****		; RESTORE OLD CURSOR COORDINATES
  3614                              <1> 	
  3615 0000240F F605[6C700100]01    <1> 	test	byte [w_str_cmd], 1	; IF CURSOR WAS NOT TO BE MOVED
  3616 00002416 0F853BF6FFFF        <1> 	JNZ	VIDEO_RETURN		; THEN EXIT WITHOUT RESETTING OLD VALUE
  3617                              <1> 	
  3618                              <1> 	;MOV	AX,0200H		; ELSE RESTORE OLD CURSOR POSITION
  3619                              <1> 	;INT	10H
  3620                              <1> 					; DONE - EXIT WRITE STRING
  3621 0000241C E876FEFFFF          <1> 	call	_set_cpos
  3622 00002421 E931F6FFFF          <1> 	JMP	VIDEO_RETURN		; RETURN TO CALLER
  3623                              <1> 
  3624                              <1> vga_write_string:
  3625                              <1> 	; 12/09/2016 - TRDOS 386 (TRDOS v2.0)
  3626                              <1> 	;
  3627                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  3628                              <1> 	; vgabios-0.7a (2011)
  3629                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  3630                              <1> 	; 'vgabios.c', ' biosfn_write_string'
  3631                              <1> 
  3632                              <1> 	; INPUT 								  :
  3633                              <1> 	;	(AL) = WRITE STRING COMMAND  0 - 3				  :
  3634                              <1> 	;	(BH) = DISPLAY PAGE (ACTIVE PAGE)				  :
  3635                              <1> 	;	(CX) = COUNT OF CHARACTERS TO WRITE, IF (CX) = 0 THEN RETURN	  :
  3636                              <1> 	;	(DX) = CURSOR POSITION FOR START OF STRING WRITE		  :
  3637                              <1> 	;	(BL) = ATTRIBUTE OF CHARACTER TO WRITE IF (AL) = 0  OR	(AL) = 1  :
  3638                              <1> 	;	(eBP) = SOURCE STRING OFFSET					  :
  3639                              <1> 	; OUTPUT								  :
  3640                              <1> 	;	NONE								  :
  3641                              <1> 	;-------------------------------------------------------------------------;
  3642                              <1> 
  3643                              <1> 	; AL = 00h: Assign all characters the attribute in BL; do not update cursor
  3644                              <1> 	; AL = 01h: Assign all characters the attribute in BL; update cursor
  3645                              <1> 	; AL = 02h: Use attributes in string; do not update cursor
  3646                              <1> 	; AL = 03h: Use attributes in string; update cursor
  3647                              <1> 	
  3648                              <1> 	; biosfn_write_string(GET_AL(),GET_BH(),GET_BL(),CX,GET_DH(),GET_DL(),ES,BP);
  3649                              <1> 	; static void biosfn_write_string (flag,page,attr,count,row,col,seg,offset) 
  3650                              <1> 
  3651                              <1> 	; // Read curs info for the page
  3652                              <1>  	; biosfn_get_cursor_pos(page,&dummy,&oldcurs);
  3653                              <1> 	; bh = video page = 0
  3654                              <1> 	;movzx	esi, word [CURSOR_POSN] ; current cursor position for video page 0
  3655                              <1> 	
  3656                              <1> 	; // if row=0xff special case : use current cursor position
  3657                              <1> 	; if(row==0xff)
  3658                              <1> 	;  {col=oldcurs&0x00ff;
  3659                              <1> 	;   row=(oldcurs&0xff00)>>8;
  3660                              <1> 	;  }
  3661                              <1> 
  3662                              <1> 	;mov	al, [w_str_cmd]
  3663                              <1> 
  3664 00002426 80FEFF              <1> 	cmp	dh, 0FFh
  3665 00002429 7407                <1> 	je	short vga_wstr_1 ; user current cursor position
  3666                              <1> vga_wstr_0:
  3667                              <1> 	; set cursor position
  3668 0000242B 668915[F6630100]    <1> 	mov	[CURSOR_POSN], dx ; save cursor pos for pg 0
  3669                              <1> vga_wstr_1:
  3670 00002432 66FF35[F6630100]    <1> 	push	word [CURSOR_POSN] ; *
  3671                              <1> 
  3672                              <1> 	; ebp = string offset in system buffer (user buffer was copied to)	
  3673                              <1> 	
  3674                              <1> 	; while(count--!=0)
  3675                              <1> 	;  {
  3676                              <1> 	;   car=read_byte(seg,offset++);
  3677                              <1> 	;   if((flag&0x02)!=0)
  3678                              <1> 	;    attr=read_byte(seg,offset++);
  3679                              <1> 	;    biosfn_write_teletype(car,page,attr,WITH_ATTR);
  3680                              <1> 	;  }
  3681                              <1> 
  3682                              <1> 	;push	eax ; **
  3683                              <1> 	;test	al, 2
  3684 00002439 F605[6C700100]02    <1> 	test	byte [w_str_cmd], 2
  3685 00002440 751D                <1> 	jnz	short vga_wstr_3
  3686 00002442 881D[07640100]      <1> 	mov	[ccolor], bl
  3687                              <1> vga_wstr_2:
  3688 00002448 51                  <1> 	push	ecx
  3689 00002449 8A4500              <1> 	mov	al, [ebp]
  3690 0000244C E8CD0A0000          <1> 	call	vga_write_teletype
  3691 00002451 59                  <1> 	pop	ecx
  3692 00002452 6649                <1> 	dec	cx
  3693 00002454 741E                <1> 	jz	short vga_wstr_4
  3694 00002456 45                  <1> 	inc	ebp
  3695 00002457 8A1D[07640100]      <1> 	mov	bl, [ccolor]
  3696 0000245D EBE9                <1> 	jmp	short vga_wstr_2
  3697                              <1> vga_wstr_3:
  3698 0000245F 51                  <1> 	push	ecx
  3699 00002460 8A4500              <1> 	mov	al, [ebp]
  3700 00002463 45                  <1> 	inc	ebp
  3701 00002464 8A5D00              <1> 	mov	bl, [ebp]
  3702 00002467 E8B20A0000          <1> 	call	vga_write_teletype
  3703 0000246C 59                  <1> 	pop	ecx
  3704 0000246D 6649                <1> 	dec	cx
  3705 0000246F 7403                <1> 	jz	short vga_wstr_4
  3706 00002471 45                  <1> 	inc	ebp
  3707 00002472 EBEB                <1> 	jmp	short vga_wstr_3
  3708                              <1> vga_wstr_4:
  3709                              <1> 	; // Set back curs pos 
  3710                              <1> 	; if((flag&0x01)==0)
  3711                              <1> 	;  biosfn_set_cursor_pos(page,oldcurs);
  3712                              <1> 	; }
  3713                              <1> 	;pop	eax ; **
  3714 00002474 665A                <1> 	pop	dx ; word [CURSOR_POSN] ; *
  3715                              <1> 	;test	al, 1
  3716 00002476 F605[6C700100]01    <1> 	test	byte [w_str_cmd], 1
  3717 0000247D 0F85D4F5FFFF        <1> 	jnz	VIDEO_RETURN
  3718 00002483 668915[F6630100]    <1> 	mov 	[CURSOR_POSN], dx
  3719 0000248A E9C8F5FFFF          <1> 	JMP	VIDEO_RETURN
  3720                              <1> 
  3721                              <1> ; 07/07/2016
  3722                              <1> ; 27/06/2016 - TRDOS 386 (TRDOS v2.0)
  3723                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  3724                              <1> ;------------------------------------------------------
  3725                              <1> ;  SCROLL UP
  3726                              <1> ;   THIS ROUTINE SCROLLS UP THE INFORMATION ON THE CRT
  3727                              <1> ; ENTRY ---
  3728                              <1> ;  CH,CL = UPPER LEFT CORNER OF REGION TO SCROLL
  3729                              <1> ;  DH,DL = LOWER RIGHT CORNER OF REGION TO SCROLL
  3730                              <1> ;   BOTH OF THE ABOVE ARE IN CHARACTER POSITIONS
  3731                              <1> ;  BH = FILL VALUE FOR BLANKED LINES
  3732                              <1> ;  AL = # LINES TO SCROLL (AL=0 MEANS BLANK THE ENTIRE FIELD)
  3733                              <1> ;  DS = DATA SEGMENT
  3734                              <1> ;  ES = REGEN SEGMENT
  3735                              <1> ; EXIT --
  3736                              <1> ;  NOTHING, THE SCREEN IS SCROLLED
  3737                              <1> ;--------------------------------------------------------
  3738                              <1> 
  3739                              <1> 	; cl = upper left column
  3740                              <1> 	; ch = upper left row
  3741                              <1> 	; dl = lower rigth column
  3742                              <1> 	; dh = lower right row
  3743                              <1> 	;
  3744                              <1> 	; al = line count (AL=0 means blank entire fields)
  3745                              <1> 	; bl = fill value for blanked lines	
  3746                              <1> 	; bh = unused
  3747                              <1> 
  3748                              <1> GRAPHICS_UP:
  3749                              <1> 	; 07/07/2016
  3750                              <1> 	;AH = Current video mode, [CRT_MODE]
  3751 0000248F 80FC07              <1> 	cmp	ah, 7
  3752 00002492 7766                <1> 	ja	short vga_graphics_up
  3753                              <1> 	;je	n0
  3754                              <1> 
  3755 00002494 88C7                <1> 	MOV	bh, al			; save line count in BH
  3756 00002496 6689C8              <1> 	MOV	AX, CX			; GET UPPER LEFT POSITION INTO AX REG
  3757                              <1> 
  3758                              <1> ;-----	USE CHARACTER SUBROUTINE FOR POSITIONING
  3759                              <1> ;-----	ADDRESS RETURNED IS MULTIPLIED BY 2 FROM CORRECT VALUE
  3760                              <1> 
  3761 00002499 E8DA050000          <1> 	CALL	GRAPH_POSN
  3762 0000249E 0FB7F8              <1> 	MOVzx	eDI, AX			; SAVE RESULT AS DESTINATION ADDRESS
  3763                              <1> 
  3764                              <1> ;-----	DETERMINE SIZE OF WINDOW
  3765                              <1> 
  3766 000024A1 6629CA              <1> 	SUB	DX, CX
  3767 000024A4 6681C20101          <1>         ADD     DX, 101h                ; ADJUST VALUES
  3768 000024A9 C0E602              <1> 	SAL	DH, 2			; MULTIPLY ROWS BY 4 AT 8 VERT DOTS/CHAR
  3769                              <1> 					; AND EVEN/ODD ROWS
  3770                              <1> ;-----	DETERMINE CRT MODE
  3771                              <1> 
  3772 000024AC 803D[9A690000]06    <1> 	CMP	byte [CRT_MODE], 6	; TEST FOR MEDIUM RES
  3773 000024B3 7305                <1>         JNC     short _R7_              ; FIND_SOURCE
  3774                              <1> 
  3775                              <1> ;-----	MEDIUM RES UP
  3776 000024B5 D0E2                <1> 	SAL	DL, 1			; # COLUMNS * 2, SINCE 2 BYTES/CHAR
  3777 000024B7 66D1E7              <1> 	SAL	DI, 1			; OFFSET *2 SINCE 2 BYTES/CHAR
  3778                              <1> 
  3779                              <1> ;-----	DETERMINE THE SOURCE ADDRESS IN THE BUFFER
  3780                              <1> _R7_:                                   ; FIND_SOURCE
  3781 000024BA 81C700800B00        <1> 	add	edi, 0B8000h
  3782 000024C0 C0E702              <1> 	sal	bh, 2			; multiply number of lines by 4
  3783 000024C3 7431                <1>         JZ      short _R11              ; IF ZERO, THEN BLANK ENTIRE FIELD
  3784 000024C5 B050                <1> 	MOV	AL, 80			; 80 BYTES/ROW
  3785 000024C7 F6E7                <1> 	mul	bh			; determine offset to source
  3786 000024C9 0FB7F0              <1> 	movzx	esi, ax			; offset to source
  3787 000024CC 01FE                <1> 	add	eSI, eDI		; SET UP SOURCE
  3788 000024CE 88F4                <1> 	MOV	AH, DH			; NUMBER OF ROWS IN FIELD
  3789 000024D0 28FC                <1> 	sub	ah, bh			; determine number to move
  3790                              <1> 
  3791                              <1> ;-----	LOOP THROUGH, MOVING ONE ROW AT A TIME, BOTH EVEN AND ODD FIELDS
  3792                              <1> _R8:                                    ; ROW_LOOP
  3793 000024D2 E813040000          <1>         CALL    _R17                    ; MOVE ONE ROW
  3794 000024D7 6681EEB01F          <1> 	SUB	SI, 2000h-80		; MOVE TO NEXT ROW
  3795 000024DC 6681EFB01F          <1> 	SUB	DI, 2000h-80
  3796 000024E1 FECC                <1> 	DEC	AH			; NUMBER OF ROWS TO MOVE
  3797 000024E3 75ED                <1>         JNZ     short _R8               ; CONTINUE TILL ALL MOVED
  3798                              <1> 
  3799                              <1> ;-----	FILL IN THE VACATED LINE(S)
  3800                              <1> _R9:                                    ; CLEAR ENTRY
  3801 000024E5 88D8                <1> 	mov	al, bl			; attribute to fill with
  3802                              <1> _R10_:
  3803 000024E7 E81A040000          <1>         CALL    _R18                    ; CLEAR THAT ROW
  3804 000024EC 6681EFB01F          <1> 	SUB	DI, 2000h-80		; POINT TO NEXT LINE
  3805 000024F1 FECF                <1> 	dec	bh			; number of lines to fill
  3806 000024F3 75F2                <1>         JNZ     short _R10_             ; CLEAR LOOP
  3807 000024F5 C3                  <1> 	retn				; EVERYYHING DONE
  3808                              <1> 
  3809                              <1> _R11:                                   ; BLANK_FIELD
  3810 000024F6 88F7                <1> 	mov	bh, dh			; set blank count to everything in field
  3811 000024F8 EBEB                <1>         JMP     short _R9               ; CLEAR THE FIELD
  3812                              <1> 
  3813                              <1> vga_graphics_up:
  3814                              <1> 	; 08/08/2016
  3815                              <1> 	; 07/08/2016
  3816                              <1> 	; 04/08/2016
  3817                              <1> 	; 01/08/2016
  3818                              <1> 	; 31/07/2016
  3819                              <1> 	; 07/07/2016 - TRDOS 386 (TRDOS v2.0)
  3820                              <1> 	;
  3821                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  3822                              <1> 	; vgabios-0.7a (2011)
  3823                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  3824                              <1> 	; 'vgabios.c', 'biosfn_scroll'
  3825                              <1> 	;
  3826                              <1> 
  3827                              <1> 	; cl = upper left column
  3828                              <1> 	; ch = upper left row
  3829                              <1> 	; dl = lower rigth column
  3830                              <1> 	; dh = lower right row
  3831                              <1> 	;
  3832                              <1> 	; al = line count (AL=0 means blank entire fields)
  3833                              <1> 	; bl = fill value for blanked lines	
  3834                              <1> 	; bh = unused
  3835                              <1> 	;
  3836                              <1> 	; ah = [CRT_MODE], current video mode	
  3837                              <1> 
  3838 000024FA 88C7                <1> 	mov	bh, al ; 31/07/2016
  3839 000024FC BE[BE690000]        <1> 	mov	esi, vga_g_modes
  3840 00002501 89F7                <1> 	mov	edi, esi
  3841 00002503 83C708              <1> 	add	edi, vga_g_mode_count
  3842                              <1> vga_g_up_0:
  3843 00002506 AC                  <1> 	lodsb
  3844 00002507 38E0                <1> 	cmp	al, ah ; [CRT_MODE]
  3845 00002509 7405                <1> 	je	short vga_g_up_1
  3846 0000250B 39FE                <1> 	cmp	esi, edi
  3847 0000250D 72F7                <1> 	jb	short vga_g_up_0
  3848                              <1> 	;xor	bh, bh ; 31/07/2016)
  3849 0000250F C3                  <1> 	retn	; nothing to do
  3850                              <1> vga_g_up_1:
  3851 00002510 88F8                <1> 	mov	al, bh ; 31/07/2016
  3852 00002512 83C64F              <1> 	add	esi, vga_g_memmodel - (vga_g_modes + 1)  
  3853                              <1> 	; [ESI] = VGA memory model number (LINEAR8, PLANAR4, PLANAR1)
  3854                              <1> 	
  3855                              <1> 	; if(rlr>=nbrows)rlr=nbrows-1;
  3856                              <1>  	; if(clr>=nbcols)clr=nbcols-1;
  3857                              <1>  	; if(nblines>nbrows)nblines=0;
  3858                              <1>  	; cols=clr-cul+1;
  3859                              <1> 
  3860 00002515 3A35[A2690000]      <1> 	cmp	dh, [VGA_ROWS]
  3861 0000251B 7208                <1> 	jb	short vga_g_up_2
  3862 0000251D 8A35[A2690000]      <1> 	mov	dh, [VGA_ROWS]
  3863 00002523 FECE                <1> 	dec	dh
  3864                              <1> vga_g_up_2:
  3865 00002525 3A15[9C690000]      <1> 	cmp	dl, [CRT_COLS]  ; = [VGA_COLS]
  3866 0000252B 7208                <1> 	jb	short vga_g_up_3
  3867 0000252D 8A15[9C690000]      <1> 	mov	dl, [CRT_COLS]
  3868 00002533 FECA                <1> 	dec	dl
  3869                              <1> vga_g_up_3:	
  3870 00002535 3A05[A2690000]      <1> 	cmp	al, [VGA_ROWS]
  3871 0000253B 7602                <1> 	jna	short vga_g_up_4
  3872 0000253D 28C0                <1> 	sub	al, al ; 0
  3873                              <1> vga_g_up_4:
  3874 0000253F 88D7                <1> 	mov	bh, dl ; clr
  3875 00002541 28CF                <1> 	sub	bh, cl ; cul
  3876 00002543 FEC7                <1> 	inc	bh ; cols = clr-cul+1
  3877                              <1> 
  3878 00002545 20C0                <1> 	and	al, al ; nblines = 0
  3879 00002547 755D                <1> 	jnz	short vga_g_up_6
  3880 00002549 20ED                <1> 	and	ch, ch ; rul = 0
  3881 0000254B 7559                <1> 	jnz	short vga_g_up_6
  3882 0000254D 20C9                <1> 	and	cl, cl ; cul = 0
  3883 0000254F 7555                <1> 	jnz	short vga_g_up_6
  3884                              <1> 
  3885 00002551 6650                <1> 	push	ax
  3886 00002553 A0[A2690000]        <1> 	mov	al, [VGA_ROWS]
  3887 00002558 FEC8                <1> 	dec	al  
  3888 0000255A 38C6                <1> 	cmp	dh, al ; rlr = nbrows-1
  3889 0000255C 7546                <1> 	jne	short vga_g_up_5
  3890 0000255E A0[9C690000]        <1>         mov     al, [CRT_COLS]  ; = VGA_COLS
  3891 00002563 FEC8                <1> 	dec	al 
  3892 00002565 38C2                <1>  	cmp	dl, al ; clr = nbcols-1
  3893 00002567 753B                <1> 	jne	short vga_g_up_5
  3894 00002569 6658                <1> 	pop	ax
  3895                              <1> 
  3896 0000256B 66B80502            <1> 	mov	ax, 0205h
  3897 0000256F 66BACE03            <1> 	mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  3898 00002573 66EF                <1> 	out	dx, ax
  3899 00002575 A0[A2690000]        <1> 	mov	al, [VGA_ROWS]
  3900 0000257A 8A25[9C690000]      <1> 	mov	ah, [CRT_COLS] ; = [VGA_COLS]
  3901 00002580 F6E4                <1> 	mul	ah
  3902 00002582 0FB7D0              <1> 	movzx	edx, ax
  3903                              <1> 	; 08/08/2016
  3904 00002585 0FB605[9E690000]    <1> 	movzx	eax, byte [CHAR_HEIGHT]
  3905 0000258C F7E2                <1> 	mul	edx
  3906                              <1> 	; eax = byte count	
  3907 0000258E 89C1                <1> 	mov	ecx, eax
  3908                              <1> 	;; 07/08/2016
  3909                              <1> 	;shl	dx, 3 ; * 8 ; * [CHAR_HEIGHT]
  3910                              <1> 	;mov	ecx, edx
  3911 00002590 88D8                <1> 	mov	al, bl ; fill value for blanked lines
  3912 00002592 BF00000A00          <1> 	mov	edi, 0A0000h
  3913 00002597 F3AA                <1> 	rep	stosb		
  3914                              <1> 	
  3915 00002599 66B80500            <1> 	mov	ax, 5
  3916 0000259D 66BACE03            <1> 	mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  3917 000025A1 66EF                <1> 	out	dx, ax ; 0005h	
  3918                              <1> 
  3919 000025A3 C3                  <1> 	retn
  3920                              <1> 
  3921                              <1> vga_g_up_5:
  3922 000025A4 6658                <1> 	pop	ax
  3923                              <1> 
  3924                              <1> vga_g_up_6:
  3925                              <1> 	; [ESI] = VGA memory model number for current video mode
  3926                              <1>         ;
  3927                              <1>         ; LINEAR8 equ 5
  3928                              <1>         ; PLANAR4 equ 4
  3929                              <1>         ; PLANAR1 equ 3
  3930                              <1> 
  3931 000025A6 803E04              <1> 	cmp	byte [esi], PLANAR4
  3932 000025A9 7424                <1> 	je	short vga_g_up_planar
  3933 000025AB 803E03              <1> 	cmp	byte [esi], PLANAR1
  3934 000025AE 741F                <1> 	je	short vga_g_up_planar
  3935                              <1> vga_g_up_linear8:
  3936                              <1> 	; 07/07/2016 (TEMPORARY)
  3937                              <1> 	;
  3938                              <1> 	; cl = upper left column ; cul
  3939                              <1> 	; ch = upper left row ; rul
  3940                              <1> 	; dl = lower rigth column ; clr
  3941                              <1> 	; dh = lower right row ; rlr
  3942                              <1> 
  3943                              <1> vga_g_up_l0:
  3944                              <1>  	;{for(i=rul;i<=rlr;i++)
  3945                              <1>   	; if((i+nblines>rlr)||(nblines==0))
  3946 000025B0 08C0                <1> 	or	al, al
  3947 000025B2 7414                <1> 	jz	short vga_g_up_l2
  3948 000025B4 88C4                <1> 	mov	ah, al
  3949 000025B6 00EC                <1> 	add	ah, ch ; i+nblines
  3950                              <1> 	;jc	short vga_g_up_l2	
  3951 000025B8 38F4                <1> 	cmp	ah, dh
  3952 000025BA 770C                <1> 	ja	short vga_g_up_l2
  3953                              <1> 	; else
  3954                              <1> 	;  vgamem_copy_pl4(cul,i+nblines,i,cols,nbcols,cheight);
  3955 000025BC E8F2000000          <1> 	call	vgamem_copy_l8
  3956                              <1> vga_g_up_l1:
  3957 000025C1 FEC5                <1> 	inc	ch
  3958 000025C3 38F5                <1> 	cmp	ch, dh
  3959 000025C5 76E9                <1> 	jna	short vga_g_up_l0
  3960 000025C7 C3                  <1> 	retn
  3961                              <1> vga_g_up_l2:
  3962                              <1> 	; vgamem_fill_pl4(cul,i,cols,nbcols,cheight,attr);
  3963 000025C8 E850010000          <1> 	call	vgamem_fill_l8
  3964 000025CD EBF2                <1> 	jmp	short vga_g_up_l1
  3965                              <1> 
  3966                              <1> vga_g_up_planar:
  3967                              <1> 	; cl = upper left column ; cul
  3968                              <1> 	; ch = upper left row ; rul
  3969                              <1> 	; dl = lower rigth column ; clr
  3970                              <1> 	; dh = lower right row ; rlr
  3971                              <1> vga_g_up_pl0:
  3972                              <1>  	;{for(i=rul;i<=rlr;i++)
  3973                              <1>   	; if((i+nblines>rlr)||(nblines==0))
  3974 000025CF 20C0                <1> 	and	al, al
  3975 000025D1 7414                <1> 	jz	short vga_g_up_pl2	
  3976 000025D3 88C4                <1> 	mov	ah, al
  3977 000025D5 00EC                <1> 	add	ah, ch ; i+nblines
  3978                              <1> 	;jc	short vga_g_up_pl2
  3979 000025D7 38F4                <1> 	cmp	ah, dh
  3980 000025D9 770C                <1> 	ja	short vga_g_up_pl2
  3981                              <1> 	; else
  3982                              <1> 	;  vgamem_copy_pl4(cul,i+nblines,i,cols,nbcols,cheight);
  3983 000025DB E80E000000          <1> 	call	vgamem_copy_pl4
  3984                              <1> vga_g_up_pl1:
  3985 000025E0 FEC5                <1> 	inc	ch 
  3986 000025E2 38F5                <1> 	cmp	ch, dh
  3987 000025E4 76E9                <1> 	jna	short vga_g_up_pl0
  3988 000025E6 C3                  <1> 	retn
  3989                              <1> vga_g_up_pl2:
  3990                              <1> 	; vgamem_fill_pl4(cul,i,cols,nbcols,cheight,attr);
  3991 000025E7 E870000000          <1> 	call	vgamem_fill_pl4
  3992 000025EC EBF2                <1> 	jmp	short vga_g_up_pl1
  3993                              <1> 
  3994                              <1> vgamem_copy_pl4:
  3995                              <1> 	; 08/08/2016
  3996                              <1> 	; 07/08/2016
  3997                              <1> 	; 07/07/2016 - TRDOS 386 (TRDOS v2.0)
  3998                              <1> 	;
  3999                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  4000                              <1> 	; vgabios-0.7a (2011)
  4001                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  4002                              <1> 	; 'vgabios.c', 'vgamem_copy_pl4'
  4003                              <1> 	;
  4004                              <1> 	; vgamem_copy_pl4(xstart,ysrc,ydest,cols,nbcols,cheight)
  4005                              <1> 	; cl = xstart, ah = ysrc (i+nblines), ch = ydest (i),
  4006                              <1> 	; bh = cols, [CRT_COLS] = nbcols, [CHAR_HEIGHT] = cheight
  4007                              <1> 
  4008                              <1> 	; src=ysrc*cheight*nbcols+xstart;
  4009                              <1> 	; dest=ydest*cheight*nbcols+xstart;
  4010                              <1> 
  4011 000025EE 52                  <1> 	push	edx
  4012 000025EF 50                  <1> 	push	eax
  4013                              <1> 
  4014                              <1> 	; outw(VGAREG_GRDC_ADDRESS, 0x0105)
  4015 000025F0 66B80501            <1> 	mov	ax, 0105h
  4016 000025F4 66BACE03            <1> 	mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  4017 000025F8 66EF                <1> 	out	dx, ax
  4018                              <1> 
  4019                              <1> 	; 07/08/2016
  4020                              <1>  	;mov     ah, [esp+1]
  4021                              <1> 	;movzx	edx, ah ; ysrc
  4022 000025FA 0FB6542401          <1> 	movzx	edx, byte [esp+1]
  4023                              <1> 	; 08/08/2016
  4024 000025FF 0FB605[9E690000]    <1> 	movzx	eax, byte [CHAR_HEIGHT]
  4025 00002606 8A25[9C690000]      <1> 	mov	ah, [CRT_COLS] ; nbcols
  4026 0000260C F6E4                <1> 	mul	ah 
  4027                              <1> 	;; 07/08/2016
  4028                              <1> 	;movzx	eax, byte [CRT_COLS]
  4029                              <1> 	;shl	ax, 3 ; * 8 ; * [CHAR_HEIGHT]
  4030 0000260E 50                  <1> 	push	eax ; cheight * nbcols
  4031 0000260F F7E2                <1> 	mul	edx ; * ysrc
  4032                              <1> 	; eax = ysrc * cheight * nbcols
  4033                              <1> 	; edx = 0
  4034 00002611 88CA                <1> 	mov	dl, cl ; edx = xstart	
  4035 00002613 01D0                <1>  	add	eax, edx
  4036 00002615 89C6                <1> 	mov	esi, eax ; src
  4037 00002617 88EA                <1> 	mov	dl, ch ; ydest
  4038 00002619 58                  <1> 	pop	eax ; cheight * nbcols
  4039 0000261A F7E2                <1> 	mul	edx
  4040                              <1> 	; eax = ydest * cheight * nbcols
  4041 0000261C 88CA                <1> 	mov	dl, cl ; edx = xstart	
  4042 0000261E 01D0                <1>  	add	eax, edx
  4043 00002620 89C7                <1> 	mov	edi, eax ; dest
  4044                              <1> 	; esi = src
  4045                              <1> 	; edi = dest
  4046                              <1> 	; for(i=0;i<cheight;i++)
  4047                              <1>   	; {
  4048                              <1>    	;  memcpyb(0xa000,dest+i*nbcols,0xa000,src+i*nbcols,cols);
  4049                              <1>   	; }
  4050 00002622 51                  <1> 	push	ecx
  4051 00002623 B900000A00          <1> 	mov	ecx, 0A0000h
  4052 00002628 01CE                <1> 	add	esi, ecx
  4053 0000262A 01CF                <1> 	add	edi, ecx
  4054                              <1> 	; 08/08/2016
  4055 0000262C 8A35[9E690000]      <1> 	mov	dh, [CHAR_HEIGHT]
  4056                              <1> 	;; 07/08/2016
  4057                              <1> 	;mov	dh, 8 ; 07/08/2016
  4058 00002632 28D2                <1> 	sub	dl, dl ; i
  4059                              <1> vgamem_copy_pl4_0:
  4060 00002634 56                  <1> 	push	esi
  4061 00002635 57                  <1> 	push	edi
  4062 00002636 0FB605[9C690000]    <1> 	movzx	eax, byte [CRT_COLS]
  4063 0000263D F6E2                <1> 	mul	dl
  4064                              <1> 	; eax = i * nbcols
  4065 0000263F 01C7                <1> 	add	edi, eax ; dest+i*nbcols
  4066 00002641 01C6                <1> 	add	esi, eax
  4067 00002643 0FB6CF              <1> 	movzx	ecx, bh ; cols
  4068 00002646 F3A4                <1> 	rep	movsb
  4069 00002648 5F                  <1> 	pop	edi
  4070 00002649 5E                  <1> 	pop	esi
  4071 0000264A FECE                <1> 	dec	dh
  4072 0000264C 75E6                <1> 	jnz	short vgamem_copy_pl4_0
  4073                              <1> vgamem_copy_pl4_1:
  4074 0000264E 59                  <1> 	pop	ecx
  4075                              <1> 
  4076                              <1> 	; outw(VGAREG_GRDC_ADDRESS, 0x0005);
  4077 0000264F 66B80500            <1> 	mov	ax, 0005h
  4078 00002653 66BACE03            <1> 	mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  4079 00002657 66EF                <1> 	out	dx, ax
  4080                              <1> 
  4081 00002659 58                  <1> 	pop	eax
  4082 0000265A 5A                  <1> 	pop	edx
  4083                              <1> 
  4084 0000265B C3                  <1> 	retn	
  4085                              <1> 
  4086                              <1> vgamem_fill_pl4:
  4087                              <1> 	; 08/08/2016
  4088                              <1> 	; 07/08/2016
  4089                              <1> 	; 04/08/2016
  4090                              <1> 	; 07/07/2016 - TRDOS 386 (TRDOS v2.0)
  4091                              <1> 	;
  4092                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  4093                              <1> 	; vgabios-0.7a (2011)
  4094                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  4095                              <1> 	; 'vgabios.c', 'vgamem_fill_pl4'
  4096                              <1> 	;
  4097                              <1> 	; vgamem_fill_pl4(xstart,ystart,cols,nbcols,cheight,attr)
  4098                              <1> 	; cl = xstart, edi = ch = ystart, bh = cols,
  4099                              <1> 	; [CRT_COLS] = nbcols, [CHAR_HEIGHT] = cheight, attr = 0
  4100                              <1> 
  4101                              <1> 	; dest=ystart*cheight*nbcols+xstart;
  4102 0000265C 52                  <1> 	push	edx
  4103 0000265D 50                  <1> 	push	eax
  4104                              <1> 
  4105                              <1> 	; outw(VGAREG_GRDC_ADDRESS, 0x0205)
  4106 0000265E 66B80502            <1> 	mov	ax, 0205h
  4107 00002662 66BACE03            <1> 	mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  4108 00002666 66EF                <1> 	out	dx, ax
  4109                              <1> 
  4110                              <1>       	; 08/08/2016
  4111 00002668 0FB605[9E690000]    <1> 	movzx   eax, byte [CHAR_HEIGHT]
  4112 0000266F F6E5                <1> 	mul	ch
  4113                              <1> 	;; 07/08/2016
  4114                              <1> 	;movzx	eax, ch
  4115                              <1> 	;shl	ax, 3 ; * 8 ; * [CHAR_HEIGHT]
  4116 00002671 0FB615[9C690000]    <1> 	movzx	edx, byte [CRT_COLS] ; = [VGA_COLS]
  4117 00002678 F7E2                <1> 	mul	edx
  4118                              <1> 	; edx  = 0
  4119 0000267A 88CA                <1> 	mov	dl, cl 
  4120 0000267C 01D0                <1> 	add	eax, edx
  4121 0000267E 89C7                <1> 	mov	edi, eax
  4122                              <1> 	; edi = dest
  4123                              <1> 	; for(i=0;i<cheight;i++)
  4124                              <1>   	; {
  4125                              <1>    	;  memsetb(0xa000,dest+i*nbcols,attr,cols);
  4126                              <1>   	; }
  4127 00002680 81C700000A00        <1> 	add	edi, 0A0000h
  4128 00002686 51                  <1> 	push	ecx
  4129                              <1> 	; 08/08/2016
  4130 00002687 8A35[9E690000]      <1> 	mov	dh, [CHAR_HEIGHT]
  4131                              <1> 	;; 07/08/2016
  4132                              <1> 	;mov	dh, 8 ; 07/08/2016
  4133 0000268D 28D2                <1> 	sub	dl, dl ; i
  4134                              <1> vgamem_fill_pl4_0:
  4135 0000268F 57                  <1> 	push	edi
  4136 00002690 0FB605[9C690000]    <1> 	movzx	eax, byte [CRT_COLS]
  4137 00002697 F6E2                <1> 	mul	dl
  4138                              <1> 	; eax = i * nbcols
  4139 00002699 01C7                <1> 	add	edi, eax ; dest+i*nbcols
  4140 0000269B 88D8                <1> 	mov	al, bl ; attr ; 04/08/2016
  4141 0000269D 0FB6CF              <1> 	movzx	ecx, bh ; cols
  4142 000026A0 F3AA                <1>  	rep	stosb
  4143 000026A2 5F                  <1> 	pop	edi
  4144 000026A3 75EA                <1> 	jnz	short vgamem_fill_pl4_0
  4145                              <1> vgamem_fill_pl4_1:
  4146 000026A5 59                  <1> 	pop	ecx
  4147                              <1> 
  4148                              <1> 	; outw(VGAREG_GRDC_ADDRESS, 0x0005);
  4149 000026A6 66B80500            <1> 	mov	ax, 0005h
  4150 000026AA 66BACE03            <1> 	mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  4151 000026AE 66EF                <1> 	out	dx, ax
  4152                              <1> 
  4153 000026B0 58                  <1> 	pop	eax
  4154 000026B1 5A                  <1> 	pop	edx 
  4155                              <1> 	
  4156 000026B2 C3                  <1> 	retn
  4157                              <1> 
  4158                              <1> vgamem_copy_l8:
  4159                              <1> 	; 08/08/2016
  4160                              <1> 	; 07/08/2016
  4161                              <1> 	; 06/08/2016
  4162                              <1> 	; 07/07/2016 - TRDOS 386 (TRDOS v2.0)
  4163                              <1> 	;
  4164                              <1> 	; TEMPORARY
  4165                              <1> 	;
  4166                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  4167                              <1> 	; vgabios-0.7a (2011)
  4168                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  4169                              <1> 	; 'vgabios.c', 'vgamem_copy_pl4'
  4170                              <1> 	;
  4171                              <1> 	; vgamem_copy_pl4(xstart,ysrc,ydest,cols,nbcols,cheight)
  4172                              <1> 	; cl = xstart, ah = ysrc (i+nblines), ch = ydest (i),
  4173                              <1> 	; bh = cols, [CRT_COLS] = nbcols, [CHAR_HEIGHT] = cheight
  4174                              <1> 
  4175                              <1> 	; src=ysrc*cheight*nbcols+xstart;
  4176                              <1> 	; dest=ydest*cheight*nbcols+xstart;
  4177                              <1> 
  4178 000026B3 52                  <1> 	push	edx
  4179 000026B4 50                  <1> 	push	eax
  4180                              <1> 
  4181                              <1> 	; outw(VGAREG_GRDC_ADDRESS, 0x0105)
  4182                              <1> 	;mov	ax, 0105h
  4183                              <1> 	;mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  4184                              <1> 	;out	dx, ax
  4185                              <1> 
  4186                              <1> 	;mov	ah, [esp+1]
  4187                              <1> 
  4188 000026B5 0FB6D4              <1> 	movzx	edx, ah ; ysrc
  4189                              <1> 	; 08/08/2016
  4190 000026B8 0FB605[9E690000]    <1> 	movzx	eax, byte [CHAR_HEIGHT]
  4191 000026BF 8A25[9C690000]      <1> 	mov	ah, [CRT_COLS] ; nbcols
  4192 000026C5 F6E4                <1> 	mul	ah 
  4193                              <1> 	;; 07/08/2016
  4194                              <1> 	;movzx	eax, byte [CRT_COLS]
  4195                              <1> 	;shl	ax, 3 ; * 8 ; * [CHAR_HEIGHT]
  4196 000026C7 50                  <1> 	push	eax ; cheight * nbcols
  4197 000026C8 F7E2                <1> 	mul	edx ; * ysrc
  4198                              <1> 	; eax = ysrc * cheight * nbcols
  4199                              <1> 	; edx = 0
  4200 000026CA 88CA                <1> 	mov	dl, cl ; edx = xstart
  4201 000026CC 01D0                <1>  	add	eax, edx
  4202 000026CE 89C6                <1> 	mov	esi, eax ; src
  4203 000026D0 66C1E603            <1> 	shl	si, 3 ; * 8 ; 06/08/2016
  4204 000026D4 88EA                <1> 	mov	dl, ch ; ydest
  4205 000026D6 58                  <1> 	pop	eax ; cheight * nbcols
  4206 000026D7 F7E2                <1> 	mul	edx
  4207                              <1> 	; eax = ydest * cheight * nbcols
  4208 000026D9 88CA                <1> 	mov	dl, cl ; edx = xstart	
  4209 000026DB 01D0                <1>  	add	eax, edx
  4210 000026DD 89C7                <1> 	mov	edi, eax ; dest
  4211 000026DF 66C1E703            <1> 	shl	di, 3 ; * 8 ; 06/08/2016
  4212                              <1> 	; esi = src
  4213                              <1> 	; edi = dest
  4214                              <1> 	; for(i=0;i<cheight;i++)
  4215                              <1>   	; {
  4216                              <1>    	;  memcpyb(0xa000,dest+i*nbcols,0xa000,src+i*nbcols,cols);
  4217                              <1>   	; }
  4218 000026E3 51                  <1> 	push	ecx
  4219 000026E4 B900000A00          <1> 	mov	ecx, 0A0000h
  4220 000026E9 01CE                <1> 	add	esi, ecx
  4221 000026EB 01CF                <1> 	add	edi, ecx
  4222                              <1> 	; 08/08/2016
  4223 000026ED 8A35[9E690000]      <1> 	mov	dh, [CHAR_HEIGHT]
  4224                              <1> 	;; 07/08/2016
  4225                              <1> 	;mov	dh, 8 ; 07/08/2016
  4226 000026F3 28D2                <1> 	sub	dl, dl ; i
  4227                              <1> vgamem_copy_l8_0:
  4228 000026F5 56                  <1> 	push	esi
  4229 000026F6 57                  <1> 	push	edi
  4230 000026F7 0FB605[9C690000]    <1> 	movzx	eax, byte [CRT_COLS]
  4231 000026FE F6E2                <1> 	mul	dl
  4232                              <1> 	; eax = i * nbcols
  4233 00002700 66C1E003            <1> 	shl	ax, 3 ; * 8 ; 06/08/2016
  4234 00002704 01C7                <1> 	add	edi, eax ; dest+i*nbcols
  4235 00002706 01C6                <1> 	add	esi, eax
  4236 00002708 0FB6CF              <1> 	movzx	ecx, bh ; cols
  4237 0000270B 66C1E103            <1> 	shl	cx, 3 ; * 8 ; 06/08/2016
  4238 0000270F F3A4                <1> 	rep	movsb
  4239 00002711 5F                  <1> 	pop	edi
  4240 00002712 5E                  <1> 	pop	esi
  4241 00002713 FEC2                <1> 	inc	dl ; 06/08/2016
  4242 00002715 FECE                <1> 	dec	dh
  4243 00002717 75DC                <1> 	jnz	short vgamem_copy_l8_0
  4244                              <1> vgamem_copy_l8_1:
  4245 00002719 59                  <1> 	pop	ecx
  4246                              <1> 
  4247                              <1> 	;; outw(VGAREG_GRDC_ADDRESS, 0x0005);
  4248                              <1> 	;mov	ax, 0005h
  4249                              <1> 	;mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  4250                              <1> 	;out	dx, ax
  4251                              <1> 
  4252 0000271A 58                  <1> 	pop	eax
  4253 0000271B 5A                  <1> 	pop	edx
  4254                              <1> 
  4255 0000271C C3                  <1> 	retn
  4256                              <1> 
  4257                              <1> vgamem_fill_l8:
  4258                              <1> 	; 08/08/2016
  4259                              <1> 	; 07/08/2016
  4260                              <1> 	; 06/08/2016
  4261                              <1> 	; 04/08/2016
  4262                              <1> 	; 07/07/2016 - TRDOS 386 (TRDOS v2.0)
  4263                              <1> 	;
  4264                              <1> 	; TEMPORARY
  4265                              <1> 	;
  4266                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  4267                              <1> 	; vgabios-0.7a (2011)
  4268                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  4269                              <1> 	; 'vgabios.c', 'vgamem_fill_pl4'
  4270                              <1> 	;
  4271                              <1> 	; vgamem_fill_pl4(xstart,ystart,cols,nbcols,cheight,attr)
  4272                              <1> 	; cl = xstart, edi = ch = ystart, bh = cols,
  4273                              <1> 	; [CRT_COLS] = nbcols, [CHAR_HEIGHT] = cheight, attr = 0
  4274                              <1> 
  4275                              <1> 	; dest=ystart*cheight*nbcols+xstart;
  4276 0000271D 52                  <1> 	push	edx
  4277 0000271E 50                  <1> 	push	eax
  4278                              <1> 
  4279                              <1> 	;; outw(VGAREG_GRDC_ADDRESS, 0x0205)
  4280                              <1> 	;mov	ax, 0205h
  4281                              <1> 	;mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  4282                              <1> 	;out	dx, ax
  4283                              <1> 
  4284                              <1>         ; 08/08/2016
  4285 0000271F 0FB605[9E690000]    <1> 	movzx   eax, byte [CHAR_HEIGHT]
  4286 00002726 F6E5                <1> 	mul	ch
  4287                              <1> 	;; 07/08/2016
  4288                              <1> 	;movzx	eax, ch
  4289                              <1> 	;shl	ax, 3 ; * 8 ; * [CHAR_HEIGHT]
  4290 00002728 0FB615[9C690000]    <1> 	movzx	edx, byte [CRT_COLS] ; = [VGA_COLS]
  4291 0000272F F7E2                <1> 	mul	edx
  4292                              <1> 	; edx  = 0
  4293 00002731 88CA                <1> 	mov	dl, cl 
  4294 00002733 01D0                <1> 	add	eax, edx
  4295 00002735 89C7                <1> 	mov	edi, eax
  4296 00002737 66C1E703            <1> 	shl	di, 3 ; * 8 ; 06/08/2016
  4297                              <1> 	; edi = dest
  4298                              <1> 	; for(i=0;i<cheight;i++)
  4299                              <1>   	; {
  4300                              <1>    	;  memsetb(0xa000,dest+i*nbcols,attr,cols);
  4301                              <1>   	; }
  4302 0000273B 81C700000A00        <1> 	add	edi, 0A0000h
  4303 00002741 51                  <1> 	push	ecx
  4304                              <1> 	; 08/08/2016
  4305 00002742 8A35[9E690000]      <1> 	mov	dh, [CHAR_HEIGHT]
  4306                              <1> 	;; 07/08/2016
  4307                              <1> 	;mov	dh, 8 ; 07/08/2016
  4308 00002748 28D2                <1> 	sub	dl, dl ; i
  4309                              <1> vgamem_fill_l8_0:
  4310 0000274A 57                  <1> 	push	edi
  4311 0000274B 0FB605[9C690000]    <1> 	movzx	eax, byte [CRT_COLS]
  4312 00002752 F6E2                <1> 	mul	dl
  4313                              <1> 	; eax = i * nbcols
  4314 00002754 66C1E003            <1> 	shl	ax, 3 ; * 8 ; 06/08/2016
  4315 00002758 01C7                <1> 	add	edi, eax ; dest+i*nbcols
  4316 0000275A 88D8                <1> 	mov	al, bl ; attr ; 04/08/2016
  4317 0000275C 0FB6CF              <1> 	movzx	ecx, bh ; cols
  4318 0000275F 66C1E103            <1> 	shl	cx, 3 ; * 8 ; 06/08/2016
  4319 00002763 F3AA                <1>  	rep	stosb
  4320 00002765 5F                  <1> 	pop	edi
  4321 00002766 FEC2                <1> 	inc	dl ; 06/08/2016
  4322 00002768 FECE                <1> 	dec	dh
  4323 0000276A 75DE                <1> 	jnz	short vgamem_fill_l8_0
  4324                              <1> vgamem_fill_l8_1:
  4325 0000276C 59                  <1> 	pop	ecx
  4326                              <1> 
  4327                              <1> 	;; outw(VGAREG_GRDC_ADDRESS, 0x0005);
  4328                              <1> 	;mov	ax, 0005h
  4329                              <1> 	;mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  4330                              <1> 	;out	dx, ax
  4331                              <1> 
  4332 0000276D 58                  <1> 	pop	eax
  4333 0000276E 5A                  <1> 	pop	edx 
  4334                              <1> 
  4335 0000276F C3                  <1> 	retn
  4336                              <1> 
  4337                              <1> vga_graphics_down:
  4338                              <1> 	; 08/08/2016
  4339                              <1> 	; 07/08/2016
  4340                              <1> 	; 31/07/2016
  4341                              <1> 	; 07/07/2016 - TRDOS 386 (TRDOS v2.0)
  4342                              <1> 	;
  4343                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  4344                              <1> 	; vgabios-0.7a (2011)
  4345                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  4346                              <1> 	; 'vgabios.c', 'biosfn_scroll'
  4347                              <1> 	;
  4348                              <1> 
  4349                              <1> 	; cl = upper left column
  4350                              <1> 	; ch = upper left row
  4351                              <1> 	; dl = lower rigth column
  4352                              <1> 	; dh = lower right row
  4353                              <1> 	;
  4354                              <1> 	; al = line count (AL=0 means blank entire fields)
  4355                              <1> 	; bl = fill value for blanked lines	
  4356                              <1> 	; bh = unused
  4357                              <1> 	;
  4358                              <1> 	; ah = [CRT_MODE], current video mode	
  4359                              <1> 
  4360 00002770 FC                  <1>         cld     ; !!! Clear direction flag !!! 
  4361                              <1> 
  4362 00002771 88C7                <1> 	mov	bh, al ; 31/07/2016
  4363                              <1> 
  4364 00002773 BE[B6690000]        <1> 	mov	esi, vga_modes
  4365 00002778 89F7                <1> 	mov	edi, esi
  4366 0000277A 83C710              <1> 	add	edi, vga_mode_count
  4367                              <1> vga_g_down_0:
  4368 0000277D AC                  <1> 	lodsb
  4369 0000277E 38E0                <1> 	cmp	al, ah ; [CRT_MODE]
  4370 00002780 7405                <1> 	je	short vga_g_down_1
  4371 00002782 39FE                <1> 	cmp	esi, edi
  4372 00002784 72F7                <1> 	jb	short vga_g_down_0
  4373                              <1> 	; xor 	bh, bh	; 31/07/2016
  4374 00002786 C3                  <1> 	retn	; nothing to do
  4375                              <1> vga_g_down_1:
  4376 00002787 88F8                <1> 	mov	al, bh ; 31/07/2016
  4377 00002789 83C64F              <1> 	add	esi, vga_memmodel - (vga_modes + 1)  
  4378                              <1> 	; [ESI] = VGA memory model number (LINEAR8, PLANAR4, PLANAR1)
  4379                              <1> 	
  4380                              <1> 	; if(rlr>=nbrows)rlr=nbrows-1;
  4381                              <1>  	; if(clr>=nbcols)clr=nbcols-1;
  4382                              <1>  	; if(nblines>nbrows)nblines=0;
  4383                              <1>  	; cols=clr-cul+1;
  4384                              <1> 
  4385 0000278C 3A35[A2690000]      <1> 	cmp	dh, [VGA_ROWS]
  4386 00002792 7208                <1> 	jb	short vga_g_down_2
  4387 00002794 8A35[A2690000]      <1> 	mov	dh, [VGA_ROWS]
  4388 0000279A FECE                <1> 	dec	dh
  4389                              <1> vga_g_down_2:
  4390 0000279C 3A15[9C690000]      <1> 	cmp	dl, [CRT_COLS]  ; = [VGA_COLS]
  4391 000027A2 7208                <1> 	jb	short vga_g_down_3
  4392 000027A4 8A15[9C690000]      <1> 	mov	dl, [CRT_COLS]
  4393 000027AA FECA                <1> 	dec	dl
  4394                              <1> vga_g_down_3:	
  4395 000027AC 3A05[A2690000]      <1> 	cmp	al, [VGA_ROWS]
  4396 000027B2 7602                <1> 	jna	short vga_g_down_4
  4397 000027B4 28C0                <1> 	sub	al, al ; 0
  4398                              <1> vga_g_down_4:
  4399 000027B6 88F7                <1> 	mov	bh, dh ; clr
  4400 000027B8 28CF                <1> 	sub	bh, cl ; cul
  4401 000027BA FEC7                <1> 	inc	bh ; cols = clr-cul+1
  4402                              <1> 
  4403 000027BC 20C0                <1> 	and	al, al ; nblines = 0
  4404 000027BE 755B                <1> 	jnz	short vga_g_down_6
  4405 000027C0 20ED                <1> 	and	ch, ch ; rul = 0
  4406 000027C2 7557                <1> 	jnz	short vga_g_down_6
  4407 000027C4 20C9                <1> 	and	cl, cl ; cul = 0
  4408 000027C6 7553                <1> 	jnz	short vga_g_down_6
  4409                              <1> 
  4410 000027C8 6650                <1> 	push	ax
  4411 000027CA A0[A2690000]        <1> 	mov	al, [VGA_ROWS]
  4412 000027CF FEC8                <1> 	dec	al  
  4413 000027D1 38C6                <1> 	cmp	dh, al ; rlr = nbrows-1
  4414 000027D3 7544                <1> 	jne	short vga_g_down_5
  4415 000027D5 A0[9C690000]        <1>         mov     al, [CRT_COLS]  ; = VGA_COLS
  4416 000027DA FEC8                <1> 	dec	al 
  4417 000027DC 38C2                <1>  	cmp	dl, al ; clr = nbcols-1
  4418 000027DE 7539                <1> 	jne	short vga_g_down_5
  4419 000027E0 6658                <1> 	pop	ax
  4420                              <1> 
  4421 000027E2 66B80502            <1> 	mov	ax, 0205h
  4422 000027E6 66BACE03            <1> 	mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  4423 000027EA 66EF                <1> 	out	dx, ax
  4424 000027EC A0[A2690000]        <1> 	mov	al, [VGA_ROWS]
  4425 000027F1 8A25[9C690000]      <1> 	mov	ah, [CRT_COLS] ; = [VGA_COLS]
  4426 000027F7 F6E4                <1> 	mul	ah
  4427 000027F9 0FB7D0              <1> 	movzx	edx, ax
  4428                              <1> 	; 08/08/2016
  4429 000027FC 0FB605[9E690000]    <1> 	movzx	eax, byte [CHAR_HEIGHT]
  4430 00002803 F7E2                <1> 	mul	edx
  4431                              <1> 	; eax = byte count	
  4432 00002805 89C1                <1> 	mov	ecx, eax
  4433                              <1> 	;; 07/08/2016
  4434                              <1> 	;shl	dx, 3 ; * 8 ; * [CHAR_HEIGHT]
  4435                              <1> 	;mov	ecx, edx
  4436 00002807 88D8                <1> 	mov	al, bl ; fill value for blanked lines
  4437 00002809 BF00000A00          <1> 	mov	edi, 0A0000h
  4438 0000280E F3AA                <1> 	rep	stosb			
  4439                              <1> 	
  4440 00002810 B005                <1> 	mov	al, 5
  4441 00002812 66BACE03            <1> 	mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  4442 00002816 66EF                <1> 	out	dx, ax ; 0005h	
  4443                              <1> 
  4444 00002818 C3                  <1> 	retn
  4445                              <1> 
  4446                              <1> vga_g_down_5:
  4447 00002819 6658                <1> 	pop	ax
  4448                              <1> 
  4449                              <1> vga_g_down_6:
  4450                              <1> 	; [ESI] = VGA memory model number for current video mode
  4451                              <1>         ;
  4452                              <1>         ; LINEAR8 equ 5
  4453                              <1>         ; PLANAR4 equ 4
  4454                              <1>         ; PLANAR1 equ 3
  4455                              <1> 
  4456 0000281B 803E04              <1> 	cmp	byte [esi], PLANAR4
  4457 0000281E 742C                <1> 	je	short vga_g_down_planar
  4458 00002820 803E03              <1> 	cmp	byte [esi], PLANAR1
  4459 00002823 7427                <1> 	je	short vga_g_down_planar
  4460                              <1> vga_g_down_linear8:
  4461                              <1> 	; 07/07/2016 (TEMPORARY)
  4462                              <1> 	;
  4463                              <1> 	; cl = upper left column ; cul
  4464                              <1> 	; ch = upper left row ; rul
  4465                              <1> 	; dl = lower rigth column ; clr
  4466                              <1> 	; dh = lower right row ; rlr
  4467                              <1> 
  4468                              <1> vga_g_down_l0:
  4469                              <1> 	;{for(i=rlr;i>=rul;i--)
  4470                              <1>         ; if((i<rul+nblines)||(nblines==0))
  4471 00002825 08C0                <1> 	or	al, al
  4472 00002827 741C                <1> 	jz	short vga_g_down_l2
  4473 00002829 88C4                <1> 	mov	ah, al
  4474 0000282B 00EC                <1> 	add	ah, ch
  4475                              <1> 	;jc	short vga_g_down_l2	
  4476 0000282D 86EE                <1> 	xchg	ch, dh
  4477 0000282F 38E5                <1> 	cmp	ch, ah
  4478 00002831 7212                <1> 	jb	short vga_g_down_l2
  4479 00002833 88EC                <1> 	mov	ah, ch
  4480 00002835 28C4                <1> 	sub	ah, al ; ah = i - nblines
  4481                              <1> 	; else
  4482                              <1> 	; vgamem_copy_pl4(cul,i,i-nblines,cols,nbcols,cheight);
  4483 00002837 E877FEFFFF          <1> 	call	vgamem_copy_l8
  4484                              <1> vga_g_down_l1:
  4485 0000283C 86F5                <1> 	xchg	dh, ch
  4486 0000283E FECE                <1> 	dec	dh 
  4487 00002840 38EE                <1> 	cmp	dh, ch
  4488 00002842 73E1                <1> 	jnb	short vga_g_down_l0
  4489 00002844 C3                  <1> 	retn
  4490                              <1> 
  4491                              <1> vga_g_down_l2:
  4492                              <1> 	; vgamem_fill_pl4(cul,i,cols,nbcols,cheight,attr);
  4493 00002845 E8D3FEFFFF          <1> 	call	vgamem_fill_l8
  4494 0000284A EBF0                <1> 	jmp	short vga_g_down_l1
  4495                              <1> 		 
  4496                              <1> vga_g_down_planar:
  4497                              <1> 	; cl = upper left column ; cul
  4498                              <1> 	; ch = upper left row ; rul
  4499                              <1> 	; dl = lower rigth column ; clr
  4500                              <1> 	; dh = lower right row ; rlr
  4501                              <1> vga_g_down_pl0:
  4502                              <1>  	;{for(i=rlr;i>=rul;i--)
  4503                              <1>         ; if((i<rul+nblines)||(nblines==0))
  4504 0000284C 08C0                <1> 	or	al, al
  4505 0000284E 741C                <1> 	jz	short vga_g_down_pl2
  4506 00002850 88C4                <1> 	mov	ah, al
  4507 00002852 00EC                <1> 	add	ah, ch
  4508                              <1> 	;jc	short vga_g_down_pl2	
  4509 00002854 86EE                <1> 	xchg	ch, dh
  4510 00002856 38E5                <1> 	cmp	ch, ah
  4511 00002858 7212                <1> 	jb	short vga_g_down_pl2
  4512 0000285A 88EC                <1> 	mov	ah, ch
  4513 0000285C 28C4                <1> 	sub	ah, al ; ah = i - nblines
  4514                              <1> 	; else
  4515                              <1> 	; vgamem_copy_pl4(cul,i,i-nblines,cols,nbcols,cheight);
  4516 0000285E E88BFDFFFF          <1> 	call	vgamem_copy_pl4
  4517                              <1> vga_g_down_pl1:
  4518 00002863 86F5                <1> 	xchg	dh, ch
  4519 00002865 FECE                <1> 	dec	dh 
  4520 00002867 38EE                <1> 	cmp	dh, ch
  4521 00002869 73E1                <1> 	jnb	short vga_g_down_pl0
  4522 0000286B C3                  <1> 	retn
  4523                              <1> 
  4524                              <1> vga_g_down_pl2:
  4525                              <1> 	; vgamem_fill_pl4(cul,i,cols,nbcols,cheight,attr);
  4526 0000286C E8EBFDFFFF          <1> 	call	vgamem_fill_pl4
  4527 00002871 EBF0                <1> 	jmp	short vga_g_down_pl1
  4528                              <1> 
  4529                              <1> ; 07/07/2016
  4530                              <1> ; 27/06/2016 - TRDOS 386 (TRDOS v2.0)
  4531                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  4532                              <1> ;------------------------------------------------------
  4533                              <1> ; SCROLL DOWN
  4534                              <1> ;  THIS ROUTINE SCROLLS DOWN THE INFORMATION ON THE CRT
  4535                              <1> ; ENTRY --
  4536                              <1> ;  CH,CL = UPPER LEFT CORNER OF REGION TO SCROLL
  4537                              <1> ;  DH,DL = LOWER RIGHT CORNER OF REGION TO SCROLL
  4538                              <1> ;   BOTH OF THE ABOVE ARE IN CHARACTER POSITIONS
  4539                              <1> ;  BH = FILL VALUE FOR BLANKED LINES
  4540                              <1> ;  AL = # LINES TO SCROLL (AL=0 MEANS BLANK THE ENTIRE FIELD)
  4541                              <1> ;  DS = DATA SEGMENT
  4542                              <1> ;  ES = REGEN SEGMENT
  4543                              <1> ; EXIT --
  4544                              <1> ;  NOTHING, THE SCREEN IS SCROLLED
  4545                              <1> ;--------------------------------------------------------
  4546                              <1> 
  4547                              <1> 	; cl = upper left column
  4548                              <1> 	; ch = upper left row
  4549                              <1> 	; dl = lower rigth column
  4550                              <1> 	; dh = lower right row
  4551                              <1> 	;
  4552                              <1> 	; al = line count (AL=0 means blank entire fields)
  4553                              <1> 	; bl = fill value for blanked lines	
  4554                              <1> 	; bh = unused
  4555                              <1> 
  4556                              <1> GRAPHICS_DOWN:
  4557                              <1> 	; 07/07/2016
  4558                              <1> 	;AH = Current video mode, [CRT_MODE]
  4559                              <1> 	;STD				; SET DIRECTION
  4560 00002873 80FC07              <1> 	cmp	ah, 7
  4561 00002876 0F87F4FEFFFF        <1>         ja      vga_graphics_down
  4562                              <1> 	;je	_n0
  4563                              <1> 
  4564 0000287C 88C7                <1> 	MOV	bh, al			; save line count in BH
  4565 0000287E 6689D0              <1> 	MOV	AX, DX			; GET LOWER RIGHT POSITION INTO AX REG
  4566                              <1> 
  4567                              <1> ;-----	USE CHARACTER SUBROUTINE FOR POSITIONING
  4568                              <1> ;-----	ADDRESS RETURNED IS MULTIPLIED BY 2 FROM CORRECT VALUE
  4569                              <1> 
  4570 00002881 E8F2010000          <1> 	CALL	GRAPH_POSN
  4571 00002886 0FB7F8              <1> 	MOVzx	eDI, AX			; SAVE RESULT AS DESTINATION ADDRESS
  4572                              <1> 
  4573                              <1> ;-----	DETERMINE SIZE OF WINDOW
  4574                              <1> 
  4575 00002889 6629CA              <1> 	SUB	DX, CX
  4576 0000288C 6681C20101          <1>         ADD     DX, 101h                ; ADJUST VALUES
  4577 00002891 C0E602              <1> 	SAL	DH, 2			; MULTIPLY ROWS BY 4 AT 8 VERT DOTS/CHAR
  4578                              <1> 					; AND EVEN/ODD ROWS
  4579                              <1> 
  4580                              <1> ;-----	DETERMINE CRT MODE
  4581                              <1> 
  4582 00002894 803D[9A690000]06    <1> 	CMP	byte [CRT_MODE], 6	; TEST FOR MEDIUM RES
  4583 0000289B 7307                <1>         JNC     short _R12              ; FIND_SOURCE_DOWN
  4584                              <1> 
  4585                              <1> ;-----	MEDIUM RES DOWN
  4586 0000289D D0E2                <1> 	SAL	DL, 1			; # COLUMNS * 2, SINCE 2 BYTES/CHAR
  4587 0000289F 66D1E7              <1> 	SAL	DI, 1			; OFFSET *2 SINCE 2 BYTES/CHAR
  4588 000028A2 6647                <1> 	INC	DI			; POINT TO LAST BYTE
  4589                              <1> 
  4590                              <1> ;-----	DETERMINE THE SOURCE ADDRESS IN THE BUFFER
  4591                              <1> 
  4592                              <1> _R12:                                   ; FIND_SOURCE_DOWN
  4593 000028A4 81C700800B00        <1> 	add	edi, 0B8000h		
  4594 000028AA 6681C7F000          <1> 	ADD	DI, 240			; POINT TO LAST ROW OF PIXELS
  4595 000028AF C0E702              <1> 	sal	bh, 2			; multiply number of lines by 4
  4596 000028B2 74(06)              <1> 	JZ	short 6			; IF ZERO, THEN BLANK ENTIRE FIELD
  4597 000028B4 B050                <1> 	MOV	AL, 80			; 80 BYTES/ROW
  4598 000028B6 F6E7                <1> 	mul	bh			; determine offset to source
  4599 000028B8 89FE                <1> 	MOV	eSI, eDI		; SET UP SOURCE
  4600 000028BA 6629C6              <1> 	SUB	SI, AX			; SUBTRACT THE OFFSET
  4601 000028BD 88F4                <1> 	MOV	AH, DH			; NUMBER OF ROWS IN FIELD
  4602 000028BF 28FC                <1> 	sub	ah, bh			; determine number to move
  4603                              <1> 
  4604                              <1> ;-----	LOOP THROUGH, MOVING ONE ROW AT A TIME, BOTH EVEN AND ODD FIELDS
  4605                              <1> 
  4606                              <1> _R13:                                   ; ROW_LOOP_DOWN
  4607 000028C1 E824000000          <1>         CALL    _R17                    ; MOVE ONE ROW
  4608 000028C6 6681EE5020          <1> 	SUB	SI, 2000h+80		; MOVE TO NEXT ROW
  4609 000028CB 6681EF5020          <1> 	SUB	DI, 2000h+80
  4610 000028D0 FECC                <1> 	DEC	AH			; NUMBER OF ROWS TO MOVE
  4611 000028D2 75ED                <1>         JNZ     short _R13              ; CONTINUE TILL ALL MOVED
  4612                              <1> 
  4613                              <1> ;-----	FILL IN THE VACATED LINE(S)
  4614                              <1> _R14:                                   ; CLEAR_ENTRY_DOWN
  4615 000028D4 88D8                <1> 	mov	al, bl			; attribute to fill with
  4616                              <1> _R15_:                                  ; CLEAR_LOOP_DOWN
  4617 000028D6 E82B000000          <1> 	CALL	_R18			; CLEAR A ROW
  4618 000028DB 6681EF5020          <1> 	SUB	DI, 2000h+80		; POINT TO NEXT LINE
  4619 000028E0 FECF                <1> 	dec	bh			; number of lines to fill
  4620 000028E2 75F2                <1>         JNZ     short _R15_             ; CLEAR_LOOP_DOWN
  4621                              <1> 	; 18/11/2020
  4622 000028E4 FC                  <1> 	CLD				; RESET THE DIRECTION FLAG
  4623                              <1> 	
  4624 000028E5 C3                  <1> 	retn				; EVERYTHING DONE
  4625                              <1> 
  4626                              <1> _R16:                                   ; BLANK_FIELD_DOWN
  4627 000028E6 88F7                <1> 	mov	bh, dh			; set blank count to everything in field
  4628 000028E8 EBEA                <1>         JMP     short _R14              ; CLEAR THE FIELD
  4629                              <1> 
  4630                              <1> ; 27/06/2016 - TRDOS 386 (TRDOS v2.0)
  4631                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  4632                              <1> 
  4633                              <1> ;-----	ROUTINE TO MOVE ONE ROW OF INFORMATION
  4634                              <1> 
  4635                              <1> _R17:
  4636 000028EA 0FB6CA              <1> 	MOVzx	ecx, DL			; NUMBER OF BYTES IN THE ROW
  4637 000028ED 56                  <1> 	PUSH	eSI
  4638 000028EE 57                  <1> 	PUSH	eDI			; SAVE POINTERS
  4639 000028EF F3A4                <1> 	REP	MOVSB			; MOVE THE EVEN FIELD
  4640 000028F1 5F                  <1> 	POP	eDI
  4641 000028F2 5E                  <1> 	POP	eSI
  4642 000028F3 6681C60020          <1> 	ADD	SI, 2000h
  4643 000028F8 6681C70020          <1> 	ADD	DI, 2000h		; POINT TO THE ODD FIELD
  4644 000028FD 56                  <1> 	PUSH	eSI
  4645 000028FE 57                  <1> 	PUSH	eDI			; SAVE THE POINTERS
  4646 000028FF 88D1                <1> 	MOV	CL, DL			; COUNT BACK
  4647 00002901 F3A4                <1> 	REP	MOVSB			; MOVE THE ODD FIELD
  4648 00002903 5F                  <1> 	POP	eDI
  4649 00002904 5E                  <1> 	POP	eSI			; POINTERS BACK
  4650 00002905 C3                  <1> 	RETn				; RETURN TO CALLER
  4651                              <1> 
  4652                              <1> ;-----	CLEAR A SINGLE ROW
  4653                              <1> 
  4654                              <1> _R18:
  4655 00002906 0FB6CA              <1> 	MOVzx	ecx, DL			; NUMBER OF BYTES IN FIELD
  4656 00002909 57                  <1> 	PUSH	eDI			; SAVE POINTER
  4657 0000290A F3AA                <1> 	REP	STOSB			; STORE THE NEW VALUE
  4658 0000290C 5F                  <1> 	POP	eDI			; POINTER BACK
  4659 0000290D 6681C70020          <1> 	ADD	DI, 2000h		; POINT TO ODD FIELD
  4660 00002912 57                  <1> 	PUSH	eDI
  4661 00002913 88D1                <1> 	MOV	CL, DL
  4662 00002915 F3AA                <1> 	REP	STOSB			; FILL THE ODD FIELD
  4663 00002917 5F                  <1> 	POP	eDI
  4664 00002918 C3                  <1> 	RETn				; RETURN TO CALLER
  4665                              <1> 
  4666                              <1> ; 04/07/2016
  4667                              <1> ; 01/07/2016
  4668                              <1> ; 30/06/2016 - TRDOS 386 (TRDOS v2.0)
  4669                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  4670                              <1> ;--------------------------------------------------
  4671                              <1> ; GRAPHICS WRITE
  4672                              <1> ;  THIS ROUTINE WRITES THE ASCII CHARACTER TO THE CURRENT
  4673                              <1> ;  POSITION ON THE SCREEN.
  4674                              <1> ; ENTRY --
  4675                              <1> ;  AL = CHARACTER TO WRITE
  4676                              <1> ;  BL = COLOR ATTRIBUTE TO BE USED FOR FOREGROUND COLOR
  4677                              <1> ;	IF BIT 7 IS SET, THE CHAR IS XOR'D INTO THE REGEN BUFFER
  4678                              <1> ;	(0 IS USED FOR THE BACKGROUND COLOR)
  4679                              <1> ;  CX = NUMBER OF CHARS TO WRITE
  4680                              <1> ;  DS = DATA SEGMENT
  4681                              <1> ;  ES = REGEN SEGMENT
  4682                              <1> ; EXIT --
  4683                              <1> ;  NOTHING IS RETURNED
  4684                              <1> ;
  4685                              <1> ; GRAPHICS READ
  4686                              <1> ;  THIS ROUTINE READS THE ASCII CHARACTER AT THE CURRENT CURSOR
  4687                              <1> ;  POSITION ON THE SCREEN BY MATCHING THE DOTS ON THE SCREEN TO THE
  4688                              <1> ;  CHARACTER GENERATOR CODE POINTS
  4689                              <1> ; ENTRY --
  4690                              <1> ;  NONE (0 IS ASSUMED AS THE BACKGROUND COLOR)
  4691                              <1> ; EXIT --
  4692                              <1> ;  AL = CHARACTER READ AT THAT POSITION (0 RETURNED IF NONE FOUND)
  4693                              <1> ;
  4694                              <1> ; FOR BOTH ROUTINES, THE IMAGES USED TO FORM CHARS ARE CONTAINED IN ROM
  4695                              <1> ;  FOR THE 1ST 128 CHARS.  TO ACCESS CHARS IN THE SECOND HALF, THE USER
  4696                              <1> ;  MUST INITIALIZE THE VECTOR AT INTERRUPT 1FH (LOCATION 0007CH) TO
  4697                              <1> ;  POINT TO THE USER SUPPLIED TABLE OF GRAPHIC IMAGES (8X8 BOXES).
  4698                              <1> ;  FAILURE TO DO SO WILL CAUSE IN STRANGE RESULTS
  4699                              <1> ;-----------------------------------------------------
  4700                              <1> 
  4701                              <1> GRAPHICS_WRITE:
  4702 00002919 25FF000000          <1> 	and 	eax, 0FFh		; ZERO TO HIGH OF CODE POINT
  4703 0000291E 50                  <1> 	PUSH	eAX			; SAVE CODE POINT VALUE
  4704                              <1> 
  4705                              <1> ;-----	DETERMINE POSITION IN REGEN BUFFER TO PUT CODE POINTS
  4706                              <1> 
  4707 0000291F E84D010000          <1> 	CALL	S26			; FIND LOCATION IN REGEN BUFFER
  4708 00002924 89C7                <1> 	MOV	eDI, eAX		; REGEN POINTER IN DI
  4709                              <1> 
  4710                              <1> ;-----	DETERMINE REGION TO GET CODE POINTS FROM
  4711                              <1> 
  4712 00002926 58                  <1> 	POP	eAX			; RECOVER CODE POINT
  4713                              <1> 
  4714 00002927 BE[F8370100]        <1> 	MOV	eSI, CRT_CHAR_GEN	; OFFSET OF IMAGES
  4715                              <1> 
  4716                              <1> ;-----	DETERMINE GRAPHICS MODE IN OPERATION
  4717                              <1> 					; DETERMINE_MODE
  4718 0000292C 66C1E003            <1> 	SAL	AX, 3			; MULTIPLY CODE POINT VALUE BY 8
  4719 00002930 01C6                <1> 	ADD	eSI, eAX		; SI HAS OFFSET OF DESIRED CODES
  4720                              <1> 	
  4721 00002932 803D[9A690000]06    <1> 	CMP	byte [CRT_MODE], 6
  4722 00002939 7231                <1> 	JC	short S6		; TEST FOR MEDIUM RESOLUTION MODE
  4723                              <1> 
  4724                              <1> ;-----	HIGH RESOLUTION MODE
  4725                              <1> 
  4726 0000293B 81C700800B00        <1> 	add	edi, 0B8000h
  4727                              <1> S1:					; HIGH_CHAR
  4728 00002941 57                  <1> 	PUSH	eDI			; SAVE REGEN POINTER
  4729 00002942 56                  <1> 	PUSH	eSI			; SAVE CODE POINTER
  4730 00002943 B604                <1> 	MOV	DH, 4			; NUMBER OF TIMES THROUGH LOOP
  4731                              <1> S2:
  4732 00002945 AC                  <1> 	LODSB				; GET BYTE FROM CODE POINTS
  4733 00002946 F6C380              <1> 	TEST	BL, 80H			; SHOULD WE USE THE FUNCTION
  4734 00002949 7515                <1> 	JNZ	short S5		; TO PUT CHAR IN
  4735 0000294B AA                  <1> 	STOSB				; STORE IN REGEN BUFFER
  4736 0000294C AC                  <1> 	LODSB
  4737                              <1> S4:
  4738 0000294D 8887FF1F0000        <1> 	MOV	[eDI+2000H-1], AL ; STORE IN SECOND HALF
  4739 00002953 83C74F              <1> 	ADD	eDI, 79			; MOVE TO NEXT ROW IN REGEN
  4740 00002956 FECE                <1> 	DEC	DH			; DONE WITH LOOP
  4741 00002958 75EB                <1> 	JNZ	short S2
  4742 0000295A 5E                  <1> 	POP	eSI
  4743 0000295B 5F                  <1> 	POP	eDI			; RECOVER REGEN POINTER
  4744 0000295C 47                  <1> 	INC	eDI			; POINT TO NEXT CHAR POSITION
  4745 0000295D E2E2                <1> 	LOOP	S1			; MORE CHARS TO WRITE
  4746 0000295F C3                  <1> 	retn
  4747                              <1> 
  4748                              <1> S5:
  4749 00002960 3207                <1> 	XOR	AL, [eDI]		; EXCLUSIVE OR WITH CURRENT
  4750 00002962 AA                  <1> 	STOSB				; STORE THE CODE POINT
  4751 00002963 AC                  <1> 	LODSB				; AGAIN FOR ODD FIELD
  4752 00002964 3287FF1F0000        <1> 	XOR	AL, [eDI+2000H-1]
  4753 0000296A EBE1                <1> 	JMP	short S4		; BACK TO MAINSTREAM
  4754                              <1> 
  4755                              <1> ;-----	MEDIUM RESOLUTION WRITE
  4756                              <1> S6:					; MED_RES_WRITE
  4757 0000296C 88DA                <1> 	MOV	DL, BL			; SAVE HIGH COLOR BIT
  4758 0000296E 66D1E7              <1> 	SAL	DI, 1			; OFFSET*2 SINCE 2 BYTES/CHAR
  4759                              <1> 					; EXPAND BL TO FULL WORD OF COLOR
  4760 00002971 80E303              <1> 	AND	BL, 3			; ISOLATE THE COLOR BITS ( LOW 2 BITS )
  4761 00002974 B055                <1> 	MOV	AL, 055H 		; GET BIT CONVERSION MULTIPLIER
  4762 00002976 F6E3                <1> 	MUL	BL			; EXPAND 2 COLOR BITS TO 4 REPLICATIONS
  4763 00002978 88C3                <1> 	MOV	BL, AL			; PLACE BACK IN WORK REGISTER
  4764 0000297A 88C7                <1> 	MOV	BH, AL			; EXPAND TO 8 REPLICATIONS OF COLOR BITS
  4765 0000297C 81C700800B00        <1> 	add	edi, 0B8000h
  4766                              <1> S7:                                     ; MED_CHAR
  4767 00002982 57                  <1> 	PUSH	eDI			; SAVE REGEN POINTER
  4768 00002983 56                  <1> 	PUSH	eSI			; SAVE THE CODE POINTER
  4769 00002984 B604                <1> 	MOV	DH, 4			; NUMBER OF LOOPS
  4770                              <1> S8:
  4771 00002986 AC                  <1> 	LODSB				; GET CODE POINT
  4772 00002987 E8B3000000          <1> 	CALL	S21			; DOUBLE UP ALL THE BITS
  4773 0000298C 6621D8              <1> 	AND	AX, BX			; CONVERT TO FOREGROUND COLOR ( 0 BACK )
  4774 0000298F 86E0                <1> 	XCHG	AH, AL			; SWAP HIGH/LOW BYTES FOR WORD MOVE
  4775 00002991 F6C280              <1> 	TEST	DL, 80H			; IS THIS XOR FUNCTION
  4776 00002994 7403                <1> 	JZ	short S9		; NO, STORE IT IN AS IS
  4777 00002996 663307              <1> 	XOR	AX, [eDI]		; DO FUNCTION WITH LOW/HIGH
  4778                              <1> S9:
  4779 00002999 668907              <1> 	MOV	[eDI], AX		; STORE FIRST BYTE HIGH, SECOND LOW
  4780 0000299C AC                  <1> 	LODSB				; GET CODE POINT
  4781 0000299D E89D000000          <1> 	CALL	S21
  4782 000029A2 6621D8              <1> 	AND	AX, BX			; CONVERT TO COLOR
  4783 000029A5 86E0                <1> 	XCHG	AH, AL			; SWAP HIGH/LOW BYTES FOR WORD MOVE
  4784 000029A7 F6C280              <1> 	TEST	DL, 80H			; AGAIN, IS THIS XOR FUNCTION
  4785 000029AA 7407                <1> 	JZ	short _S10		; NO, JUST STORE THE VALUES
  4786 000029AC 66338700200000      <1> 	XOR	AX, [eDI+2000H]		; FUNCTION WITH FIRST HALF LOW
  4787                              <1> _S10:
  4788 000029B3 66898700200000      <1> 	MOV	[eDI+2000H], AX		; STORE SECOND PORTION HIGH
  4789 000029BA 6683C750            <1> 	ADD	DI, 80			; POINT TO NEXT LOCATION
  4790 000029BE FECE                <1> 	DEC	DH
  4791 000029C0 75C4                <1> 	JNZ	short S8		; KEEP GOING
  4792 000029C2 5E                  <1> 	POP	eSI			; RECOVER CODE POINTER
  4793 000029C3 5F                  <1> 	POP	eDI			; RECOVER REGEN POINTER
  4794 000029C4 47                  <1> 	INC	eDI			; POINT TO NEXT CHAR POSITION
  4795 000029C5 47                  <1> 	INC	eDI
  4796 000029C6 E2BA                <1> 	LOOP	S7			; MORE TO WRITE
  4797 000029C8 C3                  <1> 	retn
  4798                              <1> 
  4799                              <1> ; 04/07/2016
  4800                              <1> ; 01/07/2016
  4801                              <1> ; 30/06/2016 - TRDOS 386 (TRDOS v2.0)
  4802                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  4803                              <1> ;----------------------------------------
  4804                              <1> ; GRAPHICS READ
  4805                              <1> ;----------------------------------------
  4806                              <1> GRAPHICS_READ:
  4807 000029C9 E8A3000000          <1> 	CALL	S26			; CONVERTED TO OFFSET IN REGEN
  4808 000029CE 89C6                <1> 	MOV	eSI, eAX		; SAVE IN SI
  4809 000029D0 81C600800B00        <1> 	add	esi, 0B8000h		; 01/07/2016
  4810 000029D6 83EC08              <1> 	SUB	eSP, 8			; ALLOCATE SPACE FOR THE READ CODE POINT
  4811 000029D9 89E5                <1> 	MOV	eBP, eSP		; POINTER TO SAVE AREA
  4812                              <1> 
  4813                              <1> ;-----	DETERMINE GRAPHICS MODES
  4814 000029DB B604                <1> 	mov	dh, 4			; number of passes ; 01/07/2016
  4815 000029DD 803D[9A690000]06    <1> 	CMP	byte [CRT_MODE], 6
  4816 000029E4 7219                <1> 	JC	short S12		; MEDIUM RESOLUTION
  4817                              <1> 
  4818                              <1> ;-----	HIGH RESOLUTION READ
  4819                              <1> ;-----	GET VALUES FROM REGEN BUFFER AND CONVERT TO CODE POINT
  4820                              <1> 	;MOV	DH,4			; NUMBER OF PASSES
  4821                              <1> S11:
  4822 000029E6 8A06                <1> 	MOV	AL, [eSI] 		; GET FIRST BYTE
  4823 000029E8 884500              <1> 	MOV	[eBP], AL 		; SAVE IN STORAGE AREA
  4824 000029EB 45                  <1> 	INC	eBP			; NEXT LOCATION
  4825 000029EC 8A8600200000        <1> 	MOV	AL, [eSI+2000H]		; GET LOWER REGION BYTE
  4826 000029F2 884500              <1> 	MOV	[eBP], AL 		; ADJUST AND STORE
  4827 000029F5 45                  <1> 	INC	eBP
  4828 000029F6 83C650              <1> 	ADD	eSI, 80			; POINTER INTO REGEN
  4829 000029F9 FECE                <1> 	DEC	DH			; LOOP CONTROL
  4830 000029FB 75E9                <1> 	JNZ	short S11		; DO IT SOME MORE
  4831 000029FD EB1D                <1> 	JMP	SHORT S14		; GO MATCH THE SAVED CODE POINTS
  4832                              <1> 
  4833                              <1> ;-----	MEDIUM RESOLUTION READ
  4834                              <1> S12:	
  4835 000029FF 66D1E6              <1> 	SAL	SI, 1			; OFFSET*2 SINCE 2 BYTES/CHAR
  4836                              <1> 	;MOV	DH, 4			; NUMBER OF PASSES
  4837                              <1> S13:
  4838 00002A02 E84D000000          <1> 	CALL	S23			; GET BYTES FROM REGEN INTO SINGLE SAVE
  4839 00002A07 81C6FE1F0000        <1> 	ADD	eSI, 2000H-2		; GO TO LOWER REGION
  4840 00002A0D E842000000          <1> 	CALL	S23			; GET THIS PAIR INTO SAVE
  4841 00002A12 81EEB21F0000        <1> 	SUB	eSI, 2000H-80+2		; ADJUST POINTER BACK INTO UPPER
  4842 00002A18 FECE                <1> 	DEC	DH
  4843 00002A1A 75E6                <1> 	JNZ	short S13		; KEEP GOING UNTIL ALL 8 DONE
  4844                              <1> 
  4845                              <1> ;-----	SAVE AREA HAS CHARACTER IN IT, MATCH IT
  4846                              <1> S14:					; FIND_CHAR
  4847 00002A1C BF[F8370100]        <1> 	MOV	eDI, CRT_CHAR_GEN	; ESTABLISH ADDRESSING
  4848 00002A21 83ED08              <1> 	SUB	eBP, 8			; ADJUST POINTER TO START OF SAVE AREA
  4849 00002A24 89EE                <1> 	MOV	eSI, eBP
  4850                              <1> S15:
  4851 00002A26 66B80001            <1> 	mov	ax, 256			; NUMBER TO TEST AGAINST
  4852                              <1> S16:
  4853 00002A2A 56                  <1> 	PUSH	eSI			; SAVE SAVE AREA POINTER
  4854 00002A2B 57                  <1> 	PUSH	eDI			; SAVE CODE POINTER
  4855                              <1> 	;MOV	eCX, 4			; NUMBER OF WORDS TO MATCH
  4856                              <1> 	;REPE	CMPSW			; COMPARE THE 8 BYTES AS WORDS
  4857 00002A2C A7                  <1> 	cmpsd				; compare first 4 bytes 
  4858 00002A2D 7501                <1> 	jne	short S17		; 
  4859 00002A2F A7                  <1> 	cmpsd				; compare last 4 bytes
  4860                              <1> S17:
  4861 00002A30 5F                  <1> 	POP	eDI			; RECOVER THE POINTERS
  4862 00002A31 5E                  <1> 	POP	eSI
  4863                              <1> 	;JZ	short S18		; IF ZERO FLAG SET, THEN MATCH OCCURRED
  4864 00002A32 7407                <1> 	je	short S18
  4865                              <1> 	;				; NO MATCH, MOVE ON TO NEXT
  4866 00002A34 83C708              <1> 	ADD	eDI, 8			; NEXT CODE POINT
  4867 00002A37 6648                <1> 	dec	ax			; LOOP CONTROL
  4868 00002A39 75EF                <1> 	JNZ	short S16		; DO ALL OF THEM
  4869                              <1> 
  4870                              <1> ;-----	CHARACTER IS FOUND ( AL=0 IF NOT FOUND )
  4871                              <1> S18:	
  4872 00002A3B 83C408              <1> 	ADD	eSP, 8			; READJUST THE STACK, THROW AWAY SAVE
  4873 00002A3E C3                  <1> 	retn				; ALL DONE
  4874                              <1> 
  4875                              <1> ; 30/06/2016 - TRDOS 386 (TRDOS v2.0)
  4876                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  4877                              <1> ;--------------------------------------------
  4878                              <1> ; EXPAND BYTE
  4879                              <1> ;  THIS ROUTINE TAKES THE BYTE IN AL AND DOUBLES ALL
  4880                              <1> ;  OF THE BITS, TURNING THE 8 BITS INTO 16 BITS.
  4881                              <1> ;  THE RESULT IS LEFT IN AX
  4882                              <1> ;--------------------------------------------
  4883                              <1> S21:
  4884 00002A3F 6651                <1> 	PUSH	CX			; SAVE REGISTER
  4885                              <1> 	;MOV	CX, 8			; SHIFT COUNT REGISTER FOR ONE BYTE
  4886 00002A41 B108                <1> 	mov	cl, 8
  4887                              <1> S22:
  4888 00002A43 D0C8                <1> 	ROR	AL,1			; SHIFT BITS, LOW BIT INTO CARRY FLAG
  4889 00002A45 66D1DD              <1> 	RCR	BP,1			; MOVE CARRY FLAG (LOW BIT INTO RESULTS
  4890 00002A48 66D1FD              <1> 	SAR	BP,1			; SIGN EXTEND HIGH BIT (DOUBLE IT)
  4891                              <1> 	;LOOP	S22			; REPEAT FOR ALL 8 BITS
  4892 00002A4B FEC9                <1> 	dec	cl
  4893 00002A4D 75F4                <1> 	jnz	short S22
  4894 00002A4F 6695                <1> 	XCHG	AX, BP			; MOVE RESULTS TO PARAMETER REGISTER
  4895 00002A51 6659                <1> 	POP	CX			; RECOVER REGISTER
  4896 00002A53 C3                  <1> 	RETn				; ALL DONE
  4897                              <1> 
  4898                              <1> ; 01/07/2016 - TRDOS 386 (TRDOS v2.0)
  4899                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  4900                              <1> ;--------------------------------------------------
  4901                              <1> ; MED_READ_BYTE
  4902                              <1> ; THIS ROUTINE WILL TAKE 2 BYTES FROM THE REGEN BUFFER,
  4903                              <1> ;  COMPARE AGAINST THE CURRENT FOREGROUND COLOR, AND PLACE
  4904                              <1> ;  THE CORRESPONDING ON/OFF BIT PATTERN INTO THE CURRENT
  4905                              <1> ;  POSITION IN THE SAVE AREA
  4906                              <1> ; ENTRY --
  4907                              <1> ;  SI,DS = POINTER TO REGEN AREA OF INTEREST
  4908                              <1> ;  BX = EXPANDED FOREGROUND COLOR
  4909                              <1> ;  BP = POINTER TO SAVE AREA
  4910                              <1> ; EXIT --
  4911                              <1> ;  SI AND BP ARE INCREMENTED
  4912                              <1> ;----------------------------------------------------
  4913                              <1> S23:
  4914 00002A54 66AD                <1> 	LODSW				; GET FIRST BYTE AND SECOND BYTES
  4915 00002A56 86C4                <1> 	XCHG	AL, AH			; SWAP FOR COMPARE
  4916 00002A58 66B900C0            <1> 	MOV	CX, 0C000H		; 2 BIT MASK TO TEST THE ENTRIES
  4917 00002A5C B200                <1> 	MOV	DL, 0			; RESULT REGISTER
  4918                              <1> S24:
  4919 00002A5E 6685C8              <1> 	TEST	AX, CX			; IS THIS SECTION BACKCROUND?
  4920 00002A61 7401                <1>         JZ      short S25               ; IF ZERO, IT IS BACKGROUND (CARRY=0)
  4921 00002A63 F9                  <1> 	STC				; WASN'T, SO SET CARRY
  4922                              <1> S25:
  4923 00002A64 D0D2                <1> 	RCL	DL, 1			; MOVE THAT BIT INTO THE RESULT
  4924 00002A66 66C1E902            <1> 	SHR	CX, 2			; MOVE THE MASK TO THE RIGHT BY 2 BITS
  4925 00002A6A 73F2                <1> 	JNC	short S24		; DO IT AGAIN IF MASK DIDN'T FALL OUT
  4926 00002A6C 885500              <1> 	MOV	[eBP], DL 		; STORE RESULT IN SAVE AREA
  4927 00002A6F 45                  <1> 	INC	eBP			; ADJUST POINTER
  4928 00002A70 C3                  <1> 	RETn				; ALL DONE
  4929                              <1> 
  4930                              <1> ; 30/06/2016 - TRDOS 386 (TRDOS v2.0)
  4931                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  4932                              <1> ;-----------------------------------------
  4933                              <1> ; V4_POSITION
  4934                              <1> ;  THIS ROUTINE TAKES THE CURSOR POSITION CONTAINED IN
  4935                              <1> ;  THE MEMORY LOCATION, AND CONVERTS IT INTO AN OFFSET
  4936                              <1> ;  INTO THE REGEN BUFFER, ASSUMING ONE BYTE/CHAR.
  4937                              <1> ;  FOR MEDIUM RESOLUTION GRAPHICS, THE NUMBER MUST
  4938                              <1> ;  BE DOUBLED.
  4939                              <1> ; ENTRY -- NO REGISTERS,MEMORY LOCATION @CURSOR_POSN IS USED
  4940                              <1> ; EXIT--
  4941                              <1> ;  AX CONTAINS OFFSET INTO REGEN BUFFER
  4942                              <1> ;-----------------------------------------
  4943                              <1> S26:
  4944 00002A71 0FB705[F6630100]    <1> 	movzx	eax, word [CURSOR_POSN]	; GET CURRENT CURSOR
  4945                              <1> GRAPH_POSN:
  4946 00002A78 53                  <1> 	PUSH	eBX			; SAVE REGISTER
  4947 00002A79 0FB6D8              <1> 	movzx	ebx, al			; SAVE A COPY OF CURRENT CURSOR
  4948 00002A7C A0[9C690000]        <1> 	MOV	AL, [CRT_COLS]		; GET BYTES PER COLUMN
  4949 00002A81 F6E4                <1> 	MUL	AH			; MULTIPLY BY ROWS
  4950 00002A83 66C1E002            <1> 	SHL	AX, 2			; MULTIPLY * 4 SINCE 4 ROWS/BYTE
  4951 00002A87 01D8                <1> 	ADD	eAX, eBX		; DETERMINE OFFSET
  4952 00002A89 5B                  <1> 	POP	eBX			; RECOVER POINTER
  4953 00002A8A C3                  <1> 	RETn				; ALL DONE
  4954                              <1> 
  4955                              <1> ; 09/07/2016
  4956                              <1> ; 01/07/2016 - TRDOS 386 (TRDOS v2.0)
  4957                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  4958                              <1> ;---------------------------------------------
  4959                              <1> ; SET_COLOR
  4960                              <1> ;	THIS ROUTINE WILL ESTABLISH THE BACKGROUND COLOR, THE OVERSCAN COLOR,
  4961                              <1> ;	AND THE FOREGROUND COLOR SET FOR MEDIUM RESOLUTION GRAPHICS
  4962                              <1> ; INPUT
  4963                              <1> ;	(BH) HAS COLOR ID
  4964                              <1> ;		IF BH=0, THE BACKGROUND COLOR VALUE IS SET
  4965                              <1> ;			FROM THE LOW BITS OF BL (0-31)
  4966                              <1> ;		IF BH=1, THE PALETTE SELECTION IS MADE
  4967                              <1> ;			BASED ON THE LOW BIT OF BL:
  4968                              <1> ;				0 = GREEN, RED, YELLOW FOR COLORS 1,2,3
  4969                              <1> ;				1 = BLUE, CYAN, MAGENTA FOR COLORS 1,2,3
  4970                              <1> ;	(BL) HAS THE COLOR VALUE TO BE USED
  4971                              <1> ; OUTPUT
  4972                              <1> ;	THE COLOR SELECTION IS UPDATED
  4973                              <1> ;----------------------------------------------
  4974                              <1> SET_COLOR:
  4975 00002A8B 803D[9A690000]07    <1>         cmp     byte [CRT_MODE], 7      ; 09/07/2016
  4976 00002A92 0F87BFEFFFFF        <1> 	ja	VIDEO_RETURN		; nothing to do for VGA modes	 
  4977                              <1> 
  4978                              <1> 	;MOV	DX, [ADDR_6845]		; I/O PORT FOR PALETTE
  4979                              <1> 	;mov	dx, 3D4h
  4980                              <1> 	;ADD	DX,5			; OVERSCAN PORT
  4981 00002A98 66BAD903            <1> 	mov	dx, 3D9h
  4982 00002A9C A0[9D690000]        <1> 	MOV	AL, [CRT_PALETTE] 	; GET THE CURRENT PALETTE VALUE
  4983 00002AA1 08FF                <1> 	OR	BH, BH			; IS THIS COLOR 0?
  4984 00002AA3 7512                <1> 	JNZ	short M20		; OUTPUT COLOR 1
  4985                              <1> 
  4986                              <1> ;-----	HANDLE COLOR 0 BY SETTING THE BACKGROUND COLOR
  4987                              <1> 
  4988 00002AA5 24E0                <1> 	AND	AL, 0E0H 		; TURN OFF LOW 5 BITS OF CURRENT
  4989 00002AA7 80E31F              <1> 	AND	BL, 01FH 		; TURN OFF HIGH 3 BITS OF INPUT VALUE
  4990 00002AAA 08D8                <1> 	OR	AL, BL			; PUT VALUE INTO REGISTER
  4991                              <1> M19:					; OUTPUT THE PALETTE
  4992 00002AAC EE                  <1> 	OUT	DX, AL			; OUTPUT COLOR SELECTION TO 3D9 PORT
  4993 00002AAD A2[9D690000]        <1> 	MOV	[CRT_PALETTE], AL 	; SAVE THE COLOR VALUE
  4994 00002AB2 E9A0EFFFFF          <1> 	JMP	VIDEO_RETURN
  4995                              <1> 
  4996                              <1> ;-----	HANDLE COLOR 1 BY SELECTING THE PALETTE TO BE USED
  4997                              <1> 
  4998                              <1> M20:
  4999 00002AB7 24DF                <1> 	AND	AL, 0DFH 		; TURN OFF PALETTE SELECT BIT
  5000 00002AB9 D0EB                <1> 	SHR	BL, 1			; TEST THE LOW ORDER BIT OF BL
  5001 00002ABB 73EF                <1> 	JNC	short M19		; ALREADY DONE
  5002 00002ABD 0C20                <1> 	OR	AL, 20H			; TURN ON PALETTE SELECT BIT
  5003 00002ABF EBEB                <1> 	JMP	short M19		; GO DO IT
  5004                              <1> 
  5005                              <1> ; 09/07/2016
  5006                              <1> ; 01/07/2016 - TRDOS 386 (TRDOS v2.0)
  5007                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  5008                              <1> ;--------------------------------------------
  5009                              <1> ; READ DOT -- WRITE DOT
  5010                              <1> ; THESE ROUTINES WILL WRITE A DOT, OR READ THE
  5011                              <1> ;  DOT AT THE INDICATED LOCATION
  5012                              <1> ; ENTRY --
  5013                              <1> ;   DX = ROW (0-199)	(THE ACTUAL VALUE DEPENDS ON THE MODE)
  5014                              <1> ;   CX = COLUMN ( 0-639) ( THE VALUES ARE NOT RANGE CHECKED )
  5015                              <1> ;   AL = DOT VALUE TO WRITE (1,2 OR 4 BITS DEPENDING ON MODE,
  5016                              <1> ;	REQUIRED FOR WRITE DOT ONLY, RIGHT JUSTIFIED)
  5017                              <1> ;	BIT 7 OF AL = 1 INDICATES XOR THE VALUE INTO THE LOCATION
  5018                              <1> ;   DS = DATA SEGMENT
  5019                              <1> ;   ES = REGEN SEGMENT
  5020                              <1> ;
  5021                              <1> ; EXIT
  5022                              <1> ;	AL = DOT VALUE READ, RIGHT JUSTIFIED, READ ONLY
  5023                              <1> ;----------------------------------------------
  5024                              <1> 
  5025                              <1> READ_DOT:
  5026                              <1> 	; 09/07/2016
  5027 00002AC1 8A25[9A690000]      <1> 	mov	ah,  [CRT_MODE]
  5028 00002AC7 80FC07              <1> 	cmp	ah, 7 ; 6!?
  5029 00002ACA 760A                <1> 	jna	short read_dot_cga
  5030                              <1> 
  5031 00002ACC E8CB030000          <1> 	call	vga_read_pixel
  5032                              <1> 	; al = pixel value
  5033 00002AD1 E986EFFFFF          <1> 	jmp	_video_return
  5034                              <1> 
  5035                              <1> read_dot_cga:
  5036                              <1> 	;je	VIDEO_RETURN ; 7	
  5037 00002AD6 80FC04              <1> 	cmp	ah, 4 ; graphics ? 
  5038 00002AD9 0F8278EFFFFF        <1> 	jb	VIDEO_RETURN ; no, text mode, nothing to do
  5039                              <1> 
  5040 00002ADF E855000000          <1> 	CALL	R3			; DETERMINE BYTE POSITION OF DOT
  5041 00002AE4 8A06                <1> 	MOV	AL, [eSI]		; GET THE BYTE
  5042 00002AE6 20E0                <1> 	AND	AL, AH			; MASK OFF THE OTHER BITS IN THE BYTE
  5043 00002AE8 D2E0                <1> 	SHL	AL, CL			; LEFT JUSTIFY THE VALUE
  5044 00002AEA 88F1                <1> 	MOV	CL, DH			; GET NUMBER OF BITS IN RESULT
  5045 00002AEC D2C0                <1> 	ROL	AL, CL			; RIGHT JUSTIFY THE RESULT
  5046                              <1> 	;JMP	VIDEO_RETURN		; RETURN FROM VIDEO I/O
  5047 00002AEE 0FB6C0              <1> 	movzx	eax, al
  5048 00002AF1 E966EFFFFF          <1> 	jmp	_video_return
  5049                              <1> 
  5050                              <1> ; 09/07/2016
  5051                              <1> ; 01/07/2016 - TRDOS 386 (TRDOS v2.0)
  5052                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  5053                              <1> 
  5054                              <1> WRITE_DOT:
  5055                              <1> 	; 09/07/2016
  5056 00002AF6 8A25[9A690000]      <1> 	mov	ah, [CRT_MODE]
  5057 00002AFC 80FC07              <1> 	cmp	ah, 7 ; 6!?
  5058 00002AFF 760A                <1> 	jna	short write_dot_cga
  5059                              <1> 	
  5060 00002B01 E805030000          <1> 	call	vga_write_pixel
  5061 00002B06 E94CEFFFFF          <1> 	jmp	VIDEO_RETURN
  5062                              <1> 
  5063                              <1> write_dot_cga:
  5064                              <1> 	;je	VIDEO_RETURN ; 7	
  5065 00002B0B 80FC04              <1> 	cmp	ah, 4 ; graphics ? 
  5066 00002B0E 0F8243EFFFFF        <1> 	jb	VIDEO_RETURN ; no, text mode, nothing to do
  5067                              <1> 
  5068                              <1> 	;PUSH	AX			; SAVE DOT VALUE
  5069 00002B14 6650                <1> 	PUSH	AX			; TWICE
  5070 00002B16 E81E000000          <1> 	CALL	R3			; DETERMINE BYTE POSITION OF THE DOT
  5071 00002B1B D2E8                <1> 	SHR	AL, CL			; SHIFT TO SET UP THE BITS FOR OUTPUT
  5072 00002B1D 20E0                <1> 	AND	AL, AH			; STRIP OFF THE OTHER BITS
  5073 00002B1F 8A0E                <1> 	MOV	CL, [eSI]		; GET THE CURRENT BYTE
  5074 00002B21 665B                <1> 	POP	BX			; RECOVER XOR FLAG
  5075 00002B23 F6C380              <1> 	TEST	BL, 80H			; IS IT ON
  5076 00002B26 750D                <1> 	JNZ	short R2		; YES, XOR THE DOT
  5077 00002B28 F6D4                <1> 	NOT	AH			; SET MASK TO REMOVE THE INDICATED BITS
  5078 00002B2A 20E1                <1> 	AND	CL, AH
  5079 00002B2C 08C8                <1> 	OR	AL, CL			; OR IN THE NEW VALUE OF THOSE BITS
  5080                              <1> R1:					; FINISH_DOT
  5081 00002B2E 8806                <1> 	MOV	[eSI], AL		; RESTORE THE BYTE IN MEMORY
  5082                              <1> 	;POP	AX
  5083 00002B30 E922EFFFFF          <1> 	JMP	VIDEO_RETURN		; RETURN FROM VIDEO I/O
  5084                              <1> R2:					; XOR_DOT
  5085 00002B35 30C8                <1> 	XOR	AL, CL			; EXCLUSIVE OR THE DOTS
  5086 00002B37 EBF5                <1> 	JMP	short R1		; FINISH UP THE WRITING
  5087                              <1> 
  5088                              <1> ; 01/07/2016 - TRDOS 386 (TRDOS v2.0)
  5089                              <1> ; VIDEO1.ASM - 24/03/1985 (IBM PC-AT BIOS source code)
  5090                              <1> 
  5091                              <1> ;----------------------------------------------
  5092                              <1> ; THIS SUBROUTINE DETERMINES THE REGEN BYTE LOCATION OF THE
  5093                              <1> ; INDICATED ROW COLUMN VALUE IN GRAPHICS MODE.
  5094                              <1> ; ENTRY --
  5095                              <1> ;  DX = ROW VALUE (0-199)
  5096                              <1> ;  CX = COLUMN VALUE (0-639)
  5097                              <1> ; EXIT --
  5098                              <1> ;  SI = OFFSET INTO REGEN BUFFER FOR BYTE OF INTEREST
  5099                              <1> ;  AH = MASK TO STRIP OFF THE BITS OF INTEREST
  5100                              <1> ;  CL = BITS TO SHIFT TO RIGHT JUSTIFY THE MASK IN AH
  5101                              <1> ;  DH = # BITS IN RESULT
  5102                              <1> ;  BX = MODIFIED
  5103                              <1> ;-----------------------------------------------
  5104                              <1> R3:
  5105                              <1> 
  5106                              <1> ;-----	DETERMINE 1ST BYTE IN INDICATED ROW BY MULTIPLYING ROW VALUE BY 40
  5107                              <1> ;-----	 ( LOW BIT OF ROW DETERMINES EVEN/ODD, 80 BYTES/ROW )
  5108                              <1> 
  5109 00002B39 0FB7F0              <1> 	movzx	esi, ax			; WILL SAVE AL AND AH DURING OPERATION
  5110 00002B3C B028                <1> 	MOV	AL, 40
  5111 00002B3E F6E2                <1> 	MUL	DL			; AX= ADDRESS OF START OF INDICATED ROW
  5112 00002B40 A808                <1> 	TEST	AL, 08H 		; TEST FOR EVEN/ODD ROW CALCULATED
  5113 00002B42 7404                <1> 	JZ	short R4		; JUMP IF EVEN ROW
  5114 00002B44 6605D81F            <1> 	ADD	AX, 2000H-40		; OFFSET TO LOCATION OF ODD ROWS ADJUST
  5115                              <1> R4:					; EVEN_ROW
  5116 00002B48 6696                <1> 	XCHG	SI, AX			; MOVE POINTER TO (SI) AND RECOVER (AX)
  5117 00002B4A 81C600800B00        <1> 	add	esi, 0B8000h
  5118 00002B50 6689CA              <1> 	MOV	DX, CX			; COLUMN VALUE TO DX
  5119                              <1> 
  5120                              <1> ;-----	DETERMINE GRAPHICS MODE CURRENTLY IN EFFECT
  5121                              <1> 
  5122                              <1> ; SET UP THE REGISTERS ACCORDING TO THE MODE
  5123                              <1> ; CH = MASK FOR LOW OF COLUMN ADDRESS ( 7/3 FOR HIGH/MED RES )
  5124                              <1> ; CL = # OF ADDRESS BITS IN COLUMN VALUE ( 3/2 FOR H/M )
  5125                              <1> ; BL = MASK TO SELECT BITS FROM POINTED BYTE ( 80H/C0H FOR H/M )
  5126                              <1> ; BH = NUMBER OF VALID BITS IN POINTED BYTE ( 1/2 FOR H/M )
  5127                              <1> 
  5128 00002B53 66BBC002            <1> 	MOV	BX, 2C0H
  5129 00002B57 66B90203            <1> 	MOV	CX, 302H 		; SET PARMS FOR MED RES
  5130 00002B5B 803D[9A690000]06    <1> 	CMP	byte [CRT_MODE], 6
  5131 00002B62 7208                <1> 	JC	short R5		; HANDLE IF MED RES
  5132 00002B64 66BB8001            <1> 	MOV	BX, 180H
  5133 00002B68 66B90307            <1> 	MOV	CX, 703H 		; SET PARMS FOR HIGH RES
  5134                              <1> 
  5135                              <1> ;-----	DETERMINE BIT OFFSET IN BYTE FROM COLUMN MASK
  5136                              <1> R5:
  5137 00002B6C 20D5                <1> 	AND	CH, DL			; ADDRESS OF PEL WITHIN BYTE TO CH
  5138                              <1> 
  5139                              <1> ;-----	DETERMINE BYTE OFFSET FOR THIS LOCATION IN COLUMN
  5140                              <1> 
  5141 00002B6E 66D3EA              <1> 	SHR	DX, CL			; SHIFT BY CORRECT AMOUNT
  5142 00002B71 6601D6              <1> 	ADD	SI, DX			; INCREMENT THE POINTER
  5143 00002B74 88FE                <1> 	MOV	DH, BH			; GET THE # OF BITS IN RESULT TO DH
  5144                              <1> 
  5145                              <1> ;-----	MULTIPLY BH (VALID BITS IN BYTE) BY CH (BIT OFFSET)
  5146                              <1> 
  5147 00002B76 28C9                <1> 	SUB	CL, CL			; ZERO INTO STORAGE LOCATION
  5148                              <1> R6:
  5149 00002B78 D0C8                <1> 	ROR	AL, 1			; LEFT JUSTIFY VALUE IN AL (FOR WRITE)
  5150 00002B7A 00E9                <1> 	ADD	CL, CH			; ADD IN THE BIT OFFSET VALUE
  5151 00002B7C FECF                <1> 	DEC	BH			; LOOP CONTROL
  5152 00002B7E 75F8                <1> 	JNZ	short R6		; ON EXIT, CL HAS COUNT TO RESTORE BITS
  5153 00002B80 88DC                <1> 	MOV	AH, BL			;  GET MASK TO AH
  5154 00002B82 D2EC                <1> 	SHR	AH, CL			;  MOVE THE MASK TO CORRECT LOCATION
  5155 00002B84 C3                  <1> 	RETn				;  RETURN WITH EVERYTHING SET UP
  5156                              <1> 
  5157                              <1> load_dac_palette:
  5158                              <1> 	; 29/07/2016
  5159                              <1> 	; 23/07/2016
  5160                              <1> 	; 03/07/2016 (TRDOS 386 = TRDOS v2.0)
  5161                              <1> 	; (set_mode_vga)
  5162                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  5163                              <1> 	; vgabios-0.7a (2011)
  5164                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  5165                              <1> 	; 'vgabios.c', 'load_dac_palette'
  5166                              <1> 	;
  5167                              <1> 	; Oracle VirtualBox 5.0.24 VGABios Source Code
  5168                              <1> 	; ('vgabios.c', 'vgatables.h', 'vgafonts.h', 'vgarom.asm')
  5169                              <1> 	;
  5170                              <1> 	; INPUT -> AH = DAC selection number (3, 2 or 1)
  5171                              <1> 	; OUTPUT -> ECX = 0, AX = 0
  5172                              <1> 	; (Modifed registers: EAX, ECX, EDX, ESI)
  5173                              <1> 	;
  5174 00002B85 66BAC803            <1> 	mov	dx, 3C8h  ; VGAREG_DAC_WRITE_ADDRESS
  5175 00002B89 28C0                <1> 	sub	al, al ; 0
  5176 00002B8B EE                  <1> 	out	dx, al ; 0 ; color index, always 0 at the beginning	
  5177 00002B8C 6642                <1> 	inc	dx   ; 3C9h ; VGAREG_DAC_DATA
  5178 00002B8E B900010000          <1> 	mov	ecx, 256   ; always 256*3 values
  5179                              <1> 	;push	esi
  5180 00002B93 88E0                <1> 	mov	al, ah
  5181 00002B95 B43F                <1> 	mov	ah, 3Fh	; 3Fh except DAC selection number 3
  5182 00002B97 3C02                <1> 	cmp 	al, 2
  5183 00002B99 7414                <1> 	je	short l_dac_p_2
  5184 00002B9B 7719                <1> 	ja	short l_dac_p_3
  5185 00002B9D 20C0                <1> 	and	al, al
  5186 00002B9F 7507                <1> 	jnz	short l_dac_p_1
  5187                              <1> l_dac_p_0:
  5188 00002BA1 BE[B8320100]        <1> 	mov	esi, palette0
  5189 00002BA6 EB15                <1> 	jmp	short l_dac_p_4	
  5190                              <1> l_dac_p_1:
  5191 00002BA8 BE[78330100]        <1> 	mov	esi, palette1
  5192 00002BAD EB0E                <1> 	jmp	short l_dac_p_4
  5193                              <1> l_dac_p_2:
  5194 00002BAF BE[38340100]        <1> 	mov	esi, palette2
  5195 00002BB4 EB07                <1> 	jmp	short l_dac_p_4
  5196                              <1> l_dac_p_3:
  5197 00002BB6 B4FF                <1> 	mov	ah, 0FFh ; dac registers
  5198 00002BB8 BE[F8340100]        <1> 	mov	esi, palette3
  5199                              <1> l_dac_p_4:
  5200 00002BBD AC                  <1> 	lodsb
  5201 00002BBE EE                  <1> 	out	dx, al  ; Red
  5202 00002BBF AC                  <1> 	lodsb
  5203 00002BC0 EE                  <1> 	out	dx, al	; Green
  5204 00002BC1 AC                  <1> 	lodsb
  5205 00002BC2 EE                  <1> 	out	dx, al	; Blue
  5206 00002BC3 20E4                <1> 	and	ah, ah
  5207 00002BC5 7405                <1> 	jz	short l_dac_p_5	
  5208 00002BC7 FECC                <1> 	dec	ah
  5209 00002BC9 E2F2                <1> 	loop	l_dac_p_4
  5210                              <1> 	;pop	esi
  5211 00002BCB C3                  <1> 	retn
  5212                              <1> l_dac_p_5:
  5213                              <1> 	; 29/07/2016
  5214 00002BCC FEC9                <1> 	dec	cl
  5215 00002BCE 7407                <1> 	jz	short l_dac_p_7
  5216                              <1> 	;
  5217 00002BD0 28C0                <1> 	sub	al, al ; 0
  5218                              <1> l_dac_p_6:
  5219 00002BD2 EE                  <1> 	out	dx, al ; outb(VGAREG_DAC_DATA,0);
  5220 00002BD3 EE                  <1> 	out	dx, al
  5221 00002BD4 EE                  <1> 	out	dx, al
  5222 00002BD5 E2FB                <1> 	loop	l_dac_p_6
  5223                              <1> l_dac_p_7:
  5224                              <1> 	;pop	esi
  5225 00002BD7 C3                  <1> 	retn
  5226                              <1> 
  5227                              <1> gray_scale_summing:
  5228                              <1> 	; 03/07/2016 (TRDOS 386 = TRDOS v2.0)
  5229                              <1> 	; (set_mode_vga)
  5230                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  5231                              <1> 	; vgabios-0.7a (2011)
  5232                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  5233                              <1> 	; 'vgabios.c', 'biosfn_perform_gray_scale_summing'
  5234                              <1> 	;
  5235                              <1> 	; Oracle VirtualBox 5.0.24 VGABios Source Code
  5236                              <1> 	; ('vgabios.c', 'vgatables.h', 'vgafonts.h', 'vgarom.asm')
  5237                              <1> 	;
  5238                              <1> 
  5239                              <1> 	; INPUT -> EBX = Start address (color index <= 255)
  5240                              <1> 	;	   ECX = Count (<= 256)
  5241                              <1> 	; OUTPUT -> (E)CX = 0
  5242                              <1> 	; (Modifed registers: EAX, ECX, EDX, EBX)
  5243                              <1> 
  5244 00002BD8 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  5245 00002BDC EC                  <1> 	in	al, dx
  5246 00002BDD 30C0                <1> 	xor	al, al ; 0
  5247 00002BDF 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  5248 00002BE3 EE                  <1> 	out	dx, al	; clear bit 5
  5249                              <1> 			; (while loading palette registers)
  5250                              <1> 	; set read address and switch to read mode
  5251                              <1> g_s_s_1:
  5252 00002BE4 66BAC703            <1> 	mov	dx, 3C7h ; VGAREG_DAC_READ_ADDRESS
  5253 00002BE8 88D8                <1> 	mov	al, bl
  5254 00002BEA EE                  <1> 	out	dx, al
  5255                              <1> 	; get 6-bit wide RGB data values
  5256                              <1>  	; intensity = (0.3*Red)+(0.59*Green)+(0.11*Blue)
  5257                              <1> 	; i = ( ( 77*r + 151*g + 28*b ) + 0x80 ) >> 8;
  5258 00002BEB 66BAC903            <1> 	mov	dx, 3C9h ; VGAREG_DAC_DATA
  5259 00002BEF EC                  <1> 	in	al, dx ; red
  5260 00002BF0 B44D                <1> 	mov	ah, 77 ; 0.3* Red
  5261 00002BF2 F6E4                <1> 	mul	ah
  5262 00002BF4 6650                <1> 	push	ax
  5263 00002BF6 EC                  <1> 	in	al, dx ; green
  5264 00002BF7 B497                <1> 	mov	ah, 151  ; 0.59 * Green
  5265 00002BF9 F6E4                <1> 	mul	ah
  5266 00002BFB 6650                <1> 	push	ax
  5267 00002BFD EC                  <1> 	in	al, dx ; blue
  5268 00002BFE B41C                <1> 	mov	ah, 28 ; 0.11 * Blue
  5269 00002C00 F6E4                <1> 	mul	ah
  5270 00002C02 665A                <1> 	pop	dx
  5271 00002C04 6601D0              <1> 	add	ax, dx
  5272 00002C07 665A                <1> 	pop	dx
  5273 00002C09 6601D0              <1> 	add	ax, dx
  5274 00002C0C 66058000            <1> 	add	ax, 80h  
  5275 00002C10 B03F                <1> 	mov	al, 3Fh
  5276 00002C12 38C4                <1> 	cmp	ah, al	; if(i>0x3f)i=0x3f
  5277 00002C14 7602                <1> 	jna	short g_s_s_2
  5278 00002C16 88C4                <1> 	mov	ah, al
  5279                              <1> g_s_s_2:
  5280 00002C18 66BAC803            <1> 	mov	dx, 3C8h  ; VGAREG_DAC_WRITE_ADDRESS
  5281 00002C1C 88D8                <1> 	mov	al, bl ; color index
  5282 00002C1E EE                  <1> 	out	dx, al
  5283 00002C1F 88E0                <1> 	mov	al, ah ; intensity
  5284 00002C21 6642                <1> 	inc	dx ; 3C9h ; VGAREG_DAC_DATA
  5285 00002C23 EE                  <1> 	out	dx, al ; R (R=G=B)
  5286 00002C24 88E0                <1> 	mov	al, ah ; intensity
  5287 00002C26 EE                  <1> 	out	dx, al ; G (R=G=B)
  5288 00002C27 88E0                <1>  	mov	al, ah ; intensity
  5289 00002C29 EE                  <1> 	out	dx, al ; B (R=G=B)
  5290 00002C2A 6649                <1> 	dec	cx
  5291 00002C2C 7404                <1> 	jz	short g_s_s_3
  5292 00002C2E FEC3                <1> 	inc	bl    ; next color index value
  5293 00002C30 EBB2                <1> 	jmp	short g_s_s_1
  5294                              <1> g_s_s_3:
  5295 00002C32 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  5296 00002C36 EC                  <1> 	in	al, dx
  5297 00002C37 B020                <1> 	mov	al, 20h
  5298 00002C39 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  5299 00002C3D EE                  <1> 	out	dx, al ; 20h -> set bit 5
  5300                              <1> 		        ; (after loading palette regs)	
  5301 00002C3E C3                  <1> 	retn
  5302                              <1> 
  5303                              <1> vga_write_char_attr:
  5304                              <1> vga_write_char_only: 
  5305                              <1> 	; 08/07/2016 (TRDOS 386 = TRDOS v2.0)
  5306                              <1> 	;
  5307                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  5308                              <1> 	; vgabios-0.7a (2011)
  5309                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  5310                              <1> 	; 'vgabios.c', 'biosfn_write_char_attr'
  5311                              <1> 	; 'biosfn_write_char_only'
  5312                              <1> 
  5313                              <1> 	; INPUT ->
  5314                              <1> 	; [CRT_MODE] = current video mode (>7)
  5315                              <1> 	; CX = Count of characters to write
  5316                              <1> 	; AL = Character to write
  5317                              <1> 	; BL = Color of character
  5318                              <1> 	; OUTPUT ->
  5319                              <1> 	; Regen buffer updated
  5320                              <1>  
  5321 00002C3F 8A25[9A690000]      <1> 	mov 	ah, [CRT_MODE]
  5322 00002C45 668B15[F6630100]    <1> 	mov	dx, [CURSOR_POSN] ; cursor pos for page 0
  5323                              <1> 
  5324 00002C4C BE[B6690000]        <1> 	mov	esi, vga_modes
  5325 00002C51 89F7                <1> 	mov	edi, esi
  5326 00002C53 83C710              <1> 	add	edi, vga_mode_count
  5327                              <1> vga_wca_0:
  5328 00002C56 AC                  <1> 	lodsb
  5329 00002C57 38E0                <1> 	cmp	al, ah ; [CRT_MODE]
  5330 00002C59 7405                <1> 	je	short vga_wca_2
  5331 00002C5B 39FE                <1> 	cmp	esi, edi
  5332 00002C5D 72F7                <1> 	jb	short vga_wca_0
  5333                              <1> vga_wca_1:
  5334 00002C5F C3                  <1> 	retn	; nothing to do
  5335                              <1> vga_wca_2:
  5336 00002C60 83C64F              <1> 	add	esi, vga_memmodel - (vga_modes + 1)  
  5337                              <1> 	; [ESI] = VGA memory model number (LINEAR8, PLANAR4, PLANAR1)
  5338                              <1> 
  5339                              <1> 	; biosfn_write_char_attr (car,page,attr,count) 
  5340                              <1> 	; AL = car, page = 0, BL = attr, CX = count
  5341 00002C63 803E04              <1> 	cmp	byte [esi], PLANAR4
  5342 00002C66 741D                <1> 	je	short vga_wca_planar
  5343 00002C68 803E03              <1> 	cmp	byte [esi], PLANAR1
  5344 00002C6B 7418                <1> 	je	short vga_wca_planar
  5345                              <1> vga_wca_linear8:
  5346                              <1> 	; while((count-->0) && (xcurs<nbcols))
  5347                              <1> 	; CX = count
  5348 00002C6D 6621C9              <1> 	and	cx, cx
  5349 00002C70 74ED                <1> 	jz	short vga_wca_1
  5350 00002C72 3A15[9C690000]      <1> 	cmp	dl, [CRT_COLS]
  5351 00002C78 73E5                <1> 	jnb	short vga_wca_1
  5352                              <1> 	; write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols);
  5353                              <1> 	; AL = car, BL = attr, DL = xcurs, DH = ycurs, 
  5354                              <1> 	; [CRT_COLS] = nbcols
  5355 00002C7A E81E000000          <1> 	call	write_gfx_char_lin	 
  5356 00002C7F 6649                <1> 	dec	cx ; count
  5357 00002C81 FEC2                <1> 	inc	dl ; xcurs
  5358 00002C83 EBE8                <1> 	jmp	short vga_wca_linear8
  5359                              <1> vga_wca_planar:
  5360                              <1> 	; while((count-->0) && (xcurs<nbcols))
  5361                              <1> 	; CX = count
  5362 00002C85 6621C9              <1> 	and	cx, cx
  5363 00002C88 74D5                <1> 	jz	short vga_wca_1
  5364 00002C8A 3A15[9C690000]      <1> 	cmp	dl, [CRT_COLS]
  5365 00002C90 73CD                <1> 	jnb	short vga_wca_1
  5366                              <1> 	; write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight);
  5367                              <1> 	; AL = car, BL = attr, DL = xcurs, DH = ycurs, 
  5368                              <1> 	; [CRT_COLS] = nbcols, [CHAR_HEIGHT] = cheight
  5369 00002C92 E89D000000          <1> 	call	write_gfx_char_pl4
  5370 00002C97 6649                <1> 	dec	cx ; count
  5371 00002C99 FEC2                <1> 	inc	dl ; xcurs
  5372 00002C9B EBE8                <1> 	jmp	short vga_wca_planar
  5373                              <1> 
  5374                              <1> write_gfx_char_lin:
  5375                              <1> 	; 08/08/2016
  5376                              <1> 	; 31/07/2016
  5377                              <1> 	; 08/07/2016 (TRDOS 386 = TRDOS v2.0)
  5378                              <1> 	;
  5379                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  5380                              <1> 	; vgabios-0.7a (2011)
  5381                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  5382                              <1> 	; 'vgabios.c', 'write_gfx_char_lin'
  5383                              <1> 
  5384                              <1> 	; write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols)
  5385                              <1> 	; INPUT ->
  5386                              <1> 	; AL = car, BL = attr, DL = xcurs, DH = ycurs, 
  5387                              <1> 	; [CRT_COLS] = nbcols
  5388                              <1> 	; OUTPUT ->
  5389                              <1> 	; Regen buffer updated
  5390                              <1> 
  5391 00002C9D 51                  <1> 	push	ecx
  5392 00002C9E 53                  <1> 	push	ebx
  5393 00002C9F 52                  <1> 	push	edx
  5394 00002CA0 50                  <1> 	push	eax
  5395                              <1> 	; addr=xcurs*8+ycurs*nbcols*64;
  5396                              <1> 	; 08/08/2016
  5397 00002CA1 0FB6F0              <1> 	movzx	esi, al ; car
  5398 00002CA4 0FB6C6              <1> 	movzx	eax, dh ; ycurs
  5399 00002CA7 8A25[9C690000]      <1> 	mov	ah, [CRT_COLS] ; nbcols
  5400 00002CAD F6E4                <1> 	mul	ah
  5401                              <1> 	;shl	ax, 6 ; * 64
  5402 00002CAF 66C1E003            <1>  	shl	ax, 3 ; * 8
  5403                              <1> 	;sub	dh, dh
  5404                              <1> 	;shl	dx, 3 ; xcurs * 8
  5405                              <1> 	;movzx	edi, dx
  5406 00002CB3 0FB6FA              <1> 	movzx	edi, dl
  5407 00002CB6 66C1E703            <1> 	shl	di, 3 ; xcurs * 8
  5408 00002CBA 30F6                <1> 	xor	dh, dh
  5409 00002CBC 8A15[9E690000]      <1> 	mov	dl, [CHAR_HEIGHT]
  5410 00002CC2 66F7E2              <1> 	mul	dx
  5411                              <1> 	; eax = ycurs*nbcols*8*[CHAR_HEIGHT]
  5412 00002CC5 01C7                <1> 	add	edi, eax ; addr
  5413 00002CC7 81C700000A00        <1> 	add	edi, 0A0000h
  5414                              <1> 	;shl	si, 3 ; car * 8
  5415 00002CCD 30E4                <1> 	xor	ah, ah
  5416 00002CCF A0[9E690000]        <1> 	mov	al, [CHAR_HEIGHT]
  5417 00002CD4 66F7E6              <1> 	mul	si
  5418 00002CD7 6689C6              <1> 	mov	si, ax
  5419                              <1> 	;; esi = src = car * 8
  5420                              <1> 	; esi = src = car * [CHAR_HEIGHT]
  5421                              <1> 	; i = 0
  5422                              <1> 	;add	esi, vgafont8 ; fdata [src+i]
  5423                              <1> 	; 08/08/2016
  5424 00002CDA A1[82700100]        <1> 	mov	eax, [VGA_INT43H]
  5425 00002CDF 3D[F84D0100]        <1> 	cmp	eax, vgafont16
  5426 00002CE4 740F                <1>         je      short wgfxl_0
  5427 00002CE6 3D[F83F0100]        <1> 	cmp	eax, vgafont14
  5428 00002CEB 7408                <1> 	je	short wgfxl_0
  5429 00002CED 81C6[F8370100]      <1> 	add	esi, vgafont8
  5430 00002CF3 EB02                <1> 	jmp	short wgfxl_1
  5431                              <1> wgfxl_0:
  5432 00002CF5 01C6                <1> 	add	esi, eax
  5433                              <1> wgfxl_1:
  5434 00002CF7 28FF                <1> 	sub	bh, bh ; i = 0
  5435                              <1> wgfxl_2:
  5436                              <1> 	; for(i=0;i<8;i++)
  5437 00002CF9 57                  <1> 	push	edi ; addr
  5438 00002CFA 0FB605[9C690000]    <1> 	movzx	eax, byte [CRT_COLS] ; nbcols
  5439 00002D01 F6E7                <1> 	mul	bh ; nbcols*i
  5440 00002D03 66C1E003            <1> 	shl	ax, 3 ; i*nbcols*8
  5441                              <1>  	; dest=addr+i*nbcols*8;
  5442 00002D07 01C7                <1> 	add	edi, eax ; dest + j ; j = 0
  5443 00002D09 B180                <1> 	mov	cl, 80h ; mask = 0x80;
  5444                              <1> 	; esi = fdata + src + i
  5445                              <1> 	; for(j=0;j<8;j++)
  5446 00002D0B 29D2                <1> 	sub	edx, edx ; j = 0
  5447                              <1> wgfxl_3:
  5448 00002D0D 8A06                <1> 	mov	al, [esi] ; al = fdata[src+i]
  5449 00002D0F 20C8                <1> 	and	al, cl ; if (fdata[src+i] & mask)
  5450 00002D11 7402                <1> 	jz	short wgfxl_4  ; data = 0, zf = 1
  5451 00002D13 88D8                <1> 	mov	al, bl ; data = attr;
  5452                              <1> wgfxl_4:
  5453                              <1> 	; write_byte(0xa000,dest+j,data);		
  5454 00002D15 AA                  <1> 	stosb  ; dest + j (+ 0A0000h)
  5455                              <1> 	;inc	dl ; j++
  5456                              <1> 	;cmp	dl, 8
  5457 00002D16 80FA07              <1> 	cmp	dl, 7
  5458 00002D19 720E                <1> 	jb	short wgfxl_5
  5459 00002D1B 5F                  <1> 	pop	edi
  5460                              <1> 	; 08/08/2016
  5461                              <1> 	;cmp	bh, 7
  5462                              <1> 	;jnb	short wgfxl_6
  5463 00002D1C FEC7                <1> 	inc	bh ; i++
  5464 00002D1E 3A3D[9E690000]      <1> 	cmp	bh, [CHAR_HEIGHT]
  5465 00002D24 7309                <1> 	jnb	short wgfxl_6
  5466 00002D26 46                  <1> 	inc	esi
  5467 00002D27 EBD0                <1> 	jmp	short wgfxl_2
  5468                              <1> wgfxl_5:
  5469 00002D29 D0E9                <1> 	shr	cl, 1 ; mask >>= 1;
  5470 00002D2B FEC2                <1> 	inc	dl ; j++
  5471 00002D2D EBDE                <1>         jmp     short wgfxl_3
  5472                              <1> wgfxl_6:
  5473 00002D2F 58                  <1> 	pop	eax
  5474 00002D30 5A                  <1> 	pop	edx
  5475 00002D31 5B                  <1> 	pop	ebx
  5476 00002D32 59                  <1> 	pop	ecx
  5477 00002D33 C3                  <1> 	retn
  5478                              <1> 
  5479                              <1> write_gfx_char_pl4:
  5480                              <1> 	; 08/08/2016
  5481                              <1> 	; 08/07/2016 (TRDOS 386 = TRDOS v2.0)
  5482                              <1> 	;
  5483                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  5484                              <1> 	; vgabios-0.7a (2011)
  5485                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  5486                              <1> 	; 'vgabios.c', 'write_gfx_char_pl4'
  5487                              <1> 
  5488                              <1> 	; write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight)
  5489                              <1> 	; INPUT ->
  5490                              <1> 	; AL = car, BL = attr, DL = xcurs, DH = ycurs, 
  5491                              <1> 	; [CRT_COLS] = nbcols, [CHAR_HEIGHT] = cheight
  5492                              <1> 	; OUTPUT ->
  5493                              <1> 	; Regen buffer updated
  5494                              <1> 
  5495 00002D34 51                  <1> 	push	ecx
  5496 00002D35 53                  <1> 	push	ebx
  5497 00002D36 52                  <1> 	push	edx
  5498 00002D37 50                  <1> 	push	eax
  5499                              <1> wgfxpl_f0:
  5500                              <1> 	; switch(cheight)
  5501 00002D38 8A25[9E690000]      <1> 	mov	ah, [CHAR_HEIGHT]
  5502 00002D3E 80FC10              <1> 	cmp	ah, 16 ; case 16:
  5503 00002D41 7507                <1> 	jne	short wgfxpl_f1
  5504                              <1> 	; fdata = &vgafont16;
  5505 00002D43 BE[F84D0100]        <1> 	mov	esi, vgafont16
  5506 00002D48 EB13                <1> 	jmp	short wgfxpl_f3
  5507                              <1> wgfxpl_f1:
  5508 00002D4A 80FC0E              <1> 	cmp	ah, 14 ; case 14:
  5509 00002D4D 7507                <1> 	jne	short wgfxpl_f2
  5510 00002D4F BE[F83F0100]        <1> 	mov	esi, vgafont14
  5511 00002D54 EB07                <1> 	jmp	short wgfxpl_f3
  5512                              <1> wgfxpl_f2:
  5513                              <1> 	; default:
  5514                              <1> 	;  fdata = &vgafont8;
  5515 00002D56 BE[F8370100]        <1> 	mov	esi, vgafont8
  5516 00002D5B B408                <1> 	mov	ah, 8	
  5517                              <1> wgfxpl_f3:
  5518                              <1> 	; al = car
  5519 00002D5D F6E4                <1> 	mul	ah ; ah = cheight
  5520 00002D5F 25FFFF0000          <1> 	and	eax, 0FFFFh ; car * cheight
  5521                              <1> 	; src = car * cheight;
  5522 00002D64 01C6                <1> 	add	esi, eax ; esi = fdata[src+i]
  5523                              <1> 	; addr=xcurs*8+ycurs*nbcols*64;
  5524 00002D66 88F0                <1> 	mov	al, dh ; ycurs
  5525 00002D68 8A25[9C690000]      <1> 	mov	ah, [CRT_COLS] ; nbcols
  5526 00002D6E F6E4                <1> 	mul	ah
  5527                              <1> 	; 08/08/2016
  5528                              <1> 	;shl	ax, 6 ; * 64
  5529 00002D70 66C1E003            <1> 	shl	ax, 3 ; * 8
  5530                              <1> 	;sub	dh, dh ; 0
  5531                              <1> 	;shl	dx, 3 ; xcurs * 8
  5532                              <1> 	;movzx	edi, dx
  5533 00002D74 0FB6FA              <1> 	movzx	edi, dl
  5534 00002D77 66C1E703            <1> 	shl	di, 3 ; xcurs * 8
  5535 00002D7B 30F6                <1> 	xor	dh, dh
  5536 00002D7D 8A15[9E690000]      <1> 	mov	dl, [CHAR_HEIGHT]
  5537 00002D83 66F7E2              <1> 	mul	dx
  5538                              <1> 	; eax = ycurs*nbcols*8*[CHAR_HEIGHT]
  5539 00002D86 01C7                <1> 	add	edi, eax ; addr
  5540 00002D88 81C700000A00        <1> 	add	edi, 0A0000h
  5541                              <1> 	;
  5542                              <1> 	; outw(VGAREG_SEQU_ADDRESS, 0x0f02);
  5543                              <1> 	; outw(VGAREG_GRDC_ADDRESS, 0x0205);
  5544 00002D8E 66BAC403            <1> 	mov	dx, 3C4h ; VGAREG_SEQU_ADDRESS
  5545 00002D92 66B8020F            <1> 	mov	ax, 0F02h
  5546 00002D96 66EF                <1> 	out	dx, ax
  5547 00002D98 66BACE03            <1> 	mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  5548 00002D9C 66B80502            <1> 	mov	ax, 0205h
  5549 00002DA0 66EF                <1> 	out	dx, ax
  5550                              <1> 	;
  5551 00002DA2 66BACE03            <1> 	mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  5552 00002DA6 F6C380              <1> 	test	bl, 80h ; if(attr&0x80)
  5553 00002DA9 7406                <1> 	jz	short wgfxpl_f4 ; else
  5554                              <1> 	; outw(VGAREG_GRDC_ADDRESS, 0x1803);
  5555 00002DAB 66B80318            <1> 	mov	ax, 1803h
  5556 00002DAF EB04                <1> 	jmp	short wgfxpl_f5
  5557                              <1> wgfxpl_f4:
  5558                              <1> 	; outw(VGAREG_GRDC_ADDRESS, 0x0003);
  5559 00002DB1 66B80300            <1> 	mov	ax, 0003h	
  5560                              <1> wgfxpl_f5:
  5561 00002DB5 66EF                <1> 	out	dx, ax
  5562                              <1> 	;	
  5563 00002DB7 28FF                <1> 	sub	bh, bh ; i = 0
  5564                              <1> wgfxpl_0:
  5565                              <1> 	; for(i=0;i<cheight;i++)
  5566 00002DB9 57                  <1> 	push	edi ; addr
  5567 00002DBA 0FB605[9C690000]    <1> 	movzx	eax, byte [CRT_COLS] ; nbcols
  5568 00002DC1 F6E7                <1> 	mul	bh ; nbcols*i
  5569                              <1> 	; dest=addr+i*nbcols
  5570 00002DC3 01C7                <1> 	add	edi, eax ; dest
  5571 00002DC5 B580                <1> 	mov	ch, 80h ; mask = 0x80;
  5572                              <1> 	; for(j=0;j<8;j++)
  5573 00002DC7 28C9                <1> 	sub	cl, cl ; j = 0
  5574                              <1> wgfxpl_1:
  5575 00002DC9 D2ED                <1> 	shr	ch, cl ; mask=0x80>>j;
  5576                              <1> 	;
  5577                              <1> 	; outw(VGAREG_GRDC_ADDRESS, (mask << 8) | 0x08);
  5578                              <1>      	; read_byte(0xa000,dest);
  5579                              <1> 	;mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  5580 00002DCB 88EC                <1> 	mov	ah, ch
  5581 00002DCD B008                <1> 	mov	al, 8
  5582 00002DCF 66EF                <1> 	out	dx, ax
  5583 00002DD1 8A07                <1> 	mov	al, [edi] ; ? (io delay?)
  5584                              <1> 	;
  5585 00002DD3 28C0                <1> 	sub	al, al ; attr = 0
  5586                              <1> 	; if (fdata[src+i] & mask)
  5587 00002DD5 842E                <1> 	test	byte [esi], ch
  5588 00002DD7 7404                <1> 	jz	short wgfxpl_2  ; zf = 1
  5589                              <1> 	; write_byte(0xa000,dest,attr&0x0f);
  5590 00002DD9 88D8                <1> 	mov	al, bl ; attr;
  5591 00002DDB 240F                <1> 	and	al, 0Fh	; attr&0x0f
  5592                              <1> wgfxpl_2:
  5593                              <1> 	; write_byte(0xa000,dest,0x00);		
  5594 00002DDD 8807                <1> 	mov	[edi], al ; dest (+ 0A0000h)
  5595 00002DDF FEC1                <1> 	inc	cl ; j++
  5596 00002DE1 80F908              <1> 	cmp	cl, 8
  5597 00002DE4 72E3                <1> 	jb	short wgfxpl_1
  5598 00002DE6 5F                  <1> 	pop	edi
  5599                              <1> 	; 08/08/2016
  5600                              <1> 	;cmp	bh, 7
  5601                              <1> 	;jnb	short wgfxpl_3
  5602 00002DE7 FEC7                <1> 	inc	bh ; i++
  5603 00002DE9 3A3D[9E690000]      <1> 	cmp	bh, [CHAR_HEIGHT]
  5604 00002DEF 7303                <1> 	jnb	short wgfxpl_3
  5605 00002DF1 46                  <1> 	inc	esi
  5606 00002DF2 EBC5                <1> 	jmp	short wgfxpl_0
  5607                              <1> wgfxpl_3:
  5608                              <1> 	;mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  5609 00002DF4 66B808FF            <1>   	mov	ax, 0FF08h
  5610 00002DF8 66EF                <1> 	out	dx, ax
  5611 00002DFA 66B80500            <1> 	mov	ax, 0005h
  5612 00002DFE 66EF                <1> 	out	dx, ax
  5613 00002E00 66B80300            <1> 	mov	ax, 0003h
  5614 00002E04 66EF                <1> 	out	dx, ax
  5615                              <1> 	;
  5616 00002E06 58                  <1> 	pop	eax
  5617 00002E07 5A                  <1> 	pop	edx
  5618 00002E08 5B                  <1> 	pop	ebx
  5619 00002E09 59                  <1> 	pop	ecx
  5620 00002E0A C3                  <1> 	retn
  5621                              <1> 
  5622                              <1> vga_write_pixel: 
  5623                              <1> 	; 09/07/2016 (TRDOS 386 = TRDOS v2.0)
  5624                              <1> 	;
  5625                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  5626                              <1> 	; vgabios-0.7a (2011)
  5627                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  5628                              <1> 	; 'vgabios.c', 'biosfn_write_pixel'
  5629                              <1> 
  5630                              <1> 	; INPUT ->
  5631                              <1> 	; 	DX = row (0-239)
  5632                              <1> 	; 	CX = column (0-799)
  5633                              <1> 	; 	AL = pixel value
  5634                              <1> 	;	(AH = [CRT_MODE])
  5635                              <1> 	; OUTPUT ->
  5636                              <1> 	; 	none
  5637                              <1>  
  5638 00002E0B 88C3                <1> 	mov	bl, al ; pixel value
  5639                              <1> 	;mov 	ah, [CRT_MODE]
  5640 00002E0D BE[B6690000]        <1> 	mov	esi, vga_modes
  5641 00002E12 89F7                <1> 	mov	edi, esi
  5642 00002E14 83C710              <1> 	add	edi, vga_mode_count
  5643                              <1> vga_wp_0:
  5644 00002E17 AC                  <1> 	lodsb
  5645 00002E18 38E0                <1> 	cmp	al, ah ; [CRT_MODE]
  5646 00002E1A 7405                <1> 	je	short vga_wp_1
  5647 00002E1C 39FE                <1> 	cmp	esi, edi
  5648 00002E1E 72F7                <1> 	jb	short vga_wp_0
  5649 00002E20 C3                  <1> 	retn	; nothing to do
  5650                              <1> vga_wp_1:
  5651 00002E21 83C64F              <1> 	add	esi, vga_memmodel - (vga_modes + 1)  
  5652                              <1> 	; [ESI] = VGA memory model number (LINEAR8, PLANAR4, PLANAR1)
  5653 00002E24 BF00000A00          <1> 	mov	edi, 0A0000h
  5654                              <1> 	;
  5655 00002E29 803E04              <1> 	cmp	byte [esi], PLANAR4
  5656 00002E2C 741D                <1> 	je	short vga_wp_planar
  5657 00002E2E 803E03              <1> 	cmp	byte [esi], PLANAR1
  5658 00002E31 7418                <1> 	je	short vga_wp_planar
  5659                              <1> vga_wp_linear8:
  5660                              <1> 	; addr=CX+DX*(read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8);
  5661 00002E33 0FB605[9C690000]    <1> 	movzx	eax, byte [CRT_COLS] ; = [VGA_COLS] ; nbcols
  5662 00002E3A 66C1E003            <1>      	shl	ax, 3 ; * 8
  5663 00002E3E 66F7E2              <1> 	mul	dx
  5664 00002E41 50                  <1> 	push	eax
  5665                              <1> 	;mov	edi, 0A0000h
  5666 00002E42 6601CF              <1> 	add	di, cx
  5667 00002E45 58                  <1> 	pop	eax
  5668 00002E46 01C7                <1> 	add	edi, eax ; addr
  5669                              <1> 	; write_byte(0xa000,addr,AL);
  5670 00002E48 881F                <1> 	mov	[edi], bl
  5671 00002E4A C3                  <1> 	retn    
  5672                              <1> vga_wp_planar:
  5673                              <1> 	; addr = CX/8+DX*read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
  5674 00002E4B 0FB7C1              <1> 	movzx	eax, cx
  5675 00002E4E 66C1E803            <1> 	shr	ax, 3 ; CX/8
  5676 00002E52 50                  <1> 	push	eax
  5677 00002E53 28E4                <1> 	sub	ah, ah ; 0
  5678 00002E55 A0[9C690000]        <1> 	mov	al, [CRT_COLS] ; = [VGA_COLS] ; nbcols
  5679 00002E5A 66F7E2              <1> 	mul	dx
  5680                              <1> 	;mov	edi, 0A0000h
  5681 00002E5D 6601C7              <1>         add     di, ax
  5682 00002E60 58                  <1> 	pop	eax
  5683 00002E61 01C7                <1> 	add	edi, eax ; addr
  5684 00002E63 80E107              <1> 	and	cl, 7
  5685 00002E66 B580                <1> 	mov	ch, 80h ; mask
  5686 00002E68 D2ED                <1> 	shr	ch, cl 	; mask = 0x80 >> (CX & 0x07);
  5687                              <1> 	
  5688                              <1> 	; outw(VGAREG_GRDC_ADDRESS, (mask << 8) | 0x08);
  5689 00002E6A 66BACE03            <1> 	mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  5690 00002E6E 88EC                <1> 	mov	ah, ch
  5691 00002E70 B008                <1> 	mov	al, 8
  5692 00002E72 66EF                <1> 	out	dx, ax
  5693                              <1> 	; outw(VGAREG_GRDC_ADDRESS, 0x0205);
  5694 00002E74 66B80502            <1> 	mov	ax, 0205h
  5695 00002E78 66EF                <1> 	out	dx, ax
  5696                              <1> 	; data = read_byte(0xa000,addr);
  5697 00002E7A 8A07                <1> 	mov	al, [edi] ; (delay?)	
  5698                              <1> 	; if (AL & 0x80)
  5699                              <1> 	; {
  5700                              <1> 	;  outw(VGAREG_GRDC_ADDRESS, 0x1803);
  5701                              <1> 	; }
  5702 00002E7C F6C380              <1> 	test	bl, 80h
  5703 00002E7F 7406                <1> 	jz	short vga_wp_2
  5704 00002E81 66B80318            <1> 	mov	ax, 1803h
  5705 00002E85 66EF                <1> 	out	dx, ax
  5706                              <1> vga_wp_2:	
  5707                              <1> 	; write_byte(0xa000,addr,AL);
  5708 00002E87 881F                <1> 	mov	[edi], bl
  5709                              <1> 	;
  5710                              <1> 	;mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  5711 00002E89 66B808FF            <1>   	mov	ax, 0FF08h
  5712 00002E8D 66EF                <1> 	out	dx, ax
  5713 00002E8F 66B80500            <1> 	mov	ax, 0005h
  5714 00002E93 66EF                <1> 	out	dx, ax
  5715 00002E95 66B80300            <1> 	mov	ax, 0003h
  5716 00002E99 66EF                <1> 	out	dx, ax
  5717                              <1> 	;
  5718 00002E9B C3                  <1> 	retn
  5719                              <1> 
  5720                              <1> vga_read_pixel: 
  5721                              <1> 	; 09/07/2016 (TRDOS 386 = TRDOS v2.0)
  5722                              <1> 	;
  5723                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  5724                              <1> 	; vgabios-0.7a (2011)
  5725                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  5726                              <1> 	; 'vgabios.c', 'biosfn_read_pixel'
  5727                              <1> 
  5728                              <1> 	; INPUT ->
  5729                              <1> 	; 	DX = row (0-239)
  5730                              <1> 	; 	CX = column (0-799)
  5731                              <1> 	;	(AH = [CRT_MODE])
  5732                              <1> 	; OUTPUT ->
  5733                              <1> 	; 	AL = pixel value
  5734                              <1> 	 
  5735                              <1> 	;mov 	ah, [CRT_MODE]
  5736 00002E9C BE[B6690000]        <1> 	mov	esi, vga_modes
  5737 00002EA1 89F7                <1> 	mov	edi, esi
  5738 00002EA3 83C710              <1> 	add	edi, vga_mode_count
  5739                              <1> vga_rp_0:
  5740 00002EA6 AC                  <1> 	lodsb
  5741 00002EA7 38E0                <1> 	cmp	al, ah ; [CRT_MODE]
  5742 00002EA9 7405                <1> 	je	short vga_rp_1
  5743 00002EAB 39FE                <1> 	cmp	esi, edi
  5744 00002EAD 72F7                <1> 	jb	short vga_rp_0
  5745 00002EAF C3                  <1> 	retn	; nothing to do
  5746                              <1> vga_rp_1:
  5747 00002EB0 83C64F              <1> 	add	esi, vga_memmodel - (vga_modes + 1)  
  5748                              <1> 	; [ESI] = VGA memory model number (LINEAR8, PLANAR4, PLANAR1)
  5749 00002EB3 BF00000A00          <1> 	mov	edi, 0A0000h
  5750                              <1> 	;
  5751 00002EB8 803E04              <1> 	cmp	byte [esi], PLANAR4
  5752 00002EBB 741D                <1> 	je	short vga_rp_planar
  5753 00002EBD 803E03              <1> 	cmp	byte [esi], PLANAR1
  5754 00002EC0 7418                <1> 	je	short vga_rp_planar
  5755                              <1> vga_rp_linear8:
  5756                              <1> 	; addr=CX+DX*(read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)*8);
  5757 00002EC2 0FB605[9C690000]    <1> 	movzx	eax, byte [CRT_COLS] ; = [VGA_COLS] ; nbcols
  5758 00002EC9 66C1E003            <1>      	shl	ax, 3 ; * 8
  5759 00002ECD 66F7E2              <1> 	mul	dx
  5760 00002ED0 50                  <1> 	push	eax
  5761                              <1> 	;mov	edi, 0A0000h
  5762 00002ED1 6601CF              <1> 	add	di, cx
  5763 00002ED4 58                  <1> 	pop	eax
  5764 00002ED5 01C7                <1> 	add	edi, eax ; addr
  5765                              <1> 	; attr=read_byte(0xa000,addr);
  5766 00002ED7 8A07                <1> 	mov	al, [edi] ; pixel value
  5767 00002ED9 C3                  <1> 	retn    
  5768                              <1> vga_rp_planar:
  5769                              <1> 	; addr = CX/8+DX*read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS);
  5770 00002EDA 0FB7C1              <1> 	movzx	eax, cx
  5771 00002EDD 66C1E803            <1> 	shr	ax, 3 ; CX/8
  5772 00002EE1 50                  <1> 	push	eax
  5773 00002EE2 28E4                <1> 	sub	ah, ah ; 0
  5774 00002EE4 A0[9C690000]        <1> 	mov	al, [CRT_COLS] ; = [VGA_COLS] ; nbcols
  5775 00002EE9 66F7E2              <1> 	mul	dx
  5776                              <1> 	;mov	edi, 0A0000h
  5777 00002EEC 6601C7              <1>         add     di, ax
  5778 00002EEF 58                  <1> 	pop	eax
  5779 00002EF0 01C7                <1> 	add	edi, eax ; addr
  5780 00002EF2 80E107              <1> 	and	cl, 7
  5781 00002EF5 B580                <1> 	mov	ch, 80h ; mask
  5782 00002EF7 D2ED                <1> 	shr	ch, cl 	; mask = 0x80 >> (CX & 0x07);
  5783                              <1> 	; attr = 0x00;
  5784 00002EF9 30DB                <1> 	xor	bl, bl ; attr = bl = 0, 
  5785 00002EFB 30C9                <1> 	xor	cl, cl ; i = cl = 0
  5786                              <1> 	; for(i=0;i<4;i++)
  5787                              <1>       	; {
  5788                              <1>        	;  outw(VGAREG_GRDC_ADDRESS, (i << 8) | 0x04);
  5789                              <1>        	;  data = read_byte(0xa000,addr) & mask;
  5790                              <1>        	;  if (data > 0) attr |= (0x01 << i);
  5791                              <1>       	; }
  5792                              <1> vga_rp_2:
  5793 00002EFD 88CC                <1> 	mov	ah, cl ; i << 8
  5794 00002EFF B004                <1> 	mov	al, 4  ; | 0x04
  5795 00002F01 66BACE03            <1> 	mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  5796 00002F05 66EF                <1> 	out	dx, ax
  5797                              <1> 	; data = read_byte(0xa000,addr) & mask;
  5798 00002F07 8A07                <1> 	mov	al, [edi]
  5799 00002F09 20E8                <1> 	and	al, ch ; & mask
  5800                              <1> 	; if (data > 0) attr |= (0x01 << i);
  5801 00002F0B 08C0                <1> 	or	al, al
  5802 00002F0D 7408                <1> 	jz	short vga_rp_3 ; al = 0 
  5803 00002F0F B701                <1> 	mov	bh, 1
  5804 00002F11 D2E7                <1> 	shl	bh, cl ; (0x01 << i)
  5805 00002F13 08FB                <1> 	or	bl, bh ; attr |= (0x01 << i)
  5806 00002F15 88D8                <1> 	mov	al, bl ; pixel value	
  5807                              <1> vga_rp_3:	
  5808 00002F17 C3                  <1> 	retn
  5809                              <1> 
  5810                              <1> vga_beeper:
  5811                              <1> 	; 04/08/2016  (TRDOS 386 = TRDOS v2.0)
  5812 00002F18 FB                  <1> 	sti
  5813                              <1> 	;mov	bh, [ACTIVE_PAGE]
  5814 00002F19 E9CCF3FFFF          <1>         jmp     beeper_gfx
  5815                              <1> 
  5816                              <1> vga_write_teletype:
  5817                              <1> 	; 09/12/2017
  5818                              <1> 	; 06/08/2016
  5819                              <1> 	; 04/08/2016
  5820                              <1> 	; 01/08/2016
  5821                              <1> 	; 31/07/2016
  5822                              <1> 	; 09/07/2016 (TRDOS 386 = TRDOS v2.0)
  5823                              <1> 	;
  5824                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  5825                              <1> 	; vgabios-0.7a (2011)
  5826                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  5827                              <1> 	; 'vgabios.c', 'biosfn_write_teletype'
  5828                              <1> 	; 'biosfn_write_char_only'
  5829                              <1> 
  5830                              <1> 	; INPUT ->
  5831                              <1> 	; [CRT_MODE] = current video mode (>7)
  5832                              <1> 	; AL = Character to write
  5833                              <1> 	; BL = Color of character
  5834                              <1> 	; OUTPUT ->
  5835                              <1> 	; Regen buffer updated
  5836                              <1> 
  5837                              <1> 	; biosfn_write_teletype (car, page, attr, flag) 
  5838                              <1> 	; car = character (AL)
  5839                              <1> 	; page = 0
  5840                              <1> 	; attr = color (BL)
  5841                              <1> 	; 'flag' not used
  5842                              <1> 
  5843 00002F1E 8A25[9A690000]      <1> 	mov 	ah, [CRT_MODE]
  5844 00002F24 88C7                <1> 	mov	bh, al ; character
  5845 00002F26 668B15[F6630100]    <1> 	mov	dx, [CURSOR_POSN] ; cursor pos for page 0
  5846                              <1> 
  5847 00002F2D BE[BE690000]        <1> 	mov	esi, vga_g_modes
  5848 00002F32 89F7                <1> 	mov	edi, esi
  5849 00002F34 83C708              <1> 	add	edi, vga_g_mode_count
  5850                              <1> vga_wtty_0:
  5851 00002F37 AC                  <1> 	lodsb
  5852 00002F38 38E0                <1> 	cmp	al, ah ; [CRT_MODE]
  5853 00002F3A 7405                <1> 	je	short vga_wtty_2
  5854 00002F3C 39FE                <1> 	cmp	esi, edi
  5855 00002F3E 72F7                <1> 	jb	short vga_wtty_0
  5856                              <1> vga_wtty_1:
  5857 00002F40 C3                  <1> 	retn	; nothing to do
  5858                              <1> vga_wtty_2:
  5859 00002F41 80FF07              <1> 	cmp	bh, 07h ; bell (beep)
  5860 00002F44 74D2                <1> 	je	short vga_beeper  ; u11
  5861 00002F46 80FF08              <1> 	cmp	bh, 08h ; backspace
  5862 00002F49 7508                <1> 	jne	short vga_wtty_3
  5863                              <1> 	; if(xcurs>0)xcurs--;
  5864 00002F4B 08D2                <1> 	or	dl, dl ; xcurs (column)
  5865 00002F4D 74F1                <1> 	jz	short vga_wtty_1
  5866 00002F4F FECA                <1> 	dec	dl ; xcurs--;
  5867 00002F51 EB59                <1>         jmp     short vga_wtty_12 
  5868                              <1> vga_wtty_3:			
  5869 00002F53 80FF0D              <1> 	cmp	bh, 0Dh ; carriage return (\r)
  5870 00002F56 7504                <1> 	jne	short vga_wtty_4
  5871                              <1> 	; xcurs=0;
  5872 00002F58 28D2                <1> 	sub	dl, dl ; 0
  5873 00002F5A EB50                <1>         jmp     short vga_wtty_12 
  5874                              <1> vga_wtty_4:	
  5875 00002F5C 80FF0A              <1> 	cmp	bh, 0Ah ; new line (\n)
  5876 00002F5F 7504                <1> 	jne	short vga_wtty_5
  5877                              <1> 	; ycurs++;
  5878 00002F61 FEC6                <1> 	inc	dh ; next row
  5879 00002F63 EB62                <1>         jmp     short vga_wtty_11
  5880                              <1> vga_wtty_5:
  5881 00002F65 80FF09              <1> 	cmp 	bh, 09h ; tab stop
  5882 00002F68 7527                <1> 	jne	short vga_wtty_8
  5883 00002F6A 88D0                <1> 	mov	al, dl
  5884                              <1> 	;cbw
  5885 00002F6C 30E4                <1> 	xor	ah, ah ; 09/12/2017
  5886 00002F6E B108                <1> 	mov	cl, 8
  5887 00002F70 F6F1                <1> 	div	cl
  5888 00002F72 28E1                <1> 	sub	cl, ah
  5889                              <1> 	;
  5890 00002F74 B720                <1> 	mov	bh, 20h ; space
  5891                              <1> vga_wtty_6: ; tab stop loop
  5892 00002F76 6651                <1> 	push	cx
  5893 00002F78 6653                <1> 	push	bx
  5894 00002F7A E812000000          <1> 	call	vga_wtty_8
  5895 00002F7F 665B                <1> 	pop	bx  ; bh = character, bl = color
  5896 00002F81 6659                <1> 	pop	cx
  5897 00002F83 FEC9                <1> 	dec	cl
  5898 00002F85 7409                <1> 	jz	short vga_wtty_7
  5899 00002F87 668B15[F6630100]    <1> 	mov	dx, [CURSOR_POSN] ; new cursor position (pg 0)
  5900 00002F8E EBE6                <1> 	jmp	short vga_wtty_6
  5901                              <1> vga_wtty_7:
  5902 00002F90 C3                  <1> 	retn
  5903                              <1> 	;
  5904                              <1> vga_wtty_8:
  5905 00002F91 83C64F              <1> 	add	esi, vga_g_memmodel - (vga_g_modes + 1)  
  5906                              <1> 	; [ESI] = VGA memory model number (LINEAR8, PLANAR4, PLANAR1)
  5907 00002F94 BF00000A00          <1> 	mov	edi, 0A0000h
  5908                              <1> 	;
  5909 00002F99 88F8                <1> 	mov	al, bh ; character
  5910                              <1> 	;
  5911 00002F9B 803E04              <1> 	cmp	byte [esi], PLANAR4
  5912 00002F9E 7414                <1> 	je	short vga_wtty_planar
  5913 00002FA0 803E03              <1> 	cmp	byte [esi], PLANAR1
  5914 00002FA3 740F                <1> 	je	short vga_wtty_planar
  5915                              <1> vga_wtty_linear8:
  5916                              <1> 	; write_gfx_char_lin(car,attr,xcurs,ycurs,nbcols);
  5917                              <1> 	; AL = car, BL = attr (color), DL = xcurs, DH = ycurs, 
  5918                              <1> 	; [CRT_COLS] = nbcols
  5919 00002FA5 E8F3FCFFFF          <1> 	call	write_gfx_char_lin
  5920 00002FAA EB0D                <1> 	jmp	short vga_wtty_9
  5921                              <1> 
  5922                              <1> vga_wtty_12:
  5923                              <1> 	; 09/07/2016
  5924                              <1> 	; set cursor position
  5925                              <1> 	; NOTE: Hardware cursor position will not be set
  5926                              <1> 	;   in any VGA modes (>7)
  5927                              <1> 	;   But, cursor position will be saved into
  5928                              <1> 	;   [CURSOR_POSN].
  5929                              <1> 	;   TRDOS 386 (TRDOS v2.0) uses only one page
  5930                              <1> 	;   (page 0) for all graphics modes.
  5931                              <1> 
  5932 00002FAC 668915[F6630100]    <1> 	mov	[CURSOR_POSN], dx ; save cursor pos for pg 0
  5933                              <1> 	; 04/08/2016
  5934                              <1> 	;mov	bh, [ACTIVE_PAGE] ; = 0
  5935                              <1> 	;call	_set_cpos
  5936 00002FB3 C3                  <1> 	retn
  5937                              <1> 
  5938                              <1> vga_wtty_planar:
  5939                              <1> 	; write_gfx_char_pl4(car,attr,xcurs,ycurs,nbcols,cheight);
  5940                              <1> 	; AL = car, BL = attr (color), DL = xcurs, DH = ycurs, 
  5941                              <1> 	; [CRT_COLS]= nbcols, [CHAR_HEIGHT] = cheight
  5942 00002FB4 E87BFDFFFF          <1> 	call	write_gfx_char_pl4
  5943                              <1> vga_wtty_9:
  5944 00002FB9 FEC2                <1> 	inc	dl ; xcurs++;
  5945                              <1> vga_wtty_10:
  5946                              <1> 	; Do we need to wrap ?
  5947                              <1> 	; if(xcurs==nbcols)
  5948 00002FBB 3A15[9C690000]      <1> 	cmp	dl, [CRT_COLS] ; [VGA_COLS]
  5949 00002FC1 7204                <1> 	jb	short vga_wtty_11 ; no
  5950 00002FC3 28D2                <1> 	sub	dl, dl ; xcurs=0;
  5951 00002FC5 FEC6                <1> 	inc	dh ;  ycurs++;
  5952                              <1> vga_wtty_11:
  5953                              <1> 	; Do we need to scroll ?
  5954                              <1> 	; if(ycurs==nbrows)
  5955 00002FC7 3A35[A2690000]      <1> 	cmp	dh, [VGA_ROWS]
  5956 00002FCD 72DD                <1> 	jb	short vga_wtty_12 ; no
  5957                              <1> 	;
  5958                              <1> 	; biosfn_scroll (nblines,attr,rul,cul,rlr,clr,page,dir)
  5959                              <1> 	; al = nblines = 1, bl = attr (color) = 0
  5960                              <1> 	; ch = rul, cl = cul, dh = rlr, dl = clr, page = 0
  5961                              <1> 	; dir = SCROLL_UP
  5962                              <1> 	
  5963 00002FCF B001                <1> 	mov	al, 1
  5964 00002FD1 28DB                <1> 	sub	bl, bl ; 0 ; blank/black line (attr=0) will be used
  5965 00002FD3 6629C9              <1> 	sub	cx, cx ; 0,0
  5966                              <1> 
  5967                              <1> 	; 06/08/2016
  5968 00002FD6 8A35[A2690000]      <1> 	mov	dh, [VGA_ROWS]
  5969 00002FDC FECE                <1> 	dec	dh ; nbrows -1
  5970                              <1> 
  5971 00002FDE 6652                <1> 	push	dx 	; 04/08/2016
  5972 00002FE0 8A15[9C690000]      <1> 	mov	dl, [CRT_COLS]
  5973 00002FE6 FECA                <1> 	dec	dl ; nbcols -1
  5974                              <1> 	
  5975 00002FE8 8A25[9A690000]      <1> 	mov	ah, [CRT_MODE]
  5976                              <1> 	
  5977                              <1> 	; biosfn_scroll(0x01,0x00,0,0,nbrows-1,nbcols-1,page,SCROLL_UP);
  5978 00002FEE E807F5FFFF          <1> 	call	vga_graphics_up
  5979                              <1> 	; 04/08/2016
  5980 00002FF3 665A                <1> 	pop	dx
  5981                              <1> 	;dec	dh ; ycurs-=1
  5982 00002FF5 EBB5                <1> 	jmp	short vga_wtty_12 
  5983                              <1> 
  5984                              <1> font_setup:
  5985                              <1> 	; 09/07/2016
  5986                              <1> 	; character generator (font loading) functions
  5987                              <1> 	;
  5988                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  5989                              <1> 	; vgabios-0.7a (2011)
  5990                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  5991                              <1> 	; 'vgabios.c', 'int10_func'
  5992                              <1> 
  5993                              <1> 	; AX = 1100H ; Load User-Defined Font (EGA/VGA)
  5994                              <1> 	;
  5995                              <1>         ; BH    height of each character (bytes per character definition)
  5996                              <1>         ; (BL   font block to load (EGA: 0-3; VGA: 0-7))
  5997                              <1> 	; CX    number of characters to redefine (<=256)
  5998                              <1>         ; DX    ASCII code of the first character defined at ES:BP
  5999                              <1>         ; EBP	address of font-definition information
  6000                              <1> 	;	(in user's memory space)
  6001                              <1> 
  6002                              <1> 	; case 0x11:
  6003                              <1>      	; switch(GET_AL())
  6004                              <1>       	; {
  6005                              <1> 	; case 0x00:
  6006                              <1>         ; case 0x10:
  6007                              <1>         ; biosfn_load_text_user_pat(GET_AL(),ES,BP,CX,DX,GET_BL(),GET_BH());
  6008                              <1>         ; break;
  6009                              <1> 
  6010                              <1> 	; AX = 1110H ; Load and Activate User-Defined Font (EGA/VGA)
  6011 00002FF7 08C0                <1> 	or	al, al ; 0
  6012 00002FF9 7404                <1> 	jz	short font_setup_0
  6013 00002FFB 3C10                <1> 	cmp	al, 10h
  6014 00002FFD 7511                <1> 	jne	short font_setup_1	
  6015                              <1> font_setup_0:
  6016 00002FFF E8B7000000          <1> 	call	transfer_user_fonts
  6017 00003004 721C                <1> 	jc	short font_setup_error
  6018 00003006 E8C2000000          <1> 	call	load_text_user_pat
  6019 0000300B E947EAFFFF          <1>         jmp     VIDEO_RETURN 
  6020                              <1> font_setup_1:
  6021                              <1> 	; AX = 1101H ; Load ROM 8x14 Character Set (EGA/VGA)
  6022                              <1> 	; case 0x01:
  6023                              <1>         ; case 0x11:
  6024                              <1>         ; biosfn_load_text_8_14_pat(GET_AL(),GET_BL());
  6025                              <1>         ; break;
  6026 00003010 3C01                <1> 	cmp	al, 1
  6027 00003012 7404                <1> 	je	short font_setup_2
  6028 00003014 3C11                <1> 	cmp	al, 11h
  6029 00003016 7511                <1> 	jne	short font_setup_3	
  6030                              <1> font_setup_2:
  6031                              <1> 	; AX = 1111H ; Load and Activate ROM 8x14 Character Set (EGA/VGA)
  6032                              <1> 	; (BL = font block to load (EGA: 0-3; VGA: 0-7))
  6033 00003018 E8EC010000          <1> 	call	load_text_8_14_pat
  6034 0000301D E935EAFFFF          <1>         jmp     VIDEO_RETURN
  6035                              <1> font_setup_error:
  6036 00003022 29C0                <1> 	sub	eax, eax ; 0 -> fonts could not be loaded
  6037 00003024 E933EAFFFF          <1> 	jmp	_video_return
  6038                              <1> font_setup_3:
  6039                              <1> 	; AX = 1102H ; Load ROM 8x8 Character Set (EGA/VGA)
  6040                              <1> 	; case 0x02:
  6041                              <1>         ; case 0x12:
  6042                              <1>         ; biosfn_load_text_8_8_pat(GET_AL(),GET_BL());
  6043                              <1>         ; break;
  6044 00003029 3C02                <1> 	cmp	al, 2
  6045 0000302B 7404                <1> 	je	short font_setup_4
  6046 0000302D 3C12                <1> 	cmp	al, 12h
  6047 0000302F 750A                <1> 	jne	short font_setup_5	
  6048                              <1> font_setup_4:
  6049                              <1> 	; AX = 1112H ; Load and Activate ROM 8x8 Character Set (EGA/VGA)
  6050                              <1> 	; (BL = font block to load (EGA: 0-3; VGA: 0-7))
  6051 00003031 E803020000          <1> 	call	load_text_8_8_pat
  6052 00003036 E91CEAFFFF          <1>         jmp     VIDEO_RETURN
  6053                              <1> font_setup_5:
  6054                              <1> 	; AX = 1104H ; Load ROM 8x16 Character Set (EGA/VGA)
  6055                              <1> 	; case 0x04:
  6056                              <1>         ; case 0x14:
  6057                              <1>         ; biosfn_load_text_8_16_pat(GET_AL(),GET_BL());
  6058                              <1>         ; break;
  6059 0000303B 3C04                <1> 	cmp	al, 4
  6060 0000303D 7404                <1> 	je	short font_setup_6
  6061 0000303F 3C14                <1> 	cmp	al, 14h
  6062 00003041 750A                <1> 	jne	short font_setup_7	
  6063                              <1> font_setup_6:
  6064                              <1> 	; AX = 1114H ; Load and Activate ROM 8x16 Character Set (EGA/VGA)
  6065                              <1> 	; (BL = font block to load (EGA: 0-3; VGA: 0-7))
  6066 00003043 E821020000          <1> 	call	load_text_8_16_pat
  6067 00003048 E90AEAFFFF          <1>         jmp     VIDEO_RETURN
  6068                              <1> font_setup_7:
  6069                              <1> 	; Note: AX=1120h (Setup INT 1Fh, EXT_PTR) is not needed
  6070                              <1> 	; for TRDOS 386 (TRDIOS v2.0) video functionality;
  6071                              <1> 	; because, originally EXT_PTR (font address) was used for
  6072                              <1> 	; chars 80h to 0FFh (after the first 128 ASCII char fonts), for
  6073                              <1> 	; CGA graphics mode; currenty, 'vgafont8' address has 256 chars!
  6074                              <1> 	; 
  6075                              <1> 	; case 0x20:
  6076                              <1>         ; biosfn_load_gfx_8_8_chars(ES,BP);
  6077                              <1>         ; break; 
  6078                              <1> 	; case 0x21:
  6079                              <1>         ; biosfn_load_gfx_user_chars(ES,BP,CX,GET_BL(),GET_DL());
  6080                              <1>         ; break;
  6081                              <1> 	; AX = 1121H ; Setup User-Defined Font for Graphics Mode (VGA)
  6082                              <1> 	; BL   screen rows code: 00H = user-specified (in DL)
  6083                              <1>         ;                        01H = 14 rows
  6084                              <1>         ;                        02H = 25 rows
  6085                              <1>         ;                        03H = 43 rows
  6086                              <1>         ; CX   bytes per character definition
  6087                              <1>         ; DL   (when BL=0) custom number of character rows on screen
  6088                              <1>         ; EBP  address of font-definition information (user's mem space)
  6089                              <1> 
  6090 0000304D 3C21                <1> 	cmp	al, 21h
  6091 0000304F 751A                <1> 	jne	short font_setup_9
  6092                              <1> 
  6093                              <1> 	; TRDOS 386 modification !
  6094                              <1> 	; dh = 0 -> 256 characters
  6095                              <1> 	; dh = 80h -> 128 characters
  6096                              <1> 	; (If DH <> 0 and DH <> 80h -> invalid)     
  6097 00003051 20F6                <1> 	and	dh, dh
  6098 00003053 7405                <1> 	jz	short font_setup_8 ; 256 characters
  6099 00003055 80FE80              <1> 	cmp	dh, 80h ; 128 characters
  6100 00003058 75C8                <1> 	jne	short font_setup_error ; invalid !
  6101                              <1> font_setup_8:
  6102 0000305A E85C000000          <1> 	call	transfer_user_fonts
  6103 0000305F 72C1                <1> 	jc	short font_setup_error
  6104                              <1> 	; ebp = user's font data address in system's memory space
  6105 00003061 E834020000          <1> 	call	load_gfx_user_chars
  6106 00003066 E9ECE9FFFF          <1>         jmp     VIDEO_RETURN 
  6107                              <1> font_setup_9:
  6108                              <1> 	; case 0x22:
  6109                              <1>         ; biosfn_load_gfx_8_14_chars(GET_BL());
  6110                              <1>         ; break;
  6111 0000306B 3C22                <1> 	cmp	al, 22h
  6112 0000306D 750A                <1> 	jne	short font_setup_10
  6113 0000306F E864020000          <1> 	call	load_gfx_8_14_chars	
  6114 00003074 E9DEE9FFFF          <1>         jmp     VIDEO_RETURN 
  6115                              <1> font_setup_10:	
  6116                              <1> 	; case 0x23:
  6117                              <1>         ; biosfn_load_gfx_8_8_dd_chars(GET_BL());
  6118                              <1>         ; break;
  6119 00003079 3C23                <1> 	cmp	al, 23h
  6120 0000307B 750A                <1> 	jne	short font_setup_11
  6121 0000307D E897020000          <1> 	call	load_gfx_8_8_chars	
  6122 00003082 E9D0E9FFFF          <1>         jmp     VIDEO_RETURN 
  6123                              <1> font_setup_11:	
  6124                              <1> 	; case 0x24:
  6125                              <1>         ; biosfn_load_gfx_8_16_chars(GET_BL());
  6126                              <1>         ; break;
  6127 00003087 3C24                <1> 	cmp	al, 24h
  6128 00003089 750A                <1> 	jne	short font_setup_12
  6129 0000308B E8CA020000          <1> 	call	load_gfx_8_16_chars	
  6130 00003090 E9C2E9FFFF          <1>         jmp     VIDEO_RETURN 
  6131                              <1> font_setup_12:
  6132                              <1>  	; case 0x30:
  6133                              <1>         ; biosfn_get_font_info(GET_BH(),&ES,&BP,&CX,&DX);
  6134                              <1>         ; break;
  6135 00003095 3C30                <1> 	cmp	al, 30h
  6136 00003097 750A                <1> 	jne	short font_setup_13			
  6137 00003099 E8FD020000          <1> 	call	get_font_info
  6138                              <1> 	; eax = return value (info: 4 bytes for 4 parms)
  6139                              <1> 	; eax = 0 -> invalid function (input)
  6140 0000309E E9B9E9FFFF          <1>         jmp     _video_return
  6141                              <1> font_setup_13:
  6142 000030A3 3C03                <1> 	cmp	al, 03h ; AX = 1103h	
  6143 000030A5 750D                <1> 	jne	short font_setup_14
  6144                              <1> 	; biosfn_set_text_block_specifier:
  6145                              <1> 	; BL = font block selector code	
  6146                              <1> 	; NOTE: TRDOS 386 only uses and sets font block 0
  6147                              <1> 	; (It is as BL = 0 for TRDOS 386)
  6148 000030A7 66BAC403            <1> 	mov	dx, 3C4h ; VGAREG_SEQU_ADDRESS
  6149                              <1> 	;mov	ah, bl
  6150 000030AB 28E4                <1> 	sub	ah, ah ; 0
  6151                              <1> 	;mov	al, 03h
  6152 000030AD 66EF                <1> 	out	dx, ax
  6153 000030AF E9A3E9FFFF          <1> 	jmp     VIDEO_RETURN 
  6154                              <1> 	
  6155                              <1> font_setup_14:
  6156 000030B4 29C0                <1> 	sub	eax, eax ; 0 = invalid function
  6157 000030B6 E9A1E9FFFF          <1>         jmp     _video_return
  6158                              <1> 
  6159                              <1> transfer_user_fonts:
  6160                              <1> 	; 09/07/2016
  6161                              <1> 	;and	ecx, 0FFFFh
  6162                              <1> 	; ECX = byte count
  6163                              <1> 	;push	ecx
  6164 000030BB 89EE                <1> 	mov	esi, ebp ; user buffer
  6165 000030BD BF00000700          <1> 	mov	edi, Cluster_Buffer  ; system buffer
  6166 000030C2 E814C20000          <1> 	call	transfer_from_user_buffer
  6167                              <1> 	;pop	ecx
  6168                              <1> 	; ecx = transfer (byte) count = character count
  6169 000030C7 BD00000700          <1> 	mov	ebp, Cluster_Buffer
  6170                              <1> 	; jc	VIDEO_RETURN -> failed
  6171 000030CC C3                  <1> 	retn
  6172                              <1> 
  6173                              <1> load_text_user_pat:
  6174                              <1> 	; 26/07/2016
  6175                              <1> 	; 09/07/2016
  6176                              <1> 	; load user defined (EGA/VGA) text fonts
  6177                              <1> 	;
  6178                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  6179                              <1> 	; vgabios-0.7a (2011)
  6180                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  6181                              <1> 	; 'vgabios.c', 'biosfn_load_text_user_pat'
  6182                              <1> 
  6183                              <1> 	; biosfn_load_text_user_pat (AL,ES,BP,CX,DX,BL,BH)
  6184                              <1> 
  6185                              <1> 	; get_font_access();
  6186                              <1> 	; blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
  6187                              <1> 	; for(i=0;i<CX;i++)
  6188                              <1> 	; {
  6189                              <1> 	;  src = BP + i * BH;
  6190                              <1> 	;  dest = blockaddr + (DX + i) * 32;
  6191                              <1> 	;  memcpyb(0xA000, dest, ES, src, BH);
  6192                              <1> 	; }
  6193                              <1> 	; release_font_access();
  6194                              <1> 	; if(AL>=0x10)
  6195                              <1> 	; {
  6196                              <1> 	; set_scan_lines(BH);
  6197                              <1> 	; }
  6198                              <1> 
  6199 000030CD 50                  <1> 	push	eax
  6200 000030CE E83C000000          <1> 	call	get_font_access
  6201 000030D3 28DB                <1> 	sub	bl, bl ; i = 0	
  6202                              <1> ltup_1:
  6203 000030D5 88D8                <1> 	mov	al, bl
  6204 000030D7 F6E7                <1> 	mul	bh
  6205 000030D9 0FB7F0              <1> 	movzx	esi, ax
  6206 000030DC 01EE                <1> 	add	esi, ebp
  6207 000030DE 88D8                <1> 	mov	al, bl
  6208 000030E0 28E4                <1> 	sub	ah, ah
  6209 000030E2 6601D0              <1> 	add	ax, dx ; (DX + i)
  6210 000030E5 66C1E005            <1> 	shl	ax, 5  ; * 32
  6211 000030E9 0FB7F8              <1> 	movzx	edi, ax
  6212 000030EC 81C700000A00        <1> 	add	edi, 0A0000h
  6213 000030F2 51                  <1> 	push	ecx
  6214 000030F3 0FB6CF              <1> 	movzx	ecx, bh 		
  6215 000030F6 F3A4                <1> 	rep	movsb
  6216 000030F8 59                  <1> 	pop	ecx	
  6217 000030F9 FEC3                <1> 	inc	bl
  6218 000030FB 38CB                <1> 	cmp	bl, cl
  6219 000030FD 75D6                <1> 	jne	short ltup_1	
  6220                              <1> 	;
  6221 000030FF E840000000          <1> 	call	release_font_access
  6222                              <1> 	;
  6223 00003104 58                  <1> 	pop	eax
  6224                              <1> 	; if(AL>=0x10)
  6225 00003105 3C10                <1> 	cmp	al, 10h
  6226 00003107 7205                <1> 	jb	short ltup_2
  6227                              <1>    	; set_scan_lines(BH);
  6228 00003109 E875000000          <1> 	call	set_scan_lines
  6229                              <1> ltup_2:
  6230 0000310E C3                  <1> 	retn
  6231                              <1> 
  6232                              <1> get_font_access:
  6233                              <1> 	; 09/07/2016
  6234                              <1> 	;
  6235                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  6236                              <1> 	; vgabios-0.7a (2011)
  6237                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  6238                              <1> 	; 'vgabios.c', 'get_font_access'
  6239                              <1> 
  6240                              <1> 	; get_font_access()
  6241 0000310F 52                  <1> 	push	edx
  6242 00003110 66BAC403            <1> 	mov	dx, 3C4h ; VGAREG_SEQU_ADDRESS
  6243 00003114 66B80001            <1> 	mov	ax, 0100h
  6244 00003118 66EF                <1> 	out	dx, ax
  6245 0000311A 66B80204            <1> 	mov	ax, 0402h
  6246 0000311E 66EF                <1> 	out	dx, ax
  6247 00003120 66B80407            <1> 	mov	ax, 0704h
  6248 00003124 66EF                <1> 	out	dx, ax
  6249 00003126 66B80003            <1> 	mov	ax, 0300h
  6250 0000312A 66EF                <1> 	out	dx, ax
  6251 0000312C 66BACE03            <1> 	mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  6252 00003130 66B80402            <1> 	mov	ax, 0204h
  6253 00003134 66EF                <1> 	out	dx, ax
  6254 00003136 66B80500            <1> 	mov	ax, 0005h
  6255 0000313A 66EF                <1> 	out	dx, ax
  6256 0000313C 66B80604            <1> 	mov	ax, 0406h
  6257 00003140 66EF                <1> 	out	dx, ax
  6258 00003142 5A                  <1> 	pop	edx
  6259 00003143 C3                  <1> 	retn
  6260                              <1> 
  6261                              <1> release_font_access:
  6262                              <1> 	; 29/07/2016
  6263                              <1> 	; 09/07/2016
  6264                              <1> 	;
  6265                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  6266                              <1> 	; vgabios-0.7a (2011)
  6267                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  6268                              <1> 	; 'vgabios.c', 'release_font_access'
  6269                              <1> 
  6270 00003144 66BAC403            <1> 	mov	dx, 3C4h ; VGAREG_SEQU_ADDRESS
  6271 00003148 66B80001            <1> 	mov	ax, 0100h
  6272 0000314C 66EF                <1> 	out	dx, ax
  6273 0000314E 66B80203            <1> 	mov	ax, 0302h
  6274 00003152 66EF                <1> 	out	dx, ax
  6275 00003154 66B80403            <1> 	mov	ax, 0304h
  6276 00003158 66EF                <1> 	out	dx, ax
  6277 0000315A 66B80003            <1> 	mov	ax, 0300h
  6278 0000315E 66EF                <1> 	out	dx, ax
  6279 00003160 66BACC03            <1> 	mov	dx, 3CCh ; VGAREG_READ_MISC_OUTPUT
  6280 00003164 EC                  <1>  	in	al, dx
  6281 00003165 2401                <1> 	and	al, 01h
  6282 00003167 C0E002              <1> 	shl	al, 2
  6283 0000316A 0C0A                <1> 	or	al, 0Ah
  6284 0000316C 88C4                <1> 	mov	ah, al
  6285 0000316E B006                <1> 	mov	al, 06h
  6286 00003170 66BACE03            <1> 	mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  6287 00003174 66EF                <1> 	out	dx, ax
  6288 00003176 66B80400            <1> 	mov	ax, 0004h
  6289 0000317A 66EF                <1> 	out	dx, ax
  6290 0000317C 66B80510            <1> 	mov	ax, 1005h
  6291 00003180 66EF                <1> 	out	dx, ax
  6292 00003182 C3                  <1> 	retn
  6293                              <1> 
  6294                              <1> set_scan_lines:
  6295                              <1> 	; 09/07/2016
  6296                              <1> 	;
  6297                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  6298                              <1> 	; vgabios-0.7a (2011)
  6299                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  6300                              <1> 	; 'vgabios.c', 'set_scan_lines'
  6301                              <1> 
  6302                              <1> 	; set_scan_lines(lines)
  6303                              <1> 	; BH = lines
  6304                              <1> 
  6305                              <1> 	; outb(crtc_addr, 0x09);
  6306 00003183 66BAD403            <1> 	mov	dx, 3D4h ; CRTC_ADDRESS = 3D4h (always)
  6307 00003187 B009                <1> 	mov	al, 09h
  6308 00003189 EE                  <1> 	out	dx, al
  6309                              <1> 	; crtc_r9 = inb(crtc_addr+1);
  6310 0000318A 6642                <1> 	inc	dx ; 3D5h
  6311 0000318C EC                  <1> 	in	al, dx
  6312                              <1> 	; crtc_r9 = (crtc_r9 & 0xe0) | (lines - 1);
  6313 0000318D 24E0                <1> 	and	al, 0E0h
  6314 0000318F FECF                <1> 	dec	bh ; lines - 1
  6315 00003191 08F8                <1> 	or	al, bh
  6316                              <1> 	; outb(crtc_addr+1, crtc_r9);
  6317 00003193 EE                  <1> 	out	dx, al
  6318                              <1> 	;inc	bh 
  6319                              <1> 	; if(lines==8)
  6320                              <1> 	;cmp	bh, 8
  6321 00003194 80FF07              <1> 	cmp	bh, 7
  6322 00003197 7506                <1> 	jne	short ssl_1
  6323                              <1> 	; biosfn_set_cursor_shape(0x06,0x07);
  6324 00003199 66B90706            <1> 	mov	cx, 0607h
  6325 0000319D EB06                <1> 	jmp	short ssl_2
  6326                              <1> ssl_1:
  6327                              <1> 	; biosfn_set_cursor_shape(lines-4,lines-3);
  6328 0000319F 88F9                <1> 	mov	cl, bh ; lines - 1
  6329 000031A1 88CD                <1> 	mov	ch, cl ; lines - 1 (16 -> 15)
  6330 000031A3 FECD                <1> 	dec	ch  ; lines - 2 (16 -> 14)
  6331                              <1> ssl_2:
  6332                              <1> 	; CH = start line, CL = stop line
  6333 000031A5 B40A                <1> 	mov	ah, 10	; 6845 register for cursor set
  6334 000031A7 66890D[B3690000]    <1> 	mov	[CURSOR_MODE], cx ; save in data area
  6335 000031AE E80FF1FFFF          <1> 	call	m16	; output cx register
  6336                              <1> 	; write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, lines);
  6337 000031B3 FEC7                <1> 	inc	bh ; lines
  6338 000031B5 883D[9E690000]      <1> 	mov	[CHAR_HEIGHT], bh
  6339                              <1> 	;  outb(crtc_addr, 0x12);
  6340 000031BB 66BAD403            <1> 	mov	dx, 3D4h ; CRTC_ADDRESS
  6341 000031BF B012                <1> 	mov	al, 12h
  6342 000031C1 EE                  <1> 	out	dx, al
  6343                              <1> 	; vde = inb(crtc_addr+1);
  6344 000031C2 6642                <1> 	inc	dx
  6345 000031C4 EC                  <1> 	in	al, dx
  6346 000031C5 88C4                <1> 	mov	ah, al
  6347                              <1> 	; outb(crtc_addr, 0x07);
  6348 000031C7 664A                <1> 	dec	dx
  6349 000031C9 B007                <1> 	mov	al, 07h
  6350 000031CB EE                  <1> 	out	dx, al
  6351                              <1> 	; ovl = inb(crtc_addr+1);
  6352 000031CC 6642                <1> 	inc	dx
  6353 000031CE EC                  <1> 	in	al, dx
  6354                              <1> 	; vde += (((ovl & 0x02) << 7) + ((ovl & 0x40) << 3) + 1);
  6355 000031CF 88E2                <1> 	mov	dl, ah ; vde
  6356 000031D1 88C6                <1> 	mov	dh, al ; ovl
  6357 000031D3 6683E002            <1> 	and	ax, 02h
  6358 000031D7 66C1E007            <1> 	shl	ax, 7
  6359 000031DB 6689C1              <1> 	mov	cx, ax ; (ovl & 0x02) << 7)	
  6360 000031DE 88F0                <1> 	mov	al, dh ; ovl
  6361 000031E0 6683E040            <1> 	and	ax, 40h			
  6362 000031E4 66C1E003            <1> 	shl	ax, 3  ; (ovl & 0x40) << 3)
  6363 000031E8 6640                <1> 	inc	ax ; + 1 
  6364 000031EA 6601C8              <1> 	add	ax, cx
  6365 000031ED 30F6                <1> 	xor	dh, dh
  6366 000031EF 6601D0              <1> 	add	ax, dx ; + vde
  6367                              <1> 	; rows = vde / lines;
  6368 000031F2 F6F7                <1> 	div	bh
  6369                              <1> 	;dec	al ; rows -1
  6370                              <1> 	; write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, rows-1);
  6371 000031F4 A2[A2690000]        <1> 	mov	[VGA_ROWS], al ; rows (not 'rows-1' !)
  6372                              <1> 	; write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, rows * cols * 2);
  6373                              <1> 	;mov	ah, [CRT_COLS]
  6374                              <1> 	;mul	ah
  6375                              <1> 	; 17/11/2020
  6376 000031F9 F625[9C690000]      <1> 	mul	byte [CRT_COLS]
  6377 000031FF 66D1E0              <1> 	shl	ax, 1
  6378 00003202 66A3[70700100]      <1> 	mov 	[CRT_LEN], ax	
  6379 00003208 C3                  <1> 	retn
  6380                              <1> 
  6381                              <1> load_text_8_14_pat:
  6382                              <1> 	; 26/07/2016
  6383                              <1> 	; 25/07/2016
  6384                              <1> 	; 23/07/2016
  6385                              <1> 	; 09/07/2016
  6386                              <1> 	; load user defined (EGA/VGA) text fonts
  6387                              <1> 	;
  6388                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  6389                              <1> 	; vgabios-0.7a (2011)
  6390                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  6391                              <1> 	; 'vgabios.c', 'biosfn_load_text_8_14_pat'
  6392                              <1> 
  6393                              <1> 	; biosfn_load_text_8_14_pat (AL,BL)
  6394                              <1> 
  6395                              <1> 	; get_font_access();
  6396                              <1> 	; blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
  6397                              <1> 	; for(i=0;i<0x100;i++)
  6398                              <1> 	; {
  6399                              <1> 	;  src = i * 14;
  6400                              <1> 	;  dest = blockaddr + i * 32;
  6401                              <1> 	;  memcpyb(0xA000, dest, 0xC000, vgafont14+src, 14);
  6402                              <1> 	; }
  6403                              <1> 	; release_font_access();
  6404                              <1> 	; if(AL>=0x10)
  6405                              <1> 	; {
  6406                              <1> 	; set_scan_lines(14);
  6407                              <1> 	; }
  6408                              <1> 
  6409 00003209 50                  <1> 	push	eax
  6410 0000320A E800FFFFFF          <1> 	call	get_font_access
  6411                              <1> 
  6412                              <1> 	; blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
  6413                              <1> 	;mov	dl, bl
  6414                              <1> 	;and	dl, 3
  6415                              <1> 	;shl	dx, 14
  6416                              <1> 	;xchg	dx, bx
  6417                              <1> 	;and	dl, 4
  6418                              <1> 	;shl	dx, 11
  6419                              <1> 	;add	dx, bx 	
  6420                              <1>  
  6421                              <1> 	;xor	dx, dx  ; blockaddr = 0
  6422                              <1> 	; Always block 0 for TRDOS 386 ! (blockaddr=0(
  6423                              <1> 
  6424 0000320F 28DB                <1> 	sub	bl, bl ; i = 0
  6425 00003211 B70E                <1> 	mov	bh, 14
  6426 00003213 BE[F83F0100]        <1> 	mov	esi, vgafont14
  6427 00003218 BF00000A00          <1> 	mov	edi, 0A0000h		
  6428                              <1> lt8_14_1:
  6429                              <1> 	;mov	al, bl
  6430                              <1> 	;mul	bh
  6431                              <1> 	;movzx	esi, ax
  6432                              <1> 	;add	esi, vgafont14
  6433                              <1> 	;mov	al, bl
  6434                              <1> 	;sub	ah, ah
  6435                              <1> 	;shl	ax, 5 ; * 32
  6436                              <1> 	;;add	ax, dx ; blockaddr + i * 32;
  6437                              <1> 	;movzx	edi, ax ; dest
  6438                              <1> 	;add	edi, 0A0000h
  6439 0000321D 0FB6CF              <1> 	movzx	ecx, bh 		
  6440 00003220 F3A4                <1> 	rep	movsb
  6441 00003222 83C712              <1> 	add	edi, 18 ; 32 - 14
  6442 00003225 FEC3                <1> 	inc	bl
  6443 00003227 75F4                <1> 	jnz	short lt8_14_1	
  6444                              <1> 	;
  6445 00003229 E816FFFFFF          <1> 	call	release_font_access
  6446                              <1> 	;
  6447 0000322E 58                  <1> 	pop	eax
  6448                              <1> 	; if(AL>=0x10)
  6449 0000322F 3C10                <1> 	cmp	al, 10h
  6450 00003231 7205                <1> 	jb	short lt8_14_4
  6451                              <1> 	; BH = 14
  6452                              <1>    	; set_scan_lines(14);
  6453 00003233 E84BFFFFFF          <1> 	call	set_scan_lines
  6454                              <1> lt8_14_4:
  6455 00003238 C3                  <1> 	retn
  6456                              <1> 
  6457                              <1> load_text_8_8_pat:
  6458                              <1> 	; 26/07/2016
  6459                              <1> 	; 25/07/2016
  6460                              <1> 	; 23/07/2016
  6461                              <1> 	; 09/07/2016
  6462                              <1> 	; load user defined (EGA/VGA) text fonts
  6463                              <1> 	;
  6464                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  6465                              <1> 	; vgabios-0.7a (2011)
  6466                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  6467                              <1> 	; 'vgabios.c', 'biosfn_load_text_8_8_pat'
  6468                              <1> 
  6469                              <1> 	; biosfn_load_text_8_8_pat (AL,BL)
  6470                              <1> 
  6471                              <1> 	; get_font_access();
  6472                              <1> 	; blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
  6473                              <1> 	; for(i=0;i<0x100;i++)
  6474                              <1> 	; {
  6475                              <1> 	;  src = i * 8;
  6476                              <1> 	;  dest = blockaddr + i * 32;
  6477                              <1> 	;  memcpyb(0xA000, dest, 0xC000, vgafont8+src, 8);
  6478                              <1> 	; }
  6479                              <1> 	; release_font_access();
  6480                              <1> 	; if(AL>=0x10)
  6481                              <1> 	; {
  6482                              <1> 	; set_scan_lines(8);
  6483                              <1> 	; }
  6484                              <1> 
  6485 00003239 50                  <1> 	push	eax
  6486 0000323A E8D0FEFFFF          <1> 	call	get_font_access
  6487                              <1> 
  6488                              <1> 	; blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
  6489                              <1> 	;mov	dl, bl
  6490                              <1> 	;and	dl, 3
  6491                              <1> 	;shl	dx, 14
  6492                              <1> 	;xchg	dx, bx
  6493                              <1> 	;and	dl, 4
  6494                              <1> 	;shl	dx, 11
  6495                              <1> 	;add	dx, bx 	
  6496                              <1>  
  6497                              <1> 	;xor	dx, dx  ; blockaddr = 0
  6498                              <1> 	; Always block 0 for TRDOS 386 ! (blockaddr=0(
  6499                              <1> 
  6500 0000323F 28DB                <1> 	sub	bl, bl ; i = 0
  6501 00003241 B708                <1> 	mov	bh, 8
  6502 00003243 BE[F8370100]        <1> 	mov	esi, vgafont8
  6503 00003248 BF00000A00          <1> 	mov	edi, 0A0000h		
  6504                              <1> lt8_8_1:
  6505                              <1> 	;mov	al, bl
  6506                              <1> 	;mul	bh
  6507                              <1> 	;movzx	esi, ax
  6508                              <1> 	;add	esi, vgafont8
  6509                              <1> 	;mov	al, bl
  6510                              <1> 	;sub	ah, ah
  6511                              <1> 	;shl	ax, 5 ; * 32
  6512                              <1> 	;;add	ax, dx ; blockaddr + i * 32;
  6513                              <1> 	;movzx	edi, ax ; dest
  6514                              <1> 	;add	edi, 0A0000h
  6515 0000324D 0FB6CF              <1> 	movzx	ecx, bh 		
  6516 00003250 F3A4                <1> 	rep	movsb
  6517 00003252 83C718              <1> 	add	edi, 24 ; 32 - 8
  6518 00003255 FEC3                <1> 	inc	bl
  6519 00003257 75F4                <1> 	jnz	short lt8_8_1	
  6520                              <1> 	;
  6521 00003259 E8E6FEFFFF          <1> 	call	release_font_access
  6522                              <1> 	;
  6523 0000325E 58                  <1> 	pop	eax
  6524                              <1> 	; if(AL>=0x10)
  6525 0000325F 3C10                <1> 	cmp	al, 10h
  6526 00003261 7205                <1> 	jb	short lt8_8_2
  6527                              <1> 	; BH = 8
  6528                              <1>    	; set_scan_lines(8);
  6529 00003263 E81BFFFFFF          <1> 	call	set_scan_lines
  6530                              <1> lt8_8_2:
  6531 00003268 C3                  <1> 	retn
  6532                              <1> 
  6533                              <1> load_text_8_16_pat:
  6534                              <1> 	; 26/07/2016
  6535                              <1> 	; 25/07/2016
  6536                              <1> 	; 23/07/2016
  6537                              <1> 	; 09/07/2016
  6538                              <1> 	; load user defined (EGA/VGA) text fonts
  6539                              <1> 	;
  6540                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  6541                              <1> 	; vgabios-0.7a (2011)
  6542                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  6543                              <1> 	; 'vgabios.c', 'biosfn_load_text_8_16_pat'
  6544                              <1> 
  6545                              <1> 	; biosfn_load_text_8_16_pat (AL,BL)
  6546                              <1> 
  6547                              <1> 	; get_font_access();
  6548                              <1> 	; blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
  6549                              <1> 	; for(i=0;i<0x100;i++)
  6550                              <1> 	; {
  6551                              <1> 	;  src = i * 16;
  6552                              <1> 	;  dest = blockaddr + i * 32;
  6553                              <1> 	;  memcpyb(0xA000, dest, 0xC000, vgafont16+src, 16);
  6554                              <1> 	; }
  6555                              <1> 	; release_font_access();
  6556                              <1> 	; if(AL>=0x10)
  6557                              <1> 	; {
  6558                              <1> 	; set_scan_lines(16);
  6559                              <1> 	; }
  6560                              <1> 
  6561 00003269 50                  <1> 	push	eax
  6562 0000326A E8A0FEFFFF          <1> 	call	get_font_access
  6563                              <1> 
  6564                              <1> 	; blockaddr = ((BL & 0x03) << 14) + ((BL & 0x04) << 11);
  6565                              <1> 	;mov	dl, bl
  6566                              <1> 	;and	dl, 3
  6567                              <1> 	;shl	dx, 14
  6568                              <1> 	;xchg	dx, bx
  6569                              <1> 	;and	dl, 4
  6570                              <1> 	;shl	dx, 11
  6571                              <1> 	;add	dx, bx 	
  6572                              <1>  
  6573                              <1> 	;xor	dx, dx  ; blockaddr = 0
  6574                              <1> 	; Always block 0 for TRDOS 386 ! (blockaddr=0)
  6575                              <1> 
  6576 0000326F 28DB                <1> 	sub	bl, bl ; i = 0
  6577 00003271 B710                <1> 	mov	bh, 16
  6578 00003273 BE[F84D0100]        <1> 	mov	esi, vgafont16
  6579 00003278 BF00000A00          <1> 	mov	edi, 0A0000h
  6580 0000327D 0FB6C7              <1> 	movzx	eax, bh	
  6581                              <1> lt8_16_1:
  6582                              <1> 	;mov	al, bl
  6583                              <1> 	;mul	bh
  6584                              <1> 	;movzx	esi, ax
  6585                              <1> 	;add	esi, vgafont16
  6586                              <1> 	;mov	al, bl ; i
  6587                              <1> 	;sub	ah, ah
  6588                              <1> 	;shl	ax, 5 ; * 32
  6589                              <1> 	;;add	ax, dx ; blockaddr + i * 32;
  6590                              <1> 	;movzx	edi, ax ; dest
  6591                              <1> 	;add	edi, 0A0000h
  6592                              <1> 	;movzx	ecx, bh
  6593 00003280 89C1                <1> 	mov	ecx, eax ; 16	
  6594 00003282 F3A4                <1> 	rep	movsb
  6595 00003284 01C7                <1> 	add	edi, eax ; add edi, 16
  6596 00003286 FEC3                <1> 	inc	bl
  6597 00003288 75F6                <1> 	jnz	short lt8_16_1
  6598                              <1> 	;
  6599 0000328A E8B5FEFFFF          <1> 	call	release_font_access
  6600                              <1> 	;
  6601 0000328F 58                  <1> 	pop	eax
  6602                              <1> 	; if(AL>=0x10)
  6603 00003290 3C10                <1> 	cmp	al, 10h
  6604 00003292 7205                <1> 	jb	short lt8_16_2
  6605                              <1> 	; BH = 16
  6606                              <1>    	; set_scan_lines(16);
  6607 00003294 E8EAFEFFFF          <1> 	call	set_scan_lines
  6608                              <1> lt8_16_2:
  6609 00003299 C3                  <1> 	retn
  6610                              <1> 
  6611                              <1> load_gfx_user_chars:
  6612                              <1> 	; 08/08/2016
  6613                              <1> 	; 10/07/2016
  6614                              <1> 	; Setup User-Defined Font for Graphics Mode (VGA)
  6615                              <1> 	;
  6616                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  6617                              <1> 	; vgabios-0.7a (2011)
  6618                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  6619                              <1> 	; 'vgabios.c', 'biosfn_load_gfx_user_chars'
  6620                              <1> 
  6621                              <1> 	; biosfn_load_gfx_user_chars (ES,BP,CX,BL,DL)
  6622                              <1> 	; /* set 0x43 INT pointer */
  6623                              <1>     	; write_word(0x0, 0x43*4, BP);
  6624                              <1>     	; write_word(0x0, 0x43*4+2, ES);
  6625 0000329A 31C0                <1> 	xor	eax, eax
  6626 0000329C 48                  <1> 	dec	eax ; 0FFFFFFFFh (user defined fonts)
  6627 0000329D A3[82700100]        <1> 	mov	[VGA_INT43H], eax
  6628                              <1> 		
  6629                              <1> 	; BL   screen rows code: 00H = user-specified (in DL)
  6630                              <1>         ;                        01H = 14 rows
  6631                              <1>         ;                        02H = 25 rows
  6632                              <1>         ;                        03H = 43 rows
  6633                              <1>         ; CX   bytes per character definition
  6634                              <1>         ; DL   (when BL=0) custom number of character rows on screen
  6635                              <1> 	; dh = 0 -> 256 characters
  6636                              <1> 	; dh = 80h -> 128 characters
  6637                              <1> 	; (If DH <> 0 and DH <> 80h -> invalid)     	 
  6638                              <1>         ; EBP  address of font-definition information (user's mem space)
  6639                              <1> 
  6640                              <1> 	; switch (BL) {
  6641                              <1> 	; case 0:
  6642                              <1> 	;    write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, DL-1);
  6643                              <1> 	;    break;
  6644 000032A2 20DB                <1> 	and	bl, bl
  6645 000032A4 7508                <1> 	jnz	short l_gfx_uc_1
  6646 000032A6 8815[A2690000]      <1> 	mov	[VGA_ROWS], dl  ; not DL-1 !
  6647 000032AC EB23                <1> 	jmp	short l_gfx_uc_4 	
  6648                              <1> l_gfx_uc_1:
  6649                              <1> 	; case 1:
  6650                              <1> 	;    write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 13);
  6651                              <1> 	;    break;
  6652 000032AE FECB                <1> 	dec	bl
  6653 000032B0 7509                <1> 	jnz	short l_gfx_uc_2
  6654                              <1> 	; bl = 1
  6655 000032B2 C605[A2690000]0E    <1> 	mov	byte [VGA_ROWS], 14  ; not 13 !
  6656 000032B9 EB16                <1> 	jmp	short l_gfx_uc_4 	
  6657                              <1> l_gfx_uc_2:
  6658 000032BB FECB                <1> 	dec	bl
  6659 000032BD 740B                <1> 	jz	short l_gfx_uc_3 ; bl = 2
  6660 000032BF FECB                <1> 	dec	bl
  6661 000032C1 750E                <1> 	jnz	short l_gfx_uc_4 ; bl > 3
  6662                              <1> 	; bl = 3
  6663                              <1> 	; case 3:
  6664                              <1> 	;    write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 42);
  6665                              <1> 	;    break;
  6666 000032C3 C605[A2690000]2B    <1> 	mov	byte [VGA_ROWS], 43  ; not 42 !
  6667                              <1> l_gfx_uc_3:
  6668                              <1>     	; case 2:
  6669                              <1>     	; default:
  6670                              <1> 	;    write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 24);
  6671                              <1> 	;    break;
  6672                              <1> 	; bl = 2 or bl > 3
  6673 000032CA C605[A2690000]19    <1> 	mov	byte [VGA_ROWS], 25  ; not 24 !	
  6674                              <1>     	; }
  6675                              <1> l_gfx_uc_4:
  6676                              <1>     	; write_byte(BIOSMEM_SEG, BIOSMEM_CHAR_HEIGHT, CX);
  6677 000032D1 880D[9E690000]      <1> 	mov	[CHAR_HEIGHT], cl
  6678                              <1> 	; }
  6679 000032D7 C3                  <1> 	retn	
  6680                              <1> 
  6681                              <1> load_gfx_8_14_chars:
  6682                              <1> 	; 08/08/2016
  6683                              <1> 	; 10/07/2016
  6684                              <1> 	; Setup ROM 8x14 Font for Graphics Mode (VGA)
  6685                              <1> 	;
  6686                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  6687                              <1> 	; vgabios-0.7a (2011)
  6688                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  6689                              <1> 	; 'vgabios.c', 'biosfn_load_gfx_8_14_chars'
  6690                              <1> 
  6691                              <1> 	; biosfn_load_gfx_8_14_chars (BL)
  6692                              <1> 	; /* set 0x43 INT pointer */
  6693                              <1>     	; write_word(0x0, 0x43*4, &vgafont14);
  6694                              <1>     	; write_word(0x0, 0x43*4+2, 0xC000);
  6695 000032D8 C705[82700100]-     <1> 	mov	dword [VGA_INT43H], vgafont14
  6695 000032DE [F83F0100]          <1>
  6696                              <1> 		
  6697                              <1> 	; BL    screen rows code: 00H = user-specified (in DL)
  6698                              <1>         ;                         01H = 14 rows
  6699                              <1>         ;                         02H = 25 rows
  6700                              <1>         ;                         03H = 43 rows
  6701                              <1>         ; DL    (when BL=0) custom number of char rows on screen
  6702                              <1> 
  6703                              <1> 	; switch (BL) {
  6704                              <1> 	; case 0:
  6705                              <1> 	;    write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, DL-1);
  6706                              <1> 	;    break;
  6707 000032E2 20DB                <1> 	and	bl, bl
  6708 000032E4 7508                <1> 	jnz	short l_gfx_8_14c_1
  6709 000032E6 8815[A2690000]      <1> 	mov	[VGA_ROWS], dl  ; not DL-1 !
  6710 000032EC EB23                <1> 	jmp	short l_gfx_8_14c_4 	
  6711                              <1> l_gfx_8_14c_1:
  6712                              <1> 	; case 1:
  6713                              <1> 	;    write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 13);
  6714                              <1> 	;    break;
  6715 000032EE FECB                <1> 	dec	bl
  6716 000032F0 7509                <1> 	jnz	short l_gfx_8_14c_2
  6717                              <1> 	; bl = 1
  6718 000032F2 C605[A2690000]0E    <1> 	mov	byte [VGA_ROWS], 14  ; not 13 !
  6719 000032F9 EB16                <1> 	jmp	short l_gfx_8_14c_4 	
  6720                              <1> l_gfx_8_14c_2:
  6721 000032FB FECB                <1> 	dec	bl
  6722 000032FD 740B                <1> 	jz	short l_gfx_8_14c_3 ; bl = 2
  6723 000032FF FECB                <1> 	dec	bl
  6724 00003301 750E                <1> 	jnz	short l_gfx_8_14c_4 ; bl > 3
  6725                              <1> 	; bl = 3
  6726                              <1> 	; case 3:
  6727                              <1> 	;    write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 42);
  6728                              <1> 	;    break;
  6729 00003303 C605[A2690000]2B    <1> 	mov	byte [VGA_ROWS], 43  ; not 42 !
  6730                              <1> l_gfx_8_14c_3:
  6731                              <1>     	; case 2:
  6732                              <1>     	; default:
  6733                              <1> 	;    write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 24);
  6734                              <1> 	;    break;
  6735                              <1> 	; bl = 2 or bl > 3
  6736 0000330A C605[A2690000]19    <1> 	mov	byte [VGA_ROWS], 25  ; not 24 !	
  6737                              <1>     	; }
  6738                              <1> l_gfx_8_14c_4:
  6739                              <1>     	; write_byte(BIOSMEM_SEG, BIOSMEM_CHAR_HEIGHT, 14);
  6740 00003311 C605[9E690000]0E    <1>         mov     byte [CHAR_HEIGHT], 14
  6741                              <1> 	; }
  6742 00003318 C3                  <1> 	retn	
  6743                              <1> 
  6744                              <1> load_gfx_8_8_chars:
  6745                              <1> 	; 08/08/2016
  6746                              <1> 	; 10/07/2016
  6747                              <1> 	; Setup ROM 8x14 Font for Graphics Mode (VGA)
  6748                              <1> 	;
  6749                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  6750                              <1> 	; vgabios-0.7a (2011)
  6751                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  6752                              <1> 	; 'vgabios.c', 'biosfn_load_gfx_8_8_dd_chars'
  6753                              <1> 
  6754                              <1> 	; biosfn_load_gfx_8_8_dd_chars (BL)
  6755                              <1> 	; /* set 0x43 INT pointer */
  6756                              <1>     	; write_word(0x0, 0x43*4, &vgafont8);
  6757                              <1>     	; write_word(0x0, 0x43*4+2, 0xC000);
  6758 00003319 C705[82700100]-     <1> 	mov	dword [VGA_INT43H], vgafont8
  6758 0000331F [F8370100]          <1>
  6759                              <1> 		
  6760                              <1> 	; BL    screen rows code: 00H = user-specified (in DL)
  6761                              <1>         ;                         01H = 14 rows
  6762                              <1>         ;                         02H = 25 rows
  6763                              <1>         ;                         03H = 43 rows
  6764                              <1>         ; DL    (when BL=0) custom number of char rows on screen
  6765                              <1> 
  6766                              <1> 	; switch (BL) {
  6767                              <1> 	; case 0:
  6768                              <1> 	;    write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, DL-1);
  6769                              <1> 	;    break;
  6770 00003323 20DB                <1> 	and	bl, bl
  6771 00003325 7508                <1> 	jnz	short l_gfx_8_8c_1
  6772 00003327 8815[A2690000]      <1> 	mov	[VGA_ROWS], dl  ; not DL-1 !
  6773 0000332D EB23                <1> 	jmp	short l_gfx_8_8c_4 	
  6774                              <1> l_gfx_8_8c_1:
  6775                              <1> 	; case 1:
  6776                              <1> 	;    write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 13);
  6777                              <1> 	;    break;
  6778 0000332F FECB                <1> 	dec	bl
  6779 00003331 7509                <1> 	jnz	short l_gfx_8_8c_2
  6780                              <1> 	; bl = 1
  6781 00003333 C605[A2690000]0E    <1> 	mov	byte [VGA_ROWS], 14  ; not 13 !
  6782 0000333A EB16                <1> 	jmp	short l_gfx_8_8c_4 	
  6783                              <1> l_gfx_8_8c_2:
  6784 0000333C FECB                <1> 	dec	bl
  6785 0000333E 740B                <1> 	jz	short l_gfx_8_8c_3 ; bl = 2
  6786 00003340 FECB                <1> 	dec	bl
  6787 00003342 750E                <1> 	jnz	short l_gfx_8_8c_4 ; bl > 3
  6788                              <1> 	; bl = 3
  6789                              <1> 	; case 3:
  6790                              <1> 	;    write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 42);
  6791                              <1> 	;    break;
  6792 00003344 C605[A2690000]2B    <1> 	mov	byte [VGA_ROWS], 43  ; not 42 !
  6793                              <1> l_gfx_8_8c_3:
  6794                              <1>     	; case 2:
  6795                              <1>     	; default:
  6796                              <1> 	;    write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 24);
  6797                              <1> 	;    break;
  6798                              <1> 	; bl = 2 or bl > 3
  6799 0000334B C605[A2690000]19    <1> 	mov	byte [VGA_ROWS], 25  ; not 24 !	
  6800                              <1>     	; }
  6801                              <1> l_gfx_8_8c_4:
  6802                              <1>     	; write_byte(BIOSMEM_SEG, BIOSMEM_CHAR_HEIGHT, 8);
  6803 00003352 C605[9E690000]08    <1>         mov     byte [CHAR_HEIGHT], 8
  6804                              <1> 	; }
  6805 00003359 C3                  <1> 	retn
  6806                              <1> 
  6807                              <1> load_gfx_8_16_chars:
  6808                              <1> 	; 08/08/2016
  6809                              <1> 	; 10/07/2016
  6810                              <1> 	; Setup ROM 8x14 Font for Graphics Mode (VGA)
  6811                              <1> 	;
  6812                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  6813                              <1> 	; vgabios-0.7a (2011)
  6814                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  6815                              <1> 	; 'vgabios.c', 'biosfn_load_gfx_8_16_chars'
  6816                              <1> 
  6817                              <1> 	; biosfn_load_gfx_8_16_chars (BL)
  6818                              <1> 	; /* set 0x43 INT pointer */
  6819                              <1>     	; write_word(0x0, 0x43*4, &vgafont16);
  6820                              <1>     	; write_word(0x0, 0x43*4+2, 0xC000);
  6821 0000335A C705[82700100]-     <1> 	mov	dword [VGA_INT43H], vgafont16
  6821 00003360 [F84D0100]          <1>
  6822                              <1> 		
  6823                              <1> 	; BL    screen rows code: 00H = user-specified (in DL)
  6824                              <1>         ;                         01H = 14 rows
  6825                              <1>         ;                         02H = 25 rows
  6826                              <1>         ;                         03H = 43 rows
  6827                              <1>         ; DL    (when BL=0) custom number of char rows on screen
  6828                              <1> 
  6829                              <1> 	; switch (BL) {
  6830                              <1> 	; case 0:
  6831                              <1> 	;    write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, DL-1);
  6832                              <1> 	;    break;
  6833 00003364 20DB                <1> 	and	bl, bl
  6834 00003366 7508                <1> 	jnz	short l_gfx_8_16c_1
  6835 00003368 8815[A2690000]      <1> 	mov	[VGA_ROWS], dl  ; not DL-1 !
  6836 0000336E EB23                <1> 	jmp	short l_gfx_8_16c_4 	
  6837                              <1> l_gfx_8_16c_1:
  6838                              <1> 	; case 1:
  6839                              <1> 	;    write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 13);
  6840                              <1> 	;    break;
  6841 00003370 FECB                <1> 	dec	bl
  6842 00003372 7509                <1> 	jnz	short l_gfx_8_16c_2
  6843                              <1> 	; bl = 1
  6844 00003374 C605[A2690000]0E    <1> 	mov	byte [VGA_ROWS], 14  ; not 13 !
  6845 0000337B EB16                <1> 	jmp	short l_gfx_8_16c_4 	
  6846                              <1> l_gfx_8_16c_2:
  6847 0000337D FECB                <1> 	dec	bl
  6848 0000337F 740B                <1> 	jz	short l_gfx_8_16c_3 ; bl = 2
  6849 00003381 FECB                <1> 	dec	bl
  6850 00003383 750E                <1> 	jnz	short l_gfx_8_16c_4 ; bl > 3
  6851                              <1> 	; bl = 3
  6852                              <1> 	; case 3:
  6853                              <1> 	;    write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 42);
  6854                              <1> 	;    break;
  6855 00003385 C605[A2690000]2B    <1> 	mov	byte [VGA_ROWS], 43  ; not 42 !
  6856                              <1> l_gfx_8_16c_3:
  6857                              <1>     	; case 2:
  6858                              <1>     	; default:
  6859                              <1> 	;    write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, 24);
  6860                              <1> 	;    break;
  6861                              <1> 	; bl = 2 or bl > 3
  6862 0000338C C605[A2690000]19    <1> 	mov	byte [VGA_ROWS], 25  ; not 24 !	
  6863                              <1>     	; }
  6864                              <1> l_gfx_8_16c_4:
  6865                              <1>     	; write_byte(BIOSMEM_SEG, BIOSMEM_CHAR_HEIGHT, 16);
  6866 00003393 C605[9E690000]10    <1>         mov     byte [CHAR_HEIGHT], 16
  6867                              <1> 	; }
  6868 0000339A C3                  <1> 	retn
  6869                              <1> 			
  6870                              <1> get_font_info:
  6871                              <1> 	; 19/09/2016
  6872                              <1> 	; 08/08/2016
  6873                              <1> 	; 10/07/2016
  6874                              <1> 	; Get Current Character Generator Info (VGA)
  6875                              <1> 	;
  6876                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  6877                              <1> 	; vgabios-0.7a (2011)
  6878                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  6879                              <1> 	; 'vgabios.c', 'biosfn_get_font_info'
  6880                              <1> 
  6881                              <1> 	; Modified for TRDOS 386 !
  6882                              <1> 	;
  6883                              <1> 	; INPUT ->
  6884                              <1> 	;    AX = 1130h
  6885                              <1> 	;    BL = 0 -> Get info for current VGA font
  6886                              <1> 	;	       (BH = unused)
  6887                              <1> 	;    19/09/2016
  6888                              <1> 	;    BL > 0 -> Get requested character font data
  6889                              <1> 	;	 BL = 1 -> vgafont8
  6890                              <1> 	;        BL = 2 -> vgafont14
  6891                              <1> 	;	 BL = 3 -> vgafont16   
  6892                              <1> 	;	 BL > 3 -> Invalid function (for now!)
  6893                              <1> 	;	 BH = ASCII code of the first character
  6894                              <1> 	;	 ECX = Number of characters from the 1st char
  6895                              <1> 	;	 ECX >= 256 -> All (256-BH) characters
  6896                              <1> 	;	 ECX = 0 -> All characters (BH = unused)	
  6897                              <1> 	;        EDX = User's Buffer Address	
  6898                              <1> 	; OUTPUT ->
  6899                              <1> 	;    AL = height (scanlines), bytes per character
  6900                              <1> 	;    AH = screen rows
  6901                              <1> 	;    Byte 16-23 of EAX = number of columns
  6902                              <1> 	;    Byte 24-31 of EAX = 
  6903                              <1> 	;	  0 -> default font (not configured yet)
  6904                              <1> 	;	  0FFh -> user defined font
  6905                              <1> 	;	  14 = vgafont14
  6906                              <1> 	;	   8 = vgafont8
  6907                              <1> 	;	  16 = vgafont16
  6908                              <1> 	;   If BL input > 0 -> 
  6909                              <1> 	;       EAX = Actual transfer count
  6910                              <1> 	;
  6911 0000339B 20DB                <1> 	and	bl, bl
  6912 0000339D 7408                <1> 	jz	short gfi_0
  6913                              <1> 	; invalid function (input)
  6914 0000339F 80FB03              <1> 	cmp	bl, 3
  6915 000033A2 7642                <1> 	jna	short gfi_4
  6916 000033A4 31C0                <1> 	xor	eax, eax ; 0
  6917 000033A6 C3                  <1> 	retn
  6918                              <1> gfi_0:
  6919 000033A7 A0[9E690000]        <1> 	mov	al, [CHAR_HEIGHT]
  6920 000033AC 8A25[A2690000]      <1> 	mov	ah, [VGA_ROWS]
  6921 000033B2 C1E010              <1> 	shl	eax, 16
  6922 000033B5 A0[9C690000]        <1> 	mov	al, [CRT_COLS]
  6923 000033BA 8B0D[82700100]      <1> 	mov	ecx, [VGA_INT43H]
  6924 000033C0 21C9                <1> 	and	ecx, ecx
  6925 000033C2 741E                <1> 	jz	short gfi_2 ; 0 = default font
  6926 000033C4 41                  <1> 	inc	ecx ; 0FFFFFFFFh -> 0 (user defined font)
  6927 000033C5 7504                <1> 	jnz	short gfi_1
  6928 000033C7 FECC                <1> 	dec	ah ; 0FFh
  6929 000033C9 EB17                <1> 	jmp	short gfi_2
  6930                              <1> gfi_1:
  6931 000033CB 49                  <1> 	dec	ecx ; 08/08/2016
  6932 000033CC B40E                <1> 	mov	ah, 14
  6933 000033CE 81F9[F83F0100]      <1> 	cmp	ecx, vgafont14
  6934 000033D4 740C                <1> 	je	short gfi_2
  6935 000033D6 B408                <1> 	mov	ah, 8
  6936 000033D8 81F9[F8370100]      <1> 	cmp	ecx, vgafont8
  6937 000033DE 7402                <1> 	je	short gfi_2
  6938                              <1> 	; vgafont16
  6939 000033E0 D0E4                <1> 	shl	ah, 1 ; ah = 16
  6940                              <1> gfi_2:
  6941 000033E2 C1C010              <1> 	rol	eax, 16
  6942                              <1> gfi_3:
  6943 000033E5 C3                  <1> 	retn
  6944                              <1> gfi_4:
  6945 000033E6 89D7                <1> 	mov	edi, edx ; **
  6946 000033E8 80FB02              <1> 	cmp	bl, 2
  6947 000033EB 720B                <1> 	jb	short gfi_5
  6948 000033ED 772F                <1> 	ja	short gfi_7
  6949                              <1> 	;BL = 2 -> vgafont14
  6950 000033EF BE[F83F0100]        <1> 	mov	esi, vgafont14 ; *
  6951 000033F4 B30E                <1> 	mov	bl, 14
  6952 000033F6 EB07                <1> 	jmp	short gfi_6 
  6953                              <1> gfi_5:
  6954                              <1> 	;BL = 1 -> vgafont8
  6955 000033F8 BE[F8370100]        <1> 	mov	esi, vgafont8 ; *
  6956 000033FD B308                <1> 	mov	bl, 8
  6957                              <1> gfi_6:
  6958 000033FF 09C9                <1> 	or	ecx, ecx
  6959 00003401 7424                <1> 	jz	short gfi_8 ; all chars from the 00h
  6960 00003403 88F8                <1> 	mov	al, bh ; character index
  6961 00003405 F6E3                <1> 	mul	bl ; char index * char height/size
  6962 00003407 0FB7D0              <1> 	movzx	edx, ax
  6963 0000340A 01D6                <1> 	add	esi, edx ; *
  6964 0000340C 66BAFF00            <1> 	mov	dx, 255
  6965 00003410 28FA                <1> 	sub	dl, bh
  6966 00003412 6642                <1> 	inc	dx	
  6967 00003414 39D1                <1> 	cmp	ecx, edx
  6968 00003416 770F                <1> 	ja	short gfi_8
  6969 00003418 7412                <1> 	je	short gfi_9
  6970 0000341A 89D1                <1> 	mov	ecx, edx
  6971 0000341C EB0E                <1> 	jmp	short gfi_9
  6972                              <1> gfi_7:
  6973                              <1> 	;BL = 3 -> vgafont16
  6974 0000341E BE[F84D0100]        <1> 	mov	esi, vgafont16 ; *
  6975 00003423 B310                <1> 	mov	bl, 16
  6976 00003425 EBD8                <1> 	jmp	short gfi_6
  6977                              <1> gfi_8:
  6978 00003427 B900010000          <1> 	mov	ecx, 256
  6979                              <1> gfi_9:
  6980 0000342C 6689C8              <1> 	mov	ax, cx ; character count
  6981 0000342F 30FF                <1> 	xor	bh, bh
  6982 00003431 66F7E3              <1> 	mul	bx ; char count * char height/size	
  6983 00003434 6689C1              <1>  	mov	cx, ax
  6984                              <1> 
  6985                              <1> 	; ESI = source address in system space
  6986                              <1> 	; EDI = user's buffer address
  6987                              <1> 	; ECX = transfer (byte) count
  6988 00003437 E855BE0000          <1> 	call	transfer_to_user_buffer
  6989 0000343C 89C8                <1> 	mov	eax, ecx ; actual transfer count
  6990 0000343E C3                  <1> 	retn
  6991                              <1> 	
  6992                              <1> vga_pal_funcs:
  6993                              <1> 	; 10/08/2016
  6994                              <1> 	; VGA Palette functions
  6995                              <1> 	;
  6996                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
  6997                              <1> 	; vgabios-0.7a (2011)
  6998                              <1> 	; by the LGPL VGABios developers Team (2001-2008)
  6999                              <1> 	; 'vgabios.c', 'vgarom.asm'
  7000                              <1> 
  7001 0000343F 3C00                <1> 	cmp	al, 0
  7002 00003441 0F848F000000        <1>         je      set_single_palette_reg
  7003                              <1> vga_palf_1001:
  7004 00003447 3C01                <1> 	cmp	al, 1
  7005 00003449 0F84B4000000        <1>         je      set_overscan_border_color
  7006                              <1> vga_palf_1002:
  7007 0000344F 3C02                <1> 	cmp	al, 2
  7008 00003451 0F84B0000000        <1>         je      set_all_palette_reg
  7009                              <1> vga_palf_1003:
  7010 00003457 3C03                <1> 	cmp	al, 3
  7011 00003459 0F84E8000000        <1>         je      toggle_intensity
  7012                              <1> vga_palf_1007:
  7013 0000345F 3C07                <1> 	cmp	al, 7
  7014 00003461 0F840D010000        <1>         je      get_single_palette_reg
  7015 00003467 7266                <1> 	jb	short vga_palf_unknown
  7016                              <1> vga_palf_1008:
  7017 00003469 3C08                <1> 	cmp	al, 8
  7018 0000346B 0F8437010000        <1>         je      read_overscan_border_color
  7019                              <1> vga_palf_1009:
  7020 00003471 3C09                <1> 	cmp	al, 9
  7021 00003473 0F8433010000        <1> 	je	get_all_palette_reg
  7022                              <1> vga_palf_1010:
  7023 00003479 3C10                <1> 	cmp	al, 10h
  7024 0000347B 0F8487010000        <1> 	je 	set_single_dac_reg
  7025 00003481 724C                <1> 	jb	short vga_palf_unknown
  7026                              <1> vga_palf_1012:
  7027 00003483 3C12                <1> 	cmp	al, 12h
  7028 00003485 0F8498010000        <1>         je      set_all_dac_reg
  7029 0000348B 7242                <1> 	jb	short vga_palf_unknown
  7030                              <1> vga_palf_1013:
  7031 0000348D 3C13                <1> 	cmp	al, 13h
  7032 0000348F 0F84CC010000        <1>         je      select_video_dac_color_page
  7033                              <1> vga_palf_1015:
  7034 00003495 3C15                <1> 	cmp	al, 15h
  7035 00003497 0F8412020000        <1> 	je	read_single_dac_reg
  7036 0000349D 7230                <1> 	jb	short vga_palf_unknown
  7037                              <1> vga_palf_1017:
  7038 0000349F 3C17                <1> 	cmp	al, 17h
  7039 000034A1 0F8428020000        <1>         je      read_all_dac_reg
  7040 000034A7 7226                <1> 	jb	short vga_palf_unknown
  7041                              <1> vga_palf_1018:
  7042 000034A9 3C18                <1> 	cmp	al, 18h
  7043 000034AB 0F845E020000        <1>         je      set_pel_mask
  7044                              <1> vga_palf_1019:
  7045 000034B1 3C19                <1> 	cmp	al, 19h
  7046 000034B3 0F8462020000        <1>         je      read_pel_mask
  7047                              <1> vga_palf_101A:
  7048 000034B9 3C1A                <1> 	cmp	al, 1Ah
  7049 000034BB 0F8468020000        <1>         je      read_video_dac_state
  7050                              <1> vga_palf_101B:
  7051 000034C1 3C1B                <1> 	cmp	al, 1Bh
  7052                              <1> 	;jne	short vga_palf_unknown
  7053 000034C3 770A                <1> 	ja	short vga_palf_unknown
  7054                              <1>  
  7055 000034C5 E80EF7FFFF          <1> 	call	gray_scale_summing
  7056 000034CA E988E5FFFF          <1>         jmp     VIDEO_RETURN 	
  7057                              <1> 
  7058                              <1> vga_palf_unknown:
  7059 000034CF 29C0                <1> 	sub	eax, eax ; 0 = invalid function
  7060 000034D1 E986E5FFFF          <1>         jmp     _video_return
  7061                              <1> 
  7062                              <1> set_single_palette_reg:
  7063                              <1> 	; 10/08/2016
  7064                              <1> 	; Set One Palette Register
  7065                              <1> 	; BL = register number to set
  7066                              <1> 	;     (a 4-bit attribute nibble: 00h-0Fh)
  7067                              <1> 	; BH = 6-bit RGB color to display 
  7068                              <1> 	;      for that attribute
  7069                              <1> 
  7070 000034D6 80FB14              <1> 	cmp	bl, 14h
  7071                              <1> 	;ja	short no_actl_reg1
  7072 000034D9 0F8778E5FFFF        <1> 	ja	VIDEO_RETURN
  7073 000034DF 6650                <1> 	push	ax
  7074 000034E1 6652                <1> 	push	dx
  7075 000034E3 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7076 000034E7 EC                  <1> 	in	al, dx
  7077 000034E8 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  7078 000034EC 88D8                <1> 	mov	al, bl
  7079 000034EE EE                  <1> 	out	dx, al
  7080 000034EF 88F8                <1> 	mov	al, bh
  7081 000034F1 EE                  <1> 	out	dx, al
  7082 000034F2 B020                <1> 	mov	al, 20h
  7083 000034F4 EE                  <1> 	out	dx, al
  7084                              <1> 	; ifdef VBOX
  7085 000034F5 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7086 000034F9 EC                  <1> 	in	al, dx
  7087                              <1> 	; endif ; VBOX
  7088 000034FA 665A                <1> 	pop	dx
  7089 000034FC 6658                <1> 	pop	ax
  7090                              <1> ;no_actl_reg1:
  7091 000034FE E954E5FFFF          <1> 	jmp	VIDEO_RETURN
  7092                              <1> 
  7093                              <1> set_overscan_border_color:
  7094                              <1> 	; 10/08/2016
  7095                              <1> 	; Set Overscan/Border Color Register
  7096                              <1> 	; BH = 6-bit RGB color to display 
  7097                              <1> 	;      for that attribute
  7098                              <1> 	
  7099 00003503 B311                <1> 	mov	bl, 11h
  7100 00003505 EBCF                <1>   	jmp	short set_single_palette_reg
  7101                              <1> 
  7102                              <1> set_all_palette_reg:
  7103                              <1> 	; 10/08/2016
  7104                              <1> 	; Set All Palette Registers and Overscan
  7105                              <1> 	; EDX = Address of 17 bytes; 
  7106                              <1> 	; an rgbRGB value for each of 16 palette
  7107                              <1> 	; registers plus one for the border.
  7108                              <1> 
  7109 00003507 89D6                <1> 	mov	esi, edx ; user buffer
  7110 00003509 B911000000          <1> 	mov	ecx, 17
  7111 0000350E 89E7                <1> 	mov	edi, esp
  7112 00003510 83EC14              <1> 	sub	esp, 20	 	 
  7113 00003513 E8C3BD0000          <1> 	call	transfer_from_user_buffer
  7114                              <1> 	;jc	VIDEO_RETURN
  7115                              <1> 
  7116 00003518 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7117 0000351C EC                  <1> 	in	al, dx
  7118 0000351D B100                <1> 	mov	cl, 0
  7119 0000351F 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  7120                              <1> set_palette_loop:
  7121 00003523 88C8                <1> 	mov	al, cl
  7122 00003525 EE                  <1> 	out	dx, al
  7123 00003526 8A07                <1> 	mov	al, [edi]
  7124 00003528 EE                  <1> 	out	dx, al
  7125 00003529 47                  <1> 	inc	edi
  7126 0000352A FEC1                <1> 	inc	cl
  7127 0000352C 80F910              <1> 	cmp	cl, 10h
  7128 0000352F 75F2                <1> 	jne	short set_palette_loop
  7129 00003531 B011                <1> 	mov	al, 11h
  7130 00003533 EE                  <1> 	out	dx, al
  7131 00003534 8A07                <1> 	mov	al, [edi]
  7132 00003536 EE                  <1> 	out	dx, al
  7133 00003537 B020                <1> 	mov	al, 20h
  7134 00003539 EE                  <1> 	out	dx, al
  7135                              <1> 	; ifdef VBOX
  7136 0000353A 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7137 0000353E EC                  <1> 	in	al, dx
  7138                              <1> 	; endif ; VBOX
  7139 0000353F 83C414              <1> 	add	esp, 20
  7140 00003542 E910E5FFFF          <1> 	jmp	VIDEO_RETURN
  7141                              <1> 
  7142                              <1> toggle_intensity:
  7143                              <1> 	; 10/08/2016
  7144                              <1> 	; Select Foreground Blink or Bold Background
  7145                              <1> 	; BL = 00h = enable bold backgrounds
  7146                              <1> 	;	    (16 background colors)
  7147                              <1>         ;      01h = enable blinking foreground
  7148                              <1> 	;	    (8 background colors)
  7149                              <1> 
  7150 00003547 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7151 0000354B EC                  <1> 	in	al, dx
  7152 0000354C 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  7153 00003550 B010                <1> 	mov	al, 10h
  7154 00003552 EE                  <1> 	out	dx, al
  7155 00003553 66BAC103            <1> 	mov	dx, 3C1h ; VGAREG_ACTL_READ_DATA
  7156 00003557 EC                  <1> 	in	al, dx
  7157 00003558 24F7                <1> 	and	al, 0F7h
  7158 0000355A 80E301              <1> 	and	bl, 01h
  7159 0000355D C0E303              <1> 	shl	bl, 3
  7160 00003560 08D8                <1> 	or	al, bl
  7161 00003562 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  7162 00003566 EE                  <1> 	out	dx, al
  7163 00003567 B020                <1> 	mov	al, 20h
  7164 00003569 EE                  <1> 	out	dx, al
  7165                              <1> 	; ifdef VBOX
  7166 0000356A 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7167 0000356E EC                  <1> 	in	al, dx
  7168                              <1> 	; endif ; VBOX
  7169 0000356F E9E3E4FFFF          <1> 	jmp	VIDEO_RETURN
  7170                              <1> 
  7171                              <1> get_single_palette_reg:
  7172                              <1> 	; 10/08/2016
  7173                              <1> 	; Read One Palette Register
  7174                              <1>         ; INPUT:
  7175                              <1> 	; BL = Palette register to read (00h-0Fh)
  7176                              <1> 	; OUTPUT:
  7177                              <1> 	; BH = Current rgbRGB value of specified register
  7178                              <1> 	;      for that attribute
  7179                              <1> 
  7180 00003574 80FB14              <1> 	cmp	bl, 14h
  7181                              <1> 	;ja	short no_actl_reg2
  7182 00003577 0F87DAE4FFFF        <1> 	ja	VIDEO_RETURN
  7183                              <1> 
  7184 0000357D 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7185 00003581 EC                  <1> 	in	al, dx
  7186 00003582 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  7187 00003586 88D8                <1> 	mov	al, bl
  7188 00003588 EE                  <1> 	out	dx, al
  7189 00003589 66BAC103            <1> 	mov	dx, 3C1h ; VGAREG_ACTL_READ_DATA
  7190 0000358D EC                  <1> 	in	al, dx
  7191 0000358E 8844240D            <1> 	mov	[esp+13], al ; bh
  7192 00003592 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7193 00003596 EC                  <1> 	in	al, dx
  7194 00003597 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  7195 0000359B B020                <1> 	mov	al, 20h
  7196 0000359D EE                  <1> 	out	dx, al
  7197                              <1> 	; ifdef VBOX
  7198 0000359E 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7199 000035A2 EC                  <1> 	in	al, dx
  7200                              <1> 	; endif ; VBOX
  7201 000035A3 E9AFE4FFFF          <1> 	jmp	VIDEO_RETURN
  7202                              <1> 
  7203                              <1> read_overscan_border_color:
  7204                              <1> 	; 10/08/2016
  7205                              <1> 	; Read Overscan Register
  7206                              <1> 	; OUTPUT:
  7207                              <1> 	; BH = current rgbRGB value 
  7208                              <1> 	;      of the overscan/border register
  7209                              <1> 
  7210 000035A8 B311                <1> 	mov	bl, 11h
  7211 000035AA EBC8                <1> 	jmp	short get_single_palette_reg
  7212                              <1> 
  7213                              <1> get_all_palette_reg:
  7214                              <1> 	; 10/08/2016
  7215                              <1> 	; Read All Palette Registers
  7216                              <1> 	; EDX = Address of 17-byte buffer 
  7217                              <1> 	;	to receive data
  7218                              <1> 	
  7219 000035AC 89D7                <1> 	mov	edi, edx
  7220 000035AE 89E3                <1> 	mov	ebx, esp
  7221 000035B0 89DE                <1> 	mov	esi, ebx
  7222 000035B2 83EC14              <1> 	sub	esp, 20	 
  7223                              <1> 
  7224 000035B5 B100                <1> 	mov	cl, 0
  7225                              <1> get_palette_loop:
  7226 000035B7 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7227 000035BB EC                  <1> 	in	al, dx
  7228 000035BC 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  7229 000035C0 88C8                <1> 	mov	al, cl
  7230 000035C2 EE                  <1> 	out	dx, al
  7231 000035C3 66BAC103            <1> 	mov	dx, 3C1h ; VGAREG_ACTL_READ_DATA
  7232 000035C7 EC                  <1> 	in	al, dx
  7233 000035C8 8803                <1> 	mov	[ebx], al
  7234 000035CA 43                  <1> 	inc	ebx
  7235 000035CB FEC1                <1> 	inc	cl
  7236 000035CD 80F910              <1> 	cmp	cl, 10h
  7237 000035D0 75E5                <1> 	jne	short get_palette_loop
  7238 000035D2 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7239 000035D6 EC                  <1> 	in	al, dx
  7240 000035D7 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  7241 000035DB B011                <1> 	mov	al, 11h
  7242 000035DD EE                  <1> 	out	dx, al
  7243 000035DE 66BAC103            <1> 	mov	dx, 3C1h ; VGAREG_ACTL_READ_DATA
  7244 000035E2 EC                  <1> 	in	al, dx
  7245 000035E3 8803                <1> 	mov	[ebx], al
  7246 000035E5 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7247 000035E9 EC                  <1> 	in	al, dx
  7248 000035EA 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  7249 000035EE B020                <1> 	mov	al, 20h
  7250 000035F0 EE                  <1> 	out	dx, al
  7251                              <1> 	; ifdef VBOX
  7252 000035F1 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7253 000035F5 EC                  <1> 	in	al, dx
  7254                              <1> 	; endif ; VBOX
  7255                              <1> 
  7256 000035F6 B911000000          <1> 	mov	ecx, 17 ; transfer (byte) count
  7257                              <1> 	; ESI = source address in system space
  7258                              <1> 	; EDI = user's buffer address
  7259 000035FB E891BC0000          <1> 	call	transfer_to_user_buffer
  7260                              <1> 
  7261 00003600 83C414              <1> 	add	esp, 20
  7262 00003603 E94FE4FFFF          <1> 	jmp	VIDEO_RETURN
  7263                              <1> 
  7264                              <1> set_single_dac_reg:
  7265                              <1> 	; 10/08/2016
  7266                              <1> 	; Set One DAC Color Register
  7267                              <1> 	; BX = color register to set (0-255)
  7268                              <1>         ; CH = green value (00h-3Fh)
  7269                              <1>         ; CL = blue value  (00h-3Fh)
  7270                              <1>         ; DH = red value   (00h-3Fh)
  7271                              <1> 
  7272 00003608 6652                <1> 	push	dx
  7273 0000360A 66BAC803            <1> 	mov	dx, 3C8h ; VGAREG_DAC_WRITE_ADDRESS
  7274 0000360E 88D8                <1> 	mov	al, bl
  7275 00003610 EE                  <1> 	out	dx, al
  7276                              <1> 	;mov	dx, 3C9h ; VGAREG_DAC_DATA
  7277 00003611 6642                <1> 	inc	dx
  7278 00003613 6658                <1> 	pop	ax
  7279 00003615 88E0                <1> 	mov	al, ah
  7280 00003617 EE                  <1> 	out	dx, al
  7281 00003618 88E8                <1> 	mov	al, ch
  7282 0000361A EE                  <1> 	out	dx, al
  7283 0000361B 88C8                <1> 	mov	al, cl
  7284 0000361D EE                  <1> 	out	dx, al
  7285 0000361E E934E4FFFF          <1> 	jmp	VIDEO_RETURN
  7286                              <1> 
  7287                              <1> set_all_dac_reg:
  7288                              <1> 	; 12/08/2016
  7289                              <1> 	; 11/08/2016
  7290                              <1> 	; 10/08/2016
  7291                              <1> 	; Set a Block of DAC Color Register
  7292                              <1> 	; BX = first DAC register to set (0-00FFh)
  7293                              <1> 	; ECX = number of registers to set (0-00FFh)
  7294                              <1> 	; EDX = addr of a table of R,G,B values 
  7295                              <1> 	;	(it will be CX*3 bytes long)
  7296                              <1> 
  7297 00003623 89D6                <1> 	mov	esi, edx ; user buffer
  7298 00003625 89CA                <1> 	mov	edx, ecx
  7299 00003627 66D1E1              <1> 	shl	cx, 1 ; *2
  7300 0000362A 01D1                <1> 	add	ecx, edx ; ecx = 3*ecx
  7301 0000362C 89E5                <1> 	mov	ebp, esp
  7302 0000362E 89EF                <1> 	mov	edi, ebp
  7303 00003630 29CF                <1> 	sub	edi, ecx
  7304 00003632 6683E7FC            <1> 	and	di, 0FFFCh ; (dword alignment)
  7305 00003636 89FC                <1> 	mov	esp, edi
  7306 00003638 E89EBC0000          <1> 	call	transfer_from_user_buffer
  7307                              <1> 	;jc	VIDEO_RETURN
  7308                              <1> 
  7309 0000363D 89D1                <1> 	mov	ecx, edx
  7310 0000363F 66BAC803            <1> 	mov	dx, 3C8h ; VGAREG_DAC_WRITE_ADDRESS
  7311 00003643 88D8                <1> 	mov	al, bl
  7312 00003645 EE                  <1> 	out	dx, al
  7313 00003646 66BAC903            <1> 	mov	dx, 3C9h ; VGAREG_DAC_DATA
  7314                              <1> set_dac_loop:
  7315 0000364A 8A07                <1> 	mov	al, [edi]
  7316 0000364C EE                  <1> 	out	dx, al
  7317 0000364D 47                  <1> 	inc	edi
  7318 0000364E 8A07                <1> 	mov	al, [edi]
  7319 00003650 EE                  <1> 	out	dx, al
  7320 00003651 47                  <1> 	inc	edi
  7321 00003652 8A07                <1> 	mov	al, [edi]
  7322 00003654 EE                  <1> 	out	dx, al
  7323 00003655 47                  <1> 	inc	edi
  7324 00003656 6649                <1> 	dec	cx
  7325 00003658 75F0                <1> 	jnz	short set_dac_loop
  7326 0000365A 89EC                <1> 	mov	esp, ebp
  7327 0000365C E9F6E3FFFF          <1> 	jmp	VIDEO_RETURN
  7328                              <1> 
  7329                              <1> select_video_dac_color_page:
  7330                              <1> 	; 10/08/2016
  7331                              <1> 	; DAC Color Paging Functions
  7332                              <1> 	; BL = 00H = select color paging mode
  7333                              <1>         ;       BH = paging mode
  7334                              <1>         ;            00h = 4 blocks of 64 registers
  7335                              <1>         ;            01h = 16 blocks of 16 registers
  7336                              <1> 	; BL = 01H = activate color page
  7337                              <1>         ;       BH = DAC color page number
  7338                              <1>         ;            00h-03h (4-page/64-reg mode)
  7339                              <1>         ;            00h-0Fh (16-page/16-reg mode)
  7340                              <1> 
  7341 00003661 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7342 00003665 EC                  <1> 	in	al, dx
  7343 00003666 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  7344 0000366A B010                <1> 	mov	al, 10h
  7345 0000366C EE                  <1> 	out	dx, al
  7346 0000366D 66BAC103            <1> 	mov	dx, 3C1h ; VGAREG_ACTL_READ_DATA
  7347 00003671 EC                  <1> 	in	al, dx
  7348 00003672 80E301              <1> 	and	bl, 01h
  7349 00003675 750E                <1> 	jnz	short set_dac_page
  7350 00003677 247F                <1> 	and	al, 07Fh
  7351 00003679 C0E707              <1> 	shl	bh, 7
  7352 0000367C 08F8                <1> 	or	al, bh
  7353 0000367E 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  7354 00003682 EE                  <1> 	out	dx, al
  7355 00003683 EB1D                <1> 	jmp	short set_actl_normal
  7356                              <1> set_dac_page:
  7357 00003685 6650                <1> 	push	ax
  7358 00003687 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7359 0000368B EC                  <1> 	in	al, dx
  7360 0000368C 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  7361 00003690 B014                <1> 	mov	al, 14h
  7362 00003692 EE                  <1> 	out	dx, al
  7363 00003693 6658                <1> 	pop	ax
  7364 00003695 2480                <1> 	and	al, 80h
  7365 00003697 7503                <1> 	jnz	short set_dac_16_page
  7366 00003699 C0E702              <1> 	shl	bh, 2
  7367                              <1> set_dac_16_page:
  7368 0000369C 80E70F              <1> 	and	bh, 0Fh
  7369 0000369F 88F8                <1> 	mov	al, bh
  7370 000036A1 EE                  <1> 	out	dx, al
  7371                              <1> set_actl_normal:
  7372 000036A2 B020                <1> 	mov	al, 20h
  7373 000036A4 EE                  <1> 	out	dx, al
  7374                              <1> 	; ifdef VBOX
  7375 000036A5 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7376 000036A9 EC                  <1> 	in	al, dx
  7377                              <1> 	; endif ; VBOX
  7378 000036AA E9A8E3FFFF          <1> 	jmp	VIDEO_RETURN	
  7379                              <1> 
  7380                              <1> read_single_dac_reg:
  7381                              <1> 	; 10/08/2016
  7382                              <1> 	; Read One DAC Color Register
  7383                              <1> 	; INPUT:
  7384                              <1> 	; BX = color register to read (0-255)
  7385                              <1> 	; OUTPUT:
  7386                              <1> 	; CH = green value (00h-3Fh)
  7387                              <1>         ; CL = blue value  (00h-3Fh)
  7388                              <1>         ; DH = red value   (00h-3Fh)
  7389                              <1> 
  7390 000036AF 66BAC703            <1> 	mov	dx, 3C7h ; VGAREG_DAC_READ_ADDRESS
  7391 000036B3 88D8                <1> 	mov	al, bl
  7392 000036B5 EE                  <1> 	out	dx, al
  7393 000036B6 66BAC903            <1> 	mov	dx, 3C9h ; VGAREG_DAC_DATA
  7394 000036BA EC                  <1> 	in	al, dx
  7395 000036BB 88442415            <1> 	mov	[esp+21], al ; dh
  7396 000036BF EC                  <1> 	in	al, dx
  7397 000036C0 88C5                <1> 	mov	ch, al
  7398 000036C2 EC                  <1> 	in	al, dx
  7399 000036C3 88C1                <1> 	mov	cl, al
  7400 000036C5 66894C2410          <1> 	mov	[esp+16], cx ; cx
  7401 000036CA E988E3FFFF          <1> 	jmp	VIDEO_RETURN	
  7402                              <1> 
  7403                              <1> read_all_dac_reg:
  7404                              <1> 	; 12/08/2016
  7405                              <1> 	; 11/08/2016
  7406                              <1> 	; 10/08/2016
  7407                              <1> 	; Read a Block of DAC Color Registers
  7408                              <1>         ; BX = first DAC register to read (0-00FFh)
  7409                              <1>         ; ECX = number of registers to read (0-00FFh)
  7410                              <1>         ; EDX = addr of a buffer to hold R,G,B values
  7411                              <1> 	;	(CX*3 bytes long)
  7412                              <1> 
  7413 000036CF 89D7                <1> 	mov	edi, edx ; user buffer
  7414 000036D1 89CA                <1> 	mov	edx, ecx
  7415 000036D3 66D1E2              <1> 	shl	dx, 1 ; *2
  7416 000036D6 01CA                <1> 	add	edx, ecx ; edx = 3*ecx
  7417 000036D8 89E5                <1> 	mov	ebp, esp
  7418 000036DA 89EE                <1> 	mov	esi, ebp
  7419 000036DC 29D6                <1> 	sub	esi, edx
  7420 000036DE 6683E6FC            <1> 	and	si, 0FFFCh ; (dword alignment)
  7421 000036E2 89F4                <1> 	mov	esp, esi
  7422 000036E4 52                  <1> 	push	edx ; 3*ecx
  7423 000036E5 66BAC703            <1> 	mov	dx, 3C7h ; VGAREG_DAC_READ_ADDRESS
  7424 000036E9 88D8                <1> 	mov	al, bl
  7425 000036EB EE                  <1> 	out	dx, al
  7426 000036EC 66BAC903            <1> 	mov	dx, 3C9h ; VGAREG_DAC_DATA
  7427 000036F0 89F3                <1> 	mov	ebx, esi
  7428                              <1> read_dac_loop:
  7429 000036F2 EC                  <1> 	in	al, dx
  7430 000036F3 8803                <1> 	mov	[ebx], al
  7431 000036F5 43                  <1> 	inc	ebx
  7432 000036F6 EC                  <1> 	in	al, dx
  7433 000036F7 8803                <1> 	mov	[ebx], al
  7434 000036F9 43                  <1> 	inc	ebx
  7435 000036FA EC                  <1> 	in	al, dx
  7436 000036FB 8803                <1> 	mov	[ebx], al
  7437 000036FD 43                  <1> 	inc	ebx
  7438 000036FE 6649                <1> 	dec	cx
  7439 00003700 75F0                <1> 	jnz	short read_dac_loop
  7440 00003702 59                  <1> 	pop	ecx ; 3*ecx
  7441                              <1> 	; ECX = transfer (byte) count
  7442                              <1> 	; ESI = source address in system space
  7443                              <1> 	; EDI = user's buffer address
  7444 00003703 E889BB0000          <1> 	call	transfer_to_user_buffer
  7445 00003708 89EC                <1> 	mov	esp, ebp
  7446 0000370A E948E3FFFF          <1> 	jmp	VIDEO_RETURN
  7447                              <1> 
  7448                              <1> set_pel_mask:
  7449                              <1> 	; 10/08/2016
  7450                              <1> 	; BL = mask value
  7451 0000370F 66BAC603            <1> 	mov	dx, 3C6h ; VGAREG_PEL_MASK
  7452 00003713 88D8                <1> 	mov	al, bl
  7453 00003715 EE                  <1> 	out	dx, al
  7454 00003716 E93CE3FFFF          <1> 	jmp	VIDEO_RETURN
  7455                              <1> 
  7456                              <1> read_pel_mask:
  7457                              <1> 	; 10/08/2016
  7458                              <1> 	; Output: BL = mask value 
  7459 0000371B 66BAC603            <1> 	mov	dx, 3C6h ; VGAREG_PEL_MASK
  7460 0000371F EC                  <1> 	in	al, dx
  7461 00003720 8844240C            <1> 	mov	[esp+12], al ; bl
  7462 00003724 E92EE3FFFF          <1> 	jmp	VIDEO_RETURN
  7463                              <1> 
  7464                              <1> read_video_dac_state:
  7465                              <1> 	; 10/08/2016
  7466                              <1> 	; Query DAC Color Paging State
  7467                              <1> 	; Output:
  7468                              <1> 	; BH = current active DAC color page
  7469                              <1>         ; BL = current active DAC paging mode
  7470                              <1> 
  7471 00003729 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7472 0000372D EC                  <1> 	in	al, dx
  7473 0000372E 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  7474 00003732 B010                <1> 	mov	al, 10h
  7475 00003734 EE                  <1> 	out	dx, al
  7476 00003735 66BAC103            <1> 	mov	dx, 3C1h ; VGAREG_ACTL_READ_DATA
  7477 00003739 EC                  <1> 	in	al, dx
  7478 0000373A 88C3                <1> 	mov	bl, al
  7479 0000373C C0EB07              <1> 	shr	bl, 7
  7480 0000373F 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7481 00003743 EC                  <1> 	in	al, dx
  7482 00003744 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  7483 00003748 B014                <1> 	mov	al, 14h
  7484 0000374A EE                  <1> 	out	dx, al
  7485 0000374B 66BAC103            <1> 	mov	dx, 3C1h ; VGAREG_ACTL_READ_DATA
  7486 0000374F EC                  <1> 	in	al, dx
  7487 00003750 88C7                <1> 	mov	bh, al
  7488 00003752 80E70F              <1> 	and	bh, 0Fh
  7489 00003755 F6C301              <1> 	test	bl, 01
  7490 00003758 7503                <1> 	jnz	short get_dac_16_page
  7491 0000375A C0EF02              <1> 	shr	bh, 2
  7492                              <1> get_dac_16_page:
  7493 0000375D 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7494 00003761 EC                  <1> 	in	al, dx
  7495 00003762 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  7496 00003766 B020                <1> 	mov	al, 20h
  7497 00003768 EE                  <1> 	out	dx, al
  7498                              <1> 	; ifdef VBOX
  7499 00003769 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  7500 0000376D EC                  <1> 	in	al, dx
  7501                              <1> 	; endif ; VBOX 
  7502 0000376E 66895C240C          <1> 	mov	[esp+12], bx ; bx
  7503 00003773 E9DFE2FFFF          <1> 	jmp	VIDEO_RETURN
  7504                              <1> 
  7505                              <1> ; 23/11/2020 - TRDOS 386 v2.0.3
  7506                              <1> ; VBE 2 BOCHS/QEMU emulator extensions 
  7507                              <1> ;	for TRDOS 386 v2 kernel (video bios)  
  7508                              <1> 
  7509                              <1> ; BOCH/QEMU VBE2 VGA BIOS code 
  7510                              <1> ;	by Jeroen Janssen (2002)
  7511                              <1> ;	by Volker Rupper (2003-2020)
  7512                              <1> ; vbe.c (02/01/2020) 
  7513                              <1> 
  7514                              <1> ; vbe.h (02/01/2020)
  7515                              <1> 
  7516                              <1> VBE_DISPI_BANK_ADDRESS	equ	0A0000h
  7517                              <1> VBE_DISPI_BANK_SIZE_KB	equ	64
  7518                              <1> 
  7519                              <1> VBE_DISPI_MAX_XRES	equ	2560
  7520                              <1> VBE_DISPI_MAX_YRES	equ	1600
  7521                              <1> 
  7522                              <1> VBE_DISPI_IOPORT_INDEX	equ	01CEh
  7523                              <1> VBE_DISPI_IOPORT_DATA	equ	01CFh
  7524                              <1> 
  7525                              <1> VBE_DISPI_INDEX_ID	equ	00h
  7526                              <1> VBE_DISPI_INDEX_XRES	equ	01h
  7527                              <1> VBE_DISPI_INDEX_YRES	equ	02h
  7528                              <1> VBE_DISPI_INDEX_BPP	equ	03h
  7529                              <1> VBE_DISPI_INDEX_ENABLE	equ	04h
  7530                              <1> VBE_DISPI_INDEX_BANK	equ	05h
  7531                              <1> VBE_DISPI_INDEX_VIRT_WIDTH equ	06h
  7532                              <1> VBE_DISPI_INDEX_VIRT_HEIGHT equ	07h
  7533                              <1> VBE_DISPI_INDEX_X_OFFSET equ	08h
  7534                              <1> VBE_DISPI_INDEX_Y_OFFSET equ	09h
  7535                              <1> VBE_DISPI_INDEX_VIDEO_MEMORY_64K equ 0Ah
  7536                              <1> VBE_DISPI_INDEX_DDC	equ	0Bh
  7537                              <1> 
  7538                              <1> VBE_DISPI_ID0		equ	0B0C0h
  7539                              <1> VBE_DISPI_ID1		equ	0B0C1h
  7540                              <1> VBE_DISPI_ID2		equ	0B0C2h
  7541                              <1> VBE_DISPI_ID3		equ	0B0C3h
  7542                              <1> VBE_DISPI_ID4		equ	0B0C4h
  7543                              <1> VBE_DISPI_ID5		equ	0B0C5h
  7544                              <1> 
  7545                              <1> VBE_DISPI_DISABLED	equ	00h
  7546                              <1> VBE_DISPI_ENABLED	equ	01h
  7547                              <1> VBE_DISPI_GETCAPS	equ	02h
  7548                              <1> VBE_DISPI_8BIT_DAC	equ	20h
  7549                              <1> VBE_DISPI_LFB_ENABLED	equ	40h
  7550                              <1> VBE_DISPI_NOCLEARMEM	equ	80h
  7551                              <1> 
  7552                              <1> VBE_DISPI_LFB_PHYSICAL_ADDRESS equ 0E0000000h
  7553                              <1> 
  7554                              <1> ; ***
  7555                              <1> 
  7556                              <1> ;// VBE Return Status Info
  7557                              <1> ;// AL
  7558                              <1> VBE_RETURN_STATUS_SUPPORTED	equ	4Fh
  7559                              <1> VBE_RETURN_STATUS_UNSUPPORTED	equ	00h
  7560                              <1> ;// AH
  7561                              <1> VBE_RETURN_STATUS_SUCCESSFULL	equ	00h
  7562                              <1> VBE_RETURN_STATUS_FAILED	equ	01h
  7563                              <1> VBE_RETURN_STATUS_NOT_SUPPORTED	equ	02h
  7564                              <1> VBE_RETURN_STATUS_INVALID	equ	03h
  7565                              <1> 
  7566                              <1> ;// VBE Mode Numbers
  7567                              <1> 
  7568                              <1> VBE_MODE_VESA_DEFINED		equ	0100h
  7569                              <1> VBE_MODE_REFRESH_RATE_USE_CRTC	equ	0800h
  7570                              <1> VBE_MODE_LINEAR_FRAME_BUFFER	equ	4000h
  7571                              <1> VBE_MODE_PRESERVE_DISPLAY_MEMORY equ	8000h
  7572                              <1> 
  7573                              <1> ;// Mode Attributes
  7574                              <1> 
  7575                              <1> VBE_MODE_ATTRIBUTE_SUPPORTED		   equ	0001h
  7576                              <1> VBE_MODE_ATTRIBUTE_EXTENDED_INFO_AVAILABLE equ	0002h
  7577                              <1> VBE_MODE_ATTRIBUTE_COLOR_MODE		   equ	0008h
  7578                              <1> VBE_MODE_ATTRIBUTE_GRAPHICS_MODE	   equ	0010h
  7579                              <1> VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE equ	0080h
  7580                              <1> VBE_MODE_ATTRIBUTE_DOUBLE_SCAN_MODE	   equ	0100h
  7581                              <1> VBE_MODE_ATTRIBUTE_INTERLACE_MODE	   equ	0200h
  7582                              <1> 
  7583                              <1> ;// Window attributes
  7584                              <1> 
  7585                              <1> VBE_WINDOW_ATTRIBUTE_RELOCATABLE equ	01h
  7586                              <1> VBE_WINDOW_ATTRIBUTE_READABLE	 equ	02h
  7587                              <1> VBE_WINDOW_ATTRIBUTE_WRITEABLE	 equ	04h
  7588                              <1> 
  7589                              <1> ;/* Video memory */
  7590                              <1> VGAMEM_GRAPH equ 0A000h
  7591                              <1> VGAMEM_CTEXT equ 0B800h
  7592                              <1> ;VGAMEM_MTEXT equ 0B000h
  7593                              <1> 
  7594                              <1> ;// Memory model
  7595                              <1> 
  7596                              <1> ;VBE_MEMORYMODEL_TEXT_MODE	equ	00h
  7597                              <1> ;VBE_MEMORYMODEL_CGA_GRAPHICS	equ	01h
  7598                              <1> ;VBE_MEMORYMODEL_PLANAR		equ	03h
  7599                              <1> VBE_MEMORYMODEL_PACKED_PIXEL	equ	04h
  7600                              <1> ;VBE_MEMORYMODEL_NON_CHAIN_4_256 equ	05h
  7601                              <1> VBE_MEMORYMODEL_DIRECT_COLOR	equ	06h
  7602                              <1> ;VBE_MEMORYMODEL_YUV		equ	07h
  7603                              <1> 
  7604                              <1> ;// DirectColorModeInfo
  7605                              <1> 
  7606                              <1> ;VBE_DIRECTCOLOR_COLOR_RAMP_PROGRAMMABLE equ 01h
  7607                              <1> VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE equ 02h
  7608                              <1> 
  7609                              <1> VBE_DISPI_TOTAL_VIDEO_MEMORY_MB	equ 16
  7610                              <1> 
  7611                              <1> ; 24/11/2020
  7612                              <1> ; vbe.c
  7613                              <1> 
  7614                              <1> %if 1
  7615                              <1> 
  7616                              <1> _vbe_biosfn_return_mode_info:
  7617                              <1> 	; 15/12/2020
  7618                              <1> 	; 12/12/2020
  7619                              <1> 	; Return VBE Mode Information	
  7620                              <1> 	; (call from 'sysvideo')
  7621                              <1> 	;
  7622                              <1> 	; Input:
  7623                              <1> 	;	cx = video (bios) mode
  7624                              <1> 	; Output:
  7625                              <1> 	;	cf = 0 -> (successful)
  7626                              <1> 	;	   MODE_INFO_LIST addr contains MODEINFO
  7627                              <1> 	;	cf = 1 -> error
  7628                              <1> 	;
  7629                              <1> 	; Modified registers: eax, edx, edi
  7630                              <1> 	;
  7631                              <1> 
  7632                              <1> 	; pushes for subroutine stack pops compatibility
  7633                              <1> 	
  7634                              <1> 	;push	ds  ; *
  7635                              <1> 	;push	es  ; **
  7636                              <1> 
  7637 00003778 55                  <1> 	push	ebp ; ***
  7638 00003779 56                  <1> 	push	esi ; **** 
  7639                              <1> 	
  7640 0000377A 31FF                <1> 	xor	edi, edi  ; mov edi, 0
  7641                              <1> 
  7642 0000377C 803D[44090000]03    <1> 	cmp	byte [vbe3], 3
  7643 00003783 7221                <1> 	jb	short _vbe_rmi_1
  7644                              <1> 
  7645                              <1> 	;sub	edi, edi  ; 0 = kernel call (sign)
  7646                              <1> 	;	; no transfer to user's buffer
  7647                              <1> 	
  7648                              <1> 	; cx = Video mode (for 4F01h, with LFB flag)
  7649                              <1> 
  7650 00003785 66B8014F            <1> 	mov	ax, 4F01h
  7651                              <1> 
  7652 00003789 E85DE1FFFF          <1> 	call	_vbe3_pmfn_return_mode_info
  7653                              <1> 
  7654 0000378E 6683F84F            <1> 	cmp	ax, 004Fh
  7655 00003792 7533                <1> 	jne	short _vbe_rmi_2 ; fail
  7656                              <1> 
  7657                              <1> 	; 15/12/2020
  7658                              <1> 	; cx = vbe video mode
  7659 00003794 80E501              <1> 	and	ch, 01h ; clear LFB flag
  7660 00003797 BEFE7B0900          <1> 	mov	esi, VBE3MODEINFOBLOCK - 2
  7661 0000379C 66890E              <1> 	mov	[esi], cx ; MODEINFO.mode
  7662 0000379F E8A6000000          <1> 	call	set_lfbinfo_table
  7663 000037A4 EB22                <1> 	jmp	short _vbe_rmi_3  ; cf = 0 
  7664                              <1> _vbe_rmi_1:
  7665 000037A6 803D[44090000]02    <1> 	cmp	byte [vbe3], 2
  7666 000037AD 7219                <1> 	jb	short _vbe_rmi_3 ; cf = 1
  7667 000037AF A0[45090000]        <1> 	mov	al, [vbe2bios] ; 0C0h-0C5h for emu (*)
  7668 000037B4 3CC0                <1> 	cmp	al, 0C0h ; BOCHS/QEMU/VIRTUALBOX (*) ? 
  7669 000037B6 7210                <1> 	jb	short _vbe_rmi_3  ; cf = 1
  7670 000037B8 3CC5                <1> 	cmp	al, 0C5h ; (*)
  7671 000037BA 770B                <1> 	ja	short _vbe_rmi_2 ; unknown vbios !? 
  7672                              <1> 	
  7673                              <1> 	;xor	edi, edi  ; 0 = kernel call (sign)
  7674                              <1> 	;	; no transfer to user's buffer
  7675                              <1> 
  7676                              <1> 	;mov	ax, 4F01h
  7677                              <1> 
  7678                              <1> 	; cx = Video mode (for 4F01h, with LFB flag)
  7679                              <1> 
  7680 000037BC E80A000000          <1> 	call	vbe_biosfn_return_mode_info
  7681 000037C1 6683F84F            <1> 	cmp	ax, 004Fh ; successful ?
  7682 000037C5 7401                <1> 	je	short _vbe_rmi_3  ; cf = 0
  7683                              <1> _vbe_rmi_2:
  7684 000037C7 F9                  <1> 	stc
  7685                              <1> 	; cf = 1	
  7686                              <1> _vbe_rmi_3:
  7687 000037C8 5E                  <1> 	pop	esi ; ****
  7688 000037C9 5D                  <1> 	pop	ebp ; ***
  7689                              <1> 	
  7690                              <1> 	;pop	es  ; **
  7691                              <1> 	;pop	ss  ; *
  7692                              <1> 	
  7693 000037CA C3                  <1> 	retn
  7694                              <1> 
  7695                              <1> 
  7696                              <1> ; * (TRDOS 386, INT 31h, VESA Video Bios functions) 
  7697                              <1> ; * ---------------------------------------------------------
  7698                              <1> ; * Function 01h - Return VBE Mode Information
  7699                              <1> ; * ---------------------------------------------------------
  7700                              <1> ; * Input:
  7701                              <1> ; *		AX = 4F01h
  7702                              <1> ; *		CX = Mode number
  7703                              <1> ; *    (ES:DI) EDI = Pointer to ModeInfoBlock structure	
  7704                              <1> ; * Output:
  7705                              <1> ; *		AX = VBE Return Status
  7706                              <1> ; * 
  7707                              <1> ; *----------------------------------------------------------
  7708                              <1> ; *
  7709                              <1> 
  7710                              <1> vbe_biosfn_return_mode_info:
  7711                              <1> 	; 15/12/2020 
  7712                              <1> 	; 14/12/2020
  7713                              <1> 	; 12/12/2020
  7714                              <1> 	; 11/12/2020 (TRDOS 386 v2.0.3)
  7715                              <1> 	;
  7716                              <1> 	; Input:
  7717                              <1> 	;	cx = video (bios) mode
  7718                              <1> 	;      edi = ModeInfoBlock buffer address
  7719                              <1> 	;	     (in user's memory space)		
  7720                              <1> 	;      (ax = 4F01h)
  7721                              <1> 	; Output:
  7722                              <1> 	;	ax = 004Fh (successful)
  7723                              <1> 	;	ah > 0 -> error
  7724                              <1> 	;
  7725                              <1> 	; Modified registers: esi
  7726                              <1> 
  7727                              <1> 	;;push	ds  ; *
  7728                              <1> 	;;push	es  ; **
  7729                              <1> 	;;push	ebp ; ***
  7730                              <1> 	;;push	esi ; **** 
  7731                              <1> 
  7732 000037CB F6C501              <1> 	test	ch, 1
  7733 000037CE 7505                <1> 	jnz	short vbe_rmi_1
  7734                              <1> 
  7735                              <1> 	; mode number < 100h
  7736                              <1> 	; CGA/VGA mode is not proper this VBE function 
  7737                              <1> 
  7738 000037D0 29C0                <1> 	sub	eax, eax
  7739                              <1> vbe_rmi_0:	
  7740                              <1> 	;mov	ax, 0100h  ; Function is not supported
  7741 000037D2 B401                <1> 	mov	ah, 1
  7742 000037D4 C3                  <1> 	retn
  7743                              <1> vbe_rmi_1:
  7744 000037D5 52                  <1> 	push	edx ; *****
  7745 000037D6 51                  <1> 	push	ecx ; ******
  7746 000037D7 53                  <1> 	push	ebx ; *******	
  7747 000037D8 57                  <1> 	push	edi ; ********
  7748                              <1> 	
  7749                              <1> 	; 14/12/2020
  7750 000037D9 89CB                <1> 	mov	ebx, ecx
  7751                              <1>  			
  7752                              <1> 	;xor	eax, eax
  7753 000037DB 80E7C1              <1> 	and	bh, 0C1h ; use bit 15, 14, 8 only (for bh)
  7754 000037DE 883D[9D110300]      <1> 	mov	[vbe_mode_x], bh
  7755                              <1> 	;and	bx, 1FFh
  7756 000037E4 80E701              <1> 	and	bh, 1
  7757                              <1> 	;mov	bh, 1
  7758                              <1> 
  7759                              <1> 	; Alternative 2 (instead of 'Mode_info_find_mode')
  7760 000037E7 E8B1020000          <1> 	call	set_mode_info_list ; (alternative 2)
  7761                              <1> 
  7762                              <1> 	; eax = 0	
  7763                              <1> 
  7764                              <1> 	;mov	bx, [esi] ; mode
  7765                              <1> 
  7766                              <1> 	; Alternative 1 (instead of 'set_mode_info_list')
  7767                              <1> 	;call	mode_info_find_mode ; (alternative 1)
  7768                              <1> 
  7769 000037EC 09F6                <1> 	or	esi, esi
  7770                              <1> 	; 14/12/2020
  7771 000037EE 744D                <1> 	jz	short vbe_rmi_4	; VBE mode number is wrong
  7772                              <1> 				; or it is not supported
  7773                              <1> 
  7774                              <1> 	; 15/12/2020
  7775                              <1> 	;mov	bx, [esi] ; mode
  7776                              <1> 
  7777                              <1> 	; 12/12/2020
  7778                              <1> 	;call	set_lfbinfo_table
  7779                              <1> 
  7780 000037F0 F605[9D110300]40    <1> 	test	byte [vbe_mode_x], 40h ; LFB model ?
  7781 000037F7 7404                <1> 	jz	short vbe_rmi_2
  7782                              <1> 	
  7783 000037F9 C6461C01            <1> 	mov	byte [esi+MODEINFO.NumberOfBanks], 1
  7784                              <1> vbe_rmi_2:
  7785                              <1> 	; (vbe.c, 02/01/2020, vruppert)
  7786                              <1> 	; 11/12/2020 (Erdogan Tan, video.s) 
  7787                              <1> 	; Bochs Graphics Adapter
  7788                              <1> 	; vendor_id: 1111h, device id: 1234h
  7789                              <1> 
  7790 000037FD E87C030000          <1> 	call	pci_get_lfb_addr
  7791                              <1> 	;or	eax, eax
  7792 00003802 7404                <1> 	jz	short vbe_rmi_3
  7793                              <1> 	; zf = 0, ax > 0 (high word of LFB address)
  7794                              <1> 	; set/change LFB address in MODEINFO structure
  7795 00003804 6689462C            <1> 	mov	[esi+MODEINFO.PhysBasePtr+2], ax
  7796                              <1> 	; 12/12/2020
  7797                              <1> 	;mov	[edi+LFBINFO.LFB_addr+2], ax
  7798                              <1> vbe_rmi_3:
  7799                              <1> 	;test	byte [esi+MODEINFO.WinAAttributes], 1 
  7800                              <1> 	;		; VBE_WINDOW_ATTRIBUTE_RELOCATABLE = 1
  7801                              <1>         ;jz	short vbe_rmi_4
  7802                              <1> 	;; 11/12/2020
  7803                              <1> 	;; In fact, this is far call address in (Bochs/BGA) Video Bios
  7804                              <1> 	;; Direct user access to kernel subroutines is not possible 
  7805                              <1> 	;; in TRDOS 386. Also, TRDOS 386 kernel will support only LFB.
  7806                              <1> 	;; Bank select may be a seperate sysvideo function in future
  7807                              <1> 	;; (if it will be required).
  7808                              <1> 	;mov	dword [esi+MODEINFO.WinFuncPtr], dispi_set_bank_farcall
  7809                              <1> ;vbe_rmi_4:
  7810                              <1> 	; 12/12/2020
  7811 00003808 E83D000000          <1> 	call	set_lfbinfo_table
  7812                              <1> 
  7813                              <1> 	; 11/12/2020
  7814                              <1> 	; copy 68 bytes of MODE_INFO_LIST to user
  7815                              <1> 
  7816 0000380D 8B3C24              <1> 	mov	edi, [esp]  ; user's buffer address
  7817                              <1> 	; 12/12/2020
  7818 00003810 09FF                <1> 	or	edi, edi ; 0 = kernel call 
  7819                              <1> 			 ; (call from '_vbe_biosfn_return_mode_info')
  7820 00003812 7432                <1> 	jz	short vbe_rmi_6
  7821                              <1> 
  7822                              <1> 	; 15/12/2020
  7823                              <1> 	; prepare 256 bytes MODEINFO buffer at VBE3MODEINFOBLOCK
  7824                              <1> 	; and then, copy buffer conttent to user's buffer
  7825 00003814 57                  <1> 	push	edi
  7826 00003815 BE[BC110300]        <1> 	mov	esi, MODE_INFO_LIST + 2	; MODEINFO.ModeAttributes
  7827 0000381A BF007C0900          <1> 	mov	edi, VBE3MODEINFOBLOCK
  7828 0000381F B910000000          <1> 	mov	ecx, 66/4  ; 66 bytes
  7829 00003824 F3A5                <1> 	rep	movsd
  7830 00003826 31C0                <1> 	xor	eax, eax
  7831 00003828 B12F                <1> 	mov	cl, (256-68)/4 ; 188 bytes
  7832 0000382A F3AB                <1> 	rep	stosd
  7833 0000382C 66AB                <1> 	stosw	; 2 bytes
  7834 0000382E 5F                  <1> 	pop	edi
  7835 0000382F BE007C0900          <1> 	mov	esi, VBE3MODEINFOBLOCK
  7836                              <1> 	;mov	cx, 256 
  7837 00003834 FEC5                <1> 	inc	ch ; cx = 256
  7838 00003836 E856BA0000          <1> 	call	transfer_to_user_buffer
  7839 0000383B 7309                <1> 	jnc	short vbe_rmi_5
  7840                              <1> vbe_rmi_4:
  7841                              <1> 	;mov	eax, 014Fh ; fail/error
  7842 0000383D 31C0                <1> 	xor	eax, eax
  7843 0000383F B401                <1> 	mov	ah, 01h
  7844                              <1> 	;jmp	short vbe_rmi_6
  7845 00003841 E981000000          <1> 	jmp	vbe_sm_ret1 ; 11/12/2020
  7846                              <1> vbe_rmi_5:
  7847                              <1> 	; 256 bytes of MODEINFO have been transferred to user
  7848                              <1> 	;mov	eax, 4Fh ; succesfull
  7849                              <1> vbe_rmi_6: ; 12/12/2020
  7850 00003846 31C0                <1> 	xor	eax, eax
  7851                              <1> ;vbe_rmi_6:
  7852 00003848 EB7D                <1> 	jmp	vbe_sm_ret1 ; 11/12/2020
  7853                              <1> 
  7854                              <1> 	;pop	edi ; ********
  7855                              <1> 	;pop	ebx ; *******
  7856                              <1> 	;pop	ecx ; ******
  7857                              <1> 	;pop	edx ; *****	
  7858                              <1> 	
  7859                              <1> 	;;pop	esi ; ****
  7860                              <1> 	;;pop	ebp ; ***
  7861                              <1> 	;;pop	es  ; **
  7862                              <1> 	;;pop	ds  ; * 
  7863                              <1> 
  7864                              <1> 	;retn
  7865                              <1> 
  7866                              <1> set_lfbinfo_table:
  7867                              <1> 	; 19/12/2020
  7868                              <1> 	; 11/12/2020
  7869                              <1> 	; Set/Fill LFBINFO structure/table
  7870                              <1> 	;
  7871                              <1> 	; Input:
  7872                              <1> 	;	esi = Mode info list address 
  7873                              <1> 	; Output:
  7874                              <1> 	;	LFB_Info address is filled with LFBINFO
  7875                              <1> 	;	edi = LFB_Info address
  7876                              <1> 	;
  7877                              <1> 	; Modified registers: eax, edx (=0), edi
  7878                              <1> 
  7879 0000384A BF[AA110300]        <1> 	mov	edi, LFB_Info
  7880 0000384F 8B462A              <1> 	mov	eax, [esi+MODEINFO.PhysBasePtr]
  7881 00003852 894702              <1> 	mov	[edi+LFBINFO.LFB_addr], eax ; LFB address
  7882                              <1> 	;mov	ax, [esi+MODEINFO.mode]
  7883 00003855 668B06              <1> 	mov	ax, [esi]
  7884 00003858 668907              <1> 	mov	[edi+LFBINFO.mode],ax
  7885 0000385B 8A461B              <1> 	mov	al, [esi+MODEINFO.BitsPerPixel]
  7886 0000385E 88470E              <1> 	mov	[edi+LFBINFO.bpp], al
  7887 00003861 29C0                <1> 	sub	eax, eax
  7888 00003863 668B4614            <1> 	mov	ax, [esi+MODEINFO.XResolution]
  7889 00003867 6689470A            <1> 	mov	[edi+LFBINFO.X_res], ax
  7890 0000386B 89C2                <1> 	mov	edx, eax ; 19/12/2020
  7891 0000386D 668B4616            <1> 	mov	ax, [esi+MODEINFO.YResolution]
  7892 00003871 6689470C            <1> 	mov	[edi+LFBINFO.Y_res], ax
  7893                              <1> 	; eax = Y_res ; screen height
  7894                              <1> 	; 19/12/2020	
  7895 00003875 F7E2                <1> 	mul	edx ; X_res*Y_res
  7896                              <1> 	; edx = 0
  7897 00003877 8A570E              <1> 	mov	dl, [edi+LFBINFO.bpp]
  7898                              <1> 	; Note:
  7899                              <1> 	; Bits per pixel may be 8,16,24,32 for TRDOS 386 v2.
  7900                              <1> 	; (4 bits for pixel is not used for VESA modes here)
  7901 0000387A C0EA03              <1> 	shr	dl, 3 ; convert bits to byte
  7902 0000387D F7E2                <1> 	mul	edx
  7903                              <1> 	; eax = screen/page/buffer size in bytes
  7904 0000387F 894706              <1> 	mov	[edi+LFBINFO.LFB_size], eax
  7905                              <1> 	; edx = 0
  7906                              <1> 	; clear reserved byte in LFBINFO structure/table
  7907 00003882 88570F              <1> 	mov	[edi+LFBINFO.reserved], dl ; not necessary
  7908 00003885 C3                  <1> 	retn
  7909                              <1> 
  7910                              <1> ; * (TRDOS 386, INT 31h, VESA Video Bios functions) 
  7911                              <1> ; * ---------------------------------------------------------
  7912                              <1> ; * Function 02h - Set VBE Mode
  7913                              <1> ; * ---------------------------------------------------------
  7914                              <1> ; * Input:
  7915                              <1> ; *		AX = 4F02h
  7916                              <1> ; *		BX = Desired Mode to set
  7917                              <1> ; * Output:
  7918                              <1> ; *		AX = VBE Return Status
  7919                              <1> ; * 
  7920                              <1> ; *----------------------------------------------------------
  7921                              <1> ; *
  7922                              <1> 
  7923                              <1> vbe_biosfn_set_mode:
  7924                              <1> 	; 12/12/2020
  7925                              <1> 	; 11/12/2020 (LFBINFO table for VESA VBE modes)
  7926                              <1> 	; 27/11/2020
  7927                              <1> 	; 25/11/2020
  7928                              <1> 	; 23/11/2020 (TRDOS 386 v2.0.3)
  7929                              <1> 	; (ref: vbe.c, 02/01/2020, vruppert)
  7930                              <1> 	;
  7931                              <1> 	; Input:
  7932                              <1> 	;	bx = video (bios) mode
  7933                              <1> 	;	ax = 4F02h
  7934                              <1> 	; Output:
  7935                              <1> 	;	ax = 004Fh (successful)
  7936                              <1> 	;	ah > 0 -> error
  7937                              <1> 	;
  7938                              <1> 	; Modified registers: esi
  7939                              <1> 
  7940                              <1> 	; 27/11/2020
  7941                              <1> 
  7942                              <1> 	;;push	ds  ; *
  7943                              <1> 	;;push	es  ; **
  7944                              <1> 	;;push	ebp ; ***
  7945                              <1> 	;;push	esi ; **** 
  7946                              <1> 	
  7947                              <1> 	; 11/12/2020 			
  7948 00003886 52                  <1> 	push	edx ; *****
  7949 00003887 51                  <1> 	push	ecx ; ******
  7950 00003888 53                  <1> 	push	ebx ; *******	
  7951 00003889 57                  <1> 	push	edi ; ********
  7952                              <1> 
  7953                              <1> 	;xor	eax, eax
  7954 0000388A 80E7C1              <1> 	and	bh, 0C1h ; use bit 15, 14, 8 only (for bh)
  7955 0000388D 883D[9D110300]      <1> 	mov	[vbe_mode_x], bh
  7956 00003893 80E701              <1> 	and	bh, 1
  7957 00003896 753C                <1> 	jnz	short vbe_sm_3  ; VESA VBE mode
  7958                              <1> 
  7959                              <1>  	;;test	bx, 4000h ; VBE_MODE_LINEAR_FRAME_BUFFER
  7960                              <1> 	;test	bh, 40h
  7961                              <1> 	;jz	short vbe_sm_0
  7962                              <1> 	;; lfb_flag
  7963                              <1> 	;mov	al, 40h	; VBE_DISPI_LFB_ENABLED
  7964                              <1> vbe_sm_0:
  7965                              <1> 	; 27/11/2020
  7966 00003898 B080                <1> 	mov	al, 80h
  7967                              <1> 	;test	bh, 80h ; VBE_MODE_PRESERVE_DISPLAY_MEMORY 	
  7968                              <1> 	;jnz	short vbe_sm_1 ; no_clear
  7969                              <1> 	;; clear
  7970                              <1> 	;sub	al, al ; 0
  7971 0000389A 8405[9D110300]      <1> 	test	[vbe_mode_x], al ; 80h
  7972 000038A0 7402                <1> 	jz	short vbe_sm_1 ; clear display memory
  7973                              <1> 	; no_clear
  7974 000038A2 08C3                <1> 	or	bl, al ; VBE_MODE_PRESERVE_DISPLAY_MEMORY
  7975                              <1> vbe_sm_1:
  7976                              <1> 	; check non vesa mode
  7977                              <1> 	;;cmp	bx, 100h ; VBE_MODE_VESA_DEFINED
  7978                              <1> 	;;jna	short vbe_sm_2
  7979                              <1> 	;and	bh, 1
  7980                              <1> 	;jnz	short vbe_sm_3 
  7981                              <1> 
  7982                              <1> 	; BX <= 1FFh
  7983                              <1> 
  7984                              <1> 	; 27/11/2020
  7985                              <1> 	;or	bl, al	; al = 80h if no_clear option is set 
  7986                              <1> 	;		; al = 0 if no_clear option is not set 
  7987                              <1> 
  7988                              <1> 	; 25/11/2020
  7989                              <1> 	; VBE DISPI will be disabled in 'biosfn_set_video_mode'
  7990                              <1>  
  7991                              <1> 	;xor	al, al ; 0 ; VBE_DISPI_DISABLED
  7992                              <1> 	;call	dispi_set_enable
  7993                              <1> 
  7994                              <1> 	; call the vgabios in order to set the video mode
  7995                              <1> 	; this allows for going back to textmode with a VBE call
  7996                              <1> 	; (some applications expect that to work)
  7997                              <1> 
  7998                              <1> 	;and	bx, 0FFh
  7999                              <1> 	
  8000                              <1> 	; 27/11/2020
  8001                              <1> biosfn_set_video_mode:
  8002                              <1> 	; _call: call subroutine
  8003                              <1> 	; 26/11/2020 (TRDOS 386 v2.0.3)
  8004                              <1> 	; (ref: vgabios.c, 02/01/2020, vruppert)
  8005                              <1> 	; Input:
  8006                              <1> 	;	bl = VGA video (bios) mode
  8007                              <1> 	; Output:
  8008                              <1> 	;	cf = 1 -> error
  8009                              <1> 	;	cf = 0 -> ok
  8010                              <1> 	;
  8011                              <1> 	; Modified registers: esi
  8012                              <1> 
  8013                              <1> 	; 'dispi_set_enable(VBE_DISPI_DISABLED);'
  8014                              <1> 	
  8015                              <1> 	;mov	ax, 0 ; VBE_DISPI_DISABLED 
  8016 000038A4 31C0                <1> 	xor	eax, eax ; 0 
  8017 000038A6 E8CA000000          <1> 	call	dispi_set_enable
  8018                              <1> 	
  8019 000038AB 88D8                <1> 	mov	al, bl
  8020                              <1> 	;jmp	_set_mode ; (in 'biosfn_set_video_mode' sub)
  8021 000038AD E8B6E1FFFF          <1> 	call	_set_mode ; will return with cf=1 only if
  8022                              <1> 			; desired mode is not implemented
  8023                              <1> 	; _retn: return from subroutine
  8024 000038B2 721A                <1> 	jc	short vbe_sm_2 ; 25/11/2020
  8025                              <1> 
  8026                              <1> 	; 26/11/2020
  8027 000038B4 31C0                <1> 	xor	eax, eax 
  8028 000038B6 A0[9A690000]        <1> 	mov	al, [CRT_MODE]
  8029                              <1> 	; 27/11/2020
  8030 000038BB 8A25[6F700100]      <1> 	mov	ah, [noclearmem] ; 80h or 0
  8031                              <1> 	;and	ah 80h
  8032 000038C1 66A3[9E110300]      <1> 	mov	[video_mode], ax ; bit 15 = no_clear flag
  8033                              <1> 				 ; bit 14 = 0 (not LFB model)
  8034                              <1> vbe_sm_ret1:
  8035                              <1> 	; 11/12/2020
  8036                              <1> 	; (vbe_rmi_4 and vbe_rmi_6 jump here)
  8037                              <1> 	; 27/11/2020
  8038 000038C7 B04F                <1> 	mov	al, 4Fh ; Function call successful
  8039                              <1> 	; eax = 004Fh
  8040                              <1> vbe_sm_ret2:
  8041                              <1> 	; 11/12/2020
  8042 000038C9 5F                  <1> 	pop	edi ; ********
  8043 000038CA 5B                  <1> 	pop	ebx ; *******
  8044 000038CB 59                  <1> 	pop	ecx ; ******
  8045 000038CC 5A                  <1> 	pop	edx ; *****
  8046                              <1> 
  8047                              <1> 	;;pop	esi ; ****
  8048                              <1> 	;;pop	ebp ; ***
  8049                              <1> 	;;pop	es  ; **
  8050                              <1> 	;;pop	ds  ; * 
  8051                              <1> 
  8052 000038CD C3                  <1> 	retn
  8053                              <1> 
  8054                              <1> vbe_sm_2:
  8055                              <1> 	;mov	ax, 0100h ; Function is not supported
  8056                              <1> 	; 27/11/2020
  8057 000038CE 31C0                <1> 	xor	eax, eax
  8058 000038D0 B401                <1> 	mov	ah, 01h
  8059                              <1> 	; eax = 0100h
  8060                              <1> 	;retn
  8061 000038D2 EBF5                <1> 	jmp	short vbe_sm_ret2
  8062                              <1> 
  8063                              <1> vbe_sm_3:
  8064                              <1> 	; 12/12/2020
  8065                              <1> 	; check current mode, if it is 03h
  8066                              <1> 	; save page contents and cursor positions
  8067 000038D4 803D[9A690000]03    <1> 	cmp	byte [CRT_MODE], 03h
  8068 000038DB 75BB                <1> 	jne	short vbe_sm_0
  8069 000038DD E83BE4FFFF          <1> 	call	save_mode3_multiscreen
  8070                              <1> 	; set current mode to extended (SVGA) mode
  8071                              <1> 	;mov	byte [CRT_MODE], 0FFh ; VESA VBE mode
  8072                              <1> vbe_sm_4:
  8073                              <1> 	; 27/11/2020
  8074                              <1> 	; bx = mode (bit 0 to 8)
  8075                              <1> 
  8076                              <1> 	; 25/11/2020
  8077                              <1> 
  8078                              <1> 	; Alternative 2 (instead of 'Mode_info_find_mode')
  8079                              <1> 	;push	edi
  8080 000038E2 E8B6010000          <1> 	call	set_mode_info_list ; (alternative 2)	
  8081                              <1> 	;pop	edi
  8082                              <1> 
  8083                              <1> 	;mov	bx, [esi] ; mode
  8084                              <1> 
  8085                              <1> 	; Alternative 1 (instead of 'set_mode_info_list')
  8086                              <1> 	;call	mode_info_find_mode ; (alternative 1)
  8087                              <1> 
  8088 000038E7 09F6                <1> 	or	esi, esi
  8089 000038E9 74E3                <1> 	jz	short vbe_sm_2 ; VBE mode number is wrong
  8090                              <1> 			       ; or it is not supported
  8091                              <1> 
  8092                              <1> 	; 11/12/2020
  8093 000038EB 668B1E              <1> 	mov	bx, [esi] ; mode
  8094                              <1> 
  8095                              <1> 	; 27/11/2020
  8096 000038EE 0A3D[9D110300]      <1> 	or	bh, [vbe_mode_x]
  8097                              <1> 
  8098                              <1> 	; save VESA VBE mode
  8099 000038F4 66891D[9E110300]    <1> 	mov	[video_mode], bx
  8100                              <1> 		; 27/11/2020
  8101                              <1> 		; bit 0 to 8 = VESA VBE mode
  8102                              <1> 		; bit 9 to 13 = 0 (bit 0 to 13 = mode)
  8103                              <1> 		; bit 14 = Linear/Flat Frame Buffer flag
  8104                              <1> 		; bit 15 = 'memory not cleared
  8105                              <1> 		;	   at last mode set' flag
  8106                              <1> 
  8107                              <1> 	; first disable current mode
  8108                              <1> 	; (when switching between vesa modes)
  8109                              <1> 	; 'dispi_set_enable(VBE_DISPI_DISABLED);'        
  8110                              <1> 
  8111                              <1> 	;mov	ax, VBE_DISPI_DISABLED ; 0
  8112 000038FB 29C0                <1> 	sub	eax, eax ; 0
  8113                              <1> 
  8114 000038FD E873000000          <1> 	call	dispi_set_enable
  8115                              <1> 
  8116                              <1> 	; 11/12/2020
  8117 00003902 8A461B              <1> 	mov	al, [esi+MODEINFO.BitsPerPixel]
  8118                              <1> 	; ah = 0
  8119                              <1> 
  8120                              <1> 	;cmp	byte [esi+MODEINFO.BitsPerPixel], 8
  8121 00003905 3C08                <1> 	cmp	al, 8
  8122 00003907 750B                <1> 	jne	short vbe_sm_5
  8123                              <1> 
  8124                              <1> 	; 11/12/2020
  8125                              <1> 	;push	edi
  8126 00003909 50                  <1> 	push	eax
  8127                              <1> 	; 'load_dac_palette(3);'
  8128 0000390A 56                  <1> 	push	esi
  8129 0000390B B403                <1> 	mov	ah, 3  ; palette3, 256 colors
  8130 0000390D E873F2FFFF          <1> 	call	load_dac_palette
  8131 00003912 5E                  <1> 	pop	esi
  8132                              <1> 	; 11/12/2020
  8133 00003913 58                  <1> 	pop	eax
  8134                              <1> 	;pop	edi
  8135                              <1> vbe_sm_5:	
  8136                              <1>   	;'dispi_set_bpp(cur_info->info.BitsPerPixel);'
  8137                              <1> 	; 11/12/2020 (al = bits per pixel, ah = 0)
  8138                              <1> 	;xor	ah, ah
  8139                              <1> 	;mov	al, [esi+MODEINFO.BitsPerPixel]
  8140 00003914 E870000000          <1> 	call	dispi_set_bpp
  8141                              <1>         ;'dispi_set_xres(cur_info->info.XResolution);'
  8142 00003919 668B4614            <1> 	mov	ax, [esi+MODEINFO.XResolution]
  8143 0000391D E86D000000          <1> 	call	dispi_set_xres
  8144                              <1>         ;'dispi_set_yres(cur_info->info.YResolution);'
  8145 00003922 668B4616            <1> 	mov	ax, [esi+MODEINFO.YResolution]
  8146 00003926 E86A000000          <1> 	call	dispi_set_yres
  8147                              <1> 
  8148                              <1> 	;'dispi_set_bank(0);'
  8149                              <1> 	;xor	ax, ax
  8150 0000392B 31C0                <1> 	xor	eax, eax ; 0
  8151 0000392D E869000000          <1> 	call	dispi_set_bank
  8152                              <1>         ;'dispi_set_enable(VBE_DISPI_ENABLED|no_clear|lfb_flag);'
  8153                              <1> 	;mov	ax, di
  8154                              <1> 	; ah = 0 ; 27/11/2020
  8155 00003932 A0[9D110300]        <1> 	mov	al, [vbe_mode_x] ; restore VBE mode bit 14 & 15
  8156 00003937 0C01                <1> 	or	al, 1 ; VBE_DISPI_ENABLED
  8157 00003939 E837000000          <1> 	call	dispi_set_enable
  8158                              <1> 
  8159                              <1>         ; 'vga_compat_setup();'
  8160 0000393E E86D000000          <1> 	call	vga_compat_setup
  8161                              <1> 
  8162                              <1> 	; 11/12/2020
  8163 00003943 E802FFFFFF          <1> 	call	set_lfbinfo_table
  8164                              <1> 
  8165                              <1> 	; 26/11/2020
  8166 00003948 31C0                <1> 	xor	eax, eax
  8167 0000394A FEC8                <1> 	dec	al 
  8168 0000394C A2[9A690000]        <1> 	mov	[CRT_MODE], al ; 0FFh = VESA VBE mode sign
  8169                              <1> 
  8170                              <1> 	; 27/11/2020
  8171 00003951 E971FFFFFF          <1> 	jmp	vbe_sm_ret1 ; Function call successful
  8172                              <1> 	
  8173                              <1> 	; 27/11/2020
  8174                              <1> 	;mov	al, 4Fh
  8175                              <1> 	;	; eax = 004Fh = Function call successful
  8176                              <1> 	;jmp	short vbe_sm_ret2
  8177                              <1> 
  8178                              <1> ; * (TRDOS 386, INT 31h, VESA Video Bios functions) 
  8179                              <1> ; * ---------------------------------------------------------
  8180                              <1> ; * Function 03h - Return Current VBE Mode
  8181                              <1> ; * ---------------------------------------------------------
  8182                              <1> ; * Input:
  8183                              <1> ; *		AX = 4F03h
  8184                              <1> ; * Output:
  8185                              <1> ; *		AX = VBE Return Status
  8186                              <1> ; *		BX = Current VBE Mode
  8187                              <1> ; * 
  8188                              <1> ; *----------------------------------------------------------
  8189                              <1> ; *
  8190                              <1> 
  8191                              <1> vbe_biosfn_return_current_mode:
  8192                              <1> 	; 11/12/2020
  8193                              <1> 	; 27/11/2020 (TRDOS 386 v2.0.3)
  8194                              <1> 	; (ref: vbe.c, 02/01/2020, vruppert)
  8195                              <1> 	;
  8196                              <1> 	; Input:
  8197                              <1> 	;	none
  8198                              <1> 	; Output:
  8199                              <1> 	;	ax = 004Fh (successful)
  8200                              <1> 	;	ah > 0 -> error
  8201                              <1> 	;	bx = current video (bios) mode (if ah = 0)
  8202                              <1> 	;
  8203                              <1> 	; Modified registers: eax, ebx
  8204                              <1> 
  8205                              <1> 	; 27/11/2020
  8206                              <1> 
  8207                              <1> 	;;push	ds  ; *
  8208                              <1> 	;;push	es  ; **
  8209                              <1> 	;;push	ebp ; ***
  8210                              <1> 	;;push	esi ; **** 
  8211                              <1> 	 			
  8212                              <1> 	;push	edx ; *****
  8213                              <1> 
  8214                              <1> 	; (vbe.c)
  8215                              <1> 	;call	dispi_get_enable
  8216                              <1> 	;	; ax = vbe display interface status
  8217                              <1> 	;and	al, 1 ; VBE_DISPI_ENABLED
  8218                              <1> 	;jnz	short vbe_gm_1  ; VBE graphics mode
  8219                              <1> 
  8220 00003956 A0[9A690000]        <1> 	mov	al, [CRT_MODE] ; current cga/vga mode
  8221 0000395B 3CFF                <1> 	cmp	al, 0FFh ; VBE extension signature
  8222 0000395D 720E                <1> 	jb	short vbe_gm_1 ; get CGA/VGA mode
  8223                              <1> 
  8224                              <1> 	; get VBE mode
  8225                              <1> vbe_gm_0:
  8226 0000395F 66A1[9E110300]      <1> 	mov	ax, [video_mode]
  8227                              <1> 		; BX bits:
  8228                              <1> 		; bit 0 to 8 = VESA VBE video mode
  8229                              <1> 		; bit 9 to 13 = 0 
  8230                              <1> 		; bit 14 = last mode set LFB option
  8231                              <1> 		;	   1 - linear/flat frame buffer
  8232                              <1> 		;	   0 - windowed frame buffer
  8233                              <1> 		; bit 15 = last mode set no_clear option		
  8234                              <1> 		;	   0 - video memory cleared
  8235                              <1> 		;	   1 - video memory not cleared
  8236                              <1> 	
  8237                              <1> vbe_gm_return:
  8238                              <1> 	;pop	edx ; ******
  8239 00003965 0FB7D8              <1> 	movzx	ebx, ax
  8240 00003968 31C0                <1> 	xor	eax, eax ; 0
  8241 0000396A B04F                <1> 	mov	al, 4Fh ; ax = 004Fh (successful)
  8242 0000396C C3                  <1> 	retn	
  8243                              <1> 
  8244                              <1> vbe_gm_1:
  8245                              <1> 	; legacy (old, standard) CGA/VGA bios video mode
  8246 0000396D 8A25[6F700100]      <1> 	mov	ah, [noclearmem] ; 80h or 0
  8247                              <1> 		; BX bits: 
  8248                              <1> 		; bit 0 to 7 = video mode
  8249                              <1> 		; bit 8 to 13 = 0 
  8250                              <1> 		; bit 14 = 0 (not LFB mode) CGA/VGA
  8251                              <1> 		; bit 15 = 1 if [noclearmem] = 80h
  8252                              <1> 		;	   0 if [noclearmem] = 0
  8253 00003973 EBF0                <1> 	jmp	short vbe_gm_return 
  8254                              <1> 
  8255                              <1> dispi_set_enable:
  8256                              <1> 	; 23/11/2020
  8257                              <1> 	; Input:
  8258                              <1> 	;	ax = VBE_DISPI_ENABLED = 1
  8259                              <1> 	;	     or VBE_DISPI_DISABLED = 0
  8260                              <1> 	;
  8261                              <1> 	; Modified registers: none
  8262                              <1> 	
  8263                              <1> 	;push	edx
  8264                              <1> 	;push	eax
  8265                              <1> 	;mov	dx, 01CEh ; VBE_DISPI_IOPORT_INDEX
  8266                              <1> 	;mov	ax, 04h	  ; VBE_DISPI_INDEX_ENABLE
  8267                              <1> 	;out	dx, ax
  8268                              <1> 	;pop	eax
  8269                              <1> 	;;mov	dx, 01CFh ; VBE_DISPI_IOPORT_DATA
  8270                              <1> 	;;mov	dl, 0CFh
  8271                              <1> 	;inc	dl
  8272                              <1> 	;out	dx, ax
  8273                              <1> 	;pop	edx
  8274                              <1> 	;retn
  8275                              <1> 
  8276                              <1> 	; 25/11/2020
  8277                              <1> 	; Modified registers: edx
  8278                              <1> 	;push	edx
  8279 00003975 66BA0400            <1> 	mov	dx, 04h ; VBE_DISPI_INDEX_ENABLE
  8280                              <1> 	;call	dispi_set_parms
  8281                              <1> 	;pop	edx
  8282                              <1> 	;retn
  8283                              <1> 	;;jmp	short dispi_set_parms
  8284                              <1> 
  8285                              <1> dispi_set_parms:
  8286                              <1> 	; 25/11/2020
  8287                              <1> 	; Input:
  8288                              <1> 	;	ax = data
  8289                              <1> 	;	dx = vbe dispi register index
  8290                              <1> 	;
  8291                              <1> 	; Modified registers: edx
  8292                              <1> 
  8293 00003979 50                  <1> 	push	eax
  8294 0000397A 6689D0              <1> 	mov	ax, dx
  8295 0000397D 66BACE01            <1> 	mov	dx, 01CEh ; VBE_DISPI_IOPORT_INDEX
  8296 00003981 66EF                <1> 	out	dx, ax
  8297 00003983 58                  <1> 	pop	eax
  8298                              <1> 	;mov	dx, 01CFh ; VBE_DISPI_IOPORT_DATA
  8299                              <1> 	;mov	dl, 0CFh
  8300 00003984 FEC2                <1> 	inc	dl
  8301 00003986 66EF                <1> 	out	dx, ax
  8302 00003988 C3                  <1> 	retn
  8303                              <1> 
  8304                              <1> dispi_set_bpp:
  8305                              <1> 	; 25/11/2020
  8306                              <1> 	; Input:
  8307                              <1> 	;	ax = Bits per pixel value
  8308                              <1> 	;	     (8,16,24,32)
  8309                              <1> 	;
  8310                              <1> 	; Modified registers: none
  8311                              <1> 
  8312                              <1> 	;push	edx
  8313                              <1> 	;push	eax
  8314                              <1> 	;mov	dx, 01CEh ; VBE_DISPI_IOPORT_INDEX
  8315                              <1> 	;mov	ax, 03h	  ; VBE_DISPI_INDEX_BPP
  8316                              <1> 	;out	dx, ax
  8317                              <1> 	;pop	eax
  8318                              <1> 	;;mov	dx, 01CFh ; VBE_DISPI_IOPORT_DATA
  8319                              <1> 	;;mov	dl, 0CFh
  8320                              <1> 	;inc	dl
  8321                              <1> 	;out	dx, ax
  8322                              <1> 	;pop	edx
  8323                              <1> 	;retn
  8324                              <1> 
  8325                              <1> 	; 25/11/2020
  8326                              <1> 	; Modified registers: edx
  8327                              <1> 	;push	edx
  8328 00003989 66BA0300            <1> 	mov	dx, 03h ; VBE_DISPI_INDEX_BPP
  8329                              <1> 	;call	dispi_set_parms
  8330                              <1> 	;pop	edx
  8331                              <1> 	;retn
  8332 0000398D EBEA                <1> 	jmp	short dispi_set_parms
  8333                              <1> 
  8334                              <1> dispi_set_xres:
  8335                              <1> 	; 25/11/2020
  8336                              <1> 	; Input:
  8337                              <1> 	;	ax = X resolution (screen witdh)
  8338                              <1> 	;	     (320,640,800,1024,1280,1920)
  8339                              <1> 	;
  8340                              <1> 	; Modified registers: none
  8341                              <1> 
  8342                              <1> 	;push	edx
  8343                              <1> 	;push	eax
  8344                              <1> 	;mov	dx, 01CEh ; VBE_DISPI_IOPORT_INDEX
  8345                              <1> 	;mov	ax, 01h	  ; VBE_DISPI_INDEX_XRES
  8346                              <1> 	;out	dx, ax
  8347                              <1> 	;pop	eax
  8348                              <1> 	;;mov	dx, 01CFh ; VBE_DISPI_IOPORT_DATA
  8349                              <1> 	;;mov	dl, 0CFh
  8350                              <1> 	;inc	dl
  8351                              <1> 	;out	dx, ax
  8352                              <1> 	;pop	edx
  8353                              <1> 	;retn
  8354                              <1> 
  8355                              <1> 	; 25/11/2020
  8356                              <1> 	; Modified registers: edx
  8357                              <1> 	;push	edx
  8358 0000398F 66BA0100            <1> 	mov	dx, 01h ; VBE_DISPI_INDEX_XRES
  8359                              <1> 	;call	dispi_set_parms
  8360                              <1> 	;pop	edx
  8361                              <1> 	;retn
  8362 00003993 EBE4                <1> 	jmp	short dispi_set_parms
  8363                              <1> 
  8364                              <1> dispi_set_yres:
  8365                              <1> 	; 25/11/2020
  8366                              <1> 	; Input:
  8367                              <1> 	;	ax = Y resolution (screen height)
  8368                              <1> 	;	     (200,400,600,720,768,1080)
  8369                              <1> 	;
  8370                              <1> 	; Modified registers: none
  8371                              <1> 
  8372                              <1> 	;push	edx
  8373                              <1> 	;push	eax
  8374                              <1> 	;mov	dx, 01CEh ; VBE_DISPI_IOPORT_INDEX
  8375                              <1> 	;mov	ax, 02h	  ; VBE_DISPI_INDEX_YRES
  8376                              <1> 	;out	dx, ax
  8377                              <1> 	;pop	eax
  8378                              <1> 	;;mov	dx, 01CFh ; VBE_DISPI_IOPORT_DATA
  8379                              <1> 	;;mov	dl, 0CFh
  8380                              <1> 	;inc	dl
  8381                              <1> 	;out	dx, ax
  8382                              <1> 	;pop	edx
  8383                              <1> 	;retn
  8384                              <1> 
  8385                              <1> 	; 25/11/2020
  8386                              <1> 	; Modified registers: edx
  8387                              <1> 	;push	edx
  8388 00003995 66BA0200            <1> 	mov	dx, 02h  ; VBE_DISPI_INDEX_YRES
  8389                              <1> 	;call	dispi_set_parms
  8390                              <1> 	;pop	edx
  8391                              <1> 	;retn
  8392 00003999 EBDE                <1> 	jmp	short dispi_set_parms
  8393                              <1> 
  8394                              <1> dispi_set_bank:
  8395                              <1> 	; 25/11/2020
  8396                              <1> 	; Input:
  8397                              <1> 	;	ax = video memory bank number
  8398                              <1> 	;
  8399                              <1> 	; Modified registers: none
  8400                              <1> 
  8401                              <1> 	;push	edx
  8402                              <1> 	;push	eax
  8403                              <1> 	;mov	dx, 01CEh ; VBE_DISPI_IOPORT_INDEX
  8404                              <1> 	;mov	ax, 05h	  ; VBE_DISPI_INDEX_BANK
  8405                              <1> 	;out	dx, ax
  8406                              <1> 	;pop	eax
  8407                              <1> 	;;mov	dx, 01CFh ; VBE_DISPI_IOPORT_DATA
  8408                              <1> 	;;mov	dl, 0CFh
  8409                              <1> 	;inc	dl
  8410                              <1> 	;out	dx, ax
  8411                              <1> 	;pop	edx
  8412                              <1> 	;retn
  8413                              <1> 	
  8414                              <1> 	; 25/11/2020
  8415                              <1> 	; Modified registers: edx
  8416                              <1> 	;push	edx
  8417 0000399B 66BA0500            <1> 	mov	dx, 05h  ; VBE_DISPI_INDEX_BANK
  8418                              <1> 	;call	dispi_set_parms
  8419                              <1> 	;pop	edx
  8420                              <1> 	;retn
  8421 0000399F EBD8                <1> 	jmp	short dispi_set_parms
  8422                              <1> 
  8423                              <1> dispi_get_enable:
  8424                              <1> 	; 27/11/2020
  8425                              <1> 	; Input:
  8426                              <1> 	;	none
  8427                              <1> 	; Output:
  8428                              <1> 	;	ax = vbe dispi status
  8429                              <1> 	;
  8430                              <1> 	; Modified registers: eax
  8431                              <1> 	
  8432                              <1> 	;push	edx
  8433                              <1> 	;mov	dx, 01CEh ; VBE_DISPI_IOPORT_INDEX
  8434                              <1> 	;mov	ax, 04h	  ; VBE_DISPI_INDEX_ENABLE
  8435                              <1> 	;out	dx, ax
  8436                              <1> 	;;mov	dx, 01CFh ; VBE_DISPI_IOPORT_DATA
  8437                              <1> 	;;mov	dl, 0CFh
  8438                              <1> 	;inc	dl
  8439                              <1> 	;in	ax, dx
  8440                              <1> 	;pop	edx
  8441                              <1> 	;retn
  8442                              <1> 
  8443                              <1> 	; 27/11/2020
  8444                              <1> 	; Modified registers: eax, edx
  8445                              <1> 	;push	edx
  8446 000039A1 66B80400            <1> 	mov	ax, 04h ; VBE_DISPI_INDEX_ENABLE
  8447                              <1> 	;call	dispi_get_parms
  8448                              <1> 	;pop	edx
  8449                              <1> 	;retn
  8450                              <1> 	;;jmp	short dispi_get_parms
  8451                              <1> 
  8452                              <1> dispi_get_parms:
  8453                              <1> 	; 25/11/2020
  8454                              <1> 	; Input:
  8455                              <1> 	;	ax = vbe dispi register index
  8456                              <1> 	; output:
  8457                              <1> 	;	ax = data
  8458                              <1> 	;
  8459                              <1> 	; Modified registers: eax, edx
  8460                              <1> 
  8461 000039A5 66BACE01            <1> 	mov	dx, 01CEh ; VBE_DISPI_IOPORT_INDEX
  8462 000039A9 66EF                <1> 	out	dx, ax
  8463                              <1> 	;mov	dx, 01CFh ; VBE_DISPI_IOPORT_DATA
  8464                              <1> 	;mov	dl, 0CFh
  8465 000039AB FEC2                <1> 	inc	dl
  8466 000039AD 66ED                <1> 	in	ax, dx
  8467 000039AF C3                  <1> 	retn
  8468                              <1> 
  8469                              <1> vga_compat_setup:
  8470                              <1> 	; 26/11/2020
  8471                              <1> 	; 25/11/2020
  8472                              <1> 	; VGA compatibility setup
  8473                              <1> 	; (vbe.c, 02/01/2020, vruppert)
  8474                              <1> 	;
  8475                              <1> 	; Input:
  8476                              <1> 	;	none
  8477                              <1> 	;
  8478                              <1> 	; Modified registers: eax, edx
  8479                              <1> 	
  8480                              <1> 	; 26/11/2020
  8481                              <1>   	;push	eax
  8482                              <1>   	;push	edx
  8483                              <1> 
  8484                              <1>   	; set CRT X resolution
  8485 000039B0 66BACE01            <1>   	mov	dx, 1CEh ; VBE_DISPI_IOPORT_INDEX
  8486 000039B4 66B80100            <1>   	mov	ax, 01h  ; VBE_DISPI_INDEX_XRES
  8487 000039B8 66EF                <1>   	out	dx, ax
  8488                              <1>   	;mov	dx, 1CFh ; VBE_DISPI_IOPORT_DATA
  8489 000039BA FEC2                <1>   	inc	dl
  8490 000039BC 66ED                <1> 	in	ax, dx
  8491 000039BE 50                  <1> 	push	eax
  8492 000039BF 66BAD403            <1> 	mov	dx, 3D4h ; VGAREG_VGA_CRTC_ADDRESS
  8493 000039C3 66B81100            <1>   	mov	ax, 0011h ; Vertical retrace end register
  8494 000039C7 66EF                <1>   	out	dx, ax
  8495                              <1>   	;pop	eax
  8496                              <1>   	;push	eax
  8497 000039C9 8B0424              <1>   	mov	eax, [esp]
  8498 000039CC 66C1E803            <1> 	shr	ax, 3 ; / 8 for pixel to character
  8499 000039D0 6648                <1>   	dec	ax  ; - 1 (EGA or VGA?)
  8500 000039D2 88C4                <1>   	mov	ah, al
  8501 000039D4 B001                <1>   	mov	al, 01h ; Horizontal display end register
  8502 000039D6 66EF                <1>   	out	dx, ax
  8503 000039D8 58                  <1>   	pop	eax
  8504                              <1> 
  8505 000039D9 E8B0000000          <1> 	call	vga_set_virt_width
  8506                              <1> 
  8507                              <1>   	; set CRT Y resolution
  8508 000039DE 66BACE01            <1>   	mov	dx, 1CEh ; VBE_DISPI_IOPORT_INDEX
  8509 000039E2 66B80200            <1>   	mov	ax, 02h  ; VBE_DISPI_INDEX_YRES
  8510 000039E6 66EF                <1>   	out	dx, ax
  8511                              <1>   	;mov	dx, 1CFh ; VBE_DISPI_IOPORT_DATA
  8512 000039E8 FEC2                <1>   	inc	dl
  8513 000039EA 66ED                <1> 	in	ax, dx
  8514 000039EC 50                  <1> 	push	eax
  8515 000039ED 66BAD403            <1> 	mov	dx, 3D4h ; VGAREG_VGA_CRTC_ADDRESS
  8516 000039F1 88C4                <1>   	mov	ah, al
  8517 000039F3 B012                <1> 	mov	al, 12h ; Vertical display end register
  8518 000039F5 66EF                <1>   	out	dx, ax
  8519 000039F7 58                  <1>   	pop	eax
  8520 000039F8 B007                <1>   	mov	al, 07h	; Overflow register
  8521 000039FA EE                  <1>   	out	dx, al
  8522 000039FB 6642                <1>   	inc	dx
  8523 000039FD EC                  <1>   	in	al, dx ; read overflow register
  8524 000039FE 24BD                <1>   	and	al, 0BDh ; clear VDE 9th and 10th bits	
  8525 00003A00 F6C401              <1>   	test	ah, 01h
  8526 00003A03 7402                <1>   	jz	short bit8_clear
  8527 00003A05 0C02                <1>   	or	al, 02h ; VDE 9th bit (bit 8) in bit 1
  8528                              <1> bit8_clear:
  8529 00003A07 F6C402              <1>   	test	ah, 02h
  8530 00003A0A 7402                <1>   	jz	short bit9_clear
  8531 00003A0C 0C40                <1>   	or	al, 40h ; VDE 10th bit (bit 9) in bit 6
  8532                              <1> bit9_clear:
  8533 00003A0E EE                  <1>   	out	dx, al
  8534                              <1> 
  8535                              <1>   	; other settings
  8536 00003A0F 66BAD403            <1>  	mov	dx, 3D4h ; VGAREG_VGA_CRTC_ADDRESS
  8537 00003A13 66B80900            <1>   	mov	ax, 0009h ; Maximum scan line register
  8538 00003A17 66EF                <1>   	out	dx, ax	; Reset
  8539 00003A19 B017                <1>   	mov	al, 17h ; Mode control register		
  8540 00003A1B EE                  <1>   	out	dx, al
  8541                              <1>  	;mov	dx, 3D5h ; VGAREG_VGA_CRTC_DATA
  8542 00003A1C FEC2                <1>   	inc	dl
  8543 00003A1E EC                  <1> 	in	al, dx	; Read mode control register
  8544 00003A1F 0C03                <1>   	or	al, 03h ; Set SRS and CMS bits
  8545 00003A21 EE                  <1>   	out	dx, al 
  8546 00003A22 66BADA03            <1>   	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  8547 00003A26 EC                  <1>   	in	al, dx	 ; clear flip-flop
  8548 00003A27 66BAC003            <1>   	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  8549 00003A2B B010                <1>   	mov	al, 10h	; Mode control register
  8550 00003A2D EE                  <1>   	out	dx, al
  8551                              <1> 	;mov	dx, 3C1h ; VGAREG_ACTL_READ_DATA
  8552 00003A2E FEC2                <1> 	inc	dl
  8553 00003A30 EC                  <1> 	in	al, dx
  8554 00003A31 0C01                <1> 	or	al, 01h ; select graphics mode
  8555                              <1> 	;mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  8556 00003A33 FECA                <1> 	dec	dl
  8557 00003A35 EE                  <1> 	out	dx, al ; Write to mode control register
  8558 00003A36 B020                <1> 	mov	al, 20h ; Palette RAM <-> display memory
  8559 00003A38 EE                  <1> 	out	dx, al ; Write to attribute addr register
  8560 00003A39 66BACE03            <1> 	mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  8561 00003A3D 66B80605            <1> 	mov	ax, 0506h ; Misc. register, graph, mm 1
  8562 00003A41 66EF                <1> 	out	dx, ax
  8563 00003A43 66BAC403            <1> 	mov	dx, 3C4h ; VGAREG_SEQU_ADDRESS
  8564 00003A47 66B8020F            <1> 	mov	ax, 0F02h ; Map mask register, all planes
  8565 00003A4B 66EF                <1> 	out	dx, ax
  8566                              <1> 
  8567                              <1>   	; settings for >= 8bpp
  8568                              <1> 
  8569                              <1> 	;mov	dx, 1CEh ; VBE_DISPI_IOPORT_INDEX
  8570                              <1> 	;mov	ax, 03h ; VBE_DISPI_INDEX_BPP
  8571                              <1> 	;out	dx, ax
  8572                              <1> 	;;mov	dx, 1CFh ; VBE_DISPI_IOPORT_DATA
  8573                              <1> 	;inc	dl
  8574                              <1> 	;in	ax, dx
  8575                              <1> 	;cmp	al, 08h  ; < 8 bits per pixel
  8576                              <1> 	;jb	short vga_compat_end
  8577                              <1> 
  8578 00003A4D 66BAD403            <1> 	mov	dx, 3D4h ; VGAREG_VGA_CRTC_ADDRESS
  8579 00003A51 B014                <1> 	mov	al, 14h  ; Underline location register
  8580 00003A53 EE                  <1> 	out	dx, al
  8581                              <1> 	;mov	dx, 3D5h ; VGAREG_VGA_CRTC_DATA
  8582 00003A54 FEC2                <1> 	inc	dl
  8583 00003A56 EC                  <1> 	in	al, dx	
  8584 00003A57 0C40                <1> 	or	al, 40h	 ; enable double word mode
  8585 00003A59 EE                  <1> 	out	dx, al
  8586 00003A5A 66BADA03            <1> 	mov	dx, 3DAh ; VGAREG_ACTL_RESET
  8587 00003A5E EC                  <1> 	in	al, dx	 ; clear flip-flop
  8588 00003A5F 66BAC003            <1> 	mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  8589 00003A63 B010                <1> 	mov	al, 10h	 ; Mode control register
  8590 00003A65 EE                  <1> 	out	dx, al
  8591                              <1> 	;mov	dx, 3C1h ; VGAREG_ACTL_READ_DATA
  8592 00003A66 FEC2                <1> 	inc	dl
  8593 00003A68 EC                  <1> 	in	al, dx
  8594 00003A69 0C40                <1> 	or	al, 40h  ; Pixel clock select is 1 	
  8595                              <1> 	;mov	dx, 3C0h ; VGAREG_ACTL_ADDRESS
  8596 00003A6B FECA                <1> 	dec	dl
  8597 00003A6D EE                  <1> 	out	dx, al	 ; update mode control reggister
  8598 00003A6E B020                <1> 	mov	al, 20h	 ; select display memory as PAS	
  8599 00003A70 EE                  <1> 	out	dx, al
  8600 00003A71 66BAC403            <1> 	mov	dx, 3C4h ; VGAREG_SEQU_ADDRESS
  8601 00003A75 B004                <1> 	mov	al, 04h	; Memory mode register
  8602 00003A77 EE                  <1> 	out	dx, al
  8603                              <1> 	;mov	dx, 3C5h ; VGAREG_SEQU_DATA
  8604 00003A78 FEC2                <1> 	inc	dl
  8605 00003A7A EC                  <1> 	in	al, dx
  8606 00003A7B 0C08                <1> 	or	al, 08h	; enable chain four
  8607 00003A7D EE                  <1> 	out	dx, al
  8608 00003A7E 66BACE03            <1> 	mov	dx, 3CEh ; VGAREG_GRDC_ADDRESS
  8609 00003A82 B005                <1> 	mov	al, 05h	 ; Mode register	
  8610 00003A84 EE                  <1> 	out	dx, al
  8611                              <1> 	;mov	dx, 3CFh ; VGAREG_GRDC_DATA
  8612 00003A85 FEC2                <1> 	inc	dl
  8613 00003A87 EC                  <1> 	in	al, dx	
  8614 00003A88 249F                <1> 	and	al, 9Fh	 ; clear shift register 
  8615 00003A8A 0C40                <1> 	or	al, 40h  ; set shift register to 2
  8616 00003A8C EE                  <1> 	out	dx, al
  8617                              <1> 
  8618                              <1> vga_compat_end:
  8619                              <1>   	;pop	edx
  8620                              <1>   	;pop	eax
  8621 00003A8D C3                  <1> 	retn
  8622                              <1> 
  8623                              <1> vga_set_virt_width:
  8624                              <1> 	; 27/11/2020
  8625                              <1> 	; 25/11/2020
  8626                              <1> 	; (vbe.c, 02/01/2020, vruppert)
  8627                              <1> 	;
  8628                              <1> 	; Input:
  8629                              <1> 	;	AX = resolution (screen width)
  8630                              <1> 	;
  8631                              <1> 	; Modified registers: eax, edx
  8632                              <1> 
  8633                              <1>   	;;push	ebx
  8634                              <1>   	;push	edx
  8635                              <1> 	;push	eax
  8636                              <1>   	;mov	ebx, eax
  8637                              <1>   	;call	dispi_get_bpp ; bits per pixel
  8638                              <1> 	;cmp	al, 4
  8639                              <1> 	;ja	short set_width_svga  ; 8, 16, 24, 32 
  8640                              <1> 	;shr	bx, 1
  8641                              <1> ;set_width_svga:
  8642                              <1> 	;shr	bx, 3
  8643                              <1> 	;mov	eax, [esp]
  8644 00003A8E 66C1E803            <1> 	shr	ax, 3	; / 8, bytes per row
  8645 00003A92 66BAD403            <1> 	mov	dx, 3D4h ; VGAREG_VGA_CRTC_ADDRESS
  8646                              <1> 	;mov	ah, bl	; 
  8647 00003A96 88C4                <1> 	mov	ah, al	; width in bytes
  8648 00003A98 B013                <1> 	mov	al, 13h	; offset register
  8649 00003A9A 66EF                <1> 	out	dx, ax	; index (3D4h) and data (3D5h)
  8650                              <1> 	;pop	eax
  8651                              <1> 	;pop  	edx
  8652                              <1> 	;;pop	ebx
  8653 00003A9C C3                  <1> 	retn
  8654                              <1> 
  8655                              <1> ; 24/11/2020
  8656                              <1> 
  8657                              <1> struc bmi ; BOCHS/PLEX86 MODE INFO structure/table 
  8658 00000000 <res 00000002>      <1>  .mode:	  resw 1
  8659 00000002 <res 00000002>      <1>  .width:  resw 1
  8660 00000004 <res 00000002>      <1>  .height: resw 1
  8661 00000006 <res 00000002>      <1>  .depth:  resw 1
  8662                              <1>  .size:	
  8663                              <1> endstruc
  8664                              <1> 
  8665                              <1> ; 24/11/2020
  8666                              <1> struc MODEINFO
  8667 00000000 <res 00000002>      <1>  .mode:			resw 1  ; 1XXh
  8668 00000002 <res 00000002>      <1>  .ModeAttributes:	resw 1
  8669 00000004 <res 00000001>      <1>  .WinAAttributes:	resb 1
  8670 00000005 <res 00000001>      <1>  .WinBAttributes:	resb 1	; = 0
  8671 00000006 <res 00000002>      <1>  .WinGranularity:	resw 1
  8672 00000008 <res 00000002>      <1>  .WinSize:		resw 1
  8673 0000000A <res 00000002>      <1>  .WinASegment:		resw 1
  8674 0000000C <res 00000002>      <1>  .WinBSegment:		resw 1	; = 0
  8675 0000000E <res 00000004>      <1>  .WinFuncPtr:		resd 1	; = 0
  8676 00000012 <res 00000002>      <1>  .BytesPerScanLine:	resw 1
  8677 00000014 <res 00000002>      <1>  .XResolution:		resw 1
  8678 00000016 <res 00000002>      <1>  .YResolution:		resw 1
  8679 00000018 <res 00000001>      <1>  .XCharSize:		resb 1
  8680 00000019 <res 00000001>      <1>  .YCharSize:		resb 1
  8681 0000001A <res 00000001>      <1>  .NumberOfPlanes: 	resb 1
  8682 0000001B <res 00000001>      <1>  .BitsPerPixel:		resb 1
  8683 0000001C <res 00000001>      <1>  .NumberOfBanks:	resb 1
  8684 0000001D <res 00000001>      <1>  .MemoryModel:		resb 1
  8685 0000001E <res 00000001>      <1>  .BankSize:		resb 1	; = 0
  8686 0000001F <res 00000001>      <1>  .NumberOfImagePages: 	resb 1
  8687 00000020 <res 00000001>      <1>  .Reserved_page:	resb 1	; = 0
  8688 00000021 <res 00000001>      <1>  .RedMaskSize:		resb 1
  8689 00000022 <res 00000001>      <1>  .RedFieldPosition: 	resb 1
  8690 00000023 <res 00000001>      <1>  .GreenMaskSize:	resb 1
  8691 00000024 <res 00000001>      <1>  .GreenFieldPosition: 	resb 1
  8692 00000025 <res 00000001>      <1>  .BlueMaskSize:		resb 1
  8693 00000026 <res 00000001>      <1>  .BlueFieldPosition: 	resb 1
  8694 00000027 <res 00000001>      <1>  .RsvdMaskSize:		resb 1
  8695 00000028 <res 00000001>      <1>  .RsvdFieldPosition: 	resb 1
  8696 00000029 <res 00000001>      <1>  .DirectColorModeInfo: 	resb 1
  8697 0000002A <res 00000004>      <1>  .PhysBasePtr:		resd 1
  8698 0000002E <res 00000004>      <1>  .OffScreenMemOffset: 	resd 1	; = 0
  8699 00000032 <res 00000002>      <1>  .OffScreenMemSize: 	resw 1	; = 0
  8700 00000034 <res 00000002>      <1>  .LinBytesPerScanLine: 	resw 1
  8701 00000036 <res 00000001>      <1>  .BnkNumberOfPages: 	resb 1
  8702 00000037 <res 00000001>      <1>  .LinNumberOfPages: 	resb 1
  8703 00000038 <res 00000001>      <1>  .LinRedMaskSize:	resb 1
  8704 00000039 <res 00000001>      <1>  .LinRedFieldPosition1: resb 1
  8705 0000003A <res 00000001>      <1>  .LinGreenMaskSize1: 	resb 1
  8706 0000003B <res 00000001>      <1>  .LinGreenFieldPosition:resb 1
  8707 0000003C <res 00000001>      <1>  .LinBlueMaskSize: 	resb 1
  8708 0000003D <res 00000001>      <1>  .LinBlueFieldPosition:	resb 1
  8709 0000003E <res 00000001>      <1>  .LinRsvdMaskSize: 	resb 1
  8710 0000003F <res 00000001>      <1>  .LinRsvdFieldPosition:	resb 1
  8711 00000040 <res 00000004>      <1>  .MaxPixelClock:	resd 1	; = 0
  8712                              <1> .size:
  8713                              <1> endstruc
  8714                              <1> 
  8715                              <1> ; 10/12/2020
  8716                              <1> struc LFBINFO
  8717 00000000 <res 00000002>      <1>  .mode:			resw 1  ; 1XXh
  8718 00000002 <res 00000004>      <1>  .LFB_addr:		resd 1
  8719 00000006 <res 00000004>      <1>  .LFB_size:		resd 1
  8720 0000000A <res 00000002>      <1>  .X_res:		resw 1
  8721 0000000C <res 00000002>      <1>  .Y_res:		resw 1
  8722 0000000E <res 00000001>      <1>  .bpp:			resb 1
  8723 0000000F <res 00000001>      <1>  .reserved:		resb 1
  8724                              <1> .size:	; 16 bytes
  8725                              <1> endstruc
  8726                              <1> 
  8727                              <1> set_mode_info_list:
  8728                              <1> 	; 14/12/2020
  8729                              <1> 	; 11/12/2020
  8730                              <1> 	; 24/11/2020
  8731                              <1> 	; (vbetables-gen.c)
  8732                              <1> 	; Input:
  8733                              <1> 	;	BX = VBE mode (including bochs special modes) 
  8734                              <1> 	; Output:
  8735                              <1> 	;	;;EAX = MODE_INFO_LIST address
  8736                              <1> 	;	EAX = 0 ; 11/12/2020
  8737                              <1> 	;	ESI = MODE_INFO_LIST address ; 11/12/2020
  8738                              <1> 	;	(if mode is not found, ESI = 0)
  8739                              <1> 	;
  8740                              <1> 	; Modified registers: eax, ebx, ecx, edx, esi, edi 
  8741                              <1> 
  8742 00003A9D BE[266D0000]        <1> 	mov	esi, b_vbe_modes ; bochs mode info base table	
  8743 00003AA2 BF[BA110300]        <1> 	mov	edi, MODE_INFO_LIST ; mode info list (4F01h)
  8744                              <1> sml_0:
  8745 00003AA7 66AD                <1> 	lodsw	
  8746 00003AA9 6639D8              <1> 	cmp	ax, bx ; is mode number same ?
  8747 00003AAC 7410                <1> 	je	short sml_1 ; yes
  8748 00003AAE AD                  <1> 	lodsd
  8749 00003AAF 66AD                <1> 	lodsw	
  8750 00003AB1 81FE[E66D0000]      <1> 	cmp	esi, end_of_b_vbe_modes
  8751 00003AB7 72EE                <1> 	jb	short sml_0
  8752                              <1> 	; not found
  8753 00003AB9 31C0                <1> 	xor	eax, eax ; 0
  8754                              <1> 	; 11/12/2020
  8755 00003ABB 31F6                <1> 	xor	esi, esi
  8756 00003ABD C3                  <1> 	retn
  8757                              <1> sml_1:
  8758 00003ABE 66AB                <1> 	stosw	; mode
  8759 00003AC0 AD                  <1> 	lodsd	; width, height
  8760                              <1> 	; 14/12/2020
  8761 00003AC1 89C1                <1> 	mov	ecx, eax
  8762 00003AC3 50                  <1> 	push	eax ; ***
  8763 00003AC4 29C0                <1> 	sub	eax, eax ; clear high word of eax
  8764 00003AC6 66AD                <1> 	lodsw	; depth
  8765 00003AC8 50                  <1> 	push	eax ; **
  8766                              <1> 
  8767                              <1> 	;add	al, 7 ; only for 15 bit colors (not used here)
  8768 00003AC9 C0E803              <1> 	shr	al, 3 ; / 8
  8769                              <1> 	; 14/12/2020
  8770 00003ACC 66F7E1              <1> 	mul	cx  ; pitch = width * ((depth+7)/8)
  8771                              <1> 		; ax = pitch
  8772 00003ACF 50                  <1> 	push	eax ; * ; high word of eax = 0
  8773 00003AD0 C1E910              <1> 	shr	ecx, 16
  8774                              <1> 	;mul	cx
  8775                              <1> 	;mov	cx, ax
  8776 00003AD3 31D2                <1> 	xor	edx, edx  ; clear high word of edx
  8777 00003AD5 F7E1                <1> 	mul	ecx ; height * pitch
  8778 00003AD7 89C1                <1> 	mov	ecx, eax
  8779 00003AD9 B800000001          <1> 	mov	eax, VBE_DISPI_TOTAL_VIDEO_MEMORY_MB * 1024 * 1024
  8780 00003ADE F7F1                <1> 	div	ecx
  8781                              <1> 		; eax = pages = vram_size / (height*pitch)
  8782                              <1> 	
  8783                              <1> 	;mov	cx, ax
  8784 00003AE0 89C1                <1> 	mov	ecx, eax ; pages 
  8785                              <1> 		
  8786 00003AE2 66B89B00            <1> 	mov	ax, MODE_ATTRIBUTES
  8787 00003AE6 66AB                <1> 	stosw	; ModeAttributes
  8788 00003AE8 B007                <1> 	mov	al, WINA_ATTRIBUTES
  8789 00003AEA AA                  <1> 	stosb	; WinAAttributes
  8790 00003AEB 30C0                <1> 	xor	al, al ; WinBAttributes = 0
  8791 00003AED AA                  <1> 	stosb
  8792 00003AEE 66B84000            <1> 	mov	ax, VBE_DISPI_BANK_SIZE_KB
  8793 00003AF2 66AB                <1> 	stosw	; WinGranularity
  8794 00003AF4 66AB                <1> 	stosw	; WinSize
  8795 00003AF6 66B800A0            <1> 	mov	ax, VGAMEM_GRAPH
  8796 00003AFA 66AB                <1> 	stosw	; WinASegment
  8797 00003AFC 29C0                <1> 	sub	eax, eax
  8798 00003AFE 66AB                <1> 	stosw	; WinBSegment = 0
  8799 00003B00 AB                  <1> 	stosd	; WinFuncPtr = 0
  8800                              <1> 
  8801 00003B01 58                  <1> 	pop	eax ; * ; pitch
  8802 00003B02 89C3                <1> 	mov	ebx, eax  ; high word of ebx = 0 ; 14/12/2020
  8803 00003B04 66AB                <1> 	stosw	; BytesPerScanLine
  8804                              <1> 
  8805 00003B06 5A                  <1> 	pop	edx ; ** ; depth (bits per pixel)
  8806 00003B07 58                  <1> 	pop	eax ; *** width, height
  8807                              <1> 
  8808                              <1>  	; // Mandatory information for VBE 1.2 and above
  8809                              <1> 
  8810 00003B08 66AB                <1> 	stosw	; XResolution (width)
  8811 00003B0A C1E810              <1> 	shr	eax, 16
  8812 00003B0D 50                  <1> 	push	eax ; **** height
  8813 00003B0E 66AB                <1> 	stosw	; YResolution (height)
  8814 00003B10 B008                <1> 	mov	al, 8
  8815 00003B12 AA                  <1>  	stosb	; XCharSize  ; char width
  8816 00003B13 B010                <1> 	mov	al, 16
  8817 00003B15 AA                  <1> 	stosb	; YCharSize  ; char height
  8818 00003B16 B001                <1> 	mov	al, 1
  8819 00003B18 AA                  <1> 	stosb	; NumberOfPlanes
  8820                              <1> 	;movzx	eax, dl
  8821 00003B19 88D0                <1> 	mov	al, dl ; eax <= 32
  8822 00003B1B AA                  <1> 	stosb	; BitsPerPixel
  8823                              <1> 	; Number of banks = (height * pitch + 65535) / 65536
  8824 00003B1C 58                  <1> 	pop	eax ; **** ; height
  8825                              <1> 	; 14/12/2020
  8826 00003B1D 52                  <1> 	push	edx ; ***** ; depth ; edx <= 32
  8827 00003B1E F7E3                <1> 	mul	ebx  ; pitch (ebx) * height (eax)
  8828                              <1> 	;mov	edx, [esp] ; *****
  8829                              <1> 	;mov	dl, [esp] ; *****
  8830 00003B20 05FFFF0000          <1> 	add	eax, 65535
  8831 00003B25 C1E810              <1> 	shr	eax, 16 ; / 65536 ; <= 127 ; 14/12/2020
  8832 00003B28 AA                  <1> 	stosb	; NumberOfBanks
  8833                              <1> 	; 14/12/2020
  8834                              <1> 	;cmp	dl, 8 ; 8 bits per pixel
  8835 00003B29 803C2408            <1> 	cmp	byte [esp], 8
  8836 00003B2D 7704                <1> 	ja	short sml_2
  8837 00003B2F B004                <1> 	mov	al, VBE_MEMORYMODEL_PACKED_PIXEL
  8838 00003B31 EB02                <1> 	jmp	short sml_3
  8839                              <1> sml_2:
  8840                              <1> 	; 16, 24, 32 bts per pixel
  8841 00003B33 B006                <1> 	mov	al, VBE_MEMORYMODEL_DIRECT_COLOR	
  8842                              <1> sml_3:
  8843 00003B35 AA                  <1> 	stosb
  8844 00003B36 30C0                <1> 	xor	al, al ; 0
  8845 00003B38 AA                  <1> 	stosb	; BankSize = 0
  8846 00003B39 49                  <1> 	dec	ecx ; pages - 1
  8847                              <1> 	; NumberOfImagePages = 262 for 320x200x8 mode
  8848                              <1> 	;;mov	ax, 255
  8849                              <1> 	; 14/12/2020
  8850                              <1> 	;mov	al, 255
  8851 00003B3A FEC8                <1> 	dec	al ; 255
  8852 00003B3C 39C1                <1> 	cmp	ecx, eax ; ecx <= 261, eax = 255 
  8853                              <1> 	;cmp	cx, ax
  8854 00003B3E 7302                <1> 	jnb	short sml_4
  8855 00003B40 88C8                <1> 	mov	al, cl	 
  8856                              <1> sml_4:
  8857 00003B42 AA                  <1> 	stosb	; NumberOfImagePages (1 byte)
  8858 00003B43 28C0                <1> 	sub	al, al
  8859 00003B45 AA                  <1> 	stosb	; Reserved_page = 0
  8860 00003B46 58                  <1> 	pop	eax ; ***** ; depth
  8861 00003B47 88C1                <1> 	mov	cl, al
  8862                              <1> 	; eax < = 32
  8863 00003B49 2C08                <1> 	sub	al, 8 ; 8->0, 16->8, 24->16, 32->24	
  8864 00003B4B BE[E66D0000]        <1> 	mov	esi, direct_color_fields
  8865 00003B50 01C6                <1> 	add	esi, eax
  8866 00003B52 56                  <1> 	push	esi ; ******
  8867 00003B53 AD                  <1> 	lodsd	; RedMaskSize (AL), RedFieldPosition (AH)
  8868                              <1> 	     	; GreenMaskSize (16), GreenFieldPosition (24)	
  8869 00003B54 AB                  <1> 	stosd
  8870 00003B55 AD                  <1> 	lodsd	; BlueMaskSize (AL), BlueFieldPosition (AH)
  8871                              <1> 	     	; RsvdMaskSize (16), RsvdFieldPosition (24)
  8872 00003B56 AB                  <1> 	stosd
  8873 00003B57 5E                  <1> 	pop	esi ; ******
  8874                              <1> 
  8875 00003B58 30C0                <1> 	xor	al, al ; 0
  8876 00003B5A 80F920              <1> 	cmp	cl, 32
  8877 00003B5D 7202                <1> 	jb	short sml_5
  8878 00003B5F B002                <1> 	mov	al, VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE
  8879                              <1> sml_5: 
  8880 00003B61 AA                  <1> 	stosb	; DirectColorModeInfo
  8881                              <1> 
  8882                              <1> 	; // Mandatory information for VBE 2.0 and above
  8883                              <1> 
  8884 00003B62 B8000000E0          <1> 	mov	eax, VBE_DISPI_LFB_PHYSICAL_ADDRESS
  8885 00003B67 AB                  <1> 	stosd	; PhysBasePtr
  8886 00003B68 29C0                <1> 	sub	eax, eax
  8887 00003B6A AB                  <1> 	stosd	; OffScreenMemOffset = 0
  8888 00003B6B 66AB                <1> 	stosw	; OffScreenMemSize = 0
  8889                              <1> 
  8890                              <1> 	;// Mandatory information for VBE 3.0 and above
  8891                              <1> 
  8892                              <1> 	; ebx = pitch
  8893 00003B6D 6689D8              <1> 	mov	ax, bx
  8894                              <1> 	;stosw
  8895                              <1> 
  8896                              <1> 	;xor	al, al
  8897                              <1>      	;stosb	; BnkNumberOfPages = 0
  8898                              <1>      	;stosb	; LinNumberOfPages = 0
  8899                              <1> 
  8900 00003B70 AB                  <1> 	stosd	; pitch (word), 0 (byte), 0 (byte)  
  8901                              <1> 
  8902 00003B71 AD                  <1> 	lodsd	; LinRedMaskSize (AL), LinRedFieldPosition (AH)
  8903                              <1> 	     	; LinGreenMaskSize (16), LinGreenFieldPosition (24)	
  8904 00003B72 AB                  <1> 	stosd
  8905 00003B73 AD                  <1> 	lodsd	; LinBlueMaskSize (AL), LinBlueFieldPosition (AH)
  8906                              <1> 	     	; LinRsvdMaskSize (16), LinRsvdFieldPosition (24)
  8907 00003B74 AB                  <1> 	stosd
  8908                              <1> 
  8909 00003B75 29C0                <1> 	sub	eax, eax
  8910 00003B77 AB                  <1> 	stosd	; MaxPixelClock = 0
  8911                              <1> 
  8912                              <1> 	;mov	eax, MODE_INFO_LIST
  8913                              <1> 	; 11/12/2020
  8914 00003B78 BE[BA110300]        <1> 	mov	esi, MODE_INFO_LIST
  8915                              <1> 	
  8916 00003B7D C3                  <1> 	retn	
  8917                              <1> 
  8918                              <1> ; end of set_mode_info_list ; edi = set_mode_info_list + 68
  8919                              <1> 
  8920                              <1> pci_get_lfb_addr:
  8921                              <1> 	; 11/12/2020
  8922                              <1> 	; Get linear frame buffer base from PCI
  8923                              <1> 	; (vgabios.c, 02/01/2020, vruppert)
  8924                              <1> 	;
  8925                              <1> 	; Input:
  8926                              <1> 	;	ax = PCI device vendor id
  8927                              <1> 	; Output:
  8928                              <1> 	;	ax  = LFB address (high 16 bit) (zf=0)
  8929                              <1> 	;	eax = 0 -> not found (error) (zf=1)
  8930                              <1> 	;
  8931                              <1> 	; Modified registers: eax
  8932                              <1> 
  8933 00003B7E 53                  <1> 	push	ebx
  8934 00003B7F 51                  <1> 	push	ecx
  8935 00003B80 52                  <1> 	push	edx
  8936                              <1> 	;
  8937 00003B81 89C3                <1> 	mov	ebx, eax
  8938 00003B83 31C9                <1> 	xor	ecx, ecx
  8939 00003B85 28D2                <1> 	sub	dl, dl	; mov dl, 0
  8940 00003B87 E842000000          <1> 	call	pci_read_reg
  8941 00003B8C 6683F8FF            <1> 	cmp	ax, 0FFFFh
  8942 00003B90 7417                <1> 	je	short pci_get_lfb_addr_fail
  8943                              <1> pci_get_lfb_addr_next_dev:
  8944 00003B92 28D2                <1> 	sub	dl, dl ; mov dl, 0
  8945 00003B94 E835000000          <1> 	call	pci_read_reg
  8946 00003B99 6639D8              <1> 	cmp	ax, bx	; check vendor
  8947 00003B9C 740F                <1> 	je	short pci_get_lfb_addr_found
  8948 00003B9E 6683C108            <1> 	add	cx, 08h
  8949 00003BA2 6681F90002          <1> 	cmp	cx, 200h ; search bus 0 and 1
  8950 00003BA7 72E9                <1> 	jb	short pci_get_lfb_addr_next_dev
  8951                              <1> pci_get_lfb_addr_fail:
  8952 00003BA9 31C0                <1> 	xor	eax, eax ; no LFB
  8953                              <1> 	; zf = 1
  8954 00003BAB EB1D                <1> 	jmp	short pci_get_lfb_addr_return
  8955                              <1> pci_get_lfb_addr_found:
  8956 00003BAD B210                <1> 	mov	dl, 10h	; I/O space 0
  8957 00003BAF E81A000000          <1> 	call	pci_read_reg
  8958 00003BB4 66A9F1FF            <1> 	test	ax, 0FFF1h
  8959 00003BB8 740D                <1> 	jz	short pci_get_lfb_addr_success
  8960 00003BBA B214                <1> 	mov	dl, 14h ; I/O space 1
  8961 00003BBC E80D000000          <1> 	call	pci_read_reg
  8962 00003BC1 66A9F1FF            <1> 	test	ax, 0FFF1h
  8963 00003BC5 75E2                <1> 	jnz	short pci_get_lfb_addr_fail
  8964                              <1> pci_get_lfb_addr_success:
  8965 00003BC7 C1E810              <1> 	shr	eax, 16 ; LFB address (hw)
  8966                              <1> 	; zf = 0
  8967                              <1> pci_get_lfb_addr_return:
  8968 00003BCA 5A                  <1> 	pop	edx
  8969 00003BCB 59                  <1> 	pop	ecx
  8970 00003BCC 5B                  <1> 	pop	ebx
  8971 00003BCD C3                  <1> 	retn
  8972                              <1> 
  8973                              <1> pci_read_reg:
  8974                              <1> 	; 11/12/2020
  8975                              <1> 	; Read PCI register
  8976                              <1> 	; (vgabios.c, 02/01/2020, vruppert)
  8977                              <1> 	;
  8978                              <1> 	; Input:
  8979                              <1> 	;	cx = device/function
  8980                              <1> 	;	dl = register
  8981                              <1> 	; Output:
  8982                              <1> 	;	eax = value
  8983                              <1> 	;
  8984                              <1> 	; Modified registers: eax, edx
  8985                              <1> 
  8986 00003BCE B800008000          <1> 	mov	eax, 00800000h 
  8987 00003BD3 6689C8              <1> 	mov	ax, cx
  8988 00003BD6 C1E008              <1> 	shl	eax, 8
  8989 00003BD9 88D0                <1> 	mov	al, dl
  8990 00003BDB 66BAF80C            <1> 	mov	dx, 0CF8h
  8991 00003BDF EF                  <1>  	out	dx, eax
  8992 00003BE0 80C204              <1> 	add	dl, 4 ; mov dx, 0CFCh
  8993 00003BE3 ED                  <1> 	in	eax, dx
  8994 00003BE4 C3                  <1> 	retn
  8995                              <1> 
  8996                              <1> %endif
  8997                              <1> 
  8998                              <1> ; -----------
  8999                              <1> 
  9000                              <1> %if 0
  9001                              <1> 
  9002                              <1> mode_info_find_mode:
  9003                              <1> 	; 25/11/2020
  9004                              <1> 	; Input:
  9005                              <1> 	;	bx = VESA VBE2 video mode (+ bochs extensions)
  9006                              <1> 	; Output:
  9007                              <1> 	;	esi = mode info address (for BX input)
  9008                              <1> 	;	esi = 0 -> not found
  9009                              <1> 	;
  9010                              <1> 	; Modified registers: eax, esi
  9011                              <1> 
  9012                              <1> 	xor	eax, eax
  9013                              <1> 	mov	esi, MODE_INFO_LIST
  9014                              <1> mifm_1:
  9015                              <1> 	mov	ax, [esi]
  9016                              <1> 	cmp	ax, bx
  9017                              <1> 	je	short mifm_2
  9018                              <1> 	add	esi, MODEINFO.size ; add esi, 68
  9019                              <1> 	cmp	esi, VBE_VESA_MODE_END_OF_LIST
  9020                              <1> 	jb	short mifm_1
  9021                              <1> 	; not found
  9022                              <1> 	sub	esi, esi ; 0
  9023                              <1> mifm_2
  9024                              <1> 	retn
  9025                              <1> 
  9026                              <1> dispi_get_bpp:
  9027                              <1> 	; 28/11/2020
  9028                              <1> 	; Input:
  9029                              <1> 	;	none
  9030                              <1> 	; Output:
  9031                              <1> 	;	al = Bits per pixel
  9032                              <1> 	;	     (8,16,24,32)
  9033                              <1> 	;	ah = Bytes per pixel
  9034                              <1> 	;	     (1,2,3,4)	
  9035                              <1> 	;
  9036                              <1> 	; Modified registers: none
  9037                              <1> 
  9038                              <1> 	;push	edx
  9039                              <1> 	;mov	dx, 01CEh ; VBE_DISPI_IOPORT_INDEX
  9040                              <1> 	;mov	ax, 03h	  ; VBE_DISPI_INDEX_BPP
  9041                              <1> 	;out	dx, ax
  9042                              <1> 	;;mov	dx, 01CFh ; VBE_DISPI_IOPORT_DATA
  9043                              <1> 	;;mov	dl, 0CFh
  9044                              <1> 	;inc	dl
  9045                              <1> 	;in	ax, dx
  9046                              <1> 	;mov	ah, al
  9047                              <1> 	;shr	ah, 3 ; / 8
  9048                              <1> 	;;test	al, 7 ; 15 bit graphics mode
  9049                              <1>  	;;jz	short get_bpp_noinc
  9050                              <1> 	;;inc	ah
  9051                              <1> ;;get_bpp_noinc:
  9052                              <1> 	;pop	edx
  9053                              <1> 	;retn
  9054                              <1> 
  9055                              <1> 	; 28/11/2020
  9056                              <1> 	; Modified registers: edx
  9057                              <1> 	;push	edx
  9058                              <1> 	mov	dx, 03h ; VBE_DISPI_INDEX_BPP
  9059                              <1> 	call	dispi_get_parms
  9060                              <1> 	;pop	edx
  9061                              <1> 	;retn
  9062                              <1> 	mov	ah, al
  9063                              <1> 	shr	ah, 3 ; / 8
  9064                              <1> 	;test	al, 7 ; 15 bit graphips mode
  9065                              <1>  	;jz	short get_bpp_noinc
  9066                              <1> 	;inc	ah
  9067                              <1> ;get_bpp_noinc:
  9068                              <1> 	;pop	edx
  9069                              <1> 	retn
  9070                              <1> 
  9071                              <1> restore_vesa_video_state:
  9072                              <1> 	; 06/12/2020
  9073                              <1> 	; Input:
  9074                              <1> 	;	[mode3stbufsize] <= 32 ; <= 32*64 bytes
  9075                              <1> 	; Output:
  9076                              <1> 	;	AX = 004Fh (successed)
  9077                              <1> 	;
  9078                              <1> 	;	eax = 0 -> buffer size problem
  9079                              <1> 	;	eax > 0 and ax <> 004Fh -> failed
  9080                              <1> 	;
  9081                              <1> 	; Modified regs: eax, ebx, ecx, edx, esi, edi 
  9082                              <1> 
  9083                              <1> 	;movzx	ecx, word [mode3stbufsize]  
  9084                              <1> 	;cmp	cx, 32 ; 32 * 64 bytes
  9085                              <1> 	;ja	short r_v_b_s_fail
  9086                              <1> 
  9087                              <1> 	movzx	ecx, byte [mode3stbufsize]; <=32	
  9088                              <1> 	shl	cx, 4 ; dword count for movsd
  9089                              <1> 	mov	edi, VBE3SAVERESTOREBLOCK ; destination
  9090                              <1> 					; (vbe3 pmi buff)
  9091                              <1> 	mov	esi, VBE3MODE3STATE ; source (kernel buff)
  9092                              <1> 	rep	movsd	
  9093                              <1> 
  9094                              <1> 	mov	ax, 4F02h
  9095                              <1> 	mov	dl, 02h ; restore
  9096                              <1> 	;mov	cx, 0Fh
  9097                              <1> 	mov	cl, 0Fh
  9098                              <1> 	xor 	ebx, ebx ; points to VBE3SAVERESTOREBLOCK
  9099                              <1> 	jmp	short int10h_32bit_pmi
  9100                              <1> 
  9101                              <1> ;s_v_b_s_fail:
  9102                              <1> ;r_v_b_s_fail:
  9103                              <1> ;	xor	eax, eax
  9104                              <1> ;	retn
  9105                              <1> 
  9106                              <1> save_vesa_video_state:
  9107                              <1> 	; 06/12/2020
  9108                              <1> 	; Input:
  9109                              <1> 	;	[mode3stbufsize] <= 32 ; <= 32*64 bytes
  9110                              <1> 	; Output:
  9111                              <1> 	;	AX = 004Fh (successed)
  9112                              <1> 	;
  9113                              <1> 	;	eax = 0 -> buffer size problem
  9114                              <1> 	;	eax > 0 and ax <> 004Fh -> failed
  9115                              <1> 	;
  9116                              <1> 	; Modified regs: eax, ebx, ecx, edx, esi, edi 
  9117                              <1> 
  9118                              <1> 	;cmp	word [mode3stbufsize], 32  
  9119                              <1> 	;			; 32 * 64 bytes
  9120                              <1> 	;ja	short s_v_b_s_fail
  9121                              <1> 
  9122                              <1> 	mov	ax, 4F02h
  9123                              <1> 	mov	dl, 01h ; save
  9124                              <1> 	;mov	cx, 0Fh
  9125                              <1> 	mov	cl, 0Fh
  9126                              <1> 	xor 	ebx, ebx ; points to VBE3SAVERESTOREBLOCK
  9127                              <1> 
  9128                              <1> 	call	int10h_32bit_pmi
  9129                              <1> 
  9130                              <1> 	movzx	ecx, byte [mode3stbufsize]; <=32	
  9131                              <1> 	shl	cx, 4 ; dword count for movsd
  9132                              <1> 	mov	esi, VBE3SAVERESTOREBLOCK ; destination
  9133                              <1> 					; (vbe3 pmi buff)
  9134                              <1> 	mov	edi, VBE3MODE3STATE ; source (kernel buff)
  9135                              <1> 	rep	movsd	
  9136                              <1> 	retn
  9137                              <1> 
  9138                              <1> dispi_set_bank_farcall:
  9139                              <1> 	; 11/12/2020
  9140                              <1> 	; (This may be 'sysvideo' function, later)
  9141                              <1> 	;
  9142                              <1> 	; Input: 
  9143                              <1> 	;	bx = 0000h, set bank number
  9144                              <1> 	;	   = 0100h, get bank number
  9145                              <1> 	;	dx = bank number (if bx = 0)	
  9146                              <1> 	; Output:
  9147                              <1> 	;	dx = bank number
  9148                              <1> 		 	
  9149                              <1> 	cmp	bx, 0100h
  9150                              <1> 	je	short dispi_set_bank_farcall_get
  9151                              <1> 	or	bx, bx
  9152                              <1> 	jnz	dispi_set_bank_farcall_error
  9153                              <1> 	mov	ax, dx
  9154                              <1> 	push	dx
  9155                              <1> 	push	ax
  9156                              <1> 	mov	ax, VBE_DISPI_INDEX_BANK
  9157                              <1> 	mov	dx, VBE_DISPI_IOPORT_INDEX
  9158                              <1> 	out	dx, ax
  9159                              <1> 	pop	ax
  9160                              <1> 	mov	dx, VBE_DISPI_IOPORT_DATA
  9161                              <1> 	out	dx, ax
  9162                              <1> 	in	ax, dx
  9163                              <1> 	pop	dx
  9164                              <1> 	cmp	dx, ax
  9165                              <1> 	jne	short dispi_set_bank_farcall_error
  9166                              <1> 	mov	ax, 004Fh
  9167                              <1> 	retn	; retf for real mode far call
  9168                              <1> dispi_set_bank_farcall_get:
  9169                              <1> 	mov	ax, VBE_DISPI_INDEX_BANK
  9170                              <1> 	mov	dx, VBE_DISPI_IOPORT_INDEX
  9171                              <1> 	out	dx, ax
  9172                              <1> 	mov	dx, VBE_DISPI_IOPORT_DATA
  9173                              <1> 	in	ax, dx
  9174                              <1> 	mov	dx, ax
  9175                              <1> 	retn	; retf for real mode far call
  9176                              <1> dispi_set_bank_farcall_error:
  9177                              <1> 	mov	ax, 014Fh
  9178                              <1> 	retn	; retf for real mode far call
  9179                              <1> 
  9180                              <1> %endif
  9181                              <1> 
  9182                              <1> ; % include 'vidata.s' ; VIDEO DATA
  9183                              <1> 
  9184                              <1> ; /// End Of VIDEO FUNCTIONS ///
  2608                                  
  2609                                  setup_rtc_int:
  2610                                  ; source: http://wiki.osdev.org/RTC
  2611 00003BE5 FA                      	cli		; disable interrupts
  2612                                  	; default int frequency is 1024 Hz (Lower 4 bits of register A is 0110b or 6)
  2613                                  	; in order to change this ...
  2614                                  	; frequency  = 32768 >> (rate-1) --> 32768 >> 5 = 1024
  2615                                  	; (rate must be above 2 and not over 15)
  2616                                  	; new rate = 15 --> 32768 >> (15-1) = 2 Hz
  2617 00003BE6 B08A                    	mov	al, 8Ah 
  2618 00003BE8 E670                    	out	70h, al ; set index to register A, disable NMI
  2619 00003BEA 90                      	nop
  2620 00003BEB E471                    	in	al, 71h ; get initial value of register A
  2621 00003BED 88C4                    	mov 	ah, al
  2622 00003BEF 80E4F0                  	and	ah, 0F0h
  2623 00003BF2 B08A                    	mov	al, 8Ah 
  2624 00003BF4 E670                    	out	70h, al ; reset index to register A
  2625 00003BF6 88E0                    	mov	al, ah
  2626 00003BF8 0C0F                    	or	al, 0Fh	; new rate (0Fh -> 15)
  2627 00003BFA E671                    	out	71h, al ; write only our rate to A. Note, rate is the bottom 4 bits. 
  2628                                  	; enable RTC interrupt
  2629 00003BFC B08B                    	mov	al, 8Bh ;
  2630 00003BFE E670                    	out	70h, al ; select register B and disable NMI
  2631 00003C00 90                      	nop
  2632 00003C01 E471                    	in	al, 71h ; read the current value of register B
  2633 00003C03 88C4                    	mov	ah, al  ;
  2634 00003C05 B08B                    	mov 	al, 8Bh ;
  2635 00003C07 E670                    	out	70h, al ; set the index again (a read will reset the index to register B)	
  2636 00003C09 88E0                    	mov	al, ah  ;
  2637 00003C0B 0C40                    	or	al, 40h ;
  2638 00003C0D E671                    	out	71h, al ; write the previous value ORed with 0x40. This turns on bit 6 of register B
  2639 00003C0F FB                      	sti
  2640 00003C10 C3                      	retn
  2641                                  
  2642                                  ; Write memory information
  2643                                  ; 29/01/2016
  2644                                  ; 06/11/2014
  2645                                  ; 14/08/2015 
  2646                                  memory_info:	
  2647 00003C11 A1[DC630100]            	mov	eax, [memory_size] ; in pages
  2648 00003C16 50                      	push	eax
  2649 00003C17 C1E00C                  	shl	eax, 12		   ; in bytes
  2650 00003C1A BB0A000000              	mov	ebx, 10
  2651 00003C1F 89D9                    	mov	ecx, ebx	   ; 10
  2652 00003C21 BE[ED230100]            	mov	esi, mem_total_b_str	
  2653 00003C26 E8D6000000              	call	bintdstr
  2654 00003C2B 58                      	pop	eax
  2655 00003C2C B107                    	mov	cl, 7
  2656 00003C2E BE[11240100]            	mov	esi, mem_total_p_str
  2657 00003C33 E8C9000000              	call	bintdstr	
  2658                                  	; 14/08/2015
  2659 00003C38 E8E1000000              	call	calc_free_mem
  2660                                  	; edx = calculated free pages
  2661                                  	; ecx = 0
  2662 00003C3D A1[E0630100]            	mov 	eax, [free_pages]
  2663 00003C42 39D0                    	cmp	eax, edx ; calculated free mem value 
  2664                                  		; and initial free mem value are same or not?
  2665 00003C44 751D                    	jne 	short pmim ; print mem info with '?' if not
  2666 00003C46 52                      	push 	edx ; free memory in pages	
  2667                                  	;mov 	eax, edx
  2668 00003C47 C1E00C                  	shl	eax, 12 ; convert page count
  2669                                  			; to byte count
  2670 00003C4A B10A                    	mov	cl, 10
  2671 00003C4C BE[31240100]            	mov	esi, free_mem_b_str
  2672 00003C51 E8AB000000              	call	bintdstr
  2673 00003C56 58                      	pop	eax
  2674 00003C57 B107                    	mov	cl, 7
  2675 00003C59 BE[55240100]            	mov	esi, free_mem_p_str
  2676 00003C5E E89E000000              	call	bintdstr
  2677                                  pmim:
  2678 00003C63 BE[DB230100]            	mov	esi, msg_memory_info
  2679                                  	;
  2680 00003C68 B407                    	mov	ah, 07h ; Black background, 
  2681                                  			; light gray forecolor
  2682                                  print_kmsg: ; 29/01/2016
  2683 00003C6A 8825[07640100]          	mov	[ccolor], ah
  2684                                  pkmsg_loop:
  2685 00003C70 AC                      	lodsb
  2686 00003C71 08C0                    	or	al, al
  2687 00003C73 7410                    	jz	short pkmsg_ok
  2688 00003C75 56                      	push	esi
  2689                                  	; 13/05/2016
  2690 00003C76 0FB61D[07640100]        	movzx	ebx, byte [ccolor]
  2691                                  			; Video page 0 (bh=0)
  2692 00003C7D E87BE5FFFF              	call	_write_tty
  2693 00003C82 5E                      	pop	esi
  2694 00003C83 EBEB                    	jmp	short pkmsg_loop
  2695                                  pkmsg_ok:
  2696 00003C85 C3                      	retn
  2697                                  
  2698                                  ; 19/12/2020
  2699                                  ; temporary
  2700                                  ; Write default liner frame buffer address
  2701                                  ;
  2702                                  default_lfb_info:	
  2703 00003C86 66A1[D30E0000]          	mov	ax, [def_LFB_addr] ; high word
  2704 00003C8C E829000000              	call	wordtohex
  2705 00003C91 A3[AD240100]            	mov	dword [lfb_addr_str], eax
  2706 00003C96 BE[96240100]            	mov	esi, msg_lfb_addr
  2707 00003C9B B40F                    	mov	ah, 0Fh ; Black background, 
  2708                                  			; white forecolor
  2709 00003C9D EBCB                    	jmp	short print_kmsg
  2710                                  
  2711                                  ; Convert binary number to hexadecimal string
  2712                                  ; 10/05/2015  
  2713                                  ; dsectpm.s (28/02/2015)
  2714                                  ; Retro UNIX 386 v1 - Kernel v0.2.0.6  
  2715                                  ; 01/12/2014
  2716                                  ; 25/11/2014
  2717                                  ;
  2718                                  bytetohex:
  2719                                  	; INPUT ->
  2720                                  	; 	AL = byte (binary number)
  2721                                  	; OUTPUT ->
  2722                                  	;	AX = hexadecimal string
  2723                                  	;
  2724 00003C9F 53                      	push	ebx
  2725 00003CA0 31DB                    	xor	ebx, ebx
  2726 00003CA2 88C3                    	mov	bl, al
  2727 00003CA4 C0EB04                  	shr	bl, 4
  2728 00003CA7 8A9B[F13C0000]          	mov	bl, [ebx+hexchrs] 	 	
  2729 00003CAD 86D8                    	xchg	bl, al
  2730 00003CAF 80E30F                  	and	bl, 0Fh
  2731 00003CB2 8AA3[F13C0000]          	mov	ah, [ebx+hexchrs] 
  2732 00003CB8 5B                      	pop	ebx	
  2733 00003CB9 C3                      	retn
  2734                                  
  2735                                  wordtohex:
  2736                                  	; INPUT ->
  2737                                  	; 	AX = word (binary number)
  2738                                  	; OUTPUT ->
  2739                                  	;	EAX = hexadecimal string
  2740                                  	;
  2741 00003CBA 53                      	push	ebx
  2742 00003CBB 31DB                    	xor	ebx, ebx
  2743 00003CBD 86E0                    	xchg	ah, al
  2744 00003CBF 6650                    	push	ax
  2745 00003CC1 88E3                    	mov	bl, ah
  2746 00003CC3 C0EB04                  	shr	bl, 4
  2747 00003CC6 8A83[F13C0000]          	mov	al, [ebx+hexchrs] 	 	
  2748 00003CCC 88E3                    	mov	bl, ah
  2749 00003CCE 80E30F                  	and	bl, 0Fh
  2750 00003CD1 8AA3[F13C0000]          	mov	ah, [ebx+hexchrs]
  2751 00003CD7 C1E010                  	shl	eax, 16
  2752 00003CDA 6658                    	pop	ax
  2753 00003CDC 5B                      	pop	ebx
  2754 00003CDD EBC0                    	jmp	short bytetohex
  2755                                  	;mov	bl, al
  2756                                  	;shr	bl, 4
  2757                                  	;mov	bl, [ebx+hexchrs] 	 	
  2758                                  	;xchg	bl, al	 	
  2759                                  	;and	bl, 0Fh
  2760                                  	;mov	ah, [ebx+hexchrs] 
  2761                                  	;pop	ebx	
  2762                                  	;retn
  2763                                  
  2764                                  dwordtohex:
  2765                                  	; INPUT ->
  2766                                  	; 	EAX = dword (binary number)
  2767                                  	; OUTPUT ->
  2768                                  	;	EDX:EAX = hexadecimal string
  2769                                  	;
  2770 00003CDF 50                      	push	eax
  2771 00003CE0 C1E810                  	shr	eax, 16
  2772 00003CE3 E8D2FFFFFF              	call	wordtohex
  2773 00003CE8 89C2                    	mov	edx, eax
  2774 00003CEA 58                      	pop	eax
  2775 00003CEB E8CAFFFFFF              	call	wordtohex
  2776 00003CF0 C3                      	retn
  2777                                  
  2778                                  ; 10/05/2015
  2779                                  hex_digits:
  2780                                  hexchrs:
  2781 00003CF1 303132333435363738-     	db '0123456789ABCDEF'
  2781 00003CFA 39414243444546     
  2782                                  
  2783                                  ; Convert binary number to decimal/numeric string
  2784                                  ; 06/11/2014
  2785                                  ; Temporary Code
  2786                                  ;
  2787                                  
  2788                                  bintdstr:
  2789                                  	; EAX = binary number
  2790                                  	; ESI = decimal/numeric string address
  2791                                  	; EBX = divisor (10)
  2792                                  	; ECX = string length (<=10)
  2793 00003D01 01CE                    	add	esi, ecx
  2794                                  btdstr0:
  2795 00003D03 4E                      	dec	esi
  2796 00003D04 31D2                    	xor	edx, edx
  2797 00003D06 F7F3                    	div	ebx
  2798 00003D08 80C230                  	add	dl, 30h
  2799 00003D0B 8816                    	mov	[esi], dl
  2800 00003D0D FEC9                    	dec	cl
  2801 00003D0F 740C                    	jz	short btdstr2 ; 08/09/2016
  2802 00003D11 09C0                    	or	eax, eax
  2803 00003D13 75EE                    	jnz	short btdstr0
  2804                                  btdstr1:
  2805 00003D15 4E                      	dec	esi
  2806 00003D16 C60620                          mov     byte [esi], 20h ; blank space
  2807 00003D19 FEC9                    	dec	cl
  2808 00003D1B 75F8                    	jnz	short btdstr1
  2809                                  btdstr2:
  2810 00003D1D C3                      	retn
  2811                                  
  2812                                  ; Calculate free memory pages on M.A.T.
  2813                                  ; 06/11/2014
  2814                                  ; Temporary Code
  2815                                  ;
  2816                                  
  2817                                  calc_free_mem:
  2818 00003D1E 31D2                    	xor	edx, edx
  2819                                  	;xor	ecx, ecx
  2820 00003D20 668B0D[F0630100]        	mov	cx, [mat_size] ; in pages
  2821 00003D27 C1E10A                  	shl	ecx, 10	; 1024 dwords per page
  2822 00003D2A BE00001000              	mov	esi, MEM_ALLOC_TBL
  2823                                  cfm0:
  2824 00003D2F AD                      	lodsd
  2825 00003D30 51                      	push	ecx
  2826 00003D31 B920000000              	mov	ecx, 32
  2827                                  cfm1:
  2828 00003D36 D1E8                    	shr	eax, 1
  2829 00003D38 7301                    	jnc	short cfm2
  2830 00003D3A 42                      	inc	edx
  2831                                  cfm2:
  2832 00003D3B E2F9                    	loop	cfm1
  2833 00003D3D 59                      	pop	ecx
  2834 00003D3E E2EF                    	loop	cfm0
  2835 00003D40 C3                      	retn
  2836                                  
  2837                                  %include 'diskio.s'  ; 07/03/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.2 - diskio.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 30/08/2020
     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 00003D41 F8                  <1> 	clc ; 20/07/2020
    31 00003D42 9C                  <1> 	pushfd
    32 00003D43 0E                  <1> 	push 	cs
    33 00003D44 E809000000          <1> 	call 	DISKETTE_IO_1
    34 00003D49 C3                  <1> 	retn
    35                              <1> 	
    36                              <1> ;;;;;; DISKETTE I/O ;;;;;;;;;;;;;;;;;;;; 06/02/2015 ;;;
    37                              <1> ;//////////////////////////////////////////////////////
    38                              <1> 
    39                              <1> ; DISKETTE I/O - Erdogan Tan (Retro UNIX 386 v1 project)
    40                              <1> ; 20/02/2015
    41                              <1> ; 06/02/2015 (unix386.s)
    42                              <1> ; 16/12/2014 - 02/01/2015 (dsectrm2.s)
    43                              <1> ;
    44                              <1> ; Code (DELAY) modifications - AWARD BIOS 1999 (ADISK.EQU, COMMON.MAC)
    45                              <1> ;
    46                              <1> ; ADISK.EQU
    47                              <1> 
    48                              <1> ;----- Wait control constants 
    49                              <1> 
    50                              <1> ;amount of time to wait while RESET is active.
    51                              <1> 
    52                              <1> WAITCPU_RESET_ON	EQU	21		;Reset on must last at least 14us
    53                              <1> 						;at 250 KBS xfer rate.
    54                              <1> 						;see INTEL MCS, 1985, pg. 5-456
    55                              <1> 
    56                              <1> WAITCPU_FOR_STATUS	EQU	100		;allow 30 microseconds for
    57                              <1> 						;status register to become valid
    58                              <1> 						;before re-reading.
    59                              <1> 
    60                              <1> ;After sending a byte to NEC, status register may remain
    61                              <1> ;incorrectly set for 24 us.
    62                              <1> 
    63                              <1> WAITCPU_RQM_LOW		EQU	24		;number of loops to check for
    64                              <1> 						;RQM low.
    65                              <1> 
    66                              <1> ; COMMON.MAC
    67                              <1> ;
    68                              <1> ;	Timing macros
    69                              <1> ;
    70                              <1> 
    71                              <1> %macro 		SIODELAY 0 			; SHORT IODELAY
    72                              <1> 		jmp short $+2
    73                              <1> %endmacro		
    74                              <1> 
    75                              <1> %macro		IODELAY  0			; NORMAL IODELAY
    76                              <1> 		jmp short $+2
    77                              <1> 		jmp short $+2
    78                              <1> %endmacro
    79                              <1> 
    80                              <1> %macro		NEWIODELAY 0
    81                              <1> 		out	0ebh,al
    82                              <1> %endmacro 
    83                              <1> 
    84                              <1> ; (According to) AWARD BIOS 1999 - ATORGS.ASM (dw -> equ, db -> equ)
    85                              <1> ;;; WAIT_FOR_MEM
    86                              <1> ;WAIT_FDU_INT_LO	equ	017798		; 2.5 secs in 30 micro units.
    87                              <1> ;WAIT_FDU_INT_HI	equ	1
    88                              <1> WAIT_FDU_INT_LH		equ	83334		; 27/02/2015 (2.5 seconds waiting)
    89                              <1> ;;; WAIT_FOR_PORT
    90                              <1> ;WAIT_FDU_SEND_LO	equ	16667		; .5 secons in 30 us units.
    91                              <1> ;WAIT_FDU_SEND_HI	equ	0
    92                              <1> WAIT_FDU_SEND_LH	equ 	16667		; 27/02/2015	
    93                              <1> ;Time to wait while waiting for each byte of NEC results = .5
    94                              <1> ;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
    95                              <1> ;WAIT_FDU_RESULTS_LO	equ	16667		; .5 seconds in 30 micro units.
    96                              <1> ;WAIT_FDU_RESULTS_HI	equ	0
    97                              <1> WAIT_FDU_RESULTS_LH	equ	16667  ; 27/02/2015
    98                              <1> ;;; WAIT_REFRESH
    99                              <1> ;amount of time to wait for head settle, per unit in parameter
   100                              <1> ;table = 1 ms.
   101                              <1> WAIT_FDU_HEAD_SETTLE	equ	33		; 1 ms in 30 micro units.
   102                              <1> 
   103                              <1> 
   104                              <1> ; //////////////// DISKETTE I/O ////////////////
   105                              <1> 
   106                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - POSTEQU.INC)
   107                              <1> 
   108                              <1> ;----------------------------------------
   109                              <1> ;	EQUATES USED BY POST AND BIOS	:
   110                              <1> ;----------------------------------------
   111                              <1> 
   112                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
   113                              <1> ;PORT_A		EQU	060H		; 8042 KEYBOARD SCAN CODE/CONTROL PORT
   114                              <1> ;PORT_B		EQU	061H		; PORT B READ/WRITE DIAGNOSTIC REGISTER
   115                              <1> ;REFRESH_BIT	EQU	00010000B	; REFRESH TEST BIT
   116                              <1> 
   117                              <1> ;----------------------------------------
   118                              <1> ;	CMOS EQUATES FOR THIS SYSTEM	:
   119                              <1> ;-------------------------------------------------------------------------------
   120                              <1> ;CMOS_PORT	EQU	070H		; I/O ADDRESS OF CMOS ADDRESS PORT
   121                              <1> ;CMOS_DATA	EQU	071H		; I/O ADDRESS OF CMOS DATA PORT
   122                              <1> ;NMI		EQU	10000000B	; DISABLE NMI INTERRUPTS MASK -
   123                              <1> 					;  HIGH BIT OF CMOS LOCATION ADDRESS
   124                              <1> 
   125                              <1> ;---------- CMOS TABLE LOCATION ADDRESS'S ## -----------------------------------
   126                              <1> CMOS_DISKETTE	EQU	010H		; DISKETTE DRIVE TYPE BYTE	      ;
   127                              <1> ;		EQU	011H		; - RESERVED			      ;C
   128                              <1> CMOS_DISK	EQU	012H		; FIXED DISK TYPE BYTE		      ;H
   129                              <1> ;		EQU	013H		; - RESERVED			      ;E
   130                              <1> CMOS_EQUIP	EQU	014H		; EQUIPMENT WORD LOW BYTE	      ;C
   131                              <1> 
   132                              <1> ;---------- DISKETTE EQUATES ---------------------------------------------------
   133                              <1> INT_FLAG	EQU	10000000B	; INTERRUPT OCCURRENCE FLAG
   134                              <1> DSK_CHG 	EQU	10000000B	; DISKETTE CHANGE FLAG MASK BIT
   135                              <1> DETERMINED	EQU	00010000B	; SET STATE DETERMINED IN STATE BITS
   136                              <1> HOME		EQU	00010000B	; TRACK 0 MASK
   137                              <1> SENSE_DRV_ST	EQU	00000100B	; SENSE DRIVE STATUS COMMAND
   138                              <1> TRK_SLAP	EQU	030H		; CRASH STOP (48 TPI DRIVES)
   139                              <1> QUIET_SEEK	EQU	00AH		; SEEK TO TRACK 10
   140                              <1> ;MAX_DRV 	EQU	2		; MAX NUMBER OF DRIVES
   141                              <1> HD12_SETTLE	EQU	15		; 1.2 M HEAD SETTLE TIME
   142                              <1> HD320_SETTLE	EQU	20		; 320 K HEAD SETTLE TIME
   143                              <1> MOTOR_WAIT	EQU	37		; 2 SECONDS OF COUNTS FOR MOTOR TURN OFF
   144                              <1> 
   145                              <1> ;---------- DISKETTE ERRORS ----------------------------------------------------
   146                              <1> ;TIME_OUT	EQU	080H		; ATTACHMENT FAILED TO RESPOND
   147                              <1> ;BAD_SEEK	EQU	040H		; SEEK OPERATION FAILED
   148                              <1> BAD_NEC 	EQU	020H		; DISKETTE CONTROLLER HAS FAILED
   149                              <1> BAD_CRC 	EQU	010H		; BAD CRC ON DISKETTE READ
   150                              <1> MED_NOT_FND	EQU	00CH		; MEDIA TYPE NOT FOUND
   151                              <1> DMA_BOUNDARY	EQU	009H		; ATTEMPT TO DMA ACROSS 64K BOUNDARY
   152                              <1> BAD_DMA 	EQU	008H		; DMA OVERRUN ON OPERATION
   153                              <1> MEDIA_CHANGE	EQU	006H		; MEDIA REMOVED ON DUAL ATTACH CARD
   154                              <1> RECORD_NOT_FND	EQU	004H		; REQUESTED SECTOR NOT FOUND
   155                              <1> WRITE_PROTECT	EQU	003H		; WRITE ATTEMPTED ON WRITE PROTECT DISK
   156                              <1> BAD_ADDR_MARK	EQU	002H		; ADDRESS MARK NOT FOUND
   157                              <1> BAD_CMD 	EQU	001H		; BAD COMMAND PASSED TO DISKETTE I/O
   158                              <1> 
   159                              <1> ;---------- DISK CHANGE LINE EQUATES -------------------------------------------
   160                              <1> NOCHGLN 	EQU	001H		; NO DISK CHANGE LINE AVAILABLE
   161                              <1> CHGLN		EQU	002H		; DISK CHANGE LINE AVAILABLE
   162                              <1> 
   163                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS ---------------------------------------
   164                              <1> TRK_CAPA	EQU	00000001B	; 80 TRACK CAPABILITY
   165                              <1> FMT_CAPA	EQU	00000010B	; MULTIPLE FORMAT CAPABILITY (1.2M)
   166                              <1> DRV_DET 	EQU	00000100B	; DRIVE DETERMINED
   167                              <1> MED_DET 	EQU	00010000B	; MEDIA DETERMINED BIT
   168                              <1> DBL_STEP	EQU	00100000B	; DOUBLE STEP BIT
   169                              <1> RATE_MSK	EQU	11000000B	; MASK FOR CLEARING ALL BUT RATE
   170                              <1> RATE_500	EQU	00000000B	; 500 KBS DATA RATE
   171                              <1> RATE_300	EQU	01000000B	; 300 KBS DATA RATE
   172                              <1> RATE_250	EQU	10000000B	; 250 KBS DATA RATE
   173                              <1> STRT_MSK	EQU	00001100B	; OPERATION START RATE MASK
   174                              <1> SEND_MSK	EQU	11000000B	; MASK FOR SEND RATE BITS
   175                              <1> 
   176                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS COMPATIBILITY -------------------------
   177                              <1> M3D3U		EQU	00000000B	; 360 MEDIA/DRIVE NOT ESTABLISHED
   178                              <1> M3D1U		EQU	00000001B	; 360 MEDIA,1.2DRIVE NOT ESTABLISHED
   179                              <1> M1D1U		EQU	00000010B	; 1.2 MEDIA/DRIVE NOT ESTABLISHED
   180                              <1> MED_UNK 	EQU	00000111B	; NONE OF THE ABOVE
   181                              <1> 
   182                              <1> ;---------- INTERRUPT EQUATES --------------------------------------------------
   183                              <1> ;EOI		EQU	020H		; END OF INTERRUPT COMMAND TO 8259
   184                              <1> ;INTA00		EQU	020H		; 8259 PORT
   185                              <1> INTA01		EQU	021H		; 8259 PORT
   186                              <1> INTB00		EQU	0A0H		; 2ND 8259
   187                              <1> INTB01		EQU	0A1H		;
   188                              <1> 
   189                              <1> ;-------------------------------------------------------------------------------
   190                              <1> DMA08		EQU	008H		; DMA STATUS REGISTER PORT ADDRESS
   191                              <1> DMA		EQU	000H		; DMA CH.0 ADDRESS REGISTER PORT ADDRESS
   192                              <1> DMA18		EQU	0D0H		; 2ND DMA STATUS PORT ADDRESS
   193                              <1> DMA1		EQU	0C0H		; 2ND DMA CH.0 ADDRESS REGISTER ADDRESS
   194                              <1> ;-------------------------------------------------------------------------------
   195                              <1> ;TIMER		EQU	040H		; 8254 TIMER - BASE ADDRESS
   196                              <1> 
   197                              <1> ;-------------------------------------------------------------------------------
   198                              <1> DMA_PAGE	EQU	081H		; START OF DMA PAGE REGISTERS
   199                              <1> 
   200                              <1> ; 06/02/2015 (unix386.s, protected mode modifications)
   201                              <1> ; (unix386.s <-- dsectrm2.s)
   202                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - DSEG.INC)
   203                              <1> 
   204                              <1> ; 27/05/2016 - TRDOS 386 (TRDOS v2.0)
   205                              <1> ; 10/12/2014
   206                              <1> ;
   207                              <1> ;int40h:
   208                              <1> ;	pushf
   209                              <1> ;	push 	cs
   210                              <1> ;	;cli
   211                              <1> ;	call 	DISKETTE_IO_1
   212                              <1> ;	retn
   213                              <1> 
   214                              <1> ; DSKETTE ----- 04/21/86 DISKETTE BIOS
   215                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
   216                              <1> ;
   217                              <1> 
   218                              <1> ;-- INT13H ---------------------------------------------------------------------
   219                              <1> ; DISKETTE I/O
   220                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO THE 5 1/4 INCH 360 KB,
   221                              <1> ;	1.2 MB, 720 KB AND 1.44 MB DISKETTE DRIVES.
   222                              <1> ; INPUT
   223                              <1> ;	(AH) =  00H RESET DISKETTE SYSTEM
   224                              <1> ;		HARD RESET TO NEC, PREPARE COMMAND, RECALIBRATE REQUIRED
   225                              <1> ;		ON ALL DRIVES
   226                              <1> ;------------------------------------------------------------------------------- 
   227                              <1> ;	(AH)= 01H  READ THE STATUS OF THE SYSTEM INTO (AH)
   228                              <1> ;		@DISKETTE_STATUS FROM LAST OPERATION IS USED
   229                              <1> ;-------------------------------------------------------------------------------
   230                              <1> ;	REGISTERS FOR READ/WRITE/VERIFY/FORMAT
   231                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
   232                              <1> ;	(DH) - HEAD NUMBER (0-1 ALLOWED, NOT VALUE CHECKED)
   233                              <1> ;	(CH) - TRACK NUMBER (NOT VALUE CHECKED)
   234                              <1> ;		MEDIA	DRIVE	TRACK NUMBER
   235                              <1> ;		320/360	320/360	    0-39
   236                              <1> ;		320/360	1.2M	    0-39
   237                              <1> ;		1.2M	1.2M	    0-79
   238                              <1> ;		720K	720K	    0-79
   239                              <1> ;		1.44M	1.44M	    0-79	
   240                              <1> ;	(CL) - 	SECTOR NUMBER (NOT VALUE CHECKED, NOT USED FOR FORMAT)
   241                              <1> ;		MEDIA	DRIVE	SECTOR NUMBER
   242                              <1> ;		320/360	320/360	     1-8/9
   243                              <1> ;		320/360	1.2M	     1-8/9
   244                              <1> ;		1.2M	1.2M	     1-15
   245                              <1> ;		720K	720K	     1-9
   246                              <1> ;		1.44M	1.44M	     1-18		
   247                              <1> ;	(AL)	NUMBER OF SECTORS (NOT VALUE CHECKED)
   248                              <1> ;		MEDIA	DRIVE	MAX NUMBER OF SECTORS
   249                              <1> ;		320/360	320/360	        8/9
   250                              <1> ;		320/360	1.2M	        8/9
   251                              <1> ;		1.2M	1.2M		15
   252                              <1> ;		720K	720K		9
   253                              <1> ;		1.44M	1.44M		18
   254                              <1> ;
   255                              <1> ;	(ES:BX) - ADDRESS OF BUFFER (NOT REQUIRED FOR VERIFY)
   256                              <1> ;
   257                              <1> ;-------------------------------------------------------------------------------
   258                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY
   259                              <1> ;-------------------------------------------------------------------------------
   260                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY
   261                              <1> ;-------------------------------------------------------------------------------
   262                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS
   263                              <1> ;-------------------------------------------------------------------------------
   264                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK
   265                              <1> ;		(ES,BX) MUST POINT TO THE COLLECTION OF DESIRED ADDRESS FIELDS
   266                              <1> ;		FOR THE	TRACK. EACH FIELD IS COMPOSED OF 4 BYTES, (C,H,R,N),
   267                              <1> ;		WHERE C = TRACK NUMBER, H=HEAD NUMBER, R = SECTOR NUMBER, 
   268                              <1> ;		N= NUMBER OF BYTES PER SECTOR (00=128,01=256,02=512,03=1024),
   269                              <1> ;		THERE MUST BE ONE ENTRY FOR EVERY SECTOR ON THE TRACK.
   270                              <1> ;		THIS INFORMATION IS USED TO FIND THE REQUESTED SECTOR DURING 
   271                              <1> ;		READ/WRITE ACCESS.
   272                              <1> ;		PRIOR TO FORMATTING A DISKETTE, IF THERE EXISTS MORE THAN
   273                              <1> ;		ONE SUPPORTED MEDIA FORMAT TYPE WITHIN THE DRIVE IN QUESTION,
   274                              <1> ;		THEN "SET DASD TYPE" (INT 13H, AH = 17H) OR 'SET MEDIA TYPE'
   275                              <1> ;		(INT 13H, AH =  18H) MUST BE CALLED TO SET THE DISKETTE TYPE
   276                              <1> ;		THAT IS TO BE FORMATTED. IF "SET DASD TYPE" OR "SET MEDIA TYPE"
   277                              <1> ;		IS NOT CALLED, THE FORMAT ROUTINE WILL ASSUME THE 
   278                              <1> ;		MEDIA FORMAT TO BE THE MAXIMUM CAPACITY OF THE DRIVE.
   279                              <1> ;
   280                              <1> ;		THESE PARAMETERS OF DISK BASE MUST BE CHANGED IN ORDER TO
   281                              <1> ;		FORMAT THE FOLLOWING MEDIAS:
   282                              <1> ;		---------------------------------------------
   283                              <1> ;		: MEDIA  :     DRIVE      : PARM 1 : PARM 2 :
   284                              <1> ;		---------------------------------------------
   285                              <1> ;		: 320K	 : 320K/360K/1.2M :  50H   :   8    :
   286                              <1> ;		: 360K	 : 320K/360K/1.2M :  50H   :   9    :
   287                              <1> ;		: 1.2M	 : 1.2M           :  54H   :  15    :
   288                              <1> ;		: 720K	 : 720K/1.44M     :  50H   :   9    :
   289                              <1> ;		: 1.44M	 : 1.44M          :  6CH   :  18    :		  	
   290                              <1> ;		---------------------------------------------
   291                              <1> ;		NOTES: - PARM 1 = GAP LENGTH FOR FORMAT
   292                              <1> ;		       - PARM 2 = EOT (LAST SECTOR ON TRACK)
   293                              <1> ;		       - DISK BASE IS POINTED BY DISK POINTER LOCATED
   294                              <1> ;			 AT ABSOLUTE ADDRESS 0:78.
   295                              <1> ;		       - WHEN FORMAT OPERATIONS ARE COMPLETE, THE PARAMETERS
   296                              <1> ;			 SHOULD BE RESTORED TO THEIR RESPECTIVE INITIAL VALUES.			
   297                              <1> ;-------------------------------------------------------------------------------
   298                              <1> ;	(AH) = 08H READ DRIVE PARAMETERS
   299                              <1> ;	REGISTERS
   300                              <1> ;	  INPUT
   301                              <1> ;	    (DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
   302                              <1> ;	     ** 27/05/2016 - TRDOS 386 (TRDOS v2.0) **	
   303                              <1> ;            ** EBX = Buffer address for floppy disk parameters table **
   304                              <1> ;	  OUTPUT
   305                              <1> ;	    (ES:DI) POINTS TO DRIVE PARAMETER TABLE
   306                              <1> ; 	    *** TRDOS 386 note: floppy disk parameter table (16 bytes)
   307                              <1> ;	    will be returned to user in EBX, buffer address *** 27/05/2016 ***		
   308                              <1> ;					
   309                              <1> ;	    (CH) - LOW ORDER 8 OF 10 BITS MAXIMUM NUMBER OF TRACKS
   310                              <1> ;	    (CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
   311                              <1> ;	           BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
   312                              <1> ;	    (DH) - MAXIMUM HEAD NUMBER
   313                              <1> ;	    (DL) - NUMBER OF DISKETTE DRIVES INSTALLED
   314                              <1> ;	    (BH) - 0
   315                              <1> ;	    (BL) - BITS 7 THRU 4 - 0
   316                              <1> ;	           BITS 3 THRU 0 - VALID DRIVE TYPE VALUE IN CMOS
   317                              <1> ;	    (AX) - 0
   318                              <1> ;	 UNDER THE FOLLOWING CIRCUMSTANCES:
   319                              <1> ;	    (1) THE DRIVE NUMBER IS INVALID,
   320                              <1> ;	    (2) THE DRIVE TYPE IS UNKNOWN AND CMOS IS NOT PRESENT, 
   321                              <1> ;	    (3) THE DRIVE TYPE IS UNKNOWN AND CMOS IS BAD,
   322                              <1> ;	    (4) OR THE DRIVE TYPE IS UNKNOWN AND THE CMOS DRIVE TYPE IS INVALID
   323                              <1> ;	    THEN ES,AX,BX,CX,DH,DI=0 ; DL=NUMBER OF DRIVES. 
   324                              <1> ;	    IF NO DRIVES ARE PRESENT THEN: ES,AX,BX,CX,DX,DI=0.
   325                              <1> ;	    @DISKETTE_STATUS = 0 AND CY IS RESET.
   326                              <1> ;-------------------------------------------------------------------------------
   327                              <1> ;	(AH)= 15H  READ DASD TYPE
   328                              <1> ;	OUTPUT REGISTERS
   329                              <1> ;	(AH) - ON RETURN IF CARRY FLAG NOT SET, OTHERWISE ERROR	
   330                              <1> ;		00 - DRIVE NOT PRESENT	
   331                              <1> ;		01 - DISKETTE, NO CHANGE LINE AVAILABLE
   332                              <1> ;		02 - DISKETTE, CHANGE LINE AVAILABLE	
   333                              <1> ;		03 - RESERVED (FIXED DISK)
   334                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
   335                              <1> ;-------------------------------------------------------------------------------
   336                              <1> ;	(AH)= 16H  DISK CHANGE LINE STATUS
   337                              <1> ;	OUTPUT REGISTERS
   338                              <1> ;	(AH) - 00 - DISK CHANGE LINE NOT ACTIVE	
   339                              <1> ;	       06 - DISK CHANGE LINE ACTIVE & CARRY BIT ON
   340                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
   341                              <1> ;-------------------------------------------------------------------------------
   342                              <1> ;	(AH)= 17H  SET DASD TYPE FOR FORMAT
   343                              <1> ;	INPUT REGISTERS
   344                              <1> ;	(AL) -	00 - NOT USED	
   345                              <1> ;		01 - DISKETTE 320/360K IN 360K DRIVE	
   346                              <1> ;		02 - DISKETTE 360K IN 1.2M DRIVE
   347                              <1> ;		03 - DISKETTE 1.2M IN 1.2M DRIVE
   348                              <1> ;		04 - DISKETTE 720K IN 720K DRIVE
   349                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED:
   350                              <1> ;	       (DO NOT USE WHEN DISKETTE ATTACH CARD USED)
   351                              <1> ;-------------------------------------------------------------------------------
   352                              <1> ;	(AH)= 18H  SET MEDIA TYPE FOR FORMAT
   353                              <1> ;	INPUT REGISTERS
   354                              <1> ;	(CH) - LOW ORDER 8 OF 10 BITS MAXIMUM TRACKS
   355                              <1> ;	(CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
   356                              <1> ;	       BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
   357                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHACKED)
   358                              <1> ;	OUTPUT REGISTERS:
   359                              <1> ;	(ES:DI) - POINTER TO DRIVE PARAMETERS TABLE FOR THIS MEDIA TYPE,
   360                              <1> ;		  UNCHANGED IF (AH) IS NON-ZERO
   361                              <1> ;	(AH) - 00H, CY = 0, TRACK AND SECTORS/TRACK COMBINATION IS SUPPORTED
   362                              <1> ;	     - 01H, CY = 1, FUNCTION IS NOT AVAILABLE
   363                              <1> ;	     - 0CH, CY = 1, TRACK AND SECTORS/TRACK COMBINATION IS NOT SUPPORTED
   364                              <1> ;	     - 80H, CY = 1, TIME OUT (DISKETTE NOT PRESENT)		
   365                              <1> ;-------------------------------------------------------------------------------
   366                              <1> ;	DISK CHANGE STATUS IS ONLY CHECKED WHEN A MEDIA SPECIFIED IS OTHER
   367                              <1> ;	THAN 360 KB DRIVE. IF THE DISK CHANGE LINE IS FOUND TO BE
   368                              <1> ;	ACTIVE THE FOLLOWING ACTIONS TAKE PLACE:
   369                              <1> ;		ATTEMPT TO RESET DISK CHANGE LINE TO INACTIVE STATE. 
   370                              <1> ;		IF ATTEMPT SUCCEEDS SET DASD TYPE FOR FORMAT AND RETURN DISK 
   371                              <1> ;		CHANGE ERROR CODE
   372                              <1> ;		IF ATTEMPT FAILS RETURN TIMEOUT ERROR CODE AND SET DASD TYPE 
   373                              <1> ;		TO A PREDETERMINED STATE INDICATING MEDIA TYPE UNKNOWN.
   374                              <1> ;	IF THE DISK CHANGE LINE IN INACTIVE PERFORM SET DASD TYPE FOR FORMAT.
   375                              <1> ;
   376                              <1> ; DATA VARIABLE -- @DISK_POINTER
   377                              <1> ;	DOUBLE WORD POINTER TO THE CURRENT SET OF DISKETTE PARAMETERS
   378                              <1> ;-------------------------------------------------------------------------------
   379                              <1> ; OUTPUT FOR ALL FUNCTIONS
   380                              <1> ;	AH = STATUS OF OPERATION
   381                              <1> ;		STATUS BITS ARE DEFINED IN THE EQUATES FOR @DISKETTE_STATUS
   382                              <1> ;		VARIABLE IN THE DATA SEGMENT OF THIS MODULE
   383                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN, EXCEPT FOR READ DASD
   384                              <1> ;		TYPE AH=(15)).
   385                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)
   386                              <1> ;	FOR READ/WRITE/VERIFY
   387                              <1> ;		DS,BX,DX,CX PRESERVED
   388                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISKETTE CODE, THE APPROPRIATE 
   389                              <1> ;		ACTION IS TO RESET THE DISKETTE, THEN RETRY THE OPERATION.
   390                              <1> ;		ON READ ACCESSES, NO MOTOR START DELAY IS TAKEN, SO THAT 
   391                              <1> ;		THREE RETRIES ARE REQUIRED ON READS TO ENSURE THAT THE 
   392                              <1> ;		PROBLEM IS NOT DUE TO MOTOR START-UP.
   393                              <1> ;-------------------------------------------------------------------------------
   394                              <1> ;
   395                              <1> ; DISKETTE STATE MACHINE - ABSOLUTE ADDRESS 40:90 (DRIVE A) & 91 (DRIVE B)
   396                              <1> ;
   397                              <1> ;   -----------------------------------------------------------------
   398                              <1> ;   |       |       |       |       |       |       |       |       |
   399                              <1> ;   |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
   400                              <1> ;   |       |       |       |       |       |       |       |       |
   401                              <1> ;   -----------------------------------------------------------------
   402                              <1> ;	|	|	|	|	|	|	|	|
   403                              <1> ;	|	|	|	|	|	-----------------
   404                              <1> ;	|	|	|	|	|		|
   405                              <1> ;	|	|	|	|    RESERVED		|
   406                              <1> ;	|	|	|	|		  PRESENT STATE
   407                              <1> ;	|	|	|	|	000: 360K IN 360K DRIVE UNESTABLISHED
   408                              <1> ;	|	|	|	|	001: 360K IN 1.2M DRIVE UNESTABLISHED
   409                              <1> ;	|	|	|	|	010: 1.2M IN 1.2M DRIVE UNESTABLISHED
   410                              <1> ;	|	|	|	|	011: 360K IN 360K DRIVE ESTABLISHED
   411                              <1> ;	|	|	|	|	100: 360K IN 1.2M DRIVE ESTABLISHED
   412                              <1> ;	|	|	|	|	101: 1.2M IN 1.2M DRIVE ESTABLISHED
   413                              <1> ;	|	|	|	|	110: RESERVED
   414                              <1> ;	|	|	|	|	111: NONE OF THE ABOVE
   415                              <1> ;	|	|	|	|
   416                              <1> ;	|	|	|	------>	MEDIA/DRIVE ESTABLISHED
   417                              <1> ;	|	|	|
   418                              <1> ;	|	|	-------------->	DOUBLE STEPPING REQUIRED (360K IN 1.2M
   419                              <1> ;	|	|			DRIVE)
   420                              <1> ;	|	|
   421                              <1> ;	------------------------------>	DATA TRANSFER RATE FOR THIS DRIVE:
   422                              <1> ;
   423                              <1> ;						00: 500 KBS
   424                              <1> ;						01: 300 KBS
   425                              <1> ;						10: 250 KBS
   426                              <1> ;						11: RESERVED
   427                              <1> ;
   428                              <1> ;
   429                              <1> ;-------------------------------------------------------------------------------
   430                              <1> ; STATE OPERATION STARTED - ABSOLUTE ADDRESS 40:92 (DRIVE A) & 93 (DRIVE B)
   431                              <1> ;-------------------------------------------------------------------------------
   432                              <1> ; PRESENT CYLINDER NUMBER - ABSOLUTE ADDRESS 40:94 (DRIVE A) & 95 (DRIVE B)
   433                              <1> ;-------------------------------------------------------------------------------
   434                              <1> 
   435                              <1> struc MD
   436 00000000 <res 00000001>      <1> 	.SPEC1		resb	1	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   437 00000001 <res 00000001>      <1> 	.SPEC2		resb	1	; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   438 00000002 <res 00000001>      <1> 	.OFF_TIM	resb	1	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   439 00000003 <res 00000001>      <1> 	.BYT_SEC	resb	1	; 512 BYTES/SECTOR
   440 00000004 <res 00000001>      <1> 	.SEC_TRK	resb	1	; EOT (LAST SECTOR ON TRACK)
   441 00000005 <res 00000001>      <1> 	.GAP		resb	1	; GAP LENGTH
   442 00000006 <res 00000001>      <1> 	.DTL		resb	1	; DTL
   443 00000007 <res 00000001>      <1> 	.GAP3		resb	1	; GAP LENGTH FOR FORMAT
   444 00000008 <res 00000001>      <1> 	.FIL_BYT	resb	1	; FILL BYTE FOR FORMAT
   445 00000009 <res 00000001>      <1> 	.HD_TIM		resb	1	; HEAD SETTLE TIME (MILLISECONDS)
   446 0000000A <res 00000001>      <1> 	.STR_TIM	resb	1	; MOTOR START TIME (1/8 SECONDS)
   447 0000000B <res 00000001>      <1> 	.MAX_TRK	resb	1	; MAX. TRACK NUMBER
   448 0000000C <res 00000001>      <1> 	.RATE		resb	1	; DATA TRANSFER RATE
   449                              <1> endstruc
   450                              <1> 
   451                              <1> BIT7OFF	EQU	7FH
   452                              <1> BIT7ON	EQU	80H
   453                              <1> 
   454                              <1> ; 30/08/2020 - TRDOS 386 v2
   455                              <1> 
   456                              <1> ;;int13h: ; 16/02/2015
   457                              <1> ;; 16/02/2015 - 21/02/2015
   458                              <1> int40h:
   459 00003D4A 9C                  <1> 	pushfd
   460 00003D4B 0E                  <1> 	push 	cs
   461 00003D4C E801000000          <1> 	call 	DISKETTE_IO_1
   462 00003D51 C3                  <1> 	retn	
   463                              <1> 
   464                              <1> DISKETTE_IO_1:
   465                              <1> 
   466 00003D52 FB                  <1> 	STI				; INTERRUPTS BACK ON
   467 00003D53 55                  <1> 	PUSH	eBP			; USER REGISTER
   468 00003D54 57                  <1> 	PUSH	eDI			; USER REGISTER
   469 00003D55 52                  <1> 	PUSH	eDX			; HEAD #, DRIVE # OR USER REGISTER
   470 00003D56 53                  <1> 	PUSH	eBX			; BUFFER OFFSET PARAMETER OR REGISTER
   471 00003D57 51                  <1> 	PUSH	eCX			; TRACK #-SECTOR # OR USER REGISTER
   472 00003D58 89E5                <1> 	MOV	eBP,eSP			; BP     => PARAMETER LIST DEP. ON AH
   473                              <1> 					; [BP]   = SECTOR #
   474                              <1> 					; [BP+1] = TRACK #
   475                              <1> 					; [BP+2] = BUFFER OFFSET
   476                              <1> 					; FOR RETURN OF DRIVE PARAMETERS:
   477                              <1> 					; CL/[BP] = BITS 7&6 HI BITS OF MAX CYL
   478                              <1> 					; 	    BITS 0-5 MAX SECTORS/TRACK
   479                              <1> 					; CH/[BP+1] = LOW 8 BITS OF MAX CYL.
   480                              <1> 					; BL/[BP+2] = BITS 7-4 = 0
   481                              <1> 					;	      BITS 3-0 = VALID CMOS TYPE
   482                              <1> 					; BH/[BP+3] = 0
   483                              <1> 					; DL/[BP+4] = # DRIVES INSTALLED
   484                              <1> 					; DH/[BP+5] = MAX HEAD #
   485                              <1> 					; DI/[BP+6] = OFFSET TO DISK BASE
   486 00003D5A 06                  <1> 	push	es ; 06/02/2015	
   487 00003D5B 1E                  <1> 	PUSH	DS			; BUFFER SEGMENT PARM OR USER REGISTER
   488 00003D5C 56                  <1> 	PUSH	eSI			; USER REGISTERS
   489                              <1> 	;CALL	DDS			; SEGMENT OF BIOS DATA AREA TO DS
   490                              <1> 	;mov	cx, cs
   491                              <1> 	;mov	ds, cx
   492 00003D5D 66B91000            <1> 	mov	cx, KDATA
   493 00003D61 8ED9                <1>         mov     ds, cx
   494 00003D63 8EC1                <1>         mov     es, cx
   495                              <1> 
   496                              <1> 	;CMP	AH,(FNC_TAE-FNC_TAB)/2	; CHECK FOR > LARGEST FUNCTION
   497 00003D65 80FC19              <1> 	cmp	ah,(FNC_TAE-FNC_TAB)/4  ; 18/02/2015
   498 00003D68 7202                <1> 	JB	short OK_FUNC		; FUNCTION OK
   499 00003D6A B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
   500                              <1> OK_FUNC:
   501 00003D6C 80FC01              <1> 	CMP	AH,1			; RESET OR STATUS ?
   502 00003D6F 760C                <1> 	JBE	short OK_DRV		; IF RESET OR STATUS DRIVE ALWAYS OK
   503 00003D71 80FC08              <1> 	CMP	AH,8			; READ DRIVE PARMS ?
   504 00003D74 7407                <1> 	JZ	short OK_DRV		; IF SO DRIVE CHECKED LATER
   505 00003D76 80FA01              <1> 	CMP	DL,1			; DRIVES 0 AND 1 OK
   506 00003D79 7602                <1> 	JBE	short OK_DRV		; IF 0 OR 1 THEN JUMP
   507 00003D7B B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
   508                              <1> OK_DRV:
   509 00003D7D 31C9                <1> 	xor	ecx, ecx
   510                              <1> 	;mov	esi, ecx ; 08/02/2015
   511 00003D7F 89CF                <1> 	mov	edi, ecx ; 08/02/2015
   512 00003D81 88E1                <1> 	MOV	CL,AH			; CL = FUNCTION
   513                              <1> 	;XOR	CH,CH			; CX = FUNCTION
   514                              <1> 	;SHL	CL, 1			; FUNCTION TIMES 2
   515 00003D83 C0E102              <1> 	SHL	CL, 2 ; 20/02/2015	; FUNCTION TIMES 4 (for 32 bit offset)
   516 00003D86 BB[BE3D0000]        <1> 	MOV	eBX,FNC_TAB		; LOAD START OF FUNCTION TABLE
   517 00003D8B 01CB                <1> 	ADD	eBX,eCX			; ADD OFFSET INTO TABLE => ROUTINE
   518 00003D8D 88F4                <1> 	MOV	AH,DH			; AX = HEAD #,# OF SECTORS OR DASD TYPE
   519 00003D8F 30F6                <1> 	XOR	DH,DH			; DX = DRIVE #
   520 00003D91 6689C6              <1> 	MOV	SI,AX			; SI = HEAD #,# OF SECTORS OR DASD TYPE
   521 00003D94 6689D7              <1> 	MOV     DI,DX                   ; DI = DRIVE #
   522                              <1> 	;
   523                              <1> 	; 11/12/2014
   524 00003D97 8815[BD670000]      <1>         mov     [cfd], dl               ; current floppy drive (for 'GET_PARM')        
   525                              <1> 	;
   526 00003D9D 8A25[60640100]      <1> 	MOV	AH, [DSKETTE_STATUS]	; LOAD STATUS TO AH FOR STATUS FUNCTION
   527 00003DA3 C605[60640100]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; INITIALIZE FOR ALL OTHERS
   528                              <1> 
   529                              <1> ;	THROUGHOUT THE DISKETTE BIOS, THE FOLLOWING INFORMATION IS CONTAINED IN
   530                              <1> ;	THE FOLLOWING MEMORY LOCATIONS AND REGISTERS. NOT ALL DISKETTE BIOS
   531                              <1> ;	FUNCTIONS REQUIRE ALL OF THESE PARAMETERS.
   532                              <1> ;
   533                              <1> ;		DI	: DRIVE #
   534                              <1> ;		SI-HI	: HEAD #
   535                              <1> ;		SI-LOW	: # OF SECTORS OR DASD TYPE FOR FORMAT
   536                              <1> ;		ES	: BUFFER SEGMENT
   537                              <1> ;		[BP]	: SECTOR #
   538                              <1> ;		[BP+1]	: TRACK #
   539                              <1> ;		[BP+2]	: BUFFER OFFSET
   540                              <1> ;
   541                              <1> ;	ACROSS CALLS TO SUBROUTINES THE CARRY FLAG (CY=1), WHERE INDICATED IN 
   542                              <1> ;	SUBROUTINE PROLOGUES, REPRESENTS AN EXCEPTION RETURN (NORMALLY AN ERROR 
   543                              <1> ;	CONDITION). IN MOST CASES, WHEN CY = 1, @DSKETTE_STATUS CONTAINS THE 
   544                              <1> ;	SPECIFIC ERROR CODE.
   545                              <1> ;
   546                              <1> 					; (AH) = @DSKETTE_STATUS
   547 00003DAA FF13                <1> 	CALL	dWORD [eBX]		; CALL THE REQUESTED FUNCTION
   548 00003DAC 5E                  <1> 	POP	eSI			; RESTORE ALL REGISTERS
   549 00003DAD 1F                  <1> 	POP	DS
   550 00003DAE 07                  <1> 	pop	es	; 06/02/2015
   551 00003DAF 59                  <1> 	POP	eCX
   552 00003DB0 5B                  <1> 	POP	eBX
   553 00003DB1 5A                  <1> 	POP	eDX
   554 00003DB2 5F                  <1> 	POP	eDI
   555 00003DB3 89E5                <1> 	MOV	eBP, eSP
   556 00003DB5 50                  <1> 	PUSH	eAX
   557 00003DB6 9C                  <1> 	PUSHFd
   558 00003DB7 58                  <1> 	POP	eAX
   559                              <1> 	;MOV	[BP+6], AX
   560 00003DB8 89450C              <1> 	mov	[ebp+12], eax  ; 18/02/2015, flags
   561 00003DBB 58                  <1> 	POP	eAX
   562 00003DBC 5D                  <1> 	POP	eBP
   563 00003DBD CF                  <1> 	IRETd
   564                              <1> 
   565                              <1> ;-------------------------------------------------------------------------------
   566                              <1> ; DW --> dd (06/02/2015)
   567 00003DBE [223E0000]          <1> FNC_TAB	dd	DSK_RESET		; AH = 00H; RESET
   568 00003DC2 [9B3E0000]          <1> 	dd	DSK_STATUS		; AH = 01H; STATUS
   569 00003DC6 [AC3E0000]          <1> 	dd	DSK_READ		; AH = 02H; READ
   570 00003DCA [BD3E0000]          <1> 	dd	DSK_WRITE		; AH = 03H; WRITE
   571 00003DCE [CE3E0000]          <1> 	dd	DSK_VERF		; AH = 04H; VERIFY
   572 00003DD2 [DF3E0000]          <1> 	dd	DSK_FORMAT		; AH = 05H; FORMAT
   573 00003DD6 [643F0000]          <1> 	dd	FNC_ERR			; AH = 06H; INVALID
   574 00003DDA [643F0000]          <1> 	dd	FNC_ERR			; AH = 07H; INVALID
   575 00003DDE [713F0000]          <1> 	dd	DSK_PARMS		; AH = 08H; READ DRIVE PARAMETERS
   576 00003DE2 [643F0000]          <1> 	dd	FNC_ERR			; AH = 09H; INVALID
   577 00003DE6 [643F0000]          <1> 	dd	FNC_ERR			; AH = 0AH; INVALID
   578 00003DEA [643F0000]          <1> 	dd	FNC_ERR			; AH = 0BH; INVALID
   579 00003DEE [643F0000]          <1> 	dd	FNC_ERR			; AH = 0CH; INVALID
   580 00003DF2 [643F0000]          <1> 	dd	FNC_ERR			; AH = 0DH; INVALID
   581 00003DF6 [643F0000]          <1> 	dd	FNC_ERR			; AH = 0EH; INVALID
   582 00003DFA [643F0000]          <1> 	dd	FNC_ERR			; AH = 0FH; INVALID
   583 00003DFE [643F0000]          <1> 	dd	FNC_ERR			; AH = 10H; INVALID
   584 00003E02 [643F0000]          <1> 	dd	FNC_ERR			; AH = 11H; INVALID
   585 00003E06 [643F0000]          <1> 	dd	FNC_ERR			; AH = 12H; INVALID
   586 00003E0A [643F0000]          <1> 	dd	FNC_ERR			; AH = 13H; INVALID
   587 00003E0E [643F0000]          <1> 	dd	FNC_ERR			; AH = 14H; INVALID
   588 00003E12 [61400000]          <1> 	dd	DSK_TYPE		; AH = 15H; READ DASD TYPE
   589 00003E16 [91400000]          <1> 	dd	DSK_CHANGE		; AH = 16H; CHANGE STATUS
   590 00003E1A [CB400000]          <1> 	dd	FORMAT_SET		; AH = 17H; SET DASD TYPE
   591 00003E1E [4E410000]          <1> 	dd	SET_MEDIA		; AH = 18H; SET MEDIA TYPE	
   592                              <1> FNC_TAE EQU     $                       ; END
   593                              <1> 
   594                              <1> ;-------------------------------------------------------------------------------
   595                              <1> ; DISK_RESET	(AH = 00H)	
   596                              <1> ;		RESET THE DISKETTE SYSTEM.
   597                              <1> ;
   598                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   599                              <1> ;-------------------------------------------------------------------------------
   600                              <1> DSK_RESET:
   601 00003E22 66BAF203            <1> 	MOV	DX,03F2H		; ADAPTER CONTROL PORT
   602 00003E26 FA                  <1> 	CLI				; NO INTERRUPTS
   603 00003E27 A0[5E640100]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
   604 00003E2C 243F                <1> 	AND	AL,00111111B		; KEEP SELECTED AND MOTOR ON BITS
   605 00003E2E C0C004              <1> 	ROL	AL,4			; MOTOR VALUE TO HIGH NIBBLE
   606                              <1> 					; DRIVE SELECT TO LOW NIBBLE
   607 00003E31 0C08                <1> 	OR	AL,00001000B		; TURN ON INTERRUPT ENABLE
   608 00003E33 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
   609 00003E34 C605[5D640100]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
   610                              <1> 	;JMP	$+2			; WAIT FOR I/O
   611                              <1> 	;JMP	$+2			; WAIT FOR I/O (TO INSURE MINIMUM
   612                              <1> 					;      PULSE WIDTH)
   613                              <1> 	; 19/12/2014
   614                              <1> 	NEWIODELAY
   614 00003E3B E6EB                <2>  out 0ebh,al
   615                              <1> 
   616                              <1> 	; 17/12/2014 
   617                              <1> 	; AWARD BIOS 1999 - RESETDRIVES (ADISK.ASM)
   618 00003E3D B915000000          <1> 	mov	ecx, WAITCPU_RESET_ON	; cx = 21 -- Min. 14 micro seconds !?
   619                              <1> wdw1:
   620                              <1> 	NEWIODELAY   ; 27/02/2015
   620 00003E42 E6EB                <2>  out 0ebh,al
   621 00003E44 E2FC                <1> 	loop	wdw1
   622                              <1> 	;
   623 00003E46 0C04                <1> 	OR	AL,00000100B		; TURN OFF RESET BIT
   624 00003E48 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
   625                              <1> 	; 16/12/2014
   626                              <1> 	IODELAY
   626 00003E49 EB00                <2>  jmp short $+2
   626 00003E4B EB00                <2>  jmp short $+2
   627                              <1> 	;
   628                              <1> 	;STI				; ENABLE THE INTERRUPTS
   629 00003E4D E8590C0000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
   630 00003E52 723E                <1> 	JC	short DR_ERR		; IF ERROR, RETURN IT
   631 00003E54 66B9C000            <1> 	MOV	CX,11000000B		; CL = EXPECTED @NEC_STATUS
   632                              <1> NXT_DRV:
   633 00003E58 6651                <1> 	PUSH	CX			; SAVE FOR CALL
   634 00003E5A B8[903E0000]        <1> 	MOV	eAX, DR_POP_ERR 	; LOAD NEC_OUTPUT ERROR ADDRESS
   635 00003E5F 50                  <1> 	PUSH	eAX			; "
   636 00003E60 B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
   637 00003E62 E8370B0000          <1> 	CALL	NEC_OUTPUT
   638 00003E67 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
   639 00003E68 E86E0C0000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
   640 00003E6D 6659                <1> 	POP	CX			; RESTORE AFTER CALL
   641 00003E6F 7221                <1> 	JC	short DR_ERR		; ERROR RETURN
   642 00003E71 3A0D[61640100]      <1> 	CMP	CL, [NEC_STATUS]	; TEST FOR DRIVE READY TRANSITION
   643 00003E77 7519                <1> 	JNZ	short DR_ERR		; EVERYTHING OK
   644 00003E79 FEC1                <1> 	INC	CL			; NEXT EXPECTED @NEC_STATUS
   645 00003E7B 80F9C3              <1> 	CMP	CL,11000011B		; ALL POSSIBLE DRIVES CLEARED
   646 00003E7E 76D8                <1> 	JBE	short NXT_DRV		; FALL THRU IF 11000100B OR >
   647                              <1> 	;
   648 00003E80 E886030000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
   649                              <1> RESBAC:
   650 00003E85 E83A090000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   651 00003E8A 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   652 00003E8D 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   653 00003E8F C3                  <1> 	RETn		
   654                              <1> DR_POP_ERR:
   655 00003E90 6659                <1> 	POP	CX			; CLEAR STACK
   656                              <1> DR_ERR:
   657 00003E92 800D[60640100]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; SET ERROR CODE
   658 00003E99 EBEA                <1> 	JMP	SHORT RESBAC		; RETURN FROM RESET
   659                              <1> 
   660                              <1> ;-------------------------------------------------------------------------------
   661                              <1> ; DISK_STATUS	(AH = 01H)
   662                              <1> ;	DISKETTE STATUS.
   663                              <1> ;
   664                              <1> ; ON ENTRY:	AH : STATUS OF PREVIOUS OPERATION
   665                              <1> ;
   666                              <1> ; ON EXIT:	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF PREVIOUS OPERATION.
   667                              <1> ;-------------------------------------------------------------------------------
   668                              <1> DSK_STATUS:
   669 00003E9B 8825[60640100]      <1> 	MOV	[DSKETTE_STATUS],AH	; PUT BACK FOR SETUP END
   670 00003EA1 E81E090000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   671 00003EA6 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   672 00003EA9 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   673 00003EAB C3                  <1> 	RETn		
   674                              <1> 
   675                              <1> ;-------------------------------------------------------------------------------
   676                              <1> ; DISK_READ	(AH = 02H)	
   677                              <1> ;	DISKETTE READ.
   678                              <1> ;
   679                              <1> ; ON ENTRY:	DI	: DRIVE #
   680                              <1> ;		SI-HI	: HEAD #
   681                              <1> ;		SI-LOW	: # OF SECTORS
   682                              <1> ;		ES	: BUFFER SEGMENT
   683                              <1> ;		[BP]	: SECTOR #
   684                              <1> ;		[BP+1]	: TRACK #
   685                              <1> ;		[BP+2]	: BUFFER OFFSET
   686                              <1> ;
   687                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   688                              <1> ;-------------------------------------------------------------------------------
   689                              <1> 
   690                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
   691                              <1> 
   692                              <1> DSK_READ:
   693 00003EAC 8025[5E640100]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
   694 00003EB3 66B846E6            <1> 	MOV	AX,0E646H		; AX = NEC COMMAND, DMA COMMAND
   695 00003EB7 E859040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   696 00003EBC C3                  <1> 	RETn
   697                              <1> 
   698                              <1> ;-------------------------------------------------------------------------------
   699                              <1> ; DISK_WRITE	(AH = 03H)
   700                              <1> ;	DISKETTE WRITE.
   701                              <1> ;
   702                              <1> ; ON ENTRY:	DI	: DRIVE #
   703                              <1> ;		SI-HI	: HEAD #
   704                              <1> ;		SI-LOW	: # OF SECTORS
   705                              <1> ;		ES	: BUFFER SEGMENT
   706                              <1> ;		[BP]	: SECTOR #
   707                              <1> ;		[BP+1]	: TRACK #
   708                              <1> ;		[BP+2]	: BUFFER OFFSET
   709                              <1> ;
   710                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   711                              <1> ;-------------------------------------------------------------------------------
   712                              <1> 
   713                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
   714                              <1> 
   715                              <1> DSK_WRITE:
   716 00003EBD 66B84AC5            <1> 	MOV	AX,0C54AH		; AX = NEC COMMAND, DMA COMMAND
   717 00003EC1 800D[5E640100]80    <1>         OR      byte [MOTOR_STATUS],10000000B ; INDICATE WRITE OPERATION
   718 00003EC8 E848040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   719 00003ECD C3                  <1> 	RETn
   720                              <1> 
   721                              <1> ;-------------------------------------------------------------------------------
   722                              <1> ; DISK_VERF	(AH = 04H)
   723                              <1> ;	DISKETTE VERIFY.
   724                              <1> ;
   725                              <1> ; ON ENTRY:	DI	: DRIVE #
   726                              <1> ;		SI-HI	: HEAD #
   727                              <1> ;		SI-LOW	: # OF SECTORS
   728                              <1> ;		ES	: BUFFER SEGMENT
   729                              <1> ;		[BP]	: SECTOR #
   730                              <1> ;		[BP+1]	: TRACK #
   731                              <1> ;		[BP+2]	: BUFFER OFFSET
   732                              <1> ;
   733                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   734                              <1> ;-------------------------------------------------------------------------------
   735                              <1> DSK_VERF:
   736 00003ECE 8025[5E640100]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
   737 00003ED5 66B842E6            <1> 	MOV	AX,0E642H		; AX = NEC COMMAND, DMA COMMAND
   738 00003ED9 E837040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   739 00003EDE C3                  <1> 	RETn
   740                              <1> 
   741                              <1> ;-------------------------------------------------------------------------------
   742                              <1> ; DISK_FORMAT	(AH = 05H)
   743                              <1> ;	DISKETTE FORMAT.
   744                              <1> ;
   745                              <1> ; ON ENTRY:	DI	: DRIVE #
   746                              <1> ;		SI-HI	: HEAD #
   747                              <1> ;		SI-LOW	: # OF SECTORS
   748                              <1> ;		ES	: BUFFER SEGMENT
   749                              <1> ;		[BP]	: SECTOR #
   750                              <1> ;		[BP+1]	: TRACK #
   751                              <1> ;		[BP+2]	: BUFFER OFFSET
   752                              <1> ;		@DISK_POINTER POINTS TO THE PARAMETER TABLE OF THIS DRIVE
   753                              <1> ;
   754                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   755                              <1> ;-------------------------------------------------------------------------------
   756                              <1> DSK_FORMAT:
   757 00003EDF E870030000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
   758 00003EE4 E86C050000          <1> 	CALL	FMT_INIT		; ESTABLISH STATE IF UNESTABLISHED
   759 00003EE9 800D[5E640100]80    <1>         OR      byte [MOTOR_STATUS], 10000000B ; INDICATE WRITE OPERATION
   760 00003EF0 E8B4050000          <1> 	CALL	MED_CHANGE		; CHECK MEDIA CHANGE AND RESET IF SO
   761 00003EF5 725D                <1>         JC      short FM_DON            ; MEDIA CHANGED, SKIP
   762 00003EF7 E80F030000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
   763 00003EFC E81A060000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMPT RATE IS SAME AS LAST RATE
   764 00003F01 7405                <1>         JZ      short FM_WR             ; YES, SKIP SPECIFY COMMAND
   765 00003F03 E8F1050000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO CONTROLLER
   766                              <1> FM_WR:
   767 00003F08 E8A7060000          <1> 	CALL	FMTDMA_SET		; SET UP THE DMA FOR FORMAT
   768 00003F0D 7245                <1>         JC      short FM_DON            ; RETURN WITH ERROR
   769 00003F0F B44D                <1> 	MOV	AH,04DH			; ESTABLISH THE FORMAT COMMAND
   770 00003F11 E804070000          <1> 	CALL	NEC_INIT		; INITIALIZE THE NEC
   771 00003F16 723C                <1>         JC      short FM_DON            ; ERROR - EXIT
   772 00003F18 B8[543F0000]        <1>         MOV     eAX, FM_DON             ; LOAD ERROR ADDRESS
   773 00003F1D 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
   774 00003F1E B203                <1> 	MOV	DL,3			; BYTES/SECTOR VALUE TO NEC
   775 00003F20 E873090000          <1> 	CALL	GET_PARM
   776 00003F25 E8740A0000          <1> 	CALL	NEC_OUTPUT
   777 00003F2A B204                <1> 	MOV	DL,4			; SECTORS/TRACK VALUE TO NEC
   778 00003F2C E867090000          <1> 	CALL	GET_PARM
   779 00003F31 E8680A0000          <1> 	CALL	NEC_OUTPUT
   780 00003F36 B207                <1> 	MOV	DL,7			; GAP LENGTH VALUE TO NEC
   781 00003F38 E85B090000          <1> 	CALL	GET_PARM
   782 00003F3D E85C0A0000          <1> 	CALL	NEC_OUTPUT
   783 00003F42 B208                <1> 	MOV	DL,8			; FILLER BYTE TO NEC
   784 00003F44 E84F090000          <1> 	CALL	GET_PARM
   785 00003F49 E8500A0000          <1> 	CALL	NEC_OUTPUT
   786 00003F4E 58                  <1> 	POP	eAX			; THROW AWAY ERROR
   787 00003F4F E844070000          <1> 	CALL	NEC_TERM		; TERMINATE, RECEIVE STATUS, ETC,
   788                              <1> FM_DON:
   789 00003F54 E82C030000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   790 00003F59 E866080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   791 00003F5E 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   792 00003F61 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   793 00003F63 C3                  <1> 	RETn
   794                              <1> 
   795                              <1> ;-------------------------------------------------------------------------------
   796                              <1> ; FNC_ERR
   797                              <1> ;	INVALID FUNCTION REQUESTED OR INVALID DRIVE: 
   798                              <1> ;	SET BAD COMMAND IN STATUS.
   799                              <1> ;
   800                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   801                              <1> ;-------------------------------------------------------------------------------
   802                              <1> FNC_ERR:				; INVALID FUNCTION REQUEST
   803 00003F64 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
   804 00003F67 B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
   805 00003F69 8825[60640100]      <1> 	MOV	[DSKETTE_STATUS],AH	; STORE IN DATA AREA
   806 00003F6F F9                  <1> 	STC				; SET CARRY INDICATING ERROR
   807 00003F70 C3                  <1> 	RETn
   808                              <1> 
   809                              <1> ; 30/08/2020
   810                              <1> ; 29/08/2020
   811                              <1> ; 01/06/2016
   812                              <1> ; 28/05/2016
   813                              <1> ; 27/05/2016 - TRDOS 386 (TRDOS v.2.0)
   814                              <1> ;-------------------------------------------------------------------------------
   815                              <1> ; DISK_PARMS	(AH = 08H)	
   816                              <1> ;	READ DRIVE PARAMETERS.
   817                              <1> ;
   818                              <1> ; ON ENTRY:	DI : DRIVE #
   819                              <1> ;		; 27/05/2016
   820                              <1> ;		EBX = Buffer Address for floppy disk parameters table (16 bytes)
   821                              <1> ;
   822                              <1> ; ON EXIT:	CL/[BP]   = BITS 7 & 6 HI 2 BITS OF MAX CYLINDER
   823                              <1> ;		            BITS 0-5 MAX SECTORS/TRACK
   824                              <1> ;		CH/[BP+1] = LOW 8 BITS OF MAX CYLINDER
   825                              <1> ;		BL/[BP+2] = BITS 7-4 = 0
   826                              <1> ;		            BITS 3-0 = VALID CMOS DRIVE TYPE
   827                              <1> ;		BH/[BP+3] = 0
   828                              <1> ;		DL/[BP+4] = # DRIVES INSTALLED (VALUE CHECKED)
   829                              <1> ;		DH/[BP+5] = MAX HEAD #
   830                              <1> ;	     ** 27/05/2016 - TRDOS 386 (TRDOS v2.0) **	
   831                              <1> ;            ** EBX = Buffer address for floppy disk parameters table **
   832                              <1> ;		;DI/[BP+6] = OFFSET TO DISK_BASE
   833                              <1> ;		;ES        = SEGMENT OF DISK_BASE
   834                              <1> ;
   835                              <1> ;		AX        = 0
   836                              <1> ;
   837                              <1> ;		NOTE : THE ABOVE INFORMATION IS STORED IN THE USERS STACK AT
   838                              <1> ;		       THE LOCATIONS WHERE THE MAIN ROUTINE WILL POP THEM
   839                              <1> ;		       INTO THE APPROPRIATE REGISTERS BEFORE RETURNING TO THE
   840                              <1> ;		       CALLER.
   841                              <1> ;-------------------------------------------------------------------------------
   842                              <1> DSK_PARMS:
   843 00003F71 E8DE020000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
   844                              <1>      ;	MOV	WORD [BP+2],0		; DRIVE TYPE = 0
   845                              <1>      ;  MOV     AX, [EQUIP_FLAG]        ; LOAD EQUIPMENT FLAG FOR # DISKETTES
   846                              <1>      ;  AND     AL,11000001B            ; KEEP DISKETTE DRIVE BITS
   847                              <1>      ;  MOV     DL,2                    ; DISKETTE DRIVES = 2
   848                              <1>      ;  CMP     AL,01000001B            ; 2 DRIVES INSTALLED ?
   849                              <1>      ;  JZ      short STO_DL            ; IF YES JUMP
   850                              <1>      ;  DEC     DL                      ; DISKETTE DRIVES = 1
   851                              <1>      ;  CMP     AL,00000001B            ; 1 DRIVE INSTALLED ?
   852                              <1>      ;  JNZ     short NON_DRV           ; IF NO JUMP
   853 00003F76 29D2                <1> 	sub	edx, edx
   854 00003F78 66A1[CE670000]      <1> 	mov     ax, [fd0_type]
   855 00003F7E 6621C0              <1> 	and     ax, ax
   856 00003F81 0F849B000000        <1>         jz      NON_DRV
   857 00003F87 FEC2                <1> 	inc     dl
   858 00003F89 20E4                <1> 	and     ah, ah
   859 00003F8B 7402                <1> 	jz      short STO_DL
   860 00003F8D FEC2                <1> 	inc     dl
   861                              <1> STO_DL:
   862                              <1> 	; 30/08/2020
   863 00003F8F 6639FA              <1> 	cmp	dx, di
   864 00003F92 0F868A000000        <1> 	jna	NON_DRV
   865                              <1> 	;
   866                              <1> 	;MOV	[BP+4],DL		; STORE NUMBER OF DRIVES
   867 00003F98 895508              <1> 	mov	[ebp+8], edx ; 20/02/2015	 	
   868 00003F9B 6683FF01            <1> 	CMP	DI,1			; CHECK FOR VALID DRIVE
   869                              <1> 	;JA	short NON_DRV1		; DRIVE INVALID
   870 00003F9F 0F8780000000        <1> 	ja	NON_DRV1 ; 29/08/2020
   871                              <1> 	;MOV	BYTE [BP+5],1		; MAXIMUM HEAD NUMBER =	1
   872 00003FA5 C6450901            <1> 	mov	byte [ebp+9], 1  ; 20/02/2015	
   873 00003FA9 E8E1080000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
   874                              <1> 	;;20/02/2015
   875                              <1> 	;;JC	short CHK_EST		; IF CMOS BAD CHECKSUM ESTABLISHED
   876                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE TYPE
   877 00003FAE 740F                <1> 	JZ	short CHK_EST		; JUMP IF SO
   878 00003FB0 E82B020000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   879 00003FB5 7208                <1> 	JC	short CHK_EST		; TYPE NOT IN TABLE (POSSIBLE BAD CMOS)
   880                              <1> 	;MOV	[BP+2],AL		; STORE VALID CMOS DRIVE TYPE
   881                              <1>         ;mov	[ebp+4], al ; 06/02/2015
   882 00003FB7 8A4B04              <1> 	MOV     CL, [eBX+MD.SEC_TRK]     ; GET SECTOR/TRACK
   883 00003FBA 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]     ; GET MAX. TRACK NUMBER
   884 00003FBD EB36                <1> 	JMP	SHORT STO_CX		; CMOS GOOD, USE CMOS
   885                              <1> CHK_EST:
   886 00003FBF 8AA7[6D640100]      <1> 	MOV	AH, [DSK_STATE+eDI]	; LOAD STATE FOR THIS DRIVE
   887 00003FC5 F6C410              <1> 	TEST	AH,MED_DET		; CHECK FOR ESTABLISHED STATE
   888 00003FC8 745B                <1> 	JZ	short NON_DRV1		; CMOS BAD/INVALID OR UNESTABLISHED
   889                              <1> USE_EST:
   890 00003FCA 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE STATE
   891 00003FCD 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
   892 00003FD0 757B                <1> 	JNE	short USE_EST2		; NO, GO CHECK OTHER RATE
   893                              <1> 
   894                              <1> ;-----	DATA RATE IS 250 KBS, TRY 360 KB TABLE FIRST
   895                              <1> 
   896 00003FD2 B001                <1> 	MOV	AL,01			; DRIVE TYPE 1 (360KB)
   897 00003FD4 E807020000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   898 00003FD9 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   899 00003FDC 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   900 00003FDF F687[6D640100]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; 80 TRACK ?
   901 00003FE6 740D                <1> 	JZ	short STO_CX		; MUST BE 360KB DRIVE 
   902                              <1> 
   903                              <1> ;-----	IT IS 1.44 MB DRIVE
   904                              <1> 
   905                              <1> PARM144:
   906 00003FE8 B004                <1> 	MOV	AL,04			; DRIVE TYPE 4 (1.44MB)
   907 00003FEA E8F1010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   908 00003FEF 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   909 00003FF2 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   910                              <1> STO_CX:
   911 00003FF5 894D00              <1> 	MOV	[eBP],eCX		; SAVE POINTER IN STACK FOR RETURN
   912                              <1> ES_DI:
   913                              <1> 	;MOV	[BP+6],BX		; ADDRESS OF MEDIA/DRIVE PARM TABLE 
   914                              <1> 	;mov	[ebp+12], ebx ; 06/02/2015
   915                              <1> 	;MOV	AX,CS			; SEGMENT MEDIA/DRIVE PARAMETER TABLE
   916                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
   917                              <1> 	;
   918                              <1> 	; 28/05/2016
   919                              <1> 	; 27/05/2016
   920                              <1> 	; return floppy disk parameters table to user
   921                              <1> 	; in user's buffer, which is pointed by EBX
   922                              <1> 	;
   923 00003FF8 57                  <1> 	push	edi
   924 00003FF9 8B7D04              <1> 	mov	edi, [ebp+4]  		; ebx (input), user's buffer address
   925                              <1> 	; 29/08/2020
   926 00003FFC 09FF                <1> 	or	edi, edi
   927 00003FFE 7417                <1> 	jz	short no_copy_fdpt
   928                              <1> 	;
   929 00004000 0FB6C0              <1> 	movzx	eax, al
   930 00004003 894504              <1>         mov	[ebp+4], eax   ; ebx	; drive type (for floppy drives)
   931                              <1> 	; 01/06/2016 (INT 33h, disk type return for floppy disks, in BL)
   932 00004006 A3[64700100]        <1> 	mov	[user_buffer], eax	; 01/06/2016 (overwrite ebx return value)
   933                              <1> 	;(INT 33h, Function 08h will replace user's buffer addr with disk type!)
   934                              <1> 	;
   935 0000400B 89DE                <1> 	mov	esi, ebx 		; floppy disk parameter table (16 bytes)
   936 0000400D B910000000          <1> 	mov	ecx, 16 ; 16 bytes
   937 00004012 E87AB20000          <1>         call    transfer_to_user_buffer ; trdosk6.s (16/05/2016)
   938                              <1> no_copy_fdpt:
   939 00004017 5F                  <1> 	pop	edi	
   940                              <1> DP_OUT:
   941 00004018 E868020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   942 0000401D 6631C0              <1> 	XOR	AX,AX			; CLEAR
   943 00004020 F8                  <1> 	CLC
   944 00004021 C3                  <1> 	RETn
   945                              <1> 
   946                              <1> ;-----	NO DRIYE PRESENT HANDLER
   947                              <1> 
   948                              <1> NON_DRV:
   949                              <1> 	;MOV	BYTE [BP+4],0		; CLEAR NUMBER OF DRIVES
   950 00004022 895508              <1> 	mov	[ebp+8], edx ; 0 ; 20/02/2015
   951                              <1> NON_DRV1:
   952 00004025 6681FF8000          <1> 	CMP	DI,80H			; CHECK FOR FIXED MEDIA TYPE REQUEST
   953 0000402A 720C                <1> 	JB	short NON_DRV2		; CONTINUE IF NOT REQUEST FALL THROUGH
   954                              <1> 
   955                              <1> ;-----	FIXED DISK REQUEST FALL THROUGH ERROR
   956                              <1> 	
   957 0000402C E854020000          <1> 	CALL	XLAT_OLD		; ELSE TRANSLATE TO COMPATIBLE MODE
   958 00004031 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
   959 00004034 B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
   960 00004036 F9                  <1> 	STC
   961 00004037 C3                  <1> 	RETn
   962                              <1> 
   963                              <1> NON_DRV2:
   964                              <1> 	;XOR	AX,AX			; CLEAR PARMS IF NO DRIVES OR CMOS BAD
   965 00004038 31C0                <1> 	xor	eax, eax	
   966 0000403A 66894500            <1> 	MOV	[eBP],AX		; TRACKS, SECTORS/TRACK = 0
   967                              <1> 	;MOV	[BP+5],AH		; HEAD = 0
   968 0000403E 886509              <1> 	mov	[ebp+9], ah ; 06/02/2015
   969                              <1> 	;MOV	[BP+6],AX		; OFFSET TO DISK_BASE = 0
   970 00004041 89450C              <1> 	mov	[ebp+12], eax
   971                              <1> 	;;MOV	ES,AX			; ES IS SEGMENT OF TABLE
   972                              <1> 	;JMP	SHORT DP_OUT
   973                              <1> 
   974                              <1> 	; 30/08/2020
   975 00004044 E83C020000          <1> 	call	XLAT_OLD
   976                              <1> 	;mov	ah, NOT_RDY ; drive not ready
   977 00004049 B407                <1> 	mov	ah, INIT_FAIL ; DRIVE PARAMETER ACTIVITY FAILED 
   978 0000404B F9                  <1> 	stc	; cf -> 1, ah = 'drive not ready' error code
   979 0000404C C3                  <1> 	retn		
   980                              <1> 
   981                              <1> ;-----	DATA RATE IS EITHER 300 KBS OR 500 KBS, TRY 1.2 MB TABLE FIRST
   982                              <1> 
   983                              <1> USE_EST2:
   984 0000404D B002                <1> 	MOV	AL,02			; DRIVE TYPE 2 (1.2MB)
   985 0000404F E88C010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   986 00004054 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   987 00004057 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   988 0000405A 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
   989 0000405D 7496                <1> 	JZ	short STO_CX		; MUST BE 1.2MB DRIVE
   990 0000405F EB87                <1> 	JMP	SHORT PARM144		; ELSE, IT IS 1.44MB DRIVE 
   991                              <1> 
   992                              <1> ; 30/08/2020
   993                              <1> 
   994                              <1> ;-------------------------------------------------------------------------------
   995                              <1> ; DISK_TYPE (AH = 15H)	
   996                              <1> ;	THIS ROUTINE RETURNS THE TYPE OF MEDIA INSTALLED.
   997                              <1> ;
   998                              <1> ;  ON ENTRY:	DI = DRIVE #
   999                              <1> ;
  1000                              <1> ;  ON EXIT:	AH = DRIVE TYPE, CY=0
  1001                              <1> ;-------------------------------------------------------------------------------
  1002                              <1> DSK_TYPE:
  1003 00004061 E8EE010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1004 00004066 8A87[6D640100]      <1> 	MOV	AL,[DSK_STATE+eDI]	; GET PRESENT STATE INFORMATION
  1005 0000406C 08C0                <1> 	OR	AL,AL			; CHECK FOR NO DRIVE
  1006 0000406E 7418                <1> 	JZ	short NO_DRV
  1007 00004070 B401                <1> 	MOV	AH,NOCHGLN		; NO CHANGE LINE FOR 40 TRACK DRIVE
  1008 00004072 A801                <1> 	TEST	AL,TRK_CAPA		; IS THIS DRIVE AN 80 TRACK DRIVE?
  1009 00004074 7402                <1> 	JZ	short DT_BACK		; IF NO JUMP
  1010 00004076 B402                <1> 	MOV	AH,CHGLN		; CHANGE LINE FOR 80 TRACK DRIVE
  1011                              <1> DT_BACK:
  1012 00004078 6650                <1> 	PUSH	AX			; SAVE RETURN VALUE
  1013 0000407A E806020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1014 0000407F 6658                <1> 	POP	AX			; RESTORE RETURN VALUE
  1015 00004081 F8                  <1> 	CLC				; NO ERROR
  1016 00004082 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  1017 00004085 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  1018 00004087 C3                  <1> 	RETn
  1019                              <1> NO_DRV:	
  1020                              <1> 	;XOR	AH,AH			; NO DRIVE PRESENT OR UNKNOWN
  1021                              <1> 	;JMP	SHORT DT_BACK
  1022                              <1> 	
  1023                              <1> 	; 30/08/2020
  1024 00004088 E8F8010000          <1> 	call	XLAT_OLD
  1025 0000408D 29C0                <1> 	sub	eax, eax
  1026 0000408F F9                  <1> 	stc	; cf = 1 -> drive not ready, ah = 0 (disk type = 0)
  1027 00004090 C3                  <1> 	retn
  1028                              <1> 
  1029                              <1> ;-------------------------------------------------------------------------------
  1030                              <1> ; DISK_CHANGE	(AH = 16H)
  1031                              <1> ;	THIS ROUTINE RETURNS THE STATE OF THE DISK CHANGE LINE.
  1032                              <1> ;
  1033                              <1> ; ON ENTRY:	DI = DRIVE #
  1034                              <1> ;
  1035                              <1> ; ON EXIT:	AH = @DSKETTE_STATUS
  1036                              <1> ;		     00 - DISK CHANGE LINE INACTIVE, CY = 0
  1037                              <1> ;		     06 - DISK CHANGE LINE ACTIVE, CY = 1
  1038                              <1> ;-------------------------------------------------------------------------------
  1039                              <1> DSK_CHANGE:
  1040 00004091 E8BE010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1041 00004096 8A87[6D640100]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET MEDIA STATE INFORMATION
  1042 0000409C 08C0                <1> 	OR	AL,AL			; DRIVE PRESENT ?
  1043 0000409E 7422                <1> 	JZ	short DC_NON		; JUMP IF NO DRIVE
  1044 000040A0 A801                <1> 	TEST	AL,TRK_CAPA		; 80 TRACK DRIVE ?
  1045 000040A2 7407                <1> 	JZ	short SETIT		; IF SO , CHECK CHANGE LINE
  1046                              <1> DC0:
  1047 000040A4 E88D0A0000          <1>         CALL    READ_DSKCHNG            ; GO CHECK STATE OF DISK CHANGE LINE
  1048 000040A9 7407                <1> 	JZ	short FINIS		; CHANGE LINE NOT ACTIVE
  1049                              <1> 
  1050 000040AB C605[60640100]06    <1> SETIT:	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; INDICATE MEDIA REMOVED
  1051                              <1> 
  1052 000040B2 E8CE010000          <1> FINIS:	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1053 000040B7 E808070000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1054 000040BC 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
  1055 000040BF 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  1056 000040C1 C3                  <1> 	RETn
  1057                              <1> DC_NON:
  1058 000040C2 800D[60640100]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; SET TIMEOUT, NO DRIVE
  1059 000040C9 EBE7                <1> 	JMP	SHORT FINIS
  1060                              <1> 
  1061                              <1> ;-------------------------------------------------------------------------------
  1062                              <1> ; FORMAT_SET	(AH = 17H)
  1063                              <1> ;	THIS ROUTINE IS USED TO ESTABLISH THE TYPE OF MEDIA TO BE USED
  1064                              <1> ;	FOR THE FOLLOWING FORMAT OPERATION.
  1065                              <1> ;
  1066                              <1> ; ON ENTRY:	SI LOW = DASD TYPE FOR FORMAT
  1067                              <1> ;		DI     = DRIVE #
  1068                              <1> ;
  1069                              <1> ; ON EXIT:	@DSKETTE_STATUS REFLECTS STATUS
  1070                              <1> ;		AH = @DSKETTE_STATUS
  1071                              <1> ;		CY = 1 IF ERROR
  1072                              <1> ;-------------------------------------------------------------------------------
  1073                              <1> FORMAT_SET:
  1074 000040CB E884010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1075 000040D0 6656                <1> 	PUSH	SI			; SAVE DASD TYPE
  1076 000040D2 6689F0              <1> 	MOV	AX,SI			; AH = ? , AL , DASD TYPE
  1077 000040D5 30E4                <1> 	XOR	AH,AH			; AH , 0 , AL , DASD TYPE
  1078 000040D7 6689C6              <1> 	MOV	SI,AX			; SI = DASD TYPE
  1079 000040DA 80A7[6D640100]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  1080 000040E1 664E                <1> 	DEC	SI			; CHECK FOR 320/360K MEDIA & DRIVE
  1081 000040E3 7509                <1> 	JNZ	short NOT_320		; BYPASS IF NOT
  1082 000040E5 808F[6D640100]90    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_250 ; SET TO 320/360
  1083 000040EC EB48                <1> 	JMP	SHORT S0
  1084                              <1> 
  1085                              <1> NOT_320:
  1086 000040EE E8B6030000          <1> 	CALL	MED_CHANGE		; CHECK FOR TIME_OUT
  1087 000040F3 803D[60640100]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT
  1088 000040FA 743A                <1> 	JZ	short S0		; IF TIME OUT TELL CALLER
  1089                              <1> S3:
  1090 000040FC 664E                <1> 	DEC	SI			; CHECK FOR 320/360K IN 1.2M DRIVE
  1091 000040FE 7509                <1> 	JNZ	short NOT_320_12	; BYPASS IF NOT
  1092 00004100 808F[6D640100]70    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+DBL_STEP+RATE_300 ; SET STATE
  1093 00004107 EB2D                <1> 	JMP	SHORT S0
  1094                              <1> 
  1095                              <1> NOT_320_12:
  1096 00004109 664E                <1> 	DEC	SI			; CHECK FOR 1.2M MEDIA IN 1.2M DRIVE
  1097 0000410B 7509                <1> 	JNZ	short NOT_12		; BYPASS IF NOT
  1098 0000410D 808F[6D640100]10    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_500 ; SET STATE VARIABLE
  1099 00004114 EB20                <1> 	JMP	SHORT S0		; RETURN TO CALLER
  1100                              <1> 
  1101                              <1> NOT_12:	
  1102 00004116 664E                <1> 	DEC	SI			; CHECK FOR SET DASD TYPE 04
  1103 00004118 752B                <1> 	JNZ	short FS_ERR		; BAD COMMAND EXIT IF NOT VALID TYPE
  1104                              <1> 
  1105 0000411A F687[6D640100]04    <1> 	TEST	byte [DSK_STATE+eDI], DRV_DET ; DRIVE DETERMINED ?
  1106 00004121 740B                <1> 	JZ	short ASSUME		; IF STILL NOT DETERMINED ASSUME
  1107 00004123 B050                <1> 	MOV	AL,MED_DET+RATE_300
  1108 00004125 F687[6D640100]02    <1>         TEST    byte [DSK_STATE+eDI], FMT_CAPA ; MULTIPLE FORMAT CAPABILITY ?
  1109 0000412C 7502                <1> 	JNZ	short OR_IT_IN		; IF 1.2 M THEN DATA RATE 300
  1110                              <1> 
  1111                              <1> ASSUME:
  1112 0000412E B090                <1> 	MOV	AL,MED_DET+RATE_250	; SET UP
  1113                              <1> 
  1114                              <1> OR_IT_IN:
  1115 00004130 0887[6D640100]      <1> 	OR	[DSK_STATE+eDI], AL	; OR IN THE CORRECT STATE
  1116                              <1> S0:
  1117 00004136 E84A010000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1118 0000413B E884060000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1119 00004140 665B                <1> 	POP	BX			; GET SAVED AL TO BL
  1120 00004142 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  1121 00004144 C3                  <1> 	RETn
  1122                              <1> 
  1123                              <1> FS_ERR:
  1124 00004145 C605[60640100]01    <1> 	MOV	byte [DSKETTE_STATUS], BAD_CMD ; UNKNOWN STATE,BAD COMMAND
  1125 0000414C EBE8                <1> 	JMP	SHORT S0
  1126                              <1> 
  1127                              <1> ;-------------------------------------------------------------------------------
  1128                              <1> ; SET_MEDIA	(AH = 18H)
  1129                              <1> ;	THIS ROUTINE SETS THE TYPE OF MEDIA AND DATA RATE 
  1130                              <1> ;	TO BE USED FOR THE FOLLOWING FORMAT OPERATION.
  1131                              <1> ;
  1132                              <1> ; ON ENTRY:
  1133                              <1> ;	[BP]	= SECTOR PER TRACK
  1134                              <1> ;	[BP+1]	= TRACK #
  1135                              <1> ;	DI	= DRIVE #
  1136                              <1> ;
  1137                              <1> ; ON EXIT:
  1138                              <1> ;	@DSKETTE_STATUS REFLECTS STATUS
  1139                              <1> ;	IF NO ERROR:
  1140                              <1> ;		AH = 0
  1141                              <1> ;		CY = 0
  1142                              <1> ;		ES = SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  1143                              <1> ;		DI/[BP+6] = OFFSET OF MEDIA/DRIVE PARAMETER TABLE
  1144                              <1> ;	IF ERROR:	
  1145                              <1> ;		AH = @DSKETTE_STATUS
  1146                              <1> ;		CY = 1
  1147                              <1> ;-------------------------------------------------------------------------------
  1148                              <1> SET_MEDIA:
  1149 0000414E E801010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1150 00004153 F687[6D640100]01    <1>         TEST    byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR CHANGE LINE AVAILABLE
  1151 0000415A 7415                <1> 	JZ	short SM_CMOS		; JUMP IF 40 TRACK DRIVE
  1152 0000415C E848030000          <1> 	CALL	MED_CHANGE		; RESET CHANGE LINE
  1153 00004161 803D[60640100]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT ; IF TIME OUT TELL CALLER
  1154 00004168 746B                <1> 	JE	short SM_RTN
  1155 0000416A C605[60640100]00    <1> 	MOV	byte [DSKETTE_STATUS], 0 ; CLEAR STATUS
  1156                              <1> SM_CMOS:
  1157 00004171 E819070000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  1158                              <1> 	;;20/02/2015
  1159                              <1> 	;;JC	short MD_NOT_FND	; ERROR IN CMOS
  1160                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE
  1161 00004176 745D                <1> 	JZ	short SM_RTN		; RETURN IF SO
  1162 00004178 E863000000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  1163 0000417D 7231                <1> 	JC	short MD_NOT_FND	; TYPE NOT IN TABLE (BAD CMOS)
  1164 0000417F 57                  <1> 	PUSH	eDI			; SAVE REG.
  1165 00004180 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR. TYPE TABLE
  1166 00004182 B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1167                              <1> DR_SEARCH:
  1168 00004187 8AA3[48670000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  1169 0000418D 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  1170 00004190 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH ?
  1171 00004192 7516                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT DRIVE TYPE
  1172                              <1> DR_FND:
  1173 00004194 8BBB[49670000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAM TABLE
  1174                              <1> MD_SEARCH:
  1175 0000419A 8A6704              <1>         MOV     AH, [eDI+MD.SEC_TRK]    ; GET SECTOR/TRACK
  1176 0000419D 386500              <1> 	CMP	[eBP],AH		; MATCH?
  1177 000041A0 7508                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT MEDIA
  1178 000041A2 8A670B              <1>         MOV     AH, [eDI+MD.MAX_TRK]    ; GET MAX. TRACK #
  1179 000041A5 386501              <1> 	CMP 	[eBP+1],AH		; MATCH?
  1180 000041A8 740F                <1> 	JE	short MD_FND		; YES, GO GET RATE
  1181                              <1> NXT_MD:
  1182                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  1183 000041AA 83C305              <1>         add	ebx, 5 ; 18/02/2015
  1184 000041AD E2D8                <1> 	LOOP    DR_SEARCH
  1185 000041AF 5F                  <1> 	POP	eDI			; RESTORE REG.
  1186                              <1> MD_NOT_FND:
  1187 000041B0 C605[60640100]0C    <1> 	MOV	byte [DSKETTE_STATUS], MED_NOT_FND ; ERROR, MEDIA TYPE NOT FOUND
  1188 000041B7 EB1C                <1> 	JMP	SHORT SM_RTN		; RETURN
  1189                              <1> MD_FND:
  1190 000041B9 8A470C              <1>         MOV     AL, [eDI+MD.RATE]       ; GET RATE
  1191 000041BC 3C40                <1> 	CMP	AL,RATE_300		; DOUBLE STEP REQUIRED FOR RATE 300
  1192 000041BE 7502                <1> 	JNE	short MD_SET
  1193 000041C0 0C20                <1> 	OR	AL,DBL_STEP
  1194                              <1> MD_SET:
  1195                              <1> 	;MOV	[BP+6],DI		; SAVE TABLE POINTER IN STACK
  1196 000041C2 897D0C              <1> 	mov	[ebp+12], edi ; 18/02/2015
  1197 000041C5 0C10                <1> 	OR	AL,MED_DET		; SET MEDIA ESTABLISHED
  1198 000041C7 5F                  <1> 	POP	eDI
  1199 000041C8 80A7[6D640100]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  1200 000041CF 0887[6D640100]      <1> 	OR	[DSK_STATE+eDI], AL
  1201                              <1> 	;MOV	AX, CS			; SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  1202                              <1> 	;MOV	ES, AX			; ES IS SEGMENT OF TABLE
  1203                              <1> SM_RTN:
  1204 000041D5 E8AB000000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1205 000041DA E8E5050000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1206 000041DF C3                  <1> 	RETn
  1207                              <1> 
  1208                              <1> ;----------------------------------------------------------------
  1209                              <1> ; DR_TYPE_CHECK							:
  1210                              <1> ;	CHECK IF THE GIVEN DRIVE TYPE IN REGISTER (AL)		:
  1211                              <1> ;	IS SUPPORTED IN BIOS DRIVE TYPE TABLE			:
  1212                              <1> ; ON ENTRY:							:
  1213                              <1> ;	AL = DRIVE TYPE						:
  1214                              <1> ; ON EXIT:							:
  1215                              <1> ;	CS = SEGMENT MEDIA/DRIVE PARAMETER TABLE (CODE)		:
  1216                              <1> ;	CY = 0 	DRIVE TYPE SUPPORTED				:
  1217                              <1> ;	     BX = OFFSET TO MEDIA/DRIVE PARAMETER TABLE		:
  1218                              <1> ;	CY = 1	DRIVE TYPE NOT SUPPORTED 			:
  1219                              <1> ; REGISTERS ALTERED: eBX						:
  1220                              <1> ;----------------------------------------------------------------		
  1221                              <1> DR_TYPE_CHECK:
  1222 000041E0 6650                <1> 	PUSH	AX			
  1223 000041E2 51                  <1> 	PUSH	eCX
  1224 000041E3 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  1225 000041E5 B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1226                              <1> TYPE_CHK:	
  1227 000041EA 8AA3[48670000]      <1> 	MOV	AH,[DR_TYPE+eBX]	; GET DRIVE TYPE
  1228 000041F0 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  1229 000041F2 740D                <1> 	JE	short DR_TYPE_VALID	; YES, RETURN WITH CARRY RESET
  1230                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  1231 000041F4 83C305              <1>         add	ebx, 5	; 16/02/2015 (32 bit address modification)
  1232 000041F7 E2F1                <1> 	LOOP    TYPE_CHK
  1233                              <1> 	;
  1234 000041F9 BB[A7670000]        <1> 	mov	ebx, MD_TBL6		; 1.44MB fd parameter table
  1235                              <1> 					; Default for GET_PARM (11/12/2014)
  1236                              <1> 	;
  1237 000041FE F9                  <1> 	STC				; DRIVE TYPE NOT FOUND IN TABLE
  1238 000041FF EB06                <1> 	JMP	SHORT TYPE_RTN
  1239                              <1> DR_TYPE_VALID:
  1240 00004201 8B9B[49670000]      <1> 	MOV	eBX,[DR_TYPE+eBX+1] 	; BX = MEDIA TABLE
  1241                              <1> TYPE_RTN:
  1242 00004207 59                  <1> 	POP	eCX
  1243 00004208 6658                <1> 	POP	AX
  1244 0000420A C3                  <1> 	RETn	
  1245                              <1> 		
  1246                              <1> ;----------------------------------------------------------------
  1247                              <1> ; SEND_SPEC							:
  1248                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  1249                              <1> ;	THE DRIVE PARAMETER TABLE POINTED BY @DISK_POINTER	:
  1250                              <1> ; ON ENTRY:	@DISK_POINTER = DRIVE PARAMETER TABLE		:
  1251                              <1> ; ON EXIT:	NONE						:	
  1252                              <1> ; REGISTERS ALTERED: CX, DX					:
  1253                              <1> ;----------------------------------------------------------------		
  1254                              <1> SEND_SPEC:
  1255 0000420B 50                  <1> 	PUSH	eAX			; SAVE AX
  1256 0000420C B8[32420000]        <1> 	MOV	eAX, SPECBAC		; LOAD ERROR ADDRESS
  1257 00004211 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1258 00004212 B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  1259 00004214 E885070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1260 00004219 28D2                <1> 	SUB	DL,DL			; FIRST SPECIFY BYTE
  1261 0000421B E878060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  1262 00004220 E879070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1263 00004225 B201                <1> 	MOV	DL,1			; SECOND SPECIFY BYTE
  1264 00004227 E86C060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  1265 0000422C E86D070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1266 00004231 58                  <1> 	POP	eAX			; POP ERROR RETURN
  1267                              <1> SPECBAC:
  1268 00004232 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  1269 00004233 C3                  <1> 	RETn
  1270                              <1> 
  1271                              <1> ;----------------------------------------------------------------
  1272                              <1> ; SEND_SPEC_MD							:
  1273                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  1274                              <1> ;	THE MEDIA/DRIVE PARAMETER TABLE POINTED BY (CS:BX)	:
  1275                              <1> ; ON ENTRY:	CS:BX = MEDIA/DRIVE PARAMETER TABLE		:
  1276                              <1> ; ON EXIT:	NONE						:	
  1277                              <1> ; REGISTERS ALTERED: AX						:
  1278                              <1> ;----------------------------------------------------------------		
  1279                              <1> SEND_SPEC_MD:
  1280 00004234 50                  <1> 	PUSH	eAX			; SAVE RATE DATA
  1281 00004235 B8[52420000]        <1> 	MOV	eAX, SPEC_ESBAC		; LOAD ERROR ADDRESS
  1282 0000423A 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1283 0000423B B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  1284 0000423D E85C070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1285 00004242 8A23                <1>         MOV     AH, [eBX+MD.SPEC1]      ; GET 1ST SPECIFY BYTE
  1286 00004244 E855070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1287 00004249 8A6301              <1>         MOV     AH, [eBX+MD.SPEC2]      ; GET SECOND SPECIFY BYTE
  1288 0000424C E84D070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1289 00004251 58                  <1> 	POP	eAX			; POP ERROR RETURN
  1290                              <1> SPEC_ESBAC:
  1291 00004252 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  1292 00004253 C3                  <1> 	RETn
  1293                              <1> 
  1294                              <1> ;-------------------------------------------------------------------------------
  1295                              <1> ; XLAT_NEW  
  1296                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM COMPATIBLE
  1297                              <1> ;	MODE TO NEW ARCHITECTURE.
  1298                              <1> ;
  1299                              <1> ; ON ENTRY:	DI = DRIVE #
  1300                              <1> ;-------------------------------------------------------------------------------
  1301                              <1> XLAT_NEW:
  1302 00004254 83FF01              <1> 	CMP	eDI,1				; VALID DRIVE
  1303 00004257 7725                <1> 	JA	short XN_OUT			; IF INVALID BACK
  1304 00004259 80BF[6D640100]00    <1> 	CMP	byte [DSK_STATE+eDI], 0		; NO DRIVE ?
  1305 00004260 741D                <1> 	JZ	short DO_DET			; IF NO DRIVE ATTEMPT DETERMINE
  1306 00004262 6689F9              <1> 	MOV	CX,DI				; CX = DRIVE NUMBER
  1307 00004265 C0E102              <1> 	SHL	CL,2				; CL = SHIFT COUNT, A=0, B=4
  1308 00004268 A0[6C640100]        <1> 	MOV	AL, [HF_CNTRL]			; DRIVE INFORMATION
  1309 0000426D D2C8                <1> 	ROR	AL,CL				; TO LOW NIBBLE
  1310 0000426F 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA	; KEEP DRIVE BITS
  1311 00004271 80A7[6D640100]F8    <1>         AND     byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA)
  1312 00004278 0887[6D640100]      <1> 	OR	[DSK_STATE+eDI], AL		; UPDATE DRIVE STATE
  1313                              <1> XN_OUT:
  1314 0000427E C3                  <1> 	RETn
  1315                              <1> DO_DET:
  1316 0000427F E8BF080000          <1> 	CALL	DRIVE_DET			; TRY TO DETERMINE
  1317 00004284 C3                  <1> 	RETn
  1318                              <1> 
  1319                              <1> ;-------------------------------------------------------------------------------
  1320                              <1> ; XLAT_OLD 
  1321                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM NEW
  1322                              <1> ;	ARCHITECTURE TO COMPATIBLE MODE.
  1323                              <1> ;
  1324                              <1> ; ON ENTRY:	DI = DRIVE
  1325                              <1> ;-------------------------------------------------------------------------------
  1326                              <1> XLAT_OLD:
  1327 00004285 83FF01              <1> 	CMP	eDI,1			; VALID DRIVE ?
  1328                              <1>         ;JA     short XO_OUT            ; IF INVALID BACK
  1329 00004288 0F8786000000        <1>         ja      XO_OUT
  1330 0000428E 80BF[6D640100]00    <1>         CMP	byte [DSK_STATE+eDI],0	; NO DRIVE ?
  1331 00004295 747D                <1> 	JZ	short XO_OUT		; IF NO DRIVE TRANSLATE DONE
  1332                              <1> 
  1333                              <1> ;-----	TEST FOR SAVED DRIVE INFORMATION ALREADY SET
  1334                              <1> 
  1335 00004297 6689F9              <1> 	MOV	CX,DI			; CX = DRIVE NUMBER
  1336 0000429A C0E102              <1> 	SHL	CL,2			; CL = SHIFT COUNT, A=0, B=4
  1337 0000429D B402                <1> 	MOV	AH,FMT_CAPA		; LOAD MULTIPLE DATA RATE BIT MASK
  1338 0000429F D2CC                <1> 	ROR	AH,CL			; ROTATE BY MASK
  1339 000042A1 8425[6C640100]      <1> 	TEST	[HF_CNTRL], AH		; MULTIPLE-DATA RATE DETERMINED ?
  1340 000042A7 751C                <1> 	JNZ	short SAVE_SET		; IF SO, NO NEED TO RE-SAVE
  1341                              <1> 
  1342                              <1> ;-----	ERASE DRIVE BITS IN @HF_CNTRL FOR THIS DRIVE
  1343                              <1> 
  1344 000042A9 B407                <1> 	MOV	AH,DRV_DET+FMT_CAPA+TRK_CAPA ; MASK TO KEEP
  1345 000042AB D2CC                <1> 	ROR	AH,CL			; FIX MASK TO KEEP
  1346 000042AD F6D4                <1> 	NOT	AH			; TRANSLATE MASK
  1347 000042AF 2025[6C640100]      <1> 	AND	[HF_CNTRL], AH		; KEEP BITS FROM OTHER DRIVE INTACT
  1348                              <1> 
  1349                              <1> ;-----	ACCESS CURRENT DRIVE BITS AND STORE IN @HF_CNTRL
  1350                              <1> 
  1351 000042B5 8A87[6D640100]      <1> 	MOV	AL, [DSK_STATE+eDI]	; ACCESS STATE
  1352 000042BB 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA ; KEEP DRIVE BITS
  1353 000042BD D2C8                <1> 	ROR	AL,CL			; FIX FOR THIS DRIVE
  1354 000042BF 0805[6C640100]      <1> 	OR	[HF_CNTRL], AL		; UPDATE SAVED DRIVE STATE
  1355                              <1> 
  1356                              <1> ;-----	TRANSLATE TO COMPATIBILITY MODE
  1357                              <1> 
  1358                              <1> SAVE_SET:
  1359 000042C5 8AA7[6D640100]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  1360 000042CB 88E7                <1> 	MOV	BH,AH			; TO BH FOR LATER
  1361 000042CD 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE
  1362 000042D0 80FC00              <1> 	CMP	AH,RATE_500		; RATE 500 ?
  1363 000042D3 7410                <1> 	JZ	short CHK_144		; YES 1.2/1.2 OR 1.44/1.44
  1364 000042D5 B001                <1> 	MOV	AL,M3D1U		; AL = 360 IN 1.2 UNESTABLISHED
  1365 000042D7 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
  1366 000042DA 7518                <1> 	JNZ	short CHK_250		; NO, 360/360, 720/720 OR 720/1.44
  1367 000042DC F6C720              <1> 	TEST	BH,DBL_STEP		; CHECK FOR DOUBLE STEP
  1368 000042DF 751F                <1> 	JNZ	short TST_DET		; MUST BE 360 IN 1.2
  1369                              <1> UNKNO:
  1370 000042E1 B007                <1> 	MOV	AL,MED_UNK		; NONE OF THE ABOVE
  1371 000042E3 EB22                <1> 	JMP	SHORT AL_SET		; PROCESS COMPLETE
  1372                              <1> CHK_144:
  1373 000042E5 E8A5050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  1374                              <1> 	;;20/02/2015
  1375                              <1> 	;;JC	short UNKNO		; ERROR, SET 'NONE OF ABOVE'
  1376 000042EA 74F5                <1> 	jz	short UNKNO ;; 20/02/2015
  1377 000042EC 3C02                <1> 	CMP	AL,2			; 1.2MB DRIVE ?
  1378 000042EE 75F1                <1> 	JNE	short UNKNO		; NO, GO SET 'NONE OF ABOVE'
  1379 000042F0 B002                <1> 	MOV	AL,M1D1U		; AL = 1.2 IN 1.2 UNESTABLISHED
  1380 000042F2 EB0C                <1> 	JMP	SHORT TST_DET
  1381                              <1> CHK_250:
  1382 000042F4 B000                <1> 	MOV	AL,M3D3U		; AL = 360 IN 360 UNESTABLISHED
  1383 000042F6 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
  1384 000042F9 75E6                <1> 	JNZ	short UNKNO		; IF SO FALL IHRU
  1385 000042FB F6C701              <1> 	TEST	BH,TRK_CAPA		; 80 TRACK CAPABILITY ?
  1386 000042FE 75E1                <1> 	JNZ	short UNKNO		; IF SO JUMP, FALL THRU TEST DET
  1387                              <1> TST_DET:
  1388 00004300 F6C710              <1> 	TEST	BH,MED_DET		; DETERMINED ?
  1389 00004303 7402                <1> 	JZ	short AL_SET		; IF NOT THEN SET
  1390 00004305 0403                <1> 	ADD	AL,3			; MAKE DETERMINED/ESTABLISHED
  1391                              <1> AL_SET:
  1392 00004307 80A7[6D640100]F8    <1> 	AND	byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA) ; CLEAR DRIVE
  1393 0000430E 0887[6D640100]      <1> 	OR	[DSK_STATE+eDI], AL	; REPLACE WITH COMPATIBLE MODE
  1394                              <1> XO_OUT:
  1395 00004314 C3                  <1> 	RETn
  1396                              <1> 
  1397                              <1> ;-------------------------------------------------------------------------------
  1398                              <1> ; RD_WR_VF
  1399                              <1> ;	COMMON READ, WRITE AND VERIFY: 
  1400                              <1> ;	MAIN LOOP FOR STATE RETRIES.
  1401                              <1> ;
  1402                              <1> ; ON ENTRY:	AH = READ/WRITE/VERIFY NEC PARAMETER
  1403                              <1> ;		AL = READ/WRITE/VERIFY DMA PARAMETER
  1404                              <1> ;
  1405                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1406                              <1> ;-------------------------------------------------------------------------------
  1407                              <1> RD_WR_VF:
  1408 00004315 6650                <1> 	PUSH	AX			; SAVE DMA, NEC PARAMETERS
  1409 00004317 E838FFFFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1410 0000431C E8F3000000          <1> 	CALL	SETUP_STATE		; INITIALIZE START AND END RATE
  1411 00004321 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  1412                              <1> DO_AGAIN:
  1413 00004323 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  1414 00004325 E87F010000          <1> 	CALL	MED_CHANGE		; MEDIA CHANGE AND RESET IF CHANGED
  1415 0000432A 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  1416 0000432C 0F82C9000000        <1>         JC      RWV_END                 ; MEDIA CHANGE ERROR OR TIME-OUT
  1417                              <1> RWV:
  1418 00004332 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  1419 00004334 8AB7[6D640100]      <1> 	MOV	DH, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1420 0000433A 80E6C0              <1> 	AND	DH,RATE_MSK		; KEEP ONLY RATE
  1421 0000433D E84D050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL (AL)
  1422                              <1> 	;;20/02/2015
  1423                              <1> 	;;JC	short RWV_ASSUME	; ERROR IN CMOS
  1424 00004342 7451                <1> 	jz	short RWV_ASSUME ; 20/02/2015
  1425 00004344 3C01                <1> 	CMP	AL,1			; 40 TRACK DRIVE?
  1426 00004346 750D                <1> 	JNE	short RWV_1		; NO, BYPASS CMOS VALIDITY CHECK
  1427 00004348 F687[6D640100]01    <1> 	TEST	byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR 40 TRACK DRIVE
  1428 0000434F 7413                <1> 	JZ	short RWV_2		; YES, CMOS IS CORRECT
  1429 00004351 B002                <1> 	MOV	AL,2			; CHANGE TO 1.2M
  1430 00004353 EB0F                <1> 	JMP	SHORT RWV_2
  1431                              <1> RWV_1:
  1432 00004355 720D                <1> 	JB	short RWV_2		; NO DRIVE SPECIFIED, CONTINUE
  1433 00004357 F687[6D640100]01    <1> 	TEST    byte [DSK_STATE+eDI], TRK_CAPA ; IS IT REALLY 40 TRACK?
  1434 0000435E 7504                <1> 	JNZ	short RWV_2		; NO, 80 TRACK
  1435 00004360 B001                <1> 	MOV	AL,1			; IT IS 40 TRACK, FIX CMOS VALUE
  1436 00004362 EB04                <1> 	jmp	short rwv_3
  1437                              <1> RWV_2:
  1438 00004364 08C0                <1> 	OR	AL,AL			; TEST FOR NO DRIVE
  1439 00004366 742D                <1> 	JZ	short RWV_ASSUME	; ASSUME TYPE, USE MAX TRACK
  1440                              <1> rwv_3:
  1441 00004368 E873FEFFFF          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL.
  1442 0000436D 7226                <1> 	JC	short RWV_ASSUME	; TYPE NOT IN TABLE (BAD CMOS)
  1443                              <1> 
  1444                              <1> ;-----	SEARCH FOR MEDIA/DRIVE PARAMETER TABLE
  1445                              <1> 
  1446 0000436F 57                  <1> 	PUSH	eDI			; SAVE DRIVE #
  1447 00004370 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  1448 00004372 B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1449                              <1> RWV_DR_SEARCH:
  1450 00004377 8AA3[48670000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  1451 0000437D 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  1452 00004380 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  1453 00004382 750B                <1> 	JNE	short RWV_NXT_MD	; NO, CHECK NEXT DRIVE TYPE
  1454                              <1> RWV_DR_FND:
  1455 00004384 8BBB[49670000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAMETER TABLE
  1456                              <1> RWV_MD_SEARH:
  1457 0000438A 3A770C              <1>         CMP     DH, [eDI+MD.RATE]       ; MATCH?
  1458 0000438D 741B                <1> 	JE	short RWV_MD_FND	; YES, GO GET 1ST SPECIFY BYTE
  1459                              <1> RWV_NXT_MD:
  1460                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  1461 0000438F 83C305              <1> 	add	eBX, 5
  1462 00004392 E2E3                <1> 	LOOP	RWV_DR_SEARCH
  1463 00004394 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  1464                              <1> 
  1465                              <1> ;-----	ASSUME PRIMARY DRIVE IS INSTALLED AS SHIPPED
  1466                              <1> 
  1467                              <1> RWV_ASSUME:
  1468 00004395 BB[66670000]        <1> 	MOV	eBX, MD_TBL1		; POINT TO 40 TRACK 250 KBS
  1469 0000439A F687[6D640100]01    <1> 	TEST 	byte [DSK_STATE+eDI], TRK_CAPA ; TEST FOR 80 TRACK
  1470 000043A1 740A                <1> 	JZ	short RWV_MD_FND1	; MUST BE 40 TRACK
  1471 000043A3 BB[80670000]        <1> 	MOV	eBX, MD_TBL3		; POINT TO 80 TRACK 500 KBS
  1472 000043A8 EB03                <1> 	JMP	short RWV_MD_FND1	; GO SPECIFY PARAMTERS
  1473                              <1> 
  1474                              <1> ;-----	CS:BX POINTS TO MEDIA/DRIVE PARAMETER TABLE
  1475                              <1> 	 			
  1476                              <1> RWV_MD_FND:
  1477 000043AA 89FB                <1> 	MOV	eBX,eDI			; BX = MEDIA/DRIVE PARAMETER TABLE
  1478 000043AC 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  1479                              <1> 	
  1480                              <1> ;-----	SEND THE SPECIFY COMMAND TO THE CONTROLLER
  1481                              <1> 
  1482                              <1> RWV_MD_FND1:
  1483 000043AD E882FEFFFF          <1> 	CALL	SEND_SPEC_MD
  1484 000043B2 E864010000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMP RATE IS SAME AS LAST RATE
  1485 000043B7 7405                <1> 	JZ	short RWV_DBL		; YES,SKIP SEND RATE COMMAND
  1486 000043B9 E83B010000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO NEC
  1487                              <1> RWV_DBL:
  1488 000043BE 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1489 000043BF E822040000          <1> 	CALL	SETUP_DBL		; CHECK FOR DOUBLE STEP
  1490 000043C4 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  1491 000043C5 7226                <1> 	JC	short CHK_RET		; ERROR FROM READ ID, POSSIBLE RETRY
  1492 000043C7 6658                <1> 	POP	AX			; RESTORE NEC, DMA COMMAND
  1493 000043C9 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1494 000043CB 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1495 000043CC E861010000          <1> 	CALL	DMA_SETUP		; SET UP THE DMA
  1496 000043D1 5B                  <1> 	POP	eBX 
  1497 000043D2 6658                <1> 	POP	AX			; RESTORE NEC COMMAND
  1498 000043D4 722F                <1> 	JC	short RWV_BAC		; CHECK FOR DMA BOUNDARY ERROR
  1499 000043D6 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1500 000043D8 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1501 000043D9 E83C020000          <1> 	CALL	NEC_INIT		; INITIALIZE NEC
  1502 000043DE 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  1503 000043DF 720C                <1> 	JC	short CHK_RET		; ERROR - EXIT
  1504 000043E1 E866020000          <1> 	CALL	RWV_COM			; OP CODE COMMON TO READ/WRITE/VERIFY
  1505 000043E6 7205                <1> 	JC	short CHK_RET		; ERROR - EXIT
  1506 000043E8 E8AB020000          <1> 	CALL	NEC_TERM		; TERMINATE, GET STATUS, ETC.
  1507                              <1> CHK_RET:
  1508 000043ED E84A030000          <1> 	CALL	RETRY			; CHECK FOR, SETUP RETRY
  1509 000043F2 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY PARAMETER
  1510 000043F4 7305                <1> 	JNC	short RWV_END		; CY = 0 NO RETRY
  1511 000043F6 E928FFFFFF          <1>         JMP     DO_AGAIN                ; CY = 1 MEANS RETRY
  1512                              <1> RWV_END:
  1513 000043FB E8F4020000          <1> 	CALL	DSTATE			; ESTABLISH STATE IF SUCCESSFUL
  1514 00004400 E887030000          <1> 	CALL	NUM_TRANS		; AL = NUMBER TRANSFERRED
  1515                              <1> RWV_BAC:				; BAD DMA ERROR ENTRY
  1516 00004405 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  1517 00004407 E879FEFFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1518 0000440C 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  1519 0000440E E8B1030000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1520 00004413 C3                  <1> 	RETn
  1521                              <1> 
  1522                              <1> ;-------------------------------------------------------------------------------
  1523                              <1> ; SETUP_STATE:	INITIALIZES START AND END RATES.
  1524                              <1> ;-------------------------------------------------------------------------------
  1525                              <1> SETUP_STATE:
  1526 00004414 F687[6D640100]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; MEDIA DETERMINED ?
  1527 0000441B 7537                <1> 	JNZ	short J1C		; NO STATES IF DETERMINED
  1528 0000441D 66B84000            <1>         MOV     AX,(RATE_500*256)+RATE_300  ; AH = START RATE, AL = END RATE
  1529 00004421 F687[6D640100]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE ?
  1530 00004428 740D                <1> 	JZ	short AX_SET		; DO NOT KNOW DRIVE
  1531 0000442A F687[6D640100]02    <1> 	TEST	byte [DSK_STATE+eDI], FMT_CAPA ; MULTI-RATE?
  1532 00004431 7504                <1> 	JNZ	short AX_SET		; JUMP IF YES
  1533 00004433 66B88080            <1>         MOV     AX,RATE_250*257         ; START A END RATE 250 FOR 360 DRIVE
  1534                              <1> AX_SET:	
  1535 00004437 80A7[6D640100]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP) ; TURN OFF THE RATE
  1536 0000443E 08A7[6D640100]      <1> 	OR	[DSK_STATE+eDI], AH	; RATE FIRST TO TRY
  1537 00004444 8025[68640100]F3    <1> 	AND	byte [LASTRATE], ~STRT_MSK ; ERASE LAST TO TRY RATE BITS
  1538 0000444B C0C804              <1> 	ROR	AL,4			; TO OPERATION LAST RATE LOCATION
  1539 0000444E 0805[68640100]      <1> 	OR	[LASTRATE], AL		; LAST RATE
  1540                              <1> J1C:	
  1541 00004454 C3                  <1> 	RETn
  1542                              <1> 
  1543                              <1> ;-------------------------------------------------------------------------------
  1544                              <1> ;  FMT_INIT: ESTABLISH STATE IF UNESTABLISHED AT FORMAT TIME.
  1545                              <1> ;-------------------------------------------------------------------------------
  1546                              <1> FMT_INIT:
  1547 00004455 F687[6D640100]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; IS MEDIA ESTABLISHED
  1548 0000445C 7546                <1> 	JNZ	short F1_OUT		; IF SO RETURN
  1549 0000445E E82C040000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
  1550                              <1> 	;; 20/02/2015
  1551                              <1> 	;;JC	short CL_DRV		; ERROR IN CMOS ASSUME NO DRIVE
  1552 00004463 7440                <1> 	jz	short CL_DRV ;; 20/02/2015
  1553 00004465 FEC8                <1> 	DEC	AL			; MAKE ZERO ORIGIN
  1554                              <1> 	;;JS	short CL_DRV		; NO DRIVE IF AL 0
  1555 00004467 8AA7[6D640100]      <1> 	MOV	AH, [DSK_STATE+eDI]	; AH = CURRENT STATE
  1556 0000446D 80E40F              <1> 	AND	AH, ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR
  1557 00004470 08C0                <1> 	OR	AL,AL			; CHECK FOR 360
  1558 00004472 7505                <1> 	JNZ	short N_360		; IF 360 WILL BE 0
  1559 00004474 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; ESTABLISH MEDIA
  1560 00004477 EB25                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  1561                              <1> N_360:	
  1562 00004479 FEC8                <1> 	DEC	AL			; 1.2 M DRIVE
  1563 0000447B 7505                <1> 	JNZ	short N_12		; JUMP IF NOT
  1564                              <1> F1_RATE:
  1565 0000447D 80CC10              <1> 	OR	AH,MED_DET+RATE_500	; SET FORMAT RATE
  1566 00004480 EB1C                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  1567                              <1> N_12:	
  1568 00004482 FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 3
  1569 00004484 750F                <1> 	JNZ	short N_720		; JUMP IF NOT
  1570 00004486 F6C404              <1> 	TEST	AH,DRV_DET		; IS DRIVE DETERMINED
  1571 00004489 7410                <1> 	JZ	short ISNT_12		; TREAT AS NON 1.2 DRIVE
  1572 0000448B F6C402              <1> 	TEST	AH,FMT_CAPA		; IS 1.2M
  1573 0000448E 740B                <1> 	JZ	short ISNT_12		; JUMP IF NOT
  1574 00004490 80CC50              <1> 	OR	AH,MED_DET+RATE_300	; RATE 300
  1575 00004493 EB09                <1> 	JMP	SHORT SKP_STATE		; CONTINUE
  1576                              <1> N_720:
  1577 00004495 FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 4
  1578 00004497 750C                <1> 	JNZ	short CL_DRV		; NO DRIVE, CMOS BAD
  1579 00004499 EBE2                <1> 	JMP	SHORT F1_RATE
  1580                              <1> ISNT_12: 
  1581 0000449B 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; MUST BE RATE 250
  1582                              <1> 
  1583                              <1> SKP_STATE:
  1584 0000449E 88A7[6D640100]      <1> 	MOV	[DSK_STATE+eDI], AH	; STORE AWAY
  1585                              <1> F1_OUT:
  1586 000044A4 C3                  <1> 	RETn
  1587                              <1> CL_DRV:	
  1588 000044A5 30E4                <1> 	XOR	AH,AH			; CLEAR STATE
  1589 000044A7 EBF5                <1> 	JMP	SHORT SKP_STATE		; SAVE IT
  1590                              <1> 
  1591                              <1> ;-------------------------------------------------------------------------------
  1592                              <1> ; MED_CHANGE	
  1593                              <1> ;	CHECKS FOR MEDIA CHANGE, RESETS MEDIA CHANGE, 
  1594                              <1> ;	CHECKS MEDIA CHANGE AGAIN.
  1595                              <1> ;
  1596                              <1> ; ON EXIT:	CY = 1 MEANS MEDIA CHANGE OR TIMEOUT
  1597                              <1> ;		@DSKETTE_STATUS = ERROR CODE
  1598                              <1> ;-------------------------------------------------------------------------------
  1599                              <1> MED_CHANGE:
  1600 000044A9 E888060000          <1> 	CALL	READ_DSKCHNG		; READ DISK CHANCE LINE STATE
  1601 000044AE 7447                <1> 	JZ	short MC_OUT		; BYPASS HANDLING DISK CHANGE LINE
  1602 000044B0 80A7[6D640100]EF    <1> 	AND	byte [DSK_STATE+eDI], ~MED_DET ; CLEAR STATE FOR THIS DRIVE
  1603                              <1> 
  1604                              <1> ;	THIS SEQUENCE ENSURES WHENEVER A DISKETTE IS CHANGED THAT
  1605                              <1> ;	ON THE NEXT OPERATION THE REQUIRED MOTOR START UP TIME WILL
  1606                              <1> ;	BE WAITED. (DRIVE MOTOR MAY GO OFF UPON DOOR OPENING).
  1607                              <1> 
  1608 000044B7 6689F9              <1> 	MOV	CX,DI			; CL = DRIVE 0
  1609 000044BA B001                <1> 	MOV	AL,1			; MOTOR ON BIT MASK
  1610 000044BC D2E0                <1> 	SHL	AL,CL			; TO APPROPRIATE POSITION
  1611 000044BE F6D0                <1> 	NOT	AL			; KEEP ALL BUT MOTOR ON
  1612 000044C0 FA                  <1> 	CLI				; NO INTERRUPTS
  1613 000044C1 2005[5E640100]      <1> 	AND	[MOTOR_STATUS], AL	; TURN MOTOR OFF INDICATOR
  1614 000044C7 FB                  <1> 	STI				; INTERRUPTS ENABLED
  1615 000044C8 E810040000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON
  1616                              <1> 
  1617                              <1> ;-----	THIS SEQUENCE OF SEEKS IS USED TO RESET DISKETTE CHANGE SIGNAL
  1618                              <1> 
  1619 000044CD E850F9FFFF          <1> 	CALL	DSK_RESET		; RESET NEC
  1620 000044D2 B501                <1> 	MOV	CH,01H			; MOVE TO CYLINDER 1
  1621 000044D4 E8FF040000          <1> 	CALL	SEEK			; ISSUE SEEK
  1622 000044D9 30ED                <1> 	XOR	CH,CH			; MOVE TO CYLINDER 0
  1623 000044DB E8F8040000          <1> 	CALL	SEEK			; ISSUE SEEK
  1624 000044E0 C605[60640100]06    <1> 	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; STORE IN STATUS
  1625                              <1> OK1:
  1626 000044E7 E84A060000          <1> 	CALL	READ_DSKCHNG		; CHECK MEDIA CHANGED AGAIN
  1627 000044EC 7407                <1> 	JZ	short OK2		; IF ACTIVE, NO DISKETTE, TIMEOUT
  1628                              <1> OK4:
  1629 000044EE C605[60640100]80    <1> 	MOV	byte [DSKETTE_STATUS], TIME_OUT ; TIMEOUT IF DRIVE EMPTY
  1630                              <1> OK2:		
  1631 000044F5 F9                  <1> 	STC				; MEDIA CHANGED, SET CY
  1632 000044F6 C3                  <1> 	RETn
  1633                              <1> MC_OUT:
  1634 000044F7 F8                  <1> 	CLC				; NO MEDIA CHANGED, CLEAR CY
  1635 000044F8 C3                  <1> 	RETn
  1636                              <1> 
  1637                              <1> ;-------------------------------------------------------------------------------
  1638                              <1> ; SEND_RATE
  1639                              <1> ;	SENDS DATA RATE COMMAND TO NEC
  1640                              <1> ; ON ENTRY:	DI = DRIVE #
  1641                              <1> ; ON EXIT:	NONE
  1642                              <1> ; REGISTERS ALTERED: DX
  1643                              <1> ;-------------------------------------------------------------------------------
  1644                              <1> SEND_RATE:
  1645 000044F9 6650                <1> 	PUSH	AX			; SAVE REG.
  1646 000044FB 8025[68640100]3F    <1> 	AND	byte [LASTRATE], ~SEND_MSK ; ELSE CLEAR LAST RATE ATTEMPTED
  1647 00004502 8A87[6D640100]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1648 00004508 24C0                <1> 	AND	AL,SEND_MSK		; KEEP ONLY RATE BITS
  1649 0000450A 0805[68640100]      <1> 	OR	[LASTRATE], AL		; SAVE NEW RATE FOR NEXT CHECK
  1650 00004510 C0C002              <1> 	ROL	AL,2			; MOVE TO BIT OUTPUT POSITIONS
  1651 00004513 66BAF703            <1> 	MOV	DX,03F7H		; OUTPUT NEW DATA RATE
  1652 00004517 EE                  <1> 	OUT	DX,AL
  1653 00004518 6658                <1> 	POP	AX			; RESTORE REG.
  1654 0000451A C3                  <1> 	RETn
  1655                              <1> 
  1656                              <1> ;-------------------------------------------------------------------------------
  1657                              <1> ; CHK_LASTRATE
  1658                              <1> ;	CHECK PREVIOUS DATE RATE SNT TO THE CONTROLLER.
  1659                              <1> ; ON ENTRY:
  1660                              <1> ;	DI = DRIVE #
  1661                              <1> ; ON EXIT:
  1662                              <1> ;	ZF =  1 DATA RATE IS THE SAME AS THE LAST RATE SENT TO NEC
  1663                              <1> ;	ZF =  0 DATA RATE IS DIFFERENT FROM LAST RATE
  1664                              <1> ; REGISTERS ALTERED: DX
  1665                              <1> ;-------------------------------------------------------------------------------
  1666                              <1> CHK_LASTRATE:
  1667 0000451B 6650                <1> 	PUSH	AX			; SAVE REG
  1668 0000451D 2225[68640100]      <1> 	AND	AH, [LASTRATE]		; GET LAST DATA RATE SELECTED
  1669 00004523 8A87[6D640100]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1670 00004529 6625C0C0            <1>         AND     AX, SEND_MSK*257        ; KEEP ONLY RATE BITS OF BOTH
  1671 0000452D 38E0                <1> 	CMP	AL, AH			; COMPARE TO PREVIOUSLY TRIED
  1672                              <1> 					; ZF = 1 RATE IS THE SAME
  1673 0000452F 6658                <1> 	POP	AX			; RESTORE REG.
  1674 00004531 C3                  <1> 	RETn
  1675                              <1> 
  1676                              <1> ;-------------------------------------------------------------------------------
  1677                              <1> ; DMA_SETUP
  1678                              <1> ;	THIS ROUTINE SETS UP THE DMA FOR READ/WRITE/VERIFY OPERATIONS.
  1679                              <1> ;
  1680                              <1> ; ON ENTRY:	AL = DMA COMMAND
  1681                              <1> ;
  1682                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1683                              <1> ;-------------------------------------------------------------------------------
  1684                              <1> 
  1685                              <1> ; SI = Head #, # of Sectors or DASD Type
  1686                              <1> 
  1687                              <1> ; 22/08/2015
  1688                              <1> ; 08/02/2015 - Protected Mode Modification
  1689                              <1> ; 06/02/2015 - 07/02/2015
  1690                              <1> ; NOTE: Buffer address must be in 1st 16MB of Physical Memory (24 bit limit).
  1691                              <1> ; (DMA Addres = Physical Address)
  1692                              <1> ; (Retro UNIX 386 v1 Kernel/System Mode Virtual Address = Physical Address)
  1693                              <1> ;
  1694                              <1> 
  1695                              <1> 
  1696                              <1> ; 04/02/2016 (clc)
  1697                              <1> ; 20/02/2015 modification (source: AWARD BIOS 1999, DMA_SETUP)
  1698                              <1> ; 16/12/2014 (IODELAY)
  1699                              <1> 
  1700                              <1> DMA_SETUP:
  1701                              <1> 
  1702                              <1> ;; 20/02/2015
  1703 00004532 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  1704 00004535 F7C2000000FF        <1> 	test	edx, 0FF000000h		; 16 MB limit (22/08/2015, bugfix)
  1705 0000453B 756E                <1> 	jnz	short dma_bnd_err_stc
  1706                              <1> 	;
  1707 0000453D 6650                <1> 	push	ax			; DMA command
  1708 0000453F 52                  <1> 	push	edx			; *
  1709 00004540 B203                <1> 	mov	dl, 3			; GET BYTES/SECTOR PARAMETER
  1710 00004542 E851030000          <1> 	call	GET_PARM		; 
  1711 00004547 88E1                <1> 	mov	cl, ah 			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  1712 00004549 6689F0              <1> 	mov	ax, si			; Sector count
  1713 0000454C 88C4                <1> 	mov	ah, al			; AH =  # OF SECTORS
  1714 0000454E 28C0                <1> 	sub	al, al			; AL = 0, AX = # SECTORS * 256
  1715 00004550 66D1E8              <1> 	shr	ax, 1			; AX = # SECTORS * 128
  1716 00004553 66D3E0              <1> 	shl	ax, cl			; SHIFT BY PARAMETER VALUE
  1717 00004556 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  1718 00004558 6689C1              <1> 	mov	cx, ax
  1719 0000455B 5A                  <1> 	pop	edx			; *
  1720 0000455C 6658                <1> 	pop	ax
  1721 0000455E 3C42                <1> 	cmp	al, 42h
  1722 00004560 7507                <1>         jne     short NOT_VERF
  1723 00004562 BA0000FF00          <1> 	mov	edx, 0FF0000h
  1724 00004567 EB08                <1> 	jmp	short J33
  1725                              <1> NOT_VERF:
  1726 00004569 6601CA              <1> 	add	dx, cx			; check for overflow
  1727 0000456C 723E                <1> 	jc	short dma_bnd_err
  1728                              <1> 	;
  1729 0000456E 6629CA              <1> 	sub	dx, cx			; Restore start address
  1730                              <1> J33:
  1731 00004571 FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1732 00004572 E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1733                              <1> 	IODELAY				; WAIT FOR I/O
  1733 00004574 EB00                <2>  jmp short $+2
  1733 00004576 EB00                <2>  jmp short $+2
  1734 00004578 E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1735 0000457A 89D0                <1> 	mov	eax, edx		; Buffer address
  1736 0000457C E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1737                              <1> 	IODELAY				; WAIT FOR I/O
  1737 0000457E EB00                <2>  jmp short $+2
  1737 00004580 EB00                <2>  jmp short $+2
  1738 00004582 88E0                <1> 	MOV	AL,AH
  1739 00004584 E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1740 00004586 C1E810              <1> 	shr	eax, 16
  1741                              <1> 	IODELAY				; I/O WAIT STATE
  1741 00004589 EB00                <2>  jmp short $+2
  1741 0000458B EB00                <2>  jmp short $+2
  1742 0000458D E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  1743                              <1> 	IODELAY
  1743 0000458F EB00                <2>  jmp short $+2
  1743 00004591 EB00                <2>  jmp short $+2
  1744 00004593 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  1745 00004596 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1746                              <1> 	IODELAY				; WAIT FOR I/O
  1746 00004598 EB00                <2>  jmp short $+2
  1746 0000459A EB00                <2>  jmp short $+2
  1747 0000459C 88E0                <1> 	MOV	AL, AH
  1748 0000459E E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1749                              <1> 	IODELAY
  1749 000045A0 EB00                <2>  jmp short $+2
  1749 000045A2 EB00                <2>  jmp short $+2
  1750 000045A4 FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  1751 000045A5 B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  1752 000045A7 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1753                              <1> 
  1754 000045A9 F8                  <1> 	clc	; 04/02/2016
  1755 000045AA C3                  <1> 	retn
  1756                              <1> 
  1757                              <1> dma_bnd_err_stc:
  1758 000045AB F9                  <1> 	stc
  1759                              <1> dma_bnd_err:
  1760 000045AC C605[60640100]09    <1> 	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  1761 000045B3 C3                  <1> 	RETn				; CY SET BY ABOVE IF ERROR
  1762                              <1> 
  1763                              <1> ;; 16/12/2014
  1764                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1765                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1766                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1767                              <1> ;;	IODELAY
  1768                              <1> ;; 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1769                              <1> ;;	;SIODELAY
  1770                              <1> ;;      ;CMP	AL, 42H			; DMA VERIFY COMMAND
  1771                              <1> ;;      ;JNE	short NOT_VERF		; NO
  1772                              <1> ;;      ;XOR	AX, AX			; START ADDRESS
  1773                              <1> ;;      ;JMP	SHORT J33
  1774                              <1> ;;;NOT_VERF:	
  1775                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  1776                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  1777                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  1778                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  1779                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  1780                              <1> ;;	mov	eax, [ebp+4] ; 06/02/2015	
  1781                              <1> ;;	;JNC	short J33
  1782                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  1783                              <1> ;;;J33:
  1784                              <1> ;;	PUSH	eAX			; SAVE START ADDRESS
  1785                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1786                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1787                              <1> ;;	IODELAY
  1788                              <1> ;;	MOV	AL,AH
  1789                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1790                              <1> ;;	shr	eax, 16	     ; 07/02/2015
  1791                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  1792                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  1793                              <1> ;;	IODELAY
  1794                              <1> ;;	;AND	AL,00001111B
  1795                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  1796                              <1> ;;	;SIODELAY
  1797                              <1> ;;
  1798                              <1> ;;;----- DETERMINE COUNT
  1799                              <1> ;;	sub	eax, eax ; 08/02/2015
  1800                              <1> ;;	MOV	AX, SI			; AL =  # OF SECTORS
  1801                              <1> ;;	XCHG	AL, AH			; AH =  # OF SECTORS
  1802                              <1> ;;	SUB	AL, AL			; AL = 0, AX = # SECTORS * 256
  1803                              <1> ;;	SHR	AX, 1			; AX = # SECTORS * 128
  1804                              <1> ;;	PUSH	AX			; SAVE # OF SECTORS * 128
  1805                              <1> ;;	MOV	DL, 3			; GET BYTES/SECTOR PARAMETER
  1806                              <1> ;;	CALL	GET_PARM		; "
  1807                              <1> ;;	MOV	CL,AH			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  1808                              <1> ;;	POP	AX			; AX = # SECTORS * 128
  1809                              <1> ;;	SHL	AX,CL			; SHIFT BY PARAMETER VALUE
  1810                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  1811                              <1> ;;	PUSH	eAX  ; 08/02/2015	; SAVE COUNT VALUE
  1812                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1813                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1814                              <1> ;;	IODELAY
  1815                              <1> ;;	MOV	AL, AH
  1816                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1817                              <1> ;;	;IODELAY
  1818                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  1819                              <1> ;;	POP	eCX  ; 08/02/2015 	; RECOVER COUNT VALUE
  1820                              <1> ;;	POP	eAX  ; 08/02/2015	; RECOVER ADDRESS VALUE
  1821                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  1822                              <1> ;;	add	ecx, eax ; 08/02/2015
  1823                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  1824                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1825                              <1> ;;	SIODELAY
  1826                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1827                              <1> ;;	;JNC	short NO_BAD		; CHECK FOR ERROR
  1828                              <1> ;;	jc	short dma_bnd_err ; 08/02/2015
  1829                              <1> ;;	and	ecx, 0FFF00000h ; 16 MB limit
  1830                              <1> ;;	jz	short NO_BAD
  1831                              <1> ;;dma_bnd_err:
  1832                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  1833                              <1> ;;NO_BAD:
  1834                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  1835                              <1> 
  1836                              <1> ;-------------------------------------------------------------------------------
  1837                              <1> ; FMTDMA_SET
  1838                              <1> ;	THIS ROUTINE SETS UP THE DMA CONTROLLER FOR A FORMAT OPERATION.
  1839                              <1> ;
  1840                              <1> ; ON ENTRY:	NOTHING REQUIRED
  1841                              <1> ;
  1842                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1843                              <1> ;-------------------------------------------------------------------------------
  1844                              <1> 
  1845                              <1> FMTDMA_SET:
  1846                              <1> ;; 20/02/2015 modification	
  1847 000045B4 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  1848 000045B7 F7C20000F0FF        <1> 	test	edx, 0FFF00000h		; 16 MB limit
  1849 000045BD 75EC                <1> 	jnz	short dma_bnd_err_stc
  1850                              <1> 	;
  1851 000045BF 6652                <1> 	push	dx			; *
  1852 000045C1 B204                <1> 	mov	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  1853 000045C3 E8D0020000          <1> 	call	GET_PARM		; "
  1854 000045C8 88E0                <1> 	mov	al, ah			; AL = SECTORS/TRACK VALUE
  1855 000045CA 28E4                <1> 	sub	ah, ah			; AX = SECTORS/TRACK VALUE
  1856 000045CC 66C1E002            <1> 	shl	ax, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  1857 000045D0 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  1858 000045D2 6689C1              <1> 	mov	cx, ax
  1859 000045D5 665A                <1> 	pop	dx			; *
  1860 000045D7 6601CA              <1> 	add	dx, cx			; check for overflow
  1861 000045DA 72D0                <1> 	jc	short dma_bnd_err
  1862                              <1> 	;
  1863 000045DC 6629CA              <1> 	sub	dx, cx			; Restore start address
  1864                              <1> 	;
  1865 000045DF B04A                <1> 	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  1866 000045E1 FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1867 000045E2 E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1868                              <1> 	IODELAY				; WAIT FOR I/O
  1868 000045E4 EB00                <2>  jmp short $+2
  1868 000045E6 EB00                <2>  jmp short $+2
  1869 000045E8 E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1870 000045EA 89D0                <1> 	mov	eax, edx		; Buffer address
  1871 000045EC E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1872                              <1> 	IODELAY				; WAIT FOR I/O
  1872 000045EE EB00                <2>  jmp short $+2
  1872 000045F0 EB00                <2>  jmp short $+2
  1873 000045F2 88E0                <1> 	MOV	AL,AH
  1874 000045F4 E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1875 000045F6 C1E810              <1> 	shr	eax, 16
  1876                              <1> 	IODELAY				; I/O WAIT STATE
  1876 000045F9 EB00                <2>  jmp short $+2
  1876 000045FB EB00                <2>  jmp short $+2
  1877 000045FD E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  1878                              <1> 	IODELAY
  1878 000045FF EB00                <2>  jmp short $+2
  1878 00004601 EB00                <2>  jmp short $+2
  1879 00004603 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  1880 00004606 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1881                              <1> 	IODELAY				; WAIT FOR I/O
  1881 00004608 EB00                <2>  jmp short $+2
  1881 0000460A EB00                <2>  jmp short $+2
  1882 0000460C 88E0                <1> 	MOV	AL, AH
  1883 0000460E E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1884                              <1> 	IODELAY
  1884 00004610 EB00                <2>  jmp short $+2
  1884 00004612 EB00                <2>  jmp short $+2
  1885 00004614 FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  1886 00004615 B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  1887 00004617 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1888 00004619 C3                  <1> 	retn
  1889                              <1> 
  1890                              <1> ;; 08/02/2015 - Protected Mode Modification
  1891                              <1> ;;	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  1892                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1893                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1894                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1895                              <1> ;;	IODELAY
  1896                              <1> ;;	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1897                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  1898                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  1899                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  1900                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  1901                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  1902                              <1> ;;	;JNC	short J33A
  1903                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  1904                              <1> ;;	mov	eax, [ebp+4] ; 08/02/2015
  1905                              <1> ;;;J33A:
  1906                              <1> ;;	PUSH	eAX ; 08/02/2015	; SAVE START ADDRESS
  1907                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1908                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1909                              <1> ;;	IODELAY
  1910                              <1> ;;	MOV	AL,AH
  1911                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1912                              <1> ;;	shr 	eax, 16 ; 08/02/2015
  1913                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  1914                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  1915                              <1> ;;	IODELAY
  1916                              <1> ;;	;AND	AL,00001111B
  1917                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  1918                              <1> ;;
  1919                              <1> ;;;----- DETERMINE COUNT
  1920                              <1> ;;	sub	eax, eax ; 08/02/2015
  1921                              <1> ;;	MOV	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  1922                              <1> ;;	CALL	GET_PARM		; "
  1923                              <1> ;;	XCHG	AL, AH			; AL = SECTORS/TRACK VALUE
  1924                              <1> ;;	SUB	AH, AH			; AX = SECTORS/TRACK VALUE
  1925                              <1> ;;	SHL	AX, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  1926                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  1927                              <1> ;;	PUSH	eAX 	; 08/02/2015	; SAVE # OF BYTES TO BE TRANSFERED
  1928                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1929                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1930                              <1> ;;	IODELAY
  1931                              <1> ;;	MOV	AL, AH
  1932                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1933                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  1934                              <1> ;;	POP	eCX	; 08/02/2015	; RECOVER COUNT VALUE
  1935                              <1> ;;	POP	eAX	; 08/02/2015	; RECOVER ADDRESS VALUE
  1936                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  1937                              <1> ;;	add	ecx, eax ; 08/02/2015
  1938                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  1939                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1940                              <1> ;;	SIODELAY
  1941                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1942                              <1> ;;	;JNC	short FMTDMA_OK		; CHECK FOR ERROR
  1943                              <1> ;;	jc	short fmtdma_bnd_err ; 08/02/2015
  1944                              <1> ;;	and	ecx, 0FFF00000h  ; 16 MB limit
  1945                              <1> ;;	jz	short FMTDMA_OK
  1946                              <1> ;;	stc	; 20/02/2015
  1947                              <1> ;;fmtdma_bnd_err:
  1948                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  1949                              <1> ;;FMTDMA_OK:
  1950                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  1951                              <1> 
  1952                              <1> ;-------------------------------------------------------------------------------
  1953                              <1> ; NEC_INIT	
  1954                              <1> ;	THIS ROUTINE SEEKS TO THE REQUESTED TRACK AND INITIALIZES
  1955                              <1> ;	THE NEC FOR THE READ/WRITE/VERIFY/FORMAT OPERATION.
  1956                              <1> ;
  1957                              <1> ; ON ENTRY:	AH = NEC COMMAND TO BE PERFORMED
  1958                              <1> ;
  1959                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1960                              <1> ;-------------------------------------------------------------------------------
  1961                              <1> NEC_INIT:
  1962 0000461A 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1963 0000461C E8BC020000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON FOR SPECIFIC DRIVE
  1964                              <1> 
  1965                              <1> ;-----	DO THE SEEK OPERATION
  1966                              <1> 
  1967 00004621 8A6D01              <1> 	MOV	CH,[eBP+1]		; CH = TRACK #
  1968 00004624 E8AF030000          <1> 	CALL	SEEK			; MOVE TO CORRECT TRACK
  1969 00004629 6658                <1> 	POP	AX			; RECOVER COMMAND
  1970 0000462B 721E                <1> 	JC	short ER_1		; ERROR ON SEEK
  1971 0000462D BB[4B460000]        <1> 	MOV	eBX, ER_1		; LOAD ERROR ADDRESS
  1972 00004632 53                  <1> 	PUSH	eBX			; PUSH NEC_OUT ERROR RETURN
  1973                              <1> 
  1974                              <1> ;-----	SEND OUT THE PARAMETERS TO THE CONTROLLER
  1975                              <1> 
  1976 00004633 E866030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE OPERATION COMMAND
  1977 00004638 6689F0              <1> 	MOV	AX,SI			; AH = HEAD #
  1978 0000463B 89FB                <1> 	MOV	eBX,eDI			; BL = DRIVE #
  1979 0000463D C0E402              <1> 	SAL	AH,2			; MOVE IT TO BIT 2
  1980 00004640 80E404              <1> 	AND	AH,00000100B		; ISOLATE THAT BIT
  1981 00004643 08DC                <1> 	OR	AH,BL			; OR IN THE DRIVE NUMBER
  1982 00004645 E854030000          <1> 	CALL	NEC_OUTPUT		; FALL THRU CY SET IF ERROR
  1983 0000464A 5B                  <1> 	POP	eBX			; THROW AWAY ERROR RETURN
  1984                              <1> ER_1:
  1985 0000464B C3                  <1> 	RETn
  1986                              <1> 
  1987                              <1> ;-------------------------------------------------------------------------------
  1988                              <1> ; RWV_COM
  1989                              <1> ;	THIS ROUTINE SENDS PARAMETERS TO THE NEC SPECIFIC TO THE 
  1990                              <1> ;	READ/WRITE/VERIFY OPERATIONS.
  1991                              <1> ;
  1992                              <1> ; ON ENTRY:	CS:BX = ADDRESS OF MEDIA/DRIVE PARAMETER TABLE
  1993                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1994                              <1> ;-------------------------------------------------------------------------------
  1995                              <1> RWV_COM:
  1996 0000464C B8[97460000]        <1> 	MOV	eAX, ER_2		; LOAD ERROR ADDRESS
  1997 00004651 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1998 00004652 8A6501              <1> 	MOV	AH,[eBP+1]		; OUTPUT TRACK #
  1999 00004655 E844030000          <1> 	CALL	NEC_OUTPUT
  2000 0000465A 6689F0              <1> 	MOV	AX,SI			; OUTPUT HEAD #
  2001 0000465D E83C030000          <1> 	CALL	NEC_OUTPUT
  2002 00004662 8A6500              <1>         MOV     AH,[eBP]                ; OUTPUT SECTOR #
  2003 00004665 E834030000          <1> 	CALL	NEC_OUTPUT
  2004 0000466A B203                <1> 	MOV	DL,3			; BYTES/SECTOR PARAMETER FROM BLOCK
  2005 0000466C E827020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  2006 00004671 E828030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  2007 00004676 B204                <1> 	MOV	DL,4			; EOT PARAMETER FROM BLOCK
  2008 00004678 E81B020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  2009 0000467D E81C030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  2010 00004682 8A6305              <1>         MOV     AH, [eBX+MD.GAP]        ; GET GAP LENGTH
  2011                              <1> _R15:
  2012 00004685 E814030000          <1> 	CALL	NEC_OUTPUT
  2013 0000468A B206                <1> 	MOV	DL,6			; DTL PARAMETER PROM BLOCK
  2014 0000468C E807020000          <1> 	CALL	GET_PARM		;  TO THE NEC
  2015 00004691 E808030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  2016 00004696 58                  <1> 	POP	eAX			; THROW AWAY ERROR EXIT
  2017                              <1> ER_2:
  2018 00004697 C3                  <1> 	RETn
  2019                              <1> 
  2020                              <1> ;-------------------------------------------------------------------------------
  2021                              <1> ; NEC_TERM
  2022                              <1> ;	THIS ROUTINE WAITS FOR THE OPERATION THEN ACCEPTS THE STATUS 
  2023                              <1> ;	FROM THE NEC FOR THE READ/WRITE/VERIFY/FORWAT OPERATION.
  2024                              <1> ;
  2025                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  2026                              <1> ;-------------------------------------------------------------------------------
  2027                              <1> NEC_TERM:
  2028                              <1> 
  2029                              <1> ;-----	LET THE OPERATION HAPPEN
  2030                              <1> 
  2031 00004698 56                  <1> 	PUSH	eSI			; SAVE HEAD #, # OF SECTORS
  2032 00004699 E80D040000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  2033 0000469E 9C                  <1> 	PUSHF
  2034 0000469F E837040000          <1> 	CALL	RESULTS			; GET THE NEC STATUS
  2035 000046A4 724B                <1> 	JC	short SET_END_POP
  2036 000046A6 9D                  <1> 	POPF
  2037 000046A7 723E                <1> 	JC	short SET_END		; LOOK FOR ERROR
  2038                              <1> 
  2039                              <1> ;-----	CHECK THE RESULTS RETURNED BY THE CONTROLLER
  2040                              <1> 
  2041 000046A9 FC                  <1> 	CLD				; SET THE CORRECT DIRECTION
  2042 000046AA BE[61640100]        <1> 	MOV	eSI, NEC_STATUS		; POINT TO STATUS FIELD
  2043 000046AF AC                  <1> 	lodsb				; GET ST0
  2044 000046B0 24C0                <1> 	AND	AL,11000000B		; TEST FOR NORMAL TERMINATION
  2045 000046B2 7433                <1> 	JZ	short SET_END
  2046 000046B4 3C40                <1> 	CMP	AL,01000000B		; TEST FOR ABNORMAL TERMINATION
  2047 000046B6 7527                <1> 	JNZ	short J18		; NOT ABNORMAL, BAD NEC
  2048                              <1> 
  2049                              <1> ;-----	ABNORMAL TERMINATION, FIND OUT WHY
  2050                              <1> 
  2051 000046B8 AC                  <1> 	lodsb				; GET ST1
  2052 000046B9 D0E0                <1> 	SAL	AL,1			; TEST FOR EDT FOUND
  2053 000046BB B404                <1> 	MOV	AH,RECORD_NOT_FND
  2054 000046BD 7222                <1> 	JC	short J19
  2055 000046BF C0E002              <1> 	SAL	AL,2
  2056 000046C2 B410                <1> 	MOV	AH,BAD_CRC
  2057 000046C4 721B                <1> 	JC	short J19
  2058 000046C6 D0E0                <1> 	SAL	AL,1			; TEST FOR DMA OVERRUN
  2059 000046C8 B408                <1> 	MOV	AH,BAD_DMA
  2060 000046CA 7215                <1> 	JC	short J19
  2061 000046CC C0E002              <1> 	SAL	AL,2			; TEST FOR RECORD NOT FOUND
  2062 000046CF B404                <1> 	MOV	AH,RECORD_NOT_FND
  2063 000046D1 720E                <1> 	JC	short J19
  2064 000046D3 D0E0                <1> 	SAL	AL,1
  2065 000046D5 B403                <1> 	MOV	AH,WRITE_PROTECT	; TEST FOR WRITE_PROTECT
  2066 000046D7 7208                <1> 	JC	short J19
  2067 000046D9 D0E0                <1> 	SAL	AL,1			; TEST MISSING ADDRESS MARK
  2068 000046DB B402                <1> 	MOV	AH,BAD_ADDR_MARK
  2069 000046DD 7202                <1> 	JC	short J19
  2070                              <1> 
  2071                              <1> ;----- 	NEC MUST HAVE FAILED
  2072                              <1> J18:
  2073 000046DF B420                <1> 	MOV	AH,BAD_NEC
  2074                              <1> J19:
  2075 000046E1 0825[60640100]      <1> 	OR	[DSKETTE_STATUS], AH
  2076                              <1> SET_END:
  2077 000046E7 803D[60640100]01    <1> 	CMP	byte [DSKETTE_STATUS], 1 ; SET ERROR CONDITION
  2078 000046EE F5                  <1> 	CMC
  2079 000046EF 5E                  <1> 	POP	eSI
  2080 000046F0 C3                  <1> 	RETn				; RESTORE HEAD #, # OF SECTORS
  2081                              <1> 
  2082                              <1> SET_END_POP:
  2083 000046F1 9D                  <1> 	POPF
  2084 000046F2 EBF3                <1> 	JMP	SHORT SET_END
  2085                              <1> 
  2086                              <1> ;-------------------------------------------------------------------------------
  2087                              <1> ; DSTATE:	ESTABLISH STATE UPON SUCCESSFUL OPERATION.
  2088                              <1> ;-------------------------------------------------------------------------------
  2089                              <1> DSTATE:
  2090 000046F4 803D[60640100]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  2091 000046FB 753E                <1> 	JNZ	short SETBAC		    ; IF ERROR JUMP
  2092 000046FD 808F[6D640100]10    <1> 	OR	byte [DSK_STATE+eDI],MED_DET ; NO ERROR, MARK MEDIA AS DETERMINED
  2093 00004704 F687[6D640100]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE DETERMINED ?
  2094 0000470B 752E                <1> 	JNZ	short SETBAC		; IF DETERMINED NO TRY TO DETERMINE
  2095 0000470D 8A87[6D640100]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  2096 00004713 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  2097 00004715 3C80                <1> 	CMP	AL,RATE_250		; RATE 250 ?
  2098 00004717 751B                <1> 	JNE	short M_12		; NO, MUST BE 1.2M OR 1.44M DRIVE
  2099                              <1> 
  2100                              <1> ;----- 	CHECK IF IT IS 1.44M
  2101                              <1> 
  2102 00004719 E871010000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  2103                              <1> 	;;20/02/2015
  2104                              <1> 	;;JC	short M_12		; CMOS BAD
  2105 0000471E 7414                <1> 	jz	short M_12 ;; 20/02/2015
  2106 00004720 3C04                <1> 	CMP	AL, 4			; 1.44MB DRIVE ?
  2107 00004722 7410                <1> 	JE	short M_12		; YES
  2108                              <1> M_720:
  2109 00004724 80A7[6D640100]FD    <1> 	AND	byte [DSK_STATE+eDI], ~FMT_CAPA ; TURN OFF FORMAT CAPABILITY
  2110 0000472B 808F[6D640100]04    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET  ; MARK DRIVE DETERMINED
  2111 00004732 EB07                <1> 	JMP	SHORT SETBAC		; BACK
  2112                              <1> M_12:	
  2113 00004734 808F[6D640100]06    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET+FMT_CAPA 
  2114                              <1> 					; TURN ON DETERMINED & FMT CAPA
  2115                              <1> SETBAC:
  2116 0000473B C3                  <1> 	RETn
  2117                              <1> 
  2118                              <1> ;-------------------------------------------------------------------------------
  2119                              <1> ; RETRY	
  2120                              <1> ;	DETERMINES WHETHER A RETRY IS NECESSARY. 
  2121                              <1> ;	IF RETRY IS REQUIRED THEN STATE INFORMATION IS UPDATED FOR RETRY.
  2122                              <1> ;
  2123                              <1> ; ON EXIT:	CY = 1 FOR RETRY, CY = 0 FOR NO RETRY
  2124                              <1> ;-------------------------------------------------------------------------------
  2125                              <1> RETRY:
  2126 0000473C 803D[60640100]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; GET STATUS OF OPERATION
  2127 00004743 7445                <1> 	JZ	short NO_RETRY		; SUCCESSFUL OPERATION
  2128 00004745 803D[60640100]80    <1> 	CMP	byte [DSKETTE_STATUS],TIME_OUT ; IF TIME OUT NO RETRY
  2129 0000474C 743C                <1> 	JZ	short NO_RETRY
  2130 0000474E 8AA7[6D640100]      <1> 	MOV	AH,[DSK_STATE+eDI]	; GET MEDIA STATE OF DRIVE
  2131 00004754 F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED/DETERMINED ?
  2132 00004757 7531                <1> 	JNZ	short NO_RETRY		; IF ESTABLISHED STATE THEN TRUE ERROR
  2133 00004759 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE RATE
  2134 0000475C 8A2D[68640100]      <1> 	MOV	CH,[LASTRATE]		; GET START OPERATION STATE
  2135 00004762 C0C504              <1> 	ROL	CH,4			; TO CORRESPONDING BITS
  2136 00004765 80E5C0              <1> 	AND	CH,RATE_MSK		; ISOLATE RATE BITS
  2137 00004768 38E5                <1> 	CMP	CH,AH			; ALL RATES TRIED
  2138 0000476A 741E                <1> 	JE	short NO_RETRY		; IF YES, THEN TRUE ERROR
  2139                              <1> 
  2140                              <1> ;	SETUP STATE INDICATOR FOR RETRY ATTEMPT TO NEXT RATE
  2141                              <1> ;	 00000000B (500) -> 10000000B	(250)
  2142                              <1> ;	 10000000B (250) -> 01000000B	(300)
  2143                              <1> ;	 01000000B (300) -> 00000000B	(500)
  2144                              <1> 
  2145 0000476C 80FC01              <1> 	CMP	AH,RATE_500+1		; SET CY FOR RATE 500
  2146 0000476F D0DC                <1> 	RCR	AH,1			; TO NEXT STATE
  2147 00004771 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE BITS
  2148 00004774 80A7[6D640100]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP)
  2149                              <1> 					; RATE, DBL STEP OFF
  2150 0000477B 08A7[6D640100]      <1> 	OR	[DSK_STATE+eDI],AH	; TURN ON NEW RATE
  2151 00004781 C605[60640100]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; RESET STATUS FOR RETRY
  2152 00004788 F9                  <1> 	STC				; SET CARRY FOR RETRY
  2153 00004789 C3                  <1> 	RETn				; RETRY RETURN
  2154                              <1> 
  2155                              <1> NO_RETRY:
  2156 0000478A F8                  <1> 	CLC				; CLEAR CARRY NO RETRY
  2157 0000478B C3                  <1> 	RETn				; NO RETRY RETURN
  2158                              <1> 
  2159                              <1> ;-------------------------------------------------------------------------------
  2160                              <1> ; NUM_TRANS
  2161                              <1> ;	THIS ROUTINE CALCULATES THE NUMBER OF SECTORS THAT WERE
  2162                              <1> ;	ACTUALLY TRANSFERRED TO/FROM THE DISKETTE.
  2163                              <1> ;
  2164                              <1> ; ON ENTRY:	[BP+1] = TRACK
  2165                              <1> ;		SI-HI  = HEAD
  2166                              <1> ;		[BP]   = START SECTOR
  2167                              <1> ;
  2168                              <1> ; ON EXIT:	AL = NUMBER ACTUALLY TRANSFERRED
  2169                              <1> ;-------------------------------------------------------------------------------
  2170                              <1> NUM_TRANS:
  2171 0000478C 30C0                <1> 	XOR	AL,AL			; CLEAR FOR ERROR
  2172 0000478E 803D[60640100]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  2173 00004795 752C                <1> 	JNZ	NT_OUT			; IF ERROR 0 TRANSFERRED
  2174 00004797 B204                <1> 	MOV	DL,4			; SECTORS/TRACK OFFSET TO DL
  2175 00004799 E8FA000000          <1> 	CALL	GET_PARM		; AH = SECTORS/TRACK
  2176 0000479E 8A1D[66640100]      <1> 	MOV	BL, [NEC_STATUS+5]	; GET ENDING SECTOR
  2177 000047A4 6689F1              <1> 	MOV	CX,SI			; CH = HEAD # STARTED
  2178 000047A7 3A2D[65640100]      <1> 	CMP	CH, [NEC_STATUS+4]	; GET HEAD ENDED UP ON
  2179 000047AD 750D                <1> 	JNZ	DIF_HD			; IF ON SAME HEAD, THEN NO ADJUST
  2180 000047AF 8A2D[64640100]      <1> 	MOV	CH, [NEC_STATUS+3]	; GET TRACK ENDED UP ON
  2181 000047B5 3A6D01              <1> 	CMP	CH,[eBP+1]		; IS IT ASKED FOR TRACK
  2182 000047B8 7404                <1> 	JZ	short SAME_TRK		; IF SAME TRACK NO INCREASE
  2183 000047BA 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  2184                              <1> DIF_HD:
  2185 000047BC 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  2186                              <1> SAME_TRK:
  2187 000047BE 2A5D00              <1> 	SUB	BL,[eBP]		; SUBTRACT START FROM END
  2188 000047C1 88D8                <1> 	MOV	AL,BL			; TO AL
  2189                              <1> NT_OUT:
  2190 000047C3 C3                  <1> 	RETn
  2191                              <1> 
  2192                              <1> ;-------------------------------------------------------------------------------
  2193                              <1> ; SETUP_END
  2194                              <1> ;	RESTORES @MOTOR_COUNT TO PARAMETER PROVIDED IN TABLE 
  2195                              <1> ;	AND LOADS @DSKETTE_STATUS TO AH, AND SETS CY.
  2196                              <1> ;
  2197                              <1> ; ON EXIT:
  2198                              <1> ;	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  2199                              <1> ;-------------------------------------------------------------------------------
  2200                              <1> SETUP_END:
  2201 000047C4 B202                <1> 	MOV	DL,2			; GET THE MOTOR WAIT PARAMETER
  2202 000047C6 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  2203 000047C8 E8CB000000          <1> 	CALL	GET_PARM
  2204 000047CD 8825[5F640100]      <1> 	MOV	[MOTOR_COUNT],AH	; STORE UPON RETURN
  2205 000047D3 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  2206 000047D5 8A25[60640100]      <1> 	MOV	AH, [DSKETTE_STATUS]	; GET STATUS OF OPERATION
  2207 000047DB 08E4                <1> 	OR	AH,AH			; CHECK FOR ERROR
  2208 000047DD 7402                <1> 	JZ	short NUN_ERR		; NO ERROR
  2209 000047DF 30C0                <1> 	XOR	AL,AL			; CLEAR NUMBER RETURNED
  2210                              <1> NUN_ERR: 
  2211 000047E1 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  2212 000047E4 F5                  <1> 	CMC				; SUCCESS OR FAILURE
  2213 000047E5 C3                  <1> 	RETn
  2214                              <1> 
  2215                              <1> ;-------------------------------------------------------------------------------
  2216                              <1> ; SETUP_DBL
  2217                              <1> ;	CHECK DOUBLE STEP.
  2218                              <1> ;
  2219                              <1> ; ON ENTRY :	DI = DRIVE
  2220                              <1> ;
  2221                              <1> ; ON EXIT :	CY = 1 MEANS ERROR
  2222                              <1> ;-------------------------------------------------------------------------------
  2223                              <1> SETUP_DBL:
  2224 000047E6 8AA7[6D640100]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  2225 000047EC F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED STATE ?
  2226 000047EF 757E                <1> 	JNZ	short NO_DBL			; IF ESTABLISHED THEN DOUBLE DONE
  2227                              <1> 
  2228                              <1> ;-----	CHECK FOR TRACK 0 TO SPEED UP ACKNOWLEDGE OF UNFORMATTED DISKETTE
  2229                              <1> 
  2230 000047F1 C605[5D640100]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  2231 000047F8 E8E0000000          <1> 	CALL	MOTOR_ON		; ENSURE MOTOR STAY ON
  2232 000047FD B500                <1> 	MOV	CH,0			; LOAD TRACK 0
  2233 000047FF E8D4010000          <1> 	CALL	SEEK			; SEEK TO TRACK 0
  2234 00004804 E868000000          <1> 	CALL	READ_ID			; READ ID FUNCTION
  2235 00004809 7249                <1> 	JC	short SD_ERR		; IF ERROR NO TRACK 0
  2236                              <1> 
  2237                              <1> ;-----	INITIALIZE START AND MAX TRACKS (TIMES 2 FOR BOTH HEADS)
  2238                              <1> 
  2239 0000480B 66B95004            <1> 	MOV	CX,0450H 		; START, MAX TRACKS
  2240 0000480F F687[6D640100]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; TEST FOR 80 TRACK CAPABILITY
  2241 00004816 7402                <1> 	JZ	short CNT_OK		; IF NOT COUNT IS SETUP
  2242 00004818 B1A0                <1> 	MOV	CL,0A0H			; MAXIMUM TRACK 1.2 MB
  2243                              <1> 
  2244                              <1> ;	ATTEMPT READ ID OF ALL TRACKS, ALL HEADS UNTIL SUCCESS; UPON SUCCESS,
  2245                              <1> ;	MUST SEE IF ASKED FOR TRACK IN SINGLE STEP MODE = TRACK ID READ; IF NOT
  2246                              <1> ;	THEN SET DOUBLE STEP ON.
  2247                              <1> 
  2248                              <1> CNT_OK:
  2249 0000481A C605[5F640100]FF    <1>         MOV     byte [MOTOR_COUNT], 0FFH ; ENSURE MOTOR STAYS ON FOR OPERATION 
  2250 00004821 6651                <1> 	PUSH	CX			; SAVE TRACK, COUNT
  2251 00004823 C605[60640100]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR STATUS, EXPECT ERRORS
  2252 0000482A 6631C0              <1> 	XOR	AX,AX			; CLEAR AX
  2253 0000482D D0ED                <1> 	SHR	CH,1			; HALVE TRACK, CY = HEAD
  2254 0000482F C0D003              <1> 	RCL	AL,3			; AX = HEAD IN CORRECT BIT
  2255 00004832 6650                <1> 	PUSH	AX			; SAVE HEAD
  2256 00004834 E89F010000          <1> 	CALL	SEEK			; SEEK TO TRACK
  2257 00004839 6658                <1> 	POP	AX			; RESTORE HEAD
  2258 0000483B 6609C7              <1> 	OR	DI,AX			; DI = HEAD OR'ED DRIVE
  2259 0000483E E82E000000          <1> 	CALL	READ_ID			; READ ID HEAD 0
  2260 00004843 9C                  <1> 	PUSHF				; SAVE RETURN FROM READ_ID
  2261 00004844 6681E7FB00          <1> 	AND	DI,11111011B		; TURN OFF HEAD 1 BIT
  2262 00004849 9D                  <1> 	POPF				; RESTORE ERROR RETURN
  2263 0000484A 6659                <1> 	POP	CX			; RESTORE COUNT
  2264 0000484C 7308                <1> 	JNC	short DO_CHK		; IF OK, ASKED = RETURNED TRACK ?
  2265 0000484E FEC5                <1> 	INC	CH			; INC FOR NEXT TRACK
  2266 00004850 38CD                <1> 	CMP	CH,CL			; REACHED MAXIMUM YET
  2267 00004852 75C6                <1> 	JNZ	short CNT_OK		; CONTINUE TILL ALL TRIED
  2268                              <1> 
  2269                              <1> ;-----	FALL THRU, READ ID FAILED FOR ALL TRACKS
  2270                              <1> 
  2271                              <1> SD_ERR:	
  2272 00004854 F9                  <1> 	STC				; SET CARRY FOR ERROR
  2273 00004855 C3                  <1> 	RETn				; SETUP_DBL ERROR EXIT
  2274                              <1> 
  2275                              <1> DO_CHK:
  2276 00004856 8A0D[64640100]      <1> 	MOV	CL, [NEC_STATUS+3]	; LOAD RETURNED TRACK
  2277 0000485C 888F[71640100]      <1> 	MOV	[DSK_TRK+eDI], CL	; STORE TRACK NUMBER
  2278 00004862 D0ED                <1> 	SHR	CH,1			; HALVE TRACK
  2279 00004864 38CD                <1> 	CMP	CH,CL			; IS IT THE SAME AS ASKED FOR TRACK
  2280 00004866 7407                <1> 	JZ	short NO_DBL		; IF SAME THEN NO DOUBLE STEP
  2281 00004868 808F[6D640100]20    <1> 	OR	byte [DSK_STATE+eDI],DBL_STEP ; TURN ON DOUBLE STEP REQUIRED
  2282                              <1> NO_DBL:
  2283 0000486F F8                  <1> 	CLC				; CLEAR ERROR FLAG
  2284 00004870 C3                  <1> 	RETn
  2285                              <1> 
  2286                              <1> ;-------------------------------------------------------------------------------
  2287                              <1> ; READ_ID
  2288                              <1> ;	READ ID FUNCTION.
  2289                              <1> ;
  2290                              <1> ; ON ENTRY:	DI : BIT 2 = HEAD; BITS 1,0 = DRIVE
  2291                              <1> ;
  2292                              <1> ; ON EXIT: 	DI : BIT 2 IS RESET, BITS 1,0 = DRIVE
  2293                              <1> ;		@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  2294                              <1> ;-------------------------------------------------------------------------------
  2295                              <1> READ_ID:
  2296 00004871 B8[8E480000]        <1> 	MOV	eAX, ER_3		; MOVE NEC OUTPUT ERROR ADDRESS
  2297 00004876 50                  <1> 	PUSH	eAX
  2298 00004877 B44A                <1> 	MOV	AH,4AH			; READ ID COMMAND
  2299 00004879 E820010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  2300 0000487E 6689F8              <1> 	MOV	AX,DI			; DRIVE # TO AH, HEAD 0
  2301 00004881 88C4                <1> 	MOV	AH,AL
  2302 00004883 E816010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  2303 00004888 E80BFEFFFF          <1> 	CALL	NEC_TERM		; WAIT FOR OPERATION, GET STATUS
  2304 0000488D 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  2305                              <1> ER_3:
  2306 0000488E C3                  <1> 	RETn
  2307                              <1> 
  2308                              <1> ;-------------------------------------------------------------------------------
  2309                              <1> ; CMOS_TYPE
  2310                              <1> ;	RETURNS DISKETTE TYPE FROM CMOS
  2311                              <1> ;
  2312                              <1> ; ON ENTRY:	DI = DRIVE #
  2313                              <1> ;
  2314                              <1> ; ON EXIT:	AL = TYPE; CY REFLECTS STATUS
  2315                              <1> ;-------------------------------------------------------------------------------
  2316                              <1> 
  2317                              <1> CMOS_TYPE: ; 11/12/2014
  2318 0000488F 8A87[CE670000]      <1> mov	al, [eDI+fd0_type]
  2319 00004895 20C0                <1> and 	al, al ; 18/12/2014
  2320 00004897 C3                  <1> retn
  2321                              <1> 
  2322                              <1> ;CMOS_TYPE:
  2323                              <1> ;	MOV	AL, CMOS_DIAG		; CMOS DIAGNOSTIC STATUS BYTE ADDRESS
  2324                              <1> ;	CALL	CMOS_READ		; GET CMOS STATUS
  2325                              <1> ;	TEST	AL,BAD_BAT+BAD_CKSUM	; BATTERY GOOD AND CHECKSUM VALID
  2326                              <1> ;	STC				; SET CY = 1 INDICATING ERROR FOR RETURN
  2327                              <1> ;	JNZ	short BAD_CM		; ERROR IF EITHER BIT ON
  2328                              <1> ;	MOV	AL,CMOS_DISKETTE	; ADDRESS OF DISKETTE BYTE IN CMOS
  2329                              <1> ;	CALL	CMOS_READ		; GET DISKETTE BYTE
  2330                              <1> ;	OR	DI,DI			; SEE WHICH DRIVE IN QUESTION
  2331                              <1> ;	JNZ	short TB		; IF DRIVE 1, DATA IN LOW NIBBLE
  2332                              <1> ;	ROR	AL,4			; EXCHANGE NIBBLES IF SECOND DRIVE
  2333                              <1> ;TB:
  2334                              <1> ;	AND	AL,0FH			; KEEP ONLY DRIVE DATA, RESET CY, 0
  2335                              <1> ;BAD_CM:
  2336                              <1> ;	RETn				; CY, STATUS OF READ
  2337                              <1> 
  2338                              <1> ;-------------------------------------------------------------------------------
  2339                              <1> ; GET_PARM
  2340                              <1> ;	THIS ROUTINE FETCHES THE INDEXED POINTER FROM THE DISK_BASE
  2341                              <1> ;	BLOCK POINTED TO BY THE DATA VARIABLE @DISK_POINTER. A BYTE FROM
  2342                              <1> ;	THAT TABLE IS THEN MOVED INTO AH, THE INDEX OF THAT BYTE BEING
  2343                              <1> ;	THE PARAMETER IN DL.
  2344                              <1> ;
  2345                              <1> ; ON ENTRY:	DL = INDEX OF BYTE TO BE FETCHED
  2346                              <1> ;
  2347                              <1> ; ON EXIT:	AH = THAT BYTE FROM BLOCK
  2348                              <1> ;		AL,DH DESTROYED
  2349                              <1> ;-------------------------------------------------------------------------------
  2350                              <1> GET_PARM:
  2351                              <1> 	;PUSH	DS
  2352 00004898 56                  <1> 	PUSH	eSI
  2353                              <1>     	;SUB	AX,AX			; DS = 0, BIOS DATA AREA
  2354                              <1>     	;MOV	DS,AX
  2355                              <1> 	;;mov	ax, cs
  2356                              <1> 	;;mov	ds, ax
  2357                              <1> 	; 08/02/2015 (protected mode modifications, bx -> ebx)
  2358 00004899 87D3                <1> 	XCHG	eDX,eBX			; BL = INDEX
  2359                              <1> 	;SUB	BH,BH			; BX = INDEX
  2360 0000489B 81E3FF000000        <1> 	and	ebx, 0FFh
  2361                              <1>     	;LDS	SI, [DISK_POINTER]	; POINT TO BLOCK
  2362                              <1> 	;
  2363                              <1> 	; 17/12/2014
  2364 000048A1 66A1[BD670000]      <1> 	mov	ax, [cfd] ; current (AL) and previous fd (AH)
  2365 000048A7 38E0                <1> 	cmp	al, ah
  2366 000048A9 7425                <1> 	je	short gpndc
  2367 000048AB A2[BE670000]        <1> 	mov	[pfd], al ; current drive -> previous drive
  2368 000048B0 53                  <1> 	push	ebx ; 08/02/2015
  2369 000048B1 88C3                <1> 	mov	bl, al 
  2370                              <1> 	; 11/12/2014
  2371 000048B3 8A83[CE670000]      <1> 	mov	al, [eBX+fd0_type]	; Drive type (0,1,2,3,4)
  2372                              <1> 	; 18/12/2014
  2373 000048B9 20C0                <1> 	and	al, al
  2374 000048BB 7507                <1> 	jnz	short gpdtc
  2375 000048BD BB[A7670000]        <1> 	mov	ebx, MD_TBL6		; 1.44 MB param. tbl. (default)
  2376 000048C2 EB05                <1>         jmp     short gpdpu
  2377                              <1> gpdtc:	
  2378 000048C4 E817F9FFFF          <1> 	call	DR_TYPE_CHECK
  2379                              <1> 	; cf = 1 -> eBX points to 1.44MB fd parameter table (default)
  2380                              <1> gpdpu:
  2381 000048C9 891D[44670000]      <1> 	mov	[DISK_POINTER], ebx
  2382 000048CF 5B                  <1> 	pop	ebx
  2383                              <1> gpndc:
  2384 000048D0 8B35[44670000]      <1> 	mov	esi, [DISK_POINTER] ; 08/02/2015, si -> esi
  2385 000048D6 8A241E              <1> 	MOV	AH, [eSI+eBX]		; GET THE WORD
  2386 000048D9 87D3                <1> 	XCHG	eDX,eBX			; RESTORE BX
  2387 000048DB 5E                  <1> 	POP	eSI
  2388                              <1> 	;POP	DS
  2389 000048DC C3                  <1> 	RETn
  2390                              <1> 
  2391                              <1> ;-------------------------------------------------------------------------------
  2392                              <1> ; MOTOR_ON
  2393                              <1> ;	TURN MOTOR ON AND WAIT FOR MOTOR START UP TIME. THE @MOTOR_COUNT
  2394                              <1> ;	IS REPLACED WITH A SUFFICIENTLY HIGH NUMBER (0FFH) TO ENSURE
  2395                              <1> ;	THAT THE MOTOR DOES NOT GO OFF DURING THE OPERATION. IF THE
  2396                              <1> ;	MOTOR NEEDED TO BE TURNED ON, THE MULTI-TASKING HOOK FUNCTION
  2397                              <1> ;	(AX=90FDH, INT 15) IS CALLED TELLING THE OPERATING SYSTEM
  2398                              <1> ;	THAT THE BIOS IS ABOUT TO WAIT FOR MOTOR START UP. IF THIS
  2399                              <1> ;	FUNCTION RETURNS WITH CY = 1, IT MEANS THAT THE MINIMUM WAIT
  2400                              <1> ;	HAS BEEN COMPLETED. AT THIS POINT A CHECK IS MADE TO ENSURE
  2401                              <1> ;	THAT THE MOTOR WASN'T TURNED OFF BY THE TIMER. IF THE HOOK DID
  2402                              <1> ;	NOT WAIT, THE WAIT FUNCTION (AH=086H) IS CALLED TO WAIT THE
  2403                              <1> ;	PRESCRIBED AMOUNT OF TIME. IF THE CARRY FLAG IS SET ON RETURN,
  2404                              <1> ;	IT MEANS THAT THE FUNCTION IS IN USE AND DID NOT PERFORM THE
  2405                              <1> ;	WAIT. A TIMER 1 WAIT LOOP WILL THEN DO THE WAIT.
  2406                              <1> ;
  2407                              <1> ; ON ENTRY:	DI = DRIVE #
  2408                              <1> ; ON EXIT:	AX,CX,DX DESTROYED
  2409                              <1> ;-------------------------------------------------------------------------------
  2410                              <1> MOTOR_ON:
  2411 000048DD 53                  <1> 	PUSH	eBX			; SAVE REG.
  2412 000048DE E82A000000          <1> 	CALL	TURN_ON			; TURN ON MOTOR
  2413 000048E3 7226                <1> 	JC	short MOT_IS_ON		; IF CY=1 NO WAIT
  2414 000048E5 E89BF9FFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  2415 000048EA E865F9FFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
  2416                              <1> 	;CALL	TURN_ON 		; CHECK AGAIN IF MOTOR ON
  2417                              <1> 	;JC	MOT_IS_ON		; IF NO WAIT MEANS IT IS ON
  2418                              <1> M_WAIT:
  2419 000048EF B20A                <1> 	MOV	DL,10			; GET THE MOTOR WAIT PARAMETER
  2420 000048F1 E8A2FFFFFF          <1> 	CALL	GET_PARM
  2421                              <1> 	;MOV	AL,AH			; AL = MOTOR WAIT PARAMETER
  2422                              <1> 	;XOR	AH,AH			; AX = MOTOR WAIT PARAMETER
  2423                              <1> 	;CMP	AL,8			; SEE IF AT LEAST A SECOND IS SPECIFIED
  2424 000048F6 80FC08              <1> 	cmp	ah, 8
  2425                              <1> 	;JAE	short GP2		; IF YES, CONTINUE
  2426 000048F9 7702                <1> 	ja	short J13
  2427                              <1> 	;MOV	AL,8			; ONE SECOND WAIT FOR MOTOR START UP
  2428 000048FB B408                <1> 	mov	ah, 8
  2429                              <1> 
  2430                              <1> ;-----	AS CONTAINS NUMBER OF 1/8 SECONDS (125000 MICROSECONDS) TO WAIT
  2431                              <1> GP2:	
  2432                              <1> ;----- 	FOLLOWING LOOPS REQUIRED WHEN RTC WAIT FUNCTION IS ALREADY IN USE
  2433                              <1> J13:					; WAIT FOR 1/8 SECOND PER (AL)
  2434 000048FD B95E200000          <1> 	MOV	eCX,8286		; COUNT FOR 1/8 SECOND AT 15.085737 US
  2435 00004902 E835DAFFFF          <1> 	CALL	WAITF			; GO TO FIXED WAIT ROUTINE
  2436                              <1> 	;DEC	AL			; DECREMENT TIME VALUE
  2437 00004907 FECC                <1> 	dec	ah
  2438 00004909 75F2                <1> 	JNZ	short J13		; ARE WE DONE YET
  2439                              <1> MOT_IS_ON:
  2440 0000490B 5B                  <1> 	POP	eBX			; RESTORE REG.
  2441 0000490C C3                  <1> 	RETn
  2442                              <1> 
  2443                              <1> ;-------------------------------------------------------------------------------
  2444                              <1> ; TURN_ON
  2445                              <1> ;	TURN MOTOR ON AND RETURN WAIT STATE.
  2446                              <1> ;
  2447                              <1> ; ON ENTRY:	DI = DRIVE #
  2448                              <1> ;
  2449                              <1> ; ON EXIT:	CY = 0 MEANS WAIT REQUIRED
  2450                              <1> ;		CY = 1 MEANS NO WAIT REQUIRED
  2451                              <1> ;		AX,BX,CX,DX DESTROYED
  2452                              <1> ;-------------------------------------------------------------------------------
  2453                              <1> TURN_ON:
  2454 0000490D 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2455 0000490F 88D9                <1> 	MOV	CL,BL			; CL = DRIVE #
  2456 00004911 C0C304              <1> 	ROL	BL,4			; BL = DRIVE SELECT
  2457 00004914 FA                  <1> 	CLI				; NO INTERRUPTS WHILE DETERMINING STATUS
  2458 00004915 C605[5F640100]FF    <1> 	MOV	byte [MOTOR_COUNT],0FFH	; ENSURE MOTOR STAYS ON FOR OPERATION
  2459 0000491C A0[5E640100]        <1> 	MOV	AL, [MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  2460 00004921 2430                <1> 	AND	AL,00110000B		; KEEP ONLY DRIVE SELECT BITS
  2461 00004923 B401                <1> 	MOV	AH,1			; MASK FOR DETERMINING MOTOR BIT
  2462 00004925 D2E4                <1> 	SHL	AH,CL			; AH = MOTOR ON, A=00000001, B=00000010
  2463                              <1> 
  2464                              <1> ;  AL = DRIVE SELECT FROM @MOTOR_STATUS
  2465                              <1> ;  BL = DRIVE SELECT DESIRED
  2466                              <1> ;  AH = MOTOR ON MASK DESIRED
  2467                              <1> 
  2468 00004927 38D8                <1> 	CMP	AL,BL			; REQUESTED DRIVE ALREADY SELECTED ?
  2469 00004929 7508                <1> 	JNZ	short TURN_IT_ON	; IF NOT SELECTED JUMP
  2470 0000492B 8425[5E640100]      <1> 	TEST	AH, [MOTOR_STATUS]	; TEST MOTOR ON BIT
  2471 00004931 7535                <1> 	JNZ	short NO_MOT_WAIT	; JUMP IF MOTOR ON AND SELECTED
  2472                              <1> 
  2473                              <1> TURN_IT_ON:
  2474 00004933 08DC                <1> 	OR	AH,BL			; AH = DRIVE SELECT AND MOTOR ON
  2475 00004935 8A3D[5E640100]      <1> 	MOV	BH,[MOTOR_STATUS]	; SAVE COPY OF @MOTOR_STATUS BEFORE
  2476 0000493B 80E70F              <1> 	AND	BH,00001111B		; KEEP ONLY MOTOR BITS
  2477 0000493E 8025[5E640100]CF    <1> 	AND	byte [MOTOR_STATUS],11001111B ; CLEAR OUT DRIVE SELECT
  2478 00004945 0825[5E640100]      <1> 	OR	[MOTOR_STATUS],AH	; OR IN DRIVE SELECTED AND MOTOR ON
  2479 0000494B A0[5E640100]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  2480 00004950 88C3                <1> 	MOV	BL,AL			; BL=@MOTOR_STATUS AFTER, BH=BEFORE
  2481 00004952 80E30F              <1> 	AND	BL,00001111B		; KEEP ONLY MOTOR BITS
  2482 00004955 FB                  <1> 	STI				; ENABLE INTERRUPTS AGAIN
  2483 00004956 243F                <1> 	AND	AL,00111111B		; STRIP AWAY UNWANTED BITS
  2484 00004958 C0C004              <1> 	ROL	AL,4			; PUT BITS IN DESIRED POSITIONS
  2485 0000495B 0C0C                <1> 	OR	AL,00001100B		; NO RESET, ENABLE DMA/INTERRUPT
  2486 0000495D 66BAF203            <1> 	MOV	DX,03F2H		; SELECT DRIVE AND TURN ON MOTOR
  2487 00004961 EE                  <1> 	OUT	DX,AL
  2488 00004962 38FB                <1> 	CMP	BL,BH			; NEW MOTOR TURNED ON ?
  2489                              <1> 	;JZ	short NO_MOT_WAIT	; NO WAIT REQUIRED IF JUST SELECT
  2490 00004964 7403                <1> 	je	short no_mot_w1 ; 27/02/2015 
  2491 00004966 F8                  <1> 	CLC				; (re)SET CARRY MEANING WAIT
  2492 00004967 C3                  <1> 	RETn
  2493                              <1> 
  2494                              <1> NO_MOT_WAIT:
  2495 00004968 FB                  <1> 	sti
  2496                              <1> no_mot_w1: ; 27/02/2015
  2497 00004969 F9                  <1> 	STC				; SET NO WAIT REQUIRED
  2498                              <1> 	;STI				; INTERRUPTS BACK ON
  2499 0000496A C3                  <1> 	RETn
  2500                              <1> 
  2501                              <1> ;-------------------------------------------------------------------------------
  2502                              <1> ; HD_WAIT
  2503                              <1> ;	WAIT FOR HEAD SETTLE TIME.
  2504                              <1> ;
  2505                              <1> ; ON ENTRY:	DI = DRIVE #
  2506                              <1> ;
  2507                              <1> ; ON EXIT:	AX,BX,CX,DX DESTROYED
  2508                              <1> ;-------------------------------------------------------------------------------
  2509                              <1> HD_WAIT:
  2510 0000496B B209                <1> 	MOV	DL,9			; GET HEAD SETTLE PARAMETER
  2511 0000496D E826FFFFFF          <1> 	CALL	GET_PARM
  2512 00004972 08E4                <1> 	or	ah, ah	; 17/12/2014
  2513 00004974 7519                <1> 	jnz	short DO_WAT
  2514 00004976 F605[5E640100]80    <1>         TEST    byte [MOTOR_STATUS],10000000B ; SEE IF A WRITE OPERATION
  2515                              <1> 	;JZ	short ISNT_WRITE	; IF NOT, DO NOT ENFORCE ANY VALUES
  2516                              <1> 	;OR	AH,AH			; CHECK FOR ANY WAIT?
  2517                              <1> 	;JNZ	short DO_WAT		; IF THERE DO NOT ENFORCE
  2518 0000497D 741E                <1> 	jz	short HW_DONE
  2519 0000497F B40F                <1> 	MOV	AH,HD12_SETTLE		; LOAD 1.2M HEAD SETTLE MINIMUM
  2520 00004981 8A87[6D640100]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  2521 00004987 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  2522 00004989 3C80                <1> 	CMP	AL,RATE_250		; 1.2 M DRIVE ?
  2523 0000498B 7502                <1> 	JNZ	short DO_WAT		; DEFAULT HEAD SETTLE LOADED
  2524                              <1> ;GP3:
  2525 0000498D B414                <1> 	MOV	AH,HD320_SETTLE		; USE 320/360 HEAD SETTLE
  2526                              <1> ;	JMP	SHORT DO_WAT
  2527                              <1> 
  2528                              <1> ;ISNT_WRITE:
  2529                              <1> ;	OR	AH,AH			; CHECK FOR NO WAIT
  2530                              <1> ;	JZ	short HW_DONE		; IF NOT WRITE AND 0 ITS OK
  2531                              <1> 
  2532                              <1> ;-----	AH CONTAINS NUMBER OF MILLISECONDS TO WAIT
  2533                              <1> DO_WAT:
  2534                              <1> ;	MOV	AL,AH			; AL = # MILLISECONDS
  2535                              <1> ;	;XOR	AH,AH			; AX = # MILLISECONDS
  2536                              <1> J29:					; 	1 MILLISECOND LOOP
  2537                              <1> 	;mov	cx, WAIT_FDU_HEAD_SETTLE ; 33 ; 1 ms in 30 micro units.
  2538 0000498F B942000000          <1> 	MOV	eCX,66			; COUNT AT 15.085737 US PER COUNT
  2539 00004994 E8A3D9FFFF          <1> 	CALL	WAITF			; DELAY FOR 1 MILLISECOND
  2540                              <1> 	;DEC	AL			; DECREMENT THE COUNT
  2541 00004999 FECC                <1> 	dec	ah
  2542 0000499B 75F2                <1> 	JNZ	short J29		; DO AL MILLISECOND # OF TIMES
  2543                              <1> HW_DONE:
  2544 0000499D C3                  <1> 	RETn
  2545                              <1> 
  2546                              <1> ;-------------------------------------------------------------------------------
  2547                              <1> ; NEC_OUTPUT
  2548                              <1> ;	THIS ROUTINE SENDS A BYTE TO THE NEC CONTROLLER AFTER TESTING
  2549                              <1> ;	FOR CORRECT DIRECTION AND CONTROLLER READY THIS ROUTINE WILL
  2550                              <1> ;	TIME OUT IF THE BYTE IS NOT ACCEPTED WITHIN A REASONABLE AMOUNT
  2551                              <1> ;	OF TIME, SETTING THE DISKETTE STATUS ON COMPLETION.
  2552                              <1> ; 
  2553                              <1> ; ON ENTRY: 	AH = BYTE TO BE OUTPUT
  2554                              <1> ;
  2555                              <1> ; ON EXIT:	CY = 0  SUCCESS
  2556                              <1> ;		CY = 1  FAILURE -- DISKETTE STATUS UPDATED
  2557                              <1> ;		        IF A FAILURE HAS OCCURRED, THE RETURN IS MADE ONE LEVEL
  2558                              <1> ;		        HIGHER THAN THE CALLER OF NEC OUTPUT. THIS REMOVES THE
  2559                              <1> ;		        REQUIREMENT OF TESTING AFTER EVERY CALL OF NEC_OUTPUT.
  2560                              <1> ;		AX,CX,DX DESTROYED
  2561                              <1> ;-------------------------------------------------------------------------------
  2562                              <1> 
  2563                              <1> ; 09/12/2014 [Erdogan Tan] 
  2564                              <1> ;	(from 'PS2 Hardware Interface Tech. Ref. May 88', Page 09-05.)
  2565                              <1> ; Diskette Drive Controller Status Register (3F4h)
  2566                              <1> ;	This read only register facilitates the transfer of data between
  2567                              <1> ;	the system microprocessor and the controller.
  2568                              <1> ; Bit 7 - When set to 1, the Data register is ready to transfer data 
  2569                              <1> ;	  with the system micrprocessor.
  2570                              <1> ; Bit 6 - The direction of data transfer. If this bit is set to 0,
  2571                              <1> ;	  the transfer is to the controller.
  2572                              <1> ; Bit 5 - When this bit is set to 1, the controller is in the non-DMA mode.
  2573                              <1> ; Bit 4 - When this bit is set to 1, a Read or Write command is being executed.
  2574                              <1> ; Bit 3 - Reserved.
  2575                              <1> ; Bit 2 - Reserved.
  2576                              <1> ; Bit 1 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  2577                              <1> ; Bit 0 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  2578                              <1> 
  2579                              <1> ; Data Register (3F5h)
  2580                              <1> ; This read/write register passes data, commands and parameters, and provides
  2581                              <1> ; diskette status information.
  2582                              <1>   		
  2583                              <1> NEC_OUTPUT:
  2584                              <1> 	;PUSH	BX			; SAVE REG.
  2585 0000499E 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  2586                              <1> 	;MOV	BL,2			; HIGH ORDER COUNTER
  2587                              <1> 	;XOR	CX,CX			; COUNT FOR TIME OUT
  2588                              <1> 	; 16/12/2014
  2589                              <1> 	; waiting for (max.) 0.5 seconds
  2590                              <1>         ;;mov     byte [wait_count], 0 ;; 27/02/2015
  2591                              <1> 	;
  2592                              <1> 	; 17/12/2014
  2593                              <1> 	; Modified from AWARD BIOS 1999 - ADISK.ASM - SEND_COMMAND
  2594                              <1> 	;
  2595                              <1> 	;WAIT_FOR_PORT:	Waits for a bit at a port pointed to by DX to
  2596                              <1> 	;		go on.
  2597                              <1> 	;INPUT:
  2598                              <1> 	;	AH=Mask for isolation bits.
  2599                              <1> 	;	AL=pattern to look for.
  2600                              <1> 	;	DX=Port to test for
  2601                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  2602                              <1> 	;	     (normally 30 microseconds per period.)
  2603                              <1> 	;
  2604                              <1> 	;WFP_SHORT:  
  2605                              <1> 	;	Wait for port if refresh cycle is short (15-80 Us range).
  2606                              <1> 	;
  2607                              <1> 
  2608                              <1> ;	mov	bl, WAIT_FDU_SEND_HI+1	; 0+1
  2609                              <1> ;	mov	cx, WAIT_FDU_SEND_LO	; 16667
  2610 000049A2 B91B410000          <1> 	mov	ecx, WAIT_FDU_SEND_LH   ; 16667 (27/02/2015)
  2611                              <1> ;
  2612                              <1> ;WFPS_OUTER_LP:
  2613                              <1> ;	;
  2614                              <1> ;WFPS_CHECK_PORT:
  2615                              <1> J23:
  2616 000049A7 EC                  <1> 	IN	AL,DX			; GET STATUS
  2617 000049A8 24C0                <1> 	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  2618 000049AA 3C80                <1> 	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  2619 000049AC 7418                <1> 	JZ	short J27		; STATUS AND DIRECTION OK
  2620                              <1> WFPS_HI:
  2621 000049AE E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  2622 000049B0 A810                <1> 	TEST	AL,010H			; transition on memory
  2623 000049B2 75FA                <1> 	JNZ	SHORT WFPS_HI		; refresh.
  2624                              <1> WFPS_LO:
  2625 000049B4 E461                <1> 	IN	AL, PORT_B		; SYS1
  2626 000049B6 A810                <1> 	TEST	AL,010H
  2627 000049B8 74FA                <1> 	JZ	SHORT WFPS_LO
  2628                              <1> 	;LOOP	SHORT WFPS_CHECK_PORT
  2629 000049BA E2EB                <1> 	loop	J23	; 27/02/2015
  2630                              <1> ;	;
  2631                              <1> ;	dec	bl
  2632                              <1> ;	jnz	short WFPS_OUTER_LP
  2633                              <1> ;	jmp	short WFPS_TIMEOUT	; fail
  2634                              <1> ;J23:
  2635                              <1> ;	IN	AL,DX			; GET STATUS
  2636                              <1> ;	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  2637                              <1> ;	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  2638                              <1> ;	JZ	short J27		; STATUS AND DIRECTION OK
  2639                              <1> 	;LOOP	J23			; CONTINUE TILL CX EXHAUSTED
  2640                              <1> 	;DEC	BL			; DECREMENT COUNTER
  2641                              <1> 	;JNZ	short J23		; REPEAT TILL DELAY FINISHED, CX = 0
  2642                              <1>    
  2643                              <1> 	;;27/02/2015
  2644                              <1> 	;16/12/2014
  2645                              <1>         ;;cmp     byte [wait_count], 10   ; (10/18.2 seconds)
  2646                              <1> 	;;jb	short J23
  2647                              <1> 
  2648                              <1> ;WFPS_TIMEOUT:
  2649                              <1> 
  2650                              <1> ;-----	FALL THRU TO ERROR RETURN
  2651                              <1> 
  2652 000049BC 800D[60640100]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  2653                              <1> 	;POP	BX			; RESTORE REG.
  2654 000049C3 58                  <1> 	POP	eAX ; 08/02/2015	; DISCARD THE RETURN ADDRESS
  2655 000049C4 F9                  <1> 	STC				; INDICATE ERROR TO CALLER
  2656 000049C5 C3                  <1> 	RETn
  2657                              <1> 
  2658                              <1> ;-----	DIRECTION AND STATUS OK; OUTPUT BYTE
  2659                              <1> 
  2660                              <1> J27:	
  2661 000049C6 88E0                <1> 	MOV	AL,AH			; GET BYTE TO OUTPUT
  2662 000049C8 6642                <1> 	INC	DX			; DATA PORT = STATUS PORT + 1
  2663 000049CA EE                  <1> 	OUT	DX,AL			; OUTPUT THE BYTE
  2664                              <1> 	;;NEWIODELAY  ;; 27/02/2015
  2665                              <1> 	; 27/02/2015
  2666 000049CB 9C                  <1> 	PUSHF				; SAVE FLAGS
  2667 000049CC B903000000          <1> 	MOV	eCX, 3			; 30 TO 45 MICROSECONDS WAIT FOR
  2668 000049D1 E866D9FFFF          <1> 	CALL 	WAITF			; NEC FLAGS UPDATE CYCLE
  2669 000049D6 9D                  <1> 	POPF				; RESTORE FLAGS FOR EXIT
  2670                              <1> 	;POP	BX			; RESTORE REG
  2671 000049D7 C3                  <1> 	RETn				; CY = 0 FROM TEST INSTRUCTION
  2672                              <1> 
  2673                              <1> ;-------------------------------------------------------------------------------
  2674                              <1> ; SEEK
  2675                              <1> ;	THIS ROUTINE WILL MOVE THE HEAD ON THE NAMED DRIVE TO THE NAMED
  2676                              <1> ;	TRACK. IF THE DRIVE HAS NOT BEEN ACCESSED SINCE THE DRIVE
  2677                              <1> ;	RESET COMMAND WAS ISSUED, THE DRIVE WILL BE RECALIBRATED.
  2678                              <1> ;
  2679                              <1> ; ON ENTRY:	DI = DRIVE #
  2680                              <1> ;		CH = TRACK #
  2681                              <1> ;
  2682                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2683                              <1> ;		AX,BX,CX DX DESTROYED
  2684                              <1> ;-------------------------------------------------------------------------------
  2685                              <1> SEEK:
  2686 000049D8 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2687 000049DA B001                <1> 	MOV	AL,1			; ESTABLISH MASK FOR RECALIBRATE TEST
  2688 000049DC 86CB                <1> 	XCHG	CL,BL			; SET DRIVE VALULE INTO CL
  2689 000049DE D2C0                <1> 	ROL	AL,CL			; SHIFT MASK BY THE DRIVE VALUE
  2690 000049E0 86CB                <1> 	XCHG	CL,BL			; RECOVER TRACK VALUE
  2691 000049E2 8405[5D640100]      <1> 	TEST	AL,[SEEK_STATUS]	; TEST FOR RECALIBRATE REQUIRED
  2692 000049E8 7526                <1> 	JNZ	short J28A		; JUMP IF RECALIBRATE NOT REQUIRED
  2693                              <1> 
  2694 000049EA 0805[5D640100]      <1> 	OR	[SEEK_STATUS],AL	; TURN ON THE NO RECALIBRATE BIT IN FLAG
  2695 000049F0 E862000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  2696 000049F5 730E                <1> 	JNC	short AFT_RECAL		; RECALIBRATE DONE
  2697                              <1> 
  2698                              <1> ;-----	ISSUE RECALIBRATE FOR 80 TRACK DISKETTES
  2699                              <1> 
  2700 000049F7 C605[60640100]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR OUT INVALID STATUS
  2701 000049FE E854000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  2702 00004A03 7251                <1> 	JC	short RB		; IF RECALIBRATE FAILS TWICE THEN ERROR
  2703                              <1> 
  2704                              <1> AFT_RECAL:
  2705 00004A05 C687[71640100]00    <1>         MOV     byte [DSK_TRK+eDI],0    ; SAVE NEW CYLINDER AS PRESENT POSITION
  2706 00004A0C 08ED                <1> 	OR	CH,CH			; CHECK FOR SEEK TO TRACK 0
  2707 00004A0E 743F                <1> 	JZ	short DO_WAIT		; HEAD SETTLE, CY = 0 IF JUMP
  2708                              <1> 
  2709                              <1> ;-----	DRIVE IS IN SYNCHRONIZATION WITH CONTROLLER, SEEK TO TRACK
  2710                              <1> 
  2711 00004A10 F687[6D640100]20    <1> J28A:	TEST	byte [DSK_STATE+eDI],DBL_STEP ; CHECK FOR DOUBLE STEP REQUIRED
  2712 00004A17 7402                <1> 	JZ	short _R7		; SINGLE STEP REQUIRED BYPASS DOUBLE
  2713 00004A19 D0E5                <1> 	SHL	CH,1			; DOUBLE NUMBER OF STEP TO TAKE
  2714                              <1> 
  2715 00004A1B 3AAF[71640100]      <1> _R7:	CMP	CH, [DSK_TRK+eDI]	; SEE IF ALREADY AT THE DESIRED TRACK
  2716 00004A21 7433                <1> 	JE	short RB		; IF YES, DO NOT NEED TO SEEK
  2717                              <1> 
  2718 00004A23 BA[564A0000]        <1> 	MOV	eDX, NEC_ERR		; LOAD RETURN ADDRESS
  2719 00004A28 52                  <1> 	PUSH	eDX ; (*)		; ON STACK FOR NEC OUTPUT ERROR
  2720 00004A29 88AF[71640100]      <1> 	MOV	[DSK_TRK+eDI],CH	; SAVE NEW CYLINDER AS PRESENT POSITION
  2721 00004A2F B40F                <1> 	MOV	AH,0FH			; SEEK COMMAND TO NEC
  2722 00004A31 E868FFFFFF          <1> 	CALL	NEC_OUTPUT
  2723 00004A36 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2724 00004A38 88DC                <1> 	MOV	AH,BL			; OUTPUT DRIVE NUMBER
  2725 00004A3A E85FFFFFFF          <1> 	CALL	NEC_OUTPUT
  2726 00004A3F 8AA7[71640100]      <1> 	MOV	AH, [DSK_TRK+eDI]	; GET CYLINDER NUMBER
  2727 00004A45 E854FFFFFF          <1> 	CALL	NEC_OUTPUT
  2728 00004A4A E829000000          <1> 	CALL	CHK_STAT_2		; ENDING INTERRUPT AND SENSE STATUS
  2729                              <1> 
  2730                              <1> ;-----	WAIT FOR HEAD SETTLE
  2731                              <1> 
  2732                              <1> DO_WAIT:
  2733 00004A4F 9C                  <1> 	PUSHF				; SAVE STATUS
  2734 00004A50 E816FFFFFF          <1> 	CALL	HD_WAIT			; WAIT FOR HEAD SETTLE TIME
  2735 00004A55 9D                  <1> 	POPF				; RESTORE STATUS
  2736                              <1> RB:
  2737                              <1> NEC_ERR:
  2738                              <1> 	; 08/02/2015 (code trick here from original IBM PC/AT DISKETTE.ASM)
  2739                              <1> 	; (*) nec_err -> retn (push edx -> pop edx) -> nec_err -> retn
  2740 00004A56 C3                  <1> 	RETn				; RETURN TO CALLER
  2741                              <1> 
  2742                              <1> ;-------------------------------------------------------------------------------
  2743                              <1> ; RECAL
  2744                              <1> ;	RECALIBRATE DRIVE
  2745                              <1> ;
  2746                              <1> ; ON ENTRY:	DI = DRIVE #
  2747                              <1> ;
  2748                              <1> ; ON EXIT:	CY REFLECTS STATUS OF OPERATION.
  2749                              <1> ;-------------------------------------------------------------------------------
  2750                              <1> RECAL:
  2751 00004A57 6651                <1> 	PUSH	CX
  2752 00004A59 B8[754A0000]        <1> 	MOV	eAX, RC_BACK		; LOAD NEC_OUTPUT ERROR
  2753 00004A5E 50                  <1> 	PUSH	eAX
  2754 00004A5F B407                <1> 	MOV	AH,07H			; RECALIBRATE COMMAND
  2755 00004A61 E838FFFFFF          <1> 	CALL	NEC_OUTPUT
  2756 00004A66 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2757 00004A68 88DC                <1> 	MOV	AH,BL
  2758 00004A6A E82FFFFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE DRIVE NUMBER
  2759 00004A6F E804000000          <1> 	CALL	CHK_STAT_2		; GET THE INTERRUPT AND SENSE INT STATUS
  2760 00004A74 58                  <1> 	POP	eAX			; THROW AWAY ERROR
  2761                              <1> RC_BACK:
  2762 00004A75 6659                <1> 	POP	CX
  2763 00004A77 C3                  <1> 	RETn
  2764                              <1> 
  2765                              <1> ;-------------------------------------------------------------------------------
  2766                              <1> ; CHK_STAT_2
  2767                              <1> ;	THIS ROUTINE HANDLES THE INTERRUPT RECEIVED AFTER RECALIBRATE,
  2768                              <1> ;	OR SEEK TO THE ADAPTER. THE INTERRUPT IS WAITED FOR, THE
  2769                              <1> ;	INTERRUPT STATUS SENSED, AND THE RESULT RETURNED TO THE CALLER.
  2770                              <1> ;
  2771                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2772                              <1> ;-------------------------------------------------------------------------------
  2773                              <1> CHK_STAT_2:
  2774 00004A78 B8[A04A0000]        <1>         MOV     eAX, CS_BACK            ; LOAD NEC_OUTPUT ERROR ADDRESS
  2775 00004A7D 50                  <1> 	PUSH	eAX
  2776 00004A7E E828000000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  2777 00004A83 721A                <1> 	JC	short J34		; IF ERROR, RETURN IT
  2778 00004A85 B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
  2779 00004A87 E812FFFFFF          <1> 	CALL	NEC_OUTPUT
  2780 00004A8C E84A000000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
  2781 00004A91 720C                <1> 	JC	short J34
  2782 00004A93 A0[61640100]        <1> 	MOV	AL,[NEC_STATUS]		; GET THE FIRST STATUS BYTE
  2783 00004A98 2460                <1> 	AND	AL,01100000B		; ISOLATE THE BITS
  2784 00004A9A 3C60                <1> 	CMP	AL,01100000B		; TEST FOR CORRECT VALUE
  2785 00004A9C 7403                <1> 	JZ	short J35		; IF ERROR, GO MARK IT
  2786 00004A9E F8                  <1> 	CLC				; GOOD RETURN
  2787                              <1> J34:
  2788 00004A9F 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
  2789                              <1> CS_BACK:
  2790 00004AA0 C3                  <1> 	RETn
  2791                              <1> J35:
  2792 00004AA1 800D[60640100]40    <1> 	OR	byte [DSKETTE_STATUS], BAD_SEEK
  2793 00004AA8 F9                  <1> 	STC				; ERROR RETURN CODE
  2794 00004AA9 EBF4                <1> 	JMP	SHORT J34
  2795                              <1> 
  2796                              <1> ;-------------------------------------------------------------------------------
  2797                              <1> ; WAIT_INT
  2798                              <1> ;	THIS ROUTINE WAITS FOR AN INTERRUPT TO OCCUR A TIME OUT ROUTINE
  2799                              <1> ;	TAKES PLACE DURING THE WAIT, SO THAT AN ERROR MAY BE RETURNED
  2800                              <1> ;	IF THE DRIVE IS NOT READY.
  2801                              <1> ;
  2802                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2803                              <1> ;-------------------------------------------------------------------------------
  2804                              <1> 
  2805                              <1> ; 17/12/2014
  2806                              <1> ; 2.5 seconds waiting !
  2807                              <1> ;(AWARD BIOS - 1999, WAIT_FDU_INT_LOW, WAIT_FDU_INT_HI)
  2808                              <1> ; amount of time to wait for completion interrupt from NEC.
  2809                              <1> 
  2810                              <1> 
  2811                              <1> WAIT_INT:
  2812 00004AAB FB                  <1> 	STI				; TURN ON INTERRUPTS, JUST IN CASE
  2813 00004AAC F8                  <1> 	CLC				; CLEAR TIMEOUT INDICATOR
  2814                              <1>        ;MOV	BL,10			; CLEAR THE COUNTERS
  2815                              <1>        ;XOR	CX,CX			; FOR 2 SECOND WAIT
  2816                              <1> 
  2817                              <1> 	; Modification from AWARD BIOS - 1999 (ATORGS.ASM, WAIT
  2818                              <1> 	;
  2819                              <1> 	;WAIT_FOR_MEM:	
  2820                              <1> 	;	Waits for a bit at a specified memory location pointed
  2821                              <1> 	;	to by ES:[DI] to become set.
  2822                              <1> 	;INPUT:
  2823                              <1> 	;	AH=Mask to test with.
  2824                              <1> 	;	ES:[DI] = memory location to watch.
  2825                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  2826                              <1> 	;	     (normally 30 microseconds per period.)
  2827                              <1> 
  2828                              <1> 	; waiting for (max.) 2.5 secs in 30 micro units.
  2829                              <1> ;	mov 	cx, WAIT_FDU_INT_LO		; 017798
  2830                              <1> ;;	mov 	bl, WAIT_FDU_INT_HI
  2831                              <1> ;	mov 	bl, WAIT_FDU_INT_HI + 1
  2832                              <1> 	; 27/02/2015
  2833 00004AAD B986450100          <1> 	mov 	ecx, WAIT_FDU_INT_LH	; 83334 (2.5 seconds)		
  2834                              <1> WFMS_CHECK_MEM:
  2835 00004AB2 F605[5D640100]80    <1> 	test	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  2836 00004AB9 7516                <1>         jnz     short J37
  2837                              <1> WFMS_HI:
  2838 00004ABB E461                <1> 	IN	AL,PORT_B  ; 061h	; SYS1, wait for lo to hi
  2839 00004ABD A810                <1> 	TEST	AL,010H			; transition on memory
  2840 00004ABF 75FA                <1> 	JNZ	SHORT WFMS_HI		; refresh.
  2841                              <1> WFMS_LO:
  2842 00004AC1 E461                <1> 	IN	AL,PORT_B		;SYS1
  2843 00004AC3 A810                <1> 	TEST	AL,010H
  2844 00004AC5 74FA                <1> 	JZ	SHORT WFMS_LO
  2845 00004AC7 E2E9                <1>         LOOP    WFMS_CHECK_MEM
  2846                              <1> ;WFMS_OUTER_LP:
  2847                              <1> ;;	or	bl, bl			; check outer counter
  2848                              <1> ;;	jz	short J36A		; WFMS_TIMEOUT
  2849                              <1> ;	dec	bl
  2850                              <1> ;	jz	short J36A	
  2851                              <1> ;	jmp	short WFMS_CHECK_MEM
  2852                              <1> 
  2853                              <1> 	;17/12/2014
  2854                              <1> 	;16/12/2014
  2855                              <1> ;        mov     byte [wait_count], 0    ; Reset (INT 08H) counter
  2856                              <1> ;J36:
  2857                              <1> ;	TEST	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  2858                              <1> ;	JNZ	short J37
  2859                              <1> 	;16/12/2014
  2860                              <1> 	;LOOP	J36			; COUNT DOWN WHILE WAITING
  2861                              <1> 	;DEC	BL			; SECOND LEVEL COUNTER
  2862                              <1> 	;JNZ	short J36
  2863                              <1> ;       cmp     byte [wait_count], 46   ; (46/18.2 seconds)
  2864                              <1> ;	jb	short J36
  2865                              <1> 
  2866                              <1> ;WFMS_TIMEOUT:
  2867                              <1> ;J36A:
  2868 00004AC9 800D[60640100]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; NOTHING HAPPENED
  2869 00004AD0 F9                  <1> 	STC				; ERROR RETURN
  2870                              <1> J37:
  2871 00004AD1 9C                  <1> 	PUSHF				; SAVE CURRENT CARRY
  2872 00004AD2 8025[5D640100]7F    <1> 	AND	byte [SEEK_STATUS], ~INT_FLAG ; TURN OFF INTERRUPT FLAG
  2873 00004AD9 9D                  <1> 	POPF				; RECOVER CARRY
  2874 00004ADA C3                  <1> 	RETn				; GOOD RETURN CODE
  2875                              <1> 
  2876                              <1> ;-------------------------------------------------------------------------------
  2877                              <1> ; RESULTS
  2878                              <1> ;	THIS ROUTINE WILL READ ANYTHING THAT THE NEC CONTROLLER RETURNS 
  2879                              <1> ;	FOLLOWING AN INTERRUPT.
  2880                              <1> ;
  2881                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2882                              <1> ;		AX,BX,CX,DX DESTROYED
  2883                              <1> ;-------------------------------------------------------------------------------
  2884                              <1> RESULTS:
  2885 00004ADB 57                  <1> 	PUSH	eDI
  2886 00004ADC BF[61640100]        <1> 	MOV	eDI, NEC_STATUS		; POINTER TO DATA AREA
  2887 00004AE1 B307                <1> 	MOV	BL,7			; MAX STATUS BYTES
  2888 00004AE3 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  2889                              <1> 
  2890                              <1> ;-----	WAIT FOR REQUEST FOR MASTER
  2891                              <1> 
  2892                              <1> _R10: 
  2893                              <1> 	; 16/12/2014
  2894                              <1> 	; wait for (max) 0.5 seconds
  2895                              <1> 	;MOV	BH,2			; HIGH ORDER COUNTER
  2896                              <1> 	;XOR	CX,CX			; COUNTER
  2897                              <1> 
  2898                              <1> 	;Time to wait while waiting for each byte of NEC results = .5
  2899                              <1> 	;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  2900                              <1> 	; 27/02/2015
  2901 00004AE7 B91B410000          <1> 	mov 	ecx, WAIT_FDU_RESULTS_LH ; 16667  
  2902                              <1> 	;mov	cx, WAIT_FDU_RESULTS_LO  ; 16667
  2903                              <1> 	;mov	bh, WAIT_FDU_RESULTS_HI+1 ; 0+1
  2904                              <1> 
  2905                              <1> WFPSR_OUTER_LP:
  2906                              <1> 	;
  2907                              <1> WFPSR_CHECK_PORT:
  2908                              <1> J39:					; WAIT FOR MASTER
  2909 00004AEC EC                  <1> 	IN	AL,DX			; GET STATUS
  2910 00004AED 24C0                <1> 	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  2911 00004AEF 3CC0                <1> 	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  2912 00004AF1 7418                <1> 	JZ	short J42		; STATUS AND DIRECTION OK
  2913                              <1> WFPSR_HI:
  2914 00004AF3 E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  2915 00004AF5 A810                <1> 	TEST	AL,010H			; transition on memory
  2916 00004AF7 75FA                <1> 	JNZ	SHORT WFPSR_HI		; refresh.
  2917                              <1> WFPSR_LO:
  2918 00004AF9 E461                <1> 	IN	AL, PORT_B		; SYS1
  2919 00004AFB A810                <1> 	TEST	AL,010H
  2920 00004AFD 74FA                <1> 	JZ	SHORT WFPSR_LO
  2921 00004AFF E2EB                <1>         LOOP    WFPSR_CHECK_PORT
  2922                              <1> 	;; 27/02/2015
  2923                              <1> 	;;dec	bh
  2924                              <1> 	;;jnz	short WFPSR_OUTER_LP
  2925                              <1> 	;jmp	short WFPSR_TIMEOUT	; fail
  2926                              <1> 
  2927                              <1> 	;;mov	byte [wait_count], 0
  2928                              <1> ;J39:					; WAIT FOR MASTER
  2929                              <1> ;	IN	AL,DX			; GET STATUS
  2930                              <1> ;	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  2931                              <1> ;	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  2932                              <1> ;	JZ	short J42		; STATUS AND DIRECTION OK
  2933                              <1> 	;LOOP	J39			; LOOP TILL TIMEOUT
  2934                              <1> 	;DEC	BH			; DECREMENT HIGH ORDER COUNTER
  2935                              <1> 	;JNZ	short J39		; REPEAT TILL DELAY DONE
  2936                              <1> 	;
  2937                              <1> 	;;cmp	byte [wait_count], 10  ; (10/18.2 seconds)
  2938                              <1> 	;;jb	short J39	
  2939                              <1> 
  2940                              <1> ;WFPSR_TIMEOUT:
  2941 00004B01 800D[60640100]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  2942 00004B08 F9                  <1> 	STC				; SET ERROR RETURN
  2943 00004B09 EB29                <1> 	JMP	SHORT POPRES		; POP REGISTERS AND RETURN
  2944                              <1> 
  2945                              <1> ;-----	READ IN THE STATUS
  2946                              <1> 
  2947                              <1> J42:
  2948 00004B0B EB00                <1> 	JMP	$+2			; I/O DELAY
  2949 00004B0D 6642                <1> 	INC	DX			; POINT AT DATA PORT
  2950 00004B0F EC                  <1> 	IN	AL,DX			; GET THE DATA
  2951                              <1> 	; 16/12/2014
  2952                              <1> 	NEWIODELAY
  2952 00004B10 E6EB                <2>  out 0ebh,al
  2953 00004B12 8807                <1>         MOV     [eDI],AL                ; STORE THE BYTE
  2954 00004B14 47                  <1> 	INC	eDI			; INCREMENT THE POINTER
  2955                              <1> 	; 16/12/2014
  2956                              <1> ;	push	cx
  2957                              <1> ;	mov	cx, 30
  2958                              <1> ;wdw2:
  2959                              <1> ;	NEWIODELAY
  2960                              <1> ;	loop	wdw2
  2961                              <1> ;	pop	cx
  2962                              <1> 
  2963 00004B15 B903000000          <1> 	MOV	eCX,3			; MINIMUM 24 MICROSECONDS FOR NEC
  2964 00004B1A E81DD8FFFF          <1> 	CALL	WAITF			; WAIT 30 TO 45 MICROSECONDS
  2965 00004B1F 664A                <1> 	DEC	DX			; POINT AT STATUS PORT
  2966 00004B21 EC                  <1> 	IN	AL,DX			; GET STATUS
  2967                              <1> 	; 16/12/2014
  2968                              <1> 	NEWIODELAY
  2968 00004B22 E6EB                <2>  out 0ebh,al
  2969                              <1> 	;
  2970 00004B24 A810                <1> 	TEST	AL,00010000B		; TEST FOR NEC STILL BUSY
  2971 00004B26 740C                <1> 	JZ	short POPRES		; RESULTS DONE ?
  2972                              <1> 
  2973 00004B28 FECB                <1> 	DEC	BL			; DECREMENT THE STATUS COUNTER
  2974 00004B2A 75BB                <1>         JNZ     short _R10              ; GO BACK FOR MORE
  2975 00004B2C 800D[60640100]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; TOO MANY STATUS BYTES
  2976 00004B33 F9                  <1> 	STC				; SET ERROR FLAG
  2977                              <1> 
  2978                              <1> ;-----	RESULT OPERATION IS DONE
  2979                              <1> POPRES:
  2980 00004B34 5F                  <1> 	POP	eDI
  2981 00004B35 C3                  <1> 	RETn				; RETURN WITH CARRY SET
  2982                              <1> 
  2983                              <1> ;-------------------------------------------------------------------------------
  2984                              <1> ; READ_DSKCHNG
  2985                              <1> ;	READS THE STATE OF THE DISK CHANGE LINE.
  2986                              <1> ;
  2987                              <1> ; ON ENTRY:	DI = DRIVE #
  2988                              <1> ;
  2989                              <1> ; ON EXIT:	DI = DRIVE #
  2990                              <1> ;		ZF = 0 : DISK CHANGE LINE INACTIVE
  2991                              <1> ;		ZF = 1 : DISK CHANGE LINE ACTIVE
  2992                              <1> ;		AX,CX,DX DESTROYED
  2993                              <1> ;-------------------------------------------------------------------------------
  2994                              <1> READ_DSKCHNG:
  2995 00004B36 E8A2FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON THE MOTOR IF OFF
  2996 00004B3B 66BAF703            <1> 	MOV	DX,03F7H		; ADDRESS DIGITAL INPUT REGISTER
  2997 00004B3F EC                  <1> 	IN	AL,DX			; INPUT DIGITAL INPUT REGISTER
  2998 00004B40 A880                <1> 	TEST	AL,DSK_CHG		; CHECK FOR DISK CHANGE LINE ACTIVE
  2999 00004B42 C3                  <1> 	RETn				; RETURN TO CALLER WITH ZERO FLAG SET
  3000                              <1> 
  3001                              <1> ;-------------------------------------------------------------------------------
  3002                              <1> ; DRIVE_DET
  3003                              <1> ;	DETERMINES WHETHER DRIVE IS 80 OR 40 TRACKS AND
  3004                              <1> ;	UPDATES STATE INFORMATION ACCORDINGLY.
  3005                              <1> ; ON ENTRY:	DI = DRIVE #
  3006                              <1> ;-------------------------------------------------------------------------------
  3007                              <1> DRIVE_DET:
  3008 00004B43 E895FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON MOTOR IF NOT ALREADY ON
  3009 00004B48 E80AFFFFFF          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  3010 00004B4D 7251                <1> 	JC	short DD_BAC		; ASSUME NO DRIVE PRESENT
  3011 00004B4F B530                <1> 	MOV	CH,TRK_SLAP		; SEEK TO TRACK 48
  3012 00004B51 E882FEFFFF          <1> 	CALL	SEEK
  3013 00004B56 7248                <1> 	JC	short DD_BAC		; ERROR NO DRIVE
  3014 00004B58 B50B                <1> 	MOV	CH,QUIET_SEEK+1		; SEEK TO TRACK 10
  3015                              <1> SK_GIN:
  3016 00004B5A FECD                <1> 	DEC	CH			; DECREMENT TO NEXT TRACK
  3017 00004B5C 6651                <1> 	PUSH	CX			; SAVE TRACK
  3018 00004B5E E875FEFFFF          <1> 	CALL	SEEK
  3019 00004B63 723C                <1> 	JC	short POP_BAC		; POP AND RETURN
  3020 00004B65 B8[A14B0000]        <1> 	MOV	eAX, POP_BAC		; LOAD NEC OUTPUT ERROR ADDRESS
  3021 00004B6A 50                  <1> 	PUSH	eAX
  3022 00004B6B B404                <1> 	MOV	AH,SENSE_DRV_ST		; SENSE DRIVE STATUS COMMAND BYTE
  3023 00004B6D E82CFEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  3024 00004B72 6689F8              <1> 	MOV	AX,DI			; AL = DRIVE
  3025 00004B75 88C4                <1> 	MOV	AH,AL			; AH = DRIVE
  3026 00004B77 E822FEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  3027 00004B7C E85AFFFFFF          <1> 	CALL	RESULTS			; GO GET STATUS
  3028 00004B81 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  3029 00004B82 6659                <1> 	POP	CX			; RESTORE TRACK
  3030 00004B84 F605[61640100]10    <1> 	TEST	byte [NEC_STATUS], HOME	; TRACK 0 ?
  3031 00004B8B 74CD                <1> 	JZ	short SK_GIN		; GO TILL TRACK 0
  3032 00004B8D 08ED                <1> 	OR	CH,CH			; IS HOME AT TRACK 0
  3033 00004B8F 7408                <1> 	JZ	short IS_80		; MUST BE 80 TRACK DRIVE
  3034                              <1> 
  3035                              <1> ;	DRIVE IS A 360; SET DRIVE TO DETERMINED;
  3036                              <1> ;	SET MEDIA TO DETERMINED AT RATE 250.
  3037                              <1> 
  3038 00004B91 808F[6D640100]94    <1> 	OR	byte [DSK_STATE+eDI], DRV_DET+MED_DET+RATE_250
  3039 00004B98 C3                  <1> 	RETn				; ALL INFORMATION SET
  3040                              <1> IS_80:
  3041 00004B99 808F[6D640100]01    <1> 	OR	byte [DSK_STATE+eDI], TRK_CAPA ; SETUP 80 TRACK CAPABILITY
  3042                              <1> DD_BAC:
  3043 00004BA0 C3                  <1> 	RETn
  3044                              <1> POP_BAC:
  3045 00004BA1 6659                <1> 	POP	CX			; THROW AWAY
  3046 00004BA3 C3                  <1> 	RETn
  3047                              <1> 
  3048                              <1> fdc_int:  
  3049                              <1> 	  ; 30/07/2015	
  3050                              <1> 	  ; 16/02/2015
  3051                              <1> ;int_0Eh: ; 11/12/2014
  3052                              <1> 
  3053                              <1> ;--- HARDWARE INT 0EH -- ( IRQ LEVEL  6 ) --------------------------------------
  3054                              <1> ; DISK_INT
  3055                              <1> ;	THIS ROUTINE HANDLES THE DISKETTE INTERRUPT.
  3056                              <1> ;
  3057                              <1> ; ON EXIT:	THE INTERRUPT FLAG IS SET IN @SEEK_STATUS.
  3058                              <1> ;-------------------------------------------------------------------------------
  3059                              <1> DISK_INT_1:
  3060                              <1> 
  3061 00004BA4 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER
  3062 00004BA6 1E                  <1> 	push	ds
  3063 00004BA7 66B81000            <1> 	mov	ax, KDATA
  3064 00004BAB 8ED8                <1> 	mov 	ds, ax
  3065 00004BAD 800D[5D640100]80    <1>         OR      byte [SEEK_STATUS], INT_FLAG ; TURN ON INTERRUPT OCCURRED
  3066 00004BB4 B020                <1> 	MOV     AL,EOI                  ; END OF INTERRUPT MARKER
  3067 00004BB6 E620                <1> 	OUT	INTA00,AL		; INTERRUPT CONTROL PORT
  3068 00004BB8 1F                  <1> 	pop	ds
  3069 00004BB9 6658                <1> 	POP	AX			; RECOVER REGISTER
  3070 00004BBB CF                  <1> 	IRETd				; RETURN FROM INTERRUPT
  3071                              <1> 
  3072                              <1> ;-------------------------------------------------------------------------------
  3073                              <1> ; DSKETTE_SETUP
  3074                              <1> ;	THIS ROUTINE DOES A PRELIMINARY CHECK TO SEE WHAT TYPE OF
  3075                              <1> ;	DISKETTE DRIVES ARE ATTACH TO THE SYSTEM.
  3076                              <1> ;-------------------------------------------------------------------------------
  3077                              <1> 
  3078                              <1> ; 29/05/2016 - TRDOS 386 (TRDOS v2.0)
  3079                              <1> 
  3080                              <1> DSKETTE_SETUP:
  3081                              <1> 	;PUSH	AX			; SAVE REGISTERS
  3082                              <1> 	;PUSH	BX
  3083                              <1> 	;PUSH	CX
  3084 00004BBC 52                  <1> 	PUSH	eDX
  3085                              <1> 	;PUSH	DI
  3086                              <1> 	;;PUSH	DS
  3087                              <1> 	; 14/12/2014
  3088                              <1> 	;mov	word [DISK_POINTER], MD_TBL6
  3089                              <1> 	;mov	[DISK_POINTER+2], cs
  3090                              <1> 	;
  3091                              <1> 	;OR	byte [RTC_WAIT_FLAG], 1	; NO RTC WAIT, FORCE USE OF LOOP
  3092 00004BBD 31FF                <1> 	XOR	eDI,eDI			; INITIALIZE DRIVE POINTER
  3093 00004BBF 66C705[6D640100]00- <1> 	MOV	WORD [DSK_STATE],0	; INITIALIZE STATES
  3093 00004BC7 00                  <1>
  3094 00004BC8 8025[68640100]33    <1> 	AND	byte [LASTRATE],~(STRT_MSK+SEND_MSK) ; CLEAR START & SEND
  3095 00004BCF 800D[68640100]C0    <1> 	OR	byte [LASTRATE],SEND_MSK ; INITIALIZE SENT TO IMPOSSIBLE
  3096 00004BD6 C605[5D640100]00    <1> 	MOV	byte [SEEK_STATUS],0	; INDICATE RECALIBRATE NEEDED
  3097 00004BDD C605[5F640100]00    <1> 	MOV	byte [MOTOR_COUNT],0	; INITIALIZE MOTOR COUNT
  3098 00004BE4 C605[5E640100]00    <1> 	MOV	byte [MOTOR_STATUS],0	; INITIALIZE DRIVES TO OFF STATE
  3099 00004BEB C605[60640100]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; NO ERRORS
  3100                              <1> 	;
  3101                              <1> 	; 28/02/2015
  3102                              <1> 	;mov	word [cfd], 100h 
  3103 00004BF2 E82BF2FFFF          <1> 	call	DSK_RESET
  3104 00004BF7 5A                  <1> 	pop	edx
  3105 00004BF8 F8                  <1> 	clc	; 29/05/2016
  3106 00004BF9 C3                  <1> 	retn
  3107                              <1> 
  3108                              <1> ;SUP0:
  3109                              <1> ;	CALL	DRIVE_DET		; DETERMINE DRIVE
  3110                              <1> ;	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  3111                              <1> ;	; 02/01/2015
  3112                              <1> ;	;INC	DI			; POINT TO NEXT DRIVE
  3113                              <1> ;	;CMP	DI,MAX_DRV		; SEE IF DONE
  3114                              <1> ;	;JNZ	short SUP0		; REPEAT FOR EACH ORIVE
  3115                              <1> ;       cmp     byte [fd1_type], 0	
  3116                              <1> ;	jna	short sup1
  3117                              <1> ;	or	di, di
  3118                              <1> ;	jnz	short sup1
  3119                              <1> ;	inc	di
  3120                              <1> ;       jmp     short SUP0
  3121                              <1> ;sup1:
  3122                              <1> ;	MOV	byte [SEEK_STATUS],0	; FORCE RECALIBRATE
  3123                              <1> ;	;AND	byte [RTC_WAIT_FLAG],0FEH ; ALLOW FOR RTC WAIT
  3124                              <1> ;	CALL	SETUP_END		; VARIOUS CLEANUPS
  3125                              <1> ;	;;POP	DS			; RESTORE CALLERS REGISTERS
  3126                              <1> ;	;POP	DI
  3127                              <1> ;	POP	eDX
  3128                              <1> ;	;POP	CX
  3129                              <1> ;	;POP	BX
  3130                              <1> ;	;POP	AX
  3131                              <1> ;	RETn
  3132                              <1> 
  3133                              <1> ;//////////////////////////////////////////////////////
  3134                              <1> ;; END OF DISKETTE I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3135                              <1> ;
  3136                              <1> 
  3137                              <1> int13h: ; 21/02/2015
  3138 00004BFA F8                  <1> 	clc ; 20/07/2020
  3139 00004BFB 9C                  <1> 	pushfd
  3140 00004BFC 0E                  <1> 	push 	cs
  3141 00004BFD E849010000          <1> 	call 	DISK_IO
  3142 00004C02 C3                  <1> 	retn
  3143                              <1> 
  3144                              <1> ;;;;;; DISK I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 21/02/2015 ;;;
  3145                              <1> ;/////////////////////////////////////////////////////////////////////
  3146                              <1> 
  3147                              <1> ; DISK I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  3148                              <1> ; 18/02/2016
  3149                              <1> ; 17/02/2016
  3150                              <1> ; 23/02/2015
  3151                              <1> ; 21/02/2015 (unix386.s)
  3152                              <1> ; 22/12/2014 - 14/02/2015 (dsectrm2.s)
  3153                              <1> ;
  3154                              <1> ; Original Source Code:
  3155                              <1> ; DISK ----- 09/25/85 FIXED DISK BIOS
  3156                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  3157                              <1> ;
  3158                              <1> ; Modifications: by reference of AWARD BIOS 1999 (D1A0622) 
  3159                              <1> ;		 Source Code - ATORGS.ASM, AHDSK.ASM
  3160                              <1> ;
  3161                              <1> 
  3162                              <1> 
  3163                              <1> ;The wait for controller to be not busy is 10 seconds.
  3164                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  3165                              <1> ;;WAIT_HDU_CTLR_BUSY_LO	equ	1615h		
  3166                              <1> ;;WAIT_HDU_CTLR_BUSY_HI	equ	  05h
  3167                              <1> WAIT_HDU_CTRL_BUSY_LH	equ	51615h	 ;21/02/2015		
  3168                              <1> 
  3169                              <1> ;The wait for controller to issue completion interrupt is 10 seconds.
  3170                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  3171                              <1> ;;WAIT_HDU_INT_LO	equ	1615h
  3172                              <1> ;;WAIT_HDU_INT_HI	equ	  05h
  3173                              <1> WAIT_HDU_INT_LH		equ	51615h	; 21/02/2015
  3174                              <1> 
  3175                              <1> ;The wait for Data request on read and write longs is
  3176                              <1> ;2000 us. (?)
  3177                              <1> ;;WAIT_HDU_DRQ_LO	equ	1000	; 03E8h
  3178                              <1> ;;WAIT_HDU_DRQ_HI	equ	0
  3179                              <1> WAIT_HDU_DRQ_LH		equ	1000	; 21/02/2015
  3180                              <1> 
  3181                              <1> ; Port 61h (PORT_B)
  3182                              <1> SYS1		equ	61h	; PORT_B  (diskette.inc)
  3183                              <1> 
  3184                              <1> ; 23/12/2014
  3185                              <1> %define CMD_BLOCK       eBP-8  ; 21/02/2015
  3186                              <1> 
  3187                              <1> ; 30/08/2020 - TRDOS 386 v2
  3188                              <1> 
  3189                              <1> ;--- INT 13H -------------------------------------------------------------------
  3190                              <1> ;									       :
  3191                              <1> ; FIXED DISK I/O INTERFACE						       :
  3192                              <1> ;									       :
  3193                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO 5 1/4" FIXED DISKS THROUGH           :
  3194                              <1> ;	THE IBM FIXED DISK CONTROLLER.					       :
  3195                              <1> ;									       :
  3196                              <1> ;	THE  BIOS  ROUTINES  ARE  MEANT  TO  BE  ACCESSED  THROUGH	       :
  3197                              <1> ;	SOFTWARE  INTERRUPTS  ONLY.    ANY  ADDRESSES  PRESENT	IN	       :
  3198                              <1> ;	THESE  LISTINGS  ARE  INCLUDED	 ONLY	FOR  COMPLETENESS,	       :
  3199                              <1> ;	NOT  FOR  REFERENCE.  APPLICATIONS   WHICH  REFERENCE  ANY	       :
  3200                              <1> ;	ABSOLUTE  ADDRESSES  WITHIN  THE  CODE	SEGMENTS  OF  BIOS	       :
  3201                              <1> ;	VIOLATE  THE  STRUCTURE  AND  DESIGN  OF  BIOS. 		       :
  3202                              <1> ;									       :
  3203                              <1> ;------------------------------------------------------------------------------:
  3204                              <1> ;									       :
  3205                              <1> ; INPUT  (AH)= HEX COMMAND VALUE					       :
  3206                              <1> ;									       :
  3207                              <1> ;	(AH)= 00H  RESET DISK (DL = 80H,81H) / DISKETTE 		       :
  3208                              <1> ;	(AH)= 01H  READ THE STATUS OF THE LAST DISK OPERATION INTO (AL)        :
  3209                              <1> ;		    NOTE: DL < 80H - DISKETTE				       :
  3210                              <1> ;			  DL > 80H - DISK				       :
  3211                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY 		       :
  3212                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY		       :
  3213                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS				       :
  3214                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK				       :
  3215                              <1> ;	(AH)= 06H  UNUSED						       :
  3216                              <1> ;	(AH)= 07H  UNUSED						       :
  3217                              <1> ;	(AH)= 08H  RETURN THE CURRENT DRIVE PARAMETERS			       :
  3218                              <1> ;	(AH)= 09H  INITIALIZE DRIVE PAIR CHARACTERISTICS		       :
  3219                              <1> ;		    INTERRUPT 41 POINTS TO DATA BLOCK FOR DRIVE 0	       :
  3220                              <1> ;		    INTERRUPT 46 POINTS TO DATA BLOCK FOR DRIVE 1	       :
  3221                              <1> ;	(AH)= 0AH  READ LONG						       :
  3222                              <1> ;	(AH)= 0BH  WRITE LONG  (READ & WRITE LONG ENCOMPASS 512 + 4 BYTES ECC) :
  3223                              <1> ;	(AH)= 0CH  SEEK 						       :
  3224                              <1> ;	(AH)= 0DH  ALTERNATE DISK RESET (SEE DL)			       :
  3225                              <1> ;	(AH)= 0EH  UNUSED						       :
  3226                              <1> ;	(AH)= 0FH  UNUSED						       :
  3227                              <1> ;	(AH)= 10H  TEST DRIVE READY					       :
  3228                              <1> ;	(AH)= 11H  RECALIBRATE						       :
  3229                              <1> ;	(AH)= 12H  UNUSED						       :
  3230                              <1> ;	(AH)= 13H  UNUSED						       :
  3231                              <1> ;	(AH)= 14H  CONTROLLER INTERNAL DIAGNOSTIC			       :
  3232                              <1> ;	(AH)= 15H  READ DASD TYPE					       :
  3233                              <1> ;									       :
  3234                              <1> ;-------------------------------------------------------------------------------
  3235                              <1> ;									       :
  3236                              <1> ;	REGISTERS USED FOR FIXED DISK OPERATIONS			       :
  3237                              <1> ;									       :
  3238                              <1> ;		(DL)	-  DRIVE NUMBER     (80H-81H FOR DISK. VALUE CHECKED)  :
  3239                              <1> ;		(DH)	-  HEAD NUMBER	    (0-15 ALLOWED, NOT VALUE CHECKED)  :
  3240                              <1> ;		(CH)	-  CYLINDER NUMBER  (0-1023, NOT VALUE CHECKED)(SEE CL):
  3241                              <1> ;		(CL)	-  SECTOR NUMBER    (1-17, NOT VALUE CHECKED)	       :
  3242                              <1> ;									       :
  3243                              <1> ;			   NOTE: HIGH 2 BITS OF CYLINDER NUMBER ARE PLACED     :
  3244                              <1> ;				 IN THE HIGH 2 BITS OF THE CL REGISTER	       :
  3245                              <1> ;				 (10 BITS TOTAL)			       :
  3246                              <1> ;									       :
  3247                              <1> ;		(AL)	-  NUMBER OF SECTORS (MAXIMUM POSSIBLE RANGE 1-80H,    :
  3248                              <1> ;					      FOR READ/WRITE LONG 1-79H)       :
  3249                              <1> ;									       :
  3250                              <1> ;		(ES:BX) -  ADDRESS OF BUFFER FOR READS AND WRITES,	       :
  3251                              <1> ;			   (NOT REQUIRED FOR VERIFY)			       :
  3252                              <1> ;									       :
  3253                              <1> ;		FORMAT (AH=5) ES:BX POINTS TO A 512 BYTE BUFFER. THE FIRST     :
  3254                              <1> ;			   2*(SECTORS/TRACK) BYTES CONTAIN F,N FOR EACH SECTOR.:
  3255                              <1> ;			   F = 00H FOR A GOOD SECTOR			       :
  3256                              <1> ;			       80H FOR A BAD SECTOR			       :
  3257                              <1> ;			   N = SECTOR NUMBER				       :
  3258                              <1> ;			   FOR AN INTERLEAVE OF 2 AND 17 SECTORS/TRACK	       :
  3259                              <1> ;			   THE TABLE SHOULD BE: 			       :
  3260                              <1> ;									       :
  3261                              <1> ;		   DB	   00H,01H,00H,0AH,00H,02H,00H,0BH,00H,03H,00H,0CH     :
  3262                              <1> ;		   DB	   00H,04H,00H,0DH,00H,05H,00H,0EH,00H,06H,00H,0FH     :
  3263                              <1> ;		   DB	   00H,07H,00H,10H,00H,08H,00H,11H,00H,09H	       :
  3264                              <1> ;									       :
  3265                              <1> ;-------------------------------------------------------------------------------
  3266                              <1> 
  3267                              <1> ;-------------------------------------------------------------------------------
  3268                              <1> ; OUTPUT								       :
  3269                              <1> ;	AH = STATUS OF CURRENT OPERATION				       :
  3270                              <1> ;	     STATUS BITS ARE DEFINED IN THE EQUATES BELOW		       :
  3271                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN)			       :
  3272                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)			       :
  3273                              <1> ;									       :
  3274                              <1> ;	NOTE:	ERROR 11H  INDICATES THAT THE DATA READ HAD A RECOVERABLE      :
  3275                              <1> ;		ERROR WHICH WAS CORRECTED BY THE ECC ALGORITHM.  THE DATA      :
  3276                              <1> ;		IS PROBABLY GOOD,   HOWEVER THE BIOS ROUTINE INDICATES AN      :
  3277                              <1> ;		ERROR TO ALLOW THE CONTROLLING PROGRAM A CHANCE TO DECIDE      :
  3278                              <1> ;		FOR ITSELF.  THE  ERROR  MAY  NOT  RECUR  IF  THE DATA IS      :
  3279                              <1> ;		REWRITTEN.						       :
  3280                              <1> ;									       :
  3281                              <1> ;	IF DRIVE PARAMETERS WERE REQUESTED (DL >= 80H), 		       :
  3282                              <1> ;	   INPUT:							       :
  3283                              <1> ;	     (DL) = DRIVE NUMBER					       :	
  3284                              <1> ;	     ; 27/05/2016 - TRDOS 386 (TRDOS v2.0)						       :	 	
  3285                              <1> ;	     EBX = Buffer address for fixed disk parameters table (32 bytes)   :
  3286                              <1> ;	   OUTPUT:							       :
  3287                              <1> ;	     (DL) = NUMBER OF CONSECUTIVE ACKNOWLEDGING DRIVES ATTACHED (1-2)  :
  3288                              <1> ;		    (CONTROLLER CARD ZERO TALLY ONLY)			       :
  3289                              <1> ;	     (DH) = MAXIMUM USEABLE VALUE FOR HEAD NUMBER		       :
  3290                              <1> ;	     (CH) = MAXIMUM USEABLE VALUE FOR CYLINDER NUMBER		       :
  3291                              <1> ;	     (CL) = MAXIMUM USEABLE VALUE FOR SECTOR NUMBER		       :
  3292                              <1> ;		    AND CYLINDER NUMBER HIGH BITS			       :
  3293                              <1> ;									       :
  3294                              <1> ;	IF READ DASD TYPE WAS REQUESTED,				       :
  3295                              <1> ;									       :
  3296                              <1> ;	AH = 0 - NOT PRESENT						       :
  3297                              <1> ;	     1 - DISKETTE - NO CHANGE LINE AVAILABLE			       :
  3298                              <1> ;	     2 - DISKETTE - CHANGE LINE AVAILABLE			       :
  3299                              <1> ;	     3 - FIXED DISK						       :
  3300                              <1> ;									       :
  3301                              <1> ;	CX,DX = NUMBER OF 512 BYTE BLOCKS WHEN AH = 3			       :
  3302                              <1> ;									       :
  3303                              <1> ;	REGISTERS WILL BE PRESERVED EXCEPT WHEN THEY ARE USED TO RETURN        :
  3304                              <1> ;	INFORMATION.							       :
  3305                              <1> ;									       :
  3306                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISK CODE, THE APPROPRIATE        :
  3307                              <1> ;		ACTION IS TO RESET THE DISK, THEN RETRY THE OPERATION.	       :
  3308                              <1> ;									       :
  3309                              <1> ;-------------------------------------------------------------------------------
  3310                              <1> 
  3311                              <1> SENSE_FAIL	EQU	0FFH		; NOT IMPLEMENTED
  3312                              <1> NO_ERR		EQU	0E0H		; STATUS ERROR/ERROR REGISTER=0
  3313                              <1> WRITE_FAULT	EQU	0CCH		; WRITE FAULT ON SELECTED DRIVE
  3314                              <1> UNDEF_ERR	EQU	0BBH		; UNDEFINED ERROR OCCURRED
  3315                              <1> NOT_RDY 	EQU	0AAH		; DRIVE NOT READY
  3316                              <1> TIME_OUT	EQU	80H		; ATTACHMENT FAILED TO RESPOND
  3317                              <1> BAD_SEEK	EQU	40H		; SEEK OPERATION FAILED
  3318                              <1> BAD_CNTLR	EQU	20H		; CONTROLLER HAS FAILED
  3319                              <1> DATA_CORRECTED	EQU	11H		; ECC CORRECTED DATA ERROR
  3320                              <1> BAD_ECC 	EQU	10H		; BAD ECC ON DISK READ
  3321                              <1> BAD_TRACK	EQU	0BH		; NOT IMPLEMENTED
  3322                              <1> BAD_SECTOR	EQU	0AH		; BAD SECTOR FLAG DETECTED
  3323                              <1> ;DMA_BOUNDARY	EQU	09H		; DATA EXTENDS TOO FAR
  3324                              <1> INIT_FAIL	EQU	07H		; DRIVE PARAMETER ACTIVITY FAILED
  3325                              <1> BAD_RESET	EQU	05H		; RESET FAILED
  3326                              <1> ;RECORD_NOT_FND	EQU	04H		; REQUESTED SECTOR NOT FOUND
  3327                              <1> ;BAD_ADDR_MARK	EQU	02H		; ADDRESS MARK NOT FOUND
  3328                              <1> ;BAD_CMD 	EQU	01H		; BAD COMMAND PASSED TO DISK I/O
  3329                              <1> 
  3330                              <1> ;--------------------------------------------------------
  3331                              <1> ;							:
  3332                              <1> ; FIXED DISK PARAMETER TABLE				:
  3333                              <1> ;  -  THE TABLE IS COMPOSED OF A BLOCK DEFINED AS:	:
  3334                              <1> ;							:
  3335                              <1> ;  +0	(1 WORD) - MAXIMUM NUMBER OF CYLINDERS		:
  3336                              <1> ;  +2	(1 BYTE) - MAXIMUM NUMBER OF HEADS		:
  3337                              <1> ;  +3	(1 WORD) - NOT USED/SEE PC-XT			:
  3338                              <1> ;  +5	(1 WORD) - STARTING WRITE PRECOMPENSATION CYL	:
  3339                              <1> ;  +7	(1 BYTE) - MAXIMUM ECC DATA BURST LENGTH	:
  3340                              <1> ;  +8	(1 BYTE) - CONTROL BYTE 			:
  3341                              <1> ;		   BIT	  7 DISABLE RETRIES -OR-	:
  3342                              <1> ;		   BIT	  6 DISABLE RETRIES		:
  3343                              <1> ;		   BIT	  3 MORE THAN 8 HEADS		:
  3344                              <1> ;  +9	(3 BYTES)- NOT USED/SEE PC-XT			:
  3345                              <1> ; +12	(1 WORD) - LANDING ZONE 			:
  3346                              <1> ; +14	(1 BYTE) - NUMBER OF SECTORS/TRACK		:
  3347                              <1> ; +15	(1 BYTE) - RESERVED FOR FUTURE USE		:
  3348                              <1> ;							:
  3349                              <1> ;	 - TO DYNAMICALLY DEFINE A SET OF PARAMETERS	:
  3350                              <1> ;	   BUILD A TABLE FOR UP TO 15 TYPES AND PLACE	:
  3351                              <1> ;	   THE CORRESPONDING VECTOR INTO INTERRUPT 41	:
  3352                              <1> ;	   FOR DRIVE 0 AND INTERRUPT 46 FOR DRIVE 1.	:
  3353                              <1> ;							:
  3354                              <1> ;--------------------------------------------------------
  3355                              <1> 
  3356                              <1> ;--------------------------------------------------------
  3357                              <1> ;							:
  3358                              <1> ; HARDWARE SPECIFIC VALUES				:
  3359                              <1> ;							:
  3360                              <1> ;  -  CONTROLLER I/O PORT				:
  3361                              <1> ;							:
  3362                              <1> ;     > WHEN READ FROM: 				:
  3363                              <1> ;	HF_PORT+0 - READ DATA (FROM CONTROLLER TO CPU)	:
  3364                              <1> ;	HF_PORT+1 - GET ERROR REGISTER			:
  3365                              <1> ;	HF_PORT+2 - GET SECTOR COUNT			:
  3366                              <1> ;	HF_PORT+3 - GET SECTOR NUMBER			:
  3367                              <1> ;	HF_PORT+4 - GET CYLINDER LOW			:
  3368                              <1> ;	HF_PORT+5 - GET CYLINDER HIGH (2 BITS)		:
  3369                              <1> ;	HF_PORT+6 - GET SIZE/DRIVE/HEAD 		:
  3370                              <1> ;	HF_PORT+7 - GET STATUS REGISTER 		:
  3371                              <1> ;							:
  3372                              <1> ;     > WHEN WRITTEN TO:				:
  3373                              <1> ;	HF_PORT+0 - WRITE DATA (FROM CPU TO CONTROLLER) :
  3374                              <1> ;	HF_PORT+1 - SET PRECOMPENSATION CYLINDER	:
  3375                              <1> ;	HF_PORT+2 - SET SECTOR COUNT			:
  3376                              <1> ;	HF_PORT+3 - SET SECTOR NUMBER			:
  3377                              <1> ;	HF_PORT+4 - SET CYLINDER LOW			:
  3378                              <1> ;	HF_PORT+5 - SET CYLINDER HIGH (2 BITS)		:
  3379                              <1> ;	HF_PORT+6 - SET SIZE/DRIVE/HEAD 		:
  3380                              <1> ;	HF_PORT+7 - SET COMMAND REGISTER		:
  3381                              <1> ;							:
  3382                              <1> ;--------------------------------------------------------
  3383                              <1> 
  3384                              <1> ;HF_PORT 	EQU	01F0H	; DISK PORT
  3385                              <1> ;HF1_PORT	equ	0170h	
  3386                              <1> ;HF_REG_PORT	EQU	03F6H
  3387                              <1> ;HF1_REG_PORT	equ	0376h
  3388                              <1> 
  3389                              <1> HDC1_BASEPORT	equ	1F0h
  3390                              <1> HDC2_BASEPORT	equ	170h		
  3391                              <1> 
  3392 00004C03 90                  <1> align 2
  3393                              <1> 
  3394                              <1> ;-----		STATUS REGISTER
  3395                              <1> 
  3396                              <1> ST_ERROR	EQU	00000001B	;
  3397                              <1> ST_INDEX	EQU	00000010B	;
  3398                              <1> ST_CORRCTD	EQU	00000100B	; ECC CORRECTION SUCCESSFUL
  3399                              <1> ST_DRQ		EQU	00001000B	;
  3400                              <1> ST_SEEK_COMPL	EQU	00010000B	; SEEK COMPLETE
  3401                              <1> ST_WRT_FLT	EQU	00100000B	; WRITE FAULT
  3402                              <1> ST_READY	EQU	01000000B	;
  3403                              <1> ST_BUSY 	EQU	10000000B	;
  3404                              <1> 
  3405                              <1> ;-----		ERROR REGISTER
  3406                              <1> 
  3407                              <1> ERR_DAM 	EQU	00000001B	; DATA ADDRESS MARK NOT FOUND
  3408                              <1> ERR_TRK_0	EQU	00000010B	; TRACK 0 NOT FOUND ON RECAL
  3409                              <1> ERR_ABORT	EQU	00000100B	; ABORTED COMMAND
  3410                              <1> ;		EQU	00001000B	; NOT USED
  3411                              <1> ERR_ID		EQU	00010000B	; ID NOT FOUND
  3412                              <1> ;		EQU	00100000B	; NOT USED
  3413                              <1> ERR_DATA_ECC	EQU	01000000B
  3414                              <1> ERR_BAD_BLOCK	EQU	10000000B
  3415                              <1> 
  3416                              <1> 
  3417                              <1> RECAL_CMD	EQU	00010000B	; DRIVE RECAL	(10H)
  3418                              <1> READ_CMD	EQU	00100000B	;	READ	(20H)
  3419                              <1> WRITE_CMD	EQU	00110000B	;	WRITE	(30H)
  3420                              <1> VERIFY_CMD	EQU	01000000B	;	VERIFY	(40H)
  3421                              <1> FMTTRK_CMD	EQU	01010000B	; FORMAT TRACK	(50H)
  3422                              <1> INIT_CMD	EQU	01100000B	;   INITIALIZE	(60H)
  3423                              <1> SEEK_CMD	EQU	01110000B	;	SEEK	(70H)
  3424                              <1> DIAG_CMD	EQU	10010000B	; DIAGNOSTIC	(90H)
  3425                              <1> SET_PARM_CMD	EQU	10010001B	; DRIVE PARMS	(91H)
  3426                              <1> NO_RETRIES	EQU	00000001B	; CHD MODIFIER	(01H)
  3427                              <1> ECC_MODE	EQU	00000010B	; CMD MODIFIER	(02H)
  3428                              <1> BUFFER_MODE	EQU	00001000B	; CMD MODIFIER	(08H)
  3429                              <1> 
  3430                              <1> ;MAX_FILE	EQU	2
  3431                              <1> ;S_MAX_FILE	EQU	2
  3432                              <1> MAX_FILE	equ	4		; 22/12/2014
  3433                              <1> S_MAX_FILE	equ	4		; 22/12/2014
  3434                              <1> 
  3435                              <1> DELAY_1 	EQU	25H		; DELAY FOR OPERATION COMPLETE
  3436                              <1> DELAY_2 	EQU	0600H		; DELAY FOR READY
  3437                              <1> DELAY_3 	EQU	0100H		; DELAY FOR DATA REQUEST
  3438                              <1> 
  3439                              <1> HF_FAIL 	EQU	08H		; CMOS FLAG IN BYTE 0EH
  3440                              <1> 
  3441                              <1> ;-----		COMMAND BLOCK REFERENCE
  3442                              <1> 
  3443                              <1> ;CMD_BLOCK      EQU     BP-8            ; @CMD_BLOCK REFERENCES BLOCK HEAD IN SS
  3444                              <1> 					;  (BP) POINTS TO COMMAND BLOCK TAIL
  3445                              <1> 					;	AS DEFINED BY THE "ENTER" PARMS
  3446                              <1> ; 19/12/2014
  3447                              <1> ORG_VECTOR	equ	4*13h		; INT 13h vector
  3448                              <1> DISK_VECTOR	equ	4*40h		; INT 40h vector (for floppy disks)
  3449                              <1> ;HDISK_INT	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  3450                              <1> ;HDISK_INT1	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  3451                              <1> ;HDISK_INT2	equ	4*77h		; Secondary HDC - Hardware interrupt (IRQ15)
  3452                              <1> ;HF_TBL_VEC	equ	4*41h		; Pointer to 1st fixed disk parameter table
  3453                              <1> ;HF1_TBL_VEC	equ	4*46h		; Pointer to 2nd fixed disk parameter table
  3454                              <1> 
  3455                              <1> align 2
  3456                              <1> 
  3457                              <1> ;----------------------------------------------------------------
  3458                              <1> ; FIXED DISK I/O SETUP						:
  3459                              <1> ;								:
  3460                              <1> ;  -  ESTABLISH TRANSFER VECTORS FOR THE FIXED DISK		:
  3461                              <1> ;  -  PERFORM POWER ON DIAGNOSTICS				:
  3462                              <1> ;     SHOULD AN ERROR OCCUR A "1701" MESSAGE IS DISPLAYED       :
  3463                              <1> ;								:
  3464                              <1> ;----------------------------------------------------------------
  3465                              <1> 
  3466                              <1> ; 29/05/2016 - TRDOS 386 (TRDOS v2.0)
  3467                              <1> 
  3468                              <1> DISK_SETUP:
  3469                              <1> 	;CLI
  3470                              <1> 	;;MOV	AX,ABS0 			; GET ABSOLUTE SEGMENT
  3471                              <1> 	;xor	ax,ax
  3472                              <1> 	;MOV	DS,AX				; SET SEGMENT REGISTER
  3473                              <1> 	;MOV	AX, [ORG_VECTOR] 		; GET DISKETTE VECTOR
  3474                              <1> 	;MOV	[DISK_VECTOR],AX		;  INTO INT 40H
  3475                              <1> 	;MOV	AX, [ORG_VECTOR+2]
  3476                              <1> 	;MOV	[DISK_VECTOR+2],AX
  3477                              <1> 	;MOV	word [ORG_VECTOR],DISK_IO	; FIXED DISK HANDLER
  3478                              <1> 	;MOV	[ORG_VECTOR+2],CS
  3479                              <1> 	; 1st controller (primary master, slave)   - IRQ 14
  3480                              <1> 	;;MOV	word [HDISK_INT],HD_INT		; FIXED DISK INTERRUPT
  3481                              <1> 	;mov	word [HDISK_INT1],HD_INT	;
  3482                              <1> 	;;MOV	[HDISK_INT+2],CS
  3483                              <1> 	;mov	[HDISK_INT1+2],CS
  3484                              <1> 	; 2nd controller (secondary master, slave) - IRQ 15
  3485                              <1> 	;mov	word [HDISK_INT2],HD1_INT	;
  3486                              <1> 	;mov	[HDISK_INT2+2],CS
  3487                              <1> 	;
  3488                              <1> 	;;MOV	word [HF_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80
  3489                              <1> 	;;MOV	word [HF_TBL_VEC+2],DPT_SEGM
  3490                              <1> 	;;MOV	word [HF1_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81
  3491                              <1> 	;;MOV	word [HF1_TBL_VEC+2],DPT_SEGM
  3492                              <1> 	;push	cs
  3493                              <1> 	;pop	ds
  3494                              <1> 	;mov	word [HDPM_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80h
  3495                              <1> 	;mov	word [HDPM_TBL_VEC+2],DPT_SEGM
  3496 00004C04 C705[78640100]0000- <1> 	mov 	dword [HDPM_TBL_VEC], (DPT_SEGM*16)+HD0_DPT
  3496 00004C0C 0900                <1>
  3497                              <1> 	;mov	word [HDPS_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81h
  3498                              <1> 	;mov	word [HDPS_TBL_VEC+2],DPT_SEGM
  3499 00004C0E C705[7C640100]2000- <1> 	mov 	dword [HDPS_TBL_VEC], (DPT_SEGM*16)+HD1_DPT
  3499 00004C16 0900                <1>
  3500                              <1> 	;mov	word [HDSM_TBL_VEC],HD2_DPT	; PARM TABLE DRIVE 82h
  3501                              <1> 	;mov	word [HDSM_TBL_VEC+2],DPT_SEGM
  3502 00004C18 C705[80640100]4000- <1> 	mov 	dword [HDSM_TBL_VEC], (DPT_SEGM*16)+HD2_DPT
  3502 00004C20 0900                <1>
  3503                              <1> 	;mov	word [HDSS_TBL_VEC],HD3_DPT	; PARM TABLE DRIVE 83h
  3504                              <1> 	;mov	word [HDSS_TBL_VEC+2],DPT_SEGM
  3505 00004C22 C705[84640100]6000- <1> 	mov 	dword [HDSS_TBL_VEC], (DPT_SEGM*16)+HD3_DPT
  3505 00004C2A 0900                <1>
  3506                              <1> 	;
  3507                              <1> 	;;IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  3508                              <1> 	;;;AND	AL,0BFH
  3509                              <1> 	;;and	al, 3Fh			; enable IRQ 14 and IRQ 15
  3510                              <1> 	;;;JMP	$+2
  3511                              <1> 	;;IODELAY
  3512                              <1> 	;;OUT	INTB01,AL
  3513                              <1> 	;;IODELAY
  3514                              <1> 	;;IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  3515                              <1> 	;;AND	AL,0FBH 		;  SECOND CHIP
  3516                              <1> 	;;;JMP	$+2
  3517                              <1> 	;;IODELAY
  3518                              <1> 	;;OUT	INTA01,AL
  3519                              <1> 	;
  3520                              <1> 	;STI
  3521                              <1> 	;;PUSH	DS			; MOVE ABS0 POINTER TO
  3522                              <1> 	;;POP	ES			; EXTRA SEGMENT POINTER
  3523                              <1> 	;;;CALL	DDS			; ESTABLISH DATA SEGMENT
  3524                              <1> 	;;MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  3525                              <1> 	;;MOV	byte [HF_NUM],0		; ZERO NUMBER OF FIXED DISKS
  3526                              <1> 	;;MOV	byte [CONTROL_BYTE],0
  3527                              <1> 	;;MOV	byte [PORT_OFF],0	; ZERO CARD OFFSET
  3528                              <1> 	; 20/12/2014 - private code by Erdogan Tan
  3529                              <1> 		      ; (out of original PC-AT, PC-XT BIOS code)
  3530                              <1> 	;mov	si, hd0_type
  3531 00004C2C BE[D0670000]        <1> 	mov	esi, hd0_type
  3532                              <1> 	;mov	cx, 4
  3533 00004C31 B904000000          <1> 	mov	ecx, 4
  3534                              <1> hde_l:
  3535 00004C36 AC                  <1> 	lodsb
  3536 00004C37 3C80                <1> 	cmp	al, 80h			; 8?h = existing
  3537 00004C39 7206                <1> 	jb	short _L4
  3538 00004C3B FE05[74640100]      <1> 	inc	byte [HF_NUM]		; + 1 hard (fixed) disk drives
  3539                              <1> _L4: ; 26/02/2015
  3540 00004C41 E2F3                <1> 	loop	hde_l	
  3541                              <1> ;_L4:					; 0 <= [HF_NUM] =< 4
  3542                              <1> ;L4:
  3543                              <1> 	; 
  3544                              <1> 	;; 31/12/2014 - cancel controller diagnostics here
  3545                              <1> 	;;;mov 	cx, 3  ; 26/12/2014 (Award BIOS 1999)
  3546                              <1> 	;;mov 	cl, 3
  3547                              <1> 	;;
  3548                              <1> 	;;MOV	DL,80H			; CHECK THE CONTROLLER
  3549                              <1> ;;hdc_dl:
  3550                              <1> 	;;MOV	AH,14H			; USE CONTROLLER DIAGNOSTIC COMMAND
  3551                              <1> 	;;INT	13H			; CALL BIOS WITH DIAGNOSTIC COMMAND
  3552                              <1> 	;;;JC	short CTL_ERRX		; DISPLAY ERROR MESSAGE IF BAD RETURN
  3553                              <1> 	;;;jc	short POD_DONE ;22/12/2014
  3554                              <1> 	;;jnc	short hdc_reset0
  3555                              <1> 	;;loop	hdc_dl
  3556                              <1> 	;;; 27/12/2014
  3557                              <1> 	;;stc
  3558                              <1> 	;;retn
  3559                              <1> 	;
  3560                              <1> ;;hdc_reset0:
  3561                              <1> 	; 18/01/2015
  3562 00004C43 8A0D[74640100]      <1> 	mov	cl, [HF_NUM]
  3563 00004C49 20C9                <1> 	and	cl, cl
  3564 00004C4B 740E                <1> 	jz	short POD_DONE
  3565                              <1> 	;
  3566 00004C4D B27F                <1> 	mov	dl, 7Fh
  3567                              <1> hdc_reset1:
  3568 00004C4F FEC2                <1> 	inc	dl
  3569                              <1> 	;; 31/12/2015
  3570                              <1> 	;;push	dx
  3571                              <1> 	;;push	cx
  3572                              <1> 	;;push	ds
  3573                              <1> 	;;sub	ax, ax
  3574                              <1> 	;;mov	ds, ax
  3575                              <1> 	;;MOV	AX, [TIMER_LOW]		; GET START TIMER COUNTS
  3576                              <1> 	;;pop	ds
  3577                              <1> 	;;MOV	BX,AX
  3578                              <1> 	;;ADD	AX,6*182		; 60 SECONDS* 18.2
  3579                              <1> 	;;MOV	CX,AX
  3580                              <1> 	;;mov	word [wait_count], 0	; 22/12/2014 (reset wait counter)
  3581                              <1> 	;;
  3582                              <1> 	;; 31/12/2014 - cancel HD_RESET_1
  3583                              <1> 	;;CALL	HD_RESET_1		; SET UP DRIVE 0, (1,2,3)
  3584                              <1> 	;;pop	cx
  3585                              <1> 	;;pop	dx
  3586                              <1> 	;;
  3587                              <1> 	; 18/01/2015
  3588 00004C51 B40D                <1> 	mov	ah, 0Dh ; ALTERNATE RESET
  3589                              <1> 	;int	13h
  3590 00004C53 E8A2FFFFFF          <1> 	call	int13h
  3591 00004C58 E2F5                <1> 	loop	hdc_reset1
  3592 00004C5A F8                  <1> 	clc 	; 29/05/2016
  3593                              <1> POD_DONE:
  3594 00004C5B C3                  <1> 	RETn
  3595                              <1> 
  3596                              <1> ;;-----	POD_ERROR
  3597                              <1> 
  3598                              <1> ;;CTL_ERRX:
  3599                              <1> ;	;MOV	SI,OFFSET F1782 	; CONTROLLER ERROR
  3600                              <1> ;	;CALL	SET_FAIL		; DO NOT IPL FROM DISK
  3601                              <1> ;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  3602                              <1> ;	;JMP	short POD_DONE
  3603                              <1> 
  3604                              <1> ;;HD_RESET_1:
  3605                              <1> ;;	;PUSH	BX			; SAVE TIMER LIMITS
  3606                              <1> ;;	;PUSH	CX
  3607                              <1> ;;RES_1: MOV	AH,09H			; SET DRIVE PARAMETERS
  3608                              <1> ;;	INT	13H
  3609                              <1> ;;	JC	short RES_2
  3610                              <1> ;;	MOV	AH,11H			; RECALIBRATE DRIVE
  3611                              <1> ;;	INT	13H
  3612                              <1> ;;	JNC	short RES_CK		; DRIVE OK
  3613                              <1> ;;RES_2: ;CALL	POD_TCHK		; CHECK TIME OUT
  3614                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  3615                              <1> ;;					; (30 seconds)		
  3616                              <1> ;;	;cmc
  3617                              <1> ;;	;JNC	short RES_1
  3618                              <1> ;;	jb	short RES_1
  3619                              <1> ;;;RES_FL: ;MOV	SI,OFFSET F1781 	; INDICATE DISK 1 FAILURE;
  3620                              <1> ;;	;TEST	DL,1
  3621                              <1> ;;	;JNZ	RES_E1
  3622                              <1> ;;	;MOV	SI,OFFSET F1780 	; INDICATE DISK 0 FAILURE
  3623                              <1> ;;	;CALL	SET_FAIL		; DO NOT TRY TO IPL DISK 0
  3624                              <1> ;;	;JMP	SHORT RES_E1
  3625                              <1> ;;RES_ER: ; 22/12/2014
  3626                              <1> ;;RES_OK:
  3627                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  3628                              <1> ;;	;POP	BX
  3629                              <1> ;;	RETn
  3630                              <1> ;;
  3631                              <1> ;;RES_RS: MOV	AH,00H			; RESET THE DRIVE
  3632                              <1> ;;	INT	13H
  3633                              <1> ;;RES_CK: MOV	AH,08H			; GET MAX CYLINDER,HEAD,SECTOR
  3634                              <1> ;;	MOV	BL,DL			; SAVE DRIVE CODE
  3635                              <1> ;;	INT	13H
  3636                              <1> ;;	JC	short RES_ER
  3637                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE MAX CYLINDER, SECTOR
  3638                              <1> ;;	MOV	DL,BL			; RESTORE DRIVE CODE
  3639                              <1> ;;RES_3: MOV	AX,0401H		; VERIFY THE LAST SECTOR
  3640                              <1> ;;	INT	13H
  3641                              <1> ;;	JNC	short RES_OK		; VERIFY OK
  3642                              <1> ;;	CMP	AH,BAD_SECTOR		; OK ALSO IF JUST ID READ
  3643                              <1> ;;	JE	short RES_OK
  3644                              <1> ;;	CMP	AH,DATA_CORRECTED
  3645                              <1> ;;	JE	short RES_OK
  3646                              <1> ;;	CMP	AH,BAD_ECC
  3647                              <1> ;;	JE	short RES_OK
  3648                              <1> ;;	;CALL	POD_TCHK		; CHECK FOR TIME OUT
  3649                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  3650                              <1> ;;					; (60 seconds)		
  3651                              <1> ;;	cmc
  3652                              <1> ;;	JC	short RES_ER		; FAILED
  3653                              <1> ;;	MOV	CX,[NEC_STATUS] 	; GET SECTOR ADDRESS, AND CYLINDER
  3654                              <1> ;;	MOV	AL,CL			; SEPARATE OUT SECTOR NUMBER
  3655                              <1> ;;	AND	AL,3FH
  3656                              <1> ;;	DEC	AL			; TRY PREVIOUS ONE
  3657                              <1> ;;	JZ	short RES_RS		; WE'VE TRIED ALL SECTORS ON TRACK
  3658                              <1> ;;	AND	CL,0C0H 		; KEEP CYLINDER BITS
  3659                              <1> ;;	OR	CL,AL			; MERGE SECTOR WITH CYLINDER BITS
  3660                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE CYLINDER, NEW SECTOR NUMBER
  3661                              <1> ;;	JMP	short RES_3		; TRY AGAIN
  3662                              <1> ;;;RES_ER: MOV	SI,OFFSET F1791 	; INDICATE DISK 1 ERROR
  3663                              <1> ;;	;TEST	DL,1
  3664                              <1> ;;	;JNZ	short RES_E1
  3665                              <1> ;;	;MOV	SI,OFFSET F1790 	; INDICATE DISK 0 ERROR
  3666                              <1> ;;;RES_E1:
  3667                              <1> ;;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  3668                              <1> ;;;RES_OK:
  3669                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  3670                              <1> ;;	;POP	BX
  3671                              <1> ;;	;RETn
  3672                              <1> ;
  3673                              <1> ;;SET_FAIL:
  3674                              <1> ;	;MOV	AX,X*(CMOS_DIAG+NMI)	; GET CMOS ERROR BYTE
  3675                              <1> ;	;CALL	CMOS_READ
  3676                              <1> ;	;OR	AL,HF_FAIL		; SET DO NOT IPL FROM DISK FLAG
  3677                              <1> ;	;XCHG	AH,AL			; SAVE IT
  3678                              <1> ;	;CALL	CMOS_WRITE		; PUT IT OUT
  3679                              <1> ;	;RETn
  3680                              <1> ;
  3681                              <1> ;;POD_TCHK:				; CHECK FOR 30 SECOND TIME OUT
  3682                              <1> ;	;POP	AX			; SAVE RETURN
  3683                              <1> ;	;POP	CX			; GET TIME OUT LIMITS
  3684                              <1> ;	;POP	BX
  3685                              <1> ;	;PUSH	BX			; AND SAVE THEM AGAIN
  3686                              <1> ;	;PUSH	CX
  3687                              <1> ;	;PUSH	AX
  3688                              <1> ;	;push	ds
  3689                              <1> ;	;xor	ax, ax
  3690                              <1> ;	;mov	ds, ax			; RESTORE RETURN
  3691                              <1> ;	;MOV	AX, [TIMER_LOW]		; AX = CURRENT TIME
  3692                              <1> ;	;				; BX = START TIME
  3693                              <1> ;	;				; CX = END TIME
  3694                              <1> ;	;pop	ds
  3695                              <1> ;	;CMP	BX,CX
  3696                              <1> ;	;JB	short TCHK1		; START < END
  3697                              <1> ;	;CMP	BX,AX
  3698                              <1> ;	;JB	short TCHKG		; END < START < CURRENT
  3699                              <1> ;	;JMP	SHORT TCHK2		; END, CURRENT < START
  3700                              <1> ;;TCHK1: CMP	AX,BX
  3701                              <1> ;;	JB	short TCHKNG		; CURRENT < START < END
  3702                              <1> ;;TCHK2: CMP	AX,CX
  3703                              <1> ;;	JB	short TCHKG		; START < CURRENT < END
  3704                              <1> ;;					; OR CURRENT < END < START
  3705                              <1> ;;TCHKNG: STC				; CARRY SET INDICATES TIME OUT
  3706                              <1> ;;	RETn
  3707                              <1> ;;TCHKG: CLC				; INDICATE STILL TIME
  3708                              <1> ;;	RETn
  3709                              <1> ;;
  3710                              <1> ;;int_13h:
  3711                              <1> 
  3712                              <1> ;----------------------------------------
  3713                              <1> ;	FIXED DISK BIOS ENTRY POINT	:
  3714                              <1> ;----------------------------------------
  3715                              <1> 
  3716                              <1> ; 30/08/2020
  3717                              <1> ; 29/08/2020
  3718                              <1> ; 15/01/2017
  3719                              <1> ; 14/01/2017
  3720                              <1> ; 07/01/2017
  3721                              <1> ; 02/01/2017
  3722                              <1> ; 01/06/2016
  3723                              <1> ; 16/05/2016, 27/05/2016, 28/05/2016, 29/05/2016
  3724                              <1> ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  3725                              <1> int33h:  ; DISK I/O
  3726                              <1> 	; 29/05/2016
  3727 00004C5C 80642408FE          <1> 	and	byte [esp+8], 11111110b  ; clear carry bit of eflags register
  3728                              <1> 	; 16/05/2016
  3729 00004C61 1E                  <1> 	push	ds
  3730 00004C62 53                  <1> 	push	ebx ; user's buffer address (virtual)
  3731 00004C63 66BB1000            <1> 	mov	bx, KDATA ; System (Kernel's) data segment
  3732 00004C67 8EDB                <1> 	mov	ds, bx
  3733                              <1> 
  3734                              <1> 	;;15/01/2017
  3735                              <1> 	; 14/01/2017
  3736                              <1> 	; 02/01/2017
  3737                              <1> 	;;mov	byte [intflg], 33h	; disk io interrupt 
  3738                              <1> 	;pop	ebx
  3739                              <1> 	;mov	[user_buffer], ebx		
  3740                              <1> 
  3741 00004C69 8F05[64700100]      <1> 	pop	dword [user_buffer] ; 01/06/2016
  3742                              <1> 
  3743 00004C6F C605[9E690100]00    <1> 	mov	byte [scount], 0 ; sector count for transfer
  3744 00004C76 80FC03              <1> 	cmp	ah, 03h ; chs write
  3745 00004C79 7744                <1> 	ja	short int33h_2
  3746 00004C7B 7407                <1> 	je	short int33h_0
  3747 00004C7D 80FC02              <1> 	cmp	ah, 02h ; chs read
  3748 00004C80 726F                <1> 	jb	short int33h_5
  3749 00004C82 EB68                <1> 	jmp	short int33h_4
  3750                              <1> int33h_0:
  3751                              <1> 	; transfer user's buffer content to sector buffer
  3752 00004C84 51                  <1> 	push	ecx
  3753 00004C85 0FB6C8              <1> 	movzx	ecx, al
  3754                              <1> int33h_1:
  3755 00004C88 56                  <1> 	push	esi
  3756 00004C89 8B35[64700100]      <1> 	mov	esi, [user_buffer]
  3757                              <1> 	; esi = user's buffer address (virtual, ebx)
  3758 00004C8F 57                  <1> 	push	edi
  3759 00004C90 06                  <1> 	push	es
  3760 00004C91 50                  <1> 	push	eax
  3761 00004C92 66B81000            <1> 	mov	ax, KDATA
  3762 00004C96 8EC0                <1> 	mov	es, ax
  3763 00004C98 BF00000700          <1> 	mov	edi, Cluster_Buffer
  3764 00004C9D C1E109              <1> 	shl	ecx, 9 ; * 512
  3765 00004CA0 E836A60000          <1> 	call	transfer_from_user_buffer
  3766 00004CA5 58                  <1> 	pop	eax
  3767 00004CA6 07                  <1> 	pop	es
  3768 00004CA7 5F                  <1> 	pop	edi
  3769 00004CA8 5E                  <1> 	pop	esi
  3770 00004CA9 59                  <1> 	pop	ecx
  3771 00004CAA 7345                <1> 	jnc	short int33h_5
  3772 00004CAC 8B1D[64700100]      <1> 	mov	ebx, [user_buffer] ; 01/06/2016
  3773 00004CB2 1F                  <1> 	pop	ds
  3774                              <1> 
  3775                              <1> 	;;15/01/2017
  3776                              <1> 	; 02/01/2017
  3777                              <1> 	;cli
  3778                              <1> 	;;mov	byte [ss:intflg], 0 ; 07/01/2017
  3779                              <1> 	;
  3780                              <1> 	; (*) 29/05/2016
  3781                              <1> 	; (*) retf 4 ; skip eflags on stack
  3782                              <1> 
  3783                              <1> 	; 29/05/2016 -set carry flag on stack-
  3784                              <1> 	; [esp] = EIP
  3785                              <1> 	; [esp+4] = CS
  3786                              <1> 	; [esp+8] = E-FLAGS
  3787 00004CB3 804C240801          <1> 	or	byte [esp+8], 1  ; set carry bit of eflags register
  3788                              <1> 	; [esp+12] = ESP (user)
  3789                              <1> 	; [esp+16] = SS (User)
  3790 00004CB8 B8FF000000          <1> 	mov	eax, 0FFh ; Unknown error !?
  3791                              <1> 	;iretd
  3792 00004CBD EB7E                <1> 	jmp	short int33h_7  ; 07/01/2017	
  3793                              <1> 
  3794                              <1> 	; (*) 29/05/2016 - 'ref 4' intruction causes to stack fault
  3795                              <1> 	; (OUTER-PRIVILEGE-LEVEL)
  3796                              <1> 	; INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986
  3797                              <1> 	; // RETF instruction:
  3798                              <1> 	;
  3799                              <1> 	; IF OperandMode=32 THEN
  3800                              <1>  	;    Load CS:EIP from stack;
  3801                              <1>  	;    Set CS RPL to CPL;
  3802                              <1>  	;    Increment eSP by 8 plus the immediate offset if it exists;
  3803                              <1>  	;    Load SS:eSP from stack;
  3804                              <1>  	; ELSE (* OperandMode=16 *)
  3805                              <1>  	;    Load CS:IP from stack;
  3806                              <1>  	;    Set CS RPL to CPL;
  3807                              <1>  	;    Increment eSP by 4 plus the immediate offset if it exists;
  3808                              <1> 	;    Load SS:eSP from stack;
  3809                              <1>  	; FI;
  3810                              <1> 	;
  3811                              <1> 	; //
  3812                              <1> 
  3813                              <1> int33h_2:
  3814 00004CBF 80FC05              <1> 	cmp	ah, 05h ; format track
  3815 00004CC2 770A                <1> 	ja	short int33h_3
  3816 00004CC4 722B                <1> 	jb	short int33h_5
  3817 00004CC6 51                  <1> 	push	ecx
  3818 00004CC7 B901000000          <1> 	mov	ecx, 1
  3819 00004CCC EBBA                <1> 	jmp	short int33h_1
  3820                              <1> int33h_3:
  3821 00004CCE 80FC1C              <1> 	cmp	ah, 1Ch ; LBA write
  3822 00004CD1 771E                <1> 	ja	short int33h_5
  3823 00004CD3 74AF                <1> 	je	short int33h_0
  3824 00004CD5 80FC1B              <1> 	cmp	ah, 1Bh ; LBA read
  3825 00004CD8 7412                <1> 	je	short int33h_4
  3826                              <1> 	; 29/08/2020
  3827 00004CDA 80FC08              <1> 	cmp	ah, 08h ; get disk parameters
  3828                              <1> 	;jne	short int33h_5
  3829 00004CDD 7405                <1> 	je	short int33h_10
  3830 00004CDF 80FC15              <1> 	cmp	ah, 15h	; read DASD type (get disk size)
  3831 00004CE2 750D                <1> 	jne	short int33h_5
  3832                              <1> int33h_10:
  3833                              <1> 	; 01/06/2016
  3834 00004CE4 8B1D[64700100]      <1> 	mov	ebx, [user_buffer] ; user's buffer address
  3835 00004CEA EB0A                <1> 	jmp	short int33h_6
  3836                              <1> int33h_4:
  3837 00004CEC A2[9E690100]        <1> 	mov	byte [scount], al ; <= 128 sectors
  3838                              <1> int33h_5:
  3839 00004CF1 BB00000700          <1> 	mov	ebx, Cluster_Buffer ; max. 65536 bytes
  3840                              <1> 				    ; buf. addr: 70000h	
  3841                              <1> 	;mov	byte [ClusterBuffer_Valid], 0
  3842                              <1> int33h_6:
  3843 00004CF6 1F                  <1> 	pop	ds
  3844 00004CF7 9C                  <1> 	pushfd
  3845 00004CF8 0E                  <1> 	push 	cs
  3846 00004CF9 E84D000000          <1> 	call 	DISK_IO
  3847 00004CFE 2E8B1D[64700100]    <1> 	mov	ebx, [CS:user_buffer] ; 01/06/2016
  3848 00004D05 723D                <1> 	jc	short int33h_9
  3849                              <1> 	;
  3850 00004D07 2E803D[9E690100]00  <1> 	cmp	byte [CS:scount], 0
  3851 00004D0F 762C                <1> 	jna	short int33h_7
  3852                              <1> 	;
  3853                              <1> 	; transfer sector buffer content to user's buffer
  3854 00004D11 06                  <1> 	push	es
  3855 00004D12 1E                  <1> 	push	ds
  3856 00004D13 50                  <1> 	push	eax
  3857 00004D14 66B81000            <1> 	mov	ax, KDATA
  3858 00004D18 8ED8                <1> 	mov	ds, ax
  3859 00004D1A 8EC0                <1> 	mov	es, ax
  3860 00004D1C 51                  <1> 	push	ecx
  3861 00004D1D 56                  <1> 	push	esi
  3862 00004D1E 57                  <1> 	push	edi
  3863 00004D1F 0FB60D[9E690100]    <1> 	movzx	ecx, byte [scount]
  3864 00004D26 C1E109              <1> 	shl	ecx, 9 ; * 512 bytes
  3865 00004D29 89DF                <1> 	mov	edi, ebx ; user's buffer address
  3866 00004D2B BE00000700          <1> 	mov	esi, Cluster_Buffer
  3867 00004D30 E85CA50000          <1> 	call	transfer_to_user_buffer
  3868 00004D35 5F                  <1> 	pop	edi
  3869 00004D36 5E                  <1> 	pop	esi
  3870 00004D37 59                  <1> 	pop	ecx
  3871 00004D38 58                  <1> 	pop	eax
  3872 00004D39 1F                  <1> 	pop	ds
  3873 00004D3A 07                  <1> 	pop	es
  3874 00004D3B 7202                <1> 	jc	short int33h_8
  3875                              <1> int33h_7:
  3876 00004D3D FA                  <1> 	cli
  3877                              <1> 	;;15/01/2017
  3878                              <1> 	;;mov	byte [ss:intflg], 0 ; 07/01/2017
  3879                              <1> 	; cf = 0  ; use eflags which is in stack
  3880 00004D3E CF                  <1> 	iretd	
  3881                              <1> int33h_8:
  3882 00004D3F B8FF000000          <1> 	mov	eax, 0FFh ; Unknown error !?
  3883                              <1> int33h_9:
  3884                              <1> 	; cf = 1
  3885                              <1> 
  3886                              <1> 	; (*) 29/05/2016	
  3887                              <1> 	; (*) retf 4 ; skip eflags on stack
  3888                              <1> 	; Note: This 'retf 4' was wrong, -it was causing
  3889                              <1> 	;       to stack errors in ring 3-
  3890                              <1> 	;	POP sequence of 'retf 4' is as
  3891                              <1> 	;       "eip, cs, eflags, esp, ss, +4 bytes" 
  3892                              <1>         ;       it is not as "eip, cs, +4 bytes, esp, ss" ! 
  3893                              <1> 
  3894                              <1> 	; 29/05/2016 -set carry flag on stack-
  3895 00004D44 804C240801          <1> 	or	byte [esp+8], 1  ; set carry bit of eflags register
  3896                              <1> 	;iretd
  3897 00004D49 EBF2                <1> 	jmp	short int33h_7 ; 07/01/2017
  3898                              <1> 
  3899                              <1> ; 30/08/2020
  3900                              <1> ; 09/12/2017
  3901                              <1> ; 29/05/2016
  3902                              <1> ; 27/05/2016 - TRDOS 386 (TRDOS v2.0)
  3903                              <1> 
  3904                              <1> DISK_IO:
  3905 00004D4B 80FA80              <1> 	CMP	DL,80H			; TEST FOR FIXED DISK DRIVE
  3906                              <1> 	;JAE	short A1		; YES, HANDLE HERE
  3907                              <1> 	;;;INT	40H			; DISKETTE HANDLER
  3908                              <1> 	;;call	int40h
  3909 00004D4E 0F82FEEFFFFF        <1> 	jb	DISKETTE_IO_1
  3910                              <1> ;RET_2:
  3911                              <1> 	;RETf	2			; BACK TO CALLER
  3912                              <1> ;	retf	4
  3913                              <1> A1:
  3914 00004D54 FB                  <1> 	STI				; ENABLE INTERRUPTS
  3915                              <1> 	;; 04/01/2015
  3916                              <1> 	;;OR	AH,AH
  3917                              <1> 	;;JNZ	short A2
  3918                              <1> 	;;INT	40H			; RESET NEC WHEN AH=0
  3919                              <1> 	;;SUB	AH,AH
  3920 00004D55 80FA83              <1> 	CMP	DL,(80H + S_MAX_FILE - 1) ; 83h ; 30/08/2020 
  3921                              <1> 	;JA	short RET_2
  3922 00004D58 7614                <1> 	jna	short _A0
  3923                              <1> 	; 29/05/2016
  3924 00004D5A 1E                  <1> 	push	ds
  3925 00004D5B 50                  <1> 	push	eax ; 30/08/2020 (ax --> eax)
  3926 00004D5C 66B81000            <1> 	mov	ax, KDATA
  3927 00004D60 8ED8                <1> 	mov	ds, ax
  3928 00004D62 58                  <1> 	pop	eax ; 
  3929 00004D63 B4AA                <1>         mov     ah, 0AAh        ; Hard disk drive not ready !
  3930                              <1> 				; (Programmer's guide to AMIBIOS, 1992)
  3931 00004D65 8825[73640100]      <1> 	mov     byte [DISK_STATUS1], ah
  3932 00004D6B 1F                  <1> 	pop	ds
  3933 00004D6C EB38                <1> 	jmp	short RET_2
  3934                              <1> _A0:
  3935                              <1> 	; 18/01/2015
  3936 00004D6E 08E4                <1> 	or	ah,ah
  3937 00004D70 743A                <1> 	jz	short A4
  3938 00004D72 80FC0D              <1> 	cmp	ah,0Dh	; Alternate reset
  3939 00004D75 7504                <1> 	jne	short A2
  3940 00004D77 28E4                <1> 	sub	ah,ah	; Reset
  3941 00004D79 EB31                <1> 	jmp	short A4
  3942                              <1> A2:
  3943 00004D7B 80FC08              <1> 	CMP	AH,08H			; GET PARAMETERS IS A SPECIAL CASE
  3944                              <1> 	;JNZ	short A3
  3945                              <1>         ;JMP    GET_PARM_N
  3946 00004D7E 0F8452030000        <1> 	je	GET_PARM_N
  3947 00004D84 80FC15              <1> A3:	CMP	AH,15H			; READ DASD TYPE IS ALSO
  3948                              <1> 	;JNZ	short A4
  3949                              <1>         ;JMP    READ_DASD_TYPE
  3950 00004D87 0F84DB020000        <1>         je      READ_DASD_TYPE
  3951                              <1> 	; 02/02/2015
  3952 00004D8D 80FC1D              <1> 	cmp	ah, 1Dh			;(Temporary for Retro UNIX 386 v1)
  3953                              <1> 	; 12/01/2015
  3954 00004D90 F5                  <1> 	cmc
  3955 00004D91 7319                <1> 	jnc	short A4
  3956                              <1> int33h_bad_cmd:
  3957                              <1> 	; 16/05/2016
  3958                              <1> 	; 30/01/2015
  3959                              <1> 	; 29/05/2016
  3960 00004D93 1E                  <1> 	push	ds
  3961 00004D94 6650                <1> 	push	ax
  3962 00004D96 66B81000            <1> 	mov	ax, KDATA
  3963 00004D9A 8ED8                <1> 	mov	ds, ax
  3964 00004D9C 6658                <1> 	pop	ax
  3965 00004D9E B401                <1> 	mov	ah, BAD_CMD
  3966 00004DA0 8825[73640100]      <1> 	mov     [DISK_STATUS1], ah ; BAD_CMD  ; COMMAND ERROR
  3967                              <1>         ;jmp	short RET_2
  3968                              <1> RET_2:
  3969                              <1> 	; (*) 29/05/2016
  3970                              <1> 	; (*) retf 4
  3971 00004DA6 804C240801          <1> 	or	byte [esp+8], 1 ; set carry bit of eflags register
  3972 00004DAB CF                  <1> 	iretd
  3973                              <1> A4:					; SAVE REGISTERS DURING OPERATION
  3974 00004DAC C8080000            <1> 	ENTER	8,0			; SAVE (BP) AND MAKE ROOM FOR @CMD_BLOCK
  3975 00004DB0 53                  <1> 	PUSH	eBX			;  IN THE STACK, THE COMMAND BLOCK IS:
  3976 00004DB1 51                  <1> 	PUSH	eCX			;   @CMD_BLOCK == BYTE PTR [BP]-8
  3977 00004DB2 52                  <1> 	PUSH	eDX
  3978 00004DB3 1E                  <1> 	PUSH	DS
  3979 00004DB4 06                  <1> 	PUSH	ES
  3980 00004DB5 56                  <1> 	PUSH	eSI
  3981 00004DB6 57                  <1> 	PUSH	eDI
  3982                              <1> 	;;04/01/2015
  3983                              <1> 	;;OR	AH,AH			; CHECK FOR RESET
  3984                              <1> 	;;JNZ	short A5
  3985                              <1> 	;;MOV	DL,80H			; FORCE DRIVE 80 FOR RESET
  3986                              <1> ;;A5:	
  3987                              <1> 	;push	cs
  3988                              <1> 	;pop	ds
  3989                              <1> 	; 21/02/2015
  3990 00004DB7 6650                <1> 	push	ax
  3991 00004DB9 66B81000            <1> 	mov	ax, KDATA
  3992 00004DBD 8ED8                <1> 	mov	ds, ax
  3993 00004DBF 8EC0                <1> 	mov	es, ax	
  3994 00004DC1 6658                <1> 	pop	ax
  3995 00004DC3 E88D000000          <1> 	CALL	DISK_IO_CONT		; PERFORM THE OPERATION
  3996                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  3997 00004DC8 8A25[73640100]      <1> 	MOV	AH,[DISK_STATUS1]	; GET STATUS FROM OPERATION
  3998                              <1> 	;(*) CMP AH,1			; SET THE CARRY FLAG TO INDICATE
  3999                              <1> 	;(*) CMC			; SUCCESS OR FAILURE
  4000 00004DCE 5F                  <1> 	POP	eDI			; RESTORE REGISTERS
  4001 00004DCF 5E                  <1> 	POP	eSI
  4002 00004DD0 07                  <1>         POP     ES
  4003 00004DD1 1F                  <1>         POP     DS
  4004 00004DD2 5A                  <1> 	POP	eDX
  4005 00004DD3 59                  <1> 	POP	eCX
  4006 00004DD4 5B                  <1> 	POP	eBX
  4007 00004DD5 C9                  <1> 	LEAVE				; ADJUST (SP) AND RESTORE (BP)
  4008                              <1> 	;RETf	2			; THROW AWAY SAVED FLAGS
  4009                              <1> 	; (*) 29/05/2016
  4010                              <1> 	; (*) retf 4
  4011 00004DD6 80FC01              <1> 	cmp	ah, 1
  4012 00004DD9 7205                <1> 	jc	short _A5 
  4013 00004DDB 804C240801          <1> 	or	byte [esp+8], 1 ; set carry bit of eflags register
  4014                              <1> _A5:
  4015 00004DE0 CF                  <1> 	iretd
  4016                              <1> 
  4017                              <1> ; 21/02/2015
  4018                              <1> ;       dw --> dd
  4019                              <1> D1:					; FUNCTION TRANSFER TABLE
  4020 00004DE1 [A44F0000]          <1> 	dd	DISK_RESET		; 000H
  4021 00004DE5 [1B500000]          <1> 	dd	RETURN_STATUS		; 001H
  4022 00004DE9 [28500000]          <1> 	dd	DISK_READ		; 002H
  4023 00004DED [31500000]          <1> 	dd	DISK_WRITE		; 003H
  4024 00004DF1 [3A500000]          <1> 	dd	DISK_VERF		; 004H
  4025 00004DF5 [52500000]          <1> 	dd	FMT_TRK 		; 005H
  4026 00004DF9 [9A4F0000]          <1> 	dd	BAD_COMMAND		; 006H	FORMAT BAD SECTORS
  4027 00004DFD [9A4F0000]          <1> 	dd	BAD_COMMAND		; 007H	FORMAT DRIVE
  4028 00004E01 [9A4F0000]          <1> 	dd	BAD_COMMAND		; 008H	RETURN PARAMETERS
  4029 00004E05 [6F510000]          <1> 	dd	INIT_DRV		; 009H
  4030 00004E09 [CE510000]          <1> 	dd	RD_LONG 		; 00AH
  4031 00004E0D [D7510000]          <1> 	dd	WR_LONG 		; 00BH
  4032 00004E11 [E0510000]          <1> 	dd	DISK_SEEK		; 00CH
  4033 00004E15 [A44F0000]          <1> 	dd	DISK_RESET		; 00DH
  4034 00004E19 [9A4F0000]          <1> 	dd	BAD_COMMAND		; 00EH	READ BUFFER
  4035 00004E1D [9A4F0000]          <1> 	dd	BAD_COMMAND		; 00FH	WRITE BUFFER
  4036 00004E21 [08520000]          <1> 	dd	TST_RDY 		; 010H
  4037 00004E25 [2C520000]          <1> 	dd	HDISK_RECAL		; 011H
  4038 00004E29 [9A4F0000]          <1> 	dd	BAD_COMMAND		; 012H	MEMORY DIAGNOSTIC
  4039 00004E2D [9A4F0000]          <1> 	dd	BAD_COMMAND		; 013H	DRIVE DIAGNOSTIC
  4040 00004E31 [62520000]          <1> 	dd	CTLR_DIAGNOSTIC 	; 014H	CONTROLLER DIAGNOSTIC
  4041                              <1> 	; 02/02/2015 (Temporary - Retro UNIX 386 v1 - DISK I/O test)
  4042 00004E35 [9A4F0000]          <1> 	dd	BAD_COMMAND		; 015h
  4043 00004E39 [9A4F0000]          <1> 	dd	BAD_COMMAND		; 016h
  4044 00004E3D [9A4F0000]          <1> 	dd	BAD_COMMAND		; 017h
  4045 00004E41 [9A4F0000]          <1> 	dd	BAD_COMMAND		; 018h
  4046 00004E45 [9A4F0000]          <1> 	dd	BAD_COMMAND		; 019h
  4047 00004E49 [9A4F0000]          <1> 	dd	BAD_COMMAND		; 01Ah
  4048 00004E4D [28500000]          <1> 	dd	DISK_READ		; 01Bh ; LBA read
  4049 00004E51 [31500000]          <1> 	dd	DISK_WRITE		; 01Ch ; LBA write
  4050                              <1> D1L     EQU    $ - D1
  4051                              <1> 
  4052                              <1> DISK_IO_CONT:
  4053                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  4054 00004E55 80FC01              <1> 	CMP	AH,01H			; RETURN STATUS
  4055                              <1> 	;;JNZ	short SU0
  4056                              <1>         ;;JMP	RETURN_STATUS
  4057 00004E58 0F84BD010000        <1> 	je	RETURN_STATUS
  4058                              <1> SU0:
  4059 00004E5E C605[73640100]00    <1> 	MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  4060                              <1> 	;;PUSH	BX			; SAVE DATA ADDRESS
  4061                              <1> 	;mov	si, bx ;; 14/02/2015
  4062 00004E65 89DE                <1> 	mov	esi, ebx ; 21/02/2015
  4063 00004E67 8A1D[74640100]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  4064                              <1> 	;; 04/01/2015
  4065                              <1> 	;;PUSH	AX
  4066 00004E6D 80E27F              <1> 	AND	DL,7FH			; GET DRIVE AS 0 OR 1
  4067                              <1> 					; (get drive number as 0 to 3)
  4068 00004E70 38D3                <1> 	CMP	BL,DL
  4069                              <1>         ;;JBE   BAD_COMMAND_POP         ; INVALID DRIVE
  4070 00004E72 0F8622010000        <1>         jbe     BAD_COMMAND ;; 14/02/2015
  4071                              <1>         ;
  4072                              <1> 	;;03/01/2015
  4073 00004E78 29DB                <1> 	sub	ebx, ebx
  4074 00004E7A 88D3                <1> 	mov	bl, dl
  4075                              <1> 	;sub	bh, bh
  4076 00004E7C 883D[88640100]      <1> 	mov	[LBAMode], bh 	; 0
  4077                              <1> 	;;test	byte [bx+hd0_type], 1	; LBA ready ?
  4078                              <1> 	;test	byte [ebx+hd0_type], 1
  4079                              <1> 	;jz	short su1		; no
  4080                              <1> 	;inc	byte [LBAMode]
  4081                              <1> ;su1:
  4082                              <1> 	; 21/02/2015 (32 bit modification)
  4083                              <1> 	;04/01/2015
  4084 00004E82 6650                <1> 	push	ax ; ***
  4085                              <1> 	;PUSH	ES ; **
  4086 00004E84 6652                <1> 	PUSH	DX ; *
  4087 00004E86 6650                <1> 	push	ax
  4088 00004E88 E8BB060000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS
  4089                              <1> 	; 02/02/2015
  4090                              <1> 	;mov	ax, [ES:BX+16] ; I/O port base address (1F0h, 170h)
  4091 00004E8D 668B4310            <1> 	mov	ax, [ebx+16]
  4092 00004E91 66A3[C0670000]      <1> 	mov	[HF_PORT], ax
  4093                              <1> 	;mov	dx, [ES:BX+18] ; control port address (3F6h, 376h)
  4094 00004E97 668B5312            <1> 	mov	dx, [ebx+18]
  4095 00004E9B 668915[C2670000]    <1> 	mov	[HF_REG_PORT], dx
  4096                              <1> 	;mov	al, [ES:BX+20] ; head register upper nibble (A0h,B0h,E0h,F0h)
  4097 00004EA2 8A4314              <1> 	mov	al, [ebx+20]
  4098                              <1> 	; 23/02/2015
  4099 00004EA5 A840                <1> 	test	al, 40h	 ; LBA bit (bit 6)
  4100 00004EA7 7406                <1> 	jz 	short su1
  4101 00004EA9 FE05[88640100]      <1> 	inc	byte [LBAMode] ; 1 
  4102                              <1> su1: 	 
  4103 00004EAF C0E804              <1> 	shr 	al, 4
  4104 00004EB2 2401                <1> 	and	al, 1			
  4105 00004EB4 A2[C4670000]        <1> 	mov	[hf_m_s], al 
  4106                              <1> 	;
  4107                              <1> 	; 03/01/2015
  4108                              <1> 	;MOV	AL,byte [ES:BX+8]	; GET CONTROL BYTE MODIFIER
  4109 00004EB9 8A4308              <1> 	mov	al, [ebx+8]
  4110                              <1> 	;MOV	DX,[HF_REG_PORT]	; Device Control register	
  4111 00004EBC EE                  <1> 	OUT	DX,AL			; SET EXTRA HEAD OPTION
  4112                              <1> 					; Control Byte:  (= 08h, here)
  4113                              <1> 					; bit 0 - 0
  4114                              <1> 					; bit 1 - nIEN (1 = disable irq)
  4115                              <1> 					; bit 2 - SRST (software RESET)
  4116                              <1> 					; bit 3 - use extra heads (8 to 15)
  4117                              <1> 					;         -always set to 1-	
  4118                              <1> 					; (bits 3 to 7 are reserved
  4119                              <1> 					;          for ATA devices)
  4120 00004EBD 8A25[75640100]      <1> 	MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  4121 00004EC3 80E4C0              <1> 	AND	AH,0C0H 		; CONTROL BYTE
  4122 00004EC6 08C4                <1> 	OR	AH,AL
  4123 00004EC8 8825[75640100]      <1> 	MOV	[CONTROL_BYTE],AH	
  4124                              <1> 	; 04/01/2015
  4125 00004ECE 6658                <1> 	pop	ax
  4126 00004ED0 665A                <1> 	pop	dx ; * ;; 14/02/2015
  4127 00004ED2 20E4                <1> 	and	ah, ah	; Reset function ?
  4128 00004ED4 7507                <1> 	jnz	short su2
  4129                              <1> 	;;pop	dx ; * ;; 14/02/2015
  4130                              <1> 	;pop	es ; **
  4131 00004ED6 6658                <1> 	pop	ax ; ***
  4132                              <1> 	;;pop	bx
  4133 00004ED8 E9C7000000          <1>         jmp     DISK_RESET
  4134                              <1> su2:
  4135 00004EDD 803D[88640100]00    <1> 	cmp	byte [LBAMode], 0
  4136 00004EE4 7662                <1> 	jna	short su3
  4137                              <1> 	;
  4138                              <1> 	; 02/02/2015 (LBA read/write function calls)
  4139 00004EE6 80FC1B              <1> 	cmp	ah, 1Bh
  4140 00004EE9 720B                <1> 	jb	short lbarw1
  4141 00004EEB 80FC1C              <1> 	cmp	ah, 1Ch
  4142 00004EEE 775D                <1> 	ja 	short invldfnc
  4143                              <1> 	;;pop	dx ; * ; 14/02/2015
  4144                              <1> 	;mov	ax, cx ; Lower word of LBA address (bits 0-15)
  4145 00004EF0 89C8                <1> 	mov	eax, ecx ; LBA address (21/02/2015)
  4146                              <1> 	;; 14/02/2015
  4147 00004EF2 88D1                <1> 	mov	cl, dl ; 14/02/2015
  4148                              <1> 	;;mov	dx, bx
  4149                              <1> 	;mov	dx, si ; higher word of LBA address (bits 16-23)
  4150                              <1> 	;;mov	bx, di
  4151                              <1> 	;mov	si, di ; Buffer offset
  4152 00004EF4 EB32                <1> 	jmp	short lbarw2
  4153                              <1> lbarw1:
  4154                              <1> 	; convert CHS to LBA
  4155                              <1> 	;
  4156                              <1> 	; LBA calculation - AWARD BIOS - 1999 - AHDSK.ASM
  4157                              <1> 	; LBA = "# of Heads" * Sectors/Track * Cylinder + Head * Sectors/Track
  4158                              <1> 	;	+ Sector - 1
  4159 00004EF6 6652                <1> 	push	dx ; * ;; 14/02/2015
  4160                              <1> 	;xor	dh, dh
  4161 00004EF8 31D2                <1> 	xor	edx, edx
  4162                              <1> 	;mov	dl, [ES:BX+14]	; sectors per track (logical)
  4163 00004EFA 8A530E              <1> 	mov	dl, [ebx+14]
  4164                              <1> 	;xor	ah, ah
  4165 00004EFD 31C0                <1> 	xor	eax, eax
  4166                              <1> 	;mov	al, [ES:BX+2]	; heads (logical) 	
  4167 00004EFF 8A4302              <1> 	mov	al, [ebx+2]
  4168 00004F02 FEC8                <1> 	dec	al
  4169 00004F04 6640                <1> 	inc	ax		; 0 =  256
  4170 00004F06 66F7E2              <1> 	mul 	dx
  4171                              <1> 		; AX = # of Heads" * Sectors/Track
  4172 00004F09 6689CA              <1> 	mov	dx, cx
  4173                              <1> 	;and	cx, 3Fh	 ; sector  (1 to 63)
  4174 00004F0C 83E13F              <1> 	and	ecx, 3fh
  4175 00004F0F 86D6                <1> 	xchg	dl, dh
  4176 00004F11 C0EE06              <1> 	shr	dh, 6
  4177                              <1> 		; DX = cylinder (0 to 1023)
  4178                              <1> 	;mul 	dx
  4179                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder
  4180 00004F14 F7E2                <1> 	mul	edx
  4181 00004F16 FEC9                <1> 	dec	cl  ; sector - 1
  4182                              <1> 	;add	ax, cx
  4183                              <1> 	;adc	dx, 0
  4184                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder + Sector -1
  4185 00004F18 01C8                <1> 	add	eax, ecx
  4186 00004F1A 6659                <1> 	pop	cx ; * ; ch = head, cl = drive number (zero based)
  4187                              <1> 	;push	dx
  4188                              <1> 	;push	ax
  4189 00004F1C 50                  <1> 	push	eax
  4190                              <1> 	;mov	al, [ES:BX+14]	; sectors per track (logical)	
  4191 00004F1D 8A430E              <1> 	mov	al, [ebx+14]
  4192 00004F20 F6E5                <1> 	mul	ch
  4193                              <1> 		;  AX = Head * Sectors/Track
  4194 00004F22 0FB7C0              <1>         movzx	eax, ax ; 09/12/2017
  4195                              <1> 	;pop	dx
  4196 00004F25 5A                  <1> 	pop	edx
  4197                              <1> 	;add	ax, dx
  4198                              <1> 	;pop	dx
  4199                              <1> 	;adc	dx, 0 ; add carry bit
  4200 00004F26 01D0                <1> 	add	eax, edx
  4201                              <1> lbarw2:
  4202 00004F28 29D2                <1> 	sub	edx, edx ; 21/02/2015
  4203 00004F2A 88CA                <1> 	mov	dl, cl ; 21/02/2015
  4204 00004F2C C645F800            <1>         mov     byte [CMD_BLOCK], 0 ; Features Register
  4205                              <1> 				; NOTE: Features register (1F1h, 171h)
  4206                              <1> 				; is not used for ATA device R/W functions. 
  4207                              <1> 				; It is old/obsolete 'write precompensation'
  4208                              <1> 				; register and error register
  4209                              <1> 				; for old ATA/IDE devices.
  4210                              <1> 	; 18/01/2014
  4211                              <1> 	;mov	ch, [hf_m_s]	; Drive 0 (master) or 1 (slave)
  4212 00004F30 8A0D[C4670000]      <1> 	mov	cl, [hf_m_s]
  4213                              <1> 	;shl	ch, 4		; bit 4 (drive bit)
  4214                              <1> 	;or	ch, 0E0h	; bit 5 = 1
  4215                              <1> 				; bit 6 = 1 = LBA mode
  4216                              <1> 				; bit 7 = 1
  4217 00004F36 80C90E              <1> 	or	cl, 0Eh ; 1110b
  4218                              <1> 	;and	dh, 0Fh		; LBA byte 4 (bits 24 to 27)
  4219 00004F39 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh
  4220 00004F3E C1E11C              <1> 	shl	ecx, 28 ; 21/02/2015
  4221                              <1> 	;or	dh, ch
  4222 00004F41 09C8                <1> 	or	eax, ecx	
  4223                              <1> 	;;mov	[CMD_BLOCK+2], al ; LBA byte 1 (bits 0 to 7)
  4224                              <1> 				  ; (Sector Number Register)
  4225                              <1> 	;;mov	[CMD_BLOCK+3], ah ; LBA byte 2 (bits 8 to 15)
  4226                              <1> 				  ; (Cylinder Low Register)
  4227                              <1> 	;mov	[CMD_BLOCK+2], ax ; LBA byte 1, 2
  4228                              <1> 	;mov	[CMD_BLOCK+4], dl ; LBA byte 3 (bits 16 to 23)
  4229                              <1> 				  ; (Cylinder High Register)
  4230                              <1> 	;;mov	[CMD_BLOCK+5], dh ; LBA byte 4 (bits 24 to 27)
  4231                              <1> 				  ; (Drive/Head Register)
  4232                              <1> 	
  4233                              <1> 	;mov	[CMD_BLOCK+4], dx ; LBA byte 4, LBA & DEV select bits
  4234 00004F43 8945FA              <1> 	mov	[CMD_BLOCK+2], eax ; 21/02/2015
  4235                              <1> 	;14/02/2015
  4236                              <1> 	;mov	dl, cl ; Drive number (INIT_DRV)		
  4237 00004F46 EB38                <1> 	jmp	short su4
  4238                              <1> su3:
  4239                              <1> 	; 02/02/2015 
  4240                              <1> 	; (Temporary functions 1Bh & 1Ch are not valid for CHS mode) 
  4241 00004F48 80FC14              <1> 	cmp 	ah, 14h
  4242 00004F4B 7604                <1> 	jna 	short chsfnc
  4243                              <1> invldfnc:
  4244                              <1>         ; 14/02/2015  
  4245                              <1> 	;pop	es ; **
  4246 00004F4D 6658                <1>         pop     ax ; ***
  4247                              <1>         ;jmp     short BAD_COMMAND_POP
  4248 00004F4F EB49                <1>         jmp     short BAD_COMMAND
  4249                              <1> chsfnc:	
  4250                              <1> 	;MOV	AX,[ES:BX+5]		; GET WRITE PRE-COMPENSATION CYLINDER
  4251 00004F51 668B4305            <1> 	mov	ax, [ebx+5]
  4252 00004F55 66C1E802            <1> 	SHR	AX,2
  4253 00004F59 8845F8              <1> 	MOV	[CMD_BLOCK],AL
  4254                              <1> 	;;MOV	AL,[ES:BX+8]		; GET CONTROL BYTE MODIFIER
  4255                              <1> 	;;PUSH	DX
  4256                              <1> 	;;MOV	DX,[HF_REG_PORT]
  4257                              <1> 	;;OUT	DX,AL			; SET EXTRA HEAD OPTION
  4258                              <1> 	;;POP	DX ; * 
  4259                              <1> 	;;POP	ES ; **
  4260                              <1> 	;;MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  4261                              <1> 	;;AND	AH,0C0H 		; CONTROL BYTE	
  4262                              <1> 	;;OR	AH,AL
  4263                              <1> 	;;MOV	[CONTROL_BYTE],AH
  4264                              <1> 	;
  4265 00004F5C 88C8                <1> 	MOV	AL,CL			; GET SECTOR NUMBER
  4266 00004F5E 243F                <1> 	AND	AL,3FH
  4267 00004F60 8845FA              <1> 	MOV	[CMD_BLOCK+2],AL
  4268 00004F63 886DFB              <1> 	MOV	[CMD_BLOCK+3],CH 	; GET CYLINDER NUMBER
  4269 00004F66 88C8                <1> 	MOV	AL,CL
  4270 00004F68 C0E806              <1> 	SHR	AL,6
  4271 00004F6B 8845FC              <1> 	MOV	[CMD_BLOCK+4],AL 	; CYLINDER HIGH ORDER 2 BITS
  4272                              <1> 	;;05/01/2015
  4273                              <1> 	;;MOV	AL,DL			; DRIVE NUMBER
  4274 00004F6E A0[C4670000]        <1> 	mov	al, [hf_m_s]
  4275 00004F73 C0E004              <1> 	SHL	AL,4
  4276 00004F76 80E60F              <1> 	AND	DH,0FH			; HEAD NUMBER
  4277 00004F79 08F0                <1> 	OR	AL,DH
  4278                              <1> 	;OR	AL,80H or 20H
  4279 00004F7B 0CA0                <1> 	OR	AL,80h+20h		; ECC AND 512 BYTE SECTORS
  4280 00004F7D 8845FD              <1> 	MOV	[CMD_BLOCK+5],AL 	; ECC/SIZE/DRIVE/HEAD
  4281                              <1> su4:
  4282                              <1> 	;POP	ES ; **
  4283                              <1>         ;; 14/02/2015
  4284                              <1>         ;;POP   AX
  4285                              <1>         ;;MOV   [CMD_BLOCK+1],AL        ; SECTOR COUNT
  4286                              <1>         ;;PUSH  AX
  4287                              <1>         ;;MOV   AL,AH                   ; GET INTO LOW BYTE
  4288                              <1>         ;;XOR   AH,AH                   ; ZERO HIGH BYTE
  4289                              <1>         ;;SAL   AX,1                    ; *2 FOR TABLE LOOKUP
  4290 00004F80 6658                <1>         pop     ax ; ***
  4291 00004F82 8845F9              <1>         mov     [CMD_BLOCK+1], al
  4292 00004F85 29DB                <1>         sub	ebx, ebx
  4293 00004F87 88E3                <1> 	mov     bl, ah
  4294                              <1>         ;xor     bh, bh
  4295                              <1>         ;sal     bx, 1
  4296 00004F89 66C1E302            <1>         sal	bx, 2	; 32 bit offset (21/02/2015)
  4297                              <1> 	;;MOV   SI,AX                   ; PUT INTO SI FOR BRANCH
  4298                              <1>         ;;CMP   AX,D1L                  ; TEST WITHIN RANGE
  4299                              <1>         ;;JNB   short BAD_COMMAND_POP
  4300                              <1>         ;cmp     bx, D1L
  4301 00004F8D 83FB74              <1> 	cmp	ebx, D1L
  4302 00004F90 7308                <1> 	jnb	short BAD_COMMAND
  4303                              <1>         ;xchg    bx, si
  4304 00004F92 87DE                <1>         xchg	ebx, esi
  4305                              <1> 	;;;POP	AX			; RESTORE AX
  4306                              <1> 	;;;POP	BX			; AND DATA ADDRESS
  4307                              <1> 	
  4308                              <1> 	;;PUSH	CX
  4309                              <1> 	;;PUSH	AX			; ADJUST ES:BX
  4310                              <1> 	;MOV	CX,BX			; GET 3 HIGH ORDER NIBBLES OF BX
  4311                              <1> 	;SHR	CX,4
  4312                              <1> 	;MOV	AX,ES
  4313                              <1> 	;ADD	AX,CX
  4314                              <1> 	;MOV	ES,AX
  4315                              <1> 	;AND	BX,000FH		; ES:BX CHANGED TO ES:000X
  4316                              <1> 	;;POP	AX
  4317                              <1> 	;;POP	CX
  4318                              <1> 	;;JMP	word [CS:SI+D1]
  4319                              <1> 	;jmp	word [SI+D1]
  4320 00004F94 FFA6[E14D0000]      <1> 	jmp	dword [esi+D1]
  4321                              <1> ;;BAD_COMMAND_POP:
  4322                              <1> ;;	POP	AX
  4323                              <1> ;;	POP	BX
  4324                              <1> BAD_COMMAND:
  4325 00004F9A C605[73640100]01    <1>         MOV     byte [DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  4326 00004FA1 B000                <1> 	MOV	AL,0
  4327 00004FA3 C3                  <1> 	RETn
  4328                              <1> 
  4329                              <1> ;----------------------------------------
  4330                              <1> ;	RESET THE DISK SYSTEM  (AH=00H) :
  4331                              <1> ;----------------------------------------
  4332                              <1> 
  4333                              <1> ; 18-1-2015 : one controller reset (not other one)
  4334                              <1> 
  4335                              <1> DISK_RESET:
  4336 00004FA4 FA                  <1> 	CLI
  4337 00004FA5 E4A1                <1> 	IN	AL,INTB01		; GET THE MASK REGISTER
  4338                              <1> 	;JMP	$+2
  4339                              <1> 	IODELAY
  4339 00004FA7 EB00                <2>  jmp short $+2
  4339 00004FA9 EB00                <2>  jmp short $+2
  4340                              <1> 	;AND	AL,0BFH 		; ENABLE FIXED DISK INTERRUPT
  4341 00004FAB 243F                <1> 	and	al,3Fh			; 22/12/2014 (IRQ 14 & IRQ 15)
  4342 00004FAD E6A1                <1> 	OUT	INTB01,AL
  4343 00004FAF FB                  <1> 	STI				; START INTERRUPTS
  4344                              <1> 	; 14/02/2015
  4345 00004FB0 6689D7              <1> 	mov	di, dx	
  4346                              <1> 	; 04/01/2015
  4347                              <1> 	;xor	di,di
  4348                              <1> drst0:
  4349 00004FB3 B004                <1> 	MOV	AL,04H  ; bit 2 - SRST 
  4350                              <1> 	;MOV	DX,HF_REG_PORT
  4351 00004FB5 668B15[C2670000]    <1> 	MOV	DX,[HF_REG_PORT]
  4352 00004FBC EE                  <1> 	OUT	DX,AL			; RESET
  4353                              <1> ;	MOV	CX,10			; DELAY COUNT
  4354                              <1> ;DRD:	DEC	CX
  4355                              <1> ;	JNZ	short DRD		; WAIT 4.8 MICRO-SEC
  4356                              <1> 	;mov	cx,2			; wait for 30 micro seconds	
  4357 00004FBD B902000000          <1>         mov	ecx, 2 ; 21/02/2015
  4358 00004FC2 E875D3FFFF          <1> 	call    WAITF                   ; (Award Bios 1999 - WAIT_REFRESH,
  4359                              <1>                                         ; 40 micro seconds)
  4360 00004FC7 A0[75640100]        <1> 	mov	al,[CONTROL_BYTE]
  4361 00004FCC 240F                <1> 	AND	AL,0FH			; SET HEAD OPTION
  4362 00004FCE EE                  <1> 	OUT	DX,AL			; TURN RESET OFF
  4363 00004FCF E86A040000          <1> 	CALL	NOT_BUSY
  4364 00004FD4 7515                <1> 	JNZ	short DRERR		; TIME OUT ON RESET
  4365 00004FD6 668B15[C0670000]    <1> 	MOV	DX,[HF_PORT]
  4366 00004FDD FEC2                <1> 	inc	dl  ; HF_PORT+1
  4367                              <1> 	; 02/01/2015 - Award BIOS 1999 - AHDSK.ASM
  4368                              <1>         ;mov     cl, 10
  4369 00004FDF B90A000000          <1>         mov     ecx, 10 ; 21/02/2015 
  4370                              <1> drst1:
  4371 00004FE4 EC                  <1> 	IN	AL,DX			; GET RESET STATUS
  4372 00004FE5 3C01                <1> 	CMP	AL,1
  4373                              <1> 	; 04/01/2015
  4374 00004FE7 740A                <1> 	jz	short drst2
  4375                              <1> 	;JNZ	short DRERR		; BAD RESET STATUS
  4376                              <1>         	; Drive/Head Register - bit 4
  4377 00004FE9 E2F9                <1> 	loop	drst1
  4378                              <1> DRERR:	
  4379 00004FEB C605[73640100]05    <1> 	MOV	byte [DISK_STATUS1],BAD_RESET ; CARD FAILED
  4380 00004FF2 C3                  <1> 	RETn
  4381                              <1> drst2:
  4382                              <1> 	; 14/02/2015
  4383 00004FF3 6689FA              <1> 	mov	dx,di
  4384                              <1> ;drst3:
  4385                              <1> ;	; 05/01/2015
  4386                              <1> ;	shl 	di,1
  4387                              <1> ;	; 04/01/2015
  4388                              <1> ;	mov	ax,[di+hd_cports]
  4389                              <1> ;	cmp	ax,[HF_REG_PORT]
  4390                              <1> ;	je	short drst4
  4391                              <1> ;	mov	[HF_REG_PORT], ax
  4392                              <1> ;	; 03/01/2015
  4393                              <1> ;	mov	ax,[di+hd_ports]
  4394                              <1> ;       mov     [HF_PORT], ax
  4395                              <1> ;	; 05/01/2014
  4396                              <1> ;	shr	di,1
  4397                              <1> ;	; 04/01/2015
  4398                              <1> ;	jmp	short drst0	; reset other controller
  4399                              <1> ;drst4:
  4400                              <1> ;	; 05/01/2015
  4401                              <1> ;	shr	di,1
  4402                              <1> ;	mov	al,[di+hd_dregs]
  4403                              <1> ;	and	al,10h ; bit 4 only
  4404                              <1> ;	shr	al,4 ; bit 4  -> bit 0
  4405                              <1> ;	mov	[hf_m_s], al ; (0 = master, 1 = slave)
  4406                              <1> 	;
  4407 00004FF6 A0[C4670000]        <1> 	mov	al, [hf_m_s] ; 18/01/2015
  4408 00004FFB A801                <1> 	test	al,1
  4409                              <1> ;	jnz	short drst6
  4410 00004FFD 7516                <1>         jnz     short drst4
  4411 00004FFF 8065FDEF            <1> 	AND     byte [CMD_BLOCK+5],0EFH ; SET TO DRIVE 0
  4412                              <1> ;drst5:
  4413                              <1> drst3:
  4414 00005003 E867010000          <1> 	CALL	INIT_DRV		; SET MAX HEADS
  4415                              <1> 	;mov	dx,di
  4416 00005008 E81F020000          <1> 	CALL	HDISK_RECAL		; RECAL TO RESET SEEK SPEED
  4417                              <1> 	; 04/01/2014
  4418                              <1> ;	inc	di
  4419                              <1> ;	mov	dx,di
  4420                              <1> ;	cmp	dl,[HF_NUM]
  4421                              <1> ;	jb	short drst3
  4422                              <1> ;DRE:
  4423 0000500D C605[73640100]00    <1> 	MOV	byte [DISK_STATUS1],0 	; IGNORE ANY SET UP ERRORS
  4424 00005014 C3                  <1> 	RETn
  4425                              <1> ;drst6:
  4426                              <1> drst4:		; Drive/Head Register - bit 4
  4427 00005015 804DFD10            <1> 	OR      byte [CMD_BLOCK+5],010H ; SET TO DRIVE 1     
  4428                              <1>         ;jmp    short drst5
  4429 00005019 EBE8                <1>         jmp     short drst3
  4430                              <1> 
  4431                              <1> ;----------------------------------------
  4432                              <1> ;	DISK STATUS ROUTINE  (AH = 01H) :
  4433                              <1> ;----------------------------------------
  4434                              <1> 
  4435                              <1> RETURN_STATUS:
  4436 0000501B A0[73640100]        <1> 	MOV	AL,[DISK_STATUS1]	; OBTAIN PREVIOUS STATUS
  4437 00005020 C605[73640100]00    <1>         MOV     byte [DISK_STATUS1],0   ; RESET STATUS
  4438 00005027 C3                  <1> 	RETn
  4439                              <1> 
  4440                              <1> ;----------------------------------------
  4441                              <1> ;	DISK READ ROUTINE    (AH = 02H) :
  4442                              <1> ;----------------------------------------
  4443                              <1> 
  4444                              <1> DISK_READ:
  4445 00005028 C645FE20            <1> 	MOV	byte [CMD_BLOCK+6],READ_CMD
  4446 0000502C E986020000          <1>         JMP     COMMANDI
  4447                              <1> 
  4448                              <1> ;----------------------------------------
  4449                              <1> ;	DISK WRITE ROUTINE   (AH = 03H) :
  4450                              <1> ;----------------------------------------
  4451                              <1> 
  4452                              <1> DISK_WRITE:
  4453 00005031 C645FE30            <1> 	MOV	byte [CMD_BLOCK+6],WRITE_CMD
  4454 00005035 E9D8020000          <1>         JMP     COMMANDO
  4455                              <1> 
  4456                              <1> ;----------------------------------------
  4457                              <1> ;	DISK VERIFY	     (AH = 04H) :
  4458                              <1> ;----------------------------------------
  4459                              <1> 
  4460                              <1> DISK_VERF:
  4461 0000503A C645FE40            <1> 	MOV	byte [CMD_BLOCK+6],VERIFY_CMD
  4462 0000503E E846030000          <1> 	CALL	COMMAND
  4463 00005043 750C                <1> 	JNZ	short VERF_EXIT		; CONTROLLER STILL BUSY
  4464 00005045 E8B8030000          <1> 	CALL	_WAIT			; (Original: CALL WAIT)	
  4465 0000504A 7505                <1> 	JNZ	short VERF_EXIT		; TIME OUT
  4466 0000504C E845040000          <1> 	CALL	CHECK_STATUS
  4467                              <1> VERF_EXIT:
  4468 00005051 C3                  <1> 	RETn
  4469                              <1> 
  4470                              <1> ;----------------------------------------
  4471                              <1> ;	FORMATTING	     (AH = 05H) :
  4472                              <1> ;----------------------------------------
  4473                              <1> 
  4474                              <1> FMT_TRK:				; FORMAT TRACK	(AH = 005H)
  4475 00005052 C645FE50            <1> 	MOV	byte [CMD_BLOCK+6],FMTTRK_CMD
  4476                              <1> 	;PUSH	ES
  4477                              <1> 	;PUSH	BX
  4478 00005056 53                  <1> 	push	ebx
  4479 00005057 E8EC040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS ADDRESS
  4480                              <1> 	;MOV	AL,[ES:BX+14]		; GET SECTORS/TRACK
  4481 0000505C 8A430E              <1> 	mov	al, [ebx+14]
  4482 0000505F 8845F9              <1> 	MOV	[CMD_BLOCK+1],AL 	; SET SECTOR COUNT IN COMMAND
  4483 00005062 5B                  <1> 	pop	ebx
  4484                              <1> 	;POP	BX
  4485                              <1> 	;POP	ES
  4486 00005063 E9B1020000          <1>         JMP     CMD_OF                  ; GO EXECUTE THE COMMAND
  4487                              <1> 
  4488                              <1> ; 30/08/2020
  4489                              <1> 
  4490                              <1> ;----------------------------------------
  4491                              <1> ;	READ DASD TYPE	     (AH = 15H) :
  4492                              <1> ;----------------------------------------
  4493                              <1> 
  4494                              <1> READ_DASD_TYPE:
  4495                              <1> READ_D_T:				; GET DRIVE PARAMETERS
  4496 00005068 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  4497                              <1> 	;PUSH	ES
  4498 00005069 53                  <1> 	PUSH	eBX
  4499                              <1> 	;CALL	DDS			; ESTABLISH ADDRESSING
  4500                              <1> 	;push	cs
  4501                              <1> 	;pop	ds
  4502 0000506A 66BB1000            <1>         mov	bx, KDATA
  4503 0000506E 8EDB                <1> 	mov	ds, bx
  4504                              <1> 	;mov	es, bx
  4505 00005070 C605[73640100]00    <1> 	MOV     byte [DISK_STATUS1],0
  4506 00005077 8A1D[74640100]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  4507 0000507D 80E27F              <1> 	AND	DL,7FH			; GET DRIVE NUMBER
  4508 00005080 38D3                <1> 	CMP	BL,DL
  4509 00005082 763C                <1> 	JBE	short RDT_NOT_PRESENT 	; RETURN DRIVE NOT PRESENT
  4510 00005084 0FB6C2              <1> 	movzx	eax, dl ; 28/08/2020
  4511 00005087 E8BC040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS ADDRESS
  4512                              <1> 	
  4513                              <1> 	; 28/08/2020 - TRDOS 386 v2
  4514 0000508C F6431440            <1> 	test	byte [ebx+20], 40h	; LBA bit (bit 6)
  4515 00005090 751D                <1> 	jnz	short RDT3 ; LBA disk (may be > 8GB)
  4516                              <1> 
  4517                              <1> 	;MOV	AL,[ES:BX+2]		; HEADS
  4518 00005092 8A4302              <1> 	mov	al, [ebx+2]
  4519                              <1> 	;MOV	CL,[ES:BX+14]
  4520 00005095 8A4B0E              <1> 	mov	cl, [ebx+14]
  4521 00005098 F6E9                <1> 	IMUL	CL			; * NUMBER OF SECTORS
  4522                              <1> 	;MOV	CX,[ES:BX]		; MAX NUMBER OF CYLINDERS
  4523 0000509A 668B0B              <1> 	mov	cx, [ebx]
  4524                              <1> 	;
  4525                              <1> 	; 02/01/2015 
  4526                              <1> 	; ** leave the last cylinder as reserved for diagnostics **
  4527                              <1> 	; (Also in Award BIOS - 1999, AHDSK.ASM, FUN15 -> sub ax, 1)
  4528 0000509D 6649                <1> 	DEC	CX			; LEAVE ONE FOR DIAGNOSTICS
  4529                              <1> 	;
  4530 0000509F 66F7E9              <1> 	IMUL	CX			; NUMBER OF SECTORS
  4531 000050A2 6689D1              <1> 	MOV	CX,DX			; HIGH ORDER HALF
  4532 000050A5 6689C2              <1> 	MOV	DX,AX			; LOW ORDER HALF
  4533                              <1> 	;SUB	AX,AX
  4534                              <1> 	; 28/08/2020
  4535                              <1> 	;sub	al, al
  4536                              <1> RDT4:
  4537 000050A8 29C0                <1> 	sub	eax, eax ; 28/08/2020
  4538                              <1> 	;
  4539 000050AA B403                <1> 	MOV	AH,03H			; INDICATE FIXED DISK
  4540                              <1> 	; 30/08/2020 (clc is not needed here)
  4541                              <1> 	;and	byte [esp+8], 0FEh ; clear carry bit of eflags register
  4542                              <1> RDT2:	
  4543 000050AC 5B                  <1> 	POP	eBX			; RESTORE REGISTERS
  4544                              <1> 	;POP	ES
  4545 000050AD 1F                  <1> 	POP	DS
  4546                              <1> 	; (*) CLC			; CLEAR CARRY
  4547                              <1> 	;RETf	2
  4548                              <1> 	; (*) 29/05/2016
  4549                              <1> 	; (*) retf 4
  4550                              <1> 	; 30/08/2020 (clc is not needed here)
  4551                              <1> 	;and	byte [esp+8], 0FEh ; clear carry bit of eflags register
  4552 000050AE CF                  <1> 	iretd
  4553                              <1> 
  4554                              <1> RDT3:	; 28/08/2020
  4555                              <1> 	; (use the result of INT 13h, function 48h as disk size)
  4556                              <1> 	; eax = al = zero based hard disk number
  4557                              <1> 	; 29/08/2020
  4558                              <1> 	;add	al, 2 ; hd0 = physical disk drive 2
  4559 000050AF C0E002              <1> 	shl	al, 2 ; * 4
  4560                              <1> RDT5:
  4561                              <1> 	;add	eax, drv.size
  4562 000050B2 05[06680000]        <1> 	add	eax, drv.size+8 ; 29/08/2020
  4563 000050B7 668B10              <1> 	mov	dx, [eax]   ; low word of disk size
  4564 000050BA 668B4802            <1> 	mov	cx, [eax+2] ; high word of disk size
  4565                              <1> 	;sub	eax, eax
  4566 000050BE EBE8                <1> 	jmp	short RDT4		
  4567                              <1> 
  4568                              <1> RDT_NOT_PRESENT:
  4569                              <1> 	; 30/08/2020
  4570 000050C0 C605[73640100]AA    <1> 	mov	byte [DISK_STATUS1], NOT_RDY ; DRIVE NOT READY
  4571                              <1> 
  4572                              <1> 	;SUB	AX,AX			; DRIVE NOT PRESENT RETURN
  4573 000050C7 29C0                <1> 	sub	eax, eax ; 30/08/2020
  4574 000050C9 6689C1              <1> 	MOV	CX,AX			; ZERO BLOCK COUNT
  4575 000050CC 6689C2              <1> 	MOV	DX,AX
  4576                              <1> 	; 30/08/2020
  4577 000050CF 804C241001          <1> 	or	byte [esp+16], 1 ; set carry bit of eflags register
  4578                              <1> 		; cf = 1 -> ah = 0, drive not ready, disk type = 0
  4579 000050D4 EBD6                <1> 	JMP	short RDT2
  4580                              <1> 
  4581                              <1> ; 28/05/2016
  4582                              <1> ; 27/05/2016 - TRDOS 386 (TRDOS v2.0)
  4583                              <1> 
  4584                              <1> ;----------------------------------------
  4585                              <1> ;	GET PARAMETERS	     (AH = 08H) :
  4586                              <1> ;----------------------------------------
  4587                              <1> 
  4588                              <1> GET_PARM_N:
  4589                              <1> 	; ebx = user's buffer address for parameters table
  4590                              <1> ;GET_PARM:				; GET DRIVE PARAMETERS
  4591 000050D6 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  4592 000050D7 06                  <1> 	PUSH	ES
  4593 000050D8 53                  <1> 	PUSH	eBX
  4594                              <1> 	;MOV	AX,ABS0 		; ESTABLISH ADDRESSING
  4595                              <1> 	;MOV	DS,AX
  4596                              <1> 	;TEST	DL,1			; CHECK FOR DRIVE 1
  4597                              <1> 	;JZ	short G0
  4598                              <1> 	;LES	BX,@HF1_TBL_VEC
  4599                              <1> 	;JMP	SHORT G1
  4600                              <1> ;G0:	LES	BX,@HF_TBL_VEC
  4601                              <1> ;G1:
  4602                              <1> 	;CALL	DDS			; ESTABLISH SEGMENT
  4603                              <1> 	; 22/12/2014
  4604                              <1> 	;push	cs
  4605                              <1> 	;pop	ds
  4606 000050D9 66BB1000            <1> 	mov	bx, KDATA
  4607 000050DD 8EDB                <1> 	mov	ds, bx
  4608 000050DF 8EC3                <1> 	mov	es, bx	; 27/05/2016
  4609                              <1> 	;
  4610 000050E1 80EA80              <1> 	SUB	DL,80H
  4611                              <1> 	;CMP	DL,MAX_FILE		; TEST WITHIN RANGE
  4612                              <1> 	;JAE	short G4 ; 29/08/2020 - BugFix
  4613                              <1> 	; 30/08/2020
  4614 000050E4 3A15[74640100]      <1> 	cmp	dl, [HF_NUM] ; is hard disk index < hard disk count ?	
  4615 000050EA 736A                <1> 	jae	short G4     ; no, error ! drive not ready !	
  4616                              <1> 	;
  4617 000050EC 31DB                <1> 	xor	ebx, ebx ; 21/02/2015
  4618                              <1> 	; 22/12/2014
  4619 000050EE 88D3                <1> 	mov	bl, dl
  4620                              <1> 	;xor	bh, bh  
  4621 000050F0 C0E302              <1> 	shl	bl, 2			; convert index to offset
  4622                              <1> 	;add	bx, HF_TBL_VEC
  4623 000050F3 81C3[78640100]      <1> 	add	ebx, HF_TBL_VEC
  4624                              <1> 	;mov	ax, [bx+2]
  4625                              <1> 	;mov	es, ax			; dpt segment
  4626                              <1> 	;mov	bx, [bx]		; dpt offset
  4627 000050F9 8B1B                <1> 	mov	ebx, [ebx] ; 32 bit offset	
  4628                              <1> 
  4629 000050FB C605[73640100]00    <1> 	MOV	byte [DISK_STATUS1],0
  4630                              <1>         ;MOV	AX,[ES:BX]		; MAX NUMBER OF CYLINDERS
  4631 00005102 668B03              <1> 	mov	ax, [ebx]
  4632                              <1> 	;;SUB	AX,2			; ADJUST FOR 0-N
  4633 00005105 6648                <1> 	dec	ax			; max. cylinder number
  4634 00005107 88C5                <1> 	MOV	CH,AL
  4635 00005109 66250003            <1> 	AND	AX,0300H		; HIGH TWO BITS OF CYLINDER
  4636 0000510D 66D1E8              <1> 	SHR	AX,1
  4637 00005110 66D1E8              <1> 	SHR	AX,1
  4638                              <1> 	;OR	AL,[ES:BX+14]		; SECTORS
  4639 00005113 0A430E              <1> 	or	al, [ebx+14]
  4640 00005116 88C1                <1> 	MOV	CL,AL
  4641                              <1> 	;MOV	DH,[ES:BX+2]		; HEADS
  4642 00005118 8A7302              <1> 	mov	dh, [ebx+2]
  4643 0000511B FECE                <1> 	DEC	DH			; 0-N RANGE
  4644 0000511D 8A15[74640100]      <1> 	MOV	DL,[HF_NUM]		; DRIVE COUNT
  4645 00005123 6629C0              <1> 	SUB	AX,AX
  4646                              <1>         ;27/12/2014 
  4647                              <1> 	;mov	di, bx			; HDPT offset
  4648                              <1> 
  4649                              <1> 	; 29/08/2020
  4650 00005126 833C2400            <1> 	cmp	dword [esp], 0
  4651 0000512A 7703                <1> 	ja	short G7 ; ebx > 0
  4652                              <1> 
  4653                              <1> 	; if EBX (user's buffer address) = 0, do not copy DPT
  4654 0000512C 5B                  <1> 	pop	ebx
  4655 0000512D EB24                <1> 	jmp	short G5
  4656                              <1> G7:
  4657                              <1> 	; 27/05/2016
  4658                              <1> 	; return fixed disk parameters table to user
  4659                              <1> 	; in user's buffer, which is pointed by EBX
  4660                              <1> 	;
  4661 0000512F 873C24              <1> 	xchg	edi, [esp]		; ebx (input)-> edi, edi -> [esp]
  4662 00005132 56                  <1> 	push	esi
  4663 00005133 89DE                <1> 	mov	esi, ebx		; hard disk parameter table (32 bytes)	
  4664 00005135 89FB                <1> 	mov	ebx, edi		; ebx = user's buffer address
  4665 00005137 51                  <1> 	push	ecx
  4666 00005138 50                  <1> 	push	eax
  4667 00005139 B920000000          <1> 	mov	ecx, 32 ; 32 bytes
  4668 0000513E E84EA10000          <1> 	call	transfer_to_user_buffer ; trdosk6.s (16/05/2016)
  4669 00005143 58                  <1> 	pop	eax
  4670 00005144 59                  <1> 	pop	ecx
  4671 00005145 5E                  <1> 	pop	esi
  4672 00005146 5F                  <1> 	pop	edi
  4673 00005147 730A                <1> 	jnc	short G5
  4674                              <1> 	; 29/05/2016 (*)
  4675 00005149 B8FF000000          <1> 	mov	eax, 0FFh ; unknown error !
  4676                              <1> G6:
  4677 0000514E 804C241001          <1> 	or	byte [esp+16], 1 ; set carry bit of eflags register
  4678                              <1> G5:
  4679                              <1> 	; 27/05/2016
  4680                              <1> 	;POP	eBX			; RESTORE REGISTERS
  4681 00005153 07                  <1> 	POP	ES
  4682 00005154 1F                  <1> 	POP	DS
  4683                              <1> 	;RETf	2
  4684                              <1> 	; (*) 29/05/2016
  4685                              <1> 	; (*) retf 4
  4686                              <1> 	; (*) or byte [esp+8], 1 ; set carry bit of eflags register
  4687 00005155 CF                  <1> 	iretd
  4688                              <1> G4:
  4689 00005156 C605[73640100]07    <1> 	MOV     byte [DISK_STATUS1],INIT_FAIL ; OPERATION FAILED
  4690                              <1> 	;mov	ah, NOT_DRY ; 30/08/2020 - 'drive not ready' error code
  4691 0000515D B407                <1> 	MOV	AH,INIT_FAIL
  4692 0000515F 28C0                <1> 	SUB	AL,AL
  4693                              <1> 	;SUB	DX,DX
  4694                              <1> 	; 30/08/2020
  4695 00005161 8A15[74640100]      <1> 	mov	dl, [HF_NUM] ; disk count
  4696 00005167 28F6                <1> 	sub	dh, dh
  4697 00005169 6629C9              <1> 	SUB	CX,CX
  4698                              <1> 	; 29/05/2016 (*)
  4699                              <1> 	;STC				; SET ERROR FLAG
  4700                              <1> 	;JMP	short G5
  4701                              <1> 	; 29/08/2020 - BugFix
  4702 0000516C 5B                  <1> 	pop	ebx
  4703 0000516D EBDF                <1> 	jmp	short G6
  4704                              <1> 
  4705                              <1> ;----------------------------------------
  4706                              <1> ;	INITIALIZE DRIVE     (AH = 09H) :
  4707                              <1> ;----------------------------------------
  4708                              <1> 	; 03/01/2015
  4709                              <1> 	; According to ATA-ATAPI specification v2.0 to v5.0
  4710                              <1> 	; logical sector per logical track
  4711                              <1> 	; and logical heads - 1 would be set but
  4712                              <1> 	; it is seen as it will be good
  4713                              <1> 	; if physical parameters will be set here
  4714                              <1> 	; because, number of heads <= 16.
  4715                              <1> 	; (logical heads usually more than 16)
  4716                              <1> 	; NOTE: ATA logical parameters (software C, H, S)
  4717                              <1> 	;	== INT 13h physical parameters
  4718                              <1> 
  4719                              <1> ;INIT_DRV:
  4720                              <1> ;	MOV	byte [CMD_BLOCK+6],SET_PARM_CMD
  4721                              <1> ;	CALL	GET_VEC 		; ES:BX -> PARAMETER BLOCK
  4722                              <1> ;	MOV	AL,[ES:BX+2]		; GET NUMBER OF HEADS
  4723                              <1> ;	DEC	AL			; CONVERT TO 0-INDEX
  4724                              <1> ;	MOV	AH,[CMD_BLOCK+5] 	; GET SDH REGISTER
  4725                              <1> ;	AND	AH,0F0H 		; CHANGE HEAD NUMBER
  4726                              <1> ;	OR	AH,AL			; TO MAX HEAD
  4727                              <1> ;	MOV	[CMD_BLOCK+5],AH
  4728                              <1> ;	MOV	AL,[ES:BX+14]		; MAX SECTOR NUMBER
  4729                              <1> ;	MOV	[CMD_BLOCK+1],AL
  4730                              <1> ;	SUB	AX,AX
  4731                              <1> ;	MOV	[CMD_BLOCK+3],AL 	; ZERO FLAGS
  4732                              <1> ;	CALL	COMMAND 		; TELL CONTROLLER
  4733                              <1> ;	JNZ	short INIT_EXIT		; CONTROLLER BUSY ERROR
  4734                              <1> ;	CALL	NOT_BUSY		; WAIT FOR IT TO BE DONE
  4735                              <1> ;	JNZ	short INIT_EXIT		; TIME OUT
  4736                              <1> ;	CALL	CHECK_STATUS
  4737                              <1> ;INIT_EXIT:
  4738                              <1> ;	RETn
  4739                              <1> 
  4740                              <1> ; 04/01/2015
  4741                              <1> ; 02/01/2015 - Derived from from AWARD BIOS 1999
  4742                              <1> ;				 AHDSK.ASM - INIT_DRIVE
  4743                              <1> INIT_DRV:
  4744                              <1> 	;xor	ah,ah
  4745 0000516F 31C0                <1> 	xor	eax, eax ; 21/02/2015
  4746 00005171 B00B                <1> 	mov	al,11 ; Physical heads from translated HDPT
  4747 00005173 3825[88640100]      <1>         cmp     [LBAMode], ah   ; 0
  4748 00005179 7702                <1> 	ja	short idrv0
  4749 0000517B B002                <1> 	mov	al,2  ; Physical heads from standard HDPT
  4750                              <1> idrv0:
  4751                              <1> 	; DL = drive number (0 based)
  4752 0000517D E8C6030000          <1> 	call	GET_VEC
  4753                              <1> 	;push	bx
  4754 00005182 53                  <1> 	push	ebx ; 21/02/2015
  4755                              <1> 	;add	bx,ax
  4756 00005183 01C3                <1> 	add	ebx, eax
  4757                              <1> 	;; 05/01/2015
  4758 00005185 8A25[C4670000]      <1> 	mov	ah, [hf_m_s] ; drive number (0= master, 1= slave)
  4759                              <1> 	;;and 	ah,1 
  4760 0000518B C0E404              <1> 	shl	ah,4
  4761 0000518E 80CCA0              <1> 	or	ah,0A0h  ; Drive/Head register - 10100000b (A0h)	
  4762                              <1> 	;mov	al,[es:bx]
  4763 00005191 8A03                <1> 	mov	al, [ebx] ; 21/02/2015
  4764 00005193 FEC8                <1> 	dec	al	 ; last head number 
  4765                              <1> 	;and	al,0Fh
  4766 00005195 08E0                <1> 	or	al,ah	 ; lower 4 bits for head number
  4767                              <1> 	;
  4768 00005197 C645FE91            <1> 	mov	byte [CMD_BLOCK+6],SET_PARM_CMD
  4769 0000519B 8845FD              <1> 	mov	[CMD_BLOCK+5],al
  4770                              <1> 	;pop	bx
  4771 0000519E 5B                  <1> 	pop	ebx
  4772 0000519F 29C0                <1> 	sub	eax, eax ; 21/02/2015
  4773 000051A1 B004                <1> 	mov	al,4 ; Physical sec per track from translated HDPT
  4774 000051A3 803D[88640100]00    <1> 	cmp	byte [LBAMode], 0
  4775 000051AA 7702                <1> 	ja	short idrv1
  4776 000051AC B00E                <1> 	mov	al,14 ; Physical sec per track from standard HDPT
  4777                              <1> idrv1:
  4778                              <1> 	;xor	ah,ah
  4779                              <1> 	;add	bx,ax
  4780 000051AE 01C3                <1> 	add	ebx, eax ; 21/02/2015
  4781                              <1> 	;mov	al,[es:bx]
  4782                              <1> 			; sector number
  4783 000051B0 8A03                <1> 	mov	al, [ebx]
  4784 000051B2 8845F9              <1> 	mov	[CMD_BLOCK+1],al
  4785 000051B5 28C0                <1> 	sub	al,al
  4786 000051B7 8845FB              <1> 	mov	[CMD_BLOCK+3],al  ; ZERO FLAGS
  4787 000051BA E8CA010000          <1> 	call	COMMAND 	  ; TELL CONTROLLER
  4788 000051BF 750C                <1> 	jnz	short INIT_EXIT	  ; CONTROLLER BUSY ERROR
  4789 000051C1 E878020000          <1> 	call	NOT_BUSY	  ; WAIT FOR IT TO BE DONE
  4790 000051C6 7505                <1> 	jnz	short INIT_EXIT	  ; TIME OUT
  4791 000051C8 E8C9020000          <1> 	call	CHECK_STATUS
  4792                              <1> INIT_EXIT:
  4793 000051CD C3                  <1> 	RETn
  4794                              <1> 
  4795                              <1> ;----------------------------------------
  4796                              <1> ;	READ LONG	     (AH = 0AH) :
  4797                              <1> ;----------------------------------------
  4798                              <1> 
  4799                              <1> RD_LONG:
  4800                              <1> 	;MOV	@CMD_BLOCK+6,READ_CMD OR ECC_MODE
  4801 000051CE C645FE22            <1>         mov     byte [CMD_BLOCK+6],READ_CMD + ECC_MODE 
  4802 000051D2 E9E0000000          <1>         JMP     COMMANDI
  4803                              <1> 
  4804                              <1> ;----------------------------------------
  4805                              <1> ;	WRITE LONG	     (AH = 0BH) :
  4806                              <1> ;----------------------------------------
  4807                              <1> 
  4808                              <1> WR_LONG:
  4809                              <1> 	;MOV	@CMD_BLOCK+6,WRITE_CMD OR ECC_MODE
  4810 000051D7 C645FE32            <1>         MOV     byte [CMD_BLOCK+6],WRITE_CMD + ECC_MODE
  4811 000051DB E932010000          <1>         JMP     COMMANDO
  4812                              <1> 
  4813                              <1> ;----------------------------------------
  4814                              <1> ;	SEEK		     (AH = 0CH) :
  4815                              <1> ;----------------------------------------
  4816                              <1> 
  4817                              <1> DISK_SEEK:
  4818 000051E0 C645FE70            <1>         MOV     byte [CMD_BLOCK+6],SEEK_CMD
  4819 000051E4 E8A0010000          <1> 	CALL	COMMAND
  4820 000051E9 751C                <1> 	JNZ	short DS_EXIT 		; CONTROLLER BUSY ERROR
  4821 000051EB E812020000          <1> 	CALL	_WAIT
  4822 000051F0 7515                <1>         JNZ     DS_EXIT                 ; TIME OUT ON SEEK
  4823 000051F2 E89F020000          <1> 	CALL	CHECK_STATUS
  4824 000051F7 803D[73640100]40    <1>         CMP     byte [DISK_STATUS1],BAD_SEEK
  4825 000051FE 7507                <1> 	JNE	short DS_EXIT
  4826 00005200 C605[73640100]00    <1>         MOV     byte [DISK_STATUS1],0
  4827                              <1> DS_EXIT:
  4828 00005207 C3                  <1> 	RETn
  4829                              <1> 
  4830                              <1> ;----------------------------------------
  4831                              <1> ;	TEST DISK READY      (AH = 10H) :
  4832                              <1> ;----------------------------------------
  4833                              <1> 
  4834                              <1> TST_RDY:				; WAIT FOR CONTROLLER
  4835 00005208 E831020000          <1> 	CALL	NOT_BUSY
  4836 0000520D 751C                <1> 	JNZ	short TR_EX
  4837 0000520F 8A45FD              <1> 	MOV	AL,[CMD_BLOCK+5] 	; SELECT DRIVE
  4838 00005212 668B15[C0670000]    <1> 	MOV	DX,[HF_PORT]
  4839 00005219 80C206              <1> 	add	dl,6
  4840 0000521C EE                  <1> 	OUT	DX,AL
  4841 0000521D E88C020000          <1> 	CALL	CHECK_ST		; CHECK STATUS ONLY
  4842 00005222 7507                <1> 	JNZ	short TR_EX
  4843 00005224 C605[73640100]00    <1> 	MOV	byte [DISK_STATUS1],0 	; WIPE OUT DATA CORRECTED ERROR
  4844                              <1> TR_EX:	
  4845 0000522B C3                  <1> 	RETn
  4846                              <1> 
  4847                              <1> ;----------------------------------------
  4848                              <1> ;	RECALIBRATE	     (AH = 11H) :
  4849                              <1> ;----------------------------------------
  4850                              <1> 
  4851                              <1> HDISK_RECAL:
  4852 0000522C C645FE10            <1>         MOV     byte [CMD_BLOCK+6],RECAL_CMD ; 10h, 16
  4853 00005230 E854010000          <1> 	CALL	COMMAND 		; START THE OPERATION
  4854 00005235 7523                <1> 	JNZ	short RECAL_EXIT	; ERROR
  4855 00005237 E8C6010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION
  4856 0000523C 7407                <1> 	JZ	short RECAL_X 		; TIME OUT ONE OK ?
  4857 0000523E E8BF010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION LONGER
  4858 00005243 7515                <1> 	JNZ	short RECAL_EXIT	; TIME OUT TWO TIMES IS ERROR
  4859                              <1> RECAL_X:
  4860 00005245 E84C020000          <1> 	CALL	CHECK_STATUS
  4861 0000524A 803D[73640100]40    <1> 	CMP	byte [DISK_STATUS1],BAD_SEEK ; SEEK NOT COMPLETE
  4862 00005251 7507                <1> 	JNE	short RECAL_EXIT	; IS OK
  4863 00005253 C605[73640100]00    <1> 	MOV	byte [DISK_STATUS1],0
  4864                              <1> RECAL_EXIT:
  4865 0000525A 803D[73640100]00    <1>         CMP     byte [DISK_STATUS1],0
  4866 00005261 C3                  <1> 	RETn
  4867                              <1> 
  4868                              <1> ;----------------------------------------
  4869                              <1> ;      CONTROLLER DIAGNOSTIC (AH = 14H) :
  4870                              <1> ;----------------------------------------
  4871                              <1> 
  4872                              <1> CTLR_DIAGNOSTIC:
  4873 00005262 FA                  <1>         CLI                             ; DISABLE INTERRUPTS WHILE CHANGING MASK
  4874 00005263 E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  4875                              <1> 	;AND	AL,0BFH
  4876 00005265 243F                <1> 	and	al, 3Fh			; enable IRQ 14 & IRQ 15
  4877                              <1> 	;JMP	$+2
  4878                              <1> 	IODELAY
  4878 00005267 EB00                <2>  jmp short $+2
  4878 00005269 EB00                <2>  jmp short $+2
  4879 0000526B E6A1                <1> 	OUT	INTB01,AL
  4880                              <1> 	IODELAY
  4880 0000526D EB00                <2>  jmp short $+2
  4880 0000526F EB00                <2>  jmp short $+2
  4881 00005271 E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  4882 00005273 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  4883                              <1> 	;JMP	$+2
  4884                              <1> 	IODELAY
  4884 00005275 EB00                <2>  jmp short $+2
  4884 00005277 EB00                <2>  jmp short $+2
  4885 00005279 E621                <1> 	OUT	INTA01,AL
  4886 0000527B FB                  <1> 	STI
  4887 0000527C E8BD010000          <1> 	CALL	NOT_BUSY		; WAIT FOR CARD
  4888 00005281 752B                <1> 	JNZ	short CD_ERR		; BAD CARD
  4889                              <1> 	;MOV	DX, HF_PORT+7
  4890 00005283 668B15[C0670000]    <1> 	mov	dx, [HF_PORT]
  4891 0000528A 80C207              <1> 	add	dl, 7
  4892 0000528D B090                <1> 	MOV	AL,DIAG_CMD		; START DIAGNOSE
  4893 0000528F EE                  <1> 	OUT	DX,AL
  4894 00005290 E8A9010000          <1> 	CALL	NOT_BUSY		; WAIT FOR IT TO COMPLETE
  4895 00005295 B480                <1> 	MOV	AH,TIME_OUT
  4896 00005297 7517                <1> 	JNZ	short CD_EXIT 		; TIME OUT ON DIAGNOSTIC
  4897                              <1> 	;MOV	DX,HF_PORT+1		; GET ERROR REGISTER
  4898 00005299 668B15[C0670000]    <1> 	mov	dx, [HF_PORT]
  4899 000052A0 FEC2                <1> 	inc	dl
  4900 000052A2 EC                  <1> 	IN	AL,DX
  4901 000052A3 A2[6A640100]        <1> 	MOV	[HF_ERROR],AL		; SAVE IT
  4902 000052A8 B400                <1> 	MOV	AH,0
  4903 000052AA 3C01                <1> 	CMP	AL,1			; CHECK FOR ALL OK
  4904 000052AC 7402                <1> 	JE	SHORT CD_EXIT
  4905 000052AE B420                <1> CD_ERR: MOV	AH,BAD_CNTLR
  4906                              <1> CD_EXIT:
  4907 000052B0 8825[73640100]      <1> 	MOV	[DISK_STATUS1],AH
  4908 000052B6 C3                  <1> 	RETn
  4909                              <1> 
  4910                              <1> ;----------------------------------------
  4911                              <1> ; COMMANDI				:
  4912                              <1> ;	REPEATEDLY INPUTS DATA TILL	:
  4913                              <1> ;	NSECTOR RETURNS ZERO		:
  4914                              <1> ;----------------------------------------
  4915                              <1> COMMANDI:
  4916 000052B7 E862020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  4917 000052BC 7253                <1> 	JC	short CMD_ABORT
  4918                              <1> 	;MOV	DI,BX
  4919 000052BE 89DF                <1> 	mov	edi, ebx ; 21/02/2015
  4920 000052C0 E8C4000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  4921 000052C5 754A                <1> 	JNZ	short CMD_ABORT
  4922                              <1> CMD_I1:
  4923 000052C7 E836010000          <1> 	CALL	_WAIT			; WAIT FOR DATA REQUEST INTERRUPT
  4924 000052CC 7543                <1> 	JNZ	short TM_OUT		; TIME OUT
  4925                              <1> cmd_i1x: ; 18/02/2016
  4926                              <1> 	;MOV	CX,256			; SECTOR SIZE IN WORDS
  4927 000052CE B900010000          <1> 	mov	ecx, 256 ; 21/02/2015	
  4928                              <1> 	;MOV	DX,HF_PORT
  4929 000052D3 668B15[C0670000]    <1> 	mov	dx,[HF_PORT]
  4930 000052DA FA                  <1> 	CLI
  4931 000052DB FC                  <1> 	CLD
  4932 000052DC F3666D              <1> 	REP	INSW			; GET THE SECTOR
  4933 000052DF FB                  <1> 	STI
  4934 000052E0 F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL INPUT
  4935 000052E4 7419                <1> 	JZ	short CMD_I3
  4936 000052E6 E880010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4937 000052EB 7224                <1> 	JC	short TM_OUT
  4938                              <1> 	;MOV	DX,HF_PORT
  4939 000052ED 668B15[C0670000]    <1> 	mov	dx,[HF_PORT]
  4940                              <1> 	;MOV	CX,4			; GET ECC BYTES
  4941 000052F4 B904000000          <1> 	mov 	ecx, 4 ; mov cx, 4 
  4942 000052F9 EC                  <1> CMD_I2: IN	AL,DX
  4943                              <1> 	;MOV	[ES:DI],AL		; GO SLOW FOR BOARD
  4944 000052FA 8807                <1> 	mov 	[edi], al ; 21/02/2015
  4945 000052FC 47                  <1> 	INC	eDI
  4946 000052FD E2FA                <1> 	LOOP	CMD_I2
  4947                              <1> CMD_I3: 
  4948                              <1> 	; wait for 400 ns
  4949 000052FF 80C207              <1> 	add 	dl, 7
  4950 00005302 EC                  <1> 	in	al, dx
  4951 00005303 EC                  <1> 	in	al, dx
  4952 00005304 EC                  <1> 	in	al, dx
  4953                              <1> 	;
  4954 00005305 E88C010000          <1> 	CALL	CHECK_STATUS
  4955 0000530A 7505                <1> 	JNZ	short CMD_ABORT		; ERROR RETURNED
  4956 0000530C FE4DF9              <1> 	DEC	byte [CMD_BLOCK+1]	; CHECK FOR MORE
  4957                              <1> 	;JNZ	SHORT CMD_I1
  4958 0000530F 75BD                <1> 	jnz	short cmd_i1x ; 18/02/2016
  4959                              <1> CMD_ABORT:
  4960 00005311 C3                  <1> TM_OUT: RETn
  4961                              <1> 
  4962                              <1> ;----------------------------------------
  4963                              <1> ; COMMANDO				:
  4964                              <1> ;	REPEATEDLY OUTPUTS DATA TILL	:
  4965                              <1> ;	NSECTOR RETURNS ZERO		:
  4966                              <1> ;----------------------------------------
  4967                              <1> COMMANDO:
  4968 00005312 E807020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  4969 00005317 72F8                <1> 	JC	short CMD_ABORT
  4970 00005319 89DE                <1> CMD_OF: MOV	eSI,eBX ; 21/02/2015
  4971 0000531B E869000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  4972 00005320 75EF                <1> 	JNZ	short CMD_ABORT
  4973 00005322 E844010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4974 00005327 72E8                <1> 	JC	short TM_OUT			; TOO LONG
  4975                              <1> CMD_O1: ;PUSH	DS
  4976                              <1> 	;PUSH	ES			; MOVE ES TO DS
  4977                              <1> 	;POP	DS
  4978                              <1> 	;MOV	CX,256			; PUT THE DATA OUT TO THE CARD
  4979                              <1> 	;MOV	DX,HF_PORT
  4980                              <1> 	; 01/02/2015
  4981 00005329 668B15[C0670000]    <1> 	mov	dx, [HF_PORT]
  4982                              <1> 	;push	es
  4983                              <1> 	;pop	ds
  4984                              <1> 	;mov	cx, 256
  4985 00005330 B900010000          <1> 	mov	ecx, 256 ; 21/02/2015
  4986 00005335 FA                  <1> 	CLI
  4987 00005336 FC                  <1> 	CLD
  4988 00005337 F3666F              <1> 	REP	OUTSW
  4989 0000533A FB                  <1> 	STI
  4990                              <1> 	;POP	DS			; RESTORE DS
  4991 0000533B F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL OUTPUT
  4992 0000533F 7419                <1> 	JZ	short CMD_O3
  4993 00005341 E825010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4994 00005346 72C9                <1> 	JC	short TM_OUT
  4995                              <1> 	;MOV	DX,HF_PORT
  4996 00005348 668B15[C0670000]    <1> 	mov	dx, [HF_PORT]
  4997                              <1> 	;MOV	CX,4			; OUTPUT THE ECC BYTES
  4998 0000534F B904000000          <1> 	mov	ecx, 4  ; mov cx, 4
  4999                              <1> CMD_O2: ;MOV	AL,[ES:SI]
  5000 00005354 8A06                <1> 	mov	al, [esi]
  5001 00005356 EE                  <1> 	OUT	DX,AL
  5002 00005357 46                  <1> 	INC	eSI
  5003 00005358 E2FA                <1> 	LOOP	CMD_O2
  5004                              <1> CMD_O3:
  5005 0000535A E8A3000000          <1> 	CALL	_WAIT			; WAIT FOR SECTOR COMPLETE INTERRUPT
  5006 0000535F 75B0                <1> 	JNZ	short TM_OUT		; ERROR RETURNED
  5007 00005361 E830010000          <1> 	CALL	CHECK_STATUS
  5008 00005366 75A9                <1> 	JNZ	short CMD_ABORT
  5009 00005368 F605[69640100]08    <1> 	TEST	byte [HF_STATUS],ST_DRQ	; CHECK FOR MORE
  5010 0000536F 75B8                <1> 	JNZ	SHORT CMD_O1
  5011                              <1> 	;MOV	DX,HF_PORT+2		; CHECK RESIDUAL SECTOR COUNT
  5012 00005371 668B15[C0670000]    <1> 	mov	dx, [HF_PORT]
  5013                              <1> 	;add	dl, 2
  5014 00005378 FEC2                <1> 	inc	dl
  5015 0000537A FEC2                <1> 	inc	dl
  5016 0000537C EC                  <1> 	IN	AL,DX			;
  5017 0000537D A8FF                <1> 	TEST	AL,0FFH 		;
  5018 0000537F 7407                <1> 	JZ	short CMD_O4			; COUNT = 0  OK
  5019 00005381 C605[73640100]BB    <1> 	MOV	byte [DISK_STATUS1],UNDEF_ERR 
  5020                              <1> 					; OPERATION ABORTED - PARTIAL TRANSFER
  5021                              <1> CMD_O4:
  5022 00005388 C3                  <1> 	RETn
  5023                              <1> 
  5024                              <1> ;--------------------------------------------------------
  5025                              <1> ; COMMAND						:
  5026                              <1> ;	THIS ROUTINE OUTPUTS THE COMMAND BLOCK		:
  5027                              <1> ; OUTPUT						:
  5028                              <1> ;	BL = STATUS					:
  5029                              <1> ;	BH = ERROR REGISTER				:
  5030                              <1> ;--------------------------------------------------------
  5031                              <1> 
  5032                              <1> COMMAND:
  5033 00005389 53                  <1> 	PUSH	eBX			; WAIT FOR SEEK COMPLETE AND READY
  5034                              <1> 	;;MOV	CX,DELAY_2		; SET INITIAL DELAY BEFORE TEST
  5035                              <1> COMMAND1:
  5036                              <1> 	;;PUSH	CX			; SAVE LOOP COUNT
  5037 0000538A E879FEFFFF          <1> 	CALL	TST_RDY 		; CHECK DRIVE READY
  5038                              <1> 	;;POP	CX
  5039 0000538F 7419                <1> 	JZ	short COMMAND2		; DRIVE IS READY
  5040 00005391 803D[73640100]80    <1>         CMP     byte [DISK_STATUS1],TIME_OUT ; TST_RDY TIMED OUT--GIVE UP
  5041                              <1> 	;JZ	short CMD_TIMEOUT
  5042                              <1> 	;;LOOP	COMMAND1		; KEEP TRYING FOR A WHILE
  5043                              <1> 	;JMP	SHORT COMMAND4		; ITS NOT GOING TO GET READY
  5044 00005398 7507                <1> 	jne	short COMMAND4
  5045                              <1> CMD_TIMEOUT:
  5046 0000539A C605[73640100]20    <1> 	MOV	byte [DISK_STATUS1],BAD_CNTLR
  5047                              <1> COMMAND4:
  5048 000053A1 5B                  <1> 	POP	eBX
  5049 000053A2 803D[73640100]00    <1>         CMP     byte [DISK_STATUS1],0   ; SET CONDITION CODE FOR CALLER
  5050 000053A9 C3                  <1> 	RETn
  5051                              <1> COMMAND2:
  5052 000053AA 5B                  <1> 	POP	eBX
  5053 000053AB 57                  <1> 	PUSH	eDI
  5054 000053AC C605[6B640100]00    <1> 	MOV	byte [HF_INT_FLAG],0	; RESET INTERRUPT FLAG
  5055 000053B3 FA                  <1> 	CLI				; INHIBIT INTERRUPTS WHILE CHANGING MASK
  5056 000053B4 E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  5057                              <1> 	;AND	AL,0BFH
  5058 000053B6 243F                <1> 	and	al, 3Fh			; Enable IRQ 14 & 15
  5059                              <1> 	;JMP	$+2
  5060                              <1> 	IODELAY
  5060 000053B8 EB00                <2>  jmp short $+2
  5060 000053BA EB00                <2>  jmp short $+2
  5061 000053BC E6A1                <1> 	OUT	INTB01,AL
  5062 000053BE E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  5063 000053C0 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  5064                              <1> 	;JMP	$+2
  5065                              <1> 	IODELAY
  5065 000053C2 EB00                <2>  jmp short $+2
  5065 000053C4 EB00                <2>  jmp short $+2
  5066 000053C6 E621                <1> 	OUT	INTA01,AL
  5067 000053C8 FB                  <1> 	STI
  5068 000053C9 31FF                <1> 	XOR	eDI,eDI			; INDEX THE COMMAND TABLE
  5069                              <1> 	;MOV	DX,HF_PORT+1		; DISK ADDRESS
  5070 000053CB 668B15[C0670000]    <1> 	mov	dx, [HF_PORT]
  5071 000053D2 FEC2                <1> 	inc	dl
  5072 000053D4 F605[75640100]C0    <1> 	TEST	byte [CONTROL_BYTE],0C0H ; CHECK FOR RETRY SUPPRESSION
  5073 000053DB 7411                <1> 	JZ	short COMMAND3
  5074 000053DD 8A45FE              <1> 	MOV	AL, [CMD_BLOCK+6] 	; YES-GET OPERATION CODE
  5075 000053E0 24F0                <1> 	AND	AL,0F0H 		; GET RID OF MODIFIERS
  5076 000053E2 3C20                <1> 	CMP	AL,20H			; 20H-40H IS READ, WRITE, VERIFY
  5077 000053E4 7208                <1> 	JB	short COMMAND3
  5078 000053E6 3C40                <1> 	CMP	AL,40H
  5079 000053E8 7704                <1> 	JA	short COMMAND3
  5080 000053EA 804DFE01            <1> 	OR	byte [CMD_BLOCK+6],NO_RETRIES 
  5081                              <1> 					; VALID OPERATION FOR RETRY SUPPRESS
  5082                              <1> COMMAND3:
  5083 000053EE 8A443DF8            <1> 	MOV	AL,[CMD_BLOCK+eDI]	; GET THE COMMAND STRING BYTE
  5084 000053F2 EE                  <1> 	OUT	DX,AL			; GIVE IT TO CONTROLLER
  5085                              <1> 	IODELAY
  5085 000053F3 EB00                <2>  jmp short $+2
  5085 000053F5 EB00                <2>  jmp short $+2
  5086 000053F7 47                  <1> 	INC	eDI			; NEXT BYTE IN COMMAND BLOCK
  5087 000053F8 6642                <1> 	INC	DX			; NEXT DISK ADAPTER REGISTER
  5088 000053FA 6683FF07            <1> 	cmp	di, 7	; 1/1/2015	; ALL DONE?
  5089 000053FE 75EE                <1> 	JNZ	short COMMAND3		; NO--GO DO NEXT ONE
  5090 00005400 5F                  <1> 	POP	eDI
  5091 00005401 C3                  <1> 	RETn				; ZERO FLAG IS SET
  5092                              <1> 
  5093                              <1> ;CMD_TIMEOUT:
  5094                              <1> ;	MOV	byte [DISK_STATUS1],BAD_CNTLR
  5095                              <1> ;COMMAND4:
  5096                              <1> ;	POP	BX
  5097                              <1> ;	CMP	[DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  5098                              <1> ;	RETn
  5099                              <1> 
  5100                              <1> ;----------------------------------------
  5101                              <1> ;	WAIT FOR INTERRUPT		:
  5102                              <1> ;----------------------------------------
  5103                              <1> ;WAIT:
  5104                              <1> _WAIT:
  5105 00005402 FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  5106                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  5107                              <1> 	;CLC
  5108                              <1> 	;MOV	AX,9000H		; DEVICE WAIT INTERRUPT
  5109                              <1> 	;INT	15H
  5110                              <1> 	;JC	WT2			; DEVICE TIMED OUT
  5111                              <1> 	;MOV	BL,DELAY_1		; SET DELAY COUNT
  5112                              <1> 
  5113                              <1> 	;mov	bl, WAIT_HDU_INT_HI
  5114                              <1> 	;; 21/02/2015
  5115                              <1> 	;;mov	bl, WAIT_HDU_INT_HI + 1
  5116                              <1> 	;;mov	cx, WAIT_HDU_INT_LO
  5117 00005403 B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH
  5118                              <1> 					; (AWARD BIOS -> WAIT_FOR_MEM)
  5119                              <1> ;-----	WAIT LOOP
  5120                              <1> 
  5121                              <1> WT1:	
  5122                              <1> 	;TEST	byte [HF_INT_FLAG],80H	; TEST FOR INTERRUPT
  5123 00005408 F605[6B640100]C0    <1> 	test 	byte [HF_INT_FLAG],0C0h
  5124                              <1> 	;LOOPZ	WT1
  5125 0000540F 7517                <1> 	JNZ	short WT3		; INTERRUPT--LETS GO
  5126                              <1> 	;DEC	BL
  5127                              <1> 	;JNZ	short WT1		; KEEP TRYING FOR A WHILE
  5128                              <1> 
  5129                              <1> WT1_hi:
  5130 00005411 E461                <1> 	in	al, SYS1 ; 61h (PORT_B)	; wait for lo to hi
  5131 00005413 A810                <1> 	test	al, 10h			; transition on memory
  5132 00005415 75FA                <1> 	jnz	short WT1_hi		; refresh.
  5133                              <1> WT1_lo:
  5134 00005417 E461                <1> 	in	al, SYS1 		; 061h (PORT_B)	
  5135 00005419 A810                <1> 	test	al, 10h			
  5136 0000541B 74FA                <1> 	jz	short WT1_lo
  5137 0000541D E2E9                <1> 	loop	WT1
  5138                              <1> 	;;or	bl, bl
  5139                              <1> 	;;jz	short WT2	
  5140                              <1> 	;;dec	bl
  5141                              <1> 	;;jmp	short WT1
  5142                              <1> 	;dec	bl
  5143                              <1> 	;jnz	short WT1	
  5144                              <1> 
  5145 0000541F C605[73640100]80    <1> WT2:	MOV	byte [DISK_STATUS1],TIME_OUT ; REPORT TIME OUT ERROR
  5146 00005426 EB0E                <1> 	JMP	SHORT WT4
  5147 00005428 C605[73640100]00    <1> WT3:	MOV	byte [DISK_STATUS1],0
  5148 0000542F C605[6B640100]00    <1> 	MOV	byte [HF_INT_FLAG],0
  5149 00005436 803D[73640100]00    <1> WT4:	CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  5150 0000543D C3                  <1> 	RETn
  5151                              <1> 
  5152                              <1> ;----------------------------------------
  5153                              <1> ;	WAIT FOR CONTROLLER NOT BUSY	:
  5154                              <1> ;----------------------------------------
  5155                              <1> NOT_BUSY:
  5156 0000543E FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  5157                              <1> 	;PUSH	eBX
  5158                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  5159 0000543F 668B15[C0670000]    <1> 	mov	DX, [HF_PORT]
  5160 00005446 80C207              <1> 	add	dl, 7			; Status port (HF_PORT+7)
  5161                              <1> 	;MOV	BL,DELAY_1
  5162                              <1> 					; wait for 10 seconds
  5163                              <1> 	;mov 	cx, WAIT_HDU_INT_LO	; 1615h
  5164                              <1> 	;;mov 	bl, WAIT_HDU_INT_HI	;   05h
  5165                              <1> 	;mov	bl, WAIT_HDU_INT_HI + 1
  5166 00005449 B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH  ; 21/02/2015
  5167                              <1> 	;
  5168                              <1> ;;      mov     byte [wait_count], 0    ; Reset wait counter
  5169                              <1> NB1:	
  5170 0000544E EC                  <1> 	IN	AL,DX			; CHECK STATUS
  5171                              <1> 	;TEST	AL,ST_BUSY
  5172 0000544F 2480                <1> 	and	al, ST_BUSY
  5173                              <1> 	;LOOPNZ	NB1
  5174 00005451 7410                <1> 	JZ	short NB2		; NOT BUSY--LETS GO
  5175                              <1> 	;DEC	BL			
  5176                              <1> 	;JNZ	short NB1		; KEEP TRYING FOR A WHILE
  5177                              <1> 
  5178 00005453 E461                <1> NB1_hi: IN	AL,SYS1			; wait for hi to lo
  5179 00005455 A810                <1> 	TEST	AL,010H			; transition on memory
  5180 00005457 75FA                <1> 	JNZ	SHORT NB1_hi		; refresh.
  5181 00005459 E461                <1> NB1_lo: IN	AL,SYS1
  5182 0000545B A810                <1> 	TEST	AL,010H
  5183 0000545D 74FA                <1> 	JZ	short NB1_lo
  5184 0000545F E2ED                <1> 	LOOP	NB1
  5185                              <1> 	;dec	bl
  5186                              <1> 	;jnz	short NB1
  5187                              <1> 	;
  5188                              <1> ;;      cmp     byte [wait_count], 182  ; 10 seconds (182 timer ticks)
  5189                              <1> ;;	jb	short NB1
  5190                              <1> 	;
  5191                              <1> 	;MOV	[DISK_STATUS1],TIME_OUT	; REPORT TIME OUT ERROR
  5192                              <1> 	;JMP	SHORT NB3
  5193 00005461 B080                <1> 	mov	al, TIME_OUT
  5194                              <1> NB2:	
  5195                              <1> 	;MOV	byte [DISK_STATUS1],0
  5196                              <1> ;NB3:	
  5197                              <1> 	;POP	eBX
  5198 00005463 A2[73640100]        <1> 	mov	[DISK_STATUS1], al	;;; will be set after return
  5199                              <1> 	;CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  5200 00005468 08C0                <1> 	or	al, al			; (zf = 0 --> timeout)
  5201 0000546A C3                  <1> 	RETn
  5202                              <1> 
  5203                              <1> ;----------------------------------------
  5204                              <1> ;	WAIT FOR DATA REQUEST		:
  5205                              <1> ;----------------------------------------
  5206                              <1> WAIT_DRQ:
  5207                              <1> 	;MOV	CX,DELAY_3
  5208                              <1> 	;MOV	DX,HF_PORT+7
  5209 0000546B 668B15[C0670000]    <1> 	mov	dx, [HF_PORT]
  5210 00005472 80C207              <1> 	add	dl, 7
  5211                              <1> 	;;MOV	bl, WAIT_HDU_DRQ_HI	; 0
  5212                              <1> 	;MOV	cx, WAIT_HDU_DRQ_LO	; 1000 (30 milli seconds)
  5213                              <1> 					; (but it is written as 2000
  5214                              <1> 					; micro seconds in ATORGS.ASM file
  5215                              <1> 					; of Award Bios - 1999, D1A0622)
  5216 00005475 B9E8030000          <1> 	mov 	ecx, WAIT_HDU_DRQ_LH ; 21/02/2015 
  5217 0000547A EC                  <1> WQ_1:	IN	AL,DX			; GET STATUS
  5218 0000547B A808                <1> 	TEST	AL,ST_DRQ		; WAIT FOR DRQ
  5219 0000547D 7516                <1> 	JNZ	short WQ_OK
  5220                              <1> 	;LOOP	WQ_1			; KEEP TRYING FOR A SHORT WHILE
  5221                              <1> WQ_hi:	
  5222 0000547F E461                <1> 	IN	AL,SYS1			; wait for hi to lo
  5223 00005481 A810                <1> 	TEST	AL,010H			; transition on memory
  5224 00005483 75FA                <1> 	JNZ	SHORT WQ_hi		; refresh.
  5225 00005485 E461                <1> WQ_lo:  IN      AL,SYS1
  5226 00005487 A810                <1> 	TEST	AL,010H
  5227 00005489 74FA                <1> 	JZ	SHORT WQ_lo
  5228 0000548B E2ED                <1> 	LOOP	WQ_1
  5229                              <1> 
  5230 0000548D C605[73640100]80    <1>         MOV     byte [DISK_STATUS1],TIME_OUT ; ERROR
  5231 00005494 F9                  <1> 	STC
  5232                              <1> WQ_OK:
  5233 00005495 C3                  <1> 	RETn
  5234                              <1> ;WQ_OK:	;CLC
  5235                              <1> ;	RETn
  5236                              <1> 
  5237                              <1> ;----------------------------------------
  5238                              <1> ;	CHECK FIXED DISK STATUS 	:
  5239                              <1> ;----------------------------------------
  5240                              <1> CHECK_STATUS:
  5241 00005496 E813000000          <1> 	CALL	CHECK_ST		; CHECK THE STATUS BYTE
  5242 0000549B 7509                <1> 	JNZ	short CHECK_S1		; AN ERROR WAS FOUND
  5243 0000549D A801                <1> 	TEST	AL,ST_ERROR		; WERE THERE ANY OTHER ERRORS
  5244 0000549F 7405                <1> 	JZ	short CHECK_S1		; NO ERROR REPORTED
  5245 000054A1 E849000000          <1> 	CALL	CHECK_ER		; ERROR REPORTED
  5246                              <1> CHECK_S1:
  5247 000054A6 803D[73640100]00    <1> 	CMP	byte [DISK_STATUS1],0 	; SET STATUS FOR CALLER
  5248 000054AD C3                  <1> 	RETn
  5249                              <1> 
  5250                              <1> ;----------------------------------------
  5251                              <1> ;	CHECK FIXED DISK STATUS BYTE	:
  5252                              <1> ;----------------------------------------
  5253                              <1> CHECK_ST:
  5254                              <1> 	;MOV	DX,HF_PORT+7		; GET THE STATUS
  5255 000054AE 668B15[C0670000]    <1> 	mov	dx, [HF_PORT]
  5256 000054B5 80C207              <1> 	add	dl, 7
  5257                              <1> 	
  5258                              <1> 	; 17/02/2016
  5259                              <1> 	;(http://wiki.osdev.org/ATA_PIO_Mode)
  5260                              <1> 	;"delay 400ns to allow drive to set new values of BSY and DRQ"
  5261 000054B8 EC                  <1> 	IN	AL,DX
  5262                              <1> 	;in	al, dx ; 100ns
  5263                              <1> 	;in	al, dx ; 100ns
  5264                              <1>  	;in	al, dx ; 100ns
  5265                              <1> 	NEWIODELAY ; 18/02/2016 (AWARD BIOS - 1999, 'CKST' in AHSDK.ASM)
  5265 000054B9 E6EB                <2>  out 0ebh,al
  5266                              <1> 	;
  5267 000054BB A2[69640100]        <1> 	MOV	[HF_STATUS],AL
  5268 000054C0 B400                <1> 	MOV	AH,0
  5269 000054C2 A880                <1> 	TEST	AL,ST_BUSY		; IF STILL BUSY
  5270 000054C4 751A                <1> 	JNZ	short CKST_EXIT		;  REPORT OK
  5271 000054C6 B4CC                <1> 	MOV	AH,WRITE_FAULT
  5272 000054C8 A820                <1> 	TEST	AL,ST_WRT_FLT		; CHECK FOR WRITE FAULT
  5273 000054CA 7514                <1> 	JNZ	short CKST_EXIT
  5274 000054CC B4AA                <1> 	MOV	AH,NOT_RDY
  5275 000054CE A840                <1> 	TEST	AL,ST_READY		; CHECK FOR NOT READY
  5276 000054D0 740E                <1> 	JZ	short CKST_EXIT
  5277 000054D2 B440                <1> 	MOV	AH,BAD_SEEK
  5278 000054D4 A810                <1> 	TEST	AL,ST_SEEK_COMPL	; CHECK FOR SEEK NOT COMPLETE
  5279 000054D6 7408                <1> 	JZ	short CKST_EXIT
  5280 000054D8 B411                <1> 	MOV	AH,DATA_CORRECTED
  5281 000054DA A804                <1> 	TEST	AL,ST_CORRCTD		; CHECK FOR CORRECTED ECC
  5282 000054DC 7502                <1> 	JNZ	short CKST_EXIT
  5283 000054DE B400                <1> 	MOV	AH,0
  5284                              <1> CKST_EXIT:
  5285 000054E0 8825[73640100]      <1> 	MOV	[DISK_STATUS1],AH	; SET ERROR FLAG
  5286 000054E6 80FC11              <1> 	CMP	AH,DATA_CORRECTED	; KEEP GOING WITH DATA CORRECTED
  5287 000054E9 7403                <1> 	JZ	short CKST_EX1
  5288 000054EB 80FC00              <1> 	CMP	AH,0
  5289                              <1> CKST_EX1:
  5290 000054EE C3                  <1> 	RETn
  5291                              <1> 
  5292                              <1> ;----------------------------------------
  5293                              <1> ;	CHECK FIXED DISK ERROR REGISTER :
  5294                              <1> ;----------------------------------------
  5295                              <1> CHECK_ER:
  5296                              <1> 	;MOV	DX, HF_PORT+1		; GET THE ERROR REGISTER
  5297 000054EF 668B15[C0670000]    <1> 	mov	dx, [HF_PORT]		;
  5298 000054F6 FEC2                <1> 	inc	dl
  5299 000054F8 EC                  <1> 	IN	AL,DX
  5300 000054F9 A2[6A640100]        <1> 	MOV	[HF_ERROR],AL
  5301 000054FE 53                  <1> 	PUSH	eBX ; 21/02/2015
  5302 000054FF B908000000          <1> 	MOV	eCX,8			; TEST ALL 8 BITS
  5303 00005504 D0E0                <1> CK1:	SHL	AL,1			; MOVE NEXT ERROR BIT TO CARRY
  5304 00005506 7202                <1> 	JC	short CK2		; FOUND THE ERROR
  5305 00005508 E2FA                <1> 	LOOP	CK1			; KEEP TRYING
  5306 0000550A BB[B4670000]        <1> CK2:	MOV	eBX, ERR_TBL		; COMPUTE ADDRESS OF
  5307 0000550F 01CB                <1> 	ADD	eBX,eCX			; ERROR CODE
  5308                              <1> 	;;MOV	AH,BYTE [CS:BX]		; GET ERROR CODE
  5309                              <1> 	;mov	ah, [bx]
  5310 00005511 8A23                <1> 	mov	ah, [ebx] ; 21/02/2015	
  5311 00005513 8825[73640100]      <1> CKEX:	MOV	[DISK_STATUS1],AH	; SAVE ERROR CODE
  5312 00005519 5B                  <1> 	POP	eBX
  5313 0000551A 80FC00              <1> 	CMP	AH,0
  5314 0000551D C3                  <1> 	RETn
  5315                              <1> 
  5316                              <1> ;--------------------------------------------------------
  5317                              <1> ; CHECK_DMA						:
  5318                              <1> ;  -CHECK ES:BX AND # SECTORS TO MAKE SURE THAT IT WILL :
  5319                              <1> ;   FIT WITHOUT SEGMENT OVERFLOW.			:
  5320                              <1> ;  -ES:BX HAS BEEN REVISED TO THE FORMAT SSSS:000X	:
  5321                              <1> ;  -OK IF # SECTORS < 80H (7FH IF LONG READ OR WRITE)	:
  5322                              <1> ;  -OK IF # SECTORS = 80H (7FH) AND BX <= 00H (04H)	:
  5323                              <1> ;  -ERROR OTHERWISE					:
  5324                              <1> ;--------------------------------------------------------
  5325                              <1> CHECK_DMA:
  5326 0000551E 6650                <1> 	PUSH	AX			; SAVE REGISTERS
  5327 00005520 66B80080            <1> 	MOV	AX,8000H		; AH = MAX # SECTORS AL = MAX OFFSET
  5328 00005524 F645FE02            <1>         TEST    byte [CMD_BLOCK+6],ECC_MODE
  5329 00005528 7404                <1> 	JZ	short CKD1
  5330 0000552A 66B8047F            <1> 	MOV	AX,7F04H		; ECC IS 4 MORE BYTES
  5331 0000552E 3A65F9              <1> CKD1:	CMP	AH, [CMD_BLOCK+1] 	; NUMBER OF SECTORS
  5332 00005531 7706                <1> 	JA	short CKDOK		; IT WILL FIT
  5333 00005533 7208                <1> 	JB	short CKDERR		; TOO MANY
  5334 00005535 38D8                <1> 	CMP	AL,BL			; CHECK OFFSET ON MAX SECTORS
  5335 00005537 7204                <1> 	JB	short CKDERR		; ERROR
  5336 00005539 F8                  <1> CKDOK:	CLC				; CLEAR CARRY
  5337 0000553A 6658                <1> 	POP	AX
  5338 0000553C C3                  <1> 	RETn				; NORMAL RETURN
  5339 0000553D F9                  <1> CKDERR: STC				; INDICATE ERROR
  5340 0000553E C605[73640100]09    <1>         MOV     byte [DISK_STATUS1],DMA_BOUNDARY
  5341 00005545 6658                <1> 	POP	AX
  5342 00005547 C3                  <1> 	RETn
  5343                              <1> 
  5344                              <1> ;----------------------------------------
  5345                              <1> ;	SET UP ES:BX-> DISK PARMS	:
  5346                              <1> ;----------------------------------------
  5347                              <1> 					
  5348                              <1> ; INPUT -> DL = 0 based drive number
  5349                              <1> ; OUTPUT -> ES:BX = disk parameter table address
  5350                              <1> 
  5351                              <1> GET_VEC:
  5352                              <1> 	;SUB	AX,AX			; GET DISK PARAMETER ADDRESS
  5353                              <1> 	;MOV	ES,AX
  5354                              <1> 	;TEST	DL,1
  5355                              <1> 	;JZ	short GV_0
  5356                              <1> ;	LES	BX,[HF1_TBL_VEC] 	; ES:BX -> DRIVE PARAMETERS
  5357                              <1> ;	JMP	SHORT GV_EXIT
  5358                              <1> ;GV_0:
  5359                              <1> ;	LES	BX,[HF_TBL_VEC]		; ES:BX -> DRIVE PARAMETERS
  5360                              <1> ;
  5361                              <1> 	;xor	bh, bh
  5362 00005548 31DB                <1> 	xor	ebx, ebx
  5363 0000554A 88D3                <1> 	mov	bl, dl
  5364                              <1> 	;;02/01/2015
  5365                              <1> 	;;shl	bl, 1			; port address offset
  5366                              <1> 	;;mov	ax, [bx+hd_ports]	; Base port address (1F0h, 170h)
  5367                              <1> 	;;shl	bl, 1			; dpt pointer offset
  5368 0000554C C0E302              <1> 	shl	bl, 2	;;
  5369                              <1> 	;add	bx, HF_TBL_VEC		; Disk parameter table pointer
  5370 0000554F 81C3[78640100]      <1> 	add	ebx, HF_TBL_VEC ; 21/02/2015
  5371                              <1> 	;push	word [bx+2]		; dpt segment
  5372                              <1> 	;pop	es
  5373                              <1> 	;mov	bx, [bx]		; dpt offset
  5374 00005555 8B1B                <1> 	mov	ebx, [ebx]		
  5375                              <1> ;GV_EXIT:
  5376 00005557 C3                  <1> 	RETn
  5377                              <1> 
  5378                              <1> hdc1_int: ; 21/02/2015
  5379                              <1> ;--- HARDWARE INT 76H -- ( IRQ LEVEL  14 ) ----------------------
  5380                              <1> ;								:
  5381                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  5382                              <1> ;								:
  5383                              <1> ;----------------------------------------------------------------
  5384                              <1> 
  5385                              <1> ; 22/12/2014
  5386                              <1> ; IBM PC-XT Model 286 System BIOS Source Code - DISK.ASM (HD_INT)
  5387                              <1> ;	 '11/15/85'
  5388                              <1> ; AWARD BIOS 1999 (D1A0622) 
  5389                              <1> ;	Source Code - ATORGS.ASM (INT_HDISK, INT_HDISK1)
  5390                              <1> 
  5391                              <1> ;int_76h:
  5392                              <1> HD_INT:
  5393 00005558 6650                <1> 	PUSH	AX
  5394 0000555A 1E                  <1> 	PUSH	DS
  5395                              <1> 	;CALL	DDS
  5396                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  5397 0000555B 66B81000            <1> 	mov	ax, KDATA
  5398 0000555F 8ED8                <1> 	mov 	ds, ax
  5399                              <1> 	;
  5400                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
  5401                              <1>         ;mov     byte [CS:HF_INT_FLAG], 0FFh
  5402 00005561 C605[6B640100]FF    <1> 	mov	byte [HF_INT_FLAG], 0FFh
  5403                              <1> 	;
  5404 00005568 6652                <1> 	push	dx
  5405 0000556A 66BAF701            <1> 	mov	dx, HDC1_BASEPORT+7	; Status Register (1F7h)
  5406                              <1> 					; Clear Controller
  5407                              <1> Clear_IRQ1415:				; (Award BIOS - 1999)
  5408 0000556E EC                  <1> 	in	al, dx			;
  5409 0000556F 665A                <1> 	pop	dx
  5410                              <1> 	NEWIODELAY
  5410 00005571 E6EB                <2>  out 0ebh,al
  5411                              <1> 	;
  5412 00005573 B020                <1> 	MOV	AL,EOI			; NON-SPECIFIC END OF INTERRUPT
  5413 00005575 E6A0                <1> 	OUT	INTB00,AL		; FOR CONTROLLER #2
  5414                              <1> 	;JMP	$+2			; WAIT
  5415                              <1> 	NEWIODELAY
  5415 00005577 E6EB                <2>  out 0ebh,al
  5416 00005579 E620                <1> 	OUT	INTA00,AL		; FOR CONTROLLER #1
  5417 0000557B 1F                  <1> 	POP	DS
  5418                              <1> 	;STI				; RE-ENABLE INTERRUPTS
  5419                              <1> 	;MOV	AX,9100H		; DEVICE POST
  5420                              <1> 	;INT	15H			;  INTERRUPT
  5421                              <1> irq15_iret: ; 25/02/2015
  5422 0000557C 6658                <1> 	POP	AX
  5423 0000557E CF                  <1> 	IRETd				; RETURN FROM INTERRUPT
  5424                              <1> 
  5425                              <1> hdc2_int: ; 21/02/2015
  5426                              <1> ;++++ HARDWARE INT 77H ++ ( IRQ LEVEL  15 ) +++++++++++++++++++++
  5427                              <1> ;								:
  5428                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  5429                              <1> ;								:
  5430                              <1> ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5431                              <1> 
  5432                              <1> ;int_77h:
  5433                              <1> HD1_INT:
  5434 0000557F 6650                <1> 	PUSH	AX
  5435                              <1> 	; Check if that is a spurious IRQ (from slave PIC)
  5436                              <1> 	; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  5437 00005581 B00B                <1> 	mov	al, 0Bh  ; In-Service Register
  5438 00005583 E6A0                <1> 	out	0A0h, al
  5439 00005585 EB00                <1>         jmp short $+2
  5440 00005587 EB00                <1> 	jmp short $+2
  5441 00005589 E4A0                <1> 	in	al, 0A0h
  5442 0000558B 2480                <1> 	and 	al, 80h ; bit 7 (is it real IRQ 15 or fake?)
  5443 0000558D 74ED                <1> 	jz	short irq15_iret ; Fake (spurious)IRQ, do not send EOI)
  5444                              <1> 	;
  5445 0000558F 1E                  <1> 	PUSH	DS
  5446                              <1> 	;CALL	DDS
  5447                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  5448 00005590 66B81000            <1> 	mov	ax, KDATA
  5449 00005594 8ED8                <1> 	mov 	ds, ax
  5450                              <1> 	;
  5451                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
  5452                              <1>         ;or      byte [CS:HF_INT_FLAG],0C0h 
  5453 00005596 800D[6B640100]C0    <1> 	or	byte [HF_INT_FLAG], 0C0h
  5454                              <1> 	;
  5455 0000559D 6652                <1> 	push	dx
  5456 0000559F 66BA7701            <1> 	mov	dx, HDC2_BASEPORT+7	; Status Register (177h)
  5457                              <1> 					; Clear Controller (Award BIOS 1999)
  5458 000055A3 EBC9                <1> 	jmp	short Clear_IRQ1415
  5459                              <1> 
  5460                              <1> 
  5461                              <1> ;%include 'diskdata.inc' ; 11/03/2015
  5462                              <1> ;%include 'diskbss.inc' ; 11/03/2015
  5463                              <1> 
  5464                              <1> 
  5465                              <1> ;////////////////////////////////////////////////////////////////////
  5466                              <1> ;; END OF DISK I/O SYTEM ///
  2838                                  %include 'memory.s'  ; 09/03/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.3 - memory.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 15/12/2020
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.15 (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 4 ;15/10/2016 (1->4); insufficient (out of) memory
    46                              <1> ERR_MINOR_PV	equ 6 ;15/10/2016 (1->4); protection violation
    47                              <1> SWP_DISK_READ_ERR 	   equ 40
    48                              <1> SWP_DISK_NOT_PRESENT_ERR   equ 41
    49                              <1> SWP_SECTOR_NOT_PRESENT_ERR equ 42
    50                              <1> SWP_NO_FREE_SPACE_ERR      equ 43
    51                              <1> SWP_DISK_WRITE_ERR         equ 44
    52                              <1> SWP_NO_PAGE_TO_SWAP_ERR    equ 45
    53                              <1> PTE_A_ACCESS_BIT equ 5  ; Bit 5 (accessed flag)        
    54                              <1> SECTOR_SHIFT     equ 3  ; sector shift (to convert page block number)
    55                              <1> ; 12/07/2016
    56                              <1> PTE_SHARED	 equ 400h		; AVL bit 1, direct memory access bit	
    57                              <1> 					; (Indicates that the page is not allocated
    58                              <1> 					; for the process, it is a shared or system
    59                              <1>                                         ; page, it must not be deallocated!)
    60                              <1> ; 14/12/2020
    61                              <1> ; (Linear Frame Buffer - video memory mark : AVL bit 1, outside M.A.T.)
    62                              <1> PDE_EXTERNAL	equ 400h	; Page directory entry for external memory blocks
    63                              <1> PTE_EXTERNAL	equ 400h	; Allocated kernel pages for Linear Frame Buffer
    64                              <1> 				; (Out of memory allocation table)	
    65                              <1> 
    66                              <1> ;
    67                              <1> ;; Retro Unix 386 v1 - paging method/principles
    68                              <1> ;;
    69                              <1> ;; 10/10/2014
    70                              <1> ;; RETRO UNIX 386 v1 - PAGING METHOD/PRINCIPLES
    71                              <1> ;;
    72                              <1> ;; KERNEL PAGE MAP: 1 to 1 physical memory page map
    73                              <1> ;;	(virtual address = physical address)
    74                              <1> ;; KERNEL PAGE TABLES:
    75                              <1> ;;	Kernel page directory and all page tables are
    76                              <1> ;;	on memory as initialized, as equal to physical memory
    77                              <1> ;;	layout. Kernel pages can/must not be swapped out/in.
    78                              <1> ;;
    79                              <1> ;;	what for: User pages may be swapped out, when accessing
    80                              <1> ;;	a page in kernel/system mode, if it would be swapped out,
    81                              <1> ;;	kernel would have to swap it in! But it is also may be
    82                              <1> ;;	in use by a user process. (In system/kernel mode
    83                              <1> ;;	kernel can access all memory pages even if they are
    84                              <1> ;;	reserved/allocated for user processes. Swap out/in would
    85                              <1> ;;	cause conflicts.) 
    86                              <1> ;;	
    87                              <1> ;;	As result of these conditions,
    88                              <1> ;;	all kernel pages must be initialized as equal to 
    89                              <1> ;;	physical layout for preventing page faults. 
    90                              <1> ;;	Also, calling "allocate page" procedure after
    91                              <1> ;;	a page fault can cause another page fault (double fault)
    92                              <1> ;;	if all kernel page tables would not be initialized.
    93                              <1> ;;
    94                              <1> ;;	[first_page] = Beginning of users space, as offset to 
    95                              <1> ;;	memory allocation table. (double word aligned)
    96                              <1> ;;
    97                              <1> ;;	[next_page] = first/next free space to be searched
    98                              <1> ;;	as offset to memory allocation table. (dw aligned)
    99                              <1> ;;
   100                              <1> ;;	[last_page] = End of memory (users space), as offset
   101                              <1> ;;	to memory allocation table. (double word aligned)
   102                              <1> ;;
   103                              <1> ;; USER PAGE TABLES:
   104                              <1> ;;	Demand paging (& 'copy on write' allocation method) ...
   105                              <1> ;;		'ready only' marked copies of the 
   106                              <1> ;;		parent process's page table entries (for
   107                              <1> ;;		same physical memory).
   108                              <1> ;;		(A page will be copied to a new page after
   109                              <1> ;;		 if it causes R/W page fault.)
   110                              <1> ;;
   111                              <1> ;;	Every user process has own (different)
   112                              <1> ;;	page directory and page tables.	
   113                              <1> ;;
   114                              <1> ;;	Code starts at virtual address 0, always.
   115                              <1> ;;	(Initial value of EIP is 0 in user mode.)
   116                              <1> ;;	(Programs can be written/developed as simple
   117                              <1> ;;	 flat memory programs.)
   118                              <1> ;;
   119                              <1> ;; MEMORY ALLOCATION STRATEGY:
   120                              <1> ;;	Memory page will be allocated by kernel only 
   121                              <1> ;;		(in kernel/system mode only).
   122                              <1> ;;	* After a
   123                              <1> ;;	  - 'not present' page fault
   124                              <1> ;;	  - 'writing attempt on read only page' page fault 	 	
   125                              <1> ;;	* For loading (opening, reading) a file or disk/drive
   126                              <1> ;;	* As responce to 'allocate additional memory blocks' 
   127                              <1> ;;	  request by running process.
   128                              <1> ;;	* While creating a process, allocating a new buffer,
   129                              <1> ;;	  new page tables etc.
   130                              <1> ;;
   131                              <1> ;;	At first,
   132                              <1> ;;	- 'allocate page' procedure will be called;
   133                              <1> ;,	   if it will return with a valid (>0) physical address
   134                              <1> ;;	   (that means the relevant M.A.T. bit has been RESET)	
   135                              <1> ;;	   relevant memory page/block will be cleared (zeroed).
   136                              <1> ;;	- 'allocate page' will be called for allocating page
   137                              <1> ;;	   directory, page table and running space (data/code).
   138                              <1> ;;	- every successful 'allocate page' call will decrease
   139                              <1> ;;	  'free_pages' count (pointer).
   140                              <1> ;;	- 'out of (insufficient) memory error' will be returned
   141                              <1> ;;	  if 'free_pages' points to a ZERO.
   142                              <1> ;;	- swapping out and swapping in (if it is not a new page)
   143                              <1> ;;	  procedures will be called as responce to 'out of memory'
   144                              <1> ;;	  error except errors caused by attribute conflicts.
   145                              <1> ;;	 (swapper functions)	 
   146                              <1> ;;					
   147                              <1> ;;	At second,
   148                              <1> ;;	- page directory entry will be updated then page table
   149                              <1> ;;	  entry will be updated.		
   150                              <1> ;;
   151                              <1> ;; MEMORY ALLOCATION TABLE FORMAT:
   152                              <1> ;;	- M.A.T. has a size according to available memory as
   153                              <1> ;;	  follows:
   154                              <1> ;;		  - 1 (allocation) bit per 1 page (4096 bytes)
   155                              <1> ;;		  - a bit with value of 0 means allocated page
   156                              <1> ;;		  - a bit with value of 1 means a free page
   157                              <1> ;,	- 'free_pages' pointer holds count of free pages
   158                              <1> ;;	  depending on M.A.T.
   159                              <1> ;;		(NOTE: Free page count will not be checked
   160                              <1> ;;		again -on M.A.T.- after initialization. 
   161                              <1> ;;		Kernel will trust on initial count.)
   162                              <1> ;,	- 'free_pages' count will be decreased by allocation
   163                              <1> ;;	  and it will be increased by deallocation procedures.
   164                              <1> ;;	
   165                              <1> ;;	- Available memory will be calculated during
   166                              <1> ;;	  the kernel's initialization stage (in real mode).
   167                              <1> ;;	  Memory allocation table and kernel page tables 
   168                              <1> ;;	  will be formatted/sized as result of available
   169                              <1> ;;	  memory calculation before paging is enabled.
   170                              <1> ;;
   171                              <1> ;; For 4GB Available/Present Memory: (max. possible memory size)
   172                              <1> ;;	- Memory Allocation Table size will be 128 KB.
   173                              <1> ;;	- Memory allocation for kernel page directory size 
   174                              <1> ;;	  is always 4 KB. (in addition to total allocation size
   175                              <1> ;;	  for page tables)
   176                              <1> ;;	- Memory allocation for kernel page tables (1024 tables)
   177                              <1> ;;	  is 4 MB (1024*4*1024 bytes).
   178                              <1> ;;	- User (available) space will be started 
   179                              <1> ;;	  at 6th MB of the memory (after 1MB+4MB).
   180                              <1> ;;	- The first 640 KB is for kernel's itself plus
   181                              <1> ;;	  memory allocation table and kernel's page directory
   182                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
   183                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
   184                              <1> ;; 	  for buffers.
   185                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
   186                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
   187                              <1> ;;	- Kernel page tables start at 100000h (2nd MB)
   188                              <1> ;;
   189                              <1> ;; For 1GB Available Memory:
   190                              <1> ;;	- Memory Allocation Table size will be 32 KB.
   191                              <1> ;;	- Memory allocation for kernel page directory size 
   192                              <1> ;;	  is always 4 KB. (in addition to total allocation size
   193                              <1> ;;	  for page tables)
   194                              <1> ;;	- Memory allocation for kernel page tables (256 tables)
   195                              <1> ;;	  is 1 MB (256*4*1024 bytes).
   196                              <1> ;;	- User (available) space will be started 
   197                              <1> ;;	  at 3th MB of the memory (after 1MB+1MB).
   198                              <1> ;;	- The first 640 KB is for kernel's itself plus
   199                              <1> ;;	  memory allocation table and kernel's page directory
   200                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
   201                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
   202                              <1> ;; 	  for buffers.
   203                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
   204                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
   205                              <1> ;;	- Kernel page tables start at 100000h (2nd MB).	
   206                              <1> ;;
   207                              <1> ;;
   208                              <1> 
   209                              <1> 
   210                              <1> ;;************************************************************************************
   211                              <1> ;; 
   212                              <1> ;; RETRO UNIX 386 v1 - Paging (Method for Copy On Write paging principle)
   213                              <1> ;; DEMAND PAGING - PARENT&CHILD PAGE TABLE DUPLICATION PRINCIPLES (23/04/2015)
   214                              <1> 
   215                              <1> ;; Main factor: "sys fork" system call 
   216                              <1> ;;	
   217                              <1> ;; 		FORK
   218                              <1> ;;                      |----> parent - duplicated PTEs, read only pages
   219                              <1> ;;  writable pages ---->|
   220                              <1> ;;                      |----> child - duplicated PTEs, read only pages
   221                              <1> ;; 
   222                              <1> ;; AVL bit (0) of Page Table Entry is used as duplication sign 
   223                              <1> ;; 
   224                              <1> ;; AVL Bit 0 [PTE Bit 9] = 'Duplicated PTE belongs to child' sign/flag (if it is set)
   225                              <1> ;; Note: Dirty bit (PTE bit 6) may be used instead of AVL bit 0 (PTE bit 9)
   226                              <1> ;;       -while R/W bit is 0-. 
   227                              <1> ;; 
   228                              <1> ;; Duplicate page tables with writable pages (the 1st sys fork in the process):
   229                              <1> ;; # Parent's Page Table Entries are updated to point same pages as read only, 
   230                              <1> ;;   as duplicated PTE bit  -AVL bit 0, PTE bit 9- are reset/clear.
   231                              <1> ;; # Then Parent's Page Table is copied to Child's Page Table.
   232                              <1> ;; # Child's Page Table Entries are updated as duplicated child bit
   233                              <1> ;;   -AVL bit 0, PTE bit 9- is set.	  
   234                              <1> ;; 
   235                              <1> ;; Duplicate page tables with read only pages (several sys fork system calls):
   236                              <1> ;; # Parent's read only pages are copied to new child pages. 
   237                              <1> ;;   Parent's PTE attributes are not changed.
   238                              <1> ;;   (Because, there is another parent-child fork before this fork! We must not
   239                              <1> ;;    destroy/mix previous fork result).
   240                              <1> ;; # Child's Page Table Entries (which are corresponding to Parent's 
   241                              <1> ;;   read only pages) are set as writable (while duplicated PTE bit is clear). 
   242                              <1> ;; # Parent's PTEs with writable page attribute are updated to point same pages 
   243                              <1> ;;   as read only, (while) duplicated PTE bit is reset (clear).
   244                              <1> ;; # Parent's Page Table Entries (with writable page attribute) are duplicated 
   245                              <1> ;;   as Child's Page Table Entries without copying actual page.
   246                              <1> ;; # Child 's Page Table Entries (which are corresponding to Parent's writable 
   247                              <1> ;;   pages) are updated as duplicated PTE bit (AVL bit 0, PTE bit 9- is set.
   248                              <1> ;; 
   249                              <1> ;; !? WHAT FOR (duplication after duplication):
   250                              <1> ;; In UNIX method for sys fork (a typical 'fork' application in /etc/init)
   251                              <1> ;; program/executable code continues from specified location as child process, 
   252                              <1> ;; returns back previous code location as parent process, every child after 
   253                              <1> ;; every sys fork uses last image of code and data just prior the fork.
   254                              <1> ;; Even if the parent code changes data, the child will not see the changed data 
   255                              <1> ;; after the fork. In Retro UNIX 8086 v1, parent's process segment (32KB)
   256                              <1> ;; was copied to child's process segment (all of code and data) according to
   257                              <1> ;; original UNIX v1 which copies all of parent process code and data -core- 
   258                              <1> ;; to child space -core- but swaps that core image -of child- on to disk.
   259                              <1> ;; If I (Erdogan Tan) would use a method of to copy parent's core
   260                              <1> ;; (complete running image of parent process) to the child process; 
   261                              <1> ;; for big sizes, i would force Retro UNIX 386 v1 to spend many memory pages 
   262                              <1> ;; and times only for a sys fork. (It would excessive reservation for sys fork,
   263                              <1> ;; because sys fork usually is prior to sys exec; sys exec always establishes
   264                              <1> ;; a new/fresh core -running space-, by clearing all code/data content). 
   265                              <1> ;; 'Read Only' page flag ensures page fault handler is needed only for a few write
   266                              <1> ;; attempts between sys fork and sys exec, not more... (I say so by thinking 
   267                              <1> ;; of "/etc/init" content, specially.) sys exec will clear page tables and
   268                              <1> ;; new/fresh pages will be used to load and run new executable/program.
   269                              <1> ;; That is what for i have preferred "copy on write", "duplication" method
   270                              <1> ;; for sharing same read only pages between parent and child processes.
   271                              <1> ;; That is a pitty i have to use new private flag (AVL bit 0, "duplicated PTE 
   272                              <1> ;; belongs to child" sign) for cooperation on duplicated pages between a parent 
   273                              <1> ;; and it's child processes; otherwise parent process would destroy data belongs
   274                              <1> ;; to its child or vice versa; or some pages would remain unclaimed 
   275                              <1> ;; -deallocation problem-.
   276                              <1> ;; Note: to prevent conflicts, read only pages must not be swapped out... 
   277                              <1> ;; 
   278                              <1> ;; WHEN PARENT TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
   279                              <1> ;; # Page fault handler will do those:
   280                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
   281                              <1> ;;   - If it is reset/clear, there is a child uses same page.
   282                              <1> ;;   - Parent's read only page -previous page- is copied to a new writable page. 
   283                              <1> ;;   - Parent's PTE is updated as writable page, as unique page (AVL=0)
   284                              <1> ;;   - (Page fault handler whill check this PTE later, if child process causes to
   285                              <1> ;;     page fault due to write attempt on read only page. Of course, the previous 
   286                              <1> ;;     read only page will be converted to writable and unique page which belongs
   287                              <1> ;;     to child process.)	
   288                              <1> ;; WHEN CHILD TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
   289                              <1> ;; # Page fault handler will do those:
   290                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
   291                              <1> ;;   - If it is set, there is a parent uses -or was using- same page.
   292                              <1> ;;   - Same PTE address within parent's page table is checked if it has same page
   293                              <1> ;;     address or not. 
   294                              <1> ;;   - If parent's PTE has same address, child will continue with a new writable page.
   295                              <1> ;;     Parent's PTE will point to same (previous) page as writable, unique (AVL=0).	
   296                              <1> ;;   - If parent's PTE has different address, child will continue with it's 
   297                              <1> ;;     own/same page but read only flag (0) will be changed to writable flag (1) and
   298                              <1> ;;     'duplicated PTE (belongs to child)' flag/sign will be cleared/reset. 	  	
   299                              <1> ;; 
   300                              <1> ;; NOTE: When a child process is terminated, read only flags of parent's page tables
   301                              <1> ;;       will be set as writable (and unique) in case of child process was using 
   302                              <1> ;;       same pages with duplicated child PTE sign... Depending on sys fork and 
   303                              <1> ;;       duplication method details, it is not possible multiple child processes
   304                              <1> ;;       were using same page with duplicated PTEs.
   305                              <1> ;; 
   306                              <1> ;;************************************************************************************   
   307                              <1> 
   308                              <1> ;; 08/10/2014
   309                              <1> ;; 11/09/2014 - Retro UNIX 386 v1 PAGING (further) draft
   310                              <1> ;;		by Erdogan Tan (Based on KolibriOS 'memory.inc')
   311                              <1> 
   312                              <1> ;; 'allocate_page' code is derived and modified from KolibriOS
   313                              <1> ;; 'alloc_page' procedure in 'memory.inc' 
   314                              <1> ;; (25/08/2014, Revision: 5057) file 
   315                              <1> ;; by KolibriOS Team (2004-2012)
   316                              <1> 
   317                              <1> allocate_page:
   318                              <1> 	; 01/07/2015
   319                              <1> 	; 05/05/2015
   320                              <1> 	; 30/04/2015
   321                              <1> 	; 16/10/2014
   322                              <1> 	; 08/10/2014
   323                              <1> 	; 09/09/2014 (Retro UNIX 386 v1 - beginning)
   324                              <1> 	;
   325                              <1> 	; INPUT -> none
   326                              <1> 	;
   327                              <1> 	; OUTPUT ->
   328                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
   329                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is RESET)
   330                              <1> 	;
   331                              <1> 	;	CF = 1 and EAX = 0 
   332                              <1> 	; 		   if there is not a free page to be allocated	
   333                              <1> 	;
   334                              <1> 	; Modified Registers -> none (except EAX)
   335                              <1> 	;
   336 000055A5 A1[E0630100]        <1> 	mov	eax, [free_pages]
   337 000055AA 21C0                <1> 	and	eax, eax
   338 000055AC 7438                <1> 	jz	short out_of_memory
   339                              <1> 	;
   340 000055AE 53                  <1> 	push	ebx
   341 000055AF 51                  <1> 	push	ecx
   342                              <1> 	;
   343 000055B0 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table offset
   344 000055B5 89D9                <1> 	mov	ecx, ebx
   345                              <1>  				     ; NOTE: 32 (first_page) is initial
   346                              <1> 				     ; value of [next_page].
   347                              <1> 				     ; It points to the first available
   348                              <1> 				     ; page block for users (ring 3) ...	
   349                              <1> 				     ; (MAT offset 32 = 1024/32)	
   350                              <1> 				     ; (at the of the first 4 MB)		
   351 000055B7 031D[E4630100]      <1> 	add	ebx, [next_page] ; Free page searching starts from here
   352                              <1> 				 ; next_free_page >> 5
   353 000055BD 030D[E8630100]      <1> 	add	ecx, [last_page] ; Free page searching ends here
   354                              <1> 				 ; (total_pages - 1) >> 5
   355                              <1> al_p_scan:
   356 000055C3 39CB                <1> 	cmp	ebx, ecx
   357 000055C5 770A                <1> 	ja	short al_p_notfound
   358                              <1> 	;
   359                              <1> 	; 01/07/2015
   360                              <1> 	; AMD64 Architecture Programmers Manual
   361                              <1> 	; Volume 3:
   362                              <1> 	; General-Purpose and System Instructions
   363                              <1> 	;
   364                              <1> 	; BSF - Bit Scan Forward
   365                              <1> 	;
   366                              <1> 	;   Searches the value in a register or a memory location
   367                              <1> 	;   (second operand) for the least-significant set bit. 
   368                              <1> 	;   If a set bit is found, the instruction clears the zero flag (ZF)
   369                              <1> 	;   and stores the index of the least-significant set bit in a destination
   370                              <1> 	;   register (first operand). If the second operand contains 0, 
   371                              <1> 	;   the instruction sets ZF to 1 and does not change the contents of the 
   372                              <1> 	;   destination register. The bit index is an unsigned offset from bit 0 
   373                              <1> 	;   of the searched value
   374                              <1> 	;
   375 000055C7 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
   376                              <1> 			   ; Clear ZF if a bit is found set (1) and 
   377                              <1> 			   ; loads the destination with an index to
   378                              <1> 			   ; first set bit. (0 -> 31) 
   379                              <1> 			   ; Sets ZF to 1 if no bits are found set.
   380 000055CA 7525                <1> 	jnz	short al_p_found ; ZF = 0 -> a free page has been found
   381                              <1> 			 ;
   382                              <1> 			 ; NOTE:  a Memory Allocation Table bit 
   383                              <1> 			 ;	  with value of 1 means 
   384                              <1> 			 ;	  the corresponding page is free 
   385                              <1> 			 ;	  (Retro UNIX 386 v1 feature only!)
   386 000055CC 83C304              <1> 	add	ebx, 4
   387                              <1> 			 ; We return back for searching next page block
   388                              <1> 			 ; NOTE: [free_pages] is not ZERO; so, 
   389                              <1> 			 ;	 we always will find at least 1 free page here.
   390 000055CF EBF2                <1>         jmp     short al_p_scan
   391                              <1> 	;
   392                              <1> al_p_notfound:
   393 000055D1 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
   394 000055D7 890D[E4630100]      <1> 	mov	[next_page], ecx ; next/first free page = last page 
   395                              <1> 				 ; (deallocate_page procedure will change it)
   396 000055DD 31C0                <1> 	xor	eax, eax
   397 000055DF A3[E0630100]        <1> 	mov	[free_pages], eax ; 0
   398 000055E4 59                  <1> 	pop	ecx
   399 000055E5 5B                  <1> 	pop	ebx
   400                              <1> 	;
   401                              <1> out_of_memory:
   402 000055E6 E85B040000          <1> 	call	swap_out
   403 000055EB 7325                <1> 	jnc	short al_p_ok  ; [free_pages] = 0, re-allocation by swap_out
   404                              <1> 	;
   405 000055ED 29C0                <1> 	sub 	eax, eax ; 0
   406 000055EF F9                  <1> 	stc
   407 000055F0 C3                  <1> 	retn
   408                              <1> 
   409                              <1> al_p_found:
   410 000055F1 89D9                <1> 	mov	ecx, ebx
   411 000055F3 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
   412 000055F9 890D[E4630100]      <1> 	mov	[next_page], ecx ; Set first free page searching start
   413                              <1> 				 ; address/offset (to the next)
   414 000055FF FF0D[E0630100]      <1>         dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
   415                              <1> 	;
   416 00005605 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
   417                              <1> 				 ; is copied into the Carry Flag and then cleared
   418                              <1> 				 ; in the destination.
   419                              <1> 				 ;
   420                              <1> 				 ; Reset the bit which is corresponding to the 
   421                              <1> 				 ; (just) allocated page.
   422                              <1> 	; 01/07/2015 (4*8 = 32, 1 allocation byte = 8 pages)	
   423 00005608 C1E103              <1> 	shl	ecx, 3		 ; (page block offset * 32) + page index
   424 0000560B 01C8                <1> 	add	eax, ecx	 ; = page number
   425 0000560D C1E00C              <1> 	shl	eax, 12		 ; physical address of the page (flat/real value)
   426                              <1> 	; EAX = physical address of memory page
   427                              <1> 	;
   428                              <1> 	; NOTE: The relevant page directory and page table entry will be updated
   429                              <1> 	;       according to this EAX value...
   430 00005610 59                  <1> 	pop	ecx
   431 00005611 5B                  <1> 	pop	ebx
   432                              <1> al_p_ok:
   433 00005612 C3                  <1> 	retn
   434                              <1> 
   435                              <1> 
   436                              <1> make_page_dir:
   437                              <1> 	; 18/04/2015
   438                              <1> 	; 12/04/2015
   439                              <1> 	; 23/10/2014
   440                              <1> 	; 16/10/2014
   441                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
   442                              <1> 	;
   443                              <1> 	; INPUT ->
   444                              <1> 	;	none
   445                              <1> 	; OUTPUT ->
   446                              <1> 	;	(EAX = 0)
   447                              <1> 	;	cf = 1 -> insufficient (out of) memory error
   448                              <1> 	;	cf = 0 ->
   449                              <1> 	;	u.pgdir = page directory (physical) address of the current
   450                              <1> 	;		  process/user.
   451                              <1> 	;
   452                              <1> 	; Modified Registers -> EAX
   453                              <1> 	;
   454 00005613 E88DFFFFFF          <1> 	call	allocate_page
   455 00005618 7216                <1> 	jc	short mkpd_error
   456                              <1> 	;
   457 0000561A A3[B8030300]        <1> 	mov	[u.pgdir], eax    ; Page dir address for current user/process
   458                              <1> 				  ; (Physical address)
   459                              <1> clear_page:
   460                              <1> 	; 18/04/2015
   461                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
   462                              <1> 	;
   463                              <1> 	; INPUT ->
   464                              <1> 	;	EAX = physical address of the page
   465                              <1> 	; OUTPUT ->
   466                              <1> 	;	all bytes of the page will be cleared
   467                              <1> 	;
   468                              <1> 	; Modified Registers -> none
   469                              <1> 	;
   470 0000561F 57                  <1> 	push	edi
   471 00005620 51                  <1> 	push	ecx
   472 00005621 50                  <1> 	push	eax
   473 00005622 B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
   474 00005627 89C7                <1> 	mov	edi, eax
   475 00005629 31C0                <1> 	xor	eax, eax
   476 0000562B F3AB                <1> 	rep	stosd
   477 0000562D 58                  <1> 	pop	eax
   478 0000562E 59                  <1> 	pop	ecx
   479 0000562F 5F                  <1> 	pop	edi
   480                              <1> mkpd_error:
   481                              <1> mkpt_error:
   482 00005630 C3                  <1> 	retn
   483                              <1> 
   484                              <1> make_page_table:
   485                              <1> 	; 23/06/2015
   486                              <1> 	; 18/04/2015
   487                              <1> 	; 12/04/2015
   488                              <1> 	; 16/10/2014
   489                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
   490                              <1> 	;
   491                              <1> 	; INPUT ->
   492                              <1> 	;	EBX = virtual (linear) address
   493                              <1> 	;	ECX = page table attributes (lower 12 bits)
   494                              <1> 	;	      (higher 20 bits must be ZERO)
   495                              <1> 	;	      (bit 0 must be 1)	 
   496                              <1> 	;	u.pgdir = page directory (physical) address
   497                              <1> 	; OUTPUT ->
   498                              <1> 	;	EDX = Page directory entry address
   499                              <1> 	;	EAX = Page table address
   500                              <1> 	;	cf = 1 -> insufficient (out of) memory error
   501                              <1> 	;	cf = 0 -> page table address in the PDE (EDX)
   502                              <1> 	;
   503                              <1> 	; Modified Registers -> EAX, EDX
   504                              <1> 	;
   505 00005631 E86FFFFFFF          <1> 	call	allocate_page
   506 00005636 72F8                <1> 	jc	short mkpt_error
   507 00005638 E811000000          <1> 	call	set_pde	
   508 0000563D EBE0                <1> 	jmp	short clear_page
   509                              <1> 
   510                              <1> make_page:
   511                              <1> 	; 24/07/2015
   512                              <1> 	; 23/06/2015 ; (Retro UNIX 386 v1 - beginning)
   513                              <1> 	;
   514                              <1> 	; INPUT ->
   515                              <1> 	;	EBX = virtual (linear) address
   516                              <1> 	;	ECX = page attributes (lower 12 bits)
   517                              <1> 	;	      (higher 20 bits must be ZERO)
   518                              <1> 	;	      (bit 0 must be 1)	 
   519                              <1> 	;	u.pgdir = page directory (physical) address
   520                              <1> 	; OUTPUT ->
   521                              <1> 	;	EBX = Virtual address
   522                              <1> 	;	(EDX = PTE value)
   523                              <1> 	;	EAX = Physical address
   524                              <1> 	;	cf = 1 -> insufficient (out of) memory error
   525                              <1> 	;
   526                              <1> 	; Modified Registers -> EAX, EDX
   527                              <1> 	;
   528 0000563F E861FFFFFF          <1> 	call	allocate_page
   529 00005644 7207                <1> 	jc	short mkp_err
   530 00005646 E821000000          <1> 	call	set_pte	
   531 0000564B 73D2                <1> 	jnc	short clear_page ; 18/04/2015
   532                              <1> mkp_err:
   533 0000564D C3                  <1> 	retn
   534                              <1> 
   535                              <1> 
   536                              <1> set_pde:	; Set page directory entry (PDE)
   537                              <1> 	; 20/07/2015
   538                              <1> 	; 18/04/2015
   539                              <1> 	; 12/04/2015
   540                              <1> 	; 23/10/2014
   541                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
   542                              <1> 	;
   543                              <1> 	; INPUT ->
   544                              <1> 	;	EAX = physical address
   545                              <1> 	;	      (use present value if EAX = 0)
   546                              <1> 	;	EBX = virtual (linear) address
   547                              <1> 	;	ECX = page table attributes (lower 12 bits)
   548                              <1> 	;	      (higher 20 bits must be ZERO)
   549                              <1> 	;	      (bit 0 must be 1)	 
   550                              <1> 	;	u.pgdir = page directory (physical) address
   551                              <1> 	; OUTPUT ->
   552                              <1> 	;	EDX = PDE address
   553                              <1> 	;	EAX = page table address (physical)
   554                              <1> 	;	;(CF=1 -> Invalid page address)
   555                              <1> 	;
   556                              <1> 	; Modified Registers -> EDX
   557                              <1> 	;
   558 0000564E 89DA                <1> 	mov	edx, ebx
   559 00005650 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22
   560 00005653 C1E202              <1> 	shl	edx, 2 ; offset to page directory (1024*4)
   561 00005656 0315[B8030300]      <1> 	add	edx, [u.pgdir]
   562                              <1> 	;
   563 0000565C 21C0                <1> 	and	eax, eax
   564 0000565E 7506                <1> 	jnz	short spde_1
   565                              <1> 	;
   566 00005660 8B02                <1> 	mov	eax, [edx]  ; old PDE value
   567                              <1> 	;test	al, 1
   568                              <1> 	;jz	short spde_2
   569 00005662 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h  ; clear lower 12 bits
   570                              <1> spde_1:
   571                              <1> 	;and	cx, 0FFFh
   572 00005666 8902                <1> 	mov	[edx], eax
   573 00005668 66090A              <1> 	or	[edx], cx
   574 0000566B C3                  <1> 	retn
   575                              <1> ;spde_2: ; error
   576                              <1> ;	stc
   577                              <1> ;	retn
   578                              <1> 
   579                              <1> set_pte:	; Set page table entry (PTE)
   580                              <1> 	; 24/07/2015
   581                              <1> 	; 20/07/2015
   582                              <1> 	; 23/06/2015
   583                              <1> 	; 18/04/2015
   584                              <1> 	; 12/04/2015
   585                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
   586                              <1> 	;
   587                              <1> 	; INPUT ->
   588                              <1> 	;	EAX = physical page address
   589                              <1> 	;	      (use present value if EAX = 0)
   590                              <1> 	;	EBX = virtual (linear) address
   591                              <1> 	;	ECX = page attributes (lower 12 bits)
   592                              <1> 	;	      (higher 20 bits must be ZERO)
   593                              <1> 	;	      (bit 0 must be 1)	 
   594                              <1> 	;	u.pgdir = page directory (physical) address
   595                              <1> 	; OUTPUT ->
   596                              <1> 	;	EAX = physical page address
   597                              <1> 	;	(EDX = PTE value)
   598                              <1> 	;	EBX = virtual address
   599                              <1> 	;
   600                              <1> 	;	CF = 1 -> error
   601                              <1> 	;
   602                              <1> 	; Modified Registers -> EAX, EDX
   603                              <1> 	;
   604 0000566C 50                  <1> 	push	eax
   605 0000566D A1[B8030300]        <1> 	mov	eax, [u.pgdir] ; 20/07/2015
   606 00005672 E837000000          <1> 	call 	get_pde
   607                              <1> 		; EDX = PDE address
   608                              <1> 		; EAX = PDE value
   609 00005677 5A                  <1> 	pop	edx ; physical page address
   610 00005678 722A                <1> 	jc	short spte_err ; PDE not present
   611                              <1> 	;
   612 0000567A 53                  <1> 	push	ebx ; 24/07/2015
   613 0000567B 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
   614                              <1> 			    ; EDX = PT address (physical)	
   615 0000567F C1EB0C              <1> 	shr	ebx, PAGE_SHIFT ; 12
   616 00005682 81E3FF030000        <1> 	and	ebx, PTE_MASK	; 03FFh
   617                              <1> 			 ; clear higher 10 bits (PD bits)
   618 00005688 C1E302              <1> 	shl	ebx, 2   ; offset to page table (1024*4)
   619 0000568B 01C3                <1> 	add	ebx, eax
   620                              <1> 	;
   621 0000568D 8B03                <1> 	mov	eax, [ebx] ; Old PTE value
   622 0000568F A801                <1> 	test	al, 1
   623 00005691 740C                <1> 	jz	short spte_0
   624 00005693 09D2                <1> 	or	edx, edx
   625 00005695 750F                <1> 	jnz	short spte_1
   626 00005697 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 bits
   627 0000569B 89C2                <1> 	mov	edx, eax
   628 0000569D EB09                <1> 	jmp	short spte_2	
   629                              <1> spte_0:
   630                              <1> 	; If this PTE contains a swap (disk) address,
   631                              <1> 	; it can be updated by using 'swap_in' procedure
   632                              <1> 	; only!
   633 0000569F 21C0                <1> 	and	eax, eax
   634 000056A1 7403                <1> 	jz	short spte_1
   635                              <1> 	; 24/07/2015
   636                              <1> 	; swapped page ! (on disk)
   637 000056A3 5B                  <1> 	pop	ebx
   638                              <1> spte_err:
   639 000056A4 F9                  <1> 	stc
   640 000056A5 C3                  <1> 	retn
   641                              <1> spte_1: 
   642 000056A6 89D0                <1> 	mov	eax, edx
   643                              <1> spte_2:
   644 000056A8 09CA                <1> 	or	edx, ecx
   645                              <1> 	; 23/06/2015
   646 000056AA 8913                <1> 	mov	[ebx], edx ; PTE value in EDX
   647                              <1> 	; 24/07/2015
   648 000056AC 5B                  <1> 	pop	ebx
   649 000056AD C3                  <1> 	retn
   650                              <1> 
   651                              <1> get_pde:	; Get present value of the relevant PDE
   652                              <1> 	; 20/07/2015
   653                              <1> 	; 18/04/2015
   654                              <1> 	; 12/04/2015
   655                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
   656                              <1> 	;
   657                              <1> 	; INPUT ->
   658                              <1> 	;	EBX = virtual (linear) address
   659                              <1> 	;	EAX = page directory (physical) address
   660                              <1> 	; OUTPUT ->
   661                              <1> 	;	EDX = Page directory entry address
   662                              <1> 	;	EAX = Page directory entry value
   663                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
   664                              <1> 	; Modified Registers -> EDX, EAX
   665                              <1> 	;
   666 000056AE 89DA                <1> 	mov	edx, ebx
   667 000056B0 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22  (12+10)
   668 000056B3 C1E202              <1> 	shl 	edx, 2 ; offset to page directory (1024*4)
   669 000056B6 01C2                <1> 	add	edx, eax ; page directory address (physical)
   670 000056B8 8B02                <1> 	mov	eax, [edx]
   671 000056BA A801                <1> 	test	al, PDE_A_PRESENT ; page table is present or not !
   672 000056BC 751F                <1> 	jnz	short gpte_retn
   673 000056BE F9                  <1> 	stc
   674                              <1> gpde_retn:	
   675 000056BF C3                  <1> 	retn
   676                              <1> 
   677                              <1> get_pte:
   678                              <1> 		; Get present value of the relevant PTE
   679                              <1> 	; 29/07/2015
   680                              <1> 	; 20/07/2015
   681                              <1> 	; 18/04/2015
   682                              <1> 	; 12/04/2015
   683                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
   684                              <1> 	;
   685                              <1> 	; INPUT ->
   686                              <1> 	;	EBX = virtual (linear) address
   687                              <1> 	;	EAX = page directory (physical) address
   688                              <1> 	; OUTPUT ->
   689                              <1> 	;	EDX = Page table entry address (if CF=0)
   690                              <1> 	;	      Page directory entry address (if CF=1)
   691                              <1> 	;            (Bit 0 value is 0 if PT is not present)
   692                              <1> 	;	EAX = Page table entry value (page address)
   693                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
   694                              <1> 	; Modified Registers -> EAX, EDX
   695                              <1> 	;
   696 000056C0 E8E9FFFFFF          <1> 	call 	get_pde
   697 000056C5 72F8                <1> 	jc	short gpde_retn	; page table is not present
   698                              <1> 	;jnc	short gpte_1
   699                              <1> 	;retn
   700                              <1> ;gpte_1:
   701 000056C7 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
   702 000056CB 89DA                <1> 	mov	edx, ebx
   703 000056CD C1EA0C              <1> 	shr	edx, PAGE_SHIFT ; 12
   704 000056D0 81E2FF030000        <1> 	and	edx, PTE_MASK	; 03FFh
   705                              <1> 			 ; clear higher 10 bits (PD bits)
   706 000056D6 C1E202              <1> 	shl	edx, 2 ; offset from start of page table (1024*4)
   707 000056D9 01C2                <1> 	add	edx, eax
   708 000056DB 8B02                <1> 	mov	eax, [edx]
   709                              <1> gpte_retn:
   710 000056DD C3                  <1> 	retn
   711                              <1> 
   712                              <1> deallocate_page_dir:
   713                              <1> 	; 15/09/2015
   714                              <1> 	; 05/08/2015
   715                              <1> 	; 30/04/2015
   716                              <1> 	; 28/04/2015
   717                              <1> 	; 17/10/2014
   718                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
   719                              <1> 	;
   720                              <1> 	; INPUT ->
   721                              <1> 	;	EAX = PHYSICAL ADDRESS OF THE PAGE DIRECTORY (CHILD)
   722                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
   723                              <1> 	; OUTPUT ->
   724                              <1> 	;	All of page tables in the page directory
   725                              <1> 	;	and page dir's itself will be deallocated
   726                              <1> 	;	except 'read only' duplicated pages (will be converted
   727                              <1> 	;	to writable pages).
   728                              <1> 	;
   729                              <1> 	; Modified Registers -> EAX
   730                              <1> 	;
   731                              <1> 	;
   732 000056DE 56                  <1> 	push	esi
   733 000056DF 51                  <1> 	push	ecx
   734 000056E0 50                  <1> 	push	eax
   735 000056E1 89C6                <1> 	mov	esi, eax 
   736 000056E3 31C9                <1> 	xor	ecx, ecx
   737                              <1> 	; The 1st PDE points to Kernel Page Table 0 (the 1st 4MB),
   738                              <1> 	; it must not be deallocated
   739 000056E5 890E                <1> 	mov	[esi], ecx ; 0 ; clear PDE 0
   740                              <1> dapd_0:
   741 000056E7 AD                  <1> 	lodsd
   742 000056E8 A801                <1> 	test	al, PDE_A_PRESENT ; bit 0, present flag (must be 1)
   743 000056EA 7409                <1> 	jz	short dapd_1	
   744 000056EC 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
   745 000056F0 E812000000          <1> 	call	deallocate_page_table			
   746                              <1> dapd_1:
   747 000056F5 41                  <1> 	inc	ecx ; page directory entry index
   748 000056F6 81F900040000        <1> 	cmp	ecx, PAGE_SIZE / 4 ; 1024
   749 000056FC 72E9                <1> 	jb	short dapd_0
   750                              <1> dapd_2:
   751 000056FE 58                  <1> 	pop	eax
   752 000056FF E87F000000          <1> 	call	deallocate_page	; deallocate the page dir's itself
   753 00005704 59                  <1> 	pop	ecx
   754 00005705 5E                  <1> 	pop	esi
   755 00005706 C3                  <1> 	retn
   756                              <1> 
   757                              <1> deallocate_page_table:
   758                              <1> 	; 12/07/2016
   759                              <1> 	; 19/09/2015
   760                              <1> 	; 15/09/2015
   761                              <1> 	; 05/08/2015
   762                              <1> 	; 30/04/2015
   763                              <1> 	; 28/04/2015
   764                              <1> 	; 24/10/2014
   765                              <1> 	; 23/10/2014
   766                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
   767                              <1> 	;
   768                              <1> 	; INPUT ->
   769                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE PAGE TABLE
   770                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
   771                              <1> 	;	(ECX = page directory entry index)
   772                              <1> 	; OUTPUT ->
   773                              <1> 	;	All of pages in the page table and page table's itself
   774                              <1> 	;	will be deallocated except 'read only' duplicated pages
   775                              <1> 	;	(will be converted to writable pages).
   776                              <1> 	;
   777                              <1> 	; Modified Registers -> EAX
   778                              <1> 	;
   779 00005707 56                  <1> 	push	esi
   780 00005708 57                  <1> 	push	edi
   781 00005709 52                  <1> 	push	edx
   782 0000570A 50                  <1> 	push	eax ; *
   783 0000570B 89C6                <1> 	mov	esi, eax 
   784 0000570D 31FF                <1> 	xor	edi, edi ; 0
   785                              <1> dapt_0:
   786 0000570F AD                  <1> 	lodsd
   787 00005710 A801                <1> 	test	al, PTE_A_PRESENT ; bit 0, present flag (must be 1)
   788 00005712 7441                <1> 	jz	short dapt_1
   789                              <1> 	;
   790 00005714 A802                <1> 	test	al, PTE_A_WRITE   ; bit 1, writable (r/w) flag
   791                              <1> 				  ; (must be 1)
   792 00005716 754C                <1> 	jnz	short dapt_3
   793                              <1> 	; Read only -duplicated- page (belongs to a parent or a child)
   794 00005718 66A90002            <1>         test    ax, PTE_DUPLICATED ; Was this page duplicated 
   795                              <1> 				   ; as child's page ?
   796 0000571C 7451                <1> 	jz	short dapt_4 ; Clear PTE but don't deallocate the page!
   797                              <1> 	; check the parent's PTE value is read only & same page or not.. 
   798                              <1> 	; ECX = page directory entry index (0-1023)
   799 0000571E 53                  <1> 	push	ebx
   800 0000571F 51                  <1> 	push	ecx
   801 00005720 66C1E102            <1> 	shl	cx, 2 ; *4 
   802 00005724 01CB                <1> 	add	ebx, ecx ; PDE offset (for the parent)
   803 00005726 8B0B                <1> 	mov	ecx, [ebx]
   804 00005728 F6C101              <1> 	test	cl, PDE_A_PRESENT ; present (valid) or not ?
   805 0000572B 7435                <1> 	jz	short dapt_2	; parent process does not use this page
   806 0000572D 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
   807                              <1> 	; EDI = page table entry index (0-1023)
   808 00005732 89FA                <1> 	mov	edx, edi 
   809 00005734 66C1E202            <1> 	shl	dx, 2 ; *4 
   810 00005738 01CA                <1> 	add	edx, ecx ; PTE offset (for the parent)
   811 0000573A 8B1A                <1> 	mov	ebx, [edx]
   812 0000573C F6C301              <1> 	test	bl, PTE_A_PRESENT ; present or not ?
   813 0000573F 7421                <1> 	jz	short dapt_2	; parent process does not use this page
   814 00005741 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; Clear attribute bits 
   815 00005745 6681E300F0          <1> 	and	bx, PTE_A_CLEAR ; 0F000h ; Clear attribute bits
   816 0000574A 39D8                <1> 	cmp	eax, ebx	; parent's and child's pages are same ?
   817 0000574C 7514                <1> 	jne	short dapt_2	; not same page
   818                              <1> 				; deallocate the child's page
   819 0000574E 800A02              <1>         or      byte [edx], PTE_A_WRITE ; convert to writable page (parent)
   820 00005751 59                  <1> 	pop	ecx
   821 00005752 5B                  <1> 	pop	ebx
   822 00005753 EB1A                <1> 	jmp	short dapt_4
   823                              <1> dapt_1:
   824 00005755 09C0                <1> 	or	eax, eax	; swapped page ?
   825 00005757 741D                <1> 	jz	short dapt_5	; no
   826                              <1> 				; yes
   827 00005759 D1E8                <1> 	shr	eax, 1
   828 0000575B E8CA040000          <1> 	call	unlink_swap_block ; Deallocate swapped page block
   829                              <1> 				  ; on the swap disk (or in file)
   830 00005760 EB14                <1> 	jmp	short dapt_5
   831                              <1> dapt_2:
   832 00005762 59                  <1> 	pop	ecx
   833 00005763 5B                  <1> 	pop	ebx
   834                              <1> dapt_3:	
   835                              <1> 	; 12/07/2016
   836 00005764 66A90004            <1> 	test	ax, PTE_SHARED ; shared or direct memory access indicator
   837 00005768 7505                <1> 	jnz	short dapt_4   ; AVL bit 1 = 1, do not deallocate this page!
   838                              <1> 	;
   839                              <1> 	;and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
   840 0000576A E814000000          <1> 	call	deallocate_page ; set the mem allocation bit of this page
   841                              <1> dapt_4:
   842 0000576F C746FC00000000      <1> 	mov	dword [esi-4], 0 ; clear/reset PTE (child, dupl. as parent)
   843                              <1> dapt_5:
   844 00005776 47                  <1> 	inc	edi ; page table entry index
   845 00005777 81FF00040000        <1> 	cmp	edi, PAGE_SIZE / 4 ; 1024
   846 0000577D 7290                <1> 	jb	short dapt_0
   847                              <1> 	;
   848 0000577F 58                  <1> 	pop	eax ; *
   849 00005780 5A                  <1> 	pop	edx
   850 00005781 5F                  <1> 	pop	edi	
   851 00005782 5E                  <1> 	pop	esi
   852                              <1> 	;
   853                              <1> 	;call	deallocate_page	; deallocate the page table's itself
   854                              <1> 	;retn
   855                              <1> 
   856                              <1> deallocate_page:
   857                              <1> 	; 15/09/2015
   858                              <1> 	; 28/04/2015
   859                              <1> 	; 10/03/2015
   860                              <1> 	; 17/10/2014
   861                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
   862                              <1> 	;
   863                              <1> 	; INPUT -> 
   864                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
   865                              <1> 	; OUTPUT ->
   866                              <1> 	;	[free_pages] is increased
   867                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is SET)
   868                              <1> 	;	CF = 1 if the page is already deallocated
   869                              <1> 	; 	       (or not allocated) before.  
   870                              <1> 	;
   871                              <1> 	; Modified Registers -> EAX
   872                              <1> 	;
   873 00005783 53                  <1> 	push	ebx
   874 00005784 52                  <1> 	push	edx
   875                              <1> 	;
   876 00005785 C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; shift physical address to 
   877                              <1> 				     ; 12 bits right
   878                              <1> 				     ; to get page number
   879 00005788 89C2                <1> 	mov	edx, eax
   880                              <1> 	; 15/09/2015
   881 0000578A C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
   882                              <1> 				     ; (1 allocation bit = 1 page)
   883                              <1> 				     ; (1 allocation bytes = 8 pages)
   884 0000578D 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
   885                              <1> 				     ; (to get 32 bit position)			
   886                              <1> 	;
   887 00005790 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address
   888 00005795 01D3                <1> 	add	ebx, edx
   889 00005797 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
   890                              <1> 				     ; (allocation bit position)	 
   891 0000579A 3B15[E4630100]      <1> 	cmp 	edx, [next_page]     ; is the new free page address lower
   892                              <1> 				     ; than the address in 'next_page' ?
   893                              <1> 				     ; (next/first free page value)		
   894 000057A0 7306                <1> 	jnb	short dap_1	     ; no	
   895 000057A2 8915[E4630100]      <1> 	mov	[next_page], edx     ; yes
   896                              <1> dap_1:
   897 000057A8 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate page
   898                              <1> 				     ; set relevant bit to 1.
   899                              <1> 				     ; set CF to the previous bit value	
   900                              <1> 	;cmc			     ; complement carry flag	
   901                              <1> 	;jc	short dap_2	     ; do not increase free_pages count
   902                              <1> 				     ; if the page is already deallocated
   903                              <1> 				     ; before.	
   904 000057AB FF05[E0630100]      <1>         inc     dword [free_pages]
   905                              <1> dap_2:
   906 000057B1 5A                  <1> 	pop	edx
   907 000057B2 5B                  <1> 	pop	ebx
   908 000057B3 C3                  <1> 	retn
   909                              <1> 
   910                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   911                              <1> ;;                                                              ;;
   912                              <1> ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
   913                              <1> ;; Distributed under terms of the GNU General Public License    ;;
   914                              <1> ;;                                                              ;;
   915                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   916                              <1> 
   917                              <1> ;;$Revision: 5057 $
   918                              <1> 
   919                              <1> 
   920                              <1> ;;align 4
   921                              <1> ;;proc alloc_page
   922                              <1> 
   923                              <1> ;;        pushfd
   924                              <1> ;;        cli
   925                              <1> ;;        push    ebx
   926                              <1> ;;;//-
   927                              <1> ;;        cmp     [pg_data.pages_free], 1
   928                              <1> ;;        jle     .out_of_memory
   929                              <1> ;;;//-
   930                              <1> ;;
   931                              <1> ;;        mov     ebx, [page_start]
   932                              <1> ;;        mov     ecx, [page_end]
   933                              <1> ;;.l1:
   934                              <1> ;;        bsf     eax, [ebx];
   935                              <1> ;;        jnz     .found
   936                              <1> ;;        add     ebx, 4
   937                              <1> ;;        cmp     ebx, ecx
   938                              <1> ;;        jb      .l1
   939                              <1> ;;        pop     ebx
   940                              <1> ;;        popfd
   941                              <1> ;;        xor     eax, eax
   942                              <1> ;;        ret
   943                              <1> ;;.found:
   944                              <1> ;;;//-
   945                              <1> ;;        dec     [pg_data.pages_free]
   946                              <1> ;;        jz      .out_of_memory
   947                              <1> ;;;//-
   948                              <1> ;;        btr     [ebx], eax
   949                              <1> ;;        mov     [page_start], ebx
   950                              <1> ;;        sub     ebx, sys_pgmap
   951                              <1> ;;        lea     eax, [eax+ebx*8]
   952                              <1> ;;        shl     eax, 12
   953                              <1> ;;;//-       dec [pg_data.pages_free]
   954                              <1> ;;        pop     ebx
   955                              <1> ;;        popfd
   956                              <1> ;;        ret
   957                              <1> ;;;//-
   958                              <1> ;;.out_of_memory:
   959                              <1> ;;        mov     [pg_data.pages_free], 1
   960                              <1> ;;        xor     eax, eax
   961                              <1> ;;        pop     ebx
   962                              <1> ;;        popfd
   963                              <1> ;;        ret
   964                              <1> ;;;//-
   965                              <1> ;;endp
   966                              <1> 
   967                              <1> duplicate_page_dir:
   968                              <1> 	; 21/09/2015
   969                              <1> 	; 31/08/2015
   970                              <1> 	; 20/07/2015
   971                              <1> 	; 28/04/2015
   972                              <1> 	; 27/04/2015
   973                              <1> 	; 18/04/2015
   974                              <1> 	; 12/04/2015
   975                              <1> 	; 18/10/2014
   976                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
   977                              <1> 	;
   978                              <1> 	; INPUT -> 
   979                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
   980                              <1> 	;		    page directory.
   981                              <1> 	; OUTPUT ->
   982                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
   983                              <1> 	;	       page directory.
   984                              <1> 	;	(New page directory with new page table entries.)
   985                              <1> 	;	(New page tables with read only copies of the parent's
   986                              <1> 	;	pages.)
   987                              <1> 	;	EAX = 0 -> Error (CF = 1)
   988                              <1> 	;
   989                              <1> 	; Modified Registers -> none (except EAX)
   990                              <1> 	;
   991 000057B4 E8ECFDFFFF          <1> 	call	allocate_page
   992 000057B9 723E                <1> 	jc	short dpd_err
   993                              <1> 	;
   994 000057BB 55                  <1> 	push	ebp ; 20/07/2015
   995 000057BC 56                  <1> 	push	esi
   996 000057BD 57                  <1> 	push	edi
   997 000057BE 53                  <1> 	push	ebx
   998 000057BF 51                  <1> 	push	ecx
   999 000057C0 8B35[B8030300]      <1> 	mov	esi, [u.pgdir]
  1000 000057C6 89C7                <1> 	mov	edi, eax
  1001 000057C8 50                  <1> 	push	eax ; save child's page directory address
  1002                              <1> 	; 31/08/2015
  1003                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
  1004                              <1> 	; (use same system space for all user page tables) 
  1005 000057C9 A5                  <1> 	movsd
  1006 000057CA BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
  1007 000057CF B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
  1008                              <1> dpd_0:	
  1009 000057D4 AD                  <1> 	lodsd
  1010                              <1> 	;or	eax, eax
  1011                              <1>         ;jnz     short dpd_1
  1012 000057D5 A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
  1013 000057D7 7508                <1> 	jnz	short dpd_1
  1014                              <1>  	; 20/07/2015 (virtual address at the end of the page table)	
  1015 000057D9 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
  1016 000057DF EB0F                <1> 	jmp	short dpd_2
  1017                              <1> dpd_1:	
  1018 000057E1 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
  1019 000057E5 89C3                <1> 	mov	ebx, eax
  1020                              <1> 	; EBX = Parent's page table address
  1021 000057E7 E81F000000          <1> 	call	duplicate_page_table
  1022 000057EC 720C                <1> 	jc	short dpd_p_err
  1023                              <1> 	; EAX = Child's page table address
  1024 000057EE 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
  1025                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
  1026                              <1> 			 ; (present, writable, user)
  1027                              <1> dpd_2:
  1028 000057F0 AB                  <1> 	stosd
  1029 000057F1 E2E1                <1> 	loop	dpd_0
  1030                              <1> 	;
  1031 000057F3 58                  <1> 	pop	eax  ; restore child's page directory address
  1032                              <1> dpd_3:
  1033 000057F4 59                  <1> 	pop	ecx
  1034 000057F5 5B                  <1> 	pop	ebx
  1035 000057F6 5F                  <1> 	pop	edi
  1036 000057F7 5E                  <1> 	pop	esi
  1037 000057F8 5D                  <1> 	pop	ebp ; 20/07/2015
  1038                              <1> dpd_err:
  1039 000057F9 C3                  <1> 	retn
  1040                              <1> dpd_p_err:
  1041                              <1> 	; release the allocated pages missing (recover free space)
  1042 000057FA 58                  <1> 	pop	eax  ; the new page directory address (physical)
  1043 000057FB 8B1D[B8030300]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
  1044 00005801 E8D8FEFFFF          <1> 	call 	deallocate_page_dir
  1045 00005806 29C0                <1> 	sub	eax, eax ; 0
  1046 00005808 F9                  <1> 	stc
  1047 00005809 EBE9                <1> 	jmp	short dpd_3	
  1048                              <1> 
  1049                              <1> duplicate_page_table:
  1050                              <1> 	; 20/02/2017
  1051                              <1> 	; 21/09/2015
  1052                              <1> 	; 20/07/2015
  1053                              <1> 	; 05/05/2015
  1054                              <1> 	; 28/04/2015
  1055                              <1> 	; 27/04/2015
  1056                              <1> 	; 18/04/2015
  1057                              <1> 	; 18/10/2014
  1058                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
  1059                              <1> 	;
  1060                              <1> 	; INPUT -> 
  1061                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
  1062                              <1> 	;       20/02/2017		 
  1063                              <1> 	;	EBP = Linear address of the page (from 'duplicate_page_dir')
  1064                              <1> 	;	      (Linear address = CORE + user's virtual address) 	
  1065                              <1> 	; OUTPUT ->
  1066                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
  1067                              <1> 	;	      (with 'read only' attribute of page table entries)
  1068                              <1> 	;	20/02/2017
  1069                              <1> 	;	EBP = Next linear page address (for 'duplicate_page_dir')
  1070                              <1> 	;	
  1071                              <1> 	;	CF = 1 -> error 
  1072                              <1> 	;
  1073                              <1> 	; Modified Registers -> EBP (except EAX)
  1074                              <1> 	;
  1075 0000580B E895FDFFFF          <1> 	call	allocate_page
  1076 00005810 726A                <1> 	jc	short dpt_err
  1077                              <1> 	;
  1078 00005812 50                  <1> 	push	eax ; *
  1079 00005813 56                  <1> 	push	esi
  1080 00005814 57                  <1> 	push	edi
  1081 00005815 52                  <1> 	push	edx
  1082 00005816 51                  <1> 	push	ecx
  1083                              <1> 	;
  1084 00005817 89DE                <1> 	mov	esi, ebx
  1085 00005819 89C7                <1> 	mov	edi, eax
  1086 0000581B 89C2                <1> 	mov	edx, eax
  1087 0000581D 81C200100000        <1> 	add	edx, PAGE_SIZE 	
  1088                              <1> dpt_0:
  1089 00005823 AD                  <1> 	lodsd
  1090 00005824 21C0                <1> 	and	eax, eax
  1091 00005826 7444                <1> 	jz	short dpt_3
  1092 00005828 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
  1093 0000582A 7507                <1> 	jnz	short dpt_1
  1094                              <1> 	; 20/07/2015
  1095                              <1> 	; ebp = virtual (linear) address of the memory page
  1096 0000582C E83F050000          <1> 	call	reload_page ; 28/04/2015
  1097 00005831 7244                <1> 	jc	short dpt_p_err
  1098                              <1> dpt_1:
  1099                              <1> 	; 21/09/2015
  1100 00005833 89C1                <1> 	mov	ecx, eax
  1101 00005835 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  1102 00005839 F6C102              <1> 	test	cl, PTE_A_WRITE ; writable page ?
  1103 0000583C 7525                <1> 	jnz	short dpt_2
  1104                              <1> 	; Read only (parent) page
  1105                              <1> 	; 	- there is a third process which uses this page -
  1106                              <1> 	; Allocate a new page for the child process
  1107 0000583E E862FDFFFF          <1> 	call	allocate_page
  1108 00005843 7232                <1> 	jc	short dpt_p_err
  1109 00005845 57                  <1> 	push	edi
  1110 00005846 56                  <1> 	push	esi
  1111 00005847 89CE                <1> 	mov	esi, ecx
  1112 00005849 89C7                <1> 	mov	edi, eax
  1113 0000584B B900040000          <1> 	mov	ecx, PAGE_SIZE/4
  1114 00005850 F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
  1115 00005852 5E                  <1> 	pop	esi
  1116 00005853 5F                  <1> 	pop	edi
  1117                              <1> 	; 
  1118 00005854 53                  <1> 	push	ebx
  1119 00005855 50                  <1> 	push	eax
  1120                              <1> 	; 20/07/2015
  1121 00005856 89EB                <1> 	mov	ebx, ebp
  1122                              <1> 	; ebx = virtual (linear) address of the memory page
  1123 00005858 E887030000          <1> 	call	add_to_swap_queue
  1124 0000585D 58                  <1> 	pop	eax
  1125 0000585E 5B                  <1> 	pop	ebx
  1126                              <1> 	; 21/09/2015
  1127 0000585F 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
  1128                              <1> 		; user + writable + present page
  1129 00005861 EB09                <1> 	jmp	short dpt_3
  1130                              <1> dpt_2:
  1131                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
  1132 00005863 0C05                <1> 	or	al, PTE_A_USER+PTE_A_PRESENT 
  1133                              <1> 		    ; (read only page!)
  1134 00005865 8946FC              <1> 	mov	[esi-4], eax ; update parent's PTE
  1135 00005868 660D0002            <1> 	or      ax, PTE_DUPLICATED  ; (read only page & duplicated PTE!)
  1136                              <1> dpt_3:
  1137 0000586C AB                  <1> 	stosd  ; EDI points to child's PTE  	 
  1138                              <1> 	;
  1139 0000586D 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
  1140                              <1> 	;
  1141 00005873 39D7                <1> 	cmp	edi, edx
  1142 00005875 72AC                <1> 	jb	short dpt_0
  1143                              <1> dpt_p_err:
  1144 00005877 59                  <1> 	pop	ecx
  1145 00005878 5A                  <1> 	pop	edx
  1146 00005879 5F                  <1> 	pop	edi
  1147 0000587A 5E                  <1> 	pop	esi
  1148 0000587B 58                  <1> 	pop	eax ; *
  1149                              <1> dpt_err:
  1150 0000587C C3                  <1> 	retn
  1151                              <1> 
  1152                              <1> page_fault_handler:	; CPU EXCEPTION 0Eh (14) : Page Fault !
  1153                              <1> 	; 21/09/2015
  1154                              <1> 	; 19/09/2015
  1155                              <1> 	; 17/09/2015
  1156                              <1> 	; 28/08/2015
  1157                              <1> 	; 20/07/2015
  1158                              <1> 	; 28/06/2015
  1159                              <1> 	; 03/05/2015
  1160                              <1> 	; 30/04/2015
  1161                              <1> 	; 18/04/2015
  1162                              <1> 	; 12/04/2015
  1163                              <1> 	; 30/10/2014
  1164                              <1> 	; 11/09/2014
  1165                              <1> 	; 10/09/2014 (Retro UNIX 386 v1 - beginning)
  1166                              <1> 	;
  1167                              <1> 	; Note: This is not an interrupt/exception handler.
  1168                              <1> 	;	This is a 'page fault remedy' subroutine 
  1169                              <1> 	;	which will be called by standard/uniform
  1170                              <1> 	;	exception handler.
  1171                              <1> 	;
  1172                              <1> 	; INPUT -> 
  1173                              <1> 	;	[error_code] = 32 bit ERROR CODE (lower 5 bits are valid)
  1174                              <1> 	;
  1175                              <1> 	;	cr2 = the virtual (linear) address 
  1176                              <1> 	;	      which has caused to page fault (19/09/2015)
  1177                              <1> 	;
  1178                              <1> 	; OUTPUT ->
  1179                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
  1180                              <1> 	;	EAX = 0 -> no error
  1181                              <1> 	;	EAX > 0 -> error code in EAX (also CF = 1)
  1182                              <1> 	;
  1183                              <1> 	; Modified Registers -> none (except EAX)
  1184                              <1> 	;	
  1185                              <1>         ;
  1186                              <1>         ; ERROR CODE:
  1187                              <1> 	;	 31  .....	4   3	2   1	0
  1188                              <1> 	;	+---+-- --+---+---+---+---+---+---+
  1189                              <1> 	;	|   Reserved  | I | R | U | W | P |
  1190                              <1> 	;	+---+-- --+---+---+---+---+---+---+
  1191                              <1> 	;
  1192                              <1> 	; P : PRESENT -	When set, the page fault was caused by 
  1193                              <1>     	;		a page-protection violation. When not set,
  1194                              <1> 	;		it was caused by a non-present page.
  1195                              <1> 	; W : WRITE   -	When set, the page fault was caused by
  1196                              <1> 	;		a page write. When not set, it was caused
  1197                              <1> 	;		by a page read.
  1198                              <1> 	; U : USER    -	When set, the page fault was caused 
  1199                              <1> 	;		while CPL = 3. 
  1200                              <1> 	;		This does not necessarily mean that
  1201                              <1> 	;		the page fault was a privilege violation.
  1202                              <1> 	; R : RESERVD -	When set, the page fault was caused by
  1203                              <1> 	;     WRITE	reading a 1 in a reserved field.
  1204                              <1> 	; I : INSTRUC -	When set, the page fault was caused by
  1205                              <1> 	;     FETCH	an instruction fetch
  1206                              <1> 	;
  1207                              <1> 	;; x86 (32 bit) VIRTUAL ADDRESS TRANSLATION
  1208                              <1> 	;  31               22                  12 11                    0
  1209                              <1> 	; +-------------------+-------------------+-----------------------+
  1210                              <1>        	; | PAGE DIR. ENTRY # | PAGE TAB. ENTRY # |        OFFSET         |
  1211                              <1>        	; +-------------------+-------------------+-----------------------+
  1212                              <1> 	;
  1213                              <1> 
  1214                              <1> 	;; CR3 REGISTER (Control Register 3)
  1215                              <1> 	;  31                                   12             5 4 3 2   0
  1216                              <1> 	; +---------------------------------------+-------------+---+-----+
  1217                              <1>       	; |                                       |  		|P|P|     |
  1218                              <1>       	; |   PAGE DIRECTORY TABLE BASE ADDRESS   |  reserved	|C|W|rsvrd|
  1219                              <1>       	; |                                       | 		|D|T|     |
  1220                              <1>    	; +---------------------------------------+-------------+---+-----+
  1221                              <1> 	;
  1222                              <1> 	;	PWT    - WRITE THROUGH
  1223                              <1> 	;	PCD    - CACHE DISABLE		
  1224                              <1> 	;
  1225                              <1> 	;
  1226                              <1> 	;; x86 PAGE DIRECTORY ENTRY (4 KByte Page)
  1227                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
  1228                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
  1229                              <1>       	; |                                       |     | | | | |P|P|U|R| |
  1230                              <1>       	; |     PAGE TABLE BASE ADDRESS 31..12    | AVL |G|0|D|A|C|W|/|/|P|
  1231                              <1>       	; |                                       |     | | | | |D|T|S|W| |
  1232                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
  1233                              <1> 	;
  1234                              <1>         ;       P      - PRESENT
  1235                              <1>         ;       R/W    - READ/WRITE
  1236                              <1>         ;       U/S    - USER/SUPERVISOR
  1237                              <1> 	;	PWT    - WRITE THROUGH
  1238                              <1> 	;	PCD    - CACHE DISABLE	
  1239                              <1> 	;	A      - ACCESSED	
  1240                              <1>         ;       D      - DIRTY (IGNORED)
  1241                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
  1242                              <1> 	;	G      - GLOBAL	(IGNORED) 
  1243                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
  1244                              <1> 	;
  1245                              <1> 	;
  1246                              <1> 	;; x86 PAGE TABLE ENTRY (4 KByte Page)
  1247                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
  1248                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
  1249                              <1>       	; |                                       |     | |P| | |P|P|U|R| |
  1250                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |G|A|D|A|C|W|/|/|P|
  1251                              <1>       	; |                                       |     | |T| | |D|T|S|W| |
  1252                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
  1253                              <1> 	;
  1254                              <1>         ;       P      - PRESENT
  1255                              <1>         ;       R/W    - READ/WRITE
  1256                              <1>         ;       U/S    - USER/SUPERVISOR
  1257                              <1> 	;	PWT    - WRITE THROUGH
  1258                              <1> 	;	PCD    - CACHE DISABLE	
  1259                              <1> 	;	A      - ACCESSED	
  1260                              <1>         ;       D      - DIRTY
  1261                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
  1262                              <1> 	;	G      - GLOBAL	 
  1263                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
  1264                              <1> 	;
  1265                              <1> 	;
  1266                              <1> 	;; 80386 PAGE TABLE ENTRY (4 KByte Page)
  1267                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
  1268                              <1> 	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
  1269                              <1>       	; |                                       |     | | | | | | |U|R| |
  1270                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |0|0|D|A|0|0|/|/|P|
  1271                              <1>       	; |                                       |     | | | | | | |S|W| |
  1272                              <1>       	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
  1273                              <1> 	;
  1274                              <1>         ;       P      - PRESENT
  1275                              <1>         ;       R/W    - READ/WRITE
  1276                              <1>         ;       U/S    - USER/SUPERVISOR
  1277                              <1>         ;       D      - DIRTY
  1278                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
  1279                              <1> 	;
  1280                              <1>         ;       NOTE: 0 INDICATES INTEL RESERVED. DO NOT DEFINE.
  1281                              <1> 	;
  1282                              <1> 	;
  1283                              <1> 	;; Invalid Page Table Entry
  1284                              <1> 	; 31                                                           1 0
  1285                              <1>       	; +-------------------------------------------------------------+-+
  1286                              <1>       	; |                                                             | |
  1287                              <1>       	; |                          AVAILABLE                          |0|
  1288                              <1>       	; |                                                             | |
  1289                              <1>       	; +-------------------------------------------------------------+-+
  1290                              <1> 	;
  1291                              <1> 
  1292 0000587D 53                  <1> 	push	ebx
  1293 0000587E 52                  <1> 	push	edx
  1294 0000587F 51                  <1> 	push	ecx
  1295                              <1> 	;
  1296                              <1> 	; 21/09/2015 (debugging)
  1297 00005880 FF05[CC030300]      <1> 	inc	dword [u.pfcount] ; page fault count for running process
  1298 00005886 FF05[80050300]      <1> 	inc	dword [PF_Count] ; total page fault count	
  1299                              <1> 	; 28/06/2015
  1300                              <1> 	;mov	edx, [error_code] ; Lower 5 bits are valid
  1301 0000588C 8A15[78050300]      <1> 	mov	dl, [error_code]
  1302                              <1> 	;
  1303 00005892 F6C201              <1> 	test	dl, 1	; page fault was caused by a non-present page
  1304                              <1> 			; sign
  1305 00005895 7422                <1> 	jz	short pfh_alloc_np
  1306                              <1> 	; 
  1307                              <1> 	; If it is not a 'write on read only page' type page fault
  1308                              <1> 	; major page fault error with minor reason must be returned without 
  1309                              <1> 	; fixing the problem. 'sys_exit with error' will be needed
  1310                              <1> 	; after return here!
  1311                              <1> 	; Page fault will be remedied, by copying page contents
  1312                              <1> 	; to newly allocated page with write permission;
  1313                              <1> 	; sys_fork -> sys_exec -> copy on write, demand paging method is 
  1314                              <1> 	; used for working with minimum possible memory usage. 
  1315                              <1> 	; sys_fork will duplicate page directory and tables of parent  
  1316                              <1> 	; process with 'read only' flag. If the child process attempts to
  1317                              <1> 	; write on these read only pages, page fault will be directed here
  1318                              <1> 	; for allocating a new page with same data/content. 
  1319                              <1> 	;
  1320                              <1> 	; IMPORTANT : Retro UNIX 386 v1 (and SINGLIX and TR-DOS)
  1321                              <1> 	; will not force to separate CODE and DATA space 
  1322                              <1> 	; in a process/program... 
  1323                              <1> 	; CODE segment/section may contain DATA!
  1324                              <1> 	; It is flat, smoth and simplest programming method already as in 
  1325                              <1> 	; Retro UNIX 8086 v1 and MS-DOS programs.
  1326                              <1> 	;	
  1327 00005897 F6C202              <1> 	test	dl, 2	; page fault was caused by a page write
  1328                              <1> 			; sign
  1329 0000589A 0F84AB000000        <1>         jz      pfh_p_err
  1330                              <1> 	; 31/08/2015
  1331 000058A0 F6C204              <1> 	test	dl, 4	; page fault was caused while CPL = 3 (user mode)
  1332                              <1> 			; sign.  (U+W+P = 4+2+1 = 7)
  1333 000058A3 0F84A2000000        <1>         jz	pfh_pv_err
  1334                              <1> 	;
  1335                              <1> 	; make a new page and copy the parent's page content
  1336                              <1> 	; as the child's new page content
  1337                              <1> 	;
  1338 000058A9 0F20D3              <1> 	mov	ebx, cr2 ; CR2 contains the linear address 
  1339                              <1> 			 ; which has caused to page fault
  1340 000058AC E8A2000000          <1> 	call 	copy_page
  1341 000058B1 0F828D000000        <1>         jc      pfh_im_err ; insufficient memory
  1342                              <1> 	;
  1343 000058B7 EB7D                <1>         jmp     pfh_cpp_ok
  1344                              <1> 	;
  1345                              <1> pfh_alloc_np:
  1346 000058B9 E8E7FCFFFF          <1> 	call	allocate_page	; (allocate a new page)
  1347 000058BE 0F8280000000        <1>         jc      pfh_im_err	; 'insufficient memory' error
  1348                              <1> pfh_chk_cpl:
  1349                              <1> 	; EAX = Physical (base) address of the allocated (new) page
  1350                              <1> 		; (Lower 12 bits are ZERO, because 
  1351                              <1> 		;	the address is on a page boundary)
  1352 000058C4 80E204              <1> 	and	dl, 4	; CPL = 3 ?
  1353 000058C7 7505                <1> 	jnz	short pfh_um
  1354                              <1> 			; Page fault handler for kernel/system mode (CPL=0)		
  1355 000058C9 0F20DB              <1> 	mov	ebx, cr3 ; CR3 (Control Register 3) contains physical address
  1356                              <1> 			 ; of the current/active page directory
  1357                              <1> 			 ; (Always kernel/system mode page directory, here!)
  1358                              <1> 			 ; Note: Lower 12 bits are 0. (page boundary)
  1359 000058CC EB06                <1> 	jmp	short pfh_get_pde
  1360                              <1> 	;
  1361                              <1> pfh_um:			; Page fault handler for user/appl. mode (CPL=3)
  1362 000058CE 8B1D[B8030300]      <1>  	mov	ebx, [u.pgdir] ; Page directory of current/active process
  1363                              <1> 			; Physical address of the USER's page directory
  1364                              <1> 			; Note: Lower 12 bits are 0. (page boundary)
  1365                              <1> pfh_get_pde:
  1366 000058D4 80CA03              <1> 	or	dl, 3	; USER + WRITE + PRESENT or SYSTEM + WRITE + PRESENT
  1367 000058D7 0F20D1              <1> 	mov	ecx, cr2 ; CR2 contains the virtual address 
  1368                              <1> 			 ; which has been caused to page fault
  1369                              <1> 			 ;
  1370 000058DA C1E914              <1> 	shr	ecx, 20	 ; shift 20 bits right
  1371 000058DD 80E1FC              <1> 	and	cl, 0FCh ; mask lower 2 bits to get PDE offset		
  1372                              <1> 	;
  1373 000058E0 01CB                <1> 	add	ebx, ecx ; now, EBX points to the relevant page dir entry 
  1374 000058E2 8B0B                <1> 	mov	ecx, [ebx] ; physical (base) address of the page table 	
  1375 000058E4 F6C101              <1> 	test	cl, 1	 ; check bit 0 is set (1) or not (0).
  1376 000058E7 740B                <1> 	jz	short pfh_set_pde ; Page directory entry is not valid,
  1377                              <1> 			  	  ; set/validate page directory entry
  1378 000058E9 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
  1379 000058EE 89CB                <1> 	mov	ebx, ecx ; Physical address of the page table
  1380 000058F0 89C1                <1> 	mov	ecx, eax ; new page address (physical) 	
  1381 000058F2 EB16                <1> 	jmp	short pfh_get_pte
  1382                              <1> pfh_set_pde:
  1383                              <1> 	;; NOTE: Page directories and page tables never be swapped out!
  1384                              <1> 	;;	 (So, we know this PDE is empty or invalid)
  1385                              <1> 	;
  1386 000058F4 08D0                <1> 	or	al, dl	 ; lower 3 bits are used as U/S, R/W, P flags
  1387 000058F6 8903                <1> 	mov	[ebx], eax ; Let's put the new page directory entry here !
  1388 000058F8 30C0                <1> 	xor	al, al	 ; clear lower (3..8) bits
  1389 000058FA 89C3                <1> 	mov	ebx, eax
  1390 000058FC E8A4FCFFFF          <1> 	call	allocate_page	 ; (allocate a new page)
  1391 00005901 7241                <1> 	jc	short pfh_im_err   ; 'insufficient memory' error
  1392                              <1> pfh_spde_1:
  1393                              <1> 	; EAX = Physical (base) address of the allocated (new) page
  1394 00005903 89C1                <1> 	mov	ecx, eax
  1395 00005905 E815FDFFFF          <1> 	call	clear_page ; Clear page content
  1396                              <1> pfh_get_pte:
  1397 0000590A 0F20D0              <1> 	mov	eax, cr2 ; virtual address
  1398                              <1> 			 ; which has been caused to page fault
  1399 0000590D 89C7                <1> 	mov	edi, eax ; 20/07/2015
  1400 0000590F C1E80C              <1> 	shr	eax, 12	 ; shift 12 bit right to get 
  1401                              <1> 			 ; higher 20 bits of the page fault address 
  1402 00005912 25FF030000          <1> 	and	eax, 3FFh ; mask PDE# bits, the result is PTE# (0 to 1023)
  1403 00005917 C1E002              <1> 	shl	eax, 2	; shift 2 bits left to get PTE offset
  1404 0000591A 01C3                <1> 	add	ebx, eax ; now, EBX points to the relevant page table entry 
  1405 0000591C 8B03                <1> 	mov	eax, [ebx] ; get previous value of pte
  1406                              <1> 		; bit 0 of EAX is always 0 (otherwise we would not be here)
  1407 0000591E 21C0                <1> 	and	eax, eax
  1408 00005920 7410                <1> 	jz	short pfh_gpte_1
  1409                              <1> 	; 20/07/2015
  1410 00005922 87D9                <1> 	xchg	ebx, ecx ; new page address (physical)
  1411 00005924 55                  <1> 	push	ebp ; 20/07/2015
  1412 00005925 0F20D5              <1> 	mov	ebp, cr2
  1413                              <1> 		; ECX = physical address of the page table entry
  1414                              <1> 		; EBX = Memory page address (physical!)
  1415                              <1> 		; EAX = Swap disk (offset) address
  1416                              <1> 		; EBP = virtual address (page fault address)
  1417 00005928 E8B7000000          <1> 	call	swap_in
  1418 0000592D 5D                  <1> 	pop	ebp
  1419 0000592E 7210                <1> 	jc      short pfh_err_retn
  1420 00005930 87CB                <1> 	xchg	ecx, ebx
  1421                              <1> 		; EBX = physical address of the page table entry
  1422                              <1> 		; ECX = new page
  1423                              <1> pfh_gpte_1:
  1424 00005932 08D1                <1> 	or	cl, dl	; lower 3 bits are used as U/S, R/W, P flags
  1425 00005934 890B                <1> 	mov	[ebx], ecx ; Let's put the new page table entry here !
  1426                              <1> pfh_cpp_ok:
  1427                              <1> 	; 20/07/2015
  1428 00005936 0F20D3              <1> 	mov	ebx, cr2
  1429 00005939 E8A6020000          <1> 	call 	add_to_swap_queue
  1430                              <1> 	;
  1431                              <1> 	; The new PTE (which contains the new page) will be added to 
  1432                              <1> 	; the swap queue, here. 
  1433                              <1> 	; (Later, if memory will become insufficient, 
  1434                              <1> 	; one page will be swapped out which is at the head of 
  1435                              <1> 	; the swap queue by using FIFO and access check methods.)
  1436                              <1> 	;
  1437 0000593E 31C0                <1> 	xor	eax, eax  ; 0
  1438                              <1> 	;
  1439                              <1> pfh_err_retn:
  1440 00005940 59                  <1> 	pop	ecx
  1441 00005941 5A                  <1> 	pop	edx
  1442 00005942 5B                  <1> 	pop	ebx
  1443 00005943 C3                  <1> 	retn 
  1444                              <1> 	
  1445                              <1> pfh_im_err:
  1446 00005944 B8E4000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_IM ; Error code in AX
  1447                              <1> 			; Major (Primary) Error: Page Fault
  1448                              <1> 			; Minor (Secondary) Error: Insufficient Memory !
  1449 00005949 EBF5                <1> 	jmp	short pfh_err_retn
  1450                              <1> 
  1451                              <1> 
  1452                              <1> pfh_p_err: ; 09/03/2015
  1453                              <1> pfh_pv_err:
  1454                              <1> 	; Page fault was caused by a protection-violation
  1455 0000594B B8E6000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_PV ; Error code in AX
  1456                              <1> 			; Major (Primary) Error: Page Fault
  1457                              <1> 			; Minor (Secondary) Error: Protection violation !
  1458 00005950 F9                  <1> 	stc
  1459 00005951 EBED                <1> 	jmp	short pfh_err_retn
  1460                              <1> 
  1461                              <1> copy_page:
  1462                              <1> 	; 22/09/2015
  1463                              <1> 	; 21/09/2015
  1464                              <1> 	; 19/09/2015
  1465                              <1> 	; 07/09/2015
  1466                              <1> 	; 31/08/2015
  1467                              <1> 	; 20/07/2015
  1468                              <1> 	; 05/05/2015
  1469                              <1> 	; 03/05/2015
  1470                              <1> 	; 18/04/2015
  1471                              <1> 	; 12/04/2015
  1472                              <1> 	; 30/10/2014
  1473                              <1> 	; 18/10/2014 (Retro UNIX 386 v1 - beginning)
  1474                              <1> 	;
  1475                              <1> 	; INPUT -> 
  1476                              <1> 	;	EBX = Virtual (linear) address of source page
  1477                              <1> 	;	     (Page fault address)
  1478                              <1> 	; OUTPUT ->
  1479                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
  1480                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
  1481                              <1> 	;	EAX = 0 (CF = 1) 
  1482                              <1> 	;		if there is not a free page to be allocated
  1483                              <1> 	;	(page content of the source page will be copied
  1484                              <1> 	;	onto the target/new page) 	
  1485                              <1> 	;
  1486                              <1> 	; Modified Registers -> ecx, ebx (except EAX)
  1487                              <1> 	;	
  1488 00005953 56                  <1> 	push	esi
  1489 00005954 57                  <1> 	push	edi
  1490                              <1> 	;push	ebx
  1491                              <1> 	;push	ecx
  1492 00005955 31F6                <1> 	xor 	esi, esi
  1493 00005957 C1EB0C              <1> 	shr	ebx, 12 ; shift 12 bits right to get PDE & PTE numbers
  1494 0000595A 89D9                <1> 	mov	ecx, ebx ; save page fault address (as 12 bit shifted)
  1495 0000595C C1EB08              <1> 	shr	ebx, 8	 ; shift 8 bits right and then
  1496 0000595F 80E3FC              <1> 	and	bl, 0FCh ; mask lower 2 bits to get PDE offset	
  1497 00005962 89DF                <1> 	mov 	edi, ebx ; save it for the parent of current process
  1498 00005964 031D[B8030300]      <1> 	add	ebx, [u.pgdir] ; EBX points to the relevant page dir entry 
  1499 0000596A 8B03                <1> 	mov	eax, [ebx] ; physical (base) address of the page table
  1500 0000596C 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits 	
  1501 00005970 89CB                <1> 	mov	ebx, ecx   ; (restore higher 20 bits of page fault address)
  1502 00005972 81E3FF030000        <1> 	and	ebx, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
  1503 00005978 66C1E302            <1> 	shl	bx, 2	   ; shift 2 bits left to get PTE offset
  1504 0000597C 01C3                <1> 	add	ebx, eax   ; EBX points to the relevant page table entry 
  1505                              <1> 	; 07/09/2015
  1506 0000597E 66F7030002          <1>         test    word [ebx], PTE_DUPLICATED ; (Does current process share this
  1507                              <1> 				     ; read only page as a child process?)	
  1508 00005983 7509                <1> 	jnz	short cpp_0 ; yes
  1509 00005985 8B0B                <1> 	mov	ecx, [ebx] ; PTE value
  1510 00005987 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h  ; clear page attributes
  1511 0000598C EB32                <1> 	jmp	short cpp_1
  1512                              <1> cpp_0:
  1513 0000598E 89FE                <1> 	mov	esi, edi
  1514 00005990 0335[BC030300]      <1> 	add	esi, [u.ppgdir] ; the parent's page directory entry
  1515 00005996 8B06                <1> 	mov	eax, [esi] ; physical (base) address of the page table
  1516 00005998 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  1517 0000599C 89CE                <1> 	mov	esi, ecx   ; (restore higher 20 bits of page fault address)	
  1518 0000599E 81E6FF030000        <1> 	and	esi, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
  1519 000059A4 66C1E602            <1> 	shl	si, 2	   ; shift 2 bits left to get PTE offset
  1520 000059A8 01C6                <1> 	add	esi, eax   ; EDX points to the relevant page table entry  	
  1521 000059AA 8B0E                <1> 	mov	ecx, [esi] ; PTE value of the parent process
  1522                              <1> 	; 21/09/2015
  1523 000059AC 8B03                <1> 	mov	eax, [ebx] ; PTE value of the child process
  1524 000059AE 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear page attributes	
  1525                              <1> 	;
  1526 000059B2 F6C101              <1> 	test	cl, PTE_A_PRESENT ; is it a present/valid page ?
  1527 000059B5 7424                <1> 	jz	short cpp_3 ; the parent's page is not same page  	
  1528                              <1> 	;
  1529 000059B7 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h ; clear page attributes
  1530 000059BC 39C8                <1> 	cmp	eax, ecx   ; Same page?	
  1531 000059BE 751B                <1> 	jne	short cpp_3 ; Parent page and child page are not same 
  1532                              <1> 			    ; Convert child's page to writable page
  1533                              <1> cpp_1:
  1534 000059C0 E8E0FBFFFF          <1> 	call	allocate_page
  1535 000059C5 721A                <1> 	jc	short cpp_4 ; 'insufficient memory' error
  1536 000059C7 21F6                <1> 	and	esi, esi    ; check ESI is valid or not
  1537 000059C9 7405                <1> 	jz	short cpp_2
  1538                              <1> 		; Convert read only page to writable page 
  1539                              <1> 		;(for the parent of the current process)
  1540                              <1> 	;and	word [esi], PTE_A_CLEAR ; 0F000h
  1541                              <1> 	; 22/09/2015
  1542 000059CB 890E                <1> 	mov	[esi], ecx
  1543 000059CD 800E07              <1> 	or	byte [esi], PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER
  1544                              <1> 				 ; 1+2+4 = 7
  1545                              <1> cpp_2:
  1546 000059D0 89C7                <1> 	mov	edi, eax ; new page address of the child process
  1547                              <1> 	; 07/09/2015
  1548 000059D2 89CE                <1> 	mov	esi, ecx ; the page address of the parent process
  1549 000059D4 B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
  1550 000059D9 F3A5                <1> 	rep	movsd ; 31/08/2015
  1551                              <1> cpp_3:		
  1552 000059DB 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER ; 1+2+4 = 7
  1553 000059DD 8903                <1> 	mov	[ebx], eax ; Update PTE
  1554 000059DF 28C0                <1> 	sub	al, al ; clear attributes
  1555                              <1> cpp_4:
  1556                              <1> 	;pop	ecx
  1557                              <1> 	;pop	ebx
  1558 000059E1 5F                  <1> 	pop	edi
  1559 000059E2 5E                  <1> 	pop	esi
  1560 000059E3 C3                  <1> 	retn
  1561                              <1> 
  1562                              <1> ;; 28/04/2015
  1563                              <1> ;; 24/10/2014
  1564                              <1> ;; 21/10/2014 (Retro UNIX 386 v1 - beginning)
  1565                              <1> ;; SWAP_PAGE_QUEUE (4096 bytes)
  1566                              <1> ;;
  1567                              <1> ;;   0000   0001   0002   0003   ....   1020   1021   1022   1023	
  1568                              <1> ;; +------+------+------+------+-    -+------+------+------+------+
  1569                              <1> ;; |  pg1 |  pg2 |  pg3 |  pg4 | .... |pg1021|pg1022|pg1023|pg1024|
  1570                              <1> ;; +------+------+------+------+-    -+------+------+------+------+    
  1571                              <1> ;;
  1572                              <1> ;; [swpq_last] = 0 to 4096 (step 4) -> the last position on the queue
  1573                              <1> ;;
  1574                              <1> ;; Method:
  1575                              <1> ;;	Swap page queue is a list of allocated pages with physical
  1576                              <1> ;;	addresses (system mode virtual adresses = physical addresses).
  1577                              <1> ;;	It is used for 'swap_in' and 'swap_out' procedures.
  1578                              <1> ;;	When a new page is being allocated, swap queue is updated
  1579                              <1> ;;	by 'swap_queue_shift' procedure, header of the queue (offset 0)
  1580                              <1> ;;	is checked for 'accessed' flag. If the 1st page on the queue
  1581                              <1> ;;	is 'accessed' or 'read only', it is dropped from the list;
  1582                              <1> ;;	other pages from the 2nd to the last (in [swpq_last]) shifted
  1583                              <1> ;; 	to head then the 2nd page becomes the 1st and '[swpq_last]' 
  1584                              <1> ;;	offset value becomes it's previous offset value - 4.
  1585                              <1> ;;	If the 1st page of the swap page queue is not 'accessed'	
  1586                              <1> ;;	the queue/list is not shifted.
  1587                              <1> ;;	After the queue/list shift, newly allocated page is added
  1588                              <1> ;;	to the tail of the queue at the [swpq_count*4] position.
  1589                              <1> ;;	But, if [swpq_count] > 1023, the newly allocated page
  1590                              <1> ;;	will not be added to the tail of swap page queue.  		 
  1591                              <1> ;;	
  1592                              <1> ;;	During 'swap_out' procedure, swap page queue is checked for
  1593                              <1> ;;	the first non-accessed, writable page in the list, 
  1594                              <1> ;;	from the head to the tail. The list is shifted to left 
  1595                              <1> ;;	(to the head) till a non-accessed page will be found in the list.
  1596                              <1> ;;	Then, this page	is swapped out (to disk) and then it is dropped
  1597                              <1> ;;	from the list by a final swap queue shift. [swpq_count] value
  1598                              <1> ;;	is changed. If all pages on the queue' are 'accessed', 
  1599                              <1> ;;	'insufficient memory' error will be returned ('swap_out' 
  1600                              <1> ;;	procedure will be failed)...
  1601                              <1> ;;
  1602                              <1> ;;	Note: If the 1st page of the queue is an 'accessed' page,
  1603                              <1> ;;	'accessed' flag of the page will be reset (0) and that page
  1604                              <1> ;;	(PTE) will be added to the tail of the queue after
  1605                              <1> ;;	the check, if [swpq_count] < 1023. If [swpq_count] = 1024
  1606                              <1> ;;	the queue will be rotated and the PTE in the head will be
  1607                              <1> ;;	added to the tail after resetting 'accessed' bit. 
  1608                              <1> ;;
  1609                              <1> ;;
  1610                              <1> ;;	
  1611                              <1> ;; SWAP DISK/FILE (with 4096 bytes swapped page blocks)
  1612                              <1> ;;
  1613                              <1> ;;  00000000  00000004  00000008  0000000C   ...   size-8    size-4
  1614                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+
  1615                              <1> ;; |descriptr| page(1) | page(2) | page(3) | ... |page(n-1)| page(n) |
  1616                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+    
  1617                              <1> ;;
  1618                              <1> ;; [swpd_next] = the first free block address in swapped page records
  1619                              <1> ;;    		 for next free block search by 'swap_out' procedure.
  1620                              <1> ;; [swpd_size] = swap disk/file size in sectors (512 bytes)
  1621                              <1> ;;		 NOTE: max. possible swap disk size is 1024 GB
  1622                              <1> ;; 		 (entire swap space must be accessed by using
  1623                              <1> ;;		 31 bit offset address) 
  1624                              <1> ;; [swpd_free] = free block (4096 bytes) count in swap disk/file space
  1625                              <1> ;; [swpd_start] = absolute/start address of the swap disk/file
  1626                              <1> ;;		  0 for file, or beginning sector of the swap partition
  1627                              <1> ;; [swp_drv] = logical drive description table addr. of swap disk/file
  1628                              <1> ;;
  1629                              <1> ;; 					
  1630                              <1> ;; Method:
  1631                              <1> ;;	When the memory (ram) becomes insufficient, page allocation
  1632                              <1> ;;	procedure swaps out a page from memory to the swap disk 
  1633                              <1> ;;	(partition) or swap file to get a new free page at the memory.
  1634                              <1> ;;	Swapping out is performed by using swap page queue.
  1635                              <1> ;;
  1636                              <1> ;; 	Allocation block size of swap disk/file is equal to page size
  1637                              <1> ;;	(4096 bytes). Swapping address (in sectors) is recorded
  1638                              <1> ;;	into relevant page file entry as 31 bit physical (logical)
  1639                              <1> ;;	offset address as 1 bit shifted to left for present flag (0).
  1640                              <1> ;;	Swapped page address is between 1 and swap disk/file size - 4.	  
  1641                              <1> ;;	Absolute physical (logical) address of the swapped page is 
  1642                              <1> ;;	calculated by adding offset value to the swap partition's 
  1643                              <1> ;;	start address. If the swap device (disk) is a virtual disk 
  1644                              <1> ;;	or it is a file, start address of the swap disk/volume is 0, 
  1645                              <1> ;;	and offset value is equal to absolute (physical or logical)
  1646                              <1> ;;	address/position. (It has not to be ZERO if the swap partition 
  1647                              <1> ;;	is in a partitioned virtual hard disk.) 
  1648                              <1> ;;
  1649                              <1> ;;	Note: Swap addresses are always specified/declared in sectors, 
  1650                              <1> ;;	not in bytes or	in blocks/zones/clusters (4096 bytes) as unit.
  1651                              <1> ;;
  1652                              <1> ;;	Swap disk/file allocation is mapped via 'Swap Allocation Table'
  1653                              <1> ;;	at memory as similar to 'Memory Allocation Table'.
  1654                              <1> ;;
  1655                              <1> ;;	Every bit of Swap Allocation Table repsesents one swap block
  1656                              <1> ;;	(equal to page size) respectively. Bit 0 of the S.A.T. byte 0
  1657                              <1> ;;	is reserved for swap disk/file block 0 as descriptor block
  1658                              <1> ;;	(also for compatibility with PTE). If bit value is ZERO,
  1659                              <1> ;;	it means relevant (respective) block is in use, and, 
  1660                              <1> ;;	of course, if bit value is 1, it means relevant (respective)
  1661                              <1> ;;      swap disk/file block is free.
  1662                              <1> ;;	For example: bit 1 of the byte 128 repsesents block 1025 
  1663                              <1> ;;	(128*8+1) or sector (offset) 8200 on the swap disk or
  1664                              <1> ;;	byte (offset/position) 4198400 in the swap file. 
  1665                              <1> ;;	4GB swap space is represented via 128KB Swap Allocation Table.
  1666                              <1> ;;	Initial layout of Swap Allocation Table is as follows:
  1667                              <1> ;;	------------------------------------------------------------
  1668                              <1> ;;	0111111111111111111111111 .... 11111111111111111111111111111
  1669                              <1> ;;	------------------------------------------------------------
  1670                              <1> ;;	(0 is reserved block, 1s represent free blocks respectively.)
  1671                              <1> ;;	(Note: Allocation cell/unit of the table is bit, not byte)
  1672                              <1> ;;
  1673                              <1> ;;	..............................................................
  1674                              <1> ;;
  1675                              <1> ;;	'swap_out' procedure checks 'free_swap_blocks' count at first,
  1676                              <1> ;;	then it searches Swap Allocation Table if free count is not
  1677                              <1> ;;	zero. From begining the [swpd_next] dword value, the first bit 
  1678                              <1> ;;	position with value of 1 on the table is converted to swap
  1679                              <1> ;;	disk/file offset address, in sectors (not 4096 bytes block).
  1680                              <1> ;;	'ldrv_write' procedure is called with ldrv (logical drive
  1681                              <1> ;;	number of physical swap disk or virtual swap disk)
  1682                              <1> ;;	number, sector offset (not absolute sector -LBA- number),
  1683                              <1> ;;	and sector count (8, 512*8 = 4096) and buffer adress
  1684                              <1> ;;	(memory page). That will be a direct disk write procedure.
  1685                              <1> ;;	(for preventing late memory allocation, significant waiting). 
  1686                              <1> ;;	If disk write procedure returns with error or free count of 
  1687                              <1> ;;	swap blocks is ZERO, 'swap_out' procedure will return with
  1688                              <1> ;;	'insufficient memory error' (cf=1). 
  1689                              <1> ;;
  1690                              <1> ;;	(Note: Even if free swap disk/file blocks was not zero,
  1691                              <1> ;;	any disk write error will not be fixed by 'swap_out' procedure,
  1692                              <1> ;;	in other words, 'swap_out' will not check the table for other
  1693                              <1> ;;	free blocks after a disk write error. It will return to 
  1694                              <1> ;;	the caller with error (CF=1) which means swapping is failed. 
  1695                              <1> ;;
  1696                              <1> ;;	After writing the page on to swap disk/file address/sector,
  1697                              <1> ;;	'swap_out' procesure returns with that swap (offset) sector
  1698                              <1> ;;	address (cf=0). 
  1699                              <1> ;;
  1700                              <1> ;;	..............................................................
  1701                              <1> ;;
  1702                              <1> ;;	'swap_in' procedure loads addressed (relevant) swap disk or
  1703                              <1> ;;	file sectors at specified memory page. Then page allocation
  1704                              <1> ;;	procedure updates relevant page table entry with 'present' 
  1705                              <1> ;;	attribute. If swap disk or file reading fails there is nothing
  1706                              <1> ;;	to do, except to terminate the process which is the owner of
  1707                              <1> ;;	the swapped page.
  1708                              <1> ;;
  1709                              <1> ;;	'swap_in' procedure sets the relevant/respective bit value
  1710                              <1> ;;	in the Swap Allocation Table (as free block). 'swap_in' also
  1711                              <1> ;;	updates [swpd_first] pointer if it is required.
  1712                              <1> ;;
  1713                              <1> ;;	..............................................................	 
  1714                              <1> ;;
  1715                              <1> ;;	Note: If [swap_enabled] value is ZERO, that means there is not
  1716                              <1> ;;	a swap disk or swap file in use... 'swap_in' and 'swap_out'
  1717                              <1> ;;	procedures ans 'swap page que' procedures will not be active...
  1718                              <1> ;;	'Insufficient memory' error will be returned by 'swap_out'
  1719                              <1> ;;	and 'general protection fault' will be returned by 'swap_in'
  1720                              <1> ;;	procedure, if it is called mistakenly (a wrong value in a PTE).		
  1721                              <1> ;;
  1722                              <1> 
  1723                              <1> swap_in:
  1724                              <1> 	; 31/08/2015
  1725                              <1> 	; 20/07/2015
  1726                              <1> 	; 28/04/2015
  1727                              <1> 	; 18/04/2015
  1728                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  1729                              <1> 	;
  1730                              <1> 	; INPUT -> 
  1731                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS OF THE MEMORY PAGE
  1732                              <1> 	;	EBP = VIRTUAL (LINEAR) ADDRESS (page fault address)
  1733                              <1> 	;	EAX = Offset Address for the swapped page on the
  1734                              <1> 	;	      swap disk or in the swap file.
  1735                              <1> 	;
  1736                              <1> 	; OUTPUT ->
  1737                              <1> 	;	EAX = 0 if loading at memory has been successful
  1738                              <1> 	;
  1739                              <1> 	;	CF = 1 -> swap disk reading error (disk/file not present
  1740                              <1> 	;		  or sector not present or drive not ready
  1741                              <1> 	;	     EAX = Error code
  1742                              <1> 	;	     [u.error] = EAX 
  1743                              <1> 	;		       = The last error code for the process
  1744                              <1> 	;		         (will be reset after returning to user)	  
  1745                              <1> 	;
  1746                              <1> 	; Modified Registers -> EAX
  1747                              <1> 	;
  1748                              <1> 
  1749 000059E4 833D[62050300]00    <1>         cmp     dword [swp_drv], 0
  1750 000059EB 7646                <1> 	jna	short swpin_dnp_err
  1751                              <1> 
  1752 000059ED 3B05[66050300]      <1> 	cmp	eax, [swpd_size]
  1753 000059F3 734A                <1> 	jnb	short swpin_snp_err
  1754                              <1> 
  1755 000059F5 56                  <1> 	push	esi
  1756 000059F6 53                  <1> 	push	ebx
  1757 000059F7 51                  <1> 	push	ecx
  1758 000059F8 8B35[62050300]      <1> 	mov	esi, [swp_drv]	
  1759 000059FE B908000000          <1> 	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
  1760                              <1> 		; Note: Even if corresponding physical disk's sector 
  1761                              <1> 		; size different than 512 bytes, logical disk sector
  1762                              <1> 		; size is 512 bytes and disk reading procedure
  1763                              <1> 		; will be performed for reading 4096 bytes
  1764                              <1> 		; (2*2048, 8*512). 
  1765                              <1> 	; ESI = Logical disk description table address
  1766                              <1> 	; EBX = Memory page (buffer) address (physical!)
  1767                              <1> 	; EAX = Sector adress (offset address, logical sector number)
  1768                              <1> 	; ECX = Sector count ; 8 sectors
  1769 00005A03 50                  <1> 	push	eax
  1770 00005A04 E8AF020000          <1> 	call	logical_disk_read
  1771 00005A09 58                  <1> 	pop	eax
  1772 00005A0A 730C                <1> 	jnc	short swpin_read_ok
  1773                              <1> 	;
  1774 00005A0C B828000000          <1> 	mov	eax, SWP_DISK_READ_ERR ; drive not ready or read error
  1775 00005A11 A3[C8030300]        <1> 	mov	[u.error], eax
  1776 00005A16 EB17                <1> 	jmp	short swpin_retn
  1777                              <1> 	;
  1778                              <1> swpin_read_ok:
  1779                              <1> 	; EAX = Offset address (logical sector number)
  1780 00005A18 E80D020000          <1> 	call	unlink_swap_block  ; Deallocate swap block	
  1781                              <1> 	;
  1782                              <1> 	; EBX = Memory page (buffer) address (physical!)
  1783                              <1> 	; 20/07/2015
  1784 00005A1D 89EB                <1> 	mov	ebx, ebp ; virtual address (page fault address)
  1785 00005A1F 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
  1786 00005A24 8A1D[B3030300]      <1> 	mov	bl, [u.uno] ; current process number
  1787                              <1> 	; EBX = Virtual (Linear) address & process number combination
  1788 00005A2A E8DB000000          <1> 	call	swap_queue_shift
  1789                              <1> 	; eax = 0 ; 10/06/2016 (if ebx input > 0, eax output = 0)
  1790                              <1> 	;sub	eax, eax  ; 0 ; Error Code = 0  (no error)
  1791                              <1> 	; zf = 1
  1792                              <1> swpin_retn:
  1793 00005A2F 59                  <1> 	pop	ecx
  1794 00005A30 5B                  <1> 	pop	ebx
  1795 00005A31 5E                  <1> 	pop	esi
  1796 00005A32 C3                  <1> 	retn
  1797                              <1> 
  1798                              <1> swpin_dnp_err:
  1799 00005A33 B829000000          <1> 	mov	eax, SWP_DISK_NOT_PRESENT_ERR
  1800                              <1> swpin_err_retn:
  1801 00005A38 A3[C8030300]        <1> 	mov	[u.error], eax
  1802 00005A3D F9                  <1> 	stc
  1803 00005A3E C3                  <1> 	retn
  1804                              <1> 
  1805                              <1> swpin_snp_err:
  1806 00005A3F B82A000000          <1> 	mov	eax, SWP_SECTOR_NOT_PRESENT_ERR
  1807 00005A44 EBF2                <1> 	jmp	short swpin_err_retn
  1808                              <1> 
  1809                              <1> swap_out:
  1810                              <1> 	; 10/06/2016
  1811                              <1> 	; 07/06/2016
  1812                              <1>         ; 23/05/2016
  1813                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
  1814                              <1> 	; 24/10/2014 - 31/08/2015 (Retro UNIX 386 v1)
  1815                              <1> 	;
  1816                              <1> 	; INPUT -> 
  1817                              <1> 	;	none
  1818                              <1> 	;
  1819                              <1> 	; OUTPUT ->
  1820                              <1> 	;	EAX = Physical page address (which is swapped out
  1821                              <1> 	;	      for allocating a new page)
  1822                              <1> 	;	CF = 1 -> swap disk writing error (disk/file not present
  1823                              <1> 	;		  or sector not present or drive not ready
  1824                              <1> 	;	     EAX = Error code
  1825                              <1> 	;	     [u.error] = EAX 
  1826                              <1> 	;		       = The last error code for the process
  1827                              <1> 	;		         (will be reset after returning to user)	  
  1828                              <1> 	;
  1829                              <1> 	; Modified Registers -> none (except EAX)
  1830                              <1> 	;
  1831 00005A46 66833D[60050300]01  <1> 	cmp 	word [swpq_count], 1
  1832 00005A4E 0F82AF000000        <1>         jc      swpout_im_err ; 'insufficient memory'
  1833                              <1> 
  1834                              <1>         ;cmp    dword [swp_drv], 1
  1835                              <1> 	;jc	short swpout_dnp_err ; 'swap disk/file not present'
  1836                              <1> 
  1837 00005A54 833D[6A050300]01    <1>         cmp     dword [swpd_free], 1
  1838 00005A5B 0F828F000000        <1>         jc      swpout_nfspc_err ; 'no free space on swap disk'
  1839                              <1> 
  1840 00005A61 53                  <1> 	push	ebx ; *
  1841                              <1> swpout_1:
  1842                              <1> 	; 10/06/2016
  1843 00005A62 31DB                <1> 	xor	ebx, ebx ; shift the queue and return a PTE value
  1844 00005A64 E8A1000000          <1> 	call	swap_queue_shift
  1845 00005A69 21C0                <1> 	and	eax, eax	; 0 = empty queue (improper entries)
  1846 00005A6B 0F848A000000        <1>         jz      swpout_npts_err        ; There is not any proper PTE
  1847                              <1> 				       ; pointer in the swap queue
  1848                              <1> 	; EAX = PTE value of the page
  1849                              <1> 	; EBX = PTE address of the page
  1850 00005A71 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  1851                              <1> 	;
  1852                              <1> 	; 07/06/2016
  1853                              <1> 	; 19/05/2016
  1854                              <1> 	; check this page is in timer events or not
  1855                              <1> 	
  1856                              <1> swpout_timer_page_0:
  1857 00005A75 52                  <1> 	push	edx ; **
  1858                              <1> 
  1859                              <1> 	; 07/06/2016
  1860 00005A76 803D[6B700100]00    <1> 	cmp	byte [timer_events], 0 
  1861 00005A7D 762F                <1> 	jna	short swpout_2
  1862                              <1> 	;
  1863 00005A7F 8A15[6B700100]      <1> 	mov	dl, [timer_events]
  1864                              <1> 
  1865 00005A85 51                  <1> 	push	ecx ; ***
  1866 00005A86 53                  <1> 	push	ebx ; ****
  1867 00005A87 BB[60040300]        <1> 	mov	ebx, timer_set ; beginning address of timer event
  1868                              <1> 			       ; structures 
  1869                              <1> swpout_timer_page_1:
  1870 00005A8C 8A0B                <1> 	mov	cl, [ebx]
  1871 00005A8E 08C9                <1> 	or	cl, cl ; 0 = free, >0 = process number
  1872 00005A90 7415                <1> 	jz	short swpout_timer_page_3
  1873 00005A92 8B4B0C              <1> 	mov	ecx, [ebx+12] ; response (signal return) address
  1874 00005A95 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; clear offset part (right 12 bits)
  1875                              <1> 				; of the response byte address, to
  1876                              <1> 				; get beginning of the page address)
  1877 00005A9A 39C8                <1> 	cmp	eax, ecx
  1878 00005A9C 7505                <1> 	jne	short swpout_timer_page_2 ; not same page
  1879                              <1> 	
  1880                              <1> 	; !same page!
  1881                              <1> 	;
  1882                              <1> 	; NOTE: // 19/05/2016 // - TRDOS 386 feature only ! -
  1883                              <1> 	; This page will be used by the kernel to put timer event
  1884                              <1> 	; response (signal return) byte at the requested address;
  1885                              <1> 	; in order to prevent a possible wrong write (while
  1886                              <1> 	; this page is swapped out) on physical memory,
  1887                              <1> 	; we must protect this page against to be swapped out!
  1888                              <1> 	;
  1889 00005A9E 5B                  <1> 	pop	ebx ; ****
  1890 00005A9F 59                  <1> 	pop	ecx ; ***
  1891 00005AA0 5A                  <1> 	pop	edx ; **
  1892 00005AA1 EBBF                <1> 	jmp	short swpout_1	; do not swap out this page !
  1893                              <1>  
  1894                              <1> swpout_timer_page_2:
  1895                              <1> 	; 07/06/2016
  1896 00005AA3 FECA                <1> 	dec	dl
  1897 00005AA5 7405                <1> 	jz	short swpout_timer_page_4
  1898                              <1> swpout_timer_page_3:
  1899                              <1> 	;cmp	ebx, timer_set + 240 ; last timer event (15*16) 
  1900                              <1> 	;jnb	short swpout_timer_page_4
  1901 00005AA7 83C310              <1> 	add	ebx, 16
  1902 00005AAA EBE0                <1> 	jmp	short swpout_timer_page_1	
  1903                              <1> 
  1904                              <1> swpout_timer_page_4:
  1905 00005AAC 5B                  <1> 	pop	ebx ; ****
  1906 00005AAD 59                  <1> 	pop	ecx ; ***
  1907                              <1> swpout_2:
  1908 00005AAE 89DA                <1> 	mov	edx, ebx	       ; Page table entry address	
  1909 00005AB0 89C3                <1> 	mov	ebx, eax	       ; Buffer (Page) Address				
  1910                              <1> 	;
  1911 00005AB2 E8A6010000          <1> 	call	link_swap_block
  1912 00005AB7 7304                <1> 	jnc	short swpout_3	       ; It may not be needed here	
  1913                              <1> 				       ; because [swpd_free] value
  1914                              <1> 				       ; was checked at the beginging. 	
  1915 00005AB9 5A                  <1> 	pop	edx ; **
  1916 00005ABA 5B                  <1> 	pop	ebx ; *
  1917 00005ABB EB33                <1> 	jmp	short swpout_nfspc_err 
  1918                              <1> swpout_3:
  1919 00005ABD A900000080          <1> 	test	eax, 80000000h ; test bit 31 (this may not be needed!)
  1920 00005AC2 752C                <1> 	jnz	short swpout_nfspc_err  ; 10/06/2016 (bit 31 = 1 !)
  1921                              <1> 	;	
  1922 00005AC4 56                  <1> 	push	esi ; **
  1923 00005AC5 51                  <1> 	push	ecx ; ***
  1924 00005AC6 50                  <1> 	push	eax ; sector address ; (31 bit !, bit 31 = 0)
  1925 00005AC7 8B35[62050300]      <1> 	mov	esi, [swp_drv]	
  1926 00005ACD B908000000          <1> 	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
  1927                              <1> 		; Note: Even if corresponding physical disk's sector 
  1928                              <1> 		; size different than 512 bytes, logical disk sector
  1929                              <1> 		; size is 512 bytes and disk writing procedure
  1930                              <1> 		; will be performed for writing 4096 bytes
  1931                              <1> 		; (2*2048, 8*512). 
  1932                              <1> 	; ESI = Logical disk description table address
  1933                              <1> 	; EBX = Buffer (Page) address
  1934                              <1> 	; EAX = Sector adress (offset address, logical sector number)
  1935                              <1> 	; ECX = Sector count ; 8 sectors
  1936                              <1> 	; edx = PTE address
  1937 00005AD2 E8E2010000          <1> 	call	logical_disk_write
  1938                              <1> 	; edx = PTE address
  1939 00005AD7 59                  <1> 	pop	ecx ; sector address	
  1940 00005AD8 730C                <1> 	jnc	short swpout_write_ok
  1941                              <1> 	;
  1942                              <1> 	;; call	unlink_swap_block ; this block must be left as 'in use'
  1943                              <1> swpout_dw_err:
  1944 00005ADA B82C000000          <1> 	mov	eax, SWP_DISK_WRITE_ERR ; drive not ready or write error
  1945 00005ADF A3[C8030300]        <1> 	mov	[u.error], eax
  1946 00005AE4 EB06                <1> 	jmp	short swpout_retn
  1947                              <1> 	;
  1948                              <1> swpout_write_ok:
  1949                              <1> 	; EBX = Buffer (page) address
  1950                              <1> 	; EDX = Page Table Entry address
  1951                              <1> 	; ECX = Swap disk sector (file block) address (31 bit)
  1952 00005AE6 D1E1                <1> 	shl 	ecx, 1  ; 31 bit sector address from bit 1 to bit 31 
  1953 00005AE8 890A                <1> 	mov 	[edx], ecx 
  1954                              <1> 		; bit 0 = 0 (swapped page)
  1955 00005AEA 89D8                <1> 	mov	eax, ebx
  1956                              <1> swpout_retn:
  1957 00005AEC 59                  <1> 	pop	ecx ; ***
  1958 00005AED 5E                  <1> 	pop	esi ; **
  1959 00005AEE 5B                  <1> 	pop	ebx ; *
  1960 00005AEF C3                  <1> 	retn
  1961                              <1> 
  1962                              <1> ;swpout_dnp_err:
  1963                              <1> ;	mov	eax, SWP_DISK_NOT_PRESENT_ERR ; disk not present
  1964                              <1> ;	jmp	short swpout_err_retn
  1965                              <1> swpout_nfspc_err:
  1966 00005AF0 B82B000000          <1> 	mov	eax, SWP_NO_FREE_SPACE_ERR ; no free space
  1967                              <1> swpout_err_retn:
  1968 00005AF5 A3[C8030300]        <1> 	mov	[u.error], eax
  1969                              <1> 	;stc
  1970 00005AFA C3                  <1> 	retn
  1971                              <1> swpout_npts_err:
  1972 00005AFB B82D000000          <1> 	mov	eax, SWP_NO_PAGE_TO_SWAP_ERR
  1973 00005B00 5B                  <1> 	pop	ebx
  1974 00005B01 EBF2                <1> 	jmp	short swpout_err_retn
  1975                              <1> swpout_im_err:
  1976 00005B03 B804000000          <1> 	mov	eax, ERR_MINOR_IM ; insufficient (out of) memory
  1977 00005B08 EBEB                <1> 	jmp	short swpout_err_retn
  1978                              <1> 
  1979                              <1> swap_queue_shift:
  1980                              <1> 	; 26/03/2017
  1981                              <1> 	; 10/06/2016
  1982                              <1> 	; 09/06/2016 - TRDOS 386 (TRDOS v2.0)
  1983                              <1> 	; 23/10/2014 - 20/07/2015 (Retro UNIX 386 v1)
  1984                              <1> 	;
  1985                              <1> 	; INPUT ->
  1986                              <1> 	;	EBX = Virtual (linear) address (bit 12 to 31) 
  1987                              <1> 	;	      and process number combination (bit 0 to 11)
  1988                              <1> 	;	EBX = 0 -> shift/drop from the head (offset 0)
  1989                              <1> 	;	
  1990                              <1> 	; OUTPUT ->
  1991                              <1> 	;	If EBX input > 0 
  1992                              <1> 	;	   the queue will be shifted 4 bytes (dword),
  1993                              <1> 	; 	   from the tail to the head, up to entry offset
  1994                              <1> 	; 	   which points to EBX input value or nothing
  1995                              <1> 	;	   to do if EBX value is not found on the queue.
  1996                              <1> 	;	   (The entry -with EBX value- will be removed
  1997                              <1> 	;	   from the queue if it is found.)
  1998                              <1> 	;
  1999                              <1> 	;	   EAX = 0		
  2000                              <1> 	;
  2001                              <1> 	;	If EBX input = 0
  2002                              <1> 	;	   the queue will be shifted 4 bytes (dword),
  2003                              <1> 	; 	   from the tail to the head, if the PTE address
  2004                              <1> 	;	   which is pointed in head of the queue is marked
  2005                              <1> 	;	   as "accessed" or it is marked as "non present".
  2006                              <1> 	;	   (If "accessed" flag of the PTE -which is pointed
  2007                              <1> 	;	   in the head- is set -to 1-, it will be reset
  2008                              <1> 	;	   -to 0- and then, the queue will be rotated 
  2009                              <1> 	;	   -without dropping pointer of the PTE from 
  2010                              <1> 	;	   the queue- for 4 bytes on head to tail direction.
  2011                              <1> 	;	   Pointer in the head will be moved into the tail,
  2012                              <1> 	;	   other PTEs will be shifted on head direction.)
  2013                              <1> 	;
  2014                              <1> 	;	   Swap queue will be shifted up to the first
  2015                              <1> 	;	   'present' or 'non accessed' page will be found
  2016                              <1> 	;	   (as pointed) on the queue head (then it will be
  2017                              <1>         ;          removed/dropped from the queue).
  2018                              <1> 	;
  2019                              <1> 	;	   EAX (> 0) = PTE value of the page which is
  2020                              <1> 	;		 (it's pointer -virtual address-) dropped
  2021                              <1> 	;		 (removed) from swap queue.
  2022                              <1> 	;	   EBX = PTE address of the page (if EAX > 0)
  2023                              <1> 	;	         which is (it's pointer -virtual address-)
  2024                              <1> 	;		 dropped (removed) from swap queue.
  2025                              <1> 	;
  2026                              <1> 	;	   EAX = 0 -> empty swap queue ! 
  2027                              <1> 	;
  2028                              <1> 	; Modified Registers -> EAX, EBX
  2029                              <1> 	;
  2030 00005B0A 0FB705[60050300]    <1> 	movzx   eax, word [swpq_count]  ; Max. 1024
  2031 00005B11 6621C0              <1> 	and	ax, ax
  2032 00005B14 7431                <1> 	jz	short swpqs_retn
  2033 00005B16 57                  <1> 	push	edi
  2034 00005B17 56                  <1> 	push	esi
  2035 00005B18 51                  <1> 	push	ecx
  2036 00005B19 BE00E00800          <1> 	mov	esi, swap_queue
  2037 00005B1E 89C1                <1> 	mov	ecx, eax
  2038 00005B20 09DB                <1> 	or	ebx, ebx
  2039 00005B22 7424                <1> 	jz	short swpqs_7
  2040                              <1> swpqs_1:
  2041 00005B24 AD                  <1> 	lodsd
  2042 00005B25 39D8                <1> 	cmp	eax, ebx
  2043 00005B27 7406                <1> 	je	short swpqs_2
  2044 00005B29 E2F9                <1> 	loop	swpqs_1
  2045                              <1> 	; 10/06/2016
  2046 00005B2B 29C0                <1> 	sub	eax, eax 
  2047 00005B2D EB15                <1> 	jmp	short swpqs_6
  2048                              <1> swpqs_2:
  2049 00005B2F 89F7                <1> 	mov	edi, esi
  2050 00005B31 83EF04              <1> 	sub 	edi, 4
  2051                              <1> swpqs_3:
  2052 00005B34 66FF0D[60050300]    <1> 	dec	word [swpq_count]
  2053 00005B3B 7403                <1> 	jz	short swpqs_5
  2054                              <1> swpqs_4:
  2055 00005B3D 49                  <1> 	dec 	ecx
  2056 00005B3E F3A5                <1> 	rep	movsd	; shift up (to the head)
  2057                              <1> swpqs_5:
  2058 00005B40 31C0                <1> 	xor	eax, eax
  2059 00005B42 8907                <1> 	mov	[edi], eax
  2060                              <1> swpqs_6:
  2061 00005B44 59                  <1> 	pop	ecx
  2062 00005B45 5E                  <1> 	pop	esi
  2063 00005B46 5F                  <1> 	pop	edi
  2064                              <1> swpqs_retn:
  2065 00005B47 C3                  <1> 	retn		
  2066                              <1> swpqs_7:
  2067 00005B48 89F7                <1> 	mov	edi, esi ; head
  2068 00005B4A AD                  <1> 	lodsd
  2069                              <1> 	; 20/07/2015
  2070 00005B4B 89C3                <1> 	mov	ebx, eax
  2071 00005B4D 81E300F0FFFF        <1> 	and	ebx, ~PAGE_OFF ; ~0FFFh 
  2072                              <1> 		      ; ebx = virtual address (at page boundary)	
  2073 00005B53 25FF0F0000          <1> 	and	eax, PAGE_OFF ; 0FFFh
  2074                              <1> 		      ; ax = process number (1 to 4095)
  2075 00005B58 3A05[B3030300]      <1> 	cmp	al, [u.uno]
  2076                              <1> 		; Max. 16 (nproc) processes for Retro UNIX 386 v1
  2077 00005B5E 7507                <1> 	jne	short swpqs_8
  2078 00005B60 A1[B8030300]        <1> 	mov	eax, [u.pgdir]
  2079 00005B65 EB28                <1> 	jmp	short swpqs_9
  2080                              <1> swpqs_8:
  2081                              <1> 	; 09/06/2016
  2082 00005B67 80B8[AF000300]00    <1> 	cmp	byte [eax+p.stat-1], 0
  2083 00005B6E 76C4                <1> 	jna	short swpqs_3     ; free (or terminated) process
  2084 00005B70 80B8[AF000300]02    <1> 	cmp	byte [eax+p.stat-1], 2 ; waiting
  2085 00005B77 77BB                <1> 	ja	short swpqs_3 	  ; zombie (3) or undefined ?	
  2086                              <1> 
  2087                              <1> 	;shl	ax, 2
  2088 00005B79 C0E002              <1> 	shl	al, 2
  2089 00005B7C 8B80[BC000300]      <1> 	mov 	eax, [eax+p.upage-4]
  2090 00005B82 09C0                <1> 	or	eax, eax
  2091 00005B84 74AE                <1> 	jz	short swpqs_3 ; invalid upage
  2092 00005B86 83C05C              <1> 	add	eax, u.pgdir - user
  2093                              <1> 			 ; u.pgdir value for the process
  2094                              <1> 			 ; is in [eax]
  2095 00005B89 8B00                <1> 	mov	eax, [eax]
  2096 00005B8B 21C0                <1> 	and	eax, eax
  2097 00005B8D 74A5                <1> 	jz	short swpqs_3 ; invalid page directory
  2098                              <1> swpqs_9:
  2099 00005B8F 52                  <1> 	push	edx
  2100                              <1> 	; eax = page directory
  2101                              <1> 	; ebx = virtual address
  2102 00005B90 E82BFBFFFF          <1> 	call	get_pte
  2103 00005B95 89D3                <1> 	mov	ebx, edx	; PTE address
  2104 00005B97 5A                  <1> 	pop	edx
  2105                              <1> 	; 10/06/2016
  2106 00005B98 723A                <1> 	jc	short swpqs_13 ; empty PDE
  2107                              <1> 	; EAX = PTE value
  2108 00005B9A A801                <1> 	test	al, PTE_A_PRESENT ; bit 0 = 1
  2109 00005B9C 7436                <1> 	jz	short swpqs_13  ; Drop non-present page
  2110                              <1> 			        ; from the queue (head)
  2111 00005B9E A802                <1> 	test	al, PTE_A_WRITE	; bit 1 = 0 (read only)
  2112 00005BA0 7432                <1> 	jz	short swpqs_13  ; Drop read only page
  2113                              <1> 			        ; from the queue (head) 	
  2114                              <1> 	;test	al, PTE_A_ACCESS ; bit 5 = 1 (Accessed)
  2115                              <1> 	;jnz	short swpqs_11  ; present
  2116                              <1> 			        ; accessed page
  2117 00005BA2 0FBAF005            <1>         btr     eax, PTE_A_ACCESS_BIT ; reset 'accessed' bit
  2118 00005BA6 7210                <1> 	jc	short swpqs_11  ; accessed page
  2119                              <1> 
  2120 00005BA8 49                  <1> 	dec	ecx
  2121 00005BA9 66890D[60050300]    <1> 	mov	[swpq_count], cx
  2122 00005BB0 7402                <1>         jz      short swpqs_10
  2123                              <1> 		; esi = head + 4
  2124                              <1> 		; edi = head
  2125 00005BB2 F3A5                <1> 	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
  2126                              <1> swpqs_10:
  2127 00005BB4 890F                <1> 	mov	[edi], ecx ; 0
  2128 00005BB6 EB8C                <1> 	jmp	short swpqs_6 ; 26/03/2017
  2129                              <1> 
  2130                              <1> swpqs_11:
  2131 00005BB8 8903                <1> 	mov	[ebx], eax     ; save changed attribute
  2132                              <1> 	; Rotation (head -> tail)
  2133 00005BBA 49                  <1> 	dec	ecx     ; entry count -> last entry number		
  2134 00005BBB 74F7                <1> 	jz	short swpqs_10
  2135                              <1> 		; esi = head + 4
  2136                              <1> 		; edi = head
  2137 00005BBD 8B07                <1> 	mov	eax, [edi] ; 20/07/2015
  2138 00005BBF F3A5                <1> 	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
  2139 00005BC1 8907                <1> 	mov	[edi], eax ; head -> tail ; [k] = [1]
  2140                              <1> 
  2141 00005BC3 668B0D[60050300]    <1> 	mov	cx, [swpq_count]
  2142                              <1> 
  2143                              <1> swpqs_12:
  2144 00005BCA BE00E00800          <1> 	mov	esi, swap_queue ; head
  2145 00005BCF E974FFFFFF          <1>         jmp     swpqs_7
  2146                              <1> 
  2147                              <1> swpqs_13:
  2148 00005BD4 49                  <1> 	dec	ecx
  2149 00005BD5 66890D[60050300]    <1> 	mov	[swpq_count], cx
  2150 00005BDC 0F845EFFFFFF        <1>         jz      swpqs_5
  2151 00005BE2 EBE6                <1> 	jmp	short swpqs_12
  2152                              <1> 
  2153                              <1> add_to_swap_queue:
  2154                              <1> ; temporary - 16/09/2015
  2155 00005BE4 C3                  <1> retn
  2156                              <1> 	; 20/02/2017
  2157                              <1> 	; 20/07/2015
  2158                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  2159                              <1> 	;
  2160                              <1> 	; Adds new page to swap queue
  2161                              <1> 	; (page directories and page tables must not be added
  2162                              <1> 	; to swap queue)	
  2163                              <1> 	;
  2164                              <1> 	; INPUT ->
  2165                              <1> 	;	EBX = Linear (Virtual) addr for current process
  2166                              <1> 	;	[u.uno]
  2167                              <1> 	;	20/02/2017
  2168                              <1> 	;	(Linear address = CORE + user's virtual address)
  2169                              <1> 	;
  2170                              <1> 	; OUTPUT ->
  2171                              <1> 	;	EAX = [swpq_count]
  2172                              <1> 	;	      (after the PTE has been added)
  2173                              <1> 	;	EAX = 0 -> Swap queue is full, (1024 entries)
  2174                              <1> 	;	      the PTE could not be added.
  2175                              <1> 	;
  2176                              <1> 	; Modified Registers -> EAX
  2177                              <1> 	;
  2178 00005BE5 53                  <1> 	push	ebx
  2179 00005BE6 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
  2180 00005BEB 8A1D[B3030300]      <1> 	mov	bl, [u.uno] ; current process number
  2181 00005BF1 E814FFFFFF          <1> 	call	swap_queue_shift ; drop from the queue if
  2182                              <1> 				 ; it is already on the queue
  2183                              <1> 		; then add it to the tail of the queue
  2184 00005BF6 0FB705[60050300]    <1> 	movzx	eax, word [swpq_count]
  2185 00005BFD 663D0004            <1> 	cmp	ax, 1024
  2186 00005C01 7205                <1> 	jb	short atsq_1
  2187 00005C03 6629C0              <1> 	sub	ax, ax
  2188 00005C06 5B                  <1> 	pop	ebx
  2189 00005C07 C3                  <1> 	retn
  2190                              <1> atsq_1:
  2191 00005C08 56                  <1> 	push	esi
  2192 00005C09 BE00E00800          <1> 	mov	esi, swap_queue
  2193 00005C0E 6621C0              <1> 	and	ax, ax
  2194 00005C11 740A                <1> 	jz	short atsq_2
  2195 00005C13 66C1E002            <1> 	shl	ax, 2	; convert to offset
  2196 00005C17 01C6                <1> 	add	esi, eax
  2197 00005C19 66C1E802            <1> 	shr	ax, 2
  2198                              <1> atsq_2:
  2199 00005C1D 6640                <1> 	inc	ax
  2200 00005C1F 891E                <1> 	mov	[esi], ebx ; Virtual address + [u.uno] combination
  2201 00005C21 66A3[60050300]      <1> 	mov	[swpq_count], ax
  2202 00005C27 5E                  <1> 	pop	esi
  2203 00005C28 5B                  <1> 	pop	ebx
  2204 00005C29 C3                  <1> 	retn
  2205                              <1> 
  2206                              <1> unlink_swap_block:
  2207                              <1> 	; 15/09/2015
  2208                              <1> 	; 30/04/2015
  2209                              <1> 	; 18/04/2015
  2210                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  2211                              <1> 	;
  2212                              <1> 	; INPUT -> 
  2213                              <1> 	;	EAX = swap disk/file offset address
  2214                              <1> 	;	      (bit 1 to bit 31)
  2215                              <1> 	; OUTPUT ->
  2216                              <1> 	;	[swpd_free] is increased
  2217                              <1> 	;	(corresponding SWAP DISK ALLOC. TABLE bit is SET)
  2218                              <1> 	;
  2219                              <1> 	; Modified Registers -> EAX
  2220                              <1> 	;
  2221 00005C2A 53                  <1> 	push	ebx
  2222 00005C2B 52                  <1> 	push	edx
  2223                              <1> 	;
  2224 00005C2C C1E804              <1> 	shr	eax, SECTOR_SHIFT+1  ;3+1 ; shift sector address to 
  2225                              <1> 				     ; 3 bits right
  2226                              <1> 				     ; to get swap block/page number
  2227 00005C2F 89C2                <1> 	mov	edx, eax
  2228                              <1> 	; 15/09/2015
  2229 00005C31 C1EA03              <1> 	shr	edx, 3		     ; to get offset to S.A.T.
  2230                              <1> 				     ; (1 allocation bit = 1 page)
  2231                              <1> 				     ; (1 allocation bytes = 8 pages)
  2232 00005C34 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2233                              <1> 				     ; (to get 32 bit position)			
  2234                              <1> 	;
  2235 00005C37 BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table address
  2236 00005C3C 01D3                <1> 	add	ebx, edx
  2237 00005C3E 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
  2238                              <1> 				     ; (allocation bit position)	 
  2239 00005C41 3B05[6E050300]      <1> 	cmp 	eax, [swpd_next]     ; is the new free block addr. lower
  2240                              <1> 				     ; than the address in 'swpd_next' ?
  2241                              <1> 				     ; (next/first free block value)		
  2242 00005C47 7305                <1> 	jnb	short uswpbl_1	     ; no	
  2243 00005C49 A3[6E050300]        <1> 	mov	[swpd_next], eax     ; yes	
  2244                              <1> uswpbl_1:
  2245 00005C4E 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate block
  2246                              <1> 				     ; set relevant bit to 1.
  2247                              <1> 				     ; set CF to the previous bit value	
  2248 00005C51 F5                  <1> 	cmc			     ; complement carry flag	
  2249 00005C52 7206                <1> 	jc	short uswpbl_2	     ; do not increase swfd_free count
  2250                              <1> 				     ; if the block is already deallocated
  2251                              <1> 				     ; before.	
  2252 00005C54 FF05[6A050300]      <1>         inc     dword [swpd_free]
  2253                              <1> uswpbl_2:
  2254 00005C5A 5A                  <1> 	pop	edx
  2255 00005C5B 5B                  <1> 	pop	ebx
  2256 00005C5C C3                  <1> 	retn
  2257                              <1> 
  2258                              <1> link_swap_block:
  2259                              <1> 	; 01/07/2015
  2260                              <1> 	; 18/04/2015
  2261                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  2262                              <1> 	;
  2263                              <1> 	; INPUT -> none
  2264                              <1> 	;
  2265                              <1> 	; OUTPUT ->
  2266                              <1> 	;	EAX = OFFSET ADDRESS OF THE ALLOCATED BLOCK (4096 bytes)
  2267                              <1> 	;	      in sectors (corresponding 
  2268                              <1> 	;	      SWAP DISK ALLOCATION TABLE bit is RESET)
  2269                              <1> 	;
  2270                              <1> 	;	CF = 1 and EAX = 0 
  2271                              <1> 	; 		   if there is not a free block to be allocated	
  2272                              <1> 	;
  2273                              <1> 	; Modified Registers -> none (except EAX)
  2274                              <1> 	;
  2275                              <1> 
  2276                              <1> 	;mov	eax, [swpd_free]
  2277                              <1> 	;and	eax, eax
  2278                              <1> 	;jz	short out_of_swpspc
  2279                              <1> 	;
  2280 00005C5D 53                  <1> 	push	ebx
  2281 00005C5E 51                  <1> 	push	ecx
  2282                              <1> 	;
  2283 00005C5F BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table offset
  2284 00005C64 89D9                <1> 	mov	ecx, ebx
  2285 00005C66 031D[6E050300]      <1> 	add	ebx, [swpd_next] ; Free block searching starts from here
  2286                              <1> 				 ; next_free_swap_block >> 5
  2287 00005C6C 030D[72050300]      <1> 	add	ecx, [swpd_last] ; Free block searching ends here
  2288                              <1> 				 ; (total_swap_blocks - 1) >> 5
  2289                              <1> lswbl_scan:
  2290 00005C72 39CB                <1> 	cmp	ebx, ecx
  2291 00005C74 770A                <1> 	ja	short lswbl_notfound
  2292                              <1> 	;
  2293 00005C76 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
  2294                              <1> 			   ; Clears ZF if a bit is found set (1) and 
  2295                              <1> 			   ; loads the destination with an index to
  2296                              <1> 			   ; first set bit. (0 -> 31) 
  2297                              <1> 			   ; Sets ZF to 1 if no bits are found set.
  2298                              <1> 	; 01/07/2015
  2299 00005C79 751C                <1> 	jnz	short lswbl_found ; ZF = 0 -> a free block has been found
  2300                              <1> 			 ;
  2301                              <1> 			 ; NOTE:  a Swap Disk Allocation Table bit 
  2302                              <1> 			 ;	  with value of 1 means 
  2303                              <1> 			 ;	  the corresponding page is free 
  2304                              <1> 			 ;	  (Retro UNIX 386 v1 feaure only!)
  2305 00005C7B 83C304              <1> 	add	ebx, 4
  2306                              <1> 			 ; We return back for searching next page block
  2307                              <1> 			 ; NOTE: [swpd_free] is not ZERO; so, 
  2308                              <1> 			 ;	 we always will find at least 1 free block here.
  2309 00005C7E EBF2                <1> 	jmp    	short lswbl_scan
  2310                              <1> 	;
  2311                              <1> lswbl_notfound:	
  2312 00005C80 81E900000D00        <1> 	sub	ecx, swap_alloc_table
  2313 00005C86 890D[6E050300]      <1> 	mov	[swpd_next], ecx ; next/first free page = last page 
  2314                              <1> 				 ; (unlink_swap_block procedure will change it)
  2315 00005C8C 31C0                <1> 	xor	eax, eax
  2316 00005C8E A3[6A050300]        <1> 	mov	[swpd_free], eax
  2317 00005C93 F9                  <1> 	stc
  2318                              <1> lswbl_ok:
  2319 00005C94 59                  <1> 	pop	ecx
  2320 00005C95 5B                  <1> 	pop	ebx
  2321 00005C96 C3                  <1> 	retn
  2322                              <1> 	;
  2323                              <1> ;out_of_swpspc:
  2324                              <1> ;	stc
  2325                              <1> ;	retn
  2326                              <1> 
  2327                              <1> lswbl_found:
  2328 00005C97 89D9                <1> 	mov	ecx, ebx
  2329 00005C99 81E900000D00        <1> 	sub	ecx, swap_alloc_table
  2330 00005C9F 890D[6E050300]      <1> 	mov	[swpd_next], ecx ; Set first free block searching start
  2331                              <1> 				 ; address/offset (to the next)
  2332 00005CA5 FF0D[6A050300]      <1>         dec     dword [swpd_free] ; 1 block has been allocated (X = X-1) 
  2333                              <1> 	;
  2334 00005CAB 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
  2335                              <1> 				 ; is copied into the Carry Flag and then cleared
  2336                              <1> 				 ; in the destination.
  2337                              <1> 				 ;
  2338                              <1> 				 ; Reset the bit which is corresponding to the 
  2339                              <1> 				 ; (just) allocated block.
  2340 00005CAE C1E105              <1> 	shl	ecx, 5		 ; (block offset * 32) + block index
  2341 00005CB1 01C8                <1> 	add	eax, ecx	 ; = block number
  2342 00005CB3 C1E003              <1> 	shl	eax, SECTOR_SHIFT ; 3, sector (offset) address of the block
  2343                              <1> 				 ; 1 block =  8 sectors
  2344                              <1> 	;
  2345                              <1> 	; EAX = offset address of swap disk/file sector (beginning of the block)
  2346                              <1> 	;
  2347                              <1> 	; NOTE: The relevant page table entry will be updated
  2348                              <1> 	;       according to this EAX value...
  2349                              <1> 	;
  2350 00005CB6 EBDC                <1> 	jmp	short lswbl_ok
  2351                              <1> 
  2352                              <1> logical_disk_read:
  2353                              <1> 	; 20/07/2015
  2354                              <1> 	; 09/03/2015 (temporary code here)
  2355                              <1> 	;
  2356                              <1> 	; INPUT ->
  2357                              <1> 	; 	ESI = Logical disk description table address
  2358                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
  2359                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
  2360                              <1> 	; 	ECX = Sector count
  2361                              <1> 	;
  2362                              <1> 	;
  2363 00005CB8 C3                  <1> 	retn
  2364                              <1> 
  2365                              <1> logical_disk_write:
  2366                              <1> 	; 20/07/2015
  2367                              <1> 	; 09/03/2015 (temporary code here)
  2368                              <1> 	;
  2369                              <1> 	; INPUT ->
  2370                              <1> 	; 	ESI = Logical disk description table address
  2371                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
  2372                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
  2373                              <1> 	; 	ECX = Sector count
  2374                              <1> 	;
  2375 00005CB9 C3                  <1> 	retn
  2376                              <1> 
  2377                              <1> get_physical_addr:
  2378                              <1> 	; 26/03/2017
  2379                              <1> 	; 20/02/2017
  2380                              <1> 	; 27/05/2016 - TRDOS 386 (TRDOS v2.0)
  2381                              <1> 	; 18/10/2015
  2382                              <1> 	; 29/07/2015
  2383                              <1> 	; 20/07/2015
  2384                              <1> 	; 04/06/2015
  2385                              <1> 	; 20/05/2015
  2386                              <1> 	; 28/04/2015
  2387                              <1> 	; 18/04/2015
  2388                              <1> 	; Get physical address
  2389                              <1> 	;     (allocates a new page for user if it is not present)
  2390                              <1> 	;	
  2391                              <1> 	; (This subroutine is needed for mapping user's virtual 
  2392                              <1> 	; (buffer) address to physical address (of the buffer).)
  2393                              <1> 	; ('sys write', 'sys read' system calls...)
  2394                              <1> 	;
  2395                              <1> 	; INPUT ->
  2396                              <1> 	;	EBX = virtual address
  2397                              <1> 	;	u.pgdir = page directory (physical) address
  2398                              <1> 	;
  2399                              <1> 	; OUTPUT ->
  2400                              <1> 	;	EAX = physical address 
  2401                              <1> 	;	EBX = linear address	
  2402                              <1> 	;	EDX = physical address of the page frame
  2403                              <1> 	;	      (with attribute bits)
  2404                              <1> 	;	ECX = byte count within the page frame
  2405                              <1> 	;
  2406                              <1> 	; Modified Registers -> EAX, EBX, ECX, EDX
  2407                              <1> 	;
  2408 00005CBA 81C300004000        <1> 	add	ebx, CORE ; 18/10/2015
  2409                              <1> get_physical_addr_x: ; 27/05/2016
  2410 00005CC0 A1[B8030300]        <1> 	mov	eax, [u.pgdir]
  2411 00005CC5 E8F6F9FFFF          <1> 	call	get_pte
  2412                              <1> 		; EDX = Page table entry address (if CF=0)
  2413                              <1> 	        ;       Page directory entry address (if CF=1)
  2414                              <1> 		;       (Bit 0 value is 0 if PT is not present)
  2415                              <1> 		; EAX = Page table entry value (page address)
  2416                              <1> 		;	CF = 1 -> PDE not present or invalid ? 
  2417 00005CCA 731C                <1> 	jnc	short gpa_1
  2418                              <1> 	;
  2419 00005CCC E8D4F8FFFF          <1> 	call	allocate_page
  2420 00005CD1 7248                <1> 	jc	short gpa_im_err  ; 'insufficient memory' error
  2421                              <1> gpa_0:
  2422 00005CD3 E847F9FFFF          <1> 	call 	clear_page
  2423                              <1> 	; EAX = Physical (base) address of the allocated (new) page
  2424 00005CD8 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER ; 4+2+1 = 7
  2425                              <1> 			   ; lower 3 bits are used as U/S, R/W, P flags
  2426                              <1> 			   ; (user, writable, present page)	
  2427 00005CDA 8902                <1> 	mov	[edx], eax ; Let's put the new page directory entry here !
  2428 00005CDC A1[B8030300]        <1> 	mov	eax, [u.pgdir]	
  2429 00005CE1 E8DAF9FFFF          <1> 	call	get_pte
  2430 00005CE6 7233                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
  2431                              <1> gpa_1:
  2432                              <1> 	; EAX = PTE value, EDX = PTE address
  2433 00005CE8 A801                <1> 	test 	al, PTE_A_PRESENT
  2434 00005CEA 751F                <1> 	jnz	short gpa_3 ; 26/03/2017
  2435 00005CEC 09C0                <1> 	or	eax, eax
  2436 00005CEE 7456                <1> 	jz	short gpa_7  ; Allocate a new page
  2437                              <1> 	; 20/07/2015
  2438 00005CF0 55                  <1> 	push	ebp
  2439 00005CF1 89DD                <1> 	mov	ebp, ebx ; virtual (linear) address
  2440                              <1> 	; reload swapped page
  2441 00005CF3 E878000000          <1> 	call	reload_page ; 28/04/2015
  2442 00005CF8 5D                  <1> 	pop	ebp
  2443 00005CF9 724A                <1> 	jc	short gpa_retn
  2444                              <1> gpa_2:
  2445                              <1> 	; 26/03/2017
  2446                              <1> 	; 20/02/2017
  2447                              <1> 	; If a page will contain a Signal Response Byte
  2448                              <1> 	; it must not be swapped out, because
  2449                              <1> 	; timer service or irq callback service
  2450                              <1> 	; will write a signal return/response byte 
  2451                              <1> 	; directly by using physical address of Signal
  2452                              <1> 	; Response Byte.(Even if process is not running,
  2453                              <1> 	; or it is running with swapped out pages.)
  2454                              <1> 	;
  2455                              <1> 	; 'no_page_swap' will be set by 'systimer' or
  2456                              <1> 	; 'syscalbac' sistem functions/calls. (*)
  2457                              <1> 	;
  2458 00005CFB 803D[AA750100]00    <1> 	cmp	byte [no_page_swap], 0
  2459 00005D02 761D                <1> 	jna	short gpa_4 ; this page can be swapped out
  2460                              <1> 	; this page must not be swapped out
  2461                              <1> 	; but 'no_page_swap' must be reset here
  2462                              <1> 	; imediately for other callers (*)
  2463                              <1> 	; (otherwise, swap queue would not be long enough) 
  2464 00005D04 E84B000000          <1> 	call	gpa_8 ; 26/03/2017
  2465 00005D09 EB1D                <1> 	jmp	short gpa_5
  2466                              <1> gpa_3: 
  2467                              <1> 	; 26/03/2017
  2468 00005D0B 803D[AA750100]00    <1> 	cmp	byte [no_page_swap], 0
  2469 00005D12 7618                <1> 	jna	short gpa_6 ; this page can be swapped out
  2470 00005D14 E83B000000          <1> 	call	gpa_8
  2471 00005D19 EB11                <1> 	jmp	short gpa_6
  2472                              <1> 
  2473                              <1> gpa_im_err:	
  2474 00005D1B B804000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
  2475                              <1> 				  ; Major error = 0 (No protection fault)	
  2476 00005D20 C3                  <1> 	retn
  2477                              <1> gpa_4:
  2478                              <1> 	; 20/07/2015
  2479                              <1> 	; 20/05/2015
  2480                              <1> 	; add this page to swap queue
  2481 00005D21 50                  <1> 	push	eax 
  2482                              <1> 	; EBX = Linear (CORE+virtual) address ; 20/02/2017 
  2483 00005D22 E8BDFEFFFF          <1> 	call 	add_to_swap_queue
  2484 00005D27 58                  <1> 	pop	eax
  2485                              <1> gpa_5:
  2486                              <1> 		; PTE address in EDX
  2487                              <1> 		; virtual address in EBX
  2488                              <1> 	; EAX = memory page address
  2489 00005D28 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_USER + PTE_A_WRITE
  2490                              <1> 				  ; present flag, bit 0 = 1
  2491                              <1> 				  ; user flag, bit 2 = 1	
  2492                              <1> 				  ; writable flag, bit 1 = 1
  2493 00005D2A 8902                <1> 	mov	[edx], eax  ; Update PTE value
  2494                              <1> gpa_6:
  2495                              <1> 	; 18/10/2015
  2496 00005D2C 89D9                <1> 	mov	ecx, ebx
  2497 00005D2E 81E1FF0F0000        <1> 	and	ecx, PAGE_OFF
  2498 00005D34 89C2                <1> 	mov 	edx, eax
  2499 00005D36 662500F0            <1> 	and	ax, PTE_A_CLEAR
  2500 00005D3A 01C8                <1> 	add	eax, ecx
  2501 00005D3C F7D9                <1> 	neg	ecx ; 1 -> -1 (0FFFFFFFFh), 4095 (0FFFh) -> -4095
  2502 00005D3E 81C100100000        <1> 	add	ecx, PAGE_SIZE
  2503 00005D44 F8                  <1> 	clc
  2504                              <1> gpa_retn:
  2505 00005D45 C3                  <1> 	retn
  2506                              <1> gpa_7:	
  2507 00005D46 E85AF8FFFF          <1> 	call	allocate_page
  2508 00005D4B 72CE                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
  2509 00005D4D E8CDF8FFFF          <1> 	call	clear_page
  2510 00005D52 EBA7                <1> 	jmp	short gpa_2
  2511                              <1> 
  2512                              <1> gpa_8: ; 26/03/2017
  2513 00005D54 C605[AA750100]00    <1> 	mov	byte [no_page_swap], 0
  2514 00005D5B 53                  <1> 	push	ebx
  2515 00005D5C 50                  <1> 	push	eax ; 26/03/2017
  2516 00005D5D 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
  2517 00005D62 8A1D[B3030300]      <1> 	mov	bl, [u.uno] ; current process number
  2518 00005D68 E89DFDFFFF          <1> 	call	swap_queue_shift ; drop from the queue if
  2519                              <1> 				 ; it is already on the queue
  2520 00005D6D 58                  <1> 	pop	eax ; 26/03/2017
  2521 00005D6E 5B                  <1> 	pop	ebx
  2522 00005D6F C3                  <1> 	retn
  2523                              <1> 
  2524                              <1> reload_page:
  2525                              <1> 	; 20/07/2015
  2526                              <1> 	; 28/04/2015 (Retro UNIX 386 v1 - beginning)
  2527                              <1> 	;
  2528                              <1> 	; Reload (Restore) swapped page at memory
  2529                              <1> 	;
  2530                              <1> 	; INPUT -> 
  2531                              <1> 	;	EBP = Virtual (linear) memory address
  2532                              <1> 	;	EAX = PTE value (swap disk sector address)
  2533                              <1> 	;	(Swap disk sector address = bit 1 to bit 31 of EAX)	
  2534                              <1> 	; OUTPUT ->
  2535                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF RELOADED PAGE
  2536                              <1> 	;
  2537                              <1> 	;	CF = 1 and EAX = error code
  2538                              <1> 	;
  2539                              <1> 	; Modified Registers -> none (except EAX)
  2540                              <1> 	;
  2541 00005D70 D1E8                <1> 	shr	eax, 1   ; Convert PTE value to swap disk address 
  2542 00005D72 53                  <1> 	push	ebx      ;
  2543 00005D73 89C3                <1> 	mov	ebx, eax ; Swap disk (offset) address	
  2544 00005D75 E82BF8FFFF          <1> 	call	allocate_page
  2545 00005D7A 720C                <1> 	jc	short rlp_im_err
  2546 00005D7C 93                  <1> 	xchg 	eax, ebx	
  2547                              <1> 	; EBX = Physical memory (page) address
  2548                              <1> 	; EAX = Swap disk (offset) address
  2549                              <1> 	; EBP = Virtual (linear) memory address
  2550 00005D7D E862FCFFFF          <1> 	call	swap_in
  2551 00005D82 720B                <1> 	jc	short rlp_swp_err  ; (swap disk/file read error)
  2552 00005D84 89D8                <1> 	mov	eax, ebx	
  2553                              <1> rlp_retn:
  2554 00005D86 5B                  <1> 	pop	ebx
  2555 00005D87 C3                  <1> 	retn
  2556                              <1> 	
  2557                              <1> rlp_im_err:	
  2558 00005D88 B804000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
  2559                              <1> 				  ; Major error = 0 (No protection fault)	
  2560 00005D8D EBF7                <1> 	jmp	short rlp_retn
  2561                              <1> 
  2562                              <1> rlp_swp_err:
  2563 00005D8F B828000000          <1> 	mov 	eax, SWP_DISK_READ_ERR ; Swap disk read error !
  2564 00005D94 EBF0                <1> 	jmp	short rlp_retn
  2565                              <1> 
  2566                              <1> 
  2567                              <1> copy_page_dir:
  2568                              <1> 	; 19/09/2015
  2569                              <1> 	; temporary - 07/09/2015
  2570                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
  2571                              <1> 	;
  2572                              <1> 	; INPUT -> 
  2573                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
  2574                              <1> 	;		    page directory.
  2575                              <1> 	; OUTPUT ->
  2576                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
  2577                              <1> 	;	       page directory.
  2578                              <1> 	;	(New page directory with new page table entries.)
  2579                              <1> 	;	(New page tables with read only copies of the parent's
  2580                              <1> 	;	pages.)
  2581                              <1> 	;	EAX = 0 -> Error (CF = 1)
  2582                              <1> 	;
  2583                              <1> 	; Modified Registers -> none (except EAX)
  2584                              <1> 	;
  2585 00005D96 E80AF8FFFF          <1> 	call	allocate_page
  2586 00005D9B 723E                <1> 	jc	short cpd_err
  2587                              <1> 	;
  2588 00005D9D 55                  <1> 	push	ebp ; 20/07/2015
  2589 00005D9E 56                  <1> 	push	esi
  2590 00005D9F 57                  <1> 	push	edi
  2591 00005DA0 53                  <1> 	push	ebx
  2592 00005DA1 51                  <1> 	push	ecx
  2593 00005DA2 8B35[B8030300]      <1> 	mov	esi, [u.pgdir]
  2594 00005DA8 89C7                <1> 	mov	edi, eax
  2595 00005DAA 50                  <1> 	push	eax ; save child's page directory address
  2596                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
  2597                              <1> 	; (use same system space for all user page tables) 
  2598 00005DAB A5                  <1> 	movsd
  2599 00005DAC BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
  2600 00005DB1 B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
  2601                              <1> cpd_0:	
  2602 00005DB6 AD                  <1> 	lodsd
  2603                              <1> 	;or	eax, eax
  2604                              <1>         ;jnz     short cpd_1
  2605 00005DB7 A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
  2606 00005DB9 7508                <1> 	jnz	short cpd_1
  2607                              <1>  	; (virtual address at the end of the page table)	
  2608 00005DBB 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
  2609 00005DC1 EB0F                <1> 	jmp	short cpd_2
  2610                              <1> cpd_1:	
  2611 00005DC3 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
  2612 00005DC7 89C3                <1> 	mov	ebx, eax
  2613                              <1> 	; EBX = Parent's page table address
  2614 00005DC9 E81F000000          <1> 	call	copy_page_table
  2615 00005DCE 720C                <1> 	jc	short cpd_p_err
  2616                              <1> 	; EAX = Child's page table address
  2617 00005DD0 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
  2618                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
  2619                              <1> 			 ; (present, writable, user)
  2620                              <1> cpd_2:
  2621 00005DD2 AB                  <1> 	stosd
  2622 00005DD3 E2E1                <1> 	loop	cpd_0
  2623                              <1> 	;
  2624 00005DD5 58                  <1> 	pop	eax  ; restore child's page directory address
  2625                              <1> cpd_3:
  2626 00005DD6 59                  <1> 	pop	ecx
  2627 00005DD7 5B                  <1> 	pop	ebx
  2628 00005DD8 5F                  <1> 	pop	edi
  2629 00005DD9 5E                  <1> 	pop	esi
  2630 00005DDA 5D                  <1> 	pop	ebp
  2631                              <1> cpd_err:
  2632 00005DDB C3                  <1> 	retn
  2633                              <1> cpd_p_err:
  2634                              <1> 	; release the allocated pages missing (recover free space)
  2635 00005DDC 58                  <1> 	pop	eax  ; the new page directory address (physical)
  2636 00005DDD 8B1D[B8030300]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
  2637 00005DE3 E8F6F8FFFF          <1> 	call 	deallocate_page_dir
  2638 00005DE8 29C0                <1> 	sub	eax, eax ; 0
  2639 00005DEA F9                  <1> 	stc
  2640 00005DEB EBE9                <1> 	jmp	short cpd_3	
  2641                              <1> 
  2642                              <1> copy_page_table:
  2643                              <1> 	; 19/09/2015
  2644                              <1> 	; temporary - 07/09/2015
  2645                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
  2646                              <1> 	;
  2647                              <1> 	; INPUT -> 
  2648                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
  2649                              <1> 	;	EBP = page table entry index (from 'copy_page_dir')
  2650                              <1> 	; OUTPUT ->
  2651                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
  2652                              <1> 	;	EBP = (recent) page table index (for 'add_to_swap_queue')	
  2653                              <1> 	;	CF = 1 -> error 
  2654                              <1> 	;
  2655                              <1> 	; Modified Registers -> EBP (except EAX)
  2656                              <1> 	;
  2657 00005DED E8B3F7FFFF          <1> 	call	allocate_page
  2658 00005DF2 725A                <1> 	jc	short cpt_err
  2659                              <1> 	;
  2660 00005DF4 50                  <1> 	push	eax ; *
  2661                              <1> 	;push 	ebx
  2662 00005DF5 56                  <1> 	push	esi
  2663 00005DF6 57                  <1> 	push	edi
  2664 00005DF7 52                  <1> 	push	edx
  2665 00005DF8 51                  <1> 	push	ecx
  2666                              <1> 	;
  2667 00005DF9 89DE                <1> 	mov	esi, ebx
  2668 00005DFB 89C7                <1> 	mov	edi, eax
  2669 00005DFD 89C2                <1> 	mov	edx, eax
  2670 00005DFF 81C200100000        <1> 	add	edx, PAGE_SIZE 	
  2671                              <1> cpt_0:
  2672 00005E05 AD                  <1> 	lodsd
  2673 00005E06 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
  2674 00005E08 750B                <1> 	jnz	short cpt_1
  2675 00005E0A 21C0                <1> 	and	eax, eax
  2676 00005E0C 7430                <1> 	jz	short cpt_2
  2677                              <1> 	; ebp = virtual (linear) address of the memory page
  2678 00005E0E E85DFFFFFF          <1> 	call	reload_page ; 28/04/2015
  2679 00005E13 7234                <1> 	jc	short cpt_p_err
  2680                              <1> cpt_1:
  2681 00005E15 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  2682 00005E19 89C1                <1> 	mov	ecx, eax
  2683                              <1> 	; Allocate a new page for the child process
  2684 00005E1B E885F7FFFF          <1> 	call	allocate_page
  2685 00005E20 7227                <1> 	jc	short cpt_p_err
  2686 00005E22 57                  <1> 	push	edi
  2687 00005E23 56                  <1> 	push	esi
  2688 00005E24 89CE                <1> 	mov	esi, ecx
  2689 00005E26 89C7                <1> 	mov	edi, eax
  2690 00005E28 B900040000          <1> 	mov	ecx, PAGE_SIZE/4
  2691 00005E2D F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
  2692 00005E2F 5E                  <1> 	pop	esi
  2693 00005E30 5F                  <1> 	pop	edi
  2694                              <1> 	; 
  2695 00005E31 53                  <1> 	push	ebx
  2696 00005E32 50                  <1> 	push	eax
  2697 00005E33 89EB                <1> 	mov	ebx, ebp
  2698                              <1> 	; ebx = virtual address of the memory page
  2699 00005E35 E8AAFDFFFF          <1> 	call	add_to_swap_queue
  2700 00005E3A 58                  <1> 	pop	eax
  2701 00005E3B 5B                  <1> 	pop	ebx
  2702                              <1> 	;
  2703                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
  2704 00005E3C 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
  2705                              <1> cpt_2:
  2706 00005E3E AB                  <1> 	stosd  ; EDI points to child's PTE  	 
  2707                              <1> 	;
  2708 00005E3F 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
  2709                              <1> 	;
  2710 00005E45 39D7                <1> 	cmp	edi, edx
  2711 00005E47 72BC                <1> 	jb	short cpt_0
  2712                              <1> cpt_p_err:
  2713 00005E49 59                  <1> 	pop	ecx
  2714 00005E4A 5A                  <1> 	pop	edx
  2715 00005E4B 5F                  <1> 	pop	edi
  2716 00005E4C 5E                  <1> 	pop	esi
  2717                              <1> 	;pop	ebx
  2718 00005E4D 58                  <1> 	pop	eax ; *
  2719                              <1> cpt_err:
  2720 00005E4E C3                  <1> 	retn
  2721                              <1> 
  2722                              <1> allocate_memory_block:
  2723                              <1> 	; 01/05/2017
  2724                              <1> 	; 28/04/2017
  2725                              <1> 	; 25/04/2017
  2726                              <1> 	; 01/04/2016, 02/04/2016, 03/04/2016
  2727                              <1> 	; 13/03/2016, 14/03/2016
  2728                              <1> 	; 12/03/2016 (TRDOS 386 = TRDOS v2.0)
  2729                              <1> 	; Allocating contiguous memory pages (in the kernel's memory space)
  2730                              <1> 	;
  2731                              <1> 	; INPUT -> 
  2732                              <1> 	;	EAX = Beginning address (physical)
  2733                              <1> 	;	EAX = 0 -> Allocate memory block from the first proper aperture	
  2734                              <1> 	;	ECX = Number of bytes to be allocated
  2735                              <1> 	;
  2736                              <1> 	; OUTPUT ->
  2737                              <1> 	; 	1) cf = 0 -> successful
  2738                              <1> 	;	EAX = Beginning (physical) address of the allocated memory block
  2739                              <1> 	;	ECX = Number of allocated bytes (rounded up to page borders) 
  2740                              <1> 	;	2) cf = 1 -> unsuccessful
  2741                              <1> 	;	 2.1) If EAX > 0 -> 
  2742                              <1> 	;	      (Number of requested pages is more than # of free pages
  2743                              <1> 	;	       but contiguous free pages -the aperture- is not enough!)	   	
  2744                              <1> 	;	      EAX = Beginning address of available aperture
  2745                              <1> 	;		    (one of all aperture with max. aperture size/length)		
  2746                              <1> 	;	      ECX = Size of available aperture (memory block) in bytes
  2747                              <1> 	;	 2.2) If EAX = 0 -> Out of memory error 
  2748                              <1> 	;	            (number of free pages is less than requested number)
  2749                              <1> 	;	      ECX = Total number of free bytes (free pages * 4096) 
  2750                              <1> 	;		    (It is not number of contiguous free bytes)	
  2751                              <1> 	;
  2752                              <1> 	; (Modified Registers -> EAX, ECX)
  2753                              <1> 	;
  2754                              <1> 	; PURPOSE: Loading a file at memory for copying or running etc.
  2755                              <1> 	; If this procedure returns with cf is set, ECX contains maximum
  2756                              <1> 	; available space and EAX contains the beginning address of it.
  2757                              <1> 	; If EAX has zero, ECX contains total number of free bytes.
  2758                              <1> 	; If requested block has been successfully allocated (by rounding up to
  2759                              <1> 	; the last page border), it must be deallocated later by using
  2760                              <1> 	; 'deallocate_memory_block' procedure.    
  2761                              <1> 
  2762 00005E4F 52                  <1> 	push	edx ; *
  2763 00005E50 BAFF0F0000          <1> 	mov	edx, PAGE_SIZE - 1   ; 4095
  2764 00005E55 01D0                <1> 	add	eax, edx
  2765 00005E57 01D1                <1> 	add	ecx, edx
  2766 00005E59 C1E90C              <1> 	shr	ecx, PAGE_SHIFT	     ; 12
  2767                              <1> 
  2768                              <1> 	; ECX = number of contiguous pages to be allocated
  2769 00005E5C 8B15[E0630100]      <1> 	mov	edx, [free_pages]
  2770                              <1> 	; 01/05/2017
  2771                              <1> 	;or	ecx, ecx
  2772                              <1> 	;jz	short amb3
  2773                              <1> 	; If ECX=0, set cf to 1 and return with max. available mem block size
  2774                              <1> 
  2775 00005E62 39D1                <1> 	cmp	ecx, edx
  2776 00005E64 7760                <1> 	ja	short amb_3
  2777                              <1> 
  2778 00005E66 C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; 12
  2779                              <1> 
  2780 00005E69 89C2                <1> 	mov	edx, eax 	     ; page number
  2781 00005E6B C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
  2782                              <1> 				     ; (1 allocation bit = 1 page)
  2783                              <1> 				     ; (1 allocation bytes = 8 pages)
  2784 00005E6E 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2785                              <1> 				     ; (to get 32 bit position)	
  2786 00005E71 53                  <1> 	push	ebx ; **
  2787                              <1> amb_0:
  2788 00005E72 890D[946F0100]      <1> 	mov	[mem_ipg_count], ecx ; initial (reset) value of page count
  2789 00005E78 890D[986F0100]      <1> 	mov	[mem_pg_count], ecx
  2790 00005E7E 31C9                <1> 	xor	ecx, ecx ; 0
  2791 00005E80 890D[9C6F0100]      <1> 	mov	[mem_aperture], ecx ; 0
  2792 00005E86 890D[A06F0100]      <1> 	mov	[mem_max_aperture], ecx ; 0
  2793                              <1> 	
  2794 00005E8C BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address.
  2795 00005E91 3B15[E4630100]      <1> 	cmp	edx, [next_page]     ; Is the beginning page address lower
  2796                              <1> 				     ; than the address in 'next_page' ?
  2797                              <1> 				     ; (the first/next free page of user space)		
  2798 00005E97 7208                <1> 	jb	short amb_1
  2799 00005E99 3B15[E8630100]      <1> 	cmp 	edx, [last_page]     ; is the beginning page address higher
  2800                              <1> 				     ; than the address in 'last_page' ?
  2801                              <1> 				     ; (end of the memory)		
  2802 00005E9F 7606                <1> 	jna	short amb_2	     ; no	
  2803                              <1> amb_1:
  2804 00005EA1 8B15[E4630100]      <1> 	mov	edx, [next_page]     ; M.A.T. offset (1 M.A.T. byte = 8 pages)
  2805                              <1> amb_2:
  2806 00005EA7 01D3                <1> 	add	ebx, edx
  2807                              <1> 
  2808                              <1> 	; 28/04/2017
  2809                              <1> 	;xor	ecx, ecx
  2810 00005EA9 0FBC0B              <1> 	bsf	ecx, [ebx]	     ; 0 to 31
  2811 00005EAC 89D0                <1> 	mov	eax, edx
  2812 00005EAE C1E003              <1> 	shl	eax, 3		     ; *8	
  2813 00005EB1 01C8                <1> 	add	eax, ecx	     ; beginning page number
  2814                              <1> 
  2815 00005EB3 A3[A46F0100]        <1> 	mov	[mem_pg_pos], eax    ; beginning page no (for curr. mem. aperture)
  2816 00005EB8 A3[A86F0100]        <1>  	mov	[mem_max_pg_pos], eax ; beginning page no for max. mem. aperture
  2817                              <1> 
  2818 00005EBD 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only (0 to 31)
  2819                              <1> 				     ; (allocation bit position)	 
  2820 00005EC0 750E                <1> 	jnz	short amb_4	     ; 0
  2821 00005EC2 B120                <1> 	mov	cl, 32
  2822 00005EC4 EB4B                <1> 	jmp	short amb_10
  2823                              <1> 
  2824                              <1> amb_3:	; out_of_memory
  2825 00005EC6 31C0                <1> 	xor	eax, eax ; 0
  2826 00005EC8 89D1                <1> 	mov	ecx, edx ; free pages
  2827 00005ECA C1E10C              <1> 	shl	ecx, PAGE_SHIFT
  2828 00005ECD 5A                  <1> 	pop	edx ; *
  2829 00005ECE F9                  <1> 	stc
  2830 00005ECF C3                  <1> 	retn	
  2831                              <1> amb_4:
  2832 00005ED0 8B13                <1> 	mov	edx, [ebx]
  2833 00005ED2 88C1                <1> 	mov	cl, al ; 1 to 31
  2834 00005ED4 D3EA                <1> 	shr	edx, cl
  2835 00005ED6 89D0                <1> 	mov	eax, edx
  2836                              <1> amb_5:
  2837 00005ED8 D1E8                <1> 	shr	eax, 1 ; (***)
  2838 00005EDA 7317                <1> 	jnc	short amb_7
  2839 00005EDC FF05[9C6F0100]      <1> 	inc	dword [mem_aperture]
  2840 00005EE2 FF0D[986F0100]      <1> 	dec	dword [mem_pg_count]
  2841 00005EE8 7470                <1> 	jz	short amb_15
  2842                              <1> amb_6:
  2843                              <1> 	; 28/04/2017
  2844 00005EEA FEC1                <1> 	inc	cl
  2845 00005EEC 80F920              <1> 	cmp	cl, 32
  2846 00005EEF 730D                <1> 	jnb	short amb_9
  2847 00005EF1 EBE5                <1> 	jmp	short amb_5
  2848                              <1> amb_7:
  2849 00005EF3 50                  <1> 	push	eax ; (***) allocation bits (in shifted status)
  2850 00005EF4 E81B010000          <1> 	call	amb_26 ; set maximum memory aperture (free memory block size)
  2851 00005EF9 58                  <1> 	pop	eax ; (***)
  2852 00005EFA EBEE                <1> 	jmp	short amb_6
  2853                              <1> amb_8:
  2854                              <1> 	; 28/04/2017
  2855 00005EFC B120                <1> 	mov	cl, 32
  2856                              <1> amb_9:
  2857 00005EFE 89DA                <1> 	mov	edx, ebx
  2858 00005F00 81EA00001000        <1> 	sub	edx, MEM_ALLOC_TBL
  2859 00005F06 3B15[E8630100]      <1> 	cmp	edx, [last_page]
  2860 00005F0C 7336                <1> 	jnb	short amb_14 ; contiguous pages not enough
  2861 00005F0E 83C304              <1> 	add	ebx, 4
  2862                              <1> amb_10:
  2863 00005F11 8B03                <1> 	mov	eax, [ebx]
  2864 00005F13 21C0                <1> 	and 	eax, eax
  2865 00005F15 7408                <1>         jz      short amb_11 ; there is not a free page bit in this alloc dword
  2866 00005F17 40                  <1> 	inc	eax ; 0FFFFFFFFh -> 0
  2867 00005F18 740C                <1> 	jz	short amb_12 ; all of bits are set (32 free pages)
  2868 00005F1A 48                  <1> 	dec	eax
  2869 00005F1B 28C9                <1> 	sub	cl, cl ; 0
  2870 00005F1D EBB9                <1> 	jmp	short amb_5
  2871                              <1> amb_11:
  2872 00005F1F E8F0000000          <1> 	call	amb_26 ; set maximum memory aperture (free memory block size)
  2873 00005F24 EBD8                <1> 	jmp	short amb_9	
  2874                              <1> amb_12:
  2875 00005F26 390D[986F0100]      <1> 	cmp	[mem_pg_count], ecx ; 32
  2876 00005F2C 7306                <1> 	jnb	short amb_13
  2877 00005F2E 8B0D[986F0100]      <1> 	mov	ecx, [mem_pg_count]
  2878                              <1> amb_13:
  2879 00005F34 010D[9C6F0100]      <1> 	add	[mem_aperture], ecx
  2880 00005F3A 290D[986F0100]      <1> 	sub	[mem_pg_count], ecx
  2881 00005F40 7618                <1> 	jna	short amb_15
  2882 00005F42 EBBA                <1> 	jmp	short amb_9 ; 01/05/2017
  2883                              <1> amb_14:
  2884 00005F44 E8CB000000          <1> 	call	amb_26 ; 28/04/2017
  2885 00005F49 A1[A86F0100]        <1> 	mov	eax, [mem_max_pg_pos] ; begin address of max. mem aperture	
  2886 00005F4E 8B0D[A06F0100]      <1> 	mov	ecx, [mem_max_aperture] ; max. (largest) memory aperture
  2887 00005F54 F9                  <1> 	stc
  2888 00005F55 E9AF000000          <1>         jmp     amb_25
  2889                              <1> 
  2890                              <1> amb_15: ; OK !
  2891 00005F5A A1[A46F0100]        <1> 	mov	eax, [mem_pg_pos]    ; Beginning address as page number
  2892 00005F5F 8B0D[9C6F0100]      <1> 	mov	ecx, [mem_aperture]  ; Free contiguous page count (>=1)
  2893                              <1> amb_16:
  2894                              <1> 	; allocate contiguous memory pages (via memory allocation table bits)
  2895 00005F65 89C2                <1> 	mov	edx, eax
  2896                              <1> 	; 25/04/2017
  2897 00005F67 C1EA03              <1> 	shr	edx, 3		 ; 8 pages in one allocation byte
  2898 00005F6A 80E2FC              <1> 	and	dl, 0FCh	 ; clear lower 2 bits
  2899                              <1> 				 ; (for dword/32bit positioning)	
  2900                              <1> 
  2901 00005F6D BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL
  2902 00005F72 01D3                <1> 	add	ebx, edx
  2903 00005F74 83E01F              <1> 	and	eax, 1Fh ; 31
  2904                              <1> 	; 03/04/2016
  2905 00005F77 BA20000000          <1> 	mov	edx, 32
  2906 00005F7C 28C2                <1> 	sub	dl, al
  2907 00005F7E 39CA                <1> 	cmp	edx, ecx	 ; ecx >= 1
  2908 00005F80 7602                <1> 	jna	short amb_17
  2909 00005F82 89CA                <1> 	mov	edx, ecx
  2910                              <1> amb_17:
  2911 00005F84 29D1                <1> 	sub	ecx, edx
  2912 00005F86 51                  <1> 	push	ecx ; ***
  2913 00005F87 89D1                <1> 	mov	ecx, edx
  2914                              <1> amb_18:		
  2915 00005F89 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
  2916                              <1> 				 ; is copied into the Carry Flag and then cleared
  2917                              <1> 				 ; in the destination.
  2918 00005F8C FF0D[E0630100]      <1> 	dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
  2919 00005F92 49                  <1> 	dec	ecx
  2920 00005F93 7404                <1> 	jz	short amb_19
  2921 00005F95 FEC0                <1> 	inc	al
  2922 00005F97 EBF0                <1> 	jmp	short amb_18
  2923                              <1> amb_19:	
  2924 00005F99 59                  <1> 	pop	ecx ; ***
  2925 00005F9A 21C9                <1> 	and	ecx, ecx ; 0 ?
  2926 00005F9C 741E                <1> 	jz	short amb_22	
  2927                              <1> 	; 01/04/2016
  2928 00005F9E B020                <1> 	mov	al, 32
  2929                              <1> amb_20:
  2930 00005FA0 83C304              <1> 	add	ebx, 4
  2931 00005FA3 39C1                <1> 	cmp	ecx, eax ; 32
  2932 00005FA5 7305                <1> 	jnb	short amb_21
  2933                              <1> 	; ECX < 32
  2934 00005FA7 28C0                <1> 	sub	al, al ; 0
  2935 00005FA9 50                  <1> 	push	eax ; 0 ***
  2936 00005FAA EBDD                <1> 	jmp	short amb_18
  2937                              <1> amb_21:
  2938 00005FAC 2905[E0630100]      <1> 	sub	[free_pages], eax   ; [free_pages] = [free_pages] - 32
  2939 00005FB2 C70300000000        <1> 	mov	dword [ebx], 0	    ; reset 32 bits
  2940 00005FB8 29C1                <1> 	sub	ecx, eax ; 32
  2941 00005FBA 75E4                <1> 	jnz	short amb_20
  2942                              <1> amb_22:
  2943 00005FBC A1[A46F0100]        <1> 	mov	eax, [mem_pg_pos]   ; Beginning address as page number
  2944 00005FC1 8B0D[9C6F0100]      <1> 	mov	ecx, [mem_aperture] ; Free contiguous page count
  2945                              <1> 	; [next_page] update
  2946 00005FC7 89C2                <1> 	mov	edx, eax
  2947                              <1> 	; 03/04/2016
  2948 00005FC9 C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
  2949                              <1> 				     ; (1 allocation bit = 1 page)
  2950                              <1> 				     ; (1 allocation bytes = 8 pages)
  2951 00005FCC 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2952                              <1> 				     ; (to get 32 bit position)	
  2953 00005FCF 3B15[E4630100]      <1> 	cmp	edx, [next_page] ; first free page pointer offset
  2954 00005FD5 7732                <1> 	ja	short amb_25
  2955 00005FD7 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL
  2956 00005FDC 833C1300            <1> 	cmp	dword [ebx+edx], 0
  2957 00005FE0 7721                <1> 	ja	short amb_24
  2958 00005FE2 89C2                <1> 	mov	edx, eax
  2959 00005FE4 01CA                <1> 	add	edx, ecx
  2960 00005FE6 C1EA03              <1> 	shr	edx, 3
  2961 00005FE9 80E2FC              <1> 	and	dl, 0FCh
  2962                              <1> amb_23:
  2963 00005FEC 833C1300            <1> 	cmp	dword [ebx+edx], 0
  2964 00005FF0 7711                <1> 	ja	short amb_24
  2965 00005FF2 83C204              <1> 	add	edx, 4
  2966 00005FF5 3B15[E8630100]      <1> 	cmp	edx, [last_page]    ; last page pointer offset
  2967 00005FFB 76EF                <1> 	jna	short amb_23
  2968 00005FFD 8B15[EC630100]      <1> 	mov	edx, [first_page]   ; (for) beginning of user's space
  2969                              <1> amb_24:
  2970 00006003 8915[E4630100]      <1> 	mov	[next_page], edx
  2971                              <1> amb_25:
  2972 00006009 9C                  <1> 	pushf
  2973 0000600A C1E00C              <1> 	shl	eax, PAGE_SHIFT	     ; convert to phy. address in bytes
  2974 0000600D C1E10C              <1> 	shl	ecx, PAGE_SHIFT	     ; convert to byte counts
  2975 00006010 9D                  <1> 	popf
  2976 00006011 5B                  <1> 	pop	ebx ; **
  2977 00006012 5A                  <1> 	pop	edx ; *
  2978 00006013 C3                  <1> 	retn
  2979                              <1> 
  2980                              <1> amb_26:	; set maximum free memory aperture (free memory block size) 
  2981 00006014 89DA                <1> 	mov	edx, ebx ; current address
  2982 00006016 81EA00001000        <1> 	sub	edx, MEM_ALLOC_TBL ; MAT beginning address
  2983                              <1> 	; 02/04/2016 
  2984 0000601C C1E203              <1> 	shl	edx, 3 ; MAT byte offset * 8 = page number base
  2985 0000601F 01CA                <1> 	add	edx, ecx ; current page number (ecx = 0 to 32)
  2986                              <1> 	;
  2987 00006021 A1[9C6F0100]        <1> 	mov	eax, [mem_aperture]
  2988 00006026 21C0                <1> 	and	eax, eax
  2989 00006028 7421                <1>         jz      short amb_27
  2990 0000602A C705[9C6F0100]0000- <1>         mov     dword [mem_aperture], 0
  2990 00006032 0000                <1>
  2991 00006034 3B05[A06F0100]      <1> 	cmp	eax, [mem_max_aperture]
  2992 0000603A 760F                <1> 	jna	short amb_27
  2993 0000603C A3[A06F0100]        <1> 	mov	[mem_max_aperture], eax
  2994                              <1> 	; 25/04/2017
  2995 00006041 A1[A46F0100]        <1> 	mov	eax, [mem_pg_pos]
  2996                              <1> 	; EAX = Beginning page number of the max. aperture 
  2997 00006046 A3[A86F0100]        <1> 	mov	[mem_max_pg_pos], eax
  2998                              <1> amb_27: 
  2999 0000604B 8915[A46F0100]      <1> 	mov	[mem_pg_pos], edx ; current page
  3000                              <1> 
  3001 00006051 A1[946F0100]        <1> 	mov	eax, [mem_ipg_count] ; initial (reset) value of page count
  3002 00006056 A3[986F0100]        <1> 	mov	[mem_pg_count], eax
  3003                              <1> 
  3004 0000605B C3                  <1> 	retn
  3005                              <1> 
  3006                              <1> deallocate_memory_block:
  3007                              <1> 	; 03/04/2016
  3008                              <1> 	; 14/03/2016 (TRDOS 386 = TRDOS v2.0)
  3009                              <1> 	; Deallocating contiguous memory pages (in the kernel's memory space)
  3010                              <1> 	;
  3011                              <1> 	; INPUT -> 
  3012                              <1> 	;	EAX = Beginning address (physical)
  3013                              <1> 	;	ECX = Number of bytes to be deallocated
  3014                              <1> 	;
  3015                              <1> 	; OUTPUT ->
  3016                              <1> 	;	Memory Allocation Table bits will be updated
  3017                              <1> 	;	[free_pages] will be changed (increased)
  3018                              <1> 	;
  3019                              <1> 	; (Modified Registers -> EAX, ECX)
  3020                              <1> 	;
  3021                              <1> 	; PURPOSE: Unloading/Freeing a file -or an allocated memory block- 
  3022                              <1> 	; at memory after copying, running, saving, reading, writing etc.
  3023                              <1> 	;
  3024                              <1> 
  3025 0000605C 52                  <1> 	push	edx ; *
  3026 0000605D 53                  <1> 	push	ebx ; **
  3027                              <1> 
  3028 0000605E C1E80C              <1> 	shr	eax, PAGE_SHIFT	     ; 12
  3029 00006061 C1E90C              <1> 	shr	ecx, PAGE_SHIFT	     ; 12
  3030                              <1> 
  3031                              <1> 	; EAX = Beginning page number
  3032                              <1> 	; ECX = Number of contiguous pages to be deallocated
  3033                              <1> damb_0:
  3034                              <1> 	; deallocate contiguous memory pages (via memory allocation table bits)
  3035 00006064 89C2                <1> 	mov	edx, eax
  3036 00006066 C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
  3037                              <1> 				     ; (1 allocation bit = 1 page)
  3038                              <1> 				     ; (1 allocation bytes = 8 pages)
  3039 00006069 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  3040                              <1> 				     ; (to get 32 bit position)	
  3041 0000606C 3B15[E4630100]      <1> 	cmp	edx, [next_page] ; next free page
  3042 00006072 7306                <1> 	jnb	short damb_1
  3043 00006074 8915[E4630100]      <1> 	mov	[next_page], edx
  3044                              <1> damb_1:
  3045 0000607A BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL
  3046 0000607F 01D3                <1> 	add	ebx, edx
  3047 00006081 83E01F              <1> 	and	eax, 1Fh ; 31
  3048                              <1> 
  3049                              <1> 	; 03/04/2016
  3050 00006084 BA20000000          <1> 	mov	edx, 32
  3051 00006089 28C2                <1> 	sub	dl, al
  3052 0000608B 39CA                <1> 	cmp	edx, ecx
  3053 0000608D 7602                <1> 	jna	short damb_2
  3054 0000608F 89CA                <1> 	mov	edx, ecx
  3055                              <1> damb_2:
  3056 00006091 29D1                <1> 	sub	ecx, edx
  3057 00006093 51                  <1> 	push	ecx ; ***
  3058 00006094 89D1                <1> 	mov	ecx, edx
  3059                              <1> damb_3:		
  3060 00006096 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate page
  3061                              <1> 				     ; set relevant bit to 1.
  3062                              <1> 				     ; set CF to the previous bit value	
  3063 00006099 FF05[E0630100]      <1> 	inc     dword [free_pages]   ; 1 page has been deallocated (X = X+1) 
  3064 0000609F 49                  <1> 	dec	ecx
  3065 000060A0 7404                <1> 	jz	short damb_4
  3066 000060A2 FEC0                <1> 	inc	al
  3067 000060A4 EBF0                <1> 	jmp	short damb_3
  3068                              <1> damb_4:	
  3069 000060A6 59                  <1> 	pop	ecx ; ***
  3070 000060A7 21C9                <1> 	and	ecx, ecx ; 0 ?
  3071 000060A9 741E                <1> 	jz	short damb_7
  3072                              <1> 	; 03/04/2016
  3073 000060AB B020                <1> 	mov	al, 32
  3074                              <1> damb_5:
  3075 000060AD 83C304              <1> 	add	ebx, 4
  3076 000060B0 39C1                <1> 	cmp	ecx, eax ; 32
  3077 000060B2 7305                <1> 	jnb	short damb_6
  3078                              <1> 	; ECX < 32
  3079 000060B4 28C0                <1> 	sub	al, al ; 0
  3080 000060B6 50                  <1> 	push	eax ; 0 ***
  3081 000060B7 EBDD                <1> 	jmp	short damb_3
  3082                              <1> damb_6:
  3083 000060B9 0105[E0630100]      <1> 	add	[free_pages], eax ; [free_pages] = [free_pages] + 32
  3084 000060BF C703FFFFFFFF        <1> 	mov	dword [ebx], 0FFFFFFFFh ; set 32 bits
  3085 000060C5 29C1                <1> 	sub	ecx, eax ; 32
  3086 000060C7 75E4                <1> 	jnz	short damb_5
  3087                              <1> damb_7:
  3088 000060C9 5B                  <1> 	pop	ebx ; **
  3089 000060CA 5A                  <1> 	pop	edx ; *
  3090 000060CB C3                  <1> 	retn
  3091                              <1> 
  3092                              <1> direct_memory_access:
  3093                              <1> 	; 22/07/2017
  3094                              <1> 	; 12/05/2017
  3095                              <1> 	; 16/07/2016
  3096                              <1> 	; 12/07/2016 (TRDOS 386 = TRDOS v2.0)
  3097                              <1> 	; This processure will be called to map
  3098                              <1> 	; user's (ring 3) page tables to access phsical
  3099                              <1> 	; (flat/linear) memory addresses, directly (without
  3100                              <1> 	;  kernel's data transfer functions).
  3101                              <1> 	; 
  3102                              <1> 	; Purpose: Video memory access and shared memory access.
  3103                              <1> 	;
  3104                              <1> 	; INPUT -> 
  3105                              <1> 	;	EAX = Beginning address (physical).
  3106                              <1> 	;	EBX = User's buffer address ; 12/05/2017
  3107                              <1> 	;	ECX = Number of contiguous pages to be mapped.
  3108                              <1> 	; OUTPUT ->
  3109                              <1> 	;	User's page directory and pages tables
  3110                              <1> 	;	will be updated.
  3111                              <1> 	;	
  3112                              <1> 	;	If an old page table entry has valid page address, 
  3113                              <1> 	;	that page will be deallocated just before PTE will
  3114                              <1> 	;	be changed for direct (1 to 1) memory page access.
  3115                              <1> 	;
  3116                              <1> 	;	If old PTE value points to a swapped page,
  3117                              <1>         ;       that page (block) will be unlinked on swap disk. 
  3118                              <1> 	;
  3119                              <1> 	;	Newly allocated pages (except page tables) will not
  3120                              <1> 	;	be applied to Memory Allocation Table.
  3121                              <1> 	;	AVL bit 1 (PTE bit 10) of page table entry will be
  3122                              <1> 	;	used to indicate shared (direct) memory page; then,
  3123                              <1> 	;	this page will not be deallocated later during
  3124                              <1> 	;	process termination. (Memory Allocation Table and
  3125                              <1> 	;	free memory count will not be affected.
  3126                              <1> 	;	(Except deallocating page table's itself.)
  3127                              <1> 	;	
  3128                              <1> 	;      CF = 1 -> error (EAX = error code)
  3129                              <1> 	;      CF = 0 -> success (EAX = beginning address)
  3130                              <1> 	;
  3131                              <1> 	;; (Modified Registers -> none)
  3132                              <1> 	; Modified registers: ebp, edx, ecx, ebx, esi, edi	
  3133                              <1> 	;
  3134                              <1> 
  3135                              <1> 	;push	ebp
  3136                              <1> 	;push	ebx
  3137                              <1> 	;push	ecx
  3138                              <1> 	;push	edx
  3139 000060CC 662500F0            <1> 	and	ax, PTE_A_CLEAR ; clear page offset
  3140 000060D0 50                  <1> 	push	eax
  3141                              <1> 	;and	ecx, ecx ; page count
  3142                              <1> 	;jz	dmem_acc_7  ; 'insufficient memory' error
  3143 000060D1 89C5                <1> 	mov	ebp, eax
  3144 000060D3 81C300004000        <1> 	add	ebx, CORE ; 12/05/2017
  3145                              <1> dmem_acc_0: 
  3146 000060D9 891D[947A0100]      <1> 	mov	[base_addr], ebx ; 12/05/2017
  3147 000060DF A1[B8030300]        <1> 	mov	eax, [u.pgdir] ; page dir address (physical)
  3148 000060E4 E8D7F5FFFF          <1> 	call	get_pte
  3149                              <1> 		; EDX = Page table entry address (if CF=0)
  3150                              <1> 	        ;       Page directory entry address (if CF=1)
  3151                              <1> 		;       (Bit 0 value is 0 if PT is not present)
  3152                              <1> 		; EAX = Page table entry value (page address)
  3153                              <1> 		;	CF = 1 -> PDE not present or invalid ? 	
  3154 000060E9 7324                <1> 	jnc	short dmem_acc_1
  3155                              <1> 	;
  3156 000060EB E8B5F4FFFF          <1> 	call	allocate_page
  3157 000060F0 0F82AB000000        <1>         jc      dmem_acc_7  ; 'insufficient memory' error
  3158                              <1> 	;
  3159 000060F6 E824F5FFFF          <1> 	call 	clear_page
  3160                              <1> 	; EAX = Physical (base) address of the allocated (new) page
  3161 000060FB 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER ; 4+2+1 = 7
  3162                              <1> 			   ; lower 3 bits are used as U/S, R/W, P flags
  3163                              <1> 			   ; (user, writable, present page)	
  3164 000060FD 8902                <1> 	mov	[edx], eax ; Let's put the new page directory entry here !
  3165 000060FF A1[B8030300]        <1> 	mov	eax, [u.pgdir]	
  3166 00006104 E8B7F5FFFF          <1> 	call	get_pte
  3167 00006109 0F8292000000        <1>         jc      dmem_acc_7 ; 'insufficient memory' error
  3168                              <1> dmem_acc_1:
  3169                              <1> 	; EAX = PTE value, EDX = PTE address
  3170 0000610F A801                <1> 	test 	al, PTE_A_PRESENT
  3171 00006111 750D                <1> 	jnz	short dmem_acc_2
  3172 00006113 09C0                <1> 	or	eax, eax
  3173 00006115 7468                <1> 	jz	short dmem_acc_6   ; Change PTE
  3174 00006117 D1E8                <1> 	shr	eax, 1		; swap disk block (8 sectors) address
  3175                              <1> 	; unlink swap disk block
  3176 00006119 E80CFBFFFF          <1> 	call	unlink_swap_block
  3177 0000611E EB5F                <1> 	jmp	short dmem_acc_6
  3178                              <1> 
  3179                              <1> dmem_acc_2:
  3180 00006120 A802                <1> 	test	al, PTE_A_WRITE   ; bit 1, writable (r/w) flag
  3181                              <1> 				  ; (must be 1)
  3182 00006122 7550                <1> 	jnz	short dmem_acc_4
  3183                              <1> 	; Read only -duplicated- page (belongs to a parent or a child)
  3184 00006124 66A90002            <1>         test    ax, PTE_DUPLICATED ; Was this page duplicated 
  3185                              <1> 				   ; as child's page ?
  3186 00006128 7455                <1> 	jz	short dmem_acc_5 ; Change PTE but don't deallocate the page!
  3187                              <1> 
  3188                              <1> 	;push	edi
  3189                              <1> 	;push	esi
  3190                              <1> 
  3191 0000612A 51                  <1> 	push	ecx
  3192                              <1> 	;push	ebx
  3193 0000612B 8B1D[BC030300]      <1> 	mov	ebx, [u.ppgdir] ; parent's page dir address (physical)
  3194                              <1> 	
  3195                              <1> 	; check the parent's PTE value is read only & same page or not.. 
  3196 00006131 89EF                <1> 	mov	edi, ebp
  3197 00006133 C1EF16              <1> 	shr	edi, PAGE_D_SHIFT ; 22
  3198                              <1> 	; EDI = page directory entry index (0-1023)
  3199 00006136 89EE                <1> 	mov	esi, ebp
  3200 00006138 C1EE0C              <1> 	shr	esi, PAGE_SHIFT ; 12	
  3201 0000613B 81E6FF030000        <1> 	and	esi, PTE_MASK
  3202                              <1> 	; ESI = page table entry index (0-1023)
  3203                              <1> 
  3204 00006141 66C1E702            <1> 	shl	di, 2 ; * 4
  3205 00006145 01FB                <1> 	add	ebx, edi ; PDE offset (for the parent)
  3206 00006147 8B0F                <1> 	mov	ecx, [edi]
  3207 00006149 F6C101              <1> 	test	cl, PDE_A_PRESENT ; present (valid) or not ?
  3208 0000614C 7425                <1> 	jz	short dmem_acc_3	; parent process does not use this page
  3209 0000614E 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
  3210 00006153 66C1E602            <1> 	shl	si, 2 ; *4 
  3211 00006157 01CE                <1> 	add	esi, ecx ; PTE offset (for the parent)
  3212 00006159 8B1E                <1> 	mov	ebx, [esi]
  3213 0000615B F6C301              <1> 	test	bl, PTE_A_PRESENT ; present or not ?
  3214 0000615E 7413                <1> 	jz	short dmem_acc_3	; parent process does not use this page
  3215 00006160 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; Clear attribute bits 
  3216 00006164 6681E300F0          <1> 	and	bx, PTE_A_CLEAR ; 0F000h ; Clear attribute bits
  3217 00006169 39D8                <1> 	cmp	eax, ebx	; parent's and child's pages are same ?
  3218 0000616B 7506                <1> 	jne	short dmem_acc_3	; not same page
  3219                              <1> 				; deallocate the child's page
  3220 0000616D 800E02              <1>         or      byte [esi], PTE_A_WRITE ; convert to writable page (parent)
  3221                              <1> 	;pop	ebx
  3222 00006170 59                  <1> 	pop	ecx
  3223 00006171 EB0C                <1> 	jmp	short dmem_acc_5
  3224                              <1> dmem_acc_3:
  3225                              <1> 	;pop	ebx
  3226 00006173 59                  <1> 	pop	ecx
  3227                              <1> dmem_acc_4:	
  3228 00006174 66A90004            <1> 	test	ax, PTE_SHARED ; shared or direct memory access indicator
  3229 00006178 7505                <1> 	jnz	short dmem_acc_5   ; AVL bit 1 = 1, do not deallocate this page!
  3230                              <1> 	;
  3231                              <1> 	;and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
  3232 0000617A E804F6FFFF          <1> 	call	deallocate_page
  3233                              <1> dmem_acc_5:
  3234                              <1> 	;pop	esi
  3235                              <1> 	;pop	edi
  3236                              <1> dmem_acc_6:
  3237 0000617F 89E8                <1> 	mov	eax, ebp ; physical page (offset=0) address
  3238                              <1> 	; EAX = memory page address
  3239                              <1> 	; EDX = PTE entry address (physical)
  3240 00006181 660D0704            <1> 	or	ax, PTE_A_PRESENT+PTE_A_USER+PTE_A_WRITE+PTE_SHARED
  3241                              <1> 			; present flag, bit 0 = 1
  3242                              <1> 			; user flag, bit 2 = 1	
  3243                              <1> 			; writable flag, bit 1 = 1
  3244                              <1> 			; direct memory access flag, bit 10 = 1
  3245                              <1> 			; (This page must not be deallocated!)
  3246 00006185 8902                <1> 	mov	[edx], eax  ; Update PTE value
  3247 00006187 49                  <1> 	dec	ecx ; remain count of contiguous pages
  3248 00006188 741E                <1> 	jz	short dmem_acc_8
  3249 0000618A 81C500100000        <1> 	add	ebp, PAGE_SIZE ; next physical page address
  3250                              <1> 	; 22/07/2017
  3251                              <1> 	;mov	eax, ebp
  3252                              <1> 	; 12/05/2017
  3253 00006190 8B1D[947A0100]      <1> 	mov	ebx, [base_addr] ; linear address (virtual+CORE)
  3254 00006196 81C300100000        <1> 	add	ebx, PAGE_SIZE	; next linear address
  3255 0000619C E938FFFFFF          <1>         jmp     dmem_acc_0
  3256                              <1> dmem_acc_7:  ; ERROR ! 
  3257 000061A1 C7042404000000      <1> 	mov	dword [esp], ERR_MINOR_IM 
  3258                              <1> 		; Insufficient memory (minor) error!
  3259                              <1> 		; Major error = 0 (No protection fault)	
  3260                              <1> 	; cf = 1
  3261                              <1> dmem_acc_8:
  3262 000061A8 58                  <1> 	pop	eax
  3263                              <1> 	;pop	edx
  3264                              <1> 	;pop	ecx
  3265                              <1> 	;pop	ebx
  3266                              <1> 	;pop	ebp
  3267 000061A9 C3                  <1> 	retn
  3268                              <1> 
  3269                              <1> deallocate_user_pages:
  3270                              <1> 	; 20/05/2017
  3271                              <1> 	; 15/05/2017
  3272                              <1> 	; 20/02/2017
  3273                              <1> 	; 19/02/2017 (TRDOS 386 = TRDOS v2.0)
  3274                              <1> 	;
  3275                              <1> 	; Deallocate virtually contiguous user pages (memory block)
  3276                              <1> 	; (caller: 'sysdalloc' system call)
  3277                              <1> 	;
  3278                              <1> 	; INPUT ->
  3279                              <1> 	;	EBX = VIRTUAL ADDRESS (beginning address)
  3280                              <1> 	;	ECX = byte count
  3281                              <1> 	;	[u.pgdir] = user's page directory
  3282                              <1> 	;	[u.ppdir] = parent's page directory
  3283                              <1> 	;
  3284                              <1> 	; OUTPUT ->
  3285                              <1> 	;    If CF = 0 	
  3286                              <1> 	;	EAX = Deallocated memory bytes
  3287                              <1> 	;	  (Even if shared or read only pages will not be
  3288                              <1> 	;	   deallocated on M.A.T., this byte count will be
  3289                              <1> 	;	   returned as virtually deallocated bytes; in fact
  3290                              <1> 	;	   virtually deallocated user pages * 4096.) 
  3291                              <1> 	;	EBX = Virtual address (as rounded up)
  3292                              <1> 	;    If CF = 1    	
  3293                              <1> 	;	EAX = 0 (there is not any deallocated pages)
  3294                              <1> 	;
  3295                              <1> 	; Note: Empty page tables will not be deallocated!!!
  3296                              <1> 	;     (they will be deallocated at process termination stage)
  3297                              <1> 	;
  3298                              <1> 	; Modified Registers -> EAX, EDX, ESI, EDI, EBX, ECX, EBP
  3299                              <1> 	;
  3300 000061AA 89DE                <1> 	mov	esi, ebx
  3301 000061AC 89F7                <1> 	mov	edi, esi
  3302 000061AE 01CF                <1> 	add	edi, ecx
  3303 000061B0 81C6FF0F0000        <1> 	add	esi, PAGE_SIZE - 1  ; 4095 (round up)	
  3304 000061B6 C1EE0C              <1> 	shr	esi, PAGE_SHIFT
  3305 000061B9 C1EF0C              <1> 	shr	edi, PAGE_SHIFT
  3306 000061BC 89F8                <1> 	mov	eax, edi ; end page
  3307 000061BE 29F0                <1> 	sub	eax, esi ; end page - start page
  3308 000061C0 0F86D5000000        <1> 	jna	da_u_pd_err  ; < 1
  3309 000061C6 89F3                <1> 	mov	ebx, esi
  3310 000061C8 C1E30C              <1> 	shl	ebx, PAGE_SHIFT ; virtual address (as rounded up)
  3311 000061CB 53                  <1> 	push	ebx ; *
  3312 000061CC 89C1                <1> 	mov	ecx, eax ; page count
  3313 000061CE C1E00C              <1> 	shl	eax, PAGE_SHIFT ; byte count as adjusted
  3314 000061D1 50                  <1> 	push	eax ; **
  3315 000061D2 8B1D[B8030300]      <1> 	mov	ebx, [u.pgdir] ; physical addr of user's page dir
  3316 000061D8 81C600040000        <1>  	add	esi, CORE/PAGE_SIZE 
  3317 000061DE 89F7                <1> 	mov	edi, esi
  3318 000061E0 81E7FF030000        <1> 	and	edi, PTE_MASK ; PTE entry in the page table
  3319 000061E6 57                  <1> 	push	edi ; *** ; PTE index (of page directory)
  3320 000061E7 C1EE0A              <1> 	shr	esi, PAGE_D_SHIFT - PAGE_SHIFT ; 22-12=10
  3321 000061EA 89F2                <1> 	mov	edx, esi 
  3322                              <1> 	; EDX = PDE index
  3323 000061EC C1E602              <1> 	shl	esi, 2 ; convert PDE index to dword offset
  3324 000061EF 01DE                <1> 	add	esi, ebx ; add page directory address
  3325                              <1> da_u_pd_1:
  3326 000061F1 AD                  <1> 	lodsd
  3327                              <1> 	;
  3328 000061F2 89F5                <1> 	mov	ebp, esi ; 20/02/2017
  3329                              <1> 	; EBP = next PDE address
  3330                              <1> 	;
  3331 000061F4 A801                <1> 	test	al, PDE_A_PRESENT ; bit 0, present flag (must be 1)
  3332 000061F6 0F8494000000        <1> 	jz	da_u_pd_3 ; 20/05/2017	
  3333 000061FC 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
  3334                              <1> 	; EAX = PHYSICAL (flat) ADDRESS OF THE PAGE TABLE
  3335 00006200 8B3C24              <1> 	mov	edi, [esp] ; ***
  3336                              <1> 	; EDI = PTE index (of complete page directory)
  3337                              <1> 	;and	edi, PTE_MASK ; PTE entry in the page table
  3338 00006203 C1E702              <1> 	shl	edi, 2 ; convert PTE index to dword offset
  3339 00006206 89FE                <1> 	mov	esi, edi ; PTE offset in page table (0-4092)
  3340 00006208 01C6                <1> 	add	esi, eax ; now, esi points to requested PTE
  3341                              <1> da_u_pt_0:
  3342 0000620A AD                  <1> 	lodsd
  3343 0000620B A801                <1> 	test	al, PTE_A_PRESENT ; bit 0, present flag (must be 1)
  3344 0000620D 743F                <1> 	jz	short da_u_pt_1
  3345                              <1> 	;
  3346 0000620F A802                <1> 	test	al, PTE_A_WRITE   ; bit 1, writable (r/w) flag
  3347                              <1> 				  ; (must be 1)
  3348 00006211 7549                <1> 	jnz	short da_u_pt_3
  3349                              <1> 	; Read only -duplicated- page (belongs to a parent or a child)
  3350 00006213 66A90002            <1>         test    ax, PTE_DUPLICATED ; Was this page duplicated 
  3351                              <1> 				   ; as child's page ?
  3352 00006217 744E                <1> 	jz	short da_u_pt_4 ; Clear PTE but don't deallocate the page!
  3353                              <1> 	;
  3354                              <1> 	; check the parent's PTE value is read only & same page or not.. 
  3355                              <1> 	; EDX = page directory entry index (0-1023)
  3356 00006219 52                  <1> 	push	edx ; ****
  3357                              <1> 	; EDI = page table entry offset (0-4092)
  3358 0000621A 8B1D[BC030300]      <1> 	mov	ebx, [u.ppgdir] ; page directory of the parent process
  3359 00006220 66C1E202            <1> 	shl	dx, 2 ; *4 
  3360 00006224 01D3                <1> 	add	ebx, edx ; PDE address (for the parent)
  3361 00006226 8B13                <1> 	mov	edx, [ebx] ; page table address
  3362 00006228 F6C201              <1> 	test	dl, PDE_A_PRESENT ; present (valid) or not ?
  3363 0000622B 742E                <1> 	jz	short da_u_pt_2	; parent process does not use this page
  3364 0000622D 6681E200F0          <1> 	and	dx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
  3365                              <1> 	; EDI = page table entry offset (0-4092)
  3366 00006232 01D7                <1> 	add	edi, edx	; PTE address (for the parent)
  3367 00006234 8B1F                <1> 	mov	ebx, [edi]
  3368 00006236 F6C301              <1> 	test	bl, PTE_A_PRESENT ; present or not ?
  3369 00006239 7420                <1> 	jz	short da_u_pt_2	; parent process does not use this page
  3370 0000623B 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; Clear attribute bits 
  3371 0000623F 6681E300F0          <1> 	and	bx, PTE_A_CLEAR ; 0F000h ; Clear attribute bits
  3372 00006244 39D8                <1> 	cmp	eax, ebx	; parent's and child's pages are same ?
  3373 00006246 7513                <1> 	jne	short da_u_pt_2	; not same page
  3374                              <1> 				; deallocate the child's page
  3375 00006248 800F02              <1>         or      byte [edi], PTE_A_WRITE ; convert to writable page (parent)
  3376 0000624B 5A                  <1> 	pop	edx ; ****
  3377 0000624C EB19                <1> 	jmp	short da_u_pt_4
  3378                              <1> da_u_pt_1:
  3379 0000624E 09C0                <1> 	or	eax, eax	; swapped page ?
  3380 00006250 741C                <1> 	jz	short da_u_pt_5	; no
  3381                              <1> 				; yes
  3382 00006252 D1E8                <1> 	shr	eax, 1
  3383 00006254 E8D1F9FFFF          <1> 	call	unlink_swap_block ; Deallocate swapped page block
  3384                              <1> 				  ; on the swap disk (or in file)
  3385 00006259 EB13                <1> 	jmp	short da_u_pt_5
  3386                              <1> da_u_pt_2:
  3387 0000625B 5A                  <1> 	pop	edx ; ****
  3388                              <1> da_u_pt_3:
  3389 0000625C 66A90004            <1> 	test	ax, PTE_SHARED	; shared or direct memory access indicator
  3390 00006260 7505                <1> 	jnz	short da_u_pt_4	; AVL bit 1 = 1, do not deallocate this page!
  3391                              <1> 	;
  3392                              <1> 	;and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
  3393 00006262 E81CF5FFFF          <1> 	call	deallocate_page ; set the mem allocation bit of this page
  3394                              <1> da_u_pt_4:
  3395 00006267 C746FC00000000      <1> 	mov	dword [esi-4], 0 ; clear/reset PTE (child, dupl. as parent)
  3396                              <1> da_u_pt_5:
  3397                              <1> 	; 20/05/2017
  3398 0000626E 58                  <1> 	pop	eax ; *** PTE index (of page directory)
  3399 0000626F 49                  <1> 	dec	ecx ; remain page count
  3400 00006270 7426                <1> 	jz	short da_u_pd_4
  3401 00006272 40                  <1> 	inc	eax ; next PTE
  3402 00006273 6625FF03            <1> 	and	ax, PTE_MASK ; PTE entry index in the page table
  3403 00006277 50                  <1> 	push	eax ; *** (save again)
  3404                              <1> 	;mov	edi, eax
  3405                              <1> 	;and 	di, PTE_MASK
  3406                              <1> 	;cmp	edi, PAGE_SIZE / 4 ; 1024
  3407                              <1> 	;jnb	short da_u_pd_2
  3408 00006278 89C7                <1> 	mov	edi, eax
  3409 0000627A C1E702              <1> 	shl	edi, 2 ; convert index to dword offset
  3410                              <1> 	;test	ax, PTE_MASK ; 3FFh
  3411 0000627D 09C0                <1> 	or	eax, eax
  3412 0000627F 7589                <1> 	jnz	short da_u_pt_0 ; 1-1023
  3413                              <1> da_u_pd_2:
  3414 00006281 42                  <1> 	inc	edx
  3415                              <1> 	; 20/05/2017
  3416 00006282 6681E2FF03          <1> 	and	dx, PTE_MASK  ; 3FFh
  3417 00006287 740F                <1> 	jz	short da_u_pd_4  ; 0 (1024)
  3418                              <1> 	;cmp	edx, 1024
  3419                              <1> 	;jnb	short da_u_pd_4
  3420 00006289 89EE                <1> 	mov	esi, ebp ; 20/02/2017
  3421 0000628B E961FFFFFF          <1> 	jmp	da_u_pd_1
  3422                              <1> da_u_pd_3:
  3423                              <1> 	; 15/05/2017 (empty page directory entry)
  3424 00006290 81E900040000        <1> 	sub	ecx, 1024
  3425 00006296 77E9                <1> 	ja	short da_u_pd_2 ; 20/05/2017
  3426                              <1> da_u_pd_4:
  3427 00006298 58                  <1> 	pop	eax ; **
  3428 00006299 5B                  <1> 	pop	ebx ; *
  3429 0000629A C3                  <1> 	retn
  3430                              <1> 
  3431                              <1> da_u_pd_err:
  3432 0000629B 31C0                <1> 	xor	eax, eax
  3433 0000629D F9                  <1> 	stc	
  3434 0000629E C3                  <1> 	retn
  3435                              <1> 
  3436                              <1> allocate_user_pages:
  3437                              <1> 	; 20/05/2017
  3438                              <1> 	; 01/05/2017, 02/05/2017, 15/05/2017
  3439                              <1> 	; 04/03/2017
  3440                              <1> 	; 20/02/2017 (TRDOS 386 = TRDOS v2.0)
  3441                              <1> 	;
  3442                              <1> 	; Allocate physically contiguous user pages (memory block)
  3443                              <1> 	; (caller: 'sysalloc' system call)
  3444                              <1> 	;
  3445                              <1> 	; Note: This procedure does not alloc a page's itself
  3446                              <1> 	;	(page bit) on Memory Allocation Table.
  3447                              <1> 	;	(allocate_memory_block is needed before this proc)
  3448                              <1> 	;
  3449                              <1> 	; INPUT ->
  3450                              <1> 	;	EAX = PHYSICAL ADDRESS (beginning address)
  3451                              <1> 	;	EBX = VIRTUAL ADDRESS (beginning address)
  3452                              <1> 	;	ECX = byte count (>=4096)
  3453                              <1> 	;	[u.pgdir] = user's page directory
  3454                              <1> 	;	
  3455                              <1> 	;	Note: All addresses are (must be) already adjusted
  3456                              <1> 	;	to page	borders, otherwise, lower 12bits of addresses
  3457                              <1> 	;	and byte count would be truncated.
  3458                              <1> 	;
  3459                              <1> 	; OUTPUT ->
  3460                              <1> 	;	none
  3461                              <1> 	;
  3462                              <1> 	;	CF = 1 -> insufficient memory error
  3463                              <1> 	;
  3464                              <1> 	; Note: All pages will be allocated in physical page order 
  3465                              <1> 	;	from the beginning page address. 
  3466                              <1> 	;	* A new page table will be added to the page dir
  3467                              <1> 	;	  when the requested PDE is invalid.
  3468                              <1> 	;	* Those pages will not be added to swap queue
  3469                              <1> 	;	  because main purpose of this allocation is to
  3470                              <1> 	;	  set a direct memory access (DMA controller) buffer.
  3471                              <1> 	;	 (Swapping out a page in a DMA buffer would be wrong!)
  3472                              <1> 	;	* Previous content of page tables (PTEs) would be
  3473                              <1> 	;	  (should be) deallocated before entering this
  3474                              <1> 	;	  procedure. So, new page table entries (PTEs)
  3475                              <1> 	;	  directly will be written without checking
  3476                              <1> 	;	  their previous content.	
  3477                              <1> 	;	* Only solution to increase free memory by removing
  3478                              <1> 	;	  that non-swappable memory block is to terminate
  3479                              <1> 	;	  the process or to wait until the process will 
  3480                              <1> 	;	  deallocate that memory block as itself. ('sysdalloc')
  3481                              <1> 	;	  (No problem, if the process does not grab all of
  3482                              <1> 	;	  -very big amount of- free memory by using
  3483                              <1> 	;	  'sysalloc' system call!?)
  3484                              <1> 	;	  (Even if the process has grabbed all of free memory, 
  3485                              <1> 	;	  no problem if the process is not running in 
  3486                              <1> 	;	  multitasking mode. No problem in multitasking
  3487                              <1> 	;	  mode if there is not another process which is running
  3488                              <1> 	;	  or waiting or sleeping for an event as it's pages
  3489                              <1> 	;	  are swapped-out. But a new process can not start to
  3490                              <1> 	;	  run if all of free memory has beeen allocated 
  3491                              <1> 	;	  by running processes. Deallocation -'sysdalloc'- 
  3492                              <1> 	;	  or terminate a running process is needed 
  3493                              <1> 	;	  in order to run a new process.) 
  3494                              <1> 	;
  3495                              <1> 	; Modified Registers -> EAX, EDX, ESI, EDI, EBX, ECX, EBP
  3496                              <1> 	;
  3497                              <1> 
  3498                              <1> 	; 01/05/2017
  3499 0000629F 662500F0            <1> 	and	ax, ~PAGE_OFF
  3500 000062A3 6681E300F0          <1> 	and	bx, ~PAGE_OFF
  3501                              <1> 	; 02/05/2017 
  3502 000062A8 BD00F0FFFF          <1> 	mov	ebp, 0FFFFF000h ; 4 Giga Bytes - 4096 Bytes (for Stack)
  3503 000062AD C1E90C              <1> 	shr	ecx, PAGE_SHIFT ; page count
  3504 000062B0 83F901              <1> 	cmp	ecx, 1
  3505 000062B3 7251                <1> 	jb	short a_u_im_retn
  3506 000062B5 89C2                <1> 	mov	edx, eax
  3507 000062B7 01CA                <1> 	add	edx, ecx
  3508 000062B9 724B                <1> 	jc	short a_u_im_retn
  3509 000062BB 39D5                <1> 	cmp	ebp, edx
  3510 000062BD 7247                <1> 	jb	short a_u_im_retn
  3511 000062BF 89DA                <1> 	mov	edx, ebx
  3512 000062C1 81C200004000        <1> 	add	edx, CORE
  3513 000062C7 723D                <1> 	jc	short a_u_im_retn	
  3514 000062C9 01CA                <1> 	add	edx, ecx
  3515 000062CB 7239                <1> 	jc	short a_u_im_retn
  3516 000062CD 39D5                <1> 	cmp	ebp, edx
  3517 000062CF 7235                <1> 	jb	short a_u_im_retn
  3518                              <1> 	;
  3519 000062D1 89C5                <1> 	mov	ebp, eax ; physical address
  3520 000062D3 89DE                <1> 	mov	esi, ebx
  3521 000062D5 81C600004000        <1> 	add	esi, CORE ; start of user's memory (4M) 
  3522 000062DB C1EE0C              <1> 	shr	esi, PAGE_SHIFT ; higher 20 bits of the linear address
  3523                              <1> 	;shr	ecx, PAGE_SHIFT ; page count
  3524 000062DE 8B1D[B8030300]      <1> 	mov	ebx, [u.pgdir] ; physical addr of user's page dir
  3525 000062E4 89F7                <1> 	mov	edi, esi
  3526 000062E6 81E7FF030000        <1> 	and	edi, PTE_MASK ; PTE entry index in the page table
  3527 000062EC 57                  <1> 	push	edi  ; * ; PTE index (in page directory)
  3528 000062ED C1EE0A              <1> 	shr	esi, PAGE_D_SHIFT - PAGE_SHIFT ; 22-12=10
  3529 000062F0 89F2                <1> 	mov	edx, esi 
  3530                              <1> 	; EDX = PDE index
  3531 000062F2 C1E602              <1> 	shl	esi, 2 ; convert PDE index to dword offset
  3532 000062F5 01DE                <1> 	add	esi, ebx ; add page directory address
  3533                              <1> a_u_pd_0:
  3534 000062F7 AD                  <1> 	lodsd
  3535                              <1> 	;
  3536 000062F8 89F3                <1> 	mov	ebx, esi ; next PDE address
  3537                              <1> 	;
  3538 000062FA A801                <1> 	test	al, PDE_A_PRESENT ; bit 0, present flag (must be 1)
  3539 000062FC 7513                <1> 	jnz	short a_u_pd_2
  3540                              <1> 	;
  3541                              <1> 	; empty PDE (it does not point to valid page table address)
  3542 000062FE E8A2F2FFFF          <1> 	call	allocate_page  ; (allocate a new page table)
  3543 00006303 7302                <1> 	jnc	short a_u_pd_1 ; OK... now, we have a new page table.
  3544                              <1> 	; cf = 1
  3545                              <1> 	; There is not a free memory page to allocate a new page table !!!
  3546 00006305 5E                  <1> 	pop	esi ; *
  3547                              <1> a_u_im_retn:
  3548 00006306 C3                  <1> 	retn	; return to 'sysalloc' with 'insufficient memory' error
  3549                              <1> 	;
  3550                              <1> a_u_pd_1: ; clear the new page table content 
  3551                              <1> 	; EAX = Physical (base) address of the new page table
  3552 00006307 E813F3FFFF          <1> 	call	clear_page ; Clear page content
  3553                              <1> 	;
  3554 0000630C 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
  3555                              <1> 		 ; set bit 0, bit 1 and bit 2 to 1
  3556                              <1> 		 ; (present, writable, user)
  3557 0000630E 8946FC              <1> 	mov	[esi-4], eax
  3558                              <1> a_u_pd_2:
  3559 00006311 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
  3560                              <1> 	; EAX = PHYSICAL (flat) ADDRESS OF THE PAGE TABLE
  3561 00006315 8B3C24              <1> 	mov	edi, [esp] ; *
  3562                              <1> 	; EDI = PTE index (of page directory)
  3563                              <1> 	;and	edi, PTE_MASK ; PTE entry index in the page table	
  3564                              <1> 	; EBX = next PDE address
  3565 00006318 89FE                <1> 	mov	esi, edi ; PTE index in page table (0-1023)
  3566 0000631A C1E702              <1> 	shl	edi, 2 ; convert PTE index to dword offset
  3567 0000631D 01C7                <1> 	add	edi, eax ; now, edi points to requested PTE
  3568                              <1> a_u_pt_0:
  3569                              <1> 	; 02/05/2017
  3570 0000631F 8B07                <1> 	mov	eax, [edi]
  3571                              <1> 	;
  3572 00006321 A801                <1> 	test	al, PTE_A_PRESENT ; bit 0, present flag (must be 1)
  3573 00006323 7445                <1> 	jz	short a_u_pt_1
  3574                              <1> 	;
  3575 00006325 A802                <1> 	test	al, PTE_A_WRITE   ; bit 1, writable (r/w) flag
  3576                              <1> 				  ; (must be 1)
  3577 00006327 7550                <1> 	jnz	short a_u_pt_3
  3578                              <1> 	; Read only -duplicated- page (belongs to a parent or a child)
  3579 00006329 66A90002            <1>         test    ax, PTE_DUPLICATED ; Was this page duplicated 
  3580                              <1> 				   ; as child's page ?
  3581 0000632D 7455                <1> 	jz	short a_u_pt_4	; Clear PTE but don't deallocate the page!
  3582                              <1> 	;
  3583                              <1> 	; check the parent's PTE value is read only & same page or not.. 
  3584                              <1> 	; EDX = page directory entry index (0-1023)
  3585 0000632F 52                  <1> 	push	edx ; **
  3586 00006330 53                  <1> 	push	ebx ; ***
  3587                              <1> 	; ESI = page table entry index (0-1023)
  3588                              <1> 	;push	esi ; **** ; 20/05/2017
  3589 00006331 8B1D[BC030300]      <1> 	mov	ebx, [u.ppgdir] ; page directory of the parent process
  3590 00006337 66C1E202            <1> 	shl	dx, 2 ; *4 
  3591 0000633B 01D3                <1> 	add	ebx, edx ; PTE address,0 (for the parent)
  3592 0000633D 8B13                <1> 	mov	edx, [ebx] ; page table address
  3593 0000633F F6C201              <1> 	test	dl, PDE_A_PRESENT ; present (valid) or not ?
  3594 00006342 7433                <1> 	jz	short a_u_pt_2	; parent process does not use this page
  3595 00006344 6681E200F0          <1> 	and	dx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
  3596 00006349 66C1E602            <1> 	shl	si, 2 ; *4
  3597                              <1> 	; ESI = page table entry offset (0-4092)
  3598 0000634D 01D6                <1> 	add	esi, edx	; PTE address (for the parent)
  3599 0000634F 8B1E                <1> 	mov	ebx, [esi]
  3600 00006351 F6C301              <1> 	test	bl, PTE_A_PRESENT ; present or not ?
  3601 00006354 7421                <1> 	jz	short a_u_pt_2	; parent process does not use this page
  3602 00006356 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; Clear attribute bits 
  3603 0000635A 6681E300F0          <1> 	and	bx, PTE_A_CLEAR ; 0F000h ; Clear attribute bits
  3604 0000635F 39D8                <1> 	cmp	eax, ebx	; parent's and child's pages are same ?
  3605 00006361 7514                <1> 	jne	short a_u_pt_2	; not same page
  3606                              <1> 				; deallocate the child's page
  3607 00006363 800E02              <1>         or      byte [esi], PTE_A_WRITE ; convert to writable page (parent)
  3608                              <1> 	;pop	esi ; **** ; 20/05/2017
  3609 00006366 5B                  <1> 	pop	ebx ; ***
  3610 00006367 5A                  <1> 	pop	edx ; **
  3611 00006368 EB1A                <1> 	jmp	short a_u_pt_4
  3612                              <1> a_u_pt_1:
  3613 0000636A 09C0                <1> 	or	eax, eax	; swapped page ?
  3614 0000636C 7416                <1> 	jz	short a_u_pt_4	; no
  3615                              <1> 				; yes
  3616 0000636E D1E8                <1> 	shr	eax, 1
  3617 00006370 E8B5F8FFFF          <1> 	call	unlink_swap_block ; Deallocate swapped page block
  3618                              <1> 				  ; on the swap disk (or in file)
  3619 00006375 EB0D                <1> 	jmp	short a_u_pt_4
  3620                              <1> a_u_pt_2:
  3621                              <1> 	;pop	esi ; **** ; 20/05/2017
  3622 00006377 5B                  <1> 	pop	ebx ; ***
  3623 00006378 5A                  <1> 	pop	edx ; **
  3624                              <1> a_u_pt_3:
  3625 00006379 66A90004            <1> 	test	ax, PTE_SHARED	; shared or direct memory access indicator
  3626 0000637D 7505                <1> 	jnz	short a_u_pt_4	; AVL bit 1 = 1, do not deallocate this page!
  3627                              <1> 	;
  3628                              <1> 	;and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
  3629 0000637F E8FFF3FFFF          <1> 	call	deallocate_page ; set the mem allocation bit of this page
  3630                              <1> 	;
  3631                              <1> a_u_pt_4:
  3632 00006384 89E8                <1> 	mov	eax, ebp ; physical address
  3633 00006386 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER ; 04/03/2017
  3634 00006388 AB                  <1> 	stosd
  3635 00006389 5E                  <1> 	pop	esi ; * ; 20/05/2017
  3636 0000638A 49                  <1> 	dec	ecx ; remain page count
  3637 0000638B 7417                <1> 	jz	short a_u_pd_5
  3638 0000638D 81C500100000        <1> 	add	ebp, PAGE_SIZE
  3639 00006393 46                  <1> 	inc	esi ; next PTE (index)
  3640                              <1> 	; 20/05/2017
  3641                              <1> 	;cmp	esi, PAGE_SIZE/4 ; 1024
  3642                              <1> 	;jb	short a_u_pt_0
  3643 00006394 6681E6FF03          <1> 	and	si, PTE_MASK ; 3FFh (0 to 1023)
  3644 00006399 56                  <1> 	push	esi ; *
  3645 0000639A 7583                <1> 	jnz	short a_u_pt_0 ; > 0 (<1024)
  3646                              <1> a_u_pd_3:
  3647 0000639C 42                  <1> 	inc	edx
  3648                              <1> ;	cmp	edx, 1024
  3649                              <1> ;	jnb	short a_u_pd_4 ; 02/05/2017 (error!, ecx > 0)
  3650 0000639D 89DE                <1> 	mov	esi, ebx ; the next PDE address
  3651 0000639F E953FFFFFF          <1> 	jmp	a_u_pd_0
  3652                              <1> a_u_pd_4:
  3653                              <1> 	; 02/05/2017
  3654                              <1> ;	stc
  3655                              <1> a_u_pd_5:
  3656                              <1> 	; 20/05/2017
  3657                              <1> 	;pop	edi ; *
  3658 000063A4 C3                  <1> 	retn
  3659                              <1> 
  3660                              <1> allocate_lfb_pages_for_kernel:
  3661                              <1> 	; 15/12/2020
  3662                              <1> 	; 14/12/2020 - TRDOS 386 v2.0.3
  3663                              <1> 	; Set kernel page tables for linear frame buffer 
  3664                              <1> 	; (this procedure will be called by kernel only)
  3665                              <1> 	;
  3666                              <1> 	; Input:
  3667                              <1> 	;	[LFB_ADDR] = linear frame buffer base address
  3668                              <1>  	;	[LFB_SIZE] = linear frame buffer size in bytes
  3669                              <1> 	; Output:
  3670                              <1> 	;	none
  3671                              <1> 	;	cf = 1 -> error
  3672                              <1> 	;
  3673                              <1> 	; Modified registers: eax, ecx, edx, edi
  3674                              <1> 
  3675 000063A5 8B3D[AC110300]      <1> 	mov	edi, [LFB_ADDR]
  3676 000063AB 8B15[B0110300]      <1> 	mov	edx, [LFB_SIZE]
  3677                              <1> 
  3678 000063B1 C1EF16              <1> 	shr	edi, 22	; convert address to page number
  3679                              <1> 			; and then convert it to PDE entry offset
  3680                              <1> 			; (1 PDE is for 4MB, 22 bit shift)
  3681                              <1> 
  3682 000063B4 66C1E702            <1> 	shl	di, 2	; * 4 for offset 
  3683                              <1> 
  3684                              <1> 	;add	edx, 4095
  3685 000063B8 C1EA0C              <1> 	shr	edx, 12	; convert LFB size to LFB page count
  3686                              <1> 	
  3687 000063BB 89D1                <1> 	mov	ecx, edx ; * ; LFB page count
  3688                              <1> 
  3689 000063BD 81C1FF030000        <1> 	add	ecx, 1023 ; page count + 1023
  3690 000063C3 C1E90A              <1> 	shr	ecx, 10 ; convert to page directory entry count	
  3691                              <1> 			; (page table count)
  3692 000063C6 51                  <1> 	push	ecx ; **
  3693 000063C7 C1E10C              <1> 	shl	ecx, 12 ; convert to byte count
  3694                              <1> 
  3695 000063CA 31C0                <1> 	xor	eax, eax ; first available pages
  3696                              <1> 	
  3697                              <1> 	; allocate contiguous memory block for these kernel pages
  3698                              <1> 	
  3699 000063CC E87EFAFFFF          <1> 	call	allocate_memory_block
  3700                              <1> 	; eax = start address of (contiguous) memory block
  3701 000063D1 59                  <1> 	pop	ecx ; ** ; PDE count
  3702 000063D2 7301                <1> 	jnc	short a_lfb_k_1
  3703                              <1> 	; error (cf=1)
  3704 000063D4 C3                  <1> 	retn
  3705                              <1> a_lfb_k_1:
  3706                              <1> 	; Allocate (new) page tables in kernel's page directory
  3707 000063D5 51                  <1> 	push	ecx ; PDE (page table) count
  3708 000063D6 50                  <1> 	push	eax ; start address of contiguous memory pages
  3709                              <1> 		    ; (at page boundary)	
  3710                              <1> 	; edi = 1st page directory entry offset
  3711 000063D7 033D[D8630100]      <1> 	add	edi, [k_page_dir] ; Kernel's Page Dir Address
  3712                              <1> a_lfb_k_2:
  3713 000063DD 660D0304            <1> 	or	ax, PDE_A_PRESENT + PDE_A_WRITE + PDE_EXTERNAL
  3714                              <1> 				; supervisor + read&write + present 	
  3715                              <1> 				; + external memory block (LFB)
  3716 000063E1 AB                  <1> 	stosd
  3717 000063E2 0500100000          <1> 	add	eax, 4096
  3718 000063E7 E2F4                <1> 	loop	a_lfb_k_2
  3719                              <1> 	
  3720 000063E9 5F                  <1> 	pop	edi ; start addr of contiguous memory pages
  3721 000063EA 59                  <1> 	pop	ecx ; page table (PDE) count
  3722                              <1> 
  3723                              <1> 	; Allocate pages in (new) kernel page tables
  3724                              <1> 	
  3725                              <1> 	; (Note: page tables are contiguous in pyhsical memory)
  3726 000063EB C1E10A              <1> 	shl	ecx, 10 ; * 1024, convert to (total) PTE count 
  3727                              <1> 	
  3728 000063EE A1[AC110300]        <1> 	mov	eax, [LFB_ADDR]
  3729                              <1> 	; edx = LFB page count
  3730                              <1> 	;and	ax, ~4095  ; lw of LFB address is 0
  3731                              <1> a_lfb_k_3:	
  3732 000063F3 660D0304            <1> 	or	ax, PTE_A_PRESENT + PTE_A_WRITE + PTE_EXTERNAL
  3733                              <1> 				; supervisor + read&write + present 	
  3734                              <1> 				; + external memory block (LFB)
  3735 000063F7 AB                  <1> 	stosd
  3736 000063F8 4A                  <1> 	dec	edx
  3737 000063F9 7408                <1> 	jz	short a_lfb_k_4 ; LFB size has been completed (!?)
  3738 000063FB 0500100000          <1> 	add	eax, 4096	
  3739 00006400 E2F1                <1> 	loop	a_lfb_k_3
  3740                              <1> 
  3741 00006402 C3                  <1> 	retn
  3742                              <1> 	
  3743                              <1> a_lfb_k_4:
  3744                              <1> 	; clear PTEs for empty/free pages 
  3745                              <1> 	; 	(if there are after LFB !?)
  3746 00006403 31C0                <1> 	xor	eax, eax ; clear page table entry (empty)
  3747 00006405 F3AB                <1> 	rep	stosd
  3748 00006407 C3                  <1> 	retn
  3749                              <1> 
  3750                              <1> ;deallocate_lfb_pages_for_kernel:
  3751                              <1> 	; 15/12/2020
  3752                              <1> 	; 14/12/2020 - TRDOS 386 v2.0.3
  3753                              <1> 	; Reset/Release kernel page tables
  3754                              <1> 	;	 which are used for linear frame buffer 
  3755                              <1> 	; (this procedure will be called by kernel only)
  3756                              <1> 	;
  3757                              <1> 	; Input:
  3758                              <1> 	;	[LFB_ADDR] = linear frame buffer base address
  3759                              <1>  	;	[FFB_SIZE] = linear frame buffer size in bytes
  3760                              <1> 	; Output:
  3761                              <1> 	;	none
  3762                              <1> 	;
  3763                              <1> 	; Modified registers: eax, ecx, edi
  3764                              <1> 
  3765                              <1> 	;mov	edi, [LFB_ADDR]
  3766                              <1> 	;mov	ecx, [LFB_SIZE]
  3767                              <1> 	;
  3768                              <1> 	;shr	edi, 22	; convert address to page number
  3769                              <1> 	;		; and then convert it to PDE entry offset
  3770                              <1> 	;		; (1 PDE is for 4MB, 22 bit shift)
  3771                              <1> 	;
  3772                              <1> 	;shl	di, 2	; * 4 for offset 
  3773                              <1> 	;
  3774                              <1> 	;;add	ecx, 4095
  3775                              <1> 	;shr	ecx, 12	; convert LFB size to page count  
  3776                              <1> 	;
  3777                              <1> 	;add	ecx, 1023 ; page count + 1023
  3778                              <1> 	;shr	ecx, 10 ; convert to page directory entry count	
  3779                              <1> 	;		; (page table count)
  3780                              <1> 	;push	ecx ; *
  3781                              <1> 	;shl	ecx, 12 ; convert to byte count
  3782                              <1> 	;
  3783                              <1> 	;xor	eax, eax ; first available pages
  3784                              <1> 	;
  3785                              <1> 	;; deallocate contiguous memory block for kernel pages
  3786                              <1> 	;
  3787                              <1> 	;call	deallocate_memory_block
  3788                              <1> 	;
  3789                              <1> 	;pop	ecx ; * ; PDE count
  3790                              <1> 	;
  3791                              <1> 	;; Release/Free PDEs (page tables) in kernel's page dir
  3792                              <1> 	;; edi = 1st page directory entry offset
  3793                              <1> 	;add	edi, [k_page_dir] ; Kernel's Page Dir Address
  3794                              <1> 	;sub	eax, eax ; clear (also invalidate)
  3795                              <1> 	;rep	stosd
  3796                              <1> 	;
  3797                              <1> 	;retn
  3798                              <1> 
  3799                              <1> ; /// End Of MEMORY MANAGEMENT FUNCTIONS ///
  3800                              <1> 
  3801                              <1> ;; Data:
  3802                              <1> 
  3803                              <1> ; 09/03/2015
  3804                              <1> ;swpq_count: dw 0 ; count of pages on the swap que
  3805                              <1> ;swp_drv:    dd 0 ; logical drive description table address of the swap drive/disk
  3806                              <1> ;swpd_size:  dd 0 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
  3807                              <1> ;swpd_free:  dd 0 ; free page blocks (4096 bytes) on swap disk/drive (logical)
  3808                              <1> ;swpd_next:  dd 0 ; next free page block
  3809                              <1> ;swpd_last:  dd 0 ; last swap page block
  2839                                  %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: 15/01/2017
     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 00006408 9C                  <1> 	pushfd
    30 00006409 0E                  <1> 	push 	cs
    31 0000640A E801000000          <1> 	call 	TIME_OF_DAY_1
    32 0000640F 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> ; 15/01/2017
    98                              <1> ; 14/01/2017
    99                              <1> ; 07/01/2017
   100                              <1> ; 02/01/2017
   101                              <1> ; 29/05/2016
   102                              <1> ; 29/01/2016
   103                              <1> ; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
   104                              <1> 
   105                              <1> ; 29/05/2016
   106                              <1> ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   107                              <1> int35h:  ; Date/Time functions
   108                              <1> 
   109                              <1> TIME_OF_DAY_1:
   110                              <1> 	;sti				; INTERRUPTS BACK ON
   111                              <1> 	; 29/05/2016
   112 00006410 80642408FE          <1> 	and	byte [esp+8], 11111110b	; clear carry bit of eflags register
   113                              <1> 	;
   114 00006415 80FC08              <1> 	cmp	ah, (RTC_TBE-RTC_TB)/4	; CHECK IF COMMAND IN VALID RANGE (0-7)
   115 00006418 F5                  <1> 	cmc				; COMPLEMENT CARRY FOR ERROR EXIT
   116                              <1> 	; (*) jc short TIME_9		; EXIT WITH CARRY = 1 IF NOT VALID
   117 00006419 721A                <1> 	jc	short _TIME_9 ; 29/05/2016
   118                              <1> 
   119 0000641B 1E                  <1> 	push	ds
   120 0000641C 56                  <1> 	push	esi
   121 0000641D 66BE1000            <1> 	mov	si, KDATA		; kernel data segment
   122 00006421 8EDE                <1> 	mov	ds, si
   123                              <1> 
   124                              <1> 	;;15/01/2017
   125                              <1> 	; 14/01/2017
   126                              <1> 	; 02/01/2017
   127                              <1> 	;;mov	byte [intflg], 35h	; date & time interrupt 
   128                              <1> 	;sti
   129                              <1> 	;
   130 00006423 C0E402              <1> 	shl	ah, 2			; convert function to dword offset
   131 00006426 0FB6F4              <1> 	movzx	esi, ah			; PLACE INTO ADDRESSING REGISTER
   132                              <1> 	;cli				; NO INTERRUPTS DURING TIME FUNCTIONS
   133 00006429 FF96[3B640000]      <1> 	call	[esi+RTC_TB]		; VECTOR TO FUNCTION REQUESTED WITH CY=0
   134                              <1> 					; RETURN WITH CARRY FLAG SET FOR RESULT
   135                              <1> 	;sti				; INTERRUPTS BACK ON
   136 0000642F B400                <1> 	mov	ah, 0			; CLEAR (AH) TO ZERO
   137 00006431 5E                  <1> 	pop	esi			; RECOVER USERS REGISTER
   138 00006432 1F                  <1> 	pop	ds			; RECOVER USERS SEGMENT SELECTOR
   139                              <1> 
   140                              <1> 	;;15/01/2017
   141                              <1> 	; 02/01/2017
   142                              <1> 	;;mov	byte [ss:intflg], 0 ; 07/01/2017
   143                              <1> 
   144                              <1> ;TIME_9:
   145                              <1> 					; RETURN WITH CY= 0 IF NO ERROR
   146                              <1> 	; (*) 29/05/2016
   147                              <1> 	; (*) retf 4 ; skip eflags on stack
   148 00006433 7305                <1> 	jnc	short _TIME_10
   149                              <1> _TIME_9:
   150                              <1> 	; 29/05/2016 -set carry flag on stack-
   151                              <1> 	; [esp] = EIP
   152                              <1> 	; [esp+4] = CS
   153                              <1> 	; [esp+8] = E-FLAGS
   154 00006435 804C240801          <1> 	or	byte [esp+8], 1	 ; set carry bit of eflags register
   155                              <1> 	; [esp+12] = ESP (user)
   156                              <1> 	; [esp+16] = SS (User)
   157                              <1> _TIME_10:
   158 0000643A CF                  <1> 	iretd
   159                              <1> 	
   160                              <1> 	; (*) 29/05/2016 - 'ref 4' intruction causes to stack fault
   161                              <1> 	; (OUTER-PRIVILEGE-LEVEL)
   162                              <1> 	; INTEL 80386 PROGRAMMER'S REFERENCE MANUAL 1986
   163                              <1> 	; // RETF instruction:
   164                              <1> 	;
   165                              <1> 	; IF OperandMode=32 THEN
   166                              <1>  	;    Load CS:EIP from stack;
   167                              <1>  	;    Set CS RPL to CPL;
   168                              <1>  	;    Increment eSP by 8 plus the immediate offset if it exists;
   169                              <1>  	;    Load SS:eSP from stack;
   170                              <1>  	; ELSE (* OperandMode=16 *)
   171                              <1>  	;    Load CS:IP from stack;
   172                              <1>  	;    Set CS RPL to CPL;
   173                              <1>  	;    Increment eSP by 4 plus the immediate offset if it exists;
   174                              <1> 	;    Load SS:eSP from stack;
   175                              <1>  	; FI;
   176                              <1> 	;
   177                              <1> 	; //					
   178                              <1> 					; ROUTINE VECTOR TABLE (AH)=
   179                              <1> RTC_TB:
   180 0000643B [5B640000]          <1> 	dd	RTC_00			; 0 = READ CURRENT CLOCK COUNT
   181 0000643F [6E640000]          <1> 	dd	RTC_10			; 1 = SET CLOCK COUNT
   182 00006443 [7C640000]          <1> 	dd	RTC_20			; 2 = READ THE REAL TIME CLOCK TIME
   183 00006447 [AB640000]          <1> 	dd	RTC_30			; 3 = SET REAL TIME CLOCK TIME
   184 0000644B [ED640000]          <1> 	dd	RTC_40			; 4 = READ THE REAL TIME CLOCK DATE
   185 0000644F [1A650000]          <1> 	dd	RTC_50			; 5 = SET REAL TIME CLOCK DATE
   186 00006453 [67650000]          <1> 	dd	RTC_60			; 6 = SET THE REAL TIME CLOCK ALARM
   187 00006457 [BA650000]          <1> 	dd	RTC_70			; 7 = RESET ALARM
   188                              <1> 
   189                              <1> RTC_TBE	equ	$
   190                              <1> 
   191                              <1> RTC_00:				; READ TIME COUNT
   192 0000645B A0[5C640100]        <1> 	mov	al, [TIMER_OFL]		; GET THE OVERFLOW FLAG
   193 00006460 C605[5C640100]00    <1> 	mov	byte [TIMER_OFL], 0	; AND THEN RESET THE OVERFLOW FLAG
   194 00006467 8B0D[58640100]      <1>         mov     ecx, [TIMER_LH]         ; GET COUNT OF TIME
   195 0000646D C3                  <1> 	retn
   196                              <1> 
   197                              <1> RTC_10:				; SET TIME COUNT
   198 0000646E 890D[58640100]      <1>         mov     [TIMER_LH], ecx         ; SET TIME COUNT
   199 00006474 C605[5C640100]00    <1> 	mov	byte [TIMER_OFL], 0	; RESET OVERFLOW FLAG
   200 0000647B C3                  <1> 	retn				; RETURN WITH NO CARRY
   201                              <1> 
   202                              <1> RTC_20:				; GET RTC TIME
   203 0000647C E8EB010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   204 00006481 7227                <1> 	jc	short RTC_29		; EXIT IF ERROR (CY= 1)
   205                              <1> 
   206 00006483 B000                <1> 	mov	al, CMOS_SECONDS	; SET ADDRESS OF SECONDS
   207 00006485 E8FD010000          <1> 	call	CMOS_READ		; GET SECONDS
   208 0000648A 88C6                <1> 	mov	dh, al			; SAVE
   209 0000648C B00B                <1> 	mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   210 0000648E E8F4010000          <1> 	call	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
   211 00006493 2401                <1> 	and	al, 00000001b		; MASK FOR VALID DSE BIT
   212 00006495 88C2                <1> 	mov	dl, al			; SET [DL] TO ZERO FOR NO DSE BIT
   213 00006497 B002                <1> 	mov	al, CMOS_MINUTES	; SET ADDRESS OF MINUTES
   214 00006499 E8E9010000          <1> 	call	CMOS_READ		; GET MINUTES
   215 0000649E 88C1                <1> 	mov	cl, al			; SAVE
   216 000064A0 B004                <1>         mov     al, CMOS_HOURS          ; SET ADDRESS OF HOURS
   217 000064A2 E8E0010000          <1> 	call	CMOS_READ		; GET HOURS
   218 000064A7 88C5                <1> 	mov	ch, al			; SAVE
   219 000064A9 F8                  <1> 	clc				; SET CY= 0
   220                              <1> RTC_29:
   221 000064AA C3                  <1> 	retn				; RETURN WITH RESULT IN CARRY FLAG
   222                              <1> 
   223                              <1> RTC_30:				; SET RTC TIME
   224 000064AB E8BC010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   225 000064B0 7305                <1> 	jnc	short RTC_35		; GO AROUND IF CLOCK OPERATING
   226 000064B2 E817010000          <1> 	call	RTC_STA			; ELSE TRY INITIALIZING CLOCK
   227                              <1> RTC_35:
   228 000064B7 88F4                <1> 	mov	ah, dh			; GET TIME BYTE - SECONDS
   229 000064B9 B000                <1> 	mov	al, CMOS_SECONDS	; ADDRESS SECONDS
   230 000064BB E8E0010000          <1> 	call	CMOS_WRITE		; UPDATE SECONDS
   231 000064C0 88CC                <1> 	mov	ah, cl			; GET TIME BYTE - MINUTES
   232 000064C2 B002                <1> 	mov	al, CMOS_MINUTES	; ADDRESS MINUTES
   233 000064C4 E8D7010000          <1> 	call	CMOS_WRITE		; UPDATE MINUTES
   234 000064C9 88EC                <1> 	mov	ah, ch			; GET TIME BYTE - HOURS
   235 000064CB B004                <1> 	mov	al, CMOS_HOURS		; ADDRESS HOURS
   236 000064CD E8CE010000          <1> 	call	CMOS_WRITE		; UPDATE ADDRESS
   237                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   238                              <1> 	;mov	ah, al
   239 000064D2 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   240 000064D6 E8AC010000          <1> 	call	CMOS_READ		; READ CURRENT TIME
   241 000064DB 2462                <1> 	and	al, 01100010b		; MASK FOR VALID BIT POSITIONS
   242 000064DD 0C02                <1> 	or	al, 00000010b		; TURN ON 24 HOUR MODE
   243 000064DF 80E201              <1> 	and	dl, 00000001b		; USE ONLY THE DSE BIT
   244 000064E2 08D0                <1> 	or	al, dl			; GET DAY LIGHT SAVINGS TIME BIT (OSE)
   245 000064E4 86E0                <1> 	xchg	ah, al			; PLACE IN WORK REGISTER AND GET ADDRESS
   246 000064E6 E8B5010000          <1> 	call	CMOS_WRITE		; SET NEW ALARM SITS
   247 000064EB F8                  <1> 	clc				; SET CY= 0
   248 000064EC C3                  <1> 	retn				; RETURN WITH CY= 0
   249                              <1> 
   250                              <1> RTC_40:				; GET RTC DATE
   251 000064ED E87A010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   252 000064F2 7225                <1> 	jc	short RTC_49		; EXIT IF ERROR (CY= 1)
   253                              <1> 
   254 000064F4 B007                <1> 	mov	al, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH
   255 000064F6 E88C010000          <1> 	call	CMOS_READ		; READ DAY OF MONTH
   256 000064FB 88C2                <1> 	mov	dl, al			; SAVE
   257 000064FD B008                <1> 	mov	al, CMOS_MONTH		; ADDRESS MONTH
   258 000064FF E883010000          <1> 	call	CMOS_READ		; READ MONTH
   259 00006504 88C6                <1> 	mov	dh, al			; SAVE
   260 00006506 B009                <1> 	mov	al, CMOS_YEAR		; ADDRESS YEAR
   261 00006508 E87A010000          <1> 	call	CMOS_READ		; READ YEAR
   262 0000650D 88C1                <1> 	mov	cl, al			; SAVE
   263 0000650F B032                <1> 	mov	al, CMOS_CENTURY	; ADDRESS CENTURY LOCATION
   264 00006511 E871010000          <1> 	call	CMOS_READ		; GET CENTURY BYTE
   265 00006516 88C5                <1> 	mov	ch, al			; SAVE
   266 00006518 F8                  <1> 	clc				; SET CY=0
   267                              <1> RTC_49:
   268 00006519 C3                  <1> 	retn				; RETURN WITH RESULTS IN CARRY FLAG
   269                              <1> 
   270                              <1> RTC_50:				; SET RTC DATE
   271 0000651A E84D010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   272 0000651F 7305                <1> 	jnc	short RTC_55		; GO AROUND IF NO ERROR
   273 00006521 E8A8000000          <1> 	call	RTC_STA			; ELSE INITIALIZE CLOCK
   274                              <1> RTC_55:
   275 00006526 66B80600            <1> 	mov	ax, CMOS_DAY_WEEK	; ADDRESS OF DAY OF WEEK BYTE
   276 0000652A E871010000          <1> 	call	CMOS_WRITE		; LOAD ZEROS TO DAY OF WEEK
   277 0000652F 88D4                <1> 	mov	ah, dl			; GET DAY OF MONTH BYTE
   278 00006531 B007                <1> 	mov	al, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH BYTE
   279 00006533 E868010000          <1> 	call	CMOS_WRITE		; WRITE OF DAY OF MONTH REGISTER
   280 00006538 88F4                <1> 	mov	ah, dh			; GET MONTH
   281 0000653A B008                <1> 	mov	al, CMOS_MONTH		; ADDRESS MONTH BYTE
   282 0000653C E85F010000          <1> 	call	CMOS_WRITE		; WRITE MONTH REGISTER
   283 00006541 88CC                <1> 	mov	ah, cl			; GET YEAR BYTE
   284 00006543 B009                <1> 	mov	al, CMOS_YEAR		; ADDRESS YEAR REGISTER
   285 00006545 E856010000          <1> 	call	CMOS_WRITE		; WRITE YEAR REGISTER
   286 0000654A 88EC                <1> 	mov	ah, ch			; GET CENTURY BYTE
   287 0000654C B032                <1> 	mov	al, CMOS_CENTURY	; ADDRESS CENTURY BYTE
   288 0000654E E84D010000          <1> 	call	CMOS_WRITE		; WRITE CENTURY LOCATION
   289                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   290                              <1> 	;mov	ah, al
   291 00006553 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   292 00006557 E82B010000          <1> 	call	CMOS_READ		; READ WIRRENT SETTINGS
   293 0000655C 247F                <1> 	and	al, 07Fh		; CLEAR 'SET BIT'
   294 0000655E 86E0                <1> 	xchg	ah, al			; MOVE TO WORK REGISTER
   295 00006560 E83B010000          <1> 	call	CMOS_WRITE		; AND START CLOCK UPDATING
   296 00006565 F8                  <1> 	clc				; SET CY= 0
   297 00006566 C3                  <1> 	retn				; RETURN CY=0
   298                              <1> 
   299                              <1> RTC_60:				; SET RTC ALARM
   300 00006567 B00B                <1> 	mov	al, CMOS_REG_B		; ADDRESS ALARM
   301 00006569 E819010000          <1> 	call	CMOS_READ		; READ ALARM REGISTER
   302 0000656E A820                <1> 	test	al, 20h			; CHECK FOR ALARM ALREADY ENABLED
   303 00006570 F9                  <1> 	stc				; SET CARRY IN CASE OF ERROR
   304 00006571 7542                <1> 	jnz	short RTC_69		; ERROR EXIT IF ALARM SET
   305 00006573 E8F4000000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   306 00006578 7305                <1> 	jnc	short RTC_65		; SKIP INITIALIZATION IF NO ERROR
   307 0000657A E84F000000          <1> 	call	RTC_STA			; ELSE INITIALIZE CLOCK
   308                              <1> RTC_65:	
   309 0000657F 88F4                <1> 	mov	ah, dh			; GET SECONDS BYTE
   310 00006581 B001                <1> 	mov	al, CMOS_SEC_ALARM	; ADDRESS THE SECONDS ALARM REGISTER
   311 00006583 E818010000          <1> 	call	CMOS_WRITE		; INSERT SECONDS
   312 00006588 88CC                <1> 	mov	ah, cl			; GET MINUTES PARAMETER
   313 0000658A B003                <1> 	mov	al, CMOS_MIN_ALARM	; ADDRESS MINUTES ALARM REGISTER
   314 0000658C E80F010000          <1> 	call	CMOS_WRITE		; INSERT MINUTES
   315 00006591 88EC                <1> 	mov	ah, ch			; GET HOURS PARAMETER
   316 00006593 B005                <1> 	mov	al, CMOS_HR_ALARM	; ADDRESS HOUR ALARM REGISTER
   317 00006595 E806010000          <1> 	call	CMOS_WRITE		; INSERT HOURS
   318 0000659A E4A1                <1> 	in	al, INTB01		; READ SECOND INTERRUPT MASK REGISTER
   319 0000659C 24FE                <1> 	and	al, 0FEh		; ENABLE ALARM TIMER BIT (CY= 0)
   320 0000659E E6A1                <1> 	out	INTB01, al		; WRITE UPDATED MASK
   321                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   322                              <1> 	;mov	ah, al
   323 000065A0 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   324 000065A4 E8DE000000          <1> 	call	CMOS_READ		; READ CURRENT ALARM REGISTER
   325 000065A9 247F                <1> 	and	al, 07Fh		; ENSURE SET BIT TURNED OFF
   326 000065AB 0C20                <1> 	or	al, 20h			; TURN ON ALARM ENABLE
   327 000065AD 86E0                <1> 	xchg	ah, al			; MOVE MASK TO OUTPUT REGISTER
   328 000065AF E8EC000000          <1> 	call	CMOS_WRITE		; WRITE NEW ALARM MASK
   329 000065B4 F8                  <1> 	clc				; SET CY= 0
   330                              <1> RTC_69:
   331 000065B5 66B80000            <1> 	mov	ax, 0			; CLEAR AX REGISTER
   332 000065B9 C3                  <1> 	retn				; RETURN WITH RESULTS IN CARRY FLAC
   333                              <1> 
   334                              <1> RTC_70:				; RESET ALARM
   335                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   336                              <1> 	;mov	ah, al
   337 000065BA 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257	; ADDRESS ALARM REGISTER (TO BOTH AH,AL)
   338 000065BE E8C4000000          <1> 	call	CMOS_READ		; READ ALARM REGISTER
   339 000065C3 2457                <1> 	and	al, 57h			; TURN OFF ALARM ENABLE
   340 000065C5 86E0                <1> 	xchg	ah, al			; SAVE DATA AND RECOVER ADDRESS
   341 000065C7 E8D4000000          <1> 	call	CMOS_WRITE		; RESTORE NEW VALUE
   342 000065CC F8                  <1> 	clc				; SET CY= 0
   343 000065CD C3                  <1> 	retn				; RETURN WITH NO CARRY
   344                              <1> 
   345                              <1> RTC_STA:			; INITIALIZE REAL TIME CLOCK
   346                              <1> 	;mov	al, CMOS_REG_A		; ADDRESS REGISTER A AND LOAD DATA MASK		
   347                              <1> 	;mov	ah, 26h
   348 000065CE 66B80A26            <1> 	mov	ax, (26h*100h)+CMOS_REG_A
   349 000065D2 E8C9000000          <1> 	call	CMOS_WRITE		; INITIALIZE STATUS REGISTER A
   350                              <1> 	;mov	al, CMOS_REG_B		; SET "SET BIT" FOR CLOCK INITIALIZATION	
   351                              <1> 	;mov	ah, 82h
   352 000065D7 66B80B82            <1> 	mov	ax, (82h*100h)+CMOS_REG_B
   353 000065DB E8C0000000          <1> 	call	CMOS_WRITE		; AND 24 HOUR MODE TO REGISTER B
   354 000065E0 B00C                <1> 	mov	al, CMOS_REG_C		; ADDRESS REGISTER C
   355 000065E2 E8A0000000          <1> 	call	CMOS_READ		; READ REGISTER C TO INITIALIZE
   356 000065E7 B00D                <1> 	mov	al, CMOS_REG_D		; ADDRESS REGISTER D
   357 000065E9 E899000000          <1> 	call	CMOS_READ		; READ REGISTER D TO INITIALIZE
   358 000065EE C3                  <1> 	retn
   359                              <1> 
   360                              <1> ; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
   361                              <1> 
   362                              <1> ;--- HARDWARE INT  70 H -- ( IRQ LEVEL  8) --------------------------------------
   363                              <1> ; ALARM INTERRUPT HANDLER (RTC)							:
   364                              <1> ;       THIS ROUTINE HANDLES THE PERIODIC AND ALARM INTERRUPTS FROM THE CMOS	:
   365                              <1> ;       TIMER. INPUT FREQUENCY IS 1.024 KHZ OR APPROXIMATELY 1024 INTERRUPTS	:
   366                              <1> ;       EVERY SECOND FOR THE PERIODIC INTERRUPT. FOR THE ALARM FUNCTION,	:
   367                              <1> ;       THE INTERRUPT WILL OCCUR AT THE DESIGNATED TIME.			:
   368                              <1> ;										:
   369                              <1> ;       INTERRUPTS ARE ENABLED WHEN THE EVENT OR ALARM FUNCTION IS ACTIVATED.	:
   370                              <1> ;       FOR THE EVENT INTERRUPT, THE HANDLER WILL DECREMENT THE WAIT COUNTER	:
   371                              <1> ;       AND WHEN IT EXPIRES WILL SET THE DESIGNATED LOCATION TO 80H. FOR	:
   372                              <1> ;       THE ALARM INTERRUPT. THE USER MUST PROVIDE A ROUTINE TO INTERCEPT	:
   373                              <1> ;       THE CORRECT ADDRESS FROM THE VECTOR TABLE INVOKED BY INTERRUPT 4AH	:
   374                              <1> ;       PRIOR TO SETTING THE REAL TIME CLOCK ALARM (INT 1AH, AH= 06H).		:
   375                              <1> ;--------------------------------------------------------------------------------
   376                              <1> 
   377                              <1> RTC_A_INT: ; 07/01/2017
   378                              <1> ;RTC_INT:				; ALARM INTERRUPT
   379 000065EF 1E                  <1> 	push	ds			; LEAVE INTERRUPTS DISABLED
   380 000065F0 50                  <1> 	push	eax			; SAVE REGISTERS
   381 000065F1 57                  <1> 	push	edi
   382                              <1> RTC_I_1:				; CHECK FOR SECOND INTERRUPT
   383 000065F2 66B88C8B            <1> 	mov	ax, 256*(CMOS_REG_B+NMI)+CMOS_REG_C+NMI ; ALARM AND STATUS
   384 000065F6 E670                <1> 	out	CMOS_PORT, al		; WRITE ALARM FLAG MASK ADDRESS
   385 000065F8 90                  <1> 	nop				; I/O DELAY
   386 000065F9 EB00                <1> 	jmp	short $+2
   387 000065FB E471                <1> 	in	al, CMOS_DATA		; READ AND RESET INTERRUPT REQUEST FLAGS
   388 000065FD A860                <1> 	test	al, 01100000b		; CHECK FOR EITHER INTERRUPT PENDING
   389 000065FF 745D                <1> 	jz	short	RTC_I_9		; EXIT IF NOT A VALID RTC INTERRUPT
   390                              <1> 
   391 00006601 86E0                <1> 	xchg	ah, al			; SAVE FLAGS AND GET ENABLE ADDRESS
   392 00006603 E670                <1> 	out	CMOS_PORT, al		; WRITE ALARM ENABLE MASK ADDRESS
   393 00006605 90                  <1> 	nop				; I/O DELAY
   394 00006606 EB00                <1> 	jmp	short $+2	
   395 00006608 E471                <1> 	in	al, CMOS_DATA		; READ CURRENT ALARM ENABLE MASK
   396 0000660A 20E0                <1> 	and	al, ah			; ALLOW ONLY SOURCES THAT ARE ENABLED
   397 0000660C A840                <1> 	test	al, 01000000b		; CHECK FOR PERIODIC INTERRUPT
   398 0000660E 743B                <1> 	jz	short RTC_I_5		; SKIP IF NOT A PERIODIC INTERRUPT
   399                              <1> 
   400                              <1> ;-----	DECREMENT WAIT COUNT BY INTERRUPT INTERVAL
   401                              <1> 
   402 00006610 66BF1000            <1> 	mov	di, KDATA		; kernel data segment
   403 00006614 8EDF                <1> 	mov	ds, di
   404                              <1> 	
   405 00006616 812D[50640100]D003- <1> 	sub	dword [RTC_LH], 976	; DECREMENT COUNT BY 1/1024
   405 0000661E 0000                <1>
   406 00006620 7329                <1> 	jnc	short RTC_I_5		; SKIP TILL 32 BIT WORD LESS THAN ZERO
   407                              <1> 
   408                              <1> ;-----	TURN OFF PERIODIC INTERRUPT ENABLE
   409                              <1> 
   410 00006622 6650                <1> 	push	ax			; SAVE INTERRUPT FLAG MASK
   411 00006624 66B88B8B            <1> 	mov	ax, 257*(CMOS_REG_B+NMI) ; INTERRUPT ENABLE REGISTER
   412 00006628 E670                <1> 	out	CMOS_PORT, al		; WRITE ADDRESS TO CMOS CLOCK
   413 0000662A 90                  <1> 	nop				; I/O DELAY
   414 0000662B EB00                <1> 	jmp	short $+2
   415 0000662D E471                <1> 	in	al, CMOS_DATA		; READ CURRENT ENABLES
   416 0000662F 24BF                <1> 	and	al, 0BFh		; TURN OFF PIE
   417 00006631 86C4                <1> 	xchg	al, ah			; GET CMOS ADDRESS AND SAVE VALUE
   418 00006633 E670                <1> 	out	CMOS_PORT, al		; ADDRESS REGISTER B
   419 00006635 86C4                <1> 	xchg	al, ah			; GET NEW INTERRUPT ENABLE MASK
   420 00006637 E671                <1> 	out	CMOS_DATA, al		; SET MASK IN INTERRUPT ENABLE REGISTER
   421 00006639 C605[54640100]00    <1> 	mov	byte [RTC_WAIT_FLAG], 0	; SET FUNCTION ACTIVE FLAG OFF
   422 00006640 8B3D[55640100]      <1> 	mov	edi, [USER_FLAG]	; SET UP (DS:DI) TO POINT TO USER FLAG
   423 00006646 C60780              <1> 	mov	byte [edi], 80h		; TURN ON USERS FLAG
   424 00006649 6658                <1> 	pop	ax			; GET INTERRUPT SOURCE BACK
   425                              <1> RTC_I_5:
   426 0000664B A820                <1> 	test	al, 00100000b		; TEST FOR ALARM INTERRUPT
   427 0000664D 740D                <1> 	jz	short RTC_I_7		; SKIP USER INTERRUPT CALL IF NOT ALARM
   428                              <1> 
   429 0000664F B00D                <1> 	mov	al, CMOS_REG_D		; POINT TO DEFAULT READ ONLY REGISTER
   430 00006651 E670                <1> 	out	CMOS_PORT, al		; ENABLE NMI AND CMOS ADDRESS TO DEFAULT
   431 00006653 FB                  <1> 	sti				; INTERRUPTS BACK ON NOW
   432 00006654 52                  <1> 	push	edx
   433 00006655 E8939E0000          <1> 	call	INT4Ah			; TRANSFER TO USER ROUTINE
   434 0000665A 5A                  <1> 	pop	edx
   435 0000665B FA                  <1> 	cli				; BLOCK INTERRUPT FOR RETRY
   436                              <1> RTC_I_7:				; RESTART ROUTINE TO HANDLE DELAYED
   437 0000665C EB94                <1> 	jmp	short RTC_I_1		;  ENTRY AND SECOND EVENT BEFORE DONE
   438                              <1> 
   439                              <1> RTC_I_9:				; EXIT - NO PENDING INTERRUPTS
   440 0000665E B00D                <1> 	mov	al, CMOS_REG_D		; POINT TO DEFAULT READ ONLY REGISTER
   441 00006660 E670                <1> 	out	CMOS_PORT, al		; ENABLE NMI AND CMOS ADDRESS TO DEFAULT
   442 00006662 B020                <1> 	mov	al, EOI			; END OF INTERRUPT MASK TO 8259 - 2
   443 00006664 E6A0                <1> 	out	INTB00, al		; TO 8259 - 2
   444 00006666 E620                <1> 	out	INTA00,	al		; TO 8259 - 1
   445 00006668 5F                  <1> 	pop	edi			; RESTORE REGISTERS
   446 00006669 58                  <1> 	pop	eax
   447 0000666A 1F                  <1> 	pop	ds
   448 0000666B CF                  <1> 	iretd				; END OF INTERRUPT
   449                              <1> 
   450                              <1> 	
   451                              <1> 	; 29/05/2016 - TRDOS 386 (TRDOS v2.0)
   452                              <1> 	; 22/08/2014 (Retro UNIX 386 v1)
   453                              <1> 	; IBM PC/AT BIOS source code ----- 10/06/85 (bios2.asm)
   454                              <1> UPD_IPR:				; WAIT TILL UPDATE NOT IN PROGRESS
   455 0000666C 51                  <1> 	push	ecx
   456                              <1> 
   457                              <1> 	; 29/05/2016
   458 0000666D B968110000          <1> 	mov	ecx, ((1984+244)*4)/2	; AWARD BIOS 1999, ATIME.ASM		
   459                              <1> 					; 'WAITCPU_CK_UD_STAT'
   460                              <1> 					; (244Us + 1984Us)
   461                              <1> 					; (assume each read takes
   462                              <1> 					;  2 microseconds).
   463                              <1> 	;mov	ecx, 65535		
   464                              <1> 		;mov cx, 800		; SET TIMEOUT LOOP COUNT (= 800)	
   465                              <1> UPD_10:
   466 00006672 B00A                <1> 	mov	al, CMOS_REG_A		; ADDRESS STATUS REGISTER A
   467 00006674 FA                  <1> 	cli				; NO TIMER INTERRUPTS DURING UPDATES
   468 00006675 E80D000000          <1> 	call	CMOS_READ		; READ UPDATE IN PROCESS FLAG
   469 0000667A A880                <1> 	test	al, 80h			; IF UIP BIT IS ON ( CANNOT READ TIME )
   470 0000667C 7406                <1> 	jz	short UPD_90		; EXIT WITH CY= 0 IF CAN READ CLOCK NOW
   471 0000667E FB                  <1> 	sti				; ALLOW INTERRUPTS WHILE WAITING
   472 0000667F E2F1                <1> 	loop	UPD_10			; LOOP TILL READY OR TIMEOUT
   473 00006681 31C0                <1> 	xor	eax, eax		; CLEAR RESULTS IF ERROR
   474                              <1> 		; xor ax, ax
   475 00006683 F9                  <1> 	stc				; SET CARRY FOR ERROR
   476                              <1> UPD_90:
   477 00006684 59                  <1> 	pop	ecx			; RESTORE CALLERS REGISTER
   478 00006685 FA                  <1> 	cli				; INTERRUPTS OFF DURING SET
   479 00006686 C3                  <1> 	retn				; RETURN WITH CY FLAG SET
   480                              <1> 
   481                              <1> 
   482                              <1> 	; 29/05/2016 - TRDOS 386 (TRDOS v2.0) 
   483                              <1> 	; 22/08/2014 (Retro UNIX 386 v1)
   484                              <1> 	; IBM PC/AT BIOS source code ----- 10/06/85 (test4.asm)
   485                              <1> 
   486                              <1> ;--- CMOS_READ -----------------------------------------------------------------
   487                              <1> ;		READ BYTE FROM CMOS_SYSTEM CLOCK CONFIGURATION TABLE	       :
   488                              <1> ;									       :
   489                              <1> ; INPUT: (AL)=	CMOS_TABLE ADDRESS TO BE READ				       :
   490                              <1> ;		BIT    7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT    :
   491                              <1> ;		BITS 6-0 = ADDRESS OF TABLE LOCATION TO READ		       :
   492                              <1> ;									       :
   493                              <1> ; OUTPUT: (AL)	VALUE AT LOCATION (AL) MOVED INTO (AL). IF BIT 7 OF (AL) WAS   :
   494                              <1> ;		ON THEN NMI LEFT DISABLED, DURING THE CMOS READ BOTH NMI AND   :
   495                              <1> ;		NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. :
   496                              <1> ;		THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND    :
   497                              <1> ;		THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN.      :
   498                              <1> ;		ONLY THE (AL) REGISTER AND THE NMI STATE IS CHANGED.	       :
   499                              <1> ;-------------------------------------------------------------------------------
   500                              <1> 
   501                              <1> CMOS_READ:
   502 00006687 9C                  <1> 	pushf				; SAVE INTERRUPT ENABLE STATUS AND FLAGS
   503 00006688 D0C0                <1> 	rol	al, 1			; MOVE NMI BIT TO LOW POSITION
   504 0000668A F9                  <1> 	stc				; FORCE NMI BIT ON IN CARRY FLAG
   505 0000668B D0D8                <1> 	rcr	al, 1			; HIGH BIT ON TO DISABLE NMI - OLD IN CY
   506 0000668D FA                  <1> 	cli				; DISABLE INTERRUPTS
   507 0000668E E670                <1> 	out	CMOS_PORT, al		; ADDRESS LOCATION AND DISABLE NMI
   508                              <1> 	; 29/05/2016
   509                              <1> 	;nop				; I/O DELAY
   510 00006690 E6EB                <1> 	out	0ebh,al	; NEWIODELAY ; AWARD BIOS 1999, ATIME.ASM
   511                              <1> 	;
   512 00006692 E471                <1> 	in	al, CMOS_DATA		; READ THE REQUESTED CMOS LOCATION
   513 00006694 6650                <1> 	push	ax			; SAVE (AH) REGISTER VALUE AND CMOS BYTE
   514                              <1> 	; 15/03/2015 ; IBM PC/XT Model 286 BIOS source code 
   515                              <1> 		     ; ----- 10/06/85 (test4.asm)
   516 00006696 B01E                <1> 	mov	al, CMOS_SHUT_DOWN*2 	; GET ADDRESS OF DEFAULT LOCATION
   517                              <1> 	;mov	al, CMOS_REG_D*2 	; GET ADDRESS OF DEFAULT LOCATION
   518 00006698 D0D8                <1> 	rcr	al, 1			; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
   519 0000669A E670                <1> 	out	CMOS_PORT, al		; SET DEFAULT TO READ ONLY REGISTER
   520 0000669C 6658                <1> 	pop	ax			; RESTORE (AH) AND (AL), CMOS BYTE
   521 0000669E 9D                  <1> 	popf	
   522 0000669F C3                  <1> 	retn				; RETURN WITH FLAGS RESTORED
   523                              <1> 
   524                              <1> ; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
   525                              <1> 
   526                              <1> ;--- CMOS_WRITE ----------------------------------------------------------------
   527                              <1> ;	WRITE BYTE TO CMOS SYSTEM CLOCK CONFIGURATION TABLE		       :
   528                              <1> ;									       :
   529                              <1> ; INPUT: (AL)=	CMOS TABLE ADDRESS TO BE WRITTEN TO			       :
   530                              <1> ;		BIT    7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT    :
   531                              <1> ;		BITS 6-0 = ADDRESS OF TABLE LOCATION TO WRITE		       :
   532                              <1> ;	 (AH)=	NEW VALUE TO BE PLACED IN THE ADDRESSED TABLE LOCATION	       :
   533                              <1> ;									       :
   534                              <1> ; OUTPUT:	VALUE IN (AH) PLACED IN LOCATION (AL) WITH NMI LEFT DISABLED   :
   535                              <1> ;		IF BIT 7 OF (AL) IS ON, DURING THE CMOS UPDATE BOTH NMI AND    :
   536                              <1> ;		NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. :
   537                              <1> ;		THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND    :
   538                              <1> ;		THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN.      :
   539                              <1> ;		ONLY THE CMOS LOCATION AND THE NMI STATE IS CHANGED.	       :
   540                              <1> ;-------------------------------------------------------------------------------
   541                              <1> 
   542                              <1> CMOS_WRITE:				; WRITE (AH) TO LOCATION (AL)
   543 000066A0 9C                  <1> 	pushf				; SAVE INTERRUPT ENABLE STATUS AND FLAGS
   544 000066A1 6650                <1> 	push	ax			; SAVE WORK REGISTER VALUES
   545 000066A3 D0C0                <1> 	rol	al, 1			; MOVE NMI BIT TO LOW POSITION
   546 000066A5 F9                  <1> 	stc				; FORCE NMI BIT ON IN CARRY FLAG
   547 000066A6 D0D8                <1> 	rcr	al, 1			; HIGH BIT ON TO DISABLE NMI - OLD IN CY
   548 000066A8 FA                  <1> 	cli				; DISABLE INTERRUPTS
   549 000066A9 E670                <1> 	out	CMOS_PORT, al		; ADDRESS LOCATION AND DISABLE NMI
   550 000066AB 88E0                <1> 	mov	al, ah			; GET THE DATA BYTE TO WRITE
   551 000066AD E671                <1> 	out	CMOS_DATA, al		; PLACE IN REQUESTED CMOS LOCATION
   552 000066AF B01E                <1> 	mov	al, CMOS_SHUT_DOWN*2	; GET ADDRESS OF DEFAULT LOCATION
   553                              <1> 	;mov	al, CMOS_REG_D*2 	; GET ADDRESS OF DEFAULT LOCATION
   554 000066B1 D0D8                <1> 	rcr	al, 1			; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
   555 000066B3 E670                <1> 	out	CMOS_PORT, al		; SET DEFAULT TO READ ONLY REGISTER
   556 000066B5 90                  <1> 	nop				; I/O DELAY
   557 000066B6 E471                <1> 	in	al, CMOS_DATA		; OPEN STANDBY LATCH
   558 000066B8 6658                <1> 	pop	ax			; RESTORE WORK REGISTERS
   559 000066BA 9D                  <1> 	popf
   560 000066BB C3                  <1> 	retn
   561                              <1> 
   562                              <1> ; /// End Of TIMER FUNCTIONS ///
  2840                                  
  2841 000066BC 90<rept>                Align 16
  2842                                  
  2843                                  gdt:	; Global Descriptor Table
  2844                                  	; 02/12/2020
  2845                                  	; (30/07/2015, conforming cs)
  2846                                  	; (26/03/2015)
  2847                                  	; (24/03/2015, tss)
  2848                                  	; (19/03/2015)
  2849                                  	; (29/12/2013)
  2850                                  	;
  2851 000066C0 0000000000000000        	dw 0, 0, 0, 0		; NULL descriptor
  2852                                  gdt_kcode:
  2853                                  	; 18/08/2014
  2854                                  			; 8h kernel code segment, base = 00000000h		
  2855                                  	;dw 0FFFFh, 0, 9E00h, 00CFh	; KCODE  ; 30/12/2016	 
  2856 000066C8 FFFF0000009ACF00        	dw 0FFFFh, 0, 9A00h, 00CFh	; KCODE
  2857                                  gdt_kdata:
  2858                                  			; 10h kernel data segment, base = 00000000h	
  2859 000066D0 FFFF00000092CF00        	dw 0FFFFh, 0, 9200h, 00CFh	; KDATA
  2860                                  gdt_ucode:
  2861                                  			; 1Bh user code segment, base address = 400000h ; CORE
  2862                                  	;dw 0FBFFh, 0, 0FE40h, 00CFh	; UCODE  ; 30/12/2016	
  2863 000066D8 FFFB000040FACF00        	dw 0FBFFh, 0, 0FA40h, 00CFh	; UCODE
  2864                                  gdt_udata: 
  2865                                  			; 23h user data segment, base address = 400000h ; CORE
  2866 000066E0 FFFB000040F2CF00        	dw 0FBFFh, 0, 0F240h, 00CFh	; UDATA
  2867                                  gdt_tss:
  2868                                  			; Task State Segment
  2869 000066E8 6700                    	dw 0067h ; Limit = 103 ; (104-1, tss size = 104 byte, 
  2870                                  			       ;  no IO permission in ring 3)
  2871                                  gdt_tss0:
  2872 000066EA 0000                    	dw 0  ; TSS base address, bits 0-15 
  2873                                  gdt_tss1:
  2874 000066EC 00                      	db 0  ; TSS base address, bits 16-23 
  2875                                  	      		; 49h	
  2876 000066ED E9                      	db 11101001b ; 0E9h => P=1/DPL=11/0/1/0/B/1 --> B = Task is busy (1)
  2877 000066EE 00                      	db 0 ; G/0/0/AVL/LIMIT=0000 ; (Limit bits 16-19 = 0000) (G=0, 1 byte)
  2878                                  gdt_tss2:
  2879 000066EF 00                      	db 0  ; TSS base address, bits 24-31 
  2880                                  
  2881                                  	; 30/11/2020
  2882                                  	; 29/11/2020 - TRDOS v2.0.3
  2883                                  	; VESA VBE3 VIDE BIOS 32 BIT PMI SEGMENTS (16 bit segments)
  2884                                  			; 30h ; VBE3CS
  2885                                  _vbe3_CS:  ; vesa vbe3 bios uses this as code seg (same addr with _vbe3_DS)
  2886                                  	; limit = 65536, base addr = 0, P/DPL/1/Type/C/R/A = 9Ah, 16 bit
  2887 000066F0 FFFF0000009A0000        	dw 0FFFFh, 0, 9A00h, 0 ; Note: base addr will be initialized
  2888                                  			; 38h ; VBE3BDS
  2889                                  _vbe3_BDS: ; vesa vbe3 bios uses this as equivalent of rombios data segment
  2890                                  	; limit = 1536, base addr = 0, P/DPL/1/Type/E/W/A = 92h, 16 bit
  2891 000066F8 FF05000000920000        	dw 05FFh, 0, 9200h, 0 ; Note: base addr will be initialized	
  2892                                  			; 40h ; VBE3A000 
  2893                                  _A0000Sel: ; VGA default video memory address
  2894                                  	; limit = 65536, base addr = 0A0000h, 16 bit
  2895 00006700 FFFF00000A920000        	dw 0FFFFh, 0, 920Ah, 0
  2896                                  			; 48h ; VBE3B000 
  2897                                  _B0000Sel: ; MDA (monochrome) video memory address
  2898                                  	; limit = 65536, base addr = 0B0000h, 16 bit
  2899 00006708 FFFF00000B920000        	dw 0FFFFh, 0, 920Bh, 0
  2900                                  			; 50h ; VBE3B800 
  2901                                  _B8000Sel: ; CGA video memory address
  2902                                  	; limit = 32768, base addr = 0B8000h, 16 bit
  2903 00006710 FF7F00800B920000        	dw 07FFFh, 8000h, 920Bh, 0
  2904                                  			; 58h ; VBE3DS 
  2905                                  _vbe3_DS: ; vesa vbe3 bios uses this as data seg (CodeSegSel in PMInfoBlock)
  2906                                  	; limit = 65536, base addr = 0, P/DPL/1/Type/E/W/A = 92h, 16 bit
  2907 00006718 FFFF000000920000        	dw 0FFFFh, 0, 9200h, 0 ; Note: base addr will be initialized
  2908                                  			; 60h ; VBE3SS   
  2909                                  _vbe3_SS: ; kernel's stack segment but 16 bit version (same stack addr)
  2910                                  	; limit = 1024, base addr = 0, P/DPL/1/Type/E/W/A = 92h, 16 bit
  2911 00006720 FF03000000920000        	dw 03FFh, 0, 9200h, 0 ; Note: base addr will be initialized
  2912                                  			; 68h ; VBE3ES 	
  2913                                  _vbe3_ES: ; extra 16 bit segment points to buffers in kernel's mem space
  2914                                  	; limit = 2048, base addr = 0, P/DPL/1/Type/E/W/A = 92h, 16 bit
  2915 00006728 FF07000000920000        	dw 07FFh, 0, 9200h,0 ; Note: base addr will be initialized
  2916                                  			; 70h ; KODE16	
  2917                                  _16bit_CS: ; 16 bit code segment points to kernel's far return addr
  2918                                  	; limit = 16M, base addr = 0, P/DPL/1/Type/E/W/A = 92h, 16 bit
  2919 00006730 FFFF0000009AFF00        	dw 0FFFFh, 0, 9A00h, 00FFh ; Note: base addr will be initialized
  2920                                  
  2921                                  gdt_end:
  2922                                  	;; 9Eh = 1001 1110b (GDT byte 5) P=1/DPL=00/1/TYPE=1110, 
  2923                                  					;; Type= 1 (code)/C=1/R=1/A=0
  2924                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
  2925                                  		; 1= Code C= Conforming, R= Readable, A = Accessed
  2926                                  
  2927                                  	;; 9Ah = 1001 1010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
  2928                                  					;; Type= 1 (code)/C=0/R=1/A=0
  2929                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
  2930                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
  2931                                  
  2932                                  	;; 92h = 1001 0010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
  2933                                  					;; Type= 0 (data)/E=0/W=1/A=0
  2934                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
  2935                                  		; 0= Data E= Expansion direction (1= down, 0= up)
  2936                                  		; W= Writeable, A= Accessed
  2937                                  
  2938                                  	;; FEh = 1111 1110b (GDT byte 5) P=1/DPL=11/1/TYPE=1110, 
  2939                                  					;; Type= 1 (code)/C=1/R=1/A=0
  2940                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
  2941                                  		; 1= Code C= Conforming, R= Readable, A = Accessed
  2942                                  	
  2943                                  	;; FAh = 1111 1010b (GDT byte 5) P=1/DPL=11/1/TYPE=1010, 
  2944                                  					;; Type= 1 (code)/C=0/R=1/A=0
  2945                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
  2946                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
  2947                                  
  2948                                  	;; F2h = 1111 0010b (GDT byte 5) P=1/DPL=11/1/TYPE=0010, 
  2949                                  					;; Type= 0 (data)/E=0/W=1/A=0
  2950                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
  2951                                  		; 0= Data E= Expansion direction (1= down, 0= up)
  2952                                  	
  2953                                  	;; CFh = 1100 1111b (GDT byte 6) G=1/B=1/0/AVL=0, Limit=1111b (3)
  2954                                  
  2955                                  		;; Limit = FFFFFh (=> FFFFFh+1= 100000h) // bits 0-15, 48-51 //
  2956                                  		;	 = 100000h * 1000h (G=1) = 4GB
  2957                                  		;; Limit = FFBFFh (=> FFBFFh+1= FFC00h) // bits 0-15, 48-51 //
  2958                                  		;	 = FFC00h * 1000h (G=1) = 4GB - 4MB
  2959                                  		; G= Granularity (1= 4KB), B= Big (32 bit), 
  2960                                  		; AVL= Available to programmers	
  2961                                  
  2962                                  gdtd:
  2963 00006738 7700                            dw gdt_end - gdt - 1    ; Limit (size)
  2964 0000673A [C0660000]                      dd gdt			; Address of the GDT
  2965                                  
  2966                                  	; 20/08/2014
  2967                                  idtd:
  2968 0000673E 7F02                            dw idt_end - idt - 1    ; Limit (size)
  2969 00006740 [F0600100]                      dd idt			; Address of the IDT
  2970                                  
  2971                                  ; 20/02/2017
  2972                                  ;;; 11/03/2015
  2973                                  %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 00006744 [A7670000]          <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 00006748 01                  <1> 		DB	01		;DRIVE TYPE, MEDIA TABLE
   113                              <1>                 ;DW      MD_TBL1
   114 00006749 [66670000]          <1> 		dd	MD_TBL1
   115 0000674D 82                  <1> 		DB	02+BIT7ON
   116                              <1> 		;DW      MD_TBL2
   117 0000674E [73670000]          <1>                 dd      MD_TBL2
   118 00006752 02                  <1> DR_DEFAULT:	DB	02
   119                              <1>                 ;DW      MD_TBL3
   120 00006753 [80670000]          <1> 		dd      MD_TBL3
   121 00006757 03                  <1> 		DB	03
   122                              <1>                 ;DW      MD_TBL4
   123 00006758 [8D670000]          <1> 		dd      MD_TBL4
   124 0000675C 84                  <1> 		DB	04+BIT7ON
   125                              <1>                 ;DW      MD_TBL5
   126 0000675D [9A670000]          <1> 		dd      MD_TBL5
   127 00006761 04                  <1> 		DB	04
   128                              <1>                 ;DW      MD_TBL6
   129 00006762 [A7670000]          <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 00006766 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   141 00006767 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   142 00006768 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   143 00006769 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   144 0000676A 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   145 0000676B 2A                  <1> 	DB	02AH		; GAP LENGTH
   146 0000676C FF                  <1> 	DB	0FFH		; DTL
   147 0000676D 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   148 0000676E F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   149 0000676F 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   150 00006770 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   151 00006771 27                  <1> 	DB	39		; MAX. TRACK NUMBER
   152 00006772 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 00006773 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   158 00006774 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   159 00006775 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   160 00006776 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   161 00006777 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   162 00006778 2A                  <1> 	DB	02AH		; GAP LENGTH
   163 00006779 FF                  <1> 	DB	0FFH		; DTL
   164 0000677A 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   165 0000677B F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   166 0000677C 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   167 0000677D 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   168 0000677E 27                  <1> 	DB	39		; MAX. TRACK NUMBER
   169 0000677F 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 00006780 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   175 00006781 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   176 00006782 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   177 00006783 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   178 00006784 0F                  <1> 	DB	15		; EOT (LAST SECTOR ON TRACK)
   179 00006785 1B                  <1> 	DB	01BH		; GAP LENGTH
   180 00006786 FF                  <1> 	DB	0FFH		; DTL
   181 00006787 54                  <1> 	DB	054H		; GAP LENGTH FOR FORMAT
   182 00006788 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   183 00006789 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   184 0000678A 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   185 0000678B 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   186 0000678C 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 0000678D DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   192 0000678E 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   193 0000678F 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   194 00006790 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   195 00006791 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   196 00006792 2A                  <1> 	DB	02AH		; GAP LENGTH
   197 00006793 FF                  <1> 	DB	0FFH		; DTL
   198 00006794 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   199 00006795 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   200 00006796 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   201 00006797 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   202 00006798 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   203 00006799 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 0000679A DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   209 0000679B 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   210 0000679C 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   211 0000679D 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   212 0000679E 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   213 0000679F 2A                  <1> 	DB	02AH		; GAP LENGTH
   214 000067A0 FF                  <1> 	DB	0FFH		; DTL
   215 000067A1 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   216 000067A2 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   217 000067A3 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   218 000067A4 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   219 000067A5 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   220 000067A6 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 000067A7 AF                  <1> 	DB	10101111B	; SRT=A, HD UNLOAD=0F - 1ST SPECIFY BYTE
   226 000067A8 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   227 000067A9 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   228 000067AA 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   229 000067AB 12                  <1> 	DB	18		; EOT (LAST SECTOR ON TRACK)
   230 000067AC 1B                  <1> 	DB	01BH		; GAP LENGTH
   231 000067AD FF                  <1> 	DB	0FFH		; DTL
   232 000067AE 6C                  <1> 	DB	06CH		; GAP LENGTH FOR FORMAT
   233 000067AF F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   234 000067B0 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   235 000067B1 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   236 000067B2 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   237 000067B3 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 000067B4 E0                  <1> 	db	NO_ERR
   280 000067B5 024001BB            <1> 	db	BAD_ADDR_MARK,BAD_SEEK,BAD_CMD,UNDEF_ERR
   281 000067B9 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 000067BD 00                  <1> cfd:		db 0			; current floppy drive (for GET_PARM)
   286                              <1> ; 17/12/2014				; instead of 'DISK_POINTER'
   287 000067BE 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 000067BF 90                  <1> align 2
   293                              <1> 
   294 000067C0 F001                <1> HF_PORT:	dw 	1F0h  ; Default = 1F0h
   295                              <1> 			      ; (170h)
   296 000067C2 F603                <1> HF_REG_PORT:	dw	3F6h  ; HF_PORT + 206h
   297                              <1> 
   298                              <1> ; 05/01/2015 
   299 000067C4 00                  <1> hf_m_s:         db      0     ; (0 = Master, 1 = Slave)
   300                              <1> 
   301                              <1> ; *****************************************************************************
  2974                                  
  2975 000067C5 90                      Align 2
  2976                                  
  2977                                  ; 04/11/2014 (Retro UNIX 386 v1)
  2978 000067C6 0000                    mem_1m_1k:   dw 0  ; Number of contiguous KB between
  2979                                                       ; 1 and 16 MB, max. 3C00h = 15 MB.
  2980 000067C8 0000                    mem_16m_64k: dw 0  ; Number of contiguous 64 KB blocks
  2981                                  		   ; between 16 MB and 4 GB.
  2982                                  
  2983                                  ; 12/11/2014 (Retro UNIX 386 v1)
  2984 000067CA 00                      boot_drv:    db 0 ; boot drive number (physical)
  2985                                  ; 24/11/2014
  2986 000067CB 00                      drv:	     db 0 
  2987 000067CC 00                      last_drv:    db 0 ; last hdd
  2988 000067CD 00                      hdc:         db 0  ; number of hard disk drives
  2989                                  		     ; (present/detected)
  2990                                  
  2991                                  ; 24/11/2014 (Retro UNIX 386 v1)
  2992                                  ; Physical drive type & flags
  2993 000067CE 00                      fd0_type:    db 0  ; floppy drive type
  2994 000067CF 00                      fd1_type:    db 0  ; 4 = 1.44 Mb, 80 track, 3.5" (18 spt)
  2995                                  		     ; 6 = 2.88 Mb, 80 track, 3.5" (36 spt)
  2996                                  		     ; 3 = 720 Kb, 80 track, 3.5" (9 spt)
  2997                                  		     ; 2 = 1.2 Mb, 80 track, 5.25" (15 spt)
  2998                                  		     ; 1 = 360 Kb, 40 track, 5.25" (9 spt)		
  2999 000067D0 00                      hd0_type:    db 0  ; EDD status for hd0 (bit 7 = present flag)
  3000 000067D1 00                      hd1_type:    db 0  ; EDD status for hd1 (bit 7 = present flag)
  3001 000067D2 00                      hd2_type:    db 0  ; EDD status for hd2 (bit 7 = present flag)
  3002 000067D3 00                      hd3_type:    db 0  ; EDD status for hd3 (bit 7 = present flag)
  3003                                  		     ; bit 0 - Fixed disk access subset supported
  3004                                  		     ; bit 1 - Drive locking and ejecting
  3005                                  		     ; bit 2 - Enhanced disk drive support
  3006                                  		     ; bit 3 = Reserved (64 bit EDD support)
  3007                                  		     ; (If bit 0 is '1' Retro UNIX 386 v1
  3008                                  		     ; will interpret it as 'LBA ready'!)
  3009                                  
  3010                                  ; 11/03/2015 - 10/07/2015
  3011 000067D4 000000000000000000-     drv.cylinders: dw 0,0,0,0,0,0,0
  3011 000067DD 0000000000         
  3012 000067E2 000000000000000000-     drv.heads:     dw 0,0,0,0,0,0,0
  3012 000067EB 0000000000         
  3013 000067F0 000000000000000000-     drv.spt:       dw 0,0,0,0,0,0,0
  3013 000067F9 0000000000         
  3014 000067FE 000000000000000000-     drv.size:      dd 0,0,0,0,0,0,0
  3014 00006807 000000000000000000-
  3014 00006810 000000000000000000-
  3014 00006819 00                 
  3015 0000681A 00000000000000          drv.status:    db 0,0,0,0,0,0,0
  3016 00006821 00000000000000          drv.error:     db 0,0,0,0,0,0,0	
  3017                                  
  3018                                  Align 2
  3019                                  
  3020                                  ;;; 11/03/2015
  3021                                  %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 00006828 524F50514B          <1> K30:	db	82,79,80,81,75
    36 0000682D 4C4D474849          <1> 	db	76,77,71,72,73		; 10 NUMBER ON KEYPAD
    37                              <1> ;-----	SUPER-SHIFT-TABLE 
    38 00006832 101112131415        <1> 	db	16,17,18,19,20,21	; A-Z TYPEWRITER CHARS
    39 00006838 161718191E1F        <1> 	db	22,23,24,25,30,31
    40 0000683E 202122232425        <1> 	db	32,33,34,35,36,37
    41 00006844 262C2D2E2F30        <1> 	db	38,44,45,46,47,48
    42 0000684A 3132                <1> 	db	49,50
    43                              <1> 
    44                              <1> ;-----	TABLE OF SHIFT KEYS AND MASK VALUES
    45                              <1> ;-----	KEY_TABLE 
    46 0000684C 52                  <1> _K6:    db      INS_KEY                 ; INSERT KEY
    47 0000684D 3A4546381D          <1> 	db	CAPS_KEY,NUM_KEY,SCROLL_KEY,ALT_KEY,CTL_KEY
    48 00006852 2A36                <1>         db      LEFT_KEY,RIGHT_KEY
    49                              <1> _K6L    equ     $-_K6
    50                              <1> 
    51                              <1> ;-----	MASK_TABLE
    52 00006854 80                  <1> _K7:    db      INS_SHIFT               ; INSERT MODE SHIFT
    53 00006855 4020100804          <1> 	db	CAPS_SHIFT,NUM_SHIFT,SCROLL_SHIFT,ALT_SHIFT,CTL_SHIFT
    54 0000685A 0201                <1> 	db	LEFT_SHIFT,RIGHT_SHIFT
    55                              <1> 
    56                              <1> ;-----	TABLES FOR CTRL CASE		;---- CHARACTERS ------
    57 0000685C 1BFF00FFFFFF        <1> _K8:	db	27,-1,0,-1,-1,-1	; Esc, 1, 2, 3, 4, 5
    58 00006862 1EFFFFFFFF1F        <1> 	db 	30,-1,-1,-1,-1,31	; 6, 7, 8, 9, 0, -
    59 00006868 FF7FFF111705        <1> 	db	-1,127,-1,17,23,5	; =, Bksp, Tab, Q, W, E
    60 0000686E 12141915090F        <1> 	db	18,20,25,21,9,15	; R, T, Y, U, I, O
    61 00006874 101B1D0AFF01        <1> 	db	16,27,29,10,-1,1	; P, [, ], Enter, Ctrl, A
    62 0000687A 13040607080A        <1> 	db	19,4,6,7,8,10		; S, D, F, G, H, J
    63 00006880 0B0CFFFFFFFF        <1> 	db	11,12,-1,-1,-1,-1	; K, L, :, ', `, LShift
    64 00006886 1C1A18031602        <1> 	db	28,26,24,3,22,2		; Bkslash, Z, X, C, V, B
    65 0000688C 0E0DFFFFFFFF        <1> 	db	14,13,-1,-1,-1,-1	; N, M, ,, ., /, RShift
    66 00006892 96FF20FF            <1> 	db	150,-1,' ',-1		; *, ALT, Spc, CL
    67                              <1> 	;				;----- FUNCTIONS ------		
    68 00006896 5E5F60616263        <1> 	db 	94,95,96,97,98,99	; F1 - F6
    69 0000689C 64656667FFFF        <1> 	db	100,101,102,103,-1,-1	; F7 - F10, NL, SL
    70 000068A2 778D848E738F        <1> 	db	119,141,132,142,115,143	; Home, Up, PgUp, -, Left, Pad5
    71 000068A8 749075917692        <1> 	db 	116,144,117,145,118,146 ; Right, +, End, Down, PgDn, Ins
    72 000068AE 93FFFFFF898A        <1> 	db	147,-1,-1,-1,137,138	; Del, SysReq, Undef, WT, F11, F12
    73                              <1> 
    74                              <1> ;-----	TABLES FOR LOWER CASE ----------
    75 000068B4 1B3132333435363738- <1> K10:	db 	27,'1234567890-=',8,9
    75 000068BD 39302D3D0809        <1>
    76 000068C3 71776572747975696F- <1> 	db 	'qwertyuiop[]',13,-1,'asdfghjkl;',39
    76 000068CC 705B5D0DFF61736466- <1>
    76 000068D5 67686A6B6C3B27      <1>
    77 000068DC 60FF5C7A786376626E- <1> 	db	96,-1,92,'zxcvbnm,./',-1,'*',-1,' ',-1
    77 000068E5 6D2C2E2FFF2AFF20FF  <1>
    78                              <1> ;-----	LC TABLE SCAN
    79 000068EE 3B3C3D3E3F          <1> 	db	59,60,61,62,63		; BASE STATE OF F1 - F10
    80 000068F3 4041424344          <1> 	db	64,65,66,67,68
    81 000068F8 FFFF                <1> 	db	-1,-1			; NL, SL
    82                              <1> 
    83                              <1> ;-----	KEYPAD TABLE
    84 000068FA 474849FF4BFF        <1> K15:	db	71,72,73,-1,75,-1	; BASE STATE OF KEYPAD KEYS
    85 00006900 4DFF4F50515253      <1> 	db	77,-1,79,80,81,82,83
    86 00006907 FFFF5C8586          <1> 	db	-1,-1,92,133,134	; SysRq, Undef, WT, F11, F12
    87                              <1> 
    88                              <1> ;-----	TABLES FOR UPPER CASE ----------
    89 0000690C 1B21402324255E262A- <1> K11:	db 	27,'!@#$%',94,'&*()_+',8,0
    89 00006915 28295F2B0800        <1>
    90 0000691B 51574552545955494F- <1> 	db 	'QWERTYUIOP{}',13,-1,'ASDFGHJKL:"'
    90 00006924 507B7D0DFF41534446- <1>
    90 0000692D 47484A4B4C3A22      <1>
    91 00006934 7EFF7C5A584356424E- <1> 	db	126,-1,'|ZXCVBNM<>?',-1,'*',-1,' ',-1
    91 0000693D 4D3C3E3FFF2AFF20FF  <1>
    92                              <1> ;-----	UC TABLE SCAN
    93 00006946 5455565758          <1> K12:	db	84,85,86,87,88		; SHIFTED STATE OF F1 - F10
    94 0000694B 595A5B5C5D          <1> 	db	89,90,91,92,93
    95 00006950 FFFF                <1> 	db	-1,-1			; NL, SL
    96                              <1> 
    97                              <1> ;-----	NUM STATE TABLE
    98 00006952 3738392D3435362B31- <1> K14:	db 	'789-456+1230.'		; NUMLOCK STATE OF KEYPAD KEYS
    98 0000695B 3233302E            <1>
    99                              <1> 	;
   100 0000695F 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 00006964 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 00006965 00                  <1> KB_FLAG		db	0		; KEYBOARD SHIFT STATE AND STATUS FLAGS
   118 00006966 00                  <1> KB_FLAG_1	db	0		; SECOND BYTE OF KEYBOARD STATUS
   119 00006967 00                  <1> KB_FLAG_2	db	0		; KEYBOARD LED FLAGS
   120 00006968 00                  <1> KB_FLAG_3	db	0		; KEYBOARD MODE STATE AND TYPE FLAGS
   121 00006969 00                  <1> ALT_INPUT	db	0		; STORAGE FOR ALTERNATE KEY PAD ENTRY
   122 0000696A [7A690000]          <1> BUFFER_START	dd	KB_BUFFER 	; OFFSET OF KEYBOARD BUFFER START
   123 0000696E [9A690000]          <1> BUFFER_END	dd	KB_BUFFER + 32	; OFFSET OF END OF BUFFER
   124 00006972 [7A690000]          <1> BUFFER_HEAD	dd	KB_BUFFER 	; POINTER TO HEAD OF KEYBOARD BUFFER
   125 00006976 [7A690000]          <1> BUFFER_TAIL	dd	KB_BUFFER 	; POINTER TO TAIL OF KEYBOARD BUFFER
   126                              <1> ; ------	HEAD = TAIL	INDICATES THAT THE BUFFER IS EMPTY
   127 0000697A 0000<rept>          <1> KB_BUFFER	times	16 dw 0		; ROOM FOR 16 SCAN CODE ENTRIES
   128                              <1> 
   129                              <1> ; /// End Of KEYBOARD DATA ///
  3022                                  %include 'vidata.s'	; VIDEO (BIOS) DATA
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.3 - vidata.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 24/11/2020
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 16/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.15 (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 0000699A 03                  <1> CRT_MODE:	db	3	; CURRENT DISPLAY MODE (TYPE)
    29 0000699B 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 0000699C 50                  <1> CRT_COLS:	db	80	; Number of columns
    52                              <1> 
    53                              <1> ; 01/07/2016
    54 0000699D 00                  <1> CRT_PALETTE:	db 	0	; Current palette setting
    55                              <1> 
    56                              <1> ; 03/07/2016
    57 0000699E 10                  <1> CHAR_HEIGHT:	db	16	; Default character height
    58 0000699F 60                  <1> VGA_VIDEO_CTL:	db	60h	; ROM BIOS DATA AREA Offset 87h
    59 000069A0 F9                  <1> VGA_SWITCHES:	db 	0F9h	; Feature Bit Switches (the basic screen)
    60 000069A1 51                  <1> VGA_MODESET_CTL: db	051h	; Basic mode set options (VGA video flags)
    61                              <1> 				; ROM BIOS DATA AREA Offset 89h
    62                              <1> 				; Bit 7, 4 : Mode
    63                              <1> 				;	  01 : 400-line mode
    64                              <1> 				; Bit 6	: Display switch enabled = 1			
    65                              <1> 				; Bit 5	: Reserved = 0
    66                              <1> 				; Bit 3	: Default palette loading 
    67                              <1> 				;	  disabled = 0
    68                              <1> 				; Bit 2 : Color monitor = 0
    69                              <1> 				; Bit 1 = Gray scale summing 
    70                              <1> 				;	  disabled = 0
    71                              <1> 				; Bit 0 = VGA active = 1
    72 000069A2 19                  <1> VGA_ROWS:	db	25
    73                              <1> 
    74                              <1> ; 16/01/2016
    75                              <1> chr_attrib:  ; Character color/attributes for viode pages (0 to 7)
    76 000069A3 0707070707070707    <1> 	db	07h, 07h, 07h, 07h, 07h, 07h, 07h, 07h
    77                              <1> ; 30/01/2016
    78                              <1> vmode:
    79 000069AB 0303030303030303    <1> 	db	3,3,3,3,3,3,3,3 ; video modes for pseudo screens 
    80                              <1> 
    81                              <1> CURSOR_MODE: ; cursor start (ch) = 14, cursor end (cl) = 15
    82 000069B3 0F0E                <1> 	db	15, 14 ; 07/07/2016 - TRDOS 386 (TRDOS v2.0)
    83                              <1> 
    84                              <1> ;align 4
    85                              <1> ;VGA_BASE: ; 26/07/2016
    86                              <1> ;	dd	 0B8000h  ; (Mode < 0Dh) or 0A0000h (mode >= 0Dh)
    87                              <1> 
    88 000069B5 90                  <1> align 2
    89                              <1> 
    90                              <1> vga_modes:
    91                              <1> 	; 25/07/2016
    92                              <1> 	; 09/07/2016
    93                              <1> 	; 03/07/2016
    94                              <1> 	; valid (implemented) video modes (>7, extension to IBM PC CGA modes)
    95 000069B6 0302010007040506    <1> 	db 	03h, 02h, 01h, 00h, 07h, 04h, 05h, 06h
    96                              <1> vga_g_modes: ; 31/07/2016
    97 000069BE 13F0126A0D0E1011    <1> 	db	13h, 0F0h, 12h, 6Ah, 0Dh, 0Eh, 10h, 11h
    98                              <1> vga_mode_count equ $ - vga_modes
    99                              <1> vga_g_mode_count equ $ - vga_g_modes
   100                              <1> 
   101                              <1> vga_mode_tbl_ptr:
   102                              <1> 	; 25/07/2016
   103 000069C6 [266A0000]          <1> 	dd	vga_mode_03h
   104 000069CA [266A0000]          <1> 	dd	vga_mode_03h ; mode 02h -> mode 03h 
   105 000069CE [666A0000]          <1> 	dd	vga_mode_01h
   106 000069D2 [666A0000]          <1> 	dd	vga_mode_01h ; mode 00h -> mode 01h
   107                              <1> 	;dd	vga_mode_07h
   108 000069D6 [266A0000]          <1> 	dd	vga_mode_03h ; mode 07h -> mode 03h
   109 000069DA [A66A0000]          <1> 	dd	vga_mode_04h
   110 000069DE [A66A0000]          <1> 	dd	vga_mode_04h ; mode 05h -> mode 04h	
   111 000069E2 [E66A0000]          <1> 	dd	vga_mode_06h
   112 000069E6 [266B0000]          <1> 	dd	vga_mode_13h
   113 000069EA [666B0000]          <1> 	dd	vga_mode_F0h
   114 000069EE [A66B0000]          <1> 	dd	vga_mode_12h
   115 000069F2 [E66B0000]          <1> 	dd	vga_mode_6Ah
   116 000069F6 [266C0000]          <1> 	dd	vga_mode_0Dh
   117 000069FA [666C0000]          <1> 	dd	vga_mode_0Eh
   118 000069FE [A66C0000]          <1> 	dd	vga_mode_10h
   119 00006A02 [E66C0000]          <1> 	dd	vga_mode_11h	
   120                              <1> 
   121                              <1> vga_memmodel: 
   122                              <1> 	; 25/07/2016
   123                              <1> 	; 07/07/2016
   124                              <1> 	CTEXT	equ 0
   125                              <1> 	;MTEXT	equ 1
   126                              <1> 	MTEXT	equ 0 ; mode 07h -> mode 03h
   127                              <1> 	CGA	equ 2
   128                              <1> 	LINEAR8 equ 5
   129                              <1> 	PLANAR4	equ 4
   130                              <1> 	PLANAR1	equ 3
   131 00006A06 0000000000020202    <1> 	db	CTEXT, CTEXT, CTEXT, CTEXT, MTEXT, CGA, CGA, CGA
   132                              <1> vga_g_memmodel: ; 31/07/2016
   133 00006A0E 0504040404040403    <1> 	db	LINEAR8, PLANAR4, PLANAR4, PLANAR4, PLANAR4, PLANAR4, PLANAR4, PLANAR1
   134                              <1> ;vga_pixbits:
   135                              <1> ;	; 25/07/2016
   136                              <1> ;	; 08/07/2016
   137                              <1> ;	db 	4, 4, 4, 4, 4, 2, 2, 1, 8, 4, 4, 4, 4, 4, 4, 1
   138                              <1> vga_dac_s:
   139 00006A16 020202020001010103- <1> 	db	2, 2, 2, 2, 0, 1, 1, 1, 3, 3, 2, 2, 1, 1, 2, 2  
   139 00006A1F 03020201010202      <1>
   140                              <1> 						; (vgatables.h, VGAMODES, dac) 
   141                              <1> 						; 17/11/2020
   142                              <1> vga_params:
   143                              <1> 	; 23/11/2020
   144                              <1> 	; 16/11/2020
   145                              <1> 	; 09/11/2020, 10/11/2020, 11/11/2020 (TRDOS 386 v2.0.3)
   146                              <1> 	; 25/07/2016 
   147                              <1> 	; 19/07/2016
   148                              <1> 	; 03/07/2016
   149                              <1> 	; derived from 'Plex86/Bochs VGABios' source code
   150                              <1> 	; vgabios-0.7a (2011)
   151                              <1> 	; by the LGPL VGABios Developers Team (2001-2008)
   152                              <1> 	; 'vgatables.h'
   153                              <1> 	; Oracle VirtualBox 5.0.24 VGABios Source Code
   154                              <1> 	; ('vgabios.c', 'vgatables.h', 'vgafonts.h', 'vgarom.asm')
   155                              <1> 
   156                              <1> 	; 09/11/2020
   157                              <1> 	; Block Structure of Video Parameter Table
   158                              <1> 	;
   159                              <1> 	; Offset	# Bytes		Contents
   160                              <1> 	;
   161                              <1> 	;  0		1		# columns
   162                              <1> 	;  1		1  		# rows - 1 
   163                              <1> 	;  2		1		Pixels/character
   164                              <1> 	;  3-4		2		Page length		
   165                              <1> 	;  5-8		4		Sequencer Registers
   166                              <1> 	;  9		1		Miscellaneous Register	
   167                              <1> 	;  10-34	25		CRTC Registers
   168                              <1> 	;  35-54	20		Attribute Registers
   169                              <1> 	;  55-63	9		Graphics Controller Registers
   170                              <1> 	;
   171                              <1> 	; Ref: Programmer's Guide to EGA, VGA, and Super VGA cards
   172                              <1> 	; (Richard F. Ferraro, 1994)  
   173                              <1> 
   174                              <1> 	;
   175                              <1> vga_mode_03h:  ; mode 03h, 80*25 text, CGA colors
   176                              <1> 	; 11/11/2020
   177 00006A26 5018100010          <1>  	db	80, 24, 16, 00h, 10h ; tw, th-1, ch, slength (5)
   178 00006A2B 00030002            <1>  	db	00h, 03h, 00h, 02h ; sequ regs (4)
   179 00006A2F 67                  <1>  	db	67h	; misc reg (1)
   180 00006A30 5F4F50825581BF1F    <1>  	db	5Fh, 4Fh, 50h, 82h, 55h, 81h, 0BFh, 1Fh
   181                              <1>  	; 09/11/2020
   182                              <1> 	;db	5Fh, 4Fh, 50h, 82h, 54h, 80h, 0BFh, 1Fh
   183 00006A38 004F                <1> 	db	00h, 4Fh
   184                              <1> vga_p_cm_pos equ $ - vga_mode_03h
   185 00006A3A 0D0E00000000        <1> 	db	0Dh, 0Eh, 00h, 00h, 00h, 00h
   186 00006A40 9C8E8F281F96B9A3    <1>  	db	9Ch, 8Eh, 8Fh, 28h, 1Fh, 96h, 0B9h, 0A3h
   187 00006A48 FF                  <1> 	db	0FFh	; crtc_regs (25)
   188 00006A49 0001020304051407    <1> 	db	00h, 01h, 02h, 03h, 04h, 05h, 14h, 07h
   189 00006A51 38393A3B3C3D3E3F    <1>  	db	38h, 39h, 3Ah, 3Bh, 3Ch, 3Dh, 3Eh, 3Fh
   190                              <1>  	;db	0Ch, 00h, 0Fh, 08h  ; actl regs (20)
   191 00006A59 0C000F00            <1> 	db	0Ch, 00h, 0Fh, 00h  ; 19/11/2020
   192 00006A5D 0000000000100E0FFF  <1> 	db	00h, 00h, 00h, 00h, 00h, 10h, 0Eh, 0Fh, 0FFh ; grdc regs (9)
   193                              <1> 	; 09/11/2020
   194                              <1> 	;db	00h, 00h, 00h, 00h, 00h, 10h, 0Eh, 00h, 0FFh ; grdc regs (9)
   195                              <1> vga_mode_01h:	; mode 01h, 40*25 text, CGA colors
   196 00006A66 2818100008          <1> 	db	40, 24, 16, 00h, 08h ; tw, th-1, ch, slength
   197 00006A6B 08030002            <1> 	db	08h, 03h, 00h, 02h  ; sequ regs
   198 00006A6F 67                  <1> 	db	67h	; misc reg
   199 00006A70 2D2728902BA0BF1F    <1> 	db	2Dh, 27h, 28h, 90h, 2Bh, 0A0h, 0BFh, 1Fh
   200 00006A78 004F0D0E00000000    <1> 	db	00h, 4Fh, 0Dh, 0Eh, 00h, 00h, 00h, 00h
   201 00006A80 9C8E8F141F96B9A3    <1> 	db	9Ch, 8Eh, 8Fh, 14h, 1Fh, 96h, 0B9h, 0A3h
   202 00006A88 FF                  <1> 	db	0FFh	; crtc_regs
   203 00006A89 0001020304051407    <1> 	db	00h, 01h, 02h, 03h, 04h, 05h, 14h, 07h
   204 00006A91 38393A3B3C3D3E3F    <1> 	db	38h, 39h, 3Ah, 3Bh, 3Ch, 3Dh, 3Eh, 3Fh
   205                              <1>  	;db	0Ch, 00h, 0Fh, 08h  ; actl regs (20)
   206 00006A99 0C000F00            <1> 	db	0Ch, 00h, 0Fh, 00h  ; 19/11/2020
   207 00006A9D 0000000000100E0FFF  <1> 	db	00h, 00h, 00h, 00h, 00h, 10h, 0Eh, 0Fh, 0FFh ; grdc regs
   208                              <1> ;vga_mode_07h:	; mode 07h, 80*25 text, mono color
   209                              <1> ;	db	80, 24, 16, 00h, 10h  ; tw, th-1, ch, slength
   210                              <1> ;	db	00h, 03h, 00h, 02h ; sequ regs
   211                              <1> ;	db	66h	; misc reg
   212                              <1> ;	db	5Fh, 4Fh, 50h, 82h, 55h, 81h, 0BFh, 1Fh
   213                              <1> ;	db	00h, 4Fh, 0Dh, 0Eh, 00h, 00h, 00h, 00h
   214                              <1> ;	db	9Ch, 8Eh, 8Fh, 28h, 0Fh, 96h, 0B9h, 0A3h
   215                              <1> ;	db	0FFh	; crtc regs
   216                              <1> ;	db	00h, 08h, 08h, 08h, 08h, 08h, 08h, 08h
   217                              <1> ;	db	10h, 18h, 18h, 18h, 18h, 18h, 18h, 18h
   218                              <1> ;	db	0Eh, 00h, 0Fh, 08h  ; actl regs
   219                              <1> ;	db	00h, 00h, 00h, 00h, 00h, 10h, 0Ah, 0Fh, 0FFh ; grdc regs
   220                              <1> vga_mode_04h:	; 320*200 graphics, 4 colors, CGA
   221                              <1> 	; 11/11/2020
   222 00006AA6 2818080040          <1> 	db	40, 24, 8, 00h, 40h ; tw, th-1, ch, slength
   223 00006AAB 09030002            <1> 	db	09h, 03h, 00h, 02h ; sequ regs
   224 00006AAF 63                  <1> 	db	63h	; misc reg
   225 00006AB0 2D2728902B80BF1F    <1> 	db	2Dh, 27h, 28h, 90h, 2Bh, 80h, 0BFh, 1Fh
   226 00006AB8 00C1000000000000    <1> 	db	00h, 0C1h, 00h, 00h, 00h, 00h, 00h, 00h
   227 00006AC0 9C8E8F140096B9A2    <1> 	db	9Ch, 8Eh, 8Fh, 14h, 00h, 96h, 0B9h, 0A2h
   228 00006AC8 FF                  <1> 	db	0FFh	; crtc_regs
   229 00006AC9 0013151702040607    <1> 	db	00h, 13h, 15h, 17h, 02h, 04h, 06h, 07h
   230 00006AD1 1011121314151617    <1> 	db	10h, 11h, 12h, 13h, 14h, 15h, 16h, 17h
   231 00006AD9 01000300            <1> 	db	01h, 00h, 03h, 00h ; actl regs
   232 00006ADD 0000000000300F0FFF  <1> 	db 	00h, 00h, 00h, 00h, 00h, 30h, 0Fh, 0Fh, 0FFh ; grdc regs
   233                              <1> vga_mode_06h:	; 640*200 graphics, 2 colors, CGA
   234                              <1> 	; 11/11/2020
   235 00006AE6 5018080040          <1> 	db	80, 24, 8, 00h, 40h   ;	tw, th-1, ch, slength
   236 00006AEB 01010006            <1> 	db	01h, 01h, 00h, 06h ; sequ regs
   237 00006AEF 63                  <1> 	db	63h	; misc reg
   238 00006AF0 5F4F50825480BF1F    <1> 	db	5Fh, 4Fh, 50h, 82h, 54h, 80h, 0BFh, 1Fh
   239 00006AF8 00C1000000000000    <1> 	db	00h, 0C1h, 00h, 00h, 00h, 00h, 00h, 00h
   240 00006B00 9C8E8F280096B9C2    <1> 	db	9Ch, 8Eh, 8Fh, 28h, 00h, 96h, 0B9h, 0C2h
   241 00006B08 FF                  <1> 	db	0FFh	; crtc regs
   242 00006B09 0017171717171717    <1> 	db	00h, 17h, 17h, 17h, 17h, 17h, 17h, 17h
   243 00006B11 1717171717171717    <1> 	db	17h, 17h, 17h, 17h, 17h, 17h, 17h, 17h
   244 00006B19 01000100            <1> 	db	01h, 00h, 01, 00h  ; actl regs
   245 00006B1D 0000000000000D0FFF  <1> 	db	00h, 00h, 00h, 00h, 00h, 00h, 0Dh, 0Fh, 0FFh ; grdc regs
   246                              <1> vga_mode_13h:  ; mode 13h, 300*200, 256 colors, linear
   247                              <1> 	; 11/11/2020
   248                              <1> 	;db 	40, 24, 8, 00h, 20h ; tw, th-1, ch, slength (5)
   249                              <1> 	; 23/11/2020 - 10/11/2020
   250 00006B26 28180800FA          <1> 	db 	40, 24, 8, 00h, 0FAh ; tw, th-1, ch, slength (5)
   251 00006B2B 010F000E            <1> 	db	01h, 0Fh, 00h, 0Eh ; sequ regs (4)
   252 00006B2F 63                  <1> 	db	63h	; misc reg (1)
   253 00006B30 5F4F50825480BF1F    <1> 	db	5Fh, 4Fh, 50h, 82h, 54h, 80h, 0BFh, 1Fh 
   254 00006B38 0041000000000000    <1> 	db 	00h, 041h, 00h, 00h, 00h, 00h, 00h, 00h
   255 00006B40 9C8E8F284096B9A3    <1> 	db	9Ch, 8Eh, 8Fh, 28h, 40h, 96h, 0B9h, 0A3h
   256 00006B48 FF                  <1> 	db	0FFh	; crtc regs (25)
   257 00006B49 0001020304050607    <1> 	db	00h, 01h, 02h, 03h, 04h, 05h, 06h, 07h
   258 00006B51 08090A0B0C0D0E0F    <1>  	db	08h, 09h, 0Ah, 0Bh, 0Ch, 0Dh, 0Eh, 0Fh
   259 00006B59 41000F00            <1>  	db	41h, 00h, 0Fh, 00h  ; actl regs (20)
   260                              <1> 	; 10/11/2020
   261                              <1>  	;db	41h, 01h, 0Fh, 13h  ; actl regs (20) 
   262 00006B5D 000000000040050FFF  <1> 	db	00h, 00h, 00h, 00h, 00h, 40h, 05h, 0Fh, 0FFh ; grdc regs (9)
   263                              <1> vga_mode_setl equ $ - vga_mode_13h  ; = 64
   264                              <1> vga_mode_F0h:  ; mode X ; 320*240, 256 colors, planar
   265 00006B66 2818080000          <1> 	db 	40, 24, 8, 00h, 00h ; tw, th-1, ch, slength
   266 00006B6B 010F0006            <1> 	db	01h, 0Fh, 00h, 06h ; sequ regs
   267 00006B6F E3                  <1> 	db	0E3h	; misc reg
   268 00006B70 5F4F508254800D3E    <1> 	db	5Fh, 4Fh, 50h, 82h, 54h, 80h, 0Dh, 3Eh 
   269 00006B78 0041000000000000    <1>  	db 	00h, 41h, 00h, 00h, 00h, 00h, 00h, 00h
   270 00006B80 EAACDF2800E706E3    <1> 	db	0EAh, 0ACh, 0DFh, 28h, 00h, 0E7h, 06h, 0E3h
   271 00006B88 FF                  <1> 	db	0FFh	; crtc regs (25)
   272 00006B89 0001020304050607    <1> 	db	00h, 01h, 02h, 03h, 04h, 05h, 06h, 07h
   273 00006B91 08090A0B0C0D0E0F    <1>  	db	08h, 09h, 0Ah, 0Bh, 0Ch, 0Dh, 0Eh, 0Fh
   274 00006B99 41000F00            <1>  	db	41h, 00h, 0Fh, 00h  ; actl regs
   275 00006B9D 000000000040050FFF  <1> 	db	00h, 00h, 00h, 00h, 00h, 40h, 05h, 0Fh, 0FFh ; grdc regs
   276                              <1> vga_mode_12h:  ; mode 12h, 640*480, 16 colors, planar
   277                              <1> 	; 11/11/2020
   278                              <1>  	;db 	80, 29, 16, 0, 0 ; tw, th-1, ch, slength
   279                              <1> 	; 09/11/2020
   280 00006BA6 501D1000A0          <1>  	db 	80, 29, 16, 00h, 0A0h ; tw, th-1, ch, slength
   281 00006BAB 010F0006            <1> 	db	01h, 0Fh, 00h, 06h ; sequ regs
   282 00006BAF E3                  <1> 	db 	0E3h	; misc reg
   283 00006BB0 5F4F508254800B3E    <1> 	db	5Fh, 4Fh, 50h, 82h, 54h, 80h, 0Bh, 3Eh
   284                              <1> 	; 09/11/2020
   285                              <1> 	;db	5Fh, 4Fh, 50h, 82h, 53h, 9Fh, 0Bh, 3Eh
   286 00006BB8 0040000000000000    <1> 	db	00h, 40h, 00h, 00h, 00h, 00h, 00h, 00h
   287 00006BC0 EA8CDF2800E704E3    <1>  	db	0EAh, 8Ch, 0DFh, 28h, 00h, 0E7h, 04h, 0E3h
   288                              <1> 	; 09/11/2020
   289                              <1>  	;db	0E9h, 8Bh, 0DFh, 28h, 00h, 0E7h, 04h, 0E3h
   290 00006BC8 FF                  <1> 	db	0FFh	; crtc regs
   291 00006BC9 0001020304051407    <1> 	db	00h, 01h, 02h, 03h, 04h, 05h, 14h, 07h
   292 00006BD1 38393A3B3C3D3E3F    <1> 	db	38h, 39h, 3Ah, 3Bh, 3Ch, 3Dh, 3Eh, 3Fh
   293 00006BD9 01000F00            <1> 	db	01h, 00h, 0Fh, 00h  ; actl regs
   294 00006BDD 000000000000050FFF  <1> 	db	00h, 00h, 00h, 00h, 00h, 00h, 05h, 0Fh, 0FFh ; grdc regs
   295                              <1> vga_mode_6Ah:  ; mode 6Ah, 800*600, 16 colors, planar
   296                              <1> 	; 11/11/2020
   297 00006BE6 6424100000          <1>  	db 	100, 36, 16, 00h, 00h ; tw, th-1, ch, slength
   298 00006BEB 010F0006            <1> 	db	01h, 0Fh, 00h, 06h ; sequ regs
   299 00006BEF E3                  <1> 	db 	0E3h	; misc reg
   300 00006BF0 7F6363836B1B72F0    <1> 	db	7Fh, 63h, 63h, 83h, 6Bh, 1Bh, 72h, 0F0h
   301 00006BF8 0060000000000000    <1> 	db	00h, 60h, 00h, 00h, 00h, 00h, 00h, 00h
   302 00006C00 598D5732005773E3    <1>  	db	59h, 8Dh, 57h, 32h, 00h, 57h, 73h, 0E3h
   303 00006C08 FF                  <1> 	db	0FFh	; crtc regs
   304 00006C09 0001020304051407    <1> 	db	00h, 01h, 02h, 03h, 04h, 05h, 14h, 07h
   305 00006C11 38393A3B3C3D3E3F    <1> 	db	38h, 39h, 3Ah, 3Bh, 3Ch, 3Dh, 3Eh, 3Fh
   306 00006C19 01000F00            <1> 	db	01h, 00h, 0Fh, 00h  ; actl regs
   307 00006C1D 000000000000050FFF  <1> 	db	00h, 00h, 00h, 00h, 00h, 00h, 05h, 0Fh, 0FFh ; grdc regs
   308                              <1> vga_mode_0Dh:  ; mode 0Dh, 320*200, 16 colors, planar
   309 00006C26 2818080020          <1>  	db 	40, 24, 8, 00h, 20h ; tw, th-1, ch, slength
   310 00006C2B 090F0006            <1> 	db	09h, 0Fh, 00h, 06h ; sequ regs
   311 00006C2F 63                  <1> 	db 	63h	; misc reg
   312 00006C30 2D2728902B80BF1F    <1> 	db	2Dh, 27h, 28h, 90h, 2Bh, 80h, 0BFh, 1Fh
   313 00006C38 00C0000000000000    <1> 	db	00h, 0C0h, 00h, 00h, 00h, 00h, 00h, 00h
   314 00006C40 9C8E8F140096B9E3    <1>  	db	9Ch, 8Eh, 8Fh, 14h, 00h, 96h, 0B9h, 0E3h
   315 00006C48 FF                  <1> 	db	0FFh	; crtc regs
   316 00006C49 0001020304050607    <1> 	db	00h, 01h, 02h, 03h, 04h, 05h, 06h, 07h
   317 00006C51 1011121314151617    <1> 	db	10h, 11h, 12h, 13h, 14h, 15h, 16h, 17h
   318 00006C59 01000F00            <1> 	db	01h, 00h, 0Fh, 00h  ; actl regs
   319 00006C5D 000000000000050FFF  <1> 	db	00h, 00h, 00h, 00h, 00h, 00h, 05h, 0Fh, 0FFh ; grdc regs
   320                              <1> vga_mode_0Eh:  ; mode 0Eh, 640*200, 16 colors, planar
   321 00006C66 5018080040          <1>  	db 	80, 24, 8, 00h, 40h ; tw, th-1, ch, slength
   322 00006C6B 010F0006            <1> 	db	01h, 0Fh, 00h, 06h ; sequ regs
   323 00006C6F 63                  <1> 	db 	63h	; misc reg
   324 00006C70 5F4F50825480BF1F    <1> 	db	5Fh, 4Fh, 50h, 82h, 54h, 80h, 0BFh, 1Fh
   325 00006C78 00C0000000000000    <1> 	db	00h, 0C0h, 00h, 00h, 00h, 00h, 00h, 00h
   326 00006C80 9C8E8F280096B9E3    <1>  	db	9Ch, 8Eh, 8Fh, 28h, 00h, 96h, 0B9h, 0E3h
   327 00006C88 FF                  <1> 	db	0FFh	; crtc regs
   328 00006C89 0001020304050607    <1> 	db	00h, 01h, 02h, 03h, 04h, 05h, 06h, 07h
   329 00006C91 1011121314151617    <1> 	db	10h, 11h, 12h, 13h, 14h, 15h, 16h, 17h
   330 00006C99 01000F00            <1> 	db	01h, 00h, 0Fh, 00h  ; actl regs
   331 00006C9D 000000000000050FFF  <1> 	db	00h, 00h, 00h, 00h, 00h, 00h, 05h, 0Fh, 0FFh ; grdc regs
   332                              <1> vga_mode_10h: ; mode 10h, 640*350, 16 colors, planar
   333 00006CA6 50180E0080          <1>  	db 	80, 24, 14, 00h, 80h ; tw, th-1, ch, slength
   334 00006CAB 010F0006            <1> 	db	01h, 0Fh, 00h, 06h ; sequ regs
   335 00006CAF A3                  <1> 	db 	0A3h	; misc reg
   336 00006CB0 5F4F50825480BF1F    <1> 	db	5Fh, 4Fh, 50h, 82h, 54h, 80h, 0BFh, 1Fh
   337 00006CB8 0040000000000000    <1> 	db	00h, 40h, 00h, 00h, 00h, 00h, 00h, 00h
   338 00006CC0 83855D280F63BAE3    <1>  	db	83h, 85h, 5Dh, 28h, 0Fh, 63h, 0BAh, 0E3h
   339 00006CC8 FF                  <1> 	db	0FFh	; crtc regs
   340 00006CC9 0001020304051407    <1> 	db	00h, 01h, 02h, 03h, 04h, 05h, 14h, 07h
   341 00006CD1 38393A3B3C3D3E3F    <1> 	db	38h, 39h, 3Ah, 3Bh, 3Ch, 3Dh, 3Eh, 3Fh
   342 00006CD9 01000F00            <1> 	db	01h, 00h, 0Fh, 00h  ; actl regs
   343 00006CDD 000000000000050FFF  <1> 	db	00h, 00h, 00h, 00h, 00h, 00h, 05h, 0Fh, 0FFh ; grdc regs
   344                              <1> vga_mode_11h: ; mode 11h, 640*480, mono color, planar
   345                              <1>  	; 11/11/2020
   346 00006CE6 501D1000A0          <1> 	db 	80, 29, 16, 00h, 0A0h ; tw, th-1, ch, slength
   347 00006CEB 010F0006            <1> 	db	01h, 0Fh, 00h, 06h ; sequ regs
   348 00006CEF E3                  <1> 	db 	0E3h	; misc reg
   349 00006CF0 5F4F508254800B3E    <1> 	db	5Fh, 4Fh, 50h, 82h, 54h, 80h, 0Bh, 3Eh
   350 00006CF8 0040000000000000    <1> 	db	00h, 40h, 00h, 00h, 00h, 00h, 00h, 00h
   351 00006D00 EA8CDF2800E704C3    <1>  	db	0EAh, 8Ch, 0DFh, 28h, 00h, 0E7h, 04h, 0C3h ; 11/11/2020
   352 00006D08 FF                  <1> 	db	0FFh	; crtc regs
   353 00006D09 003F003F003F003F    <1> 	db	00h, 3Fh, 00h, 3Fh, 00h, 3Fh, 00h, 3Fh
   354 00006D11 003F003F003F003F    <1> 	db	00h, 3Fh, 00h, 3Fh, 00h, 3Fh, 00h, 3Fh
   355 00006D19 01000F00            <1> 	db	01h, 00h, 0Fh, 00h  ; actl regs
   356 00006D1D 000000000000050FFF  <1> 	db	00h, 00h, 00h, 00h, 00h, 00h, 05h, 0Fh, 0FFh ; grdc regs
   357                              <1> end_of_vga_params:
   358                              <1> 
   359                              <1> ; /// End Of VIDEO DATA ///
   360                              <1> 
   361                              <1> ; 23/11/2020
   362                              <1> ; VBE 2 BOCHS/QEMU emulator extensions 
   363                              <1> ;	for TRDOS 386 v2 kernel (video bios)  
   364                              <1> 
   365                              <1> ; vbetables.h by Volker Rupper (02/01/2020)
   366                              <1> 
   367                              <1> b_vbe_modes:
   368                              <1> 	;/* standard VESA modes */	
   369 00006D26 0001800290010800    <1> 	dw 100h,  640, 400,  8
   370 00006D2E 01018002E0010800    <1> 	dw 101h,  640, 480,  8
   371 00006D36 0301200358020800    <1> 	dw 103h,  800, 600,  8
   372 00006D3E 0501000400030800    <1> 	dw 105h, 1024, 768,  8
   373 00006D46 0E014001C8001000    <1> 	dw 10Eh,  320, 200, 16
   374 00006D4E 0F014001C8001800    <1> 	dw 10Fh,  320, 200, 24
   375 00006D56 11018002E0011000    <1> 	dw 111h,  640, 480, 16
   376 00006D5E 12018002E0011800    <1> 	dw 112h,  640, 480, 24
   377 00006D66 1401200358021000    <1> 	dw 114h,  800, 600, 16
   378 00006D6E 1501200358021800    <1> 	dw 115h,  800, 600, 24
   379 00006D76 1701000400031000    <1> 	dw 117h, 1024, 768, 16
   380 00006D7E 1801000400031800    <1> 	dw 118h, 1024, 768, 24
   381                              <1> 
   382                              <1> ;/* BOCHS/PLEX86 'own' mode numbers */
   383 00006D86 40014001C8002000    <1> 	dw 140h,  320,  200, 32
   384 00006D8E 4101800290012000    <1> 	dw 141h,  640,  400, 32
   385 00006D96 42018002E0012000    <1> 	dw 142h,  640,  480, 32
   386 00006D9E 4301200358022000    <1> 	dw 143h,  800,  600, 32
   387 00006DA6 4401000400032000    <1> 	dw 144h, 1024,  768, 32
   388 00006DAE 46014001C8000800    <1> 	dw 146h,  320,  200,  8
   389 00006DB6 8D010005D0021000    <1> 	dw 18Dh, 1280,  720, 16
   390 00006DBE 8E010005D0021800    <1> 	dw 18Eh, 1280,  720, 24
   391 00006DC6 8F010005D0022000    <1> 	dw 18Fh, 1280,  720, 32
   392 00006DCE 9001800738041000    <1> 	dw 190h, 1920, 1080, 16
   393 00006DD6 9101800738041800    <1> 	dw 191h, 1920, 1080, 24
   394 00006DDE 9201800738042000    <1> 	dw 192h, 1920, 1080, 32
   395                              <1> 
   396                              <1> end_of_b_vbe_modes:
   397                              <1> 
   398                              <1> MA1 equ VBE_MODE_ATTRIBUTE_SUPPORTED
   399                              <1> MA2 equ VBE_MODE_ATTRIBUTE_EXTENDED_INFO_AVAILABLE
   400                              <1> MA3 equ VBE_MODE_ATTRIBUTE_COLOR_MODE
   401                              <1> MA4 equ VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE
   402                              <1> MA5 equ	VBE_MODE_ATTRIBUTE_GRAPHICS_MODE
   403                              <1> 
   404                              <1> MODE_ATTRIBUTES equ MA1|MA2|MA3|MA4|MA5
   405                              <1> 
   406                              <1> WA1 equ VBE_WINDOW_ATTRIBUTE_RELOCATABLE
   407                              <1> WA2 equ	VBE_WINDOW_ATTRIBUTE_READABLE
   408                              <1> WA3 equ VBE_WINDOW_ATTRIBUTE_WRITEABLE
   409                              <1> 
   410                              <1> WINA_ATTRIBUTES equ WA1|WA2|WA3
   411                              <1> 
   412                              <1> ; 24/11/2020
   413                              <1> 
   414                              <1> %if 0
   415                              <1> 
   416                              <1> MODE_INFO_LIST: 
   417                              <1> 
   418                              <1> ; 24/11/2020
   419                              <1> ; '%if 0' disables 24 mode info tables here, until %endif 
   420                              <1> ; ('set_mode_info_list' will set only 1 list for selected mode)
   421                              <1> ; (Purpose: To save about 1 KB kernel size by removing fixed data)
   422                              <1> 
   423                              <1> 			dw	0100h ; 640x400x8 
   424                              <1> ModeAttributes1: 	dw	MODE_ATTRIBUTES
   425                              <1> WinAAttributes1: 	db	WINA_ATTRIBUTES
   426                              <1> WinBAttributes1: 	db	0
   427                              <1> WinGranularity1: 	dw	VBE_DISPI_BANK_SIZE_KB
   428                              <1> WinSize1: 		dw	VBE_DISPI_BANK_SIZE_KB
   429                              <1> WinASegment1:		dw	VGAMEM_GRAPH
   430                              <1> WinBSegment1:		dw	0000h
   431                              <1> WinFuncPtr1:		dd	0
   432                              <1> BytesPerScanLine1: 	dw	640
   433                              <1> XResolution1:		dw	640
   434                              <1> YResolution1:		dw	400
   435                              <1> XCharSize1:		db	8
   436                              <1> YCharSize1:		db	16
   437                              <1> NumberOfPlanes1: 	db	1
   438                              <1> BitsPerPixel1:		db	8
   439                              <1> NumberOfBanks1:		db	4
   440                              <1> MemoryModel1:		db	VBE_MEMORYMODEL_PACKED_PIXEL
   441                              <1> BankSize1:		db	0
   442                              <1> NumberOfImagePages1: 	db	64
   443                              <1> Reserved_page1:		db	0
   444                              <1> RedMaskSize1:		db	0
   445                              <1> RedFieldPosition1: 	db	0
   446                              <1> GreenMaskSize1:		db	0
   447                              <1> GreenFieldPosition1: 	db	0
   448                              <1> BlueMaskSize1:		db	0
   449                              <1> BlueFieldPosition1: 	db	0
   450                              <1> RsvdMaskSize1: 		db	0
   451                              <1> RsvdFieldPosition1: 	db	0
   452                              <1> DirectColorModeInfo1: 	db	0
   453                              <1> PhysBasePtr1:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
   454                              <1> OffScreenMemOffset1: 	dd	0
   455                              <1> OffScreenMemSize1: 	dw	0
   456                              <1> LinBytesPerScanLine1: 	dw	640
   457                              <1> BnkNumberOfPages1: 	db	0
   458                              <1> LinNumberOfPages1: 	db	0
   459                              <1> LinRedMaskSize1:	db	0
   460                              <1> LinRedFieldPosition1: 	db	0
   461                              <1> LinGreenMaskSize1: 	db	0
   462                              <1> LinGreenFieldPosition1: db	0
   463                              <1> LinBlueMaskSize1: 	db	0
   464                              <1> LinBlueFieldPosition1: 	db	0
   465                              <1> LinRsvdMaskSize1: 	db	0
   466                              <1> LinRsvdFieldPosition1: 	db	0
   467                              <1> MaxPixelClock1:		dd	0
   468                              <1> 
   469                              <1> 			dw	0101h ; 640x480x8
   470                              <1> ModeAttributes2: 	dw	MODE_ATTRIBUTES
   471                              <1> WinAAttributes2: 	db	WINA_ATTRIBUTES
   472                              <1> WinBAttributes2: 	db	0
   473                              <1> WinGranularity2: 	dw	VBE_DISPI_BANK_SIZE_KB
   474                              <1> WinSize2: 		dw	VBE_DISPI_BANK_SIZE_KB
   475                              <1> WinASegment2:		dw	VGAMEM_GRAPH
   476                              <1> WinBSegment2:		dw	0000h
   477                              <1> WinFuncPtr2:		dd	0
   478                              <1> BytesPerScanLine2:	dw	640
   479                              <1> XResolution2:		dw	640
   480                              <1> YResolution2:		dw	480
   481                              <1> XCharSize2:		db	8
   482                              <1> YCharSize2:		db	16
   483                              <1> NumberOfPlanes2:	db	1
   484                              <1> BitsPerPixel2:		db	8
   485                              <1> NumberOfBanks2:		db	5
   486                              <1> MemoryModel2:		db	VBE_MEMORYMODEL_PACKED_PIXEL
   487                              <1> BankSize2:		db	0
   488                              <1> NumberOfImagePages2:	db	53
   489                              <1> Reserved_page2:		db	0
   490                              <1> RedMaskSize2:		db	0
   491                              <1> RedFieldPosition2:	db	0
   492                              <1> GreenMaskSize2:		db	0
   493                              <1> GreenFieldPosition2:	db	0
   494                              <1> BlueMaskSize2:		db	0
   495                              <1> BlueFieldPosition2:	db	0
   496                              <1> RsvdMaskSize2:		db	0
   497                              <1> RsvdFieldPosition2:	db	0
   498                              <1> DirectColorModeInfo2:	db	0
   499                              <1> PhysBasePtr2:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
   500                              <1> OffScreenMemOffset2:	dd	0
   501                              <1> OffScreenMemSize2:	dw	0
   502                              <1> LinBytesPerScanLine2:	dw	640
   503                              <1> BnkNumberOfPages2: 	db	0
   504                              <1> LinNumberOfPages2: 	db	0
   505                              <1> LinRedMaskSize2:	db	0
   506                              <1> LinRedFieldPosition2: 	db	0
   507                              <1> LinGreenMaskSize2: 	db	0
   508                              <1> LinGreenFieldPosition2: db	0
   509                              <1> LinBlueMaskSize2: 	db	0
   510                              <1> LinBlueFieldPosition2: 	db	0
   511                              <1> LinRsvdMaskSize2: 	db	0
   512                              <1> LinRsvdFieldPosition2: 	db	0
   513                              <1> MaxPixelClock2:		dd	0
   514                              <1> 			
   515                              <1> 			dw	0103h ; 800x600x8
   516                              <1> ModeAttributes3: 	dw	MODE_ATTRIBUTES
   517                              <1> WinAAttributes3: 	db	WINA_ATTRIBUTES
   518                              <1> WinBAttributes3: 	db	0
   519                              <1> WinGranularity3: 	dw	VBE_DISPI_BANK_SIZE_KB
   520                              <1> WinSize3: 		dw	VBE_DISPI_BANK_SIZE_KB
   521                              <1> WinASegment3:		dw	VGAMEM_GRAPH
   522                              <1> WinBSegment3:		dw	0000h
   523                              <1> WinFuncPtr3:		dd	0
   524                              <1> BytesPerScanLine3:	dw	800
   525                              <1> XResolution3:		dw	800
   526                              <1> YResolution3:		dw	600
   527                              <1> XCharSize3:		db	8
   528                              <1> YCharSize3:		db	16
   529                              <1> NumberOfPlanes3:	db	1
   530                              <1> BitsPerPixel3:		db	8
   531                              <1> NumberOfBanks3:		db	8
   532                              <1> MemoryModel3:		db	VBE_MEMORYMODEL_PACKED_PIXEL
   533                              <1> BankSize3:		db	0
   534                              <1> NumberOfImagePages3:	db	33
   535                              <1> Reserved_page3:		db	0
   536                              <1> RedMaskSize3:		db	0
   537                              <1> RedFieldPosition3:	db	0
   538                              <1> GreenMaskSize3:		db	0
   539                              <1> GreenFieldPosition3:	db	0
   540                              <1> BlueMaskSize3:		db	0
   541                              <1> BlueFieldPosition3:	db	0
   542                              <1> RsvdMaskSize3:		db	0
   543                              <1> RsvdFieldPosition3:	db	0
   544                              <1> DirectColorModeInfo3:	db	0
   545                              <1> PhysBasePtr3:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
   546                              <1> OffScreenMemOffset3:	dd	0
   547                              <1> OffScreenMemSize3:	dw	0
   548                              <1> LinBytesPerScanLine3:	dw	800
   549                              <1> BnkNumberOfPages3: 	db	0
   550                              <1> LinNumberOfPages3: 	db	0
   551                              <1> LinRedMaskSize3:	db	0
   552                              <1> LinRedFieldPosition3: 	db	0
   553                              <1> LinGreenMaskSize3: 	db	0
   554                              <1> LinGreenFieldPosition: 	db	0
   555                              <1> LinBlueMaskSize: 	db	0
   556                              <1> LinBlueFieldPosition: 	db	0
   557                              <1> LinRsvdMaskSize: 	db	0
   558                              <1> LinRsvdFieldPosition: 	db	0
   559                              <1> MaxPixelClock:		dd	0
   560                              <1> 			
   561                              <1> 			dw	0105h ; 1024x768x8
   562                              <1> ModeAttributes4: 	dw	MODE_ATTRIBUTES
   563                              <1> WinAAttributes4: 	db	WINA_ATTRIBUTES
   564                              <1> WinBAttributes4: 	db	0
   565                              <1> WinGranularity4: 	dw	VBE_DISPI_BANK_SIZE_KB
   566                              <1> WinSize4: 		dw	VBE_DISPI_BANK_SIZE_KB
   567                              <1> WinASegment4:		dw	VGAMEM_GRAPH
   568                              <1> WinBSegment4:		dw	0000h
   569                              <1> WinFuncPtr4:		dd	0
   570                              <1> BytesPerScanLine4:	dw	1024
   571                              <1> XResolution4:		dw	1024
   572                              <1> YResolution4:		dw	768
   573                              <1> XCharSize4:		db	8
   574                              <1> YCharSize4:		db	16
   575                              <1> NumberOfPlanes4:	db	1
   576                              <1> BitsPerPixel4:		db	8
   577                              <1> NumberOfBanks4:		db	12
   578                              <1> MemoryModel4:		db	VBE_MEMORYMODEL_PACKED_PIXEL
   579                              <1> BankSize4:		db	0
   580                              <1> NumberOfImagePages4:	db	20
   581                              <1> Reserved_page4:		db	0
   582                              <1> RedMaskSize4:		db	0
   583                              <1> RedFieldPosition4:	db	0
   584                              <1> GreenMaskSize4:		db	0
   585                              <1> GreenFieldPosition4:	db	0
   586                              <1> BlueMaskSize4:		db	0
   587                              <1> BlueFieldPosition4:	db	0
   588                              <1> RsvdMaskSize4:		db	0
   589                              <1> RsvdFieldPosition4:	db	0
   590                              <1> DirectColorModeInfo4:	db	0
   591                              <1> PhysBasePtr4:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
   592                              <1> OffScreenMemOffset4:	dd	0
   593                              <1> OffScreenMemSize4:	dw	0
   594                              <1> LinBytesPerScanLine4:	dw	1024
   595                              <1> BnkNumberOfPages4: 	db	0
   596                              <1> LinNumberOfPages4: 	db	0
   597                              <1> LinRedMaskSize4:	db	0
   598                              <1> LinRedFieldPosition4: 	db	0
   599                              <1> LinGreenMaskSize4: 	db	0
   600                              <1> LinGreenFieldPosition4: db	0
   601                              <1> LinBlueMaskSize4: 	db	0
   602                              <1> LinBlueFieldPosition4: 	db	0
   603                              <1> LinRsvdMaskSize4: 	db	0
   604                              <1> LinRsvdFieldPosition4: 	db	0
   605                              <1> MaxPixelClock4:		dd	0
   606                              <1> 
   607                              <1> 			dw	010Eh ; 320x200x16
   608                              <1> ModeAttributes5: 	dw	MODE_ATTRIBUTES
   609                              <1> WinAAttributes5: 	db	WINA_ATTRIBUTES
   610                              <1> WinBAttributes5: 	db	0
   611                              <1> WinGranularity5: 	dw	VBE_DISPI_BANK_SIZE_KB
   612                              <1> WinSize5: 		dw	VBE_DISPI_BANK_SIZE_KB
   613                              <1> WinASegment5:		dw	VGAMEM_GRAPH
   614                              <1> WinBSegment5:		dw	0000h
   615                              <1> WinFuncPtr5:		dd	0
   616                              <1> BytesPerScanLine5:	dw	640
   617                              <1> XResolution5:		dw	320
   618                              <1> YResolution5:		dw	200
   619                              <1> XCharSize5:		db	8
   620                              <1> YCharSize5:		db	16
   621                              <1> NumberOfPlanes5:	db	1
   622                              <1> BitsPerPixel5:		db	16
   623                              <1> NumberOfBanks5:		db	2
   624                              <1> MemoryModel5:		db	VBE_MEMORYMODEL_DIRECT_COLOR
   625                              <1> BankSize5:		db	0
   626                              <1> NumberOfImagePages5:	db	130
   627                              <1> Reserved_page5:		db	0
   628                              <1> RedMaskSize5:		db	5
   629                              <1> RedFieldPosition5:	db	11
   630                              <1> GreenMaskSize5:		db	6
   631                              <1> GreenFieldPosition5:	db	5
   632                              <1> BlueMaskSize5:		db	5
   633                              <1> BlueFieldPosition5:	db	0
   634                              <1> RsvdMaskSize5:		db	0
   635                              <1> RsvdFieldPosition5:	db	0
   636                              <1> DirectColorModeInfo5:	db	0
   637                              <1> PhysBasePtr5:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
   638                              <1> OffScreenMemOffset5:	dd	0
   639                              <1> OffScreenMemSize5:	dw	0
   640                              <1> LinBytesPerScanLine5:	dw	640
   641                              <1> BnkNumberOfPages5: 	db	0
   642                              <1> LinNumberOfPages5: 	db	0
   643                              <1> LinRedMaskSize5:	db	5
   644                              <1> LinRedFieldPosition5:	db	11
   645                              <1> LinGreenMaskSize5:	db	6
   646                              <1> LinGreenFieldPosition5:	db	5
   647                              <1> LinBlueMaskSize5:	db	5
   648                              <1> LinBlueFieldPosition5:	db	0
   649                              <1> LinRsvdMaskSize5:	db	0
   650                              <1> LinRsvdFieldPosition5:	db	0
   651                              <1> MaxPixelClock5:		dd	0
   652                              <1> 	
   653                              <1> 			dw	010Fh ; 320x200x24
   654                              <1> ModeAttributes6: 	dw	MODE_ATTRIBUTES
   655                              <1> WinAAttributes6: 	db	WINA_ATTRIBUTES
   656                              <1> WinBAttributes6: 	db	0
   657                              <1> WinGranularity6: 	dw	VBE_DISPI_BANK_SIZE_KB
   658                              <1> WinSize6: 		dw	VBE_DISPI_BANK_SIZE_KB
   659                              <1> WinASegment6:		dw	VGAMEM_GRAPH
   660                              <1> WinBSegment6:		dw	0000h
   661                              <1> WinFuncPtr6:		dd	0
   662                              <1> BytesPerScanLine6:	dw	960
   663                              <1> XResolution6:		dw	320
   664                              <1> YResolution6:		dw	200
   665                              <1> XCharSize6:		db	8
   666                              <1> YCharSize6:		db	16
   667                              <1> NumberOfPlanes6:	db	1
   668                              <1> BitsPerPixel6:		db	24
   669                              <1> NumberOfBanks6:		db	3
   670                              <1> MemoryModel6:		db	VBE_MEMORYMODEL_DIRECT_COLOR
   671                              <1> BankSize6:		db	0
   672                              <1> NumberOfImagePages6:	db	86
   673                              <1> Reserved_page6:		db	0
   674                              <1> RedMaskSize6:		db	8
   675                              <1> RedFieldPosition6:	db	16
   676                              <1> GreenMaskSize6:		db	8
   677                              <1> GreenFieldPosition6:	db	8
   678                              <1> BlueMaskSize6:		db	8
   679                              <1> BlueFieldPosition6:	db	0
   680                              <1> RsvdMaskSize6:		db	0
   681                              <1> RsvdFieldPosition6:	db	0
   682                              <1> DirectColorModeInfo6:	db	0
   683                              <1> PhysBasePtr6:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
   684                              <1> OffScreenMemOffset6:	dd	0
   685                              <1> OffScreenMemSize6:	dw	0
   686                              <1> LinBytesPerScanLine6:	dw	960
   687                              <1> BnkNumberOfPages6: 	db	0
   688                              <1> LinNumberOfPages6: 	db	0
   689                              <1> LinRedMaskSize6:	db	8
   690                              <1> LinRedFieldPosition6:	db	16
   691                              <1> LinGreenMaskSize6:	db	8
   692                              <1> LinGreenFieldPosition6:	db	8
   693                              <1> LinBlueMaskSize6:	db	8
   694                              <1> LinBlueFieldPosition6:	db	0
   695                              <1> LinRsvdMaskSize6:	db	0
   696                              <1> LinRsvdFieldPosition6:	db	0
   697                              <1> MaxPixelClock6:		dd	0
   698                              <1> 	
   699                              <1> 			dw	0111h ; 640x480x16
   700                              <1> ModeAttributes7: 	dw	MODE_ATTRIBUTES
   701                              <1> WinAAttributes7: 	db	WINA_ATTRIBUTES
   702                              <1> WinBAttributes7: 	db	0
   703                              <1> WinGranularity7: 	dw	VBE_DISPI_BANK_SIZE_KB
   704                              <1> WinSize7: 		dw	VBE_DISPI_BANK_SIZE_KB
   705                              <1> WinASegment7:		dw	VGAMEM_GRAPH
   706                              <1> WinBSegment7:		dw	0000h
   707                              <1> WinFuncPtr7:		dd	0
   708                              <1> BytesPerScanLine7:	dw	1280
   709                              <1> XResolution7:		dw	640
   710                              <1> YResolution7:		dw	480
   711                              <1> XCharSize7:		db	8
   712                              <1> YCharSize7:		db	16
   713                              <1> NumberOfPlanes7:	db	1
   714                              <1> BitsPerPixel7:		db	16
   715                              <1> NumberOfBanks7:		db	10
   716                              <1> MemoryModel7:		db	VBE_MEMORYMODEL_DIRECT_COLOR
   717                              <1> BankSize7:		db	0
   718                              <1> NumberOfImagePages7:	db	26
   719                              <1> Reserved_page7:		db	0
   720                              <1> RedMaskSize7:		db	5
   721                              <1> RedFieldPosition7:	db	11
   722                              <1> GreenMaskSize7:		db	6
   723                              <1> GreenFieldPosition7:	db	5
   724                              <1> BlueMaskSize7:		db	5
   725                              <1> BlueFieldPosition7:	db	0
   726                              <1> RsvdMaskSize7:		db	0
   727                              <1> RsvdFieldPosition7:	db	0
   728                              <1> DirectColorModeInfo7:	db	0
   729                              <1> PhysBasePtr7:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS,
   730                              <1> OffScreenMemOffset7:	dd	0
   731                              <1> OffScreenMemSize7:	dw	0
   732                              <1> LinBytesPerScanLine7:	dw	1280
   733                              <1> BnkNumberOfPages7: 	db	0
   734                              <1> LinNumberOfPages7: 	db	0
   735                              <1> LinRedMaskSize7:	db	5
   736                              <1> LinRedFieldPosition7:	db	11
   737                              <1> LinGreenMaskSize7:	db	6
   738                              <1> LinGreenFieldPosition7:	db	5
   739                              <1> LinBlueMaskSize7:	db	5
   740                              <1> LinBlueFieldPosition7:	db	0
   741                              <1> LinRsvdMaskSize7:	db	0
   742                              <1> LinRsvdFieldPosition7:	db	0
   743                              <1> MaxPixelClock7:		dd	0
   744                              <1> 
   745                              <1> 			dw	0112h ; 640x480x24
   746                              <1> ModeAttributes8: 	dw	MODE_ATTRIBUTES
   747                              <1> WinAAttributes8: 	db	WINA_ATTRIBUTES
   748                              <1> WinBAttributes8: 	db	0
   749                              <1> WinGranularity8: 	dw	VBE_DISPI_BANK_SIZE_KB
   750                              <1> WinSize8: 		dw	VBE_DISPI_BANK_SIZE_KB
   751                              <1> WinASegment8:		dw	VGAMEM_GRAPH
   752                              <1> WinBSegment8:		dw	0000h
   753                              <1> WinFuncPtr8:		dd	0
   754                              <1> BytesPerScanLine8:	dw	1920
   755                              <1> XResolution8:		dw	640
   756                              <1> YResolution8:		dw	480
   757                              <1> XCharSize8:		db	8
   758                              <1> YCharSize8:		db	16
   759                              <1> NumberOfPlanes8:	db	1
   760                              <1> BitsPerPixel8:		db	24
   761                              <1> NumberOfBanks8:		db	15
   762                              <1> MemoryModel8:		db	VBE_MEMORYMODEL_DIRECT_COLOR
   763                              <1> BankSize8:		db	0
   764                              <1> NumberOfImagePages8:	db	17
   765                              <1> Reserved_page8:		db	0
   766                              <1> RedMaskSize8:		db	8
   767                              <1> RedFieldPosition8:	db	16
   768                              <1> GreenMaskSize8:		db	8
   769                              <1> GreenFieldPosition8:	db	8
   770                              <1> BlueMaskSize8:		db	8
   771                              <1> BlueFieldPosition8:	db	0
   772                              <1> RsvdMaskSize8:		db	0
   773                              <1> RsvdFieldPosition8:	db	0
   774                              <1> DirectColorModeInfo8:	db	0
   775                              <1> PhysBasePtr8:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
   776                              <1> OffScreenMemOffset8:	dd	0
   777                              <1> OffScreenMemSize8:	dw	0
   778                              <1> LinBytesPerScanLine8:	dw	1920
   779                              <1> BnkNumberOfPages8: 	db	0
   780                              <1> LinNumberOfPages8: 	db	0
   781                              <1> LinRedMaskSize8:	db	8
   782                              <1> LinRedFieldPosition8:	db	16
   783                              <1> LinGreenMaskSize8:	db	8
   784                              <1> LinGreenFieldPosition8:	db	8
   785                              <1> LinBlueMaskSize8:	db	8
   786                              <1> LinBlueFieldPosition8:	db	0
   787                              <1> LinRsvdMaskSize8:	db	0
   788                              <1> LinRsvdFieldPosition8:	db	0
   789                              <1> MaxPixelClock8:		dd	0
   790                              <1> 
   791                              <1> 			dw	0114h ; 800x600x16
   792                              <1> ModeAttributes9: 	dw	MODE_ATTRIBUTES
   793                              <1> WinAAttributes9: 	db	WINA_ATTRIBUTES
   794                              <1> WinBAttributes9: 	db	0
   795                              <1> WinGranularity9: 	dw	VBE_DISPI_BANK_SIZE_KB
   796                              <1> WinSize9: 		dw	VBE_DISPI_BANK_SIZE_KB
   797                              <1> WinASegment9:		dw	VGAMEM_GRAPH
   798                              <1> WinBSegment9:		dw	0000h
   799                              <1> WinFuncPtr9:		dd	0
   800                              <1> BytesPerScanLine9:	dw	1600
   801                              <1> XResolution9:		dw	800
   802                              <1> YResolution9:		dw	600
   803                              <1> XCharSize9:		db	8
   804                              <1> YCharSize9:		db	16
   805                              <1> NumberOfPlanes9:	db	1
   806                              <1> BitsPerPixel9:		db	16
   807                              <1> NumberOfBanks9:		db	15
   808                              <1> MemoryModel9:		db	VBE_MEMORYMODEL_DIRECT_COLOR
   809                              <1> BankSize9:		db	0
   810                              <1> NumberOfImagePages9:	db	16
   811                              <1> Reserved_page9:		db	0
   812                              <1> RedMaskSize9:		db	5
   813                              <1> RedFieldPosition9:	db	11
   814                              <1> GreenMaskSize9:		db	6
   815                              <1> GreenFieldPosition9:	db	5
   816                              <1> BlueMaskSize9:		db	5
   817                              <1> BlueFieldPosition9:	db	0
   818                              <1> RsvdMaskSize9:		db	0
   819                              <1> RsvdFieldPosition9:	db	0
   820                              <1> DirectColorModeInfo9:	db	0
   821                              <1> PhysBasePtr9:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
   822                              <1> OffScreenMemOffset9:	dd	0
   823                              <1> OffScreenMemSize9:	dw	0
   824                              <1> LinBytesPerScanLine9:	dw	1600
   825                              <1> BnkNumberOfPages9: 	db	0
   826                              <1> LinNumberOfPages9: 	db	0
   827                              <1> LinRedMaskSize9:	db	5
   828                              <1> LinRedFieldPosition9:	db	11
   829                              <1> LinGreenMaskSize9:	db	6
   830                              <1> LinGreenFieldPosition9:	db	5
   831                              <1> LinBlueMaskSize9:	db	5
   832                              <1> LinBlueFieldPosition9:	db	0
   833                              <1> LinRsvdMaskSize9:	db	0
   834                              <1> LinRsvdFieldPosition9:	db	0
   835                              <1> MaxPixelClock9:		dd	0
   836                              <1> 	
   837                              <1> 			dw	0115h ; 800x600x24
   838                              <1> ModeAttributes10: 	dw	MODE_ATTRIBUTES
   839                              <1> WinAAttributes10: 	db	WINA_ATTRIBUTES
   840                              <1> WinBAttributes10: 	db	0
   841                              <1> WinGranularity10: 	dw	VBE_DISPI_BANK_SIZE_KB
   842                              <1> WinSize10: 		dw	VBE_DISPI_BANK_SIZE_KB
   843                              <1> WinASegment10:		dw	VGAMEM_GRAPH
   844                              <1> WinBSegment10:		dw	0000h
   845                              <1> WinFuncPtr10:		dd	0
   846                              <1> BytesPerScanLine10:	dw	2400
   847                              <1> XResolution10:		dw	800
   848                              <1> YResolution10:		dw	600
   849                              <1> XCharSize10:		db	8
   850                              <1> YCharSize10:		db	16
   851                              <1> NumberOfPlanes10:	db	1
   852                              <1> BitsPerPixel10:		db	24
   853                              <1> NumberOfBanks10:	db	22
   854                              <1> MemoryModel10:		db	VBE_MEMORYMODEL_DIRECT_COLOR
   855                              <1> BankSize10:		db	0
   856                              <1> NumberOfImagePages10:	db	10
   857                              <1> Reserved_page10:	db	0
   858                              <1> RedMaskSize10:		db	8
   859                              <1> RedFieldPosition10:	db	16
   860                              <1> GreenMaskSize10:	db	8
   861                              <1> GreenFieldPosition10:	db	8
   862                              <1> BlueMaskSize10:		db	8
   863                              <1> BlueFieldPosition10:	db	0
   864                              <1> RsvdMaskSize10:		db	0
   865                              <1> RsvdFieldPosition10:	db	0
   866                              <1> DirectColorModeInfo10:	db	0
   867                              <1> PhysBasePtr10:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
   868                              <1> OffScreenMemOffset10:	dd	0
   869                              <1> OffScreenMemSize10:	dw	0
   870                              <1> LinBytesPerScanLine10:	dw	2400
   871                              <1> BnkNumberOfPages10: 	db	0
   872                              <1> LinNumberOfPages10: 	db	0
   873                              <1> LinRedMaskSize10:	db	8
   874                              <1> LinRedFieldPosition10:	db	16
   875                              <1> LinGreenMaskSize10:	db	8
   876                              <1> LinGreenFieldPosition10:db	8
   877                              <1> LinBlueMaskSize10:	db	8
   878                              <1> LinBlueFieldPosition10:	db	0
   879                              <1> LinRsvdMaskSize10:	db	0
   880                              <1> LinRsvdFieldPosition10:	db	0
   881                              <1> MaxPixelClock10:	dd	0
   882                              <1> 
   883                              <1> 			dw	0117h ; 1024x768x16
   884                              <1> ModeAttributes11: 	dw	MODE_ATTRIBUTES
   885                              <1> WinAAttributes11: 	db	WINA_ATTRIBUTES
   886                              <1> WinBAttributes11: 	db	0
   887                              <1> WinGranularity11: 	dw	VBE_DISPI_BANK_SIZE_KB
   888                              <1> WinSize11: 		dw	VBE_DISPI_BANK_SIZE_KB
   889                              <1> WinASegment11:		dw	VGAMEM_GRAPH
   890                              <1> WinBSegment11:		dw	0000h
   891                              <1> WinFuncPtr11:		dd	0
   892                              <1> BytesPerScanLine11:	dw	2048
   893                              <1> XResolution11:		dw	1024
   894                              <1> YResolution11:		dw	768
   895                              <1> XCharSize11:		db	8
   896                              <1> YCharSize11:		db	16
   897                              <1> NumberOfPlanes11:	db	1
   898                              <1> BitsPerPixel11:		db	16
   899                              <1> NumberOfBanks11:	db	24
   900                              <1> MemoryModel11:		db	VBE_MEMORYMODEL_DIRECT_COLOR
   901                              <1> BankSize11:		db	0
   902                              <1> NumberOfImagePages11:	db	9
   903                              <1> Reserved_page11:	db	0
   904                              <1> RedMaskSize11:		db	5
   905                              <1> RedFieldPosition11:	db	11
   906                              <1> GreenMaskSize11:	db	6
   907                              <1> GreenFieldPosition11:	db	5
   908                              <1> BlueMaskSize11:		db	5
   909                              <1> BlueFieldPosition11:	db	0
   910                              <1> RsvdMaskSize11:		db	0
   911                              <1> RsvdFieldPosition11:	db	0
   912                              <1> DirectColorModeInfo11:	db	0
   913                              <1> PhysBasePtr11:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS,
   914                              <1> OffScreenMemOffset11:	dd	0
   915                              <1> OffScreenMemSize11:	dw	0
   916                              <1> LinBytesPerScanLine11:	dw	2048
   917                              <1> BnkNumberOfPages11: 	db	0
   918                              <1> LinNumberOfPages11: 	db	0
   919                              <1> LinRedMaskSize11:	db	5
   920                              <1> LinRedFieldPosition11:	db	11
   921                              <1> LinGreenMaskSize11:	db	6
   922                              <1> LinGreenFieldPosition11:db	5
   923                              <1> LinBlueMaskSize11:	db	5
   924                              <1> LinBlueFieldPosition11:	db	0
   925                              <1> LinRsvdMaskSize11:	db	0
   926                              <1> LinRsvdFieldPosition11:	db	0
   927                              <1> MaxPixelClock11:	dd	0
   928                              <1> 
   929                              <1> 			dw	0118h ; 1024x768x24
   930                              <1> ModeAttributes12: 	dw	MODE_ATTRIBUTES
   931                              <1> WinAAttributes12: 	db	WINA_ATTRIBUTES
   932                              <1> WinBAttributes12: 	db	0
   933                              <1> WinGranularity12: 	dw	VBE_DISPI_BANK_SIZE_KB
   934                              <1> WinSize12: 		dw	VBE_DISPI_BANK_SIZE_KB
   935                              <1> WinASegment12:		dw	VGAMEM_GRAPH
   936                              <1> WinBSegment12:		dw	0000h
   937                              <1> WinFuncPtr12:		dd	0
   938                              <1> BytesPerScanLine12:	dw	3072
   939                              <1> XResolution12:		dw	1024
   940                              <1> YResolution12:		dw	768
   941                              <1> XCharSize12:		db	8
   942                              <1> YCharSize12:		db	16
   943                              <1> NumberOfPlanes12:	db	1
   944                              <1> BitsPerPixel12:		db	24
   945                              <1> NumberOfBanks12:	db	36
   946                              <1> MemoryModel12:		db	VBE_MEMORYMODEL_DIRECT_COLOR
   947                              <1> BankSize12:		db	0
   948                              <1> NumberOfImagePages12:	db	6
   949                              <1> Reserved_page12:	db	0
   950                              <1> RedMaskSize12:		db	8
   951                              <1> RedFieldPosition12:	db	16
   952                              <1> GreenMaskSize12:	db	8
   953                              <1> GreenFieldPosition12:	db	8
   954                              <1> BlueMaskSize12:		db	8
   955                              <1> BlueFieldPosition12:	db	0
   956                              <1> RsvdMaskSize12:		db	0
   957                              <1> RsvdFieldPosition12:	db	0
   958                              <1> DirectColorModeInfo12:	db	0
   959                              <1> PhysBasePtr12:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
   960                              <1> OffScreenMemOffset12:	dd	0
   961                              <1> OffScreenMemSize12:	dw	0
   962                              <1> LinBytesPerScanLine12:	dw	3072
   963                              <1> BnkNumberOfPages12: 	db	0
   964                              <1> LinNumberOfPages12: 	db	0
   965                              <1> LinRedMaskSize12:	db	8
   966                              <1> LinRedFieldPosition12:	db	16
   967                              <1> LinGreenMaskSize12:	db	8
   968                              <1> LinGreenFieldPosition12:db	8
   969                              <1> LinBlueMaskSize12:	db	8
   970                              <1> LinBlueFieldPosition12:	db	0
   971                              <1> LinRsvdMaskSize12:	db	0
   972                              <1> LinRsvdFieldPosition12:	db	0
   973                              <1> MaxPixelClock12:	dd	0
   974                              <1> 
   975                              <1> 			dw	0140h ; 320x200x32
   976                              <1> ModeAttributes13: 	dw	MODE_ATTRIBUTES
   977                              <1> WinAAttributes13: 	db	WINA_ATTRIBUTES
   978                              <1> WinBAttributes13: 	db	0
   979                              <1> WinGranularity13: 	dw	VBE_DISPI_BANK_SIZE_KB
   980                              <1> WinSize13: 		dw	VBE_DISPI_BANK_SIZE_KB
   981                              <1> WinASegment13:		dw	VGAMEM_GRAPH
   982                              <1> WinBSegment13:		dw	0000h
   983                              <1> WinFuncPtr13:		dd	0
   984                              <1> BytesPerScanLine13:	dw	1280
   985                              <1> XResolution13:		dw	320
   986                              <1> YResolution13:		dw	200
   987                              <1> XCharSize13:		db	8
   988                              <1> YCharSize13:		db	16
   989                              <1> NumberOfPlanes13:	db	1
   990                              <1> BitsPerPixel13:		db	32
   991                              <1> NumberOfBanks13:	db	4
   992                              <1> MemoryModel13:		db	VBE_MEMORYMODEL_DIRECT_COLOR
   993                              <1> BankSize13:		db	0
   994                              <1> NumberOfImagePages13:	db	64
   995                              <1> Reserved_page13:	db	0
   996                              <1> RedMaskSize13:		db	8
   997                              <1> RedFieldPosition13:	db	16
   998                              <1> GreenMaskSize13:	db	8
   999                              <1> GreenFieldPosition13:	db	8
  1000                              <1> BlueMaskSize13:		db	8
  1001                              <1> BlueFieldPosition13:	db	0
  1002                              <1> RsvdMaskSize13:		db	8
  1003                              <1> RsvdFieldPosition13:	db	24
  1004                              <1> DirectColorModeInfo13:	db	VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE
  1005                              <1> PhysBasePtr13:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
  1006                              <1> OffScreenMemOffset13:	dd	0
  1007                              <1> OffScreenMemSize13:	dw	0
  1008                              <1> LinBytesPerScanLine13:	dw	1280
  1009                              <1> BnkNumberOfPages13: 	db	0
  1010                              <1> LinNumberOfPages13: 	db	0
  1011                              <1> LinRedMaskSize13:	db	8
  1012                              <1> LinRedFieldPosition13:	db	16
  1013                              <1> LinGreenMaskSize13:	db	8
  1014                              <1> LinGreenFieldPosition13:db	8
  1015                              <1> LinBlueMaskSize13:	db	8
  1016                              <1> LinBlueFieldPosition13:	db	0
  1017                              <1> LinRsvdMaskSize13:	db	8
  1018                              <1> LinRsvdFieldPosition13:	db	24
  1019                              <1> MaxPixelClock13:	dd	0
  1020                              <1> 
  1021                              <1> 			dw	0141h ; 640x400x32
  1022                              <1> ModeAttributes14: 	dw	MODE_ATTRIBUTES
  1023                              <1> WinAAttributes14: 	db	WINA_ATTRIBUTES
  1024                              <1> WinBAttributes14: 	db	0
  1025                              <1> WinGranularity14: 	dw	VBE_DISPI_BANK_SIZE_KB
  1026                              <1> WinSize14: 		dw	VBE_DISPI_BANK_SIZE_KB
  1027                              <1> WinASegment14:		dw	VGAMEM_GRAPH
  1028                              <1> WinBSegment14:		dw	0000h
  1029                              <1> WinFuncPtr14:		dd	0
  1030                              <1> BytesPerScanLine14:	dw	2560
  1031                              <1> XResolution14:		dw	640
  1032                              <1> YResolution14:		dw	400
  1033                              <1> XCharSize14:		db	8
  1034                              <1> YCharSize14:		db	16
  1035                              <1> NumberOfPlanes14:	db	1
  1036                              <1> BitsPerPixel14:		db	32
  1037                              <1> NumberOfBanks14:	db	16
  1038                              <1> MemoryModel14:		db	VBE_MEMORYMODEL_DIRECT_COLOR
  1039                              <1> BankSize14:		db	0
  1040                              <1> NumberOfImagePages14:	db	15
  1041                              <1> Reserved_page14:	db	0
  1042                              <1> RedMaskSize14:		db	8
  1043                              <1> RedFieldPosition14:	db	16
  1044                              <1> GreenMaskSize14:	db	8
  1045                              <1> GreenFieldPosition14:	db	8
  1046                              <1> BlueMaskSize14:		db	8
  1047                              <1> BlueFieldPosition14:	db	0
  1048                              <1> RsvdMaskSize14:		db	8
  1049                              <1> RsvdFieldPosition14:	db	24
  1050                              <1> DirectColorModeInfo14:	db	VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE
  1051                              <1> PhysBasePtr14:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
  1052                              <1> OffScreenMemOffset14:	dd  	0
  1053                              <1> OffScreenMemSize14:	dw	0
  1054                              <1> LinBytesPerScanLine14:	dw	2560
  1055                              <1> BnkNumberOfPages14: 	db	0
  1056                              <1> LinNumberOfPages14: 	db	0
  1057                              <1> LinRedMaskSize14:	db	8
  1058                              <1> LinRedFieldPosition14:	db	16
  1059                              <1> LinGreenMaskSize14:	db	8
  1060                              <1> LinGreenFieldPosition14:db	8
  1061                              <1> LinBlueMaskSize14:	db	8
  1062                              <1> LinBlueFieldPosition14:	db	0
  1063                              <1> LinRsvdMaskSize14:	db	8
  1064                              <1> LinRsvdFieldPosition14:	db	24
  1065                              <1> MaxPixelClock14:	dd	0
  1066                              <1> 
  1067                              <1> 			dw	0142 ; 640x480x32
  1068                              <1> ModeAttributes15: 	dw	MODE_ATTRIBUTES
  1069                              <1> WinAAttributes15: 	db	WINA_ATTRIBUTES
  1070                              <1> WinBAttributes15: 	db	0
  1071                              <1> WinGranularity15: 	dw	VBE_DISPI_BANK_SIZE_KB
  1072                              <1> WinSize15: 		dw	VBE_DISPI_BANK_SIZE_KB
  1073                              <1> WinASegment15:		dw	VGAMEM_GRAPH
  1074                              <1> WinBSegment15:		dw	0000h
  1075                              <1> WinFuncPtr15:		dd	0
  1076                              <1> BytesPerScanLine15:	dw	2560
  1077                              <1> XResolution15:		dw	640
  1078                              <1> YResolution15:		dw	480
  1079                              <1> XCharSize15:		db	8
  1080                              <1> YCharSize15:		db	16
  1081                              <1> NumberOfPlanes15:	db	1
  1082                              <1> BitsPerPixel15:		db	32
  1083                              <1> NumberOfBanks15:	db	19
  1084                              <1> MemoryModel15:		db	VBE_MEMORYMODEL_DIRECT_COLOR
  1085                              <1> BankSize15:		db	0
  1086                              <1> NumberOfImagePages15:	db	12
  1087                              <1> Reserved_page15:	db	0
  1088                              <1> RedMaskSize15:		db	8
  1089                              <1> RedFieldPosition15:	db	16
  1090                              <1> GreenMaskSize15:	db	8
  1091                              <1> GreenFieldPosition15:	db	8
  1092                              <1> BlueMaskSize15:		db	8
  1093                              <1> BlueFieldPosition15:	db	0
  1094                              <1> RsvdMaskSize15:		db	8
  1095                              <1> RsvdFieldPosition15:	db	24
  1096                              <1> DirectColorModeInfo15:	db	VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE,
  1097                              <1> PhysBasePtr15:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS,
  1098                              <1> OffScreenMemOffset15:	dd	0
  1099                              <1> OffScreenMemSize15:	dw	0
  1100                              <1> LinBytesPerScanLine15:	dw	2560
  1101                              <1> BnkNumberOfPages15: 	db	0
  1102                              <1> LinNumberOfPages15: 	db	0
  1103                              <1> LinRedMaskSize15:	db	8
  1104                              <1> LinRedFieldPosition15:	db	16
  1105                              <1> LinGreenMaskSize15:	db	8
  1106                              <1> LinGreenFieldPosition15:db	8
  1107                              <1> LinBlueMaskSize15:	db	8
  1108                              <1> LinBlueFieldPosition15:	db	0
  1109                              <1> LinRsvdMaskSize15:	db	8
  1110                              <1> LinRsvdFieldPosition15:	db	24
  1111                              <1> MaxPixelClock15:	dd	0
  1112                              <1> 
  1113                              <1> 			dw	0143h ; 800x600x32
  1114                              <1> ModeAttributes16: 	dw	MODE_ATTRIBUTES
  1115                              <1> WinAAttributes16: 	db	WINA_ATTRIBUTES
  1116                              <1> WinBAttributes16: 	db	0
  1117                              <1> WinGranularity16: 	dw	VBE_DISPI_BANK_SIZE_KB
  1118                              <1> WinSize16: 		dw	VBE_DISPI_BANK_SIZE_KB
  1119                              <1> WinASegment16:		dw	VGAMEM_GRAPH
  1120                              <1> WinBSegment16:		dw	0000h
  1121                              <1> WinFuncPtr16:		dd	0
  1122                              <1> BytesPerScanLine16:	dw	3200
  1123                              <1> XResolution16:		dw	800
  1124                              <1> YResolution16:		dw	600
  1125                              <1> XCharSize16:		db	8
  1126                              <1> YCharSize16:		db	16
  1127                              <1> NumberOfPlanes16:	db	1
  1128                              <1> BitsPerPixel16:		db	32
  1129                              <1> NumberOfBanks16:	db	30
  1130                              <1> MemoryModel16:		db	VBE_MEMORYMODEL_DIRECT_COLOR
  1131                              <1> BankSize16:		db	0
  1132                              <1> NumberOfImagePages16:	db	7
  1133                              <1> Reserved_page16:	db	0
  1134                              <1> RedMaskSize16:		db	8
  1135                              <1> RedFieldPosition16:	db	16
  1136                              <1> GreenMaskSize16:	db	8
  1137                              <1> GreenFieldPosition16:	db	8
  1138                              <1> BlueMaskSize16:		db	8
  1139                              <1> BlueFieldPosition16:	db	0
  1140                              <1> RsvdMaskSize16:		db	8
  1141                              <1> RsvdFieldPosition16:	db	24
  1142                              <1> DirectColorModeInfo16:	db	VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE,
  1143                              <1> PhysBasePtr16:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS,
  1144                              <1> OffScreenMemOffset16:	dd	0
  1145                              <1> OffScreenMemSize16:	dw	0
  1146                              <1> LinBytesPerScanLine16:	dw	3200
  1147                              <1> BnkNumberOfPages16: 	db	0
  1148                              <1> LinNumberOfPages16: 	db	0
  1149                              <1> LinRedMaskSize16:	db	8
  1150                              <1> LinRedFieldPosition16:	db	16
  1151                              <1> LinGreenMaskSize16:	db	8
  1152                              <1> LinGreenFieldPosition16:db	8
  1153                              <1> LinBlueMaskSize16:	db	8
  1154                              <1> LinBlueFieldPosition16:	db	0
  1155                              <1> LinRsvdMaskSize16:	db	8
  1156                              <1> LinRsvdFieldPosition16:	db	24
  1157                              <1> MaxPixelClock16:	dd	0
  1158                              <1> 	
  1159                              <1> 			dw	0144h ; 1024x768x32
  1160                              <1> ModeAttributes17: 	dw	MODE_ATTRIBUTES
  1161                              <1> WinAAttributes17: 	db	WINA_ATTRIBUTES
  1162                              <1> WinBAttributes17: 	db	0
  1163                              <1> WinGranularity17: 	dw	VBE_DISPI_BANK_SIZE_KB
  1164                              <1> WinSize17: 		dw	VBE_DISPI_BANK_SIZE_KB
  1165                              <1> WinASegment17:		dw	VGAMEM_GRAPH
  1166                              <1> WinBSegment17:		dw	0000h
  1167                              <1> WinFuncPtr17:		dd	0
  1168                              <1> BytesPerScanLine17:	dw	4096
  1169                              <1> XResolution17:		dw	1024
  1170                              <1> YResolution17:		dw	768
  1171                              <1> XCharSize17:		db	8
  1172                              <1> YCharSize17:		db	16
  1173                              <1> NumberOfPlanes17:	db	1
  1174                              <1> BitsPerPixel17:		db	32
  1175                              <1> NumberOfBanks17:	db	48
  1176                              <1> MemoryModel17:		db	VBE_MEMORYMODEL_DIRECT_COLOR
  1177                              <1> BankSize17:		db	0
  1178                              <1> NumberOfImagePages17:	db	4
  1179                              <1> Reserved_page17:	db	0
  1180                              <1> RedMaskSize17:		db	8
  1181                              <1> RedFieldPosition17:	db	16
  1182                              <1> GreenMaskSize17:	db	8
  1183                              <1> GreenFieldPosition17:	db	8
  1184                              <1> BlueMaskSize17:		db	8
  1185                              <1> BlueFieldPosition17:	db	0
  1186                              <1> RsvdMaskSize17:		db	8
  1187                              <1> RsvdFieldPosition17:	db	24
  1188                              <1> DirectColorModeInfo17:	db	VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE
  1189                              <1> PhysBasePtr17:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
  1190                              <1> OffScreenMemOffset17:	dd	0
  1191                              <1> OffScreenMemSize17:	dw	0
  1192                              <1> LinBytesPerScanLine17:	dw	4096
  1193                              <1> BnkNumberOfPages17: 	db	0
  1194                              <1> LinNumberOfPages17: 	db	0
  1195                              <1> LinRedMaskSize17:	db	8
  1196                              <1> LinRedFieldPosition17:	db	16
  1197                              <1> LinGreenMaskSize17:	db	8
  1198                              <1> LinGreenFieldPosition17:db	8
  1199                              <1> LinBlueMaskSize17:	db	8
  1200                              <1> LinBlueFieldPosition17:	db	0
  1201                              <1> LinRsvdMaskSize17:	db	8
  1202                              <1> LinRsvdFieldPosition17:	db	24
  1203                              <1> MaxPixelClock17:	dd	0
  1204                              <1> 	
  1205                              <1> 			dw	0146h ; 320x200x8
  1206                              <1> ModeAttributes18: 	dw	MODE_ATTRIBUTES
  1207                              <1> WinAAttributes18: 	db	WINA_ATTRIBUTES
  1208                              <1> WinBAttributes18: 	db	0
  1209                              <1> WinGranularity18: 	dw	VBE_DISPI_BANK_SIZE_KB
  1210                              <1> WinSize18: 		dw	VBE_DISPI_BANK_SIZE_KB
  1211                              <1> WinASegment18:		dw	VGAMEM_GRAPH
  1212                              <1> WinBSegment18:		dw	0000h
  1213                              <1> WinFuncPtr18:		dd	0
  1214                              <1> BytesPerScanLine18:	dw	320
  1215                              <1> XResolution18:		dw	320
  1216                              <1> YResolution18:		dw	200
  1217                              <1> XCharSize18:		db	8
  1218                              <1> YCharSize18:		db	16
  1219                              <1> NumberOfPlanes18:	db	1
  1220                              <1> BitsPerPixel18:		db	8
  1221                              <1> NumberOfBanks18:	db	1
  1222                              <1> MemoryModel18:		db	VBE_MEMORYMODEL_PACKED_PIXEL
  1223                              <1> BankSize18:		db	0
  1224                              <1> NumberOfImagePages18:	db	255 ; 261 in vbetables.h (03/01/2020) !
  1225                              <1> Reserved_page18:	db	0
  1226                              <1> RedMaskSize18:		db	0
  1227                              <1> RedFieldPosition18:	db	0
  1228                              <1> GreenMaskSize18:	db	0
  1229                              <1> GreenFieldPosition18:	db	0
  1230                              <1> BlueMaskSize18:		db	0
  1231                              <1> BlueFieldPosition18:	db	0
  1232                              <1> RsvdMaskSize18:		db	0
  1233                              <1> RsvdFieldPosition18:	db	0
  1234                              <1> DirectColorModeInfo18:	db	0
  1235                              <1> PhysBasePtr18:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
  1236                              <1> OffScreenMemOffset18:	dd	0
  1237                              <1> OffScreenMemSize18:	dw	0
  1238                              <1> LinBytesPerScanLine18:	dw	320
  1239                              <1> BnkNumberOfPages18: 	db	0
  1240                              <1> LinNumberOfPages18: 	db	0
  1241                              <1> LinRedMaskSize18:	db	0
  1242                              <1> LinRedFieldPosition18: 	db	0
  1243                              <1> LinGreenMaskSize18: 	db	0
  1244                              <1> LinGreenFieldPosition18:db	0
  1245                              <1> LinBlueMaskSize18: 	db	0
  1246                              <1> LinBlueFieldPosition18: db	0
  1247                              <1> LinRsvdMaskSize18: 	db	0
  1248                              <1> LinRsvdFieldPosition18: db	0
  1249                              <1> MaxPixelClock18:	dd	0
  1250                              <1> 
  1251                              <1> 			dw	018Dh ; 1280x720x16
  1252                              <1> ModeAttributes19: 	dw	MODE_ATTRIBUTES
  1253                              <1> WinAAttributes19: 	db	WINA_ATTRIBUTES
  1254                              <1> WinBAttributes19: 	db	0
  1255                              <1> WinGranularity19: 	dw	VBE_DISPI_BANK_SIZE_KB
  1256                              <1> WinSize19: 		dw	VBE_DISPI_BANK_SIZE_KB
  1257                              <1> WinASegment19:		dw	VGAMEM_GRAPH
  1258                              <1> WinBSegment19:		dw	0000h
  1259                              <1> WinFuncPtr19:		dd	0
  1260                              <1> BytesPerScanLine19:	dw	2560
  1261                              <1> XResolution19:		dw	1280
  1262                              <1> YResolution19:		dw	720
  1263                              <1> XCharSize19:		db	8
  1264                              <1> YCharSize19:		db	16
  1265                              <1> NumberOfPlanes19:	db	1
  1266                              <1> BitsPerPixel19:		db	16
  1267                              <1> NumberOfBanks19:	db	29
  1268                              <1> MemoryModel19:		db	VBE_MEMORYMODEL_DIRECT_COLOR
  1269                              <1> BankSize19:		db	0
  1270                              <1> NumberOfImagePages19:	db	8
  1271                              <1> Reserved_page19:	db	0
  1272                              <1> RedMaskSize19:		db	5
  1273                              <1> RedFieldPosition19:	db	11
  1274                              <1> GreenMaskSize19:	db	6
  1275                              <1> GreenFieldPosition19:	db	5
  1276                              <1> BlueMaskSize19:		db	5
  1277                              <1> BlueFieldPosition19:	db	0
  1278                              <1> RsvdMaskSize19:		db	0
  1279                              <1> RsvdFieldPosition19:	db	0
  1280                              <1> DirectColorModeInfo19:	db	0
  1281                              <1> PhysBasePtr19:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
  1282                              <1> OffScreenMemOffset19:	dd	0
  1283                              <1> OffScreenMemSize19:	dw	0
  1284                              <1> LinBytesPerScanLine19:	dw	2560
  1285                              <1> BnkNumberOfPages19: 	db	0
  1286                              <1> LinNumberOfPages19: 	db	0
  1287                              <1> LinRedMaskSize19:	db	5
  1288                              <1> LinRedFieldPosition19:	db	11
  1289                              <1> LinGreenMaskSize19:	db	6
  1290                              <1> LinGreenFieldPosition19:db	5
  1291                              <1> LinBlueMaskSize19:	db	5
  1292                              <1> LinBlueFieldPosition19:	db	0
  1293                              <1> LinRsvdMaskSize19:	db	0
  1294                              <1> LinRsvdFieldPosition19:	db	0
  1295                              <1> MaxPixelClock19:	dd	0
  1296                              <1> 
  1297                              <1> 			dw	018Eh ; 1280x720x24
  1298                              <1> ModeAttributes20: 	dw	MODE_ATTRIBUTES
  1299                              <1> WinAAttributes20: 	db	WINA_ATTRIBUTES
  1300                              <1> WinBAttributes20: 	db	0
  1301                              <1> WinGranularity20: 	dw	VBE_DISPI_BANK_SIZE_KB
  1302                              <1> WinSize20: 		dw	VBE_DISPI_BANK_SIZE_KB
  1303                              <1> WinASegment20:		dw	VGAMEM_GRAPH
  1304                              <1> WinBSegment20:		dw	0000h
  1305                              <1> WinFuncPtr20:		dd	0
  1306                              <1> BytesPerScanLine20:	dw	3840
  1307                              <1> XResolution20:		dw	1280
  1308                              <1> YResolution20:		dw	720
  1309                              <1> XCharSize20:		db	8
  1310                              <1> YCharSize20:		db	16
  1311                              <1> NumberOfPlanes20:	db	1
  1312                              <1> BitsPerPixel20:		db	24
  1313                              <1> NumberOfBanks20:	db	43
  1314                              <1> MemoryModel20:		db	VBE_MEMORYMODEL_DIRECT_COLOR
  1315                              <1> BankSize20:		db	0
  1316                              <1> NumberOfImagePages20:	db	5
  1317                              <1> Reserved_page20:	db	0
  1318                              <1> RedMaskSize20:		db	8
  1319                              <1> RedFieldPosition20:	db	16
  1320                              <1> GreenMaskSize20:	db	8
  1321                              <1> GreenFieldPosition20:	db	8
  1322                              <1> BlueMaskSize20:		db	8
  1323                              <1> BlueFieldPosition20:	db	0
  1324                              <1> RsvdMaskSize20:		db	0
  1325                              <1> RsvdFieldPosition20:	db	0
  1326                              <1> DirectColorModeInfo20:	db	0
  1327                              <1> PhysBasePtr20:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
  1328                              <1> OffScreenMemOffset20:	dd	0
  1329                              <1> OffScreenMemSize20:	dw	0
  1330                              <1> LinBytesPerScanLine20:	dw	3840
  1331                              <1> BnkNumberOfPages20: 	db	0
  1332                              <1> LinNumberOfPages20: 	db	0
  1333                              <1> LinRedMaskSize20:	db	8
  1334                              <1> LinRedFieldPosition20:	db	16
  1335                              <1> LinGreenMaskSize20:	db	8
  1336                              <1> LinGreenFieldPosition20:db	8
  1337                              <1> LinBlueMaskSize20:	db	8
  1338                              <1> LinBlueFieldPosition20:	db	0
  1339                              <1> LinRsvdMaskSize20:	db	0
  1340                              <1> LinRsvdFieldPosition20:	db	0
  1341                              <1> MaxPixelClock20:	dd	0
  1342                              <1> 	
  1343                              <1> 			dw	018Fh ; 1280x720x32
  1344                              <1> ModeAttributes21: 	dw	MODE_ATTRIBUTES
  1345                              <1> WinAAttributes21: 	db	WINA_ATTRIBUTES
  1346                              <1> WinBAttributes21: 	db	0
  1347                              <1> WinGranularity21: 	dw	VBE_DISPI_BANK_SIZE_KB
  1348                              <1> WinSize21: 		dw	VBE_DISPI_BANK_SIZE_KB
  1349                              <1> WinASegment21:		dw	VGAMEM_GRAPH
  1350                              <1> WinBSegment21:		dw	0000h
  1351                              <1> WinFuncPtr21:		dd	0
  1352                              <1> BytesPerScanLine21:	dw	5120
  1353                              <1> XResolution21:		dw	1280
  1354                              <1> YResolution21:		dw	720
  1355                              <1> XCharSize21:		db	8
  1356                              <1> YCharSize21:		db	16
  1357                              <1> NumberOfPlanes21:	db	1
  1358                              <1> BitsPerPixel21:		db	32
  1359                              <1> NumberOfBanks21:	db	57
  1360                              <1> MemoryModel21:		db	VBE_MEMORYMODEL_DIRECT_COLOR
  1361                              <1> BankSize21:		db	0
  1362                              <1> NumberOfImagePages21:	db	3
  1363                              <1> Reserved_page21:	db	0
  1364                              <1> RedMaskSize21:		db	8
  1365                              <1> RedFieldPosition21:	db	16
  1366                              <1> GreenMaskSize21:	db	8
  1367                              <1> GreenFieldPosition21:	db	8
  1368                              <1> BlueMaskSize21:		db	8
  1369                              <1> BlueFieldPosition21:	db	0
  1370                              <1> RsvdMaskSize21:		db	8
  1371                              <1> RsvdFieldPosition21:	db	24
  1372                              <1> DirectColorModeInfo21:	db	VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE
  1373                              <1> PhysBasePtr21:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
  1374                              <1> OffScreenMemOffset21:	dd	0
  1375                              <1> OffScreenMemSize21:	dw	0
  1376                              <1> LinBytesPerScanLine21:	dw	5120
  1377                              <1> BnkNumberOfPages21: 	db	0
  1378                              <1> LinNumberOfPages21: 	db	0
  1379                              <1> LinRedMaskSize21:	db	8
  1380                              <1> LinRedFieldPosition21:	db	16
  1381                              <1> LinGreenMaskSize21:	db	8
  1382                              <1> LinGreenFieldPosition21:db	8
  1383                              <1> LinBlueMaskSize21:	db	8
  1384                              <1> LinBlueFieldPosition21:	db	0
  1385                              <1> LinRsvdMaskSize21:	db	8
  1386                              <1> LinRsvdFieldPosition21:	db	24
  1387                              <1> MaxPixelClock21:	dd	0
  1388                              <1> 			
  1389                              <1> 			dw	0190h ; 1920x1080x16
  1390                              <1> ModeAttributes22: 	dw	MODE_ATTRIBUTES
  1391                              <1> WinAAttributes22: 	db	WINA_ATTRIBUTES
  1392                              <1> WinBAttributes22: 	db	0
  1393                              <1> WinGranularity22: 	dw	VBE_DISPI_BANK_SIZE_KB
  1394                              <1> WinSize22: 		dw	VBE_DISPI_BANK_SIZE_KB
  1395                              <1> WinASegment22:		dw	VGAMEM_GRAPH
  1396                              <1> WinBSegment22:		dw	0000h
  1397                              <1> WinFuncPtr22:		dd	0
  1398                              <1> BytesPerScanLine22:	dw	3840
  1399                              <1> XResolution22:		dw	1920
  1400                              <1> YResolution22:		dw	1080
  1401                              <1> XCharSize22:		db	8
  1402                              <1> YCharSize22:		db	16
  1403                              <1> NumberOfPlanes22:	db	1
  1404                              <1> BitsPerPixel22:		db	16
  1405                              <1> NumberOfBanks22:	db	64
  1406                              <1> MemoryModel22:		db	VBE_MEMORYMODEL_DIRECT_COLOR,
  1407                              <1> BankSize22:		db	0
  1408                              <1> NumberOfImagePages22:	db	3
  1409                              <1> Reserved_page22:	db	0
  1410                              <1> RedMaskSize22:		db	5
  1411                              <1> RedFieldPosition22:	db	11
  1412                              <1> GreenMaskSize22:	db	6
  1413                              <1> GreenFieldPosition22:	db	5
  1414                              <1> BlueMaskSize22:		db	5
  1415                              <1> BlueFieldPosition22:	db	0
  1416                              <1> RsvdMaskSize22:		db	0
  1417                              <1> RsvdFieldPosition22:	db	0
  1418                              <1> DirectColorModeInfo22:	db	0
  1419                              <1> PhysBasePtr22:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
  1420                              <1> OffScreenMemOffset22:	dd	0
  1421                              <1> OffScreenMemSize22:	dw	0
  1422                              <1> LinBytesPerScanLine22:	dw	3840
  1423                              <1> BnkNumberOfPages22: 	db	0
  1424                              <1> LinNumberOfPages22: 	db	0
  1425                              <1> LinRedMaskSize22:	db	5
  1426                              <1> LinRedFieldPosition22:	db	11
  1427                              <1> LinGreenMaskSize22:	db	6
  1428                              <1> LinGreenFieldPosition22:db	5
  1429                              <1> LinBlueMaskSize22:	db	5
  1430                              <1> LinBlueFieldPosition22:	db	0
  1431                              <1> LinRsvdMaskSize22:	db	0
  1432                              <1> LinRsvdFieldPosition22:	db	0
  1433                              <1> MaxPixelClock22:	dd	0
  1434                              <1> 			
  1435                              <1> 			dw	0191h ; 1920x1080x24
  1436                              <1> ModeAttributes23: 	dw	MODE_ATTRIBUTES
  1437                              <1> WinAAttributes23: 	db	WINA_ATTRIBUTES
  1438                              <1> WinBAttributes23: 	db	0
  1439                              <1> WinGranularity23: 	dw	VBE_DISPI_BANK_SIZE_KB
  1440                              <1> WinSize23: 		dw	VBE_DISPI_BANK_SIZE_KB
  1441                              <1> WinASegment23:		dw	VGAMEM_GRAPH
  1442                              <1> WinBSegment23:		dw	0000h
  1443                              <1> WinFuncPtr23:		dd	0
  1444                              <1> BytesPerScanLine23:	dw	5760
  1445                              <1> XResolution23:		dw	1920
  1446                              <1> YResolution23:		dw	1080
  1447                              <1> XCharSize23:		db	8
  1448                              <1> YCharSize23:		db	16
  1449                              <1> NumberOfPlanes23:	db	1
  1450                              <1> BitsPerPixel23:		db	24
  1451                              <1> NumberOfBanks23:	db	95
  1452                              <1> MemoryModel23:		db	VBE_MEMORYMODEL_DIRECT_COLOR
  1453                              <1> BankSize23:		db	0
  1454                              <1> NumberOfImagePages23:	db	1
  1455                              <1> Reserved_page23:	db	0
  1456                              <1> RedMaskSize23:		db	8
  1457                              <1> RedFieldPosition23:	db	16
  1458                              <1> GreenMaskSize23:	db	8
  1459                              <1> GreenFieldPosition23:	db	8
  1460                              <1> BlueMaskSize23:		db	8
  1461                              <1> BlueFieldPosition23:	db	0
  1462                              <1> RsvdMaskSize23:		db	0
  1463                              <1> RsvdFieldPosition23:	db	0
  1464                              <1> DirectColorModeInfo23:	db	0
  1465                              <1> PhysBasePtr23:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
  1466                              <1> OffScreenMemOffset23:	dd	0
  1467                              <1> OffScreenMemSize23:	dw	0
  1468                              <1> LinBytesPerScanLine23:	dw	5760
  1469                              <1> BnkNumberOfPages23: 	db	0
  1470                              <1> LinNumberOfPages23: 	db	0
  1471                              <1> LinRedMaskSize23:	db	8
  1472                              <1> LinRedFieldPosition23:	db	16
  1473                              <1> LinGreenMaskSize23:	db	8
  1474                              <1> LinGreenFieldPosition23:db	8
  1475                              <1> LinBlueMaskSize23:	db	8
  1476                              <1> LinBlueFieldPosition23:	db	0
  1477                              <1> LinRsvdMaskSize23:	db	0
  1478                              <1> LinRsvdFieldPosition23:	db	0
  1479                              <1> MaxPixelClock23:	dd	0
  1480                              <1> 
  1481                              <1> 			dw	0192h ; 1920x1080x32
  1482                              <1> ModeAttributes24: 	dw	MODE_ATTRIBUTES
  1483                              <1> WinAAttributes24: 	db	WINA_ATTRIBUTES
  1484                              <1> WinBAttributes24: 	db	0
  1485                              <1> WinGranularity24: 	dw	VBE_DISPI_BANK_SIZE_KB
  1486                              <1> WinSize24: 		dw	VBE_DISPI_BANK_SIZE_KB
  1487                              <1> WinASegment24:		dw	VGAMEM_GRAPH
  1488                              <1> WinBSegment24:		dw	0000h
  1489                              <1> WinFuncPtr24:		dd	0
  1490                              <1> BytesPerScanLine24:	dw	7680
  1491                              <1> XResolution24:		dw	1920
  1492                              <1> YResolution24:		dw	1080
  1493                              <1> XCharSize24:		db	8
  1494                              <1> YCharSize24:		db	16
  1495                              <1> NumberOfPlanes24:	db	1
  1496                              <1> BitsPerPixel24:		db	32
  1497                              <1> NumberOfBanks24:	db	127
  1498                              <1> MemoryModel24:		db	VBE_MEMORYMODEL_DIRECT_COLOR
  1499                              <1> BankSize24:		db	0
  1500                              <1> NumberOfImagePages24:	db	1
  1501                              <1> Reserved_page24:	db	0
  1502                              <1> RedMaskSize24:		db	8
  1503                              <1> RedFieldPosition24:	db	16
  1504                              <1> GreenMaskSize24:	db	8
  1505                              <1> GreenFieldPosition24:	db	8
  1506                              <1> BlueMaskSize24:		db	8
  1507                              <1> BlueFieldPosition24:	db	0
  1508                              <1> RsvdMaskSize24:		db	8
  1509                              <1> RsvdFieldPosition24:	db	24
  1510                              <1> DirectColorModeInfo24:	db	VBE_DIRECTCOLOR_RESERVED_BITS_AVAILABLE
  1511                              <1> PhysBasePtr24:		dd	VBE_DISPI_LFB_PHYSICAL_ADDRESS
  1512                              <1> OffScreenMemOffset24:	dd	0
  1513                              <1> OffScreenMemSize24:	dw	0
  1514                              <1> LinBytesPerScanLine24:	dw 	7680
  1515                              <1> BnkNumberOfPages24: 	db	0
  1516                              <1> LinNumberOfPages24: 	db	0
  1517                              <1> LinRedMaskSize24:	db	8
  1518                              <1> LinRedFieldPosition24:	db	16
  1519                              <1> LinGreenMaskSize24:	db	8
  1520                              <1> LinGreenFieldPosition24:db	8
  1521                              <1> LinBlueMaskSize24:	db	8
  1522                              <1> LinBlueFieldPosition24:	db	0
  1523                              <1> LinRsvdMaskSize24:	db	8
  1524                              <1> LinRsvdFieldPosition24:	db	24
  1525                              <1> MaxPixelClock24:	dd	0
  1526                              <1> 
  1527                              <1> VBE_VESA_MODE_END_OF_LIST: dw	0
  1528                              <1> 
  1529                              <1> %endif
  1530                              <1> 
  1531                              <1> ; 24/11/2020
  1532                              <1> 
  1533                              <1> direct_color_fields:
  1534                              <1> 	; 24/11/2020
  1535                              <1> 
  1536                              <1> ; (vbetables-gen.c)
  1537                              <1> ; // Direct Color fields 
  1538                              <1> ; (required for direct/6 and YUV/7 memory models)
  1539                              <1> ; switch(pm->depth) {
  1540                              <1>     
  1541                              <1> ;case 8:
  1542 00006DE6 00                  <1> r_size_8:  db 0
  1543 00006DE7 00                  <1> r_pos_8:   db 0
  1544 00006DE8 00                  <1> g_size_8:  db 0
  1545 00006DE9 00                  <1> g_pos_8:   db 0
  1546 00006DEA 00                  <1> b_size_8:  db 0
  1547 00006DEB 00                  <1> b_pos_8:   db 0
  1548 00006DEC 00                  <1> a_size_8:  db 0
  1549 00006DED 00                  <1> a_pos_8:   db 0
  1550                              <1> 
  1551                              <1> ;case 16:
  1552 00006DEE 05                  <1> r_size_16:  db 5
  1553 00006DEF 0B                  <1> r_pos_16:   db 11
  1554 00006DF0 06                  <1> g_size_16:  db 6
  1555 00006DF1 05                  <1> g_pos_16:   db 5
  1556 00006DF2 05                  <1> b_size_16:  db 5
  1557 00006DF3 00                  <1> b_pos_16:   db 0
  1558 00006DF4 00                  <1> a_size_16:  db 0
  1559 00006DF5 00                  <1> a_pos_16:   db 0
  1560                              <1> 
  1561                              <1> ;case 24:
  1562 00006DF6 08                  <1> r_size_24:  db 8
  1563 00006DF7 10                  <1> r_pos_24:   db 16
  1564 00006DF8 08                  <1> g_size_24:  db 8
  1565 00006DF9 08                  <1> g_pos_24:   db 8
  1566 00006DFA 08                  <1> b_size_24:  db 8
  1567 00006DFB 00                  <1> b_pos_24:   db 0
  1568 00006DFC 00                  <1> a_size_24:  db 0
  1569 00006DFD 00                  <1> a_pos_24:   db 0
  1570                              <1> 
  1571                              <1> ;case 32:
  1572 00006DFE 08                  <1> r_size_32:  db 8
  1573 00006DFF 10                  <1> r_pos_32:   db 16
  1574 00006E00 08                  <1> g_size_32:  db 8
  1575 00006E01 08                  <1> g_pos_32:   db 8
  1576 00006E02 08                  <1> b_size_32:  db 8
  1577 00006E03 00                  <1> b_pos_32:   db 0
  1578 00006E04 08                  <1> a_size_32:  db 8
  1579 00006E05 18                  <1> a_pos_32:   db 24
  3023                                  ;%include 'diskdata.s'	; DISK (BIOS) DATA (initialized)
  3024                                  ;;;
  3025                                  
  3026                                  Align 2
  3027                                  
  3028                                  %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: 31/12/2017
     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> ; 31/12/2017
    79                              <1> ; 19/02/2017
    80                              <1> ; 15/10/2016
    81                              <1> ; 20/05/2016
    82                              <1> ; 19/05/2016
    83                              <1> ; 18/05/2016
    84                              <1> ; 29/04/2016 
    85                              <1> ; TRDOS 386 (TRDOS v2.0) system calls - temporary List 
    86                              <1> ; 14/07/2013 - 21/09/2015 (Retro UNIX 8086 & 386 system calls) 
    87                              <1> _ver 	equ 0 ; Get TRDOS version (v2.0)
    88                              <1> _exit 	equ 1
    89                              <1> _fork 	equ 2
    90                              <1> _read 	equ 3
    91                              <1> _write	equ 4
    92                              <1> _open	equ 5
    93                              <1> _close 	equ 6
    94                              <1> _wait 	equ 7
    95                              <1> _creat 	equ 8
    96                              <1> _rename	equ 9  ; TRDOS 386, Rename File (31/12/2017)	
    97                              <1> _delete	equ 10 ; TRDOS 386, Delete File (29/12/2017)
    98                              <1> _exec	equ 11
    99                              <1> _chdir	equ 12
   100                              <1> _time 	equ 13 ; TRDOS 386, Get Sys Date&Time (30/12/2017)
   101                              <1> _mkdir 	equ 14
   102                              <1> _chmod	equ 15 ; TRDOS 386, Change Attributes (30/12/2017) 
   103                              <1> _rmdir	equ 16 ; TRDOS 386, Remove Directory (29/12/2017)
   104                              <1> _break	equ 17
   105                              <1> _drive	equ 18 ; TRDOS 386, Get/Set Current Drv (30/12/2017) 
   106                              <1> _seek	equ 19
   107                              <1> _tell 	equ 20
   108                              <1> _mem	equ 21 ; TRDOS 386, Get Total&Free Mem (31/12/2017)
   109                              <1> _prompt	equ 22 ; TRDOS 386, Change Cmd Prompt (31/12/2017)
   110                              <1> _path	equ 23 ; TRDOS 386, Get/Set Run Path (31/12/2017)
   111                              <1> _env	equ 24 ; TRDOS 386, Get/Set Env Vars (31/12/2017)
   112                              <1> _stime	equ 25 ; TRDOS 386, Set Sys Date&Time (30/12/2017)
   113                              <1> _quit	equ 26	
   114                              <1> _intr	equ 27
   115                              <1> _dir	equ 28 ; TRDOS 386, Get Curr Drive&Dir (30/12/2017) 
   116                              <1> _emt 	equ 29
   117                              <1> _ldrvt 	equ 30 ; TRDOS 386, Get Logical DOS DDT (30/12/2017)
   118                              <1> _video  equ 31 ; TRDOS 386 Video Functions (16/05/2016)
   119                              <1> _audio	equ 32 ; TRDOS 386 Video Functions (16/05/2016)
   120                              <1> _timer	equ 33 ; TRDOS 386 Timer Functions (18/05/2016)
   121                              <1> _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
   122                              <1> _msg	equ 35 ; Retro UNIX 386 v1 feature only !
   123                              <1> _geterr	equ 36 ; Retro UNIX 386 v1 feature only !
   124                              <1> _fpsave equ 37 ; TRDOS 386 FPU state option (28/02/2017)
   125                              <1> _pri 	equ 38 ; change priority - TRDOS 386 (20/05/2016)
   126                              <1> _rele	equ 39 ; TRDOS 386 (19/05/2016)
   127                              <1> _fff	equ 40 ; Find First File - TRDOS 386 (15/10/2016)
   128                              <1> _fnf	equ 41 ; Find Next File - TRDOS 386 (15/10/2016)
   129                              <1> _alloc	equ 42 ; Allocate memory - TRDOS 386 (19/02/2017)
   130                              <1> 	       ; TRDOS 386 (19/02/2017) DMA buff fuctions		
   131                              <1> _dalloc equ 43 ; Deallocate mem - TRDOS 386 (19/02/2017)
   132                              <1> _calbac equ 44 ; Set IRQ callback - TRDOS 386 (20/02/2017)  				
   133                              <1> _dma	equ 45 ; DMA service - TRDOS 386 (20/08/2017)  
   134                              <1> 
   135                              <1> %macro sys 1-4
   136                              <1>     ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)	
   137                              <1>     ; 03/09/2015	
   138                              <1>     ; 13/04/2015
   139                              <1>     ; Retro UNIX 386 v1 system call.		
   140                              <1>     %if %0 >= 2   
   141                              <1>         mov ebx, %2
   142                              <1>         %if %0 >= 3    
   143                              <1>             mov ecx, %3
   144                              <1>             %if %0 = 4
   145                              <1>                mov edx, %4   
   146                              <1>             %endif
   147                              <1>         %endif
   148                              <1>     %endif
   149                              <1>     mov eax, %1
   150                              <1>     ;int 30h
   151                              <1>     int 40h ; TRDOS 386 (TRDOS v2.0)		   
   152                              <1> %endmacro
   153                              <1> 
   154                              <1> ; TRDOS 386 system calls, interrupt number
   155                              <1> ; 25/12/2016
   156                              <1> SYSCALL_INT_NUM   equ '40' ; '40h'
   157                              <1> 
   158                              <1> ; 13/05/2015 - ERROR CODES
   159                              <1> ERR_FILE_NOT_OPEN  equ 10 ; 'file not open !' error
   160                              <1> ERR_FILE_ACCESS    equ 11 ; 'permission denied !' error
   161                              <1> ; 14/05/2015
   162                              <1> ERR_DIR_ACCESS     equ 11 ; 'permission denied !' error
   163                              <1> ERR_FILE_NOT_FOUND equ 12 ; 'file not found !' error
   164                              <1> ERR_TOO_MANY_FILES equ 13 ; 'too many open files !' error
   165                              <1> ERR_DIR_EXISTS     equ 14 ; 'directory already exists !' error 	
   166                              <1> ; 16/05/2015		
   167                              <1> ERR_DRV_NOT_RDY    equ 15 ; 'drive not ready !' error
   168                              <1> ; 18/05/2015
   169                              <1> ERR_DEV_NOT_RDY    equ 15 ; 'device not ready !' error
   170                              <1> ERR_DEV_ACCESS     equ 11 ; 'permission denied !' error 
   171                              <1> ERR_DEV_NOT_OPEN   equ 10 ; 'device not open !' error	
   172                              <1> ; 07/06/2015
   173                              <1> ERR_FILE_EOF	   equ 16 ; 'end of file !' error
   174                              <1> ERR_DEV_VOL_SIZE   equ 16 ; 'out of volume !' error
   175                              <1> ; 09/06/2015
   176                              <1> ERR_DRV_READ	   equ 17 ; 'disk read error !'
   177                              <1> ERR_DRV_WRITE	   equ 18 ; 'disk write error !'
   178                              <1> ; 16/06/2015
   179                              <1> ERR_NOT_DIR	   equ 19 ; 'not a (valid) directory !' error
   180                              <1> ERR_FILE_SIZE	   equ 20 ; 'file size error !'	
   181                              <1> ; 22/06/2015
   182                              <1> ERR_NOT_SUPERUSER  equ 11 ; 'permission denied !' error
   183                              <1> ERR_NOT_OWNER      equ 11 ; 'permission denied !' error
   184                              <1> ERR_NOT_FILE       equ 11 ; 'permission denied !' error	
   185                              <1> ; 23/06/2015
   186                              <1> ERR_FILE_EXISTS    equ 14 ; 'file already exists !' error
   187                              <1> ERR_DRV_NOT_SAME   equ 21 ; 'not same drive !' error
   188                              <1> ERR_DIR_NOT_FOUND  equ 12 ; 'directory not found !' error
   189                              <1> ERR_NOT_EXECUTABLE equ 22 ; 'not executable file !' error
   190                              <1> ; 27/06/2015
   191                              <1> ERR_INV_PARAMETER  equ 23 ; 'invalid parameter !' error
   192                              <1> ERR_INV_DEV_NAME   equ 24 ; 'invalid device name !' error
   193                              <1> ; 29/06/2015
   194                              <1> ERR_TIME_OUT	   equ 25 ; 'time out !' error			
   195                              <1> ERR_DEV_NOT_RESP   equ 25 ; 'device not responding !' error
   196                              <1> ; 10/10/2016
   197                              <1> ERR_INV_FILE_NAME  equ 26 ; 'invalid file name !' error
   198                              <1> ERR_INV_FLAGS	   equ 23 ; 'invalid flags !' error
   199                              <1> ; For code compatibility with previous version of TRDOS (2011)
   200                              <1> ; (Temporary error codes for current TRDOS 386 -2016- version) 
   201                              <1> ERR_NO_MORE_FILES  equ 12 ; 'no more files !' error
   202                              <1> ERR_PATH_NOT_FOUND equ  3 ; 'path not found !' error 
   203                              <1> 			  ; 'dir not found !' ; TRDOS 8086
   204                              <1> ERR_NOT_FOUND:	   equ  2 ; 'file not found !' ; TRDOS 8086
   205                              <1> ERR_DISK_SPACE	   equ 39 ; 'out of volume !' TRDOS 8086
   206                              <1> 			  ; 'insufficient disk space !' ; 27h
   207                              <1> ERR_DISK_WRITE	   equ 30 ; 'disk write protected !' ; 16/10/2016
   208                              <1> ERR_ACCESS_DENIED  equ  5 ; 'access denied !' ; TRDOS 8086 	
   209                              <1> ; 28/02/2017
   210                              <1> ERR_PERM_DENIED	   equ 11 ; 'permission denied !' error  	
   211                              <1> ; 18/05/2016
   212                              <1> ERR_MISC	   equ 27 ; miscellaneous/other errors
   213                              <1> ; 15/10/2016
   214                              <1> ; TRDOS 8086 -> TRDOS 386 (0Bh -> 28)
   215                              <1> ERR_INV_FORMAT	   equ 28 ; 'invalid format !' error
   216                              <1> ; TRDOS 8086 -> TRDOS 386 (0Dh -> 29)
   217                              <1> ERR_INV_DATA	   equ 29 ; 'invalid data !' error
   218                              <1> ; TRDOS 8086 -> TRDOS 386 (0Eh -> 20)
   219                              <1> ERR_ZERO_LENGTH	   equ 20  ; 'zero length !' error 	
   220                              <1> ; TRDOS 8086 -> TRDOS 386 (15h -> 17, 1Dh -> 18, 1Eh -> 17) 	
   221                              <1> ERR_DRV_NR_READ	   equ 17 ; 'drive not ready or read error !'
   222                              <1> ERR_DRV_NR_WRITE   equ 18 ; 'drive not ready or write error !'		
   223                              <1> ; 15/10/2016
   224                              <1> ERR_INV_PATH_NAME  equ 19 ; 'bad path name !' error
   225                              <1> ERR_BAD_CMD_ARG	   equ  1 ; 'bad command argument !' ; TRDOS 8086
   226                              <1> ERR_INV_FNUMBER	   equ  1 ; 'invalid function number !' ; TRDOS 8086
   227                              <1> ERR_BIG_FILE	   equ  8 ; 'big file & out of memory ! ; TRDOS 8086 	
   228                              <1> ERR_BIG_DATA	   equ  8 ; 'big data & out of memory ! ; TRDOS 8086
   229                              <1> ERR_CLUSTER	   equ 35 ; 'cluster not available !' ; TRDOS 8086
   230                              <1> ERR_OUT_OF_MEMORY  equ  4 ; 'out of memory !'
   231                              <1> 			  ; 'insufficient memory !'
   232                              <1> ERR_P_VIOLATION	   equ	6 ; 'protection violation !'
   233                              <1> ERR_PAGE_FAULT	   equ 224 ;'page fault !' ;0E0h						 
   234                              <1> ERR_SWP_DISK_READ  	   equ 40
   235                              <1> ERR_SWP_DISK_NOT_PRESENT   equ 41
   236                              <1> ERR_SWP_SECTOR_NOT_PRESENT equ 42
   237                              <1> ERR_SWP_NO_FREE_SPACE      equ 43
   238                              <1> ERR_SWP_DISK_WRITE         equ 44
   239                              <1> ERR_SWP_NO_PAGE_TO_SWAP    equ 45
   240                              <1> ; 10/04/2017
   241                              <1> ERR_BUFFER	   equ 46  ; 'buffer error !'
   242                              <1> ; 28/08/2017 (20/08/2017)
   243                              <1> ERR_DMA		   equ -1  ; DMA buffer (allocation/misc.) error!
   244                              <1> 
   245                              <1> ; 26/08/2015
   246                              <1> ; 24/07/2015
   247                              <1> ; 24/06/2015
   248                              <1> MAX_ARG_LEN	   equ 256 ; max. length of sys exec arguments
   249                              <1> ; 01/07/2015
   250                              <1> MAX_MSG_LEN	   equ 255 ; max. msg length for 'sysmsg'
   251                              <1> ;	
   252                              <1> ; 06/10/2016
   253                              <1> OPENFILES	   equ 10  ; max. number of open files (system)
   254                              <1> ; 07/10/2016
   255                              <1> ;NUMOFDEVICES	   equ 20  ; max. num of available devices (sys)
   256                              <1> 			 		
  3029                                  %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
  3030                                  %include 'trdosk1.s' ; 04/01/2016 
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.3) - SYS INIT : trdosk1.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 06/12/2020
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 04/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.15 (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> 	; 20/01/2018  (v2.0.1)
    18                              <1> 	; 23/01/2017  (v2.0.0)
    19                              <1> 	; 07/05/2016
    20                              <1> 	; 02/05/2016
    21                              <1> 	; 24/04/2016
    22                              <1> 	; 14/04/2016
    23                              <1> 	; 13/04/2016
    24                              <1> 	; 30/03/2016
    25                              <1> 	; 24/01/2016
    26                              <1> 	; 06/01/2016
    27                              <1> 	; 04/01/2016
    28                              <1> 
    29                              <1> 	; 23/01/2017 - reset timer frequency (to 18.2Hz)
    30 00006E06 B036                <1> 	mov	al, 00110110b ; 36h
    31 00006E08 E643                <1>  	out	43h, al
    32 00006E0A 31C0                <1> 	xor	eax, eax  ; sub	al, al ; 0
    33 00006E0C E640                <1> 	out	40h, al ; LB
    34 00006E0E E640                <1> 	out	40h, al ; HB
    35                              <1>  	; 
    36                              <1> 	; 30/03/2016
    37                              <1> 	; Clear Logical DOS Disk Description Tables Area
    38                              <1> 	;xor	eax, eax
    39 00006E10 BF00010900          <1> 	mov	edi, Logical_DOSDisks
    40 00006E15 B980060000          <1> 	mov	ecx, 6656/4 ; 26*256 = 6656 bytes
    41 00006E1A F3AB                <1> 	rep	stosd ; 1664 times 4 bytes
    42                              <1> 
    43 00006E1C B83F3A2F00          <1> 	mov	eax, '?:/'
    44 00006E21 A3[9F640100]        <1> 	mov	[Current_Dir_Drv], eax
    45                              <1> 
    46                              <1> 	; Logical DRV INIT (only for hard disks)
    47 00006E26 E825040000          <1> 	call 	ldrv_init  ; trdosk2.s
    48                              <1> 	
    49                              <1> 	; When floppy_drv_init call is disabled
    50                              <1> 	; media changed sign is needed
    51                              <1> 	; for proper drive initialization
    52                              <1>         
    53 00006E2B BE00010900          <1> 	mov 	esi, Logical_DOSDisks
    54 00006E30 B001                <1> 	mov 	al, 1 ; Initialization sign (invalid_fd_parameter)
    55 00006E32 83C67E              <1> 	add 	esi, LD_MediaChanged ; Media Change Status = 1 (init needed)
    56 00006E35 8806                <1> 	mov 	[esi], al ; A:
    57 00006E37 81C600010000        <1> 	add 	esi, 100h 
    58 00006E3D 8806                <1> 	mov 	[esi], al ; B: 
    59                              <1>            
    60                              <1> _current_drive_bootdisk:
    61 00006E3F 8A15[CA670000]      <1> 	mov 	dl, [boot_drv] ; physical drive number
    62 00006E45 80FAFF              <1> 	cmp 	dl, 0FFh
    63 00006E48 740A                <1> 	je 	short _last_dos_diskno_check
    64                              <1> _boot_drive_check:
    65 00006E4A 80FA80              <1> 	cmp 	dl, 80h
    66 00006E4D 7218                <1> 	jb 	short _current_drive_a
    67 00006E4F 80EA7E              <1> 	sub 	dl, 7Eh ; C = 2 , D = 3
    68 00006E52 EB13                <1> 	jmp 	short _current_drive_a 
    69                              <1> 
    70                              <1> _last_dos_diskno_check:
    71 00006E54 8A15[F5170100]      <1> 	mov 	dl, [Last_DOS_DiskNo]
    72 00006E5A 80FA02              <1> 	cmp 	dl, 2
    73 00006E5D 7706                <1> 	ja 	short _current_drive_c
    74 00006E5F 7406                <1> 	je 	short _current_drive_a
    75 00006E61 30D2                <1> 	xor 	dl, dl ; A:
    76 00006E63 EB02                <1> 	jmp 	short _current_drive_a
    77                              <1> 
    78                              <1> _current_drive_c:
    79 00006E65 B202                <1> 	mov 	dl, 2 ; C:
    80                              <1> 
    81                              <1> _current_drive_a:
    82 00006E67 8815[CB670000]      <1> 	mov	[drv], dl
    83 00006E6D BE[F7170100]        <1>         mov     esi, msg_CRLF_temp
    84 00006E72 E8AE000000          <1> 	call 	print_msg
    85                              <1> 
    86 00006E77 8A15[CB670000]      <1> 	mov	dl, [drv]
    87                              <1> _default_drive_c:
    88 00006E7D E82C0C0000          <1> 	call 	change_current_drive
    89 00006E82 731C                <1> 	jnc 	short _start_mainprog
    90                              <1> 
    91                              <1> _drv_not_ready_error: 
    92 00006E84 BE[B21A0100]        <1> 	mov 	esi, msgl_drv_not_ready
    93 00006E89 E897000000          <1> 	call 	print_msg
    94                              <1>         ;jmp	_end_of_mainprog
    95                              <1> 
    96                              <1> 	; 20/01/2018
    97 00006E8E B202                <1> 	mov	dl, 2
    98 00006E90 3815[CB670000]      <1> 	cmp	[drv], dl
    99 00006E96 736B                <1> 	jnb	short _end_of_mainprog
   100 00006E98 8815[CB670000]      <1> 	mov	[drv], dl
   101 00006E9E EBDD                <1> 	jmp	short _default_drive_c
   102                              <1> 
   103                              <1> _start_mainprog:
   104                              <1> 	; 07/01/2017
   105                              <1> 	; 07/05/2016
   106                              <1> 	; 02/05/2016
   107                              <1> 	; 24/04/2016
   108                              <1> 	; Retro UNIX 386 v1, 'sys_init' (u0.s)
   109                              <1> 	; 23/06/2015
   110                              <1> 
   111                              <1> 	; 02/05/2016
   112                              <1> 	; 24/04/2016
   113 00006EA0 66B80100            <1> 	mov	ax, 1
   114 00006EA4 A2[B3030300]        <1> 	mov	[u.uno], al
   115 00006EA9 66A3[4E030300]      <1> 	mov	[mpid], ax
   116 00006EAF 66A3[20000300]      <1> 	mov	[p.pid], ax
   117 00006EB5 A2[B0000300]        <1> 	mov	[p.stat], al
   118 00006EBA C605[A8030300]04    <1> 	mov	byte [u.quant], time_count  ; 07/01/2017
   119                              <1> 	;
   120 00006EC1 A1[D8630100]        <1> 	mov	eax, [k_page_dir]
   121 00006EC6 A3[B8030300]        <1> 	mov	[u.pgdir], eax ; reset
   122                              <1> 	;
   123 00006ECB E8D5E6FFFF          <1> 	call	allocate_page
   124 00006ED0 0F82B5000000        <1> 	jc	panic
   125 00006ED6 A3[B4030300]        <1> 	mov	[u.upage], eax ; user structure page	
   126 00006EDB A3[C0000300]        <1> 	mov	[p.upage], eax
   127 00006EE0 E83AE7FFFF          <1> 	call	clear_page
   128                              <1> 	;
   129                              <1> 	; 24/08/2015
   130 00006EE5 FE0D[5B030300]      <1> 	dec 	byte [sysflg] ; FFh = ready for system call
   131                              <1> 			      ; 0 = executing a system call
   132                              <1> 	; 13/04/2016
   133                              <1> 	; Clear Environment Variables Page/Area
   134 00006EEB BF00300900          <1> 	mov	edi, Env_Page ; 93000h
   135 00006EF0 B980000000          <1> 	mov	ecx, Env_Page_Size / 4 	; 512/4  (4096/4)				 	  		 	  
   136 00006EF5 31C0                <1> 	xor	eax, eax
   137 00006EF7 F3AB                <1> 	rep	stosd
   138                              <1> 
   139                              <1> 	; 14/04/2016
   140 00006EF9 E807350000          <1>  	call	mainprog_startup_configuration
   141                              <1> 
   142 00006EFE E8EC0C0000          <1>         call    dos_prompt
   143                              <1>               
   144                              <1> _end_of_mainprog:
   145 00006F03 BE[F7170100]        <1>         mov     esi, msg_CRLF_temp
   146 00006F08 E818000000          <1> 	call 	print_msg
   147 00006F0D BE[FD170100]        <1> 	mov 	esi, mainprog_Version
   148 00006F12 E80E000000          <1> 	call 	print_msg
   149                              <1> 	; 24/01/2016
   150 00006F17 28E4                <1> 	sub	ah, ah
   151 00006F19 E8B79FFFFF          <1> 	call	int16h ; call getch
   152 00006F1E E997A4FFFF          <1> 	jmp	cpu_reset
   153                              <1> 
   154 00006F23 EBFE                <1> infinitiveloop: jmp short infinitiveloop
   155                              <1> 
   156                              <1> print_msg:
   157                              <1> 	; 13/05/2016
   158                              <1> 	; 04/01/2016
   159                              <1> 	; 01/07/2015
   160                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
   161                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
   162                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
   163                              <1> 	;
   164 00006F25 8A3D[06640100]      <1> 	mov	bh, [ACTIVE_PAGE] ; 04/01/2016 (ptty)
   165                              <1> 	;mov	bl, 07h ; Black background, light gray forecolor
   166                              <1> 
   167 00006F2B AC                  <1> 	lodsb
   168                              <1> pmsg1:
   169 00006F2C 56                  <1> 	push 	esi
   170                              <1> 	;mov	bh, [ACTIVE_PAGE] ; 04/01/2016 (ptty)
   171 00006F2D B307                <1> 	mov	bl, 07h ; Black background, light gray forecolor
   172 00006F2F E8C9B2FFFF          <1> 	call 	_write_tty
   173 00006F34 5E                  <1> 	pop	esi
   174 00006F35 AC                  <1> 	lodsb
   175 00006F36 20C0                <1> 	and 	al, al
   176 00006F38 75F2                <1> 	jnz 	short pmsg1
   177 00006F3A C3                  <1> 	retn
   178                              <1> 
   179                              <1> clear_screen:
   180                              <1> 	; 06/12/2020 
   181                              <1> 	; 03/12/2020 (TRDOS 386 v2.0.3)
   182                              <1> 	; 13/05/2016
   183                              <1> 	; 30/01/2016
   184                              <1> 	; 24/01/2016
   185                              <1> 	; 04/01/2016
   186 00006F3B 0FB61D[06640100]    <1> 	movzx	ebx, byte [ACTIVE_PAGE] ; video page number (0 to 7)
   187 00006F42 8AA3[AB690000]      <1> 	mov 	ah, [ebx+vmode] ; default = 03h (80x25 text)
   188 00006F48 80FC04              <1> 	cmp	ah, 4
   189 00006F4B 7205                <1> 	jb	short cls1
   190 00006F4D 80FC07              <1> 	cmp	ah, 7
   191 00006F50 7530                <1> 	jne	short vga_clear
   192                              <1> cls1:
   193                              <1> 	;mov	bh, bl
   194                              <1> 	;mov	bl, 7
   195 00006F52 3A25[9A690000]      <1> 	cmp	ah, [CRT_MODE] ; current video mode ? 
   196 00006F58 740E                <1> 	je	short cls2 ; yes (current video mode = 3)
   197                              <1> 	;;call	set_mode_3 ; set video mode to 3 (& clear screen)
   198                              <1> 	;;retn
   199                              <1> 	; 06/12/2020
   200 00006F5A 803D[9C110300]00    <1> 	cmp	byte [pmi32], 0
   201 00006F61 771F                <1> 	ja	short vga_clear 	
   202 00006F63 E99FB2FFFF          <1> 	jmp	set_mode_3
   203                              <1> cls2:
   204 00006F68 88DF                <1> 	mov	bh, bl ; video page (0 to 7)
   205 00006F6A B307                <1> 	mov	bl, 07h ; attribute to be used on blanked line
   206 00006F6C 28C0                <1> 	sub 	al, al ; 0 =  entire window
   207 00006F6E 6631C9              <1> 	xor 	cx, cx
   208 00006F71 66BA4F18            <1> 	mov 	dx, 184Fh
   209 00006F75 E8C3AFFFFF          <1> 	call	_scroll_up ; 24/01/2016
   210                              <1> 	;
   211                              <1> 	;mov	bh, [ACTIVE_PAGE] ; video page number (0 to 7)
   212 00006F7A 6631D2              <1> 	xor 	dx, dx
   213                              <1> 	;call	_set_cpos ; 24/01/2016 
   214                              <1> 	;;retn
   215                              <1> 	; 03/12/2020
   216 00006F7D E915B3FFFF          <1> 	jmp	_set_cpos ; returns to the caller of this proc
   217                              <1> ;cls3:
   218                              <1> ;	retn
   219                              <1> 	; 06/12/2020
   220                              <1> vga_clear:
   221                              <1> 	; 03/12/2020
   222                              <1> 	; set mode by using _int10h
   223                              <1> 	; (also clears screen)
   224 00006F82 88E0                <1> 	mov	al, ah
   225 00006F84 28E4                <1> 	sub	ah, ah  ; set current video mode
   226                              <1> 	;call	_int10h ; simulates int 10h in TRDOS 386 kernel
   227                              <1> 	;jmp	short cls3
   228 00006F86 E9CEA7FFFF          <1> 	jmp	_int10h ; returns to the caller of this proc
   229                              <1> 
   230                              <1> panic:
   231                              <1> 	; 13/05/2016 (TRDOS 386 = TRDOS v2)
   232                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
   233                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
   234 00006F8B BE[BB240100]        <1> 	mov 	esi, panic_msg
   235 00006F90 E890FFFFFF          <1> 	call 	print_msg
   236                              <1> key_to_reboot:
   237                              <1>         ; 24/01/2016
   238 00006F95 28E4                <1>         sub     ah, ah
   239 00006F97 E8399FFFFF          <1>         call    int16h ; call   getch
   240                              <1>         ; wait for a character from the current tty
   241                              <1> 	;
   242 00006F9C B00A                <1> 	mov	al, 0Ah
   243 00006F9E 8A3D[06640100]      <1> 	mov	bh, [ptty] ; [ACTIVE_PAGE]
   244 00006FA4 B307                <1> 	mov	bl, 07h ; Black background, 
   245                              <1> 			; light gray forecolor
   246 00006FA6 E852B2FFFF          <1> 	call 	_write_tty
   247 00006FAB E90AA4FFFF          <1> 	jmp	cpu_reset 
   248                              <1> 
   249                              <1> ctrlbrk:
   250                              <1> 	; 12/11/2015
   251                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
   252                              <1> 	; 06/12/2013 (Retro UNIX 8086 v1)
   253                              <1> 	;
   254                              <1> 	; INT 1Bh (control+break) handler		
   255                              <1> 	;
   256                              <1>       	; Retro Unix 8086 v1 feature only!
   257                              <1>       	;
   258 00006FB0 66833D[AA030300]00  <1> 	cmp 	word [u.intr], 0
   259 00006FB8 7645                <1> 	jna 	short cbrk4
   260                              <1> cbrk0:
   261                              <1> 	; 12/11/2015
   262                              <1> 	; 06/12/2013
   263 00006FBA 66833D[AC030300]00  <1> 	cmp 	word [u.quit], 0
   264 00006FC2 743B                <1> 	jz	short cbrk4
   265                              <1> 	;
   266                              <1> 	; 20/09/2013	
   267 00006FC4 6650                <1> 	push 	ax
   268 00006FC6 A0[06640100]        <1> 	mov	al, [ptty]
   269                              <1> 	;
   270                              <1> 	; 12/11/2015
   271                              <1> 	;
   272                              <1> 	; ctrl+break (EOT, CTRL+D) from serial port
   273                              <1> 	; or ctrl+break from console (pseudo) tty
   274                              <1> 	; (!redirection!)
   275                              <1> 	;
   276 00006FCB 3C08                <1> 	cmp	al, 8 ; serial port tty nums > 7
   277 00006FCD 7211                <1>         jb      short cbrk1 ; console (pseudo) tty
   278                              <1> 	;	
   279                              <1> 	; Serial port interrupt handler sets [ptty]
   280                              <1> 	; to the port's tty number (as temporary).
   281                              <1> 	;
   282                              <1> 	; If active process is using a stdin or 
   283                              <1> 	; stdout redirection (by the shell),
   284                              <1>         ; console tty keyboard must be available
   285                              <1> 	; to terminate running process,
   286                              <1> 	; in order to prevent a deadlock. 
   287                              <1> 	;
   288 00006FCF 52                  <1> 	push	edx
   289 00006FD0 0FB615[B3030300]    <1> 	movzx	edx, byte [u.uno]
   290 00006FD7 3A82[7F000300]      <1> 	cmp     al, [edx+p.ttyc-1] ; console tty (rw)
   291 00006FDD 5A                  <1> 	pop	edx
   292 00006FDE 7412                <1> 	je	short cbrk2
   293                              <1> cbrk1:
   294 00006FE0 FEC0                <1> 	inc 	al  ; [u.ttyp] : 1 based tty number
   295                              <1> 	; 06/12/2013
   296 00006FE2 3A05[94030300]      <1> 	cmp	al, [u.ttyp] ; recent open tty (r)
   297 00006FE8 7408                <1> 	je	short cbrk2	
   298 00006FEA 3A05[95030300]      <1>         cmp     al, [u.ttyp+1] ; recent open tty (w)
   299 00006FF0 750B                <1> 	jne	short cbrk3	
   300                              <1> cbrk2:
   301                              <1> 	;; 06/12/2013
   302                              <1> 	;mov	ax, [u.quit]
   303                              <1> 	;and	ax, ax
   304                              <1> 	;jz	short cbrk3
   305                              <1> 	;
   306 00006FF2 6631C0              <1> 	xor	ax, ax ; 0
   307 00006FF5 6648                <1> 	dec	ax
   308                              <1> 	; 0FFFFh = 'ctrl+brk' keystroke
   309 00006FF7 66A3[AC030300]      <1> 	mov	[u.quit], ax
   310                              <1> cbrk3:
   311 00006FFD 6658                <1> 	pop	ax
   312                              <1> cbrk4:
   313 00006FFF C3                  <1> 	retn
   314                              <1> 
   315                              <1> 
   316                              <1> ; 31/12/2017
   317                              <1> ; TRDOS 386 - 30/12/2017
   318                              <1> %define get_rtc_date RTC_40
   319                              <1> %define get_rtc_time RTC_20
   320                              <1> %define	set_rtc_date RTC_50
   321                              <1> %define set_rtc_time RTC_30	
   322                              <1> get_rtc_date_time:
   323                              <1> ; Retro UNIX 8086 v1 - UNIX.ASM (01/09/2014)
   324                              <1> ;epoch:
   325                              <1> 	; 30/12/2017 (TRDOS 386 = TRDOS v2.0)
   326                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
   327                              <1> 	; 09/04/2013 (Retro UNIX 8086 v1 - UNIX.ASM)
   328                              <1> 	; 'epoch' procedure prototype: 
   329                              <1> 	; 	            UNIXCOPY.ASM, 10/03/2013
   330                              <1> 	; 14/11/2012
   331                              <1> 	; unixboot.asm (boot file configuration)
   332                              <1> 	; version of "epoch" procedure in "unixproc.asm"
   333                              <1> 	; 21/7/2012
   334                              <1> 	; 15/7/2012
   335                              <1> 	; 14/7/2012		
   336                              <1> 	; Erdogan Tan - RETRO UNIX v0.1
   337                              <1> 	; compute current date and time as UNIX Epoch/Time
   338                              <1> 	; UNIX Epoch: seconds since 1/1/1970 00:00:00
   339                              <1> 	;
   340                              <1>         ;  ((Modified registers: EAX, EDX, ECX, EBX))  
   341                              <1> 	;
   342                              <1> 
   343 00007000 E877F4FFFF          <1> 	call 	get_rtc_time		; Return Current Time
   344 00007005 86E9                <1>         xchg 	ch,cl
   345 00007007 66890D[A2600100]    <1>         mov 	[hour], cx
   346 0000700E 86F2                <1>         xchg 	dh,dl
   347 00007010 668915[A6600100]    <1>         mov 	[second], dx
   348                              <1> 	;
   349 00007017 E8D1F4FFFF          <1>         call 	get_rtc_date		; Return Current Date
   350 0000701C 86E9                <1>         xchg 	ch,cl
   351 0000701E 66890D[9C600100]    <1>         mov 	[year], cx
   352 00007025 86F2                <1>         xchg 	dh,dl
   353 00007027 668915[9E600100]    <1>         mov 	[month], dx
   354                              <1> 	;
   355 0000702E 66B93030            <1> 	mov 	cx, 3030h
   356                              <1> 	;
   357 00007032 A0[A2600100]        <1> 	mov 	al, [hour] ; Hour
   358                              <1>         	; AL <= BCD number)
   359 00007037 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
   360                              <1> 					; AH = AL / 10h
   361                              <1> 					; AL = AL MOD 10h
   362 00007039 D50A                <1>         aad 	; AX= AH*10+AL
   363 0000703B A2[A2600100]        <1> 	mov 	[hour], al
   364 00007040 A0[A3600100]        <1> 	mov 	al, [hour+1] ; Minute
   365                              <1>         	; AL <= BCD number)
   366 00007045 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
   367                              <1> 					; AH = AL / 10h
   368                              <1> 					; AL = AL MOD 10h
   369 00007047 D50A                <1>         aad 	; AX= AH*10+AL
   370 00007049 A2[A4600100]        <1> 	mov 	[minute], al
   371 0000704E A0[A6600100]        <1> 	mov 	al, [second] ; Second
   372                              <1>         	; AL <= BCD number)
   373 00007053 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
   374                              <1> 					; AH = AL / 10h
   375                              <1> 					; AL = AL MOD 10h
   376 00007055 D50A                <1>         aad 	; AX= AH*10+AL
   377 00007057 A2[A6600100]        <1> 	mov 	[second], al
   378 0000705C 66A1[9C600100]      <1> 	mov 	ax, [year] ; Year (century)
   379 00007062 6650                <1>         push 	ax
   380                              <1> 	   	; AL <= BCD number)
   381 00007064 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
   382                              <1> 					; AH = AL / 10h
   383                              <1> 					; AL = AL MOD 10h
   384 00007066 D50A                <1>         aad 	; AX= AH*10+AL
   385 00007068 B464                <1> 	mov 	ah, 100
   386 0000706A F6E4                <1> 	mul 	ah
   387 0000706C 66A3[9C600100]      <1> 	mov 	[year], ax
   388 00007072 6658                <1> 	pop	ax
   389 00007074 88E0                <1> 	mov	al, ah
   390                              <1>         	; AL <= BCD number)
   391 00007076 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
   392                              <1> 					; AH = AL / 10h
   393                              <1> 					; AL = AL MOD 10h
   394 00007078 D50A                <1>         aad 	; AX= AH*10+AL
   395 0000707A 660105[9C600100]    <1> 	add 	[year], ax
   396 00007081 A0[9E600100]        <1> 	mov 	al, [month] ; Month
   397                              <1>            	; AL <= BCD number)
   398 00007086 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
   399                              <1> 					; AH = AL / 10h
   400                              <1> 					; AL = AL MOD 10h
   401 00007088 D50A                <1>         aad 	; AX= AH*10+AL
   402 0000708A A2[9E600100]        <1> 	mov 	[month], al	
   403 0000708F A0[9F600100]        <1>         mov     al, [month+1]      	; Day
   404                              <1>            	; AL <= BCD number)
   405 00007094 D410                <1>         db 	0D4h,10h		; Undocumented inst. AAM
   406                              <1> 					; AH = AL / 10h
   407                              <1> 					; AL = AL MOD 10h
   408 00007096 D50A                <1>         aad 	; AX= AH*10+AL
   409 00007098 A2[A0600100]        <1>         mov     [day], al
   410                              <1> 	
   411 0000709D C3                  <1> 	retn	; 30/12/2017
   412                              <1> 
   413                              <1> epoch:
   414 0000709E E85DFFFFFF          <1> 	call	get_rtc_date_time ; TRDOS 386 - 30/12/2017
   415                              <1> 
   416                              <1> convert_to_epoch:
   417                              <1> 	; 31/12/2017 (TRDOS 386 = TRDOS v2.0)
   418                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit modification)
   419                              <1> 	; 09/04/2013 (Retro UNIX 8086 v1)
   420                              <1> 	;
   421                              <1> 	; ((Modified registers: EAX, EDX, EBX)) 
   422                              <1> 	;
   423                              <1> 	; Derived from DALLAS Semiconductor
   424                              <1> 	; Application Note 31 (DS1602/DS1603)
   425                              <1> 	; 6 May 1998
   426 000070A3 29C0                <1> 	sub 	eax, eax
   427 000070A5 66A1[9C600100]      <1> 	mov 	ax, [year]
   428 000070AB 662DB207            <1> 	sub 	ax, 1970
   429 000070AF BA6D010000          <1> 	mov 	edx, 365
   430 000070B4 F7E2                <1> 	mul 	edx
   431 000070B6 31DB                <1> 	xor 	ebx, ebx
   432 000070B8 8A1D[9E600100]      <1> 	mov 	bl, [month]
   433 000070BE FECB                <1> 	dec 	bl
   434 000070C0 D0E3                <1> 	shl 	bl, 1
   435                              <1> 	;sub	edx, edx
   436 000070C2 668B93[A8600100]    <1> 	mov 	dx, [EBX+DMonth]
   437 000070C9 8A1D[A0600100]      <1>         mov     bl, [day]
   438 000070CF FECB                <1> 	dec 	bl
   439 000070D1 01D0                <1> 	add 	eax, edx
   440 000070D3 01D8                <1> 	add 	eax, ebx
   441                              <1> 			; EAX = days since 1/1/1970
   442 000070D5 668B15[9C600100]    <1> 	mov 	dx, [year]
   443 000070DC 6681EAB107          <1> 	sub 	dx, 1969
   444 000070E1 66D1EA              <1> 	shr 	dx, 1
   445 000070E4 66D1EA              <1> 	shr 	dx, 1		
   446                              <1> 		; (year-1969)/4
   447 000070E7 01D0                <1> 	add 	eax, edx
   448                              <1> 			; + leap days since 1/1/1970
   449 000070E9 803D[9E600100]02    <1> 	cmp 	byte [month], 2	; if past february
   450 000070F0 7610                <1> 	jna 	short cte1
   451 000070F2 668B15[9C600100]    <1> 	mov 	dx, [year]
   452 000070F9 6683E203            <1> 	and 	dx, 3 ; year mod 4
   453 000070FD 7503                <1> 	jnz 	short cte1		
   454                              <1> 			; and if leap year
   455 000070FF 83C001              <1> 	add 	eax, 1 	; add this year's leap day (february 29)
   456                              <1> cte1: 			; compute seconds since 1/1/1970
   457 00007102 BA18000000          <1> 	mov 	edx, 24
   458 00007107 F7E2                <1> 	mul	edx
   459 00007109 8A15[A2600100]      <1> 	mov 	dl, [hour]
   460 0000710F 01D0                <1> 	add 	eax, edx
   461                              <1> 		; EAX = hours since 1/1/1970 00:00:00
   462                              <1> 	;mov	ebx, 60
   463 00007111 B33C                <1> 	mov	bl, 60
   464 00007113 F7E3                <1> 	mul	ebx
   465 00007115 8A15[A4600100]      <1> 	mov 	dl, [minute]
   466 0000711B 01D0                <1> 	add 	eax, edx
   467                              <1> 		; EAX = minutes since 1/1/1970 00:00:00
   468                              <1> 	;mov 	ebx, 60
   469 0000711D F7E3                <1> 	mul	ebx
   470 0000711F 8A15[A6600100]      <1> 	mov 	dl, [second]
   471 00007125 01D0                <1> 	add 	eax, edx
   472                              <1>  		; EAX -> seconds since 1/1/1970 00:00:00
   473 00007127 C3                  <1> 	retn
   474                              <1> 
   475                              <1> ;set_date_time:
   476                              <1> convert_from_epoch:
   477                              <1> 	; 31/12/2017 (v2.0.0)
   478                              <1> 	; 30/12/2017 (TRDOS 386 = TRDOS v2.0)
   479                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
   480                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
   481                              <1> 	; 'convert_from_epoch' procedure prototype: 
   482                              <1> 	; 	            UNIXCOPY.ASM, 10/03/2013
   483                              <1> 	;
   484                              <1> 	; ((Modified registers: EAX, EDX, ECX, EBX))	
   485                              <1> 	;
   486                              <1> 	; Derived from DALLAS Semiconductor
   487                              <1> 	; Application Note 31 (DS1602/DS1603)
   488                              <1> 	; 6 May 1998
   489                              <1> 	;
   490                              <1> 	; INPUT:
   491                              <1> 	; EAX = Unix (Epoch) Time
   492                              <1> 	;
   493 00007128 31D2                <1> 	xor 	edx, edx
   494 0000712A B93C000000          <1> 	mov 	ecx, 60
   495 0000712F F7F1                <1> 	div	ecx
   496                              <1> 	;mov 	[imin], eax   ; whole minutes
   497                              <1> 			  ; since 1/1/1970
   498 00007131 668915[A6600100]    <1> 	mov 	[second], dx  ; leftover seconds
   499 00007138 29D2                <1> 	sub 	edx, edx
   500 0000713A F7F1                <1> 	div	ecx
   501                              <1> 	;mov 	[ihrs], eax   ; whole hours
   502                              <1> 	;		      ; since 1/1/1970
   503 0000713C 668915[A4600100]    <1> 	mov 	[minute], dx  ; leftover minutes
   504 00007143 31D2                <1> 	xor	edx, edx
   505                              <1> 	;mov 	cx, 24
   506 00007145 B118                <1> 	mov 	cl, 24
   507 00007147 F7F1                <1> 	div	ecx
   508                              <1> 	;mov 	[iday], ax   ; whole days
   509                              <1> 			     ; since 1/1/1970
   510 00007149 668915[A2600100]    <1> 	mov 	[hour], dx   ; leftover hours
   511 00007150 05DB020000          <1> 	add 	eax, 365+366 ; whole day since
   512                              <1> 			     ; 1/1/1968 	
   513                              <1> 	;mov 	[iday], ax
   514 00007155 50                  <1> 	push 	eax
   515 00007156 29D2                <1> 	sub	edx, edx
   516 00007158 B9B5050000          <1> 	mov 	ecx, (4*365)+1 ; 4 years = 1461 days
   517 0000715D F7F1                <1> 	div	ecx
   518 0000715F 59                  <1> 	pop 	ecx
   519                              <1> 	;mov 	[lday], ax   ; count of quadyrs (4 years)
   520 00007160 6652                <1> 	push 	dx
   521                              <1> 	;mov 	[qday], dx   ; days since quadyr began
   522 00007162 6683FA3C            <1> 	cmp 	dx, 31 + 29  ; if past feb 29 then
   523 00007166 F5                  <1> 	cmc		     ; add this quadyr's leap day
   524 00007167 83D000              <1> 	adc 	eax, 0	     ; to # of qadyrs (leap days)
   525                              <1> 	;mov 	[lday], ax   ; since 1968			  
   526                              <1> 	;mov 	cx, [iday]
   527 0000716A 91                  <1> 	xchg 	ecx, eax     ; ECX = lday, EAX = iday		  
   528 0000716B 29C8                <1> 	sub 	eax, ecx     ; iday - lday
   529 0000716D B96D010000          <1> 	mov 	ecx, 365
   530 00007172 31D2                <1> 	xor	edx, edx
   531                              <1> 	; EAX = iday-lday, EDX = 0
   532 00007174 F7F1                <1> 	div	ecx
   533                              <1> 	;mov 	[iyrs], ax   ; whole years since 1968
   534                              <1> 	;jday = iday - (iyrs*365) - lday
   535                              <1> 	;mov [jday], dx      ; days since 1/1 of current year
   536                              <1> 	;add	eax, 1968
   537 00007176 6605B007            <1> 	add 	ax, 1968     ; compute year
   538 0000717A 66A3[9C600100]      <1> 	mov 	[year], ax
   539 00007180 6689D1              <1> 	mov 	cx, dx
   540                              <1> 	;mov 	dx, [qday]
   541 00007183 665A                <1> 	pop 	dx
   542 00007185 6681FA6D01          <1> 	cmp 	dx, 365	     ; if qday <= 365 and qday >= 60	
   543 0000718A 7709                <1> 	ja 	short cfe1   ; jday = jday +1
   544 0000718C 6683FA3C            <1> 	cmp 	dx, 60       ; if past 2/29 and leap year then
   545 00007190 F5                  <1>         cmc		     ; add a leap day to the # of whole
   546 00007191 6683D100            <1> 	adc 	cx, 0        ; days since 1/1 of current year
   547                              <1> cfe1:			
   548                              <1> 	;mov 	[jday], cx
   549 00007195 66BB0C00            <1> 	mov 	bx, 12       ; estimate month
   550 00007199 66BA6E01            <1> 	mov 	dx, 366      ; mday, max. days since 1/1 is 365
   551 0000719D 6683E003            <1> 	and 	ax, 11b      ; year mod 4 (and dx, 3) 
   552                              <1> cfe2:	; Month calculation  ; 0 to 11  (11 to 0)	
   553 000071A1 6639D1              <1> 	cmp 	cx, dx       ; mday = # of days passed from 1/1
   554 000071A4 731D                <1> 	jnb 	short cfe3
   555 000071A6 664B                <1> 	dec 	bx           ; month = month - 1
   556 000071A8 66D1E3              <1> 	shl 	bx, 1 
   557 000071AB 668B93[A8600100]    <1> 	mov 	dx, [EBX+DMonth] ; # elapsed days at 1st of month
   558 000071B2 66D1EB              <1> 	shr 	bx, 1        ; bx = month - 1 (0 to 11)
   559 000071B5 6683FB01            <1> 	cmp	bx, 1        ; if month > 2 and year mod 4  = 0	
   560 000071B9 76E6                <1> 	jna 	short cfe2   ; then mday = mday + 1
   561 000071BB 08C0                <1> 	or 	al, al       ; if past 2/29 and leap year then
   562 000071BD 75E2                <1> 	jnz 	short cfe2   ; add leap day (to mday)
   563 000071BF 6642                <1> 	inc 	dx           ; mday = mday + 1
   564 000071C1 EBDE                <1> 	jmp 	short cfe2
   565                              <1> cfe3:
   566 000071C3 6643                <1> 	inc 	bx	     ; -> bx = month, 1 to 12
   567 000071C5 66891D[9E600100]    <1> 	mov 	[month], bx
   568 000071CC 6629D1              <1> 	sub 	cx, dx	     ; day = jday - mday + 1	
   569 000071CF 6641                <1> 	inc 	cx 			  
   570 000071D1 66890D[A0600100]    <1> 	mov 	[day], cx
   571                              <1> 	
   572                              <1> 	; eax, ebx, ecx, edx is changed at return
   573                              <1> 	; output ->
   574                              <1> 	; [year], [month], [day], [hour], [minute], [second]
   575                              <1> 
   576 000071D8 C3                  <1> 	retn	; 31/12/2017 (TRDOS 386)
   577                              <1> 
   578                              <1> set_rtc_date_time:
   579                              <1> 	; 31/12/2017 (v2.0.0)
   580                              <1> 	; 30/12/2017 (TRDOS 386)
   581                              <1> 	; 15/03/2015 (Retro UNIX 386 v1 - 32 bit version)
   582                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
   583 000071D9 E80F000000          <1> 	call	set_date_bcd
   584                              <1> 	; Set real-time clock date
   585 000071DE E837F3FFFF          <1> 	call	set_rtc_date ; RTC_50
   586                              <1> 	; Set real-time clock time
   587 000071E3 E832000000          <1> 	call	set_time_bcd
   588 000071E8 E9BEF2FFFF          <1> 	jmp	set_rtc_time ; RTC_30	
   589                              <1> 
   590                              <1> ; 31/12/2017
   591                              <1> set_date_bcd:
   592 000071ED A0[9D600100]        <1>         mov     al, [year+1]
   593 000071F2 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
   594 000071F4 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
   595                              <1> 			     ; AL = AH * 10h + AL
   596 000071F6 88C5                <1> 	mov 	ch, al ; century (BCD)
   597 000071F8 A0[9C600100]        <1> 	mov 	al, [year]
   598 000071FD D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
   599 000071FF D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
   600                              <1> 			     ; AL = AH * 10h + AL
   601 00007201 88C1                <1> 	mov 	cl, al ; year (BCD)
   602 00007203 A0[9E600100]        <1>         mov 	al, [month]
   603 00007208 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
   604 0000720A D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
   605                              <1> 			     ; AL = AH * 10h + AL
   606 0000720C 88C6                <1> 	mov 	dh, al ; month (BCD)
   607 0000720E A0[A0600100]        <1> 	mov 	al, [day]
   608 00007213 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
   609 00007215 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
   610                              <1> 			     ; AL = AH * 10h + AL
   611 00007217 88C6                <1> 	mov 	dh, al ; day (BCD)
   612 00007219 C3                  <1> 	retn	; 30/12/2017
   613                              <1> 
   614                              <1> ; 31/12/2017
   615                              <1> set_time_bcd:
   616                              <1>         ; Read real-time clock time 
   617                              <1> 	; (get day light saving time bit status)
   618 0000721A FA                  <1>  	cli
   619 0000721B E84CF4FFFF          <1> 	CALL	UPD_IPR 		; CHECK FOR UPDATE IN PROCESS
   620                              <1> 	; cf = 1 -> al = 0
   621 00007220 7207                <1>         jc      short stime1
   622 00007222 B00B                <1> 	MOV	AL,CMOS_REG_B		; ADDRESS ALARM REGISTER
   623 00007224 E85EF4FFFF          <1> 	CALL	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
   624                              <1> stime1:
   625 00007229 FB                  <1> 	sti
   626 0000722A 2401                <1> 	AND	AL,00000001B		; MASK FOR VALID DSE BIT
   627 0000722C 88C2                <1> 	MOV	DL,AL			; SET [DL] TO ZERO FOR NO DSE BIT
   628                              <1> 	; DL = 1 or 0 (day light saving time)
   629                              <1> 	;	
   630 0000722E A0[A2600100]        <1> 	mov 	al, [hour]
   631 00007233 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
   632 00007235 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
   633                              <1> 			     ; AL = AH * 10h + AL
   634 00007237 88C5                <1> 	mov 	ch, al ; hour (BCD)
   635 00007239 A0[A4600100]        <1>         mov     al, [minute]
   636 0000723E D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
   637 00007240 D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
   638                              <1> 			     ; AL = AH * 10h + AL
   639 00007242 88C1                <1> 	mov 	cl, al       ; minute (BCD)
   640 00007244 A0[A6600100]        <1>         mov     al, [second]
   641 00007249 D40A                <1> 	aam 	; ah = al / 10, al = al mod 10
   642 0000724B D510                <1> 	db 	0D5h,10h     ; Undocumented inst. AAD
   643                              <1> 			     ; AL = AH * 10h + AL
   644 0000724D 88C6                <1> 	mov 	dh, al	     ; second (BCD)
   645 0000724F C3                  <1> 	retn	; 30/12/2017
  3031                                  %include 'trdosk2.s' ; 04/01/2016
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.2) - DRV INIT : trdosk2.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 30/08/2020
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 04/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.14 (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> 	; 30/08/2020
    18                              <1> 	; 25/08/2020
    19                              <1> 	; 11/08/2020, 13/08/2020
    20                              <1> 	; 17/07/2020, 20/07/2020
    21                              <1> 	; 14/07/2020, 15/07/2020
    22                              <1> 	; 30/01/2018
    23                              <1> 	; 27/12/2017
    24                              <1> 	; 12/02/2016
    25                              <1> 	; 06/01/2016
    26                              <1> 	;  	('diskinit.inc', 'diskio.inc' integration)
    27                              <1> 	; 04/01/2016 (TRDOS 386 = TRDOS v2.0)
    28                              <1> 	; 07/08/2011
    29                              <1> 	; 20/09/2009
    30                              <1> 	; 2005
    31                              <1> 
    32                              <1> 	; 15/07/2020
    33                              <1> 	;movzx	ecx, byte [HF_NUM] ; number of fixed disks
    34                              <1> 	;cmp	cl, 1
    35                              <1> 	;jnb	short load_hd_partition_tables
    36                              <1> 
    37 00007250 A0[74640100]        <1> 	mov	al, [HF_NUM] ; number of fixed disks
    38 00007255 20C0                <1> 	and 	al, al
    39 00007257 7501                <1> 	jnz	short load_hd_partition_tables
    40                              <1> 
    41                              <1> 	; no any hard disks
    42 00007259 C3                  <1> 	retn			
    43                              <1> 
    44                              <1> load_hd_partition_tables:
    45                              <1> 	;mov	esi, [HDPM_TBL_VEC] ; primary master disk FDPT
    46                              <1> 	; 15/07/2020
    47 0000725A BE[78640100]        <1> 	mov	esi, HDPM_TBL_VEC
    48 0000725F BF[9E680100]        <1> 	mov 	edi, PTable_hd0
    49 00007264 B280                <1> 	mov 	dl, 80h
    50                              <1> 	; 15/07/2020
    51 00007266 A2[CD670000]        <1> 	mov	[hdc], al
    52                              <1> 	;xor	ecx, ecx ; 0
    53                              <1> load_next_hd_partition_table:
    54                              <1> 	; 20/07/2020
    55 0000726B 31C9                <1> 	xor	ecx, ecx ; 0
    56                              <1> 	;push	ecx
    57 0000726D 57                  <1> 	push	edi ; *
    58                              <1> 	;push	esi ; FDPT (+ DPTE) address
    59                              <1> 	; 15/07/2020
    60 0000726E AD                  <1> 	lodsd
    61 0000726F 56                  <1> 	push	esi ; ** ; next FDPT (+ DPTE) address ptr
    62                              <1> 	
    63                              <1> 	;mov	al, [esi+20] ; DPTE offset 4
    64                              <1> 	;and	al, 40h ;  LBA bit (bit 6)
    65                              <1> 	;;shr	al, 6
    66                              <1> 	;mov 	[HD_LBA_yes], al
    67                              <1> 	
    68                              <1> 	; 15/07/2020
    69 00007270 8A4814              <1> 	mov	cl, [eax+20]
    70 00007273 80E140              <1> 	and	cl, 40h
    71 00007276 880D[A2690100]      <1> 	mov	[HD_LBA_yes], cl
    72                              <1> 	
    73 0000727C E844040000          <1> 	call	load_masterboot
    74                              <1> 	;jc	short pass_pt_this_hard_disk
    75                              <1> 	; 13/08/2020
    76 00007281 0F828A000000        <1> 	jc	pass_pt_this_hard_disk
    77                              <1> 
    78 00007287 BB[5C680100]        <1> 	mov	ebx, PartitionTable
    79 0000728C 89DE                <1> 	mov	esi, ebx
    80                              <1> 	;mov	ecx, 16
    81 0000728E B110                <1> 	mov	cl, 16
    82 00007290 F3A5                <1> 	rep 	movsd
    83 00007292 89DE                <1> 	mov 	esi, ebx 
    84                              <1> 	;mov 	byte [hdc], 4 ; 4 - partition index
    85                              <1> 	; 15/07/2020
    86 00007294 C605[A3690100]04    <1> 	mov	byte [PP_Counter], 4
    87                              <1> loc_validate_hdp_partition:
    88                              <1> 	;cmp 	byte [esi+ptFileSystemID], 0
    89                              <1> 	;jna	short loc_validate_next_hdp_partition2
    90                              <1> 	; 13/08/2020
    91 0000729B 8A4604              <1> 	mov	al, [esi+ptFileSystemID]
    92 0000729E 20C0                <1> 	and	al, al
    93 000072A0 7457                <1> 	jz	short loc_validate_next_hdp_partition2
    94                              <1> 
    95 000072A2 56                  <1> 	push	esi ; *** ; Masterboot partition table offset
    96 000072A3 52                  <1> 	push	edx ; **** ; dl = Physical drive number
    97                              <1> 
    98                              <1> 	; 13/08/2020
    99 000072A4 3C05                <1> 	cmp	al, 05h  ; Extended partition CHS
   100 000072A6 7404                <1>  	je	short loc_set_ep_counter
   101 000072A8 3C0F                <1> 	cmp	al, 0Fh  ; Extended partition LBA
   102 000072AA 7511                <1>  	jne	short loc_validate_next_hdp_partition0
   103                              <1> 	
   104                              <1> 	;;inc	byte [PP_Counter]
   105                              <1> 	; 15/07/2020
   106                              <1> 	;inc 	byte [EP_Counter] ; disk has valid partition(s)
   107                              <1> 
   108                              <1> loc_set_ep_counter:
   109                              <1> 	; 13/08/2020
   110 000072AC 803D[A4690100]80    <1> 	cmp	byte [EP_Counter], 80h
   111 000072B3 7342                <1> 	jnb	short loc_validate_next_hdp_partition1
   112                              <1> 
   113 000072B5 8815[A4690100]      <1> 	mov	byte [EP_Counter], dl ; disk drv has extd. part.
   114                              <1> 
   115 000072BB EB3A                <1> 	jmp	short loc_validate_next_hdp_partition1
   116                              <1> 
   117                              <1> loc_validate_next_hdp_partition0:
   118 000072BD 31FF                <1> 	xor	edi, edi ; 0  
   119                              <1> 	; Input -> ESI = PartitionTable offset
   120                              <1> 	; DL = Hard disk drive number 
   121                              <1> 	; EDI = 0 -> Primary Partition
   122                              <1> 	; EDI > 0 -> Extended Partition's Start Sector   
   123 000072BF E885010000          <1> 	call 	validate_hd_fat_partition
   124 000072C4 730E                <1> 	jnc 	short loc_set_valid_hdp_partition_entry
   125                              <1> 
   126                              <1> 	;pop	edx
   127                              <1> 	;push	edx
   128 000072C6 8B1424              <1> 	mov	edx, [esp]  ; ****
   129 000072C9 8B742404            <1> 	mov	esi, [esp+4] ; *** ; 30/01/2018
   130 000072CD E8D1020000          <1> 	call	validate_hd_fs_partition
   131 000072D2 7223                <1> 	jc	short loc_validate_next_hdp_partition1
   132                              <1> loc_set_valid_hdp_partition_entry:
   133 000072D4 8A0D[F5170100]      <1> 	mov 	cl, [Last_DOS_DiskNo] 
   134 000072DA 80C141              <1> 	add 	cl, 'A'
   135                              <1> 	; ESI = Logical dos drive description table address
   136 000072DD 880E                <1> 	mov	[esi+LD_Name], cl
   137                              <1> 	; 15/07/2020
   138 000072DF 8A4602              <1> 	mov	al, [esi+LD_PhyDrvNo] ; Physical drive number
   139                              <1> 	;mov	al, [esp] ; ****
   140 000072E2 2C7F                <1> 	sub	al, 7Fh
   141                              <1> 		; AL = 1 to 4	
   142 000072E4 C0E002              <1> 	shl	al, 2 ; AL = 4 to 16
   143                              <1> 
   144 000072E7 8A15[A3690100]      <1> 	mov	dl, [PP_Counter]
   145                              <1> 
   146                              <1> 	;sub	al, [PP_Counter]
   147 000072ED 28D0                <1> 	sub	al, dl ; [PP_Counter] ; 4 - partition index
   148                              <1> 
   149                              <1> 	; AL = Partition entry/index, 0 based
   150                              <1> 	;  0 -> hd 0, Partition Table offset = 0
   151                              <1> 	; 15 -> hd 3, Partition Table offset = 3
   152                              <1> 
   153                              <1> 	;mov	[esi+LD_PartitionEntry], al 
   154                              <1> 	
   155                              <1> 	; 15/07/2020
   156 000072EF B404                <1> 	mov	ah, 4
   157                              <1> 	;sub	ah, [PP_Counter]
   158 000072F1 28D4                <1> 	sub	ah, dl
   159                              <1> 
   160                              <1> 	; AH = Primary partition index, 0 to 3 ; pt entry
   161                              <1> 	;		(4 to 7 for logical disk partitions)
   162                              <1> 
   163                              <1> 	;mov 	[esi+LD_DParamEntry], ah 
   164 000072F3 6689467C            <1> 	mov 	[esi+LD_PartitionEntry], ax
   165                              <1> 
   166                              <1> loc_validate_next_hdp_partition1:
   167 000072F7 5A                  <1> 	pop 	edx ; **** ; dl = Physical drive number 
   168 000072F8 5E                  <1> 	pop	esi ; *** ; Masterboot partition table offset
   169                              <1> 
   170                              <1> loc_validate_next_hdp_partition2:
   171                              <1> 	; ESI = PartitionTable offset
   172                              <1> 	; DL = Hard/Fixed disk drive number
   173                              <1> 	
   174                              <1> 	;dec	byte [hdc] ; 4 - partition index
   175                              <1> 	;jz	short pass_pt_this_hard_disk
   176                              <1> 	; 15/07/2020
   177 000072F9 FE0D[A3690100]      <1> 	dec	byte [PP_Counter] ; 4 - partition index
   178 000072FF 7410                <1> 	jz	short pass_pt_this_hard_disk
   179                              <1> 	
   180 00007301 83C610              <1> 	add	esi, 16 ; 10h
   181 00007304 EB95                <1> 	jmp	short loc_validate_hdp_partition
   182                              <1> 
   183                              <1> loc_not_any_extd_partitions:
   184                              <1> 	; 15/07/2020
   185 00007306 C3                  <1> 	retn	
   186                              <1> 
   187                              <1> loc_next_hd_partition_table:
   188 00007307 FEC2                <1> 	inc	dl
   189                              <1> 	; 15/07/2020
   190                              <1> 	;add	esi, 32 ; next FDPT address
   191 00007309 83C740              <1> 	add	edi, 64 ; next partition table destination
   192 0000730C E95AFFFFFF          <1>         jmp     load_next_hd_partition_table
   193                              <1> 
   194                              <1> pass_pt_this_hard_disk:
   195                              <1> 	;pop	esi ; FDPT (+ DPTE) address
   196                              <1> 	; 15/07/2020
   197 00007311 5E                  <1> 	pop	esi ; ** ; next FDPT (+ DPTE) address ptr
   198 00007312 5F                  <1> 	pop	edi ; * ; Ptable_hd?
   199                              <1> 	;pop	ecx
   200                              <1> 	;loop	loc_next_hd_partition_table
   201 00007313 FE0D[CD670000]      <1> 	dec	byte [hdc]
   202 00007319 75EC                <1> 	jnz	short loc_next_hd_partition_table
   203                              <1> 
   204                              <1> 	;cmp	byte [PP_Counter], 1
   205                              <1> 	;jnb	short load_extended_dos_partitions
   206                              <1> 	;; Empty partition table
   207                              <1> 	;retn
   208                              <1> 
   209                              <1> 	; 11/08/2020
   210                              <1> 	; 17/07/2020
   211                              <1> check_extended_partitions:
   212                              <1> 	; 15/07/2020
   213                              <1> 	;cmp	byte [EP_Counter], 0
   214                              <1> 	;jna	short loc_not_any_extd_partitions
   215                              <1> 	; 13/08/2020
   216 0000731B A0[A4690100]        <1> 	mov	al, [EP_Counter] ; 1st disk drv has extd partition
   217 00007320 08C0                <1> 	or	al, al ; 0 ?
   218 00007322 74E2                <1> 	jz	short loc_not_any_extd_partitions
   219                              <1> 
   220                              <1> load_extended_dos_partitions:
   221                              <1> 	;mov	byte [hdc], 80h
   222                              <1> 	; 13/08/2020
   223 00007324 A2[CD670000]        <1> 	mov	byte [hdc], al ; 1st disk drv has extd partition
   224                              <1> 	; 25/08/2020
   225 00007329 2C80                <1> 	sub	al, 80h
   226 0000732B 740E                <1> 	jz	short loc_set_ext_ptable_hd0
   227 0000732D C0E006              <1> 	shl	al, 6 ; * 64
   228 00007330 0FB6F0              <1> 	movzx	esi, al
   229 00007333 81C6[9E680100]      <1> 	add	esi, PTable_hd0
   230 00007339 EB05                <1> 	jmp 	short next_hd_extd_partition
   231                              <1> 
   232                              <1> 	; 25/08/2020
   233                              <1> loc_set_ext_ptable_hd0:
   234 0000733B BE[9E680100]        <1> 	mov	esi, PTable_hd0
   235                              <1> 
   236                              <1> next_hd_extd_partition:
   237                              <1> 	; 17/07/2020
   238                              <1> 	;mov 	byte [EP_Counter], 0 ; Reset for each physical disk
   239                              <1> 	; 13/08/2020
   240                              <1> 	;mov	byte [LD_Counter], 0 ; Reset logical drive index
   241 00007340 66C705[A4690100]00- <1> 	mov 	word [EP_Counter], 0 ; Reset EP index and LD index	
   241 00007348 00                  <1>
   242                              <1> 
   243 00007349 56                  <1> 	push	esi ; **** ; PTable_hd? offset
   244                              <1> 	
   245 0000734A C605[A3690100]04    <1> 	mov 	byte [PP_Counter], 4 
   246                              <1> 				; set for each extd partition table
   247                              <1> 	;;mov	ecx, 4
   248                              <1> 	;mov	cl, 4
   249 00007351 8A15[CD670000]      <1> 	mov	dl, [hdc]
   250                              <1> hd_check_fs_id_05h:
   251 00007357 8A4604              <1> 	mov	al, [esi+ptFileSystemID]
   252 0000735A 3C05                <1> 	cmp	al, 05h ; Is it an extended dos partition ?
   253 0000735C 7411                <1> 	je	short loc_set_ep_start_sector ; yes
   254                              <1> hd_check_fs_id_0Fh:
   255 0000735E 3C0F                <1> 	cmp	al, 0Fh ; Is it an extended win4 (LBA mode) partition ?
   256 00007360 740D                <1> 	je	short loc_set_ep_start_sector ; yes
   257                              <1> 
   258                              <1> continue_to_check_ep:
   259                              <1> 	;add	esi, 16
   260                              <1> 	;loop	hd_check_fs_id_05h
   261                              <1> 	; 15/07/2020
   262                              <1> 	;dec	cl
   263                              <1> 	;jz	short continue_check_ep_next_disk
   264 00007362 FE0D[A3690100]      <1> 	dec	byte [PP_Counter] ; 4 --> 0
   265 00007368 742D                <1> 	jz	short continue_check_ep_next_disk
   266 0000736A 83C610              <1> 	add	esi, 16
   267 0000736D EBE8                <1> 	jmp	short hd_check_fs_id_05h
   268                              <1> 
   269                              <1> loc_set_ep_start_sector:
   270                              <1> 	; dl = [hdc] ; Drive number
   271                              <1> 	; 15/07/2020
   272 0000736F 8B4E08              <1> 	mov	ecx, [esi+ptStartSector]
   273                              <1> 	; 30/08/2020
   274 00007372 890D[A6690100]      <1> 	mov	[MBR_EP_StartSector], ecx 
   275                              <1> 	; 20/07/2020
   276                              <1> loc_validate_hde_partition_next:
   277 00007378 890D[AA690100]      <1> 	mov	[EP_StartSector], ecx ; Extended partition's start sector
   278 0000737E BB[9E660100]        <1>         mov	ebx, MasterBootBuff
   279 00007383 803D[A2690100]01    <1> 	cmp	byte [HD_LBA_yes], 1 ; LBA ready = Yes
   280 0000738A 7227                <1> 	jb	short loc_hd_load_ep_05h ; cf = 1 ; 20/07/2020 
   281                              <1> 	; 11/08/2020
   282                              <1> 	; (BugFix for extended partition type 05h beyond CHS limit)
   283                              <1> 	; (Infact if extended partition starts at the beyond of CHS limit,
   284                              <1> 	;  it's partition ID must be 0Fh but they/somebodies had used 05h.)
   285                              <1> 	;cmp	al, 05h
   286                              <1> 	;je	short loc_hd_load_ep_05h
   287                              <1> loc_hd_load_ep_0Fh:
   288                              <1> 	; 04/01/2016
   289                              <1> 	;push	ecx
   290                              <1> 	; 15/07/2020
   291                              <1> 	;mov	ecx, [esi+ptStartSector] ; sector number
   292                              <1> 	;mov	ebx, MasterBootBuff ; buffer address
   293                              <1> 	; LBA read/write (with private LBA function) 
   294                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
   295                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
   296                              <1> 	;mov	ah, 1Bh ; LBA read
   297                              <1> 	;mov	al, 1 ; sector count
   298 0000738C 66B8011B            <1> 	mov	ax, 1B01h
   299 00007390 E865D8FFFF          <1> 	call	int13h
   300                              <1> 	;pop	ecx
   301                              <1> 	;jnc	short loc_hd_move_ep_table
   302                              <1> 	; 15/07/2020
   303 00007395 732E                <1> 	jnc	short loc_validate_hde_partition
   304                              <1> 
   305                              <1> continue_check_ep_next_disk:
   306                              <1> 	; 15/07/2020
   307                              <1> 	;pop	edi ; PTable_ep?
   308 00007397 5E                  <1> 	pop	esi ; **** ; PTable_hd?
   309 00007398 A0[74640100]        <1> 	mov	al, [HF_NUM] ; number of hard disks
   310 0000739D 047F                <1> 	add	al, 7Fh
   311 0000739F 3805[CD670000]      <1> 	cmp	[hdc], al
   312 000073A5 730B                <1> 	jnb	short loc_validating_hd_partitions_ok
   313 000073A7 83C640              <1> 	add	esi, 64
   314                              <1> 	; 15/07/2020
   315                              <1> 	;add	edi, 64
   316 000073AA FE05[CD670000]      <1> 	inc	byte [hdc]
   317 000073B0 EB8E                <1> 	jmp	short next_hd_extd_partition
   318                              <1> 
   319                              <1> loc_validating_hd_partitions_ok:
   320                              <1> 	; 15/07/2020
   321                              <1> 	;mov	al, [Last_DOS_DiskNo]
   322                              <1> loc_drv_init_retn:
   323 000073B2 C3                  <1> 	retn
   324                              <1> 	
   325                              <1> loc_hd_load_ep_05h:
   326                              <1> 	; 20/07/2020 ('diskio.s', int13h, cf = 1 -> bugfix)
   327                              <1> 	;clc    ; (Bug: int13h would not clear carry flag bit, 
   328                              <1> 	;	; even if there would not be an error)
   329                              <1> 	;	; ((Fix: now, int13h procedure clears carry flag
   330                              <1> 	;	;  at the entrance of it.. 20/07/2020))
   331                              <1> 	; 15/07/2020
   332                              <1> 	;push	ecx 
   333 000073B3 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   334 000073B6 668B4E02            <1>         mov     cx, [esi+ptBeginSector]
   335 000073BA 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   336                              <1> 	;mov	ebx, MasterBootBuff
   337 000073BE E837D8FFFF          <1> 	call	int13h ; 20/07/2020
   338                              <1> 		       ; 'diskio.s' modification, 'clc'
   339                              <1> 	;pop	ecx  
   340 000073C3 72D2                <1> 	jc	short continue_check_ep_next_disk
   341                              <1> 	; 15/07/2020
   342                              <1> 	;jmp	short loc_validate_hde_partition
   343                              <1> 
   344                              <1> 	; 15/07/2020
   345                              <1> ;loc_hd_move_ep_table:
   346                              <1> 	;;pop	edi
   347                              <1> 	;;push	edi  ; PTable_ep?
   348                              <1> 	;mov	edi, [esp]        
   349                              <1>         ;mov	esi, PartitionTable ; Extended
   350                              <1> 	;mov	ebx, esi
   351                              <1> 	;;mov	ecx, 16
   352                              <1> 	;mov	cl, 16
   353                              <1>        	;rep	movsd
   354                              <1> 	;mov	esi, ebx 
   355                              <1> ;loc_set_hde_sub_partition_count:
   356                              <1> 	;mov	byte [PP_Counter], 4
   357                              <1> 	;mov	byte [EP_Counter], 0
   358                              <1> 
   359                              <1> loc_validate_hde_partition:
   360                              <1> 	; 13/08/2020
   361                              <1> 	; 15/07/2020
   362                              <1> 	;mov	byte [PP_Counter], 4
   363 000073C5 BE[5C680100]        <1> 	mov	esi, PartitionTable ; (in MasterBootBuff)
   364                              <1> 	; 13/08/2020
   365                              <1> 	;jmp	short get_minidisk_partition_entry
   366                              <1> 
   367                              <1> ;get_minidisk_partition_entry:
   368                              <1> ;	; 20/07/2020
   369                              <1> ;	cmp	byte [esi+ptFileSystemID], 0
   370                              <1> ;	ja	short loc_validate_minidisk_partition
   371                              <1> ;	; 13/08/2020
   372                              <1> ;	jmp	short continue_check_ep_next_disk
   373                              <1> 
   374                              <1> ;	; 11/08/2020
   375                              <1> ;get_minidisk_partition_entry_next:
   376                              <1> ;	; 13/08/2020
   377                              <1> ;	;dec 	byte [PP_Counter]
   378                              <1> ;	;jz	short continue_check_ep_next_disk
   379                              <1> ;	; 20/07/2020
   380                              <1> ;;get_minidisk_partition_entry_next:
   381                              <1> ;	; 13/08/2020
   382                              <1> ;	cmp	esi, PartitionTable+64 
   383                              <1> ;	jnb	short continue_check_ep_next_disk
   384                              <1> ;	
   385                              <1> ;	add 	esi, 16 ; 10h
   386                              <1> ;	;jmp	short get_minidisk_partition_entry
   387                              <1> 
   388                              <1> 	; 13/08/2020
   389                              <1> get_minidisk_partition_entry:
   390                              <1> 	; 20/07/2020
   391 000073CA 807E0400            <1> 	cmp	byte [esi+ptFileSystemID], 0
   392 000073CE 76C7                <1> 	jna	short continue_check_ep_next_disk ; 13/08/2020
   393                              <1> 
   394                              <1> loc_validate_minidisk_partition:
   395                              <1> 	; 13/08/2020
   396                              <1> 	; 20/07/2020
   397                              <1> 	;push	esi ; *** ; Extended partition table offset
   398                              <1> 
   399                              <1> 	; 13/08/2020
   400 000073D0 FE05[A4690100]      <1> 	inc	byte [EP_Counter] ; current (sub partition) index 
   401                              <1> 				  ; in current extended partition
   402                              <1> 
   403 000073D6 BF[AA690100]        <1> 	mov	edi, EP_StartSector
   404                              <1> 
   405                              <1> 	; Input -> ESI = PartitionTable offset
   406                              <1> 	; DL = Hard disk drive number   
   407                              <1> 	; EDI = Extended partition start sector pointer
   408 000073DB E869000000          <1> 	call	validate_hd_fat_partition
   409                              <1> 	;pop	ecx ; *
   410 000073E0 7308                <1> 	jnc	short loc_set_valid_hde_partition_entry
   411                              <1> 			 ; jump down to deep !!!
   412                              <1> 
   413                              <1> 	;pop	esi ; *** ; Extended partition table offset
   414                              <1> 	; 13/08/2020
   415                              <1> 	;mov	esi, PartitionTable
   416                              <1> 
   417                              <1> 	; 11/08/2020
   418                              <1> 	; ESI = Extended partition table offset
   419 000073E2 8A15[CD670000]      <1> 	mov	dl, [hdc]
   420                              <1> 
   421                              <1> 	;; DL = Hard disk drive number
   422                              <1> 	;dec	byte [PP_Counter]
   423                              <1> 	;jz	short continue_check_ep_next_disk
   424                              <1> 	;add 	esi, 16 ; 10h
   425                              <1> 	;mov	dl, [hdc]
   426                              <1> 	;jmp	short get_minidisk_partition_entry
   427                              <1> 
   428                              <1> 	; 11/08/2020
   429                              <1> 	;jmp	short get_minidisk_partition_entry_next
   430                              <1> 
   431                              <1> 	; 23/08/2020
   432 000073E8 EB3D                <1> 	jmp	short validate_next_minidisk_partition_ok
   433                              <1> 
   434                              <1> 	; 17/07/2020
   435                              <1> 	;; jumping down to deep levels !!!
   436                              <1> 	; ((That is a pitty microsoft preferred ep table chain
   437                              <1> 	; instead of a single table as mbr partition table!?))
   438                              <1> 
   439                              <1> loc_set_valid_hde_partition_entry:
   440                              <1> 	; 15/07/2020
   441 000073EA A0[CD670000]        <1> 	mov	al, [hdc] ; Hard disk drive number (>=80h)
   442 000073EF 88C2                <1> 	mov	dl, al ; mov dl, [hdc]
   443 000073F1 2C7F                <1> 	sub	al, 7Fh
   444                              <1> 		    ; 1 to 4	
   445 000073F3 C0E002              <1> 	shl	al, 2 ; 4 to 16
   446 000073F6 2A05[A3690100]      <1> 	sub	al, [PP_Counter] ; al - (4 - partition index)
   447                              <1> 			; (disk number * 4) + partition index
   448                              <1> 	
   449                              <1> 	; AL = Partition entry/index, 0 based
   450                              <1>         ;  0 -> hd 0, Partition Table offset = 0
   451                              <1>         ; 15 -> hd 3, Partition Table offset = 3
   452                              <1> 
   453                              <1> 	;mov	ah, 4 ; Logical dos partition (>= 4)
   454                              <1> 	;add	ah, [EP_Counter]
   455                              <1> 		; Logical disk partition index = 4 to 7
   456                              <1> 		; (Primary disk partition index = 0 to 3)
   457                              <1> 
   458                              <1> 	; 13/08/2020
   459 000073FC 8A25[A5690100]      <1> 	mov	ah, [LD_Counter] ; Logical drive index number
   460                              <1> 				; (in current extended partition)
   461 00007402 80C404              <1> 	add	ah, 4 ; 4 to 7
   462                              <1> 	
   463                              <1> 	; 15/07/2020
   464                              <1> 	; CX -> AX
   465                              <1> 	;; 06/01/2016 (TRDOS v2.0)
   466                              <1> 	;; BUGFIX *
   467                              <1> 	;;mov	[esi+LD_PartitionEntry], cl 
   468                              <1> 	;;mov	[esi+LD_DParamEntry], ch 
   469                              <1> 	;mov	[esi+LD_PartitionEntry], cx 
   470 00007405 6689467C            <1> 	mov	[esi+LD_PartitionEntry], ax 	
   471                              <1> 
   472 00007409 8A0D[F5170100]      <1> 	mov	cl, [Last_DOS_DiskNo] 
   473 0000740F 80C141              <1> 	add	cl, 'A'
   474 00007412 880E                <1> 	mov	[esi+LD_Name], cl
   475                              <1> 
   476                              <1> 	; 17/07/2020
   477                              <1> 	;cmp	cl, 'Z'
   478                              <1> 	;jb	short logical_drive_count_ok_for_next
   479                              <1> 	;pop	esi ; ***
   480                              <1> 	;pop	esi ; ****
   481                              <1> 	;retn
   482                              <1> 
   483                              <1> ;logical_drive_count_ok_for_next:
   484                              <1> 
   485                              <1> 	;; 15/07/2020
   486                              <1> 	;inc	byte [EP_Counter]
   487                              <1> 	; 13/08/2020
   488 00007414 FE05[A5690100]      <1> 	inc	byte [LD_Counter]	
   489                              <1> 
   490                              <1> 	;mov	dl, [hdc]
   491                              <1> 
   492                              <1> 	; 17/07/2020
   493                              <1> 	;; Now, 
   494                              <1> 	;; we are swimming in deep of an extended partition !!!
   495                              <1> 	; (! sub or chained extended partition tables !)
   496                              <1> 	; ((Logical dos partitions in extended partition were called
   497                              <1> 	;  as 'mini disk partition' in msdos 6.0 source code.))
   498                              <1> 
   499                              <1> validate_next_minidisk_partition:
   500                              <1> 	; 13/08/2020
   501                              <1> 	;pop	esi ; *** ; Extended partition table offset
   502                              <1> 
   503                              <1> 	; 17/07/2020
   504                              <1> 	;cmp	byte [EP_Counter], 4
   505                              <1> 	; 13/08/2020
   506 0000741A 803D[A5690100]04    <1> 	cmp	byte [LD_Counter], 4 ; maximum 4 logical disks
   507                              <1> 				     ; per extended partition
   508 00007421 0F8370FFFFFF        <1> 	jnb	continue_check_ep_next_disk
   509                              <1> 
   510                              <1> validate_next_minidisk_partition_ok:
   511                              <1> 	; 13/08/2020
   512                              <1> 	;dec	byte [PP_Counter] ; 4 --> 0
   513                              <1> 	;jz	continue_check_ep_next_disk
   514                              <1> 	
   515                              <1> 	;cmp	esi, PartitionTable+64 
   516                              <1> 	;jnb	continue_check_ep_next_disk
   517                              <1> 
   518                              <1> 	;add	esi, 16
   519                              <1> 	; 13/08/2020
   520 00007427 BE[6C680100]        <1> 	mov	esi, PartitionTable+16
   521                              <1> 
   522                              <1> 	; 20/07/2020
   523 0000742C 8A4604              <1> 	mov	al, [esi+ptFileSystemID]
   524                              <1> 
   525                              <1> 	; 20/07/2020
   526 0000742F 3C05                <1> 	cmp	al, 05h ; Is it an extended dos partition ?
   527 00007431 7408                <1> 	je	short loc_minidisk_next_ep_lba_chs ; 17/07/2020
   528 00007433 3C0F                <1> 	cmp	al, 0Fh ; Is it an extended win4 (LBA mode) partition ?
   529 00007435 0F855CFFFFFF        <1> 	jne	continue_check_ep_next_disk ; AL must be 0 here
   530                              <1> 					; (when it is not 05h or 0Fh)
   531                              <1> 					; If AL is not ZERO -> EP Bug!
   532                              <1> 					; (!Microsoft DOS convention!)
   533                              <1> loc_minidisk_next_ep_lba_chs:
   534                              <1> 	; 17/07/2020
   535 0000743B 8B4E08              <1> 	mov	ecx, [esi+ptStartSector] ; relative start sector number
   536                              <1> 	;add	ecx, [EP_StartSector]
   537                              <1> 	; 30/08/2020	
   538 0000743E 030D[A6690100]      <1> 	add	ecx, [MBR_EP_StartSector] 
   539                              <1> 	; 20/07/2020
   540 00007444 E92FFFFFFF          <1> 	jmp	loc_validate_hde_partition_next
   541                              <1> 
   542                              <1> validate_hd_fat_partition:
   543                              <1> 	; 17/07/2020
   544                              <1> 	; 15/07/2020
   545                              <1> 	;	(optimization)
   546                              <1> 	; 14/07/2020
   547                              <1> 	;	(fat16 -big- partition search bugfix)
   548                              <1> 	; 27/12/2017
   549                              <1> 	; 12/02/2016
   550                              <1> 	; 07/01/2016 (TRDOS 386 = TRDOS v2.0)
   551                              <1> 	; 07/08/2011
   552                              <1> 	; 23/07/2011
   553                              <1> 	; Input
   554                              <1> 	;   DL = Hard/Fixed Disk Drive Number
   555                              <1> 	;   ESI = PartitionTable offset
   556                              <1> 	;   EDI = Extend. Part. Start Sector Pointer
   557                              <1> 	;   EDI = 0 -> Primary Partition 
   558                              <1> 	;   byte [Last_DOS_DiskNo]
   559                              <1>  	; Output
   560                              <1> 	;  cf=0 -> Validated
   561                              <1> 	;   ESI = Logical dos drv desc. table
   562                              <1> 	;   EBX = FAT boot sector buffer
   563                              <1> 	;   byte [Last_DOS_DiskNo]
   564                              <1> 	;  cf=1 -> Not a valid FAT partition
   565                              <1> 	; EAX, EDX, ECX, EDI -> changed 
   566                              <1> 	
   567                              <1> 	;mov 	esi, PartitionTable
   568 00007449 8A6604              <1> 	mov 	ah, [esi+ptFileSystemID]
   569 0000744C B002                <1> 	mov	al, 2 ; 27/12/2017
   570 0000744E 80FC06              <1> 	cmp 	ah, 06h ; FAT16 CHS partition (>=32MB)
   571                              <1> 	; 12/02/2016
   572                              <1> 	;;jb	short loc_not_a_valid_fat_partition2
   573                              <1>  	;jnb	short vhdp_FAT16_32
   574                              <1> 	; 14/07/2020 (BugFix)
   575 00007451 7711                <1> 	ja	short vhdp_FAT16_32
   576 00007453 7425                <1> 	je	short loc_set_valid_hd_partition_params
   577                              <1> 
   578                              <1> vhdp_FAT12_16:
   579                              <1> 	; 27/12/2017
   580 00007455 FEC8                <1> 	dec	al ; mov al, 1
   581 00007457 38C4                <1> 	cmp	ah, al ; 1 ; FAT12 partition
   582 00007459 741F                <1> 	je	short loc_set_valid_hd_partition_params
   583                              <1> 	;
   584 0000745B FEC0                <1> 	inc	al ; mov al, 2
   585 0000745D 80FC04              <1> 	cmp	ah, 04h ; FAT16 CHS partition (< 32MB)
   586 00007460 7418                <1> 	je	short loc_set_valid_hd_partition_params
   587                              <1> 	
   588                              <1> 	; 15/07/2020
   589                              <1> 	; (ah = 05h, 02h or 03h)
   590                              <1> loc_not_a_valid_fat_partition1:
   591 00007462 F9                  <1> 	stc
   592                              <1> 	; cf=1
   593 00007463 C3                  <1> 	retn
   594                              <1> 
   595                              <1> vhdp_FAT16_32:
   596                              <1> 	; 15/07/2020
   597                              <1> 	;mov	al, 3
   598 00007464 FEC0                <1> 	inc	al
   599 00007466 80FC0C              <1> 	cmp	ah, 0Ch ; FAT32 LBA partition
   600 00007469 740F                <1> 	je	short loc_set_valid_hd_partition_params
   601 0000746B 7706                <1> 	ja	short vhdp_check_FAT16_lba
   602                              <1> 
   603                              <1> vhdp_check_FAT32_chs:
   604 0000746D 80FC0B              <1> 	cmp	ah, 0Bh ; FAT32 CHS partition 
   605 00007470 7408                <1> 	je	short loc_set_valid_hd_partition_params
   606                              <1> 	;jne	short loc_not_a_valid_fat_partition1
   607                              <1> 
   608                              <1> 	;stc
   609                              <1> loc_not_a_valid_fat_partition2:
   610 00007472 C3                  <1> 	retn
   611                              <1> 
   612                              <1> vhdp_check_FAT16_lba:
   613 00007473 80FC0E              <1> 	cmp	ah, 0Eh ; FAT16 LBA partition
   614 00007476 75EA                <1> 	jne	short loc_not_a_valid_fat_partition1
   615                              <1> 
   616                              <1> 	;mov	al, 2
   617 00007478 FEC8                <1> 	dec	al
   618                              <1> 
   619                              <1> loc_set_valid_hd_partition_params:
   620                              <1> 	; 15/07/2020
   621                              <1> 	;inc 	byte [Last_DOS_DiskNo] ; > 1
   622                              <1> 	;
   623 0000747A 31DB                <1> 	xor	ebx, ebx
   624 0000747C 8A3D[F5170100]      <1> 	mov	bh, [Last_DOS_DiskNo] ; * 256	
   625 00007482 FEC7                <1> 	inc	bh ; 15/07/2020
   626 00007484 81C300010900        <1> 	add	ebx, Logical_DOSDisks
   627                              <1> 	;
   628 0000748A C6430102            <1> 	mov	byte [ebx+LD_DiskType], 2
   629 0000748E 885302              <1> 	mov	byte [ebx+LD_PhyDrvNo], dl
   630                              <1> 	;mov	byte [ebx+LD_FATType], al ; 2 or 3
   631                              <1> 	;mov	byte [ebx+LD_FSType], ah ; 06h, 0Eh, 0Bh, 0Ch
   632 00007491 66894303            <1> 	mov	word [ebx+LD_FATType], ax
   633                              <1> 	;
   634 00007495 8B4E08              <1> 	mov	ecx, [esi+ptStartSector]
   635 00007498 09FF                <1> 	or	edi, edi 
   636 0000749A 7402                <1> 	jz	short pass_hd_FAT_ep_start_sector_adding
   637                              <1> loc_add_hd_FAT_ep_start_sector:
   638                              <1> 	; 17/07/2020
   639 0000749C 030F                <1> 	add	ecx, [edi]
   640                              <1> pass_hd_FAT_ep_start_sector_adding:
   641 0000749E 894B6C              <1> 	mov	[ebx+LD_StartSector], ecx
   642                              <1> loc_hd_FAT_logical_drv_init:
   643 000074A1 89DD                <1> 	mov	ebp, ebx
   644                              <1> 	;mov	dl, [ebx+LD_PhyDrvNo]
   645 000074A3 A0[A2690100]        <1> 	mov	al, [HD_LBA_yes] ; 07/01/2016
   646 000074A8 884305              <1> 	mov	[ebx+LD_LBAYes], al
   647 000074AB BB[AE690100]        <1> 	mov	ebx, DOSBootSectorBuff ; buffer address
   648 000074B0 08C0                <1> 	or	al, al
   649 000074B2 740C                <1> 	jz	short loc_hd_FAT_drv_init_load_bs_chs
   650                              <1> loc_hd_FAT_drv_init_load_bs_lba:
   651                              <1> 	; DL = Physical drive number
   652                              <1>    	;mov	ecx, [esi+ptStartSector] ; sector number
   653                              <1> 	;mov	ebx, DOSBootSectorBuff ; buffer address
   654                              <1> 	; LBA read/write (with private LBA function) 
   655                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
   656                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
   657 000074B4 B41B                <1> 	mov	ah, 1Bh ; LBA read
   658 000074B6 B001                <1> 	mov	al, 1 ; sector count
   659 000074B8 E83DD7FFFF          <1> 	call	int13h
   660 000074BD 7313                <1> 	jnc	short loc_hd_drv_FAT_boot_validation
   661                              <1> loc_not_a_valid_fat_partition3:
   662 000074BF C3                  <1> 	retn
   663                              <1> loc_hd_FAT_drv_init_load_bs_chs:
   664 000074C0 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   665 000074C3 668B4E02            <1> 	mov	cx, [esi+ptBeginSector]
   666 000074C7 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   667                              <1> 	;mov	ebx, DOSBootSectorBuff
   668 000074CB E82AD7FFFF          <1> 	call	int13h
   669 000074D0 72ED                <1> 	jc	short loc_not_a_valid_fat_partition3
   670                              <1> loc_hd_drv_FAT_boot_validation:
   671                              <1> 	;mov	esi, DOSBootSectorBuff
   672 000074D2 89DE                <1> 	mov	esi, ebx
   673 000074D4 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
   674 000074DD 7512                <1> 	jne	short loc_not_a_valid_fat_partition4
   675 000074DF 807E15F8            <1> 	cmp	byte [esi+BPB_Media], 0F8h
   676 000074E3 750C                <1> 	jne	short loc_not_a_valid_fat_partition4
   677                              <1> 
   678                              <1> 	; 27/12/2017
   679 000074E5 807D0303            <1> 	cmp	byte [ebp+LD_FATType], 3
   680 000074E9 7508                <1> 	jne	short loc_hd_FAT16_BPB
   681                              <1> 
   682                              <1> loc_hd_drv_FAT32_boot_validation:
   683 000074EB 807E4229            <1> 	cmp	byte [esi+BS_FAT32_BootSig], 29h
   684 000074EF 7416                <1> 	je	short loc_hd_FAT32_BPB
   685                              <1> 
   686                              <1> loc_not_a_valid_fat_partition4:
   687 000074F1 F9                  <1> 	stc
   688 000074F2 C3                  <1> 	retn
   689                              <1> 
   690                              <1> loc_hd_FAT16_BPB:
   691 000074F3 807E2629            <1> 	cmp	byte [esi+BS_BootSig], 29h
   692 000074F7 75F8                <1> 	jne	short loc_not_a_valid_fat_partition4
   693                              <1> 
   694 000074F9 66837E1600          <1> 	cmp	word [esi+BPB_FATSz16], 0
   695 000074FE 7607                <1> 	jna	short loc_hd_big_FAT16_BPB
   696 00007500 B920000000          <1> 	mov	ecx, 32
   697 00007505 EB05                <1> 	jmp	short loc_hd_move_FAT_BPB
   698                              <1> 
   699                              <1> loc_hd_FAT32_BPB:
   700                              <1> 	;cmp	word [esi+BPB_FATSz16], 0
   701                              <1> 	;ja	short loc_not_a_valid_fat_partition4
   702                              <1> loc_hd_big_FAT16_BPB:
   703 00007507 B92D000000          <1> 	mov	ecx, 45
   704                              <1> 	
   705                              <1> loc_hd_move_FAT_BPB:
   706 0000750C 89EF                <1> 	mov 	edi, ebp
   707                              <1> 	;mov	esi, ebx ; Boot sector
   708 0000750E 57                  <1> 	push	edi
   709 0000750F 83C706              <1> 	add	edi, LD_BPB
   710 00007512 F366A5              <1> 	rep	movsw 
   711 00007515 5E                  <1> 	pop	esi
   712 00007516 0FB74614            <1> 	movzx	eax, word [esi+LD_BPB+BPB_RsvdSecCnt]
   713 0000751A 03466C              <1> 	add	eax, [esi+LD_StartSector]
   714 0000751D 894660              <1> 	mov	[esi+LD_FATBegin], eax
   715 00007520 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3
   716 00007524 7224                <1> 	jb	short loc_set_FAT16_RootDirLoc
   717                              <1> loc_set_FAT32_RootDirLoc:
   718 00007526 8B462A              <1> 	mov	eax, [esi+LD_BPB+BPB_FATSz32]
   719 00007529 0FB65E16            <1>         movzx	ebx, byte [esi+LD_BPB+BPB_NumFATs]
   720 0000752D F7E3                <1> 	mul	ebx
   721 0000752F 034660              <1> 	add	eax, [esi+LD_FATBegin]
   722                              <1> loc_set_FAT32_data_begin:
   723 00007532 894668              <1> 	mov	[esi+LD_DATABegin], eax
   724 00007535 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
   725                              <1> 	; If Root Directory Cluster <> 2 then
   726                              <1> 	; change the beginning sector value 
   727                              <1> 	; of the root dir by adding sector offset.
   728 00007538 8B4632              <1> 	mov	eax, [esi+LD_BPB+BPB_RootClus]
   729 0000753B 83E802              <1> 	sub	eax, 2
   730 0000753E 7435                <1> 	jz	short short loc_set_32bit_FAT_total_sectors  
   731                              <1> 	;movzx	ebx, byte [esi+LD_BPB+BPB_SecPerClust]
   732 00007540 8A5E13              <1> 	mov	bl, [esi+LD_BPB+BPB_SecPerClust] 
   733 00007543 F7E3                <1> 	mul	ebx
   734 00007545 014664              <1> 	add	[esi+LD_ROOTBegin], eax
   735 00007548 EB2B                <1> 	jmp	short loc_set_32bit_FAT_total_sectors
   736                              <1> 	;
   737                              <1> loc_set_FAT16_RootDirLoc:
   738 0000754A 0FB64616            <1> 	movzx	eax, byte [esi+LD_BPB+BPB_NumFATs]
   739 0000754E 0FB7561C            <1> 	movzx	edx, word [esi+LD_BPB+BPB_FATSz16]
   740 00007552 F7E2                <1> 	mul	edx
   741 00007554 034660              <1> 	add	eax, [esi+LD_FATBegin]  
   742 00007557 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
   743                              <1> loc_set_FAT16_data_begin:
   744 0000755A 894668              <1> 	mov	[esi+LD_DATABegin], eax 
   745                              <1> 	;mov	eax, 20h  ; Size of a directory entry
   746                              <1> 	;;movzx	edx, word [esi+LD_BPB+BPB_RootEntCnt]
   747                              <1>         ;mov     dx, [esi+LD_BPB+BPB_RootEntCnt]
   748                              <1>         ;mul	edx
   749                              <1> 	;;mov	ecx, 511
   750                              <1> 	;mov	cx, 511
   751                              <1> 	;add	eax, ecx
   752                              <1> 	;inc	ecx ; 512
   753                              <1> 	;div	ecx
   754                              <1> 	; 14/07/2020
   755 0000755D 0FB74617            <1> 	movzx	eax, word [esi+LD_BPB+BPB_RootEntCnt]
   756 00007561 6683C00F            <1> 	add	ax, 15
   757 00007565 66C1E804            <1> 	shr	ax, 4 ; / 16 ; (16 entries per sector)
   758 00007569 014668              <1> 	add	[esi+LD_DATABegin], eax
   759                              <1> 	;movzx	eax, word [esi+LD_BPB+BPB_TotalSec16]
   760 0000756C 668B4619            <1> 	mov	ax, [esi+LD_BPB+BPB_TotalSec16]
   761 00007570 6685C0              <1> 	test	ax, ax
   762                              <1> 	;jz	short loc_set_32bit_FAT_total_sectors
   763                              <1> ;loc_set_16bit_FAT_total_sectors:
   764                              <1> 	;mov	[esi+LD_TotalSectors], eax
   765                              <1> 	;jmp	short loc_set_hd_FAT_cluster_count
   766                              <1> 	; 14/07/2020
   767 00007573 7503                <1> 	jnz	short loc_set_hd_FAT_cluster_count
   768                              <1> loc_set_32bit_FAT_total_sectors:
   769 00007575 8B4626              <1> 	mov	eax, [esi+LD_BPB+BPB_TotalSec32]
   770                              <1> 	;mov	[esi+LD_TotalSectors], eax
   771                              <1> loc_set_hd_FAT_cluster_count:
   772 00007578 894670              <1> 	mov	[esi+LD_TotalSectors], eax ; 14/07/2020
   773 0000757B 8B5668              <1> 	mov	edx, [esi+LD_DATABegin]
   774 0000757E 2B566C              <1> 	sub	edx, [esi+LD_StartSector]
   775 00007581 29D0                <1> 	sub	eax, edx
   776 00007583 31D2                <1> 	xor	edx, edx ; 0
   777 00007585 0FB64E13            <1>         movzx   ecx, byte [esi+LD_BPB+BPB_SecPerClust]
   778 00007589 F7F1                <1>         div	ecx 
   779 0000758B 894678              <1> 	mov	[esi+LD_Clusters], eax
   780                              <1> 	; Maximum Valid Cluster Number= EAX +1
   781                              <1> 	; with 2 reserved clusters= EAX +2
   782                              <1> loc_set_hd_FAT_fs_free_sectors:
   783                              <1> 	;mov	dword [esi+LD_FreeSectors], 0
   784 0000758E E855010000          <1> 	call	get_free_FAT_sectors
   785 00007593 720D                <1> 	jc	short loc_validate_hd_FAT_partition_retn
   786 00007595 894674              <1> 	mov	[esi+LD_FreeSectors], eax
   787 00007598 C6467E06            <1> 	mov	byte [esi+LD_MediaChanged], 6  ; Volume Name Reset
   788                              <1> 
   789                              <1> 	; 15/07/2020
   790 0000759C FE05[F5170100]      <1> 	inc 	byte [Last_DOS_DiskNo] ; > 1
   791                              <1> 
   792                              <1> 	;mov	cl, [Last_DOS_DiskNo] 
   793                              <1> 	;add	cl, 'A'
   794                              <1> 	;mov	[esi+LD_FS_Name], cl
   795                              <1> 
   796                              <1> loc_validate_hd_FAT_partition_retn:         
   797 000075A2 C3                  <1> 	retn
   798                              <1> 
   799                              <1> validate_hd_fs_partition:
   800                              <1> 	; 03/02/2018
   801                              <1> 	; 09/12/2017
   802                              <1> 	; 13/02/2016
   803                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
   804                              <1> 	; 29/01/2011
   805                              <1> 	; 23/07/2011
   806                              <1> 	; Input
   807                              <1> 	;   DL = Hard/Fixed Disk Drive Number
   808                              <1> 	;   ESI = PartitionTable offset
   809                              <1> 	;   byte [Last_DOS_DiskNo]
   810                              <1> 	; Output
   811                              <1> 	;  cf=0 -> Validated
   812                              <1> 	;   ESI = Logical dos drv desc. table
   813                              <1> 	;   EBX = Singlix FS boot sector buffer
   814                              <1> 	;   byte [Last_DOS_DiskNo]
   815                              <1> 	;  cf=1 -> Not a valid 'Singlix FS' partition
   816                              <1> 	; EAX, EDX, ECX, EDI -> changed 
   817                              <1> 
   818                              <1> 	;mov	esi, PartitionTable
   819 000075A3 8A6604              <1> 	mov	ah, [esi+ptFileSystemID]
   820 000075A6 80FCA1              <1> 	cmp	ah, 0A1h ; SINGLIX FS1 (trfs1) partition
   821 000075A9 7549                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   822                              <1> loc_set_valid_hd_fs_partition_params:
   823 000075AB FE05[F5170100]      <1> 	inc	byte [Last_DOS_DiskNo] ; > 1
   824 000075B1 30C0                <1> 	xor	al, al ; mov al, 0
   825                              <1> 	;mov	[drv], dl
   826 000075B3 29DB                <1> 	sub	ebx, ebx ; 0
   827 000075B5 8A3D[F5170100]      <1> 	mov	bh, [Last_DOS_DiskNo] 
   828 000075BB 81C300010900        <1> 	add	ebx, Logical_DOSDisks
   829 000075C1 C6430102            <1> 	mov	byte [ebx+LD_DiskType], 2
   830 000075C5 885302              <1> 	mov	[ebx+LD_PhyDrvNo], dl
   831                              <1> 	;mov	[ebx+LD_FATType], al ; 0
   832                              <1> 	;mov	[ebx+LD_FSType], ah
   833 000075C8 66894303            <1> 	mov	[ebx+LD_FATType], ax
   834                              <1> 	;mov	eax, [esi+ptStartSector]
   835                              <1> 	;mov	[ebx+LD_StartSector], eax
   836                              <1> loc_hd_fs_logical_drv_init:
   837 000075CC 89DD                <1> 	mov	ebp, ebx ; 10/01/2016
   838                              <1> 	;mov	dl, [ebx+LD_PhyDrvNo]
   839 000075CE A0[A2690100]        <1> 	mov	al, [HD_LBA_yes] ; 10/01/2016
   840 000075D3 884305              <1> 	mov	[ebx+LD_LBAYes], al
   841 000075D6 89DE                <1> 	mov	esi, ebx
   842 000075D8 BB[AE690100]        <1> 	mov	ebx, DOSBootSectorBuff ; buffer address
   843 000075DD 08C0                <1> 	or	al, al
   844 000075DF 7515                <1> 	jnz	short loc_hd_fs_drv_init_load_bs_lba
   845                              <1> loc_hd_fs_drv_init_load_bs_chs:
   846 000075E1 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   847 000075E4 668B4E02            <1> 	mov	cx, [esi+ptBeginSector]
   848 000075E8 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   849                              <1> 	;mov	ebx, DOSBootSectorBuff
   850 000075EC E809D6FFFF          <1> 	call	int13h
   851 000075F1 7311                <1> 	jnc	short loc_hd_drv_fs_boot_validation
   852                              <1> loc_validate_hd_fs_partition_err_retn:
   853 000075F3 C3                  <1> 	retn
   854                              <1> loc_validate_hd_fs_partition_stc_retn:
   855 000075F4 F9                  <1> 	stc
   856 000075F5 C3                  <1> 	retn
   857                              <1> loc_hd_fs_drv_init_load_bs_lba:
   858                              <1> 	; DL = Physical drive number
   859                              <1> 	;mov	esi, ebx
   860 000075F6 8B4E08              <1>    	mov	ecx, [esi+ptStartSector] ; sector number
   861                              <1> 	;mov	ebx, DOSBootSectorBuff ; buffer address
   862                              <1> 	; LBA read/write (with private LBA function) 
   863                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
   864                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
   865 000075F9 B41B                <1> 	mov	ah, 1Bh ; LBA read
   866 000075FB B001                <1> 	mov	al, 1 ; sector count
   867 000075FD E8F8D5FFFF          <1> 	call	int13h
   868 00007602 72EF                <1> 	jc	short loc_validate_hd_fs_partition_err_retn
   869                              <1> loc_hd_drv_fs_boot_validation:
   870                              <1> 	;mov	esi, DOSBootSectorBuff
   871 00007604 89DE                <1> 	mov	esi, ebx ; Boot sector buffer
   872 00007606 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
   873 0000760F 75E3                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   874                              <1>         ;
   875                              <1> 	;Singlix FS Extensions to TR-DOS (7/6/2009) 
   876 00007611 66817E034653        <1> 	cmp	word [esi+bs_FS_Identifier], 'FS' ; 03/02/2018
   877 00007617 75DB                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   878                              <1>         ;'A1h' check is not necessary
   879                              <1> 	;  if 'FS' check is passed as OK/Yes.
   880 00007619 807E09A1            <1> 	cmp	byte [esi+bs_FS_PartitionID], 0A1h
   881 0000761D 75D5                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   882                              <1> 	;
   883 0000761F 89EF                <1> 	mov	edi, ebp ; 10/01/2016
   884                              <1> 	;
   885 00007621 8A462D              <1> 	mov	al, byte [esi+bs_FS_LBA_Ready]
   886 00007624 884705              <1> 	mov	[edi+LD_FS_LBAYes], al
   887                              <1> 	;
   888                              <1> 	; 03/01/2010 CHS -> DOS FAT/BPB compatibility fix
   889 00007627 8A4608              <1> 	mov	al, [esi+bs_FS_MediaAttrib]
   890 0000762A 884706              <1> 	mov	byte [edi+LD_FS_MediaAttrib], al
   891                              <1> 	;
   892 0000762D 8A460A              <1> 	mov	al, [esi+bs_FS_VersionMaj]
   893 00007630 884707              <1> 	mov	[edi+LD_FS_VersionMajor], al
   894                              <1> 	;
   895 00007633 668B4606            <1> 	mov	ax, [esi+bs_FS_BytesPerSec]
   896 00007637 66894711            <1> 	mov	[edi+LD_FS_BytesPerSec], ax
   897 0000763B 8A462E              <1> 	mov	al, [esi+bs_FS_SecPerTrack]
   898 0000763E 30E4                <1> 	xor	ah, ah ; 09/12/2017
   899 00007640 6689471E            <1> 	mov	[edi+LD_FS_SecPerTrack], ax
   900 00007644 8A462F              <1> 	mov	al, [esi+bs_FS_Heads]
   901 00007647 66894720            <1> 	mov	[edi+LD_FS_NumHeads], ax
   902                              <1> 	;
   903 0000764B 8B4628              <1> 	mov	eax, [esi+bs_FS_UnDelDirD]
   904 0000764E 894722              <1> 	mov	[edi+LD_FS_UnDelDirD], eax
   905 00007651 8B5618              <1> 	mov	edx, [esi+bs_FS_MATLocation]
   906 00007654 89570C              <1> 	mov	[edi+LD_FS_MATLocation], edx
   907 00007657 8B461C              <1> 	mov	eax, [esi+bs_FS_RootDirD]
   908 0000765A 894708              <1> 	mov	[edi+LD_FS_RootDirD], eax
   909 0000765D 8B460C              <1> 	mov	eax, [esi+bs_FS_BeginSector]
   910 00007660 89476C              <1> 	mov	[edi+LD_FS_BeginSector], eax
   911 00007663 8B4710              <1> 	mov	eax, [edi+bs_FS_VolumeSize]
   912 00007666 894770              <1> 	mov	[edi+LD_FS_VolumeSize], eax
   913                              <1> 	;
   914 00007669 89D0                <1> 	mov	eax, edx ; [edi+LD_FS_MATLocation]
   915 0000766B 03476C              <1> 	add	eax, [edi+LD_FS_BeginSector]
   916 0000766E 89FE                <1> 	mov	esi, edi
   917                              <1> mread_hd_fs_MAT_sector:
   918                              <1>        ;mov	ebx, DOSBootSectorBuff
   919 00007670 B901000000          <1> 	mov	ecx, 1
   920 00007675 E8768C0000          <1> 	call	disk_read
   921 0000767A 7248                <1> 	jc	short loc_validate_hd_fs_partition_retn
   922                              <1> 	; EDI will not be changed
   923 0000767C 89DE                <1> 	mov	esi, ebx
   924                              <1> use_hdfs_mat_sector_params:
   925 0000767E 8B460C              <1> 	mov	eax, [esi+FS_MAT_DATLocation]
   926 00007681 894714              <1> 	mov	[edi+LD_FS_DATLocation], eax
   927 00007684 8B4610              <1> 	mov	eax, [esi+FS_MAT_DATScount]
   928 00007687 894718              <1> 	mov	[edi+LD_FS_DATSectors], eax
   929 0000768A 8B4614              <1> 	mov	eax, [esi+FS_MAT_FreeSectors]
   930 0000768D 894774              <1>         mov     [edi+LD_FS_FreeSectors], eax
   931 00007690 8B4618              <1> 	mov	eax, [esi+FS_MAT_FirstFreeSector]
   932 00007693 894778              <1> 	mov	[edi+LD_FS_FirstFreeSector], eax
   933 00007696 8B4708              <1> 	mov	eax, [edi+LD_FS_RootDirD]
   934 00007699 03476C              <1> 	add	eax, [edi+LD_FS_BeginSector]
   935 0000769C 89FE                <1> 	mov	esi, edi   
   936                              <1> read_hd_fs_RDT_sector:
   937 0000769E BB[AE690100]        <1> 	mov	ebx, DOSBootSectorBuff
   938                              <1> 	;mov	ecx, 1
   939 000076A3 B101                <1> 	mov	cl, 1
   940 000076A5 E8468C0000          <1> 	call	disk_read
   941 000076AA 7218                <1> 	jc	short loc_validate_hd_fs_partition_retn
   942                              <1> 	; EDI will not be changed
   943 000076AC 89DE                <1> 	mov	esi, ebx
   944                              <1> use_hdfs_RDT_sector_params:
   945 000076AE 8B461C              <1> 	mov	eax, [esi+FS_RDT_VolumeSerialNo]
   946 000076B1 894728              <1> 	mov	[edi+LD_FS_VolumeSerial], eax
   947 000076B4 57                  <1> 	push	edi
   948                              <1> 	;mov	ecx, 16
   949 000076B5 B110                <1> 	mov	cl, 16
   950 000076B7 83C640              <1> 	add	esi, FS_RDT_VolumeName
   951 000076BA 83C72C              <1> 	add	edi, LD_FS_VolumeName
   952 000076BD F3A5                <1> 	rep	movsd ; 64 bytes
   953 000076BF 5E                  <1> 	pop	esi
   954                              <1> 		; Volume Name Reset
   955 000076C0 C6467E06            <1>         mov     byte [esi+LD_FS_MediaChanged], 6
   956                              <1> 	;
   957                              <1>         ;mov	cl, [Last_DOS_DiskNo] 
   958                              <1> 	;add	cl, 'A'
   959                              <1> 	;mov	[esi+LD_FS_Name], cl
   960                              <1> 
   961                              <1> loc_validate_hd_fs_partition_retn:
   962 000076C4 C3                  <1> 	retn
   963                              <1> 
   964                              <1> load_masterboot:
   965                              <1> 	; 14/07/2020 (Reset function has been removed)
   966                              <1> 	;
   967                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
   968                              <1> 	; 2005 - 2011
   969                              <1> 	; input -> DL = drive number
   970                              <1> ;	mov	ah, 0Dh ; Alternate disk reset
   971                              <1> ;	call	int13h
   972                              <1> ;	jnc	short pass_reset_error
   973                              <1> ;harddisk_error:
   974                              <1> ;  	retn
   975                              <1> ;pass_reset_error:
   976 000076C5 BB[9E660100]        <1> 	mov	ebx, MasterBootBuff
   977 000076CA 66B80102            <1> 	mov	ax, 0201h
   978 000076CE 66B90100            <1> 	mov	cx, 1
   979 000076D2 30F6                <1> 	xor	dh, dh
   980 000076D4 E821D5FFFF          <1>  	call	int13h
   981 000076D9 720C                <1> 	jc	short harddisk_error
   982                              <1> 	;
   983 000076DB 66813D[9C680100]55- <1> 	cmp	word [MBIDCode], 0AA55h
   983 000076E3 AA                  <1>
   984 000076E4 7401                <1> 	je	short load_masterboot_ok
   985 000076E6 F9                  <1> 	stc
   986                              <1> harddisk_error:
   987                              <1> load_masterboot_ok:
   988 000076E7 C3                  <1> 	retn
   989                              <1> 
   990                              <1> get_free_FAT_sectors:
   991                              <1> 	; 21/12/2017
   992                              <1> 	; 29/02/2016
   993                              <1> 	; 13/02/2016
   994                              <1> 	; 04/02/2016
   995                              <1> 	; 07/01/2016 (TRDOS 386 = TRDOS v2.0)
   996                              <1> 	; 11/07/2010
   997                              <1> 	; 21/06/2009
   998                              <1> 	; INPUT: ESI = Logical DOS Drive Description Table address
   999                              <1> 	; OUTPUT: STC => Error
  1000                              <1>         ;	cf = 0 and EAX = Free FAT sectors
  1001                              <1> 	; Also, related parameters and FAT buffer will be reset and updated
  1002                              <1> 
  1003 000076E8 31C0                <1> 	xor	eax, eax
  1004                              <1> 	;mov	[esi+LD_FreeSectors], eax ; Reset
  1005                              <1> 	
  1006 000076EA 807E0302            <1>         cmp     byte [esi+LD_FATType], 2
  1007 000076EE 7654                <1> 	jna	short loc_gfc_get_fat_free_clusters
  1008                              <1> 
  1009                              <1> 	; 29/02/2016
  1010 000076F0 48                  <1> 	dec	eax ; 0FFFFFFFFh
  1011 000076F1 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count (reset)
  1012 000076F4 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; First Free Cluster (reset)
  1013 000076F7 40                  <1> 	inc	eax ; 0
  1014                              <1> 	;
  1015 000076F8 668B4636            <1> 	mov	ax, [esi+LD_BPB+BPB_FSInfo]
  1016 000076FC 03466C              <1> 	add	eax, [esi+LD_StartSector]
  1017                              <1> 
  1018 000076FF BB[AE690100]        <1> 	mov	ebx, DOSBootSectorBuff
  1019 00007704 B901000000          <1> 	mov	ecx, 1
  1020 00007709 E8E28B0000          <1>  	call	disk_read
  1021 0000770E 7301                <1> 	jnc	short loc_gfc_check_fsinfo_signs
  1022                              <1> retn_gfc_get_fsinfo_sec:
  1023 00007710 C3                  <1> 	retn
  1024                              <1> 
  1025                              <1> loc_gfc_check_fsinfo_signs:
  1026 00007711 BB[AE690100]        <1> 	mov 	ebx, DOSBootSectorBuff ; 13/02/2016
  1027 00007716 813B52526141        <1>         cmp     dword [ebx], 41615252h
  1028 0000771C 7524                <1> 	jne	short retn_gfc_get_fsinfo_stc
  1029                              <1> 	;add	ebx, 484
  1030                              <1> 	;cmp	dword [ebx], 61417272h
  1031 0000771E 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
  1031 00007727 61                  <1>
  1032 00007728 7518                <1> 	jne	short retn_gfc_get_fsinfo_stc
  1033                              <1> 	;add	ebx, 4
  1034                              <1> 	;mov	eax, [ebx]
  1035 0000772A 8B83E8010000        <1> 	mov	eax, [ebx+488]
  1036                              <1> 	; 29/02/2016
  1037 00007730 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count
  1038 00007733 8B93EC010000        <1> 	mov	edx,  [ebx+492] 
  1039 00007739 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; First Free Cluster
  1040                              <1> 	; 21/12/2017
  1041 0000773C 89C3                <1> 	mov	ebx, eax ; (initial value = 0FFFFFFFFh)
  1042 0000773E 43                  <1> 	inc	ebx ; 0FFFFFFFFh -> 0  
  1043 0000773F 7513                <1> 	jnz	short short retn_from_get_free_fat32_clusters
  1044 00007741 C3                  <1> 	retn
  1045                              <1> 
  1046                              <1> retn_gfc_get_fsinfo_stc:
  1047 00007742 F9                  <1> 	stc
  1048 00007743 C3                  <1> 	retn
  1049                              <1> 
  1050                              <1> loc_gfc_get_fat_free_clusters:
  1051                              <1> 	;mov	eax, 2
  1052 00007744 B002                <1> 	mov	al, 2
  1053                              <1> 	;mov	[FAT_CurrentCluster], eax
  1054                              <1> loc_gfc_loop_get_next_cluster:
  1055 00007746 E8EB4F0000          <1> 	call	get_next_cluster
  1056 0000774B 730E                <1> 	jnc	short loc_gfc_free_fat_clusters_cont
  1057 0000774D 21C0                <1> 	and	eax, eax
  1058 0000774F 7411                <1> 	jz	short loc_gfc_pass_inc_free_cluster_count
  1059                              <1>  
  1060                              <1> retn_from_get_free_fat_clusters:
  1061 00007751 8B4674              <1> 	mov	eax, [esi+LD_FreeSectors] ; Free clusters !
  1062                              <1> retn_from_get_free_fat32_clusters:
  1063 00007754 0FB65E13            <1>         movzx	ebx, byte [esi+LD_BPB+BPB_SecPerClust]
  1064 00007758 F7E3                <1>       	mul	ebx
  1065                              <1> 	;mov	[esi+LD_FreeSectors], eax ; Free sectors
  1066                              <1> retn_get_free_sectors_calc:
  1067 0000775A C3                  <1> 	retn
  1068                              <1> 
  1069                              <1> loc_gfc_free_fat_clusters_cont:
  1070 0000775B 09C0                <1> 	or	eax, eax
  1071 0000775D 7503                <1> 	jnz	short loc_gfc_pass_inc_free_cluster_count
  1072 0000775F FF4674              <1> 	inc	dword [esi+LD_FreeSectors] ; Free clusters !
  1073                              <1>    
  1074                              <1> loc_gfc_pass_inc_free_cluster_count:
  1075                              <1> 	;mov	eax, [FAT_CurrentCluster]
  1076 00007762 89C8                <1> 	mov	eax, ecx ; [FAT_CurrentCluster]
  1077 00007764 3B4678              <1> 	cmp	eax, [esi+LD_Clusters]
  1078 00007767 77E8                <1> 	ja	short retn_from_get_free_fat_clusters
  1079 00007769 40                  <1> 	inc	eax
  1080                              <1> 	;mov	[FAT_CurrentCluster], eax
  1081 0000776A EBDA                <1> 	jmp	short loc_gfc_loop_get_next_cluster
  1082                              <1> 
  1083                              <1> floppy_drv_init:
  1084                              <1> 	; 09/12/2017
  1085                              <1> 	; 06/07/2016
  1086                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
  1087                              <1> 	; 24/07/2011
  1088                              <1> 	; 04/07/2009
  1089                              <1> 	; INPUT ->
  1090                              <1> 	;	DL = Drive number (0,1)
  1091                              <1> 	; OUTPUT ->
  1092                              <1> 	;	BL = drive name
  1093                              <1> 	;	BH = drive number
  1094                              <1> 	;	ESI = Logical DOS drv description table
  1095                              <1> 	;	EAX = Volume serial number
  1096                              <1>  
  1097 0000776C BE[CE670000]        <1> 	mov	esi, fd0_type ; 10/01/2016
  1098 00007771 BF00010900          <1> 	mov	edi, Logical_DOSDisks
  1099 00007776 08D2                <1> 	or	dl, dl
  1100 00007778 7407                <1> 	jz	short loc_drv_init_fd0_fd1
  1101 0000777A 81C700010000        <1> 	add	edi, 100h
  1102 00007780 46                  <1> 	inc	esi ; fd1_type ; 10/01/2016
  1103                              <1> loc_drv_init_fd0_fd1:
  1104 00007781 C6477E00            <1> 	mov	byte [edi+LD_MediaChanged], 0
  1105 00007785 803E01              <1> 	cmp	byte [esi], 1 ; type (>0 if it is existing) 
  1106                              <1> 		; 4 = 1.44 MB, 80 track, 3 1/2"
  1107 00007788 7221                <1> 	jb	short read_fd_boot_sector_retn
  1108 0000778A 885702              <1> 	mov	[edi+LD_PhyDrvNo], dl
  1109                              <1> read_fd_boot_sector:
  1110 0000778D 30F6                <1> 	xor	dh, dh
  1111 0000778F B904000000          <1> 	mov	ecx, 4 ; Retry Count
  1112                              <1> read_fd_boot_sector_again:
  1113 00007794 51                  <1> 	push 	ecx
  1114                              <1> 	;mov	cx, 1
  1115 00007795 B101                <1> 	mov	cl, 1
  1116 00007797 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
  1117 0000779B BB[AE690100]        <1> 	mov	ebx, DOSBootSectorBuff
  1118 000077A0 E855D4FFFF          <1> 	call	int13h
  1119 000077A5 59                  <1> 	pop	ecx
  1120 000077A6 7304                <1> 	jnc	short use_fd_boot_sector_params
  1121 000077A8 E2EA                <1> 	loop	read_fd_boot_sector_again
  1122                              <1> 
  1123                              <1> read_fd_boot_sector_stc_retn:
  1124 000077AA F9                  <1> 	stc
  1125                              <1> read_fd_boot_sector_retn:
  1126 000077AB C3                  <1> 	retn
  1127                              <1> 
  1128                              <1> use_fd_boot_sector_params:
  1129                              <1> 	;mov	esi, DOSBootSectorBuff
  1130 000077AC 89DE                <1> 	mov	esi, ebx
  1131 000077AE 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
  1132 000077B7 75F1                <1> 	jne	short read_fd_boot_sector_stc_retn
  1133 000077B9 66817E035346        <1>         cmp     word [esi+bs_FS_Identifier], 'SF'
  1134 000077BF 0F85A2000000        <1>         jne     use_fd_fatfs_boot_sector_params
  1135                              <1> 	;
  1136 000077C5 8A462D              <1> 	mov	al, [esi+bs_FS_LBA_Ready]
  1137 000077C8 884705              <1> 	mov	[edi+LD_FS_LBAYes], al
  1138                              <1> 	;
  1139                              <1> 	; 03/01/2010 CHS -> DOS FAT/BPB compatibility fix
  1140 000077CB 8A4608              <1> 	mov	al, [esi+bs_FS_MediaAttrib]
  1141 000077CE 884706              <1> 	mov	[edi+LD_FS_MediaAttrib], al
  1142                              <1> 	;
  1143 000077D1 8A460A              <1>         mov	al, [esi+bs_FS_VersionMaj]
  1144 000077D4 884707              <1> 	mov	byte [edi+LD_FS_VersionMajor], al
  1145 000077D7 668B4606            <1> 	mov	ax, [esi+bs_FS_BytesPerSec]
  1146 000077DB 66894711            <1> 	mov	[edi+LD_FS_BytesPerSec], ax
  1147 000077DF 8A462E              <1> 	mov	al, [esi+bs_FS_SecPerTrack]
  1148 000077E2 28E4                <1> 	sub	ah, ah ; 09/12/2017
  1149 000077E4 6689471E            <1> 	mov	[edi+LD_FS_SecPerTrack], ax
  1150 000077E8 8A462F              <1> 	mov	al, [esi+bs_FS_Heads]
  1151 000077EB 66894720            <1> 	mov	[edi+LD_FS_NumHeads], ax
  1152                              <1> 	;
  1153 000077EF 8B4628              <1> 	mov	eax, [esi+bs_FS_UnDelDirD]
  1154 000077F2 894722              <1> 	mov	[edi+LD_FS_UnDelDirD], eax
  1155 000077F5 8B4618              <1> 	mov	eax, [esi+bs_FS_MATLocation]
  1156 000077F8 89470C              <1> 	mov	[edi+LD_FS_MATLocation], eax
  1157 000077FB 8B461C              <1> 	mov	eax, [esi+bs_FS_RootDirD]
  1158 000077FE 894708              <1> 	mov	[edi+LD_FS_RootDirD], eax
  1159 00007801 8B460C              <1> 	mov	eax, [esi+bs_FS_BeginSector]
  1160 00007804 89476C              <1> 	mov	[edi+LD_FS_BeginSector], eax
  1161 00007807 8B4610              <1> 	mov	eax, [esi+bs_FS_VolumeSize]
  1162 0000780A 894770              <1> 	mov	[edi+LD_FS_VolumeSize], eax
  1163                              <1> 	;		
  1164 0000780D 89FE                <1> 	mov	esi, edi
  1165 0000780F 8B460C              <1>  	mov	eax, [esi+LD_FS_MATLocation]
  1166                              <1> 	;add	eax, [edi+LD_FS_BeginSector]
  1167                              <1> read_fd_MAT_sector_again:
  1168                              <1> 	;mov	ebx, DOSBootSectorBuff
  1169                              <1> 	;mov	ecx, 1
  1170 00007812 B101                <1> 	mov	cl, 1
  1171 00007814 E8DD8A0000          <1> 	call	chs_read
  1172 00007819 89DE                <1> 	mov	esi, ebx
  1173 0000781B 7301                <1> 	jnc	short use_fdfs_mat_sector_params
  1174                              <1> 	;jmp	short read_fd_boot_sector_retn
  1175 0000781D C3                  <1> 	retn
  1176                              <1> use_fdfs_mat_sector_params:
  1177 0000781E 8B460C              <1> 	mov	eax, [esi+FS_MAT_DATLocation]
  1178 00007821 894714              <1> 	mov	[edi+LD_FS_DATLocation], eax
  1179 00007824 8B4610              <1> 	mov	eax, [esi+FS_MAT_DATScount]
  1180 00007827 894718              <1> 	mov	[edi+LD_FS_DATSectors], eax
  1181 0000782A 8B4714              <1> 	mov	eax, [edi+FS_MAT_FreeSectors]
  1182 0000782D 894774              <1> 	mov	[edi+LD_FS_FreeSectors], eax
  1183 00007830 8B4618              <1> 	mov	eax, [esi+FS_MAT_FirstFreeSector]
  1184 00007833 894778              <1> 	mov	[edi+LD_FS_FirstFreeSector], eax
  1185                              <1> 	;
  1186 00007836 89FE                <1> 	mov	esi, edi
  1187 00007838 8B4608              <1>  	mov	eax, [esi+LD_FS_RootDirD]
  1188                              <1> read_fd_RDT_sector_again:
  1189                              <1> 	;mov	ebx, DOSBootSectorBuff
  1190                              <1> 	;mov	cx, 1
  1191 0000783B B101                <1> 	mov	cl, 1
  1192 0000783D E8B48A0000          <1> 	call	chs_read
  1193 00007842 89DE                <1> 	mov	esi, ebx
  1194 00007844 7220                <1> 	jc	short read_fd_RDT_sector_retn
  1195                              <1> use_fdfs_RDT_sector_params:
  1196 00007846 8B461C              <1> 	mov	eax, [esi+FS_RDT_VolumeSerialNo]
  1197 00007849 894728              <1> 	mov	[edi+LD_FS_VolumeSerial], eax
  1198 0000784C 57                  <1> 	push	edi
  1199                              <1> 	;mov	ecx, 16
  1200 0000784D B110                <1> 	mov	cl, 16	
  1201 0000784F 83C640              <1> 	add	esi, FS_RDT_VolumeName
  1202 00007852 83C72C              <1> 	add	edi, LD_FS_VolumeName
  1203 00007855 F3A5                <1> 	rep	movsd ; 64 bytes
  1204 00007857 5E                  <1> 	pop	esi
  1205 00007858 C6460300            <1> 	mov	byte [esi+LD_FATType], 0
  1206 0000785C C64604A1            <1> 	mov	byte [esi+LD_FSType], 0A1h  
  1207 00007860 E9A5000000          <1>         jmp     loc_cont_use_fd_boot_sector_params
  1208                              <1> 
  1209                              <1> read_fd_RDT_sector_stc_retn:
  1210 00007865 F9                  <1> 	stc
  1211                              <1> read_fd_RDT_sector_retn:
  1212 00007866 C3                  <1> 	retn
  1213                              <1> 
  1214                              <1> use_fd_fatfs_boot_sector_params:
  1215 00007867 807E2629            <1> 	cmp	byte [esi+BS_BootSig], 29h
  1216 0000786B 75F8                <1> 	jne	short read_fd_RDT_sector_stc_retn
  1217 0000786D 807E15F0            <1> 	cmp	byte [esi+BPB_Media], 0F0h
  1218 00007871 72F3                <1> 	jb	short read_fd_RDT_sector_retn
  1219 00007873 57                  <1> 	push	edi
  1220 00007874 83C706              <1> 	add	edi, LD_BPB
  1221                              <1> 	;mov	ecx, 16
  1222 00007877 B110                <1> 	mov	cl, 16
  1223 00007879 F3A5                <1> 	rep	movsd ; 64 bytes 
  1224 0000787B 5E                  <1> 	pop	esi
  1225 0000787C 31C0                <1> 	xor	eax, eax
  1226 0000787E 89466C              <1> 	mov	[esi+LD_StartSector], eax ; 0
  1227 00007881 668B461C            <1> 	mov	ax, [esi+LD_BPB+BPB_FATSz16]
  1228 00007885 8A4E16              <1> 	mov	cl, [esi+LD_BPB+BPB_NumFATs] 
  1229 00007888 F7E1                <1>   	mul	ecx
  1230                              <1> 	; edx = 0 !
  1231 0000788A 668B5614            <1> 	mov	dx, [esi+LD_BPB+BPB_RsvdSecCnt]
  1232 0000788E 66895660            <1> 	mov	[esi+LD_FATBegin], dx
  1233                              <1> 	;add	eax, edx
  1234 00007892 6601D0              <1> 	add	ax, dx
  1235 00007895 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
  1236 00007898 894668              <1> 	mov	[esi+LD_DATABegin], eax 
  1237 0000789B 668B5617            <1> 	mov	dx, [esi+LD_BPB+BPB_RootEntCnt]
  1238                              <1> 	;;shl	edx, 5 ; * 32 (Size of a directory entry)
  1239                              <1> 	;shl	dx, 5
  1240                              <1> 	;;add	edx, 511
  1241                              <1> 	;add	dx, 511
  1242                              <1> 	;;shr	edx, 9 ; edx = ((edx*32)+511) / 512
  1243                              <1> 	;shr	dx, 9
  1244 0000789F 6683C20F            <1> 	add	dx, 15 ; 06/07/2016 (+(512/32)-1)
  1245 000078A3 66C1EA04            <1> 	shr	dx, 4 ; / 16 (==16 entries per sector)
  1246 000078A7 015668              <1> 	add 	[esi+LD_DATABegin], edx ; + rd sectors
  1247                              <1> 	;movzx	eax, word [esi+LD_BPB+BPB_TotalSec16]
  1248 000078AA 668B4619            <1> 	mov	ax, [esi+LD_BPB+BPB_TotalSec16]
  1249 000078AE 894670              <1> 	mov	[esi+LD_TotalSectors], eax
  1250 000078B1 2B4668              <1> 	sub	eax, [esi+LD_DATABegin]
  1251                              <1>   	;movzx	ecx, byte [esi+LD_BPB+BPB_SecPerClust]
  1252 000078B4 8A4E13              <1> 	mov	cl, [esi+LD_BPB+BPB_SecPerClust]  
  1253 000078B7 80F901              <1> 	cmp	cl, 1
  1254 000078BA 7605                <1> 	jna	short save_fd_fatfs_cluster_count
  1255                              <1> 	;sub	edx, edx
  1256 000078BC 6629D2              <1> 	sub	dx, dx ; 0
  1257                              <1> 	;sub	dl, dl ; 06/07/2016
  1258 000078BF F7F1                <1> 	div	ecx
  1259                              <1> save_fd_fatfs_cluster_count:
  1260 000078C1 894678              <1> 	mov	[esi+LD_Clusters], eax
  1261                              <1> 
  1262                              <1>       ; Maximum Valid Cluster Number = EAX +1
  1263                              <1>       ; with 2 reserved clusters= EAX +2
  1264                              <1>  
  1265                              <1> reset_FAT_buffer_decriptors:
  1266 000078C4 29C0                <1> 	sub	eax, eax ; 0  
  1267 000078C6 A2[B26B0100]        <1> 	mov	[FAT_BuffValidData], al ; 0
  1268 000078CB A2[B36B0100]        <1> 	mov	[FAT_BuffDrvName], al ; 0
  1269 000078D0 A3[B66B0100]        <1> 	mov	[FAT_BuffSector], eax ; 0
  1270                              <1> 
  1271                              <1> read_fd_FAT_sectors:
  1272 000078D5 BB001C0900          <1>   	mov	ebx, FAT_Buffer
  1273 000078DA 668B4614            <1> 	mov	ax, [esi+LD_BPB+BPB_RsvdSecCnt]
  1274                              <1> 	;mov	ecx, 3
  1275 000078DE B103                <1> 	mov	cl, 3 ; 3 sectors
  1276 000078E0 E8118A0000          <1> 	call	chs_read
  1277 000078E5 7240                <1> 	jc	short read_fd_FAT_sectors_retn
  1278                              <1> use_fd_FAT_sectors:
  1279 000078E7 8A4602              <1> 	mov	al, [esi+LD_PhyDrvNo]
  1280 000078EA 0441                <1> 	add	al, 'A' 
  1281 000078EC A2[B36B0100]        <1> 	mov	[FAT_BuffDrvName], al 
  1282 000078F1 C605[B26B0100]01    <1>  	mov	byte [FAT_BuffValidData], 1
  1283 000078F8 E82B000000          <1> 	call	fd_init_calculate_free_clusters
  1284 000078FD 7228                <1> 	jc	short read_fd_FAT_sectors_retn
  1285                              <1>   
  1286                              <1> loc_use_fd_boot_sector_params_FAT:
  1287 000078FF C6460301            <1> 	mov	byte [esi+LD_FATType], 1 ; FAT 12
  1288 00007903 C6460401            <1> 	mov	byte [esi+LD_FSType], 1
  1289 00007907 8B462D              <1>         mov     eax, [esi+LD_BPB+VolumeID]
  1290                              <1> loc_cont_use_fd_boot_sector_params:
  1291 0000790A 8A7E02              <1> 	mov	bh, [esi+LD_PhyDrvNo]
  1292 0000790D 887E7D              <1> 	mov	[esi+LD_DParamEntry], bh
  1293 00007910 88FB                <1> 	mov	bl, bh
  1294 00007912 80C341              <1> 	add	bl, 'A'
  1295 00007915 881E                <1> 	mov	byte [esi+LD_Name], bl
  1296 00007917 C6460101            <1> 	mov	byte [esi+LD_DiskType], 1
  1297 0000791B C6460500            <1> 	mov	byte [esi+LD_LBAYes], 0
  1298 0000791F C6467C00            <1> 	mov	byte [esi+LD_PartitionEntry], 0
  1299 00007923 C6467E06            <1> 	mov	byte [esi+LD_MediaChanged], 6 ; Volume Name Reset
  1300                              <1> 
  1301                              <1> read_fd_FAT_sectors_retn:
  1302 00007927 C3                  <1> 	retn   
  1303                              <1> 
  1304                              <1> fd_init_calculate_free_clusters:
  1305                              <1> 	; 09/12/2017
  1306                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
  1307                              <1> 	; 04/07/2009
  1308                              <1> 	; INPUT ->
  1309                              <1> 	;     ESI = Logical DOS drive description table address
  1310                              <1> 	; OUTPUT ->
  1311                              <1> 	;    [ESI+LD_FreeSectors] will be set
  1312                              <1> 	
  1313 00007928 29C0                <1> 	sub	eax, eax
  1314 0000792A 894674              <1> 	mov	[esi+LD_FreeSectors], eax ; 0
  1315 0000792D B002                <1> 	mov	al, 2 ; eax = 2
  1316                              <1> 
  1317                              <1> fd_init_loop_get_next_cluster:
  1318 0000792F E830000000          <1> 	call	fd_init_get_next_cluster
  1319 00007934 722D                <1> 	jc	short fd_init_calculate_free_clusters_retn
  1320                              <1> 
  1321                              <1> fd_init_free_fat_clusters:
  1322                              <1> 	;cmp 	eax, 0
  1323                              <1> 	;ja	short fd_init_pass_inc_free_cluster_count
  1324                              <1> 	;and	eax, eax
  1325                              <1> 	;jnz	short fd_init_pass_inc_free_cluster_count
  1326 00007936 6621C0              <1> 	and	ax, ax
  1327 00007939 7504                <1> 	jnz	short fd_init_pass_inc_free_cluster_count
  1328                              <1> 	;inc	dword [esi+LD_FreeSectors]
  1329 0000793B 66FF4674            <1>         inc	word [esi+LD_FreeSectors]
  1330                              <1>     
  1331                              <1> fd_init_pass_inc_free_cluster_count:
  1332                              <1>   	;mov	eax, [FAT_CurrentCluster]
  1333 0000793F 66A1[AE6B0100]      <1> 	mov	ax, [FAT_CurrentCluster]
  1334                              <1> 	;cmp	eax, [esi+LD_Clusters]
  1335 00007945 663B4678            <1> 	cmp	ax, [esi+LD_Clusters]
  1336 00007949 7704                <1> 	ja	short short retn_from_fd_init_calculate_free_clusters
  1337                              <1> 	;inc	eax
  1338 0000794B 6640                <1> 	inc	ax
  1339 0000794D EBE0                <1> 	jmp	short fd_init_loop_get_next_cluster
  1340                              <1> 
  1341                              <1> retn_from_fd_init_calculate_free_clusters:
  1342 0000794F 8A4613              <1>   	mov	al, [esi+LD_BPB+BPB_SecPerClust]
  1343 00007952 3C01                <1>   	cmp	al, 1
  1344 00007954 760D                <1> 	jna	short fd_init_calculate_free_clusters_retn
  1345                              <1> 	;movzx	eax, al
  1346 00007956 30E4                <1> 	xor	ah, ah ; 09/12/2017
  1347                              <1> 	;mov	ecx, [esi+LD_FreeSectors]
  1348 00007958 668B4E74            <1> 	mov	cx, [esi+LD_FreeSectors] ; Count of free clusters
  1349                              <1>   	;mul	ecx
  1350 0000795C 66F7E1              <1> 	mul	cx
  1351                              <1> 	;mov	[esi+LD_FreeSectors], eax
  1352 0000795F 66894674            <1> 	mov	[esi+LD_FreeSectors], ax
  1353                              <1> fd_init_calculate_free_clusters_retn:
  1354 00007963 C3                  <1> 	retn
  1355                              <1> 
  1356                              <1> fd_init_get_next_cluster:
  1357                              <1> 	; 04/02/2016
  1358                              <1> 	; 02/02/2016
  1359                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
  1360                              <1> 	; 04/07/2009
  1361                              <1> 	; INPUT ->
  1362                              <1> 	;    EAX = Current cluster
  1363                              <1> 	;    ESI = Logical DOS drive description table address
  1364                              <1> 	;    EDX = 0
  1365                              <1> 	; OUTPUT ->
  1366                              <1> 	;    EAX = Next cluster
  1367                              <1> 
  1368 00007964 A3[AE6B0100]        <1> 	mov	[FAT_CurrentCluster], eax
  1369                              <1> fd_init_get_next_cluster_readnext:
  1370 00007969 29D2                <1> 	sub	edx, edx ; 0
  1371 0000796B BB00040000          <1>   	mov	ebx, 1024 ; 400h
  1372 00007970 F7F3                <1>   	div	ebx
  1373                              <1>   	; EAX = Count of 3 FAT sectors
  1374                              <1>   	; EDX = Buffer entry index
  1375 00007972 89C1                <1> 	mov	ecx, eax
  1376                              <1> 	;mov	eax, 3
  1377 00007974 B003                <1> 	mov	al, 3
  1378 00007976 F7E2                <1> 	mul	edx ; Multiply by 3
  1379 00007978 66D1E8              <1> 	shr	ax, 1 ; Divide by 2
  1380 0000797B 89C3                <1> 	mov	ebx, eax ; Buffer byte offset
  1381 0000797D 81C3001C0900        <1> 	add	ebx, FAT_Buffer
  1382 00007983 89C8                <1> 	mov	eax, ecx
  1383                              <1> 	;mov	edx, 3
  1384 00007985 66BA0300            <1> 	mov	dx, 3
  1385 00007989 F7E2                <1> 	mul	edx 
  1386                              <1>   	; EAX = FAT Beginning Sector
  1387                              <1> 	; EDX = 0
  1388 0000798B 8A0E                <1> 	mov	cl, [esi+LD_Name]
  1389                              <1> 	;cmp	byte [FAT_BuffValidData], 0
  1390                              <1> 	;jna	short fd_init_load_FAT_sectors0
  1391 0000798D 3A0D[B36B0100]      <1> 	cmp	cl, [FAT_BuffDrvName]
  1392 00007993 751E                <1> 	jne	short fd_init_load_FAT_sectors0
  1393 00007995 3B05[B66B0100]      <1> 	cmp	eax, [FAT_BuffSector]
  1394 0000799B 751C                <1> 	jne	short fd_init_load_FAT_sectors1
  1395                              <1> 	;mov	eax, [FAT_CurrentCluster]
  1396 0000799D A0[AE6B0100]        <1> 	mov	al, [FAT_CurrentCluster]
  1397                              <1> 	;shr	eax, 1
  1398 000079A2 D0E8                <1> 	shr	al, 1
  1399 000079A4 668B03              <1> 	mov	ax, [ebx]
  1400 000079A7 7306                <1>   	jnc	short fd_init_gnc_even
  1401 000079A9 66C1E804            <1> 	shr	ax, 4
  1402                              <1> fd_init_gnc_clc_retn:
  1403 000079AD F8                  <1> 	clc
  1404 000079AE C3                  <1> 	retn
  1405                              <1> 
  1406                              <1> fd_init_gnc_even:
  1407 000079AF 80E40F              <1> 	and	ah, 0Fh
  1408 000079B2 C3                  <1> 	retn
  1409                              <1> 
  1410                              <1> fd_init_load_FAT_sectors0:
  1411 000079B3 880D[B36B0100]      <1> 	mov 	[FAT_BuffDrvName], cl
  1412                              <1> fd_init_load_FAT_sectors1:
  1413 000079B9 C605[B26B0100]00    <1> 	mov	byte [FAT_BuffValidData], 0
  1414 000079C0 A3[B66B0100]        <1> 	mov	[FAT_BuffSector], eax
  1415 000079C5 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1416 000079C8 BB001C0900          <1>  	mov	ebx, FAT_Buffer
  1417                              <1> 	;movzx	ecx, word [esi+LD_BPB+BPB_FATSz16]
  1418 000079CD 668B4E1C            <1> 	mov	cx, [esi+LD_BPB+BPB_FATSz16]
  1419 000079D1 662B0D[B66B0100]    <1> 	sub	cx, [FAT_BuffSector]
  1420                              <1>         ;cmp	ecx, 3
  1421 000079D8 6683F903            <1> 	cmp	cx, 3
  1422 000079DC 7605                <1> 	jna	short fdinit_pass_fix_sector_count_3
  1423                              <1> 	;mov	ecx, 3
  1424 000079DE B903000000          <1> 	mov	ecx, 3
  1425                              <1> fdinit_pass_fix_sector_count_3:  
  1426 000079E3 E80E890000          <1> 	call	chs_read
  1427 000079E8 730D                <1> 	jnc	short fd_init_FAT_sectors_no_load_error
  1428 000079EA C605[B26B0100]00    <1> 	mov	byte [FAT_BuffValidData], 0
  1429                              <1> 		; Drv not ready or read Error !
  1430 000079F1 B80F000000          <1> 	mov	eax, ERR_DRV_NOT_RDY ; 15
  1431                              <1> 	;xor	edx, edx
  1432 000079F6 C3                  <1> 	retn
  1433                              <1> 
  1434                              <1> fd_init_FAT_sectors_no_load_error:
  1435 000079F7 C605[B26B0100]01    <1> 	mov	byte [FAT_BuffValidData], 1
  1436 000079FE A1[AE6B0100]        <1> 	mov	eax, [FAT_CurrentCluster]
  1437 00007A03 E961FFFFFF          <1>         jmp     fd_init_get_next_cluster_readnext
  1438                              <1> 
  1439                              <1> get_FAT_volume_name:
  1440                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
  1441                              <1> 	; 12/09/2009
  1442                              <1> 	; INPUT ->
  1443                              <1> 	;	BH = Logical DOS drive number (0,1,2,3,4 ...)
  1444                              <1> 	;       BL = 0
  1445                              <1> 	; OUTPUT ->
  1446                              <1> 	;	CF = 0 -> ESI = Volume name address
  1447                              <1> 	; 	CF = 1 -> Root volume name not found
  1448                              <1> 
  1449                              <1> 	;mov 	ah, 0FFh
  1450                              <1> 	;mov 	al, [Last_Dos_DiskNo]
  1451                              <1> 	;cmp 	al, bh
  1452                              <1> 	;jb     short loc_gfvn_dir_load_err
  1453                              <1> 
  1454 00007A08 89DE                <1> 	mov	esi, ebx
  1455 00007A0A 81E600FF0000        <1> 	and	esi, 0FF00h ; esi = bh
  1456 00007A10 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1457 00007A16 8A06                <1> 	mov     al, [esi+LD_Name]
  1458 00007A18 8A6603              <1> 	mov     ah, [esi+LD_FATType]
  1459 00007A1B 80FC01              <1> 	cmp     ah, 1
  1460 00007A1E 7210                <1> 	jb    	short loc_gfvn_dir_load_err
  1461 00007A20 3C41                <1> 	cmp 	al, 'A'
  1462 00007A22 720C                <1> 	jb      short loc_gfvn_dir_load_err
  1463 00007A24 80FC02              <1> 	cmp 	ah, 2 
  1464 00007A27 7708                <1> 	ja      short get_FAT32_root_cluster
  1465                              <1> 	
  1466 00007A29 E8634E0000          <1> 	call    load_FAT_root_directory
  1467 00007A2E 730B                <1> 	jnc     short loc_get_volume_name
  1468                              <1> 
  1469                              <1> loc_gfvn_dir_load_err:
  1470 00007A30 C3                  <1> 	retn
  1471                              <1> 
  1472                              <1> get_FAT32_root_cluster:
  1473 00007A31 8B4632              <1> 	mov	eax, [esi+LD_BPB+BPB_RootClus]
  1474 00007A34 E8E34E0000          <1> 	call    load_FAT_sub_directory
  1475 00007A39 7224                <1> 	jc	short loc_get_volume_name_retn
  1476                              <1> 
  1477                              <1> loc_get_volume_name:
  1478 00007A3B BE00000800          <1>         mov     esi, Directory_Buffer
  1479 00007A40 6631C9              <1> 	xor	cx, cx ; 0
  1480                              <1> check_root_volume_name:
  1481 00007A43 8A06                <1> 	mov	al, [esi]
  1482 00007A45 08C0                <1> 	or      al, al
  1483 00007A47 7416                <1> 	jz      short loc_get_volume_name_retn
  1484 00007A49 807E0B08            <1> 	cmp     byte [esi+0Bh], 08h
  1485 00007A4D 7410                <1> 	je      short loc_get_volume_name_retn
  1486 00007A4F 663B0D[C76B0100]    <1> 	cmp     cx, [DirBuff_LastEntry]
  1487 00007A56 7308                <1> 	jnb     short pass_check_root_volume_name
  1488 00007A58 6641                <1> 	inc     cx
  1489 00007A5A 83C620              <1> 	add     esi, 32
  1490 00007A5D EBE4                <1> 	jmp     short check_root_volume_name
  1491                              <1> 
  1492                              <1> loc_get_volume_name_retn:
  1493 00007A5F C3                  <1> 	retn
  1494                              <1>     
  1495                              <1> pass_check_root_volume_name:
  1496 00007A60 803D[C36B0100]03    <1> 	cmp	byte [DirBuff_FATType], 3
  1497 00007A67 7230                <1> 	jb	short loc_get_volume_name_retn_xor
  1498                              <1> 
  1499 00007A69 BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1500 00007A6E BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1501 00007A73 31C0                <1> 	xor	eax, eax
  1502 00007A75 8A25[C26B0100]      <1> 	mov	ah, [DirBuff_DRV]
  1503 00007A7B 80EC41              <1> 	sub	ah, 'A' 
  1504 00007A7E 01C6                <1> 	add	esi, eax
  1505 00007A80 A1[C96B0100]        <1> 	mov	eax, [DirBuff_Cluster]
  1506 00007A85 E8AC4C0000          <1> 	call	get_next_cluster
  1507 00007A8A 7305                <1> 	jnc 	short loc_gfvn_load_FAT32_dir_cluster
  1508                              <1>   	
  1509 00007A8C 83F801              <1> 	cmp     eax, 1
  1510 00007A8F F5                  <1> 	cmc
  1511 00007A90 C3                  <1> 	retn
  1512                              <1>   
  1513                              <1> loc_gfvn_load_FAT32_dir_cluster:
  1514 00007A91 E8864E0000          <1> 	call	load_FAT_sub_directory
  1515 00007A96 73A3                <1> 	jnc	short loc_get_volume_name
  1516 00007A98 C3                  <1> 	retn
  1517                              <1> 
  1518                              <1> loc_get_volume_name_retn_xor:
  1519 00007A99 31C0                <1> 	xor 	eax, eax
  1520 00007A9B C3                  <1> 	retn
  1521                              <1> 
  1522                              <1> get_media_change_status:
  1523                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
  1524                              <1> 	; 09/09/2009
  1525                              <1> 	; INPUT:
  1526                              <1> 	;     DL = Drive number (physical)
  1527                              <1> 	; OUTPUT: clc & AH = 6 media changed
  1528                              <1> 	;     clc & AH = 0 media not changed         
  1529                              <1> 	;     stc -> Drive not ready or an error 
  1530                              <1>   
  1531 00007A9C B416                <1> 	mov	ah, 16h
  1532 00007A9E E857D1FFFF          <1>   	call	int13h
  1533 00007AA3 80FC06              <1> 	cmp	ah, 06h
  1534 00007AA6 7405                <1> 	je	short loc_gmc_status_retn
  1535 00007AA8 08E4                <1> 	or	ah, ah
  1536 00007AAA 7401                <1> 	jz	short loc_gmc_status_retn
  1537                              <1> loc_gmc_status_stc_retn:    
  1538 00007AAC F9                  <1> 	stc
  1539                              <1> loc_gmc_status_retn:
  1540 00007AAD C3                  <1> 	retn
  3032                                  %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: 31/12/2017
     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> 	; 16/10/2016
    21                              <1> 	; 02/02/2016
    22                              <1> 	; 15/01/2016 (TRDOS 386 = TRDOS v2.0)
    23                              <1> 	; 18/08/2011
    24                              <1> 	; 09/09/2009
    25                              <1> 	; INPUT:
    26                              <1> 	;   DL = Logical DOS Drive Number
    27                              <1> 	; OUTPUT:
    28                              <1> 	;  cf=1 -> Not successful
    29                              <1> 	;   EAX = Error code
    30                              <1> 	;  cf=0 ->
    31                              <1> 	;   EAX = 0 (successful)
    32                              <1> 
    33 00007AAE 31DB                <1> 	xor	ebx, ebx
    34 00007AB0 88D7                <1> 	mov	bh, dl
    35                              <1> 
    36                              <1> 	;cmp	dl, 1
    37                              <1> 	;jna	short loc_ccdrv_initial_media_change_check
    38                              <1> 	;cmp	bh, [Last_Dos_DiskNo]
    39                              <1> 	;ja	short loc_ccdrv_drive_not_ready_err
    40                              <1> 
    41                              <1> loc_ccdrv_initial_media_change_check:
    42 00007AB2 BE00010900          <1> 	mov	esi, Logical_DOSDisks
    43 00007AB7 01DE                <1> 	add	esi, ebx
    44                              <1> loc_ccdrv_dos_drive_name_check:
    45 00007AB9 80FA02              <1> 	cmp	dl, 2
    46 00007ABC 720F                <1> 	jb	short loc_ccdrv_dos_drive_name_check_ok
    47                              <1> 
    48 00007ABE 8A06                <1> 	mov	al, [esi+LD_Name]
    49 00007AC0 2C41                <1> 	sub	al, 'A'
    50 00007AC2 38D0                <1> 	cmp	al, dl
    51 00007AC4 7407                <1> 	je	short loc_ccdrv_dos_drive_name_check_ok
    52                              <1> 
    53                              <1> loc_ccdrv_drive_not_ready_err:
    54                              <1> 	; 16/10/2016 (15h -> 15)
    55 00007AC6 B80F000000          <1> 	mov	eax, 15 ; Drive not ready
    56                              <1> loc_change_current_drive_stc_retn:
    57 00007ACB F9                  <1> 	stc
    58 00007ACC C3                  <1> 	retn  
    59                              <1> 
    60                              <1> loc_ccdrv_dos_drive_name_check_ok:
    61 00007ACD 8A667E              <1> 	mov	ah, [esi+LD_MediaChanged]
    62 00007AD0 80FC06              <1> 	cmp	ah, 6  ; VOLUME NAME CHECK/MOVE SIGN
    63 00007AD3 7455                <1> 	je	short loc_ccdrv_get_FAT_volume_name_0
    64                              <1> 
    65 00007AD5 80FA01              <1> 	cmp	dl, 1
    66 00007AD8 777D                <1> 	ja	short loc_gmcs_init_drv_hd
    67                              <1> 
    68                              <1> loc_gmcs_init_drv_fd:
    69 00007ADA 08E4                <1> 	or	ah, ah 
    70                              <1> 	; AH = 1 is initialization sign (invalid_fd_parameter)
    71 00007ADC 7517                <1> 	jnz	short loc_ccdrv_call_fd_init
    72                              <1> 
    73 00007ADE E8B9FFFFFF          <1> 	call	get_media_change_status
    74 00007AE3 72E1                <1> 	jc	short loc_ccdrv_drive_not_ready_err
    75                              <1> 
    76 00007AE5 20E4                <1> 	and	ah, ah
    77 00007AE7 7476                <1> 	jz	short loc_change_current_drv3
    78                              <1> 
    79 00007AE9 80F406              <1> 	xor	ah, 6
    80 00007AEC 75D8                <1> 	jnz	short loc_ccdrv_drive_not_ready_err
    81                              <1> 
    82                              <1> loc_ccdrv_call_fd_init_check_vol_id:
    83 00007AEE E8440A0000          <1> 	call	get_volume_serial_number
    84 00007AF3 730D                <1> 	jnc	short loc_ccdrv_check_vol_serial
    85                              <1> 
    86                              <1> loc_ccdrv_call_fd_init:
    87 00007AF5 E872FCFFFF          <1> 	call	floppy_drv_init
    88 00007AFA 731A                <1> 	jnc	short loc_reset_drv_fd_current_dir
    89                              <1> 
    90                              <1> loc_ccdrv_fdinit_fail_retn:
    91                              <1> 	; 16/10/2016
    92 00007AFC B80F000000          <1> 	mov	eax, 15 ; Drive not ready
    93 00007B01 C3                  <1> 	retn
    94                              <1> 
    95                              <1> loc_ccdrv_check_vol_serial:
    96 00007B02 A3[94640100]        <1> 	mov	[Current_VolSerial], eax
    97                              <1> 	;mov	dl, bh
    98 00007B07 E860FCFFFF          <1> 	call	floppy_drv_init
    99 00007B0C 72EE                <1> 	jc	short loc_ccdrv_fdinit_fail_retn
   100                              <1> 
   101 00007B0E 3B05[94640100]      <1> 	cmp	eax, [Current_VolSerial]
   102 00007B14 7445                <1> 	je	short loc_change_current_drv2
   103                              <1> 
   104                              <1> loc_reset_drv_fd_current_dir:
   105 00007B16 31C0                <1> 	xor	eax, eax              
   106 00007B18 88467F              <1>         mov	[esi+LD_CDirLevel], al
   107 00007B1B 89F7                <1> 	mov	edi, esi
   108 00007B1D 81C780000000        <1> 	add	edi, LD_CurrentDirectory
   109 00007B23 B920000000          <1> 	mov	ecx, 32
   110 00007B28 F3AB                <1> 	rep	stosd   
   111                              <1>  
   112                              <1> loc_ccdrv_get_FAT_volume_name_0:
   113 00007B2A 8A4603              <1> 	mov	al, [esi+LD_FATType]
   114 00007B2D 08C0                <1> 	or	al, al
   115 00007B2F 742A                <1> 	jz	short loc_change_current_drv2
   116                              <1> 
   117 00007B31 56                  <1> 	push	esi 
   118 00007B32 3C02                <1> 	cmp	al, 2
   119 00007B34 7705                <1> 	ja	short loc_ccdrv_get_FAT32_vol_name
   120                              <1>              
   121                              <1> loc_ccdrv_get_FAT2_16_vol_name:
   122 00007B36 83C631              <1> 	add	esi, LD_BPB + VolumeLabel
   123 00007B39 EB03                <1> 	jmp	short loc_ccdrv_get_FAT_volume_name_1
   124                              <1> 
   125                              <1> loc_ccdrv_get_FAT32_vol_name:
   126 00007B3B 83C64D              <1> 	add	esi, LD_BPB + FAT32_VolLab
   127                              <1> loc_ccdrv_get_FAT_volume_name_1:
   128 00007B3E 53                  <1> 	push	ebx
   129 00007B3F 56                  <1> 	push	esi
   130 00007B40 E8C3FEFFFF          <1> 	call	get_FAT_volume_name
   131 00007B45 5F                  <1> 	pop	edi
   132 00007B46 5B                  <1> 	pop	ebx
   133                              <1> 	; BL = 0
   134 00007B47 720B                <1> 	jc	short loc_change_current_drv1
   135 00007B49 20C0                <1> 	and	al, al
   136 00007B4B 7407                <1> 	jz	short loc_change_current_drv1
   137                              <1> 
   138                              <1> loc_ccdrv_move_FAT_volume_name:
   139 00007B4D B90B000000          <1> 	mov	ecx, 11
   140 00007B52 F3A4                <1> 	rep	movsb
   141                              <1> 
   142                              <1> loc_change_current_drv1:
   143 00007B54 5E                  <1> 	pop	esi
   144 00007B55 EB04                <1> 	jmp	short loc_change_current_drv2
   145                              <1> 
   146                              <1> loc_gmcs_init_drv_hd:
   147 00007B57 08E4                <1> 	or	ah, ah
   148 00007B59 7404                <1> 	jz	short loc_change_current_drv3
   149                              <1> 	; BL = 0, BH = Logical DOS drive number
   150                              <1> loc_change_current_drv2:
   151 00007B5B C6467E00            <1> 	mov	byte [esi+LD_MediaChanged], 0
   152                              <1> loc_change_current_drv3:
   153 00007B5F 883D[9E640100]      <1> 	mov	[Current_Drv], bh
   154                              <1> 
   155                              <1> 	;call	restore_current_directory
   156                              <1> 	;retn
   157                              <1> 
   158                              <1> restore_current_directory:
   159                              <1> 	; 11/02/2016
   160                              <1> 	; 15/01/2016 (TRDOS 386 = TRDOS v2.0)
   161                              <1> 	; 25/01/2010
   162                              <1> 	; 12/10/2009
   163                              <1> 	;
   164                              <1> 	; INPUT:
   165                              <1> 	;   ESI = Logical DOS Drive Description Table
   166                              <1> 	;
   167                              <1> 	; OUTPUT:
   168                              <1> 	;   ESI = Logical DOS Drive Description Table
   169                              <1> 	;   EDI = offset Current_Dir_Drv 
   170                              <1> 
   171 00007B65 8A4603              <1> 	mov	al, [esi+LD_FATType]
   172 00007B68 A2[9D640100]        <1> 	mov	[Current_FATType], al
   173                              <1> 
   174 00007B6D 8A26                <1> 	mov	ah, [esi+LD_Name] 
   175 00007B6F 8825[9F640100]      <1> 	mov	[Current_Dir_Drv], ah
   176                              <1> 
   177 00007B75 20C0                <1> 	and	al, al
   178 00007B77 741D                <1> 	jz	short loc_restore_FS_current_directory
   179                              <1> 
   180                              <1> loc_restore_FAT_current_directory:
   181 00007B79 8A667F              <1> 	mov	ah, [esi+LD_CDirLevel]
   182 00007B7C 8825[9C640100]      <1> 	mov	[Current_Dir_Level], ah
   183 00007B82 08E4                <1> 	or	ah, ah
   184 00007B84 7416                <1>         jz	short loc_ccdrv_reset_cdir_FAT_12_16_32_fcluster
   185                              <1> 
   186 00007B86 0FB6D4              <1> 	movzx	edx, ah
   187 00007B89 C0E204              <1> 	shl	dl, 4 ; * 16
   188 00007B8C 01F2                <1>         add	edx, esi
   189 00007B8E 8B828C000000        <1> 	mov	eax, [edx+LD_CurrentDirectory+12]
   190 00007B94 EB2C                <1> 	jmp	short loc_ccdrv_reset_cdir_FAT_fcluster
   191                              <1> 
   192                              <1> loc_restore_FS_current_directory:
   193 00007B96 E8BC4D0000          <1> 	call	load_current_FS_directory 
   194 00007B9B C3                  <1> 	retn 
   195                              <1> 
   196                              <1> loc_ccdrv_reset_cdir_FAT_12_16_32_fcluster:
   197 00007B9C 3C03                <1> 	cmp	al, 3
   198 00007B9E 7205                <1> 	jb	short loc_ccdrv_reset_cdir_FAT_12_16_fcluster
   199                              <1> loc_ccdrv_reset_cdir_FAT32_fcluster:
   200 00007BA0 8B4632              <1> 	mov	eax, [esi+LD_BPB+FAT32_RootFClust]
   201 00007BA3 EB04                <1> 	jmp	short loc_ccdrv_check_rootdir_sign
   202                              <1> loc_ccdrv_reset_cdir_FAT_12_16_fcluster:   
   203 00007BA5 30C0                <1> 	xor	al, al  ; xor eax, eax
   204 00007BA7 31D2                <1> 	xor	edx, edx
   205                              <1> loc_ccdrv_check_rootdir_sign:
   206 00007BA9 80BE8000000000      <1> 	cmp	byte [esi+LD_CurrentDirectory], 0
   207 00007BB0 7510                <1> 	jne	short loc_ccdrv_reset_cdir_FAT_fcluster
   208                              <1> loc_ccdrv_set_rootdir_FAT_fcluster:
   209 00007BB2 89868C000000        <1>         mov     [esi+LD_CurrentDirectory+12], eax
   210 00007BB8 C78680000000524F4F- <1> 	mov	dword [esi+LD_CurrentDirectory], 'ROOT'
   210 00007BC1 54                  <1>
   211                              <1> 
   212                              <1> loc_ccdrv_reset_cdir_FAT_fcluster:
   213 00007BC2 A3[98640100]        <1> 	mov	[Current_Dir_FCluster], eax
   214                              <1> 
   215 00007BC7 BF[FB6B0100]        <1> 	mov	edi, PATH_Array
   216 00007BCC 89F2                <1> 	mov	edx, esi
   217 00007BCE 81C680000000        <1> 	add	esi, LD_CurrentDirectory
   218 00007BD4 B920000000          <1> 	mov	ecx, 32
   219 00007BD9 F3A5                <1> 	rep	movsd
   220                              <1> 
   221 00007BDB E84C2D0000          <1> 	call	change_prompt_dir_string
   222                              <1> 	
   223 00007BE0 89D6                <1> 	mov	esi, edx
   224                              <1> 	
   225 00007BE2 29C0                <1>         sub	eax, eax
   226                              <1>        ;sub	edx, edx
   227 00007BE4 BF[9F640100]        <1> 	mov	edi, Current_Dir_Drv
   228                              <1> 
   229 00007BE9 A2[F6170100]        <1> 	mov	[Restore_CDIR], al ; 0
   230 00007BEE C3                  <1> 	retn
   231                              <1> 
   232                              <1> dos_prompt:
   233                              <1> 	; 06/05/2016
   234                              <1> 	; 30/01/2016
   235                              <1> 	; 29/01/2016
   236                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   237                              <1> 	; 15/09/2011
   238                              <1> 	; 13/09/2009
   239                              <1> 	; 2004-2005
   240                              <1> 
   241                              <1> 	; 06/05/2016
   242 00007BEF C705[58700100]-     <1> 	mov	dword [mainprog_return_addr], return_from_cmd_interpreter
   242 00007BF5 [A37C0000]          <1>
   243                              <1> 
   244                              <1> loc_TRDOS_prompt:
   245 00007BF9 BF[9E650100]        <1> 	mov	edi, TextBuffer
   246 00007BFE C6075B              <1> 	mov	byte [edi], "["
   247 00007C01 47                  <1> 	inc	edi
   248 00007C02 BE[49180100]        <1> 	mov	esi, TRDOSPromptLabel
   249                              <1> get_next_prompt_label_char:
   250 00007C07 803E20              <1> 	cmp	byte [esi], 20h
   251 00007C0A 7203                <1> 	jb	short pass_prompt_label
   252 00007C0C A4                  <1> 	movsb
   253 00007C0D EBF8                <1> 	jmp	short get_next_prompt_label_char
   254                              <1> pass_prompt_label:
   255 00007C0F C6075D              <1> 	mov	byte [edi], "]"
   256 00007C12 47                  <1> 	inc	edi
   257 00007C13 C60720              <1> 	mov	byte [edi], 20h
   258 00007C16 47                  <1> 	inc	edi
   259 00007C17 BE[9F640100]        <1> 	mov	esi, Current_Dir_Drv
   260 00007C1C 66A5                <1> 	movsw
   261 00007C1E A4                  <1> 	movsb 
   262                              <1> loc_prompt_current_directory:
   263 00007C1F 803E20              <1> 	cmp	byte [esi], 20h
   264 00007C22 7203                <1> 	jb	short pass_prompt_current_directory
   265 00007C24 A4                  <1> 	movsb
   266 00007C25 EBF8                <1> 	jmp	short loc_prompt_current_directory  
   267                              <1> pass_prompt_current_directory:
   268 00007C27 C6073E              <1> 	mov	byte [edi], '>'
   269 00007C2A 47                  <1> 	inc	edi
   270 00007C2B C60700              <1> 	mov	byte [edi], 0  
   271 00007C2E BE[9E650100]        <1> 	mov	esi, TextBuffer
   272 00007C33 E8EDF2FFFF          <1> 	call	print_msg
   273                              <1>         
   274                              <1> 	;sub	bh, bh ; video page = 0
   275                              <1> 	;call	get_cpos ; get cursor position
   276 00007C38 668B15[F6630100]    <1> 	mov	dx, [CURSOR_POSN] ; video page 0
   277 00007C3F 8815[FE640100]      <1> 	mov	[CursorColumn], dl
   278                              <1> 
   279                              <1> 	; 30/01/2016 (to show cursor on the row, again)
   280                              <1> 	; (Initial color attributes of video page 0 is 0)
   281                              <1> 	; (see: 'StartPMP' in trdos386.s)
   282                              <1> 	; 
   283                              <1> 	;mov	edi, 0B8000h ; start of video page 0
   284                              <1> 	;movzx	ecx, dl ; column	 
   285                              <1> 	;mov	al, 80
   286                              <1> 	;mul	dh
   287                              <1> 	;add	ax, cx
   288                              <1> 	;shl	ax, 1 ; character + attribute
   289                              <1> 	;add	di, ax ; (2*80*row) + (2*column)
   290                              <1> 	;neg	cl
   291                              <1> 	;add	cl, 80
   292                              <1> 	;mov	ax, 700h ;  ah = 7 (color attribute)
   293                              <1> 	;rep	stosw	
   294                              <1> 
   295                              <1> loc_rw_char:
   296 00007C45 E899000000          <1> 	call	rw_char
   297                              <1> loc_move_command:
   298 00007C4A BE[4E650100]        <1> 	mov	esi, CommandBuffer
   299 00007C4F 89F7                <1> 	mov	edi, esi
   300 00007C51 31C9                <1> 	xor	ecx, ecx
   301                              <1> first_command_char:
   302 00007C53 AC                  <1> 	lodsb
   303 00007C54 3C20                <1> 	cmp	al, 20h
   304 00007C56 772E                <1> 	ja	short pass_space_control
   305 00007C58 7241                <1> 	jb	short loc_move_cmd_arguments_ok
   306 00007C5A 81FE[9D650100]      <1> 	cmp	esi, CommandBuffer + 79
   307 00007C60 72F1                <1> 	jb	short first_command_char
   308 00007C62 EB37                <1> 	jmp	short loc_move_cmd_arguments_ok
   309                              <1> 
   310                              <1> next_command_char:
   311 00007C64 AC                  <1> 	lodsb
   312 00007C65 3C20                <1> 	cmp	al, 20h
   313 00007C67 771D                <1> 	ja	short pass_space_control
   314 00007C69 7230                <1> 	jb	short loc_move_cmd_arguments_ok
   315                              <1> 
   316                              <1> loc_1st_cmd_arg: ; 30/01/2016
   317 00007C6B AC                  <1> 	lodsb
   318 00007C6C 3C20                <1> 	cmp	al, 20h
   319 00007C6E 74FB                <1> 	je	short loc_1st_cmd_arg
   320 00007C70 7229                <1> 	jb	short loc_move_cmd_arguments_ok
   321                              <1> 	
   322 00007C72 C60700              <1>         mov     byte [edi], 0
   323 00007C75 47                  <1> 	inc	edi
   324                              <1> 
   325                              <1> loc_move_cmd_arguments:
   326 00007C76 AA                  <1> 	stosb
   327 00007C77 81FE[9D650100]      <1> 	cmp	esi, CommandBuffer + 79
   328 00007C7D 731C                <1> 	jnb	short loc_move_cmd_arguments_ok
   329 00007C7F AC                  <1>         lodsb
   330 00007C80 3C20                <1> 	cmp	al, 20h
   331 00007C82 73F2                <1> 	jnb	short loc_move_cmd_arguments
   332 00007C84 EB15                <1> 	jmp	short loc_move_cmd_arguments_ok
   333                              <1> 
   334                              <1> pass_space_control:
   335 00007C86 3C61                <1> 	cmp	al, 61h
   336 00007C88 7206                <1> 	jb	short pass_capitalize
   337 00007C8A 3C7A                <1> 	cmp	al, 7Ah
   338 00007C8C 7702                <1> 	ja	short pass_capitalize
   339 00007C8E 24DF                <1> 	and	al, 0DFh
   340                              <1> pass_capitalize:
   341 00007C90 AA                  <1> 	stosb   
   342 00007C91 FEC1                <1> 	inc     cl
   343 00007C93 81FE[9D650100]      <1>         cmp     esi, CommandBuffer + 79
   344 00007C99 72C9                <1> 	jb      short next_command_char 
   345                              <1> 
   346                              <1> loc_move_cmd_arguments_ok:
   347 00007C9B C60700              <1>         mov     byte [edi], 0
   348                              <1> 
   349                              <1> call_command_interpreter:
   350 00007C9E E8CF080000          <1> 	call    command_interpreter
   351                              <1> 
   352                              <1> return_from_cmd_interpreter:
   353 00007CA3 B950000000          <1>         mov	ecx, 80
   354                              <1> 	;mov	cx, 80
   355 00007CA8 BF[4E650100]        <1> 	mov	edi, CommandBuffer
   356 00007CAD 30C0                <1> 	xor	al, al
   357 00007CAF F3AA                <1> 	rep	stosb
   358                              <1> 	;cmp	byte [Program_Exit], 0
   359                              <1> 	;ja	short loc_terminate_trdos
   360                              <1>         
   361                              <1> 	; 16/01/2016
   362 00007CB1 803D[9A690000]03    <1> 	cmp	byte [CRT_MODE], 3 ; 80*25 color
   363 00007CB8 741D                <1> 	je	short pass_set_txt_mode
   364                              <1> 
   365 00007CBA E8A79DFFFF          <1> 	call	set_txt_mode ; set vide mode to 03h
   366                              <1> 	; 07/01/2017
   367 00007CBF 30C0                <1> 	xor	al, al
   368                              <1> 
   369                              <1> loc_check_active_page:
   370                              <1> 	;xor	al, al
   371 00007CC1 3805[06640100]      <1> 	cmp	[ACTIVE_PAGE], al ; 0
   372 00007CC7 0F842CFFFFFF        <1>         je      loc_TRDOS_prompt 
   373                              <1> 	; AL = 0 = video page 0
   374 00007CCD E8DDA1FFFF          <1> 	call	set_active_page
   375 00007CD2 E922FFFFFF          <1>         jmp     loc_TRDOS_prompt ; infinitive loop
   376                              <1> 
   377                              <1> pass_set_txt_mode: 
   378 00007CD7 BE[93240100]        <1> 	mov	esi, nextline
   379 00007CDC E844F2FFFF          <1> 	call	print_msg
   380 00007CE1 EBDE                <1> 	jmp     short loc_check_active_page
   381                              <1> 
   382                              <1> rw_char:
   383                              <1> 	; 13/05/2016
   384                              <1> 	; 30/01/2016
   385                              <1> 	; 29/01/2016
   386                              <1> 	; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
   387                              <1> 	; 2004-2005
   388                              <1> 	
   389                              <1> 	; DH = cursor row, DL = cursor column
   390                              <1> 	; BH = 0 = video page number (active page)
   391                              <1> 
   392                              <1> 	;xor	bh, bh ; 0 = video page 0
   393                              <1> 
   394                              <1> readnextchar:
   395 00007CE3 30E4                <1> 	xor     ah, ah
   396 00007CE5 E8EB91FFFF          <1> 	call	int16h
   397 00007CEA 20C0                <1> 	and	al, al
   398 00007CEC 7432                <1> 	jz	short loc_arrow    
   399 00007CEE 3CE0                <1> 	cmp	al, 0E0h          
   400 00007CF0 742E                <1> 	je	short loc_arrow
   401 00007CF2 3C08                <1> 	cmp	al, 08h             
   402 00007CF4 7542                <1> 	jne	short char_return
   403                              <1> loc_back:
   404 00007CF6 3A15[FE640100]      <1> 	cmp	dl, [CursorColumn]
   405 00007CFC 76E5                <1> 	jna     short readnextchar
   406                              <1> prev_column:
   407 00007CFE FECA                <1> 	dec	dl
   408                              <1> set_cursor_pos:
   409                              <1> 	;push	dx
   410 00007D00 52                  <1> 	push	edx ; 29/12/2017
   411                              <1> 	;xor	bh, bh ; 0 = video page 0
   412                              <1> 	; DH = Row, DL = Column
   413 00007D01 E891A5FFFF          <1> 	call	_set_cpos ; 17/01/2016
   414 00007D06 5A                  <1>         pop	edx ; 29/12/2017
   415                              <1> 	;pop	dx
   416                              <1> 	;movzx	ebx, dl
   417 00007D07 88D3                <1> 	mov	bl, dl
   418 00007D09 2A1D[FE640100]      <1> 	sub	bl, [CursorColumn] 
   419 00007D0F B020                <1> 	mov	al, 20h
   420 00007D11 8883[4E650100]      <1> 	mov	[CommandBuffer+ebx], al
   421                              <1> 	;sub	bh, bh ; video page 0
   422                              <1> 	;mov	cx, 1
   423 00007D17 B307                <1> 	mov	bl, 7 ; color attribute
   424 00007D19 E858A4FFFF          <1> 	call	_write_c_current ; 17/01/2016
   425                              <1> 	;mov	dx, [CURSOR_POSN]
   426 00007D1E EBC3                <1> 	jmp	short readnextchar
   427                              <1> loc_arrow:    
   428 00007D20 80FC4B              <1> 	cmp	ah, 4Bh
   429 00007D23 74D1                <1> 	je	short loc_back
   430 00007D25 80FC53              <1> 	cmp	ah, 53h
   431 00007D28 74CC                <1> 	je      short loc_back
   432 00007D2A 80FC4D              <1> 	cmp	ah, 4Dh
   433 00007D2D 75B4                <1> 	jne	short readnextchar
   434 00007D2F 80FA4F              <1> 	cmp	dl, 79
   435 00007D32 73AF                <1> 	jnb	short readnextchar
   436 00007D34 FEC2                <1> 	inc	dl
   437 00007D36 EBC8                <1> 	jmp	short set_cursor_pos
   438                              <1> char_return:
   439 00007D38 0FB6DA              <1> 	movzx	ebx, dl
   440 00007D3B 2A1D[FE640100]      <1> 	sub	bl, [CursorColumn] 
   441 00007D41 3C20                <1> 	cmp	al, 20h
   442 00007D43 721D                <1> 	jb	short loc_escape
   443 00007D45 8883[4E650100]      <1> 	mov	[CommandBuffer+ebx], al
   444 00007D4B 80FA4F              <1> 	cmp	dl, 79
   445 00007D4E 7393                <1> 	jnb	short readnextchar
   446 00007D50 66BB0700            <1> 	mov	bx, 7 ; color attribute
   447 00007D54 E8A4A4FFFF          <1> 	call	_write_tty
   448 00007D59 668B15[F6630100]    <1> 	mov	dx, [CURSOR_POSN] ; video page 0
   449 00007D60 EB81                <1>         jmp     readnextchar
   450                              <1> loc_escape:
   451 00007D62 3C1B                <1> 	cmp	al, 1Bh
   452 00007D64 7418                <1> 	je	short rw_char_retn
   453                              <1> 	;
   454 00007D66 3C0D                <1> 	cmp	al, 0Dh ; CR
   455 00007D68 0F8575FFFFFF        <1>         jne     readnextchar
   456                              <1> 	; 13/05/2016
   457 00007D6E 66BB0700            <1> 	mov	bx, 7 ; attribute/color (bl)
   458                              <1> 		      ; video page 0 (bh=0)	
   459 00007D72 E886A4FFFF          <1> 	call	_write_tty
   460                              <1> 	;mov	bx, 7  ; attribute/color
   461                              <1> 		      ; video page 0 (bh=0)
   462 00007D77 B00A                <1> 	mov	al, 0Ah ; LF
   463 00007D79 E87FA4FFFF          <1> 	call	_write_tty
   464                              <1> rw_char_retn:
   465 00007D7E C3                  <1> 	retn
   466                              <1> 
   467                              <1> show_date:
   468                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   469                              <1>         ; 2004-2005
   470                              <1> 
   471                              <1> 	;mov	ah, 04h
   472                              <1> 	;call	int1Ah
   473 00007D7F E869E7FFFF          <1> 	call	RTC_40	; GET RTC DATE
   474                              <1> 
   475 00007D84 88D0                <1> 	mov	al, dl
   476 00007D86 E83D91FFFF          <1>   	call	bcd_to_ascii
   477 00007D8B 66A3[35190100]      <1> 	mov	[Day], ax
   478                              <1> 
   479 00007D91 88F0                <1> 	mov	al, dh
   480 00007D93 E83091FFFF          <1>   	call	bcd_to_ascii
   481 00007D98 66A3[38190100]      <1> 	mov	[Month], ax
   482                              <1> 
   483 00007D9E 88E8                <1> 	mov	al, ch
   484 00007DA0 E82391FFFF          <1>   	call	bcd_to_ascii
   485 00007DA5 66A3[3B190100]      <1> 	mov	[Century], ax
   486                              <1> 
   487 00007DAB 88C8                <1> 	mov	al, cl
   488 00007DAD E81691FFFF          <1>   	call	bcd_to_ascii
   489 00007DB2 66A3[3D190100]      <1> 	mov	word [Year], ax
   490                              <1> 
   491 00007DB8 BE[25190100]        <1> 	mov	esi, Msg_Show_Date
   492 00007DBD E863F1FFFF          <1> 	call	print_msg
   493                              <1> 
   494 00007DC2 C3                  <1> 	retn
   495                              <1> 
   496                              <1> set_date:
   497                              <1> 	; 13/05/2016
   498                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   499                              <1>         ; 2004-2005
   500                              <1> 
   501 00007DC3 BE[09190100]        <1> 	mov	esi, Msg_Enter_Date
   502 00007DC8 E858F1FFFF          <1> 	call	print_msg
   503                              <1> 
   504                              <1> loc_enter_day_1:
   505 00007DCD 30E4                <1> 	xor     ah, ah
   506 00007DCF E80191FFFF          <1> 	call	int16h
   507                              <1> 	; AL = ASCII Code of the Character
   508 00007DD4 3C0D                <1> 	cmp	al, 13
   509 00007DD6 0F84B7010000        <1> 	je	loc_set_date_retn
   510 00007DDC 3C1B                <1> 	cmp	al, 27
   511 00007DDE 0F84AF010000        <1> 	je	loc_set_date_retn
   512 00007DE4 A2[35190100]        <1> 	mov	[Day], al
   513 00007DE9 3C30                <1> 	cmp	al, '0'
   514 00007DEB 0F82AD010000        <1> 	jb	loc_set_date_stc_0
   515 00007DF1 3C33                <1> 	cmp	al, '3'
   516 00007DF3 0F87A5010000        <1> 	ja	loc_set_date_stc_0
   517                              <1> 	; 13/05/2016
   518                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   519                              <1> 		      ; video page 0 (bh)	
   520 00007DF9 B307                <1> 	mov	bl, 7
   521 00007DFB E8FDA3FFFF          <1> 	call	_write_tty
   522                              <1> loc_enter_day_2:
   523 00007E00 30E4                <1> 	xor     ah, ah
   524 00007E02 E8CE90FFFF          <1> 	call	int16h
   525                              <1> 	; AL = ASCII Code of the Character
   526 00007E07 3C1B                <1> 	cmp	al, 27
   527 00007E09 0F8484010000        <1>         je      loc_set_date_retn
   528 00007E0F A2[36190100]        <1> 	mov	[Day+1], al
   529 00007E14 3C30                <1> 	cmp	al, '0'
   530 00007E16 0F828C010000        <1>         jb      loc_set_date_stc_1
   531 00007E1C 3C39                <1> 	cmp	al, '9'
   532 00007E1E 0F8784010000        <1>         ja      loc_set_date_stc_1
   533 00007E24 803D[35190100]33    <1> 	cmp	byte [Day], '3'
   534 00007E2B 7208                <1> 	jb	short pass_set_day_31
   535 00007E2D 3C31                <1> 	cmp	al, '1'
   536 00007E2F 0F8773010000        <1>         ja      loc_set_date_stc_1
   537                              <1> pass_set_day_31:
   538                              <1> 	; 13/05/2016
   539                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   540                              <1> 		      ; video page 0 (bh)	
   541 00007E35 B307                <1> 	mov	bl, 7
   542 00007E37 E8C1A3FFFF          <1> 	call	_write_tty
   543                              <1> loc_enter_separator_1:
   544 00007E3C 28E4                <1> 	sub     ah, ah ; 0
   545 00007E3E E89290FFFF          <1> 	call	int16h
   546                              <1> 	; AL = ASCII Code of the Character
   547 00007E43 3C1B                <1> 	cmp	al, 27
   548 00007E45 0F8448010000        <1>         je      loc_set_date_retn
   549 00007E4B 3C2D                <1> 	cmp	al, '-'
   550 00007E4D 7408                <1> 	je	short pass_set_date_separator_1
   551 00007E4F 3C2F                <1> 	cmp	al, '/'
   552 00007E51 0F856C010000        <1>         jne     loc_set_date_stc_2
   553                              <1> pass_set_date_separator_1:
   554                              <1> 	; 13/05/2016
   555                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   556                              <1> 		      ; video page 0 (bh)
   557 00007E57 B307                <1> 	mov	bl, 7	
   558 00007E59 E89FA3FFFF          <1> 	call	_write_tty
   559                              <1> loc_enter_month_1:
   560 00007E5E 30E4                <1> 	xor     ah, ah ; 0
   561 00007E60 E87090FFFF          <1> 	call	int16h
   562                              <1> 	; AL = ASCII Code of the Character
   563 00007E65 3C1B                <1> 	cmp	al, 27
   564 00007E67 0F8426010000        <1>         je      loc_set_date_retn
   565 00007E6D A2[38190100]        <1> 	mov	[Month], al
   566 00007E72 3C30                <1> 	cmp	al, '0'
   567 00007E74 0F8264010000        <1>         jb      loc_set_date_stc_3
   568 00007E7A 3C31                <1> 	cmp	al, '1'
   569 00007E7C 0F875C010000        <1>         ja      loc_set_date_stc_3
   570                              <1> 	; 13/05/2016
   571                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   572                              <1> 		      ; video page 0 (bh)	
   573 00007E82 B307                <1> 	mov	bl, 7
   574 00007E84 E874A3FFFF          <1> 	call	_write_tty
   575                              <1> loc_enter_month_2:
   576 00007E89 30E4                <1> 	xor     ah, ah
   577 00007E8B E84590FFFF          <1> 	call	int16h
   578                              <1> 	; AL = ASCII Code of the Character
   579 00007E90 3C1B                <1> 	cmp	al, 27
   580 00007E92 0F84FB000000        <1>         je      loc_set_date_retn
   581 00007E98 A2[39190100]        <1> 	mov	[Month+1], al
   582 00007E9D 3C30                <1> 	cmp	al, '0'
   583 00007E9F 0F8254010000        <1>         jb      loc_set_date_stc_4
   584 00007EA5 3C39                <1> 	cmp	al, '9'
   585 00007EA7 0F874C010000        <1>         ja      loc_set_date_stc_4
   586 00007EAD 803D[38190100]31    <1> 	cmp	byte [Month], '1'
   587 00007EB4 7208                <1> 	jb	short pass_set_month_12
   588 00007EB6 3C32                <1> 	cmp	al, '2'
   589 00007EB8 0F873B010000        <1>         ja      loc_set_date_stc_4
   590                              <1> pass_set_month_12:
   591                              <1> 	; 13/05/2016
   592                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   593                              <1> 		      ; video page 0 (bh)
   594 00007EBE B307                <1> 	mov	bl, 7	
   595 00007EC0 E838A3FFFF          <1> 	call	_write_tty
   596                              <1> loc_enter_separator_2:
   597 00007EC5 28E4                <1> 	sub     ah, ah
   598 00007EC7 E80990FFFF          <1> 	call	int16h
   599                              <1> 	; AL = ASCII Code of the Character
   600 00007ECC 3C1B                <1> 	cmp	al, 27
   601 00007ECE 0F84BF000000        <1>         je      loc_set_date_retn
   602 00007ED4 3C2D                <1> 	cmp	al, '-'
   603 00007ED6 7408                <1> 	je	short pass_set_date_separator_2
   604 00007ED8 3C2F                <1> 	cmp	al, '/'
   605 00007EDA 0F8534010000        <1>         jne     loc_set_date_stc_5
   606                              <1> pass_set_date_separator_2:
   607                              <1> 	; 13/05/2016
   608                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   609                              <1> 		      ; video page 0 (bh)	
   610 00007EE0 B307                <1> 	mov	bl, 7
   611 00007EE2 E816A3FFFF          <1> 	call	_write_tty
   612                              <1> loc_enter_year_1:
   613 00007EE7 30E4                <1> 	xor    ah, ah
   614 00007EE9 E8E78FFFFF          <1> 	call	int16h
   615                              <1> 	; AL = ASCII Code of the Character
   616 00007EEE 3C1B                <1> 	cmp	al, 27
   617 00007EF0 0F849D000000        <1>         je      loc_set_date_retn
   618 00007EF6 A2[3D190100]        <1> 	mov	[Year], al
   619 00007EFB 3C30                <1> 	cmp	al, '0'
   620 00007EFD 0F822C010000        <1>         jb      loc_set_date_stc_6
   621 00007F03 3C39                <1> 	cmp	al, '9'
   622 00007F05 0F8724010000        <1>         ja      loc_set_date_stc_6
   623                              <1> 	; 13/05/2016
   624                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   625                              <1> 		      ; video page 0 (bh)
   626 00007F0B B307                <1> 	mov	bl, 7	
   627 00007F0D E8EBA2FFFF          <1> 	call	_write_tty
   628                              <1> loc_enter_year_2:
   629 00007F12 30E4                <1> 	xor	ah, ah
   630 00007F14 E8BC8FFFFF          <1> 	call	int16h
   631                              <1> 	; AL = ASCII Code of the Character
   632 00007F19 3C1B                <1> 	cmp	al, 27
   633 00007F1B 7476                <1> 	je	short loc_set_date_retn
   634 00007F1D A2[3E190100]        <1> 	mov	byte [Year+1], al
   635 00007F22 3C30                <1> 	cmp	al, '0'
   636 00007F24 0F8220010000        <1>         jb      loc_set_date_stc_7
   637 00007F2A 3C39                <1> 	cmp	al, '9'
   638 00007F2C 0F8718010000        <1>         ja      loc_set_date_stc_7
   639                              <1> 	; 13/05/2016
   640                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   641                              <1> 		      ; video page 0 (bh)
   642 00007F32 B307                <1> 	mov	bl, 7	
   643 00007F34 E8C4A2FFFF          <1> 	call	_write_tty
   644                              <1> loc_set_date_get_lchar_again:
   645 00007F39 28E4                <1> 	sub	ah, ah ; 0
   646 00007F3B E8958FFFFF          <1> 	call	int16h
   647                              <1> 	; AL = ASCII Code of the Character
   648 00007F40 3C0D                <1> 	cmp	al, 13 ; ENTER key
   649 00007F42 7412                <1> 	je	short loc_set_date_progress
   650 00007F44 3C1B                <1> 	cmp	al, 27 ; ESC key
   651 00007F46 744B                <1> 	je	short loc_set_date_retn
   652                              <1> 	;
   653 00007F48 E82A010000          <1> 	call	check_for_backspace
   654 00007F4D 75EA                <1> 	jne	short loc_set_date_get_lchar_again
   655                              <1> 
   656                              <1> loc_set_date_bs_8:
   657 00007F4F E811010000          <1> 	call	write_backspace
   658 00007F54 EBBC                <1> 	jmp	short loc_enter_year_2
   659                              <1> 
   660                              <1> loc_set_date_progress:
   661                              <1> 	; Get Current Date
   662                              <1> 	;mov	ah, 04h
   663                              <1> 	;call	int1Ah
   664 00007F56 E892E5FFFF          <1> 	call	RTC_40	; GET RTC DATE
   665                              <1> 	; CH = century (in BCD)
   666                              <1> 
   667 00007F5B 66A1[3D190100]      <1> 	mov	ax, [Year]
   668 00007F61 662D3030            <1> 	sub	ax, '00'
   669 00007F65 C0E004              <1> 	shl	al, 4 ; * 16
   670 00007F68 88C1                <1> 	mov	cl, al
   671 00007F6A 00E1                <1> 	add	cl, ah
   672 00007F6C 66A1[38190100]      <1> 	mov	ax, [Month]
   673 00007F72 662D3030            <1> 	sub	ax, '00'
   674 00007F76 C0E004              <1> 	shl	al, 4 ; * 16
   675 00007F79 88C6                <1> 	mov	dh, al
   676 00007F7B 00E6                <1> 	add	dh, ah
   677 00007F7D 66A1[35190100]      <1> 	mov	ax, [Day]
   678 00007F83 662D3030            <1> 	sub	ax, '00'
   679 00007F87 C0E004              <1> 	shl	al, 4 ; * 16
   680 00007F8A 88C2                <1> 	mov	dl, al
   681 00007F8C 00E2                <1> 	add	dl, ah
   682                              <1> 
   683                              <1> 	;mov	ah, 05h
   684                              <1> 	;call	int1Ah
   685 00007F8E E887E5FFFF          <1> 	call	RTC_50	; SET RTC DATE
   686                              <1> 
   687                              <1> loc_set_date_retn:
   688 00007F93 BE[93240100]        <1> 	mov	esi, nextline
   689 00007F98 E888EFFFFF          <1> 	call	print_msg
   690 00007F9D C3                  <1> 	retn
   691                              <1> 
   692                              <1> loc_set_date_stc_0:
   693                              <1> 	;xor	bh, bh ; video page 0
   694 00007F9E E83EA3FFFF          <1> 	call	beeper ; BEEP !
   695 00007FA3 E925FEFFFF          <1>         jmp     loc_enter_day_1
   696                              <1> loc_set_date_stc_1:
   697 00007FA8 E8CA000000          <1> 	call	check_for_backspace
   698 00007FAD 740A                <1> 	je	short loc_set_date_bs_1
   699                              <1> 	;xor	bh, bh ; video page 0
   700 00007FAF E82DA3FFFF          <1> 	call	beeper ; BEEP !
   701 00007FB4 E947FEFFFF          <1>         jmp     loc_enter_day_2
   702                              <1> loc_set_date_bs_1:
   703 00007FB9 E8A7000000          <1> 	call	write_backspace
   704 00007FBE E90AFEFFFF          <1>         jmp     loc_enter_day_1
   705                              <1> loc_set_date_stc_2:
   706 00007FC3 E8AF000000          <1> 	call	check_for_backspace
   707 00007FC8 740A                <1> 	je	short loc_set_date_bs_2
   708                              <1> 	;xor	bh, bh ; video page 0
   709 00007FCA E812A3FFFF          <1> 	call	beeper ; BEEP !
   710 00007FCF E968FEFFFF          <1>         jmp     loc_enter_separator_1
   711                              <1> loc_set_date_bs_2:
   712 00007FD4 E88C000000          <1> 	call	write_backspace
   713 00007FD9 E922FEFFFF          <1>         jmp     loc_enter_day_2
   714                              <1> loc_set_date_stc_3:
   715 00007FDE E894000000          <1> 	call	check_for_backspace	
   716 00007FE3 740A                <1> 	je short loc_set_date_bs_3
   717                              <1> 	;xor	bh, bh ; video page 0
   718 00007FE5 E8F7A2FFFF          <1> 	call	beeper ; BEEP !
   719 00007FEA E96FFEFFFF          <1>         jmp     loc_enter_month_1
   720                              <1> loc_set_date_bs_3:
   721 00007FEF E871000000          <1> 	call	write_backspace
   722 00007FF4 E943FEFFFF          <1>         jmp     loc_enter_separator_1
   723                              <1> loc_set_date_stc_4:
   724 00007FF9 E879000000          <1> 	call	check_for_backspace	
   725 00007FFE 740A                <1> 	je	short loc_set_date_bs_4
   726                              <1> 	;xor	bh, bh ; video page 0
   727 00008000 E8DCA2FFFF          <1> 	call	beeper ; BEEP !
   728 00008005 E97FFEFFFF          <1>         jmp     loc_enter_month_2
   729                              <1> loc_set_date_bs_4:
   730 0000800A E856000000          <1> 	call	write_backspace
   731 0000800F E94AFEFFFF          <1>         jmp     loc_enter_month_1
   732                              <1> loc_set_date_stc_5:
   733 00008014 E85E000000          <1> 	call	check_for_backspace
   734 00008019 740A                <1> 	je	short loc_set_date_bs_5
   735                              <1> 	;xor	bh, bh ; video page 0
   736 0000801B E8C1A2FFFF          <1> 	call	beeper ; BEEP !
   737 00008020 E9A0FEFFFF          <1>         jmp     loc_enter_separator_2
   738                              <1> loc_set_date_bs_5:
   739 00008025 E83B000000          <1> 	call	write_backspace
   740 0000802A E95AFEFFFF          <1>         jmp     loc_enter_month_2
   741                              <1> loc_set_date_stc_6:
   742 0000802F E843000000          <1> 	call	check_for_backspace
   743 00008034 740A                <1>         je      short  loc_set_date_bs_6
   744                              <1> 	;xor	bh, bh ; video page 0
   745 00008036 E8A6A2FFFF          <1> 	call	beeper ; BEEP !
   746 0000803B E9A7FEFFFF          <1>         jmp     loc_enter_year_1
   747                              <1> loc_set_date_bs_6:
   748 00008040 E820000000          <1> 	call	write_backspace
   749 00008045 E97BFEFFFF          <1>         jmp     loc_enter_separator_2
   750                              <1> loc_set_date_stc_7:
   751 0000804A E828000000          <1> 	call	check_for_backspace
   752 0000804F 740A                <1> 	je	short loc_set_date_bs_7
   753                              <1> 	;xor	bh, bh ; video page 0
   754 00008051 E88BA2FFFF          <1> 	call	beeper ; BEEP !
   755 00008056 E9B7FEFFFF          <1>         jmp     loc_enter_year_2
   756                              <1> loc_set_date_bs_7:
   757 0000805B E805000000          <1> 	call	write_backspace
   758 00008060 E982FEFFFF          <1>         jmp     loc_enter_year_1
   759                              <1> 
   760                              <1> write_backspace:
   761                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   762 00008065 B008                <1> 	mov	al, 08h ; BACKSPACE
   763                              <1> 	; 13/05/2016
   764 00008067 66BB0700            <1> 	mov	bx, 7 ; bl = attribute/color
   765                              <1> 		      ; bh = video page = 0	
   766 0000806B E88DA1FFFF          <1> 	call	_write_tty
   767 00008070 B020                <1> 	mov	al, 20h ; BLANK/SPACE char 
   768                              <1> 	;mov	bx, 7 ; attribute/color
   769                              <1> 	;call	_write_c_current
   770                              <1> 	;retn
   771 00008072 E9FFA0FFFF          <1> 	jmp	_write_c_current
   772                              <1> 
   773                              <1> check_for_backspace:
   774                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   775 00008077 663D080E            <1> 	cmp	ax, 0E08h
   776 0000807B 7410                <1> 	je	short cfbs_retn
   777 0000807D 663DE04B            <1> 	cmp	ax, 4BE0h
   778 00008081 740A                <1> 	je	short cfbs_retn
   779 00008083 663D004B            <1> 	cmp	ax, 4B00h
   780 00008087 7404                <1> 	je	short cfbs_retn
   781 00008089 663DE053            <1> 	cmp	ax, 53E0h
   782                              <1> cfbs_retn:
   783 0000808D C3                  <1> 	retn
   784                              <1> 
   785                              <1> show_time:
   786                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   787                              <1>         ; 2004-2005
   788                              <1> 
   789                              <1> 	;mov	ah, 02h
   790                              <1> 	;call	int1Ah
   791 0000808E E8E9E3FFFF          <1> 	call	RTC_20	; GET RTC TIME
   792                              <1> 	
   793 00008093 88E8                <1> 	mov	al, ch
   794 00008095 E82E8EFFFF          <1> 	call	bcd_to_ascii
   795 0000809A 66A3[63190100]      <1> 	mov	[Hour], ax
   796                              <1> 
   797 000080A0 88C8                <1> 	mov	al, cl
   798 000080A2 E8218EFFFF          <1> 	call	bcd_to_ascii
   799 000080A7 66A3[66190100]      <1> 	mov	[Minute], ax
   800                              <1> 
   801 000080AD 88F0                <1> 	mov	al, dh
   802 000080AF E8148EFFFF          <1> 	call	bcd_to_ascii
   803 000080B4 66A3[69190100]      <1> 	mov	[Second], ax
   804                              <1> 
   805 000080BA BE[53190100]        <1> 	mov	esi, Msg_Show_Time
   806 000080BF E861EEFFFF          <1> 	call	print_msg
   807 000080C4 C3                  <1> 	retn
   808                              <1> 
   809                              <1> set_time:
   810                              <1> 	; 13/05/2016
   811                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   812                              <1>         ; 2004-2005
   813                              <1> 
   814 000080C5 BE[42190100]        <1> 	mov 	esi, Msg_Enter_Time
   815 000080CA E856EEFFFF          <1> 	call	print_msg
   816                              <1> 
   817                              <1> loc_enter_hour_1:
   818 000080CF 30E4                <1> 	xor     ah, ah
   819 000080D1 E8FF8DFFFF          <1> 	call	int16h
   820                              <1> 	; AL = ASCII Code of the Character
   821 000080D6 3C0D                <1> 	cmp	al, 13 ; ENTER key
   822 000080D8 0F84AE010000        <1>         je      loc_set_time_retn
   823 000080DE 3C1B                <1> 	cmp	al, 27 ; ESC key
   824 000080E0 0F84A6010000        <1>         je      loc_set_time_retn
   825 000080E6 A2[63190100]        <1> 	mov	[Hour], al
   826 000080EB 3C30                <1> 	cmp	al, '0'
   827 000080ED 0F82A4010000        <1>         jb      loc_set_time_stc_0
   828 000080F3 3C32                <1> 	cmp	al, '2'
   829 000080F5 0F879C010000        <1>         ja      loc_set_time_stc_0
   830                              <1> 	; 13/05/2016
   831                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   832                              <1> 		      ; video page 0 (bh)
   833 000080FB B307                <1> 	mov	bl, 7	
   834 000080FD E8FBA0FFFF          <1> 	call	_write_tty
   835                              <1> loc_enter_hour_2:
   836 00008102 30E4                <1> 	xor     ah, ah
   837 00008104 E8CC8DFFFF          <1> 	call	int16h
   838                              <1> 	; AL = ASCII Code of the Character
   839 00008109 3C1B                <1> 	cmp	al, 27
   840 0000810B 0F847B010000        <1>         je      loc_set_time_retn
   841 00008111 A2[64190100]        <1> 	mov	[Hour+1], al
   842 00008116 3C30                <1> 	cmp	al, '0'
   843 00008118 0F8283010000        <1>         jb      loc_set_time_stc_1
   844 0000811E 3C39                <1> 	cmp	al, '9'
   845 00008120 0F877B010000        <1> 	ja	loc_set_time_stc_1
   846 00008126 803D[63190100]32    <1>         cmp     byte [Hour], '2'
   847 0000812D 7208                <1> 	jb	short pass_set_time_24
   848 0000812F 3C34                <1> 	cmp	al, '4'
   849 00008131 0F876A010000        <1>         ja      loc_set_time_stc_1
   850                              <1> pass_set_time_24:
   851                              <1> 	; 13/05/2016
   852                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   853                              <1> 		      ; video page 0 (bh)
   854 00008137 B307                <1> 	mov	bl, 7	
   855 00008139 E8BFA0FFFF          <1> 	call	_write_tty
   856                              <1> loc_enter_time_separator_1:
   857 0000813E 28E4                <1> 	sub    ah, ah ; 0
   858 00008140 E8908DFFFF          <1> 	call	int16h
   859                              <1> 	; AL = ASCII Code of the Character
   860 00008145 3C1B                <1> 	cmp	al, 27
   861 00008147 0F843F010000        <1>         je      loc_set_time_retn
   862 0000814D 3C3A                <1> 	cmp	al, ':'
   863 0000814F 0F8567010000        <1>         jne     loc_set_time_stc_2
   864                              <1> 	; 13/05/2016
   865                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   866                              <1> 		      ; video page 0 (bh)
   867 00008155 B307                <1> 	mov	bl, 7	
   868 00008157 E8A1A0FFFF          <1> 	call	_write_tty
   869                              <1> loc_enter_minute_1:
   870 0000815C 30E4                <1> 	xor     ah, ah
   871 0000815E E8728DFFFF          <1> 	call	int16h
   872                              <1> 	; AL = ASCII Code of the Character
   873 00008163 3C1B                <1> 	cmp	al, 27
   874 00008165 0F8421010000        <1>         je      loc_set_time_retn
   875 0000816B A2[66190100]        <1> 	mov	[Minute], al
   876 00008170 3C30                <1> 	cmp	al, '0'
   877 00008172 0F825F010000        <1>         jb      loc_set_time_stc_3
   878 00008178 3C35                <1> 	cmp	al, '5'
   879 0000817A 0F8757010000        <1>         ja      loc_set_time_stc_3
   880                              <1> 	; 13/05/2016
   881                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   882                              <1> 		      ; video page 0 (bh)
   883 00008180 B307                <1> 	mov	bl, 7	
   884 00008182 E876A0FFFF          <1> 	call	_write_tty
   885                              <1> loc_enter_minute_2:
   886 00008187 30E4                <1> 	xor     ah, ah
   887 00008189 E8478DFFFF          <1> 	call	int16h
   888                              <1> 	; AL = ASCII Code of the Character
   889 0000818E 3C1B                <1> 	cmp	al, 27
   890 00008190 0F84F6000000        <1>         je      loc_set_time_retn
   891 00008196 A2[67190100]        <1> 	mov	[Minute+1], al
   892 0000819B 3C30                <1> 	cmp	al, '0'
   893 0000819D 0F824F010000        <1>         jb      loc_set_time_stc_4
   894 000081A3 3C39                <1> 	cmp	al, '9'
   895 000081A5 0F8747010000        <1>         ja      loc_set_time_stc_4
   896                              <1> 	; 13/05/2016
   897                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   898                              <1> 		      ; video page 0 (bh)
   899 000081AB B307                <1> 	mov	bl, 7	
   900 000081AD E84BA0FFFF          <1> 	call	_write_tty
   901                              <1> loc_enter_time_separator_2:
   902 000081B2 66C705[69190100]30- <1> 	mov	word [Second], 3030h
   902 000081BA 30                  <1>
   903 000081BB 28E4                <1> 	sub     ah, ah
   904 000081BD E8138DFFFF          <1> 	call	int16h
   905                              <1> 	; AL = ASCII Code of the Character
   906 000081C2 3C0D                <1> 	cmp	al, 13
   907 000081C4 0F8485000000        <1>         je      loc_set_time_progress
   908 000081CA 3C1B                <1> 	cmp	al, 27
   909 000081CC 0F84BA000000        <1>         je      loc_set_time_retn
   910 000081D2 3C3A                <1> 	cmp	al, ':'
   911 000081D4 0F8533010000        <1>         jne     loc_set_time_stc_5
   912                              <1> 	; 13/05/2016
   913                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   914                              <1> 		      ; video page 0 (bh)
   915 000081DA B307                <1> 	mov	bl, 7	
   916 000081DC E81CA0FFFF          <1> 	call	_write_tty
   917                              <1> loc_enter_second_1:
   918 000081E1 30E4                <1> 	xor     ah, ah
   919 000081E3 E8ED8CFFFF          <1> 	call	int16h
   920                              <1> 	; AL = ASCII Code of the Character
   921 000081E8 3C0D                <1> 	cmp	al, 13
   922 000081EA 7463                <1> 	je	short loc_set_time_progress
   923 000081EC 3C1B                <1> 	cmp	al, 27
   924 000081EE 0F8498000000        <1>         je      loc_set_time_retn
   925 000081F4 A2[69190100]        <1> 	mov	[Second], al
   926 000081F9 3C30                <1> 	cmp	al, '0'
   927 000081FB 0F8227010000        <1>         jb      loc_set_time_stc_6
   928 00008201 3C35                <1> 	cmp	al, '5'
   929 00008203 0F871F010000        <1>         ja      loc_set_time_stc_6
   930                              <1> 	; 13/05/2016
   931                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   932                              <1> 		      ; video page 0 (bh)
   933 00008209 B307                <1> 	mov	bl, 7	
   934 0000820B E8ED9FFFFF          <1> 	call	_write_tty
   935                              <1> loc_enter_second_2:
   936 00008210 30E4                <1> 	xor     ah, ah
   937 00008212 E8BE8CFFFF          <1> 	call	int16h
   938                              <1> 	; AL = ASCII Code of the Character
   939 00008217 3C1B                <1> 	cmp	al, 27
   940 00008219 7471                <1> 	je	short loc_set_time_retn
   941 0000821B 3C30                <1> 	cmp	al, '0'
   942 0000821D 0F8229010000        <1>         jb      loc_set_time_stc_7
   943 00008223 3C39                <1> 	cmp	al, '9'
   944 00008225 0F8721010000        <1>         ja      loc_set_time_stc_7
   945                              <1> 	; 13/05/2016
   946                              <1> 	;mov	bx, 7 ; attribute/color (bl)
   947                              <1> 		      ; video page 0 (bh)
   948 0000822B B307                <1> 	mov	bl, 7	
   949 0000822D E8CB9FFFFF          <1> 	call	_write_tty
   950                              <1> loc_set_time_get_lchar_again:
   951 00008232 28E4                <1> 	sub	ah, ah ; 0
   952 00008234 E89C8CFFFF          <1> 	call	int16h
   953                              <1> 	; AL = ASCII Code of the Character
   954 00008239 3C0D                <1> 	cmp	al, 13
   955 0000823B 7412                <1> 	je	short loc_set_time_progress
   956 0000823D 3C1B                <1> 	cmp	al, 27
   957 0000823F 744B                <1> 	je	short loc_set_time_retn
   958                              <1> 	;
   959 00008241 E831FEFFFF          <1> 	call	check_for_backspace
   960 00008246 75EA                <1> 	jne	short loc_set_time_get_lchar_again
   961                              <1> 
   962                              <1> loc_set_time_bs_8:
   963 00008248 E818FEFFFF          <1> 	call	write_backspace
   964 0000824D EBC1                <1> 	jmp	short loc_enter_second_2
   965                              <1> 
   966                              <1> loc_set_time_progress:
   967                              <1> 	; Get Current Time
   968                              <1> 	;mov 	ah, 02h
   969                              <1> 	;call	int1Ah
   970 0000824F E828E2FFFF          <1> 	call	RTC_20	; GET RTC TIME
   971                              <1> 	;DL = Daylight Savings Enable option (0-1)	
   972                              <1> 
   973 00008254 66A1[63190100]      <1> 	mov	ax, [Hour]
   974 0000825A 662D3030            <1> 	sub	ax, '00'
   975 0000825E C0E004              <1> 	shl	al, 4 ; * 16
   976 00008261 88C5                <1> 	mov	ch, al
   977 00008263 00E5                <1> 	add	ch, ah
   978 00008265 66A1[66190100]      <1> 	mov	ax, [Minute]
   979 0000826B 662D3030            <1> 	sub	ax, '00'
   980 0000826F C0E004              <1> 	shl	al, 4 ; * 16
   981 00008272 88C1                <1> 	mov	cl, al
   982 00008274 00E1                <1> 	add	cl, ah
   983 00008276 66A1[69190100]      <1> 	mov	ax, [Second]
   984 0000827C 662D3030            <1> 	sub	ax, '00'
   985 00008280 C0E004              <1> 	shl	al, 4 ; * 16
   986 00008283 88C6                <1> 	mov	dh, al
   987 00008285 00E6                <1> 	add	dh, ah
   988                              <1> 	
   989                              <1> 	;mov	ah, 03h
   990                              <1> 	;call	int1Ah
   991 00008287 E81FE2FFFF          <1> 	call	RTC_30	; SET RTC TIME
   992                              <1> 
   993                              <1> loc_set_time_retn:
   994 0000828C BE[93240100]        <1> 	mov 	esi, nextline
   995 00008291 E88FECFFFF          <1> 	call	print_msg
   996 00008296 C3                  <1> 	retn
   997                              <1> 
   998                              <1> loc_set_time_stc_0:
   999                              <1> 	;xor	bh, bh ; video page 0
  1000 00008297 E845A0FFFF          <1> 	call	beeper ; BEEP !
  1001 0000829C E92EFEFFFF          <1>         jmp     loc_enter_hour_1
  1002                              <1> loc_set_time_stc_1:
  1003 000082A1 E8D1FDFFFF          <1> 	call	check_for_backspace
  1004 000082A6 740A                <1> 	je	short loc_set_time_bs_1
  1005                              <1> 	;xor	bh, bh ; video page 0
  1006 000082A8 E834A0FFFF          <1> 	call	beeper ; BEEP !
  1007 000082AD E950FEFFFF          <1>         jmp     loc_enter_hour_2
  1008                              <1> loc_set_time_bs_1:
  1009 000082B2 E8AEFDFFFF          <1> 	call	write_backspace
  1010 000082B7 E913FEFFFF          <1>         jmp     loc_enter_hour_1
  1011                              <1> loc_set_time_stc_2:
  1012 000082BC E8B6FDFFFF          <1> 	call	check_for_backspace
  1013 000082C1 740A                <1> 	je	short loc_set_time_bs_2
  1014                              <1> 	;xor	bh, bh ; video page 0
  1015 000082C3 E819A0FFFF          <1> 	call	beeper ; BEEP !
  1016 000082C8 E971FEFFFF          <1>         jmp     loc_enter_time_separator_1
  1017                              <1> loc_set_time_bs_2:
  1018 000082CD E893FDFFFF          <1> 	call	write_backspace
  1019 000082D2 E92BFEFFFF          <1>         jmp     loc_enter_hour_2
  1020                              <1> loc_set_time_stc_3:
  1021 000082D7 E89BFDFFFF          <1> 	call	check_for_backspace
  1022 000082DC 740A                <1> 	je	short loc_set_time_bs_3
  1023                              <1> 	;xor	bh, bh ; video page 0
  1024 000082DE E8FE9FFFFF          <1> 	call	beeper ; BEEP !6
  1025 000082E3 E974FEFFFF          <1>         jmp     loc_enter_minute_1
  1026                              <1> loc_set_time_bs_3:
  1027 000082E8 E878FDFFFF          <1> 	call	write_backspace
  1028 000082ED E94CFEFFFF          <1>         jmp     loc_enter_time_separator_1
  1029                              <1> loc_set_time_stc_4:
  1030 000082F2 E880FDFFFF          <1> 	call	check_for_backspace
  1031 000082F7 740A                <1> 	je	short loc_set_time_bs_4
  1032                              <1> 	;xor	bh, bh ; video page 0
  1033 000082F9 E8E39FFFFF          <1> 	call	beeper ; BEEP !
  1034 000082FE E984FEFFFF          <1>         jmp     loc_enter_minute_2
  1035                              <1> loc_set_time_bs_4:
  1036 00008303 E85DFDFFFF          <1> 	call	write_backspace
  1037 00008308 E94FFEFFFF          <1>         jmp     loc_enter_minute_1
  1038                              <1> loc_set_time_stc_5:
  1039 0000830D E865FDFFFF          <1> 	call	check_for_backspace
  1040 00008312 740A                <1> 	je	short loc_set_time_bs_5
  1041                              <1> 	;xor	bh, bh ; video page 0
  1042 00008314 E8C89FFFFF          <1> 	call	beeper ; BEEP !
  1043 00008319 E994FEFFFF          <1>         jmp     loc_enter_time_separator_2
  1044                              <1> loc_set_time_bs_5:
  1045 0000831E E842FDFFFF          <1> 	call	write_backspace
  1046 00008323 E95FFEFFFF          <1>         jmp     loc_enter_minute_2
  1047                              <1> loc_set_time_stc_6:
  1048 00008328 E84AFDFFFF          <1> 	call	check_for_backspace
  1049 0000832D 7413                <1> 	je	short loc_set_time_bs_6
  1050                              <1> 	;xor	bh, bh ; video page 0
  1051 0000832F E8AD9FFFFF          <1> 	call	beeper ; BEEP !
  1052 00008334 66C705[69190100]30- <1> 	mov	word [Second], 3030h
  1052 0000833C 30                  <1>
  1053 0000833D E99FFEFFFF          <1>         jmp     loc_enter_second_1
  1054                              <1> loc_set_time_bs_6:
  1055 00008342 E81EFDFFFF          <1> 	call	write_backspace
  1056 00008347 E966FEFFFF          <1>         jmp     loc_enter_time_separator_2
  1057                              <1> loc_set_time_stc_7:
  1058 0000834C E826FDFFFF          <1> 	call	check_for_backspace
  1059 00008351 740A                <1> 	je	short loc_set_time_bs_7
  1060                              <1> 	;xor	bh, bh ; video page 0
  1061 00008353 E8899FFFFF          <1> 	call	beeper ; BEEP !
  1062 00008358 E9B3FEFFFF          <1>         jmp     loc_enter_second_2
  1063                              <1> loc_set_time_bs_7:
  1064 0000835D E803FDFFFF          <1> 	call	write_backspace
  1065 00008362 E97AFEFFFF          <1>         jmp     loc_enter_second_1
  1066                              <1> 
  1067                              <1> print_volume_info:
  1068                              <1> 	; 01/03/2016
  1069                              <1> 	; 08/02/2016
  1070                              <1> 	; 06/02/2016
  1071                              <1> 	; 04/02/2016
  1072                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
  1073                              <1> 	; 25/10/2009
  1074                              <1> 	;
  1075                              <1> 	; "Volume Serial No: "
  1076                              <1>  	;
  1077                              <1> 	; INPUT  : AL = DOS Drive Number
  1078                              <1> 	; OUTPUT : AH = FS Type
  1079                              <1> 	;          AL = DOS Drive Name
  1080                              <1> 	; CF = 0 -> OK
  1081                              <1> 	; CF = 1 -> Drive not ready 
  1082                              <1> 
  1083 00008367 88C4                <1> 	mov	ah, al
  1084 00008369 28C0                <1> 	sub	al, al
  1085 0000836B 0FB7F0              <1> 	movzx	esi, ax	
  1086 0000836E 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1087 00008374 8A06                <1> 	mov	al, [esi]
  1088 00008376 3C41                <1> 	cmp	al, 'A'  
  1089 00008378 7304                <1> 	jnb	short loc_pvi_set_vol_name
  1090 0000837A 8A6604              <1> 	mov	ah, [esi+LD_FSType]
  1091 0000837D C3                  <1> 	retn
  1092                              <1> 
  1093                              <1> loc_pvi_set_vol_name:
  1094 0000837E A2[9D190100]        <1> 	mov	[Vol_Drv_Name], al
  1095 00008383 56                  <1> 	push	esi
  1096 00008384 E858010000          <1> 	call	move_volume_name_and_serial_no ;;;
  1097 00008389 7302                <1> 	jnc	short loc_pvi_mvn_ok
  1098 0000838B 5E                  <1> 	pop	esi
  1099 0000838C C3                  <1> 	retn
  1100                              <1> 
  1101                              <1> loc_pvi_mvn_ok:
  1102 0000838D 8B3424              <1> 	mov	esi, [esp]
  1103 00008390 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  1104 00008394 7509                <1> 	jne	short loc_pvi_fat_vol_size
  1105 00008396 8B4670              <1> 	mov	eax, [esi+LD_FS_VolumeSize]
  1106 00008399 0FB75E11            <1> 	movzx	ebx, word [esi+LD_FS_BytesPerSec]
  1107 0000839D EB07                <1> 	jmp	short loc_vol_size_mul32
  1108                              <1> loc_pvi_fat_vol_size:
  1109 0000839F 8B4670              <1> 	mov	eax, [esi+LD_TotalSectors]
  1110 000083A2 0FB75E11            <1> 	movzx	ebx, word [esi+LD_BPB+BPB_BytsPerSec]
  1111                              <1> loc_vol_size_mul32:
  1112 000083A6 F7E3                <1> 	mul	ebx
  1113 000083A8 09D2                <1> 	or	edx, edx
  1114 000083AA 7507                <1> 	jnz	short loc_vol_size_in_kbytes
  1115                              <1> loc_vol_size_in_bytes:
  1116 000083AC B9[7B190100]        <1> 	mov	ecx, VolSize_Bytes
  1117 000083B1 EB0D                <1> 	jmp	short loc_write_vol_size_str
  1118                              <1> loc_vol_size_in_kbytes:
  1119 000083B3 66BB0004            <1> 	mov	bx, 1024
  1120 000083B7 F7F3                <1> 	div	ebx
  1121 000083B9 B9[6E190100]        <1> 	mov 	ecx, VolSize_KiloBytes
  1122 000083BE 31D2                <1> 	xor	edx, edx ; 0
  1123                              <1> loc_write_vol_size_str:
  1124 000083C0 890D[D36B0100]      <1> 	mov	[VolSize_Unit1], ecx
  1125                              <1> 	; 
  1126 000083C6 BF[E96B0100]        <1> 	mov	edi, Vol_Tot_Sec_Str_End
  1127                              <1>         ;mov	byte [edi], 0
  1128 000083CB B90A000000          <1> 	mov	ecx, 10
  1129                              <1> loc_write_vol_size_chr:
  1130 000083D0 F7F1                <1> 	div	ecx
  1131 000083D2 80C230              <1> 	add	dl, '0'
  1132 000083D5 4F                  <1> 	dec	edi	
  1133 000083D6 8817                <1> 	mov	[edi], dl
  1134 000083D8 85C0                <1> 	test	eax, eax
  1135 000083DA 7404                <1> 	jz	short loc_write_vol_size_str_ok
  1136 000083DC 28D2                <1> 	sub	dl, dl ; 0
  1137 000083DE EBF0                <1> 	jmp	short loc_write_vol_size_chr
  1138                              <1> 
  1139                              <1> loc_write_vol_size_str_ok:
  1140 000083E0 893D[DB6B0100]      <1> 	mov	[Vol_Tot_Sec_Str_Start], edi
  1141                              <1> 	;
  1142 000083E6 BF[86190100]        <1> 	mov	edi, Vol_FS_Name
  1143 000083EB 8A4E03              <1> 	mov	cl, [esi+LD_FATType]
  1144 000083EE 20C9                <1> 	and	cl, cl ; 0 ?
  1145 000083F0 7515                <1> 	jnz	short loc_write_vol_FAT_str_1
  1146 000083F2 66C7075452          <1> 	mov	word [edi], 'TR'
  1147 000083F7 C7470420465331      <1> 	mov	dword [edi+4], ' FS1'
  1148                              <1> 	;movzx	ebx, word [esi+LD_FS_BytesPerSec]
  1149 000083FE 668B5E11            <1> 	mov	bx, [esi+LD_FS_BytesPerSec]
  1150 00008402 8B4674              <1> 	mov	eax, [esi+LD_FS_FreeSectors]
  1151 00008405 EB36                <1> 	jmp	short loc_vol_freespace_mul32
  1152                              <1> 
  1153                              <1> loc_write_vol_FAT_str_1:
  1154 00008407 66B83332            <1> 	mov	ax, '32' ; FAT32
  1155 0000840B 80F902              <1> 	cmp	cl, 2 ; [esi+LD_FATType]
  1156 0000840E 7708                <1> 	ja	short loc_write_vol_FAT_str_2
  1157 00008410 66B83132            <1> 	mov	ax, '12' ; FAT12
  1158 00008414 7202                <1> 	jb	short loc_write_vol_FAT_str_2
  1159 00008416 B436                <1> 	mov	ah, '6'  ; FAT16
  1160                              <1> loc_write_vol_FAT_str_2:
  1161 00008418 C70746415420        <1> 	mov	dword [edi], 'FAT '
  1162 0000841E 66894704            <1> 	mov	word [edi+4], ax
  1163                              <1> 	;
  1164                              <1> 	;movzx	ebx, word [esi+LD_BPB+BPB_BytsPerSec]
  1165 00008422 668B5E11            <1> 	mov	bx, [esi+LD_BPB+BPB_BytsPerSec]
  1166 00008426 8B4674              <1> 	mov	eax, [esi+LD_FreeSectors]
  1167                              <1> 
  1168                              <1> loc_vol_freespace_recalc0:
  1169                              <1> 	; 01/03/2016
  1170 00008429 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh
  1171 0000842C 720F                <1> 	jb	short loc_vol_freespace_mul32
  1172                              <1> 	;inc	eax ; 0
  1173 0000842E 20C9                <1> 	and	cl, cl ; byte [esi+LD_FATType]
  1174 00008430 740B                <1> 	jz	short loc_vol_freespace_mul32 	
  1175 00008432 53                  <1> 	push	ebx
  1176 00008433 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free sectors
  1177 00008437 E876490000          <1> 	call	calculate_fat_freespace
  1178 0000843C 5B                  <1> 	pop	ebx
  1179                              <1> 
  1180                              <1> loc_vol_freespace_mul32:
  1181 0000843D F7E3                <1> 	mul	ebx
  1182 0000843F 09D2                <1> 	or	edx, edx
  1183 00008441 7507                <1> 	jnz	short loc_vol_fspace_in_kbytes
  1184                              <1> loc_vol_fspace_in_bytes:
  1185 00008443 B9[7B190100]        <1> 	mov	ecx, VolSize_Bytes
  1186 00008448 EB0D                <1> 	jmp	short loc_write_vol_fspace_str
  1187                              <1> loc_vol_fspace_in_kbytes:
  1188 0000844A 66BB0004            <1> 	mov	bx, 1024
  1189 0000844E F7F3                <1> 	div	ebx
  1190 00008450 B9[6E190100]        <1> 	mov 	ecx, VolSize_KiloBytes
  1191 00008455 31D2                <1> 	xor	edx, edx ; 0
  1192                              <1> loc_write_vol_fspace_str:
  1193 00008457 890D[D76B0100]      <1> 	mov	[VolSize_Unit2], ecx
  1194                              <1> 	;	
  1195 0000845D BF[F96B0100]        <1> 	mov	edi, Vol_Free_Sectors_Str_End
  1196                              <1>         ;mov	byte [edi], 0
  1197 00008462 B90A000000          <1> 	mov	ecx, 10
  1198                              <1> loc_write_vol_fspace_chr:
  1199 00008467 F7F1                <1> 	div	ecx
  1200 00008469 80C230              <1> 	add	dl, '0'
  1201 0000846C 4F                  <1> 	dec	edi	
  1202 0000846D 8817                <1> 	mov	[edi], dl
  1203 0000846F 85C0                <1> 	test	eax, eax
  1204 00008471 7404                <1> 	jz	short loc_write_vol_fspace_str_ok
  1205 00008473 28D2                <1> 	sub	dl, dl ; 0
  1206 00008475 EBF0                <1> 	jmp	short loc_write_vol_fspace_chr
  1207                              <1> 
  1208                              <1> loc_write_vol_fspace_str_ok:
  1209 00008477 893D[EB6B0100]      <1> 	mov	[Vol_Free_Sectors_Str_Start], edi
  1210                              <1> 	;
  1211 0000847D BE[84190100]        <1> 	mov	esi, Volume_in_drive
  1212 00008482 E89EEAFFFF          <1> 	call	print_msg
  1213 00008487 BE[C4190100]        <1> 	mov	esi, Vol_Name
  1214 0000848C E894EAFFFF          <1> 	call	print_msg
  1215 00008491 BE[93240100]        <1> 	mov	esi, nextline
  1216 00008496 E88AEAFFFF          <1> 	call	print_msg
  1217                              <1> 	;
  1218 0000849B BE[251A0100]        <1> 	mov	esi, Vol_Total_Sector_Header
  1219 000084A0 E880EAFFFF          <1> 	call	print_msg
  1220 000084A5 8B35[DB6B0100]      <1> 	mov	esi, [Vol_Tot_Sec_Str_Start]
  1221 000084AB E875EAFFFF          <1> 	call	print_msg
  1222 000084B0 8B35[D36B0100]      <1> 	mov	esi, [VolSize_Unit1]
  1223 000084B6 E86AEAFFFF          <1> 	call	print_msg
  1224                              <1> 	;
  1225 000084BB BE[361A0100]        <1> 	mov	esi, Vol_Free_Sectors_Header
  1226 000084C0 E860EAFFFF          <1> 	call	print_msg
  1227 000084C5 8B35[EB6B0100]      <1> 	mov	esi, [Vol_Free_Sectors_Str_Start]
  1228 000084CB E855EAFFFF          <1> 	call	print_msg
  1229 000084D0 8B35[D76B0100]      <1> 	mov	esi, [VolSize_Unit2]
  1230 000084D6 E84AEAFFFF          <1> 	call	print_msg
  1231                              <1> 	;
  1232 000084DB 5E                  <1> 	pop	esi
  1233                              <1> 	
  1234                              <1> 	;mov	ah, [esi+LD_FSType]
  1235                              <1> 	;mov	al, [esi+LD_FATType]
  1236 000084DC 668B4603            <1> 	mov	ax, [esi+LD_FATType]
  1237                              <1> 
  1238 000084E0 C3                  <1> 	retn
  1239                              <1> 
  1240                              <1> move_volume_name_and_serial_no:
  1241                              <1> 	; 08/02/2016  (TRDOS 386 = TRDOS v2.0)
  1242                              <1> 	; this routine will be called by
  1243                              <1> 	; "print_volume_info" and "print_directory"
  1244                              <1> 	; INPUT ->
  1245                              <1> 	;	ESI = Logical DOS drv descripton table address
  1246                              <1> 	; OUTPUT ->
  1247                              <1> 	;	*Volume name will be moved to text area
  1248                              <1> 	;	*Volume serial number will be converted to
  1249                              <1> 	;	 text and will be moved to text area
  1250                              <1> 	;   cf = 1 -> invalid/unknown dos drive
  1251                              <1> 	;   cf = 0 -> ecx = 0
  1252                              <1> 	;
  1253                              <1> 	; (eax, edx, ecx, esi, edi will be changed)
  1254                              <1> 
  1255 000084E1 BF[C4190100]        <1> 	mov 	edi, Vol_Name
  1256                              <1> 
  1257                              <1> 	;mov	ah, [esi+LD_FSType]
  1258                              <1> 	;mov	al, [esi+LD_FATType]
  1259 000084E6 668B4603            <1> 	mov	ax, [esi+LD_FATType]
  1260 000084EA 80FCA1              <1> 	cmp	ah, 0A1h
  1261 000084ED 7418                <1> 	je	short mvn_2
  1262 000084EF 08E4                <1> 	or	ah, ah
  1263 000084F1 7404                <1> 	jz	short mvn_0
  1264 000084F3 08C0                <1> 	or	al, al
  1265 000084F5 7504                <1> 	jnz	short mvn_1
  1266                              <1> mvn_0:
  1267 000084F7 8A06                <1> 	mov	al, [esi]
  1268 000084F9 F9                  <1> 	stc
  1269 000084FA C3                  <1> 	retn
  1270                              <1> mvn_1:
  1271 000084FB 3C02                <1> 	cmp	al, 2
  1272 000084FD 7717                <1> 	ja	short mvn_3 
  1273                              <1> 	;or	al, al
  1274                              <1> 	;jz	short mvn_2
  1275 000084FF 8B462D              <1> 	mov	eax, [esi+LD_BPB+VolumeID]
  1276 00008502 83C631              <1> 	add	esi, LD_BPB+VolumeLabel
  1277 00008505 EB15                <1> 	jmp	short mvn_4
  1278                              <1> mvn_2:
  1279 00008507 8B4628              <1> 	mov	eax, [esi+LD_FS_VolumeSerial]
  1280 0000850A 83C62C              <1> 	add	esi, LD_FS_VolumeName
  1281 0000850D B910000000          <1> 	mov	ecx, 16
  1282 00008512 F3A5                <1> 	rep	movsd
  1283 00008514 EB10                <1> 	jmp	short mvn_5
  1284                              <1> mvn_3:
  1285 00008516 8B4649              <1> 	mov	eax, [esi+LD_BPB+FAT32_VolID]
  1286 00008519 83C64D              <1> 	add	esi, LD_BPB+FAT32_VolLab
  1287                              <1> mvn_4:
  1288 0000851C B90B000000          <1> 	mov	ecx, 11
  1289 00008521 F3A4                <1> 	rep	movsb
  1290 00008523 C60700              <1> 	mov	byte [edi], 0
  1291                              <1> mvn_5:
  1292                              <1> 	;mov	[Current_VolSerial], eax  
  1293 00008526 E8B4B7FFFF          <1> 	call	dwordtohex
  1294 0000852B 8915[191A0100]      <1> 	mov	[Vol_Serial1], edx
  1295 00008531 A3[1E1A0100]        <1> 	mov	[Vol_Serial2], eax
  1296                              <1> 	; ecx = 0
  1297 00008536 C3                  <1> 	retn
  1298                              <1> 
  1299                              <1> get_volume_serial_number:
  1300                              <1> 	; 19/01/2016 (TRDOS 386 = TRDOS v2.0)
  1301                              <1> 	; 08/08/2010
  1302                              <1> 	;
  1303                              <1> 	; INPUT -> DL = Logical DOS Drive number
  1304                              <1> 	; OUTPUT -> EAX = Volume serial number
  1305                              <1> 	;          BL= FAT Type	    
  1306                              <1> 	;          BH = Logical DOS drv Number (DL input)
  1307                              <1> 	; cf = 1 -> Drive not ready
  1308                              <1> 
  1309 00008537 31DB                <1> 	xor	ebx, ebx
  1310 00008539 88D7                <1> 	mov	bh, dl
  1311 0000853B 3815[F5170100]      <1> 	cmp	[Last_DOS_DiskNo], dl
  1312 00008541 7304                <1> 	jnb	short loc_gvsn_start
  1313                              <1> loc_gvsn_stc_retn:
  1314 00008543 31C0                <1> 	xor	eax, eax
  1315 00008545 F9                  <1> 	stc 
  1316 00008546 C3                  <1>         retn 
  1317                              <1> loc_gvsn_start:
  1318 00008547 56                  <1> 	push	esi
  1319 00008548 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1320 0000854D 01DE                <1> 	add	esi, ebx
  1321 0000854F 8A5E03              <1> 	mov	bl, [esi+LD_FATType]
  1322 00008552 20DB                <1> 	and	bl, bl
  1323 00008554 740F                <1> 	jz	short loc_gvsn_fs
  1324 00008556 80FB02              <1> 	cmp	bl, 2
  1325 00008559 7705                <1> 	ja	short loc_gvsn_fat32
  1326                              <1> loc_gvsn_fat:
  1327 0000855B 83C62D              <1> 	add	esi, LD_BPB + VolumeID
  1328 0000855E EB0E                <1> 	jmp	short loc_gvsn_return
  1329                              <1> loc_gvsn_fat32: 
  1330 00008560 83C649              <1> 	add	esi, LD_BPB + FAT32_VolID
  1331 00008563 EB09                <1> 	jmp	short loc_gvsn_return 
  1332                              <1> loc_gvsn_fs:
  1333 00008565 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  1334 00008569 75D8                <1> 	jne	short loc_gvsn_stc_retn 
  1335 0000856B 83C628              <1> 	add	esi, LD_FS_VolumeSerial
  1336                              <1> loc_gvsn_return:
  1337 0000856E 8B06                <1> 	mov	eax, [esi]
  1338 00008570 5E                  <1> 	pop	esi
  1339 00008571 C3                  <1> 	retn
  1340                              <1> 
  1341                              <1> ; CMD_INTR.ASM [ TRDOS Command Interpreter Procedure ]
  1342                              <1> ; 09/11/2011
  1343                              <1> ; 29/01/2005
  1344                              <1> 
  1345                              <1> command_interpreter:
  1346                              <1> 	; 16/10/2016
  1347                              <1> 	; 12/10/2016
  1348                              <1> 	; 13/05/2016
  1349                              <1> 	; 07/05/2016
  1350                              <1> 	; 04/03/2016
  1351                              <1> 	; 04/02/2016
  1352                              <1> 	; 03/02/2016
  1353                              <1> 	; 30/01/2016
  1354                              <1> 	; 29/01/2016 (TRDOS 386 = TRDOS 2.0)
  1355                              <1> 	; 15/09/2011         
  1356                              <1> 	; 29/01/2005
  1357                              <1>         
  1358                              <1> 	; Input: ecx = command word length (CL)
  1359                              <1> 	;	 CommandBuffer = Command string offset
  1360                              <1>  
  1361 00008572 C605[8C6C0100]00    <1> 	mov	byte [Program_Exit],0
  1362 00008579 80F904              <1> 	cmp	cl, 4
  1363 0000857C 0F87B5020000        <1>         ja      c_6
  1364 00008582 0F8237010000        <1>         jb      c_2
  1365                              <1> c_4:
  1366                              <1> 
  1367                              <1> cmp_cmd_exit:
  1368 00008588 BF[63180100]        <1> 	mov	edi, Cmd_Exit
  1369 0000858D E8C2030000          <1> 	call	cmp_cmd	
  1370 00008592 7208                <1> 	jc	short cmp_cmd_date
  1371                              <1> 
  1372 00008594 C605[8C6C0100]01    <1>         mov     byte [Program_Exit], 1
  1373 0000859B C3                  <1>         retn
  1374                              <1> 
  1375                              <1> cmp_cmd_date:
  1376 0000859C B104                <1> 	mov	cl, 4
  1377 0000859E BF[7F180100]        <1> 	mov	edi, Cmd_Date
  1378 000085A3 E8AC030000          <1> 	call	cmp_cmd	
  1379 000085A8 720B                <1>         jc	short cmp_cmd_time
  1380                              <1> 	
  1381 000085AA E8D0F7FFFF          <1> 	call	show_date
  1382 000085AF E80FF8FFFF          <1> 	call	set_date
  1383 000085B4 C3                  <1> 	retn
  1384                              <1> 
  1385                              <1> cmp_cmd_time:
  1386 000085B5 B104                <1> 	mov	cl, 4
  1387 000085B7 BF[84180100]        <1> 	mov	edi, Cmd_Time
  1388 000085BC E893030000          <1>    	call	cmp_cmd	
  1389 000085C1 720B                <1> 	jc	short cmp_cmd_show
  1390                              <1> 
  1391 000085C3 E8C6FAFFFF          <1> 	call	show_time
  1392 000085C8 E8F8FAFFFF          <1> 	call	set_time
  1393 000085CD C3                  <1> 	retn
  1394                              <1> 
  1395                              <1> cmp_cmd_show:
  1396 000085CE B104                <1> 	mov	cl, 4
  1397 000085D0 BF[95180100]        <1> 	mov	edi, Cmd_Show
  1398 000085D5 E87A030000          <1>    	call	cmp_cmd	
  1399 000085DA 0F83050A0000        <1>         jnc     show_file
  1400                              <1> 
  1401                              <1> cmp_cmd_echo:
  1402 000085E0 B104                <1> 	mov	cl, 4
  1403 000085E2 BF[D1180100]        <1> 	mov	edi, Cmd_Echo
  1404 000085E7 E868030000          <1>    	call	cmp_cmd	
  1405 000085EC 7224                <1> 	jc	short cmp_cmd_copy
  1406                              <1> 	
  1407                              <1> 	; 22/11/2017
  1408                              <1> 	; AL = 0
  1409 000085EE 803E20              <1> 	cmp	byte [esi], 20h
  1410 000085F1 7215                <1> 	jb	short cmd_echo_nextline
  1411                              <1> 	; 14/04/2016
  1412 000085F3 56                  <1> 	push	esi
  1413                              <1> cmd_echo_asciiz:
  1414                              <1> 	;inc	esi
  1415                              <1> 	;mov	al, [esi]
  1416                              <1> 	; 22/11/2017
  1417 000085F4 AC                  <1> 	lodsb
  1418 000085F5 3C20                <1> 	cmp	al, 20h
  1419 000085F7 73FB                <1> 	jnb	short cmd_echo_asciiz
  1420 000085F9 4E                  <1> 	dec	esi
  1421 000085FA C60600              <1> 	mov	byte [esi], 0
  1422 000085FD 5E                  <1> 	pop	esi
  1423 000085FE 89F7                <1> 	mov	edi, esi
  1424 00008600 E820E9FFFF          <1> 	call	print_msg
  1425 00008605 C60700              <1> 	mov	byte [edi], 0	
  1426                              <1> cmd_echo_nextline:
  1427 00008608 BE[01250100]        <1> 	mov	esi, NextLine
  1428                              <1> 	;call	print_msg   
  1429                              <1> 	;retn
  1430 0000860D E913E9FFFF          <1> 	jmp	print_msg
  1431                              <1> 
  1432                              <1> cmp_cmd_copy:
  1433 00008612 B104                <1> 	mov	cl, 4
  1434 00008614 BF[B8180100]        <1> 	mov	edi, Cmd_Copy
  1435 00008619 E836030000          <1>    	call	cmp_cmd	
  1436 0000861E 0F83CC170000        <1> 	jnc	copy_file
  1437                              <1> 
  1438                              <1> cmp_cmd_move:
  1439 00008624 B104                <1> 	mov	cl, 4
  1440 00008626 BF[BD180100]        <1> 	mov	edi, Cmd_Move
  1441 0000862B E824030000          <1>    	call	cmp_cmd	
  1442 00008630 0F836E160000        <1> 	jnc	move_file
  1443                              <1> 
  1444                              <1> cmp_cmd_path:
  1445 00008636 B104                <1> 	mov	cl, 4
  1446 00008638 BF[C2180100]        <1> 	mov	edi, Cmd_Path
  1447 0000863D E812030000          <1>    	call	cmp_cmd	
  1448 00008642 0F83F0190000        <1> 	jnc	set_get_path
  1449                              <1> 
  1450                              <1> cmp_cmd_beep:
  1451 00008648 B104                <1> 	mov	cl, 4
  1452 0000864A BF[EF180100]        <1> 	mov	edi, Cmd_Beep
  1453 0000864F E800030000          <1>    	call	cmp_cmd	
  1454 00008654 720B                <1> 	jc	short cmp_cmd_find
  1455                              <1> 	; 13/05/2016
  1456 00008656 8A3D[06640100]      <1> 	mov	bh, [ptty] ; [ACTIVE_PAGE]
  1457 0000865C E9809CFFFF          <1> 	jmp	beeper
  1458                              <1> 
  1459                              <1> cmp_cmd_find:
  1460 00008661 B104                <1> 	mov	cl, 4
  1461 00008663 BF[CC180100]        <1> 	mov	edi, Cmd_Find
  1462 00008668 E8E7020000          <1>    	call	cmp_cmd	
  1463 0000866D 0F82C4020000        <1>         jc      cmp_cmd_external
  1464                              <1> 
  1465                              <1> 	;call	find_and_list_files
  1466 00008673 E9AF220000          <1> 	jmp	find_and_list_files
  1467                              <1> 	;retn
  1468                              <1> 
  1469                              <1> c_1:
  1470 00008678 AD                  <1> 	lodsd
  1471                              <1> cmp_cmd_help:
  1472 00008679 3C3F                <1> 	cmp	al, '?'
  1473 0000867B 751D                <1>         jne     short cmp_cmd_remark
  1474                              <1> 
  1475 0000867D BE[55180100]        <1> 	mov	esi, Command_List
  1476                              <1> cmd_help_next_w:
  1477 00008682 E89EE8FFFF          <1> 	call	print_msg
  1478                              <1> 
  1479 00008687 803E20              <1> 	cmp	byte [esi], 20h ; 0
  1480 0000868A 7232                <1> 	jb	short cmd_help_retn
  1481                              <1> 	
  1482 0000868C 56                  <1> 	push	esi
  1483 0000868D BE[93240100]        <1> 	mov	esi, nextline
  1484 00008692 E88EE8FFFF          <1> 	call	print_msg
  1485 00008697 5E                  <1> 	pop	esi
  1486 00008698 EBE8                <1> 	jmp	short cmd_help_next_w	
  1487                              <1> 
  1488                              <1> cmp_cmd_remark:
  1489 0000869A 3C2A                <1> 	cmp	al, '*'
  1490 0000869C 0F8595020000        <1>         jne     cmp_cmd_external
  1491 000086A2 46                  <1> 	inc	esi
  1492 000086A3 BF[00650100]        <1> 	mov	edi, Remark
  1493 000086A8 8A06                <1> 	mov	al, [esi]
  1494 000086AA 3C20                <1> 	cmp	al, 20h
  1495 000086AC 7707                <1> 	ja	short cmd_remark_write
  1496 000086AE 89FE                <1> 	mov	esi, edi ; Remark
  1497 000086B0 E970E8FFFF          <1> 	jmp	print_msg
  1498                              <1> 
  1499                              <1> cmd_remark_write:
  1500 000086B5 AA                  <1> 	stosb
  1501 000086B6 AC                  <1> 	lodsb
  1502 000086B7 3C20                <1> 	cmp	al, 20h
  1503 000086B9 73FA                <1> 	jnb	short cmd_remark_write
  1504 000086BB C60700              <1> 	mov	byte [edi], 0
  1505                              <1> 
  1506                              <1> cmd_help_retn:
  1507                              <1> cmd_remark_retn:
  1508                              <1> cd_retn:
  1509 000086BE C3                  <1> 	retn
  1510                              <1> 
  1511                              <1> c_2:
  1512 000086BF 80F902              <1> 	cmp	cl, 2
  1513 000086C2 0F87AF000000        <1>         ja      c_3
  1514 000086C8 BE[4E650100]        <1> 	mov	esi, CommandBuffer
  1515 000086CD 72A9                <1> 	jb	short c_1
  1516                              <1> 
  1517                              <1> cmp_cmd_cd:
  1518 000086CF 66AD                <1> 	lodsw
  1519 000086D1 663D4344            <1> 	cmp	ax, 'CD'
  1520 000086D5 7551                <1> 	jne	short cmp_cmd_drive
  1521 000086D7 46                  <1>         inc	esi
  1522                              <1> cd_0:
  1523 000086D8 668B06              <1> 	mov	ax, [esi]	
  1524 000086DB 3C20                <1> 	cmp	al, 20h
  1525 000086DD 76DF                <1> 	jna	short cd_retn
  1526                              <1> 	; 10/02/2016
  1527 000086DF 80FC3A              <1> 	cmp	ah, ':'
  1528 000086E2 7504                <1> 	jne	short cd_1
  1529 000086E4 46                  <1> 	inc	esi
  1530 000086E5 46                  <1> 	inc	esi
  1531 000086E6 EB49                <1> 	jmp	short cd_2
  1532                              <1> 
  1533                              <1> cd_1:	; change current directory
  1534                              <1> 	; 29/11/2009
  1535                              <1> 	; AH = CDh	; to separate 'CD' command from others
  1536                              <1> 			; for restoring current directory
  1537                              <1> 			; 0CDh sign is for saving cdir into 
  1538                              <1> 			; DOS drv description table cdir area
  1539                              <1> 	
  1540 000086E8 B4CD                <1> 	mov	ah, 0CDh ; mov byte [CD_COMMAND], 0CDh 
  1541                              <1> 
  1542 000086EA E81D230000          <1> 	call	change_current_directory
  1543 000086EF 0F8337220000        <1>         jnc     change_prompt_dir_string
  1544                              <1> 
  1545                              <1> cd_error_messages:
  1546 000086F5 3C03                <1> 	cmp	al, 3
  1547 000086F7 740C                <1> 	je	short cd_path_not_found
  1548                              <1> 	; 16/10/2016 (15h -> 15)
  1549 000086F9 3C0F                <1> 	cmp	al, 15 ; drive not ready error 
  1550 000086FB 7459                <1> 	je	short cd_drive_not_ready
  1551 000086FD 3C11                <1> 	cmp	al, 17 ; read error
  1552 000086FF 7455                <1> 	je	short cd_drive_not_ready	
  1553 00008701 3C13                <1> 	cmp	al, 19 ; ; Bad directory/path name 
  1554 00008703 7466                <1> 	je	short cd_command_failed
  1555                              <1> 
  1556                              <1> cd_path_not_found:
  1557 00008705 50                  <1> 	push	eax ; 29/12/2017
  1558                              <1> 	;push	ax	
  1559 00008706 BE[F81A0100]        <1> 	mov	esi, Msg_Dir_Not_Found
  1560 0000870B E815E8FFFF          <1> 	call	print_msg
  1561                              <1> 	;pop	ax
  1562 00008710 58                  <1> 	pop	eax ; 29/12/2017
  1563 00008711 3A25[9C640100]      <1> 	cmp	ah, [Current_Dir_Level]
  1564 00008717 0F830F220000        <1>         jnb     change_prompt_dir_string
  1565 0000871D 8825[9C640100]      <1> 	mov	[Current_Dir_Level], ah
  1566 00008723 E904220000          <1>         jmp     change_prompt_dir_string   
  1567                              <1> 
  1568                              <1> cmp_cmd_drive: ; change current drive
  1569                              <1> 	; C:, D:, E: etc.
  1570 00008728 80FC3A              <1> 	cmp	ah, ':'
  1571 0000872B 0F8506020000        <1>         jne     cmp_cmd_external
  1572                              <1> 
  1573                              <1> cd_2:	; 'CD C:', 'CD D:' ...
  1574 00008731 803E20              <1> 	cmp	byte [esi], 20h
  1575 00008734 0F8707020000        <1>         ja      loc_cmd_failed
  1576                              <1> 
  1577 0000873A 24DF                <1> 	and	al, 0DFh
  1578 0000873C 2C41                <1> 	sub	al, 'A'
  1579 0000873E 0F82FD010000        <1>         jc      loc_cmd_failed
  1580                              <1> 
  1581 00008744 3A05[F5170100]      <1>         cmp     al, [Last_DOS_DiskNo]
  1582 0000874A 770A                <1>         ja	short cd_drive_not_ready
  1583                              <1> 	
  1584 0000874C 88C2                <1> 	mov	dl, al
  1585 0000874E E85BF3FFFF          <1> 	call 	change_current_drive
  1586 00008753 7201                <1> 	jc	short cd_drive_not_ready	
  1587 00008755 C3                  <1> 	retn
  1588                              <1> 
  1589                              <1> cd_drive_not_ready:
  1590 00008756 BE[B51A0100]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1591 0000875B E8C5E7FFFF          <1> 	call	print_msg
  1592                              <1> 
  1593                              <1> cd_fail_drive_restart:
  1594 00008760 8A15[9E640100]      <1> 	mov	dl, [Current_Drv]
  1595                              <1> 	;call 	change_current_drive
  1596 00008766 E943F3FFFF          <1>         jmp     change_current_drive
  1597                              <1> 	;retn
  1598                              <1> 
  1599                              <1> cd_command_failed:
  1600 0000876B BE[961A0100]        <1> 	mov	esi, Msg_Bad_Command
  1601 00008770 E8B0E7FFFF          <1> 	call	print_msg
  1602 00008775 EBE9                <1> 	jmp	short cd_fail_drive_restart
  1603                              <1> 
  1604                              <1> c_3:
  1605                              <1> cmp_cmd_dir:
  1606 00008777 BF[55180100]        <1> 	mov	edi, Cmd_Dir
  1607 0000877C E8D3010000          <1> 	call	cmp_cmd	
  1608 00008781 0F8380020000        <1> 	jnc	print_directory_list
  1609                              <1> 
  1610                              <1> cmp_cmd_cls:
  1611 00008787 B103                <1> 	mov	cl, 3
  1612 00008789 BF[91180100]        <1> 	mov	edi, Cmd_Cls
  1613 0000878E E8C1010000          <1> 	call	cmp_cmd	
  1614 00008793 0F83A2E7FFFF        <1>         jnc	clear_screen
  1615                              <1> 
  1616                              <1> cmp_cmd_ver:
  1617 00008799 B103                <1> 	mov	cl, 3
  1618 0000879B BF[5F180100]        <1> 	mov	edi, Cmd_Ver
  1619 000087A0 E8AF010000          <1> 	call	cmp_cmd	
  1620 000087A5 720A                <1> 	jc	short cmp_cmd_mem
  1621                              <1> 
  1622 000087A7 BE[FD170100]        <1> 	mov	esi, mainprog_Version
  1623                              <1> 	;call	print_msg
  1624 000087AC E974E7FFFF          <1> 	jmp	print_msg
  1625                              <1> 	;retn
  1626                              <1> 
  1627                              <1> cmp_cmd_mem:
  1628 000087B1 B103                <1> 	mov	cl, 3
  1629 000087B3 BF[C7180100]        <1> 	mov	edi, Cmd_Mem
  1630 000087B8 E897010000          <1> 	call	cmp_cmd	
  1631 000087BD 0F834EB4FFFF        <1> 	jnc	memory_info
  1632                              <1> 
  1633                              <1> cmp_cmd_del:
  1634 000087C3 B103                <1> 	mov	cl, 3
  1635 000087C5 BF[9A180100]        <1> 	mov	edi, Cmd_Del
  1636 000087CA E885010000          <1> 	call	cmp_cmd	
  1637 000087CF 0F83280F0000        <1>         jnc     delete_file
  1638                              <1> 
  1639                              <1> cmp_cmd_set:
  1640 000087D5 B103                <1> 	mov	cl, 3
  1641 000087D7 BF[8D180100]        <1> 	mov	edi, Cmd_Set
  1642 000087DC E873010000          <1> 	call	cmp_cmd	
  1643 000087E1 0F83C9170000        <1>         jnc     set_get_env
  1644                              <1> 
  1645                              <1> cmp_cmd_run:
  1646 000087E7 B103                <1> 	mov	cl, 3
  1647 000087E9 BF[89180100]        <1> 	mov	edi, Cmd_Run
  1648 000087EE E861010000          <1> 	call	cmp_cmd	
  1649                              <1> 	; 07/05/2016
  1650 000087F3 0F823E010000        <1>         jc      cmp_cmd_external
  1651 000087F9 E90F1E0000          <1> 	jmp	load_and_execute_file
  1652                              <1> c_5:
  1653                              <1> cmp_cmd_mkdir:
  1654 000087FE BF[B2180100]        <1> 	mov	edi, Cmd_Mkdir
  1655 00008803 E84C010000          <1> 	call	cmp_cmd	
  1656 00008808 0F83990A0000        <1>         jnc     make_directory
  1657                              <1> 
  1658                              <1> cmp_cmd_rmdir:
  1659 0000880E B105                <1> 	mov	cl, 5
  1660 00008810 BF[AC180100]        <1> 	mov	edi, Cmd_Rmdir
  1661 00008815 E83A010000          <1> 	call	cmp_cmd	
  1662 0000881A 0F83AA0B0000        <1>         jnc     delete_directory
  1663                              <1> 
  1664                              <1> cmp_cmd_chdir:
  1665 00008820 B105                <1> 	mov	cl, 5
  1666 00008822 BF[E9180100]        <1> 	mov	edi, Cmd_Chdir
  1667 00008827 E828010000          <1> 	call	cmp_cmd	
  1668 0000882C 0F8205010000        <1>         jc      cmp_cmd_external
  1669                              <1> 
  1670 00008832 E9A1FEFFFF          <1> 	jmp	cd_0
  1671                              <1> 
  1672                              <1> c_6:
  1673 00008837 80F906              <1> 	cmp	cl, 6
  1674 0000883A 0F87E0000000        <1>         ja      c_8
  1675 00008840 72BC                <1> 	jb	short c_5
  1676                              <1> cmp_cmd_prompt:
  1677 00008842 BF[68180100]        <1> 	mov	edi, Cmd_Prompt
  1678 00008847 E808010000          <1> 	call	cmp_cmd	
  1679 0000884C 722F                <1>         jc	short cmp_cmd_volume
  1680                              <1> get_prompt_name_fchar:
  1681 0000884E AC                  <1> 	lodsb
  1682 0000884F 3C20                <1> 	cmp	al, 20h
  1683 00008851 74FB                <1> 	je	short get_prompt_name_fchar
  1684 00008853 7713                <1> 	ja	short loc_change_prompt_label
  1685                              <1> default_command_prompt: ; 31/12/2017 ('sysprompt')
  1686 00008855 BE[49180100]        <1> 	mov	esi, TRDOSPromptLabel
  1687 0000885A C7065452444F        <1> 	mov	dword [esi], "TRDO"
  1688 00008860 66C746045300        <1>        	mov	word [esi+4], "S" 
  1689                              <1> loc_cmd_prompt_return:
  1690 00008866 C3                  <1> 	retn
  1691                              <1> 
  1692                              <1> set_command_prompt: ; 31/12/2017 ('sysprompt')
  1693 00008867 AC                  <1> 	lodsb
  1694                              <1> loc_change_prompt_label:
  1695 00008868 66B90B00            <1> 	mov	cx, 11
  1696 0000886C BF[49180100]        <1> 	mov	edi, TRDOSPromptLabel
  1697                              <1> put_char_new_prompt_label:
  1698 00008871 AA                  <1> 	stosb
  1699 00008872 AC                  <1> 	lodsb
  1700 00008873 3C20                <1> 	cmp	al, 20h
  1701 00008875 7202                <1> 	jb	short pass_put_new_prompt_label
  1702 00008877 E2F8                <1> 	loop	put_char_new_prompt_label
  1703                              <1> pass_put_new_prompt_label:
  1704 00008879 C60700              <1> 	mov	byte [edi], 0
  1705 0000887C C3                  <1> 	retn
  1706                              <1> 
  1707                              <1> cmp_cmd_volume:
  1708 0000887D B106                <1> 	mov	cl, 6
  1709 0000887F BF[6F180100]        <1> 	mov	edi, Cmd_Volume
  1710 00008884 E8CB000000          <1> 	call	cmp_cmd	
  1711 00008889 7255                <1>         jc	short cmp_cmd_attrib
  1712                              <1> 
  1713                              <1> cmd_vol1:
  1714 0000888B AC                  <1> 	lodsb
  1715 0000888C 3C20                <1> 	cmp	al, 20h
  1716 0000888E 7707                <1> 	ja	short cmd_vol2
  1717 00008890 A0[9E640100]        <1> 	mov	al, [Current_Drv]
  1718 00008895 EB3D                <1> 	jmp	short cmd_vol4
  1719                              <1> cmd_vol2:
  1720 00008897 3C41                <1> 	cmp	al, 'A'
  1721 00008899 0F82A2000000        <1>         jb      loc_cmd_failed
  1722 0000889F 3C7A                <1> 	cmp	al, 'z'
  1723 000088A1 0F879A000000        <1>         ja      loc_cmd_failed
  1724 000088A7 3C5A                <1> 	cmp	al, 'Z'
  1725 000088A9 760A                <1> 	jna	short cmd_vol3
  1726 000088AB 3C61                <1> 	cmp	al, 'a'
  1727 000088AD 0F828E000000        <1>         jb      loc_cmd_failed
  1728 000088B3 24DF                <1> 	and	al, 0DFh
  1729                              <1> cmd_vol3:
  1730 000088B5 8A26                <1> 	mov	ah, [esi]
  1731 000088B7 80FC3A              <1> 	cmp	ah, ':'
  1732 000088BA 0F8581000000        <1>         jne     loc_cmd_failed
  1733 000088C0 2C41                <1> 	sub	al, 'A'
  1734 000088C2 3A05[F5170100]      <1>         cmp     al, [Last_DOS_DiskNo]
  1735 000088C8 760A                <1> 	jna	short cmd_vol4
  1736                              <1> 
  1737 000088CA BE[B51A0100]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1738 000088CF E951E6FFFF          <1> 	jmp	print_msg
  1739                              <1> 	
  1740                              <1> cmd_vol4:
  1741 000088D4 E88EFAFFFF          <1> 	call	print_volume_info
  1742 000088D9 0F8277FEFFFF        <1>         jc      cd_drive_not_ready
  1743 000088DF C3                  <1> 	retn
  1744                              <1> 
  1745                              <1> cmp_cmd_attrib:
  1746 000088E0 B106                <1> 	mov	cl, 6
  1747 000088E2 BF[9E180100]        <1> 	mov	edi, Cmd_Attrib
  1748 000088E7 E868000000          <1> 	call	cmp_cmd	
  1749 000088EC 0F831D0F0000        <1>         jnc     set_file_attributes
  1750                              <1> 
  1751                              <1> cmp_cmd_rename:
  1752 000088F2 B106                <1> 	mov	cl, 6
  1753 000088F4 BF[A5180100]        <1> 	mov	edi, Cmd_Rename
  1754 000088F9 E856000000          <1> 	call	cmp_cmd	
  1755 000088FE 0F8353110000        <1>         jnc     rename_file
  1756                              <1> 
  1757                              <1> cmp_cmd_device:
  1758 00008904 B106                <1> 	mov	cl, 6
  1759 00008906 BF[DA180100]        <1> 	mov	edi, Cmd_Device
  1760 0000890B E844000000          <1> 	call	cmp_cmd	
  1761 00008910 7225                <1>         jc	short cmp_cmd_external
  1762                              <1> 
  1763 00008912 C3                  <1> 	retn
  1764                              <1> 
  1765                              <1> c_7:
  1766                              <1> cmp_cmd_devlist:
  1767 00008913 BF[E1180100]        <1> 	mov	edi, Cmd_DevList
  1768 00008918 E837000000          <1> 	call	cmp_cmd	
  1769 0000891D 7218                <1>         jc	short cmp_cmd_external
  1770                              <1> 
  1771                              <1> loc_cmd_return:
  1772 0000891F C3                  <1> 	retn
  1773                              <1> 
  1774                              <1> c_8:
  1775 00008920 80F908              <1>         cmp	cl, 8
  1776 00008923 7712                <1> 	ja	short cmp_cmd_external
  1777 00008925 72EC                <1> 	jb	short c_7
  1778                              <1> 
  1779                              <1> cmp_cmd_longname:
  1780 00008927 BF[76180100]        <1> 	mov	edi, Cmd_LongName
  1781 0000892C E823000000          <1> 	call	cmp_cmd	
  1782 00008931 0F8350060000        <1>         jnc     get_and_print_longname
  1783                              <1> 
  1784                              <1> cmp_cmd_external:
  1785                              <1> 	; 07/05/2016
  1786                              <1> 	; 22/04/2016
  1787 00008937 BE[4E650100]        <1> 	mov	esi, CommandBuffer
  1788 0000893C E9CC1C0000          <1> 	jmp	loc_run_check_filename 
  1789                              <1> 
  1790                              <1> loc_cmd_failed:
  1791 00008941 803D[4E650100]20    <1> 	cmp	byte [CommandBuffer], 20h
  1792 00008948 76D5                <1> 	jna	short loc_cmd_return
  1793 0000894A BE[961A0100]        <1> 	mov	esi, Msg_Bad_Command
  1794                              <1> ;	call	print_msg
  1795                              <1> ;loc_cmd_return:
  1796                              <1> ;	retn
  1797 0000894F E9D1E5FFFF          <1> 	jmp	print_msg
  1798                              <1> 
  1799                              <1> cmp_cmd:
  1800                              <1> 	 ; 29/01/2016 (TRDOS 386 = TRDOS v2.0)
  1801 00008954 BE[4E650100]        <1>          mov	esi, CommandBuffer
  1802                              <1>          ; edi = internal command word (ASCIIZ)
  1803                              <1> 	 ; ecx = command length (<=8)
  1804                              <1> cmp_cmd_1:
  1805 00008959 AC                  <1> 	lodsb
  1806 0000895A AE                  <1> 	scasb
  1807 0000895B 750D                <1> 	jne	short cmp_cmd_3
  1808 0000895D E2FA                <1> 	loop	cmp_cmd_1
  1809 0000895F AC                  <1>  	lodsb
  1810 00008960 3C20                <1> 	cmp	al, 20h
  1811 00008962 7703                <1> 	ja	short cmp_cmd_2
  1812 00008964 30C0                <1> 	xor	al, al
  1813                              <1> 	; ZF = 1 -> internal command word matches
  1814 00008966 C3                  <1> 	retn
  1815                              <1> cmp_cmd_2:
  1816                              <1> 	; ZF = 0 (CF = 0) -> external command word 	
  1817 00008967 58                  <1> 	pop	eax ; no return to the caller from here 
  1818 00008968 EBCD                <1> 	jmp	cmp_cmd_external	
  1819                              <1> cmp_cmd_3:
  1820 0000896A F9                  <1> 	stc
  1821                              <1> 	; CF = 1 -> internal command word does not match
  1822 0000896B C3                  <1> 	retn
  1823                              <1> 
  1824                              <1> loc_run_cmd_failed:
  1825                              <1> 	; 15/03/2016
  1826                              <1> 	; 15/02/2016 (TRDOS 386 = TRDOS v2.0)
  1827                              <1> 	; 07/12/2009 (CMD_INTR.ASM)	
  1828                              <1> 	; 29/11/2009
  1829                              <1> 
  1830 0000896C E863000000          <1> 	call	restore_cdir_after_cmd_fail
  1831                              <1> 
  1832                              <1> loc_run_cmd_failed_cmp_al:
  1833                              <1> 	; End of Restore_CDIR code (29/11/2009)
  1834                              <1> 
  1835 00008971 3C01                <1> 	cmp	al, 1 ; Bad command or file name
  1836 00008973 74CC                <1> 	je	loc_cmd_failed
  1837                              <1> loc_run_dir_not_found:
  1838 00008975 3C03                <1> 	cmp	al, 3
  1839 00008977 750A                <1> 	jne	short loc_run_file_notfound_msg
  1840                              <1> 	; Path not found (MS-DOS Error Code = 3)
  1841 00008979 BE[F81A0100]        <1> 	mov	esi, Msg_Dir_Not_Found
  1842 0000897E E9A2E5FFFF          <1> 	jmp	print_msg
  1843                              <1> 
  1844                              <1> loc_run_file_notfound_msg:
  1845 00008983 3C02                <1> 	cmp	al, 2 ; File not found
  1846 00008985 750A                <1> 	jne	short loc_run_file_drv_read_err
  1847                              <1> 
  1848                              <1> loc_print_file_notfound_msg: 
  1849 00008987 BE[0F1B0100]        <1>         mov     esi, Msg_File_Not_Found
  1850                              <1> 	;call	proc_printmsg
  1851                              <1> 	;retn
  1852 0000898C E994E5FFFF          <1> 	jmp	print_msg
  1853                              <1> 
  1854                              <1> loc_run_file_drv_read_err:
  1855                              <1> 	; Err: 17 (Read fault)
  1856 00008991 3C11                <1> 	cmp	al, 17 ; Drive not ready or read error
  1857 00008993 7404                <1> 	je	short loc_run_file_print_drv_read_err
  1858                              <1> 	;
  1859 00008995 3C0F                <1> 	cmp	al, 15 ; Drive not ready (or read error)
  1860 00008997 750A                <1> 	jne	short loc_run_file_toobig
  1861                              <1> 
  1862                              <1> loc_run_file_print_drv_read_err:
  1863 00008999 BE[B51A0100]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1864 0000899E E982E5FFFF          <1> 	jmp	print_msg
  1865                              <1> 
  1866                              <1> loc_run_file_toobig:
  1867 000089A3 3C08                <1> 	cmp	al, 8 ; Not enough free memory to load&run file
  1868 000089A5 750A                <1> 	jne	short loc_run_file_perm_denied
  1869 000089A7 BE[5A1B0100]        <1> 	mov	esi, Msg_Insufficient_Memory
  1870 000089AC E974E5FFFF          <1> 	jmp	print_msg
  1871                              <1> 
  1872                              <1> loc_run_file_perm_denied:
  1873                              <1> 	; 29/12/2017
  1874 000089B1 3C0B                <1> 	cmp	al, ERR_PERM_DENIED ; 11 ; Permission denied
  1875 000089B3 750A                <1> 	jne	short loc_run_misc_error
  1876 000089B5 BE[EE1C0100]        <1> 	mov	esi, Msg_Permission_Denied
  1877 000089BA E966E5FFFF          <1> 	jmp	print_msg	
  1878                              <1> 
  1879                              <1> 	; 15/03/2016
  1880                              <1> print_misc_error_msg:
  1881                              <1> loc_run_misc_error:
  1882                              <1> 	; AL = Error code
  1883 000089BF E8DBB2FFFF          <1> 	call	bytetohex
  1884 000089C4 66A3[8E1B0100]      <1>         mov     [error_code_hex], ax
  1885                              <1> 	
  1886 000089CA BE[711B0100]        <1> 	mov	esi, Msg_Error_Code 
  1887                              <1> 	;call	print_msg 
  1888                              <1> 	;retn
  1889                              <1> 
  1890 000089CF E951E5FFFF          <1> 	jmp	print_msg
  1891                              <1> 
  1892                              <1> restore_cdir_after_cmd_fail:
  1893                              <1> 	; 15/02/2016 (TRDOS 386 = TRDOS v2.0)
  1894 000089D4 50                  <1> 	push	eax
  1895 000089D5 8A3D[FA6B0100]      <1> 	mov	bh, [RUN_CDRV] ; it is set at the beginning
  1896                              <1> 				; of the 'run' command.
  1897 000089DB 3A3D[9E640100]      <1> 	cmp	bh, [Current_Drv]
  1898 000089E1 7409                <1> 	je	short loc_run_restore_cdir
  1899 000089E3 88FA                <1> 	mov	dl, bh
  1900 000089E5 E8C4F0FFFF          <1> 	call	change_current_drive 
  1901 000089EA EB19                <1> 	jmp	short loc_run_err_pass_restore_cdir
  1902                              <1> 
  1903                              <1> loc_run_restore_cdir:
  1904 000089EC 803D[F6170100]00    <1> 	cmp	byte [Restore_CDIR], 0
  1905 000089F3 7610                <1> 	jna	short loc_run_err_pass_restore_cdir
  1906 000089F5 30DB                <1> 	xor	bl, bl
  1907 000089F7 0FB7F3              <1> 	movzx	esi, bx
  1908 000089FA 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1909 00008A00 E860F1FFFF          <1> 	call	restore_current_directory
  1910                              <1> 
  1911                              <1> loc_run_err_pass_restore_cdir:
  1912 00008A05 58                  <1> 	pop	eax
  1913 00008A06 C3                  <1> 	retn
  1914                              <1> 
  1915                              <1> print_directory_list:
  1916                              <1> 	; 10/02/2016
  1917                              <1> 	; 08/02/2016 (TRDOS 386 = TRDOS v2.0)
  1918                              <1> 	; 06/12/2009 ('cmp_cmd_dir')	
  1919                              <1> 	;
  1920 00008A07 66C705[3C6D0100]00- <1> 	mov	word [AttributesMask], 0800h ; ..except volume names..
  1920 00008A0F 08                  <1>
  1921 00008A10 A0[9E640100]        <1> 	mov	al, [Current_Drv]
  1922 00008A15 A2[FA6B0100]        <1> 	mov	[RUN_CDRV], al
  1923                              <1> get_dfname_fchar:
  1924 00008A1A AC                  <1> 	lodsb
  1925 00008A1B 3C20                <1> 	cmp	al, 20h
  1926 00008A1D 74FB                <1> 	je	short get_dfname_fchar
  1927 00008A1F 0F82A4000000        <1>         jb      loc_print_dir_call_all
  1928 00008A25 3C2D                <1> 	cmp	al, '-'
  1929 00008A27 7542                <1> 	jne	short loc_print_dir_call_flt
  1930                              <1> get_next_attr_char:
  1931 00008A29 AC                  <1> 	lodsb
  1932 00008A2A 3C20                <1> 	cmp	al, 20h
  1933 00008A2C 74FB                <1> 	je	short get_next_attr_char
  1934 00008A2E 0F820DFFFFFF        <1>         jb      loc_cmd_failed
  1935 00008A34 24DF                <1> 	and	al, 0DFh
  1936 00008A36 3C44                <1> 	cmp	al, 'D' ; directories only ?
  1937 00008A38 7512                <1> 	jne	short pass_only_directories
  1938 00008A3A AC                  <1> 	lodsb
  1939 00008A3B 3C20                <1> 	cmp	al, 20h
  1940 00008A3D 0F87FEFEFFFF        <1>         ja      loc_cmd_failed
  1941 00008A43 800D[3C6D0100]10    <1> 	or	byte [AttributesMask], 10h ; ..directory..
  1942 00008A4A EB18                <1> 	jmp	short get_dfname_fchar_attr
  1943                              <1> pass_only_directories:
  1944 00008A4C 3C46                <1> 	cmp	al, 'F'	; files only ?
  1945 00008A4E 0F85B0000000        <1>         jne     check_attr_s
  1946 00008A54 AC                  <1> 	lodsb
  1947 00008A55 3C20                <1> 	cmp	al, 20h
  1948 00008A57 0F87E4FEFFFF        <1>         ja      loc_cmd_failed
  1949 00008A5D 800D[3D6D0100]10    <1> 	or	byte [AttributesMask+1], 10h ; ..except directories..
  1950                              <1> get_dfname_fchar_attr:
  1951 00008A64 AC                  <1> 	lodsb
  1952 00008A65 3C20                <1> 	cmp	al, 20h
  1953 00008A67 74FB                <1> 	je	short get_dfname_fchar_attr
  1954 00008A69 725E                <1> 	jb	short loc_print_dir_call_all
  1955                              <1> 
  1956                              <1> loc_print_dir_call_flt:
  1957 00008A6B 4E                  <1> 	dec	esi
  1958 00008A6C BF[3E6D0100]        <1> 	mov	edi, FindFile_Drv
  1959 00008A71 E8AC250000          <1> 	call	parse_path_name
  1960 00008A76 7308                <1>  	jnc	short loc_print_dir_change_drv_1
  1961 00008A78 3C01                <1> 	cmp	al, 1
  1962 00008A7A 0F87ECFEFFFF        <1>         ja      loc_run_cmd_failed
  1963                              <1> 
  1964                              <1> loc_print_dir_change_drv_1:
  1965 00008A80 8A15[3E6D0100]      <1> 	mov	dl, [FindFile_Drv]
  1966                              <1> loc_print_dir_change_drv_2:
  1967 00008A86 3A15[FA6B0100]      <1> 	cmp	dl, [RUN_CDRV]
  1968 00008A8C 740B                <1> 	je	short loc_print_dir_change_directory 
  1969 00008A8E E81BF0FFFF          <1> 	call	change_current_drive
  1970 00008A93 0F82D3FEFFFF        <1>         jc      loc_run_cmd_failed
  1971                              <1> loc_print_dir_change_directory:
  1972 00008A99 803D[3F6D0100]20    <1> 	cmp	byte [FindFile_Directory], 20h ; 0 or 20h ?
  1973 00008AA0 761D                <1> 	jna	short pass_print_dir_change_directory
  1974                              <1> 
  1975 00008AA2 FE05[F6170100]      <1> 	inc	byte [Restore_CDIR]
  1976 00008AA8 BE[3F6D0100]        <1> 	mov	esi, FindFile_Directory
  1977 00008AAD 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  1978 00008AAF E8581F0000          <1> 	call	change_current_directory
  1979 00008AB4 0F82B2FEFFFF        <1>         jc      loc_run_cmd_failed
  1980                              <1> 
  1981                              <1> loc_print_dir_change_prompt_dir_string:
  1982 00008ABA E86D1E0000          <1> 	call	change_prompt_dir_string
  1983                              <1> 
  1984                              <1> pass_print_dir_change_directory:
  1985 00008ABF BE[806D0100]        <1> 	mov	esi, FindFile_Name
  1986 00008AC4 803E20              <1> 	cmp	byte [esi], 20h ; ; 0 or 20h ?
  1987 00008AC7 7706                <1> 	ja	short loc_print_dir_call
  1988                              <1> 
  1989                              <1> loc_print_dir_call_all:
  1990 00008AC9 C7062A2E2A00        <1> 	mov	dword [esi], '*.*'
  1991                              <1> loc_print_dir_call:
  1992 00008ACF E87E000000          <1> 	call	print_directory
  1993                              <1> 
  1994 00008AD4 8A15[FA6B0100]      <1> 	mov	dl, [RUN_CDRV]  ; it is set at the beginning
  1995 00008ADA 3A15[9E640100]      <1> 	cmp	dl, [Current_Drv]
  1996 00008AE0 7406                <1> 	je	short loc_print_dir_call_restore_cdir_retn
  1997 00008AE2 E8C7EFFFFF          <1> 	call	change_current_drive 
  1998 00008AE7 C3                  <1> 	retn
  1999                              <1> 
  2000                              <1> loc_print_dir_call_restore_cdir_retn:
  2001 00008AE8 803D[F6170100]00    <1> 	cmp	byte [Restore_CDIR], 0
  2002 00008AEF 7610                <1> 	jna	short pass_print_dir_call_restore_cdir_retn
  2003                              <1> 
  2004 00008AF1 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2005 00008AF6 31C0                <1> 	xor	eax, eax
  2006 00008AF8 88D4                <1> 	mov	ah, dl
  2007 00008AFA 01C6                <1> 	add	esi, eax
  2008                              <1> 
  2009 00008AFC E864F0FFFF          <1> 	call	restore_current_directory
  2010                              <1> 
  2011                              <1> pass_print_dir_call_restore_cdir_retn:
  2012 00008B01 C3                  <1> 	retn
  2013                              <1> 
  2014                              <1> check_attr_s_cap:
  2015 00008B02 24DF                <1> 	and	al, 0DFh
  2016                              <1> check_attr_s:
  2017 00008B04 3C53                <1> 	cmp	al, 'S'
  2018 00008B06 7514                <1> 	jne	short pass_attr_s
  2019 00008B08 800D[3C6D0100]04    <1> 	or	byte [AttributesMask], 4 ; system
  2020 00008B0F AC                  <1> 	lodsb
  2021 00008B10 3C20                <1> 	cmp	al, 20h
  2022 00008B12 0F844CFFFFFF        <1>         je      get_dfname_fchar_attr
  2023 00008B18 72AF                <1> 	jb	short loc_print_dir_call_all
  2024 00008B1A 24DF                <1> 	and	al, 0DFh
  2025                              <1> pass_attr_s:
  2026 00008B1C 3C48                <1> 	cmp	al, 'H'
  2027 00008B1E 7514                <1> 	jne	short pass_attr_h
  2028 00008B20 800D[3C6D0100]02    <1> 	or	byte [AttributesMask], 2 ; hidden
  2029                              <1> pass_attr_shr:
  2030 00008B27 AC                  <1> 	lodsb
  2031 00008B28 3C20                <1> 	cmp	al, 20h
  2032 00008B2A 0F8434FFFFFF        <1>         je      get_dfname_fchar_attr
  2033 00008B30 7297                <1> 	jb	short loc_print_dir_call_all
  2034 00008B32 EBCE                <1> 	jmp	short check_attr_s_cap
  2035                              <1> 
  2036                              <1> pass_attr_h:
  2037 00008B34 3C52                <1> 	cmp	al, 'R'
  2038 00008B36 7509                <1> 	jne	short pass_attr_r
  2039 00008B38 800D[3C6D0100]01    <1> 	or	byte [AttributesMask], 1 ; read only
  2040 00008B3F EBE6                <1> 	jmp	short pass_attr_shr
  2041                              <1> 
  2042                              <1> pass_attr_r:
  2043 00008B41 3C41                <1> 	cmp	al, 'A'
  2044 00008B43 0F85F8FDFFFF        <1>         jne     loc_cmd_failed
  2045 00008B49 800D[3C6D0100]20    <1> 	or	byte [AttributesMask], 20h ; archive
  2046 00008B50 EBD5                <1> 	jmp	short pass_attr_shr
  2047                              <1> 
  2048                              <1> print_directory:
  2049                              <1> 	; 13/05/2016
  2050                              <1> 	; 11/02/2016
  2051                              <1> 	; 10/02/2016
  2052                              <1> 	; 08/02/2016 (TRDOS 386 = TRDOS v2.0)
  2053                              <1> 	; 30/10/2010 ('proc_print_directory')	
  2054                              <1> 	; 19/09/2009
  2055                              <1> 	; 2005 
  2056                              <1> 	; INPUT ->
  2057                              <1> 	;	ESI = Asciiz File/Dir Name Address
  2058                              <1> 
  2059 00008B52 56                  <1> 	push	esi
  2060                              <1> 
  2061 00008B53 29C0                <1> 	sub	eax, eax
  2062                              <1> 
  2063 00008B55 66A3[C86D0100]      <1> 	mov	word [Dir_Count], ax ; 0
  2064 00008B5B 66A3[C66D0100]      <1> 	mov 	word [File_Count], ax ; 0
  2065 00008B61 A3[CA6D0100]        <1> 	mov 	dword [Total_FSize], eax ; 0
  2066                              <1> 
  2067 00008B66 E8D0E3FFFF          <1> 	call    clear_screen
  2068                              <1> 	
  2069 00008B6B 31C9                <1> 	xor	ecx, ecx	
  2070 00008B6D 8A2D[9E640100]      <1> 	mov     ch, [Current_Drv] ; DirBuff_Drv - 'A'
  2071 00008B73 A0[9F640100]        <1> 	mov     al, [Current_Dir_Drv] 
  2072 00008B78 A2[B3190100]        <1> 	mov     [Dir_Drive_Name], al
  2073 00008B7D BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2074 00008B82 01CE                <1> 	add	esi, ecx
  2075                              <1> 
  2076 00008B84 E858F9FFFF          <1> 	call	move_volume_name_and_serial_no
  2077 00008B89 730C                <1> 	jnc	short print_dir_strlen_check
  2078                              <1> 
  2079 00008B8B 5E                  <1> 	pop	esi
  2080 00008B8C 8A3D[06640100]      <1> 	mov	bh, [ptty] ; [ACTIVE_PAGE]
  2081                              <1> 	;call	beeper
  2082                              <1> 	;retn
  2083 00008B92 E94A97FFFF          <1> 	jmp	beeper  ; beep ! and return
  2084                              <1> 
  2085                              <1> print_dir_strlen_check:
  2086 00008B97 BE[A1640100]        <1> 	mov	esi, Current_Dir_Root
  2087 00008B9C BF[501A0100]        <1> 	mov	edi, Dir_Str_Root
  2088                              <1> 	
  2089                              <1> 	;xor	ecx, ecx
  2090 00008BA1 8A0D[FD640100]      <1>         mov     cl, [Current_Dir_StrLen]
  2091 00008BA7 FEC1                <1> 	inc	cl
  2092 00008BA9 80F940              <1> 	cmp	cl, 64
  2093 00008BAC 760D                <1> 	jna	short pass_print_dir_strlen_shorting
  2094 00008BAE 46                  <1> 	inc	esi
  2095 00008BAF 01CE                <1> 	add	esi, ecx
  2096 00008BB1 83EE40              <1> 	sub	esi, 64 
  2097 00008BB4 47                  <1> 	inc	edi
  2098 00008BB5 B82E2E2E20          <1> 	mov	eax, '... ' 
  2099 00008BBA AB                  <1> 	stosd
  2100                              <1>  
  2101                              <1> pass_print_dir_strlen_shorting:
  2102 00008BBB F3A4                <1> 	rep	movsb
  2103                              <1> 
  2104 00008BBD BE[A6190100]        <1> 	mov	esi, Dir_Drive_Str
  2105 00008BC2 E85EE3FFFF          <1> 	call	print_msg
  2106                              <1> 
  2107 00008BC7 BE[051A0100]        <1> 	mov	esi, Vol_Serial_Header
  2108 00008BCC E854E3FFFF          <1> 	call	print_msg
  2109                              <1> 
  2110 00008BD1 BE[451A0100]        <1> 	mov	esi, Dir_Str_Header
  2111 00008BD6 E84AE3FFFF          <1> 	call	print_msg
  2112                              <1> 	
  2113 00008BDB BE[91240100]        <1> 	mov	esi, next2line
  2114 00008BE0 E840E3FFFF          <1> 	call	print_msg
  2115                              <1> 
  2116                              <1> loc_print_dir_first_file:
  2117 00008BE5 C605[DD6D0100]10    <1> 	mov	byte [PrintDir_RowCounter], 16
  2118 00008BEC 66A1[3C6D0100]      <1> 	mov	ax, [AttributesMask]
  2119 00008BF2 5E                  <1> 	pop	esi
  2120                              <1> 
  2121 00008BF3 E859020000          <1> 	call	find_first_file
  2122 00008BF8 0F826F010000        <1>         jc      loc_dir_ok
  2123                              <1> 	 
  2124                              <1> loc_dfname_use_this:
  2125                              <1> 	; bl =	File Attributes (bh = Long Name Entry Length)
  2126 00008BFE F6C310              <1> 	test	bl, 10h  ; Is it a directory?
  2127 00008C01 741B                <1> 	jz	short loc_not_dir
  2128                              <1> 
  2129 00008C03 66FF05[C86D0100]    <1> 	inc	word [Dir_Count]
  2130 00008C0A 89F2                <1> 	mov	edx, esi 	; FindFile_DirEntry address
  2131 00008C0C BE[941B0100]        <1>  	mov	esi, Type_Dir	; '<DIR>     '
  2132 00008C11 BF[AB1B0100]        <1> 	mov	edi, Dir_Or_FileSize
  2133                              <1> 	; move 10 bytes
  2134 00008C16 A5                  <1> 	movsd
  2135 00008C17 A5                  <1> 	movsd
  2136 00008C18 66A5                <1> 	movsw	    	
  2137 00008C1A 89D6                <1> 	mov	esi, edx
  2138 00008C1C EB36                <1> 	jmp     short loc_dir_attribute
  2139                              <1> 
  2140                              <1> loc_not_dir:
  2141 00008C1E 66FF05[C66D0100]    <1> 	inc	word [File_Count]
  2142 00008C25 0105[CA6D0100]      <1> 	add	[Total_FSize], eax
  2143                              <1> 
  2144 00008C2B B90A000000          <1> 	mov	ecx, 10  ; 32 bit divisor
  2145 00008C30 89CF                <1> 	mov	edi, ecx
  2146 00008C32 81C7[AB1B0100]      <1> 	add	edi, Dir_Or_FileSize
  2147                              <1> loc_dir_rdivide:
  2148 00008C38 29D2                <1> 	sub	edx, edx
  2149 00008C3A F7F1                <1> 	div	ecx 	 ; remainder in dl (< 10)
  2150 00008C3C 80C230              <1> 	add     dl, '0'	 ; to make visible (ascii)
  2151 00008C3F 4F                  <1> 	dec	edi
  2152 00008C40 8817                <1> 	mov     [edi], dl
  2153 00008C42 21C0                <1> 	and	eax, eax
  2154 00008C44 75F2                <1> 	jnz	short loc_dir_rdivide
  2155                              <1> 
  2156                              <1> loc_dir_fill_space:
  2157 00008C46 81FF[AB1B0100]      <1> 	cmp     edi, Dir_Or_FileSize
  2158 00008C4C 7606                <1> 	jna     short loc_dir_attribute
  2159 00008C4E 4F                  <1> 	dec     edi
  2160 00008C4F C60720              <1> 	mov     byte [edi], 20h
  2161 00008C52 EBF2                <1> 	jmp     short loc_dir_fill_space
  2162                              <1> 
  2163                              <1> loc_dir_attribute:
  2164 00008C54 C705[B61B0100]2020- <1> 	mov	dword [File_Attribute], 20202020h
  2164 00008C5C 2020                <1>
  2165                              <1> 
  2166 00008C5E 80FB20              <1> 	cmp	bl, 20h  ; Is it an archive file?
  2167 00008C61 7207                <1> 	jb	short loc_dir_pass_arch
  2168 00008C63 C605[B91B0100]41    <1> 	mov	byte [File_Attribute+3], 'A'
  2169                              <1> 
  2170                              <1> loc_dir_pass_arch:
  2171 00008C6A 80E307              <1> 	and	bl, 7
  2172 00008C6D 7428                <1> 	jz	short loc_dir_file_name
  2173 00008C6F 88DF                <1> 	mov	bh, bl
  2174 00008C71 80E303              <1> 	and	bl, 3
  2175 00008C74 38DF                <1> 	cmp	bh, bl
  2176 00008C76 7607                <1> 	jna	short loc_dir_pass_s
  2177 00008C78 C605[B61B0100]53    <1> 	mov	byte [File_Attribute], 'S'
  2178                              <1> 
  2179                              <1> loc_dir_pass_s:
  2180 00008C7F 80E302              <1> 	and     bl,2
  2181 00008C82 7407                <1> 	jz      short loc_dir_pass_h
  2182 00008C84 C605[B71B0100]48    <1> 	mov     byte [File_Attribute+1], 'H'
  2183                              <1> loc_dir_pass_h:
  2184 00008C8B 80E701              <1> 	and     bh,1
  2185 00008C8E 7407                <1> 	jz      short loc_dir_file_name
  2186 00008C90 C605[B81B0100]52    <1> 	mov     byte [File_Attribute+2], 'R'
  2187                              <1> loc_dir_file_name:
  2188                              <1> 	;mov     bx, [esi+18h] ; Date
  2189                              <1> 	;mov     dx, [esi+16h] ; Time
  2190 00008C97 8B5E16              <1> 	mov	ebx, [esi+16h]
  2191 00008C9A 89F1                <1> 	mov	ecx, esi ; FindFile_DirEntry address
  2192 00008C9C BF[9E1B0100]        <1> 	mov     edi, File_Name
  2193                              <1> 	; move 8 bytes
  2194 00008CA1 A5                  <1> 	movsd
  2195 00008CA2 A5                  <1> 	movsd
  2196 00008CA3 C60720              <1> 	mov	byte [edi], 20h
  2197 00008CA6 47                  <1> 	inc	edi
  2198                              <1> 	; move 3 bytes
  2199 00008CA7 66A5                <1> 	movsw
  2200 00008CA9 A4                  <1> 	movsb
  2201 00008CAA 89CE                <1> 	mov	esi, ecx
  2202                              <1> 
  2203                              <1> Dir_Time_start:
  2204                              <1> 	;mov	ax, dx		; Time
  2205 00008CAC 6689D8              <1> 	mov	ax, bx
  2206 00008CAF 66C1E805            <1> 	shr	ax, 5		; shift right 5 times
  2207 00008CB3 6683E03F            <1> 	and	ax, 0000111111b	; Minute Mask
  2208 00008CB7 D40A                <1> 	aam			; Q([AL]/10)->AH
  2209                              <1> 				; R([AL]/10)->AL
  2210                              <1> 				; [AL]+[AH]= Minute as BCD
  2211 00008CB9 660D3030            <1> 	or	ax, '00'	; Convert to ASCII
  2212 00008CBD 86E0                <1> 	xchg	ah, al
  2213 00008CBF 66A3[C91B0100]      <1> 	mov	[File_Minute], ax
  2214                              <1> 
  2215                              <1> 	;mov	al, dh
  2216 00008CC5 88F8                <1> 	mov	al, bh
  2217 00008CC7 C0E803              <1> 	shr	al, 3		; shift right 3 times
  2218 00008CCA D40A                <1> 	aam			; [AL]+[AH]= Hours as BCD
  2219 00008CCC 660D3030            <1> 	or	ax, '00'
  2220 00008CD0 86E0                <1> 	xchg	ah, al
  2221 00008CD2 66A3[C61B0100]      <1> 	mov     [File_Hour], ax
  2222                              <1> 
  2223 00008CD8 C1EB10              <1> 	shr	ebx, 16		; BX = Date
  2224                              <1> 	
  2225                              <1> Dir_Date_start:
  2226 00008CDB 6689D8              <1> 	mov	ax, bx		; Date
  2227 00008CDE 6683E01F            <1> 	and	ax, 00011111b	; Day Mask
  2228 00008CE2 D40A                <1> 	aam			; Q([AL]/10)->AH
  2229                              <1> 				; R([AL]/10)->AL
  2230                              <1> 				; [AL]+[AH]= Day as BCD
  2231 00008CE4 660D3030            <1> 	or	ax, '00'	; Convert to ASCII
  2232 00008CE8 86C4                <1> 	xchg	al, ah
  2233                              <1> 
  2234 00008CEA 66A3[BB1B0100]      <1> 	mov	[File_Day], ax
  2235                              <1> 
  2236 00008CF0 6689D8              <1> 	mov	ax, bx
  2237 00008CF3 66C1E805            <1> 	shr	ax, 5		; shift right 5 times
  2238 00008CF7 6683E00F            <1> 	and	ax, 00001111b	; Month Mask
  2239 00008CFB D40A                <1> 	aam
  2240 00008CFD 660D3030            <1> 	or	ax, '00'
  2241 00008D01 86E0                <1> 	xchg	ah, al
  2242 00008D03 66A3[BE1B0100]      <1> 	mov	[File_Month], ax
  2243                              <1> 
  2244 00008D09 6689D8              <1> 	mov	ax, bx
  2245 00008D0C 66C1E809            <1> 	shr     ax, 9
  2246 00008D10 6683E07F            <1> 	and	ax, 01111111b	; Result = Year - 1980
  2247 00008D14 6605BC07            <1> 	add	ax, 1980
  2248                              <1> 
  2249 00008D18 B10A                <1> 	mov	cl, 10
  2250 00008D1A F6F1                <1> 	div	cl		; Q -> AL, R -> AH 
  2251 00008D1C 80CC30              <1> 	or	ah, '0'
  2252 00008D1F 8825[C41B0100]      <1> 	mov	[File_Year+3], ah
  2253 00008D25 D40A                <1> 	aam
  2254 00008D27 86E0                <1> 	xchg	ah, al
  2255 00008D29 80CC30              <1> 	or	ah, '0'	  ; Convert to ASCII
  2256 00008D2C 8825[C31B0100]      <1> 	mov	[File_Year+2], ah
  2257 00008D32 D40A                <1> 	aam
  2258 00008D34 86C4                <1> 	xchg	al, ah
  2259 00008D36 660D3030            <1> 	or	ax, '00'
  2260 00008D3A 66A3[C11B0100]      <1> 	mov	[File_Year], ax
  2261                              <1> 
  2262                              <1> loc_show_line:
  2263 00008D40 56                  <1> 	push	esi
  2264 00008D41 BE[9E1B0100]        <1> 	mov     esi, File_Name
  2265 00008D46 E8DAE1FFFF          <1> 	call	print_msg
  2266 00008D4B BE[93240100]        <1> 	mov	esi, nextline
  2267 00008D50 E8D0E1FFFF          <1> 	call	print_msg
  2268 00008D55 5E                  <1> 	pop	esi
  2269                              <1> 
  2270 00008D56 FE0D[DD6D0100]      <1> 	dec	byte [PrintDir_RowCounter]
  2271 00008D5C 0F84D4000000        <1>         jz      pause_dir_scroll
  2272                              <1> 
  2273                              <1> loc_next_entry:
  2274 00008D62 E899010000          <1> 	call	find_next_file
  2275 00008D67 0F8391FEFFFF        <1>         jnc     loc_dfname_use_this
  2276                              <1> 
  2277                              <1> loc_dir_ok:
  2278 00008D6D B90A000000          <1> 	mov     ecx, 10
  2279 00008D72 66A1[C86D0100]      <1> 	mov	ax, [Dir_Count]
  2280 00008D78 BF[DF1B0100]        <1> 	mov	edi, Decimal_Dir_Count
  2281 00008D7D 6639C8              <1> 	cmp	ax, cx ; 10
  2282 00008D80 7216                <1> 	jb	short pass_ddc
  2283 00008D82 47                  <1> 	inc	edi
  2284 00008D83 6683F864            <1> 	cmp	ax, 100
  2285 00008D87 720F                <1> 	jb	short pass_ddc
  2286 00008D89 47                  <1> 	inc	edi
  2287 00008D8A 663DE803            <1> 	cmp	ax, 1000
  2288 00008D8E 7208                <1> 	jb	short pass_ddc
  2289 00008D90 47                  <1> 	inc	edi
  2290 00008D91 663D1027            <1> 	cmp	ax, 10000
  2291 00008D95 7201                <1> 	jb	short pass_ddc
  2292 00008D97 47                  <1> 	inc	edi
  2293                              <1> pass_ddc:
  2294 00008D98 886F01              <1> 	mov     [edi+1], ch ; 0
  2295                              <1> loc_ddc_rediv:
  2296 00008D9B 31D2                <1> 	xor     edx, edx
  2297 00008D9D 66F7F1              <1> 	div     cx	; 10
  2298 00008DA0 80C230              <1> 	add     dl, '0'
  2299 00008DA3 8817                <1> 	mov     [edi], dl
  2300 00008DA5 4F                  <1> 	dec     edi
  2301 00008DA6 6609C0              <1> 	or	ax, ax
  2302 00008DA9 75F0                <1> 	jnz	short loc_ddc_rediv
  2303                              <1> 
  2304 00008DAB 66A1[C66D0100]      <1> 	mov     ax, [File_Count]
  2305 00008DB1 BF[CE1B0100]        <1> 	mov     edi, Decimal_File_Count
  2306 00008DB6 6639C8              <1> 	cmp     ax, cx ; 10
  2307 00008DB9 7216                <1> 	jb      short pass_dfc
  2308 00008DBB 47                  <1> 	inc     edi
  2309 00008DBC 6683F864            <1> 	cmp     ax, 100
  2310 00008DC0 720F                <1> 	jb      short pass_dfc
  2311 00008DC2 47                  <1> 	inc     edi
  2312 00008DC3 663DE803            <1> 	cmp     ax, 1000
  2313 00008DC7 7208                <1> 	jb      short pass_dfc
  2314 00008DC9 47                  <1> 	inc     edi
  2315 00008DCA 663D1027            <1> 	cmp     ax, 10000
  2316 00008DCE 7201                <1> 	jb      short pass_dfc
  2317 00008DD0 47                  <1> 	inc     edi
  2318                              <1> pass_dfc:
  2319                              <1> 	;mov    cx, 10
  2320 00008DD1 886F01              <1> 	mov     [edi+1], ch ; 00
  2321                              <1> loc_dfc_rediv:
  2322                              <1> 	;xor	dx, dx
  2323 00008DD4 30D2                <1> 	xor	dl, dl
  2324 00008DD6 66F7F1              <1> 	div	cx
  2325 00008DD9 80C230              <1> 	add	dl, '0'
  2326 00008DDC 8817                <1> 	mov	[edi], dl
  2327 00008DDE 4F                  <1> 	dec	edi
  2328 00008DDF 6609C0              <1> 	or	ax, ax
  2329 00008DE2 75F0                <1> 	jnz	short loc_dfc_rediv
  2330                              <1> 
  2331 00008DE4 BF[DC6D0100]        <1> 	mov     edi, TFS_Dec_End
  2332                              <1>         ;mov    byte [edi], 0
  2333 00008DE9 A1[CA6D0100]        <1> 	mov     eax, [Total_FSize]
  2334                              <1> 	;mov    ecx, 10
  2335                              <1> rediv_tfs_hex:
  2336                              <1> 	;sub	edx, edx
  2337 00008DEE 28D2                <1> 	sub	dl, dl
  2338 00008DF0 F7F1                <1> 	div	ecx
  2339 00008DF2 80C230              <1> 	add	dl, '0'
  2340 00008DF5 4F                  <1> 	dec     edi
  2341 00008DF6 8817                <1> 	mov     [edi], dl
  2342 00008DF8 21C0                <1> 	and	eax, eax
  2343 00008DFA 75F2                <1> 	jnz	short rediv_tfs_hex
  2344                              <1> 	
  2345 00008DFC 893D[CE6D0100]      <1> 	mov	[TFS_Dec_Begin], edi
  2346 00008E02 BE[CC1B0100]        <1> 	mov	esi, Decimal_File_Count_Header
  2347 00008E07 E819E1FFFF          <1> 	call	print_msg
  2348 00008E0C BE[D41B0100]        <1> 	mov	esi, str_files
  2349 00008E11 E80FE1FFFF          <1> 	call	print_msg
  2350 00008E16 BE[E51B0100]        <1> 	mov	esi, str_dirs
  2351 00008E1B E805E1FFFF          <1> 	call	print_msg
  2352 00008E20 8B35[CE6D0100]      <1> 	mov	esi, [TFS_Dec_Begin]
  2353 00008E26 E8FAE0FFFF          <1> 	call	print_msg
  2354 00008E2B BE[F61B0100]        <1> 	mov	esi, str_bytes
  2355 00008E30 E8F0E0FFFF          <1> 	call	print_msg
  2356                              <1> 
  2357 00008E35 C3                  <1> 	retn
  2358                              <1> 
  2359                              <1> pause_dir_scroll:
  2360 00008E36 28E4                <1> 	sub	ah, ah           
  2361 00008E38 E89880FFFF          <1> 	call	int16h
  2362 00008E3D 3C1B                <1> 	cmp	al, 1Bh
  2363 00008E3F 0F8428FFFFFF        <1>         je      loc_dir_ok
  2364 00008E45 C605[DD6D0100]10    <1> 	mov	byte [PrintDir_RowCounter], 16 ; Reset counter
  2365 00008E4C E911FFFFFF          <1>         jmp     loc_next_entry
  2366                              <1> 
  2367                              <1> find_first_file:
  2368                              <1> 	; 11/02/2016
  2369                              <1> 	; 10/02/2016
  2370                              <1> 	; 08/02/2016 (TRDOS 386 = TRDOS v2.0)
  2371                              <1> 	; 09/10/2011
  2372                              <1> 	; 17/09/2009
  2373                              <1> 	; 2005
  2374                              <1> 	; INPUT ->
  2375                              <1> 	;	ESI = ASCIIZ File/Dir Name Address (in Current Directory)
  2376                              <1> 	;	AL = Attributes AND mask (The AND result must be equal to AL)
  2377                              <1> 	;	      bit 0 = Read Only
  2378                              <1> 	;	      bir 1 = Hidden
  2379                              <1> 	;	      bit 2 = System
  2380                              <1> 	;	      bit 3 = Volume Label
  2381                              <1> 	;	      bit 4 = Directory
  2382                              <1> 	;	      bit 5 = Archive
  2383                              <1> 	;	      bit 6 = Reserved, must be 0
  2384                              <1> 	;	      bit 7 = Reserved, must be 0
  2385                              <1> 	;       AH = Attributes Negative AND mask (The AND result must be ZERO)
  2386                              <1> 	;
  2387                              <1> 	; OUTPUT ->
  2388                              <1> 	;	CF = 1 -> Error, Error Code in EAX (AL)
  2389                              <1> 	;	CF = 0 ->
  2390                              <1> 	;	     ESI = Directory Entry (FindFile_DirEntry) Location
  2391                              <1> 	;	     EDI = Directory Buffer Directory Entry Location
  2392                              <1> 	;	     EAX = File Size
  2393                              <1> 	;	      BL = Attributes of The File/Directory
  2394                              <1> 	;	      BH = Long Name Yes/No Status (>0 is YES)
  2395                              <1> 	;             DX > 0 : Ambiguous filename chars are used
  2396                              <1> 	;
  2397                              <1> 	; (EAX, EBX, ECX, EDX, ESI, EDI will be changed)
  2398                              <1> 
  2399 00008E51 66A3[8E6D0100]      <1> 	mov	[FindFile_AttributesMask], ax
  2400 00008E57 BF[906D0100]        <1> 	mov	edi, FindFile_DirEntry ; TR-DOS Fullfilename formatted buffer
  2401 00008E5C 31C0                <1> 	xor	eax, eax
  2402 00008E5E B90B000000          <1> 	mov	ecx, 11
  2403 00008E63 F3AB                <1> 	rep	stosd	; 44 bytes
  2404                              <1> 	;stosw		; +2 bytes 
  2405                              <1> 	    
  2406 00008E65 BF[806D0100]        <1> 	mov	edi, FindFile_Name ; FFF structure, offset 66
  2407 00008E6A 39FE                <1> 	cmp	esi, edi
  2408 00008E6C 7408                <1> 	je	short loc_fff_mfn_ok
  2409 00008E6E 89FA                <1> 	mov	edx, edi 
  2410                              <1> 	 ; move 13 bytes
  2411 00008E70 A5                  <1> 	movsd
  2412 00008E71 A5                  <1> 	movsd
  2413 00008E72 A5                  <1> 	movsd
  2414 00008E73 AA                  <1> 	stosb
  2415 00008E74 89D6                <1> 	mov	esi, edx
  2416                              <1> loc_fff_mfn_ok:
  2417 00008E76 BF[2F6D0100]        <1> 	mov	edi, Dir_Entry_Name ; Dir Entry Format File Name
  2418 00008E7B E8D7200000          <1> 	call	convert_file_name
  2419 00008E80 89FE                <1> 	mov	esi, edi ; offset Dir_Entry_Name
  2420                              <1> 
  2421 00008E82 66A1[8E6D0100]      <1> 	mov	ax, [FindFile_AttributesMask]
  2422                              <1> 	;xor	ecx, ecx
  2423 00008E88 30C9                <1> 	xor	cl, cl  
  2424 00008E8A E8D11D0000          <1> 	call	locate_current_dir_file
  2425 00008E8F 726E                <1> 	jc	short loc_fff_retn
  2426                              <1> 	; EDI = Directory Entry
  2427                              <1> 	; EBX = Directory Buffer Entry Index/Number
  2428                              <1> 
  2429                              <1> loc_fff_fnf_ln_check:
  2430 00008E91 30ED                <1> 	xor	ch, ch 
  2431 00008E93 80F60F              <1> 	xor	dh, 0Fh
  2432 00008E96 7408                <1> 	jz	short loc_fff_longname_yes
  2433 00008E98 882D[8D6D0100]      <1> 	mov	[FindFile_LongNameYes], ch ; 0
  2434 00008E9E EB0C                <1> 	jmp	short loc_fff_longname_no
  2435                              <1> 
  2436                              <1> loc_fff_longname_yes:
  2437                              <1> 	;inc	byte [FindFile_LongNameYes]
  2438 00008EA0 8A0D[9A6C0100]      <1> 	mov	cl, [LFN_EntryLength]  
  2439 00008EA6 880D[8D6D0100]      <1> 	mov	[FindFile_LongNameEntryLength], cl ; FindFile_LongNameYes
  2440                              <1> 
  2441                              <1> loc_fff_longname_no:
  2442                              <1> 	;mov	bx, [DirBuff_CurrentEntry]
  2443 00008EAC 66891D[B86D0100]    <1> 	mov	[FindFile_DirEntryNumber], bx
  2444 00008EB3 6689C2              <1> 	mov	dx, ax ; Ambiguous Filename chars used sign > 0
  2445                              <1> 
  2446 00008EB6 A0[9E640100]        <1> 	mov	al, [Current_Drv]
  2447 00008EBB A2[3E6D0100]        <1> 	mov	[FindFile_Drv], al 
  2448                              <1> 
  2449 00008EC0 A1[98640100]        <1> 	mov	eax, [Current_Dir_FCluster]
  2450 00008EC5 A3[B06D0100]        <1> 	mov	[FindFile_DirFirstCluster], eax
  2451                              <1> 
  2452 00008ECA A1[C96B0100]        <1> 	mov	eax, [DirBuff_Cluster]
  2453 00008ECF A3[B46D0100]        <1> 	mov	[FindFile_DirCluster], eax
  2454                              <1> 
  2455 00008ED4 66FF05[BA6D0100]    <1> 	inc	word [FindFile_MatchCounter]
  2456                              <1> 
  2457 00008EDB 89FB                <1> 	mov	ebx, edi
  2458 00008EDD 89FE                <1> 	mov	esi, edi
  2459 00008EDF BF[906D0100]        <1> 	mov	edi, FindFile_DirEntry
  2460 00008EE4 89F8                <1> 	mov	eax, edi
  2461 00008EE6 B108                <1> 	mov	cl, 8
  2462 00008EE8 F3A5                <1> 	rep	movsd
  2463 00008EEA 89C6                <1> 	mov	esi, eax
  2464 00008EEC 89DF                <1> 	mov	edi, ebx
  2465                              <1> 
  2466 00008EEE A1[AC6D0100]        <1> 	mov	eax, [FindFile_DirEntry+28] ; File Size
  2467                              <1> 
  2468 00008EF3 8A1D[9B6D0100]      <1> 	mov	bl, [FindFile_DirEntry+11] ; File Attributes 
  2469 00008EF9 8A3D[8D6D0100]      <1> 	mov	bh, [FindFile_LongNameYes]
  2470                              <1> 
  2471                              <1> 	;mov	cx, [DirBuff_EntryCounter]
  2472                              <1> 	;mov	[FindFile_DirEntryNumber], cx
  2473                              <1> 	;mov	cx, [FindFile_DirEntryNumber]
  2474                              <1> 	; ecx = 0
  2475                              <1> 
  2476                              <1> loc_fff_retn:
  2477 00008EFF C3                  <1> 	retn
  2478                              <1> 
  2479                              <1> find_next_file:
  2480                              <1> 	; 15/10/2016
  2481                              <1> 	; 10/02/2016
  2482                              <1> 	; 08/02/2016 (TRDOS 386 = TRDOS v2.0)
  2483                              <1> 	; 06/02/2011
  2484                              <1> 	; 17/09/2009
  2485                              <1> 	; 2005
  2486                              <1> 	; INPUT ->
  2487                              <1> 	;	NONE, Find First File Parameters
  2488                              <1> 	; OUTPUT ->
  2489                              <1> 	;	CF = 1 -> Error, Error Code in EAX (AL)
  2490                              <1> 	;	CF = 0 -> 
  2491                              <1> 	;	    ESI = Directory Entry (FindFile_DirEntry) Location
  2492                              <1> 	;	    EDI = Directory Buffer Directory Entry Location
  2493                              <1> 	;	    EAX = File Size
  2494                              <1> 	;	      BL = Attributes of The File/Directory
  2495                              <1> 	;	      BH = Long Name Yes/No Status (>0 is YES)
  2496                              <1> 	;             DX > 0 : Ambiguous filename chars are used 
  2497                              <1> 	;
  2498                              <1> 	; (EAX, EBX, ECX, EDX, ESI, EDI will be changed)
  2499                              <1> 
  2500 00008F00 66833D[BA6D0100]00  <1> 	cmp	word [FindFile_MatchCounter], 0
  2501 00008F08 7707                <1> 	ja	short loc_start_search_next_file
  2502                              <1> 
  2503                              <1> loc_fnf_stc_retn:
  2504 00008F0A F9                  <1> 	stc
  2505                              <1> loc_fnf_ax12h_retn:
  2506 00008F0B B80C000000          <1> 	mov	eax, 12 ; No More files
  2507                              <1> ;loc_fnf_retn:
  2508 00008F10 C3                  <1> 	retn
  2509                              <1> 
  2510                              <1> loc_start_search_next_file:
  2511 00008F11 668B1D[B86D0100]    <1> 	mov	bx, [FindFile_DirEntryNumber]
  2512 00008F18 6643                <1> 	inc	bx
  2513 00008F1A 663B1D[C76B0100]    <1> 	cmp	bx, [DirBuff_LastEntry]
  2514 00008F21 7719                <1> 	ja	short loc_cont_search_next_file
  2515                              <1> 
  2516                              <1> loc_fnf_search:
  2517 00008F23 BE[2F6D0100]        <1> 	mov	esi, Dir_Entry_Name
  2518 00008F28 66A1[8E6D0100]      <1> 	mov	ax, [FindFile_AttributesMask]
  2519 00008F2E 6631C9              <1> 	xor	cx, cx
  2520 00008F31 E82E1E0000          <1> 	call	find_directory_entry
  2521 00008F36 0F8355FFFFFF        <1>         jnc     loc_fff_fnf_ln_check
  2522                              <1> 
  2523                              <1> loc_cont_search_next_file:
  2524 00008F3C 31DB                <1> 	xor	ebx, ebx
  2525 00008F3E 8A3D[9E640100]      <1> 	mov	bh, [Current_Drv]
  2526 00008F44 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2527 00008F49 01DE                <1> 	add	esi, ebx
  2528                              <1> 
  2529 00008F4B 803D[9C640100]00    <1> 	cmp	byte [Current_Dir_Level], 0
  2530 00008F52 7608                <1> 	jna	short loc_fnf_check_FAT_type
  2531 00008F54 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  2532 00008F58 72B1                <1> 	jb	short loc_fnf_ax12h_retn
  2533 00008F5A EB06                <1> 	jmp	short loc_fnf_check_next_cluster
  2534                              <1>  
  2535                              <1> loc_fnf_check_FAT_type:
  2536 00008F5C 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3
  2537 00008F60 72A9                <1> 	jb	short loc_fnf_ax12h_retn
  2538                              <1> 
  2539                              <1> loc_fnf_check_next_cluster:
  2540 00008F62 A1[C96B0100]        <1> 	mov	eax, [DirBuff_Cluster]
  2541 00008F67 E8CA370000          <1> 	call	get_next_cluster
  2542 00008F6C 7306                <1> 	jnc	short loc_fnf_load_next_dir_cluster
  2543 00008F6E 09C0                <1> 	or	eax, eax
  2544 00008F70 7498                <1> 	jz	short loc_fnf_stc_retn
  2545                              <1> 	;mov	eax, 17 ;Drive not ready or read error
  2546 00008F72 F5                  <1>  	cmc	;stc
  2547                              <1> loc_fnf_retn:
  2548 00008F73 C3                  <1> 	retn
  2549                              <1> 
  2550                              <1> loc_fnf_load_next_dir_cluster:
  2551 00008F74 E8A3390000          <1> 	call	load_FAT_sub_directory
  2552 00008F79 72F8                <1> 	jc	short loc_fnf_retn
  2553 00008F7B 6631DB              <1> 	xor	bx, bx
  2554 00008F7E 66891D[B86D0100]    <1> 	mov	[FindFile_DirEntryNumber], bx
  2555 00008F85 EB9C                <1> 	jmp	short loc_fnf_search
  2556                              <1> 
  2557                              <1> get_and_print_longname:
  2558                              <1> 	; 16/10/2016
  2559                              <1> 	; 13/02/2016 (TRDOS 386 = TRDOS v2.0)
  2560                              <1> 	; 24/01/2010
  2561                              <1> 	; 17/10/2009 (CMD_INTR.ASM, 'cmp_cmd_longname')
  2562                              <1> get_longname_fchar:
  2563 00008F87 803E20              <1> 	cmp	byte [esi], 20h
  2564 00008F8A 7701                <1> 	ja	short loc_find_longname
  2565                              <1> 	;jb	short loc_longname_retn
  2566                              <1> 	;inc	esi
  2567                              <1> 	;je	short get_longname_fchar
  2568                              <1> ;loc_longname_retn:
  2569 00008F8C C3                  <1> 	retn
  2570                              <1> loc_find_longname:
  2571 00008F8D E839210000          <1> 	call	find_longname
  2572 00008F92 7328                <1> 	jnc	short loc_print_longname
  2573                              <1> 	
  2574 00008F94 08C0                <1> 	or	al, al
  2575 00008F96 741A                <1> 	jz	short loc_longname_not_found
  2576                              <1> 	  
  2577                              <1> 	; 16/10/2016 (15h -> 15, 17)
  2578 00008F98 3C0F                <1> 	cmp	al, 15
  2579 00008F9A 0F84B6F7FFFF        <1> 	je	cd_drive_not_ready ; drive not ready
  2580                              <1> 				   ; or
  2581 00008FA0 3C11                <1> 	cmp	al, 17		   ; read error	
  2582 00008FA2 0F84AEF7FFFF        <1> 	je	cd_drive_not_ready 
  2583                              <1> 
  2584                              <1> loc_ln_file_dir_not_found:
  2585 00008FA8 BE[211B0100]        <1> 	mov	esi, Msg_File_Directory_Not_Found
  2586                              <1> 	;call	print_msg	
  2587                              <1>         ;retn
  2588 00008FAD E973DFFFFF          <1> 	jmp	print_msg
  2589                              <1> 
  2590                              <1> loc_longname_not_found:
  2591 00008FB2 BE[401B0100]        <1>         mov     esi, Msg_LongName_Not_Found
  2592                              <1> 	;call	print_msg	
  2593                              <1>         ;retn
  2594 00008FB7 E969DFFFFF          <1> 	jmp	print_msg
  2595                              <1> 
  2596                              <1> loc_print_longname:
  2597                              <1> 	;mov	esi, LongFileName
  2598 00008FBC BF[9E650100]        <1> 	mov	edi, TextBuffer
  2599 00008FC1 57                  <1> 	push	edi 
  2600 00008FC2 3C00                <1> 	cmp	al, 0
  2601 00008FC4 7708                <1> 	ja	short loc_print_longname_1
  2602                              <1> loc_print_FS_longname: ; Singlix FS (64 byte ASCIIZ file name)
  2603 00008FC6 AC                  <1> 	lodsb
  2604 00008FC7 AA                  <1> 	stosb  
  2605 00008FC8 08C0                <1> 	or	al, al
  2606 00008FCA 75FA                <1> 	jnz	short loc_print_FS_longname
  2607 00008FCC EB07                <1> 	jmp	short loc_print_longname_2
  2608                              <1> 	;
  2609                              <1> loc_print_longname_1: ; MS Windows long name (UNICODE chars)
  2610 00008FCE 66AD                <1> 	lodsw
  2611 00008FD0 AA                  <1> 	stosb  
  2612 00008FD1 08C0                <1> 	or	al, al
  2613 00008FD3 75F9                <1> 	jnz	short loc_print_longname_1
  2614                              <1> 	;
  2615                              <1> loc_print_longname_2:	
  2616 00008FD5 5E                  <1> 	pop	esi
  2617 00008FD6 E84ADFFFFF          <1> 	call	print_msg
  2618 00008FDB BE[93240100]        <1>   	mov	esi, nextline
  2619                              <1> 	;call	print_msg
  2620                              <1> 	;retn
  2621 00008FE0 E940DFFFFF          <1> 	jmp	print_msg	
  2622                              <1> 
  2623                              <1> show_file:
  2624                              <1> 	; 18/02/2016
  2625                              <1> 	; 17/02/2016
  2626                              <1> 	; 15/02/2016 (TRDOS 386 = TRDOS v2.0)
  2627                              <1> 	; 13/09/2011 (CMD_INTR.ASM, 'cmp_cmd_show')
  2628                              <1> 	; 08/11/2009
  2629                              <1> 
  2630                              <1> loc_show_parse_path_name:
  2631 00008FE5 BF[3E6D0100]        <1> 	mov	edi, FindFile_Drv
  2632 00008FEA E833200000          <1> 	call	parse_path_name
  2633 00008FEF 0F824CF9FFFF        <1> 	jc	loc_cmd_failed
  2634                              <1> 
  2635                              <1> loc_show_check_filename_exists:
  2636 00008FF5 BE[806D0100]        <1> 	mov	esi, FindFile_Name
  2637 00008FFA 803E20              <1> 	cmp	byte [esi], 20h
  2638 00008FFD 0F863EF9FFFF        <1> 	jna	loc_cmd_failed
  2639                              <1> 
  2640                              <1> 	; 15/02/2016 (invalid file name check)
  2641 00009003 E807020000          <1> 	call	check_filename 	
  2642 00009008 730A                <1> 	jnc	short loc_show_change_drv
  2643                              <1> 
  2644 0000900A BE[0C1C0100]        <1> 	mov	esi, Msg_invalid_name_chars
  2645 0000900F E911DFFFFF          <1> 	jmp	print_msg
  2646                              <1>    
  2647                              <1> loc_show_change_drv:
  2648 00009014 8A35[9E640100]      <1> 	mov	dh, [Current_Drv]
  2649 0000901A 8835[FA6B0100]      <1> 	mov	[RUN_CDRV], dh
  2650 00009020 8A15[3E6D0100]      <1> 	mov	dl, [FindFile_Drv]
  2651 00009026 38F2                <1> 	cmp	dl, dh
  2652 00009028 740B                <1> 	je	short loc_show_change_directory
  2653 0000902A E87FEAFFFF          <1> 	call	change_current_drive
  2654                              <1> 	;jc	loc_file_rw_cmd_failed
  2655 0000902F 0F8237F9FFFF        <1> 	jc	loc_run_cmd_failed
  2656                              <1> 
  2657                              <1> loc_show_change_directory:
  2658 00009035 803D[3F6D0100]20    <1> 	cmp	byte [FindFile_Directory], 20h
  2659 0000903C 7618                <1> 	jna	short loc_findload_showfile
  2660                              <1> 
  2661 0000903E FE05[F6170100]      <1> 	inc	byte [Restore_CDIR]
  2662 00009044 BE[3F6D0100]        <1> 	mov	esi, FindFile_Directory
  2663 00009049 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2664 0000904B E8BC190000          <1> 	call	change_current_directory
  2665                              <1> 	;jc	loc_file_rw_cmd_failed
  2666 00009050 0F8216F9FFFF        <1> 	jc	loc_run_cmd_failed
  2667                              <1> 
  2668                              <1> ;loc_show_change_prompt_dir_string:
  2669                              <1> 	;call	change_prompt_dir_string
  2670                              <1> 
  2671                              <1> loc_findload_showfile:
  2672                              <1> 	; 15/02/2016
  2673 00009056 BE[806D0100]        <1> 	mov	esi, FindFile_Name
  2674 0000905B BF[2F6D0100]        <1> 	mov	edi, Dir_Entry_Name ; Dir Entry Format File Name
  2675 00009060 E8F21E0000          <1> 	call	convert_file_name
  2676 00009065 89FE                <1> 	mov	esi, edi ; offset Dir_Entry_Name
  2677                              <1> 
  2678 00009067 28C0                <1> 	sub	al, al	; Attrib AND mask = 0
  2679                              <1> 	; Directory attribute : 10h
  2680                              <1> 	; Volume name attribute: 8h
  2681 00009069 B418                <1> 	mov	ah, 00011000b ; 18h (Attrib NAND, AND --> zero mask)
  2682                              <1> 	;
  2683 0000906B 6631C9              <1> 	xor	cx, cx  
  2684 0000906E E8ED1B0000          <1> 	call	locate_current_dir_file
  2685                              <1> 	;jc	loc_file_rw_cmd_failed
  2686 00009073 0F82F3F8FFFF        <1> 	jc	loc_run_cmd_failed
  2687                              <1> 
  2688                              <1> loc_show_load_file:
  2689                              <1> 	; EDI = Directory Entry
  2690 00009079 668B4714            <1> 	mov	ax, [edi+DirEntry_FstClusHI] ; First Cluster High Word
  2691 0000907D C1E010              <1> 	shl	eax, 16
  2692 00009080 668B471A            <1> 	mov	ax, [edi+DirEntry_FstClusLO] ; First Cluster Low Word
  2693 00009084 A3[E86D0100]        <1> 	mov	[Show_Cluster], eax
  2694 00009089 8B471C              <1> 	mov	eax, [edi+DirEntry_FileSize] ; File Size
  2695 0000908C 21C0                <1> 	and	eax, eax ; Empty file !
  2696 0000908E 0F8491000000        <1>         jz      end_of_show_file 
  2697 00009094 A3[EC6D0100]        <1> 	mov	[Show_FileSize], eax
  2698 00009099 31C0                <1> 	xor	eax, eax
  2699 0000909B A3[F06D0100]        <1> 	mov	[Show_FilePointer], eax ; 0
  2700 000090A0 66A3[F46D0100]      <1> 	mov	[Show_ClusterPointer], ax ; 0
  2701 000090A6 29DB                <1> 	sub	ebx, ebx
  2702 000090A8 8A3D[9E640100]      <1> 	mov	bh, [Current_Drv]
  2703 000090AE BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2704 000090B3 01DE                <1> 	add	esi, ebx
  2705 000090B5 8935[E46D0100]      <1> 	mov	[Show_LDDDT], esi ; Logical DOS Drv Description Table addr
  2706                              <1> 
  2707 000090BB 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0	
  2708 000090BF 7713                <1> 	ja	short loc_show_calculate_cluster_size
  2709                              <1> 	; Singlix FS
  2710                              <1> 	; First Cluster Number is FDT number (in compatibility buffer)
  2711 000090C1 8B15[E86D0100]      <1> 	mov	edx, [Show_Cluster] ; Compatibility dir. buffer value (FDT)	
  2712 000090C7 8915[E06D0100]      <1> 	mov	[Show_FDT], edx
  2713 000090CD 31C0                <1> 	xor	eax, eax
  2714 000090CF A3[E86D0100]        <1> 	mov	[Show_Cluster], eax ; Sector index  = 0
  2715                              <1> 				    ; (next time it will be 1)			
  2716                              <1> loc_show_calculate_cluster_size:
  2717 000090D4 668B5E11            <1> 	mov	bx, [esi+LD_BPB+BPB_BytsPerSec] ; FAT 12-16-32 (512)
  2718                              <1> 	; BX = 512 = [esi+LD_FS_BytesPerSec] ; Singlix FS	
  2719 000090D8 8A4613              <1> 	mov	al, [esi+LD_BPB+BPB_SecPerClust] ; FAT 12-16-32 (<= 128)
  2720                              <1> 	; AL = 1 = [esi+LD_FS_Reserved2] ; SectPerClust for Singlix FS
  2721 000090DB F7E3                <1> 	mul	ebx	
  2722                              <1> 
  2723                              <1> 	;cmp	eax, 65536 ; non-compatible (very big) cluster size
  2724                              <1> 	;ja	short end_of_show_file	
  2725 000090DD 66A3[F66D0100]      <1> 	mov	[Show_ClusterSize], ax
  2726                              <1> 
  2727                              <1> loc_start_show_file:
  2728 000090E3 BE[93240100]        <1> 	mov	esi, nextline
  2729 000090E8 E838DEFFFF          <1> 	call	print_msg
  2730                              <1> 
  2731 000090ED A1[E86D0100]        <1> 	mov	eax, [Show_Cluster]
  2732 000090F2 C605[F86D0100]17    <1> 	mov	byte [Show_RowCount], 23
  2733                              <1> 
  2734                              <1> 	; 17/02/2016
  2735 000090F9 8B35[E46D0100]      <1> 	mov	esi, [Show_LDDDT]
  2736                              <1> 
  2737                              <1> loc_show_next_cluster:
  2738                              <1> 	; 15/02/2016
  2739 000090FF BB00000700          <1> 	mov	ebx, Cluster_Buffer ; 70000h (for current TRDOS 386 version)
  2740                              <1> 	; ESI = Logical DOS drv description table address
  2741 00009104 E851380000          <1> 	call	read_cluster
  2742                              <1> 	;jc	loc_file_rw_cmd_failed
  2743 00009109 0F825DF8FFFF        <1> 	jc	loc_run_cmd_failed
  2744                              <1> 
  2745 0000910F 31DB                <1> 	xor 	ebx, ebx
  2746                              <1> loc_show_next_byte:
  2747 00009111 803D[F86D0100]00    <1> 	cmp	byte [Show_RowCount], 0
  2748 00009118 7521                <1> 	jne	short pass_show_wait_for_key
  2749 0000911A 30E4                <1> 	xor	ah, ah
  2750 0000911C E8B47DFFFF          <1> 	call	int16h
  2751 00009121 3C1B                <1> 	cmp	al, 1Bh
  2752 00009123 750F                <1> 	jne	short pass_exit_show
  2753                              <1> end_of_show_file:
  2754                              <1> pass_show_file:
  2755 00009125 BE[93240100]        <1> 	mov	esi, nextline
  2756 0000912A E8F6DDFFFF          <1> 	call	print_msg
  2757 0000912F E94B010000          <1> 	jmp	loc_file_rw_restore_retn
  2758                              <1> 
  2759                              <1> pass_exit_show:
  2760 00009134 C605[F86D0100]14    <1> 	mov	byte [Show_RowCount], 20
  2761                              <1> pass_show_wait_for_key:
  2762 0000913B 81C300000700        <1> 	add	ebx, Cluster_Buffer
  2763 00009141 8A03                <1> 	mov	al, [ebx]
  2764 00009143 3C0D                <1> 	cmp	al, 0Dh
  2765 00009145 0F8590000000        <1>         jne     loc_show_check_tab_space
  2766 0000914B FE0D[F86D0100]      <1> 	dec	byte [Show_RowCount]
  2767                              <1> pass_show_dec_rowcount:
  2768 00009151 B307                <1> 	mov	bl, 7 ; (light gray character color, black background)
  2769 00009153 8A3D[06640100]      <1> 	mov	bh, [ACTIVE_PAGE] ; [ptty]
  2770 00009159 E89F90FFFF          <1> 	call	_write_tty
  2771                              <1> loc_show_check_eof:
  2772 0000915E FF05[F06D0100]      <1> 	inc	dword [Show_FilePointer]
  2773 00009164 A1[F06D0100]        <1> 	mov	eax, [Show_FilePointer]
  2774 00009169 3B05[EC6D0100]      <1> 	cmp	eax, [Show_FileSize]
  2775 0000916F 73B4                <1> 	jnb	short end_of_show_file
  2776 00009171 66FF05[F46D0100]    <1> 	inc	word [Show_ClusterPointer]
  2777 00009178 0FB71D[F46D0100]    <1> 	movzx	ebx, word [Show_ClusterPointer]
  2778                              <1> 
  2779                              <1> 	; 17/02/2016
  2780                              <1> 	; (sector boundary -9 bits- check, 512 = 0)
  2781 0000917F 66F7C3FF01          <1>         test    bx, 1FFh ;  1 to 511
  2782 00009184 758B                <1> 	jnz	short loc_show_next_byte
  2783                              <1> 
  2784                              <1> 	; 16/02/2016
  2785 00009186 8B35[E46D0100]      <1> 	mov	esi, [Show_LDDDT]
  2786                              <1> 	;
  2787 0000918C 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  2788 00009190 7719                <1> 	ja	short loc_show_check_fat_cluster_size
  2789                              <1> 
  2790                              <1> 	; Singlix FS
  2791                              <1> 	; 1 sector, more... (cluster size = 1 sector)
  2792 00009192 A1[E86D0100]        <1> 	mov	eax, [Show_Cluster]
  2793 00009197 40                  <1> 	inc	eax
  2794 00009198 A3[E86D0100]        <1> 	mov	[Show_Cluster], eax
  2795                              <1> 
  2796 0000919D 6621DB              <1> 	and	bx, bx ; 65536 -> 0
  2797 000091A0 0F856BFFFFFF        <1>         jnz	loc_show_next_byte
  2798 000091A6 E954FFFFFF          <1> 	jmp     loc_show_next_cluster
  2799                              <1> 	 
  2800                              <1> loc_show_check_fat_cluster_size:
  2801                              <1> 	; 17/02/2016
  2802 000091AB 663B1D[F66D0100]    <1> 	cmp	bx, [Show_ClusterSize] ; cluster size in bytes
  2803 000091B2 0F8259FFFFFF        <1>         jb	loc_show_next_byte
  2804 000091B8 66C705[F46D0100]00- <1> 	mov	word [Show_ClusterPointer], 0
  2804 000091C0 00                  <1>
  2805                              <1> 
  2806 000091C1 A1[E86D0100]        <1> 	mov	eax, [Show_Cluster]
  2807                              <1> 	;mov	esi, [Show_LDDDT]
  2808                              <1> loc_show_get_next_cluster:
  2809 000091C6 E86B350000          <1> 	call	get_next_cluster
  2810                              <1> 	;jc	loc_file_rw_cmd_failed
  2811 000091CB 0F829BF7FFFF        <1> 	jc	loc_run_cmd_failed
  2812                              <1> loc_show_update_ccluster:
  2813 000091D1 A3[E86D0100]        <1> 	mov	[Show_Cluster], eax			
  2814 000091D6 E924FFFFFF          <1>         jmp     loc_show_next_cluster
  2815                              <1> 
  2816                              <1> loc_show_check_tab_space:
  2817 000091DB 3C09                <1> 	cmp	al, 09h
  2818 000091DD 0F856EFFFFFF        <1>         jne     pass_show_dec_rowcount
  2819                              <1> loc_show_put_tab_space:
  2820 000091E3 8A3D[06640100]      <1> 	mov	bh, [ACTIVE_PAGE] ; [ptty]
  2821 000091E9 E88B8CFFFF          <1> 	call	get_cpos
  2822                              <1> 	; dl = cursor column
  2823 000091EE 80E207              <1> 	and	dl, 7 ; 18/02/2016
  2824                              <1> 	;shr	bh, 1 ; [ACTIVE_PAGE]
  2825 000091F1 8A3D[06640100]      <1> 	mov	bh, [ACTIVE_PAGE]
  2826 000091F7 B307                <1> 	mov	bl, 7 ; color attribute
  2827                              <1> loc_show_put_space_chars:
  2828 000091F9 B020                <1> 	mov	al, 20h ; space
  2829                              <1> 	;mov	bh, [ACTIVE_PAGE] ; [ptty]
  2830                              <1> 	;mov	bl, 7 ; color attribute
  2831                              <1> 	;push	dx
  2832 000091FB 52                  <1> 	push	edx ; 29/12/2017
  2833 000091FC E8FC8FFFFF          <1> 	call	_write_tty
  2834 00009201 5A                  <1> 	pop	edx ; 29/12/2017
  2835                              <1> 	;pop	dx
  2836                              <1> 	; 18/02/2016
  2837 00009202 80FA07              <1> 	cmp	dl, 7
  2838 00009205 0F8353FFFFFF        <1> 	jnb	loc_show_check_eof
  2839 0000920B FEC2                <1> 	inc	dl
  2840 0000920D EBEA                <1> 	jmp	short loc_show_put_space_chars
  2841                              <1> 
  2842                              <1> check_filename:
  2843                              <1> 	; 10/10/2016
  2844                              <1> 	; 15/02/2016 (TRDOS 386 = TRDOS v2.0)
  2845                              <1> 	; 07/08/2010 (FILE.ASM, 'proc_check_filename')
  2846                              <1> 	; 10/07/2010
  2847                              <1> 	; Derived from 'proc_check_filename'
  2848                              <1> 	; in the old TRDOS.ASM (09/02/2005).
  2849                              <1> 	;
  2850                              <1> 	; INPUT -> 
  2851                              <1> 	;	ESI = Dot File Name Location
  2852                              <1> 	; OUTPUT ->
  2853                              <1> 	;	cf = 1 -> error code in AL
  2854                              <1> 	;	     AL = ERR_INV_FILE_NAME (=26)
  2855                              <1> 	;		  Invalid file name chars   
  2856                              <1> 	;	cf = 0 -> valid file name
  2857                              <1> 	; 
  2858                              <1> 	;(EAX, ECX, EDI will be changed)
  2859                              <1> 
  2860                              <1> check_invalid_filename_chars:
  2861                              <1> 	; 15/02/2016 (TRDOS 386 = TRDOS v2.0)
  2862                              <1> 	; 10/07/2010 (FILE.ASM, 'proc_check_invalid_filename_chars')
  2863                              <1> 	; 10/02/2010
  2864                              <1> 	; Derived from 'proc_check_invalid_filename_chars'
  2865                              <1> 	; in the old TRDOS.ASM (09/02/2005).
  2866                              <1> 	;
  2867                              <1> 	; INPUT -> 
  2868                              <1> 	;	ESI = ASCIIZ FileName
  2869                              <1> 	; OUTPUT ->
  2870                              <1> 	;	cf = 1 -> invalid
  2871                              <1> 	;	cf = 0 -> valid
  2872                              <1> 	; 
  2873                              <1> 	;(EAX, ECX, EDI will be changed)
  2874                              <1>   
  2875 0000920F 56                  <1> 	push	esi
  2876                              <1> 
  2877 00009210 BF[F5180100]        <1>         mov     edi, invalid_fname_chars
  2878 00009215 AC                  <1> 	lodsb
  2879                              <1> check_filename_next_char:
  2880 00009216 B914000000          <1> 	mov	ecx, sizeInvFnChars
  2881 0000921B BF[F5180100]        <1> 	mov	edi, invalid_fname_chars
  2882                              <1> loc_scan_invalid_filename_char:
  2883 00009220 AE                  <1> 	scasb 
  2884 00009221 741F                <1> 	je	short loc_invalid_filename_stc 
  2885 00009223 E2FB                <1> 	loop	loc_scan_invalid_filename_char
  2886 00009225 AC                  <1> 	lodsb
  2887 00009226 3C1F                <1> 	cmp	al, 1Fh  ; 20h and above 
  2888 00009228 77EC                <1> 	ja	short check_filename_next_char
  2889                              <1> 
  2890                              <1> check_filename_dot:
  2891 0000922A 8B3424              <1> 	mov	esi, [esp]
  2892                              <1> 
  2893 0000922D B421                <1> 	mov	ah, 21h
  2894 0000922F B908000000          <1> 	mov	ecx, 8
  2895                              <1> loc_check_filename_next_char:
  2896 00009234 AC                  <1> 	lodsb
  2897 00009235 3C2E                <1> 	cmp	al, 2Eh
  2898 00009237 7511                <1> 	jne	short pass_check_fn_dot_check
  2899                              <1> loc_check_filename_ext_0:
  2900 00009239 AC                  <1> 	lodsb
  2901 0000923A 38E0                <1> 	cmp	al, ah ; 21h
  2902 0000923C 7205                <1> 	jb	short loc_invalid_filename
  2903 0000923E 3C2E                <1> 	cmp	al, 2Eh
  2904 00009240 7519                <1> 	jne	short loc_check_filename_ext_1
  2905                              <1> 
  2906                              <1> loc_invalid_filename_stc:
  2907                              <1> loc_check_fn_stc_rtn:
  2908 00009242 F9                  <1> 	stc
  2909                              <1> loc_invalid_filename:
  2910                              <1> 	; 10/10/2016 (0Bh -> 26)
  2911 00009243 B81A000000          <1> 	mov	eax, ERR_INV_FILE_NAME ; (=26)
  2912                              <1> 	; Invalid file name chars
  2913                              <1> loc_check_fn_rtn:
  2914 00009248 5E                  <1> 	pop	esi
  2915 00009249 C3                  <1> 	retn
  2916                              <1> 
  2917                              <1> pass_check_fn_dot_check:
  2918 0000924A 38E0                <1> 	cmp	al, ah ; 21h
  2919 0000924C 7224                <1> 	jb	short loc_check_fn_clc_rtn
  2920 0000924E E2E4                <1> 	loop	loc_check_filename_next_char
  2921 00009250 AC                  <1> 	lodsb
  2922 00009251 38E0                <1> 	cmp	al, ah ; 21h
  2923 00009253 721D                <1> 	jb	short loc_check_fn_clc_rtn
  2924 00009255 3C2E                <1> 	cmp	al, 2Eh
  2925 00009257 75E9                <1> 	jne	short loc_check_fn_stc_rtn
  2926 00009259 EBDE                <1> 	jmp	short loc_check_filename_ext_0
  2927                              <1> 
  2928                              <1> loc_check_filename_ext_1:
  2929 0000925B AC                  <1> 	lodsb
  2930 0000925C 38E0                <1> 	cmp	al, ah ; 21h
  2931 0000925E 7212                <1> 	jb	short loc_check_fn_clc_rtn
  2932 00009260 3C2E                <1> 	cmp	al, 2Eh
  2933 00009262 74DE                <1> 	je	short loc_check_fn_stc_rtn
  2934 00009264 AC                  <1> 	lodsb
  2935 00009265 38E0                <1> 	cmp	al, ah ; 21h
  2936 00009267 7209                <1> 	jb	short loc_check_fn_clc_rtn
  2937 00009269 3C2E                <1> 	cmp	al, 2Eh
  2938 0000926B 74D5                <1> 	je	short loc_check_fn_stc_rtn
  2939 0000926D AC                  <1> 	lodsb
  2940 0000926E 38E0                <1> 	cmp	al, ah ; 21h
  2941 00009270 73D0                <1> 	jnb	short loc_check_fn_stc_rtn
  2942                              <1> 
  2943                              <1> loc_check_fn_clc_rtn:
  2944 00009272 5E                  <1> 	pop	esi
  2945 00009273 F8                  <1> 	clc
  2946 00009274 C3                  <1> 	retn
  2947                              <1> 
  2948                              <1> loc_print_deleted_message:
  2949 00009275 BE[E11C0100]        <1> 	mov	esi, Msg_Deleted
  2950 0000927A E8A6DCFFFF          <1> 	call	print_msg
  2951                              <1> 
  2952                              <1> 	;clc
  2953                              <1> 
  2954                              <1> loc_file_rw_restore_retn:
  2955                              <1> 	; 15/02/2016 (TRDOS 386 = TRDOS v2.0)
  2956                              <1> 	; 28/02/2010 (CMD_INTR.ASM)
  2957                              <1> loc_file_rw_cmd_failed:
  2958 0000927F 9C                  <1> 	pushf 
  2959 00009280 E84FF7FFFF          <1> 	call	restore_cdir_after_cmd_fail	
  2960 00009285 9D                  <1> 	popf
  2961 00009286 720D                <1> 	jc	short loc_file_rw_check_write_fault
  2962 00009288 C3                  <1> 	retn
  2963                              <1> 
  2964                              <1> loc_permission_denied:
  2965                              <1> 	; 27/02/2016
  2966 00009289 BE[EE1C0100]        <1> 	mov	esi, Msg_Permission_Denied
  2967 0000928E E892DCFFFF          <1> 	call	print_msg
  2968 00009293 EBEA                <1> 	jmp	short loc_file_rw_restore_retn
  2969                              <1> 
  2970                              <1> loc_file_rw_check_write_fault:
  2971                              <1> 	;cmp	al, 1Dh ; Write Fault
  2972 00009295 3C12                <1>         cmp	al, 18 ; 05/11/2016
  2973 00009297 0F85D4F6FFFF        <1> 	jne     loc_run_cmd_failed_cmp_al
  2974 0000929D BE[D61A0100]        <1> 	mov	esi, Msg_Not_Ready_Write_Err
  2975                              <1> 	;call	print_msg
  2976                              <1> 	;retn
  2977 000092A2 E97EDCFFFF          <1> 	jmp	print_msg
  2978                              <1> 
  2979                              <1> make_directory:
  2980                              <1> 	; 21/02/2016 (TRDOS 386 = TRDOS v2.0)
  2981                              <1> 	; 12/03/2011 (CMD_INTR.ASM, 'cmp_cmd_mkdir')
  2982                              <1> 	; 14/08/2010
  2983                              <1> 	; 10/07/2010
  2984                              <1> 	; 29/11/2009
  2985                              <1> 	;
  2986                              <1> get_mkdir_fchar:
  2987                              <1> 	; esi = directory name
  2988 000092A7 803E20              <1> 	cmp	byte [esi], 20h
  2989 000092AA 7701                <1>         ja	short loc_mkdir_parse_path_name
  2990                              <1> 
  2991                              <1> loc_mkdir_nodirname_retn:
  2992 000092AC C3                  <1> 	retn
  2993                              <1> 
  2994                              <1> loc_mkdir_parse_path_name:
  2995 000092AD BF[3E6D0100]        <1> 	mov	edi, FindFile_Drv
  2996 000092B2 E86B1D0000          <1>         call    parse_path_name
  2997 000092B7 0F8284F6FFFF        <1> 	jc	loc_cmd_failed
  2998                              <1> 
  2999                              <1> loc_mkdir_check_dirname_exists:
  3000 000092BD BE[806D0100]        <1> 	mov	esi, FindFile_Name
  3001 000092C2 803E20              <1> 	cmp	byte [esi], 20h
  3002 000092C5 0F8676F6FFFF        <1> 	jna	loc_cmd_failed
  3003 000092CB 8935[FC6D0100]      <1> 	mov	[DelFile_FNPointer], esi
  3004 000092D1 E839FFFFFF          <1> 	call	check_filename
  3005 000092D6 7259                <1> 	jc	short loc_mkdir_invalid_dir_name_chars
  3006                              <1> 
  3007                              <1> loc_mkdir_drv:
  3008 000092D8 8A35[9E640100]      <1> 	mov	dh, [Current_Drv]
  3009 000092DE 8835[FA6B0100]      <1> 	mov	[RUN_CDRV], dh
  3010                              <1> 	
  3011 000092E4 8A15[3E6D0100]      <1> 	mov	dl, [FindFile_Drv]
  3012 000092EA 38F2                <1> 	cmp	dl, dh
  3013 000092EC 7407                <1> 	je	short loc_mkdir_change_directory
  3014                              <1> 
  3015 000092EE E8BBE7FFFF          <1> 	call	change_current_drive
  3016 000092F3 728A                <1> 	jc	loc_file_rw_cmd_failed
  3017                              <1> 
  3018                              <1> loc_mkdir_change_directory:
  3019 000092F5 803D[3F6D0100]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3020 000092FC 7614                <1> 	jna	short loc_mkdir_find_directory
  3021                              <1> 
  3022 000092FE FE05[F6170100]      <1> 	inc	byte [Restore_CDIR]
  3023 00009304 BE[3F6D0100]        <1> 	mov	esi, FindFile_Directory
  3024 00009309 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3025 0000930B E8FC160000          <1> 	call	change_current_directory
  3026 00009310 722E                <1> 	jc	short loc_mkdir_check_error_code
  3027                              <1> 
  3028                              <1> ;loc_mkdir_change_prompt_dir_string:
  3029                              <1> 	;call	change_prompt_dir_string
  3030                              <1> 
  3031                              <1> loc_mkdir_find_directory:
  3032                              <1> 	;mov	esi, FindFile_Name
  3033 00009312 8B35[FC6D0100]      <1> 	mov	esi, [DelFile_FNPointer]
  3034                              <1> 	;xor	eax, eax
  3035 00009318 6631C0              <1> 	xor	ax, ax ; any name (dir, file, volume)
  3036 0000931B E831FBFFFF          <1> 	call	find_first_file
  3037 00009320 721E                <1> 	jc	short loc_mkdir_check_error_code
  3038                              <1> 
  3039                              <1> loc_mkdir_directory_found:
  3040 00009322 BE[391C0100]        <1> 	mov	esi, Msg_Name_Exists
  3041 00009327 E8F9DBFFFF          <1> 	call	print_msg
  3042                              <1> 
  3043 0000932C E94EFFFFFF          <1>         jmp     loc_file_rw_restore_retn
  3044                              <1> 
  3045                              <1> loc_mkdir_invalid_dir_name_chars:
  3046 00009331 BE[0C1C0100]        <1> 	mov	esi, Msg_invalid_name_chars
  3047 00009336 E8EADBFFFF          <1> 	call	print_msg
  3048                              <1> 
  3049 0000933B E93FFFFFFF          <1>         jmp     loc_file_rw_restore_retn
  3050                              <1> 
  3051                              <1> loc_mkdir_check_error_code:
  3052 00009340 3C02                <1> 	cmp	al, 2
  3053                              <1> 	;je	short loc_mkdir_directory_not_found
  3054 00009342 7406                <1> 	je	short loc_mkdir_ask_for_yes_no
  3055 00009344 F9                  <1> 	stc
  3056 00009345 E935FFFFFF          <1>         jmp     loc_file_rw_cmd_failed
  3057                              <1> 
  3058                              <1> loc_mkdir_directory_not_found:
  3059                              <1> loc_mkdir_ask_for_yes_no:
  3060 0000934A BE[5A1C0100]        <1> 	mov	esi, Msg_DoYouWantMkdir
  3061 0000934F E8D1DBFFFF          <1> 	call	print_msg
  3062 00009354 8B35[FC6D0100]      <1> 	mov	esi, [DelFile_FNPointer]
  3063 0000935A E8C6DBFFFF          <1> 	call	print_msg
  3064 0000935F BE[791C0100]        <1> 	mov	esi, Msg_YesNo
  3065 00009364 E8BCDBFFFF          <1> 	call	print_msg
  3066                              <1> 
  3067 00009369 C605[831C0100]20    <1> 	mov	byte [Y_N_nextline], 20h
  3068                              <1> 
  3069                              <1> loc_mkdir_ask_again:
  3070 00009370 30E4                <1> 	xor	ah, ah
  3071 00009372 E85E7BFFFF          <1> 	call	int16h
  3072 00009377 3C1B                <1> 	cmp	al, 1Bh
  3073                              <1> 	;je	short loc_do_not_make_directory
  3074 00009379 7439                <1> 	je	short loc_mkdir_y_n_escape
  3075 0000937B 24DF                <1> 	and	al, 0DFh ; y -> Y, n -> N
  3076 0000937D 3C59                <1> 	cmp	al, 'Y' ; 'yes'
  3077 0000937F 7404                <1> 	je	short loc_mkdir_yes_make_directory
  3078 00009381 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3079 00009383 75EB                <1> 	jne	short loc_mkdir_ask_again
  3080                              <1> 
  3081                              <1> loc_do_not_make_directory:
  3082                              <1> loc_mkdir_yes_make_directory:
  3083 00009385 E82E000000          <1> 	call	y_n_answer ; 29/12/2017
  3084                              <1> 	;cmp	al, 'Y' ; 'yes'
  3085                              <1> 	;cmc
  3086                              <1>         ;jnc	loc_file_rw_restore_retn
  3087 0000938A 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3088 0000938C 0F84EDFEFFFF        <1>         je	loc_file_rw_restore_retn  
  3089                              <1> 
  3090                              <1> loc_mkdir_call_make_sub_directory:
  3091 00009392 8B35[FC6D0100]      <1> 	mov	esi, [DelFile_FNPointer]
  3092 00009398 B110                <1> 	mov	cl, 10h ; Directory attributes 
  3093 0000939A E8821D0000          <1> 	call	make_sub_directory
  3094                              <1> loc_rename_file_ok: ; 06/03/2016
  3095 0000939F 0F82DAFEFFFF        <1>         jc	loc_file_rw_cmd_failed
  3096                              <1> move_source_file_to_destination_OK:
  3097 000093A5 BE[871C0100]        <1> 	mov	esi, Msg_OK
  3098 000093AA E876DBFFFF          <1> 	call	print_msg
  3099 000093AF E9CBFEFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3100                              <1> 
  3101                              <1> loc_mkdir_y_n_escape:
  3102 000093B4 B04E                <1> 	mov	al, 'N' ; 'no'
  3103 000093B6 EBCD                <1> 	jmp	short loc_do_not_make_directory
  3104                              <1> 
  3105                              <1> y_n_answer:
  3106                              <1> 	; 29/12/2017
  3107 000093B8 A2[831C0100]        <1> 	mov	[Y_N_nextline], al
  3108                              <1> 	;push	ax
  3109 000093BD 50                  <1> 	push	eax
  3110 000093BE BE[831C0100]        <1> 	mov	esi, Y_N_nextline
  3111 000093C3 E85DDBFFFF          <1> 	call	print_msg
  3112 000093C8 58                  <1> 	pop	eax
  3113                              <1> 	;pop	ax
  3114 000093C9 C3                  <1> 	retn
  3115                              <1> 
  3116                              <1> delete_directory:
  3117                              <1> 	; 29/12/2017
  3118                              <1> 	; 15/10/2016
  3119                              <1> 	; 01/03/2016, 06/03/2016
  3120                              <1> 	; 27/02/2016, 28/02/2016, 29/02/2016
  3121                              <1> 	; 26/02/2016 (TRDOS 386 = TRDOS v2.0)
  3122                              <1> 	; 16/10/2010 (CMD_INTR.ASM, 'cmp_cmd_rmdir')
  3123                              <1> 	; 05/06/2010
  3124                              <1> 	;
  3125                              <1> get_fchar:
  3126                              <1> 	; esi = directory name
  3127 000093CA 803E20              <1> 	cmp	byte [esi], 20h
  3128 000093CD 7701                <1>         ja	short loc_rmdir_parse_path_name
  3129                              <1> 
  3130                              <1> loc_rmdir_nodirname_retn:
  3131 000093CF C3                  <1> 	retn
  3132                              <1> 
  3133                              <1> loc_rmdir_parse_path_name:
  3134 000093D0 BF[3E6D0100]        <1> 	mov	edi, FindFile_Drv
  3135 000093D5 E8481C0000          <1> 	call	parse_path_name
  3136 000093DA 0F8261F5FFFF        <1> 	jc	loc_cmd_failed
  3137                              <1> 
  3138                              <1> loc_rmdir_check_dirname_exists:
  3139 000093E0 BE[806D0100]        <1> 	mov	esi, FindFile_Name
  3140 000093E5 803E20              <1> 	cmp	byte [esi], 20h
  3141 000093E8 0F8653F5FFFF        <1> 	jna	loc_cmd_failed
  3142 000093EE 8935[FC6D0100]      <1> 	mov	[DelFile_FNPointer], esi 
  3143                              <1> 
  3144                              <1> loc_rmdir_drv:
  3145 000093F4 8A35[9E640100]      <1> 	mov	dh, [Current_Drv]
  3146 000093FA 8835[FA6B0100]      <1> 	mov	[RUN_CDRV], dh
  3147                              <1> 
  3148 00009400 8A15[3E6D0100]      <1> 	mov	dl, [FindFile_Drv]
  3149 00009406 38F2                <1> 	cmp	dl, dh
  3150 00009408 740B                <1> 	je	short loc_rmdir_change_directory
  3151                              <1> 
  3152 0000940A E89FE6FFFF          <1> 	call	change_current_drive
  3153 0000940F 0F826AFEFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3154                              <1> 
  3155                              <1> loc_rmdir_change_directory:
  3156 00009415 803D[3F6D0100]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3157 0000941C 7614                <1> 	jna	short loc_rmdir_find_directory
  3158                              <1> 
  3159 0000941E FE05[F6170100]      <1> 	inc	byte [Restore_CDIR]
  3160 00009424 BE[3F6D0100]        <1> 	mov	esi, FindFile_Directory
  3161 00009429 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3162 0000942B E8DC150000          <1> 	call	change_current_directory
  3163 00009430 7211                <1> 	jc	short loc_rmdir_check_error_code
  3164                              <1> 
  3165                              <1> ;loc_rmdir_change_prompt_dir_string:
  3166                              <1> 	;call	change_prompt_dir_string
  3167                              <1> 
  3168                              <1> loc_rmdir_find_directory:
  3169                              <1> 	;mov	esi, FindFile_Name
  3170 00009432 8B35[FC6D0100]      <1> 	mov	esi, [DelFile_FNPointer]
  3171 00009438 66B81008            <1> 	mov	ax, 0810h ; Only directories
  3172 0000943C E810FAFFFF          <1> 	call	find_first_file
  3173 00009441 730A                <1> 	jnc	short loc_rmdir_ambgfn_check
  3174                              <1> 
  3175                              <1> loc_rmdir_check_error_code:
  3176 00009443 3C02                <1> 	cmp	al, 2
  3177 00009445 740B                <1> 	je	short loc_rmdir_directory_not_found
  3178 00009447 F9                  <1> 	stc
  3179 00009448 E932FEFFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3180                              <1> 
  3181                              <1> loc_rmdir_ambgfn_check:
  3182 0000944D 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3183 00009450 740F                <1> 	jz	short loc_rmdir_directory_found
  3184                              <1> 
  3185                              <1> loc_rmdir_directory_not_found:
  3186 00009452 BE[F81A0100]        <1> 	mov	esi, Msg_Dir_Not_Found
  3187 00009457 E8C9DAFFFF          <1> 	call	print_msg
  3188                              <1> 
  3189 0000945C E91EFEFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3190                              <1> 
  3191                              <1> loc_rmdir_directory_found:
  3192 00009461 80E307              <1> 	and	bl, 07h ; Attributes
  3193 00009464 0F851FFEFFFF        <1> 	jnz	loc_permission_denied
  3194                              <1> 
  3195                              <1> loc_rmdir_save_lnel: ; 28/02/2016
  3196                              <1>        ;mov	bh, [LongName_EntryLength]
  3197 0000946A 883D[066E0100]      <1> 	mov	[DelFile_LNEL], bh ; Long name entry length (if > 0)
  3198                              <1> 	; edi = Directory Entry Offset (DirBuff)
  3199                              <1> 	; esi = Directory Entry (FFF Structure)
  3200                              <1> 	;mov	[DelFile_DirEntryAddr], edi ; not required
  3201                              <1> 	;mov	ax, [edi+20] ; First Cluster High Word
  3202                              <1>         ;shl	eax, 16
  3203                              <1> 	;mov	ax, [edi+26] ; First Cluster Low Word
  3204                              <1> 	; ROOT Dir First Cluster = 0
  3205                              <1>         ;cmp	eax, 2
  3206                              <1> 	;jb	loc_update_direntry_1
  3207                              <1> 
  3208                              <1> pass_rmdir_fc_check:
  3209 00009470 57                  <1> 	push	edi ; * (29/02/2016)
  3210                              <1> 
  3211 00009471 BE[8D1C0100]        <1> 	mov	esi, Msg_DoYouWantRmDir
  3212 00009476 E8AADAFFFF          <1> 	call	print_msg
  3213 0000947B 8B35[FC6D0100]      <1> 	mov	esi, [DelFile_FNPointer]
  3214 00009481 E89FDAFFFF          <1> 	call	print_msg
  3215 00009486 BE[791C0100]        <1> 	mov	esi, Msg_YesNo
  3216 0000948B E895DAFFFF          <1> 	call	print_msg
  3217                              <1> 
  3218                              <1> loc_rmdir_ask_again:
  3219 00009490 30E4                <1> 	xor	ah, ah
  3220 00009492 E83E7AFFFF          <1> 	call	int16h
  3221 00009497 3C1B                <1> 	cmp	al, 1Bh
  3222                              <1> 	;je	short loc_do_not_delete_directory
  3223 00009499 7433                <1>         je      loc_rmdir_y_n_escape ; 06/03/2016
  3224 0000949B 24DF                <1> 	and	al, 0DFh
  3225 0000949D A2[831C0100]        <1> 	mov	[Y_N_nextline], al
  3226 000094A2 3C59                <1> 	cmp	al, 'Y'
  3227 000094A4 7404                <1> 	je	short loc_rmdir_yes_delete_directory
  3228 000094A6 3C4E                <1> 	cmp	al, 'N'
  3229 000094A8 75E6                <1> 	jne	short loc_rmdir_ask_again
  3230                              <1> 
  3231                              <1> loc_do_not_delete_directory:
  3232                              <1> loc_rmdir_yes_delete_directory:
  3233 000094AA E809FFFFFF          <1> 	call	y_n_answer ; 29/12/2017
  3234 000094AF 5F                  <1> 	pop	edi ; * (29/02/2016)
  3235                              <1> 	;cmp	al, 'Y' ; 'yes'
  3236                              <1> 	;cmc
  3237                              <1>         ;jnc	loc_file_rw_restore_retn
  3238 000094B0 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3239 000094B2 0F84C7FDFFFF        <1>         je	loc_file_rw_restore_retn 
  3240                              <1> 
  3241                              <1> 	; 29/12/2017
  3242 000094B8 E869000000          <1> 	call	delete_sub_directory
  3243 000094BD 7213                <1> 	jc	short loc_rmdir_cmd_failed
  3244                              <1> 
  3245                              <1> loc_rmdir_ok:
  3246 000094BF BE[871C0100]        <1> 	mov	esi, Msg_OK
  3247 000094C4 E85CDAFFFF          <1> 	call	print_msg
  3248 000094C9 E9B1FDFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3249                              <1> 
  3250                              <1> loc_rmdir_y_n_escape:
  3251 000094CE B04E                <1> 	mov	al, 'N' ; 'no'
  3252 000094D0 EBD8                <1>         jmp     loc_do_not_delete_directory
  3253                              <1> 
  3254                              <1> loc_rmdir_cmd_failed:
  3255                              <1> 	; 29/12/2017
  3256 000094D2 09C0                <1> 	or	eax, eax ; EAX = 0 -> Directory not empty!
  3257 000094D4 7426                <1> 	jz	short loc_rmdir_directory_not_empty
  3258                              <1> 
  3259                              <1> 	; EAX > 0 -> Error code in AL (or AX or EAX)
  3260                              <1> 
  3261 000094D6 833D[BA6B0100]01    <1> 	cmp	dword [FAT_ClusterCounter], 1
  3262 000094DD 0F829CFDFFFF        <1> 	jb	loc_file_rw_cmd_failed	
  3263 000094E3 F9                  <1> 	stc
  3264                              <1> loc_rmdir_cmd_return:
  3265                              <1> 	; 01/03/2016
  3266 000094E4 9C                  <1> 	pushf
  3267                              <1> 	; ESI = Logical DOS Drive Description Table address	
  3268 000094E5 66BB00FF            <1> 	mov	bx, 0FF00h ; BH = FFh -> use ESI for Drive parameters
  3269                              <1> 	           ; BL = 0 -> Recalculate free cluster count
  3270 000094E9 50                  <1> 	push	eax
  3271 000094EA E8C3380000          <1> 	call	calculate_fat_freespace	
  3272 000094EF 58                  <1> 	pop	eax
  3273 000094F0 9D                  <1> 	popf
  3274 000094F1 0F8288FDFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3275 000094F7 E983FDFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3276                              <1> 
  3277                              <1> loc_rmdir_directory_not_empty:
  3278 000094FC BE[AE1C0100]        <1> 	mov	esi, Msg_Dir_Not_Empty
  3279 00009501 E81FDAFFFF          <1> 	call	print_msg
  3280                              <1> 	; 01/03/2016
  3281 00009506 A1[BA6B0100]        <1> 	mov	eax, [FAT_ClusterCounter]
  3282 0000950B 09C0                <1> 	or	eax, eax ; 0 ?
  3283 0000950D 0F846CFDFFFF        <1> 	jz	loc_file_rw_restore_retn
  3284                              <1> 	; ESI = Logical DOS Drive Description Table address	
  3285 00009513 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> use ESI for Drive parameters
  3286                              <1> 	           ; BL = 1 -> add free clusters
  3287 00009517 E896380000          <1> 	call	calculate_fat_freespace
  3288 0000951C 09C9                <1> 	or	ecx, ecx
  3289 0000951E 0F845BFDFFFF        <1>         jz      loc_file_rw_restore_retn ; ecx = 0 -> OK
  3290                              <1> 	; ecx > 0 -> Error (Recalculation is needed)
  3291 00009524 EBBE                <1> 	jmp	short loc_rmdir_cmd_return
  3292                              <1> 
  3293                              <1> 
  3294                              <1> delete_sub_directory:
  3295                              <1> 	; 29/12/2017 
  3296                              <1> 	; (moved here from 'delete_directory' for 'sysrmdir' )
  3297                              <1> 
  3298                              <1> 	; EDI = Directory buffer entry offset/address
  3299                              <1> 
  3300                              <1> loc_rmdir_delete_short_name_check_dir_empty:
  3301 00009526 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  3302 0000952A C1E010              <1>         shl	eax, 16
  3303 0000952D 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  3304                              <1> 
  3305                              <1> 	;mov 	[DelFile_FCluster], eax
  3306                              <1> 
  3307                              <1> 	;;mov	bx, [DirBuff_EntryCounter]
  3308                              <1> 	;mov	bx, [FindFile_DirEntryNumber] ; 27/02/2016
  3309                              <1> 	;mov	[DelFile_EntryCounter], bx
  3310                              <1> 
  3311 00009531 29DB                <1>     	sub	ebx, ebx
  3312                              <1> 	; 29/12/2017
  3313 00009533 891D[BA6B0100]      <1> 	mov	[FAT_ClusterCounter], ebx ; 0 ; Reset
  3314                              <1> 
  3315 00009539 8A3D[3E6D0100]      <1> 	mov	bh, [FindFile_Drv]
  3316 0000953F BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3317 00009544 01DE                <1> 	add	esi, ebx
  3318                              <1> 
  3319 00009546 66817F0CA101        <1> 	cmp	word [edi+DirEntry_NTRes], 01A1h
  3320 0000954C 745A                <1> 	je	short loc_rmdir_check_fs_directory
  3321                              <1> 
  3322                              <1> 	;cmp	byte [esi+LD_FATType], 1
  3323                              <1> 	;jb	short loc_rmdir_get__last_cluster_0
  3324                              <1> 
  3325                              <1> 	; 29/12/2017
  3326 0000954E 83F802              <1> 	cmp	eax, 2
  3327 00009551 7306                <1> 	jnb	short loc_rmdir_get_last_cluster_1
  3328                              <1> 	; eax < 2
  3329                              <1> loc_rmdir_get_last_cluster_0:
  3330                              <1> 	;mov	eax, ERR_INV_FORMAT ; invalid format!
  3331 00009553 B813000000          <1> 	mov	eax, ERR_NOT_DIR ; not a valid directory!
  3332                              <1> 	;stc
  3333 00009558 C3                  <1> 	retn
  3334                              <1> 
  3335                              <1> loc_rmdir_get_last_cluster_1:
  3336 00009559 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3 ; FAT32
  3337 0000955D 750C                <1> 	jne	short loc_rmdir_get_last_cluster_2
  3338                              <1> 
  3339                              <1> 	; is it root directory ?
  3340 0000955F 3B4632              <1> 	cmp	eax, [esi+LD_BPB+BPB_RootClus]
  3341 00009562 7507                <1> 	jne	short loc_rmdir_get_last_cluster_2
  3342                              <1> 
  3343                              <1> 	; root directory can not be deleted !!
  3344                              <1> loc_rmdir_permission_denied:
  3345 00009564 B80B000000          <1> 	mov	eax, ERR_PERM_DENIED ; permission denied!
  3346 00009569 F9                  <1> 	stc
  3347 0000956A C3                  <1> 	retn		
  3348                              <1> 
  3349                              <1> loc_rmdir_get_last_cluster_2:
  3350                              <1> 	; 29/12/2017
  3351 0000956B A3[006E0100]        <1> 	mov 	[DelFile_FCluster], eax
  3352                              <1> 	
  3353                              <1> 	;mov	dx, [DirBuff_EntryCounter]
  3354 00009570 668B15[B86D0100]    <1> 	mov	dx, [FindFile_DirEntryNumber] ; 27/02/2016
  3355 00009577 668915[046E0100]    <1> 	mov	[DelFile_EntryCounter], dx
  3356                              <1> 	
  3357 0000957E 8B15[C96B0100]      <1> 	mov	edx, [DirBuff_Cluster]
  3358 00009584 8915[306E0100]      <1> 	mov	[RmDir_ParentDirCluster], edx
  3359                              <1> 
  3360 0000958A 893D[2C6E0100]      <1> 	mov	[RmDir_DirEntryOffset], edi
  3361                              <1> 
  3362                              <1> 	; 01/03/2016
  3363                              <1> 	;mov	dword [FAT_ClusterCounter], 0 ; Reset
  3364                              <1> 
  3365                              <1> loc_rmdir_get_last_cluster_3:
  3366 00009590 E89C390000          <1> 	call	get_last_cluster
  3367                              <1>         ;jc	loc_rmdir_cmd_failed
  3368 00009595 721E                <1> 	jc	short loc_delete_sub_dir_retn ; 29/12/2017
  3369                              <1> 	
  3370 00009597 3B05[006E0100]      <1> 	cmp	eax, [DelFile_FCluster]
  3371 0000959D 7517                <1> 	jne	short loc_rmdir_multi_dir_clusters
  3372                              <1> 
  3373 0000959F C605[2B6E0100]00    <1> 	mov	byte [RmDir_MultiClusters], 0
  3374 000095A6 EB15                <1> 	jmp	short pass_rmdir_multi_dir_clusters
  3375                              <1> 
  3376                              <1> loc_rmdir_check_fs_directory:
  3377                              <1> 	; 29/12/2017
  3378 000095A8 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  3379 000095AC 75B6                <1> 	jne	short loc_rmdir_permission_denied
  3380                              <1> 
  3381                              <1> loc_rmdir_delete_fs_directory:
  3382 000095AE E876130000          <1> 	call	delete_fs_directory
  3383                              <1> 	;jnc	loc_print_deleted_message
  3384 000095B3 7300                <1> 	jnc	short loc_delete_sub_dir_retn ; 29/12/2017
  3385                              <1> 
  3386                              <1> 	; EAX=0 -> Directory not empty !
  3387                              <1> 	; EAX>0 -> Disk r/w error or another (misc) error
  3388                              <1> 	
  3389                              <1> 	;or	eax, eax
  3390                              <1> 	;jz	loc_rmdir_directory_not_empty_2         
  3391                              <1> 	;;stc
  3392                              <1> 	;;jmp	loc_file_rw_cmd_failed
  3393                              <1> 	
  3394                              <1> loc_delete_sub_dir_retn:
  3395 000095B5 C3                  <1> 	retn
  3396                              <1>  
  3397                              <1> loc_rmdir_multi_dir_clusters:
  3398 000095B6 C605[2B6E0100]01    <1> 	mov	byte [RmDir_MultiClusters], 1
  3399                              <1> 
  3400                              <1> pass_rmdir_multi_dir_clusters:
  3401 000095BD A3[346E0100]        <1> 	mov 	[RmDir_DirLastCluster], eax
  3402 000095C2 890D[386E0100]      <1> 	mov	[RmDir_PreviousCluster], ecx
  3403                              <1> 
  3404                              <1> loc_rmdir_load_fat_sub_directory:
  3405 000095C8 E84F330000          <1> 	call	load_FAT_sub_directory
  3406                              <1> 	;jc	loc_rmdir_cmd_failed
  3407 000095CD 72E6                <1> 	jc	short loc_delete_sub_dir_retn
  3408                              <1> 
  3409                              <1> loc_rmdir_find_last_dir_entry:
  3410 000095CF 56                  <1> 	push	esi
  3411 000095D0 BE[226D0100]        <1> 	mov	esi, Dir_File_Name
  3412 000095D5 C6062A              <1> 	mov	byte [esi], '*'
  3413 000095D8 C646082A            <1> 	mov	byte [esi+8], '*'
  3414 000095DC 31DB                <1> 	xor	ebx, ebx ; Entry offset  = 0
  3415                              <1> loc_rmdir_find_last_dir_entry_next:
  3416 000095DE 66B80008            <1> 	mov	ax, 0800h ; Except volume/long names
  3417 000095E2 6631C9              <1> 	xor	cx, cx ; 0 = Find a valid file or dir name
  3418 000095E5 E87A170000          <1> 	call	find_directory_entry
  3419 000095EA 7225                <1> 	jc	short loc_rmdir_empty_dir_cluster
  3420 000095EC 83FB01              <1> 	cmp	ebx, 1
  3421 000095EF 771B                <1> 	ja	short loc_rmdir_directory_not_empty_1
  3422                              <1> loc_rmdir_dot_entry_check:
  3423 000095F1 80FD2E              <1> 	cmp	ch, '.' ; The first char of the dir entry
  3424 000095F4 7516                <1> 	jne	short loc_rmdir_directory_not_empty_1
  3425 000095F6 08DB                <1> 	or	bl, bl
  3426 000095F8 7506                <1> 	jnz	short loc_rmdir_dotdot_entry_check
  3427 000095FA 807F0120            <1> 	cmp	byte [edi+1], 20h
  3428 000095FE EB06                <1> 	jmp	short pass_rmdir_dot_entry_check
  3429                              <1> 
  3430                              <1> loc_rmdir_dotdot_entry_check:
  3431 00009600 66817F012E20        <1> 	cmp	word [edi+1], '. '
  3432                              <1> pass_rmdir_dot_entry_check:	
  3433 00009606 7504                <1> 	jne	short loc_rmdir_directory_not_empty_1 
  3434 00009608 FEC3                <1> 	inc	bl
  3435 0000960A EBD2                <1> 	jmp	short loc_rmdir_find_last_dir_entry_next 
  3436                              <1> 
  3437                              <1> loc_rmdir_directory_not_empty_1:
  3438 0000960C 58                  <1> 	pop	eax ; pushed esi 
  3439 0000960D 31C0                <1> 	xor	eax, eax ; 0
  3440                              <1> loc_rmdir_directory_not_empty_2:
  3441                              <1> loc_delete_sub_dir_stc_retn:
  3442 0000960F F9                  <1> 	stc
  3443 00009610 C3                  <1> 	retn
  3444                              <1> 
  3445                              <1> loc_rmdir_empty_dir_cluster:
  3446 00009611 5E                  <1> 	pop	esi
  3447                              <1> 
  3448                              <1> loc_rmdir_set_prev_cluster_dir_last_cluster:
  3449 00009612 803D[2B6E0100]00    <1> 	cmp	byte [RmDir_MultiClusters], 0
  3450 00009619 7613                <1> 	jna	short loc_rmdir_unlink_dir_last_cluster
  3451                              <1> 
  3452 0000961B A1[386E0100]        <1> 	mov	eax, [RmDir_PreviousCluster]
  3453                              <1> 	;xor	ecx, ecx
  3454 00009620 49                  <1> 	dec	ecx ; FFFFFFFFh
  3455 00009621 E83A340000          <1> 	call	update_cluster
  3456 00009626 7306                <1> 	jnc	short loc_rmdir_unlink_dir_last_cluster
  3457                              <1> 
  3458                              <1> 	; 01/03/2016
  3459                              <1> 	;cmp	eax, 1  ; eax = 0 -> end of cluster chain
  3460                              <1> 	;cmc 
  3461                              <1> 	;jc	short loc_rmdir_cmd_failed
  3462                              <1> 	;jmp	short loc_rmdir_save_fat_buffer
  3463                              <1> 	; 29/12/2017 
  3464 00009628 21C0                <1> 	and	eax, eax
  3465 0000962A 75E3                <1> 	jnz	short loc_delete_sub_dir_stc_retn
  3466 0000962C EB12                <1> 	jmp	short loc_rmdir_save_fat_buffer	
  3467                              <1> 
  3468                              <1> loc_rmdir_unlink_dir_last_cluster:
  3469 0000962E A1[346E0100]        <1> 	mov	eax, [RmDir_DirLastCluster]
  3470 00009633 31C9                <1> 	xor	ecx, ecx ; 0
  3471 00009635 E826340000          <1> 	call	update_cluster
  3472 0000963A 7327                <1> 	jnc	short loc_rmdir_unlink_stc_retn_0Bh
  3473                              <1> 	; Because of it is the last cluster
  3474                              <1> 	; 'update_cluster' must return with eocc error 
  3475 0000963C 09C0                <1> 	or	eax, eax
  3476                              <1> 	;jz	short loc_rmdir_save_fat_buffer ; eocc	
  3477                              <1> 	;stc
  3478                              <1>         ;jmp     short loc_rmdir_cmd_failed
  3479                              <1> 	; 29/12/2017
  3480 0000963E 75CF                <1> 	jnz	short loc_delete_sub_dir_stc_retn
  3481                              <1> 	
  3482                              <1> loc_rmdir_save_fat_buffer:
  3483 00009640 803D[B26B0100]02    <1> 	cmp	byte [FAT_BuffValidData], 2
  3484 00009647 7528                <1> 	jne	short loc_rmdir_calculate_FAT_freespace
  3485 00009649 E8CF360000          <1> 	call	save_fat_buffer
  3486                              <1> 	;jc	short loc_rmdir_cmd_failed
  3487                              <1> 	; 29/12/2017
  3488 0000964E 7219                <1> 	jc	short loc_rmdir_unlink_error_retn
  3489                              <1> 
  3490                              <1> 	; 01/03/2016
  3491 00009650 803D[2B6E0100]00    <1> 	cmp	byte [RmDir_MultiClusters], 0
  3492 00009657 7618                <1> 	jna	short loc_rmdir_calculate_FAT_freespace
  3493                              <1> 
  3494 00009659 A1[006E0100]        <1> 	mov	eax, [DelFile_FCluster]
  3495 0000965E E92DFFFFFF          <1>         jmp     loc_rmdir_get_last_cluster_3
  3496                              <1> 
  3497                              <1> loc_rmdir_unlink_stc_retn_0Bh:
  3498                              <1> 	; 15/10/2016 (0Bh -> 28)
  3499 00009663 B81C000000          <1> 	mov	eax, ERR_INV_FORMAT ; 28 = Invalid format
  3500                              <1> loc_rmdir_unlink_stc_retn:
  3501 00009668 F9                  <1> 	stc
  3502                              <1> loc_rmdir_unlink_error_retn:
  3503 00009669 C3                  <1> 	retn
  3504                              <1> 
  3505                              <1> loc_rmdir_delete_short_name_invalid_data:
  3506 0000966A B81D000000          <1> 	mov	eax, 29 ; Invalid data (15/10/2016)
  3507                              <1> 	;stc
  3508                              <1>         ;jmp	loc_rmdir_cmd_failed
  3509                              <1> 	; 29/12/2017
  3510 0000966F EBF7                <1> 	jmp	short loc_rmdir_unlink_stc_retn
  3511                              <1> 
  3512                              <1> loc_rmdir_calculate_FAT_freespace:
  3513                              <1> 	;mov	eax, [FAT_ClusterCounter]
  3514                              <1> 	; 29/12/2017
  3515 00009671 29C0                <1> 	sub	eax, eax ; 0
  3516 00009673 8705[BA6B0100]      <1> 	xchg	eax, [FAT_ClusterCounter]
  3517                              <1> 	;
  3518 00009679 66BB01FF            <1> 	mov	bx, 0FF01h
  3519                              <1> 	; BL = 1 -> Add EAX to free space count
  3520                              <1> 	; BH = FFh ->
  3521                              <1> 	; ESI = Logical DOS Drive Description Table address
  3522 0000967D E830370000          <1> 	call	calculate_fat_freespace
  3523                              <1> 
  3524 00009682 21C9                <1> 	and	ecx, ecx ; ecx = 0 -> valid free sector count
  3525 00009684 7409                <1> 	jz 	short loc_rmdir_delete_short_name_continue
  3526                              <1> 
  3527                              <1> loc_rmdir_recalculate_FAT_freespace:
  3528 00009686 66BB00FF            <1>         mov     bx, 0FF00h ; BL = 0 -> Recalculate free space
  3529 0000968A E823370000          <1> 	call	calculate_fat_freespace
  3530                              <1> 	          
  3531                              <1> loc_rmdir_delete_short_name_continue:
  3532 0000968F A1[306E0100]        <1> 	mov	eax, [RmDir_ParentDirCluster]
  3533 00009694 83F802              <1> 	cmp	eax, 2
  3534 00009697 7309                <1> 	jnb	short loc_rmdir_del_short_name_load_sub_dir
  3535 00009699 E8F3310000          <1> 	call	load_FAT_root_directory
  3536                              <1> 	;jc	loc_file_rw_cmd_failed
  3537                              <1> 	; 29/12/2017
  3538 0000969E 72C9                <1> 	jc	short loc_rmdir_unlink_error_retn
  3539 000096A0 EB07                <1> 	jmp	short loc_rmdir_del_short_name_ld_chk_fclust
  3540                              <1> 
  3541                              <1> loc_rmdir_del_short_name_load_sub_dir:	
  3542 000096A2 E875320000          <1> 	call	load_FAT_sub_directory
  3543                              <1> 	;jc	loc_file_rw_cmd_failed
  3544                              <1> 	; 29/12/2017
  3545 000096A7 72C0                <1> 	jc	short loc_rmdir_unlink_error_retn
  3546                              <1> 
  3547                              <1> loc_rmdir_del_short_name_ld_chk_fclust:
  3548 000096A9 0FB73D[2C6E0100]    <1> 	movzx	edi, word [RmDir_DirEntryOffset]
  3549 000096B0 81C700000800        <1> 	add	edi, Directory_Buffer
  3550                              <1> 
  3551 000096B6 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  3552 000096BA C1E010              <1> 	shl	eax, 16
  3553 000096BD 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  3554                              <1>         ; Not necessary... 
  3555 000096C1 3B05[006E0100]      <1> 	cmp	eax, [DelFile_FCluster]
  3556 000096C7 75A1                <1> 	jne	short loc_rmdir_delete_short_name_invalid_data
  3557                              <1> 	;
  3558 000096C9 C607E5              <1> 	mov	byte [edi], 0E5h ; 'Deleted' sign
  3559                              <1> 	; 27/02/2016
  3560                              <1> 	; TRDOS v1 has a bug here! it does not set
  3561                              <1> 	; 'DirBuff_ValidData' to 2; as result of this bug,
  3562                              <1> 	; 'save_directory_buffer' would not save the change ! 
  3563 000096CC C605[C46B0100]02    <1>   	mov	byte [DirBuff_ValidData], 2 ; change sign
  3564                              <1> 	;
  3565 000096D3 E8AE1D0000          <1> 	call	save_directory_buffer
  3566                              <1> 	;jc	loc_file_rw_cmd_failed
  3567                              <1> 	; 29/12/2017
  3568 000096D8 728F                <1> 	jc	short loc_rmdir_unlink_error_retn
  3569                              <1> 
  3570                              <1> loc_rmdir_del_long_name:
  3571 000096DA 0FB615[066E0100]    <1> 	movzx	edx, byte [DelFile_LNEL]
  3572 000096E1 08D2                <1> 	or	dl, dl
  3573 000096E3 7410                <1> 	jz	short loc_rmdir_update_parent_dir_lmdt
  3574                              <1>              
  3575 000096E5 0FB705[046E0100]    <1> 	movzx	eax, word [DelFile_EntryCounter]
  3576 000096EC 29D0                <1> 	sub	eax, edx
  3577                              <1> 	; 29/12/2017
  3578 000096EE 7205                <1> 	jc	short loc_rmdir_update_parent_dir_lmdt
  3579                              <1>  
  3580                              <1>  	; EAX = Directory Entry Number of the long name last entry
  3581 000096F0 E8EF1E0000          <1> 	call	delete_longname
  3582                              <1> 
  3583                              <1> loc_rmdir_update_parent_dir_lmdt:
  3584 000096F5 E8271E0000          <1> 	call	update_parent_dir_lmdt
  3585                              <1> 	;jc	short loc_file_rw_cmd_failed
  3586                              <1> 	; 29/12/2017
  3587                              <1> 	;jc	short loc_rmdir_unlink_error_retn
  3588                              <1> 
  3589                              <1> loc_delete_sub_directory_ok:
  3590                              <1> 	; 29/12/2017
  3591 000096FA 31C0                <1> 	xor	eax, eax ;  0 ;  cf = 0
  3592 000096FC C3                  <1> 	retn
  3593                              <1> 
  3594                              <1> 
  3595                              <1> delete_file:
  3596                              <1> 	; 29/02/2016
  3597                              <1> 	; 28/02/2016 (TRDOS 386 = TRDOS v2.0)
  3598                              <1> 	; 09/08/2010 (CMD_INTR.ASM, 'cmp_cmd_del')
  3599                              <1> 	; 28/02/2010
  3600                              <1> 
  3601                              <1> get_delfile_fchar:
  3602                              <1> 	; esi = file name
  3603 000096FD 803E20              <1> 	cmp	byte [esi], 20h
  3604 00009700 7701                <1>         ja	short loc_delfile_parse_path_name
  3605                              <1> 
  3606                              <1> loc_delfile_nofilename_retn:
  3607 00009702 C3                  <1> 	retn
  3608                              <1> 
  3609                              <1> loc_delfile_parse_path_name:
  3610 00009703 BF[3E6D0100]        <1> 	mov	edi, FindFile_Drv
  3611 00009708 E815190000          <1> 	call	parse_path_name
  3612 0000970D 0F822EF2FFFF        <1> 	jc	loc_cmd_failed
  3613                              <1> 
  3614                              <1> loc_delfile_check_filename_exists:
  3615 00009713 BE[806D0100]        <1> 	mov	esi, FindFile_Name
  3616 00009718 803E20              <1> 	cmp	byte [esi], 20h
  3617 0000971B 0F8620F2FFFF        <1> 	jna	loc_cmd_failed
  3618 00009721 8935[FC6D0100]      <1> 	mov	[DelFile_FNPointer], esi 
  3619                              <1> 
  3620                              <1> loc_delfile_drv:
  3621 00009727 8A15[3E6D0100]      <1> 	mov	dl, [FindFile_Drv]
  3622 0000972D 8A35[9E640100]      <1> 	mov	dh, [Current_Drv]
  3623 00009733 8835[FA6B0100]      <1> 	mov	[RUN_CDRV], dh
  3624 00009739 38F2                <1> 	cmp	dl, dh
  3625 0000973B 740B                <1> 	je	short loc_delfile_change_directory
  3626                              <1> 
  3627 0000973D E86CE3FFFF          <1> 	call	change_current_drive
  3628 00009742 0F8237FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3629                              <1> 
  3630                              <1> loc_delfile_change_directory:
  3631 00009748 803D[3F6D0100]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3632 0000974F 7618                <1> 	jna	short loc_delfile_find
  3633                              <1> 
  3634 00009751 FE05[F6170100]      <1> 	inc	byte [Restore_CDIR]
  3635 00009757 BE[3F6D0100]        <1> 	mov	esi, FindFile_Directory
  3636 0000975C 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3637 0000975E E8A9120000          <1> 	call	change_current_directory
  3638 00009763 0F8216FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3639                              <1> 
  3640                              <1> ;loc_delfile_change_prompt_dir_string:
  3641                              <1> 	;call	change_prompt_dir_string
  3642                              <1> 
  3643                              <1> loc_delfile_find:
  3644                              <1> 	;mov	esi, FindFile_Name
  3645 00009769 8B35[FC6D0100]      <1> 	mov	esi, [DelFile_FNPointer]
  3646 0000976F 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  3647 00009773 E8D9F6FFFF          <1> 	call	find_first_file
  3648 00009778 0F8201FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3649                              <1> 
  3650                              <1> loc_delfile_ambgfn_check:
  3651 0000977E 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3652 00009781 740B                <1> 	jz	short loc_delfile_found
  3653                              <1> 
  3654                              <1> loc_file_not_found:
  3655 00009783 B802000000          <1> 	mov	eax, 2 ; File not found sign
  3656 00009788 F9                  <1> 	stc
  3657 00009789 E9F1FAFFFF          <1> 	jmp	loc_file_rw_cmd_failed   
  3658                              <1> 
  3659                              <1> loc_delfile_found:
  3660 0000978E 80E307              <1> 	and	bl, 07h ; Attributes
  3661 00009791 0F85F2FAFFFF        <1>         jnz     loc_permission_denied
  3662                              <1> 
  3663                              <1> ;loc_delfile_found_save_lnel:
  3664                              <1> ;	mov	[DelFile_LNEL], bh ; Long name entry length (if > 0)
  3665                              <1> 
  3666                              <1> loc_delfile_ask_for_delete:
  3667 00009797 57                  <1> 	push	edi ; * (29/02/2016)
  3668                              <1> 
  3669 00009798 BE[C51C0100]        <1> 	mov	esi, Msg_DoYouWantDelete
  3670 0000979D E883D7FFFF          <1> 	call	print_msg
  3671 000097A2 8B35[FC6D0100]      <1> 	mov	esi, [DelFile_FNPointer]
  3672 000097A8 E878D7FFFF          <1> 	call	print_msg
  3673 000097AD BE[791C0100]        <1> 	mov	esi, Msg_YesNo
  3674 000097B2 E86ED7FFFF          <1> 	call	print_msg
  3675                              <1> 
  3676                              <1> loc_delfile_ask_again:
  3677 000097B7 30E4                <1> 	xor	ah, ah
  3678 000097B9 E81777FFFF          <1> 	call	int16h
  3679 000097BE 3C1B                <1> 	cmp	al, 1Bh
  3680                              <1> 	;je	short loc_do_not_delete_file
  3681 000097C0 7449                <1> 	je	short loc_delfile_y_n_escape ; 06/03/2016
  3682 000097C2 24DF                <1> 	and	al, 0DFh
  3683 000097C4 A2[831C0100]        <1> 	mov	[Y_N_nextline], al
  3684 000097C9 3C59                <1> 	cmp	al, 'Y'
  3685 000097CB 7404                <1> 	je	short loc_yes_delete_file
  3686 000097CD 3C4E                <1> 	cmp	al, 'N'
  3687 000097CF 75E6                <1> 	jne	short loc_delfile_ask_again
  3688                              <1> 
  3689                              <1> loc_do_not_delete_file:
  3690                              <1> loc_yes_delete_file:
  3691 000097D1 E8E2FBFFFF          <1> 	call	y_n_answer ; 29/12/2017
  3692 000097D6 5F                  <1> 	pop	edi ; * (29/02/2016)
  3693                              <1> 	;cmp	al, 'Y' ; 'yes'
  3694                              <1> 	;cmc
  3695                              <1>         ;jnc	loc_file_rw_restore_retn
  3696 000097D7 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3697 000097D9 0F84A0FAFFFF        <1>         je	loc_file_rw_restore_retn  
  3698                              <1> 
  3699                              <1> loc_delete_file:
  3700 000097DF 8A3D[3E6D0100]      <1> 	mov	bh, [FindFile_Drv]
  3701                              <1> 	;mov	bl, [DelFile_LNEL]
  3702 000097E5 8A1D[8D6D0100]      <1> 	mov	bl, [FindFile_LongNameEntryLength]
  3703                              <1> 	;mov	cx, [DirBuff_EntryCounter]
  3704 000097EB 668B0D[B86D0100]    <1> 	mov	cx, [FindFile_DirEntryNumber]
  3705                              <1> 	; (*) EDI = Directory buffer entry offset/address 
  3706 000097F2 E8D71F0000          <1> 	call	remove_file ; (FILE.ASM, 'proc_delete_file')
  3707 000097F7 0F8378FAFFFF        <1> 	jnc	loc_print_deleted_message
  3708                              <1> 
  3709                              <1> 	;cmp	al, 05h
  3710 000097FD 3C0B                <1> 	cmp	al, ERR_PERM_DENIED  ; 29/12/2017 (5 -> 11)
  3711 000097FF 0F8484FAFFFF        <1> 	je	loc_permission_denied
  3712 00009805 F9                  <1> 	stc
  3713 00009806 E974FAFFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3714                              <1> 
  3715                              <1> loc_delfile_y_n_escape:
  3716 0000980B B04E                <1> 	mov	al, 'N' ; 'no'
  3717 0000980D EBC2                <1> 	jmp	short loc_do_not_delete_file
  3718                              <1> 
  3719                              <1> set_file_attributes:
  3720                              <1> 	; 06/03/2016
  3721                              <1> 	; 04/03/2016 (TRDOS 386 = TRDOS v2.0)
  3722                              <1> 	; 10/07/2010 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_attrib')
  3723                              <1> 	; 23/05/2010 
  3724                              <1> 	; 17/12/2000 (P2000.ASM)
  3725                              <1> 
  3726                              <1> 	; esi = file or directory name
  3727 0000980F 6631C0              <1> 	xor	ax, ax
  3728 00009812 66A3[161D0100]      <1> 	mov	[Attr_Chars], ax
  3729 00009818 A2[546E0100]        <1> 	mov	[Attributes], al
  3730                              <1> 
  3731                              <1> get_attrib_fchar:
  3732                              <1> 	; esi = file name
  3733 0000981D 8A06                <1> 	mov	al, [esi]
  3734 0000981F 3C20                <1> 	cmp	al, 20h
  3735 00009821 7623                <1> 	jna	short loc_attr_file_nofilename_retn
  3736                              <1> 
  3737                              <1> loc_scan_attrib_params:
  3738 00009823 3C2D                <1> 	cmp	al, '-'
  3739 00009825 0F871C010000        <1> 	ja	loc_attr_file_parse_path_name
  3740 0000982B 7408                <1> 	je	short loc_attr_space
  3741                              <1> 
  3742 0000982D 3C2B                <1> 	cmp	al, '+'
  3743 0000982F 0F850CF1FFFF        <1> 	jne	loc_cmd_failed
  3744                              <1> 
  3745                              <1> loc_attr_space:
  3746 00009835 8A6601              <1> 	mov	ah, [esi+1]
  3747 00009838 80FC20              <1>  	cmp	ah, 20h
  3748 0000983B 770A                <1> 	ja	short pass_attr_space
  3749 0000983D 0F82FEF0FFFF        <1> 	jb	loc_cmd_failed
  3750 00009843 46                  <1> 	inc	esi
  3751 00009844 EBEF                <1> 	jmp	short loc_attr_space
  3752                              <1> 
  3753                              <1> loc_attr_file_nofilename_retn:
  3754 00009846 C3                  <1> 	retn
  3755                              <1> 
  3756                              <1> pass_attr_space:
  3757 00009847 80E4DF              <1> 	and	ah, 0DFh
  3758 0000984A 80FC53              <1> 	cmp	ah, 'S'
  3759 0000984D 0F87EEF0FFFF        <1> 	ja	loc_cmd_failed
  3760 00009853 7204                <1> 	jb	short pass_attr_system
  3761 00009855 B404                <1> 	mov	ah, 04h   ; System
  3762 00009857 EB21                <1> 	jmp	short pass_attr_archive
  3763                              <1> 
  3764                              <1> pass_attr_system:
  3765 00009859 80FC48              <1> 	cmp	ah, 'H'
  3766 0000985C 7706                <1> 	ja	short pass_attr_hidden
  3767 0000985E 7213                <1> 	jb	short pass_attr_read_only
  3768 00009860 B402                <1> 	mov	ah, 02h    ; Hidden
  3769 00009862 EB16                <1> 	jmp	short pass_attr_archive
  3770                              <1> 
  3771                              <1> pass_attr_hidden:
  3772 00009864 80FC52              <1> 	cmp	ah, 'R'
  3773 00009867 0F87D4F0FFFF        <1> 	ja	loc_cmd_failed
  3774 0000986D 7204                <1> 	jb	short pass_attr_read_only ; Read only
  3775 0000986F B401                <1> 	mov	ah, 01h
  3776 00009871 EB07                <1> 	jmp	short pass_attr_archive
  3777                              <1> 
  3778                              <1> pass_attr_read_only:
  3779 00009873 80FC41              <1> 	cmp	ah, 'A'
  3780 00009876 753B                <1> 	jne	short loc_chk_attr_enter
  3781 00009878 B420                <1> 	mov	ah, 20h    ; Archive
  3782                              <1> 
  3783                              <1> pass_attr_archive:
  3784 0000987A 3C2D                <1> 	cmp	al, '-'
  3785 0000987C 7508                <1> 	jne	short pass_reducing_attributes
  3786 0000987E 0825[161D0100]      <1> 	or	[Attr_Chars], ah
  3787 00009884 EB06                <1> 	jmp	short loc_change_attributes_inc
  3788                              <1> 
  3789                              <1> pass_reducing_attributes:
  3790 00009886 0825[171D0100]      <1> 	or	[Attr_Chars+1], ah
  3791                              <1> 
  3792                              <1> loc_change_attributes_inc:
  3793 0000988C 46                  <1> 	inc	esi
  3794 0000988D 8A6601              <1> 	mov	ah, [esi+1]
  3795 00009890 80FC20              <1> 	cmp	ah, 20h
  3796 00009893 7227                <1> 	jb	short pass_change_attr
  3797 00009895 74F5                <1> 	je	short loc_change_attributes_inc
  3798 00009897 80FC2D              <1> 	cmp	ah, '-'
  3799 0000989A 770D                <1> 	ja	short loc_chk_next_attr_char1
  3800 0000989C 7405                <1> 	je	short loc_chk_next_attr_char0
  3801 0000989E 80FC2B              <1> 	cmp	ah, '+'
  3802 000098A1 7506                <1> 	jne	short loc_chk_next_attr_char1
  3803                              <1> 
  3804                              <1> loc_chk_next_attr_char0:
  3805 000098A3 46                  <1> 	inc	esi
  3806 000098A4 668B06              <1> 	mov	ax, [esi]
  3807 000098A7 EB9E                <1> 	jmp	short pass_attr_space
  3808                              <1> 
  3809                              <1> loc_chk_next_attr_char1:
  3810 000098A9 803E2D              <1> 	cmp	byte [esi], '-'
  3811 000098AC 7799                <1> 	ja	short pass_attr_space
  3812 000098AE E988000000          <1>         jmp     loc_attr_file_check_fname_fchar
  3813                              <1> 
  3814                              <1> loc_chk_attr_enter:
  3815 000098B3 80FC0D              <1> 	cmp	ah, 0Dh
  3816 000098B6 0F8585F0FFFF        <1> 	jne	loc_cmd_failed
  3817                              <1> 
  3818                              <1> pass_change_attr:
  3819 000098BC A0[161D0100]        <1> 	mov	al, [Attr_Chars]
  3820 000098C1 F6D0                <1> 	not	al
  3821 000098C3 2005[546E0100]      <1> 	and	[Attributes], al
  3822 000098C9 A0[171D0100]        <1> 	mov	al, [Attr_Chars+1]
  3823 000098CE 0805[546E0100]      <1> 	or	[Attributes], al
  3824                              <1> 
  3825                              <1> loc_show_attributes:
  3826 000098D4 BE[93240100]        <1> 	mov	esi, nextline
  3827 000098D9 E847D6FFFF          <1> 	call	print_msg
  3828                              <1> 
  3829                              <1> loc_show_attributes_no_nextline:
  3830 000098DE C705[161D0100]4E4F- <1> 	mov	dword [Attr_Chars], 'NORM'
  3830 000098E6 524D                <1>
  3831 000098E8 66C705[1A1D0100]41- <1> 	mov	word [Attr_Chars+4], 'AL'
  3831 000098F0 4C                  <1>
  3832 000098F1 BE[161D0100]        <1> 	mov	esi, Attr_Chars
  3833 000098F6 A0[546E0100]        <1> 	mov	al, [Attributes]
  3834 000098FB A804                <1> 	test	al, 04h
  3835 000098FD 7406                <1> 	jz	short pass_put_attr_s
  3836 000098FF 66C7065300          <1> 	mov	word [esi], 0053h     ; S
  3837 00009904 46                  <1> 	inc	esi
  3838                              <1> 
  3839                              <1> pass_put_attr_s:
  3840 00009905 A802                <1> 	test	al, 02h
  3841 00009907 7406                <1> 	jz	short pass_put_attr_h
  3842 00009909 66C7064800          <1> 	mov	word [esi], 0048h     ; H
  3843 0000990E 46                  <1> 	inc	esi
  3844                              <1> 
  3845                              <1> pass_put_attr_h:
  3846 0000990F A801                <1> 	test	al, 01h
  3847 00009911 7406                <1> 	jz	short pass_put_attr_r
  3848 00009913 66C7065200          <1> 	mov	word [esi], 0052h     ; R
  3849 00009918 46                  <1> 	inc	esi
  3850                              <1> 
  3851                              <1> pass_put_attr_r:
  3852 00009919 3C20                <1> 	cmp	al, 20h
  3853 0000991B 7205                <1> 	jb	short pass_put_attr_a
  3854 0000991D 66C7064100          <1> 	mov	word [esi], 0041h     ; A
  3855                              <1> 
  3856                              <1> pass_put_attr_a:
  3857 00009922 BE[091D0100]        <1> 	mov	esi, Str_Attributes
  3858 00009927 E8F9D5FFFF          <1> 	call	print_msg
  3859 0000992C BE[93240100]        <1> 	mov	esi, nextline
  3860 00009931 E8EFD5FFFF          <1> 	call	print_msg
  3861 00009936 E944F9FFFF          <1> 	jmp	loc_file_rw_restore_retn 
  3862                              <1> 
  3863                              <1> loc_attr_file_check_fname_fchar:
  3864 0000993B 46                  <1> 	inc	esi
  3865 0000993C 803E20              <1> 	cmp	byte [esi], 20h
  3866 0000993F 74FA                <1> 	je	short loc_attr_file_check_fname_fchar
  3867 00009941 0F8275FFFFFF        <1>         jb      pass_change_attr
  3868                              <1> 		   
  3869                              <1> loc_attr_file_parse_path_name:
  3870 00009947 BF[3E6D0100]        <1> 	mov	edi, FindFile_Drv
  3871 0000994C E8D1160000          <1> 	call	parse_path_name
  3872 00009951 0F82EAEFFFFF        <1> 	jc	loc_cmd_failed
  3873                              <1> 
  3874                              <1> loc_attr_file_check_filename_exists:
  3875 00009957 BE[806D0100]        <1> 	mov	esi, FindFile_Name
  3876 0000995C 803E20              <1> 	cmp	byte [esi], 20h
  3877 0000995F 0F86DCEFFFFF        <1> 	jna	loc_cmd_failed
  3878 00009965 8935[FC6D0100]      <1> 	mov	[DelFile_FNPointer], esi 
  3879                              <1> 
  3880                              <1> loc_attr_file_drv:
  3881 0000996B 8A35[9E640100]      <1> 	mov	dh, [Current_Drv]
  3882 00009971 8835[FA6B0100]      <1> 	mov	[RUN_CDRV], dh
  3883                              <1> 
  3884 00009977 8A15[3E6D0100]      <1> 	mov	dl, [FindFile_Drv]
  3885 0000997D 38F2                <1> 	cmp	dl, dh
  3886 0000997F 740B                <1> 	je	short loc_attr_file_change_directory
  3887                              <1> 
  3888 00009981 E828E1FFFF          <1> 	call	change_current_drive
  3889 00009986 0F82F3F8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3890                              <1> 
  3891                              <1> loc_attr_file_change_directory:
  3892 0000998C 803D[3F6D0100]20    <1>         cmp     byte [FindFile_Directory], 20h
  3893 00009993 7618                <1> 	jna	short loc_attr_file_find
  3894                              <1> 
  3895 00009995 FE05[F6170100]      <1> 	inc	byte [Restore_CDIR]
  3896                              <1> 	
  3897 0000999B BE[3F6D0100]        <1> 	mov	esi, FindFile_Directory
  3898 000099A0 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3899 000099A2 E865100000          <1> 	call	change_current_directory
  3900 000099A7 0F82D2F8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3901                              <1> 
  3902                              <1> ;loc_attr_file_change_prompt_dir_string:
  3903                              <1> 	;call	change_prompt_dir_string
  3904                              <1> 
  3905                              <1> loc_attr_file_find:
  3906                              <1> 	;mov	esi, FindFile_Name
  3907 000099AD 8B35[FC6D0100]      <1> 	mov	esi, [DelFile_FNPointer]
  3908 000099B3 66B80008            <1> 	mov	ax, 0800h ; Except volume labels
  3909 000099B7 E895F4FFFF          <1> 	call	find_first_file
  3910 000099BC 0F82BDF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3911                              <1> 
  3912                              <1> loc_attr_file_ambgfn_check:
  3913 000099C2 6609D2              <1> 	or	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3914                              <1> 	;	(Note: It was BX in TRDOS v1)
  3915                              <1> 	;jz	short loc_attr_file_found
  3916 000099C5 0F85B8FDFFFF        <1>         jnz     loc_file_not_found ; 06/03/2016 
  3917                              <1> 
  3918                              <1> 	;mov	eax, 2 ; File not found sign
  3919                              <1> 	;stc
  3920                              <1> 	;jmp	loc_file_rw_cmd_failed   
  3921                              <1> 
  3922                              <1> loc_attr_file_found:
  3923                              <1> 	; EDI = Directory buffer entry offset/address
  3924                              <1> 	; BL = File (or Directory) Attributes 
  3925                              <1> 	;	(Note: It was 'CL' in TRDOS v1)
  3926                              <1> 	; mov	bl, [EDI+0Bh]
  3927                              <1> 	
  3928 000099CB 66833D[161D0100]00  <1> 	cmp	word [Attr_Chars], 0
  3929 000099D3 770B                <1> 	ja	short loc_attr_file_change_attributes
  3930 000099D5 881D[546E0100]      <1> 	mov	[Attributes], bl
  3931 000099DB E9F4FEFFFF          <1> 	jmp	loc_show_attributes
  3932                              <1> 
  3933                              <1> loc_attr_file_change_attributes:
  3934 000099E0 A0[161D0100]        <1> 	mov	al, [Attr_Chars]
  3935 000099E5 F6D0                <1> 	not	al
  3936 000099E7 20C3                <1> 	and	bl, al
  3937 000099E9 A0[171D0100]        <1> 	mov	al, [Attr_Chars+1]
  3938 000099EE 08C3                <1> 	or	bl, al
  3939                              <1> 
  3940 000099F0 66817F0CA101        <1> 	cmp	word [edi+DirEntry_NTRes], 01A1h ; Singlix FS
  3941 000099F6 741D                <1> 	je	short loc_attr_file_fs_check
  3942                              <1> 
  3943 000099F8 881D[546E0100]      <1> 	mov	[Attributes], bl
  3944 000099FE 885F0B              <1> 	mov	[edi+0Bh], bl    ; Attributes (New!)
  3945                              <1> 
  3946                              <1> 	; 04/03/2016
  3947                              <1> 	; TRDOS v1 has a bug here! it does not set
  3948                              <1> 	; 'DirBuff_ValidData' to 2; as result of this bug,
  3949                              <1> 	; 'save_directory_buffer' would not save the new attributes ! 
  3950                              <1> 	
  3951 00009A01 C605[C46B0100]02    <1> 	mov	byte [DirBuff_ValidData], 2
  3952                              <1> 
  3953 00009A08 E8791A0000          <1> 	call 	save_directory_buffer
  3954 00009A0D 0F826CF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3955                              <1> 
  3956 00009A13 EB33                <1> 	jmp	short loc_print_attr_changed_message
  3957                              <1> 
  3958                              <1> loc_attr_file_fs_check:
  3959 00009A15 29C0                <1> 	sub	eax, eax
  3960 00009A17 8A25[C26B0100]      <1>         mov     ah, [DirBuff_DRV]
  3961 00009A1D BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3962 00009A22 01C6                <1>         add     esi, eax
  3963 00009A24 807E04A1            <1>         cmp     byte [esi+LD_FSType], 0A1h
  3964 00009A28 7309                <1> 	jnc	short loc_attr_file_change_fs_file_attributes
  3965                              <1> 	; 29/12/2017 (0Dh -> 29)	
  3966 00009A2A 66B81D00            <1> 	mov	ax, 29 ; Invalid Data
  3967 00009A2E E94CF8FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3968                              <1> 
  3969                              <1> loc_attr_file_change_fs_file_attributes:
  3970                              <1> 	; BL = New MS-DOS File Attributes
  3971 00009A33 88D8                <1> 	mov	al, bl ; File/Directory Attributes
  3972 00009A35 30E4                <1> 	xor	ah, ah ; Attributes in MS-DOS format sign	  
  3973 00009A37 E873050000          <1> 	call	change_fs_file_attributes
  3974 00009A3C 0F823DF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3975                              <1> 
  3976 00009A42 881D[546E0100]      <1> 	mov	[Attributes], bl 
  3977                              <1> 
  3978                              <1> loc_print_attr_changed_message:
  3979 00009A48 BE[041D0100]        <1> 	mov	esi, Msg_New
  3980 00009A4D E8D3D4FFFF          <1> 	call	print_msg
  3981 00009A52 E987FEFFFF          <1> 	jmp	loc_show_attributes_no_nextline
  3982                              <1> 
  3983                              <1> rename_file:
  3984                              <1> 	; 13/11/2017
  3985                              <1> 	; 06/11/2016
  3986                              <1> 	; 05/11/2016
  3987                              <1> 	; 16/10/2016
  3988                              <1> 	; 08/03/2016
  3989                              <1> 	; 06/03/2016 (TRDOS 386 = TRDOS v2.0)
  3990                              <1> 	; 20/11/2010 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_rename')
  3991                              <1> 	; 16/11/2010 
  3992                              <1> 
  3993                              <1> get_rename_source_fchar:
  3994                              <1> 	; esi = file name
  3995 00009A57 803E20              <1> 	cmp	byte [esi], 20h
  3996 00009A5A 7614                <1>         jna	short loc_rename_nofilename_retn
  3997                              <1> 
  3998 00009A5C 8935[7C6E0100]      <1> 	mov	[SourceFilePath], esi
  3999                              <1> 
  4000                              <1> rename_scan_source_file:
  4001 00009A62 46                  <1> 	inc	esi
  4002 00009A63 803E20              <1> 	cmp	byte [esi], 20h
  4003 00009A66 7409                <1> 	je	short rename_scan_destination_file_1
  4004                              <1> 	;jb	short loc_rename_nofilename_retn
  4005 00009A68 0F82D3EEFFFF        <1> 	jb	loc_cmd_failed
  4006 00009A6E EBF2                <1> 	jmp	short rename_scan_source_file
  4007                              <1> 
  4008                              <1> loc_rename_nofilename_retn: ; 08/03/2016
  4009 00009A70 C3                  <1> 	retn
  4010                              <1> 
  4011                              <1> rename_scan_destination_file_1:
  4012 00009A71 C60600              <1> 	mov	byte [esi], 0
  4013                              <1> 
  4014                              <1> rename_scan_destination_file_2:
  4015 00009A74 46                  <1> 	inc	esi  
  4016 00009A75 803E20              <1> 	cmp	byte [esi], 20h
  4017 00009A78 74FA                <1> 	je	short rename_scan_destination_file_2
  4018                              <1> 	;jb	short loc_rename_nofilename_retn
  4019 00009A7A 0F82C1EEFFFF        <1> 	jb	loc_cmd_failed
  4020                              <1> 
  4021 00009A80 8935[806E0100]      <1> 	mov	[DestinationFilePath], esi
  4022                              <1> 
  4023                              <1> rename_scan_destination_file_3:
  4024 00009A86 46                  <1> 	inc	esi  
  4025 00009A87 803E20              <1> 	cmp	byte [esi], 20h
  4026 00009A8A 77FA                <1> 	ja	short rename_scan_destination_file_3
  4027                              <1> 
  4028 00009A8C C60600              <1> 	mov	byte [esi], 0
  4029                              <1> 
  4030                              <1> loc_rename_save_current_drive:
  4031 00009A8F 8A35[9E640100]      <1> 	mov	dh, [Current_Drv]
  4032 00009A95 8835[FA6B0100]      <1> 	mov	byte [RUN_CDRV], dh
  4033                              <1> 
  4034                              <1> loc_rename_sf_parse_path_name:
  4035 00009A9B 8B35[7C6E0100]      <1> 	mov	esi, [SourceFilePath] 
  4036 00009AA1 BF[3E6D0100]        <1> 	mov	edi, FindFile_Drv
  4037 00009AA6 E877150000          <1> 	call	parse_path_name
  4038 00009AAB 0F8290EEFFFF        <1> 	jc	loc_cmd_failed
  4039                              <1> 
  4040                              <1> loc_rename_sf_check_filename_exists:
  4041 00009AB1 BE[806D0100]        <1> 	mov	esi, FindFile_Name
  4042 00009AB6 803E20              <1> 	cmp	byte [esi], 20h
  4043 00009AB9 0F8682EEFFFF        <1> 	jna	loc_cmd_failed
  4044                              <1> 
  4045                              <1> 	;mov	[DelFile_FNPointer], esi 
  4046                              <1> 
  4047                              <1> loc_rename_sf_drv:
  4048                              <1> 	;mov	dh, [Current_Drv]
  4049                              <1> 	;mov	[RUN_CDRV], dh
  4050                              <1> 
  4051 00009ABF 8A15[3E6D0100]      <1> 	mov	dl, [FindFile_Drv]
  4052 00009AC5 38F2                <1> 	cmp	dl, dh ; dh = [Current_Drv]
  4053 00009AC7 740B                <1> 	je	short rename_sf_change_directory
  4054                              <1> 
  4055 00009AC9 E8E0DFFFFF          <1> 	call	change_current_drive
  4056 00009ACE 0F82ABF7FFFF        <1> 	jc	loc_file_rw_cmd_failed
  4057                              <1> 
  4058                              <1> rename_sf_change_directory:
  4059 00009AD4 803D[3F6D0100]20    <1> 	cmp	byte [FindFile_Directory], 20h
  4060 00009ADB 7618                <1> 	jna	short rename_sf_find
  4061                              <1> 
  4062 00009ADD FE05[F6170100]      <1> 	inc	byte [Restore_CDIR]
  4063 00009AE3 BE[3F6D0100]        <1> 	mov	esi, FindFile_Directory
  4064 00009AE8 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  4065 00009AEA E81D0F0000          <1> 	call	change_current_directory
  4066 00009AEF 0F828AF7FFFF        <1>  	jc	loc_file_rw_cmd_failed
  4067                              <1> 
  4068                              <1> ;rename_sf_change_prompt_dir_string:
  4069                              <1> 	;call	change_prompt_dir_string
  4070                              <1> 
  4071                              <1> rename_sf_find:
  4072                              <1> 	;mov	esi, [DelFile_FNPointer]
  4073 00009AF5 BE[806D0100]        <1> 	mov	esi, FindFile_Name
  4074                              <1> 
  4075 00009AFA 66B80008            <1> 	mov	ax, 0800h ; Except volume labels
  4076 00009AFE E84EF3FFFF          <1> 	call	find_first_file
  4077 00009B03 0F8276F7FFFF        <1> 	jc	loc_file_rw_cmd_failed
  4078                              <1> 
  4079                              <1> loc_rename_sf_ambgfn_check:
  4080 00009B09 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  4081                              <1> 	;	(Note: It was BX in TRDOS v1)
  4082                              <1> 	;jz	short loc_rename_sf_found
  4083 00009B0C 0F8571FCFFFF        <1> 	jnz	loc_file_not_found
  4084                              <1> 
  4085                              <1> 	;mov	eax, 2 ; File not found sign
  4086                              <1> 	;stc
  4087                              <1> 	;jmp	loc_file_rw_cmd_failed   
  4088                              <1> 
  4089                              <1> loc_rename_sf_found:
  4090                              <1> 	; EDI = Directory buffer entry offset/address
  4091                              <1> 	; BL = File (or Directory) Attributes 
  4092                              <1> 	;	(Note: It was 'CL' in TRDOS v1)
  4093                              <1> 	; mov	bl, [EDI+0Bh]
  4094                              <1> 
  4095 00009B12 F6C307              <1> 	test	bl, 07h ; Attributes, S-H-R
  4096 00009B15 0F856EF7FFFF        <1> 	jnz	loc_permission_denied
  4097                              <1> 	
  4098 00009B1B BE[3E6D0100]        <1>         mov     esi, FindFile_Drv
  4099 00009B20 BF[846E0100]        <1>         mov     edi, SourceFile_Drv
  4100 00009B25 B920000000          <1> 	mov	ecx, 32
  4101 00009B2A F3A5                <1> 	rep	movsd
  4102                              <1> 
  4103                              <1> loc_rename_df_parse_path_name:
  4104 00009B2C 8B35[806E0100]      <1> 	mov	esi, [DestinationFilePath]
  4105 00009B32 BF[3E6D0100]        <1> 	mov	edi, FindFile_Drv
  4106 00009B37 E8E6140000          <1> 	call	parse_path_name
  4107 00009B3C 7219                <1> 	jc	short loc_rename_df_cmd_failed
  4108                              <1> 
  4109                              <1> 	;mov	dh, [RUN_CDRV]
  4110 00009B3E 8A35[9E640100]      <1> 	mov	dh, [Current_Drv]
  4111                              <1> 
  4112                              <1> 	; 'rename' command is valid only for same dos drive and same dir!
  4113                              <1> 	; ('move' command must be used if source file and destination file
  4114                              <1> 	; directories are not same!) 
  4115 00009B44 8A15[3E6D0100]      <1> 	mov	dl, [FindFile_Drv]
  4116 00009B4A 38F2                <1> 	cmp	dl, dh ; are source and destination drives different ?!
  4117 00009B4C 7509                <1> 	jne	short loc_rename_df_cmd_failed ; yes! 
  4118                              <1> 
  4119                              <1> rename_df_check_dirname_exists:
  4120 00009B4E 803D[3F6D0100]00    <1> 	cmp	byte [FindFile_Directory], 0
  4121 00009B55 760B                <1> 	jna	short rename_df_check_filename_exists
  4122                              <1> 
  4123                              <1> 	; different source file and destination file directories !
  4124                              <1> loc_rename_df_cmd_failed:
  4125 00009B57 B801000000          <1> 	mov	eax, 1 ; TRDOS 'Bad command or file name' error
  4126 00009B5C F9                  <1> 	stc
  4127 00009B5D E91DF7FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  4128                              <1> 	  
  4129                              <1> rename_df_check_filename_exists:
  4130 00009B62 BE[806D0100]        <1> 	mov	esi, FindFile_Name
  4131 00009B67 E8A3F6FFFF          <1> 	call	check_filename
  4132 00009B6C 0F82BFF7FFFF        <1> 	jc	loc_mkdir_invalid_dir_name_chars
  4133                              <1> 
  4134                              <1> 	;mov	[DelFile_FNPointer], esi 
  4135                              <1> 	;cmp	byte [esi], 20h
  4136                              <1> 	;ja	short loc_rename_df_find
  4137                              <1> 
  4138                              <1> 	;mov	dh, [Current_Drv] ; dh has not been changed
  4139                              <1> 
  4140                              <1> rename_df_drv_check_writable:
  4141 00009B72 0FB6F6              <1> 	movzx	esi, dh
  4142                              <1> 	;movzx	esi, byte [Current_Drv]
  4143 00009B75 81C600010900        <1> 	add	esi, Logical_DOSDisks
  4144                              <1> 
  4145 00009B7B 88F2                <1> 	mov	dl, dh ; dl = [Current_Drv]
  4146 00009B7D 8A7601              <1> 	mov	dh, [esi+LD_DiskType]
  4147                              <1> 
  4148 00009B80 80FE01              <1> 	cmp	dh, 1 ; 0 = Invalid
  4149 00009B83 7310                <1> 	jnb	short rename_df_compare_sf_df_name
  4150                              <1> 
  4151                              <1> 	; 16/10/2016 (13h -> 30)
  4152 00009B85 B81E000000          <1> 	mov	eax, 30 ; 'Disk write-protected' error
  4153 00009B8A 8B1D[806E0100]      <1> 	mov	ebx, [DestinationFilePath] 
  4154 00009B90 E9EAF6FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  4155                              <1> 
  4156                              <1> rename_df_compare_sf_df_name:
  4157 00009B95 BE[806D0100]        <1> 	mov	esi, FindFile_Name
  4158 00009B9A BF[C66E0100]        <1> 	mov	edi, SourceFile_Name
  4159 00009B9F B90C000000          <1> 	mov	ecx, 12
  4160                              <1> rename_df_compare_sf_df_name_next: 
  4161 00009BA4 AC                  <1> 	lodsb
  4162 00009BA5 AE                  <1> 	scasb
  4163 00009BA6 7506                <1> 	jne	short loc_rename_df_find
  4164 00009BA8 08C0                <1> 	or	al, al
  4165 00009BAA 74AB                <1> 	jz	short loc_rename_df_cmd_failed
  4166 00009BAC E2F6                <1> 	loop	rename_df_compare_sf_df_name_next 
  4167                              <1> 
  4168                              <1> loc_rename_df_find:
  4169                              <1> 	;mov	esi, [DelFile_FNPointer]
  4170 00009BAE BE[806D0100]        <1> 	mov	esi, FindFile_Name
  4171                              <1> 
  4172 00009BB3 6631C0              <1> 	xor	ax, ax ; Any
  4173 00009BB6 E896F2FFFF          <1> 	call	find_first_file
  4174                              <1> 	;jnc	short loc_rename_df_found
  4175                              <1> 	; 29/12/2017
  4176 00009BBB 0F83C8F6FFFF        <1> 	jnc	loc_permission_denied
  4177                              <1> 
  4178                              <1> loc_rename_df_check_error_code:
  4179                              <1> 	;cmp	eax, 2
  4180 00009BC1 3C02                <1> 	cmp	al, 2 ; Not found error
  4181 00009BC3 7406                <1> 	je	short rename_df_move_find_struct_to_dest
  4182 00009BC5 F9                  <1> 	stc
  4183 00009BC6 E9B4F6FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  4184                              <1> 
  4185                              <1> ;loc_rename_df_found:
  4186                              <1> 	; 05/11/2016
  4187                              <1> 	; Permission denied error
  4188                              <1> 	;mov	eax, ERR_PERM_DENIED ; 29/12/2017
  4189                              <1> 	;stc
  4190                              <1> 	;jmp	loc_permission_denied  ; 06/11/2016
  4191                              <1> 
  4192                              <1> rename_df_move_find_struct_to_dest:
  4193 00009BCB BE[3E6D0100]        <1>         mov     esi, FindFile_Drv
  4194 00009BD0 BF[046F0100]        <1>         mov     edi, DestinationFile_Drv
  4195 00009BD5 B920000000          <1> 	mov	ecx, 32
  4196 00009BDA F3A5                <1> 	rep	movsd
  4197                              <1> 
  4198                              <1> loc_rename_df_process_q_sf:
  4199                              <1> 	;mov	ecx, 12
  4200 00009BDC B10C                <1> 	mov	cl, 12
  4201 00009BDE BE[C66E0100]        <1>  	mov	esi, SourceFile_Name
  4202 00009BE3 BF[451D0100]        <1> 	mov	edi, Rename_OldName
  4203                              <1> rename_df_process_q_nml_1_sf:
  4204 00009BE8 AC                  <1> 	lodsb
  4205 00009BE9 3C20                <1>         cmp	al, 20h
  4206 00009BEB 7603                <1>         jna	short rename_df_process_q_nml_2_sf
  4207 00009BED AA                  <1> 	stosb
  4208 00009BEE E2F8                <1> 	loop	rename_df_process_q_nml_1_sf
  4209                              <1> 
  4210                              <1> rename_df_process_q_nml_2_sf:
  4211 00009BF0 C60700              <1> 	mov	byte [edi], 0
  4212                              <1> 
  4213                              <1> loc_rename_df_process_q_df:
  4214                              <1> 	;mov	ecx, 12
  4215 00009BF3 B10C                <1> 	mov	cl, 12
  4216 00009BF5 BE[466F0100]        <1> 	mov	esi, DestinationFile_Name
  4217 00009BFA BF[561D0100]        <1> 	mov	edi, Rename_NewName
  4218                              <1> rename_df_process_q_nml_1_df:
  4219 00009BFF AC                  <1> 	lodsb
  4220 00009C00 3C20                <1> 	cmp	al, 20h
  4221 00009C02 7603                <1> 	jna	short loc_rename_df_process_q_nml_2_df
  4222 00009C04 AA                  <1> 	stosb
  4223 00009C05 E2F8                <1> 	loop	rename_df_process_q_nml_1_df
  4224                              <1> 
  4225                              <1> loc_rename_df_process_q_nml_2_df:
  4226 00009C07 C60700              <1> 	mov	byte [edi], 0
  4227                              <1> 
  4228                              <1> loc_rename_confirmation_question:
  4229 00009C0A BE[1D1D0100]        <1> 	mov	esi, Msg_DoYouWantRename
  4230 00009C0F E811D3FFFF          <1> 	call	print_msg
  4231                              <1> 
  4232 00009C14 A0[E16E0100]        <1> 	mov	al, [SourceFile_DirEntry+11] ; Attributes
  4233 00009C19 2410                <1> 	and	al, 10h
  4234 00009C1B 750C                <1> 	jnz	short rename_confirmation_question_dir
  4235                              <1> 
  4236                              <1> rename_confirmation_question_file:
  4237 00009C1D BE[341D0100]        <1> 	mov	esi, Rename_File
  4238 00009C22 E8FED2FFFF          <1> 	call	print_msg 
  4239 00009C27 EB0A                <1> 	jmp	short rename_confirmation_question_as 
  4240                              <1> 
  4241                              <1> rename_confirmation_question_dir:
  4242 00009C29 BE[3A1D0100]        <1> 	mov	esi, Rename_Directory
  4243 00009C2E E8F2D2FFFF          <1> 	call	print_msg
  4244                              <1> 
  4245                              <1> rename_confirmation_question_as:
  4246 00009C33 BE[451D0100]        <1> 	mov	esi, Rename_OldName
  4247 00009C38 E8E8D2FFFF          <1> 	call	print_msg
  4248 00009C3D BE[521D0100]        <1> 	mov	esi, Msg_File_rename_as
  4249 00009C42 E8DED2FFFF          <1> 	call	print_msg
  4250 00009C47 BE[791C0100]        <1> 	mov	esi, Msg_YesNo
  4251 00009C4C E8D4D2FFFF          <1> 	call	print_msg
  4252                              <1> 
  4253                              <1> loc_rename_ask_again:
  4254 00009C51 30E4                <1> 	xor	ah, ah
  4255 00009C53 E87D72FFFF          <1> 	call	int16h
  4256 00009C58 3C1B                <1> 	cmp	al, 1Bh
  4257 00009C5A 740F                <1> 	je	short loc_do_not_rename_file
  4258 00009C5C 24DF                <1> 	and	al, 0DFh
  4259 00009C5E A2[831C0100]        <1> 	mov	[Y_N_nextline], al
  4260 00009C63 3C59                <1> 	cmp	al, 'Y'
  4261 00009C65 7404                <1> 	je	short loc_yes_rename_file
  4262 00009C67 3C4E                <1> 	cmp	al, 'N'
  4263 00009C69 75E6                <1> 	jne	short loc_rename_ask_again
  4264                              <1> 
  4265                              <1> loc_do_not_rename_file:
  4266                              <1> loc_yes_rename_file:
  4267 00009C6B E848F7FFFF          <1> 	call	y_n_answer ; 29/12/2017
  4268                              <1> 	;cmp	al, 'Y' ; 'yes'
  4269                              <1> 	;cmc
  4270                              <1>         ;jnc	loc_file_rw_restore_retn
  4271 00009C70 3C4E                <1> 	cmp	al, 'N' ; 'no'
  4272 00009C72 0F8407F6FFFF        <1>         je	loc_file_rw_restore_retn  
  4273                              <1> 
  4274 00009C78 BE[561D0100]        <1> 	mov	esi, Rename_NewName
  4275 00009C7D 668B0D[FE6E0100]    <1> 	mov	cx, [SourceFile_DirEntryNumber] 
  4276 00009C84 66A1[EA6E0100]      <1> 	mov	ax, [SourceFile_DirEntry+20] ; First Cluster, HW 
  4277 00009C8A C1E010              <1> 	shl	eax, 16 ; 13/11/2017
  4278 00009C8D 66A1[F06E0100]      <1> 	mov	ax, [SourceFile_DirEntry+26] ; First Cluster, LW 
  4279                              <1> 
  4280 00009C93 0FB61D[D36E0100]    <1>   	movzx	ebx, byte [SourceFile_LongNameEntryLength]  
  4281 00009C9A E8CB1B0000          <1>    	call	rename_directory_entry
  4282 00009C9F E9FBF6FFFF          <1> 	jmp	loc_rename_file_ok	
  4283                              <1> ;loc_rename_file_ok:
  4284                              <1> ;	jc	loc_run_cmd_failed
  4285                              <1> ;	mov	esi, Msg_OK
  4286                              <1> ;	call	proc_printmsg
  4287                              <1> ;	jmp	loc_file_rw_restore_retn
  4288                              <1> 
  4289                              <1> move_file:
  4290                              <1> 	; 11/03/2016
  4291                              <1> 	; 09/03/2016
  4292                              <1> 	; 08/03/2016 (TRDOS 386 = TRDOS v2.0)
  4293                              <1> 	; 21/05/2011 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_move')
  4294                              <1> 	; 23/04/2011
  4295                              <1> 
  4296                              <1> get_move_source_fchar:
  4297                              <1> 	; esi = file name
  4298 00009CA4 803E20              <1> 	cmp	byte [esi], 20h
  4299 00009CA7 7614                <1>         jna	short loc_move_nofilename_retn
  4300                              <1> 
  4301 00009CA9 8935[7C6E0100]      <1> 	mov	[SourceFilePath], esi
  4302                              <1> 
  4303                              <1> move_scan_source_file:
  4304 00009CAF 46                  <1> 	inc	esi
  4305 00009CB0 803E20              <1> 	cmp	byte [esi], 20h
  4306 00009CB3 7409                <1>         je      short move_scan_destination_1
  4307                              <1> 	;jb	short loc_move_nofilename_retn
  4308 00009CB5 0F8286ECFFFF        <1> 	jb	loc_cmd_failed
  4309 00009CBB EBF2                <1> 	jmp	short move_scan_source_file
  4310                              <1> 
  4311                              <1> loc_move_nofilename_retn:
  4312 00009CBD C3                  <1> 	retn
  4313                              <1> 
  4314                              <1> move_scan_destination_1:
  4315 00009CBE C60600              <1> 	mov	byte [esi], 0
  4316                              <1> 
  4317                              <1> move_scan_destination_2:
  4318 00009CC1 46                  <1> 	inc	esi  
  4319 00009CC2 803E20              <1> 	cmp	byte [esi], 20h
  4320 00009CC5 74FA                <1> 	je	short move_scan_destination_2
  4321                              <1> 	;jb	short loc_move_nofilename_retn
  4322 00009CC7 0F8274ECFFFF        <1> 	jb	loc_cmd_failed
  4323                              <1> 
  4324 00009CCD 8935[806E0100]      <1> 	mov	[DestinationFilePath], esi
  4325                              <1> 
  4326                              <1> move_scan_destination_3:
  4327 00009CD3 46                  <1> 	inc	esi  
  4328 00009CD4 803E20              <1> 	cmp	byte [esi], 20h
  4329 00009CD7 77FA                <1> 	ja	short move_scan_destination_3
  4330 00009CD9 C60600              <1> 	mov	byte [esi], 0
  4331                              <1> 
  4332                              <1> loc_move_scan_destination_OK:
  4333 00009CDC 8B35[7C6E0100]      <1> 	mov	esi, [SourceFilePath]
  4334 00009CE2 8B3D[806E0100]      <1> 	mov	edi, [DestinationFilePath]
  4335                              <1> 
  4336 00009CE8 B001                <1> 	mov	al, 1  ; move procedure Phase 1
  4337 00009CEA E8F71B0000          <1> 	call	move_source_file_to_destination_file
  4338 00009CEF 7328                <1> 	jnc	short move_source_file_to_destination_question
  4339                              <1> 
  4340                              <1> loc_move_cmd_failed_1:
  4341 00009CF1 08C0                <1> 	or	al, al
  4342 00009CF3 0F8448ECFFFF        <1> 	jz	loc_cmd_failed 
  4343 00009CF9 3C11                <1> 	cmp	al, 11h
  4344 00009CFB 740D                <1> 	je	short loc_msg_not_same_device   
  4345                              <1> 	;cmp	al, 05h
  4346                              <1> 	;cmp	al, ERR_PERM_DENIED ; 29/12/2017
  4347                              <1> 	;jne	loc_run_cmd_failed
  4348                              <1> 	;jmp	loc_permission_denied
  4349 00009CFD 3C0B                <1> 	cmp	al, ERR_PERM_DENIED
  4350 00009CFF 0F8484F5FFFF        <1> 	je	loc_permission_denied
  4351 00009D05 E962ECFFFF          <1> 	jmp	loc_run_cmd_failed
  4352                              <1> 
  4353                              <1> 	;mov	esi, Msg_Permission_denied
  4354                              <1> 	;call	print_msg
  4355                              <1> 	;jmp	loc_file_rw_restore_retn
  4356                              <1> 
  4357                              <1> loc_msg_not_same_device:
  4358 00009D0A BE[631D0100]        <1> 	mov	esi, msg_not_same_drv 
  4359 00009D0F E811D2FFFF          <1> 	call	print_msg
  4360 00009D14 E966F5FFFF          <1> 	jmp	loc_file_rw_restore_retn
  4361                              <1> 
  4362                              <1> move_source_file_to_destination_question:
  4363 00009D19 A0[846E0100]        <1>         mov     al, [SourceFile_Drv]
  4364 00009D1E 0441                <1> 	add	al, 'A'
  4365 00009D20 A2[C51D0100]        <1> 	mov	[msg_source_file_drv], al
  4366 00009D25 A0[046F0100]        <1>         mov     al, [DestinationFile_Drv]
  4367 00009D2A 0441                <1> 	add	al, 'A'
  4368 00009D2C A2[E41D0100]        <1> 	mov	[msg_destination_file_drv], al
  4369                              <1> 
  4370 00009D31 57                  <1> 	push	edi ; *
  4371                              <1> 
  4372 00009D32 BE[A91D0100]        <1> 	mov	esi, msg_source_file
  4373 00009D37 E8E9D1FFFF          <1> 	call	print_msg
  4374 00009D3C BE[856E0100]        <1> 	mov	esi, SourceFile_Directory
  4375 00009D41 803E20              <1> 	cmp	byte [esi], 20h
  4376 00009D44 7605                <1> 	jna	short msftdfq_sfn
  4377 00009D46 E8DAD1FFFF          <1> 	call	print_msg
  4378                              <1> msftdfq_sfn:
  4379 00009D4B BE[C66E0100]        <1> 	mov	esi, SourceFile_Name
  4380 00009D50 E8D0D1FFFF          <1> 	call	print_msg
  4381 00009D55 BE[C81D0100]        <1> 	mov	esi, msg_destination_file
  4382 00009D5A E8C6D1FFFF          <1> 	call	print_msg
  4383 00009D5F BE[056F0100]        <1> 	mov	esi, DestinationFile_Directory
  4384 00009D64 803E20              <1> 	cmp	byte [esi], 20h
  4385 00009D67 7605                <1> 	jna	short msftdfq_dfn
  4386 00009D69 E8B7D1FFFF          <1> 	call	print_msg
  4387                              <1> msftdfq_dfn:
  4388 00009D6E BE[466F0100]        <1> 	mov	esi, DestinationFile_Name
  4389 00009D73 E8ADD1FFFF          <1> 	call	print_msg
  4390 00009D78 BE[E71D0100]        <1> 	mov	esi, msg_copy_nextline
  4391 00009D7D E8A3D1FFFF          <1> 	call	print_msg
  4392 00009D82 BE[E71D0100]        <1> 	mov	esi, msg_copy_nextline
  4393 00009D87 E899D1FFFF          <1> 	call	print_msg
  4394                              <1> 
  4395                              <1> loc_move_ask_for_new_file_yes_no:
  4396 00009D8C BE[751D0100]        <1> 	mov	esi, Msg_DoYouWantMoveFile
  4397 00009D91 E88FD1FFFF          <1> 	call	print_msg
  4398 00009D96 BE[791C0100]        <1> 	mov	esi, Msg_YesNo
  4399 00009D9B E885D1FFFF          <1> 	call	print_msg
  4400                              <1> loc_move_ask_for_new_file_again:
  4401 00009DA0 30E4                <1> 	xor	ah, ah
  4402 00009DA2 E82E71FFFF          <1> 	call	int16h
  4403 00009DA7 3C1B                <1> 	cmp	al, 1Bh
  4404                              <1> 	;je	short loc_do_not_move_file
  4405 00009DA9 7441                <1> 	je	short loc_move_y_n_escape
  4406 00009DAB 24DF                <1> 	and	al, 0DFh
  4407 00009DAD A2[831C0100]        <1>         mov     [Y_N_nextline], al
  4408 00009DB2 3C59                <1> 	cmp	al, 'Y'
  4409 00009DB4 7404                <1> 	je	short loc_yes_move_file
  4410 00009DB6 3C4E                <1> 	cmp	al, 'N'
  4411 00009DB8 75E6                <1> 	jne	short loc_move_ask_for_new_file_again
  4412                              <1> 
  4413                              <1> loc_do_not_move_file:
  4414                              <1> loc_yes_move_file:
  4415 00009DBA E8F9F5FFFF          <1> 	call	y_n_answer ; 29/12/2017
  4416 00009DBF 5F                  <1> 	pop	edi ; *
  4417                              <1> 	;cmp	al, 'Y' ; 'yes'
  4418                              <1> 	;cmc
  4419                              <1>         ;jnc	loc_file_rw_restore_retn
  4420 00009DC0 3C4E                <1> 	cmp	al, 'N' ; 'no'
  4421 00009DC2 0F84B7F4FFFF        <1>         je	loc_file_rw_restore_retn
  4422                              <1> 
  4423                              <1> loc_move_yes_move_file:
  4424 00009DC8 B002                <1> 	mov	al, 2 ; move procedure Phase 2
  4425 00009DCA E8171B0000          <1> 	call	move_source_file_to_destination_file
  4426                              <1> 	;jc	short loc_move_cmd_failed_2
  4427 00009DCF 0F83D0F5FFFF        <1>         jnc     move_source_file_to_destination_OK
  4428                              <1> 
  4429                              <1> ;move_source_file_to_destination_OK:
  4430                              <1> ;	mov	esi, Msg_OK
  4431                              <1> ;	call	print_msg
  4432                              <1> ;	jmp	loc_file_rw_restore_retn
  4433                              <1> 
  4434                              <1> loc_move_cmd_failed_2:
  4435 00009DD5 3C27                <1> 	cmp	al, 27h
  4436 00009DD7 0F858FEBFFFF        <1> 	jne	loc_run_cmd_failed
  4437                              <1> 
  4438 00009DDD BE[8E1D0100]        <1> 	mov	esi, msg_insufficient_disk_space
  4439 00009DE2 E83ED1FFFF          <1> 	call	print_msg
  4440                              <1> 
  4441 00009DE7 E993F4FFFF          <1> 	jmp	loc_file_rw_restore_retn
  4442                              <1> 
  4443                              <1> loc_move_y_n_escape:
  4444 00009DEC B04E                <1> 	mov	al, 'N' ; 'no'
  4445 00009DEE EBCA                <1> 	jmp	short loc_do_not_move_file
  4446                              <1> 
  4447                              <1> copy_file:
  4448                              <1> 	; 15/10/2016
  4449                              <1> 	; 24/03/2016
  4450                              <1> 	; 21/03/2016
  4451                              <1> 	; 15/03/2016 (TRDOS 386 = TRDOS v2.0)
  4452                              <1> 	; 21/05/2011 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_copy')
  4453                              <1> 	; 01/08/2010
  4454                              <1> 
  4455                              <1> get_copy_source_fchar:
  4456                              <1> 	; esi = file name
  4457 00009DF0 803E20              <1> 	cmp	byte [esi], 20h
  4458 00009DF3 7614                <1>         jna     short loc_copy_nofilename_retn
  4459                              <1> 
  4460 00009DF5 8935[7C6E0100]      <1> 	mov	[SourceFilePath], esi
  4461                              <1> 
  4462                              <1> copy_scan_source_file:
  4463 00009DFB 46                  <1> 	inc	esi  
  4464 00009DFC 803E20              <1> 	cmp	byte [esi], 20h
  4465 00009DFF 7409                <1> 	je	short copy_scan_destination_1
  4466                              <1> 	;jb	short loc_copy_nofilename_retn
  4467 00009E01 0F823AEBFFFF        <1> 	jb	loc_cmd_failed
  4468 00009E07 EBF2                <1> 	jmp	short copy_scan_source_file
  4469                              <1> 
  4470                              <1> loc_copy_nofilename_retn:
  4471 00009E09 C3                  <1> 	retn
  4472                              <1> 
  4473                              <1> copy_scan_destination_1:
  4474 00009E0A C60600              <1> 	mov	byte [esi], 0
  4475                              <1> 
  4476                              <1> copy_scan_destination_2:
  4477 00009E0D 46                  <1> 	inc	esi  
  4478 00009E0E 803E20              <1> 	cmp	byte [esi], 20h
  4479 00009E11 74FA                <1> 	je	short copy_scan_destination_2
  4480                              <1> 	;jb	short loc_copy_nofilename_retn
  4481 00009E13 0F8228EBFFFF        <1> 	jb	loc_cmd_failed
  4482                              <1> 
  4483 00009E19 8935[806E0100]      <1> 	mov	[DestinationFilePath], esi
  4484                              <1> 
  4485                              <1> copy_scan_destination_3:
  4486 00009E1F 46                  <1> 	inc	esi  
  4487 00009E20 803E20              <1> 	cmp	byte [esi], 20h
  4488 00009E23 77FA                <1> 	ja	short copy_scan_destination_3
  4489 00009E25 C60600              <1> 	mov	byte [esi], 0
  4490                              <1> 
  4491                              <1> loc_copy_save_current_drive:
  4492 00009E28 8A35[9E640100]      <1> 	mov	dh, [Current_Drv]
  4493 00009E2E 8835[FA6B0100]      <1> 	mov	[RUN_CDRV], dh
  4494                              <1> 
  4495                              <1> copy_source_file_to_destination_phase_1:
  4496 00009E34 8B35[7C6E0100]      <1> 	mov	esi, [SourceFilePath]
  4497 00009E3A 8B3D[806E0100]      <1> 	mov	edi, [DestinationFilePath]
  4498                              <1> 
  4499 00009E40 B001                <1> 	mov	al, 1  ; copy procedure Phase 1
  4500 00009E42 E83C1D0000          <1> 	call	copy_source_file_to_destination_file
  4501 00009E47 732B                <1> 	jnc	short copy_source_file_to_destination_question
  4502                              <1> 
  4503                              <1> loc_copy_cmd_failed_1:
  4504                              <1> 	; 18/03/2016 (restore current drive and directory)
  4505 00009E49 08C0                <1> 	or	al, al
  4506 00009E4B 7507                <1> 	jnz	short loc_copy_cmd_failed_2
  4507                              <1> 
  4508 00009E4D FEC0                <1>         inc     al ; mov al, 1 ; Bad command or file name !
  4509 00009E4F E918EBFFFF          <1> 	jmp	loc_run_cmd_failed
  4510                              <1> 
  4511                              <1> loc_copy_cmd_failed_2:
  4512 00009E54 3C27                <1> 	cmp	al, 27h ; Insufficient disk space 
  4513 00009E56 740D                <1> 	je	short loc_file_write_insuff_disk_space_msg
  4514                              <1>  
  4515                              <1> 	; 29/12/2017
  4516                              <1> 	;cmp	al, 05h
  4517 00009E58 3C0B                <1> 	cmp	al, ERR_PERM_DENIED
  4518 00009E5A 0F850CEBFFFF        <1> 	jne	loc_run_cmd_failed
  4519                              <1> 	
  4520 00009E60 E924F4FFFF          <1> 	jmp	loc_permission_denied
  4521                              <1> 
  4522                              <1> loc_file_write_insuff_disk_space_msg:
  4523 00009E65 BE[8E1D0100]        <1> 	mov	esi, msg_insufficient_disk_space
  4524 00009E6A E8B6D0FFFF          <1> 	call	print_msg
  4525 00009E6F E90BF4FFFF          <1>         jmp     loc_file_rw_restore_retn 
  4526                              <1> 
  4527                              <1> copy_source_file_to_destination_question:
  4528 00009E74 57                  <1> 	push	edi ; *
  4529                              <1> 
  4530                              <1> 	; dh = source file attributes
  4531                              <1> 	; dl > 0 -> destination file found
  4532 00009E75 20D2                <1> 	and	dl, dl            
  4533 00009E77 7449                <1> 	jz	short copy_source_file_to_destination_pass_owrq
  4534                              <1> 
  4535                              <1> loc_copy_ask_for_owr_yes_no:
  4536 00009E79 BE[EA1D0100]        <1> 	mov	esi, Msg_DoYouWantOverWriteFile
  4537 00009E7E E8A2D0FFFF          <1> 	call	print_msg
  4538 00009E83 BE[466F0100]        <1> 	mov	esi, DestinationFile_Name
  4539 00009E88 E898D0FFFF          <1> 	call	print_msg
  4540 00009E8D BE[791C0100]        <1> 	mov	esi, Msg_YesNo
  4541 00009E92 E88ED0FFFF          <1> 	call	print_msg
  4542                              <1> 
  4543                              <1> loc_copy_ask_for_owr_again:
  4544 00009E97 30E4                <1> 	xor	ah, ah
  4545 00009E99 E83770FFFF          <1> 	call	int16h
  4546 00009E9E 3C1B                <1> 	cmp	al, 1Bh
  4547                              <1>         ;je     loc_do_not_copy_file
  4548 00009EA0 7419                <1>         je      short loc_copy_y_n_escape
  4549 00009EA2 24DF                <1> 	and	al, 0DFh
  4550 00009EA4 A2[831C0100]        <1>         mov     [Y_N_nextline], al
  4551 00009EA9 3C59                <1> 	cmp	al, 'Y'
  4552 00009EAB 0F84B1000000        <1>         je      loc_yes_copy_file
  4553 00009EB1 3C4E                <1> 	cmp	al, 'N'
  4554 00009EB3 0F84A9000000        <1>         je      loc_do_not_copy_file
  4555 00009EB9 EBDC                <1> 	jmp	short loc_copy_ask_for_owr_again
  4556                              <1> 
  4557                              <1> loc_copy_y_n_escape:
  4558 00009EBB B04E                <1> 	mov	al, 'N' ; 'no'
  4559 00009EBD E9A0000000          <1>         jmp     loc_do_not_copy_file
  4560                              <1> 
  4561                              <1> copy_source_file_to_destination_pass_owrq:
  4562 00009EC2 A0[846E0100]        <1> 	mov     al, [SourceFile_Drv]
  4563 00009EC7 0441                <1> 	add	al, 'A'
  4564 00009EC9 A2[C51D0100]        <1> 	mov	[msg_source_file_drv], al
  4565 00009ECE A0[046F0100]        <1>         mov     al, [DestinationFile_Drv]
  4566 00009ED3 0441                <1> 	add	al, 'A'
  4567 00009ED5 A2[E41D0100]        <1> 	mov	[msg_destination_file_drv], al
  4568                              <1> 
  4569 00009EDA BE[A91D0100]        <1> 	mov	esi, msg_source_file
  4570 00009EDF E841D0FFFF          <1> 	call	print_msg
  4571 00009EE4 BE[856E0100]        <1> 	mov	esi, SourceFile_Directory
  4572 00009EE9 803E20              <1> 	cmp	byte [esi], 20h
  4573 00009EEC 7605                <1> 	jna	short csftdfq_sfn
  4574 00009EEE E832D0FFFF          <1> 	call	print_msg
  4575                              <1> csftdfq_sfn:
  4576 00009EF3 BE[C66E0100]        <1> 	mov	esi, SourceFile_Name
  4577 00009EF8 E828D0FFFF          <1> 	call	print_msg
  4578 00009EFD BE[C81D0100]        <1> 	mov	esi, msg_destination_file
  4579 00009F02 E81ED0FFFF          <1> 	call	print_msg
  4580 00009F07 BE[056F0100]        <1> 	mov	esi, DestinationFile_Directory
  4581 00009F0C 803E20              <1> 	cmp	byte [esi], 20h
  4582 00009F0F 7605                <1> 	jna	short csftdfq_dfn
  4583 00009F11 E80FD0FFFF          <1> 	call	print_msg
  4584                              <1> csftdfq_dfn:
  4585 00009F16 BE[466F0100]        <1> 	mov	esi, DestinationFile_Name
  4586 00009F1B E805D0FFFF          <1> 	call	print_msg
  4587 00009F20 BE[E71D0100]        <1> 	mov	esi, msg_copy_nextline
  4588 00009F25 E8FBCFFFFF          <1> 	call	print_msg
  4589 00009F2A BE[E71D0100]        <1> 	mov	esi, msg_copy_nextline
  4590 00009F2F E8F1CFFFFF          <1> 	call	print_msg
  4591                              <1> 
  4592                              <1> loc_copy_ask_for_new_file_yes_no:
  4593 00009F34 BE[091E0100]        <1> 	mov	esi, Msg_DoYouWantCopyFile
  4594 00009F39 E8E7CFFFFF          <1> 	call	print_msg
  4595 00009F3E BE[791C0100]        <1> 	mov	esi, Msg_YesNo
  4596 00009F43 E8DDCFFFFF          <1> 	call	print_msg
  4597                              <1> 
  4598                              <1> loc_copy_ask_for_new_file_again:
  4599 00009F48 30E4                <1> 	xor	ah, ah
  4600 00009F4A E8866FFFFF          <1> 	call	int16h
  4601 00009F4F 3C1B                <1> 	cmp	al, 1Bh
  4602 00009F51 740F                <1> 	je	short loc_do_not_copy_file
  4603 00009F53 24DF                <1> 	and	al, 0DFh
  4604 00009F55 A2[831C0100]        <1>         mov     [Y_N_nextline], al
  4605 00009F5A 3C59                <1> 	cmp	al, 'Y'
  4606 00009F5C 7404                <1> 	je	short loc_yes_copy_file
  4607 00009F5E 3C4E                <1> 	cmp	al, 'N'
  4608 00009F60 75E6                <1> 	jne	short loc_copy_ask_for_new_file_again
  4609                              <1> 
  4610                              <1> loc_do_not_copy_file:
  4611                              <1> loc_yes_copy_file:
  4612 00009F62 E851F4FFFF          <1> 	call	y_n_answer ; 29/12/2017
  4613 00009F67 5F                  <1> 	pop	edi ; *
  4614                              <1> 	;cmp	al, 'Y' ; 'yes'
  4615                              <1> 	;cmc
  4616                              <1>         ;jnc	loc_file_rw_restore_retn
  4617 00009F68 3C4E                <1> 	cmp	al, 'N' ; 'no'
  4618 00009F6A 0F840FF3FFFF        <1>         je	loc_file_rw_restore_retn
  4619                              <1> 
  4620                              <1> copy_source_file_to_destination_pass_q:
  4621 00009F70 B002                <1> 	mov	al, 2  ; copy procedure Phase 2
  4622 00009F72 E80C1C0000          <1> 	call	copy_source_file_to_destination_file
  4623                              <1> 	;jc	short loc_file_write_check_disk_space_err
  4624                              <1> 
  4625                              <1> 	; 24/03/2016
  4626                              <1> 	;push	cx
  4627 00009F77 51                  <1> 	push	ecx ; 29/12/2017
  4628 00009F78 BE[E71D0100]        <1> 	mov	esi, msg_copy_nextline
  4629 00009F7D E8A3CFFFFF          <1> 	call	print_msg
  4630 00009F82 58                  <1> 	pop	eax ; 29/12/2017
  4631                              <1> 	;;pop	cx
  4632                              <1> 	;pop	ax
  4633                              <1> 
  4634                              <1> 	;or	cl, cl
  4635 00009F83 08C0                <1> 	or	al, al
  4636 00009F85 7419                <1> 	jz	short copy_source_file_to_destination_OK
  4637                              <1> 	
  4638                              <1> 	; 15/10/2016 (1Dh -> 18)
  4639                              <1> 	; 18/03/2016 (1Dh)
  4640                              <1> 	;cmp	cl, 18 ; write error
  4641 00009F87 3C12                <1> 	cmp	al, 18
  4642 00009F89 7506                <1> 	jne	short copy_source_file_to_destination_not_OK
  4643                              <1> 	;
  4644                              <1> 	;mov	al, cl ; error number (write fault!)
  4645 00009F8B F9                  <1> 	stc
  4646 00009F8C E9EEF2FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  4647                              <1> 
  4648                              <1> copy_source_file_to_destination_not_OK:
  4649 00009F91 BE[221E0100]        <1> 	mov	esi, Msg_read_file_error_before_EOF
  4650 00009F96 E88ACFFFFF          <1> 	call	print_msg
  4651 00009F9B E9DFF2FFFF          <1> 	jmp	loc_file_rw_restore_retn	      
  4652                              <1>  
  4653                              <1> copy_source_file_to_destination_OK:
  4654 00009FA0 BE[871C0100]        <1> 	mov	esi, Msg_OK
  4655 00009FA5 E87BCFFFFF          <1> 	call	print_msg
  4656                              <1> 
  4657 00009FAA E9D0F2FFFF          <1> 	jmp	loc_file_rw_restore_retn
  4658                              <1> 
  4659                              <1> ;loc_file_write_check_disk_space_err:
  4660                              <1> 	;cmp	al, 27h ; Insufficient disk space 
  4661                              <1> 	;je	loc_file_write_insuff_disk_space_msg
  4662                              <1>         ;jb	loc_file_rw_cmd_failed
  4663                              <1> 
  4664                              <1> 	;call	print_misc_error_msg ; 15/03/2016
  4665                              <1>         ;jmp	loc_file_rw_restore_retn 
  4666                              <1> 
  4667                              <1> change_fs_file_attributes:
  4668                              <1> 	; 04/03/2016 ; Temporary
  4669                              <1> 	; AL = File or directory attributes
  4670                              <1> 	; AH = 0 -> Attributes are in MS-DOS format
  4671                              <1> 	; AH > 0 -> Attributes are in SINGLIX format
  4672                              <1> 	;push	ebx
  4673                              <1> 	; ... do somethings here ...
  4674                              <1> 	;pop	ebx
  4675                              <1> 	; BL = File or directory attributes
  4676 00009FAF C3                  <1> 	retn
  4677                              <1> 
  4678                              <1> set_get_env:
  4679                              <1> 	; 11/04/2016 (TRDOS 386 = TRDOS v2.0)
  4680                              <1> 	; 02/09/2011 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_set')
  4681                              <1> 	; 2005 - 28/08/2011 
  4682                              <1> get_setenv_fchar:
  4683                              <1> 	; esi = environment variable/string
  4684 00009FB0 8A06                <1> 	mov	al, [esi]
  4685 00009FB2 3C20                <1> 	cmp	al, 20h
  4686 00009FB4 771E                <1> 	ja	short loc_find_env
  4687                              <1> 
  4688 00009FB6 BE00300900          <1> 	mov	esi, Env_Page
  4689                              <1> loc_print_setline:
  4690 00009FBB 803E00              <1> 	cmp	byte [esi], 0
  4691 00009FBE 7613                <1> 	jna	short loc_setenv_retn
  4692 00009FC0 E860CFFFFF          <1> 	call	print_msg
  4693 00009FC5 56                  <1> 	push	esi
  4694 00009FC6 BE[93240100]        <1> 	mov	esi, nextline
  4695 00009FCB E855CFFFFF          <1> 	call	print_msg 
  4696 00009FD0 5E                  <1> 	pop	esi
  4697 00009FD1 EBE8                <1> 	jmp	short loc_print_setline   
  4698                              <1> 
  4699                              <1> loc_setenv_retn: 
  4700 00009FD3 C3                  <1> 	retn
  4701                              <1> 
  4702                              <1> loc_find_env:
  4703 00009FD4 3C3D                <1> 	cmp	al, '='
  4704 00009FD6 0F8465E9FFFF        <1> 	je	loc_cmd_failed
  4705                              <1> 
  4706 00009FDC 56                  <1> 	push	esi
  4707                              <1> loc_repeat_env_equal_check:
  4708 00009FDD 46                  <1> 	inc	esi
  4709 00009FDE 803E3D              <1> 	cmp	byte [esi], '='
  4710 00009FE1 7431                <1> 	je	short pass_env_equal_check
  4711 00009FE3 803E20              <1> 	cmp	byte [esi], 20h
  4712 00009FE6 73F5                <1> 	jnb	short loc_repeat_env_equal_check
  4713 00009FE8 C60600              <1> 	mov	byte [esi], 0 
  4714 00009FEB 5E                  <1> 	pop	esi
  4715 00009FEC BF[9E650100]        <1> 	mov	edi, TextBuffer ; out buffer
  4716 00009FF1 B9FF000000          <1> 	mov	ecx, 255 ; maximum size (limit)
  4717 00009FF6 30C0                <1> 	xor	al, al ; 0 -> use [ESI]
  4718 00009FF8 E89E000000          <1> 	call	get_environment_string
  4719 00009FFD 72D4                <1> 	jc	short loc_setenv_retn
  4720                              <1> 
  4721 00009FFF BE[9E650100]        <1> 	mov	esi, TextBuffer
  4722 0000A004 E81CCFFFFF          <1> 	call	print_msg
  4723 0000A009 BE[93240100]        <1> 	mov	esi, nextline
  4724 0000A00E E812CFFFFF          <1> 	call	print_msg
  4725                              <1> 
  4726 0000A013 C3                  <1> 	retn 
  4727                              <1>               
  4728                              <1> pass_env_equal_check:
  4729 0000A014 46                  <1> 	inc	esi
  4730 0000A015 803E20              <1> 	cmp	byte [esi], 20h
  4731 0000A018 73FA                <1> 	jnb	short pass_env_equal_check
  4732 0000A01A C60600              <1> 	mov	byte [esi], 0	
  4733                              <1> 
  4734                              <1> loc_call_set_env_string:
  4735 0000A01D 5E                  <1> 	pop	esi
  4736 0000A01E E83B010000          <1> 	call	set_environment_string
  4737 0000A023 73AE                <1> 	jnc	short loc_setenv_retn
  4738                              <1> 
  4739                              <1> loc_set_cmd_failed:
  4740 0000A025 3C08                <1> 	cmp	al, 08h
  4741 0000A027 0F8514E9FFFF        <1> 	jne	loc_cmd_failed
  4742                              <1> 
  4743 0000A02D BE[621E0100]        <1> 	mov	esi, Msg_No_Set_Space
  4744 0000A032 E8EECEFFFF          <1> 	call	print_msg
  4745                              <1> 
  4746 0000A037 C3                  <1> 	retn
  4747                              <1> 
  4748                              <1> set_get_path:
  4749                              <1> 	; 11/04/2016 (TRDOS 386 = TRDOS v2.0)
  4750                              <1> 	; 03/09/2011 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_path')
  4751                              <1> 	; 2005
  4752                              <1> get_path_fchar:
  4753                              <1>  	; esi = path
  4754 0000A038 803E20              <1> 	cmp	byte [esi], 20h
  4755 0000A03B 7737                <1> 	ja	short loc_set_path
  4756                              <1> 
  4757 0000A03D BE00300900          <1> 	mov	esi, Env_Page
  4758                              <1> loc_print_path:
  4759 0000A042 803E00              <1> 	cmp	byte [esi], 0
  4760 0000A045 762C                <1> 	jna	short loc_path_retn
  4761                              <1> 
  4762 0000A047 BE[C2180100]        <1> 	mov	esi, Cmd_Path ; 'PATH' address
  4763 0000A04C BF[9E650100]        <1> 	mov	edi, TextBuffer ; out buffer
  4764 0000A051 30C0                <1> 	xor	al, al  ; use [ESI]
  4765 0000A053 B9FF000000          <1> 	mov	ecx, 255 ; maximum size (limit)
  4766 0000A058 E83E000000          <1> 	call	get_environment_string
  4767 0000A05D 7214                <1> 	jc	short loc_path_retn
  4768                              <1> 
  4769 0000A05F BE[9E650100]        <1> 	mov	esi, TextBuffer
  4770 0000A064 E8BCCEFFFF          <1> 	call	print_msg
  4771 0000A069 BE[93240100]        <1> 	mov	esi, nextline
  4772 0000A06E E8B2CEFFFF          <1> 	call	print_msg   
  4773                              <1> 
  4774                              <1> loc_path_retn: 
  4775 0000A073 C3                  <1> 	retn
  4776                              <1> 
  4777                              <1> loc_set_path:
  4778 0000A074 56                  <1> 	push	esi 
  4779                              <1> loc_set_path_find_end:
  4780 0000A075 46                  <1> 	inc	esi
  4781 0000A076 803E20              <1> 	cmp	byte [esi], 20h
  4782 0000A079 73FA                <1> 	jnb	short loc_set_path_find_end
  4783 0000A07B C60600              <1> 	mov	byte [esi], 0 
  4784                              <1> loc_set_path_header: 
  4785 0000A07E 5E                  <1> 	pop	esi
  4786                              <1> set_path_x: ; 31/12/2017 ('syspath')	  
  4787 0000A07F 4E                  <1> 	dec	esi
  4788 0000A080 C6063D              <1> 	mov	byte [esi], '='
  4789 0000A083 4E                  <1> 	dec	esi
  4790 0000A084 C60648              <1> 	mov	byte [esi], 'H'
  4791 0000A087 4E                  <1> 	dec	esi
  4792 0000A088 C60654              <1> 	mov	byte [esi], 'T'
  4793 0000A08B 4E                  <1> 	dec	esi
  4794 0000A08C C60641              <1> 	mov	byte [esi], 'A'
  4795 0000A08F 4E                  <1> 	dec	esi
  4796 0000A090 C60650              <1> 	mov	byte [esi], 'P'   
  4797                              <1> 
  4798                              <1> loc_path_call_set_env_string:
  4799 0000A093 E8C6000000          <1> 	call	set_environment_string
  4800 0000A098 728B                <1>         jc	short loc_set_cmd_failed
  4801                              <1> 
  4802 0000A09A C3                  <1> 	retn              
  4803                              <1> 
  4804                              <1> get_environment_string:
  4805                              <1> 	; 12/04/2016
  4806                              <1> 	; 11/04/2016
  4807                              <1> 	; 05/04/2016 (TRDOS 386 = TRDOS v2.0)
  4808                              <1> 	; 02/09/2011 (TRDOS v1, MAINPROG.ASM)
  4809                              <1> 	; 28/08/2011
  4810                              <1> 	; INPUT->
  4811                              <1> 	;	EDI = Output buffer
  4812                              <1> 	;	CX = Buffer length (<= ENV_PAGE_SIZE)
  4813                              <1> 	;
  4814                              <1> 	;	AL > 0 = AL = String sequence number
  4815                              <1> 	;	AL = 0 -> ESI = ASCIIZ Set word 
  4816                              <1> 	;		(environment variable)
  4817                              <1> 	; OUTPUT ->
  4818                              <1> 	;	ESI is not changed
  4819                              <1> 	;	EDI is not changed
  4820                              <1> 	;	EAX = String length (with zero tail)
  4821                              <1> 	;	EDX = Environment variables page address
  4822                              <1> 	;	CF = 1 -> Not found (EAX not valid)
  4823                              <1> 	;
  4824                              <1> 	; (Modified registers: EAX, EDX) 
  4825                              <1> 
  4826 0000A09B BA00300900          <1> 	mov	edx, Env_Page
  4827 0000A0A0 803A00              <1> 	cmp	byte [edx], 0
  4828 0000A0A3 7474                <1> 	jz	short get_env_string_with_word_stc_retn
  4829                              <1> 
  4830 0000A0A5 66890D[08700100]    <1> 	mov	[env_var_length], cx
  4831                              <1> 
  4832 0000A0AC 51                  <1> 	push	ecx ; *
  4833 0000A0AD 56                  <1> 	push	esi ; **
  4834                              <1> 
  4835 0000A0AE 08C0                <1> 	or	al, al
  4836 0000A0B0 7449                <1> 	jz	short get_env_string_with_word
  4837                              <1> 
  4838                              <1> get_env_string_with_seq_number:
  4839 0000A0B2 B101                <1> 	mov	cl, 1
  4840 0000A0B4 88C5                <1> 	mov	ch, al
  4841 0000A0B6 31C0                <1> 	xor	eax, eax
  4842 0000A0B8 89D6                <1> 	mov	esi, edx ; Env_Page
  4843                              <1> 
  4844                              <1> get_env_string_seq_number_check:
  4845 0000A0BA 38CD                <1> 	cmp	ch, cl
  4846 0000A0BC 7726                <1> 	ja	short get_env_string_seq_number_next
  4847                              <1> 
  4848                              <1> get_env_string_move_to_buff:
  4849 0000A0BE 57                  <1> 	push	edi ; ***
  4850                              <1> 
  4851 0000A0BF 29D2                <1> 	sub	edx, edx
  4852                              <1> 
  4853                              <1> get_env_string_seq_number_repeat1:
  4854 0000A0C1 42                  <1> 	inc	edx
  4855 0000A0C2 AC                  <1> 	lodsb
  4856 0000A0C3 AA                  <1> 	stosb
  4857                              <1> 
  4858 0000A0C4 66FF0D[08700100]    <1> 	dec	word [env_var_length]
  4859 0000A0CB 7508                <1> 	jnz	short get_env_string_seq_number_repeat3
  4860                              <1> 
  4861                              <1> get_env_string_seq_number_repeat2:
  4862 0000A0CD 20C0                <1> 	and	al, al
  4863 0000A0CF 7408                <1> 	jz	short get_env_string_seq_number_ok
  4864 0000A0D1 42                  <1> 	inc	edx
  4865 0000A0D2 AC                  <1> 	lodsb
  4866 0000A0D3 EBF8                <1> 	jmp	short get_env_string_seq_number_repeat2
  4867                              <1> 
  4868                              <1> get_env_string_seq_number_repeat3:
  4869 0000A0D5 08C0                <1> 	or	al, al
  4870 0000A0D7 75E8                <1> 	jnz	short get_env_string_seq_number_repeat1
  4871                              <1> 
  4872                              <1> get_env_string_seq_number_ok:
  4873 0000A0D9 5F                  <1> 	pop	edi ; ***
  4874 0000A0DA 89D0                <1> 	mov	eax, edx ; Length of the environment string
  4875                              <1> 			 ; (ASCIIZ, includes ZERO tail)
  4876 0000A0DC BA00300900          <1> 	mov	edx, Env_Page
  4877                              <1> 
  4878                              <1> get_env_string_stc_retn:
  4879 0000A0E1 5E                  <1> 	pop	esi ; **
  4880 0000A0E2 59                  <1> 	pop	ecx ; *
  4881 0000A0E3 C3                  <1> 	retn   
  4882                              <1> 	
  4883                              <1> get_env_string_seq_number_next:
  4884 0000A0E4 AC                  <1> 	lodsb
  4885 0000A0E5 08C0                <1> 	or	al, al
  4886 0000A0E7 75FB                <1> 	jnz	short get_env_string_seq_number_next
  4887                              <1> 
  4888 0000A0E9 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size ; +512 (+4096)
  4889 0000A0EF F5                  <1> 	cmc
  4890 0000A0F0 72EF                <1> 	jc	short get_env_string_stc_retn
  4891                              <1> 
  4892 0000A0F2 AC                  <1> 	lodsb
  4893 0000A0F3 3C01                <1> 	cmp	al, 1
  4894 0000A0F5 72EA                <1> 	jb	short get_env_string_stc_retn
  4895 0000A0F7 FEC1                <1> 	inc	cl
  4896 0000A0F9 EBBF                <1> 	jmp	short get_env_string_seq_number_check
  4897                              <1> 
  4898                              <1> get_env_string_with_word:
  4899 0000A0FB 31C9                <1> 	xor	ecx, ecx
  4900                              <1> 
  4901                              <1> get_env_string_calc_word_length:
  4902 0000A0FD AC                  <1> 	lodsb 
  4903 0000A0FE 3C20                <1> 	cmp	al, 20h
  4904 0000A100 7211                <1> 	jb	short get_env_string_calc_word_length_ok
  4905                              <1> 	;inc	cx
  4906 0000A102 FEC1                <1> 	inc	cl
  4907                              <1> 
  4908 0000A104 3C61                <1> 	cmp	al, 'a'
  4909 0000A106 72F5                <1> 	jb	short get_env_string_calc_word_length
  4910 0000A108 3C7A                <1> 	cmp	al, 'z'
  4911 0000A10A 77F1                <1> 	ja	short get_env_string_calc_word_length
  4912 0000A10C 24DF                <1> 	and	al, 0DFh
  4913 0000A10E 8846FF              <1> 	mov	[esi-1], al
  4914 0000A111 EBEA                <1> 	jmp	short get_env_string_calc_word_length
  4915                              <1> 	
  4916                              <1> get_env_string_calc_word_length_ok:
  4917 0000A113 08C9                <1> 	or	cl, cl
  4918 0000A115 7506                <1> 	jnz	short get_env_string_calc_word_length_save
  4919                              <1>      
  4920 0000A117 5E                  <1> 	pop	esi ; **
  4921                              <1> 
  4922                              <1> get_env_string_stc_retn1:
  4923 0000A118 59                  <1> 	pop	ecx ; *
  4924                              <1>         
  4925                              <1> get_env_string_with_word_stc_retn:
  4926 0000A119 31C0                <1> 	xor	eax, eax  
  4927 0000A11B F9                  <1> 	stc
  4928 0000A11C C3                  <1> 	retn
  4929                              <1>   
  4930                              <1> get_env_string_calc_word_length_save:
  4931 0000A11D 871C24              <1> 	xchg	ebx, [esp] ; **
  4932 0000A120 89DE                <1> 	mov	esi, ebx 
  4933                              <1> 		; Start of the env string (to be searched)
  4934                              <1> 
  4935 0000A122 57                  <1> 	push	edi ; ***
  4936 0000A123 89D7                <1> 	mov	edi, edx ; Env_Page
  4937                              <1> 
  4938                              <1> get_env_string_compare:
  4939 0000A125 57                  <1> 	push	edi ; ****
  4940 0000A126 51                  <1> 	push	ecx ; ***** ; Variable name length
  4941                              <1> 
  4942                              <1> get_env_string_compare_rep:
  4943 0000A127 AC                  <1> 	lodsb
  4944 0000A128 AE                  <1> 	scasb
  4945 0000A129 7511                <1> 	jne	short get_env_string_compare_next1
  4946 0000A12B E2FA                <1> 	loop	get_env_string_compare_rep
  4947                              <1> 	
  4948 0000A12D 803F3D              <1> 	cmp	byte [edi], '='
  4949 0000A130 750A                <1> 	jne	short get_env_string_compare_next1
  4950                              <1>  
  4951 0000A132 59                  <1> 	pop	ecx ; *****
  4952 0000A133 5F                  <1> 	pop	edi ; ****
  4953 0000A134 89FE                <1> 	mov	esi, edi
  4954 0000A136 5F                  <1> 	pop	edi ; ***
  4955 0000A137 871C24              <1> 	xchg	ebx, [esp] ; **
  4956 0000A13A EB82                <1> 	jmp	short get_env_string_move_to_buff
  4957                              <1> 
  4958                              <1> get_env_string_compare_next1:
  4959 0000A13C 89FE                <1> 	mov	esi, edi
  4960 0000A13E 59                  <1> 	pop	ecx ; *****
  4961 0000A13F 5F                  <1> 	pop	edi ; ****
  4962                              <1> get_env_string_compare_next2:
  4963 0000A140 81FEFF310900        <1> 	cmp	esi, Env_Page + Env_Page_Size - 1 ; +511 (+4095)
  4964 0000A146 7310                <1> 	jnb	short get_env_string_compare_not_ok
  4965 0000A148 20C0                <1> 	and	al, al
  4966 0000A14A AC                  <1> 	lodsb
  4967 0000A14B 75F3                <1> 	jnz	short get_env_string_compare_next2
  4968 0000A14D 08C0                <1> 	or	al, al
  4969 0000A14F 7407                <1> 	jz	short get_env_string_compare_not_ok
  4970 0000A151 4E                  <1> 	dec	esi ; 12/04/2016
  4971 0000A152 89F7                <1> 	mov	edi, esi
  4972 0000A154 89DE                <1> 	mov	esi, ebx
  4973 0000A156 EBCD                <1> 	jmp	short get_env_string_compare
  4974                              <1> 
  4975                              <1> get_env_string_compare_not_ok:
  4976 0000A158 5F                  <1> 	pop	edi ; ***
  4977 0000A159 89DE                <1> 	mov	esi, ebx
  4978 0000A15B 5B                  <1> 	pop	ebx ; **
  4979 0000A15C EBBA                <1> 	jmp	short get_env_string_stc_retn1
  4980                              <1> 
  4981                              <1> set_environment_string:
  4982                              <1> 	; 13/04/2016
  4983                              <1> 	; 12/04/2016
  4984                              <1> 	; 11/04/2016
  4985                              <1> 	; 06/04/2016
  4986                              <1> 	; 05/04/2016 (TRDOS 386 = TRDOS v2.0)
  4987                              <1> 	; 02/09/2011 (TRDOS v1, MAINPROG.ASM)
  4988                              <1> 	; 29/08/2011
  4989                              <1> 	; 29/08/2011
  4990                              <1> 	; INPUT->
  4991                              <1> 	;	ESI = ASCIIZ environment string
  4992                              <1> 	; OUTPUT ->
  4993                              <1> 	;	ESI is not changed
  4994                              <1> 	;	CF = 1 -> Could not set, 
  4995                              <1> 	;	     insufficient environment space
  4996                              <1> 	;
  4997                              <1> 	; (EAX, EDX will be changed) 
  4998                              <1> 	;
  4999                              <1> 	;    (EAX = Start address of the env string if > 0)	
  5000                              <1> 	;    (EDX = Environment string length)	
  5001                              <1> 
  5002 0000A15E 56                  <1> 	push 	esi ; *
  5003                              <1> 
  5004 0000A15F 31C0                <1> 	xor	eax, eax
  5005                              <1> 
  5006                              <1> set_env_chk_validation1:
  5007 0000A161 FEC4                <1> 	inc	ah ; variable (string) length
  5008 0000A163 AC                  <1> 	lodsb
  5009 0000A164 3C3D                <1> 	cmp	al, '='
  5010 0000A166 7415                <1> 	je	short set_env_chk_validation2
  5011 0000A168 3C20                <1> 	cmp	al, 20h
  5012 0000A16A 720F                <1> 	jb	short set_env_string_stc
  5013                              <1> 
  5014                              <1> 	; 06/04/2016
  5015 0000A16C 3C61                <1> 	cmp	al, 'a'
  5016 0000A16E 72F1                <1> 	jb	short set_env_chk_validation1
  5017 0000A170 3C7A                <1> 	cmp	al, 'z'
  5018 0000A172 77ED                <1> 	ja	short set_env_chk_validation1
  5019 0000A174 2C20                <1> 	sub	al, 'a'-'A'
  5020 0000A176 8846FF              <1> 	mov	[esi-1], al
  5021 0000A179 EBE6                <1> 	jmp	short set_env_chk_validation1
  5022                              <1> 
  5023                              <1> set_env_string_stc:
  5024 0000A17B 5E                  <1> 	pop	esi ; *
  5025                              <1> 	;stc
  5026 0000A17C C3                  <1> 	retn 
  5027                              <1> 	   
  5028                              <1> set_env_chk_validation2:
  5029 0000A17D 51                  <1> 	push	ecx ; **
  5030 0000A17E 53                  <1> 	push	ebx ; *** 
  5031 0000A17F 57                  <1> 	push	edi ; ****
  5032                              <1> 
  5033                              <1> 	; 12/04/2016
  5034 0000A180 8B5C240C            <1> 	mov	ebx, [esp+12]
  5035                              <1> 
  5036                              <1> set_env_chk_validation2w:
  5037 0000A184 89F7                <1> 	mov	edi, esi
  5038 0000A186 4F                  <1> 	dec	edi
  5039                              <1> 
  5040 0000A187 807FFF20            <1> 	cmp	byte [edi-1], 20h
  5041 0000A18B 771A                <1> 	ja	short set_env_chk_validation2z
  5042                              <1> 	
  5043 0000A18D 56                  <1> 	push	esi
  5044 0000A18E 89FE                <1> 	mov	esi, edi
  5045 0000A190 4E                  <1> 	dec	esi
  5046                              <1> 
  5047                              <1> set_env_chk_validation2x:
  5048 0000A191 4E                  <1> 	dec	esi
  5049                              <1> 
  5050 0000A192 39DE                <1> 	cmp	esi, ebx
  5051 0000A194 7207                <1> 	jb	short set_env_chk_validation2y
  5052                              <1> 
  5053 0000A196 4F                  <1> 	dec	edi
  5054                              <1> 
  5055 0000A197 8A06                <1> 	mov	al, [esi]
  5056 0000A199 8807                <1> 	mov	[edi], al
  5057                              <1> 
  5058 0000A19B EBF4                <1> 	jmp	short set_env_chk_validation2x
  5059                              <1> 
  5060                              <1> set_env_chk_validation2y:
  5061 0000A19D 5E                  <1> 	pop	esi
  5062                              <1> 
  5063                              <1> 	;mov	byte [ebx], 20h
  5064                              <1> 	
  5065 0000A19E 43                  <1> 	inc 	ebx
  5066 0000A19F 895C240C            <1> 	mov	[esp+12], ebx
  5067                              <1> 
  5068 0000A1A3 FECC                <1> 	dec 	ah ; 13/04/2016
  5069                              <1> 
  5070 0000A1A5 EBDD                <1> 	jmp	short set_env_chk_validation2w
  5071                              <1> 	
  5072                              <1> set_env_chk_validation2z:	
  5073 0000A1A7 BA00300900          <1> 	mov	edx, Env_Page
  5074 0000A1AC 89D7                <1> 	mov	edi, edx
  5075                              <1> 
  5076                              <1> set_env_chk_validation3:
  5077 0000A1AE AC                  <1> 	lodsb
  5078 0000A1AF 3C20                <1> 	cmp	al, 20h
  5079 0000A1B1 74FB                <1> 	je	short set_env_chk_validation3
  5080                              <1> 
  5081 0000A1B3 9C                  <1> 	pushf
  5082                              <1> 
  5083                              <1> 	; 12/04/2016
  5084                              <1> set_env_chk_validation3n:
  5085 0000A1B4 3C61                <1> 	cmp	al, 'a'
  5086 0000A1B6 720C                <1> 	jb	short set_env_chk_validation3c
  5087 0000A1B8 3C7A                <1> 	cmp	al, 'z'
  5088 0000A1BA 7705                <1> 	ja	short set_env_chk_validation3x
  5089 0000A1BC 2C20                <1> 	sub	al, 'a'-'A'
  5090 0000A1BE 8846FF              <1> 	mov	[esi-1], al
  5091                              <1> 
  5092                              <1> set_env_chk_validation3x:
  5093 0000A1C1 AC                  <1> 	lodsb
  5094 0000A1C2 EBF0                <1> 	jmp	short set_env_chk_validation3n
  5095                              <1> 
  5096                              <1> set_env_chk_validation3c:
  5097 0000A1C4 3C20                <1> 	cmp	al, 20h
  5098 0000A1C6 73F9                <1> 	jnb	short set_env_chk_validation3x
  5099                              <1> 		
  5100 0000A1C8 803F00              <1> 	cmp	byte [edi], 0
  5101 0000A1CB 7731                <1> 	ja	short set_env_chk_validation4
  5102                              <1> 
  5103 0000A1CD 9D                  <1> 	popf
  5104 0000A1CE 7228                <1> 	jb	short set_env_string_nothing
  5105                              <1> 
  5106 0000A1D0 B900020000          <1> 	mov	ecx, Env_Page_Size ; 512 (4096)
  5107                              <1> 
  5108 0000A1D5 89DE                <1> 	mov	esi, ebx ; 12/04/2016
  5109                              <1> 
  5110                              <1> set_env_string_copy_to_envb:
  5111 0000A1D7 AC                  <1> 	lodsb
  5112 0000A1D8 3C20                <1> 	cmp	al, 20h
  5113 0000A1DA 720A                <1> 	jb	short set_env_string_copy_to_envb_z
  5114 0000A1DC AA                  <1> 	stosb
  5115 0000A1DD E2F8                <1> 	loop	set_env_string_copy_to_envb
  5116                              <1> 
  5117                              <1> 	; 11/04/2016
  5118 0000A1DF 89D7                <1> 	mov	edi, edx ; Env_Page
  5119 0000A1E1 B900020000          <1> 	mov	ecx, Env_Page_Size 
  5120                              <1> 
  5121                              <1> set_env_string_copy_to_envb_z:
  5122 0000A1E6 52                  <1> 	push	edx  ; Start address of the variable
  5123 0000A1E7 BA00020000          <1> 	mov	edx, Env_Page_Size
  5124 0000A1EC 29CA                <1> 	sub	edx, ecx ; variable (string) length
  5125                              <1> 
  5126 0000A1EE 28C0                <1> 	sub	al, al ; 0
  5127 0000A1F0 F3AA                <1>  	rep	stosb ; clear remain bytes of the env page
  5128                              <1> 
  5129 0000A1F2 58                  <1> 	pop	eax  ; Start address of the variable
  5130                              <1> 
  5131                              <1> set_env_string_allocate_envb_retn:  ; stc or clc return
  5132 0000A1F3 5F                  <1> 	pop	edi ; ****
  5133 0000A1F4 5B                  <1> 	pop	ebx ; ***
  5134 0000A1F5 59                  <1> 	pop	ecx ; **
  5135 0000A1F6 5E                  <1> 	pop	esi ; *	
  5136 0000A1F7 C3                  <1> 	retn
  5137                              <1> 
  5138                              <1> set_env_string_nothing:
  5139 0000A1F8 31C0                <1> 	xor	eax, eax
  5140 0000A1FA 31D2                <1> 	xor	edx, edx ; 11/04/2016
  5141 0000A1FC EBF5                <1> 	jmp	short set_env_string_allocate_envb_retn
  5142                              <1> 
  5143                              <1> set_env_chk_validation4:
  5144                              <1> 	; 11/04/2016
  5145 0000A1FE 9D                  <1> 	popf
  5146                              <1> 
  5147 0000A1FF 89D6                <1> 	mov	esi, edx  ; Env_Page
  5148                              <1> 
  5149                              <1> set_env_chk_validation5:	
  5150 0000A201 89DF                <1> 	mov	edi, ebx  ; ASCIIZ environment string address	
  5151 0000A203 0FB6CC              <1> 	movzx	ecx, ah ; Variable (string) length (with '=')
  5152                              <1> 
  5153                              <1> set_env_chk_validation5_loop:
  5154 0000A206 AC                  <1> 	lodsb
  5155 0000A207 AE                  <1> 	scasb
  5156 0000A208 750A                <1> 	jne	short set_env_chk_validation6
  5157 0000A20A E2FA                <1> 	loop	set_env_chk_validation5_loop
  5158                              <1> 
  5159 0000A20C 3C3D                <1> 	cmp	al, '='
  5160 0000A20E 0F8483000000        <1>         je      set_env_change_variable
  5161                              <1> 
  5162                              <1> set_env_chk_validation6:
  5163 0000A214 08C0                <1> 	or	al, al ; 0
  5164 0000A216 7403                <1> 	jz	short set_env_chk_validation7
  5165                              <1> 
  5166 0000A218 AC                  <1> 	lodsb
  5167 0000A219 EBF9                <1> 	jmp	short set_env_chk_validation6
  5168                              <1> 
  5169                              <1> set_env_chk_validation7:
  5170 0000A21B 88E1                <1> 	mov	cl, ah
  5171 0000A21D 01F1                <1> 	add	ecx, esi
  5172 0000A21F 81F9FF310900        <1> 	cmp	ecx, Env_Page + Env_Page_Size - 1 
  5173                              <1> 		; 511 (4095) 
  5174                              <1> 		; strlen + '=' + 0
  5175 0000A225 72DA                <1> 	jb	short set_env_chk_validation5
  5176                              <1> 
  5177                              <1> set_env_chk_validation8: ; variable not found
  5178 0000A227 0FB6F4              <1> 	movzx	esi, ah  ; variable name length (with '=') 
  5179 0000A22A 01DE                <1> 	add	esi, ebx ; position just after of the '='
  5180                              <1> 
  5181                              <1> set_env_chk_validation8_loop:
  5182 0000A22C AC                  <1> 	lodsb
  5183 0000A22D 3C20                <1> 	cmp	al, 20h
  5184 0000A22F 74FB                <1> 	je	short set_env_chk_validation8_loop	
  5185 0000A231 72C5                <1> 	jb	short set_env_string_nothing
  5186                              <1> 
  5187                              <1> set_env_chk_validation9:
  5188 0000A233 AC                  <1> 	lodsb
  5189 0000A234 3C20                <1> 	cmp	al, 20h
  5190 0000A236 73FB                <1> 	jnb	short set_env_chk_validation9
  5191                              <1> 
  5192                              <1> 	; End of ASCIIZ environment string
  5193                              <1> 
  5194                              <1> set_env_add_variable:
  5195 0000A238 29DE                <1> 	sub	esi, ebx ; variable+definition length
  5196                              <1> 	
  5197 0000A23A 56                  <1> 	push	esi ; *****
  5198                              <1> 
  5199 0000A23B 89D6                <1> 	mov	esi, edx ; Environment page address
  5200                              <1> 
  5201 0000A23D B900020000          <1> 	mov	ecx, Env_Page_Size ; 512 (4096)	
  5202                              <1> 
  5203                              <1> set_env_add_variable_loop:
  5204 0000A242 AC                  <1> 	lodsb
  5205 0000A243 20C0                <1> 	and	al, al		
  5206 0000A245 7406                <1> 	jz	short set_env_add_variable_chk1 ; 0
  5207 0000A247 E2F9                <1> 	loop	set_env_add_variable_loop
  5208                              <1> 
  5209                              <1> 	; 11/04/2016
  5210 0000A249 884EFF              <1> 	mov	[esi-1], cl ; 0
  5211 0000A24C 41                  <1> 	inc	ecx
  5212                              <1> 	
  5213                              <1> set_env_add_variable_chk1: 
  5214 0000A24D 49                  <1> 	dec	ecx
  5215 0000A24E 7408                <1> 	jz	short set_env_add_variable_nspc
  5216 0000A250 AC                  <1> 	lodsb
  5217 0000A251 08C0                <1> 	or 	al, al
  5218 0000A253 740C                <1> 	jz	short set_env_add_variable_chk2 ; 00
  5219 0000A255 49                  <1> 	dec	ecx
  5220 0000A256 75EA                <1> 	jnz	short set_env_add_variable_loop
  5221                              <1> 
  5222                              <1> set_env_add_variable_nspc: ; no space on environment page
  5223 0000A258 58                  <1> 	pop	eax ; *****
  5224 0000A259 B808000000          <1> 	mov	eax, 8 ; No space for new environment string
  5225 0000A25E F9                  <1> 	stc
  5226 0000A25F EB92                <1>         jmp     short set_env_string_allocate_envb_retn
  5227                              <1> 
  5228                              <1> set_env_add_variable_chk2:
  5229 0000A261 8B0C24              <1> 	mov	ecx, [esp] ; *****
  5230 0000A264 4E                  <1> 	dec	esi ; beginning address of the new variable
  5231 0000A265 89F0                <1> 	mov	eax, esi
  5232 0000A267 01C8                <1> 	add	eax, ecx ; string length (with CR)
  5233 0000A269 81C200020000        <1> 	add	edx, Env_Page_Size ; 512 (4096)
  5234 0000A26F 39D0                <1> 	cmp	eax, edx 
  5235 0000A271 77E5                <1> 	ja	short set_env_add_variable_nspc
  5236 0000A273 49                  <1> 	dec	ecx ; except CR at the end
  5237 0000A274 89CA                <1> 	mov	edx, ecx ; 12/04/2016
  5238 0000A276 89F7                <1> 	mov	edi, esi
  5239 0000A278 893C24              <1> 	mov	[esp], edi ; ***** ; Start address of new variable
  5240 0000A27B 89DE                <1> 	mov	esi, ebx ; ASCIIZ environment string address
  5241 0000A27D F3A4                <1> 	rep	movsb
  5242 0000A27F 28C0                <1> 	sub	al, al
  5243 0000A281 AA                  <1> 	stosb
  5244 0000A282 58                  <1> 	pop	eax ; ***** ; Beginning address of new variable			
  5245 0000A283 81FF00320900        <1>         cmp     edi, Env_Page + Env_Page_Size ; 12/04/2016
  5246 0000A289 0F8364FFFFFF        <1>         jnb     set_env_string_allocate_envb_retn ; OK !
  5247 0000A28F 880F                <1> 	mov	[edi], cl ; 0
  5248 0000A291 F8                  <1> 	clc	; 13/04/2016
  5249 0000A292 E95CFFFFFF          <1>         jmp     set_env_string_allocate_envb_retn ; OK !
  5250                              <1> 
  5251                              <1> set_env_change_variable:
  5252                              <1> 	; 06/04/2016
  5253                              <1> 	; esi = Variable's address in environment page (after '=')
  5254                              <1> 	; edi = ASCIIZ environment string address (after '=')
  5255                              <1> 
  5256                              <1> 	; ah = variable length from start to the '='
  5257 0000A297 8825[08700100]      <1> 	mov	[env_var_length], ah
  5258                              <1> 
  5259 0000A29D 28C9                <1> 	sub	cl, cl ; ecx = 0
  5260                              <1> 
  5261 0000A29F 57                  <1> 	push	edi ; *****
  5262                              <1> 
  5263 0000A2A0 89F7                <1> 	mov	edi, esi ; 11/04/2016
  5264                              <1> 
  5265                              <1> set_env_change_variable_calc1:
  5266 0000A2A2 AC                  <1> 	lodsb
  5267 0000A2A3 08C0                <1> 	or	al, al
  5268 0000A2A5 7403                <1> 	jz	short set_env_change_variable_calc2
  5269                              <1> 
  5270 0000A2A7 41                  <1> 	inc	ecx ; length of environment string (after the '=')
  5271                              <1> 
  5272 0000A2A8 EBF8                <1> 	jmp	short set_env_change_variable_calc1	
  5273                              <1> 
  5274                              <1> set_env_change_variable_calc2:
  5275 0000A2AA 8B3424              <1> 	mov	esi, [esp] ; ASCIIZ environment string address
  5276                              <1> 	
  5277 0000A2AD 29D2                <1> 	sub	edx, edx
  5278                              <1> 
  5279                              <1> set_env_change_variable_calc3:
  5280 0000A2AF AC                  <1> 	lodsb
  5281 0000A2B0 3C20                <1> 	cmp	al, 20h
  5282 0000A2B2 7203                <1> 	jb	short set_env_change_variable_calc4
  5283                              <1> 
  5284 0000A2B4 42                  <1> 	inc	edx ; length of ASCIIZ string (after the '=')
  5285                              <1> 	
  5286 0000A2B5 EBF8                <1> 	jmp	short set_env_change_variable_calc3
  5287                              <1> 	
  5288                              <1> set_env_change_variable_calc4:
  5289 0000A2B7 C646FF00            <1> 	mov	byte [esi-1], 0  ; put ZERO instead of CR
  5290                              <1> 	
  5291 0000A2BB 5E                  <1> 	pop	esi ; ***** ; ASCIIZ string address (after '=')
  5292                              <1> 
  5293                              <1> 	; EDI = Old variable's address (after '=')
  5294                              <1> 	
  5295                              <1> 	; compare the new string with the old string
  5296 0000A2BC 39CA                <1> 	cmp	edx, ecx
  5297 0000A2BE 7717                <1> 	ja	short set_env_change_variable_calc5 ; longer
  5298 0000A2C0 0F828F000000        <1>         jb      set_env_change_variable_calc9 ; shorter
  5299                              <1> 	
  5300                              <1> 	;same length (simple copy)
  5301 0000A2C6 0FB6C4              <1> 	movzx	eax, ah
  5302 0000A2C9 01C2                <1> 	add	edx, eax
  5303 0000A2CB F7D8                <1> 	neg	eax
  5304 0000A2CD 01F8                <1> 	add	eax, edi
  5305                              <1> 	; EAX = Start address of the variable
  5306                              <1> 	; EDX = Variable length (without ZERO at the end of variable)
  5307                              <1> 
  5308 0000A2CF F3A4                <1> 	rep	movsb
  5309 0000A2D1 F8                  <1> 	clc	; 13/04/2016
  5310 0000A2D2 E91CFFFFFF          <1>         jmp     set_env_string_allocate_envb_retn ; OK !
  5311                              <1> 
  5312                              <1> set_env_change_variable_calc5:
  5313                              <1> 	; 11/04/2016
  5314 0000A2D7 52                  <1> 	push	edx ; *****
  5315 0000A2D8 29CA                <1> 	sub	edx, ecx ; difference ; (the new string is longer)
  5316 0000A2DA 89F3                <1> 	mov 	ebx, esi
  5317 0000A2DC 89FE                <1> 	mov	esi, edi
  5318                              <1> 
  5319                              <1> set_env_change_variable_calc6:
  5320 0000A2DE AC                  <1> 	lodsb 
  5321 0000A2DF 20C0                <1> 	and	al, al
  5322 0000A2E1 75FB                <1> 	jnz	short set_env_change_variable_calc6
  5323                              <1> 
  5324 0000A2E3 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size ; 512 (4096)
  5325 0000A2E9 0F8369FFFFFF        <1>         jnb     set_env_add_variable_nspc
  5326                              <1> 
  5327 0000A2EF 89F9                <1> 	mov	ecx, edi  ; current (old) variable's address
  5328 0000A2F1 89F7                <1> 	mov	edi, esi  ; next variable's address 
  5329                              <1> 
  5330 0000A2F3 AC                  <1> 	lodsb
  5331 0000A2F4 08C0                <1> 	or	al, al
  5332 0000A2F6 7416                <1> 	jz	short set_env_change_variable_calc8 ; 00
  5333                              <1> 
  5334                              <1> set_env_change_variable_calc7:
  5335 0000A2F8 AC                  <1> 	lodsb
  5336 0000A2F9 20C0                <1> 	and	al, al
  5337 0000A2FB 75FB                <1> 	jnz	short set_env_change_variable_calc7
  5338                              <1> 
  5339 0000A2FD 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size ; 512 (4096)
  5340 0000A303 0F834FFFFFFF        <1>         jnb     set_env_add_variable_nspc
  5341                              <1> 
  5342 0000A309 AC                  <1> 	lodsb
  5343 0000A30A 08C0                <1> 	or	al, al
  5344 0000A30C 75EA                <1> 	jnz	short set_env_change_variable_calc7
  5345                              <1> 
  5346                              <1> set_env_change_variable_calc8:
  5347 0000A30E 4E                  <1> 	dec	esi ; address of the second (last) 0 of the 00
  5348                              <1> 
  5349 0000A30F 01F2                <1> 	add	edx, esi ; final position of the last 0
  5350                              <1> 
  5351 0000A311 81FA00320900        <1> 	cmp	edx, Env_Page + Env_Page_Size ; 512 (4096)
  5352 0000A317 0F833BFFFFFF        <1>         jnb     set_env_add_variable_nspc
  5353                              <1> 
  5354 0000A31D 89C8                <1> 	mov	eax, ecx ; old variable's address (after '=')
  5355                              <1> 
  5356 0000A31F 89F1                <1> 	mov	ecx, esi 
  5357 0000A321 29F9                <1> 	sub	ecx, edi ; count of bytes to move forward
  5358                              <1> 
  5359                              <1> 	; 13/04/2016
  5360 0000A323 C60200              <1> 	mov	byte [edx], 0
  5361 0000A326 89D7                <1> 	mov	edi, edx
  5362 0000A328 29F2                <1> 	sub	edx, esi ; difference (additional byte count)
  5363 0000A32A 4F                  <1> 	dec	edi ; the last zero address (first byte of the 00)
  5364 0000A32B 89FE                <1> 	mov	esi, edi
  5365 0000A32D 29D6                <1> 	sub	esi, edx ; - displacement
  5366                              <1> 	
  5367 0000A32F FA                  <1> 	cli	; disable interrupts
  5368 0000A330 FD                  <1> 	std	; backward
  5369                              <1> 
  5370 0000A331 F3A4                <1> 	rep	movsb ; move ECX bytes from DS:ESI to ES:EDI
  5371                              <1> 
  5372 0000A333 FC                  <1> 	cld	; forward (default)
  5373 0000A334 FB                  <1> 	sti	; enable interrupts
  5374                              <1> 	
  5375 0000A335 89C7                <1> 	mov	edi, eax
  5376 0000A337 59                  <1> 	pop	ecx ; ***** ; byte count (after '=')
  5377 0000A338 89CA                <1> 	mov	edx, ecx
  5378 0000A33A 89DE                <1> 	mov	esi, ebx ; ASCIIZ string address (after '=')
  5379 0000A33C 89FB                <1> 	mov	ebx, edi
  5380                              <1> 
  5381 0000A33E F3A4                <1> 	rep	movsb
  5382                              <1> 
  5383 0000A340 880F                <1> 	mov	[edi], cl ; 0 ; end of variable
  5384                              <1> 
  5385 0000A342 0FB605[08700100]    <1> 	movzx	eax, byte [env_var_length]
  5386 0000A349 01C2                <1> 	add	edx, eax ; variable length (total)
  5387 0000A34B F7D8                <1> 	neg	eax
  5388 0000A34D 01D8                <1> 	add	eax, ebx ; start address of the variable
  5389 0000A34F F8                  <1> 	clc	; 13/04/2016
  5390 0000A350 E99EFEFFFF          <1>         jmp     set_env_string_allocate_envb_retn ; OK !
  5391                              <1> 
  5392                              <1> set_env_change_variable_calc9:
  5393                              <1> 	; 11/04/2016
  5394 0000A355 21D2                <1> 	and	edx, edx ; is empty ?
  5395 0000A357 753B                <1> 	jnz	short set_env_change_variable_calc15
  5396                              <1> 	
  5397 0000A359 0FB6DC              <1> 	movzx	ebx, ah
  5398 0000A35C F7DB                <1> 	neg	ebx
  5399 0000A35E 01FB                <1> 	add	ebx, edi
  5400                              <1> 
  5401                              <1> 	; EBX = Start address of the variable (in env page)
  5402                              <1> 	; EDX = Variable length = 0
  5403                              <1> 	
  5404 0000A360 89FE                <1> 	mov	esi, edi
  5405                              <1> 
  5406                              <1> set_env_change_variable_calc10:
  5407 0000A362 AC                  <1> 	lodsb
  5408 0000A363 08C0                <1> 	or	al, al
  5409 0000A365 75FB                <1> 	jnz	short set_env_change_variable_calc10
  5410                              <1> 
  5411 0000A367 B9FF310900          <1> 	mov	ecx, Env_Page + Env_Page_Size - 1
  5412                              <1> 
  5413 0000A36C 39CE                <1> 	cmp	esi, ecx ; +511 (+4095)
  5414 0000A36E 7604                <1> 	jna	short set_env_change_variable_calc11
  5415                              <1> 
  5416 0000A370 89CE                <1> 	mov	esi, ecx
  5417 0000A372 8806                <1> 	mov	[esi], al ; 0
  5418                              <1> 
  5419                              <1> set_env_change_variable_calc11:
  5420 0000A374 89DF                <1> 	mov	edi, ebx ; old variable's start address
  5421                              <1> 
  5422                              <1> set_env_change_variable_calc12:
  5423 0000A376 AC                  <1> 	lodsb
  5424 0000A377 AA                  <1> 	stosb
  5425 0000A378 20C0                <1> 	and	al, al
  5426 0000A37A 75FA                <1> 	jnz	short set_env_change_variable_calc12
  5427 0000A37C 39CE                <1> 	cmp	esi, ecx
  5428 0000A37E 7706                <1> 	ja	short set_env_change_variable_calc13
  5429 0000A380 AC                  <1> 	lodsb
  5430 0000A381 AA                  <1> 	stosb
  5431 0000A382 20C0                <1> 	and	al, al
  5432 0000A384 75F0                <1> 	jnz	short set_env_change_variable_calc12	
  5433                              <1> 
  5434                              <1> set_env_change_variable_calc13:
  5435 0000A386 29F9                <1> 	sub	ecx, edi
  5436 0000A388 7203                <1> 	jb	short set_env_change_variable_calc14
  5437 0000A38A 41                  <1> 	inc	ecx ; 1-512 (1-4096)
  5438 0000A38B F3AA                <1> 	rep	stosb ; al = 0	
  5439                              <1> 
  5440                              <1> set_env_change_variable_calc14:
  5441 0000A38D 29C0                <1> 	sub	eax, eax ; Start address of the variable
  5442                              <1> 	; EAX = 0 -> Variable is removed
  5443                              <1> 	; EDX = Variable length = 0	
  5444                              <1> 
  5445 0000A38F E95FFEFFFF          <1>         jmp     set_env_string_allocate_envb_retn ; OK !
  5446                              <1> 	    
  5447                              <1> set_env_change_variable_calc15:	
  5448 0000A394 52                  <1> 	push	edx ; *****
  5449 0000A395 F7DA                <1> 	neg	edx
  5450 0000A397 01CA                <1> 	add	edx, ecx ; difference (the old string is longer)
  5451 0000A399 89F3                <1> 	mov 	ebx, esi
  5452 0000A39B 89FE                <1> 	mov	esi, edi
  5453                              <1> 
  5454                              <1> set_env_change_variable_calc16:
  5455 0000A39D AC                  <1> 	lodsb 
  5456 0000A39E 20C0                <1> 	and	al, al
  5457 0000A3A0 75FB                <1> 	jnz	short set_env_change_variable_calc16
  5458                              <1> 
  5459 0000A3A2 B900320900          <1> 	mov	ecx, Env_Page + Env_Page_Size
  5460                              <1> 
  5461 0000A3A7 39CE                <1> 	cmp	esi, ecx ; +512 (+4096)
  5462 0000A3A9 7605                <1> 	jna	short set_env_change_variable_calc17
  5463                              <1> 
  5464 0000A3AB 89CE                <1> 	mov	esi, ecx
  5465 0000A3AD 8846FF              <1> 	mov	[esi-1], al ; 0
  5466                              <1> 
  5467                              <1> set_env_change_variable_calc17:
  5468 0000A3B0 89F9                <1> 	mov	ecx, edi  ; current (old) variable's address
  5469 0000A3B2 89F7                <1> 	mov	edi, esi  ; next variable's address 
  5470                              <1> 
  5471 0000A3B4 AC                  <1> 	lodsb
  5472 0000A3B5 08C0                <1> 	or	al, al
  5473 0000A3B7 741D                <1> 	jz	short set_env_change_variable_calc20
  5474                              <1> 
  5475                              <1> set_env_change_variable_calc18:
  5476 0000A3B9 AC                  <1> 	lodsb
  5477 0000A3BA 20C0                <1> 	and	al, al
  5478 0000A3BC 75FB                <1> 	jnz	short set_env_change_variable_calc18
  5479                              <1> 
  5480 0000A3BE 81FE00320900        <1> 	cmp	esi, Env_Page + Env_Page_Size
  5481 0000A3C4 720B                <1> 	jb	short set_env_change_variable_calc19
  5482 0000A3C6 740E                <1> 	je	short set_env_change_variable_calc20
  5483                              <1> 
  5484 0000A3C8 BEFF310900          <1> 	mov	esi, Env_Page + Env_Page_Size - 1
  5485 0000A3CD 8806                <1> 	mov	[esi], al ; 0
  5486 0000A3CF EB06                <1> 	jmp	short set_env_change_variable_calc21
  5487                              <1> 
  5488                              <1> set_env_change_variable_calc19:
  5489 0000A3D1 AC                  <1> 	lodsb
  5490 0000A3D2 08C0                <1> 	or	al, al
  5491 0000A3D4 75E3                <1> 	jnz	short set_env_change_variable_calc18
  5492                              <1> 
  5493                              <1> set_env_change_variable_calc20:
  5494 0000A3D6 4E                  <1> 	dec	esi ; address of the second (last) 0 of the 00
  5495                              <1> 
  5496                              <1> set_env_change_variable_calc21:
  5497                              <1> 	; edx = difference (byte count)
  5498                              <1> 	
  5499 0000A3D7 89C8                <1> 	mov	eax, ecx ; old variable's address (after '=')
  5500                              <1> 
  5501 0000A3D9 89F1                <1> 	mov	ecx, esi 
  5502 0000A3DB 29F9                <1> 	sub	ecx, edi ; count of bytes to move backward
  5503                              <1> 
  5504 0000A3DD 89FE                <1> 	mov	esi, edi ; next variable's address
  5505 0000A3DF 29D7                <1> 	sub	edi, edx ; (displacement)
  5506                              <1> 	
  5507 0000A3E1 F3A4                <1> 	rep	movsb
  5508                              <1> 
  5509 0000A3E3 880F                <1> 	mov	[edi], cl ; 0 ; 00 ; end of environment variables
  5510                              <1> 
  5511 0000A3E5 89C7                <1> 	mov	edi, eax
  5512 0000A3E7 5A                  <1> 	pop	edx ; ***** ; byte count (after '=')
  5513 0000A3E8 89D1                <1> 	mov	ecx, edx
  5514 0000A3EA 89DE                <1> 	mov	esi, ebx ; ASCIIZ string address (after '=')
  5515 0000A3EC 89FB                <1> 	mov	ebx, edi
  5516                              <1> 	
  5517 0000A3EE F3A4                <1> 	rep	movsb
  5518                              <1> 
  5519 0000A3F0 880F                <1> 	mov	[edi], cl ; 0 ; end of variable
  5520                              <1> 
  5521 0000A3F2 0FB605[08700100]    <1> 	movzx	eax, byte [env_var_length]
  5522 0000A3F9 01C2                <1> 	add	edx, eax ; variable length (total)
  5523 0000A3FB F7D8                <1> 	neg	eax
  5524 0000A3FD 01D8                <1> 	add	eax, ebx ; start address of the variable
  5525 0000A3FF F8                  <1> 	clc	; 13/04/2016
  5526 0000A400 E9EEFDFFFF          <1>         jmp     set_env_string_allocate_envb_retn ; OK !
  5527                              <1> 
  5528                              <1> mainprog_startup_configuration:
  5529                              <1> 	; 22/11/2017
  5530                              <1> 	; 06/05/2016
  5531                              <1> 	; 14/04/2016 (TRDOS 386 = TRDOS v2.0)
  5532                              <1> 	; 17/09/2011 (TRDOS v1, MAINPROG.ASM)
  5533                              <1> 	;
  5534                              <1> loc_load_mainprog_cfg_file:
  5535 0000A405 BE[3C180100]        <1> 	mov	esi, MainProgCfgFile
  5536 0000A40A 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  5537 0000A40E E83EEAFFFF          <1> 	call	find_first_file
  5538 0000A413 7256                <1> 	jc	short loc_load_mainprog_cfg_exit
  5539                              <1> 
  5540                              <1> 	;or	eax, eax
  5541                              <1> 	;jz	short loc_load_mainprog_cfg_exit
  5542                              <1> 
  5543                              <1> loc_start_mainprog_configuration:
  5544                              <1> 	; ESI = FindFile_DirEntry Location
  5545                              <1> 	; EAX = File Size
  5546                              <1> 
  5547 0000A415 A3[8C640100]        <1> 	mov	[MainProgCfg_FileSize], eax
  5548                              <1> 
  5549 0000A41A 668B5614            <1> 	mov	dx, [esi+DirEntry_FstClusHI]
  5550 0000A41E C1E210              <1> 	shl	edx, 16
  5551 0000A421 668B561A            <1> 	mov	dx, [esi+DirEntry_FstClusLO]
  5552 0000A425 8915[BC6F0100]      <1> 	mov	[csftdf_sf_cluster], edx
  5553                              <1> 
  5554 0000A42B 89C1                <1> 	mov	ecx, eax
  5555 0000A42D 29C0                <1> 	sub	eax, eax
  5556                              <1> 
  5557                              <1> 	; TRDOS 386 (TRDOS v2.0)
  5558                              <1> 	; Allocate contiguous memory block for loading the file
  5559                              <1> 	
  5560                              <1> 	; eax = 0 (Allocate memory from the beginning)
  5561                              <1> 	; ecx = File (Allocation) size in bytes
  5562                              <1> 	
  5563 0000A42F E81BBAFFFF          <1> 	call	allocate_memory_block
  5564 0000A434 7235                <1> 	jc	short loc_load_mainprog_cfg_exit
  5565                              <1> 
  5566 0000A436 A3[B46F0100]        <1> 	mov	[csftdf_sf_mem_addr], eax ; loading address
  5567 0000A43B 890D[B86F0100]      <1> 	mov	[csftdf_sf_mem_bsize], ecx ; block size
  5568                              <1> 
  5569 0000A441 31DB                <1> 	xor	ebx, ebx
  5570                              <1> 	;mov	[csftdf_sf_rbytes], ebx ; 0, reset
  5571                              <1> 
  5572 0000A443 8A3D[9E640100]      <1> 	mov	bh, [Current_Drv] ; [FindFile_Drv]
  5573 0000A449 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  5574 0000A44E 01DE                <1> 	add	esi, ebx
  5575                              <1> 
  5576 0000A450 8B1D[B46F0100]      <1> 	mov	ebx, [csftdf_sf_mem_addr] ; memory block address
  5577                              <1> 
  5578 0000A456 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5579 0000A45A 7710                <1>         ja	short loc_mcfg_load_fat_file
  5580                              <1> 
  5581 0000A45C C705[C46F0100]0000- <1> 	mov	dword [csftdf_r_size], 65536
  5581 0000A464 0100                <1>
  5582 0000A466 E9A1010000          <1>         jmp     loc_mcfg_load_fs_file
  5583                              <1> 
  5584                              <1> loc_load_mainprog_cfg_exit:
  5585 0000A46B C3                  <1> 	retn 
  5586                              <1> 
  5587                              <1> loc_mcfg_load_fat_file:
  5588 0000A46C 0FB74611            <1> 	movzx	eax, word [esi+LD_BPB+BytesPerSec]
  5589 0000A470 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  5590 0000A474 F7E1                <1> 	mul	ecx
  5591 0000A476 A3[C46F0100]        <1> 	mov	[csftdf_r_size], eax
  5592                              <1> 
  5593                              <1> loc_mcfg_load_fat_file_next:
  5594 0000A47B E822010000          <1> 	call	mcfg_read_fat_file_sectors
  5595 0000A480 0F8206010000        <1>         jc      mcfg_deallocate_mem
  5596                              <1> 
  5597 0000A486 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  5598 0000A488 74F1                <1> 	jz	short loc_mcfg_load_fat_file_next
  5599                              <1> 
  5600                              <1> loc_mcfg_load_fat_file_ok:
  5601                              <1> 	; 06/05/2016
  5602 0000A48A C705[58700100]-     <1> 	mov	dword [mainprog_return_addr], loc_mcfg_ci_return_addr 
  5602 0000A490 [4DA50000]          <1>
  5603                              <1> 	;
  5604 0000A494 8B35[B46F0100]      <1> 	mov	esi, [csftdf_sf_mem_addr]
  5605 0000A49A 8935[90640100]      <1> 	mov	[MainProgCfg_LineOffset], esi
  5606                              <1> 	
  5607 0000A4A0 A1[8C640100]        <1> 	mov	eax, [MainProgCfg_FileSize]
  5608 0000A4A5 89C2                <1> 	mov	edx, eax
  5609 0000A4A7 01F2                <1> 	add	edx, esi
  5610                              <1> 
  5611                              <1> loc_mcfg_process_next_line_check:
  5612 0000A4A9 89C1                <1> 	mov	ecx, eax
  5613                              <1> 
  5614 0000A4AB 803E2A              <1> 	cmp	byte [esi], "*" ; Remark sign
  5615 0000A4AE 7503                <1> 	jne	short loc_mcfg_process_next_line
  5616 0000A4B0 46                  <1> 	inc	esi
  5617 0000A4B1 EB17                <1> 	jmp	short loc_move_mainprog_cfg_nl1
  5618                              <1> 
  5619                              <1> loc_mcfg_process_next_line:
  5620 0000A4B3 83F94F              <1> 	cmp	ecx, 79
  5621 0000A4B6 7605                <1> 	jna	short loc_start_mainprog_cfg_process
  5622                              <1> 	
  5623 0000A4B8 B94F000000          <1> 	mov	ecx, 79 
  5624                              <1> 
  5625                              <1> loc_start_mainprog_cfg_process:
  5626 0000A4BD BF[4E650100]        <1> 	mov	edi, CommandBuffer
  5627                              <1> 
  5628                              <1> loc_move_mainprog_cfg_line:
  5629 0000A4C2 AC                  <1> 	lodsb
  5630 0000A4C3 3C20                <1> 	cmp	al, 20h
  5631 0000A4C5 720C                <1> 	jb	short loc_move_mainprog_cfg_nl2
  5632 0000A4C7 AA                  <1> 	stosb
  5633 0000A4C8 E2F8                <1> 	loop	loc_move_mainprog_cfg_line
  5634                              <1> 
  5635                              <1> loc_move_mainprog_cfg_nl1:
  5636 0000A4CA 39D6                <1> 	cmp	esi, edx ; + configuration file size
  5637 0000A4CC 7312                <1> 	jnb	short loc_end_of_mainprog_cfg_line
  5638 0000A4CE AC                  <1> 	lodsb
  5639 0000A4CF 3C20                <1> 	cmp	al, 20h
  5640 0000A4D1 73F7                <1> 	jnb	short loc_move_mainprog_cfg_nl1
  5641                              <1> 
  5642                              <1> loc_move_mainprog_cfg_nl2:
  5643 0000A4D3 39D6                <1> 	cmp	esi, edx
  5644 0000A4D5 7309                <1> 	jnb	short loc_end_of_mainprog_cfg_line
  5645 0000A4D7 8A06                <1> 	mov	al, [esi]
  5646 0000A4D9 3C20                <1> 	cmp	al, 20h
  5647 0000A4DB 7703                <1>  	ja	short loc_end_of_mainprog_cfg_line
  5648 0000A4DD 46                  <1> 	inc	esi
  5649 0000A4DE EBF3                <1> 	jmp	short loc_move_mainprog_cfg_nl2	               
  5650                              <1> 
  5651                              <1> loc_end_of_mainprog_cfg_line:
  5652 0000A4E0 C60700              <1> 	mov	byte [edi], 0
  5653                              <1> 
  5654 0000A4E3 8935[90640100]      <1> 	mov	[MainProgCfg_LineOffset], esi
  5655                              <1> 
  5656                              <1> 	; 22/11/2017
  5657 0000A4E9 BE[56650100]        <1> 	mov	esi, CommandBuffer + 8
  5658 0000A4EE 29FE                <1> 	sub	esi, edi
  5659 0000A4F0 7606                <1> 	jna	short loc_move_mainprog_cfg_command
  5660 0000A4F2 30C0                <1> 	xor	al, al
  5661                              <1> loc_mainprog_cfg_clear_chrs:
  5662 0000A4F4 AA                  <1> 	stosb
  5663 0000A4F5 4E                  <1> 	dec	esi
  5664 0000A4F6 75FC                <1> 	jnz	short loc_mainprog_cfg_clear_chrs	
  5665                              <1> 
  5666                              <1> loc_move_mainprog_cfg_command:
  5667 0000A4F8 BE[4E650100]        <1> 	mov	esi, CommandBuffer
  5668 0000A4FD 89F7                <1> 	mov	edi, esi
  5669 0000A4FF 31DB                <1> 	xor	ebx, ebx
  5670                              <1> 	;xor	ecx, ecx
  5671 0000A501 30C9                <1> 	xor	cl, cl
  5672                              <1> 
  5673                              <1> loc_move_mcfg_first_cmd_char:
  5674 0000A503 8A041E              <1> 	mov	al, [esi+ebx]
  5675 0000A506 FEC3                <1> 	inc	bl 
  5676 0000A508 3C20                <1> 	cmp	al, 20h
  5677 0000A50A 7712                <1> 	ja	short loc_move_mcfg_cmd_capitalizing
  5678 0000A50C 7237                <1> 	jb	short loc_move_mcfg_cmd_arguments_ok
  5679 0000A50E 80FB4F              <1> 	cmp	bl, 79
  5680 0000A511 72F0                <1> 	jb	short loc_move_mcfg_first_cmd_char
  5681 0000A513 EB30                <1> 	jmp	short loc_move_mcfg_cmd_arguments_ok
  5682                              <1> 
  5683                              <1> loc_move_mcfg_next_cmd_char:
  5684 0000A515 8A041E              <1> 	mov	al, [esi+ebx]
  5685 0000A518 FEC3                <1> 	inc	bl
  5686 0000A51A 3C20                <1> 	cmp	al, 20h
  5687 0000A51C 7614                <1> 	jna	short loc_move_mcfg_cmd_ok
  5688                              <1> 
  5689                              <1> loc_move_mcfg_cmd_capitalizing:
  5690 0000A51E 3C61                <1> 	cmp	al, 61h ; 'a'
  5691 0000A520 7206                <1> 	jb	short loc_move_mcfg_cmd_caps_ok
  5692 0000A522 3C7A                <1> 	cmp	al, 7Ah ; 'z'
  5693 0000A524 7702                <1> 	ja	short loc_move_mcfg_cmd_caps_ok
  5694 0000A526 24DF                <1> 	and	al, 0DFh ; sub	al, 'a'-'A'
  5695                              <1> 
  5696                              <1> loc_move_mcfg_cmd_caps_ok:
  5697 0000A528 AA                  <1> 	stosb 
  5698 0000A529 FEC1                <1> 	inc	cl
  5699 0000A52B 80FB4F              <1> 	cmp	bl, 79
  5700 0000A52E 72E5                <1> 	jb	short loc_move_mcfg_next_cmd_char
  5701 0000A530 EB13                <1> 	jmp	short loc_move_mcfg_cmd_arguments_ok
  5702                              <1> 
  5703                              <1> loc_move_mcfg_cmd_ok:
  5704 0000A532 30C0                <1> 	xor	al, al ; 0
  5705                              <1> 
  5706                              <1> loc_move_mcfg_cmd_arguments:
  5707 0000A534 8807                <1> 	mov	[edi], al
  5708 0000A536 47                  <1> 	inc	edi
  5709 0000A537 80FB4F              <1> 	cmp	bl, 79
  5710 0000A53A 7309                <1> 	jnb	short loc_move_mcfg_cmd_arguments_ok
  5711 0000A53C 8A041E              <1> 	mov	al, [esi+ebx]
  5712 0000A53F FEC3                <1> 	inc	bl
  5713 0000A541 3C20                <1> 	cmp	al, 20h
  5714 0000A543 73EF                <1> 	jnb	short loc_move_mcfg_cmd_arguments
  5715                              <1> 	
  5716                              <1> loc_move_mcfg_cmd_arguments_ok:
  5717 0000A545 C60700              <1> 	mov	byte [edi], 0
  5718                              <1>        
  5719                              <1> loc_mcfg_process_cmd_interpreter:
  5720 0000A548 E825E0FFFF          <1> 	call    command_interpreter
  5721                              <1> 
  5722                              <1> loc_mcfg_ci_return_addr: 
  5723 0000A54D A1[8C640100]        <1> 	mov	eax, [MainProgCfg_FileSize]
  5724 0000A552 89C2                <1> 	mov	edx, eax
  5725 0000A554 8B35[90640100]      <1> 	mov	esi, [MainProgCfg_LineOffset]
  5726 0000A55A 01F2                <1> 	add	edx, esi
  5727 0000A55C 0305[B46F0100]      <1> 	add	eax, [csftdf_sf_mem_addr]
  5728 0000A562 29F0                <1> 	sub	eax, esi
  5729 0000A564 0F873FFFFFFF        <1>         ja      loc_mcfg_process_next_line_check
  5730                              <1> 
  5731 0000A56A E81D000000          <1> 	call	mcfg_deallocate_mem
  5732                              <1>  
  5733 0000A56F B94F000000          <1>  	mov	ecx, 79 ; 80 ?
  5734 0000A574 BF[4E650100]        <1> 	mov	edi, CommandBuffer
  5735 0000A579 30C0                <1> 	xor	al, al
  5736 0000A57B F3AA                <1> 	rep	stosb
  5737                              <1> 
  5738                              <1> 	; 06/05/2016
  5739 0000A57D BE[93240100]        <1> 	mov	esi, nextline
  5740 0000A582 E89EC9FFFF          <1> 	call	print_msg
  5741 0000A587 E963D6FFFF          <1> 	jmp	dos_prompt
  5742                              <1> 
  5743                              <1> mcfg_deallocate_mem:
  5744 0000A58C A1[B46F0100]        <1> 	mov	eax, [csftdf_sf_mem_addr] ; start address
  5745 0000A591 8B0D[B86F0100]      <1> 	mov	ecx, [csftdf_sf_mem_bsize] ; block size	
  5746                              <1> 	;call	deallocate_memory_block
  5747                              <1> 	;retn
  5748 0000A597 E9C0BAFFFF          <1> 	jmp	deallocate_memory_block
  5749                              <1> 
  5750                              <1> mcfg_read_file_sectors:
  5751                              <1> 	; 14/04/2016
  5752 0000A59C 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  5753 0000A5A0 7669                <1>         jna	short mcfg_read_fs_file_sectors
  5754                              <1> 
  5755                              <1> mcfg_read_fat_file_sectors:
  5756                              <1> 	; return:
  5757                              <1> 	;   CF = 0 & EDX > 0 -> END OF FILE
  5758                              <1> 	;   CF = 0 & EDX = 0 -> not EOF
  5759                              <1> 	;   CF = 1 -> read error (error code in AL)	
  5760                              <1> 
  5761                              <1> mcfg_read_fat_file_secs_0:
  5762 0000A5A2 8B15[8C640100]      <1> 	mov	edx, [MainProgCfg_FileSize]
  5763 0000A5A8 2B15[CC6F0100]      <1> 	sub	edx, [csftdf_sf_rbytes]
  5764 0000A5AE 3B15[C46F0100]      <1> 	cmp	edx, [csftdf_r_size]	
  5765 0000A5B4 7306                <1> 	jnb	short mcfg_read_fat_file_secs_1
  5766 0000A5B6 8915[C46F0100]      <1> 	mov	[csftdf_r_size], edx
  5767                              <1> 		
  5768                              <1> mcfg_read_fat_file_secs_1:
  5769 0000A5BC A1[C46F0100]        <1> 	mov	eax, [csftdf_r_size]
  5770 0000A5C1 29D2                <1> 	sub	edx, edx
  5771 0000A5C3 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec]
  5772 0000A5C7 01C8                <1> 	add	eax, ecx
  5773 0000A5C9 48                  <1> 	dec	eax
  5774 0000A5CA F7F1                <1> 	div	ecx
  5775 0000A5CC 89C1                <1> 	mov	ecx, eax ; sector count
  5776 0000A5CE A1[BC6F0100]        <1> 	mov	eax, [csftdf_sf_cluster]
  5777                              <1> 
  5778                              <1> 	; EBX = memory block address (current)
  5779                              <1> 	
  5780 0000A5D3 E88C230000          <1> 	call	read_fat_file_sectors
  5781 0000A5D8 7230                <1> 	jc	short mcfg_read_fat_file_secs_3
  5782                              <1> 
  5783                              <1> 	; EBX = next memory address
  5784                              <1> 
  5785 0000A5DA A1[CC6F0100]        <1> 	mov	eax, [csftdf_sf_rbytes]
  5786 0000A5DF 0305[C46F0100]      <1> 	add	eax, [csftdf_r_size]
  5787 0000A5E5 8B15[8C640100]      <1> 	mov	edx, [MainProgCfg_FileSize]
  5788 0000A5EB 39D0                <1> 	cmp	eax, edx
  5789 0000A5ED 731B                <1> 	jnb	short mcfg_read_fat_file_secs_3 ; edx > 0
  5790 0000A5EF A3[CC6F0100]        <1> 	mov	[csftdf_sf_rbytes], eax
  5791                              <1> 
  5792 0000A5F4 53                  <1> 	push	ebx ; *
  5793                              <1> 	; get next cluster (csftdf_r_size! bytes)
  5794 0000A5F5 A1[BC6F0100]        <1> 	mov	eax, [csftdf_sf_cluster]
  5795 0000A5FA E837210000          <1> 	call	get_next_cluster
  5796 0000A5FF 5B                  <1> 	pop	ebx ; *
  5797 0000A600 7301                <1> 	jnc	short mcfg_read_fat_file_secs_2
  5798                              <1> 
  5799                              <1> 	;mov	eax, 17; Read error !
  5800 0000A602 C3                  <1> 	retn
  5801                              <1> 
  5802                              <1> mcfg_read_fat_file_secs_2:
  5803 0000A603 29D2                <1> 	sub	edx, edx ; 0
  5804 0000A605 A3[BC6F0100]        <1> 	mov	[csftdf_sf_cluster], eax ; next cluster
  5805                              <1> 
  5806                              <1> mcfg_read_fat_file_secs_3:
  5807 0000A60A C3                  <1> 	retn
  5808                              <1> 
  5809                              <1> mcfg_read_fs_file_sectors:
  5810 0000A60B C3                  <1> 	retn
  5811                              <1> 
  5812                              <1> loc_mcfg_load_fs_file:
  5813 0000A60C C3                  <1> 	retn
  5814                              <1> 
  5815                              <1> load_and_execute_file:
  5816                              <1> 	; 04/01/2017
  5817                              <1> 	; 06/05/2016, 07/05/2016, 11/05/2016
  5818                              <1> 	; 23/04/2016, 24/04/2016
  5819                              <1> 	; 22/04/2016 (TRDOS 386 = TRDOS v2.0)
  5820                              <1> 	; 05/11/2011 
  5821                              <1> 	; (TRDOS v1, CMDINTR.ASM, 'cmp_cmd_run', 'cmp_cmd_external')
  5822                              <1> 	; ('loc_run_check_filename')
  5823                              <1> 	; 29/08/2011
  5824                              <1> 	; 10/09/2011
  5825                              <1> 	; INPUT->
  5826                              <1> 	;	ESI = Path Name address (CommandBuffer address)
  5827                              <1> 	; OUTPUT ->
  5828                              <1> 	;	none (error message will be shown if an error will occur)
  5829                              <1> 	;
  5830                              <1> 	; (EAX, EBX, ECX, EDX, ESI, EDI, EBP will be changed) 
  5831                              <1> 	;
  5832                              <1> loc_run_check_filename:
  5833 0000A60D 803E20              <1> 	cmp	byte [esi], 20h
  5834 0000A610 0F822BE3FFFF        <1> 	jb	loc_cmd_failed
  5835 0000A616 7703                <1> 	ja	short loc_run_check_filename_ok
  5836 0000A618 46                  <1> 	inc	esi
  5837 0000A619 EBF2                <1> 	jmp	short loc_run_check_filename
  5838                              <1> 
  5839                              <1> loc_run_check_filename_ok:
  5840 0000A61B C605[FF640100]00    <1> 	mov	byte [CmdArgStart], 0 ; reset
  5841 0000A622 56                  <1> 	push	esi ; *
  5842                              <1> loc_run_get_first_arg_pos:
  5843 0000A623 46                  <1> 	inc	esi
  5844 0000A624 8A06                <1> 	mov	al, [esi]
  5845 0000A626 3C20                <1> 	cmp	al, 20h
  5846 0000A628 77F9                <1> 	ja	short loc_run_get_first_arg_pos
  5847 0000A62A C60600              <1> 	mov	byte [esi], 0
  5848                              <1> loc_run_get_external_arg_pos:
  5849                              <1> 	; 11/05/2016
  5850 0000A62D 46                  <1> 	inc	esi
  5851 0000A62E 8A06                <1> 	mov	al, [esi]
  5852 0000A630 3C20                <1> 	cmp	al, 20h
  5853 0000A632 760C                <1> 	jna	short loc_run_parse_path_name
  5854 0000A634 89F0                <1> 	mov	eax, esi
  5855 0000A636 2D[4E650100]        <1> 	sub	eax, CommandBuffer
  5856 0000A63B A2[FF640100]        <1> 	mov	byte [CmdArgStart], al
  5857                              <1> loc_run_parse_path_name:
  5858 0000A640 5E                  <1> 	pop	esi ; *
  5859 0000A641 BF[3E6D0100]        <1> 	mov	edi, FindFile_Drv
  5860 0000A646 E8D7090000          <1> 	call	parse_path_name
  5861 0000A64B 0F82F0E2FFFF        <1> 	jc	loc_cmd_failed
  5862                              <1> 
  5863                              <1> loc_run_check_filename_exists:
  5864 0000A651 BE[806D0100]        <1> 	mov	esi, FindFile_Name
  5865 0000A656 803E20              <1> 	cmp	byte [esi], 20h
  5866 0000A659 0F86E2E2FFFF        <1> 	jna	loc_cmd_failed
  5867                              <1> 
  5868                              <1> loc_run_check_exe_filename_ext:
  5869 0000A65F E890020000          <1> 	call	check_prg_filename_ext
  5870 0000A664 0F82D7E2FFFF        <1> 	jc	loc_cmd_failed
  5871                              <1> 	
  5872                              <1> loc_run_check_exe_filename_ext_ok:
  5873 0000A66A 66A3[56700100]      <1> 	mov	word [EXE_ID], ax
  5874                              <1> 
  5875                              <1> loc_run_drv:
  5876 0000A670 C605[55700100]00    <1> 	mov	byte [Run_Manual_Path], 0
  5877 0000A677 A1[98640100]        <1> 	mov	eax, [Current_Dir_FCluster]
  5878 0000A67C A3[50700100]        <1>         mov     [Run_CDirFC], eax
  5879                              <1> 	;
  5880 0000A681 8A35[9E640100]      <1> 	mov	dh, [Current_Drv]
  5881 0000A687 8835[FA6B0100]      <1> 	mov	[RUN_CDRV], dh
  5882                              <1> 
  5883 0000A68D 8A15[3E6D0100]      <1> 	mov	dl, [FindFile_Drv]
  5884 0000A693 38F2                <1> 	cmp	dl, dh
  5885 0000A695 7412                <1> 	je	short loc_run_change_directory
  5886                              <1>                
  5887 0000A697 8005[55700100]02    <1> 	add	byte [Run_Manual_Path], 2
  5888                              <1> 
  5889 0000A69E E80BD4FFFF          <1> 	call	change_current_drive
  5890 0000A6A3 0F82C3E2FFFF        <1> 	jc	loc_run_cmd_failed
  5891                              <1> 
  5892                              <1> loc_run_change_directory:
  5893 0000A6A9 803D[3F6D0100]20    <1> 	cmp	byte [FindFile_Directory], 20h
  5894 0000A6B0 7623                <1> 	jna	short loc_run_find_executable_file
  5895                              <1> 
  5896 0000A6B2 FE05[55700100]      <1> 	inc	byte [Run_Manual_Path]
  5897                              <1>      
  5898 0000A6B8 FE05[F6170100]      <1> 	inc	byte [Restore_CDIR]
  5899                              <1> 
  5900 0000A6BE BE[3F6D0100]        <1> 	mov	esi, FindFile_Directory
  5901 0000A6C3 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  5902 0000A6C5 E842030000          <1> 	call	change_current_directory
  5903 0000A6CA 0F829CE2FFFF        <1> 	jc	loc_run_cmd_failed
  5904                              <1> 
  5905                              <1> loc_run_change_prompt_dir_string:
  5906 0000A6D0 E857020000          <1> 	call	change_prompt_dir_string
  5907                              <1> 
  5908                              <1> loc_run_find_executable_file:
  5909 0000A6D5 66C705[54700100]00- <1> 	mov	word [Run_Auto_Path], 0
  5909 0000A6DD 00                  <1>
  5910                              <1> 
  5911                              <1> loc_run_find_executable_file_next:
  5912 0000A6DE BE[806D0100]        <1> 	mov	esi, FindFile_Name
  5913                              <1> loc_run_find_program_file_next:
  5914 0000A6E3 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  5915 0000A6E7 E865E7FFFF          <1> 	call	find_first_file
  5916                              <1> 	; ESI = Directory Entry (FindFile_DirEntry) Location
  5917                              <1> 	; EDI = Directory Buffer Directory Entry Location
  5918                              <1> 	; EAX = File size
  5919 0000A6EC 0F835C010000        <1> 	jnc	loc_load_and_run_file
  5920                              <1> 	 
  5921 0000A6F2 3C02                <1> 	cmp	al, 2 ; file not found
  5922 0000A6F4 0F8572E2FFFF        <1> 	jne	loc_run_cmd_failed
  5923                              <1> 
  5924 0000A6FA 66A1[56700100]      <1> 	mov	ax, word [EXE_ID]
  5925 0000A700 80FC2E              <1> 	cmp	ah, '.' ; File name has extension sign
  5926 0000A703 7424                <1> 	je	short loc_run_check_auto_path
  5927                              <1> 
  5928 0000A705 08C0                <1> 	or	al, al
  5929 0000A707 7520                <1> 	jnz	short loc_run_check_auto_path
  5930                              <1> 
  5931 0000A709 80FC08              <1> 	cmp	ah, 8 ; count of file name chars
  5932 0000A70C 771B                <1> 	ja	short loc_run_check_auto_path
  5933                              <1> 
  5934                              <1> loc_run_change_file_ext_to_prg:
  5935 0000A70E 0FB6DC              <1> 	movzx	ebx, ah ; count of file name chars
  5936 0000A711 BE[806D0100]        <1> 	mov	esi, FindFile_Name
  5937 0000A716 01F3                <1> 	add	ebx, esi	
  5938                              <1> 	; 07/05/2016
  5939 0000A718 C7032E505247        <1> 	mov	dword [ebx],  '.PRG'
  5940 0000A71E 66C705[56700100]50- <1> 	mov	word [EXE_ID], 'P.'
  5940 0000A726 2E                  <1>
  5941 0000A727 EBBA                <1> 	jmp	short loc_run_find_program_file_next	
  5942                              <1> 
  5943                              <1> loc_run_check_auto_path:
  5944                              <1> 	; NOTE: /// 07/05/2016 ///
  5945                              <1> 	; If the path is given, value of byte [Run_Manual_Path]
  5946                              <1> 	; will not be ZERO. If so, file searching by using
  5947                              <1> 	; Automatic Path (via 'PATH' environment variable)
  5948                              <1> 	; will not be applicable, because the program file 
  5949                              <1> 	; is already/absolutely not found.
  5950                              <1> 
  5951 0000A729 A0[55700100]        <1> 	mov	al, [Run_Manual_Path]
  5952 0000A72E 08C0                <1> 	or	al, al
  5953 0000A730 0F850BE2FFFF        <1> 	jnz	loc_cmd_failed
  5954                              <1> 
  5955                              <1> loc_run_check_auto_path_again:
  5956 0000A736 66833D[54700100]FF  <1> 	cmp	word [Run_Auto_Path], 0FFFFh		 
  5957                              <1> 		; 0FFFFh = Not a valid run path (in ENV block) 
  5958 0000A73E 0F83FDE1FFFF        <1> 	jnb	loc_cmd_failed
  5959                              <1> 	; xor	al, al 
  5960 0000A744 BE[C2180100]        <1> 	mov	esi, Cmd_Path ; 'PATH'
  5961 0000A749 BF[9E650100]        <1> 	mov	edi, TextBuffer
  5962 0000A74E E848F9FFFF          <1> 	call	get_environment_string
  5963 0000A753 730E                <1> 	jnc	short loc_run_chk_filename_ext_again
  5964 0000A755 66C705[54700100]FF- <1> 	mov	word [Run_Auto_Path], 0FFFFh ; invalid
  5964 0000A75D FF                  <1>
  5965 0000A75E E9DEE1FFFF          <1> 	jmp	loc_cmd_failed
  5966                              <1> 
  5967                              <1> loc_run_chk_filename_ext_again:
  5968 0000A763 89C1                <1> 	mov	ecx, eax ; string length (with zero tail)
  5969 0000A765 49                  <1> 	dec	ecx ; without zero tail
  5970 0000A766 66A1[56700100]      <1> 	mov	ax, [EXE_ID]
  5971 0000A76C 80FC2E              <1> 	cmp	ah, '.'
  5972 0000A76F 740E                <1> 	je	short loc_run_chk_auto_path_pos
  5973                              <1> 	 
  5974                              <1> loc_run_change_file_ext_to_noext_again:
  5975 0000A771 0FB6DC              <1> 	movzx	ebx, ah
  5976 0000A774 BE[806D0100]        <1> 	mov	esi, FindFile_Name
  5977 0000A779 01F3                <1> 	add 	ebx, esi
  5978 0000A77B 29C0                <1> 	sub	eax, eax
  5979 0000A77D 8903                <1> 	mov	[ebx], eax ; 0 ; erase extension (.PRG)
  5980                              <1> 
  5981                              <1> loc_run_chk_auto_path_pos:
  5982                              <1> 	;movzx	eax,  word [Run_Auto_Path]
  5983 0000A77F 66A1[54700100]      <1> 	mov	ax, [Run_Auto_Path]
  5984 0000A785 39C8                <1> 	cmp	eax, ecx ; ecx = string length (except zero tail)
  5985 0000A787 0F83B4E1FFFF        <1> 	jnb	loc_cmd_failed
  5986                              <1> 	;or	eax, eax
  5987 0000A78D 6609C0              <1> 	or	ax, ax
  5988 0000A790 7502                <1> 	jnz	short loc_run_auto_path_pos_move
  5989 0000A792 B005                <1> 	mov	al, 5
  5990                              <1> 
  5991                              <1> loc_run_auto_path_pos_move:
  5992 0000A794 89FE                <1> 	mov	esi, edi ; offset TextBuffer
  5993 0000A796 01C6                <1> 	add	esi, eax
  5994                              <1> 
  5995                              <1> loc_run_auto_path_pos_space_loop:
  5996 0000A798 AC                  <1> 	lodsb
  5997 0000A799 3C20                <1> 	cmp	al, 20h 
  5998 0000A79B 74FB                <1> 	je	short loc_run_auto_path_pos_space_loop
  5999 0000A79D 0F829EE1FFFF        <1> 	jb	loc_cmd_failed 
  6000 0000A7A3 AA                  <1> 	stosb
  6001                              <1> loc_run_auto_path_pos_move_next: 
  6002 0000A7A4 AC                  <1> 	lodsb
  6003 0000A7A5 3C3B                <1> 	cmp	al, ';'
  6004 0000A7A7 7414                <1> 	je	short loc_run_auto_path_pos_move_last_byte
  6005 0000A7A9 3C20                <1> 	cmp	al, 20h
  6006 0000A7AB 74F7                <1> 	je	short loc_run_auto_path_pos_move_next
  6007 0000A7AD 7203                <1> 	jb	short loc_byte_ptr_end_of_path
  6008 0000A7AF AA                  <1> 	stosb
  6009 0000A7B0 EBF2                <1> 	jmp	short loc_run_auto_path_pos_move_next 
  6010                              <1> 
  6011                              <1> loc_byte_ptr_end_of_path: 
  6012 0000A7B2 66C705[54700100]FF- <1> 	mov	word [Run_Auto_Path], 0FFFFh ; end of path
  6012 0000A7BA FF                  <1>
  6013 0000A7BB EB0D                <1> 	jmp	short loc_run_auto_path_move_ok 
  6014                              <1> 
  6015                              <1> loc_run_auto_path_pos_move_last_byte:
  6016 0000A7BD 89F0                <1> 	mov	eax, esi
  6017 0000A7BF 2D[9E650100]        <1> 	sub	eax, TextBuffer 
  6018 0000A7C4 66A3[54700100]      <1> 	mov	[Run_Auto_Path], ax ; next path position
  6019                              <1> 
  6020                              <1> loc_run_auto_path_move_ok:
  6021 0000A7CA 4F                  <1> 	dec	edi
  6022 0000A7CB B02F                <1> 	mov	al, '/'
  6023 0000A7CD 3807                <1> 	cmp	[edi], al
  6024 0000A7CF 7403                <1> 	je	short loc_run_auto_path_move_file_name
  6025 0000A7D1 47                  <1> 	inc	edi
  6026 0000A7D2 8807                <1> 	mov	[edi], al
  6027                              <1> 
  6028                              <1> loc_run_auto_path_move_file_name:
  6029 0000A7D4 47                  <1> 	inc	edi   
  6030 0000A7D5 BE[806D0100]        <1> 	mov	esi, FindFile_Name
  6031                              <1> 
  6032                              <1> loc_run_auto_path_move_fn_loop:
  6033 0000A7DA AC                  <1> 	lodsb
  6034 0000A7DB AA                  <1> 	stosb
  6035 0000A7DC 08C0                <1> 	or	al, al
  6036 0000A7DE 75FA                <1> 	jnz	short loc_run_auto_path_move_fn_loop
  6037                              <1> 
  6038 0000A7E0 BE[9E650100]        <1> 	mov	esi, TextBuffer
  6039 0000A7E5 BF[3E6D0100]        <1> 	mov	edi, FindFile_Drv
  6040 0000A7EA E833080000          <1> 	call	parse_path_name
  6041 0000A7EF 0F824CE1FFFF        <1> 	jc	loc_cmd_failed
  6042                              <1> 
  6043 0000A7F5 8A35[9E640100]      <1> 	mov	dh, [Current_Drv]
  6044 0000A7FB 8A15[3E6D0100]      <1> 	mov	dl, [FindFile_Drv]
  6045 0000A801 38F2                <1> 	cmp	dl, dh
  6046 0000A803 740B                <1> 	je	short loc_run_change_directory_again
  6047                              <1>                
  6048 0000A805 E8A4D2FFFF          <1> 	call	change_current_drive
  6049 0000A80A 0F825CE1FFFF        <1> 	jc	loc_run_cmd_failed
  6050                              <1> 
  6051                              <1> loc_run_change_directory_again:
  6052 0000A810 803D[3F6D0100]20    <1> 	cmp	byte [FindFile_Directory], 20h
  6053 0000A817 761D                <1> 	jna	short loc_load_executable_cdir_chk_again
  6054                              <1> 
  6055 0000A819 FE05[F6170100]      <1> 	inc	byte [Restore_CDIR]
  6056 0000A81F BE[3F6D0100]        <1> 	mov	esi, FindFile_Directory
  6057 0000A824 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  6058 0000A826 E8E1010000          <1> 	call	change_current_directory
  6059 0000A82B 0F823BE1FFFF        <1> 	jc	loc_run_cmd_failed
  6060                              <1> 
  6061                              <1> loc_run_chg_prompt_dir_str_again:
  6062 0000A831 E8F6000000          <1> 	call	change_prompt_dir_string
  6063                              <1> 
  6064                              <1> loc_load_executable_cdir_chk_again:
  6065 0000A836 A1[98640100]        <1> 	mov	eax, [Current_Dir_FCluster]
  6066 0000A83B 3B05[50700100]      <1> 	cmp	eax, [Run_CDirFC]
  6067 0000A841 0F8597FEFFFF        <1> 	jne	loc_run_find_executable_file_next
  6068 0000A847 30C0                <1> 	xor	al, al ; 0
  6069 0000A849 E9E8FEFFFF          <1> 	jmp	loc_run_check_auto_path_again
  6070                              <1> 
  6071                              <1> loc_load_and_run_file:
  6072                              <1> 	; 13/11/2017
  6073                              <1> 	; 04/01/2017
  6074                              <1> 	; 23/04/2016
  6075 0000A84E BE[806D0100]        <1> 	mov	esi, FindFile_Name
  6076 0000A853 BF[9E650100]        <1> 	mov	edi, TextBuffer
  6077                              <1> 
  6078                              <1>  	; 24/04/2016
  6079 0000A858 31D2                <1> 	xor	edx, edx
  6080 0000A85A 668915[4A040300]    <1> 	mov	word [argc], dx ; 0
  6081 0000A861 8915[8C030300]      <1> 	mov	dword [u.nread], edx ; 0
  6082                              <1> 
  6083                              <1> loc_load_and_run_file_1:
  6084 0000A867 AC                  <1> 	lodsb	
  6085 0000A868 AA                  <1> 	stosb
  6086 0000A869 FF05[8C030300]      <1> 	inc	dword [u.nread]
  6087 0000A86F 20C0                <1> 	and	al, al
  6088 0000A871 75F4                <1> 	jnz 	short loc_load_and_run_file_1
  6089                              <1> 	
  6090 0000A873 A0[FF640100]        <1> 	mov	al, [CmdArgStart]
  6091 0000A878 20C0                <1> 	and	al, al
  6092 0000A87A 7445                <1> 	jz	short loc_load_and_run_file_7
  6093                              <1> 
  6094 0000A87C 0FB6F0              <1> 	movzx	esi, al ; 11/05/2016
  6095 0000A87F B950000000          <1> 	mov	ecx, 80
  6096 0000A884 29F1                <1> 	sub	ecx, esi
  6097 0000A886 81C6[4E650100]      <1> 	add	esi, CommandBuffer
  6098                              <1> 
  6099 0000A88C 66FF05[4A040300]    <1> 	inc	word [argc] ; 11/05/2016
  6100                              <1> 
  6101                              <1> loc_load_and_run_file_2:
  6102 0000A893 AC                  <1> 	lodsb
  6103 0000A894 3C20                <1> 	cmp	al, 20h
  6104 0000A896 7717                <1> 	ja	short loc_load_and_run_file_5	
  6105 0000A898 721E                <1> 	jb	short loc_load_and_run_file_6
  6106                              <1> 
  6107                              <1> loc_load_and_run_file_3:
  6108 0000A89A 803E20              <1> 	cmp	byte [esi], 20h
  6109 0000A89D 7707                <1> 	ja	short loc_load_and_run_file_4
  6110 0000A89F 7217                <1> 	jb	short loc_load_and_run_file_6
  6111 0000A8A1 46                  <1> 	inc	esi
  6112 0000A8A2 E2F6                <1> 	loop	loc_load_and_run_file_3
  6113 0000A8A4 EB12                <1> 	jmp	short loc_load_and_run_file_6
  6114                              <1> 
  6115                              <1> loc_load_and_run_file_4:
  6116 0000A8A6 28C0                <1> 	sub	al, al ; 0
  6117 0000A8A8 66FF05[4A040300]    <1> 	inc	word [argc]
  6118                              <1> loc_load_and_run_file_5:
  6119 0000A8AF AA                  <1> 	stosb
  6120 0000A8B0 FF05[8C030300]      <1> 	inc	dword [u.nread]
  6121 0000A8B6 E2DB                <1> 	loop	loc_load_and_run_file_2
  6122                              <1> 			
  6123                              <1> loc_load_and_run_file_6:
  6124 0000A8B8 30C0                <1> 	xor	al, al ; 0
  6125 0000A8BA AA                  <1> 	stosb
  6126 0000A8BB FF05[8C030300]      <1> 	inc	dword [u.nread]
  6127                              <1> loc_load_and_run_file_7:
  6128 0000A8C1 8807                <1> 	mov 	[edi], al ; 0
  6129 0000A8C3 66FF05[4A040300]    <1> 	inc	word [argc] ; 24/04/2016
  6130 0000A8CA FF05[8C030300]      <1> 	inc	dword [u.nread] ; 24/04/2016
  6131 0000A8D0 BE[9E650100]        <1> 	mov	esi, TextBuffer
  6132 0000A8D5 8B15[AC6D0100]      <1> 	mov	edx, [FindFile_DirEntry+DirEntry_FileSize]
  6133 0000A8DB 66A1[A46D0100]      <1> 	mov	ax, [FindFile_DirEntry+DirEntry_FstClusHI]
  6134 0000A8E1 C1E010              <1> 	shl	eax, 16 ; 13/11/2017
  6135 0000A8E4 66A1[AA6D0100]      <1> 	mov	ax, [FindFile_DirEntry+DirEntry_FstClusLO]
  6136                              <1> 	; EAX = First Cluster number
  6137                              <1> 	; EDX = File Size
  6138                              <1> 	; ESI = Argument list address
  6139                              <1> 	; [argc] = argument count
  6140                              <1> 	; [u.nread] = argument list length
  6141 0000A8EA E8C7410000          <1> 	call	load_and_run_file ; trdosk6.s
  6142                              <1>         ;jc	loc_run_cmd_failed ; 04/01/2017
  6143                              <1> loc_load_and_run_file_8: ; 06/05/2016
  6144 0000A8EF E98BE9FFFF          <1> 	jmp	loc_file_rw_restore_retn
  6145                              <1> 
  6146                              <1> check_prg_filename_ext:
  6147                              <1> 	; 23/04/2016 (TRDOS 386 = TRDOS v2.0)
  6148                              <1> 	; 10/09/2011 
  6149                              <1> 	; (TRDOS v1, CMDINTR.ASM, 'proc_check_exe_filename_ext')
  6150                              <1> 	; 14/11/2009
  6151                              <1> 	; INPUT -> 
  6152                              <1> 	;	ESI = Dot File Name
  6153                              <1> 	; OUTPUT ->
  6154                              <1> 	;     cf = 0 -> EXE_ID in AL
  6155                              <1> 	;	ESI = Last char + 1 position
  6156                              <1> 	;     cf = 1 -> Invalid executable file name
  6157                              <1> 	;	or no file name extension if AH<=8
  6158                              <1> 	;	AL = Last file name char     
  6159                              <1> 	;     cf = 0 -> AL='P' (PRG), AL=0 (no extension)
  6160                              <1> 	;
  6161                              <1> 	; (Modified registers: EAX, ESI)
  6162                              <1>   
  6163 0000A8F4 30E4                <1> 	xor	ah, ah
  6164                              <1> loc_run_check_filename_ext:	
  6165 0000A8F6 AC                  <1> 	lodsb
  6166 0000A8F7 3C21                <1> 	cmp	al, 21h
  6167 0000A8F9 7229                <1> 	jb	short loc_check_exe_fn_retn 
  6168 0000A8FB FEC4                <1> 	inc	ah
  6169 0000A8FD 3C2E                <1> 	cmp	al, '.'
  6170 0000A8FF 75F5                <1> 	jne	short loc_run_check_filename_ext	
  6171                              <1> 		 
  6172                              <1> loc_run_check_filename_ext_dot:
  6173 0000A901 80FC02              <1> 	cmp	ah, 2 ; .??? is not valid
  6174 0000A904 88C4                <1> 	mov	ah, al ; '.' 
  6175 0000A906 7219                <1> 	jb	short loc_check_prg_fn_retn
  6176                              <1> 
  6177                              <1> loc_run_check_filename_ext_dot_ok:
  6178 0000A908 AC                  <1> 	lodsb
  6179 0000A909 24DF                <1> 	and	al, 0DFh 
  6180                              <1> 
  6181                              <1> loc_run_check_filename_ext_prg:
  6182 0000A90B 3C50                <1> 	cmp	al, 'P'
  6183 0000A90D 7212                <1> 	jb	short loc_check_prg_fn_retn
  6184 0000A90F 7711                <1> 	ja	short loc_check_prg_fn_stc
  6185 0000A911 AC                  <1> 	lodsb
  6186 0000A912 24DF                <1> 	and	al, 0DFh 
  6187 0000A914 3C52                <1> 	cmp	al, 'R'
  6188 0000A916 750A                <1> 	jne	short loc_check_prg_fn_stc
  6189 0000A918 AC                  <1> 	lodsb
  6190 0000A919 24DF                <1> 	and	al, 0DFh
  6191 0000A91B 3C47                <1> 	cmp	al, 'G'
  6192 0000A91D 7503                <1> 	jne	short loc_check_prg_fn_stc
  6193                              <1> 
  6194 0000A91F B050                <1> 	mov	al, 'P'
  6195                              <1> loc_check_prg_fn_retn:
  6196 0000A921 C3                  <1> 	retn
  6197                              <1> 
  6198                              <1> loc_check_prg_fn_stc:
  6199 0000A922 F9                  <1> 	stc
  6200 0000A923 C3                  <1> 	retn
  6201                              <1>  
  6202                              <1> loc_check_exe_fn_retn:
  6203 0000A924 28C0                <1> 	sub	al, al ; 0
  6204 0000A926 C3                  <1> 	retn
  6205                              <1>               
  6206                              <1> find_and_list_files:
  6207 0000A927 C3                  <1> 	retn
  6208                              <1> set_exec_arguments:
  6209 0000A928 C3                  <1> 	retn
  6210                              <1> delete_fs_directory:
  6211 0000A929 31C0                <1> 	xor eax, eax
  6212 0000A92B C3                  <1> 	retn
  3033                                  %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: 29/12/2017
     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> 	; 05/10/2016
    20                              <1> 	; 24/01/2016 (TRDOS 386 = TRDOS v2.0)
    21                              <1> 	; 27/03/2011
    22                              <1> 	; 09/10/2009
    23                              <1> 	; INPUT/OUTPUT => none
    24                              <1> 	; this procedure changes current directory string/text  
    25                              <1> 	; 2005
    26                              <1> 
    27 0000A92C BE[FB6B0100]        <1> 	mov	esi, PATH_Array
    28                              <1> change_prompt_dir_str: ; 05/10/2016 (call from 'set_working_path')
    29 0000A931 BF[A2640100]        <1> 	mov	edi, Current_Directory
    30 0000A936 8A25[9C640100]      <1> 	mov	ah, [Current_Dir_Level]
    31 0000A93C E807000000          <1> 	call	set_current_directory_string
    32 0000A941 880D[FD640100]      <1> 	mov	[Current_Dir_StrLen], cl
    33                              <1> 
    34 0000A947 C3                  <1> 	retn
    35                              <1> 
    36                              <1> set_current_directory_string:
    37                              <1> 	; 24/01/2016 (TRDOS 386 = TRDOS v2.0)
    38                              <1> 	; 27/03/2011
    39                              <1> 	; 09/10/2009
    40                              <1> 	; INPUT:
    41                              <1> 	;    ESI = Path Array Address 
    42                              <1> 	;    EDI = Current Directory String Buffer
    43                              <1> 	;    AH = Current Directory Level
    44                              <1> 	; OUTPUT => EAX, EBX, ESI will be changed
    45                              <1> 	;    EDI will be same with input
    46                              <1> 	;    ECX = Current Directory String Length 
    47                              <1> 
    48 0000A948 57                  <1> 	push    edi
    49 0000A949 80FC00              <1> 	cmp     ah, 0
    50 0000A94C 7652                <1> 	jna	short pass_write_path
    51 0000A94E 83C610              <1> 	add	esi, 16
    52 0000A951 89F3                <1> 	mov	ebx, esi
    53                              <1> loc_write_path:
    54 0000A953 B908000000          <1> 	mov	ecx, 8
    55                              <1> path_write_dirname1:
    56 0000A958 AC                  <1> 	lodsb
    57 0000A959 3C20                <1> 	cmp	al, 20h
    58 0000A95B 7612                <1> 	jna	short pass_write_dirname1
    59 0000A95D AA                  <1> 	stosb
    60 0000A95E 81FF[FC640100]      <1> 	cmp	edi, End_Of_Current_Dir_Str
    61 0000A964 733A                <1> 	jnb	short pass_write_path
    62 0000A966 E2F0                <1> 	loop	path_write_dirname1
    63 0000A968 803E20              <1> 	cmp	byte [esi], 20h
    64 0000A96B 7624                <1> 	jna	short pass_write_dirname2
    65 0000A96D EB0A                <1> 	jmp     short loc_put_dot_cont_ext
    66                              <1> pass_write_dirname1:
    67 0000A96F 89DE                <1> 	mov	esi, ebx
    68 0000A971 83C608              <1> 	add	esi, 8
    69 0000A974 803E20              <1> 	cmp	byte [esi], 20h
    70 0000A977 7618                <1> 	jna	short pass_write_dirname2
    71                              <1> loc_put_dot_cont_ext:
    72 0000A979 C6072E              <1> 	mov	byte [edi], "."
    73                              <1> 	;mov	ecx, 3
    74 0000A97C B103                <1> 	mov	cl, 3
    75                              <1> loc_check_dir_name_ext:
    76 0000A97E AC                  <1> 	lodsb
    77 0000A97F 47                  <1> 	inc	edi
    78 0000A980 3C20                <1> 	cmp	al, 20h
    79 0000A982 760D                <1> 	jna	short pass_write_dirname2
    80 0000A984 8807                <1> 	mov	[edi], al
    81 0000A986 81FF[FC640100]      <1> 	cmp	edi, End_Of_Current_Dir_Str
    82 0000A98C 7312                <1> 	jnb	short pass_write_path
    83 0000A98E E2EE                <1> 	loop    loc_check_dir_name_ext
    84 0000A990 47                  <1> 	inc	edi
    85                              <1> pass_write_dirname2:
    86 0000A991 FECC                <1> 	dec	ah
    87 0000A993 740B                <1> 	jz      short pass_write_path
    88 0000A995 83C310              <1> 	add	ebx, 16
    89 0000A998 89DE                <1> 	mov	esi, ebx
    90 0000A99A C6072F              <1> 	mov	byte [edi],"/"
    91 0000A99D 47                  <1> 	inc	edi
    92 0000A99E EBB3                <1> 	jmp	short loc_write_path
    93                              <1> pass_write_path:
    94 0000A9A0 C60700              <1> 	mov	byte [edi], 0
    95 0000A9A3 47                  <1> 	inc	edi
    96 0000A9A4 89F9                <1> 	mov	ecx, edi
    97 0000A9A6 5F                  <1> 	pop	edi
    98 0000A9A7 29F9                <1> 	sub	ecx, edi
    99                              <1> 	; ECX = Current Directory String Length
   100 0000A9A9 C3                  <1> 	retn
   101                              <1> 
   102                              <1> get_current_directory:
   103                              <1> 	; 15/10/2016
   104                              <1> 	; 14/02/2016
   105                              <1> 	; 24/01/2016 (TRDOS 386 = TRDOS v2.0)
   106                              <1> 	; 27/03/2011
   107                              <1> 	;
   108                              <1> 	; INPUT-> ESI = Current Directory Buffer
   109                              <1> 	;         DL = TRDOS Logical Dos Drive Number + 1
   110                              <1> 	;              (0= Default/Current Drive)
   111                              <1> 	;           
   112                              <1> 	;   Note: Required dir buffer length may be <= 92 bytes
   113                              <1> 	;         for TRDOS (7*12 name chars + 7 slash + 0)
   114                              <1> 	; OUTPUT ->  ESI = Current Directory Buffer
   115                              <1> 	;            EAX, EBX, ECX, EDX, EDI will be changed
   116                              <1> 	;            CX/CL = Current Directory String Length
   117                              <1> 	;	     DL = Drive Number (0 based)
   118                              <1> 	;            (If input is 0, output is current drv number) 
   119                              <1> 	;            DH = same with input 
   120                              <1> 	;   cf = 0 -> AL = 0
   121                              <1> 	;   cf = 1 -> error code in AL 
   122                              <1>               
   123                              <1> loc_get_current_drive_0:
   124 0000A9AA 80FA00              <1> 	cmp	dl, 0
   125 0000A9AD 7708                <1> 	ja	short loc_get_current_drive_1
   126 0000A9AF 8A15[9E640100]      <1> 	mov	dl, [Current_Drv]
   127 0000A9B5 EB17                <1> 	jmp	short loc_get_current_drive_2
   128                              <1> loc_get_current_drive_1:
   129 0000A9B7 FECA                <1> 	dec 	dl
   130 0000A9B9 3A15[F5170100]      <1> 	cmp	dl, [Last_DOS_DiskNo]
   131 0000A9BF 760D                <1> 	jna	short loc_get_current_drive_2
   132 0000A9C1 B80F000000          <1> 	mov	eax, 0Fh ; Invalid drive (Drive not ready!)
   133 0000A9C6 F5                  <1> 	cmc 	; stc
   134 0000A9C7 C3                  <1> 	retn
   135                              <1> 
   136                              <1> loc_get_current_drive_not_ready_retn:
   137 0000A9C8 5E                  <1> 	pop	esi
   138                              <1> 	;mov	eax, 15
   139 0000A9C9 66B80F00            <1> 	mov	ax, 15 ; Drive not ready
   140 0000A9CD C3                  <1> 	retn  
   141                              <1>  
   142                              <1> loc_get_current_drive_2:
   143 0000A9CE 31C0                <1> 	xor	eax, eax
   144 0000A9D0 88D4                <1> 	mov	ah, dl
   145 0000A9D2 56                  <1> 	push	esi
   146 0000A9D3 BE00010900          <1> 	mov	esi, Logical_DOSDisks
   147 0000A9D8 01C6                <1> 	add	esi, eax
   148 0000A9DA 8A06                <1> 	mov	al, [esi+LD_Name] 
   149 0000A9DC 3C41                <1> 	cmp	al, 'A'
   150 0000A9DE 72E8                <1> 	jb	short loc_get_current_drive_not_ready_retn
   151                              <1> 
   152 0000A9E0 8A667F              <1> 	mov	ah, [esi+LD_CDirLevel]
   153 0000A9E3 08E4                <1> 	or	ah, ah
   154 0000A9E5 7506                <1> 	jnz	short loc_get_current_drive_3
   155                              <1> 
   156                              <1> 	;xor	ah, ah ; mov ah, 0
   157 0000A9E7 8826                <1> 	mov	[esi], ah
   158 0000A9E9 31C9                <1> 	xor	ecx, ecx
   159 0000A9EB EB1C                <1> 	jmp	short loc_get_current_drive_4
   160                              <1> 
   161                              <1> loc_get_current_drive_3:
   162 0000A9ED BF[FB6B0100]        <1>         mov     edi, PATH_Array
   163 0000A9F2 57                  <1> 	push	edi
   164 0000A9F3 81C680000000        <1> 	add	esi, LD_CurrentDirectory
   165 0000A9F9 B920000000          <1> 	mov	ecx, 32
   166 0000A9FE F3A5                <1> 	rep	movsd
   167 0000AA00 5E                  <1> 	pop	esi ; Path Array Address
   168 0000AA01 5F                  <1> 	pop	edi ; pushed esi (current dir buffer offset) 
   169                              <1> 	;
   170 0000AA02 E841FFFFFF          <1> 	call	set_current_directory_string
   171 0000AA07 89FE                <1> 	mov	esi, edi
   172                              <1> 
   173                              <1> loc_get_current_drive_4:
   174 0000AA09 30C0                <1> 	xor	al, al
   175 0000AA0B C3                  <1> 	retn
   176                              <1> 
   177                              <1> change_current_directory:
   178                              <1> 	; 19/02/2016
   179                              <1> 	; 11/02/2016
   180                              <1> 	; 10/02/2016
   181                              <1> 	; 08/02/2016
   182                              <1> 	; 06/02/2016 (TRDOS 386 = TRDOS v2.0)
   183                              <1> 	; 18/09/2011 (DIR.ASM, 09/10/2011)	
   184                              <1> 	; 04/10/2009
   185                              <1> 	; 2005
   186                              <1> 	; INPUT -> 
   187                              <1> 	;	ESI = Directory string
   188                              <1> 	;	ah = CD command (CDh = save current dir string)
   189                              <1> 	; OUTPUT -> 
   190                              <1> 	; 	EDI = DOS Drive Description Table
   191                              <1> 	; 	cf = 1 -> error
   192                              <1> 	;	   EAX = Error code
   193                              <1> 	;	cf = 0 -> successful
   194                              <1> 	;	   ESI = PATH_Array
   195                              <1> 	;	   EAX = Current Directory First Cluster
   196                              <1> 	;
   197                              <1> 	; (EAX, EBX, ECX, EDX, ESI, EDI will be changed)
   198                              <1> 	
   199 0000AA0C 8825[896C0100]      <1> 	mov	[CD_COMMAND], ah
   200 0000AA12 803E2F              <1> 	cmp	byte [esi], '/'
   201 0000AA15 7505                <1> 	jne	short loc_ccd_cdir_level
   202 0000AA17 46                  <1> 	inc	esi
   203 0000AA18 30C0                <1> 	xor	al, al
   204 0000AA1A EB05                <1> 	jmp	short loc_ccd_parse_path_name
   205                              <1> loc_ccd_cdir_level:
   206 0000AA1C A0[9C640100]        <1> 	mov	al, [Current_Dir_Level]
   207                              <1> loc_ccd_parse_path_name:
   208 0000AA21 88C4                <1> 	mov	ah, al
   209 0000AA23 BF[FB6B0100]        <1> 	mov	edi, PATH_Array
   210                              <1> 
   211                              <1> ; Reset directory levels > cdir level
   212                              <1> 	; is this required !?
   213                              <1> 	;
   214                              <1> 	; Relations:
   215                              <1> 	; MAINPROG.ASM (pass_ccdrv_reset_cdir_FAT_fcluster)
   216                              <1> 	; proc_parse_dir_name,
   217                              <1> 	; proc_change_current_directory (this procedure)
   218                              <1> 	; proc_change_prompt_dir_string 
   219                              <1>  
   220 0000AA28 0FB6C8              <1> 	movzx	ecx, al
   221 0000AA2B FEC1                <1> 	inc	cl
   222 0000AA2D C0E104              <1> 	shl	cl, 4
   223 0000AA30 01CF                <1> 	add	edi, ecx
   224 0000AA32 B107                <1> 	mov	cl, 7
   225 0000AA34 28C1                <1> 	sub	cl, al
   226 0000AA36 C0E102              <1> 	shl	cl, 2
   227 0000AA39 89C3                <1> 	mov	ebx, eax
   228 0000AA3B 31C0                <1> 	xor	eax, eax ; 0
   229 0000AA3D F3AB                <1> 	rep	stosd
   230 0000AA3F 89D8                <1> 	mov	eax, ebx
   231                              <1> 
   232 0000AA41 BF[FB6B0100]        <1> 	mov	edi, PATH_Array
   233                              <1> 
   234 0000AA46 803E20              <1> 	cmp	byte [esi], 20h
   235 0000AA49 F5                  <1> 	cmc
   236 0000AA4A 7305                <1> 	jnc	short pass_ccd_parse_dir_name
   237                              <1> 
   238                              <1> 		; ESI = Path name
   239                              <1> 		; AL = CCD_Level
   240 0000AA4C E872010000          <1>         call    parse_dir_name
   241                              <1> 		; AL = CCD_Level 
   242                              <1> 		; AH = Last_Dir_Level
   243                              <1> 		; (EDI = PATH_Array)
   244                              <1> 
   245                              <1> pass_ccd_parse_dir_name:
   246 0000AA51 9C                  <1> 	pushf
   247                              <1> 
   248                              <1> 	;mov	[CCD_Level], al
   249                              <1>         ;mov	[Last_Dir_Level], ah
   250 0000AA52 66A3[7F6C0100]      <1> 	mov	[CCD_Level], ax
   251                              <1> 
   252 0000AA58 31DB                <1> 	xor	ebx, ebx
   253 0000AA5A 8A3D[9E640100]      <1> 	mov	bh, [Current_Drv]
   254 0000AA60 BE00010900          <1> 	mov	esi, Logical_DOSDisks
   255 0000AA65 01DE                <1> 	add	esi, ebx
   256                              <1> 
   257 0000AA67 9D                  <1> 	popf 
   258 0000AA68 720A                <1> 	jc	short loc_ccd_bad_path_name_retn
   259                              <1> 
   260 0000AA6A 8935[7B6C0100]      <1> 	mov	[CCD_DriveDT], esi
   261                              <1> 
   262 0000AA70 3C07                <1> 	cmp	al, 7
   263 0000AA72 7209                <1> 	jb	short loc_ccd_load_child_dir
   264                              <1> 
   265                              <1> loc_ccd_bad_path_name_retn:
   266 0000AA74 87F7                <1> 	xchg	esi, edi
   267 0000AA76 B813000000          <1> 	mov	eax, 19 ; Bad directory/path name 
   268 0000AA7B F9                  <1> 	stc
   269                              <1> loc_ccd_retn_p:
   270 0000AA7C C3                  <1> 	retn
   271                              <1> 
   272                              <1> loc_ccd_load_child_dir:
   273                              <1> 	; AL = CCD_Level
   274 0000AA7D 08C0                <1> 	or	al, al
   275 0000AA7F 7468                <1> 	jz	short loc_ccd_load_root_dir
   276                              <1> 
   277 0000AA81 6689C1              <1> 	mov	cx, ax
   278 0000AA84 C0E004              <1> 	shl	al, 4
   279 0000AA87 0FB6F0              <1> 	movzx	esi, al
   280 0000AA8A 01FE                <1>      	add	esi, edi  ; offset PATH_Array
   281                              <1> 
   282 0000AA8C 8B460C              <1> 	mov	eax, [esi+12]
   283 0000AA8F 38E9                <1> 	cmp	cl, ch
   284 0000AA91 0F84FA000000        <1>         je      loc_ccd_load_sub_directory
   285 0000AA97 A3[98640100]        <1> 	mov	[Current_Dir_FCluster], eax
   286                              <1> 
   287                              <1> loc_ccd_load_child_dir_next:
   288 0000AA9C 83C610              <1> 	add	esi, 16 ; DOS DirEntry Format FileName Address
   289                              <1> 
   290                              <1>  	; Directory attribute : 10h
   291 0000AA9F B010                <1> 	mov	al, 00010000b ; 10h (Attrib AND mask)
   292                              <1> 	;mov	ah, 11001000b ; C8h
   293                              <1> 	; Volume name attribute: 8h
   294 0000AAA1 B408                <1> 	mov	ah, 00001000b ; 08h (Attrib NAND, AND --> zero mask)
   295                              <1> 
   296 0000AAA3 6631C9              <1> 	xor	cx, cx  
   297 0000AAA6 E8B5010000          <1> 	call	locate_current_dir_file
   298 0000AAAB 7353                <1> 	jnc	short loc_ccd_set_dir_cluster_ptr
   299                              <1> 
   300                              <1> 	 ; 19/02/2016
   301                              <1> 	;mov	edi, [CCD_DriveDT]
   302 0000AAAD 8A25[7F6C0100]      <1> 	mov	ah, [CCD_Level]
   303 0000AAB3 803D[896C0100]CD    <1> 	cmp	byte [CD_COMMAND], 0CDh ;'CD' command or another
   304 0000AABA 7509                <1> 	jne	short loc_ccd_load_child_dir_err
   305                              <1> 	; It is better to save recent successful part 
   306                              <1> 	; of the (requested) path as current directory.
   307                              <1> 	; (Otherwise the path would be reset to back
   308                              <1> 	; on the next 'CD' command.)
   309 0000AABC 88E1                <1> 	mov	cl, ah
   310 0000AABE 50                  <1> 	push	eax
   311 0000AABF E8E3000000          <1> 	call	loc_ccd_save_current_dir
   312 0000AAC4 58                  <1> 	pop	eax
   313                              <1> loc_ccd_load_child_dir_err:            
   314 0000AAC5 3C03                <1> 	cmp	al, 3	; AL = 2 => File not found error
   315 0000AAC7 7202                <1> 	jb	short loc_ccd_path_not_found_retn
   316 0000AAC9 F9                  <1> 	stc
   317 0000AACA C3                  <1> 	retn
   318                              <1> 
   319                              <1> loc_ccd_path_not_found_retn:
   320 0000AACB B003                <1> 	mov	al, 3	; Path not found
   321 0000AACD C3                  <1> 	retn
   322                              <1> 
   323                              <1> loc_ccd_load_FAT_root_dir:
   324 0000AACE 803D[9D640100]02    <1> 	cmp	byte [Current_FATType], 2
   325 0000AAD5 776B                <1> 	ja	short loc_ccd_load_FAT32_root_dir
   326                              <1> 
   327                              <1> 	;mov	esi, [CCD_DriveDT]
   328                              <1> 	;push	esi
   329 0000AAD7 E8B51D0000          <1> 	call	load_FAT_root_directory
   330                              <1> 	;pop	edi ; Dos Drv Description Table
   331                              <1> 
   332 0000AADC 89F7                <1> 	mov	edi, esi
   333 0000AADE BE[FB6B0100]        <1> 	mov	esi, PATH_Array
   334 0000AAE3 7297                <1> 	jc	short loc_ccd_retn_p
   335                              <1> 
   336 0000AAE5 31C0                <1> 	xor	eax, eax
   337 0000AAE7 EB78                <1>         jmp	short loc_ccd_set_cdfc
   338                              <1> 
   339                              <1> loc_ccd_load_root_dir:
   340 0000AAE9 803D[9D640100]01    <1> 	cmp	byte [Current_FATType], 1
   341 0000AAF0 73DC                <1> 	jnb	short loc_ccd_load_FAT_root_dir
   342                              <1> 
   343                              <1> loc_ccd_load_FS_root_dir:
   344 0000AAF2 E8611E0000          <1> 	call	load_FS_root_directory
   345 0000AAF7 EB5C                <1> 	jmp	short pass_ccd_load_FAT_sub_directory
   346                              <1> 
   347                              <1> loc_ccd_load_FS_sub_directory_next:
   348 0000AAF9 E85B1E0000          <1> 	call	load_FS_sub_directory
   349 0000AAFE EB1F                <1> 	jmp	short pass_ccd_set_dir_cluster_ptr  
   350                              <1> 
   351                              <1> loc_ccd_set_dir_cluster_ptr:
   352                              <1> 	; EDI = Directory Entry
   353 0000AB00 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
   354 0000AB04 C1E010              <1> 	shl	eax, 16
   355 0000AB07 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
   356                              <1> 
   357 0000AB0B 8B35[7B6C0100]      <1> 	mov	esi, [CCD_DriveDT]
   358 0000AB11 803D[9D640100]01    <1> 	cmp	byte [Current_FATType], 1
   359 0000AB18 72DF                <1> 	jb	short loc_ccd_load_FS_sub_directory_next
   360                              <1> 	;push	esi
   361 0000AB1A E8FD1D0000          <1> 	call	load_FAT_sub_directory
   362                              <1> 	;pop	edi ; Dos Drv Description Table
   363                              <1> 
   364                              <1> pass_ccd_set_dir_cluster_ptr:
   365                              <1> 	;mov	edi, esi
   366 0000AB1F BE[FB6B0100]        <1> 	mov	esi, PATH_Array
   367 0000AB24 7264                <1> 	jc	short loc_ccd_retn_c
   368                              <1> 
   369 0000AB26 A1[C96B0100]        <1> 	mov	eax, [DirBuff_Cluster]
   370                              <1> 
   371 0000AB2B FE05[7F6C0100]      <1> 	inc	byte [CCD_Level]
   372 0000AB31 0FB61D[7F6C0100]    <1> 	movzx	ebx, byte [CCD_Level]
   373 0000AB38 C0E304              <1> 	shl	bl, 4 ; * 16 (<= 128)   
   374 0000AB3B 01DE                <1> 	add	esi, ebx ; 19/02/2016
   375 0000AB3D 89460C              <1> 	mov	[esi+12], eax
   376 0000AB40 EB1F                <1> 	jmp	short loc_ccd_set_cdfc
   377                              <1> 
   378                              <1> loc_ccd_load_FAT32_root_dir:
   379 0000AB42 BE[FB6B0100]        <1> 	mov	esi, PATH_Array
   380 0000AB47 8B460C              <1> 	mov	eax, [esi+12]
   381 0000AB4A 8B35[7B6C0100]      <1> 	mov	esi, [CCD_DriveDT]
   382                              <1>  
   383                              <1> loc_ccd_load_FAT_sub_directory:
   384                              <1> 	;push	esi
   385 0000AB50 E8C71D0000          <1> 	call	load_FAT_sub_directory
   386                              <1> 	;pop	edi ; Dos Drv Description Table
   387                              <1> 
   388                              <1> pass_ccd_load_FAT_sub_directory:
   389                              <1> 	;mov	edi, esi
   390 0000AB55 BE[FB6B0100]        <1> 	mov	esi, PATH_Array
   391 0000AB5A 722E                <1> 	jc	short loc_ccd_retn_c
   392                              <1> 
   393 0000AB5C A1[C96B0100]        <1> 	mov	eax, [DirBuff_Cluster]
   394                              <1> 
   395                              <1> loc_ccd_set_cdfc:
   396 0000AB61 8A0D[7F6C0100]      <1> 	mov	cl, [CCD_Level]
   397 0000AB67 880D[9C640100]      <1> 	mov	[Current_Dir_Level], cl
   398 0000AB6D A3[98640100]        <1> 	mov	[Current_Dir_FCluster], eax
   399                              <1> 
   400 0000AB72 8A2D[806C0100]      <1> 	mov	ch, [Last_Dir_Level]
   401 0000AB78 38E9                <1> 	cmp	cl, ch 
   402 0000AB7A 0F821CFFFFFF        <1> 	jb	loc_ccd_load_child_dir_next
   403                              <1> 	
   404 0000AB80 803D[896C0100]CD    <1> 	cmp	byte [CD_COMMAND], 0CDh ;'CD' command or another
   405 0000AB87 741E                <1> 	je	short loc_ccd_save_current_dir
   406                              <1> 
   407                              <1>         ; jne -> don't save, restore (the previous cdir) later !
   408                              <1>         ; (saving the cdir would prevent previous cdir restoration!)
   409                              <1> 
   410 0000AB89 F8                  <1> 	clc
   411                              <1> 
   412                              <1> loc_ccd_retn_c:
   413 0000AB8A 8B3D[7B6C0100]      <1> 	mov	edi, [CCD_DriveDT]
   414 0000AB90 C3                  <1> 	retn
   415                              <1> 
   416                              <1> loc_ccd_load_sub_directory:
   417 0000AB91 8B35[7B6C0100]      <1> 	mov	esi, [CCD_DriveDT]
   418 0000AB97 803D[9D640100]01    <1> 	cmp	byte [Current_FATType], 1
   419 0000AB9E 73B0                <1> 	jnb	short loc_ccd_load_FAT_sub_directory 
   420 0000ABA0 E8B41D0000          <1> 	call	load_FS_sub_directory
   421 0000ABA5 EBAE                <1> 	jmp	short pass_ccd_load_FAT_sub_directory 
   422                              <1> 
   423                              <1> loc_ccd_save_current_dir:
   424 0000ABA7 BE[FB6B0100]        <1> 	mov	esi, PATH_Array ; 19/02/2016
   425 0000ABAC 8B3D[7B6C0100]      <1> 	mov	edi, [CCD_DriveDT]
   426 0000ABB2 57                  <1> 	push	edi
   427 0000ABB3 83C77F              <1>         add     edi, LD_CDirLevel
   428 0000ABB6 880F                <1> 	mov	[edi], cl
   429 0000ABB8 47                  <1> 	inc	edi ; LD_CurrentDirectory 
   430 0000ABB9 56                  <1> 	push	esi
   431                              <1> 	;mov	ecx, 32  ; always < 65536 (in this procedure)
   432 0000ABBA 66B92000            <1> 	mov	cx, 32
   433 0000ABBE F3A5                <1> 	rep	movsd
   434                              <1> 	; Current directory has been saved to 
   435                              <1> 	; the DOS drive description table, cdir area !
   436 0000ABC0 5E                  <1> 	pop	esi  ; PATH_Array
   437 0000ABC1 5F                  <1> 	pop	edi  ; Dos Drv Description Table
   438                              <1> 
   439 0000ABC2 C3                  <1> 	retn
   440                              <1> 
   441                              <1> parse_dir_name:
   442                              <1> 	; 11/02/2016
   443                              <1> 	; 10/02/2016
   444                              <1> 	; 07/02/2016 (TRDOS 386 = TRDOS v2.0)
   445                              <1> 	; 18/09/2011
   446                              <1> 	; 17/10/2009
   447                              <1> 	; INPUT ->
   448                              <1> 	;	ESI = ASCIIZ Directory String Address
   449                              <1> 	;	AL = Current Directory Level
   450                              <1> 	;	EDI = Destination Adress
   451                              <1> 	;	     (8 levels, each one 12+4 byte)
   452                              <1> 	; OUTPUT ->
   453                              <1> 	;	EDI = Dir Entry Formatted Array
   454                              <1> 	;	     with zero cluster pointer at the last level
   455                              <1> 	;	AH = Last Dir Level
   456                              <1> 	;	AL = Current Dir Level
   457                              <1> 	;
   458                              <1> 	; (esi, ebx, ecx will be changed) 
   459                              <1> 
   460                              <1> 	;mov	[PATH_Array_Ptr], edi
   461 0000ABC3 88C4                <1> 	mov	ah, al
   462 0000ABC5 66A3[206D0100]      <1> 	mov	[PATH_CDLevel], ax
   463                              <1> repeat_ppdn_check_slash:
   464 0000ABCB AC                  <1> 	lodsb
   465 0000ABCC 3C2F                <1> 	cmp	al, '/'
   466 0000ABCE 74FB                <1> 	je	short repeat_ppdn_check_slash
   467 0000ABD0 3C21                <1> 	cmp	al, 21h
   468 0000ABD2 7219                <1> 	jb	short loc_ppdn_retn
   469 0000ABD4 57                  <1> 	push	edi
   470                              <1> loc_ppdn_get_dir_name:
   471 0000ABD5 B90C000000          <1> 	mov	ecx, 12
   472 0000ABDA BF[226D0100]        <1> 	mov	edi, Dir_File_Name
   473                              <1> repeat_ppdn_get_dir_name:
   474 0000ABDF AA                  <1> 	stosb
   475 0000ABE0 AC                  <1> 	lodsb
   476 0000ABE1 3C2F                <1> 	cmp	al, '/'
   477 0000ABE3 740A                <1> 	je	short loc_check_level_dot_conv_dir_name
   478 0000ABE5 3C20                <1> 	cmp	al, 20h
   479 0000ABE7 7605                <1> 	jna	short loc_ppdn_end_of_path_scan
   480 0000ABE9 E2F4                <1> 	loop	repeat_ppdn_get_dir_name
   481 0000ABEB 5F                  <1> 	pop	edi
   482 0000ABEC F9                  <1> 	stc
   483                              <1> loc_ppdn_retn:
   484 0000ABED C3                  <1> 	retn
   485                              <1> 
   486                              <1> loc_ppdn_end_of_path_scan:
   487 0000ABEE 4E                  <1> 	dec	esi
   488                              <1> loc_check_level_dot_conv_dir_name:
   489 0000ABEF 31C0                <1> 	xor	eax, eax
   490 0000ABF1 AA                  <1> 	stosb
   491 0000ABF2 89F3                <1> 	mov	ebx, esi
   492 0000ABF4 BE[226D0100]        <1> 	mov	esi, Dir_File_Name
   493 0000ABF9 AC                  <1> 	lodsb
   494                              <1> repeat_ppdn_name_check_dot:
   495 0000ABFA 3C2E                <1> 	cmp	al, '.'
   496 0000ABFC 7509                <1> 	jne	short loc_ppdn_convert_sub_dir_name
   497                              <1> repeat_ppdn_name_dot_dot:
   498 0000ABFE AC                  <1> 	lodsb
   499 0000ABFF 3C2E                <1> 	cmp	al, '.'
   500 0000AC01 743E                <1> 	je	short loc_ppdn_dot_dot
   501 0000AC03 3C21                <1> 	cmp	al, 21h
   502 0000AC05 7226                <1> 	jb	short pass_ppdn_convert_sub_dir_name
   503                              <1> loc_ppdn_convert_sub_dir_name:
   504 0000AC07 8A25[216D0100]      <1> 	mov	ah, [PATH_Level]
   505 0000AC0D 80FC07              <1> 	cmp	ah, 7
   506 0000AC10 731B                <1> 	jnb	short pass_ppdn_convert_sub_dir_name
   507 0000AC12 FEC4                <1> 	inc	ah  
   508 0000AC14 8825[216D0100]      <1> 	mov	[PATH_Level], ah
   509 0000AC1A BE[226D0100]        <1> 	mov	esi, Dir_File_Name
   510                              <1> 	;mov	edi, [PATH_Array_Ptr]
   511 0000AC1F B010                <1> 	mov	al, 16
   512 0000AC21 F6E4                <1> 	mul	ah
   513 0000AC23 8B3C24              <1> 	mov	edi, [esp]
   514                              <1> 	;push	edi 
   515 0000AC26 01C7                <1> 	add	edi, eax
   516 0000AC28 E82A030000          <1> 	call	convert_file_name
   517                              <1> 	;pop	edi
   518                              <1> pass_ppdn_convert_sub_dir_name:
   519 0000AC2D 89DE                <1> 	mov	esi, ebx
   520                              <1> repeat_ppdn_check_last_slash:
   521 0000AC2F AC                  <1> 	lodsb
   522 0000AC30 3C2F                <1> 	cmp	al, '/'
   523 0000AC32 74FB                <1> 	je	short repeat_ppdn_check_last_slash
   524 0000AC34 3C21                <1> 	cmp	al, 21h
   525 0000AC36 739D                <1> 	jnb	short loc_ppdn_get_dir_name
   526                              <1> end_of_parse_dir_name:
   527 0000AC38 5F                  <1> 	pop	edi
   528 0000AC39 F5                  <1> 	cmc  
   529                              <1> 	;mov	al, [PATH_CDLevel]
   530                              <1> 	;mov	ah, [PATH_Level]
   531 0000AC3A 66A1[206D0100]      <1> 	mov	ax, [PATH_CDLevel]
   532 0000AC40 C3                  <1> 	retn
   533                              <1> 
   534                              <1> loc_ppdn_dot_dot:
   535 0000AC41 AC                  <1> 	lodsb
   536 0000AC42 3C21                <1> 	cmp	al, 21h
   537 0000AC44 73F2                <1> 	jnb	short end_of_parse_dir_name 
   538                              <1> loc_ppdn_dot_dot_prev_level:
   539 0000AC46 66A1[206D0100]      <1> 	mov	ax, [PATH_CDLevel]
   540 0000AC4C 80EC01              <1> 	sub	ah, 1
   541 0000AC4F 80D400              <1> 	adc	ah, 0
   542 0000AC52 38E0                <1> 	cmp	al, ah
   543 0000AC54 7602                <1> 	jna	short pass_ppdn_set_al_to_ah
   544 0000AC56 88E0                <1> 	mov	al, ah
   545                              <1> pass_ppdn_set_al_to_ah:
   546 0000AC58 66A3[206D0100]      <1> 	mov	[PATH_CDLevel], ax
   547 0000AC5E EBCD                <1> 	jmp	short pass_ppdn_convert_sub_dir_name
   548                              <1> 
   549                              <1> locate_current_dir_file:
   550                              <1> 	; 20/11/2017
   551                              <1> 	; 14/02/2016
   552                              <1> 	; 13/02/2016
   553                              <1> 	; 10/02/2016
   554                              <1> 	; 06/02/2016 (TRDOS 386 = TRDOS v2.0)
   555                              <1> 	; 14/08/2010
   556                              <1> 	; 19/09/2009
   557                              <1>         ; 2005
   558                              <1> 	; INPUT ->
   559                              <1> 	;	ESI = DOS DirEntry Format FileName Address
   560                              <1> 	;	AL = Attributes Mask 
   561                              <1> 	;	(<AL AND EntryAttrib> must be equal to AL)
   562                              <1> 	;	AH = Negative Attributes Mask (If AH>0)
   563                              <1> 	;	(<AH AND EntryAttrib> must be ZERO)
   564                              <1> 	;	CH > 0 Find First Free Dir Entry or Deleted Entry
   565                              <1> 	;	CL = 0 -> Return the First Free Dir Entry
   566                              <1> 	;	CL = E5h -> Return the 1st deleted entry
   567                              <1> 	;	CL = FFh -> Return the 1st deleted or free entry
   568                              <1> 	;	CL > 0 and CL <> E5h and CL <> FFh -> Return the first 
   569                              <1> 	;	     proper entry (which fits with Atributes Masks)
   570                              <1> 	;	CX = 0 Find Valid File/Directory/VolumeName
   571                              <1> 	;	? = Any One Char
   572                              <1> 	;	* = Every Chars
   573                              <1> 	; OUTPUT ->
   574                              <1> 	;	EDI = Directory Entry Address (in Directory Buffer)
   575                              <1> 	;	ESI = DOS DirEntry Format FileName Address
   576                              <1> 	;	CF = 0 -> No Error, Proper Entry,
   577                              <1> 	;	DL = Attributes
   578                              <1> 	;	DH = Previous Entry Attr (LongName Check)
   579                              <1> 	;	AL > 0 -> Ambiguous filename wildcard "?" used
   580                              <1> 	;	AH > 0 -> Ambiguous filename wildcard "*" used
   581                              <1> 	;	AX = 0 -> Filename full fits with directory entry
   582                              <1> 	;	CH = The 1st Name Char of Current Dir Entry
   583                              <1> 	;	CF = 1 -> Proper entry not found, Error Code in EAX/AL
   584                              <1> 	;	CL = 0 and CH = 0 -> Free Entry (End Of Dir)
   585                              <1> 	;	CL = 0 and CH = E5h -> Deleted Entry fits with filters
   586                              <1> 	;	CL > 0 -> Entry not found, CH invalid
   587                              <1> 	;	CF = 0 -> 
   588                              <1> 	;	EBX = Current Directory Entry Index/Number (BX)
   589                              <1> 
   590                              <1> 	;mov	word [DirBuff_EntryCounter], 0 ; Zero Based
   591                              <1> 
   592 0000AC60 8935[836C0100]      <1> 	mov	[CDLF_FNAddress], esi
   593 0000AC66 66A3[816C0100]      <1> 	mov	[CDLF_AttributesMask], ax
   594 0000AC6C 66890D[876C0100]    <1> 	mov	[CDLF_DEType], cx
   595                              <1> 
   596 0000AC73 31DB                <1> 	xor	ebx, ebx
   597 0000AC75 881D[986C0100]      <1> 	mov	[PreviousAttr], bl ; 0  ; 13/02/2016
   598                              <1> 
   599 0000AC7B 8A3D[9E640100]      <1> 	mov	bh, [Current_Drv]
   600 0000AC81 381D[C46B0100]      <1> 	cmp	byte [DirBuff_ValidData], bl ; 0
   601 0000AC87 761D                <1> 	jna	short loc_lcdf_reload_current_dir2
   602 0000AC89 8A1D[C26B0100]      <1>         mov     bl, [DirBuff_DRV]
   603 0000AC8F 80EB41              <1> 	sub	bl, 'A'
   604 0000AC92 38DF                <1> 	cmp	bh, bl
   605 0000AC94 750E                <1> 	jne	short loc_lcdf_reload_current_dir1
   606 0000AC96 8B15[C96B0100]      <1> 	mov	edx, [DirBuff_Cluster]
   607 0000AC9C 3B15[98640100]      <1> 	cmp	edx, [Current_Dir_FCluster]
   608 0000ACA2 7412                <1> 	je	short loc_cdir_locatefile_search
   609                              <1> 
   610                              <1> loc_lcdf_reload_current_dir1:
   611 0000ACA4 30DB                <1> 	xor	bl, bl
   612                              <1> loc_lcdf_reload_current_dir2:
   613 0000ACA6 89DE                <1> 	mov	esi, ebx
   614 0000ACA8 81C600010900        <1>         add     esi, Logical_DOSDisks
   615 0000ACAE E874000000          <1> 	call	reload_current_directory 
   616 0000ACB3 735D                <1> 	jnc	short loc_locatefile_search_again 
   617 0000ACB5 C3                  <1> 	retn  
   618                              <1> 
   619                              <1> loc_cdir_locatefile_search:
   620 0000ACB6 31DB                <1> 	xor	ebx, ebx
   621 0000ACB8 55                  <1> 	push	ebp ; 20/11/2017
   622 0000ACB9 E8A6000000          <1> 	call	find_directory_entry
   623 0000ACBE 5D                  <1> 	pop	ebp ; 20/11/2017
   624 0000ACBF 7349                <1> 	jnc	short loc_cdir_locate_file_retn
   625                              <1> 
   626                              <1> loc_locatefile_check_stc_reason:
   627 0000ACC1 08ED                <1> 	or	ch, ch
   628 0000ACC3 7444                <1> 	jz	short loc_cdir_locate_file_stc_retn
   629                              <1> 
   630                              <1> loc_locatefile_check_next_entryblock:
   631 0000ACC5 8A3D[9E640100]      <1> 	mov	bh, [Current_Drv]
   632 0000ACCB 28DB                <1> 	sub	bl, bl
   633 0000ACCD 0FB7F3              <1> 	movzx	esi, bx
   634 0000ACD0 81C600010900        <1>         add     esi, Logical_DOSDisks
   635                              <1> 
   636 0000ACD6 803D[9C640100]00    <1> 	cmp	byte [Current_Dir_Level], 0
   637 0000ACDD 760A                <1> 	jna	short loc_locatefile_check_FAT_type
   638                              <1>             
   639 0000ACDF 803D[9D640100]01    <1> 	cmp	byte [Current_FATType], 1
   640 0000ACE6 730A                <1> 	jnb	short loc_locatefile_load_subdir_cluster
   641 0000ACE8 C3                  <1> 	retn  
   642                              <1> 
   643                              <1> loc_locatefile_check_FAT_type:
   644 0000ACE9 803D[9D640100]03    <1> 	cmp	byte [Current_FATType], 3
   645 0000ACF0 7218                <1> 	jb	short loc_cdir_locate_file_retn
   646                              <1> 
   647                              <1> loc_locatefile_load_subdir_cluster:
   648 0000ACF2 A1[C96B0100]        <1> 	mov	eax, [DirBuff_Cluster]
   649 0000ACF7 E83A1A0000          <1> 	call	get_next_cluster
   650 0000ACFC 730D                <1> 	jnc	short loc_locatefile_next_cluster
   651 0000ACFE 09C0                <1> 	or	eax, eax
   652 0000AD00 7507                <1> 	jnz	short loc_locatefile_drive_not_ready_read_err
   653 0000AD02 F9                  <1> 	stc
   654                              <1> loc_locatefile_file_notfound:
   655 0000AD03 B802000000          <1> 	mov	eax, 2 ; File/Directory/VolName not found
   656 0000AD08 C3                  <1> 	retn
   657                              <1> 
   658                              <1> loc_locatefile_drive_not_ready_read_err:
   659                              <1> 	;mov	eax, 17 ;Drive not ready or read error
   660                              <1> loc_cdir_locate_file_stc_retn:
   661 0000AD09 F5                  <1> 	cmc ;stc
   662                              <1> loc_cdir_locate_file_retn:
   663 0000AD0A C3                  <1> 	retn
   664                              <1> 
   665                              <1> loc_locatefile_next_cluster:
   666 0000AD0B E80C1C0000          <1> 	call	load_FAT_sub_directory
   667                              <1> 	;jc	short loc_locatefile_drive_not_ready_read_err
   668 0000AD10 72F8                <1> 	jc	short loc_cdir_locate_file_retn 
   669                              <1> 
   670                              <1> loc_locatefile_search_again:
   671 0000AD12 8B35[836C0100]      <1> 	mov	esi, [CDLF_FNAddress] 
   672 0000AD18 66A1[816C0100]      <1> 	mov	ax, [CDLF_AttributesMask]
   673 0000AD1E 668B0D[876C0100]    <1> 	mov	cx, [CDLF_DEType] 
   674 0000AD25 EB8F                <1> 	jmp	short loc_cdir_locatefile_search
   675                              <1> 
   676                              <1> reload_current_directory:
   677                              <1> 	; 06/02/2016 (TRDOS 386 = TRDOS v2.0)
   678                              <1> 	; 13/06/2010
   679                              <1> 	; 22/09/2009
   680                              <1>         ;
   681                              <1> 	; INPUT ->
   682                              <1> 	;	ESI = Dos drive description table address
   683                              <1> 	
   684                              <1> 	;mov	al, [esi+LD_FATType]
   685 0000AD27 A0[9D640100]        <1> 	mov	al, [Current_FATType]
   686 0000AD2C 3C02                <1> 	cmp	al, 2
   687 0000AD2E 7729                <1> 	ja	short loc_reload_FAT_sub_directory
   688 0000AD30 8A25[9C640100]      <1> 	mov	ah, [Current_Dir_Level]
   689 0000AD36 08C0                <1> 	or	al, al
   690 0000AD38 740A                <1> 	jz	short loc_reload_FS_directory
   691 0000AD3A 08E4                <1> 	or	ah, ah
   692 0000AD3C 751B                <1> 	jnz	short loc_reload_FAT_sub_directory
   693                              <1> loc_reload_FAT_12_16_root_directory:
   694 0000AD3E E84E1B0000          <1> 	call	load_FAT_root_directory
   695 0000AD43 C3                  <1> 	retn
   696                              <1> loc_reload_FS_directory:
   697 0000AD44 20E4                <1> 	and	ah, ah
   698 0000AD46 7506                <1> 	jnz	short loc_reload_FS_sub_directory 
   699                              <1> loc_reload_FS_root_directory: 
   700 0000AD48 E80B1C0000          <1> 	call	load_FS_root_directory
   701 0000AD4D C3                  <1> 	retn
   702                              <1> loc_reload_FS_sub_directory:
   703 0000AD4E A1[98640100]        <1> 	mov	eax, [Current_Dir_FCluster]
   704 0000AD53 E8011C0000          <1> 	call	load_FS_sub_directory
   705 0000AD58 C3                  <1> 	retn 
   706                              <1> loc_reload_FAT_sub_directory:
   707 0000AD59 A1[98640100]        <1> 	mov	eax, [Current_Dir_FCluster]
   708 0000AD5E E8B91B0000          <1> 	call	load_FAT_sub_directory
   709 0000AD63 C3                  <1> 	retn
   710                              <1> 
   711                              <1> find_directory_entry:
   712                              <1> 	; 14/02/2016
   713                              <1> 	; 13/02/2016
   714                              <1> 	; 10/02/2016
   715                              <1> 	; 06/02/2016 (TRDOS 386 = TRDOS v2.0)
   716                              <1> 	; 14/08/2010 (DIR.ASM, "proc_find_direntry")
   717                              <1> 	; 19/09/2009
   718                              <1> 	; 2005
   719                              <1> 	; INPUT ->
   720                              <1> 	;	ESI = Sub Dir or File Name Address
   721                              <1> 	;	AL = Attributes Mask 
   722                              <1> 	;	(<AL AND EntryAttrib> must be equal to AL)
   723                              <1> 	;	AH = Negative Attributes Mask (If AH>0)
   724                              <1> 	;	(<AH AND EntryAttrib> must be ZERO)
   725                              <1> 	;	CH > 0 Find First Free Dir Entry or Deleted Entry
   726                              <1> 	;	CL = 0 -> Return the First Free Dir Entry
   727                              <1> 	;	CL = E5h -> Return the 1st deleted entry
   728                              <1> 	;	CL = FFh -> Return the 1st deleted or free entry
   729                              <1> 	;	CL > 0 and CL <> E5h and CL <> FFh -> Return the first 
   730                              <1> 	;            proper entry (which fits with Atributes Masks)
   731                              <1> 	;	CX = 0 -> Find Valid File/Directory/VolumeName
   732                              <1> 	;	? = Any One Char
   733                              <1> 	;	* = Every Chars
   734                              <1> 	;	EBX = Current Dir Entry (BX)
   735                              <1> 	;
   736                              <1> 	; OUTPUT -> 
   737                              <1> 	;	EDI = Directory Entry Address (in DirectoryBuffer)
   738                              <1> 	;	ESI = Sub Dir or File Name Address
   739                              <1> 	;	CF = 0 -> No Error, Proper Entry,
   740                              <1> 	;	DL = Attributes
   741                              <1> 	;	DH = Previous Entry Attr (LongName Check)
   742                              <1> 	;	AL > 0 -> Ambiguous filename wildcard "?" used
   743                              <1> 	;	AH > 0 -> Ambiguous filename wildcard "*" used
   744                              <1> 	;	AX = 0 -> Filename full fits with directory entry
   745                              <1> 	;	EBX = CurrentDirEntry (BX)
   746                              <1> 	;	CH = The 1st Name Char of Current Dir Entry
   747                              <1> 	;	CF = 1 -> Proper entry not found, Error Code in AX/AL
   748                              <1> 	;	CL = 0 and CH = 0 -> Free Entry (End Of Dir)
   749                              <1> 	;	CL = 0 and CH = E5h -> Deleted Entry fits with filters
   750                              <1> 	;	CL > 0 -> Entry not found, CH invalid
   751                              <1> 	;
   752                              <1> 	; (EAX, EBX, ECX, EDX, EDI, EBP will be changed)	 
   753                              <1> 
   754 0000AD64 663B1D[C76B0100]    <1> 	cmp	bx, [DirBuff_LastEntry]
   755 0000AD6B 0F8739010000        <1>         ja      loc_ffde_stc_retn_255
   756                              <1> 
   757                              <1> 	;mov    [DirBuff_CurrentEntry], bx  
   758                              <1> 
   759 0000AD71 BF00000800          <1>   	mov	edi, Directory_Buffer
   760 0000AD76 66A3[946C0100]      <1> 	mov	[FDE_AttrMask], ax
   761                              <1> 
   762 0000AD7C 29C0                <1> 	sub	eax, eax
   763                              <1>             
   764                              <1> 	;;mov	[PreviousAttr], al ; 0 ;; 13/02/2016
   765 0000AD7E 66A3[966C0100]      <1> 	mov	[AmbiguousFileName], ax ; 0
   766                              <1> 
   767 0000AD84 6689D8              <1> 	mov	ax, bx
   768 0000AD87 66C1E005            <1> 	shl	ax, 5 ; ; * 32 ; Directory entry size
   769 0000AD8B 01C7                <1> 	add     edi, eax
   770                              <1> 
   771 0000AD8D 08ED                <1> 	or	ch, ch
   772 0000AD8F 0F852C010000        <1>         jnz     loc_find_free_deleted_entry_0
   773                              <1> 
   774 0000AD95 08C9                <1> 	or      cl, cl
   775 0000AD97 0F850D010000        <1>         jnz     loc_ffde_stc_retn_255
   776                              <1>  
   777                              <1> check_find_dir_entry:
   778 0000AD9D 66A1[946C0100]      <1> 	mov	ax, [FDE_AttrMask]
   779 0000ADA3 8A2F                <1> 	mov	ch, [edi]
   780 0000ADA5 80FD00              <1> 	cmp     ch, 0 ; Is it never used entry?
   781 0000ADA8 0F86FF000000        <1> 	jna	loc_find_direntry_stc_retn 
   782 0000ADAE 56                  <1> 	push	esi
   783 0000ADAF 8A570B              <1> 	mov	dl, [edi+0Bh] ; File attributes
   784 0000ADB2 80FDE5              <1> 	cmp	ch, 0E5h ; Is it a deleted file?
   785 0000ADB5 746D                <1> 	je	short loc_find_dir_next_entry_prevdeleted
   786                              <1> 
   787 0000ADB7 80FA0F              <1> 	cmp     dl, 0Fh ; longname sub component check
   788 0000ADBA 7505                <1> 	jne     short loc_check_attributes_mask
   789 0000ADBC E8ED010000          <1> 	call	save_longname_sub_component
   790                              <1> 
   791                              <1> loc_check_attributes_mask:
   792 0000ADC1 88C6                <1> 	mov	dh, al
   793 0000ADC3 20D6                <1> 	and	dh, dl    
   794 0000ADC5 38F0                <1> 	cmp	al, dh
   795 0000ADC7 0F85BA000000        <1>         jne     loc_find_dir_next_entry
   796 0000ADCD 20D4                <1> 	and	ah, dl
   797 0000ADCF 0F85B2000000        <1>         jnz     loc_find_dir_next_entry
   798 0000ADD5 80FA0F              <1> 	cmp	dl, 0Fh
   799 0000ADD8 751A                <1> 	jne	short pass_direntry_attr_check
   800                              <1> 
   801 0000ADDA 3C0F                <1> 	cmp	al, 0Fh ; AL = 0Fh -> find long name
   802 0000ADDC 0F85A5000000        <1>         jne     loc_find_dir_next_entry
   803                              <1> 
   804 0000ADE2 5E                  <1> 	pop	esi
   805 0000ADE3 6631C0              <1> 	xor	ax, ax
   806 0000ADE6 8A35[986C0100]      <1> 	mov	dh, [PreviousAttr]
   807 0000ADEC 66891D[C56B0100]    <1> 	mov	[DirBuff_CurrentEntry], bx
   808 0000ADF3 C3                  <1> 	retn
   809                              <1> 
   810                              <1> pass_direntry_attr_check:
   811 0000ADF4 89FD                <1> 	mov	ebp, edi ; 14/02/2016
   812 0000ADF6 B908000000          <1> 	mov	ecx, 8
   813                              <1> loc_lodsb_find_dir:
   814 0000ADFB AC                  <1> 	lodsb
   815 0000ADFC 3C2A                <1> 	cmp	al, '*'
   816 0000ADFE 7508                <1> 	jne	short pass_fde_ambiguous1_check
   817 0000AE00 FE05[976C0100]      <1>         inc     byte [AmbiguousFileName+1]
   818 0000AE06 EB28                <1> 	jmp	short loc_check_direntry_extension
   819                              <1> 
   820                              <1> pass_fde_ambiguous1_check:
   821 0000AE08 3C3F                <1> 	cmp	al, '?'
   822 0000AE0A 750D                <1> 	jne	short pass_fde_ambiguous2_check
   823 0000AE0C FE05[966C0100]      <1> 	inc	byte [AmbiguousFileName]
   824 0000AE12 803F20              <1> 	cmp	byte [edi], 20h
   825 0000AE15 764E                <1> 	jna	short loc_find_dir_next_entry_ebp
   826 0000AE17 EB14                <1> 	jmp	short loc_scasb_find_dir_inc_di
   827                              <1> 
   828                              <1> pass_fde_ambiguous2_check:
   829 0000AE19 3C20                <1> 	cmp	al, 20h
   830 0000AE1B 750C                <1> 	jne	short loc_scasb_find_dir
   831 0000AE1D 803F20              <1> 	cmp	byte [edi], 20h
   832 0000AE20 7543                <1> 	jne	short loc_find_dir_next_entry_ebp
   833 0000AE22 EB0C                <1> 	jmp	short loc_check_direntry_extension
   834                              <1> 
   835                              <1> loc_find_dir_next_entry_prevdeleted:
   836 0000AE24 80CA80              <1> 	or	dl, 80h  ; Bit 7 -> deleted entry sign
   837 0000AE27 EB5E                <1> 	jmp	short loc_find_dir_next_entry
   838                              <1> 
   839                              <1> loc_scasb_find_dir:
   840 0000AE29 3A07                <1> 	cmp	al, [edi]
   841 0000AE2B 7538                <1> 	jne	short loc_find_dir_next_entry_ebp
   842                              <1> loc_scasb_find_dir_inc_di:
   843 0000AE2D 47                  <1> 	inc	edi
   844 0000AE2E E2CB                <1> 	loop	loc_lodsb_find_dir
   845                              <1> 
   846                              <1> loc_check_direntry_extension:
   847 0000AE30 BE08000000          <1> 	mov	esi, 8
   848 0000AE35 89F7                <1> 	mov	edi, esi ; 8
   849 0000AE37 033424              <1> 	add	esi, [esp] ; Sub Dir or File Name Address
   850 0000AE3A 01EF                <1> 	add	edi, ebp
   851 0000AE3C B103                <1> 	mov	cl, 3
   852                              <1> loc_lodsb_find_dir_ext:
   853 0000AE3E AC                  <1> 	lodsb
   854 0000AE3F 3C2A                <1> 	cmp	al, '*'
   855 0000AE41 7508                <1> 	jne	short pass_fde_ambiguous3_check
   856 0000AE43 FE05[976C0100]      <1> 	inc	byte [AmbiguousFileName+1]
   857 0000AE49 EB1E                <1> 	jmp	short loc_find_dir_proper_direntry
   858                              <1> 
   859                              <1> pass_fde_ambiguous3_check:
   860 0000AE4B 3C3F                <1> 	cmp	al, '?'
   861 0000AE4D 750D                <1> 	jne	short pass_fde_ambiguous4_check
   862 0000AE4F FE05[966C0100]      <1> 	inc	byte [AmbiguousFileName]
   863 0000AE55 803F20              <1> 	cmp	byte [edi], 20h
   864 0000AE58 760B                <1> 	jna	short loc_find_dir_next_entry_ebp
   865 0000AE5A EB49                <1> 	jmp	short loc_scasb_find_dir_ext_inc_di
   866                              <1> 
   867                              <1> pass_fde_ambiguous4_check:
   868 0000AE5C 3C20                <1> 	cmp	al, 20h
   869 0000AE5E 7541                <1> 	jne	short loc_scasb_find_dir_ext
   870 0000AE60 803F20              <1> 	cmp	byte [edi], 20h
   871 0000AE63 7404                <1> 	je	short loc_find_dir_proper_direntry
   872                              <1> 
   873                              <1> loc_find_dir_next_entry_ebp:
   874 0000AE65 89EF                <1> 	mov	edi, ebp ; 14/02/2016
   875 0000AE67 EB1E                <1> 	jmp	short loc_find_dir_next_entry
   876                              <1> 
   877                              <1> loc_find_dir_proper_direntry:
   878 0000AE69 30C9                <1> 	xor	cl, cl
   879                              <1> loc_find_dir_proper_direntry_1:
   880 0000AE6B 5E                  <1> 	pop	esi
   881 0000AE6C 89EF                <1>         mov     edi, ebp
   882 0000AE6E 8A2F                <1> 	mov	ch, [edi]
   883 0000AE70 8A570B              <1> 	mov     dl, [edi+0Bh] ; Dir entry attributes
   884 0000AE73 66A1[966C0100]      <1> 	mov	ax, [AmbiguousFileName]
   885                              <1> loc_find_dir_proper_direntry_2:
   886 0000AE79 8A35[986C0100]      <1> 	mov     dh, [PreviousAttr]
   887 0000AE7F 66891D[C56B0100]    <1> 	mov	[DirBuff_CurrentEntry], bx
   888 0000AE86 C3                  <1> 	retn
   889                              <1> 
   890                              <1> loc_find_dir_next_entry:
   891 0000AE87 8815[986C0100]      <1> 	mov	byte [PreviousAttr], dl ; LongName check
   892                              <1> loc_find_dir_next_entry_1:
   893 0000AE8D 5E                  <1> 	pop	esi
   894 0000AE8E 83C720              <1> 	add	edi, 32
   895                              <1> 	;inc	word [DirBuff_EntryCounter]
   896 0000AE91 6643                <1> 	inc	bx
   897 0000AE93 663B1D[C76B0100]    <1> 	cmp	bx, [DirBuff_LastEntry]
   898 0000AE9A 770E                <1> 	ja	short loc_ffde_stc_retn_255
   899 0000AE9C E9FCFEFFFF          <1>         jmp     check_find_dir_entry 
   900                              <1> 
   901                              <1> loc_scasb_find_dir_ext:
   902 0000AEA1 3A07                <1> 	cmp	al, [edi]
   903 0000AEA3 75C0                <1> 	jne	short loc_find_dir_next_entry_ebp
   904                              <1> loc_scasb_find_dir_ext_inc_di:
   905 0000AEA5 47                  <1> 	inc	edi
   906 0000AEA6 E296                <1> 	loop    loc_lodsb_find_dir_ext
   907 0000AEA8 EBC1                <1> 	jmp	short loc_find_dir_proper_direntry_1
   908                              <1> 
   909                              <1> loc_ffde_stc_retn_255:
   910                              <1> 	;mov	cx, 0FFFFh
   911 0000AEAA 31C9                <1> 	xor	ecx, ecx
   912 0000AEAC 49                  <1> 	dec	ecx ; 0FFFFFFFFh
   913                              <1> 	;xor	eax, eax
   914                              <1> loc_find_direntry_stc_retn:
   915                              <1> loc_check_ffde_retn_1:
   916                              <1> 	;mov	ax, 2
   917 0000AEAD B802000000          <1> 	mov	eax, 2 ; File Not Found
   918 0000AEB2 8A35[986C0100]      <1> 	mov	dh, [PreviousAttr]
   919 0000AEB8 66891D[C56B0100]    <1> 	mov	[DirBuff_CurrentEntry], bx
   920 0000AEBF F9                  <1> 	stc
   921 0000AEC0 C3                  <1> 	retn
   922                              <1> 
   923                              <1> loc_find_free_deleted_entry_0:
   924 0000AEC1 66A1[946C0100]      <1> 	mov	ax, [FDE_AttrMask]
   925 0000AEC7 8A2F                <1> 	mov	ch, [edi]
   926 0000AEC9 8A570B              <1> 	mov	dl, [edi+0Bh] ; File attributes
   927 0000AECC 08C9                <1> 	or	cl, cl 
   928 0000AECE 7407                <1> 	jz	short loc_check_ffde_0_repeat
   929                              <1> 	;cmp	cl, 0E5h
   930                              <1> 	;je	short pass_loc_check_ffde_0_err
   931 0000AED0 80F9FF              <1> 	cmp	cl, 0FFh
   932 0000AED3 7432                <1> 	je	short loc_find_free_deleted_entry_1
   933 0000AED5 EB4D                <1> 	jmp	short pass_loc_check_ffde_0_err
   934                              <1> 
   935                              <1> loc_check_ffde_0_repeat:
   936 0000AED7 08ED                <1> 	or	ch, ch
   937 0000AED9 7511                <1> 	jnz	short loc_check_ffde_0_next
   938                              <1> 
   939                              <1> loc_check_ffde_retn_2:
   940 0000AEDB 6629C0              <1> 	sub	ax, ax
   941 0000AEDE 8A35[986C0100]      <1> 	mov	dh, [PreviousAttr]
   942 0000AEE4 66891D[C56B0100]    <1> 	mov	[DirBuff_CurrentEntry], bx
   943 0000AEEB C3                  <1> 	retn
   944                              <1>  
   945                              <1> loc_check_ffde_0_next:
   946 0000AEEC 6643                <1> 	inc	bx
   947 0000AEEE 83C720              <1> 	add	edi, 32
   948                              <1> 	;inc	word [DirBuff_EntryCounter]
   949                              <1> 	 
   950 0000AEF1 663B1D[C76B0100]    <1>         cmp	bx, [DirBuff_LastEntry]
   951 0000AEF8 77B0                <1> 	ja	short loc_ffde_stc_retn_255
   952 0000AEFA 8815[986C0100]      <1> 	mov	[PreviousAttr], dl
   953 0000AF00 8A2F                <1> 	mov	ch, [edi]
   954 0000AF02 8A570B              <1> 	mov	dl, [edi+0Bh] ; file attributes
   955 0000AF05 EBD0                <1> 	jmp	short loc_check_ffde_0_repeat
   956                              <1> 
   957                              <1> loc_find_free_deleted_entry_1:
   958 0000AF07 28D2                <1> 	sub	dl, dl      
   959                              <1> loc_find_free_deleted_entry_2:
   960 0000AF09 20ED                <1> 	and	ch, ch  
   961 0000AF0B 74CE                <1> 	jz	short loc_check_ffde_retn_2
   962 0000AF0D 80FDE5              <1> 	cmp	ch, 0E5h
   963 0000AF10 74C9                <1> 	je	short loc_check_ffde_retn_2
   964 0000AF12 6643                <1> 	inc	bx
   965 0000AF14 83C720              <1> 	add	edi, 32
   966 0000AF17 663B1D[C76B0100]    <1> 	cmp	bx, [DirBuff_LastEntry]
   967 0000AF1E 778A                <1> 	ja	short loc_ffde_stc_retn_255
   968 0000AF20 8A2F                <1> 	mov	ch, [edi]
   969 0000AF22 EBE5                <1> 	jmp	short loc_find_free_deleted_entry_2
   970                              <1> 
   971                              <1> pass_loc_check_ffde_0_err:
   972 0000AF24 38CD                <1> 	cmp	ch, cl
   973 0000AF26 741F                <1> 	je	short loc_check_ffde_attrib 
   974                              <1> 
   975 0000AF28 6643                <1> 	inc	bx
   976 0000AF2A 83C720              <1> 	add	edi, 32
   977 0000AF2D 663B1D[C76B0100]    <1> 	cmp	bx, [DirBuff_LastEntry]
   978 0000AF34 0F8770FFFFFF        <1>         ja      loc_ffde_stc_retn_255
   979 0000AF3A 8815[986C0100]      <1> 	mov	[PreviousAttr], dl
   980 0000AF40 8A2F                <1> 	mov	ch, [edi]
   981 0000AF42 8A570B              <1> 	mov	dl, [edi+0Bh]
   982 0000AF45 EBDD                <1> 	jmp	short pass_loc_check_ffde_0_err
   983                              <1> 
   984                              <1> loc_check_ffde_attrib:
   985 0000AF47 88C6                <1> 	mov	dh, al
   986 0000AF49 20D6                <1> 	and	dh, dl    
   987 0000AF4B 38F0                <1> 	cmp	al, dh
   988 0000AF4D 759D                <1> 	jne	short loc_check_ffde_0_next
   989 0000AF4F 20D4                <1> 	and	ah, dl
   990 0000AF51 7599                <1> 	jnz	short loc_check_ffde_0_next
   991 0000AF53 30C9                <1> 	xor	cl, cl 
   992 0000AF55 EB84                <1>         jmp     loc_check_ffde_retn_2
   993                              <1> 
   994                              <1> convert_file_name:
   995                              <1> 	; 06/03/2016
   996                              <1> 	; 11/02/2016
   997                              <1> 	; 07/02/2016 (TRDOS 386 = TRDOS v2.0)
   998                              <1> 	; 06/10/2009
   999                              <1> 	; 2005
  1000                              <1> 	;
  1001                              <1> 	; INPUT  ->
  1002                              <1> 	;	ESI = Dot File Name Location
  1003                              <1> 	;	EDI = Dir Entry Format File Name Location
  1004                              <1> 	; OUTPUT ->
  1005                              <1> 	;	EDI = Dir Entry Format File Name Location
  1006                              <1> 	;	ESI = Dot File Name Location (capitalized)
  1007                              <1> 	;
  1008                              <1> 	; (ECX, AL will be changed) 
  1009                              <1>      
  1010 0000AF57 56                  <1> 	push	esi  
  1011 0000AF58 57                  <1> 	push	edi
  1012                              <1> 
  1013 0000AF59 B90B000000          <1> 	mov	ecx, 11
  1014 0000AF5E B020                <1> 	mov	al, 20h
  1015 0000AF60 F3AA                <1> 	rep	stosb
  1016                              <1> 
  1017 0000AF62 8B3C24              <1> 	mov	edi, [esp]
  1018                              <1> 
  1019 0000AF65 B10C                <1> 	mov	cl, 12 ; file name length (max.)
  1020                              <1> 	; 06/03/2016
  1021                              <1> 	; Directory entry name limit (11 bytes) check for
  1022                              <1> 	; 'rename_directory_entry' procedure.
  1023                              <1> 	; (EDI points to Directory Entry)
  1024                              <1> 	; (If the file name would not contain a dot
  1025                              <1> 	; and file name length would be 12, this would cause to
  1026                              <1> 	; overwrite the attributes byte of the directory entry.)
  1027                              <1> 	;
  1028 0000AF67 B50B                <1> 	mov	ch, 11 ; directory entry's name length
  1029                              <1> loc_check_first_dot:
  1030 0000AF69 8A06                <1> 	mov	al, [esi]
  1031 0000AF6B 3C2E                <1> 	cmp	al, 2Eh
  1032 0000AF6D 750C                <1> 	jne	short pass_check_first_dot
  1033 0000AF6F 8807                <1> 	mov	[edi], al
  1034 0000AF71 47                  <1> 	inc	edi
  1035 0000AF72 46                  <1> 	inc	esi
  1036 0000AF73 FEC9                <1> 	dec	cl
  1037 0000AF75 75F2                <1> 	jnz	short loc_check_first_dot
  1038                              <1> 	;;(ecx <= 12)
  1039                              <1> 	;;loop	loc_check_first_dot 
  1040 0000AF77 EB30                <1> 	jmp	short stop_convert_file
  1041                              <1> 
  1042                              <1> loc_get_fchar:
  1043 0000AF79 8A06                <1> 	mov	al, [esi]
  1044                              <1> pass_check_first_dot:
  1045 0000AF7B 3C61                <1> 	cmp	al, 61h ; 'a'
  1046 0000AF7D 7208                <1> 	jb	short pass_name_capitalize
  1047 0000AF7F 3C7A                <1> 	cmp	al, 7Ah ; 'z'
  1048 0000AF81 7704                <1> 	ja	short pass_name_capitalize
  1049 0000AF83 24DF                <1> 	and	al, 0DFh
  1050 0000AF85 8806                <1> 	mov	[esi], al
  1051                              <1> pass_name_capitalize:
  1052 0000AF87 3C21                <1> 	cmp	al, 21h
  1053 0000AF89 721E                <1> 	jb	short stop_convert_file
  1054 0000AF8B 3C2E                <1> 	cmp	al, 2Eh ; '.'
  1055 0000AF8D 750C                <1> 	jne	short pass_dot_space
  1056                              <1> add_dot_space: 
  1057 0000AF8F 80F904              <1> 	cmp	cl, 4
  1058 0000AF92 760E                <1> 	jna	short inc_and_loop
  1059 0000AF94 47                  <1> 	inc	edi
  1060 0000AF95 FECD                <1> 	dec	ch ; 06/03/2016
  1061 0000AF97 FEC9                <1> 	dec	cl
  1062 0000AF99 EBF4                <1> 	jmp	short add_dot_space
  1063                              <1> 	
  1064                              <1> 	;mov	al, 4
  1065                              <1> 	;cmp	cl, al
  1066                              <1> 	;jna	short inc_and_loop
  1067                              <1> 	;sub	cl, al
  1068                              <1> 	;add	edi, ecx
  1069                              <1> 	;mov	cl, al
  1070                              <1> 	;jmp	short inc_and_loop	
  1071                              <1> 
  1072                              <1> pass_dot_space:
  1073 0000AF9B 8807                <1> 	mov	[edi], al
  1074                              <1> loc_after_double_dot:
  1075                              <1> 	; 06/03/2016
  1076 0000AF9D FECD                <1> 	dec	ch ; count down for 11 bytes dir entry limit
  1077 0000AF9F 740A                <1> 	jz	short stop_convert_file_x
  1078 0000AFA1 47                  <1> 	inc	edi
  1079                              <1> inc_and_loop:
  1080 0000AFA2 FEC9                <1> 	dec	cl ; count down for 12 bytes filename limit 
  1081 0000AFA4 7403                <1> 	jz	short stop_convert_file	
  1082 0000AFA6 46                  <1> 	inc	esi
  1083                              <1> 	;;(ecx <= 12)
  1084                              <1> 	;;loop	loc_get_fchar
  1085 0000AFA7 EBD0                <1> 	jmp	short loc_get_fchar
  1086                              <1> 
  1087                              <1> stop_convert_file:
  1088                              <1> 	; 06/03/2016
  1089 0000AFA9 30ED                <1> 	xor	ch, ch
  1090                              <1> 	; ECX < 256 ; 'find_first_file' -> xor cl, cl
  1091                              <1> stop_convert_file_x:
  1092 0000AFAB 5F                  <1> 	pop	edi
  1093 0000AFAC 5E                  <1> 	pop	esi
  1094 0000AFAD C3                  <1> 	retn
  1095                              <1>  
  1096                              <1> save_longname_sub_component:
  1097                              <1> 	; 13/02/2016
  1098                              <1> 	; 06/02/2016 (TRDOS 386 = TRDOS v2.0)
  1099                              <1> 	; 28/02/2010
  1100                              <1> 	; 17/10/2009
  1101                              <1> 	; INPUT ->
  1102                              <1> 	;	EDI = Directory Entry    
  1103                              <1> 	;     	// This procedure is called
  1104                              <1> 	;	// from 'find_directory_entry' procedure.
  1105                              <1> 	;	// If the last entry returns with
  1106                              <1> 	;	// a non-zero LongnameFound value and
  1107                              <1> 	;	// if LFN_CheckSum value is equal to
  1108                              <1> 	;	// the next shortname checksum,
  1109                              <1> 	;	// long name is valid.
  1110                              <1> 	;	// If a longname is longer than 65 bytes,
  1111                              <1> 	;	// it is invalid for trdos. (>45h)
  1112                              <1>  
  1113 0000AFAE 57                  <1> 	push	edi
  1114 0000AFAF 56                  <1> 	push	esi
  1115                              <1> 	;push	ebx
  1116                              <1> 	;push	ecx
  1117                              <1> 	;push	edx
  1118 0000AFB0 50                  <1> 	push	eax
  1119                              <1>            
  1120 0000AFB1 29C9                <1> 	sub	ecx, ecx
  1121                              <1> 	;sub	eax, eax
  1122 0000AFB3 B11A                <1> 	mov	cl, 26
  1123                              <1> 
  1124 0000AFB5 0FB607              <1> 	movzx	eax, byte [edi] ; LDIR_Order
  1125 0000AFB8 3C41                <1> 	cmp	al, 41h  ; 40h (last long entry sign) + 1
  1126 0000AFBA 722B                <1> 	jb	short pass_pslnsc_last_long_entry
  1127                              <1> 
  1128 0000AFBC 88C4                <1> 	mov	ah, al
  1129 0000AFBE 80EC40              <1> 	sub	ah, 40h
  1130 0000AFC1 8825[9A6C0100]      <1> 	mov	[LFN_EntryLength], ah
  1131                              <1> 	
  1132 0000AFC7 3C45                <1> 	cmp	al, 45h  ; 40h (last long entry sign) + 5
  1133                              <1>  		; Max 130 byte length is usable in TRDOS
  1134                              <1> ; 26*5 = 130
  1135 0000AFC9 7753                <1> 	ja	short loc_pslnsc_retn
  1136                              <1> 
  1137 0000AFCB 2407                <1> 	and	al, 07h ; 0Fh
  1138 0000AFCD A2[996C0100]        <1> 	mov	[LongNameFound], al
  1139                              <1> 
  1140 0000AFD2 FEC8                <1> 	dec	al
  1141                              <1> 	;mov	cl, 26
  1142 0000AFD4 F6E1                <1> 	mul	cl
  1143                              <1> 
  1144 0000AFD6 89C6                <1> 	mov	esi, eax
  1145 0000AFD8 01CE                <1> 	add	esi, ecx
  1146                              <1> 		; to make is an ASCIIZ string
  1147                              <1> 		; with ax+26 bytes length
  1148 0000AFDA 81C6[9C6C0100]      <1> 	add	esi, LongFileName
  1149 0000AFE0 66C7060000          <1> 	mov	word [esi], 0   
  1150 0000AFE5 EB16                <1> 	jmp	short loc_pslsc_move_ldir_name2 
  1151                              <1> 
  1152                              <1> pass_pslnsc_last_long_entry:
  1153 0000AFE7 3C04                <1> 	cmp	al, 04h
  1154 0000AFE9 7733                <1> 	ja	short loc_pslnsc_retn
  1155 0000AFEB FE0D[996C0100]      <1> 	dec	byte [LongNameFound]
  1156 0000AFF1 3A05[996C0100]      <1> 	cmp	al, [LongNameFound]
  1157 0000AFF7 7525                <1> 	jne	short loc_pslnsc_retn
  1158                              <1> 
  1159                              <1> loc_pslsc_move_ldir_name1:
  1160 0000AFF9 FEC8                <1> 	dec	al
  1161                              <1> 	;mov	cl, 26
  1162 0000AFFB F6E1                <1> 	mul	cl
  1163                              <1> 
  1164                              <1> loc_pslsc_move_ldir_name2:
  1165 0000AFFD 8A4F0D              <1> 	mov	cl, [edi+0Dh] ; long name checksum
  1166 0000B000 880D[9B6C0100]      <1> 	mov	[LFN_CheckSum], cl 
  1167 0000B006 89FE                <1> 	mov	esi, edi ; LDIR_Order
  1168 0000B008 BF[9C6C0100]        <1> 	mov	edi, LongFileName
  1169 0000B00D 01C7                <1> 	add	edi, eax
  1170 0000B00F 46                  <1> 	inc	esi
  1171 0000B010 B105                <1> 	mov	cl, 5 ; chars 1 to 5
  1172 0000B012 F366A5              <1> 	rep	movsw
  1173 0000B015 83C603              <1> 	add	esi, 3
  1174 0000B018 A5                  <1> 	movsd	; char 6 & 7 
  1175 0000B019 A5                  <1> 	movsd	; char 8 & 9
  1176 0000B01A A5                  <1> 	movsd	; char 10 & 11
  1177 0000B01B 46                  <1> 	inc	esi
  1178 0000B01C 46                  <1> 	inc	esi 
  1179 0000B01D A5                  <1> 	movsd   ; char 12 & 13 
  1180                              <1> 
  1181                              <1> loc_pslnsc_retn:
  1182 0000B01E 58                  <1>  	pop	eax
  1183                              <1> 	;pop	edx
  1184                              <1> 	;pop	ecx
  1185                              <1> 	;pop	ebx
  1186 0000B01F 5E                  <1> 	pop	esi  
  1187 0000B020 5F                  <1> 	pop	edi
  1188                              <1>  
  1189 0000B021 C3                  <1>     	retn
  1190                              <1> 
  1191                              <1> parse_path_name:
  1192                              <1> 	; 10/02/2016
  1193                              <1> 	; 08/02/2016 (TRDOS 386 = TRDOS v2.0)
  1194                              <1> 	; 10/009/2011 ('proc_parse_pathname')
  1195                              <1> 	; 27/11/2009
  1196                              <1> 	; 05/12/2004
  1197                              <1> 	;
  1198                              <1> 	; INPUT ->
  1199                              <1> 	;	ESI = Beginning of ASCIIZ pathname string
  1200                              <1> 	;       EDI = Destination Address
  1201                              <1> 	;	      (which is TR-DOS FindFile data buffer)
  1202                              <1> 	; OUTPUT ->
  1203                              <1> 	;	CF = 1 -> Error
  1204                              <1> 	;	     EAX = Error Code (AL)
  1205                              <1> 	;
  1206                              <1> 	; (Modified registers: eax, ecx, esi, edi) 
  1207                              <1> 	
  1208                              <1> 	; Clear the pathname bytes in TR-DOS Findfile data buffer 
  1209 0000B022 57                  <1> 	push	edi
  1210 0000B023 B914000000          <1> 	mov	ecx, 20  ; 80 bytes
  1211 0000B028 31C0                <1> 	xor	eax, eax
  1212 0000B02A F3AB                <1> 	rep	stosd 
  1213 0000B02C 5F                  <1> 	pop	edi
  1214                              <1> 
  1215 0000B02D 668B06              <1> 	mov	ax, [esi]
  1216 0000B030 80FC3A              <1> 	cmp	ah, ':'
  1217 0000B033 741C                <1> 	je	short loc_ppn_change_drive
  1218 0000B035 A0[9E640100]        <1> 	mov	al, [Current_Drv]
  1219 0000B03A EB33                <1> 	jmp	short pass_ppn_change_drive
  1220                              <1> 
  1221                              <1> pass_ppn_cdir:
  1222 0000B03C 8B35[BE6D0100]      <1> 	mov	esi, [First_Path_Pos]
  1223 0000B042 AC                  <1> 	lodsb
  1224                              <1> loc_ppn_get_filename:
  1225 0000B043 83C741              <1> 	add	edi, 65 ; FindFile_Name location
  1226                              <1> 	; TRDOS Filename length must not be more than 12 bytes
  1227                              <1> 	;mov	ecx, 12
  1228 0000B046 B10C                <1> 	mov	cl, 12
  1229                              <1> loc_ppn_get_fnchar_next:
  1230 0000B048 AA                  <1> 	stosb
  1231 0000B049 AC                  <1> 	lodsb
  1232 0000B04A 3C21                <1> 	cmp	al, 21h
  1233 0000B04C 7274                <1> 	jb	short loc_ppn_clc_return 
  1234 0000B04E E2F8                <1>         loop    loc_ppn_get_fnchar_next
  1235                              <1> loc_ppn_return:
  1236 0000B050 C3                  <1> 	retn
  1237                              <1> 
  1238                              <1> loc_ppn_change_drive:
  1239 0000B051 24DF                <1> 	and	al, 0DFh
  1240 0000B053 2C41                <1> 	sub	al, 'A'; A:
  1241 0000B055 726F                <1> 	jc	short loc_ppn_invalid_drive
  1242 0000B057 3805[F5170100]      <1> 	cmp	[Last_DOS_DiskNo], al
  1243 0000B05D 7267                <1> 	jb	short loc_ppn_invalid_drive
  1244                              <1> 
  1245 0000B05F 46                  <1> 	inc	esi
  1246 0000B060 46                  <1> 	inc	esi
  1247 0000B061 8A26                <1> 	mov	ah, [esi]
  1248 0000B063 80FC21              <1> 	cmp	ah, 21h
  1249 0000B066 7307                <1> 	jnb	short pass_ppn_change_drive
  1250                              <1> 
  1251                              <1> loc_ppn_cmd_failed:
  1252                              <1> 	; File or directory name is not existing
  1253 0000B068 8807                <1> 	mov	[edi], al ; Drv 
  1254 0000B06A 66B80100            <1> 	mov	ax, 1 ; eax = 1
  1255                              <1> 	; TR-DOS Error Code 01h = Bad Command Argument
  1256                              <1> 	; MS-DOS Error Code 01h : Invalid Function Number
  1257                              <1> 	;stc
  1258                              <1> 	; (MainProg ErrMsg: "Bad command or file name!")
  1259 0000B06E C3                  <1> 	retn
  1260                              <1> 
  1261                              <1> pass_ppn_change_drive:
  1262 0000B06F 8935[BE6D0100]      <1> 	mov	[First_Path_Pos], esi
  1263 0000B075 C705[C26D0100]0000- <1> 	mov	dword [Last_Slash_Pos], 0
  1263 0000B07D 0000                <1>
  1264 0000B07F AA                  <1> 	stosb
  1265 0000B080 8A06                <1> 	mov	al, [esi]
  1266                              <1> loc_scan_ppn_dslash:
  1267 0000B082 3C2F                <1> 	cmp	al, '/'
  1268 0000B084 7506                <1>   	jne	short loc_scan_next_slash_pos
  1269 0000B086 8935[C26D0100]      <1> 	mov	[Last_Slash_Pos], esi
  1270                              <1> loc_scan_next_slash_pos:
  1271 0000B08C 46                  <1> 	inc	esi
  1272 0000B08D 8A06                <1> 	mov	al, [esi]
  1273 0000B08F 3C20                <1> 	cmp	al, 20h
  1274 0000B091 77EF                <1> 	ja	short loc_scan_ppn_dslash
  1275 0000B093 833D[C26D0100]00    <1> 	cmp	dword [Last_Slash_Pos], 0
  1276 0000B09A 76A0                <1> 	jna	short pass_ppn_cdir
  1277                              <1> 	
  1278 0000B09C 8B0D[C26D0100]      <1> 	mov	ecx, [Last_Slash_Pos]
  1279 0000B0A2 8B35[BE6D0100]      <1> 	mov	esi, [First_Path_Pos]
  1280 0000B0A8 29F1                <1> 	sub	ecx, esi
  1281 0000B0AA 41                  <1> 	inc	ecx
  1282                              <1> 	;cmp	ecx, 64
  1283 0000B0AB 80F940              <1> 	cmp	cl, 64
  1284 0000B0AE 7715                <1> 	ja	short loc_ppn_invalid_drive_stc
  1285                              <1> 
  1286 0000B0B0 89F8                <1> 	mov	eax, edi ; Dest Dir String Location (65 byte)
  1287 0000B0B2 F3A4                <1> 	rep	movsb
  1288                              <1> 	;mov	[edi], cl ; 0, End of Dir String
  1289 0000B0B4 8B35[C26D0100]      <1> 	mov	esi, [Last_Slash_Pos]
  1290 0000B0BA 46                  <1> 	inc	esi
  1291 0000B0BB 89C7                <1> 	mov	edi, eax
  1292 0000B0BD AC                  <1> 	lodsb
  1293 0000B0BE 3C21                <1> 	cmp	al, 21h
  1294 0000B0C0 7381                <1> 	jnb	short loc_ppn_get_filename
  1295                              <1> loc_ppn_clc_return:
  1296                              <1> 	;clc
  1297 0000B0C2 31C0                <1> 	xor	eax, eax
  1298 0000B0C4 C3                  <1> 	retn
  1299                              <1> 
  1300                              <1> loc_ppn_invalid_drive_stc:
  1301 0000B0C5 F5                  <1> 	cmc	 ; stc
  1302                              <1> loc_ppn_invalid_drive:
  1303                              <1> 	; cf = 1
  1304                              <1> 	; The Drive Letter/Char < "A" or > "Z"
  1305 0000B0C6 66B80F00            <1> 	mov	ax, 0Fh
  1306                              <1> 	; MS-DOS Error Code 0Fh = Disk Drive Invalid 
  1307                              <1> 	; (MainProg ErrMsg: "Drive not ready or read error!")
  1308 0000B0CA C3                  <1> 	retn
  1309                              <1> 
  1310                              <1> find_longname:
  1311                              <1> 	; 13/02/2016 (TRDOS 386 = TRDOS v2.0)
  1312                              <1> 	; 24/01/2010 (DIR.ASM, 'proc_find_longname')
  1313                              <1> 	; 17/10/2009
  1314                              <1> 	
  1315                              <1> 	; INPUT -> 
  1316                              <1> 	;	ESI = DOS short file name address
  1317                              <1> 	; 	for example: "filename.ext"
  1318                              <1> 	;
  1319                              <1> 	; OUTPUT ->
  1320                              <1> 	; 	ESI = ASCIIZ longname address (cf = 0)
  1321                              <1> 	;	cf = 1 -> error number returns in EAX (AL)
  1322                              <1> 	;	AL = 0 & CF=1 -> longname not found
  1323                              <1> 	;	     the file/directory has no longname
  1324                              <1> 	; 	cf = 0 -> AL = FAT Type 
  1325                              <1>  
  1326                              <1> 	; 17/10/2009
  1327                              <1> 	; ASCIIZ string will be returned
  1328                              <1> 	; as LongFileName
  1329                              <1> 	; clearing/reset is not needed
  1330                              <1> 	;mov	ecx, 33
  1331                              <1> 	;mov	edi, LongFileName
  1332                              <1> 	;sub	ax, ax ; 0
  1333                              <1> 	;rep	stosw
  1334                              <1> 
  1335                              <1> 	;mov	byte [LongNameFound], 0
  1336                              <1> 
  1337                              <1> 	; ESI = ASCIIZ file/directory name address
  1338                              <1> 	;   AL = Attributes AND mask 
  1339                              <1> 	;	(Result of AND must be equal to AL)
  1340                              <1> 	;   AH = Negative attributes mask 
  1341                              <1> 	;	(Result of AND must be ZERO)
  1342 0000B0CB 66B80008            <1> 	mov	ax, 0800h 
  1343                              <1> 		; it must not be volume name or longname
  1344 0000B0CF E87DDDFFFF          <1> 	call	find_first_file
  1345 0000B0D4 7216                <1> 	jc	short loc_fln_retn
  1346                              <1>  
  1347                              <1> loc_fln_check_FAT_Type:
  1348 0000B0D6 803D[9D640100]01    <1> 	cmp	byte [Current_FATType], 1
  1349 0000B0DD 7306                <1> 	jnb	short loc_fln_check_longname_yes_sign
  1350                              <1> 
  1351 0000B0DF E839000000          <1> 	call	get_fs_longname
  1352 0000B0E4 C3                  <1> 	retn
  1353                              <1> 
  1354                              <1> loc_fln_check_longname_yes_sign:
  1355 0000B0E5 08FF                <1> 	or	bh, bh
  1356 0000B0E7 7504                <1> 	jnz	short loc_fln_check_longnamefound_number
  1357                              <1> loc_fln_longname_not_found_retn:
  1358 0000B0E9 31C0                <1> 	xor	eax, eax 
  1359                              <1> 	; cf = 1 & al = 0 -> longname not found
  1360 0000B0EB F9                  <1> 	stc
  1361                              <1> loc_fln_retn:
  1362 0000B0EC C3                  <1> 	retn
  1363                              <1> 
  1364                              <1> loc_fln_check_longnamefound_number:
  1365                              <1> 	; 'LongNameFound' is set by
  1366                              <1>         ; by 'save_longname_sub_component'
  1367                              <1> 	; which is called from
  1368                              <1> 	; 'find_directory_entry' 
  1369                              <1> 	; which is called from 
  1370                              <1> 	; 'find_first_file'
  1371                              <1> 	; It must 1 if the longname is valid
  1372 0000B0ED 803D[996C0100]01    <1>         cmp     byte [LongNameFound], 1
  1373 0000B0F4 75F3                <1> 	jne	short loc_fln_longname_not_found_retn
  1374                              <1>              
  1375                              <1> loc_fln_calculate_checksum: 
  1376 0000B0F6 E813000000          <1> 	call	calculate_checksum
  1377                              <1> 	; AL = shortname checksum
  1378                              <1> 
  1379                              <1> loc_fln_longname_validation:
  1380                              <1> 	; 'LFN_CheckSum' has been set already
  1381                              <1> 	; by 'save_longname_sub_component'
  1382                              <1> 	; which is called from
  1383                              <1> 	; 'find_directory_entry' 
  1384                              <1> 	; which is called from 
  1385                              <1> 	; 'find_first_file'
  1386 0000B0FB 3805[9B6C0100]      <1> 	cmp	[LFN_CheckSum], al
  1387 0000B101 75E6                <1> 	jne	short loc_fln_longname_not_found_retn
  1388                              <1> 
  1389 0000B103 BE[9C6C0100]        <1> 	mov	esi, LongFileName
  1390 0000B108 A0[9D640100]        <1> 	mov	al, [Current_FATType]
  1391 0000B10D C3                  <1> 	retn
  1392                              <1> 
  1393                              <1> calculate_checksum:
  1394                              <1> 	; 13/02/2016 (TRDOS 386 = TRDOS v2.0)
  1395                              <1> 	; 17/10/2009 (DIR.ASM, 'proc_calculate_checksum')
  1396                              <1>         ;    
  1397                              <1> 	; INPUT ->
  1398                              <1> 	;	ESI = 11 byte DOS File Name location
  1399                              <1> 	;	(in DOS Directory Entry Format)
  1400                              <1> 	; OUTPUT ->
  1401                              <1> 	;	 AL = 8 bit checksum (CRC) value
  1402                              <1> 	;
  1403                              <1> 	; (Modified registers: EAX, ECX, ESI)
  1404                              <1> 
  1405                              <1> 	; Erdogan Tan [ 17-10-2009 ]
  1406                              <1> 	;  'ror al, 1' instruction
  1407                              <1> 
  1408                              <1> 	; Erdogan Tan [ 20-06-2004 ]
  1409                              <1> 	; This 8086 assembly code is an original code
  1410                              <1> 	; which is adapted from C code in
  1411                              <1> 	; Microsoft FAT32 File System Specification
  1412                              <1> 	; Version 1.03, December 6, 2000
  1413                              <1> 	; Page 28
  1414                              <1> 
  1415 0000B10E 30C0                <1> 	xor	al, al
  1416 0000B110 B90B000000          <1> 	mov	ecx, 11
  1417                              <1> loc_next_sum:
  1418                              <1> 	;xor	ah, ah
  1419                              <1> 	;test	al, 1
  1420                              <1> 	;jz	short pass_ah_80h
  1421                              <1> 	;mov	ah, 80h
  1422                              <1> ;pass_ah_80h:
  1423                              <1> 	;shr	al, 1
  1424 0000B115 D0C8                <1> 	ror	al, 1 ; 17/10/2009  
  1425 0000B117 0206                <1> 	add	al, [esi]
  1426 0000B119 46                  <1> 	inc	esi
  1427                              <1> 	;add	al, ah
  1428 0000B11A E2F9                <1> 	loop	loc_next_sum
  1429 0000B11C C3                  <1> 	retn
  1430                              <1> 
  1431                              <1> get_fs_longname:
  1432                              <1> 	; temporary (13/02/2016)
  1433 0000B11D 31C0                <1> 	xor eax, eax
  1434 0000B11F F9                  <1> 	stc
  1435 0000B120 C3                  <1> 	retn
  1436                              <1> 
  1437                              <1> make_sub_directory:
  1438                              <1> 	; 16/10/2016
  1439                              <1> 	; 02/03/2016, 03/03/2016
  1440                              <1> 	; 26/02/2016, 27/02/2016
  1441                              <1> 	; 21/02/2016 (TRDOS 386 = TRDOS v2.0)
  1442                              <1> 	; 01/08/2011 (DIR.ASM, 'proc_make_directory')
  1443                              <1> 	; 10/07/2010
  1444                              <1> 	; INPUT ->
  1445                              <1> 	; 	ESI = ASCIIZ Directory Name
  1446                              <1> 	;	CL = Directory Attributes
  1447                              <1> 	; OUTPUT ->
  1448                              <1> 	;	EAX = New sub dir's first cluster
  1449                              <1> 	;	ESI = Logical Dos Drv Descr. Table Addr.
  1450                              <1> 	;	CF = 1 -> error code in AL (EAX)
  1451                              <1> 
  1452                              <1> 	;test	cl, 10h  ; directory
  1453                              <1> 	;jz	short loc_make_directory_access_denied
  1454                              <1> 	;test	cl, 08h ; volume name
  1455                              <1> 	;jnz	short loc_make_directory_access_denied
  1456                              <1> 
  1457 0000B121 80E107              <1> 	and	cl, 07h
  1458 0000B124 880D[186E0100]      <1> 	mov	byte [mkdir_attrib], cl
  1459                              <1> 
  1460 0000B12A 56                  <1> 	push	esi
  1461 0000B12B 31DB                <1> 	xor	ebx, ebx
  1462 0000B12D 8A3D[9E640100]      <1> 	mov	bh, [Current_Drv]
  1463 0000B133 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1464 0000B138 01DE                <1> 	add	esi, ebx
  1465 0000B13A 5B                  <1> 	pop	ebx
  1466                              <1> 
  1467                              <1> 	; 10/07/2010 -> 1st writable disk check for trdos
  1468                              <1> 	; LD_DiskType = 0 for write protection (read only) 
  1469 0000B13B 807E0101            <1> 	cmp	byte [esi+LD_DiskType], 1 ; 0 = Invalid
  1470 0000B13F 730B                <1> 	jnb	short loc_mkdir_check_file_sytem
  1471                              <1> 	; 16/10/2016 (13h -> 30)
  1472 0000B141 B81E000000          <1> 	mov	eax, 30 ; 'Disk write-protected' error
  1473 0000B146 BA00000000          <1> 	mov	edx, 0
  1474                              <1> 	; err retn: EDX = 0, EBX = Dir name offset
  1475                              <1> 	;ESI = Logical DOS drive description table address
  1476 0000B14B C3                  <1> 	retn
  1477                              <1> 
  1478                              <1> ;loc_make_directory_access_denied:
  1479                              <1> 	;mov	ax, 05h ; access denied (invalid attributes input)
  1480                              <1> 	;stc
  1481                              <1> 	;retn
  1482                              <1> 
  1483                              <1> loc_mkdir_check_file_sytem:
  1484 0000B14C 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  1485 0000B150 730B                <1> 	jnb	short loc_mkdir_check_free_sectors
  1486                              <1> 
  1487                              <1> loc_make_fs_directory:
  1488 0000B152 A1[98640100]        <1> 	mov	eax, [Current_Dir_FCluster]
  1489                              <1> 	; EAX = Parent directory DDT Address
  1490                              <1> 	; ESI = Logical DOS Drive DT Address
  1491                              <1> 	; EBX = Directory name offset (as ASCIIZ name)
  1492 0000B157 E8D5150000          <1> 	call	make_fs_directory
  1493 0000B15C C3                  <1> 	retn
  1494                              <1> 
  1495                              <1> loc_mkdir_check_free_sectors:
  1496 0000B15D 0FB64613            <1>         movzx   eax, byte [esi+LD_BPB+SecPerClust]
  1497 0000B161 8B4E74              <1> 	mov	ecx, [esi+LD_FreeSectors]
  1498 0000B164 39C1                <1> 	cmp	ecx, eax
  1499 0000B166 7255                <1> 	jb	short loc_mkdir_insufficient_disk_space
  1500                              <1> 
  1501                              <1> loc_make_fat_directory:
  1502 0000B168 891D[086E0100]      <1> 	mov	[mkdir_DirName_Offset], ebx
  1503 0000B16E 890D[146E0100]      <1> 	mov	[mkdir_FreeSectors], ecx
  1504                              <1> 
  1505                              <1> 	;mov	al, [esi+LD_BPB+SecPerClust]
  1506 0000B174 A2[1A6E0100]        <1> 	mov	byte [mkdir_SecPerClust], al
  1507                              <1> 
  1508                              <1> loc_mkdir_gffc_1:
  1509 0000B179 E80F180000          <1> 	call	get_first_free_cluster
  1510 0000B17E 722A                <1> 	jc	short loc_mkdir_gffc_retn
  1511                              <1> 
  1512                              <1> ;loc_mkdir_gffc_1_cont: 
  1513                              <1> 	;cmp	eax, 2
  1514                              <1> 	;jb	short loc_mkdir_gffc_insufficient_disk_space
  1515                              <1> 
  1516                              <1> ;loc_mkdir_gffc_1_save_fcluster:  
  1517 0000B180 A3[0C6E0100]        <1> 	mov	[mkdir_FFCluster], eax
  1518                              <1> 
  1519                              <1> loc_mkdir_locate_ffe:
  1520                              <1> 	; Current directory fcluster <> Directory buffer cluster
  1521                              <1> 	; Current directory will be reloaded by
  1522                              <1> 	; 'locate_current_dir_file' procedure
  1523                              <1> 	;
  1524                              <1> 	; ESI = Logical DOS Drive Description Table Address 
  1525                              <1> 	;push	esi ; 27/02/2016
  1526 0000B185 31C0                <1> 	xor	eax, eax
  1527 0000B187 89C1                <1>         mov	ecx, eax
  1528 0000B189 6649                <1> 	dec	cx ; FFFFh  
  1529                              <1> 	; CX = FFFFh -> find first deleted or free entry
  1530                              <1> 	; ESI would be ASCIIZ filename address if the call
  1531                              <1> 	; would not be for first free or deleted dir entry
  1532 0000B18B E8D0FAFFFF          <1> 	call	locate_current_dir_file
  1533 0000B190 734C                <1> 	jnc	short loc_mkdir_set_ff_dir_entry_1
  1534                              <1> 	;pop	esi 
  1535                              <1> 	; ESI = Logical DOS Drive Description Table Address 
  1536 0000B192 83F802              <1> 	cmp	eax, 2  ; cmp al, 2 ; File/Dir not found !
  1537 0000B195 752B                <1> 	jne	short loc_mkdir_stc_return
  1538                              <1> 
  1539                              <1> loc_mkdir_add_new_cluster:
  1540 0000B197 3805[9D640100]      <1> 	cmp	byte [Current_FATType], al ; 2
  1541                              <1> 	;cmp	byte ptr [esi+LD_FATType], 2
  1542 0000B19D 770C                <1> 	ja	short loc_mkdir_add_new_cluster_check_fsc
  1543 0000B19F 803D[9C640100]01    <1> 	cmp	byte [Current_Dir_Level], 1
  1544                              <1> 	;cmp	byte [esi+LD_CDirLevel], 1
  1545 0000B1A6 7303                <1> 	jnb	short loc_mkdir_add_new_cluster_check_fsc
  1546                              <1> 
  1547 0000B1A8 B00C                <1> 	mov	al, 12 ; No more files 
  1548                              <1> loc_mkdir_gffc_retn:
  1549 0000B1AA C3                  <1> 	retn
  1550                              <1> 
  1551                              <1> loc_mkdir_add_new_cluster_check_fsc:
  1552 0000B1AB 8B0D[146E0100]      <1> 	mov	ecx, [mkdir_FreeSectors]
  1553                              <1> 	;movzx	eax, byte [mkdir_SecPerClust]
  1554 0000B1B1 A0[1A6E0100]        <1> 	mov	al, [mkdir_SecPerClust]
  1555 0000B1B6 66D1E0              <1> 	shl	ax, 1 ; AX = 2 * AX
  1556 0000B1B9 39C1                <1> 	cmp	ecx, eax
  1557 0000B1BB 7350                <1> 	jnb	short loc_mkdir_add_new_subdir_cluster
  1558                              <1> 
  1559                              <1> loc_mkdir_insufficient_disk_space:
  1560                              <1> 	;mov	edx, ecx
  1561                              <1> ;loc_mkdir_gffc_insufficient_disk_space:
  1562 0000B1BD 66B82700            <1> 	mov	ax, 27h ; MSDOS err => insufficient disk space
  1563                              <1> 	; err retn: EDX = Free sectors, EBX = Dir name offset
  1564                              <1>         ; ESI -> Dos drive description table address
  1565                              <1> 	;; ecx = edx
  1566                              <1> 	;
  1567 0000B1C1 C3                  <1> 	retn
  1568                              <1> 
  1569                              <1> loc_mkdir_stc_return:
  1570 0000B1C2 F9                  <1> 	stc
  1571 0000B1C3 C3                  <1> 	retn 
  1572                              <1> 
  1573                              <1> loc_mkdir_gffc_2:
  1574 0000B1C4 E8C4170000          <1> 	call	get_first_free_cluster
  1575 0000B1C9 72DF                <1> 	jc	short loc_mkdir_gffc_retn
  1576                              <1> 
  1577                              <1> ;loc_mkdir_gffc_1_cont: 
  1578                              <1> 	;cmp	eax, 2
  1579                              <1> 	;jb	short loc_mkdir_gffc_insufficient_disk_space
  1580                              <1> 
  1581                              <1> ;loc_mkdir_gffc_2_save_fcluster:  
  1582 0000B1CB A3[0C6E0100]        <1> 	mov	[mkdir_FFCluster], eax
  1583                              <1> 
  1584 0000B1D0 A1[106E0100]        <1> 	mov	eax, [mkdir_LastDirCluster]
  1585                              <1> 
  1586 0000B1D5 E842170000          <1> 	call	load_FAT_sub_directory 
  1587 0000B1DA 72CE                <1> 	jc	short loc_mkdir_gffc_retn
  1588                              <1> 
  1589 0000B1DC 31FF                <1> 	xor	edi, edi
  1590                              <1> loc_mkdir_set_ff_dir_entry_1:
  1591                              <1> 	; 27/02/2016
  1592 0000B1DE 56                  <1> 	push	esi ; Logical DOS Drv Desc. Tbl. address
  1593                              <1> 	; EDI = Directory Entry Address
  1594 0000B1DF 8B35[086E0100]      <1> 	mov	esi, [mkdir_DirName_Offset]
  1595 0000B1E5 A1[0C6E0100]        <1> 	mov	eax, [mkdir_FFCluster]
  1596                              <1> 
  1597 0000B1EA 66B91000            <1> 	mov	cx, 10h	; CL = Directory attribute
  1598                              <1> 			; CH = 0 -> File size is 0
  1599 0000B1EE 0A0D[186E0100]      <1> 	or	cl, [mkdir_attrib] ; S, H, R  
  1600 0000B1F4 E8B0010000          <1> 	call	make_directory_entry
  1601                              <1> 
  1602 0000B1F9 5E                  <1> 	pop	esi
  1603                              <1> 
  1604 0000B1FA C605[C46B0100]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1605 0000B201 E880020000          <1> 	call	save_directory_buffer
  1606 0000B206 0F83DA000000        <1>         jnc     loc_mkdir_set_ff_dir_entry_2
  1607                              <1> 
  1608                              <1> loc_mkdir_return:
  1609 0000B20C C3                  <1> 	retn
  1610                              <1> 
  1611                              <1> loc_mkdir_add_new_subdir_cluster:
  1612 0000B20D 8B15[C96B0100]      <1> 	mov	edx, [DirBuff_Cluster]
  1613 0000B213 8915[106E0100]      <1> 	mov	[mkdir_LastDirCluster], edx       
  1614                              <1> 
  1615 0000B219 A1[0C6E0100]        <1> 	mov	eax, [mkdir_FFCluster]
  1616 0000B21E E8F9160000          <1> 	call	load_FAT_sub_directory 
  1617 0000B223 72E7                <1> 	jc	short loc_mkdir_return
  1618                              <1> 	; eax = 0
  1619                              <1> 	; ecx =  directory buffer sector count (<= 128)
  1620                              <1> 
  1621                              <1> pass_mkdir_add_new_subdir_cluster:
  1622 0000B225 29FF                <1> 	sub	edi, edi ; 0
  1623                              <1> 	;mov	al, 128 ; double word
  1624                              <1> 	;mul	ecx ; ecx =  directory buffer sector count
  1625                              <1> 	;mov	ecx, eax
  1626                              <1> 	;shl	cx, 7 ; 128 * sector count	
  1627 0000B227 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec] ; 512
  1628 0000B22B 66C1E802            <1> 	shr	ax, 2 ; 'byte count / 4' for 'stosd'
  1629 0000B22F 66F7E1              <1> 	mul	cx ; max = 128*(512/4) -> 16384 (stosd)
  1630 0000B232 6689C1              <1> 	mov	cx, ax
  1631 0000B235 6629C0              <1> 	sub	ax, ax ; 0
  1632 0000B238 F3AB                <1> 	rep	stosd ; clear directory buffer
  1633                              <1> 
  1634 0000B23A C605[C46B0100]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1635 0000B241 E840020000          <1> 	call	save_directory_buffer 
  1636 0000B246 72C4                <1> 	jc	short loc_mkdir_return
  1637                              <1> 
  1638                              <1> loc_mkdir_save_added_cluster:
  1639 0000B248 A1[106E0100]        <1> 	mov	eax, [mkdir_LastDirCluster]
  1640 0000B24D 8B0D[0C6E0100]      <1> 	mov	ecx, [mkdir_FFCluster]
  1641                              <1> 	; 01/03/2016
  1642 0000B253 31D2                <1> 	xor	edx, edx
  1643 0000B255 8915[BA6B0100]      <1> 	mov	[FAT_ClusterCounter], edx ; 0 ; reset
  1644 0000B25B E800180000          <1> 	call	update_cluster
  1645 0000B260 7304                <1> 	jnc	short loc_mkdir_save_fat_buffer_0
  1646 0000B262 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  1647 0000B264 7518                <1> 	jnz	short loc_mkdir_save_fat_buffer_stc_retn
  1648                              <1> 
  1649                              <1> loc_mkdir_save_fat_buffer_0:
  1650 0000B266 A1[0C6E0100]        <1> 	mov	eax, [mkdir_FFCluster]
  1651 0000B26B A3[106E0100]        <1> 	mov	[mkdir_LastDirCluster], eax
  1652                              <1> 
  1653 0000B270 31C9                <1> 	xor	ecx, ecx
  1654 0000B272 49                  <1> 	dec	ecx ; FFFFFFFFh
  1655                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1656 0000B273 E8E8170000          <1> 	call	update_cluster
  1657 0000B278 731A                <1> 	jnc	short loc_mkdir_save_fat_buffer_1
  1658 0000B27A 09C0                <1> 	or	eax, eax
  1659 0000B27C 7416                <1> 	jz	short loc_mkdir_save_fat_buffer_1
  1660                              <1> 
  1661                              <1> loc_mkdir_save_fat_buffer_stc_retn:
  1662                              <1> 	; 01/03/2016
  1663 0000B27E 803D[BA6B0100]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1664 0000B285 720C                <1> 	jb	short loc_mkdir_save_fat_buffer_retn
  1665                              <1> 
  1666 0000B287 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free space (BL = 0)
  1667                              <1> 			   ; (BH = FFh -> Use ESI as Drv Param. Tbl.)
  1668 0000B28B 50                  <1> 	push	eax
  1669 0000B28C E8211B0000          <1> 	call	calculate_fat_freespace
  1670 0000B291 58                  <1> 	pop	eax
  1671 0000B292 F9                  <1> 	stc
  1672                              <1> loc_mkdir_save_fat_buffer_retn:
  1673 0000B293 C3                  <1> 	retn
  1674                              <1> 
  1675                              <1> loc_mkdir_save_fat_buffer_1:
  1676                              <1> 	; byte [FAT_BuffValidData] = 2 
  1677 0000B294 E8841A0000          <1> 	call	save_fat_buffer
  1678 0000B299 72E3                <1> 	jc	short loc_mkdir_save_fat_buffer_stc_retn
  1679                              <1> 
  1680                              <1> 	; 01/03/2016
  1681 0000B29B 803D[BA6B0100]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1682 0000B2A2 721B                <1> 	jb	short loc_mkdir_save_fat_buffer_2
  1683                              <1> 
  1684                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1685 0000B2A4 A1[BA6B0100]        <1> 	mov	eax, [FAT_ClusterCounter]
  1686 0000B2A9 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  1687 0000B2AD E8001B0000          <1> 	call	calculate_fat_freespace
  1688                              <1> 
  1689                              <1> 	;inc	eax ; 0FFFFFFFFh -> 0 ; recalculation is needed!
  1690                              <1> 	;jnz	short loc_mkdir_save_fat_buffer_2
  1691                              <1> 
  1692                              <1> 	; ecx > 0 -> Recalculation is needed
  1693 0000B2B2 09C9                <1> 	or	ecx, ecx 
  1694 0000B2B4 7409                <1> 	jz	short loc_mkdir_save_fat_buffer_2
  1695                              <1> 
  1696 0000B2B6 66BB00FF            <1> 	mov	bx, 0FF00h ; ; recalculate free space
  1697 0000B2BA E8F31A0000          <1> 	call	calculate_fat_freespace
  1698                              <1> 
  1699                              <1> loc_mkdir_save_fat_buffer_2:
  1700 0000B2BF C605[1B6E0100]01    <1> 	mov	byte [mkdir_add_new_cluster], 1
  1701 0000B2C6 E9C4000000          <1> 	jmp	loc_mkdir_upd_parent_dir_lmdt
  1702                              <1> 
  1703                              <1> loc_mkdir_update_sub_dir_cluster:
  1704 0000B2CB A1[0C6E0100]        <1> 	mov	eax, [mkdir_FFCluster]
  1705 0000B2D0 29C9                <1> 	sub	ecx, ecx ; 0
  1706                              <1> 	; 01/03/2016
  1707 0000B2D2 890D[BA6B0100]      <1> 	mov	[FAT_ClusterCounter], ecx ; 0 ; Reset
  1708 0000B2D8 49                  <1> 	dec	ecx ; 0FFFFFFFFh
  1709                              <1> 
  1710                              <1> 	; ESI = Logical DOS Drive Descisption Table address  
  1711 0000B2D9 E882170000          <1> 	call	update_cluster
  1712 0000B2DE 7379                <1> 	jnc	short loc_mkdir_save_fat_buffer_3
  1713 0000B2E0 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  1714 0000B2E2 7475                <1> 	jz	short loc_mkdir_save_fat_buffer_3
  1715                              <1> 	; 01/03/2016
  1716 0000B2E4 EB98                <1> 	jmp	short loc_mkdir_save_fat_buffer_stc_retn
  1717                              <1> 
  1718                              <1> loc_mkdir_set_ff_dir_entry_2:
  1719                              <1> 	; ESI = Logical DOS Drive Description Table address  
  1720 0000B2E6 A1[0C6E0100]        <1> 	mov	eax, [mkdir_FFCluster]
  1721                              <1> 	; Load disk sectors as a directory cluster
  1722 0000B2EB E82C160000          <1> 	call	load_FAT_sub_directory 
  1723 0000B2F0 7266                <1> 	jc	short retn_make_fat_directory
  1724                              <1> 	
  1725                              <1> 	; eax = 0
  1726                              <1> 	; ecx =  directory buffer sector count (<= 128)
  1727                              <1> 
  1728 0000B2F2 BF40000800          <1> 	mov	edi, Directory_Buffer + 64 ; 26/02/2016
  1729                              <1> 
  1730                              <1> 	; 02/03/2016
  1731 0000B2F7 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec] ; 512
  1732 0000B2FB 66C1E802            <1> 	shr	ax, 2 ; 'byte count / 4' for 'stosd'
  1733 0000B2FF F7E1                <1> 	mul 	ecx
  1734 0000B301 89C1                <1> 	mov	ecx, eax
  1735 0000B303 6629C0              <1> 	sub	ax, ax
  1736 0000B306 F3AB                <1> 	rep	stosd
  1737                              <1> 
  1738                              <1> 	;;mov	al, 128 ; double word
  1739                              <1> 	;;mul	ecx ; ecx =  directory buffer sector count
  1740                              <1> 	;;mov	ecx, eax
  1741                              <1> 	;shl	cx, 7 ; 128 * sector count	
  1742                              <1> 	;;sub	eax, eax
  1743                              <1> 	;;sub	al, al ; 0
  1744                              <1> 	;rep	stosd ; clear directory buffer
  1745                              <1> 
  1746 0000B308 BF00000800          <1> 	mov	edi, Directory_Buffer ; 26/02/2016
  1747                              <1> 	
  1748 0000B30D 56                  <1> 	push	esi
  1749                              <1> 
  1750 0000B30E BE[1C6E0100]        <1> 	mov	esi, mkdir_Name
  1751 0000B313 66C7062E00          <1> 	mov	word [esi], 2Eh ; db '.', '0'
  1752                              <1> 
  1753 0000B318 A1[0C6E0100]        <1> 	mov	eax, [mkdir_FFCluster]
  1754 0000B31D 66B91000            <1> 	mov	cx, 10h ; CL = Directory attribute
  1755                              <1> 			; CH = 0 -> File size is 0
  1756 0000B321 E883000000          <1> 	call	make_directory_entry
  1757                              <1> 
  1758 0000B326 BF20000800          <1> 	mov	edi, Directory_Buffer + 32 ; 26/02/2016
  1759                              <1> 
  1760                              <1> 	; 03/03/2016
  1761                              <1> 	; Following modification has been done according to 
  1762                              <1> 	; 'Microsoft Extensible Firmware Initiative
  1763                              <1> 	; FAT32 File System Specification' document,
  1764                              <1> 	; 'FAT: General Overview of On-Disk FormatPage 25'.
  1765                              <1> 	; "Finally, you set DIR_FstClusLO and DIR_FstClusHI
  1766                              <1> 	; for the dotdot entry (the second entry) to the
  1767                              <1> 	; first cluster number of the directory in which you 
  1768                              <1> 	; just created the directory (value is 0 if this directory
  1769                              <1> 	; is the root directory even for FAT32 volumes)."
  1770                              <1> 	; (Correctness of this modification has been verified
  1771                              <1> 	;  by using Windows 98 'scandisk.exe'.)
  1772                              <1> 
  1773 0000B32B 29C0                <1> 	sub	eax, eax
  1774 0000B32D 3805[9C640100]      <1> 	cmp	byte [Current_Dir_Level], al ; 0
  1775 0000B333 7605                <1> 	jna	short loc_mkdir_set_ff_dir_entry_3
  1776 0000B335 A1[98640100]        <1> 	mov	eax, [Current_Dir_FCluster] ; parent dir
  1777                              <1> loc_mkdir_set_ff_dir_entry_3:
  1778 0000B33A 66C746012E00        <1> 	mov	word [esi+1], 2Eh ; db '.', '0'
  1779                              <1> 
  1780                              <1> 	;mov	cx, 10h
  1781 0000B340 E864000000          <1> 	call	make_directory_entry
  1782                              <1> 
  1783 0000B345 5E                  <1> 	pop	esi
  1784                              <1> 
  1785 0000B346 C605[C46B0100]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1786 0000B34D E834010000          <1> 	call	save_directory_buffer
  1787 0000B352 0F8373FFFFFF        <1>         jnc     loc_mkdir_update_sub_dir_cluster
  1788                              <1>  
  1789                              <1> retn_make_fat_directory:
  1790 0000B358 C3                  <1> 	retn
  1791                              <1> 
  1792                              <1> loc_mkdir_save_fat_buffer_3:
  1793                              <1> 	; 01/03/2016
  1794                              <1> 	; byte [FAT_BuffValidData] = 2 
  1795 0000B359 E8BF190000          <1> 	call	save_fat_buffer
  1796 0000B35E 0F821AFFFFFF        <1>         jc      loc_mkdir_save_fat_buffer_stc_retn
  1797                              <1> 
  1798 0000B364 803D[BA6B0100]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1799 0000B36B 721B                <1> 	jb	short loc_mkdir_save_fat_buffer_4
  1800                              <1> 
  1801                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1802 0000B36D A1[BA6B0100]        <1> 	mov	eax, [FAT_ClusterCounter]
  1803 0000B372 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  1804 0000B376 E8371A0000          <1> 	call	calculate_fat_freespace
  1805                              <1> 
  1806                              <1> 	;inc	eax ; 0FFFFFFFFh -> 0 ; recalculation is needed!
  1807                              <1>         ;jnz    short loc_mkdir_save_fat_buffer_4
  1808                              <1> 
  1809                              <1> 	; ecx > 0 -> Recalculation is needed
  1810 0000B37B 09C9                <1> 	or	ecx, ecx 
  1811 0000B37D 7409                <1>         jz      short loc_mkdir_save_fat_buffer_4
  1812                              <1> 
  1813 0000B37F 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free space
  1814 0000B383 E82A1A0000          <1> 	call	calculate_fat_freespace
  1815                              <1> 
  1816                              <1> loc_mkdir_save_fat_buffer_4:	
  1817 0000B388 C605[1B6E0100]00    <1> 	mov	byte [mkdir_add_new_cluster], 0
  1818                              <1> 
  1819                              <1> loc_mkdir_upd_parent_dir_lmdt:
  1820 0000B38F E88D010000          <1> 	call	update_parent_dir_lmdt
  1821                              <1> 
  1822                              <1> 	; 01/03/2016
  1823 0000B394 803D[1B6E0100]00    <1> 	cmp	byte [mkdir_add_new_cluster], 0
  1824 0000B39B 0F8723FEFFFF        <1>         ja      loc_mkdir_gffc_2
  1825                              <1> 
  1826                              <1> loc_mkdir_retn_new_dir_cluster:
  1827 0000B3A1 A1[0C6E0100]        <1> 	mov	eax, [mkdir_FFCluster]
  1828 0000B3A6 31D2                <1> 	xor	edx, edx
  1829                              <1> loc_mkdir_retn:
  1830 0000B3A8 C3                  <1> 	retn
  1831                              <1> 
  1832                              <1> make_directory_entry:
  1833                              <1> 	; 02/03/2016
  1834                              <1> 	; 21/02/2016 (TRDOS 386 = TRDOS v2.0)
  1835                              <1> 	; 09/08/2010 (DIR.ASM, 'proc_make_directory_entry')
  1836                              <1> 	; 17/07/2010
  1837                              <1> 	; INPUT ->
  1838                              <1> 	; 	EDI = Directory Entry Address
  1839                              <1> 	;	ESI = Dot File Name Location
  1840                              <1> 	;	EAX = First Cluster
  1841                              <1> 	;	File Size = 0 (Must be set later)
  1842                              <1> 	;	CL = Attributes
  1843                              <1> 	;	CH = 0 (File size = 0) 
  1844                              <1> 	;	(If CH>0, File size is in dword [EBX]) (*)
  1845                              <1> 	; OUTPUT -> 
  1846                              <1> 	;	EDI = Directory Entry Address
  1847                              <1> 	;	ESI = Dot File Name Location (Capitalized)
  1848                              <1> 	;	If CH input = 0, File Size = 0
  1849                              <1> 	;	Otherwise file size is as dword [EBX] (*)
  1850                              <1> 	;	DX = Date, AX = Time in DOS Dir Entry format
  1851                              <1> 	;	EBX = same
  1852                              <1> 	;	ECX = same
  1853                              <1> 
  1854 0000B3A9 51                  <1> 	push	ecx
  1855                              <1> 
  1856 0000B3AA 884F0B              <1> 	mov	[edi+11], cl ; Attributes
  1857 0000B3AD 6689471A            <1> 	mov	[edi+26], ax ; FClusterLw, 26
  1858 0000B3B1 C1E810              <1> 	shr	eax, 16
  1859 0000B3B4 66894714            <1> 	mov	[edi+20], ax ; FClusterHw, 20
  1860 0000B3B8 6631C0              <1> 	xor	ax, ax 
  1861 0000B3BB 6689470C            <1> 	mov	[edi+12], ax ; NTReserved, 12
  1862                              <1> 			     ; CrtTimeTenth, 13
  1863 0000B3BF 08ED                <1> 	or	ch, ch
  1864 0000B3C1 7402                <1> 	jz	short loc_make_direntry_set_filesize
  1865                              <1> 
  1866 0000B3C3 8B03                <1> 	mov	eax, [ebx]
  1867                              <1>         
  1868                              <1> loc_make_direntry_set_filesize:
  1869 0000B3C5 89471C              <1> 	mov	[edi+28], eax ; FileSize, 28
  1870                              <1> 	
  1871 0000B3C8 E88AFBFFFF          <1> 	call	convert_file_name
  1872                              <1> 	;EDI = Dir Entry Format File Name Location
  1873                              <1> 	;ESI = Dot File Name Location (capitalized)
  1874                              <1> 
  1875 0000B3CD E816000000          <1> 	call	convert_current_date_time
  1876                              <1> 	; OUTPUT -> DX = Date in dos dir entry format
  1877                              <1>         ; 	    AX = Time in dos dir entry format
  1878 0000B3D2 6689470E            <1> 	mov	[edi+14], ax ; CrtTime, 14
  1879 0000B3D6 66895710            <1> 	mov	[edi+16], dx ; CrtDate, 16
  1880 0000B3DA 66895712            <1> 	mov	[edi+18], dx ; LastAccDate, 18
  1881 0000B3DE 66894716            <1> 	mov	[edi+22], ax ; WrtTime, 14
  1882 0000B3E2 66895718            <1> 	mov	[edi+24], dx ; WrtDate, 16
  1883 0000B3E6 59                  <1> 	pop	ecx
  1884                              <1> 
  1885 0000B3E7 C3                  <1> 	retn
  1886                              <1> 
  1887                              <1> convert_current_date_time:
  1888                              <1> 	; 21/02/2016 (TRDOS 386 = TRDOS v2.0)
  1889                              <1> 	; 13/06/2010 (DIR.ASM, 'proc_convert_current_date_time')
  1890                              <1> 	; converts date&time to dos dir entry format
  1891                              <1> 	; INPUT -> none
  1892                              <1> 	; OUTPUT -> DX = Date in dos dir entry format
  1893                              <1> 	;           AX = Time in dos dir entry format
  1894                              <1>  
  1895 0000B3E8 B404                <1> 	mov	ah, 04h ; Return Current Date
  1896 0000B3EA E819B0FFFF          <1> 	call	int1Ah 
  1897                              <1> 
  1898 0000B3EF 88E8                <1> 	mov	al, ch ; <- century BCD
  1899 0000B3F1 240F                <1> 	and	al, 0Fh
  1900 0000B3F3 88EC                <1> 	mov	ah, ch
  1901 0000B3F5 C0EC04              <1> 	shr	ah, 4
  1902 0000B3F8 D50A                <1> 	aad
  1903 0000B3FA 88C5                <1> 	mov	ch, al ; -> century 
  1904                              <1> 
  1905 0000B3FC 88C8                <1> 	mov	al, cl ; <- year BCD
  1906 0000B3FE 240F                <1> 	and	al, 0Fh
  1907 0000B400 88CC                <1> 	mov	ah, cl
  1908 0000B402 C0EC04              <1> 	shr	ah, 4
  1909 0000B405 D50A                <1> 	aad
  1910 0000B407 88C1                <1> 	mov	cl, al ; -> year
  1911                              <1> 
  1912 0000B409 88E8                <1> 	mov	al, ch
  1913 0000B40B B464                <1> 	mov	ah, 100
  1914 0000B40D F6E4                <1> 	mul	ah
  1915 0000B40F 30ED                <1> 	xor	ch, ch
  1916 0000B411 6601C8              <1> 	add	ax, cx
  1917 0000B414 662DBC07            <1> 	sub	ax, 1980 ; ms-dos epoch
  1918 0000B418 6689C1              <1> 	mov	cx, ax
  1919                              <1> 
  1920 0000B41B 88F0                <1> 	mov	al, dh ; <- month in bcd
  1921 0000B41D 240F                <1> 	and	al, 0Fh
  1922 0000B41F 88F4                <1> 	mov	ah, dh
  1923 0000B421 C0EC04              <1> 	shr	ah, 4
  1924 0000B424 D50A                <1> 	aad
  1925 0000B426 88C6                <1> 	mov	dh, al ; -> month
  1926                              <1> 
  1927 0000B428 88D0                <1> 	mov	al, dl ; <- day BCD
  1928 0000B42A 240F                <1> 	and	al, 0Fh
  1929 0000B42C 88D4                <1> 	mov	ah, dl
  1930 0000B42E C0EC04              <1> 	shr	ah, 4
  1931 0000B431 D50A                <1> 	aad
  1932 0000B433 88C2                <1> 	mov	dl, al ; -> day
  1933                              <1> 
  1934 0000B435 88C8                <1> 	mov	al, cl ; count of years from 1980
  1935 0000B437 66C1E004            <1> 	shl	ax, 4
  1936 0000B43B 08F0                <1> 	or	al, dh ; month of year, 1 to 12
  1937 0000B43D 66C1E005            <1> 	shl	ax, 5
  1938 0000B441 08D0                <1> 	or	al, dl ; day of year, 1 to 31
  1939                              <1> 	
  1940 0000B443 6650                <1> 	push	ax ; push date
  1941                              <1> 
  1942 0000B445 B402                <1> 	mov	ah, 02h ; Return Current Time
  1943 0000B447 E8BCAFFFFF          <1> 	call	int1Ah
  1944                              <1> 
  1945 0000B44C 88E8                <1> 	mov	al, ch ; <- hours BCD
  1946 0000B44E 240F                <1> 	and	al, 0Fh
  1947 0000B450 88EC                <1> 	mov	ah, ch
  1948 0000B452 C0EC04              <1> 	shr	ah, 4
  1949 0000B455 D50A                <1> 	aad
  1950 0000B457 88C5                <1> 	mov	ch, al ; -> hours
  1951                              <1> 
  1952 0000B459 88C8                <1> 	mov	al, cl ; <- minutes BCD
  1953 0000B45B 240F                <1> 	and	al, 0Fh
  1954 0000B45D 88CC                <1> 	mov	ah, cl
  1955 0000B45F C0EC04              <1> 	shr	ah, 4
  1956 0000B462 D50A                <1> 	aad
  1957 0000B464 88C1                <1> 	mov	cl, al ; -> minutes
  1958                              <1> 
  1959 0000B466 88F0                <1> 	mov	al, dh ; <- seconds BCD
  1960 0000B468 240F                <1> 	and	al, 0Fh
  1961 0000B46A 88F4                <1> 	mov	ah, dh
  1962 0000B46C C0EC04              <1> 	shr	ah, 4
  1963 0000B46F D50A                <1> 	aad
  1964 0000B471 88C6                <1> 	mov	dh, al ; -> seconds
  1965                              <1> 
  1966 0000B473 88E8                <1> 	mov	al, ch ; hours
  1967 0000B475 66C1E006            <1> 	shl	ax, 6
  1968 0000B479 08C8                <1> 	or	al, cl ; minutes
  1969 0000B47B 66C1E005            <1> 	shl	ax, 5
  1970 0000B47F D0EE                <1> 	shr	dh, 1 ; 2 seconds
  1971                              <1> 	; There is a bug in TRDOS v1 here !
  1972                              <1> 	; it was 'or al, dl' ! 
  1973 0000B481 08F0                <1> 	or	al, dh ; seconds
  1974                              <1> 
  1975 0000B483 665A                <1> 	pop	dx ; pop date
  1976                              <1> 	
  1977 0000B485 C3                  <1> 	retn
  1978                              <1> 
  1979                              <1> save_directory_buffer:
  1980                              <1> 	; 15/10/2016
  1981                              <1> 	; 23/03/2016
  1982                              <1> 	; 26/02/2016
  1983                              <1> 	; 22/02/2016 (TRDOS 386 = TRDOS v2.0)
  1984                              <1> 	; 01/08/2011
  1985                              <1> 	; 14/03/2010
  1986                              <1> 	; INPUT ->
  1987                              <1> 	; 	 none
  1988                              <1> 	; OUTPUT ->
  1989                              <1> 	;  cf = 0 -> write OK...
  1990                              <1> 	;  cf = 1 -> error code in AL (EAX)
  1991                              <1> 	;  cf = 1 & AL = 0Dh => CH & CL = FS & FAT type
  1992                              <1> 	;  EBX = Directory Buffer Address
  1993                              <1> 	;
  1994                              <1> 	;  (EAX, ECX, EDX will be modified)
  1995                              <1>  
  1996 0000B486 BB00000800          <1> 	mov	ebx, Directory_Buffer
  1997 0000B48B 803D[C46B0100]02    <1> 	cmp	byte [DirBuff_ValidData], 2
  1998 0000B492 7403                <1> 	je	short loc_save_dir_buffer
  1999 0000B494 31C0                <1> 	xor	eax, eax
  2000 0000B496 C3                  <1> 	retn            
  2001                              <1> 
  2002                              <1> loc_save_dir_buffer:
  2003 0000B497 56                  <1> 	push	esi
  2004 0000B498 31DB                <1> 	xor	ebx, ebx 
  2005 0000B49A 8A3D[C26B0100]      <1>         mov     bh, [DirBuff_DRV]
  2006 0000B4A0 80EF41              <1> 	sub	bh, 'A'
  2007 0000B4A3 BE00010900          <1>         mov     esi, Logical_DOSDisks
  2008 0000B4A8 01DE                <1> 	add	esi, ebx
  2009 0000B4AA 668B4E03            <1>         mov     cx, [esi+LD_FATType]
  2010                              <1> 	; CH = FS Type (A1h for FS)
  2011                              <1> 	; CL = FAT Type (0 for FS)
  2012 0000B4AE 08C9                <1> 	or	cl, cl
  2013 0000B4B0 7433                <1> 	jz	short loc_save_dir_buff_stc_retn
  2014                              <1> 
  2015                              <1> loc_save_dir_buffer_check_cluster_no:    
  2016 0000B4B2 A1[C96B0100]        <1> 	mov	eax, [DirBuff_Cluster]
  2017 0000B4B7 28FF                <1> 	sub	bh, bh ; ebx = 0
  2018 0000B4B9 09C0                <1> 	or	eax, eax
  2019 0000B4BB 7540                <1> 	jnz	short loc_save_sub_dir_buffer
  2020 0000B4BD 8A25[C36B0100]      <1> 	mov	ah, [DirBuff_FATType]
  2021 0000B4C3 FEC3                <1> 	inc	bl ;  bl = 1
  2022 0000B4C5 38DC                <1> 	cmp	ah, bl
  2023 0000B4C7 721D                <1> 	jb	short loc_save_dir_buff_inv_data_retn
  2024 0000B4C9 FEC3                <1> 	inc	bl ; bl = 2
  2025 0000B4CB 38E3                <1> 	cmp	bl, ah
  2026 0000B4CD 7217                <1> 	jb	short loc_save_dir_buff_inv_data_retn
  2027                              <1> 
  2028                              <1> loc_save_root_dir_buffer:
  2029 0000B4CF 668B5E17            <1> 	mov	bx, [esi+LD_BPB+RootDirEnts]
  2030 0000B4D3 6683C30F            <1> 	add	bx, 15
  2031 0000B4D7 66C1EB04            <1> 	shr	bx, 4 ; 16 dir entries per sector
  2032 0000B4DB 6609DB              <1> 	or	bx, bx
  2033 0000B4DE 7405                <1> 	jz	short loc_save_dir_buff_stc_retn
  2034                              <1> 	;mov	ecx, ebx 
  2035 0000B4E0 8B4664              <1> 	mov	eax, [esi+LD_ROOTBegin] ; 26/02/2016
  2036 0000B4E3 EB23                <1> 	jmp	short loc_write_directory_to_disk
  2037                              <1> 
  2038                              <1> loc_save_dir_buff_stc_retn:
  2039 0000B4E5 F9                  <1> 	stc
  2040                              <1> loc_save_dir_buff_inv_data_retn:
  2041                              <1> 	; 15/10/2016 (0Dh -> 29)
  2042 0000B4E6 B01D                <1> 	mov	al, 29 ; Invalid data !
  2043 0000B4E8 C605[C46B0100]00    <1> 	mov	byte [DirBuff_ValidData], 0
  2044 0000B4EF EB05                <1> 	jmp	short loc_save_dir_buff_retn 
  2045                              <1> 
  2046                              <1> loc_write_directory_to_disk_err:
  2047                              <1> 	; 15/10/2016 (disk write error code, 1Dh -> 18)
  2048 0000B4F1 B812000000          <1> 	mov	eax, 18 ; Drive not ready or write error 
  2049                              <1> 
  2050                              <1> loc_save_dir_buff_retn:
  2051 0000B4F6 BB00000800          <1> 	mov	ebx, Directory_Buffer
  2052 0000B4FB 5E                  <1> 	pop	esi
  2053 0000B4FC C3                  <1> 	retn
  2054                              <1>  
  2055                              <1> loc_save_sub_dir_buffer:
  2056                              <1> 	; ebx  = 0
  2057 0000B4FD 83E802              <1> 	sub	eax, 2
  2058 0000B500 8A5E13              <1> 	mov	bl, [esi+LD_BPB+SecPerClust]
  2059 0000B503 F7E3                <1> 	mul	ebx
  2060 0000B505 034668              <1>         add     eax, [esi+LD_DATABegin]
  2061                              <1>  	;mov	ecx, ebx
  2062                              <1> 
  2063                              <1> loc_write_directory_to_disk:
  2064 0000B508 89D9                <1>  	mov	ecx, ebx
  2065 0000B50A BB00000800          <1> 	mov	ebx, Directory_Buffer
  2066 0000B50F E8CD4D0000          <1> 	call	disk_write
  2067 0000B514 72DB                <1> 	jc	short loc_write_directory_to_disk_err
  2068                              <1> 
  2069                              <1> loc_save_dir_buff_validate_retn:
  2070 0000B516 C605[C46B0100]01    <1> 	mov	byte [DirBuff_ValidData], 1
  2071 0000B51D 31C0                <1> 	xor	eax, eax
  2072                              <1> 	; 26/02/2016
  2073 0000B51F EBD5                <1> 	jmp	short loc_save_dir_buff_retn
  2074                              <1> 
  2075                              <1> update_parent_dir_lmdt:
  2076                              <1> 	; 29/12/2017
  2077                              <1> 	; 22/02/2016 (TRDOS 386 = TRDOS v2.0)
  2078                              <1> 	; 01/08/2011
  2079                              <1> 	; 16/10/2010 
  2080                              <1> 	; 
  2081                              <1> 	; INPUT -> 
  2082                              <1> 	;	none
  2083                              <1>  	; OUTPUT ->
  2084                              <1> 	;	(last modification date & time of the parent dir
  2085                              <1> 	;	will be changed/updated)
  2086                              <1> 	;
  2087                              <1> 	; (EAX, EBX, ECX, EDX, EDI will be changed)
  2088                              <1> 
  2089 0000B521 29C0                <1> 	sub	eax, eax
  2090 0000B523 8A25[9C640100]      <1> 	mov	ah, [Current_Dir_Level]
  2091 0000B529 A0[9D640100]        <1> 	mov	al, [Current_FATType]
  2092 0000B52E 3C01                <1> 	cmp	al, 1
  2093 0000B530 723A                <1> 	jb	short loc_UPDLMDT_proc_retn
  2094                              <1>     
  2095                              <1> loc_update_parent_dir_lm_date_time:
  2096 0000B532 08E4                <1> 	or	ah, ah
  2097 0000B534 7436                <1> 	jz	short loc_UPDLMDT_proc_retn
  2098                              <1> 
  2099 0000B536 56                  <1> 	push	esi ; *
  2100 0000B537 8825[3C6E0100]      <1> 	mov	[UPDLMDT_CDirLevel], ah
  2101 0000B53D 8B15[98640100]      <1> 	mov	edx, [Current_Dir_FCluster]
  2102 0000B543 8915[3D6E0100]      <1> 	mov	[UPDLMDT_CDirFCluster], edx
  2103                              <1> 
  2104 0000B549 FECC                <1> 	dec	ah
  2105 0000B54B B90C000000          <1> 	mov	ecx, 12
  2106 0000B550 BE[FB6B0100]        <1>         mov     esi, PATH_Array
  2107                              <1> 
  2108 0000B555 8825[9C640100]      <1> 	mov	[Current_Dir_Level], ah
  2109 0000B55B 08E4                <1> 	or	ah, ah
  2110 0000B55D 750E                <1> 	jnz	short loc_update_parent_dir_lmdt_load_sub_dir_1
  2111 0000B55F 803D[9D640100]02    <1> 	cmp	byte [Current_FATType], 2
  2112 0000B566 770B                <1> 	ja	short loc_update_parent_dir_lmdt_load_sub_dir_2
  2113 0000B568 28C0                <1> 	sub	al, al ; eax = 0
  2114 0000B56A EB0A                <1> 	jmp	short loc_update_parent_dir_lmdt_load_sub_dir_3
  2115                              <1> 
  2116                              <1> loc_UPDLMDT_proc_retn:
  2117 0000B56C C3                  <1> 	retn
  2118                              <1>          
  2119                              <1> loc_update_parent_dir_lmdt_load_sub_dir_1:
  2120 0000B56D B010                <1> 	mov	al, 16
  2121 0000B56F F6E4                <1> 	mul	ah 
  2122 0000B571 01C6                <1> 	add	esi, eax
  2123                              <1> 
  2124                              <1> loc_update_parent_dir_lmdt_load_sub_dir_2:  
  2125 0000B573 8B460C              <1> 	mov	eax, [esi+12] ; Parent Dir First Cluster
  2126                              <1> 
  2127                              <1> loc_update_parent_dir_lmdt_load_sub_dir_3:
  2128 0000B576 A3[98640100]        <1> 	mov	[Current_Dir_FCluster], eax
  2129                              <1> 
  2130 0000B57B 83C610              <1> 	add	esi, 16
  2131 0000B57E 66BF[226D]          <1> 	mov	di, Dir_File_Name  
  2132 0000B582 F3A4                <1> 	rep	movsb
  2133                              <1> 	
  2134 0000B584 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2135 0000B589 29DB                <1> 	sub	ebx, ebx
  2136 0000B58B 8A3D[9E640100]      <1> 	mov	bh, [Current_Drv]
  2137 0000B591 01DE                <1> 	add	esi, ebx
  2138 0000B593 E88FF7FFFF          <1> 	call	reload_current_directory
  2139 0000B598 7230                <1> 	jc	short loc_update_parent_dir_lmdt_restore_cdirlevel
  2140                              <1> 
  2141                              <1> loc_update_parent_dir_lmdt_locate_dir: 
  2142 0000B59A BE[226D0100]        <1> 	mov	esi, Dir_File_Name        
  2143 0000B59F 6631C9              <1> 	xor	cx, cx
  2144 0000B5A2 66B81008            <1> 	mov	ax, 0810h ; Only directories
  2145 0000B5A6 E8B5F6FFFF          <1>         call    locate_current_dir_file
  2146                              <1> 	; EDI = DirBuff Directory Entry Address
  2147 0000B5AB 721D                <1> 	jc	short loc_update_parent_dir_lmdt_restore_cdirlevel
  2148                              <1> 
  2149 0000B5AD E836FEFFFF          <1> 	call	convert_current_date_time
  2150 0000B5B2 66895712            <1> 	mov	[edi+18], dx ; Last Access Date
  2151 0000B5B6 66895718            <1> 	mov	[edi+24], dx ; Last Write Date
  2152 0000B5BA 66894716            <1> 	mov	[edi+22], ax ; Last Write Time
  2153                              <1> 
  2154 0000B5BE C605[C46B0100]02    <1> 	mov	byte [DirBuff_ValidData], 2
  2155 0000B5C5 E8BCFEFFFF          <1> 	call	save_directory_buffer
  2156                              <1> 	; 29/12/2017
  2157                              <1> 	;jc	short loc_update_parent_dir_lmdt_restore_cdirlevel
  2158                              <1> 	;xor	al, al 
  2159                              <1> loc_update_parent_dir_lmdt_restore_cdirlevel:
  2160                              <1>  	;current directory level restoration
  2161 0000B5CA 8A25[3C6E0100]      <1> 	mov	ah, [UPDLMDT_CDirLevel]
  2162 0000B5D0 8825[9C640100]      <1> 	mov	[Current_Dir_Level], ah
  2163 0000B5D6 8B15[3D6E0100]      <1>         mov     edx, [UPDLMDT_CDirFCluster]
  2164 0000B5DC 8915[98640100]      <1> 	mov	[Current_Dir_FCluster], edx
  2165                              <1> 
  2166 0000B5E2 5E                  <1> 	pop	esi ; *
  2167 0000B5E3 C3                  <1> 	retn
  2168                              <1> 
  2169                              <1> delete_longname:
  2170                              <1> 	; 27/02/2016 (TRDOS 386 = TRDOS v2.0)
  2171                              <1> 	; 01/08/2011 (DIR.ASM, 'proc_delete_longname')
  2172                              <1> 	; 14/03/2010
  2173                              <1> 	; INPUT ->
  2174                              <1> 	; 	EAX = Directory Entry (Index) Number (< 65536)
  2175                              <1> 	; OUTPUT ->
  2176                              <1> 	;	cf = 0 -> OK  (EAX = 0)
  2177                              <1> 	; 	cf = 1 -> error code in EAX (AL)
  2178                              <1> 	;
  2179                              <1> 	; (Modified registers: EAX, EDX, ECX, EBX, EDI) 
  2180                              <1> 
  2181 0000B5E4 66A3[6C6E0100]      <1> 	mov	[DLN_EntryNumber], ax
  2182 0000B5EA C605[6E6E0100]40    <1>         mov     byte [DLN_40h], 40h
  2183                              <1> 
  2184 0000B5F1 E858000000          <1> 	call	locate_current_dir_entry
  2185 0000B5F6 7308                <1> 	jnc	short loc_dln_check_attributes
  2186 0000B5F8 C3                  <1> 	retn
  2187                              <1> 
  2188                              <1> loc_dln_longname_not_found:
  2189 0000B5F9 B802000000          <1> 	mov	eax, 2
  2190 0000B5FE F9                  <1> 	stc
  2191 0000B5FF C3                  <1> 	retn
  2192                              <1> 
  2193                              <1> loc_dln_check_attributes:
  2194 0000B600 B00F                <1> 	mov	al, 0Fh  ; long name
  2195 0000B602 8A670B              <1> 	mov	ah, [edi+0Bh] ; dir entry attributes
  2196 0000B605 38C4                <1> 	cmp	ah, al
  2197 0000B607 75F0                <1> 	jne	short loc_dln_longname_not_found
  2198 0000B609 8A27                <1> 	mov	ah, [edi]
  2199 0000B60B 2A25[6E6E0100]      <1> 	sub	ah, [DLN_40h]
  2200 0000B611 76E6                <1> 	jna	short loc_dln_longname_not_found         
  2201 0000B613 80FC14              <1> 	cmp	ah, 14h ; 84-64=20 -> 20*13=260 bytes
  2202 0000B616 77E1                <1> 	ja	short loc_dln_longname_not_found
  2203                              <1>              
  2204 0000B618 C607E5              <1> 	mov	byte [edi], 0E5h  ; deleted sign
  2205 0000B61B C605[C46B0100]02    <1> 	mov	byte [DirBuff_ValidData], 2 ; changed/write sign
  2206 0000B622 C605[6E6E0100]00    <1> 	mov	byte [DLN_40h], 0 ; 40h -> 0
  2207                              <1> 	  
  2208                              <1> loc_dln_delete_next_ln_entry:
  2209 0000B629 80FC01              <1> 	cmp	ah, 1
  2210 0000B62C 7616                <1> 	jna	short loc_dln_longname_retn
  2211                              <1> loc_dln_delete_next_ln_entry_0:
  2212 0000B62E 66FF05[6C6E0100]    <1> 	inc	word [DLN_EntryNumber]
  2213 0000B635 0FB705[6C6E0100]    <1> 	movzx	eax, word [DLN_EntryNumber] 
  2214 0000B63C E80D000000          <1> 	call	locate_current_dir_entry
  2215 0000B641 73BD                <1> 	jnc	short loc_dln_check_attributes
  2216                              <1> 
  2217                              <1> loc_dln_longname_stc_retn:
  2218 0000B643 C3                  <1> 	retn 
  2219                              <1> 	   
  2220                              <1> loc_dln_longname_retn:
  2221                              <1> 	;cmp	byte [DirBuff_ValidData], 2
  2222                              <1> 	;jne	short loc_dln_longname_retn_xor_eax
  2223 0000B644 E83DFEFFFF          <1> 	call	save_directory_buffer
  2224 0000B649 72F8                <1> 	jc	short loc_dln_longname_stc_retn
  2225                              <1> 
  2226                              <1> loc_dln_longname_retn_xor_eax:
  2227 0000B64B 31C0                <1> 	xor	eax, eax
  2228 0000B64D C3                  <1> 	retn
  2229                              <1> 
  2230                              <1> locate_current_dir_entry:
  2231                              <1> 	; 16/10/2016
  2232                              <1> 	; 15/10/2016
  2233                              <1> 	; 23/03/2016
  2234                              <1> 	; 27/02/2016 (TRDOS 386 = TRDOS v2.0)
  2235                              <1> 	; 01/08/2011 (DIR.ASM, 'proc_locate_current_dir_entry')
  2236                              <1> 	; 07/03/2010
  2237                              <1> 	; INPUT ->
  2238                              <1> 	;	EAX = Directory Entry (Index) Number (< 65536) 
  2239                              <1> 	; OUTPUT ->
  2240                              <1> 	;	EDI = Directory Entry Address
  2241                              <1> 	; 	EAX = Cluster Number of Directory Buffer
  2242                              <1> 	;	EBX = Directory Buffer Entry Offset
  2243                              <1> 	;	ECX = DirBuff Valid Data identifier (CL)
  2244                              <1> 	;   	If CF = 0 and CL = 2 then
  2245                              <1> 	;	   directory buffer modified and
  2246                              <1> 	;	   must be written to disk.
  2247                              <1> 	; 	If CF = 0  and CL = 1 then
  2248                              <1> 	;	   dir buffer has been written to disk, already.
  2249                              <1> 	;	CF = 1 -> Error code in EAX (AL)
  2250                              <1> 	;
  2251                              <1> 	; (Modified registers: EAX, EDX, ECX, EBX, EDI) 
  2252                              <1> 
  2253                              <1> loc_locate_current_dir_entry:
  2254 0000B64E 56                  <1> 	push	esi
  2255 0000B64F 89C1                <1> 	mov	ecx, eax
  2256 0000B651 BA20000000          <1> 	mov	edx, 32
  2257 0000B656 F7E2                <1> 	mul	edx 
  2258 0000B658 A3[786E0100]        <1> 	mov	[LCDE_ByteOffset], eax
  2259 0000B65D 31DB                <1> 	xor	ebx, ebx
  2260 0000B65F 8A3D[9E640100]      <1> 	mov	bh, [Current_Drv]
  2261 0000B665 A0[C26B0100]        <1>         mov     al, [DirBuff_DRV]
  2262 0000B66A 2C41                <1> 	sub	al, 'A'
  2263 0000B66C BE00010900          <1>         mov     esi, Logical_DOSDisks
  2264 0000B671 01DE                <1> 	add	esi, ebx
  2265 0000B673 38C7                <1> 	cmp	bh, al
  2266 0000B675 0F8592000000        <1>         jne     loc_lcde_reload_current_directory
  2267                              <1> loc_lcde_cdl_check:
  2268 0000B67B 803D[9C640100]00    <1> 	cmp	byte [Current_Dir_Level], 0
  2269 0000B682 772A                <1> 	ja	short loc_lcde_calc_dirbuff_cluster_offset
  2270                              <1> 	; 27/02/2016
  2271                              <1> 	; TRDOS v1 has bug here for FAT32 fs !
  2272                              <1> 	; (Root Directory Entries for FAT32 = 0)
  2273 0000B684 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3  ; FAT32
  2274 0000B688 7324                <1> 	jnb	short loc_lcde_calc_dirbuff_cluster_offset
  2275                              <1> 
  2276                              <1> loc_lcde_cdl_check_FAT12_16:
  2277 0000B68A 668B4617            <1> 	mov	ax, [esi+LD_BPB+RootDirEnts]
  2278 0000B68E 6648                <1> 	dec	ax
  2279                              <1> 	;xor	dx, dx  
  2280 0000B690 6639C8              <1> 	cmp	ax, cx ; cx = Directory Entry (Index) Number
  2281 0000B693 720E                <1> 	jb	short loc_lcde_stc_12h_retn
  2282 0000B695 66890D[706E0100]    <1> 	mov	[LCDE_EntryIndex], cx
  2283 0000B69C 31C0                <1> 	xor	eax, eax
  2284 0000B69E E993000000          <1>         jmp     loc_lcde_check_dir_buffer_cluster
  2285                              <1> 
  2286                              <1> loc_lcde_stc_12h_retn:
  2287 0000B6A3 5E                  <1> 	pop	esi
  2288 0000B6A4 89CB                <1> 	mov	ebx, ecx
  2289 0000B6A6 89D1                <1> 	mov	ecx, edx
  2290                              <1> 	; 16/10/2016 (12h -> 12)
  2291 0000B6A8 B80C000000          <1> 	mov	eax, 12 ; No more files
  2292 0000B6AD C3                  <1> 	retn 
  2293                              <1> 
  2294                              <1> loc_lcde_calc_dirbuff_cluster_offset:
  2295 0000B6AE 8A5E13              <1> 	mov	bl, [esi+LD_BPB+SecPerClust]
  2296 0000B6B1 30FF                <1> 	xor	bh, bh
  2297 0000B6B3 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec]
  2298 0000B6B7 66F7E3              <1> 	mul	bx
  2299 0000B6BA 6609D2              <1>  	or	dx, dx ; If bytes per cluster > 32KB it is invalid
  2300 0000B6BD 755D                <1> 	jnz	short loc_lcde_invalid_format
  2301                              <1> 	;mov	ecx, eax
  2302 0000B6BF 6689C1              <1> 	mov	cx, ax ; BYTES PER CLUSTER
  2303 0000B6C2 A1[786E0100]        <1> 	mov	eax, [LCDE_ByteOffset]
  2304                              <1> 	;sub	edx, edx
  2305 0000B6C7 F7F1                <1> 	div	ecx
  2306 0000B6C9 3DFFFF0000          <1> 	cmp	eax, 65535
  2307 0000B6CE 774C                <1> 	ja	short loc_lcde_invalid_format
  2308                              <1> 
  2309                              <1> 	; cluster sequence number of directory (< 65536)
  2310 0000B6D0 66A3[726E0100]      <1> 	mov	[LCDE_ClusterSN], ax 
  2311                              <1> 
  2312 0000B6D6 6689D0              <1> 	mov	ax, dx ; byte offset in cluster (directory buffer)
  2313 0000B6D9 66BB2000            <1> 	mov	bx, 32 ; ; 1 dir entry = 32 bytes
  2314 0000B6DD 6629D2              <1>         sub     dx, dx  ; 0
  2315 0000B6E0 66F7F3              <1> 	div	bx 
  2316 0000B6E3 66A3[706E0100]      <1> 	mov	[LCDE_EntryIndex], ax ; dir entry index/sequence number
  2317                              <1> 				      ; (in directory buffer/cluster)	  
  2318                              <1> loc_lcde_get_current_sub_dir_fcluster:
  2319 0000B6E9 A1[98640100]        <1> 	mov	eax, [Current_Dir_FCluster]
  2320                              <1> 
  2321                              <1> loc_lcde_get_next_cluster:
  2322 0000B6EE 66833D[726E0100]00  <1> 	cmp	word [LCDE_ClusterSN], 0
  2323 0000B6F6 763E                <1> 	jna	short loc_lcde_check_dir_buffer_cluster
  2324 0000B6F8 A3[746E0100]        <1> 	mov	[LCDE_Cluster], eax
  2325 0000B6FD E834100000          <1> 	call	get_next_cluster
  2326 0000B702 7220                <1> 	jc	short loc_lcde_check_gnc_error
  2327 0000B704 66FF0D[726E0100]    <1>   	dec	word [LCDE_ClusterSN]
  2328 0000B70B EBE1                <1> 	jmp	short loc_lcde_get_next_cluster
  2329                              <1> 
  2330                              <1> loc_lcde_reload_current_directory:
  2331 0000B70D 51                  <1> 	push	ecx
  2332 0000B70E E814F6FFFF          <1> 	call	reload_current_directory
  2333 0000B713 59                  <1> 	pop	ecx
  2334 0000B714 0F8361FFFFFF        <1>         jnc     loc_lcde_cdl_check
  2335 0000B71A 5E                  <1> 	pop	esi
  2336 0000B71B C3                  <1> 	retn
  2337                              <1> 
  2338                              <1> loc_lcde_invalid_format:
  2339                              <1> 	; 15/10/2016 (0Bh -> 28)
  2340 0000B71C B81C000000          <1> 	mov	eax, 28 ; Invalid Format !
  2341                              <1> loc_lcde_drive_not_ready_read_err:
  2342 0000B721 F9                  <1> 	stc
  2343 0000B722 5E                  <1> 	pop	esi 
  2344 0000B723 C3                  <1> 	retn  
  2345                              <1> 
  2346                              <1> loc_lcde_check_gnc_error:
  2347 0000B724 09C0                <1> 	or	eax, eax
  2348 0000B726 75F9                <1> 	jnz	short loc_lcde_drive_not_ready_read_err
  2349 0000B728 66FF0D[726E0100]    <1> 	dec	word [LCDE_ClusterSN]
  2350 0000B72F 75EB                <1> 	jnz	short loc_lcde_invalid_format 
  2351 0000B731 A1[746E0100]        <1> 	mov	eax, [LCDE_Cluster]
  2352                              <1> 
  2353                              <1> loc_lcde_check_dir_buffer_cluster:
  2354 0000B736 3B05[C96B0100]      <1> 	cmp	eax, [DirBuff_Cluster]
  2355 0000B73C 755C                <1> 	jne	short loc_lcde_load_dir_cluster
  2356 0000B73E 803D[C46B0100]00    <1> 	cmp	byte [DirBuff_ValidData], 0
  2357 0000B745 7727                <1> 	ja	short lcde_check_dir_buffer_cluster_next
  2358 0000B747 803D[9C640100]00    <1> 	cmp	byte [Current_Dir_Level], 0    
  2359 0000B74E 775F                <1> 	ja	short loc_lcde_load_dir_cluster_0
  2360                              <1> 	; 27/02/2016
  2361                              <1> 	; TRDOS v1 has bug here for FAT32 fs !
  2362 0000B750 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3  ; FAT32
  2363 0000B754 7359                <1> 	jnb	short loc_lcde_load_dir_cluster_0
  2364                              <1> 	;
  2365 0000B756 0FB74E17            <1> 	movzx	ecx, word [esi+LD_BPB+RootDirEnts]
  2366 0000B75A 6683C10F            <1> 	add	cx, 15 ; round up (16 entries per sector)
  2367 0000B75E 66C1E904            <1> 	shr	cx, 4 ; 1 sector contains 16 dir entries	
  2368                              <1> 
  2369 0000B762 8B4664              <1>         mov     eax, [esi+LD_ROOTBegin]
  2370 0000B765 EB54                <1> 	jmp	short loc_lcde_load_dir_cluster_1 
  2371                              <1> 
  2372                              <1> loc_lcde_validate_dirBuff:
  2373 0000B767 C605[C46B0100]01    <1> 	mov	byte [DirBuff_ValidData], 1
  2374                              <1> 
  2375                              <1> lcde_check_dir_buffer_cluster_next:
  2376 0000B76E 0FB71D[706E0100]    <1> 	movzx	ebx, word [LCDE_EntryIndex]
  2377 0000B775 663B1D[C76B0100]    <1> 	cmp	bx, [DirBuff_LastEntry]
  2378 0000B77C 779E                <1> 	ja	short loc_lcde_invalid_format 
  2379 0000B77E B820000000          <1> 	mov	eax, 32
  2380 0000B783 F7E3                <1> 	mul	ebx
  2381                              <1> 	;or	edx, edx
  2382                              <1> 	;jnz	short loc_lcde_invalid_format
  2383                              <1> 
  2384 0000B785 BF00000800          <1> 	mov	edi, Directory_Buffer  
  2385 0000B78A 01C7                <1> 	add	edi, eax ; add entry offset to buffer address
  2386                              <1> 
  2387                              <1> loc_lcde_dir_buffer_last_check:
  2388 0000B78C A1[C96B0100]        <1> 	mov	eax, [DirBuff_Cluster]
  2389 0000B791 0FB60D[C46B0100]    <1> 	movzx	ecx, byte [DirBuff_ValidData]
  2390                              <1> 
  2391                              <1> loc_lcde_retn:
  2392 0000B798 5E                  <1> 	pop	esi
  2393 0000B799 C3                  <1> 	retn
  2394                              <1> 
  2395                              <1> loc_lcde_load_dir_cluster:
  2396                              <1> 	;cmp	byte [DirBuff_ValidData], 2
  2397                              <1> 	;jne	short loc_lcde_load_dir_cluster_n2
  2398 0000B79A 50                  <1> 	push	eax
  2399 0000B79B E8E6FCFFFF          <1> 	call	save_directory_buffer
  2400 0000B7A0 58                  <1> 	pop	eax
  2401 0000B7A1 72F5                <1> 	jc	short loc_lcde_retn
  2402                              <1> 
  2403                              <1> loc_lcde_load_dir_cluster_n2:
  2404 0000B7A3 C605[C46B0100]00    <1> 	mov	byte [DirBuff_ValidData], 0
  2405 0000B7AA A3[C96B0100]        <1> 	mov	[DirBuff_Cluster], eax
  2406                              <1> 
  2407                              <1> loc_lcde_load_dir_cluster_0:
  2408 0000B7AF 83E802              <1> 	sub	eax, 2
  2409 0000B7B2 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  2410 0000B7B6 F7E1                <1> 	mul	ecx
  2411 0000B7B8 034668              <1>         add     eax, [esi+LD_DATABegin]
  2412                              <1> 
  2413                              <1> loc_lcde_load_dir_cluster_1:
  2414 0000B7BB BB00000800          <1> 	mov	ebx, Directory_Buffer
  2415                              <1> 	; ecx = sector count
  2416 0000B7C0 E82B4B0000          <1> 	call	disk_read
  2417 0000B7C5 73A0                <1> 	jnc	short loc_lcde_validate_dirBuff
  2418                              <1> 
  2419                              <1> 	; 15/10/2016 
  2420                              <1> 	; (Disk read error instead of drv not ready err)
  2421 0000B7C7 B811000000          <1> 	mov	eax, 17 ; Drive not ready or read error !
  2422 0000B7CC EBCA                <1> 	jmp	short loc_lcde_retn
  2423                              <1> 
  2424                              <1> 
  2425                              <1> remove_file:
  2426                              <1> 	; 15/10/2016
  2427                              <1> 	; 28/02/2016 (TRDOS 386 = TRDOS v2.0)
  2428                              <1> 	; 10/04/2011 (FILE.ASM, 'proc_delete_file')
  2429                              <1> 	; 09/08/2010
  2430                              <1> 	; INPUT ->
  2431                              <1> 	;	EDI = Directory Buffer Entry Address
  2432                              <1> 	;	 CX = Directory Buffer Entry Counter/Index
  2433                              <1> 	;	 BL = Longname Entry Length
  2434                              <1> 	;	 BH = Logical DOS Drive Number 
  2435                              <1> 
  2436 0000B7CE 29C0                <1> 	sub	eax, eax
  2437 0000B7D0 88FC                <1> 	mov	ah, bh
  2438 0000B7D2 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2439 0000B7D7 01C6                <1> 	add	esi, eax
  2440                              <1> 
  2441 0000B7D9 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  2442 0000B7DD 7312                <1> 	jnb	short loc_del_fat_file 
  2443                              <1>               
  2444 0000B7DF 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  2445 0000B7E3 7406                <1> 	je	short loc_del_fs_file
  2446                              <1> 
  2447                              <1> loc_del_file_invalid_format:
  2448 0000B7E5 30E4                <1> 	xor	ah, ah
  2449                              <1> 	; 15/10/2016 (0Bh -> 28)
  2450 0000B7E7 B01C                <1> 	mov	al, 28  ; Invalid Format
  2451 0000B7E9 F9                  <1> 	stc 
  2452 0000B7EA C3                  <1> 	retn
  2453                              <1> 
  2454                              <1> loc_del_fs_file:
  2455 0000B7EB E83F0F0000          <1> 	call	delete_fs_file
  2456 0000B7F0 C3                  <1> 	retn
  2457                              <1> 
  2458                              <1> loc_del_fat_file:
  2459 0000B7F1 E808000000          <1> 	call	delete_directory_entry
  2460 0000B7F6 7205                <1> 	jc	short loc_del_file_err_retn 
  2461                              <1> 
  2462                              <1> loc_delfile_unlink_cluster_chain:
  2463 0000B7F8 E863170000          <1> 	call	truncate_cluster_chain
  2464                              <1> 	;jc	short loc_del_file_err_retn
  2465                              <1> 
  2466                              <1> loc_delfile_return:
  2467                              <1> loc_del_file_err_retn:
  2468 0000B7FD C3                  <1> 	retn
  2469                              <1> 
  2470                              <1> delete_directory_entry:
  2471                              <1> 	; 15/10/2016
  2472                              <1> 	; 28/02/2016 (TRDOS 386 = TRDOS v2.0)
  2473                              <1> 	; 01/08/2011 (DIR.ASM, 'proc_delete_directory_entry')
  2474                              <1> 	; 10/04/2011 
  2475                              <1> 	; INPUT ->
  2476                              <1> 	; 	ESI = Logical Dos Drive Descripton Table Address 
  2477                              <1> 	;	EDI = Directory Buffer Entry Address
  2478                              <1> 	;	 CX = Directory Buffer Entry Counter/Index
  2479                              <1> 	;	 BL = Longname Entry Length
  2480                              <1> 	; OUTPUT ->
  2481                              <1> 	; 	ESI = Logical dos drive descripton table address 
  2482                              <1> 	;	EAX = First cluster to be truncated/unlinked
  2483                              <1> 	;       CF = 1 -> Error code in EAX (AL)
  2484                              <1> 	;       CF = 0 & BH <> 0 -> LMDT write error  (BH = 1)
  2485                              <1> 	;       CF = 0 & BL <> 0 -> Long name delete error (BL = FFh) 
  2486                              <1> 	;
  2487                              <1> 	;  (EDI, EBX, ECX register contents will be changed)
  2488                              <1> 
  2489 0000B7FE 881D[066E0100]      <1> 	mov	[DelFile_LNEL], bl
  2490 0000B804 66890D[046E0100]    <1> 	mov	[DelFile_EntryCounter], cx
  2491                              <1> 
  2492 0000B80B 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  2493 0000B80F C1E010              <1> 	shl	eax, 16
  2494 0000B812 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  2495                              <1> 
  2496 0000B816 A3[006E0100]        <1> 	mov	[DelFile_FCluster], eax
  2497                              <1> 
  2498                              <1> loc_del_short_name:
  2499 0000B81B C607E5              <1> 	mov	byte [edi], 0E5h  ; Deleted sign
  2500                              <1> 
  2501 0000B81E C605[C46B0100]02    <1> 	mov	byte [DirBuff_ValidData], 2
  2502 0000B825 E85CFCFFFF          <1> 	call	save_directory_buffer
  2503 0000B82A 723D                <1> 	jc	short loc_delete_direntry_err_return
  2504                              <1>  
  2505                              <1> loc_del_long_name:
  2506 0000B82C 0FB615[066E0100]    <1> 	movzx	edx, byte [DelFile_LNEL]
  2507 0000B833 08D2                <1> 	or	dl, dl
  2508 0000B835 7416                <1> 	jz	short loc_del_dir_entry_update_parent_dir_lm_date
  2509                              <1> 
  2510 0000B837 8835[066E0100]      <1> 	mov	byte [DelFile_LNEL], dh ; 0              
  2511                              <1>   
  2512 0000B83D 0FB705[046E0100]    <1> 	movzx	eax,  word [DelFile_EntryCounter]
  2513 0000B844 29D0                <1> 	sub	eax, edx
  2514                              <1> 	;jnc	short loc_del_long_name_continue
  2515 0000B846 7205                <1> 	jc	short loc_del_dir_entry_update_parent_dir_lm_date   
  2516                              <1> 
  2517                              <1> ;loc_del_direntry_inv_data_return: ; 15/10/2016 (0Dh -> 29)
  2518                              <1> ;	mov	eax, 29 ; 0Dh (TRDOS 8086) ; Invalid data
  2519                              <1> ;	retn
  2520                              <1> 
  2521                              <1> loc_del_long_name_continue: 
  2522                              <1> 	; AX = Directory Entry Number of the long name last entry
  2523 0000B848 E897FDFFFF          <1> 	call	delete_longname
  2524                              <1> 	;jc	short loc_delete_direntry_err_return
  2525                              <1> 
  2526                              <1> loc_del_dir_entry_update_parent_dir_lm_date:
  2527 0000B84D 801D[066E0100]00    <1> 	sbb	byte [DelFile_LNEL], 0 ; 0FFh if cf = 1
  2528                              <1> 
  2529 0000B854 E8C8FCFFFF          <1> 	call	update_parent_dir_lmdt
  2530 0000B859 B700                <1> 	mov	bh, 0
  2531 0000B85B 80D700              <1> 	adc	bh, 0
  2532                              <1> 
  2533 0000B85E 8A1D[066E0100]      <1> 	mov	bl, byte [DelFile_LNEL]
  2534                              <1>  
  2535                              <1> loc_delete_direntry_return:
  2536 0000B864 A1[006E0100]        <1> 	mov	eax, [DelFile_FCluster]
  2537                              <1> loc_delete_direntry_err_return:
  2538 0000B869 C3                  <1> 	retn
  2539                              <1> 
  2540                              <1> rename_directory_entry:
  2541                              <1> 	; 13/11/2017
  2542                              <1> 	; 15/10/2016
  2543                              <1> 	; 06/03/2016 (TRDOS 386 = TRDOS v2.0)
  2544                              <1> 	; 01/08/2011 (DIR.ASM, 'proc_rename_directory_entry')
  2545                              <1> 	; 19/11/2010
  2546                              <1> 	; INPUT -> (Current Directory)
  2547                              <1> 	;	CX = Directory Entry Number
  2548                              <1> 	;      EAX = First Cluster number of file or directory
  2549                              <1> 	;      EBX = Longname Length (dir entry count) (< 256)
  2550                              <1> 	;      ESI = New file (or directory) name (no path).
  2551                              <1> 	;           (ASCIIZ string)  
  2552                              <1> 	; OUTPUT -> 
  2553                              <1> 	;      CF = 0 -> successfull
  2554                              <1> 	;      CF = 1 -> error code in EAX (AL)
  2555                              <1> 	;
  2556                              <1> 	; (EAX, EBX, ECX, EDX, ESI, EDI will be changed)
  2557                              <1> 
  2558 0000B86A 803D[9D640100]00    <1> 	cmp	byte [Current_FATType], 0
  2559 0000B871 7706                <1> 	ja	short loc_rename_directory_entry
  2560                              <1> 
  2561 0000B873 E8B80E0000          <1> 	call	rename_fs_file_or_directory
  2562 0000B878 C3                  <1> 	retn 
  2563                              <1> 	
  2564                              <1> loc_rename_directory_entry:
  2565 0000B879 881D[066E0100]      <1> 	mov	[DelFile_LNEL], bl
  2566 0000B87F 66890D[046E0100]    <1> 	mov	[DelFile_EntryCounter], cx
  2567 0000B886 A3[006E0100]        <1> 	mov	[DelFile_FCluster], eax
  2568                              <1> 
  2569 0000B88B 0FB7C1              <1> 	movzx	eax, cx
  2570 0000B88E E8BBFDFFFF          <1> 	call	locate_current_dir_entry
  2571 0000B893 7308                <1> 	jnc	short loc_rename_direntry_check_fcluster
  2572                              <1> 
  2573                              <1> loc_rename_direntry_pop_retn:
  2574 0000B895 C3                  <1> 	retn
  2575                              <1> 
  2576                              <1> loc_rename_direntry_pop_invd_retn:
  2577 0000B896 F9                  <1> 	stc
  2578                              <1> loc_rename_direntry_invd_retn:
  2579                              <1> 	; 15/10/2016 (0Dh -> 29)
  2580 0000B897 B81D000000          <1> 	mov	eax, 29 ; Invalid data
  2581                              <1> loc_rename_retn:
  2582 0000B89C C3                  <1> 	retn 
  2583                              <1> 
  2584                              <1> loc_rename_direntry_check_fcluster:
  2585 0000B89D 668B5714            <1> 	mov	dx, [edi+20] ; First Cluster HW
  2586 0000B8A1 C1E210              <1> 	shl	edx, 16 ; 13/11/2017
  2587 0000B8A4 668B571A            <1> 	mov	dx, [edi+26] ; First Cluster LW
  2588 0000B8A8 3B15[006E0100]      <1> 	cmp	edx, [DelFile_FCluster]
  2589 0000B8AE 75E6                <1> 	jne	short loc_rename_direntry_pop_invd_retn
  2590                              <1> 	; ESI = New file (or directory) name. (ASCIIZ string)
  2591                              <1> 	; 06/03/2016
  2592                              <1> 	; TRDOS v2 - NOTE: 'convert_file_name' procedure
  2593                              <1> 	; has been modified for eliminating following situation.
  2594                              <1> 	; 
  2595                              <1> 	; TRDOS v1 - NOTE: If file/dir name is more than 11 bytes
  2596                              <1> 	; without a dot, attributes (edi+11) byte will be overwritten !
  2597                              <1> 	; (Dot file name input must be proper for 11 byte dir entry
  2598                              <1> 	;  type file name output.) 
  2599 0000B8B0 E8A2F6FFFF          <1> 	call	convert_file_name
  2600                              <1> 
  2601 0000B8B5 C605[C46B0100]02    <1>         mov     byte [DirBuff_ValidData], 2
  2602 0000B8BC E8C5FBFFFF          <1> 	call	save_directory_buffer
  2603 0000B8C1 72D9                <1> 	jc	short loc_rename_retn
  2604                              <1> 
  2605                              <1> loc_rename_direntry_del_ln:
  2606 0000B8C3 0FB615[066E0100]    <1> 	movzx	edx, byte [DelFile_LNEL]
  2607 0000B8CA 08D2                <1> 	or	dl, dl
  2608 0000B8CC 7410                <1> 	jz	short loc_rename_direntry_update_parent_dir_lm_date
  2609                              <1> 
  2610 0000B8CE 0FB705[046E0100]    <1> 	movzx	eax, word [DelFile_EntryCounter]
  2611 0000B8D5 29D0                <1> 	sub	eax, edx
  2612 0000B8D7 72BE                <1> 	jc	short loc_rename_direntry_invd_retn
  2613                              <1> 
  2614                              <1> loc_rename_direntry_del_ln_continue: 
  2615                              <1> 	; EAX = Directory Entry Number of the long name last entry
  2616 0000B8D9 E806FDFFFF          <1> 	call	delete_longname
  2617                              <1> 
  2618                              <1> loc_rename_direntry_update_parent_dir_lm_date:
  2619 0000B8DE E83EFCFFFF          <1> 	call	update_parent_dir_lmdt
  2620 0000B8E3 31C0                <1> 	xor	eax, eax 
  2621 0000B8E5 C3                  <1> 	retn
  2622                              <1> 
  2623                              <1> move_source_file_to_destination_file:
  2624                              <1> 	; 15/10/2016
  2625                              <1> 	; 11/03/2016
  2626                              <1> 	; 10/03/2016 (TRDOS 386 = TRDOS v2.0)
  2627                              <1> 	; 01/08/2011 (FILE.ASM)
  2628                              <1> 	; 04/08/2010
  2629                              <1> 	;
  2630                              <1> 	;   Phase 1 -> Check destination file, 
  2631                              <1> 	;              'not found' is required
  2632                              <1> 	;   Phase 2 -> Check source file
  2633                              <1> 	;              'found' and proper attributes is required
  2634                              <1> 	;   Phase 3 -> Make destination directory entry,
  2635                              <1> 	;           add new dir cluster or section if it is required
  2636                              <1> 	;   Phase 4 -> Delete source directory entry.
  2637                              <1> 	;       cf = 1 causes to return before the phase 4.
  2638                              <1> 	;    (source file protection against any possible errors)    
  2639                              <1> 	;
  2640                              <1> 	; 08/05/2011 major modification
  2641                              <1> 	;            -> destination file deleting is removed   
  2642                              <1> 	;            for msdos move/rename compatibility.
  2643                              <1> 	;            (Access denied error will return if
  2644                              <1> 	;            the destination file is found...)
  2645                              <1> 	; INPUT ->
  2646                              <1> 	;	 ESI = Source File Pathname (Asciiz)
  2647                              <1> 	;        EDI = Destination File Pathname (Asciiz)
  2648                              <1> 	;        AL = 0 --> Interrupt (System call)
  2649                              <1> 	;        AL > 0 --> Command Interpreter (Question)
  2650                              <1> 	;        AL = 1 --> Question Phase
  2651                              <1> 	;        AL = 2 --> Progress Phase        
  2652                              <1> 	; OUTPUT -> 
  2653                              <1> 	;	 cf = 0 -> OK
  2654                              <1> 	;        EAX = Destination directory first cluster
  2655                              <1> 	;        ESI = Logical DOS drive description table 
  2656                              <1> 	;        EBX = Destination file structure offset
  2657                              <1> 	;        CX = 0 (CX > 0 --> calculate free space error)
  2658                              <1> 	;        cf = 1 -> Error code in EAX (AL) 
  2659                              <1> 	;
  2660                              <1> 	;  (EDX, ECX, EBX, ESI, EDI will be changed)
  2661                              <1> 
  2662 0000B8E6 3C02                <1> 	cmp	al, 2
  2663 0000B8E8 0F847F010000        <1> 	je	msftdf_df2_check_directory
  2664 0000B8EE A2[866F0100]        <1> 	mov	[move_cmd_phase], al
  2665                              <1> 
  2666                              <1> msftdf_parse_sf_path:
  2667                              <1> 	; ESI = ASCIIZ pathname (Source)
  2668 0000B8F3 57                  <1> 	push	edi 
  2669 0000B8F4 BF[846E0100]        <1> 	mov	edi, SourceFile_Drv
  2670 0000B8F9 E824F7FFFF          <1> 	call	parse_path_name
  2671 0000B8FE 5E                  <1> 	pop	esi
  2672 0000B8FF 7211                <1> 	jc	short msftdf_psf_retn
  2673                              <1> 
  2674                              <1> msftdf_parse_df_path:
  2675                              <1> 	; ESI = ASCIIZ pathname	(Destination)
  2676 0000B901 BF[046F0100]        <1> 	mov	edi, DestinationFile_Drv
  2677 0000B906 E817F7FFFF          <1> 	call	parse_path_name
  2678 0000B90B 7306                <1> 	jnc	short msftdf_check_sf_drv
  2679                              <1> 
  2680 0000B90D 3C01                <1> 	cmp	al, 1 ; File or directory name is not existing
  2681 0000B90F 7602                <1> 	jna	short msftdf_check_sf_drv
  2682                              <1> 
  2683                              <1> msftdf_stc_retn:
  2684 0000B911 F9                  <1> 	stc
  2685                              <1> msftdf_psf_retn:
  2686 0000B912 C3                  <1> 	retn 
  2687                              <1> 
  2688                              <1> msftdf_check_sf_drv:
  2689 0000B913 A0[846E0100]        <1> 	mov	al, [SourceFile_Drv]
  2690                              <1> 
  2691                              <1> msftdf_check_df_drv:
  2692 0000B918 8A15[046F0100]      <1> 	mov	dl, [DestinationFile_Drv]
  2693                              <1> 
  2694                              <1> msftdf_compare_sf_df_drv:
  2695 0000B91E 29DB                <1> 	sub	ebx, ebx
  2696 0000B920 8A3D[9E640100]      <1> 	mov	bh, [Current_Drv]
  2697 0000B926 38C2                <1> 	cmp	dl, al
  2698 0000B928 7409                <1> 	je	short msftdf_check_sf_df_drv_ok
  2699                              <1> 
  2700                              <1> msftdf_not_same_drv:
  2701                              <1>         ; DL = source file's drive number
  2702 0000B92A 88C6                <1> 	mov	dh, al ; destination file's drive number
  2703                              <1> 	; 15/10/2016 (11h -> 21)
  2704 0000B92C B815000000          <1> 	mov	eax, 21 ; Not the same drive
  2705 0000B931 F9                  <1> 	stc
  2706 0000B932 C3                  <1> 	retn 
  2707                              <1> 
  2708                              <1> msftdf_check_sf_df_drv_ok:
  2709 0000B933 8815[876F0100]      <1> 	mov	[msftdf_sf_df_drv], dl
  2710                              <1> 
  2711 0000B939 29C0                <1>         sub	eax, eax
  2712 0000B93B 88D4                <1> 	mov	ah, dl
  2713 0000B93D 0500010900          <1> 	add	eax, Logical_DOSDisks
  2714 0000B942 A3[886F0100]        <1> 	mov	[msftdf_drv_offset], eax
  2715                              <1> 
  2716 0000B947 38FA                <1> 	cmp	dl, bh ; byte [Current_Drv]
  2717 0000B949 7407                <1> 	je	short msftdf_df_check_directory
  2718                              <1> 
  2719                              <1> msftdf_change_drv:
  2720 0000B94B E85EC1FFFF          <1> 	call 	change_current_drive
  2721 0000B950 726D                <1> 	jc	short msftdf_df_error_retn
  2722                              <1> 	  
  2723                              <1> msftdf_check_destination_file:
  2724                              <1> msftdf_df_check_directory:
  2725 0000B952 BE[056F0100]        <1> 	mov	esi, DestinationFile_Directory
  2726 0000B957 803E20              <1> 	cmp	byte [esi], 20h
  2727 0000B95A 760F                <1> 	jna	short msftdf_df_find_1
  2728                              <1> 
  2729                              <1> msftdf_df_change_directory:
  2730 0000B95C FE05[F6170100]      <1> 	inc	byte [Restore_CDIR]
  2731 0000B962 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2732 0000B964 E8A3F0FFFF          <1> 	call	change_current_directory
  2733 0000B969 7254                <1> 	jc	short msftdf_df_error_retn
  2734                              <1> 
  2735                              <1> ;msftdf_df_change_prompt_dir_string:
  2736                              <1> ;	call 	change_prompt_dir_string
  2737                              <1> 
  2738                              <1> msftdf_df_find_1:
  2739 0000B96B BE[466F0100]        <1>         mov     esi, DestinationFile_Name
  2740 0000B970 803E20              <1> 	cmp	byte [esi], 20h
  2741 0000B973 7631                <1> 	jna	short msftdf_df_copy_sf_name
  2742                              <1> 
  2743                              <1> msftdf_df_find_2:
  2744 0000B975 6631C0              <1> 	xor	ax, ax ; DestinationFile_AttributesMask -> any/zero
  2745 0000B978 E8D4D4FFFF          <1> 	call	find_first_file
  2746 0000B97D 0F838D000000        <1> 	jnc	msftdf_permission_denied_retn
  2747                              <1> 
  2748                              <1> msftdf_df_check_error_code:
  2749                              <1> 	;cmp	eax, 2 ; File not found error
  2750 0000B983 3C02                <1> 	cmp	al, 2
  2751 0000B985 7537                <1> 	jne	short msftdf_df_stc_retn
  2752                              <1>               
  2753                              <1> msftdf_df_check_fname:
  2754                              <1> 	; 15/10/2016
  2755 0000B987 BE[466F0100]        <1> 	mov	esi, DestinationFile_Name ; *
  2756 0000B98C E87ED8FFFF          <1> 	call	check_filename
  2757 0000B991 7307                <1> 	jnc	short msftdf_convert_df_direntry_name
  2758                              <1> 	; invalid file name chars !
  2759 0000B993 B81A000000          <1> 	mov	eax, ERR_INV_FILE_NAME  ; 26
  2760 0000B998 EB24                <1> 	jmp	short msftdf_df_stc_retn
  2761                              <1> 
  2762                              <1> msftdf_convert_df_direntry_name:
  2763                              <1> 	; mov	esi, DestinationFile_Name ; *
  2764 0000B99A BF[566F0100]        <1> 	mov	edi, DestinationFile_DirEntry
  2765 0000B99F E8B3F5FFFF          <1> 	call	convert_file_name
  2766 0000B9A4 EB1A                <1>   	jmp	short msftdf_restore_current_dir_1
  2767                              <1> 
  2768                              <1> msftdf_df_copy_sf_name:
  2769 0000B9A6 89F7                <1> 	mov	edi, esi
  2770 0000B9A8 57                  <1> 	push	edi 
  2771 0000B9A9 BE[C66E0100]        <1>         mov     esi, SourceFile_Name
  2772 0000B9AE B90C000000          <1> 	mov	ecx, 12
  2773                              <1> msftdf_df_copy_sf_name_loop:
  2774 0000B9B3 AC                  <1> 	lodsb
  2775 0000B9B4 AA                  <1>         stosb
  2776 0000B9B5 08C0                <1> 	or	al, al
  2777 0000B9B7 7402                <1> 	jz	short msftdf_df_copy_sf_name_ok	
  2778 0000B9B9 E2F8                <1>         loop    msftdf_df_copy_sf_name_loop
  2779                              <1> msftdf_df_copy_sf_name_ok:	
  2780 0000B9BB 5E                  <1> 	pop	esi  
  2781 0000B9BC EBB7                <1> 	jmp	short msftdf_df_find_2
  2782                              <1> 
  2783                              <1> msftdf_df_stc_retn:
  2784 0000B9BE F9                  <1> 	stc
  2785                              <1> msftdf_restore_cdir_failed:
  2786                              <1> msftdf_df_error_retn:
  2787 0000B9BF C3                  <1> 	retn
  2788                              <1> 
  2789                              <1> msftdf_restore_current_dir_1:
  2790 0000B9C0 803D[F6170100]00    <1> 	cmp	byte [Restore_CDIR], 0
  2791 0000B9C7 760D                <1> 	jna	short msftdf_sf_check_directory
  2792 0000B9C9 8B35[886F0100]      <1> 	mov	esi, [msftdf_drv_offset] 
  2793 0000B9CF E891C1FFFF          <1> 	call	restore_current_directory
  2794 0000B9D4 72E9                <1> 	jc	short msftdf_restore_cdir_failed
  2795                              <1> 
  2796                              <1> msftdf_sf_check_directory:
  2797 0000B9D6 BE[856E0100]        <1> 	mov	esi, SourceFile_Directory
  2798 0000B9DB 803E20              <1> 	cmp	byte [esi], 20h
  2799 0000B9DE 760F                <1> 	jna	short msftdf_sf_find
  2800                              <1> msftdf_sf_change_directory:
  2801 0000B9E0 FE05[F6170100]      <1> 	inc	byte [Restore_CDIR]
  2802 0000B9E6 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2803 0000B9E8 E81FF0FFFF          <1> 	call	change_current_directory
  2804 0000B9ED 7227                <1> 	jc	short msftdf_return
  2805                              <1> 
  2806                              <1> ;msftdf_sf_change_prompt_dir_string:
  2807                              <1> ;	call	change_prompt_dir_string
  2808                              <1> 
  2809                              <1> msftdf_sf_find:
  2810 0000B9EF BE[C66E0100]        <1>         mov     esi, SourceFile_Name  ; Offset 66
  2811 0000B9F4 66B80018            <1> 	mov	ax, 1800h ; Only files
  2812 0000B9F8 E854D4FFFF          <1> 	call	find_first_file
  2813 0000B9FD 7217                <1> 	jc	short msftdf_return
  2814                              <1> 
  2815                              <1> msftdf_sf_ambgfn_check:
  2816 0000B9FF 6609D2              <1> 	or	dx, dx ; Ambiguous filename chars used sign (DX>0)
  2817 0000BA02 7407                <1> 	jz	short msftdf_sf_found
  2818                              <1> 
  2819                              <1> msftdf_ambiguous_file_name_error:
  2820 0000BA04 B802000000          <1> 	mov	eax, 2 ; File not found error
  2821 0000BA09 F9                  <1> 	stc
  2822 0000BA0A C3                  <1> 	retn
  2823                              <1> 
  2824                              <1> msftdf_sf_found:
  2825 0000BA0B 80E31F              <1> 	and	bl, 1Fh ; Attributes, D-V-S-H-R
  2826 0000BA0E 7416                <1> 	jz	short msftdf_save_sf_structure
  2827                              <1> 
  2828                              <1> msftdf_permission_denied_retn:
  2829 0000BA10 B805000000          <1> 	mov	eax, 05h ; Access (Permission) denied !
  2830 0000BA15 F9                  <1> 	stc
  2831                              <1> msftdf_rest_cdir_err_retn:
  2832                              <1> msftdf_return:
  2833 0000BA16 C3                  <1> 	retn
  2834                              <1> 
  2835                              <1> msftdf_phase_1_return:
  2836 0000BA17 31C0                <1> 	xor	eax, eax
  2837 0000BA19 A2[866F0100]        <1> 	mov	[move_cmd_phase], al ; 0
  2838 0000BA1E FEC0                <1> 	inc	al ; mov al, 1
  2839 0000BA20 BB[6DBA0000]        <1> 	mov	ebx, msftdf_df2_check_directory
  2840                              <1> 	;mov	edx, 0FFFFFFFFh 
  2841 0000BA25 C3                  <1> 	retn
  2842                              <1> 
  2843                              <1> msftdf_save_sf_structure:
  2844 0000BA26 BE[906D0100]        <1> 	mov	esi, FindFile_DirEntry
  2845 0000BA2B BF[D66E0100]        <1> 	mov	edi, SourceFile_DirEntry
  2846 0000BA30 B908000000          <1> 	mov	ecx, 8
  2847 0000BA35 F3A5                <1> 	rep	movsd
  2848                              <1> 
  2849                              <1> msftdf_df_copy_sf_parameters:
  2850 0000BA37 BE0B000000          <1> 	mov	esi, 11
  2851 0000BA3C 89F7                <1> 	mov	edi, esi
  2852 0000BA3E 81C6[D66E0100]      <1> 	add	esi, SourceFile_DirEntry
  2853 0000BA44 81C7[566F0100]      <1> 	add	edi, DestinationFile_DirEntry
  2854                              <1> 	;mov	ecx, 21
  2855 0000BA4A B115                <1> 	mov	cl, 21
  2856 0000BA4C F3A4                <1> 	rep	movsb
  2857                              <1> 
  2858                              <1> msftdf_restore_current_dir_2:
  2859 0000BA4E 803D[F6170100]00    <1> 	cmp	byte [Restore_CDIR], 0
  2860 0000BA55 760D                <1> 	jna	short msftdf_df2_check_move_cmd_phase
  2861 0000BA57 8B35[886F0100]      <1>  	mov	esi, [msftdf_drv_offset]
  2862 0000BA5D E803C1FFFF          <1> 	call	restore_current_directory
  2863 0000BA62 72B2                <1> 	jc	short msftdf_rest_cdir_err_retn
  2864                              <1> 
  2865                              <1> msftdf_df2_check_move_cmd_phase:
  2866 0000BA64 803D[866F0100]01    <1> 	cmp	byte [move_cmd_phase], 1
  2867 0000BA6B 74AA                <1> 	je	short msftdf_phase_1_return
  2868                              <1> 
  2869                              <1> msftdf_df2_check_directory:
  2870 0000BA6D BE[056F0100]        <1> 	mov	esi, DestinationFile_Directory
  2871 0000BA72 803E20              <1> 	cmp	byte [esi], 20h
  2872 0000BA75 760F                <1> 	jna	short msftdf_make_dfde_locate_ffe_on_directory
  2873                              <1> msftdf_df2_change_directory:
  2874 0000BA77 FE05[F6170100]      <1> 	inc	byte [Restore_CDIR]
  2875 0000BA7D 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2876 0000BA7F E888EFFFFF          <1> 	call	change_current_directory
  2877 0000BA84 7290                <1> 	jc	short msftdf_return
  2878                              <1> 
  2879                              <1> ;msftdf_df2_change_prompt_dir_string:
  2880                              <1> ;	call	change_prompt_dir_string
  2881                              <1> 
  2882                              <1> msftdf_make_dfde_locate_ffe_on_directory:
  2883                              <1> 	; Current directory fcluster <> Directory buffer cluster
  2884                              <1> 	; Current directory will be reloaded by
  2885                              <1> 	; 'locate_current_dir_file' procedure
  2886                              <1> 	;
  2887                              <1> 	;xor	ax, ax
  2888 0000BA86 31C0                <1> 	xor	eax, eax
  2889 0000BA88 89C1                <1> 	mov	ecx, eax
  2890 0000BA8A 6649                <1> 	dec	cx ; FFFFh  
  2891                              <1> 		; CX = FFFFh -> find first deleted or free entry
  2892                              <1> 		; ESI would be ASCIIZ filename address if the call
  2893                              <1> 		; would not be for first free or deleted dir entry  
  2894 0000BA8C E8CFF1FFFF          <1> 	call	locate_current_dir_file
  2895 0000BA91 733F                <1> 	jnc	msftdf_make_dfde_set_ff_dir_entry
  2896                              <1> 	
  2897                              <1> 	;cmp	eax, 2
  2898 0000BA93 3C02                <1>         cmp	al, 2
  2899 0000BA95 7537                <1> 	jne	short msftdf_error_retn
  2900                              <1> 
  2901                              <1> msftdf_add_new_dir_entry_check_fs:
  2902 0000BA97 8B35[886F0100]      <1> 	mov	esi, [msftdf_drv_offset]
  2903 0000BA9D A1[C96B0100]        <1> 	mov 	eax, [DirBuff_Cluster]
  2904 0000BAA2 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  2905 0000BAA6 7711                <1> 	ja	short msftdf_add_new_subdir_cluster
  2906                              <1> 
  2907                              <1> msftdf_add_new_fs_subdir_section:
  2908                              <1> 	;CL=0, CH=E5h --> deleted entry, CH=0 --> free entry
  2909                              <1>         ;xor	cx, cx
  2910 0000BAA8 30ED                <1> 	xor	ch, ch ; cx = 0 --> add a new subdir section
  2911 0000BAAA E8830C0000          <1> 	call	add_new_fs_section
  2912 0000BAAF 721E                <1>         jc	short msftdf_dsfde_error_retn
  2913                              <1> 	;mov	[createfile_LastDirCluster], eax
  2914                              <1> 
  2915 0000BAB1 E8A30E0000          <1> 	call	load_FS_sub_directory 
  2916                              <1> 	;mov	ebx, Directory_Buffer 
  2917 0000BAB6 7318                <1> 	jnc	short msftdf_add_new_fs_subdir_section_ok
  2918 0000BAB8 C3                  <1> 	retn	 
  2919                              <1> 
  2920                              <1> msftdf_add_new_subdir_cluster:
  2921 0000BAB9 E881150000          <1> 	call	add_new_cluster
  2922 0000BABE 720F                <1> 	jc	short msftdf_dsfde_error_retn
  2923                              <1> 	
  2924                              <1> 	;mov	[createfile_LastDirCluster], eax
  2925                              <1> 
  2926 0000BAC0 E8570E0000          <1> 	call	load_FAT_sub_directory
  2927 0000BAC5 7309                <1> 	jnc	short msftdf_add_new_subdir_cluster_ok
  2928                              <1> 	; EBX = Directory buffer address
  2929                              <1> 
  2930                              <1> msftdf_ansdc_update_parent_dir_lmdt:
  2931                              <1> msftdf_make_dfde_err_upd_pdir_lmdt:
  2932 0000BAC7 50                  <1> 	push	eax
  2933 0000BAC8 E854FAFFFF          <1> 	call	update_parent_dir_lmdt
  2934 0000BACD 58                  <1> 	pop	eax
  2935                              <1> 
  2936                              <1> msftdf_error_retn:
  2937 0000BACE F9                  <1> 	stc
  2938                              <1> msftdf_dsfde_restore_cdir_failed:
  2939                              <1> msftdf_dsfde_error_retn:
  2940 0000BACF C3                  <1> 	retn
  2941                              <1> 
  2942                              <1> msftdf_add_new_fs_subdir_section_ok:
  2943                              <1> msftdf_add_new_subdir_cluster_ok:
  2944 0000BAD0 89DF                <1> 	mov	edi, ebx ; Directory buffer address
  2945                              <1> 
  2946                              <1> msftdf_make_dfde_set_ff_dir_entry:
  2947 0000BAD2 8B15[98640100]      <1> 	mov	edx, [Current_Dir_FCluster]
  2948 0000BAD8 8915[EC6F0100]      <1> 	mov	[createfile_FFCluster], edx
  2949                              <1> 	; EDI = Directory entry offset
  2950 0000BADE BE[566F0100]        <1> 	mov	esi, DestinationFile_DirEntry
  2951 0000BAE3 B908000000          <1> 	mov	ecx, 8
  2952 0000BAE8 F3A5                <1> 	rep	movsd
  2953                              <1> 
  2954 0000BAEA C605[C46B0100]02    <1> 	mov	byte [DirBuff_ValidData], 2 
  2955 0000BAF1 E890F9FFFF          <1> 	call	save_directory_buffer
  2956 0000BAF6 72CF                <1> 	jc	short msftdf_make_dfde_err_upd_pdir_lmdt
  2957                              <1> 
  2958                              <1> msftdf_make_dfde_update_pdir_lmdt:
  2959 0000BAF8 E824FAFFFF          <1> 	call	update_parent_dir_lmdt
  2960                              <1> 
  2961                              <1> msftdf_dsfde_restore_current_dir_1:
  2962 0000BAFD 803D[F6170100]00    <1> 	cmp	byte [Restore_CDIR], 0
  2963 0000BB04 760D                <1> 	jna	short msftdf_dsfde_check_directory
  2964 0000BB06 8B35[886F0100]      <1>  	mov	esi, [msftdf_drv_offset]
  2965 0000BB0C E854C0FFFF          <1> 	call	restore_current_directory
  2966 0000BB11 72BC                <1> 	jc	short msftdf_dsfde_restore_cdir_failed
  2967                              <1> 
  2968                              <1> msftdf_dsfde_check_directory:
  2969 0000BB13 BE[856E0100]        <1> 	mov	esi, SourceFile_Directory
  2970 0000BB18 803E20              <1> 	cmp	byte [esi], 20h
  2971 0000BB1B 760F                <1> 	jna	short msftdf_dsfde_find_file
  2972                              <1> 
  2973                              <1> msftdf_dsfde_change_directory:
  2974 0000BB1D FE05[F6170100]      <1> 	inc	byte [Restore_CDIR]
  2975 0000BB23 28E4                <1> 	sub	ah, ah ; CD_COMMAND sign -> 0 
  2976 0000BB25 E8E2EEFFFF          <1> 	call	change_current_directory
  2977 0000BB2A 72A3                <1> 	jc	short msftdf_dsfde_error_retn
  2978                              <1> 
  2979                              <1> ;msftdf_dsfde_sf_change_prompt_dir_string:
  2980                              <1> ;	call	change_prompt_dir_string
  2981                              <1> 
  2982                              <1> msftdf_dsfde_find_file:
  2983 0000BB2C BE[C66E0100]        <1> 	mov	esi, SourceFile_Name  ; Offset 66
  2984 0000BB31 668B460E            <1> 	mov	ax, [esi+14] ; 80 -> SourceFile_AttributesMask
  2985 0000BB35 E817D3FFFF          <1> 	call	find_first_file
  2986 0000BB3A 7293                <1> 	jc	short msftdf_dsfde_error_retn
  2987                              <1> 
  2988                              <1> msftdf_dsfde_delete_direntry:
  2989 0000BB3C 8B35[886F0100]      <1> 	mov	esi, [msftdf_drv_offset]
  2990                              <1> 	
  2991 0000BB42 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  2992 0000BB46 770A                <1> 	ja	short msftdf_delete_FAT_direntry
  2993                              <1> 	
  2994 0000BB48 30DB                <1> 	xor	bl, bl
  2995                              <1> 	; BL = 0 -> File
  2996                              <1> 	; EDI -> Directory buffer entry offset/address 
  2997 0000BB4A E8E40B0000          <1> 	call	delete_fs_directory_entry
  2998 0000BB4F 7315                <1> 	jnc	short msftdf_dsfde_restore_current_dir_2
  2999 0000BB51 C3                  <1> 	retn
  3000                              <1> 
  3001                              <1> msftdf_delete_FAT_direntry:	
  3002 0000BB52 8A1D[8D6D0100]      <1> 	mov	bl, [FindFile_LongNameEntryLength]
  3003 0000BB58 668B0D[B86D0100]    <1> 	mov	cx, [FindFile_DirEntryNumber]
  3004                              <1> 	; ESI = Logical DOS drive description table address
  3005                              <1> 	; EDI = Directory buffer entry offset/address 
  3006 0000BB5F E89AFCFFFF          <1> 	call	delete_directory_entry
  3007 0000BB64 721C                <1> 	jc	short msftdf_retn
  3008                              <1> 
  3009                              <1> msftdf_dsfde_restore_current_dir_2:
  3010 0000BB66 803D[F6170100]00    <1> 	cmp	byte [Restore_CDIR], 0
  3011 0000BB6D 7607                <1> 	jna	short msftdf_new_dir_fcluster_retn
  3012                              <1> 	;mov	esi, [msftdf_drv_offset]
  3013 0000BB6F E8F1BFFFFF          <1> 	call	restore_current_directory
  3014 0000BB74 720C                <1> 	jc	short msftdf_retn
  3015                              <1> 
  3016                              <1> msftdf_new_dir_fcluster_retn:
  3017 0000BB76 31C9                <1> 	xor	ecx, ecx 
  3018 0000BB78 A1[EC6F0100]        <1> 	mov	eax, [createfile_FFCluster]
  3019 0000BB7D BB[046F0100]        <1> 	mov	ebx, DestinationFile_Drv
  3020                              <1> 
  3021                              <1> msftdf_retn:
  3022 0000BB82 C3                  <1> 	retn
  3023                              <1> 
  3024                              <1> 
  3025                              <1> copy_source_file_to_destination_file:
  3026                              <1> 	; 17/10/2016
  3027                              <1> 	; 16/10/2016
  3028                              <1> 	; 15/10/2016
  3029                              <1> 	; 30/03/2016, 31/03/2016
  3030                              <1> 	; 24/03/2016, 25/03/2016, 28/03/2016
  3031                              <1> 	; 21/03/2016, 22/03/2016, 23/03/2016
  3032                              <1> 	; 16/03/2016, 17/03/2016, 18/03/2016
  3033                              <1> 	; 15/03/2016 (TRDOS 386 = TRDOS v2.0)
  3034                              <1> 	; 02/09/2011 (FILE.ASM 'copy_source_file_to_destination_file')
  3035                              <1> 	; 01/08/2010 - 18/05/2011
  3036                              <1> 	;
  3037                              <1> 	;   Command Interpreter phase 1 enter ->
  3038                              <1> 	;           AL = 1 -> Caller is command interpreter
  3039                              <1> 	;           AL = 2 -> The second call, re-enter/continue
  3040                              <1> 	;   Phase 1 -> Check source file
  3041                              <1> 	;              'found' is required
  3042                              <1> 	;   Phase 2 -> Check destination file, 
  3043                              <1> 	;              save 'found' or 'not found' status
  3044                              <1> 	;              'permission denied' error will be return
  3045                              <1> 	;              if attributes have not for ordinary file 
  3046                              <1> 	;              without readonly attribute
  3047                              <1> 	;   Command Interpreter phase 1 return ->
  3048                              <1> 	;              DH = Source file attributes
  3049                              <1> 	;              DL = Destination file found status
  3050                              <1> 	;              EAX = 0 
  3051                              <1> 	;   Command Interpreter phase 2 enter ->
  3052                              <1> 	;              AL = 2 -> Continue from the last position
  3053                              <1> 	;              AH = 
  3054                              <1> 	;   Phase 3 -> Load source file or use read/write cluster method
  3055                              <1> 	;   Phase 4 -> Create destination file if it is not found
  3056                              <1> 	;   Phase 5 -> Open destination file
  3057                              <1> 	;   Phase 6 -> Read from source and write to destination
  3058                              <1> 	;   Phase 7 -> Unload source file, if it is loaded at memory
  3059                              <1> 	;       cf = 1 causes to return before the phase 7
  3060                              <1> 	;              but loaded file will be unloaded
  3061                              <1> 	;	       (allocated memory block will be deallocated) 
  3062                              <1> 	;
  3063                              <1> 	; INPUT -> 
  3064                              <1> 	;	 ESI = Source File Pathname (Asciiz)
  3065                              <1> 	;        EDI = Destination File Pathname (Asciiz)
  3066                              <1> 	;        AL = 0 --> Interrupt (System call)
  3067                              <1> 	;        AL > 0 --> Command Interpreter (Question)
  3068                              <1> 	;        AL = 1 --> Question Phase
  3069                              <1> 	;        AL = 2 --> Progress Phase        
  3070                              <1> 	;
  3071                              <1> 	; OUTPUT -> 
  3072                              <1> 	;	cf = 0 -> OK
  3073                              <1> 	;	EAX = Destination file first cluster
  3074                              <1> 	;
  3075                              <1> 	;        CL > 0 if there is file reading error before EOF
  3076                              <1> 	;	        (incomplete copy) 
  3077                              <1> 	;        CH > 0 if file is (full) loaded at memory
  3078                              <1> 	;
  3079                              <1> 	;	cf = 1 -> Error code in AL (EAX) 
  3080                              <1> 	;
  3081                              <1> 	; (EBX, ECX, ESI, EDI register contents will be changed)           
  3082                              <1> 
  3083                              <1> 
  3084 0000BB83 3C02                <1> 	cmp	al, 2
  3085 0000BB85 0F845A020000        <1> 	je	csftdf2_check_cdrv
  3086                              <1> 
  3087                              <1> ; Phase 1
  3088                              <1> 
  3089 0000BB8B A2[AC6F0100]        <1> 	mov	byte [copy_cmd_phase], al
  3090                              <1> 
  3091 0000BB90 57                  <1> 	push	edi ; *
  3092                              <1> 
  3093                              <1> csftdf_parse_sf_path:
  3094 0000BB91 BF[846E0100]        <1> 	mov	edi, SourceFile_Drv
  3095 0000BB96 E887F4FFFF          <1> 	call	parse_path_name
  3096 0000BB9B 721C                <1> 	jc	short csftdf_parse_sf_path_failed
  3097                              <1> 
  3098                              <1> csftdf_parse_df_path:	
  3099 0000BB9D 5E                  <1> 	pop	esi ; * (pushed edi) 
  3100                              <1> 
  3101                              <1> csftdf_sf_check_filename_exists:
  3102 0000BB9E 803D[C66E0100]21    <1> 	cmp	byte [SourceFile_Name], 21h
  3103 0000BBA5 7215                <1> 	jb	short csftdf_sf_file_not_found_error
  3104                              <1> 
  3105 0000BBA7 BF[046F0100]        <1> 	mov	edi, DestinationFile_Drv
  3106 0000BBAC E871F4FFFF          <1> 	call	parse_path_name
  3107 0000BBB1 7310                <1> 	jnc	short csftdf_check_sf_cdrv
  3108                              <1> 	
  3109 0000BBB3 3C01                <1> 	cmp	al, 1 ; File or directory name is not existing
  3110 0000BBB5 760C                <1> 	jna	short csftdf_check_sf_cdrv
  3111                              <1> 
  3112                              <1> csftdf_parse_df_path_failed:
  3113 0000BBB7 F9                  <1> 	stc 
  3114                              <1> csftdf_sf_error_retn: 
  3115 0000BBB8 C3                  <1> 	retn
  3116                              <1> 
  3117                              <1> csftdf_parse_sf_path_failed:	
  3118 0000BBB9 5F                  <1> 	pop	edi ; *
  3119 0000BBBA EBFC                <1> 	jmp	short csftdf_sf_error_retn
  3120                              <1> 
  3121                              <1> csftdf_sf_file_not_found_error:
  3122 0000BBBC B802000000          <1> 	mov	eax, 2 ; File not found 
  3123 0000BBC1 EBF5                <1> 	jmp	short csftdf_sf_error_retn
  3124                              <1> 
  3125                              <1> csftdf_check_sf_cdrv:
  3126 0000BBC3 8A3D[9E640100]      <1> 	mov	bh, [Current_Drv]
  3127                              <1> 
  3128 0000BBC9 883D[AF6F0100]      <1> 	mov	[csftdf_cdrv], bh ; 23/03/2016
  3129                              <1> 
  3130 0000BBCF 8A15[846E0100]      <1> 	mov	dl, [SourceFile_Drv]
  3131 0000BBD5 38FA                <1> 	cmp	dl, bh ; byte [Current_Drv]
  3132 0000BBD7 7407                <1> 	je	short csftdf_sf_check_directory
  3133                              <1> 
  3134 0000BBD9 E8D0BEFFFF          <1> 	call	change_current_drive
  3135 0000BBDE 72D8                <1> 	jc	short csftdf_sf_error_retn
  3136                              <1> 
  3137                              <1> csftdf_sf_check_directory:
  3138 0000BBE0 BE[856E0100]        <1> 	mov	esi, SourceFile_Directory
  3139 0000BBE5 803E20              <1> 	cmp	byte [esi], 20h
  3140 0000BBE8 760F                <1> 	jna	short csftdf_find_sf
  3141                              <1> 
  3142                              <1> csftdf_sf_change_directory:
  3143 0000BBEA FE05[F6170100]      <1> 	inc	byte [Restore_CDIR]
  3144 0000BBF0 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3145 0000BBF2 E815EEFFFF          <1> 	call	change_current_directory
  3146 0000BBF7 72BF                <1> 	jc	short csftdf_sf_error_retn
  3147                              <1> 
  3148                              <1> ;csftdf_sf_change_prompt_dir_string:
  3149                              <1> ;	call	change_prompt_dir_string
  3150                              <1> 
  3151                              <1> csftdf_find_sf:
  3152 0000BBF9 BE[C66E0100]        <1> 	mov	esi, SourceFile_Name
  3153 0000BBFE 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  3154 0000BC02 E84AD2FFFF          <1> 	call	find_first_file
  3155 0000BC07 72AF                <1> 	jc	short csftdf_sf_error_retn
  3156                              <1> 
  3157                              <1> csftdf_sf_ambgfn_check:
  3158 0000BC09 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3159 0000BC0C 7407                <1> 	jz	short csftdf_sf_found
  3160                              <1> 
  3161                              <1> csftdf_ambiguous_file_name_error:
  3162 0000BC0E B802000000          <1> 	mov	eax, 2 ; File not found error
  3163 0000BC13 F9                  <1> 	stc
  3164 0000BC14 C3                  <1> 	retn
  3165                              <1> 
  3166                              <1> csftdf_sf_found:
  3167 0000BC15 A3[B06F0100]        <1> 	mov	[csftdf_filesize], eax
  3168                              <1> 
  3169 0000BC1A 09C0                <1> 	or	eax, eax
  3170 0000BC1C 7507                <1> 	jnz	short csftdf_set_source_file_direntry
  3171                              <1> 
  3172                              <1> csftdf_sf_file_size_zero:
  3173 0000BC1E B814000000          <1> 	mov	eax, 20 ; TRDOS zero length (file size) error
  3174 0000BC23 F9                  <1> 	stc
  3175 0000BC24 C3                  <1> 	retn
  3176                              <1> 
  3177                              <1> csftdf_set_source_file_direntry:
  3178 0000BC25 BE[906D0100]        <1> 	mov	esi, FindFile_DirEntry
  3179 0000BC2A BF[D66E0100]        <1> 	mov	edi, SourceFile_DirEntry
  3180 0000BC2F B908000000          <1> 	mov	ecx, 8
  3181 0000BC34 F3A5                <1> 	rep	movsd
  3182                              <1> 
  3183                              <1> csftdf_sf_restore_cdrv:
  3184                              <1> 	; 22/03/2016
  3185 0000BC36 8A15[AF6F0100]      <1> 	mov	dl, [csftdf_cdrv]
  3186 0000BC3C 3A15[9E640100]      <1> 	cmp	dl, [Current_Drv]
  3187 0000BC42 7407                <1> 	je	short csftdf_sf_restore_cdir
  3188 0000BC44 E865BEFFFF          <1> 	call	change_current_drive 
  3189 0000BC49 724F                <1> 	jc	short csftdf_df_error_retn ; 30/03/2016
  3190                              <1> 
  3191                              <1> csftdf_sf_restore_cdir:
  3192 0000BC4B 803D[F6170100]00    <1> 	cmp	byte [Restore_CDIR], 0
  3193 0000BC52 7612                <1> 	jna	short csftdf_df_check_filename_exists
  3194 0000BC54 29C0                <1> 	sub	eax, eax
  3195 0000BC56 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3196 0000BC5B 88D4                <1> 	mov	ah, dl ; byte [csftdf_cdrv]
  3197 0000BC5D 01C6                <1> 	add	esi, eax
  3198 0000BC5F E801BFFFFF          <1> 	call	restore_current_directory
  3199 0000BC64 7234                <1> 	jc	short csftdf_df_error_retn
  3200                              <1>   
  3201                              <1> csftdf_df_check_filename_exists:
  3202 0000BC66 803D[466F0100]20    <1> 	cmp	byte [DestinationFile_Name], 20h
  3203 0000BC6D 7716                <1> 	ja	short csftdf_check_df_cdrv
  3204                              <1> 
  3205                              <1> csftdf_copy_sf_name:
  3206 0000BC6F BF[466F0100]        <1> 	mov	edi, DestinationFile_Name
  3207 0000BC74 BE[C66E0100]        <1> 	mov	esi, SourceFile_Name
  3208 0000BC79 B10C                <1> 	mov	cl, 12
  3209                              <1> 
  3210                              <1> csftdf_df_copy_sf_name_loop:
  3211 0000BC7B AC                  <1> 	lodsb
  3212 0000BC7C AA                  <1> 	stosb
  3213 0000BC7D 08C0                <1> 	or	al, al
  3214 0000BC7F 7404                <1> 	jz	short csftdf_check_df_cdrv             
  3215 0000BC81 FEC9                <1> 	dec	cl
  3216 0000BC83 75F6                <1> 	jnz	csftdf_df_copy_sf_name_loop
  3217                              <1> 
  3218                              <1> csftdf_check_df_cdrv:
  3219 0000BC85 8A15[046F0100]      <1> 	mov	dl, [DestinationFile_Drv]
  3220 0000BC8B 3A15[9E640100]      <1> 	cmp	dl, [Current_Drv]
  3221 0000BC91 7408                <1> 	je	short csftdf_df_check_directory
  3222                              <1> 
  3223 0000BC93 E816BEFFFF          <1> 	call	change_current_drive
  3224 0000BC98 7301                <1> 	jnc	short csftdf_df_check_directory
  3225                              <1> 
  3226                              <1> csftdf_df_error_retn:
  3227 0000BC9A C3                  <1> 	retn
  3228                              <1> 
  3229                              <1> csftdf_df_check_directory:
  3230 0000BC9B BE[056F0100]        <1> 	mov	esi, DestinationFile_Directory
  3231 0000BCA0 803E20              <1>         cmp     byte [esi], 20h
  3232 0000BCA3 760F                <1> 	jna	short csftdf_find_df
  3233                              <1> 
  3234                              <1> csftdf_df_change_directory:
  3235 0000BCA5 FE05[F6170100]      <1> 	inc	byte [Restore_CDIR]
  3236 0000BCAB 28E4                <1> 	sub	ah, ah ; CD_COMMAND sign -> 0 
  3237 0000BCAD E85AEDFFFF          <1> 	call	change_current_directory
  3238 0000BCB2 72E6                <1> 	jc	short csftdf_df_error_retn
  3239                              <1> 
  3240                              <1> ;csftdf_df_change_prompt_dir_string:
  3241                              <1> ;	call	change_prompt_dir_string
  3242                              <1> 
  3243                              <1> csftdf_find_df:
  3244                              <1> 	; 23/03/2016
  3245 0000BCB4 29DB                <1> 	sub	ebx, ebx
  3246 0000BCB6 8A3D[046F0100]      <1> 	mov	bh,  [DestinationFile_Drv]
  3247 0000BCBC 81C300010900        <1> 	add	ebx, Logical_DOSDisks
  3248 0000BCC2 891D[DC6F0100]      <1> 	mov	[csftdf_df_drv_dt], ebx
  3249                              <1> 
  3250 0000BCC8 BE[466F0100]        <1> 	mov	esi, DestinationFile_Name
  3251 0000BCCD 6631C0              <1> 	xor	ax, ax 
  3252                              <1> 		; DestinationFile_AttributesMask -> any/zero
  3253 0000BCD0 E87CD1FFFF          <1> 	call	find_first_file
  3254 0000BCD5 7218                <1> 	jc	short csftdf_df_check_error_code
  3255                              <1> 
  3256                              <1> csftdf_df_ambgfn_check:
  3257 0000BCD7 6609D2              <1> 	or	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3258 0000BCDA 752A                <1> 	jnz	short csftdf_df_error_inv_fname
  3259                              <1> 	
  3260                              <1> csftdf_df_found:
  3261 0000BCDC C605[AE6F0100]01    <1> 	mov	byte [DestinationFileFound], 1
  3262                              <1> 	; 17/10/2016 (cl -> bl)
  3263 0000BCE3 80E31F              <1> 	and	bl, 1Fh ; Attributes, D-V-S-H-R
  3264 0000BCE6 745F                <1> 	jz	short csftdf_df_save_first_cluster
  3265                              <1> 
  3266                              <1> csftdf_df_permission_denied_retn:	 
  3267 0000BCE8 B805000000          <1> 	mov	eax, 05h ; Access/Permission denied.
  3268                              <1> csftdf_df_error_stc_retn:
  3269 0000BCED F9                  <1> 	stc
  3270 0000BCEE C3                  <1> 	retn
  3271                              <1> 
  3272                              <1> csftdf_df_check_error_code:
  3273                              <1> 	;cmp	eax, 2
  3274 0000BCEF 3C02                <1> 	cmp	al, 2
  3275 0000BCF1 75FA                <1> 	jne	short csftdf_df_error_stc_retn
  3276                              <1> 
  3277 0000BCF3 C605[AE6F0100]00    <1> 	mov	byte [DestinationFileFound], 0
  3278                              <1> 
  3279                              <1> 	; 15/10/2016
  3280 0000BCFA BE[806D0100]        <1> 	mov	esi, FindFile_Name ; *
  3281 0000BCFF E80BD5FFFF          <1> 	call	check_filename
  3282 0000BD04 7307                <1> 	jnc	short csftdf_df_valid_fname
  3283                              <1> csftdf_df_error_inv_fname: ; 'invalid file name !'
  3284 0000BD06 B81A000000          <1> 	mov 	eax, ERR_INV_FILE_NAME  ; 26
  3285 0000BD0B F9                  <1> 	stc	
  3286 0000BD0C C3                  <1> 	retn
  3287                              <1> 
  3288                              <1> csftdf_df_valid_fname:	
  3289                              <1> 	; 21/03/2016
  3290                              <1> 	; (Capitalized file name)
  3291                              <1> 	;mov	esi, FindFile_Name ; * ; 15/10/2016
  3292 0000BD0D BF[466F0100]        <1> 	mov	edi, DestinationFile_Name
  3293 0000BD12 A5                  <1> 	movsd
  3294 0000BD13 A5                  <1> 	movsd	
  3295 0000BD14 A5                  <1> 	movsd
  3296                              <1> 	;movsb
  3297                              <1> 
  3298                              <1> csftdf_check_disk_free_size_0:
  3299 0000BD15 A1[F26E0100]        <1> 	mov	eax, [SourceFile_DirEntry+DirEntry_FileSize]
  3300                              <1> 
  3301                              <1> csftdf_check_disk_free_size_1:
  3302                              <1> 	;sub	ebx, ebx
  3303                              <1> 	;mov 	esi, Logical_DOSDisks
  3304                              <1> 	;mov	bh,  [DestinationFile_Drv]
  3305                              <1> 	;add	esi, ebx
  3306                              <1> 	
  3307 0000BD1A 8B35[DC6F0100]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 23/03/2016
  3308                              <1> 
  3309 0000BD20 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec] ; 17, LD_BPB + 0Bh
  3310 0000BD24 01C8                <1> 	add	eax, ecx
  3311 0000BD26 48                  <1> 	dec	eax  ; file size (additional bytes) + 511 (round up)
  3312                              <1> csftdf_check_disk_free_size_3: ; 16/03/2016
  3313 0000BD27 29D2                <1> 	sub	edx, edx
  3314 0000BD29 F7F1                <1> 	div	ecx ; bytes per sector
  3315                              <1> 
  3316                              <1> csftdf_check_disk_free_size:
  3317 0000BD2B 3B4674              <1> 	cmp	eax, [esi+LD_FreeSectors]
  3318 0000BD2E 0F8294000000        <1>         jb      csftdf_check_disk_free_size_ok
  3319 0000BD34 770A                <1> 	ja	short csftdf_df_insufficient_disk_space
  3320                              <1> 
  3321 0000BD36 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0 ; FS needs FDT sector also.
  3322 0000BD3A 0F8788000000        <1>         ja      csftdf_check_disk_free_size_ok 
  3323                              <1> 
  3324                              <1> csftdf_df_insufficient_disk_space:
  3325 0000BD40 B827000000          <1> 	mov	eax, 27h ; insufficient disk space
  3326 0000BD45 EBA6                <1> 	jmp	short csftdf_df_error_stc_retn
  3327                              <1> 
  3328                              <1> csftdf_df_save_first_cluster:
  3329                              <1> 	; ESI = FindFile_DirEntry (for the old destination file)
  3330                              <1> 	; EAX = Old destination file size
  3331                              <1> 	; 24/03/2016
  3332                              <1> 	; EDI = Directory entry address (within Dir Buffer boundaries)
  3333 0000BD47 81EF00000800        <1> 	sub	edi, Directory_Buffer  ; (<65536)
  3334 0000BD4D 66C1EF05            <1> 	shr	di, 5 ; Convert entry offset to entry index/number
  3335 0000BD51 66893D[7E6F0100]    <1> 	mov	[DestinationFile_DirEntryNumber], di ; (<2048)
  3336                              <1> 
  3337                              <1> csftdf_df_check_sf_df_fcluster:
  3338 0000BD58 668B5614            <1> 	mov	dx, [esi+DirEntry_FstClusHI]
  3339 0000BD5C C1E210              <1> 	shl	edx, 16
  3340 0000BD5F 668B561A            <1> 	mov	dx, [esi+DirEntry_FstClusLO]
  3341 0000BD63 8915[C06F0100]      <1> 	mov	[csftdf_df_cluster], edx
  3342                              <1> csftdf_df_check_sf_df_fcluster_1:
  3343 0000BD69 668B15[EA6E0100]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusHI]
  3344 0000BD70 C1E210              <1> 	shl	edx, 16
  3345 0000BD73 668B15[F06E0100]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusLO]
  3346 0000BD7A 3B15[C06F0100]      <1> 	cmp	edx, [csftdf_df_cluster]
  3347 0000BD80 7512                <1> 	jne	short csftdf_df_check_sf_df_fcluster_ok
  3348                              <1> csftdf_df_check_sf_df_drv:
  3349 0000BD82 8A15[846E0100]      <1> 	mov	dl, [SourceFile_Drv]
  3350 0000BD88 3A15[046F0100]      <1> 	cmp	dl, [DestinationFile_Drv]
  3351 0000BD8E 7504                <1> 	jne	short csftdf_df_check_sf_df_fcluster_ok
  3352                              <1> 
  3353                              <1> 	; source and destination files are same !
  3354                              <1> 	; (they have same first cluster value on same logical disk)
  3355                              <1> 
  3356 0000BD90 31C0                <1> 	xor	eax, eax ; mov eax, 0 -> Bad command or file name !
  3357 0000BD92 F9                  <1> 	stc
  3358 0000BD93 C3                  <1> 	retn 
  3359                              <1>    
  3360                              <1> csftdf_df_check_sf_df_fcluster_ok:
  3361                              <1> csftdf_df_move_findfile_struct:
  3362                              <1> 	; mov	esi, FindFile_DirEntry
  3363 0000BD94 BF[566F0100]        <1> 	mov	edi, DestinationFile_DirEntry
  3364 0000BD99 B908000000          <1> 	mov	ecx, 8
  3365 0000BD9E F3A5                <1> 	rep	movsd
  3366                              <1> 	
  3367                              <1> csftdf_check_disk_free_size_2:
  3368 0000BDA0 89C2                <1> 	mov	edx, eax ; Old destination file size
  3369                              <1> 
  3370                              <1> 	;mov	eax, [SourceFile_DirEntry+DirEntry_FileSize]
  3371 0000BDA2 A1[B06F0100]        <1> 	mov	eax, [csftdf_filesize] ; 23/03/2016
  3372                              <1> 
  3373                              <1> 	;;sub	ecx, ecx ; 0
  3374                              <1> 	;mov 	esi, Logical_DOSDisks
  3375                              <1> 	;mov	ch,  [DestinationFile_Drv]
  3376                              <1> 	;add	esi, ecx
  3377                              <1> 	;
  3378                              <1> 	;mov	[csftdf_df_drv_dt], esi
  3379                              <1> 
  3380 0000BDA7 8B35[DC6F0100]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 23/03/2016
  3381                              <1> 
  3382 0000BDAD 668B4E11            <1> 	mov	cx, [esi+LD_BPB+BytesPerSec] ; 17, LD_BPB + 0Bh
  3383 0000BDB1 01CA                <1> 	add	edx, ecx ; + 512
  3384 0000BDB3 01C8                <1> 	add	eax, ecx ; + 512
  3385 0000BDB5 4A                  <1> 	dec	edx ; old file size + 511 (round up)
  3386 0000BDB6 48                  <1> 	dec	eax ; new file size + 511 (round up)
  3387 0000BDB7 F7D9                <1> 	neg	ecx ; -512 ; 0FFFFFE00h
  3388 0000BDB9 21CA                <1> 	and	edx, ecx ; = old sector count * 512 
  3389 0000BDBB 21C8                <1> 	and	eax, ecx ; = new sector count * 512 
  3390                              <1> 
  3391 0000BDBD 29D0                <1> 	sub	eax, edx ; new file size - old file size (on disk)
  3392 0000BDBF 7607                <1> 	jna	short csftdf_check_disk_free_size_ok
  3393                              <1> 
  3394 0000BDC1 F7D9                <1> 	neg	ecx ; 512 (bytes per sector) ; 200h
  3395                              <1> 	; check free space for additional sectors
  3396                              <1> 	; eax = number of additional sectors * bytes per sector
  3397                              <1> 	; esi = Logical DOS drive number (of destination disk)
  3398 0000BDC3 E95FFFFFFF          <1>         jmp     csftdf_check_disk_free_size_3
  3399                              <1>  
  3400                              <1> csftdf_check_disk_free_size_ok:
  3401                              <1> 	; 18/03/2016
  3402                              <1> csftdf_df_check_copy_cmd_phase:
  3403 0000BDC8 A0[AC6F0100]        <1> 	mov	al, [copy_cmd_phase]
  3404 0000BDCD 3C01                <1> 	cmp	al, 1
  3405 0000BDCF 7514                <1> 	jne	short csftdf2_check_cdrv
  3406                              <1> 	
  3407 0000BDD1 31C0                <1> 	xor	eax, eax
  3408 0000BDD3 A2[AC6F0100]        <1> 	mov	[copy_cmd_phase], al ; 0
  3409                              <1> 
  3410 0000BDD8 8A15[AE6F0100]      <1> 	mov	dl, [DestinationFileFound]            
  3411 0000BDDE 8A35[E16E0100]      <1> 	mov	dh, [SourceFile_DirEntry+11] ; Attributes
  3412                              <1>  
  3413                              <1> csftdf_return:	
  3414 0000BDE4 C3                  <1> 	retn
  3415                              <1> 
  3416                              <1> ; Phase 2
  3417                              <1> 
  3418                              <1> csftdf2_check_cdrv:
  3419                              <1> 	; 18/03/2016
  3420                              <1> 	; Here, destination drive and directory are ready !
  3421                              <1> 	; (checking/restoring is not needed)
  3422                              <1> 	; (Since at the end of the phase 1)
  3423                              <1> 
  3424                              <1> ;	mov	dl, [DestinationFile_Drv]
  3425                              <1> ;	cmp	dl, [Current_Drv]
  3426                              <1> ;	je	short csftdf2_df_check_directory
  3427                              <1> ;
  3428                              <1> ;	call	change_current_drive
  3429                              <1> ;	jc	short csftdf2_read_error
  3430                              <1> ;
  3431                              <1> ;csftdf2_df_check_directory:
  3432                              <1> ;	mov	esi, DestinationFile_Directory  
  3433                              <1> ;	cmp	byte [esi], 20h
  3434                              <1> ;	jna	short csftdf2_df_check_found_or_not
  3435                              <1> ;
  3436                              <1> ;csftdf2_df_change_directory:
  3437                              <1> ;	inc	byte [Restore_CDIR]
  3438                              <1> ;	xor	ah, ah ; CD_COMMAND sign -> 0 
  3439                              <1> ;	call	change_current_directory
  3440                              <1> ;	jc	short csftdf2_stc_return
  3441                              <1> ;
  3442                              <1> ;;csftdf2_df_change_prompt_dir_string:
  3443                              <1> ;;	call	change_prompt_dir_string
  3444                              <1> 
  3445                              <1> csftdf2_df_check_found_or_not:
  3446                              <1> 	; 21/03/2016
  3447 0000BDE5 803D[AE6F0100]00    <1> 	cmp	byte [DestinationFileFound], 0 
  3448 0000BDEC 7739                <1> 	ja	short csftdf2_set_sf_percentage
  3449                              <1> 
  3450                              <1> csftdf2_create_file:
  3451 0000BDEE BE[466F0100]        <1> 	mov	esi, DestinationFile_Name
  3452 0000BDF3 A1[B06F0100]        <1> 	mov	eax, [csftdf_filesize]
  3453 0000BDF8 30C9                <1> 	xor	cl, cl ; 0
  3454                              <1> 
  3455 0000BDFA 31DB                <1> 	xor	ebx, ebx ; 0
  3456 0000BDFC 4B                  <1> 	dec	ebx ; 0FFFFFFFFh 
  3457                              <1> 
  3458                              <1> 	; INPUT ->
  3459                              <1> 	; 	EAX -> File Size
  3460                              <1> 	; 	ESI = ASCIIZ File name
  3461                              <1> 	;	 CL = File attributes
  3462                              <1> 	;	EBX = FFFFFFFFh -> empty file sign for FAT fs
  3463                              <1> 	;	EBX <> FFFFFFFFh -> use file size for FAT fs 
  3464                              <1> 	;
  3465                              <1> 	; OUTPUT ->
  3466                              <1> 	;	EAX = New file's first cluster
  3467                              <1> 	;	ESI = Logical Dos Drv Descr. Table Addr.
  3468                              <1> 	;	EBX = CreateFile_Size address
  3469                              <1> 	;	ECX = Sectors per cluster (<256)
  3470                              <1> 	;	EDX = Directory Entry Index/Number (<65536)
  3471                              <1> 	;		
  3472                              <1> 	;	cf = 1 -> error code in AL (EAX)
  3473                              <1> 
  3474 0000BDFD E8EC050000          <1> 	call	create_file
  3475                              <1> 	;pop	esi
  3476 0000BE02 0F82A3050000        <1>         jc      csftdf2_rw_error
  3477                              <1> 
  3478                              <1> csftdf2_create_file_OK:
  3479 0000BE08 A3[C06F0100]        <1> 	mov	[csftdf_df_cluster], eax
  3480                              <1> 	
  3481                              <1> 	; 24/03/2016
  3482 0000BE0D 668915[7E6F0100]    <1> 	mov	[DestinationFile_DirEntryNumber], dx 
  3483                              <1> 
  3484                              <1> 	; 21/03/2016
  3485 0000BE14 BE00000800          <1> 	mov	esi, Directory_Buffer
  3486 0000BE19 C1E205              <1> 	shl	edx, 5 ; 32 * index number
  3487 0000BE1C 01D6                <1> 	add	esi, edx
  3488 0000BE1E BF[566F0100]        <1> 	mov	edi, DestinationFile_DirEntry	
  3489 0000BE23 B108                <1> 	mov	cl, 8 ; 32 bytes
  3490 0000BE25 F3A5                <1> 	rep	movsd
  3491                              <1> 
  3492                              <1> csftdf2_set_sf_percentage:
  3493                              <1> 	; 17/03/2016
  3494 0000BE27 31C0                <1> 	xor	eax, eax	
  3495 0000BE29 A2[D46F0100]        <1> 	mov 	[csftdf_percentage], al ; 0, reset
  3496                              <1> 
  3497 0000BE2E A3[CC6F0100]        <1> 	mov	[csftdf_sf_rbytes], eax ; 0, reset
  3498 0000BE33 A3[D06F0100]        <1> 	mov	[csftdf_df_wbytes], eax ; 0, reset
  3499                              <1> 
  3500 0000BE38 8A25[846E0100]      <1> 	mov	ah, [SourceFile_Drv]	
  3501 0000BE3E BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3502 0000BE43 01C6                <1> 	add	esi, eax
  3503                              <1> 	
  3504 0000BE45 8935[D86F0100]      <1> 	mov	[csftdf_sf_drv_dt], esi ; 23/03/2016
  3505                              <1> 
  3506 0000BE4B 668B15[EA6E0100]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusHI]
  3507 0000BE52 C1E210              <1> 	shl	edx, 16
  3508 0000BE55 668B15[F06E0100]    <1> 	mov	dx, [SourceFile_DirEntry+DirEntry_FstClusLO]
  3509 0000BE5C 8915[BC6F0100]      <1> 	mov	[csftdf_sf_cluster], edx
  3510                              <1> 
  3511                              <1> 	; 16/03/2016
  3512                              <1> 	; Note: Singlix FS boot sector parameters (for cluster
  3513                              <1> 	;	related calculations) has same offset
  3514                              <1> 	;	values from LD_BPB as in FAT file system.
  3515                              <1> 	;	[esi+LD_BPB+SecPerClust] is 1 for Singlix FS.
  3516                              <1> 	;	
  3517 0000BE62 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  3518 0000BE66 880D[026F0100]      <1> 	mov	[SourceFile_SecPerClust], cl
  3519                              <1> 
  3520                              <1> 	; 17/03/2016
  3521 0000BE6C 386E03              <1> 	cmp	[esi+LD_FATType], ch ; 0
  3522 0000BE6F 7707                <1> 	ja	short csftdf2_set_sf_percent_rsize1
  3523                              <1> 
  3524 0000BE71 B800000100          <1> 	mov	eax, 65536 ; read/write buffer size for Singlix FS
  3525 0000BE76 EB06                <1> 	jmp	short csftdf2_set_sf_percent_rsize2	
  3526                              <1>  
  3527                              <1> csftdf2_set_sf_percent_rsize1:
  3528 0000BE78 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec]
  3529 0000BE7C F7E1                <1> 	mul	ecx
  3530                              <1> 	;sub	edx, edx
  3531                              <1> csftdf2_set_sf_percent_rsize2:
  3532 0000BE7E A3[C46F0100]        <1> 	mov	[csftdf_r_size], eax
  3533                              <1> 
  3534                              <1> csftdf2_set_df_percentage:
  3535                              <1> 	;sub	eax, eax
  3536                              <1> 	;mov	ah, [DestinationFile_Drv]	
  3537                              <1> 	;mov	edi, Logical_DOSDisks
  3538                              <1> 	;add	edi, eax
  3539                              <1> 	;mov	[csftdf_df_drv_dt], edi ; 17/03/2016
  3540                              <1> 
  3541 0000BE83 8B3D[DC6F0100]      <1> 	mov	edi, [csftdf_df_drv_dt] ; 23/03/2016
  3542                              <1> 
  3543                              <1> 	; 16/03/2016
  3544                              <1> 	; Note: Singlix FS boot sector parameters (for cluster
  3545                              <1> 	;	related calculations) has same offset
  3546                              <1> 	;	values from LD_BPB as in FAT file system.
  3547                              <1> 	;	[edi+LD_BPB+SecPerClust] is 1 for Singlix FS.
  3548                              <1> 	;	
  3549                              <1> 	;movzx	ecx, byte [edi+LD_BPB+SecPerClust]
  3550 0000BE89 8A4F13              <1> 	mov	cl, [edi+LD_BPB+SecPerClust]
  3551 0000BE8C 880D[826F0100]      <1> 	mov	[DestinationFile_SecPerClust], cl
  3552                              <1> 
  3553                              <1> 	; 17/03/2016
  3554 0000BE92 386F03              <1> 	cmp	[edi+LD_FATType], ch ; 0
  3555 0000BE95 7707                <1> 	ja	short csftdf2_set_df_percent_wsize1
  3556                              <1> 	
  3557 0000BE97 B800000100          <1> 	mov	eax, 65536 ; read/write buffer size for Singlix FS
  3558 0000BE9C EB06                <1> 	jmp	short csftdf2_set_df_percent_wsize2	
  3559                              <1> 
  3560                              <1> csftdf2_set_df_percent_wsize1:
  3561 0000BE9E 0FB74711            <1> 	movzx	eax, word [edi+LD_BPB+BytesPerSec]
  3562 0000BEA2 F7E1                <1> 	mul	ecx
  3563                              <1> 	;sub	edx, edx
  3564                              <1> csftdf2_set_df_percent_wsize2:
  3565 0000BEA4 A3[C86F0100]        <1> 	mov	[csftdf_w_size], eax
  3566                              <1> 
  3567 0000BEA9 A1[B06F0100]        <1> 	mov	eax, [csftdf_filesize]
  3568                              <1> 
  3569 0000BEAE 3D00000100          <1> 	cmp	eax, 65536 ; 64KB	; small file
  3570 0000BEB3 721F                <1> 	jb	short csftdf2_load_file ; do not display percentage
  3571                              <1> 	
  3572                              <1> csftdf2_reset_wf_percent_ptr_chk_64k:
  3573 0000BEB5 B201                <1> 	mov	dl, 1 ; 25/03/2016
  3574                              <1> 
  3575 0000BEB7 3D00000400          <1> 	cmp	eax, 65536*4 ; 256KB
  3576 0000BEBC 7310                <1> 	jnb	short csftdf2_enable_percentage_display ; big file
  3577                              <1> 
  3578                              <1> 	; 64-128KB file size for floppy disks
  3579 0000BEBE 3815[846E0100]      <1> 	cmp	byte [SourceFile_Drv], dl ; 1 ; read from floppy disk ?
  3580 0000BEC4 7608                <1> 	jna	short csftdf2_enable_percentage_display
  3581                              <1> 
  3582 0000BEC6 3815[046F0100]      <1> 	cmp	byte [DestinationFile_Drv], dl ; 1 ; write to floppy disk ?
  3583 0000BECC 7706                <1> 	ja	short csftdf2_load_file
  3584                              <1> 
  3585                              <1> csftdf2_enable_percentage_display:	
  3586 0000BECE 8815[D46F0100]      <1> 	mov	[csftdf_percentage], dl ; 1	
  3587                              <1> 	
  3588                              <1> csftdf2_load_file:
  3589                              <1> 	; 13/05/2016
  3590                              <1> 	; 19/03/2016
  3591                              <1> 	; 18/03/2016
  3592                              <1> 	; 17/03/2016
  3593 0000BED4 B40F                <1> 	mov	ah, 0Fh
  3594 0000BED6 E87E58FFFF          <1> 	call	_int10h
  3595                              <1> 	; 13/05/2016
  3596 0000BEDB 883D[D56F0100]      <1> 	mov	[csftdf_videopage], bh ; active video page
  3597 0000BEE1 B403                <1> 	mov	ah, 03h
  3598 0000BEE3 E87158FFFF          <1> 	call	_int10h
  3599 0000BEE8 668915[D66F0100]    <1> 	mov	[csftdf_cursorpos], dx
  3600                              <1> 
  3601 0000BEEF 29C0                <1> 	sub	eax, eax
  3602 0000BEF1 A2[AD6F0100]        <1> 	mov	[csftdf_rw_err], al ; 0 
  3603                              <1> 
  3604                              <1> ; ///
  3605                              <1> csftdf_sf_amb: ; 15/03/2016
  3606 0000BEF6 8B0D[B06F0100]      <1> 	mov	ecx, [csftdf_filesize]	; 23/03/2016
  3607                              <1> 
  3608                              <1> 	; TRDOS 386 (TRDOS v2.0)
  3609                              <1> 	; Allocate contiguous memory block for loading the file
  3610                              <1> 	
  3611                              <1> 	;mov	ecx, [SourceFile_DirEntry+DirEntry_FileSize]
  3612                              <1> 	
  3613                              <1> 	;sub	eax, eax ; First free memory aperture
  3614                              <1> 	
  3615                              <1> 	; eax = 0 (Allocate memory from the beginning)
  3616                              <1> 	; ecx = File (Allocation) size in bytes
  3617                              <1> 	
  3618 0000BEFC E84E9FFFFF          <1> 	call	allocate_memory_block
  3619 0000BF01 7304                <1> 	jnc	short loc_check_sf_save_loading_parms
  3620                              <1> 
  3621 0000BF03 29C0                <1> 	sub	eax, eax
  3622 0000BF05 29C9                <1> 	sub	ecx, ecx
  3623                              <1> 	
  3624                              <1> loc_check_sf_save_loading_parms:
  3625 0000BF07 A3[B46F0100]        <1> 	mov	[csftdf_sf_mem_addr], eax ; loading address
  3626 0000BF0C 890D[B86F0100]      <1> 	mov	[csftdf_sf_mem_bsize], ecx ; block size
  3627                              <1> ; ///   
  3628                              <1> 	; 19/03/2016
  3629 0000BF12 8B35[D86F0100]      <1> 	mov	esi, [csftdf_sf_drv_dt] ; logical dos drv desc. tbl.
  3630                              <1> 
  3631                              <1> 	; 17/03/2016
  3632 0000BF18 09C0                <1> 	or	eax, eax ; contiguous free memory block address 
  3633 0000BF1A 0F845B010000        <1>         jz      csftdf2_read_sf_cluster
  3634                              <1> 
  3635                              <1> 	; 18/03/2016
  3636 0000BF20 8B1D[B46F0100]      <1> 	mov	ebx, [csftdf_sf_mem_addr] ; memory block address
  3637                              <1> 
  3638 0000BF26 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3639 0000BF2A 0F8605020000        <1>         jna     csftdf2_load_fs_file
  3640                              <1> 
  3641                              <1> csftdf2_load_fat_file:
  3642 0000BF30 53                  <1> 	push	ebx ; *
  3643                              <1> 
  3644                              <1> csftdf2_load_fat_file_next:
  3645 0000BF31 BE[451E0100]        <1> 	mov	esi, msg_reading
  3646 0000BF36 E8EAAFFFFF          <1> 	call	print_msg
  3647                              <1> 
  3648 0000BF3B 803D[D46F0100]00    <1> 	cmp	byte [csftdf_percentage], 0
  3649 0000BF42 7605                <1> 	jna	short csftdf2_load_fat_file_1
  3650                              <1> 	
  3651 0000BF44 E87C000000          <1> 	call	csftdf2_print_percentage ; 19/03/2016
  3652                              <1> 
  3653                              <1> csftdf2_load_fat_file_1:
  3654 0000BF49 8B35[D86F0100]      <1> 	mov	esi, [csftdf_sf_drv_dt]	
  3655 0000BF4F 5B                  <1> 	pop	ebx ; *
  3656                              <1> 
  3657                              <1> csftdf2_load_fat_file_2:
  3658 0000BF50 E8B8000000          <1> 	call	csftdf2_read_fat_file_sectors ; 19/03/2016
  3659 0000BF55 0F8250040000        <1>         jc      csftdf2_rw_error ; eocc! or disk error! 
  3660                              <1> 
  3661 0000BF5B 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3662 0000BF5D 7520                <1> 	jnz	short csftdf2_load_fat_file_ok
  3663                              <1> 
  3664 0000BF5F 803D[D46F0100]00    <1> 	cmp	byte [csftdf_percentage], 0
  3665 0000BF66 76E8                <1> 	jna	short csftdf2_load_fat_file_2
  3666                              <1> 
  3667 0000BF68 53                  <1> 	push	ebx ; *	
  3668                              <1> 
  3669                              <1> 	; Set cursor position
  3670                              <1> 	; AH= 02h, BH= Page Number, DH= Row, DL= Column
  3671 0000BF69 8A3D[D56F0100]      <1> 	mov	bh, [csftdf_videopage]
  3672 0000BF6F 668B15[D66F0100]    <1> 	mov	dx, [csftdf_cursorpos]
  3673 0000BF76 B402                <1> 	mov	ah, 2
  3674 0000BF78 E8DC57FFFF          <1> 	call	_int10h
  3675 0000BF7D EBB2                <1> 	jmp	short csftdf2_load_fat_file_next
  3676                              <1> 	
  3677                              <1> csftdf2_load_fat_file_ok:
  3678 0000BF7F 803D[D46F0100]00    <1> 	cmp	byte [csftdf_percentage], 0
  3679 0000BF86 0F8651020000        <1>         jna     csftdf2_save_file ; 25/03/2016
  3680                              <1> 	
  3681                              <1> 	; "Reading... 100%"
  3682 0000BF8C BF[5D1E0100]        <1> 	mov	edi, percentagestr
  3683 0000BF91 B031                <1> 	mov	al, '1'
  3684 0000BF93 AA                  <1> 	stosb
  3685 0000BF94 B030                <1> 	mov	al, '0'
  3686 0000BF96 AA                  <1> 	stosb
  3687 0000BF97 AA                  <1> 	stosb
  3688                              <1> 
  3689 0000BF98 8A3D[D56F0100]      <1> 	mov	bh, [csftdf_videopage]
  3690 0000BF9E 668B15[D66F0100]    <1> 	mov	dx, [csftdf_cursorpos]
  3691 0000BFA5 B402                <1> 	mov	ah, 2
  3692 0000BFA7 E8AD57FFFF          <1> 	call	_int10h
  3693                              <1> 
  3694 0000BFAC BE[451E0100]        <1> 	mov	esi, msg_reading
  3695 0000BFB1 E86FAFFFFF          <1> 	call	print_msg
  3696                              <1> 	
  3697 0000BFB6 BE[5D1E0100]        <1> 	mov	esi, percentagestr
  3698 0000BFBB E865AFFFFF          <1> 	call	print_msg
  3699                              <1> 
  3700 0000BFC0 E918020000          <1>         jmp     csftdf2_save_file ; 25/03/2016
  3701                              <1> 
  3702                              <1> csftdf2_print_percentage:
  3703                              <1> 	; 09/12/2017
  3704                              <1> 	; 19/03/2016
  3705                              <1> 	; 18/03/2016
  3706 0000BFC5 B020                <1> 	mov	al, 20h
  3707 0000BFC7 BF[5D1E0100]        <1> 	mov	edi, percentagestr
  3708 0000BFCC AA                  <1> 	stosb
  3709 0000BFCD AA                  <1> 	stosb
  3710 0000BFCE A1[CC6F0100]        <1> 	mov	eax, [csftdf_sf_rbytes]
  3711 0000BFD3 BA64000000          <1> 	mov	edx, 100
  3712 0000BFD8 F7E2                <1> 	mul	edx
  3713 0000BFDA 8B0D[B06F0100]      <1> 	mov	ecx, [csftdf_filesize]	
  3714 0000BFE0 F7F1                <1> 	div	ecx
  3715 0000BFE2 B10A                <1> 	mov	cl, 10
  3716 0000BFE4 F6F1                <1> 	div	cl
  3717 0000BFE6 80C430              <1> 	add	ah, '0'
  3718 0000BFE9 8827                <1> 	mov	[edi], ah
  3719 0000BFEB 20C0                <1> 	and	al, al
  3720 0000BFED 740A                <1> 	jz	short csftdf2_print_percent_1
  3721 0000BFEF 4F                  <1> 	dec	edi
  3722                              <1> 	;cbw
  3723 0000BFF0 28E4                <1> 	sub	ah, ah ; 09/12/2017
  3724 0000BFF2 F6F1                <1> 	div	cl
  3725 0000BFF4 80C430              <1> 	add	ah, '0'
  3726 0000BFF7 8827                <1> 	mov	[edi], ah
  3727                              <1> 	;and	al, al
  3728                              <1> 	;jz	short csftdf2_print_percent_1
  3729                              <1> 	;dec	edi
  3730                              <1> 	;mov	[edi], '1' ; 100%		
  3731                              <1> 
  3732                              <1> csftdf2_print_percent_1:
  3733 0000BFF9 BE[5D1E0100]        <1> 	mov	esi, percentagestr
  3734                              <1> 	;call	print_msg
  3735                              <1> 	;retn
  3736 0000BFFE E922AFFFFF          <1> 	jmp	print_msg
  3737                              <1> 
  3738                              <1> csftdf2_read_file_sectors:
  3739                              <1> 	; 19/03/2016
  3740 0000C003 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3741 0000C007 0F8627070000        <1>         jna     csftdf2_read_fs_file_sectors
  3742                              <1> 
  3743                              <1> csftdf2_read_fat_file_sectors:
  3744                              <1> 	; 19/03/2016
  3745                              <1> 	; 18/03/2016
  3746                              <1> 	; return:
  3747                              <1> 	;   CF = 0 & EDX > 0 -> END OF FILE
  3748                              <1> 	;   CF = 0 & EDX = 0 -> not EOF
  3749                              <1> 	;   CF = 1 -> read error (error code in AL)	
  3750                              <1> 
  3751                              <1> csftdf2_read_fat_file_secs_0:
  3752 0000C00D 8B15[B06F0100]      <1> 	mov	edx, [csftdf_filesize]
  3753 0000C013 2B15[CC6F0100]      <1> 	sub	edx, [csftdf_sf_rbytes]
  3754 0000C019 3B15[C46F0100]      <1> 	cmp	edx, [csftdf_r_size]	
  3755 0000C01F 7306                <1> 	jnb	short csftdf2_read_fat_file_secs_1
  3756 0000C021 8915[C46F0100]      <1> 	mov	[csftdf_r_size], edx
  3757                              <1> 		
  3758                              <1> csftdf2_read_fat_file_secs_1:
  3759 0000C027 A1[C46F0100]        <1> 	mov	eax, [csftdf_r_size]
  3760 0000C02C 29D2                <1> 	sub	edx, edx
  3761 0000C02E 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec]
  3762 0000C032 01C8                <1> 	add	eax, ecx
  3763 0000C034 48                  <1> 	dec	eax
  3764 0000C035 F7F1                <1> 	div	ecx
  3765 0000C037 89C1                <1> 	mov	ecx, eax ; sector count
  3766 0000C039 A1[BC6F0100]        <1> 	mov	eax, [csftdf_sf_cluster]
  3767                              <1> 
  3768                              <1> 	; EBX = memory block address (current)
  3769                              <1> 	
  3770 0000C03E E821090000          <1> 	call	read_fat_file_sectors
  3771 0000C043 7235                <1> 	jc	short csftdf2_read_fat_file_secs_3
  3772                              <1> 
  3773                              <1> 	; EBX = next memory address
  3774                              <1> 
  3775 0000C045 A1[CC6F0100]        <1> 	mov	eax, [csftdf_sf_rbytes]
  3776 0000C04A 0305[C46F0100]      <1> 	add	eax, [csftdf_r_size]
  3777 0000C050 8B15[B06F0100]      <1> 	mov	edx, [csftdf_filesize]
  3778 0000C056 39D0                <1> 	cmp	eax, edx
  3779 0000C058 7320                <1> 	jnb	short csftdf2_read_fat_file_secs_3 ; edx > 0
  3780 0000C05A A3[CC6F0100]        <1> 	mov	[csftdf_sf_rbytes], eax
  3781                              <1> 
  3782 0000C05F 53                  <1> 	push	ebx ; *
  3783                              <1> 	; get next cluster (csftdf_r_size! bytes)
  3784 0000C060 A1[BC6F0100]        <1> 	mov	eax, [csftdf_sf_cluster]
  3785 0000C065 E8CC060000          <1> 	call	get_next_cluster
  3786 0000C06A 5B                  <1> 	pop	ebx ; *
  3787 0000C06B 7306                <1> 	jnc	short csftdf2_read_fat_file_secs_2
  3788                              <1> 
  3789                              <1> 	; 15/10/2016
  3790                              <1> 	;Disk read error instad of drv not ready err
  3791 0000C06D B811000000          <1> 	mov	eax, 17 ; Read error !
  3792 0000C072 C3                  <1> 	retn
  3793                              <1> 
  3794                              <1> csftdf2_read_fat_file_secs_2:
  3795 0000C073 29D2                <1> 	sub	edx, edx ; 0
  3796 0000C075 A3[BC6F0100]        <1> 	mov	[csftdf_sf_cluster], eax ; next cluster
  3797                              <1> 
  3798                              <1> csftdf2_read_fat_file_secs_3:
  3799 0000C07A C3                  <1> 	retn
  3800                              <1> 
  3801                              <1> csftdf2_read_sf_cluster:
  3802                              <1> 	; 19/03/2016
  3803 0000C07B BB00000700          <1> 	mov	ebx, Cluster_Buffer ; buffer address (64KB)
  3804                              <1> 
  3805 0000C080 803D[D46F0100]00    <1> 	cmp	byte [csftdf_percentage], 0
  3806 0000C087 760D                <1> 	jna	short csftdf2_read_sf_clust_2
  3807                              <1> 
  3808 0000C089 53                  <1> 	push	ebx ; *	
  3809                              <1> 
  3810                              <1> csftdf2_read_sf_clust_next:
  3811 0000C08A E836FFFFFF          <1> 	call	csftdf2_print_percentage
  3812                              <1> 
  3813                              <1> csftdf2_read_sf_clust_0:
  3814 0000C08F 8B35[D86F0100]      <1> 	mov	esi, [csftdf_sf_drv_dt]	
  3815                              <1> csftdf2_read_sf_clust_1:
  3816 0000C095 5B                  <1> 	pop	ebx ; *
  3817                              <1> 
  3818                              <1> csftdf2_read_sf_clust_2:
  3819 0000C096 89DA                <1> 	mov	edx, ebx
  3820 0000C098 0315[C46F0100]      <1> 	add	edx, [csftdf_r_size]
  3821 0000C09E 81FA00000800        <1> 	cmp	edx, Cluster_Buffer + 65536
  3822 0000C0A4 772F                <1> 	ja	short csftdf2_write_df_cluster
  3823                              <1> 
  3824 0000C0A6 E858FFFFFF          <1> 	call	csftdf2_read_file_sectors ; 19/03/2016
  3825 0000C0AB 0F8280020000        <1>         jc      csftdf2_save_fat_file_err2 ; eocc! or disk error! 
  3826                              <1> 
  3827 0000C0B1 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3828 0000C0B3 7520                <1> 	jnz	short csftdf2_write_df_cluster
  3829                              <1> 
  3830 0000C0B5 803D[D46F0100]00    <1> 	cmp	byte [csftdf_percentage], 0
  3831 0000C0BC 76D8                <1> 	jna	short csftdf2_read_sf_clust_2
  3832                              <1> 
  3833 0000C0BE 53                  <1> 	push	ebx ; *	
  3834                              <1> 
  3835                              <1> 	; Set cursor position
  3836                              <1> 	; AH= 02h, BH= Page Number, DH= Row, DL= Column
  3837 0000C0BF 8A3D[D56F0100]      <1> 	mov	bh, [csftdf_videopage]
  3838 0000C0C5 668B15[D66F0100]    <1> 	mov	dx, [csftdf_cursorpos]
  3839 0000C0CC B402                <1> 	mov	ah, 2
  3840 0000C0CE E88656FFFF          <1> 	call	_int10h
  3841 0000C0D3 EBB5                <1> 	jmp	short csftdf2_read_sf_clust_next
  3842                              <1> 
  3843                              <1> csftdf2_write_df_cluster:
  3844                              <1> 	; 19/03/2016
  3845 0000C0D5 8B35[DC6F0100]      <1> 	mov	esi, [csftdf_df_drv_dt]	
  3846 0000C0DB BB00000700          <1> 	mov	ebx, Cluster_Buffer ; buffer address (64KB)
  3847                              <1> 
  3848                              <1> csftdf2_write_df_clust_next:
  3849 0000C0E0 E855000000          <1> 	call	csftdf2_write_file_sectors ; 19/03/2016
  3850 0000C0E5 0F8246020000        <1>         jc      csftdf2_save_fat_file_err2 ; eocc! or disk error! 
  3851                              <1> 
  3852 0000C0EB 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  3853 0000C0ED 750A                <1> 	jnz	short csftdf2_rw_f_clust_ok
  3854                              <1> 
  3855 0000C0EF 81FB00000800        <1> 	cmp	ebx, Cluster_Buffer + 65536
  3856 0000C0F5 72E9                <1> 	jb	short csftdf2_write_df_clust_next
  3857                              <1> 	
  3858 0000C0F7 EB82                <1> 	jmp	short csftdf2_read_sf_cluster
  3859                              <1>  
  3860                              <1> csftdf2_rw_f_clust_ok:
  3861 0000C0F9 803D[D46F0100]00    <1> 	cmp	byte [csftdf_percentage], 0
  3862 0000C100 0F86B2010000        <1>         jna     csftdf2_save_fat_file_4 ; 25/03/2016
  3863                              <1> 
  3864                              <1> 	; "100%"
  3865 0000C106 BF[5D1E0100]        <1> 	mov	edi, percentagestr
  3866 0000C10B B031                <1> 	mov	al, '1'
  3867 0000C10D AA                  <1> 	stosb
  3868 0000C10E B030                <1> 	mov	al, '0'
  3869 0000C110 AA                  <1> 	stosb
  3870 0000C111 AA                  <1> 	stosb
  3871                              <1> 
  3872 0000C112 8A3D[D56F0100]      <1> 	mov	bh, [csftdf_videopage]
  3873 0000C118 668B15[D66F0100]    <1> 	mov	dx, [csftdf_cursorpos]
  3874 0000C11F B402                <1> 	mov	ah, 2
  3875 0000C121 E83356FFFF          <1> 	call	_int10h
  3876                              <1> 
  3877 0000C126 BE[5D1E0100]        <1> 	mov	esi, percentagestr
  3878 0000C12B E8F5ADFFFF          <1> 	call	print_msg
  3879                              <1> 
  3880 0000C130 E983010000          <1>         jmp     csftdf2_save_fat_file_4
  3881                              <1> 
  3882                              <1> csftdf2_load_fs_file:
  3883                              <1> 	; temporary - 18/03/2016
  3884 0000C135 E96F020000          <1>         jmp     csftdf2_read_error
  3885                              <1> 
  3886                              <1> csftdf2_write_file_sectors:
  3887                              <1> 	; 19/03/2016
  3888 0000C13A 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3889 0000C13E 0F86F1050000        <1>         jna     csftdf2_write_fs_file_sectors
  3890                              <1> 
  3891                              <1> csftdf2_write_fat_file_sectors:
  3892                              <1> 	; 19/03/2016
  3893                              <1> 	; 18/03/2016
  3894                              <1> 	; return:
  3895                              <1> 	;   CF = 0 & EDX > 0 -> END OF FILE
  3896                              <1> 	;   CF = 0 & EDX = 0 -> not EOF
  3897                              <1> 	;   CF = 1 -> write error (error code in AL)	
  3898                              <1> 
  3899                              <1> csftdf2_write_fat_file_secs_0:
  3900 0000C144 8B15[B06F0100]      <1> 	mov	edx, [csftdf_filesize]
  3901 0000C14A 2B15[D06F0100]      <1> 	sub	edx, [csftdf_df_wbytes]
  3902 0000C150 3B15[C86F0100]      <1> 	cmp	edx, [csftdf_w_size]	
  3903 0000C156 7306                <1> 	jnb	short csftdf2_write_fat_file_secs_1
  3904 0000C158 8915[C86F0100]      <1> 	mov	[csftdf_w_size], edx		
  3905                              <1> 
  3906                              <1> csftdf2_write_fat_file_secs_1:
  3907 0000C15E A1[C86F0100]        <1> 	mov	eax, [csftdf_w_size]
  3908 0000C163 29D2                <1> 	sub	edx, edx
  3909 0000C165 0FB74E11            <1> 	movzx	ecx, word [esi+LD_BPB+BytesPerSec]
  3910 0000C169 01C8                <1> 	add	eax, ecx
  3911 0000C16B 48                  <1> 	dec	eax
  3912 0000C16C F7F1                <1> 	div	ecx
  3913 0000C16E 89C1                <1> 	mov	ecx, eax ; sector count
  3914 0000C170 A1[C06F0100]        <1> 	mov	eax, [csftdf_df_cluster]
  3915                              <1> 
  3916                              <1> 	; EBX = memory block address (current)	
  3917                              <1> 
  3918 0000C175 E8A20F0000          <1> 	call	write_fat_file_sectors
  3919 0000C17A 7259                <1> 	jc	short csftdf2_write_fat_file_secs_4
  3920                              <1> 
  3921                              <1> 	; EBX = next memory address
  3922                              <1> 
  3923 0000C17C A1[D06F0100]        <1> 	mov	eax, [csftdf_df_wbytes]
  3924 0000C181 0305[C86F0100]      <1> 	add	eax, [csftdf_w_size]
  3925 0000C187 8B15[B06F0100]      <1> 	mov	edx, [csftdf_filesize]
  3926 0000C18D 39D0                <1> 	cmp	eax, edx
  3927 0000C18F 7344                <1> 	jnb	short csftdf2_write_fat_file_secs_4
  3928 0000C191 A3[D06F0100]        <1> 	mov	[csftdf_df_wbytes], eax
  3929                              <1> 	;
  3930 0000C196 A3[726F0100]        <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], eax
  3931                              <1> 
  3932 0000C19B 53                  <1> 	push	ebx ; *
  3933                              <1> 
  3934 0000C19C 803D[AE6F0100]01    <1> 	cmp	byte [DestinationFileFound], 1
  3935 0000C1A3 7210                <1> 	jb	short csftdf2_write_fat_file_secs_2
  3936                              <1> 
  3937                              <1> 	; get next cluster (csftdf_w_size! bytes)
  3938 0000C1A5 A1[C06F0100]        <1> 	mov	eax, [csftdf_df_cluster]
  3939 0000C1AA E887050000          <1> 	call	get_next_cluster
  3940 0000C1AF 731C                <1> 	jnc	short csftdf2_write_fat_file_secs_3
  3941                              <1> 
  3942 0000C1B1 21C0                <1> 	and	eax, eax ; end of cluster chain!?
  3943 0000C1B3 7521                <1> 	jnz	short csftdf2_write_fat_file_secs_5 ; disk error !
  3944                              <1> 
  3945                              <1> csftdf2_write_fat_file_secs_2:
  3946 0000C1B5 A1[C06F0100]        <1> 	mov	eax, [csftdf_df_cluster] ; last cluster
  3947 0000C1BA E8800E0000          <1> 	call	add_new_cluster		
  3948 0000C1BF 7215                <1> 	jc	short csftdf2_write_fat_file_secs_5
  3949                              <1> 
  3950                              <1> 	; NOTE: Destination file size may be bigger than
  3951                              <1> 	; source file size when the last reading fails after here.
  3952                              <1> 	; (The last -empty- cluster of destination file must be 
  3953                              <1> 	; truncated and LMDT must be current date&time for partial
  3954                              <1> 	; copy result!) 
  3955 0000C1C1 8B15[C86F0100]      <1> 	mov	edx, [csftdf_w_size] ; bytes per cluster
  3956 0000C1C7 0115[726F0100]      <1> 	add	[DestinationFile_DirEntry+DirEntry_FileSize], edx
  3957                              <1> 
  3958                              <1> csftdf2_write_fat_file_secs_3:
  3959 0000C1CD 5B                  <1> 	pop	ebx ; *
  3960 0000C1CE 29D2                <1> 	sub	edx, edx ; 0
  3961 0000C1D0 A3[C06F0100]        <1> 	mov	[csftdf_df_cluster], eax ; next cluster
  3962                              <1> 
  3963                              <1> csftdf2_write_fat_file_secs_4:
  3964 0000C1D5 C3                  <1> 	retn
  3965                              <1> 
  3966                              <1> csftdf2_write_fat_file_secs_5:
  3967 0000C1D6 5B                  <1> 	pop	ebx ; *
  3968                              <1> 	; 16/10/2016 (1Dh -> 18)
  3969 0000C1D7 B812000000          <1> 	mov	eax, 18 ; Write error !
  3970 0000C1DC C3                  <1> 	retn
  3971                              <1> 
  3972                              <1> csftdf2_save_file:
  3973                              <1> 	; 09/12/2017
  3974                              <1> 	; 25/03/2016
  3975                              <1> 	; 19/03/2016
  3976                              <1> 	; 18/03/2016
  3977 0000C1DD 8B35[DC6F0100]      <1> 	mov	esi, [csftdf_df_drv_dt] ; logical dos drv desc. tbl.
  3978                              <1> 
  3979 0000C1E3 8B1D[B46F0100]      <1> 	mov	ebx, [csftdf_sf_mem_addr] ; memory block address
  3980                              <1> 
  3981 0000C1E9 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  3982 0000C1ED 0F86F4010000        <1>         jna     csftdf2_save_fs_file
  3983                              <1> 
  3984                              <1> csftdf2_save_fat_file:
  3985 0000C1F3 53                  <1> 	push	ebx; *
  3986                              <1> 
  3987 0000C1F4 803D[D46F0100]00    <1> 	cmp	byte [csftdf_percentage], 0
  3988 0000C1FB 7724                <1> 	ja	short csftdf2_save_fat_file_0
  3989                              <1> 
  3990                              <1> 	; Set cursor position
  3991                              <1> 	; AH= 02h, BH= Page Number, DH= Row, DL= Column
  3992 0000C1FD 8A3D[D56F0100]      <1> 	mov	bh, [csftdf_videopage]
  3993 0000C203 668B15[D66F0100]    <1> 	mov	dx, [csftdf_cursorpos]
  3994 0000C20A B402                <1> 	mov	ah, 2
  3995 0000C20C E84855FFFF          <1> 	call	_int10h
  3996                              <1> 	
  3997 0000C211 BE[511E0100]        <1> 	mov	esi, msg_writing
  3998 0000C216 E80AADFFFF          <1> 	call	print_msg
  3999                              <1> 
  4000                              <1> csftdf2_save_fat_file_next:
  4001 0000C21B 8B35[DC6F0100]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 25/03/2016
  4002                              <1> 
  4003                              <1> csftdf2_save_fat_file_0:
  4004 0000C221 5B                  <1> 	pop	ebx ; *
  4005                              <1> 
  4006                              <1> csftdf2_save_fat_file_1:
  4007 0000C222 E813FFFFFF          <1> 	call	csftdf2_write_file_sectors ; 19/03/2016	
  4008 0000C227 0F827E010000        <1>         jc      csftdf2_rw_error ; eocc! or disk error! 
  4009                              <1> 
  4010 0000C22D 09D2                <1> 	or	edx, edx ; edx > 0 -> EOF
  4011 0000C22F 756D                <1>         jnz     short csftdf2_save_fat_file_3 ; 25/03/2016
  4012                              <1> 
  4013 0000C231 803D[D46F0100]00    <1> 	cmp	byte [csftdf_percentage], 0
  4014 0000C238 76E8                <1> 	jna	short csftdf2_save_fat_file_1
  4015                              <1> 
  4016 0000C23A B020                <1> 	mov	al, 20h
  4017 0000C23C BF[5D1E0100]        <1> 	mov	edi, percentagestr
  4018 0000C241 AA                  <1> 	stosb
  4019 0000C242 AA                  <1> 	stosb
  4020 0000C243 A1[D06F0100]        <1> 	mov	eax, [csftdf_df_wbytes]
  4021 0000C248 BA64000000          <1> 	mov	edx, 100
  4022 0000C24D F7E2                <1> 	mul	edx
  4023 0000C24F 8B0D[B06F0100]      <1> 	mov	ecx, [csftdf_filesize]	
  4024 0000C255 F7F1                <1> 	div	ecx
  4025 0000C257 B10A                <1> 	mov	cl, 10
  4026 0000C259 F6F1                <1> 	div	cl
  4027 0000C25B 80C430              <1> 	add	ah, '0'
  4028 0000C25E 8827                <1> 	mov	[edi], ah
  4029 0000C260 20C0                <1> 	and	al, al
  4030 0000C262 740A                <1> 	jz	short csftdf2_save_fat_file_2
  4031 0000C264 4F                  <1> 	dec	edi
  4032                              <1> 	;cbw
  4033 0000C265 30E4                <1> 	xor	ah, ah ; 09/12/2017
  4034 0000C267 F6F1                <1> 	div	cl
  4035 0000C269 80C430              <1> 	add	ah, '0'
  4036 0000C26C 8827                <1> 	mov	[edi], ah
  4037                              <1> 	;and	al, al
  4038                              <1> 	;jz	short csftdf2_save_fat_file_2
  4039                              <1> 	;dec	edi
  4040                              <1> 	;mov	[edi], '1' ; 100%		
  4041                              <1> 
  4042                              <1> csftdf2_save_fat_file_2:
  4043 0000C26E 53                  <1> 	push	ebx ; *
  4044                              <1> 
  4045 0000C26F E802000000          <1> 	call	csftdf2_print_wr_percentage ; 25/03/2016
  4046                              <1> 
  4047 0000C274 EBA5                <1>         jmp     csftdf2_save_fat_file_next
  4048                              <1> 
  4049                              <1> csftdf2_print_wr_percentage:
  4050                              <1> 	; Set cursor position
  4051                              <1> 	; AH= 02h, BH= Page Number, DH= Row, DL= Column
  4052 0000C276 8A3D[D56F0100]      <1> 	mov	bh, [csftdf_videopage]
  4053 0000C27C 668B15[D66F0100]    <1> 	mov	dx, [csftdf_cursorpos]
  4054 0000C283 B402                <1> 	mov	ah, 2
  4055 0000C285 E8CF54FFFF          <1> 	call	_int10h
  4056                              <1> 
  4057 0000C28A BE[511E0100]        <1> 	mov	esi, msg_writing
  4058 0000C28F E891ACFFFF          <1> 	call	print_msg
  4059                              <1> 
  4060 0000C294 BE[5D1E0100]        <1> 	mov	esi, percentagestr
  4061                              <1> 	;call	print_msg
  4062                              <1> 	;retn
  4063 0000C299 E987ACFFFF          <1> 	jmp	print_msg
  4064                              <1> 
  4065                              <1> csftdf2_save_fat_file_3:
  4066 0000C29E 803D[D46F0100]00    <1> 	cmp	byte [csftdf_percentage], 0
  4067 0000C2A5 7611                <1>         jna     csftdf2_save_fat_file_4 ; 25/03/2016
  4068                              <1> 
  4069                              <1> 	; "100%"
  4070 0000C2A7 BF[5D1E0100]        <1> 	mov	edi, percentagestr
  4071 0000C2AC B031                <1> 	mov	al, '1'
  4072 0000C2AE AA                  <1> 	stosb
  4073 0000C2AF B030                <1> 	mov	al, '0'
  4074 0000C2B1 AA                  <1> 	stosb
  4075 0000C2B2 AA                  <1> 	stosb
  4076                              <1> 
  4077 0000C2B3 E8BEFFFFFF          <1> 	call	csftdf2_print_wr_percentage
  4078                              <1> 
  4079                              <1> csftdf2_save_fat_file_4:
  4080 0000C2B8 803D[AE6F0100]00    <1> 	cmp	byte [DestinationFileFound], 0
  4081 0000C2BF 7647                <1> 	jna	short csftdf2_save_fat_file_6
  4082                              <1> 
  4083 0000C2C1 8B35[DC6F0100]      <1> 	mov	esi, [csftdf_df_drv_dt] ; 31/03/2016	
  4084                              <1> 
  4085 0000C2C7 A1[C06F0100]        <1> 	mov	eax, [csftdf_df_cluster] ; last cluster
  4086 0000C2CC E865040000          <1> 	call	get_next_cluster
  4087 0000C2D1 7235                <1> 	jc	short csftdf2_save_fat_file_6 ; eocc! or disk error!
  4088                              <1> 
  4089 0000C2D3 A1[C06F0100]        <1> 	mov	eax, [csftdf_df_cluster] ; last cluster
  4090                              <1> 	;xor	ecx, ecx
  4091                              <1> 	;mov	[FAT_ClusterCounter], ecx ; 0 ; reset
  4092                              <1> 	;dec	ecx ; 0FFFFFFFFh
  4093                              <1> 	;shr	ecx, 4 ; 28 bit ; 0FFFFFFFh
  4094 0000C2D8 B9FFFFFF0F          <1> 	mov	ecx, 0FFFFFFFh
  4095 0000C2DD E87E070000          <1> 	call	update_cluster
  4096 0000C2E2 7224                <1> 	jc	short csftdf2_save_fat_file_6 ; really last cluster!?
  4097                              <1> 
  4098 0000C2E4 A3[C06F0100]        <1> 	mov	[csftdf_df_cluster], eax ; next cluster
  4099                              <1> 	
  4100                              <1> 	; byte [FAT_BuffValidData] = 2 
  4101 0000C2E9 E82F0A0000          <1> 	call	save_fat_buffer
  4102 0000C2EE 730E                <1> 	jnc	short csftdf2_save_fat_file_5
  4103                              <1> 	
  4104 0000C2F0 8B15[B06F0100]      <1> 	mov	edx, [csftdf_filesize]
  4105 0000C2F6 8915[726F0100]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], edx
  4106 0000C2FC EB58                <1> 	jmp	short csftdf2_save_fat_file_err3
  4107                              <1> 
  4108                              <1> csftdf2_save_fat_file_5:
  4109 0000C2FE A1[C06F0100]        <1> 	mov	eax, [csftdf_df_cluster]
  4110                              <1> 
  4111                              <1> 	; EAX = First cluster to be truncated/unlinked
  4112                              <1> 	; ESI = Logical dos drive description table address
  4113 0000C303 E8580C0000          <1> 	call	truncate_cluster_chain
  4114                              <1> 
  4115                              <1> csftdf2_save_fat_file_6:
  4116                              <1> 	; 28/03/2016
  4117 0000C308 BE[E16E0100]        <1> 	mov	esi, SourceFile_DirEntry+DirEntry_Attr ; +11 to + 18
  4118 0000C30D BF[616F0100]        <1> 	mov	edi, DestinationFile_DirEntry+DirEntry_Attr ; +11 to + 18
  4119 0000C312 A4                  <1> 	movsb ; +11
  4120 0000C313 A5                  <1> 	movsd ; +12 .. +15
  4121 0000C314 66A5                <1> 	movsw ; +16 .. +17
  4122                              <1> 		; + 18
  4123 0000C316 83C604              <1> 	add	esi, 4
  4124 0000C319 83C704              <1> 	add	edi, 4
  4125 0000C31C A5                  <1> 	movsd	; DirEntry_WrtTime ; +22 .. +25
  4126                              <1> 
  4127 0000C31D 8B15[B06F0100]      <1> 	mov	edx, [csftdf_filesize]
  4128 0000C323 8915[726F0100]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], edx
  4129                              <1> 
  4130 0000C329 E8BAF0FFFF          <1> 	call	convert_current_date_time
  4131                              <1> 	; DX = Date in dos dir entry format
  4132                              <1> 	; AX = Time in dos dir entry format
  4133 0000C32E EB4D                <1> 	jmp	short csftdf2_save_fat_file_7
  4134                              <1> 
  4135                              <1> csftdf2_save_fat_file_err1:
  4136 0000C330 5B                  <1> 	pop	ebx ; *	
  4137                              <1> csftdf2_save_fat_file_err2:
  4138 0000C331 A1[D06F0100]        <1> 	mov	eax, [csftdf_df_wbytes]
  4139 0000C336 8B15[726F0100]      <1> 	mov	edx, [DestinationFile_DirEntry+DirEntry_FileSize]
  4140 0000C33C 39C2                <1> 	cmp	edx, eax
  4141 0000C33E 7616                <1> 	jna	short csftdf2_save_fat_file_err3
  4142 0000C340 A1[C06F0100]        <1> 	mov	eax, [csftdf_df_cluster] ; last (empty) cluster
  4143                              <1> 	; ESI = Logical dos drive description table address
  4144 0000C345 E8160C0000          <1> 	call	truncate_cluster_chain
  4145 0000C34A 720A                <1> 	jc	short csftdf2_save_fat_file_err3
  4146 0000C34C A1[D06F0100]        <1> 	mov	eax, [csftdf_df_wbytes]	
  4147 0000C351 A3[726F0100]        <1> 	mov	[DestinationFile_DirEntry+DirEntry_FileSize], eax
  4148                              <1> csftdf2_save_fat_file_err3:
  4149 0000C356 E88DF0FFFF          <1> 	call	convert_current_date_time
  4150                              <1> 	; DX = Date in dos dir entry format
  4151                              <1> 	; AX = Time in dos dir entry format
  4152 0000C35B C605[636F0100]00    <1> 	mov	byte [DestinationFile_DirEntry+DirEntry_CrtTimeTenth], 0
  4153 0000C362 66A3[646F0100]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_CrtTime], ax
  4154 0000C368 668915[666F0100]    <1> 	mov	[DestinationFile_DirEntry+DirEntry_CrtDate], dx		
  4155 0000C36F 66A3[6C6F0100]      <1> 	mov	[DestinationFile_DirEntry+DirEntry_WrtTime], ax
  4156 0000C375 668915[6E6F0100]    <1> 	mov	[DestinationFile_DirEntry+DirEntry_WrtDate], dx
  4157 0000C37C F9                  <1> 	stc
  4158                              <1> csftdf2_save_fat_file_7:
  4159 0000C37D 9C                  <1> 	pushf
  4160 0000C37E 668915[686F0100]    <1> 	mov	[DestinationFile_DirEntry+DirEntry_LastAccDate], dx
  4161 0000C385 BE[566F0100]        <1> 	mov	esi, DestinationFile_DirEntry
  4162 0000C38A BF00000800          <1> 	mov	edi, Directory_Buffer
  4163 0000C38F 0FB70D[7E6F0100]    <1> 	movzx	ecx, word [DestinationFile_DirEntryNumber] ; (<2048)
  4164 0000C396 66C1E105            <1> 	shl	cx, 5 ; 32 * directory entry number
  4165 0000C39A 01CF                <1> 	add	edi, ecx
  4166                              <1> 	;mov	ecx, 8
  4167 0000C39C 66B90800            <1> 	mov	cx, 8
  4168 0000C3A0 F3A5                <1> 	rep	movsd
  4169 0000C3A2 9D                  <1> 	popf
  4170 0000C3A3 730B                <1> 	jnc	short csftdf2_write_file_OK
  4171                              <1> 	 		
  4172                              <1> csftdf2_write_error:
  4173                              <1> 	; 18/03/2016
  4174 0000C3A5 B01D                <1> 	mov	al, 1Dh ; write error
  4175 0000C3A7 EB02                <1> 	jmp	short csftdf2_rw_error
  4176                              <1> 
  4177                              <1> 	; 16/03/2016
  4178                              <1> csftdf2_read_error:
  4179 0000C3A9 B011                <1> 	mov	al, 17 ; ; Drive not ready or read error!
  4180                              <1> csftdf2_rw_error:
  4181 0000C3AB A2[AD6F0100]        <1> 	mov	[csftdf_rw_err], al 
  4182                              <1> 
  4183                              <1> csftdf2_write_file_OK:
  4184                              <1> 	; 18/03/2016
  4185 0000C3B0 C605[C46B0100]02    <1> 	mov	byte [DirBuff_ValidData], 2
  4186 0000C3B7 E8CAF0FFFF          <1> 	call	save_directory_buffer
  4187                              <1> 
  4188                              <1>  	; Update last modification date&time of destination
  4189                              <1> 	; file's (parent) directory
  4190 0000C3BC E860F1FFFF          <1> 	call	update_parent_dir_lmdt
  4191                              <1> 	;
  4192 0000C3C1 A1[B46F0100]        <1> 	mov	eax, [csftdf_sf_mem_addr] ; start address
  4193                              <1> 
  4194 0000C3C6 21C0                <1> 	and	eax, eax
  4195 0000C3C8 750E                <1> 	jnz	short csftdf2_dealloc_mblock
  4196                              <1> 
  4197 0000C3CA 88C5                <1> 	mov	ch, al ; 0 (Cluster r/w, not full loading)
  4198                              <1> csftdf2_dealloc_retn:
  4199 0000C3CC 8A0D[AD6F0100]      <1> 	mov	cl, [csftdf_rw_err]
  4200 0000C3D2 A1[C06F0100]        <1> 	mov	eax, [csftdf_df_cluster]
  4201 0000C3D7 C3                  <1> 	retn
  4202                              <1> 
  4203                              <1> csftdf2_dealloc_mblock:
  4204 0000C3D8 8B0D[B86F0100]      <1> 	mov	ecx, [csftdf_sf_mem_bsize] ; block size	
  4205 0000C3DE E8799CFFFF          <1> 	call	deallocate_memory_block
  4206 0000C3E3 B5FF                <1>         mov     ch, 0FFh ; (File was full loaded at memory)
  4207 0000C3E5 EBE5                <1> 	jmp	short csftdf2_dealloc_retn
  4208                              <1> 
  4209                              <1> csftdf2_save_fs_file:
  4210                              <1> 	; 16/10/2016 (1Dh -> 18)
  4211                              <1> 	; temporary - (21/03/2016)
  4212 0000C3E7 B812000000          <1> 	mov	eax, 18 ; write error
  4213 0000C3EC F9                  <1> 	stc
  4214 0000C3ED C3                  <1> 	retn
  4215                              <1> 
  4216                              <1> create_file:
  4217                              <1> 	; 16/10/2016
  4218                              <1> 	; 24/03/2016, 31/03/2016
  4219                              <1> 	; 20/03/2016, 21/03/2016, 23/03/2016
  4220                              <1> 	; 19/03/2016 (TRDOS 396 = TRDOS v2.0)
  4221                              <1> 	; 03/09/2011 (FILE.ASM, 'proc_create_file')
  4222                              <1> 	; 09/08/2010
  4223                              <1> 	;
  4224                              <1> 	; INPUT ->
  4225                              <1> 	; 	EAX = File Size
  4226                              <1> 	; 	ESI = ASCIIZ File Name
  4227                              <1> 	; 	CL = File Attributes 
  4228                              <1> 	;	EBX = FFFFFFFFh -> create empty file 
  4229                              <1> 	;			 (only for FAT fs) 
  4230                              <1> 	; OUTPUT ->
  4231                              <1> 	;     CF = 0 ->
  4232                              <1> 	;	EAX = New file's first cluster
  4233                              <1> 	; 	ESI = Logical Dos Drv Descr. Table Addr.
  4234                              <1> 	; 	EBX = offset CreateFile_Size
  4235                              <1> 	; 	ECX = Sectors per cluster (<256) 
  4236                              <1> 	; 	EDX = Directory entry index/number (<65536)
  4237                              <1> 	;     CF = 1 -> error code in AL
  4238                              <1> 
  4239                              <1> ;	test	cl, 18h (directory or volume name)
  4240                              <1> ;	jnz	short loc_createfile_access_denied
  4241 0000C3EE 80E107              <1> 	and	cl, 07h ; S, H, R
  4242 0000C3F1 880D[FC6F0100]      <1>         mov     [createfile_attrib], cl 
  4243                              <1> 
  4244 0000C3F7 89D9                <1> 	mov	ecx, ebx
  4245 0000C3F9 89F3                <1> 	mov	ebx, esi ; ASCIIZ File Name address
  4246 0000C3FB 29D2                <1> 	sub	edx, edx
  4247 0000C3FD 8A35[9E640100]      <1>         mov     dh, [Current_Drv]
  4248 0000C403 BE00010900          <1>         mov     esi, Logical_DOSDisks
  4249 0000C408 01D6                <1> 	add	esi, edx
  4250                              <1> 
  4251 0000C40A 8815[07700100]      <1> 	mov	[createfile_UpdatePDir], dl ; 0 ; 31/03/2016 
  4252                              <1> 
  4253                              <1> 	; LD_DiskType = 0 for write protection (read only) 
  4254 0000C410 807E0101            <1> 	cmp	byte [esi+LD_DiskType], 1 ; 0 = Invalid
  4255 0000C414 730A                <1> 	jnb	short loc_createfile_check_file_sytem
  4256                              <1> 	; 16/10/2016 (TRDOS Error code: 30, disk write protected) 
  4257 0000C416 B81E000000          <1> 	mov	eax, 30 ; 13h, MSDOS err : Disk write-protected 
  4258 0000C41B 66BA0000            <1> 	mov	dx, 0
  4259                              <1> 	; err retn: EDX = 0, EBX = File name offset
  4260                              <1> 	; ESI -> Dos drive description table address	
  4261 0000C41F C3                  <1> 	retn
  4262                              <1> 
  4263                              <1> ;loc_createfile_access_denied:
  4264                              <1> ;	mov	eax, 05h ; access denied (invalid attributes input)
  4265                              <1> ;	stc
  4266                              <1> ;	retn
  4267                              <1> 
  4268                              <1> loc_createfile_check_file_sytem:
  4269 0000C420 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  4270 0000C424 730A                <1> 	jnb	short loc_createfile_chk_empty_FAT_file_sign1
  4271                              <1> 
  4272 0000C426 A3[E86F0100]        <1> 	mov	[createfile_size], eax
  4273                              <1> 	; ESI = Logical Dos Drive Description Table address
  4274                              <1> 	; EBX = ASCIIZ File Name address
  4275 0000C42B E9FE020000          <1> 	jmp	create_fs_file
  4276                              <1> 
  4277                              <1> loc_createfile_chk_empty_FAT_file_sign1:
  4278                              <1> 	; ECX = FFFFFFFFh -> create empty file if drive has FAT fs
  4279 0000C430 41                  <1> 	inc	ecx
  4280 0000C431 7506                <1> 	jnz	short loc_createfile_chk_empty_FAT_file_sign2
  4281 0000C433 890D[E86F0100]      <1> 	mov	[createfile_size], ecx ; 0 ; empty file
  4282                              <1> 
  4283                              <1> loc_createfile_chk_empty_FAT_file_sign2:
  4284                              <1> 	; 23/03/2016
  4285 0000C439 668B4E11            <1> 	mov	cx, [esi+LD_BPB+BytesPerSec]
  4286 0000C43D 66890D[04700100]    <1> 	mov	[createfile_BytesPerSec], cx
  4287                              <1> 	
  4288                              <1> 	; EBX = ASCIIZ File Name address
  4289 0000C444 0FB65613            <1> 	movzx	edx, byte [esi+LD_BPB+SecPerClust]
  4290 0000C448 8815[FD6F0100]      <1> 	mov	[createfile_SecPerClust], dl
  4291 0000C44E 8B4E74              <1> 	mov	ecx, [esi+LD_FreeSectors]
  4292 0000C451 39D1                <1> 	cmp	ecx, edx ; byte [createfile_SecPerClust]
  4293 0000C453 7306                <1> 	jnb	short loc_create_fat_file
  4294                              <1> 	  
  4295                              <1> loc_createfile_insufficient_disk_space:
  4296 0000C455 B827000000          <1> 	mov	eax, 27h
  4297                              <1> loc_createfile_gffc_retn:
  4298 0000C45A C3                  <1> 	retn
  4299                              <1> 
  4300                              <1> loc_create_fat_file:
  4301 0000C45B 891D[E06F0100]      <1> 	mov	[createfile_Name_Offset], ebx
  4302 0000C461 890D[E46F0100]      <1> 	mov	[createfile_FreeSectors], ecx
  4303                              <1> 
  4304                              <1> loc_createfile_gffc_1:
  4305 0000C467 E821050000          <1> 	call	get_first_free_cluster
  4306 0000C46C 72EC                <1> 	jc	short loc_createfile_gffc_retn
  4307                              <1> 
  4308 0000C46E A3[EC6F0100]        <1> 	mov	[createfile_FFCluster], eax
  4309                              <1> 
  4310                              <1> loc_createfile_locate_ffe_on_directory:
  4311                              <1> 	; Current directory fcluster <> Directory buffer cluster
  4312                              <1> 	; Current directory will be reloaded by
  4313                              <1> 	; 'locate_current_dir_file' procedure
  4314                              <1> 	;
  4315                              <1> 	; ESI = Logical Dos Drv Desc. Table Adress
  4316 0000C473 56                  <1> 	push	esi ; *
  4317 0000C474 31C0                <1> 	xor	eax, eax
  4318                              <1> 
  4319 0000C476 A3[BA6B0100]        <1> 	mov	dword [FAT_ClusterCounter], eax ; 0
  4320                              <1> 	; 21/03/2016
  4321 0000C47B A2[06700100]        <1> 	mov	byte [createfile_wfc], al ; 0 
  4322                              <1> 
  4323 0000C480 89C1                <1>  	mov	ecx, eax
  4324 0000C482 6649                <1> 	dec	cx ; FFFFh  
  4325                              <1> 	; CX = FFFFh -> find first deleted or free entry
  4326                              <1> 	; ESI would be ASCIIZ filename address if the call
  4327                              <1> 	; would not be for first free or deleted dir entry  
  4328 0000C484 E8D7E7FFFF          <1> 	call	locate_current_dir_file
  4329 0000C489 0F83EE000000        <1> 	jnc	loc_createfile_set_ff_dir_entry
  4330 0000C48F 5E                  <1> 	pop	esi ; *
  4331                              <1> 	 ; ESI = Logical DOS Drv. Description Table Address 
  4332 0000C490 83F802              <1> 	cmp	eax, 2
  4333 0000C493 7402                <1> 	je	short loc_createfile_add_new_cluster
  4334                              <1> loc_createfile_locate_file_stc_retn:
  4335 0000C495 F9                  <1> 	stc
  4336 0000C496 C3                  <1> 	retn
  4337                              <1> 
  4338                              <1> loc_createfile_add_new_cluster:
  4339 0000C497 803D[9D640100]02    <1> 	cmp	byte [Current_FATType], 2
  4340                              <1> 	;cmp	byte [esi+LD_FATType], 2
  4341 0000C49E 770C                <1> 	ja	short loc_createfile_add_new_cluster_check_fsc
  4342 0000C4A0 803D[9C640100]01    <1> 	cmp	byte [Current_Dir_Level], 1
  4343                              <1> 	;cmp	byte [esi+LD_CDirLevel], 1
  4344 0000C4A7 7303                <1> 	jnb	short loc_createfile_add_new_cluster_check_fsc
  4345                              <1> 	
  4346                              <1> 	;mov	eax, 12
  4347 0000C4A9 B00C                <1> 	mov	al, 12 ; No more files 
  4348                              <1> 
  4349                              <1> loc_createfile_anc_retn:
  4350 0000C4AB C3                  <1> 	retn
  4351                              <1> 
  4352                              <1> loc_createfile_add_new_cluster_check_fsc:
  4353 0000C4AC 8B0D[E46F0100]      <1> 	mov	ecx, [createfile_FreeSectors]
  4354 0000C4B2 0FB605[FD6F0100]    <1> 	movzx	eax, byte [createfile_SecPerClust]
  4355 0000C4B9 66D1E0              <1> 	shl	ax, 1 ; AX = 2 * AX
  4356 0000C4BC 39C1                <1> 	cmp	ecx, eax
  4357 0000C4BE 7295                <1>         jb	short loc_createfile_insufficient_disk_space
  4358                              <1> 
  4359                              <1> loc_createfile_add_new_subdir_cluster:
  4360 0000C4C0 8B15[C96B0100]      <1> 	mov	edx, [DirBuff_Cluster]
  4361 0000C4C6 8915[F06F0100]      <1> 	mov	[createfile_LastDirCluster], edx	
  4362                              <1> 
  4363 0000C4CC A1[EC6F0100]        <1> 	mov	eax, [createfile_FFCluster]
  4364 0000C4D1 E846040000          <1> 	call	load_FAT_sub_directory 
  4365 0000C4D6 72D3                <1> 	jc	short loc_createfile_anc_retn
  4366                              <1> 
  4367                              <1> pass_createfile_add_new_subdir_cluster:
  4368                              <1> 	;movzx	eax, word [esi+LD_BPB+BytesPerSec]
  4369 0000C4D8 0FB705[04700100]    <1> 	movzx	eax, word [createfile_BytesPerSec] ; 23/03/2016
  4370 0000C4DF F7E1                <1> 	mul	ecx ; ecx = directory buffer sector count
  4371 0000C4E1 89C1                <1> 	mov	ecx, eax
  4372 0000C4E3 C1E902              <1> 	shr	ecx, 2 ; dword count
  4373 0000C4E6 29C0                <1> 	sub	eax, eax ; 0
  4374 0000C4E8 F3AB                <1> 	rep	stosd 
  4375                              <1> 	;
  4376 0000C4EA C605[C46B0100]02    <1> 	mov	byte [DirBuff_ValidData], 2 
  4377 0000C4F1 E890EFFFFF          <1> 	call	save_directory_buffer
  4378 0000C4F6 72B3                <1> 	jc	short loc_createfile_anc_retn
  4379                              <1> 
  4380                              <1> loc_createfile_save_added_subdir_cluster:
  4381 0000C4F8 A1[F06F0100]        <1> 	mov	eax, [createfile_LastDirCluster]
  4382 0000C4FD 8B0D[EC6F0100]      <1> 	mov	ecx, [createfile_FFCluster]
  4383 0000C503 E858050000          <1> 	call	update_cluster
  4384 0000C508 7304                <1> 	jnc	short loc_createfile_save_fat_buffer_0
  4385 0000C50A 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  4386 0000C50C 751A                <1> 	jnz	short loc_createfile_save_fat_buffer_stc_retn
  4387                              <1> 
  4388                              <1> loc_createfile_save_fat_buffer_0:
  4389 0000C50E A1[EC6F0100]        <1> 	mov	eax, [createfile_FFCluster]
  4390 0000C513 A3[F06F0100]        <1> 	mov	[createfile_LastDirCluster], eax
  4391 0000C518 B9FFFFFF0F          <1> 	mov	ecx, 0FFFFFFFh ; 28 bit
  4392 0000C51D E83E050000          <1> 	call	update_cluster
  4393 0000C522 7306                <1> 	jnc	short loc_createfile_save_fat_buffer_1
  4394 0000C524 09C0                <1> 	or	eax, eax ; Was it free cluster
  4395 0000C526 7402                <1> 	jz	short loc_createfile_save_fat_buffer_1
  4396                              <1> 
  4397                              <1> loc_createfile_save_fat_buffer_stc_retn:
  4398 0000C528 F9                  <1> 	stc
  4399                              <1> loc_createfile_save_fat_buffer_retn:
  4400                              <1> loc_createfile_gffc_2_stc_retn:
  4401 0000C529 C3                  <1> 	retn
  4402                              <1> 
  4403                              <1> loc_createfile_save_fat_buffer_1:
  4404                              <1> 	; byte [FAT_BuffValidData] = 2 
  4405 0000C52A E8EE070000          <1> 	call	save_fat_buffer
  4406 0000C52F 72F8                <1> 	jc	short loc_createfile_save_fat_buffer_retn
  4407                              <1> 
  4408 0000C531 803D[BA6B0100]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  4409 0000C538 7222                <1> 	jb	short loc_createfile_save_fat_buffer_2
  4410                              <1> 
  4411                              <1> 	; ESI = Logical DOS Drive Description Table address 
  4412 0000C53A A1[BA6B0100]        <1> 	mov	eax, [FAT_ClusterCounter]
  4413                              <1> 
  4414 0000C53F C605[BA6B0100]00    <1> 	mov	byte [FAT_ClusterCounter], 0 ; 21/03/2016
  4415                              <1> 
  4416 0000C546 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  4417 0000C54A E863080000          <1> 	call	calculate_fat_freespace
  4418                              <1> 
  4419                              <1> 	;inc	eax ; 0FFFFFFFFh -> 0 ; recalculation is needed!
  4420                              <1> 	;jnz	short loc_createfile_save_fat_buffer_2
  4421                              <1> 
  4422                              <1> 	; ecx > 0 -> Recalculation is needed
  4423 0000C54F 09C9                <1> 	or	ecx, ecx 
  4424 0000C551 7409                <1> 	jz	short loc_createfile_save_fat_buffer_2
  4425                              <1> 
  4426 0000C553 66BB00FF            <1> 	mov	bx, 0FF00h ; ; recalculate free space
  4427 0000C557 E856080000          <1> 	call	calculate_fat_freespace
  4428                              <1> 
  4429                              <1> loc_createfile_save_fat_buffer_2:
  4430                              <1> 	;call	update_parent_dir_lmdt
  4431                              <1> 
  4432                              <1> loc_createfile_gffc_2:
  4433 0000C55C E82C040000          <1> 	call	get_first_free_cluster
  4434 0000C561 72C6                <1> 	jc	short loc_createfile_gffc_2_stc_retn
  4435                              <1> 
  4436 0000C563 A3[EC6F0100]        <1> 	mov	[createfile_FFCluster], eax
  4437                              <1> 
  4438 0000C568 A1[F06F0100]        <1> 	mov	eax, [createfile_LastDirCluster]
  4439                              <1> 	
  4440 0000C56D E8AA030000          <1> 	call	load_FAT_sub_directory 
  4441 0000C572 72B5                <1> 	jc	short loc_createfile_gffc_2_stc_retn
  4442                              <1> 
  4443 0000C574 BF00000800          <1> 	mov	edi, Directory_Buffer
  4444                              <1> 
  4445 0000C579 6629DB              <1> 	sub	bx, bx ; directory entry index/number = 0
  4446                              <1> 
  4447 0000C57C 56                  <1> 	push	esi ; * ; 23/03/2016
  4448                              <1> 
  4449                              <1> loc_createfile_set_ff_dir_entry:
  4450 0000C57D 66891D[FE6F0100]    <1> 	mov	[createfile_DirIndex], bx
  4451                              <1> 
  4452                              <1>         ; EDI = Directory entry address
  4453 0000C584 8B35[E06F0100]      <1> 	mov	esi, [createfile_Name_Offset]
  4454 0000C58A A1[EC6F0100]        <1> 	mov	eax, [createfile_FFCluster]
  4455 0000C58F A3[F46F0100]        <1> 	mov	[createfile_Cluster], eax ; 24/03/2016
  4456 0000C594 B5FF                <1> 	mov	ch, 0FFh
  4457 0000C596 8A0D[FC6F0100]      <1>         mov	cl, [createfile_attrib] ; file attributes
  4458                              <1> 	; CH > 0 -> File size is in [EBX]
  4459 0000C59C BB[E86F0100]        <1> 	mov	ebx, createfile_size
  4460                              <1>   
  4461 0000C5A1 E803EEFFFF          <1> 	call	make_directory_entry
  4462                              <1> 	
  4463 0000C5A6 5E                  <1> 	pop	esi ; * ; ESI = Logical Dos Drv Desc. Table address
  4464                              <1> 
  4465 0000C5A7 C605[C46B0100]02    <1> 	mov	byte [DirBuff_ValidData], 2 
  4466 0000C5AE E8D3EEFFFF          <1> 	call	save_directory_buffer
  4467 0000C5B3 7221                <1> 	jc	short loc_createfile_set_ff_dir_entry_retn
  4468                              <1> 
  4469 0000C5B5 C605[07700100]01    <1> 	mov	byte [createfile_UpdatePDir], 1 ; 31/03/2016 
  4470                              <1> 
  4471                              <1> loc_createfile_get_set_write_file_cluster:
  4472 0000C5BC A1[E86F0100]        <1> 	mov	eax, [createfile_size]
  4473 0000C5C1 09C0                <1> 	or	eax, eax
  4474 0000C5C3 7570                <1> 	jnz	short loc_createfile_get_set_wfc_cont
  4475 0000C5C5 40                  <1> 	inc	eax
  4476                              <1> 	; 23/03/2016
  4477 0000C5C6 0FB61D[FD6F0100]    <1> 	movzx	ebx, byte [createfile_SecPerClust]
  4478                              <1> 	;movzx	ecx, word [esi+LD_BPB+BytesPerSec] ; 512
  4479 0000C5CD 0FB70D[04700100]    <1>         movzx   ecx, word [createfile_BytesPerSec] ; 512
  4480 0000C5D4 EB7C                <1> 	jmp	loc_createfile_set_cluster_count 
  4481                              <1> 
  4482                              <1> loc_createfile_set_ff_dir_entry_retn:
  4483 0000C5D6 C3                  <1> 	retn
  4484                              <1> 
  4485                              <1> loc_createfile_write_fcluster_to_disk:
  4486 0000C5D7 034668              <1> 	add	eax, [esi+LD_DATABegin] ; convert to physical address
  4487 0000C5DA BB00000700          <1> 	mov	ebx, Cluster_Buffer
  4488                              <1> 	; ESI = Logical DOS Drv. Desc. Tbl. address
  4489                              <1> 	; EAX = Disk address
  4490                              <1> 	; EBX = Sector Buffer
  4491                              <1> 	; ECX = sectors per cluster
  4492 0000C5DF E8FD3C0000          <1> 	call	disk_write
  4493 0000C5E4 7211                <1> 	jc	short loc_createfile_dsk_wr_err
  4494                              <1> 
  4495                              <1> loc_createfile_update_fat_cluster:
  4496                              <1> 	; 21/03/2016	
  4497 0000C5E6 803D[06700100]00    <1> 	cmp	byte [createfile_wfc], 0 
  4498 0000C5ED 7712                <1> 	ja	short loc_createfile_update_fat_cluster_n1
  4499                              <1> 
  4500 0000C5EF FE05[06700100]      <1> 	inc	byte [createfile_wfc] ; 1
  4501 0000C5F5 EB24                <1> 	jmp	short loc_createfile_update_fat_cluster_n2
  4502                              <1> 
  4503                              <1> loc_createfile_dsk_wr_err:
  4504                              <1> 	; 16/10/2016 (1Dh -> 18)
  4505                              <1> 	; 23/03/2016
  4506 0000C5F7 B812000000          <1> 	mov	eax, 18 ; Drive not ready or write error !
  4507 0000C5FC E9BD000000          <1> 	jmp	loc_createfile_stc_retn
  4508                              <1> 
  4509                              <1> loc_createfile_update_fat_cluster_n1:
  4510 0000C601 A1[F86F0100]        <1> 	mov	eax, [createfile_PCluster]
  4511 0000C606 8B0D[F46F0100]      <1> 	mov	ecx, [createfile_Cluster]
  4512 0000C60C E84F040000          <1> 	call	update_cluster
  4513 0000C611 7308                <1> 	jnc	short loc_createfile_update_fat_cluster_n2
  4514 0000C613 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  4515 0000C615 0F85A3000000        <1> 	jnz	loc_createfile_stc_retn
  4516                              <1> 
  4517                              <1> loc_createfile_update_fat_cluster_n2:
  4518 0000C61B A1[F46F0100]        <1>         mov	eax, [createfile_Cluster]
  4519 0000C620 B9FFFFFF0F          <1> 	mov	ecx, 0FFFFFFFh
  4520 0000C625 E836040000          <1> 	call	update_cluster
  4521 0000C62A 734E                <1> 	jnc	short loc_createfile_save_fat_buffer_3
  4522 0000C62C 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  4523 0000C62E 744A                <1> 	jz	short loc_createfile_save_fat_buffer_3
  4524                              <1> 
  4525                              <1> loc_createfile_upd_fat_fcluster_stc_retn:
  4526 0000C630 E989000000          <1> 	jmp	loc_createfile_stc_retn
  4527                              <1> 
  4528                              <1> loc_createfile_get_set_wfc_cont:
  4529                              <1> 	;movzx	ecx, word [esi+LD_BPB+BytesPerSec] ; 512	
  4530 0000C635 0FB70D[04700100]    <1> 	movzx	ecx, word [createfile_BytesPerSec] ; 512
  4531 0000C63C 01C8                <1> 	add	eax, ecx
  4532 0000C63E 48                  <1> 	dec	eax  ; add eax, 511
  4533 0000C63F 29D2                <1> 	sub	edx, edx
  4534 0000C641 F7F1                <1> 	div	ecx
  4535 0000C643 0FB61D[FD6F0100]    <1> 	movzx	ebx, byte [createfile_SecPerClust]
  4536 0000C64A 01D8                <1> 	add	eax, ebx
  4537 0000C64C 48                  <1> 	dec	eax  ; add eax, SecPerClust - 1
  4538 0000C64D 6631D2              <1> 	xor	dx, dx
  4539 0000C650 F7F3                <1> 	div	ebx
  4540                              <1> 
  4541                              <1> loc_createfile_set_cluster_count:
  4542 0000C652 A3[00700100]        <1> 	mov 	[createfile_CCount], eax
  4543                              <1> 	
  4544 0000C657 BF00000700          <1> 	mov	edi, Cluster_Buffer
  4545 0000C65C 89C8                <1> 	mov	eax, ecx ; Bytes per Sector
  4546 0000C65E F7E3                <1> 	mul	ebx ; Sectors per Cluster 
  4547                              <1> 	; EAX = Bytes per Cluster
  4548 0000C660 89C1                <1> 	mov	ecx, eax
  4549 0000C662 C1E902              <1> 	shr	ecx, 2 ; dword count
  4550 0000C665 31C0                <1> 	xor	eax, eax
  4551 0000C667 F3AB                <1> 	rep	stosd ; clear cluster buffer
  4552                              <1> 
  4553 0000C669 A1[F46F0100]        <1> 	mov	eax, [createfile_Cluster] ; 24/03/2016
  4554                              <1> 
  4555 0000C66E 89D9                <1> 	mov	ecx, ebx
  4556                              <1> 
  4557                              <1> loc_createfile_get_set_wf_fclust_cont:
  4558 0000C670 83E802              <1> 	sub	eax, 2
  4559 0000C673 F7E1                <1> 	mul	ecx
  4560                              <1> 	; EAX = Logical DOS disk address (offset)
  4561 0000C675 E95DFFFFFF          <1>         jmp     loc_createfile_write_fcluster_to_disk
  4562                              <1> 
  4563                              <1> loc_createfile_save_fat_buffer_3:
  4564                              <1> 	; byte [FAT_BuffValidData] = 2
  4565 0000C67A E89E060000          <1> 	call	save_fat_buffer
  4566 0000C67F 723D                <1> 	jc	loc_createfile_stc_retn
  4567                              <1> 
  4568                              <1> 	; 21/03/2016
  4569 0000C681 803D[BA6B0100]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  4570 0000C688 721B                <1> 	jb	short loc_createfile_save_fat_buffer_4
  4571                              <1> 
  4572                              <1> 	; ESI = Logical DOS Drive Description Table address 
  4573 0000C68A A1[BA6B0100]        <1> 	mov	eax, [FAT_ClusterCounter]
  4574 0000C68F 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  4575 0000C693 E81A070000          <1> 	call	calculate_fat_freespace
  4576                              <1> 
  4577                              <1> 	;inc	eax ; 0FFFFFFFFh -> 0 ; recalculation is needed!
  4578                              <1> 	;jnz	short loc_createfile_save_fat_buffer_4
  4579                              <1> 
  4580                              <1> 	; ecx > 0 -> Recalculation is needed
  4581 0000C698 09C9                <1> 	or	ecx, ecx 
  4582 0000C69A 7409                <1> 	jz	short loc_createfile_save_fat_buffer_4
  4583                              <1> 
  4584 0000C69C 66BB00FF            <1> 	mov	bx, 0FF00h ; ; recalculate free space
  4585 0000C6A0 E80D070000          <1> 	call	calculate_fat_freespace
  4586                              <1> 
  4587                              <1> loc_createfile_save_fat_buffer_4:
  4588 0000C6A5 FF0D[00700100]      <1> 	dec	dword [createfile_CCount]
  4589                              <1> 	;jz	short loc_createfile_upd_dir_modif_date_time
  4590 0000C6AB 743F                <1> 	jz	short loc_createfile_stc_retn_cc ; 31/03/2016
  4591                              <1> 
  4592                              <1> loc_createfile_get_set_write_next_cluster:
  4593 0000C6AD E8DB020000          <1> 	call	get_first_free_cluster
  4594 0000C6B2 720A                <1> 	jc	short loc_createfile_stc_retn
  4595                              <1> 
  4596                              <1> loc_createfile_get_set_write_next_cluster_1:
  4597 0000C6B4 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh
  4598 0000C6B7 7213                <1> 	jb	short loc_createfile_get_set_write_next_cluster_2
  4599                              <1> 
  4600                              <1> loc_createfile_wnc_insufficient_disk_space:	
  4601 0000C6B9 B827000000          <1> 	mov	eax, 27h ; Insufficient disk space
  4602                              <1> 
  4603                              <1> loc_createfile_stc_retn:
  4604 0000C6BE 803D[06700100]01    <1> 	cmp	byte [createfile_wfc], 1
  4605 0000C6C5 7324                <1> 	jnb	short loc_createfile_err_retn
  4606 0000C6C7 C3                  <1> 	retn
  4607                              <1> 
  4608                              <1> loc_createfile_wnc_inv_format_retn:
  4609                              <1> 	;mov	eax, 28
  4610 0000C6C8 B01C                <1> 	mov	al, 28 ; Invalid format
  4611 0000C6CA EBF2                <1> 	jmp	short loc_createfile_stc_retn
  4612                              <1> 	         
  4613                              <1> loc_createfile_get_set_write_next_cluster_2:
  4614 0000C6CC 83F802              <1> 	cmp	eax, 2
  4615 0000C6CF 72F7                <1> 	jb	short loc_createfile_wnc_inv_format_retn
  4616                              <1> 
  4617                              <1> loc_createfile_get_set_write_next_cluster_3:
  4618 0000C6D1 8B0D[F46F0100]      <1> 	mov	ecx, [createfile_Cluster]
  4619 0000C6D7 A3[F46F0100]        <1> 	mov	[createfile_Cluster], eax
  4620 0000C6DC 890D[F86F0100]      <1> 	mov	[createfile_PCluster], ecx
  4621 0000C6E2 0FB60D[FD6F0100]    <1> 	movzx	ecx, byte [createfile_SecPerClust]
  4622 0000C6E9 EB85                <1> 	jmp	short loc_createfile_get_set_wf_fclust_cont
  4623                              <1> 
  4624                              <1> loc_createfile_err_retn:
  4625 0000C6EB F9                  <1> 	stc
  4626                              <1> 
  4627                              <1> ;loc_createfile_upd_dir_modif_date_time:
  4628                              <1> loc_createfile_stc_retn_cc: ; 31/03/2016
  4629 0000C6EC 9C                  <1> 	pushf	; cpu is here for an error return or completion 
  4630 0000C6ED 50                  <1> 	push	eax ; error code if cf = 1
  4631                              <1> 
  4632                              <1> 	;call	update_parent_dir_lmdt
  4633                              <1> 
  4634                              <1> ;loc_createfile_stc_retn_cc:
  4635 0000C6EE A1[BA6B0100]        <1> 	mov	eax, [FAT_ClusterCounter]
  4636 0000C6F3 09C0                <1> 	or	eax, eax
  4637 0000C6F5 741A                <1> 	jz	short loc_createfile_stc_retn_pop_eax
  4638 0000C6F7 8A3D[9E640100]      <1> 	mov	bh, [Current_Drv]
  4639 0000C6FD B301                <1> 	mov	bl, 01h ; BL = 1 -> add clusters
  4640                              <1> 	; NOTE: EAX value will be added to Free Cluster Count
  4641                              <1> 	; (If EAX value is negative, Free Cluster Count will be decreased)
  4642 0000C6FF E8AE060000          <1>   	call	calculate_fat_freespace
  4643                              <1>         ; ESI = Logical DOS Drive Description Table Address 
  4644                              <1>         ;jc	short loc_createfile_stc_retn_pop_eax_cf
  4645 0000C704 21C9                <1> 	and	ecx, ecx ; cx = 0 -> valid free sector count
  4646 0000C706 7409                <1> 	jz	short loc_createfile_stc_retn_pop_eax
  4647                              <1> 
  4648                              <1> loc_createfile_stc_retn_recalc_FAT_freespace:
  4649 0000C708 66BB00FF            <1> 	mov	bx, 0FF00h ; bh = 0FFh -> 
  4650                              <1> 	; ESI = Logical DOS Drv DT Addr
  4651                              <1> 	; BL = 0 -> Recalculate 
  4652 0000C70C E8A1060000          <1> 	call	calculate_fat_freespace
  4653                              <1> 
  4654                              <1> loc_createfile_stc_retn_pop_eax:
  4655 0000C711 58                  <1> 	pop	eax
  4656 0000C712 9D                  <1> 	popf
  4657 0000C713 7218                <1> 	jc	short loc_createfile_retn
  4658                              <1> 
  4659                              <1> loc_createfile_retn_fcluster:
  4660 0000C715 A1[EC6F0100]        <1> 	mov	eax, [createfile_FFCluster]
  4661 0000C71A BB[E86F0100]        <1> 	mov	ebx, createfile_size
  4662                              <1> 	;movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  4663 0000C71F 0FB60D[FD6F0100]    <1> 	movzx	ecx, byte [createfile_SecPerClust] ; 23/03/2016
  4664 0000C726 0FB715[FE6F0100]    <1> 	movzx	edx, word [createfile_DirIndex]
  4665                              <1> 
  4666                              <1> loc_createfile_retn:
  4667 0000C72D C3                  <1> 	retn
  4668                              <1> 
  4669                              <1> create_fs_file:
  4670                              <1> 	; temporary (21/03/2016)
  4671 0000C72E C3                  <1> 	retn
  4672                              <1> 
  4673                              <1> delete_fs_file:
  4674                              <1> 	; temporary (28/02/2016)
  4675 0000C72F C3                  <1> 	retn
  4676                              <1> 
  4677                              <1> rename_fs_file_or_directory:
  4678 0000C730 C3                  <1> 	retn
  4679                              <1> 
  4680                              <1> make_fs_directory:
  4681                              <1> 	; temporary (21/02/2016)
  4682 0000C731 C3                  <1> 	retn
  4683                              <1> 
  4684                              <1> add_new_fs_section:
  4685                              <1> 	; temporary (11/03/2016)
  4686 0000C732 C3                  <1> 	retn
  4687                              <1> 
  4688                              <1> delete_fs_directory_entry:
  4689                              <1> 	; temporary (11/03/2016)
  4690 0000C733 C3                  <1> 	retn
  4691                              <1> 
  4692                              <1> csftdf2_read_fs_file_sectors:
  4693                              <1> 	; temporary (19/03/2016)
  4694 0000C734 C3                  <1> 	retn
  4695                              <1> 
  4696                              <1> csftdf2_write_fs_file_sectors:
  4697                              <1> 	; temporary (19/03/2016)
  4698 0000C735 C3                  <1> 	retn
  3034                                  %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: 23/10/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> 	; 15/10/2016
    17                              <1> 	; 23/03/2016
    18                              <1> 	; 01/02/2016 (TRDOS 386 =  TRDOS v2.0)
    19                              <1> 	; 05/07/2011
    20                              <1> 	; 07/07/2009
    21                              <1> 	; 2005
    22                              <1> 	; INPUT ->
    23                              <1> 	;	EAX = Cluster Number (32 bit)
    24                              <1> 	;	ESI = Logical DOS Drive Parameters Table
    25                              <1> 	; OUTPUT ->
    26                              <1> 	;	cf = 0 -> No Error, EAX valid
    27                              <1> 	;	cf = 1 & EAX = 0 -> End Of Cluster Chain
    28                              <1> 	;	cf = 1 & EAX > 0 -> Error
    29                              <1> 	;	ECX = Current/Previous cluster (if CF = 0)
    30                              <1> 	;	EAX = Next Cluster Number (32 bit)
    31                              <1> 	;
    32                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
    33                              <1> 
    34 0000C736 A3[AE6B0100]        <1> 	mov	[FAT_CurrentCluster], eax
    35                              <1> check_next_cluster_fat_type:
    36 0000C73B 29D2                <1> 	sub	edx, edx ; 0
    37 0000C73D 807E0302            <1>         cmp     byte [esi+LD_FATType], 2
    38 0000C741 7250                <1> 	jb	short get_FAT12_next_cluster
    39 0000C743 0F87AF000000        <1>         ja      get_FAT32_next_cluster
    40                              <1> get_FAT16_next_cluster:
    41 0000C749 BB00030000          <1> 	mov	ebx, 300h ;768
    42 0000C74E F7F3                <1> 	div	ebx
    43                              <1> 	; EAX = Count of 3 FAT sectors
    44                              <1> 	; EDX = Cluster Offset (< 768)
    45 0000C750 66D1E2              <1> 	shl	dx, 1 ; Multiply by 2
    46 0000C753 89D3                <1> 	mov	ebx, edx ; Byte Offset
    47 0000C755 81C3001C0900        <1> 	add	ebx, FAT_Buffer
    48 0000C75B 66BA0300            <1> 	mov	dx, 3
    49 0000C75F F7E2                <1> 	mul	edx  
    50                              <1> 	; EAX = FAT Sector (<= 256)
    51                              <1> 	; EDX = 0
    52 0000C761 8A0E                <1> 	mov	cl, [esi+LD_Name]
    53 0000C763 803D[B26B0100]00    <1> 	cmp	byte [FAT_BuffValidData], 0
    54 0000C76A 0F86CC000000        <1>         jna     load_FAT_sectors0
    55 0000C770 3A0D[B36B0100]      <1> 	cmp	cl, [FAT_BuffDrvName]
    56 0000C776 0F85C0000000        <1>         jne     load_FAT_sectors0
    57 0000C77C 3B05[B66B0100]      <1> 	cmp	eax, [FAT_BuffSector]
    58 0000C782 0F85BA000000        <1>         jne     load_FAT_sectors1
    59                              <1> 	;movzx	eax, word [ebx]
    60 0000C788 668B03              <1> 	mov	ax, [ebx]
    61                              <1> 	; 01/02/2016
    62                              <1> 	; DRV_FAT.ASM (21/08/2011) had a FATal bug here !
    63                              <1> 	; (cmp ah, 0Fh) ! (ax >= FF7h)
    64                              <1> 	; (how can i do a such mistake!?)
    65                              <1> 	;cmp	al, 0F7h
    66                              <1> 	;jb	short loc_pass_gnc_FAT16_eoc_check
    67                              <1> 	;cmp	ah, 0FFh
    68                              <1> 	;jb	short loc_pass_gnc_FAT16_eoc_check
    69 0000C78B 6683F8F7            <1> 	cmp	ax, 0FFF7h
    70 0000C78F 725A                <1> 	jb	short loc_pass_gnc_FAT16_eoc_check
    71                              <1> 	; ax >= FFF7h (cluster 0002h to FFF6h is valid, in use)
    72 0000C791 EB56                <1> 	jmp	short loc_pass_gnc_FAT16_eoc_check_xor_eax
    73                              <1> 
    74                              <1> get_FAT12_next_cluster:
    75 0000C793 BB00040000          <1> 	mov	ebx, 400h ;1024
    76 0000C798 F7F3                <1> 	div	ebx
    77                              <1> 	; EAX = Count of 3 FAT sectors
    78                              <1> 	; EDX = Cluster Offset (< 1024)
    79 0000C79A 6650                <1> 	push	ax
    80 0000C79C 66B80300            <1> 	mov	ax, 3	
    81 0000C7A0 66F7E2              <1> 	mul	dx    	; Multiply by 3
    82 0000C7A3 66D1E8              <1> 	shr	ax, 1	; Divide by 2
    83 0000C7A6 6689C3              <1>         mov	bx, ax 	; Byte Offset
    84 0000C7A9 81C3001C0900        <1> 	add	ebx, FAT_Buffer
    85 0000C7AF 6658                <1> 	pop	ax
    86 0000C7B1 66BA0300            <1> 	mov	dx, 3
    87 0000C7B5 F7E2                <1> 	mul	edx 
    88                              <1> 	; EAX = FAT Sector (<= 12)
    89                              <1> 	; EDX = 0
    90 0000C7B7 8A0E                <1> 	mov	cl, [esi+LD_Name]
    91 0000C7B9 803D[B26B0100]00    <1> 	cmp	byte [FAT_BuffValidData], 0
    92 0000C7C0 767A                <1> 	jna	short load_FAT_sectors0
    93 0000C7C2 3A0D[B36B0100]      <1> 	cmp	cl, [FAT_BuffDrvName]
    94 0000C7C8 7572                <1> 	jne	short load_FAT_sectors0
    95 0000C7CA 3B05[B66B0100]      <1> 	cmp	eax, [FAT_BuffSector]
    96 0000C7D0 7570                <1> 	jne	short load_FAT_sectors1
    97 0000C7D2 A1[AE6B0100]        <1> 	mov	eax, [FAT_CurrentCluster]
    98 0000C7D7 66D1E8              <1> 	shr	ax, 1
    99                              <1> 	;movzx	eax, word [ebx]
   100 0000C7DA 668B03              <1> 	mov	ax, [ebx]
   101 0000C7DD 7314                <1> 	jnc	short get_FAT12_nc_even
   102 0000C7DF 66C1E804            <1> 	shr	ax, 4
   103                              <1> loc_gnc_fat12_eoc_check:
   104                              <1> 	;cmp	al, 0F7h
   105                              <1> 	;jb	short loc_pass_gnc_FAT16_eoc_check
   106                              <1> 	;cmp	ah, 0Fh
   107                              <1> 	;jb	short loc_pass_gnc_FAT16_eoc_check
   108 0000C7E3 663DF70F            <1> 	cmp	ax, 0FF7h
   109 0000C7E7 7202                <1> 	jb	short loc_pass_gnc_FAT16_eoc_check
   110                              <1> 	; ax >= FF7h (cluster 0002h to FF6h is valid, in use)
   111                              <1> 
   112                              <1> loc_pass_gnc_FAT16_eoc_check_xor_eax:
   113 0000C7E9 31C0                <1> 	xor	eax, eax ; 0
   114                              <1> loc_pass_gnc_FAT16_eoc_check:
   115                              <1> loc_pass_gnc_FAT32_eoc_check:
   116 0000C7EB 8B0D[AE6B0100]      <1> 	mov	ecx, [FAT_CurrentCluster]
   117 0000C7F1 F5                  <1> 	cmc
   118 0000C7F2 C3                  <1> 	retn
   119                              <1> 
   120                              <1> get_FAT12_nc_even:
   121 0000C7F3 80E40F              <1> 	and	ah, 0Fh
   122 0000C7F6 EBEB                <1> 	jmp	short loc_gnc_fat12_eoc_check
   123                              <1> 
   124                              <1> get_FAT32_next_cluster:
   125 0000C7F8 BB80010000          <1> 	mov	ebx, 180h ;384
   126 0000C7FD F7F3                <1> 	div	ebx
   127                              <1> 	; EAX = Count of 3 FAT sectors
   128                              <1> 	; EDX = Cluster Offset (< 384)
   129 0000C7FF 66C1E202            <1> 	shl	dx, 2	; Multiply by 4
   130 0000C803 89D3                <1> 	mov	ebx, edx ; Byte Offset
   131 0000C805 81C3001C0900        <1> 	add	ebx, FAT_Buffer
   132 0000C80B 66BA0300            <1> 	mov	dx, 3
   133 0000C80F F7E2                <1> 	mul	edx	
   134                              <1>         ; EAX = FAT Sector (<= 2097152) ; (FFFFFF7h * 4) / 512
   135                              <1> 	; 	for 32KB cluster size:
   136                              <1> 	;	EAX <= 1024 = (4GB / 32KB) * 4) / 512 	
   137                              <1> 	; EDX = 0
   138 0000C811 8A0E                <1> 	mov	cl, [esi+LD_Name]
   139 0000C813 803D[B26B0100]00    <1> 	cmp	byte [FAT_BuffValidData], 0
   140 0000C81A 7620                <1> 	jna	short load_FAT_sectors0
   141 0000C81C 3A0D[B36B0100]      <1> 	cmp	cl, [FAT_BuffDrvName]
   142 0000C822 7518                <1> 	jne	short load_FAT_sectors0
   143 0000C824 3B05[B66B0100]      <1> 	cmp	eax, [FAT_BuffSector] ; 0, 3, 6, 9 ...
   144 0000C82A 7516                <1> 	jne	short load_FAT_sectors1
   145 0000C82C 8B03                <1> 	mov	eax, [ebx]
   146 0000C82E 25FFFFFF0F          <1>  	and	eax, 0FFFFFFFh ; 28 bit Cluster
   147 0000C833 3DF7FFFF0F          <1> 	cmp	eax, 0FFFFFF7h
   148 0000C838 72B1                <1> 	jb	short loc_pass_gnc_FAT32_eoc_check
   149                              <1> 	; eax >= FFFFFF7h (cluster 0002h to FFFFFF6h is valid)
   150 0000C83A EBAD                <1> 	jmp	short loc_pass_gnc_FAT16_eoc_check_xor_eax
   151                              <1> 
   152                              <1> load_FAT_sectors0:
   153 0000C83C 880D[B36B0100]      <1> 	mov	[FAT_BuffDrvName], cl
   154                              <1> load_FAT_sectors1:
   155 0000C842 A3[B66B0100]        <1> 	mov	[FAT_BuffSector], eax
   156 0000C847 89C3                <1> 	mov	ebx, eax
   157 0000C849 034660              <1>         add     eax, [esi+LD_FATBegin]
   158 0000C84C 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
   159 0000C850 7706                <1>         ja      short load_FAT_sectors3
   160 0000C852 0FB74E1C            <1> 	movzx	ecx, word [esi+LD_BPB+BPB_FATSz16]
   161 0000C856 EB03                <1> 	jmp	short load_FAT_sectors4
   162                              <1> load_FAT_sectors3:
   163 0000C858 8B4E2A              <1> 	mov	ecx, [esi+LD_BPB+BPB_FATSz32]
   164                              <1> load_FAT_sectors4:
   165 0000C85B 29D9                <1> 	sub	ecx, ebx ; [FAT_BuffSector]
   166 0000C85D 83F903              <1>         cmp     ecx, 3
   167 0000C860 7605                <1>         jna     short load_FAT_sectors5
   168 0000C862 B903000000          <1> 	mov	ecx, 3
   169                              <1> load_FAT_sectors5:
   170 0000C867 BB001C0900          <1> 	mov	ebx, FAT_Buffer
   171 0000C86C E87F3A0000          <1> 	call	disk_read
   172 0000C871 730D                <1> 	jnc	short load_FAT_sectors_ok
   173                              <1> 	; 15/10/2016 (15h -> 17)
   174                              <1> 	; 23/03/2016 (15h)
   175 0000C873 B811000000          <1> 	mov	eax, 17 ; Drive not ready or read error
   176 0000C878 C605[B26B0100]00    <1> 	mov	byte [FAT_BuffValidData], 0
   177 0000C87F C3                  <1> 	retn
   178                              <1> load_FAT_sectors_ok:
   179 0000C880 C605[B26B0100]01    <1> 	mov	byte [FAT_BuffValidData], 1
   180 0000C887 A1[AE6B0100]        <1> 	mov	eax, [FAT_CurrentCluster]
   181 0000C88C E9AAFEFFFF          <1>         jmp     check_next_cluster_fat_type
   182                              <1> 
   183                              <1> load_FAT_root_directory:
   184                              <1> 	; 23/10/2016
   185                              <1> 	; 15/10/2016
   186                              <1> 	; 07/02/2016
   187                              <1> 	; 02/02/2016
   188                              <1> 	; 01/02/2016 (TRDOS 386 =  TRDOS v2.0)
   189                              <1> 	; 21/05/2011
   190                              <1> 	; 22/08/2009
   191                              <1> 	;
   192                              <1> 	; INPUT ->
   193                              <1> 	;	ESI = Logical DOS Drive Description Table
   194                              <1> 	; OUTPUT ->
   195                              <1> 	;	cf = 1 -> Root directory could not be loaded
   196                              <1> 	;	    EAX > 0 -> Error number
   197                              <1> 	;	cf = 0 -> EAX = 0
   198                              <1> 	;	ECX = Directory buffer size in sectors (CL)
   199                              <1> 	;	EBX = Directory buffer address
   200                              <1> 	; 	NOTE: DirBuffer_Size is in bytes ! (word)
   201                              <1> 	;
   202                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
   203                              <1> 
   204                              <1> 	; NOTE: Only for FAT12 and FAT16 file systems !
   205                              <1> 	; (FAT32 fs root dir must be loaded as sub directory)
   206                              <1> 
   207 0000C891 8A1E                <1> 	mov	bl, [esi+LD_Name]
   208 0000C893 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   209                              <1> 
   210                              <1> 	;mov	[DirBuff_DRV], bl
   211                              <1> 	;mov	[DirBuff_FATType], bh
   212 0000C896 66891D[C26B0100]    <1> 	mov	[DirBuff_DRV], bx
   213                              <1> 	
   214                              <1> 	;cmp	bh, 2
   215                              <1> 	;ja	short load_FAT32_root_dir0 ; FAT32 root dir
   216                              <1> 
   217                              <1> load_FAT_root_dir0: ; 23/10/2016
   218 0000C89D 0FB75617            <1> 	movzx	edx, word [esi+LD_BPB+RootDirEnts]
   219                              <1> 
   220                              <1> 	;or	dx, dx ; 0 for FAT32 file systems
   221                              <1> 	;jz	short load_FAT32_root_dir0 ; FAT32 root dir
   222                              <1> 
   223 0000C8A1 6681FA0002          <1> 	cmp	dx, 512 ; Number of Root Dir Entries
   224 0000C8A6 7414                <1> 	je	short lrd_mov_ecx_32
   225 0000C8A8 89D0                <1> 	mov	eax, edx
   226                              <1> 	; 23/10/2016
   227 0000C8AA 89C1                <1> 	mov	ecx, eax
   228 0000C8AC 6683C10F            <1> 	add	cx, 15 ; round up 
   229 0000C8B0 66C1E904            <1> 	shr	cx, 4  ; 16 entries per sector (512/32)
   230                              <1> 	; ecx = Root directory size in sectors
   231 0000C8B4 66C1E005            <1> 	shl	ax, 5 ; Root directory size in bytes
   232 0000C8B8 664A                <1> 	dec	dx    ; Last entry number of root dir
   233                              <1> 	; cx = Dir Buffer sector count             
   234 0000C8BA EB0B                <1> 	jmp	short lrd_check_dir_buffer
   235                              <1> 
   236                              <1> lrd_mov_ecx_32:
   237 0000C8BC B920000000          <1> 	mov	ecx, 32
   238 0000C8C1 664A                <1> 	dec	dx ; 511
   239 0000C8C3 66B80040            <1> 	mov	ax, 32*512 
   240                              <1>  
   241                              <1> lrd_check_dir_buffer:
   242 0000C8C7 29DB                <1> 	sub	ebx, ebx ; 0
   243 0000C8C9 881D[C46B0100]      <1> 	mov	[DirBuff_ValidData], bl ; 0
   244 0000C8CF 668915[C76B0100]    <1> 	mov	[DirBuff_LastEntry], dx
   245 0000C8D6 891D[C96B0100]      <1> 	mov	[DirBuff_Cluster], ebx ; 0
   246 0000C8DC 66A3[CD6B0100]      <1> 	mov	[DirBuffer_Size], ax
   247                              <1> 
   248 0000C8E2 8B4664              <1> 	mov	eax, [esi+LD_ROOTBegin]
   249                              <1> read_directory:
   250 0000C8E5 BB00000800          <1> 	mov	ebx, Directory_Buffer
   251 0000C8EA 51                  <1> 	push	ecx ; Directory buffer sector count
   252 0000C8EB 53                  <1> 	push	ebx
   253 0000C8EC E8FF390000          <1> 	call	disk_read
   254 0000C8F1 5B                  <1> 	pop	ebx
   255 0000C8F2 720B                <1> 	jc	short load_DirBuff_error
   256                              <1> 
   257                              <1> validate_DirBuff_and_return:
   258 0000C8F4 59                  <1> 	pop	ecx ; Number of loaded sectors
   259 0000C8F5 C605[C46B0100]01    <1> 	mov	byte [DirBuff_ValidData], 1
   260 0000C8FC 31C0                <1> 	xor	eax, eax ; 0 = no error
   261 0000C8FE C3                  <1> 	retn
   262                              <1> 
   263                              <1> load_DirBuff_error:
   264 0000C8FF 89C8                <1> 	mov	eax, ecx ; remaining sectors
   265 0000C901 59                  <1> 	pop	ecx ; sector count
   266 0000C902 29C1                <1> 	sub	ecx, eax ; Number of loaded sectors
   267                              <1> 	; 15/10/2016 (15h -> 17)
   268 0000C904 B811000000          <1> 	mov	eax, 17 ; DRV NOT READY OR READ ERROR !
   269 0000C909 F9                  <1> 	stc
   270 0000C90A C3                  <1>         retn
   271                              <1> 
   272                              <1> load_FAT32_root_directory:
   273                              <1> 	; 02/02/2016 (TRDOS 386 =  TRDOS v2.0)
   274                              <1> 	;
   275                              <1> 	; INPUT ->
   276                              <1> 	;	ESI = Logical DOS Drive Description Table
   277                              <1> 	; OUTPUT ->
   278                              <1> 	;	cf = 1 -> Root directory could not be loaded
   279                              <1> 	;	    EAX > 0 -> Error number
   280                              <1> 	;	cf = 0 -> EAX = 0
   281                              <1> 	;	ECX = Directory buffer size in sectors (CL)
   282                              <1> 	;	EBX = Directory buffer address
   283                              <1> 	; 	NOTE: DirBuffer_Size is in bytes ! (word)
   284                              <1> 	;
   285                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
   286                              <1> 
   287                              <1> 
   288 0000C90B 8A1E                <1> 	mov	bl, [esi+LD_Name]
   289 0000C90D 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   290                              <1> 
   291                              <1> 	;mov	[DirBuff_DRV], bl
   292                              <1> 	;mov	[DirBuff_FATType], bh
   293 0000C910 66891D[C26B0100]    <1> 	mov	[DirBuff_DRV], bx
   294                              <1> 
   295                              <1> load_FAT32_root_dir0:
   296 0000C917 8B4632              <1> 	mov	eax, [esi+LD_BPB+FAT32_RootFClust]
   297 0000C91A EB0C                <1> 	jmp	short load_FAT_sub_dir0
   298                              <1> 	
   299                              <1> load_FAT_sub_directory:
   300                              <1> 	; 01/02/2016 (TRDOS 386 =  TRDOS v2.0)
   301                              <1> 	; 05/07/2011
   302                              <1> 	; 23/08/2009
   303                              <1> 	;
   304                              <1> 	; INPUT ->
   305                              <1> 	;	ESI = Logical DOS Drive Description Table
   306                              <1> 	;	EAX = Cluster Number
   307                              <1> 	; OUTPUT ->
   308                              <1> 	;	cf = 1 -> Sub directory could not be loaded
   309                              <1> 	;	    EAX > 0 -> Error number
   310                              <1> 	;	cf = 0 -> EAX = 0
   311                              <1> 	;	ECX = Directory buffer size in sectors (CL)
   312                              <1> 	;	EBX = Directory buffer address
   313                              <1> 	;
   314                              <1> 	; 	NOTE: DirBuffer_Size is in bytes ! (word)
   315                              <1> 	;
   316                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
   317                              <1> 
   318 0000C91C 8A1E                <1> 	mov	bl, [esi+LD_Name]
   319 0000C91E 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   320                              <1> 
   321                              <1> 	;mov	[DirBuff_DRV], bl
   322                              <1> 	;mov	[DirBuff_FATType], bh
   323 0000C921 66891D[C26B0100]    <1> 	mov	[DirBuff_DRV], bx
   324                              <1> 
   325                              <1> load_FAT_sub_dir0:
   326 0000C928 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
   327                              <1> 
   328 0000C92C 882D[C46B0100]      <1> 	mov	[DirBuff_ValidData], ch ; 0
   329 0000C932 A3[C96B0100]        <1> 	mov	[DirBuff_Cluster], eax
   330                              <1> 
   331 0000C937 0FB74611            <1> 	movzx	eax, word [esi+LD_BPB+BytesPerSec]
   332 0000C93B F7E1                <1> 	mul	ecx
   333 0000C93D C1E805              <1> 	shr	eax, 5 ; directory entry count (dir size / 32)
   334 0000C940 6648                <1> 	dec	ax ; last entry
   335 0000C942 66A3[C76B0100]      <1> 	mov	[DirBuff_LastEntry], ax
   336                              <1> 
   337 0000C948 A1[C96B0100]        <1> 	mov	eax, [DirBuff_Cluster]
   338 0000C94D 83E802              <1> 	sub	eax, 2
   339 0000C950 F7E1                <1> 	mul	ecx
   340 0000C952 034668              <1> 	add	eax, [esi+LD_DATABegin]
   341                              <1> 	; ecx = sector per cluster (dir buffer size = 32 sectors)
   342 0000C955 EB8E                <1> 	jmp	short read_directory
   343                              <1> 
   344                              <1> ; DRV_FS.ASM
   345                              <1> 
   346                              <1> load_current_FS_directory:
   347 0000C957 C3                  <1> 	retn
   348                              <1> load_FS_root_directory:
   349 0000C958 C3                  <1> 	retn
   350                              <1> load_FS_sub_directory:
   351 0000C959 C3                  <1> 	retn
   352                              <1> 
   353                              <1> read_cluster:
   354                              <1> 	; 15/10/2016
   355                              <1> 	; 18/03/2016
   356                              <1> 	; 16/03/2016
   357                              <1> 	; 17/02/2016
   358                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
   359                              <1> 	;
   360                              <1> 	; INPUT ->
   361                              <1> 	;	EAX = Cluster Number (Sector index for SINGLIX FS)
   362                              <1> 	;	ESI = Logical DOS Drive Description Table address
   363                              <1> 	;	EBX = Cluster (File R/W) Buffer address (max. 64KB)
   364                              <1> 	;	Only for SINGLIX FS:
   365                              <1> 	;	EDX = File Number (The 1st FDT address) 
   366                              <1> 	; OUTPUT ->
   367                              <1> 	;	cf = 1 -> Cluster can not be loaded at the buffer
   368                              <1> 	;	    EAX > 0 -> Error number
   369                              <1> 	;	cf = 0 -> Cluster has been loaded at the buffer
   370                              <1> 	;
   371                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
   372                              <1> 	
   373 0000C95A 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+BPB_SecPerClust] 
   374                              <1> 	; CL = 1 = [esi+LD_FS_Reserved2] ; SectPerClust for Singlix FS
   375                              <1> 
   376                              <1> read_file_sectors: ; 16/03/2016
   377 0000C95E 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
   378 0000C962 761C                <1> 	jna	short read_fs_cluster
   379                              <1> 
   380                              <1> read_fat_file_sectors: ; 18/03/2016
   381 0000C964 83E802              <1> 	sub	eax, 2 ; Beginning cluster number is always 2
   382 0000C967 0FB65613            <1> 	movzx	edx, byte [esi+LD_BPB+BPB_SecPerClust] ; 18/03/2016 
   383 0000C96B F7E2                <1> 	mul	edx
   384 0000C96D 034668              <1> 	add	eax, [esi+LD_DATABegin] ; absolute address of the cluster
   385                              <1> 
   386                              <1> 	; EAX = Disk sector address
   387                              <1> 	; ECX = Sector count
   388                              <1> 	; EBX = Buffer address
   389                              <1> 	; (EDX = 0)
   390                              <1> 	; ESI = Logical DOS drive description table address	
   391                              <1> 
   392 0000C970 E87B390000          <1> 	call	disk_read
   393 0000C975 7306                <1> 	jnc	short rclust_retn
   394                              <1> 	
   395                              <1> 	; 15/10/2016 (15h -> 17)
   396 0000C977 B811000000          <1> 	mov	eax, 17 ; Drive not ready or read error !
   397 0000C97C C3                  <1> 	retn
   398                              <1> 
   399                              <1> rclust_retn:
   400 0000C97D 29C0                <1> 	sub	eax, eax ; 0
   401 0000C97F C3                  <1> 	retn
   402                              <1> 
   403                              <1> read_fs_cluster:
   404                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
   405                              <1> 	; Singlix FS
   406                              <1> 	
   407                              <1> 	; EAX = Cluster number is sector index number of the file (eax)
   408                              <1> 	
   409                              <1> 	; EDX = File number is the first File Descriptor Table address 
   410                              <1> 	;	of the file. (Absolute address of the FDT).
   411                              <1> 	
   412                              <1> 	; eax = sector index (0 for the first sector)
   413                              <1> 	; edx = FDT0 address
   414                              <1> 		; 64 KB buffer = 128 sectors (limit) 
   415 0000C980 B980000000          <1> 	mov	ecx, 128 ; maximum count of sectors (before eof) 
   416 0000C985 E801000000          <1> 	call	read_fs_sectors
   417 0000C98A C3                  <1> 	retn
   418                              <1> 
   419                              <1> read_fs_sectors:
   420                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
   421 0000C98B F9                  <1> 	stc
   422 0000C98C C3                  <1> 	retn
   423                              <1> 
   424                              <1> get_first_free_cluster:
   425                              <1> 	; 02/03/2016
   426                              <1> 	; 21/02/2016 (TRDOS 386 =  TRDOS v2.0)
   427                              <1> 	; 26/10/2010 (DRV_FAT.ASM, 'proc_get_first_free_cluster')
   428                              <1> 	; 10/07/2010
   429                              <1> 	; INPUT ->
   430                              <1> 	;	ESI = Logical DOS Drive Description Table address
   431                              <1> 	; OUTPUT ->
   432                              <1> 	;	cf = 1 -> Error code in AL (EAX)
   433                              <1> 	;	cf = 0 -> 
   434                              <1> 	;	  EAX = Cluster number 
   435                              <1> 	;	  If EAX = FFFFFFFFh -> no free space
   436                              <1> 	;	If the drive has FAT32 fs:
   437                              <1> 	;	  EBX = FAT32 FSI sector buffer address (if > 0)
   438                              <1> 
   439 0000C98D 8B4678              <1> 	mov	eax, [esi+LD_Clusters]
   440 0000C990 40                  <1> 	inc	eax ; add eax, 1
   441 0000C991 A3[4C6E0100]        <1> 	mov	[gffc_last_free_cluster], eax
   442                              <1> 
   443 0000C996 31DB                <1> 	xor	ebx, ebx ; 0 ; 02/03/2016
   444                              <1> 
   445 0000C998 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
   446 0000C99C 760E                <1> 	jna	short loc_gffc_get_first_fat_free_cluster0
   447                              <1> 
   448                              <1> loc_gffc_get_first_fat32_free_cluster:
   449                              <1> 	; 02/03/2016
   450 0000C99E E844060000          <1> 	call	get_fat32_fsinfo_sector_parms
   451 0000C9A3 7207                <1> 	jc	short loc_gffc_get_first_fat_free_cluster0 
   452                              <1> 
   453                              <1> loc_gffc_check_fsinfo_parms:
   454                              <1> 	;;mov	ebx, DOSBootSectorBuff
   455                              <1> 	;cmp	dword [ebx], 41615252h
   456                              <1> 	;jne	short loc_gffc_fat32_fsinfo_err
   457                              <1> 	;cmp	dword [ebx+484], 61417272h
   458                              <1> 	;jne	short loc_gffc_fat32_fsinfo_err
   459                              <1> 	;mov	eax, [ebx+492] ; FSI_Next_Free
   460                              <1> 	;EAX = First free cluster 
   461                              <1> 	;(from FAT32 FSInfo sector)
   462 0000C9A5 89D0                <1> 	mov	eax, edx ; FSI_Next_Free (First Free Cluster)
   463 0000C9A7 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh ; invalid (unknown) !
   464 0000C9AA 7205                <1> 	jb	short loc_gffc_get_first_fat_free_cluster1
   465                              <1> 
   466                              <1> 	; Start from the 1st cluster of the FAT(32) file system
   467                              <1> loc_gffc_get_first_fat_free_cluster0:
   468 0000C9AC B802000000          <1> 	mov	eax, 2
   469                              <1> 	;xor	edx, edx
   470                              <1> 
   471                              <1> loc_gffc_get_first_fat_free_cluster1:
   472 0000C9B1 53                  <1> 	push	ebx ; 02/03/2016 
   473                              <1> 
   474                              <1> loc_gffc_get_first_fat_free_cluster2:   
   475 0000C9B2 A3[486E0100]        <1> 	mov	[gffc_first_free_cluster], eax
   476 0000C9B7 A3[446E0100]        <1> 	mov	[gffc_next_free_cluster], eax
   477                              <1> 
   478                              <1> 	; EBX = FAT32 FSINFO sector buffer address
   479                              <1> 	; (EBX = 0, if the drive has not got FAT32 fs or
   480                              <1> 	; FAT32 FSINFO sector buffer is invalid.)
   481                              <1> 
   482                              <1> loc_gffc_get_first_fat_free_cluster3:
   483 0000C9BC E875FDFFFF          <1> 	call	get_next_cluster
   484 0000C9C1 7307                <1> 	jnc	short loc_gffc_get_first_fat_free_cluster4
   485 0000C9C3 09C0                <1> 	or	eax, eax
   486 0000C9C5 740B                <1> 	jz	short loc_gffc_first_free_fat_cluster_next
   487 0000C9C7 5B                  <1> 	pop	ebx ; 02/03/2016
   488 0000C9C8 F5                  <1> 	cmc 	; stc
   489 0000C9C9 C3                  <1> 	retn
   490                              <1> 
   491                              <1> loc_gffc_get_first_fat_free_cluster4:
   492 0000C9CA 21C0                <1> 	and	eax, eax ; next cluster value
   493 0000C9CC 7504                <1> 	jnz	short loc_gffc_first_free_fat_cluster_next
   494 0000C9CE 89C8                <1> 	mov	eax, ecx ; current (previous cluster) value
   495 0000C9D0 EB22                <1> 	jmp	short loc_gffc_check_for_set
   496                              <1>  
   497                              <1> loc_gffc_first_free_fat_cluster_next:
   498 0000C9D2 A1[446E0100]        <1> 	mov	eax, [gffc_next_free_cluster]
   499 0000C9D7 3B05[4C6E0100]      <1> 	cmp	eax, [gffc_last_free_cluster]
   500 0000C9DD 7308                <1> 	jnb	short retn_stc_from_get_first_free_cluster
   501                              <1> pass_gffc_last_cluster_eax_check:
   502 0000C9DF 40                  <1> 	inc	eax ; add eax, 1
   503 0000C9E0 A3[446E0100]        <1> 	mov	[gffc_next_free_cluster], eax
   504 0000C9E5 EBD5                <1> 	jmp	short loc_gffc_get_first_fat_free_cluster3
   505                              <1> 
   506                              <1> retn_stc_from_get_first_free_cluster:
   507 0000C9E7 A1[486E0100]        <1> 	mov	eax, [gffc_first_free_cluster]
   508 0000C9EC 83F802              <1> 	cmp	eax, 2
   509 0000C9EF 7709                <1> 	ja	short loc_gffc_check_previous_clusters
   510 0000C9F1 29C0                <1> 	sub	eax, eax
   511 0000C9F3 48                  <1> 	dec	eax ; FFFFFFFFh
   512                              <1> 
   513                              <1> loc_gffc_check_for_set:
   514                              <1> 	; 02/03/2016
   515 0000C9F4 5B                  <1> 	pop	ebx
   516                              <1> 
   517                              <1> 	; EBX = FAT32 FSINFO sector buffer address
   518                              <1> 	; (EBX = 0, if the drive has not got FAT32 fs or
   519                              <1> 	; FAT32 FSINFO sector buffer is invalid.)
   520                              <1> 
   521 0000C9F5 09DB                <1> 	or	ebx, ebx
   522 0000C9F7 750E                <1> 	jnz	short loc_gffc_set_ffree_fat32_cluster
   523                              <1> 
   524                              <1> 	;cmp	byte [esi+LD_FATType], 3
   525                              <1> 	;jnb	short loc_gffc_set_ffree_fat32_cluster
   526                              <1> 
   527                              <1> 	;xor	ebx, ebx ; 0
   528                              <1> 
   529                              <1> loc_gffc_retn:
   530 0000C9F9 C3                  <1> 	retn
   531                              <1> 
   532                              <1> loc_gffc_check_previous_clusters:
   533 0000C9FA 48                  <1> 	dec	eax ; sub eax, 1
   534 0000C9FB A3[4C6E0100]        <1> 	mov	[gffc_last_free_cluster], eax 
   535 0000CA00 B802000000          <1> 	mov	eax, 2
   536                              <1> 	;xor	edx, edx
   537 0000CA05 EBAB                <1> 	jmp	short loc_gffc_get_first_fat_free_cluster2
   538                              <1> 
   539                              <1> loc_gffc_set_ffree_fat32_cluster:
   540                              <1> 	;call	set_first_free_cluster
   541                              <1> 	;retn
   542                              <1> 	;jmp	short set_first_free_cluster	
   543                              <1> 
   544                              <1> set_first_free_cluster:
   545                              <1> 	; 15/10/2016
   546                              <1> 	; 23/03/2016
   547                              <1> 	; 02/03/2016
   548                              <1> 	; 29/02/2016
   549                              <1> 	; 26/02/2016
   550                              <1> 	; 21/02/2016 (TRDOS 386 =  TRDOS v2.0)
   551                              <1> 	; 21/08/2011 (DRV_FAT.ASM, 'proc_set_first_free_cluster')
   552                              <1> 	; 11/07/2010
   553                              <1> 	; INPUT -> 
   554                              <1> 	;	ESI = Logical DOS Drive Description Table address
   555                              <1> 	;	EAX = First free cluster
   556                              <1> 	;	EBX = FSINFO sector buffer address
   557                              <1> 	;  	;;If EBX > 0, it is FSINFO sector buffer address
   558                              <1> 	;	;;EBX = 0, if FSINFO sector is not loaded
   559                              <1> 	; OUTPUT->
   560                              <1> 	;	ESI = Logical DOS Drive Description Table address
   561                              <1> 	;  	If EBX > 0, it is FSINFO sector buffer address
   562                              <1> 	;	EBX = 0, if FSINFO sector could not be loaded
   563                              <1> 	; 	CF = 1 -> Error code in AL (EAX)
   564                              <1> 	;	CF = 0 -> first free cluster is successfully updated 
   565                              <1> 
   566                              <1> 	;cmp	byte [esi+LD_FATType], 3
   567                              <1> 	;jb	short loc_sffc_invalid_drive
   568                              <1> 
   569                              <1> 	; Save First Free Cluster value for 'update_cluster'
   570 0000CA07 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; First free Cluster	
   571                              <1> 
   572                              <1> 	;or	ebx, ebx
   573                              <1> 	;jnz	short loc_sffc_read_fsinfo_sector
   574                              <1> 
   575 0000CA0A 813B52526141        <1> 	cmp     dword [ebx], 41615252h
   576 0000CA10 7540                <1> 	jne	short loc_sffc_read_fsinfo_sector
   577 0000CA12 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
   577 0000CA1B 61                  <1>
   578 0000CA1C 7534                <1> 	jne	short loc_sffc_read_fsinfo_sector
   579                              <1> 
   580 0000CA1E 3B83EC010000        <1> 	cmp	eax, [ebx+492]  ; FSI_Next_Free
   581 0000CA24 741F                <1> 	je	short loc_sffc_retn
   582                              <1> 
   583                              <1> loc_sffc_write_fsinfo_sector:
   584                              <1> 	; EBX = FSINFO sector buffer
   585                              <1> 	; [CFS_FAT32FSINFOSEC] is set in 'get_fat32_fsinfo_sector_parms'
   586 0000CA26 8983EC010000        <1> 	mov	[ebx+492], eax
   587 0000CA2C A1[5C6E0100]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC] 
   588 0000CA31 B901000000          <1> 	mov	ecx, 1
   589 0000CA36 53                  <1> 	push	ebx
   590 0000CA37 E8A5380000          <1> 	call	disk_write
   591 0000CA3C 7208                <1> 	jc      short loc_sffc_read_fsinfo_sector_err1
   592 0000CA3E 5B                  <1> 	pop	ebx
   593                              <1> 
   594 0000CA3F 8B83EC010000        <1> 	mov	eax, [ebx+492] ; First (Next) Free Cluster
   595                              <1> 
   596                              <1> loc_sffc_retn:
   597 0000CA45 C3                  <1> 	retn
   598                              <1> 
   599                              <1> ;loc_sffc_invalid_drive:
   600                              <1> ;	mov	eax, 0Fh ; MSDOS Error : Invalid drive
   601                              <1> ;	push	edx
   602                              <1> 
   603                              <1> loc_sffc_read_fsinfo_sector_err1:
   604 0000CA46 BB00000000          <1> 	mov	ebx, 0
   605                              <1> 	; 15/10/2016 (1Dh -> 18)
   606                              <1> 	; 23/03/2016 (1Dh)
   607 0000CA4B B812000000          <1> 	mov	eax, 18 ; Drive not ready or write error
   608                              <1> 
   609                              <1> loc_sffc_read_fsinfo_sector_err2:
   610 0000CA50 5A                  <1> 	pop	edx
   611 0000CA51 C3                  <1> 	retn
   612                              <1> 	
   613                              <1> loc_sffc_read_fsinfo_sector:
   614 0000CA52 50                  <1> 	push	eax
   615                              <1> 
   616 0000CA53 E88F050000          <1> 	call	get_fat32_fsinfo_sector_parms
   617 0000CA58 72F6                <1> 	jc	short loc_sffc_read_fsinfo_sector_err2
   618                              <1> 
   619 0000CA5A 58                  <1> 	pop	eax
   620                              <1> 	; EDX = First (Next) Free Cluster value from FSINFO sector
   621                              <1> 	; EAX = First Free Cluster value from 'get_next_cluster'
   622                              <1> 	; (edx = old value)
   623 0000CA5B 39D0                <1> 	cmp	eax, edx ; First free Cluster (eax = new value) 
   624 0000CA5D 75C7                <1> 	jne	short loc_sffc_write_fsinfo_sector
   625                              <1> 
   626 0000CA5F C3                  <1> 	retn	
   627                              <1> 
   628                              <1> update_cluster:
   629                              <1> 	; 23/10/2016
   630                              <1> 	; 23/03/2016
   631                              <1> 	; 02/03/2016
   632                              <1> 	; 01/03/2016
   633                              <1> 	; 29/02/2016
   634                              <1> 	; 27/02/2016
   635                              <1> 	; 26/02/2016
   636                              <1> 	; 22/02/2016 (TRDOS 386 =  TRDOS v2.0)
   637                              <1> 	; 11/08/2011  
   638                              <1> 	; 09/02/2005
   639                              <1> 	; INPUT ->
   640                              <1> 	;	EAX = Cluster Number
   641                              <1> 	;	ECX = New Cluster Value
   642                              <1> 	;	ESI = Logical Dos Drive Parameters Table
   643                              <1> 	;
   644                              <1> 	;	/// dword [FAT_ClusterCounter] ///
   645                              <1> 	;
   646                              <1> 	; OUTPUT ->
   647                              <1> 	;	cf = 0 -> No Error, EAX is valid
   648                              <1> 	;	cf = 1 & EAX = 0 -> End Of Cluster Chain
   649                              <1> 	; 	cf = 1 & EAX > 0 -> Error
   650                              <1> 	;		(ECX -> any value)
   651                              <1> 	; 	EAX = Next Cluster
   652                              <1> 	;	ECX = New Cluster Value
   653                              <1> 	;
   654                              <1> 	;	/// [FAT_ClusterCounter] is updated,
   655                              <1> 	;	/// decreased when a free cluster is assigned,
   656                              <1> 	;	/// increased if an assigned cluster is freed.	
   657                              <1> 	;		
   658                              <1> 	;
   659                              <1> 	; (Modified registers: EAX, EBX, -ECX-, EDX)
   660                              <1> 	
   661 0000CA60 A3[AE6B0100]        <1> 	mov	[FAT_CurrentCluster], eax
   662 0000CA65 890D[506E0100]      <1> 	mov	[ClusterValue], ecx
   663                              <1> 
   664                              <1> loc_update_cluster_check_fat_buffer:
   665 0000CA6B 8A1E                <1> 	mov	bl, [esi+LD_Name]
   666 0000CA6D 381D[B36B0100]      <1> 	cmp	[FAT_BuffDrvName], bl
   667 0000CA73 741A                <1> 	je	short loc_update_cluster_check_fat_type
   668 0000CA75 803D[B26B0100]02    <1> 	cmp	byte [FAT_BuffValidData], 2
   669 0000CA7C 0F84C2000000        <1>         je      loc_uc_save_fat_buffer
   670                              <1> 
   671                              <1> loc_uc_reset_fat_buffer_validation:
   672 0000CA82 C605[B26B0100]00    <1> 	mov	byte [FAT_BuffValidData], 0
   673                              <1> 
   674                              <1> loc_uc_check_fat_type_reset_drvname:
   675 0000CA89 881D[B36B0100]      <1> 	mov	[FAT_BuffDrvName], bl
   676                              <1> 
   677                              <1> loc_update_cluster_check_fat_type:
   678 0000CA8F 29D2                <1> 	sub	edx, edx ; 26/02/2016
   679 0000CA91 8A5E03              <1> 	mov	bl, [esi+LD_FATType]
   680 0000CA94 83F802              <1> 	cmp	eax, 2
   681 0000CA97 0F82BE000000        <1>         jb      update_cluster_inv_data
   682 0000CA9D 80FB02              <1> 	cmp	bl, 2 
   683 0000CAA0 0F877A010000        <1>         ja      update_fat32_cluster
   684                              <1> 	;cmp	bl, 1
   685                              <1> 	;jb	short update_cluster_inv_data
   686 0000CAA6 8B4E78              <1> 	mov	ecx, [esi+LD_Clusters]
   687 0000CAA9 41                  <1> 	inc	ecx  
   688 0000CAAA 890D[BE6B0100]      <1> 	mov	[LastCluster], ecx
   689 0000CAB0 39C8                <1> 	cmp	eax, ecx ; dword [LastCluster]
   690 0000CAB2 0F87A6000000        <1>         ja      return_uc_fat_stc
   691                              <1> 	; TRDOS v1 has a FATal bug here ! 
   692                              <1> 		; or bl, bl ; cmp bl, 0
   693                              <1> 		; jz short update_fat12_cluster
   694                              <1> 	; !! It would destroy FAT12 floppy disk fs here !!
   695                              <1> 	; ('A:' disks of TRDOS v1 operating system project
   696                              <1> 	; had 'singlix fs', so, I could not differ this mistake
   697                              <1> 	; on a drive 'A:')
   698 0000CAB8 80FB01              <1> 	cmp	bl, 1 ; correct comparison is this !
   699 0000CABB 0F86A2000000        <1>         jna     update_fat12_cluster 
   700                              <1> 
   701                              <1> update_fat16_cluster:
   702                              <1> pass_uc_fat16_errc:
   703                              <1> 	;sub	edx, edx
   704 0000CAC1 BB00030000          <1> 	mov	ebx, 300h ;768
   705 0000CAC6 F7F3                <1> 	div	ebx
   706                              <1> 	; EAX = Count of 3 FAT sectors
   707                              <1> 	; DX = Cluster offset in FAT buffer
   708 0000CAC8 6689D3              <1> 	mov	bx, dx  
   709 0000CACB 66D1E3              <1> 	shl	bx, 1 ; Multiply by 2
   710 0000CACE 66BA0300            <1> 	mov	dx, 3
   711 0000CAD2 F7E2                <1> 	mul	edx  
   712                              <1> 	; EAX = FAT Sector
   713                              <1> 	; EDX = 0
   714                              <1> 	; EBX = Byte offset in FAT buffer
   715 0000CAD4 8A0D[B26B0100]      <1> 	mov	cl, [FAT_BuffValidData]
   716 0000CADA 80F902              <1> 	cmp	cl, 2
   717 0000CADD 750A                <1> 	jne	short loc_uc_check_fat16_buff_sector_load
   718                              <1> 
   719                              <1> loc_uc_check_fat16_buff_sector_save:
   720 0000CADF 3B05[B66B0100]      <1> 	cmp	eax, [FAT_BuffSector]
   721 0000CAE5 755D                <1> 	jne	short loc_uc_save_fat_buffer
   722 0000CAE7 EB15                <1> 	jmp	short loc_update_fat16_cell
   723                              <1> 
   724                              <1> loc_uc_check_fat16_buff_sector_load:
   725 0000CAE9 80F901              <1> 	cmp	cl, 1 ; byte [FAT_BuffValidData]
   726 0000CAEC 0F85FB010000        <1>         jne     loc_uc_load_fat_sectors
   727 0000CAF2 3B05[B66B0100]      <1> 	cmp	eax, [FAT_BuffSector]
   728 0000CAF8 0F85EF010000        <1>         jne     loc_uc_load_fat_sectors
   729                              <1> 
   730                              <1> loc_update_fat16_cell:
   731                              <1> loc_update_fat16_buffer:
   732 0000CAFE 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   733                              <1> 	;movzx	eax, word [ebx]
   734 0000CB04 668B03              <1> 	mov	ax, [ebx]
   735                              <1> 	; 01/03/2016
   736 0000CB07 89C2                <1> 	mov	edx, eax ; old value of the cluster
   737 0000CB09 A3[AE6B0100]        <1> 	mov	[FAT_CurrentCluster], eax
   738 0000CB0E 8B0D[506E0100]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   739 0000CB14 66890B              <1> 	mov	[ebx], cx ; 16 bits !
   740                              <1> 
   741 0000CB17 C605[B26B0100]02    <1> 	mov	byte [FAT_BuffValidData], 2
   742                              <1> 	
   743 0000CB1E 6683F802            <1> 	cmp	ax, 2
   744 0000CB22 723A                <1> 	jb	short return_uc_fat_stc
   745 0000CB24 3B05[BE6B0100]      <1> 	cmp	eax, [LastCluster]
   746 0000CB2A 7732                <1> 	ja	short return_uc_fat_stc
   747                              <1> 
   748                              <1> loc_fat_buffer_updated:
   749                              <1> 	; 01/03/2016
   750 0000CB2C F8                  <1> 	clc
   751                              <1> loc_fat_buffer_stc_1:
   752 0000CB2D 9C                  <1> 	pushf
   753 0000CB2E 21C9                <1> 	and	ecx, ecx
   754 0000CB30 7506                <1> 	jnz	short loc_fat_buffer_updated_1
   755                              <1> 
   756                              <1> 	; 01/03/2016 
   757                              <1> 	; new value of the cluster = 0 (free)
   758                              <1> 	; increase free(d) cluster count
   759 0000CB32 FF05[BA6B0100]      <1> 	inc	dword [FAT_ClusterCounter]
   760                              <1> 
   761                              <1> loc_fat_buffer_updated_1: ; new value of the cluster > 0
   762 0000CB38 09D2                <1> 	or	edx, edx ; 02/03/2016
   763 0000CB3A 7506                <1> 	jnz	short loc_fat_buffer_updated_2
   764                              <1> 	; old value of the cluster = 0 (it was free cluster)
   765                              <1> 	; decrease free(d) cluster count
   766 0000CB3C FF0D[BA6B0100]      <1> 	dec	dword [FAT_ClusterCounter] ; it may be negative number
   767                              <1> 
   768                              <1> loc_fat_buffer_updated_2:
   769 0000CB42 9D                  <1> 	popf
   770 0000CB43 C3                  <1> 	retn
   771                              <1> 
   772                              <1> loc_uc_save_fat_buffer:
   773                              <1> 	; byte [FAT_BuffValidData] = 2 
   774 0000CB44 E8D4010000          <1> 	call	save_fat_buffer
   775 0000CB49 0F8297010000        <1>         jc      loc_fat_sectors_rw_error2
   776                              <1> 	;mov	byte [FAT_BuffValidData], 1
   777 0000CB4F A1[AE6B0100]        <1> 	mov	eax, [FAT_CurrentCluster]
   778                              <1> 	;mov	ecx, [ClusterValue]
   779                              <1> 	;jmp	short loc_update_cluster_check_fat_buffer
   780 0000CB54 8A1E                <1> 	mov	bl, [esi+LD_Name] ; 01/03/2016
   781 0000CB56 E927FFFFFF          <1>         jmp     loc_uc_reset_fat_buffer_validation
   782                              <1> 
   783                              <1> update_cluster_inv_data:
   784                              <1> 	;mov	eax, 0Dh
   785 0000CB5B B00D                <1> 	mov	al, 0Dh  ; Invalid Data
   786 0000CB5D C3                  <1> 	retn 
   787                              <1> 
   788                              <1> return_uc_fat_stc:
   789                              <1> 	; 01/03/2016
   790 0000CB5E 31C0                <1> 	xor	eax, eax
   791 0000CB60 F9                  <1> 	stc
   792 0000CB61 EBCA                <1> 	jmp	short loc_fat_buffer_stc_1
   793                              <1> 
   794                              <1> update_fat12_cluster:
   795                              <1> pass_uc_fat12_errc:
   796                              <1> 	;sub	edx, edx
   797 0000CB63 BB00040000          <1> 	mov	ebx, 400h ;1024
   798 0000CB68 F7F3                <1> 	div	ebx
   799                              <1> 	; EAX = Count of 3 FAT sectors
   800                              <1> 	; DX = Cluster offset in FAT buffer
   801 0000CB6A 66B90300            <1> 	mov	cx, 3
   802 0000CB6E 6689C3              <1> 	mov	bx, ax
   803 0000CB71 6689C8              <1> 	mov	ax, cx ; 3
   804 0000CB74 66F7E2              <1> 	mul	dx     ; Multiply by 3
   805 0000CB77 66D1E8              <1> 	shr	ax, 1  ; Divide by 2
   806 0000CB7A 6693                <1> 	xchg	bx, ax
   807                              <1> 	; EAX = Count of 3 FAT sectors
   808                              <1> 	; EBX = Byte Offset in FAT buffer   
   809 0000CB7C 66F7E1              <1> 	mul	cx  ; 3 * AX
   810                              <1> 	; EAX = FAT Beginning Sector
   811                              <1> 	; EDX = 0
   812 0000CB7F 8A0D[B26B0100]      <1> 	mov	cl, [FAT_BuffValidData]
   813                              <1> 	; TRDOS v1 has a FATal bug here ! 
   814                              <1> 	; (it does not have 'cmp cl, 2' instruction here !
   815                              <1> 	;  while 'jne' is existing !)
   816 0000CB85 80F902              <1> 	cmp	cl, 2 ; 2 = dirty buffer (must be written to disk)
   817 0000CB88 750A                <1> 	jne	short loc_uc_check_fat12_buff_sector_load
   818                              <1> 
   819                              <1> loc_uc_check_fat12_buff_sector_save:
   820 0000CB8A 3B05[B66B0100]      <1> 	cmp	eax, [FAT_BuffSector]
   821 0000CB90 75B2                <1>         jne     short loc_uc_save_fat_buffer
   822 0000CB92 EB15                <1> 	jmp	short loc_update_fat12_cell
   823                              <1> 
   824                              <1> loc_uc_check_fat12_buff_sector_load:
   825 0000CB94 80F901              <1> 	cmp	cl, 1 ; byte ptr [FAT_BuffValidData]
   826 0000CB97 0F8550010000        <1>         jne     loc_uc_load_fat_sectors
   827 0000CB9D 3B05[B66B0100]      <1> 	cmp	eax, [FAT_BuffSector]
   828 0000CBA3 0F8544010000        <1>         jne     loc_uc_load_fat_sectors
   829                              <1> 
   830                              <1> loc_update_fat12_cell:
   831 0000CBA9 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   832 0000CBAF 668B0D[AE6B0100]    <1> 	mov	cx, [FAT_CurrentCluster]
   833 0000CBB6 66D1E9              <1> 	shr	cx, 1
   834 0000CBB9 668B03              <1> 	mov	ax, [ebx]
   835 0000CBBC 6689C2              <1> 	mov	dx, ax
   836 0000CBBF 7344                <1> 	jnc	short uc_fat12_nc_even
   837                              <1> 
   838 0000CBC1 6683E00F            <1> 	and	ax, 0Fh
   839 0000CBC5 8B0D[506E0100]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   840 0000CBCB 66C1E104            <1> 	shl	cx, 4
   841 0000CBCF 6609C1              <1> 	or	cx, ax
   842 0000CBD2 6689D0              <1> 	mov	ax, dx
   843 0000CBD5 66890B              <1> 	mov	[ebx], cx  ; 16 bits !
   844 0000CBD8 66C1E804            <1> 	shr	ax, 4 ; al(bit4..7)+ah(bit0..7)
   845                              <1> 
   846                              <1> update_fat12_buffer:
   847 0000CBDC A3[AE6B0100]        <1> 	mov	[FAT_CurrentCluster], eax
   848 0000CBE1 89C2                <1> 	mov	edx, eax ; 01/03/2016
   849 0000CBE3 C605[B26B0100]02    <1> 	mov	byte [FAT_BuffValidData], 2
   850 0000CBEA 6683F802            <1> 	cmp	ax, 2
   851 0000CBEE 0F826AFFFFFF        <1>         jb      return_uc_fat_stc
   852 0000CBF4 3B05[BE6B0100]      <1> 	cmp	eax, [LastCluster]
   853 0000CBFA 0F875EFFFFFF        <1>         ja      return_uc_fat_stc
   854 0000CC00 E927FFFFFF          <1>         jmp     loc_fat_buffer_updated
   855                              <1> 
   856                              <1> uc_fat12_nc_even:
   857 0000CC05 662500F0            <1> 	and	ax, 0F000h
   858 0000CC09 8B0D[506E0100]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   859 0000CC0F 80E50F              <1> 	and	ch, 0Fh
   860 0000CC12 6609C1              <1> 	or	cx, ax
   861 0000CC15 6689D0              <1> 	mov	ax, dx
   862 0000CC18 66890B              <1> 	mov	[ebx], cx ; 16 bits !
   863 0000CC1B 80E40F              <1> 	and	ah, 0Fh ; al(bit0..7)+ah(bit0..3)
   864 0000CC1E EBBC                <1> 	jmp	short update_fat12_buffer
   865                              <1> 
   866                              <1> update_fat32_cluster:
   867 0000CC20 8B4E78              <1> 	mov	ecx, [esi+LD_Clusters]
   868 0000CC23 41                  <1> 	inc	ecx
   869 0000CC24 890D[BE6B0100]      <1> 	mov	[LastCluster], ecx
   870                              <1> 
   871 0000CC2A 39C8                <1> 	cmp	eax, ecx
   872 0000CC2C 0F872CFFFFFF        <1>         ja      return_uc_fat_stc
   873                              <1> 
   874                              <1> pass_uc_fat32_errc:
   875                              <1> 	;sub	edx, edx
   876 0000CC32 BB80010000          <1> 	mov	ebx, 180h ;384
   877 0000CC37 F7F3                <1> 	div	ebx
   878                              <1> 	; EAX = Count of 3 FAT sectors
   879                              <1> 	; DX = Cluster offset in FAT buffer
   880 0000CC39 89D3                <1> 	mov	ebx, edx
   881 0000CC3B C1E302              <1> 	shl	ebx, 2 ; Multiply by 4
   882 0000CC3E BA03000000          <1> 	mov	edx, 3	
   883 0000CC43 F7E2                <1> 	mul	edx
   884                              <1> 	; EBX = Cluster Offset in FAT buffer
   885                              <1> 	; EAX = FAT Sector
   886                              <1> 	; EDX = 0
   887 0000CC45 8A0D[B26B0100]      <1> 	mov	cl, [FAT_BuffValidData]
   888 0000CC4B 80F902              <1> 	cmp	cl, 2
   889 0000CC4E 750E                <1> 	jne	short loc_uc_check_fat32_buff_sector_load
   890                              <1> 
   891                              <1> loc_uc_check_fat32_buff_sector_save:
   892 0000CC50 3B05[B66B0100]      <1> 	cmp	eax, [FAT_BuffSector]
   893 0000CC56 0F85E8FEFFFF        <1>         jne     loc_uc_save_fat_buffer
   894 0000CC5C EB11                <1> 	jmp	short loc_update_fat32_cell
   895                              <1> 
   896                              <1> loc_uc_check_fat32_buff_sector_load:
   897 0000CC5E 80F901              <1> 	cmp	cl, 1 ; byte [FAT_BuffValidData]
   898 0000CC61 0F8586000000        <1>         jne     loc_uc_load_fat_sectors
   899 0000CC67 3B05[B66B0100]      <1> 	cmp	eax, [FAT_BuffSector]
   900 0000CC6D 757E                <1>         jne     loc_uc_load_fat_sectors
   901                              <1> 
   902                              <1> loc_update_fat32_cell:
   903                              <1> loc_update_fat32_buffer:
   904 0000CC6F 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   905 0000CC75 8B03                <1> 	mov	eax, [ebx]
   906 0000CC77 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh ; 28 bit cluster value
   907                              <1> 	
   908 0000CC7C 8B15[AE6B0100]      <1> 	mov	edx, [FAT_CurrentCluster] ; 01/03/2016
   909                              <1> 
   910 0000CC82 A3[AE6B0100]        <1> 	mov 	[FAT_CurrentCluster], eax
   911 0000CC87 8B0D[506E0100]      <1> 	mov	ecx, [ClusterValue]
   912 0000CC8D 890B                <1> 	mov	[ebx], ecx ; 29/02/2016 
   913                              <1> 
   914 0000CC8F C605[B26B0100]02    <1> 	mov	byte [FAT_BuffValidData], 2
   915                              <1> 
   916                              <1> 	; 01/03/2016
   917 0000CC96 21C0                <1> 	and	eax, eax ; was it free cluster ?
   918 0000CC98 7514                <1> 	jnz	short loc_upd_fat32_c0
   919                              <1> 
   920                              <1> 	;or	ecx, ecx ; it will be left free ?!
   921                              <1> 	;jz	short loc_upd_fat32_c3
   922                              <1> 
   923 0000CC9A 3B563E              <1> 	cmp	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free cluster
   924 0000CC9D 7520                <1> 	jne	short loc_upd_fat32_c3
   925                              <1> 
   926 0000CC9F 3B15[BE6B0100]      <1> 	cmp	edx, [LastCluster]
   927 0000CCA5 7207                <1> 	jb	short loc_upd_fat32_c0
   928                              <1> 
   929 0000CCA7 BA02000000          <1> 	mov	edx, 2 ; rewind !
   930 0000CCAC EB0E                <1> 	jmp	short loc_upd_fat32_c2
   931                              <1> 
   932                              <1> loc_upd_fat32_c0:
   933 0000CCAE FF463E              <1> 	inc	dword [esi+LD_BPB+BPB_Reserved+4] ; set it to next cluster		
   934 0000CCB1 EB0C                <1> 	jmp	short loc_upd_fat32_c3
   935                              <1> 
   936                              <1> loc_upd_fat32_c1:
   937 0000CCB3 09C9                <1> 	or	ecx, ecx ; will it be free cluster ?
   938 0000CCB5 7508                <1> 	jnz	short loc_upd_fat32_c3
   939                              <1> 
   940 0000CCB7 3B563E              <1> 	cmp	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free cluster
   941 0000CCBA 7303                <1> 	jnb	short loc_upd_fat32_c3
   942                              <1> 
   943                              <1> loc_upd_fat32_c2:	
   944 0000CCBC 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx			
   945                              <1> 
   946                              <1> loc_upd_fat32_c3:
   947 0000CCBF 89C2                <1> 	mov	edx, eax
   948                              <1> 
   949                              <1> loc_upd_fat32_c4:
   950 0000CCC1 83F802              <1> 	cmp	eax, 2
   951 0000CCC4 0F8294FEFFFF        <1>         jb      return_uc_fat_stc
   952                              <1> 
   953                              <1> pass_uc_fat32_c_zero_check_2:
   954 0000CCCA 3B05[BE6B0100]      <1> 	cmp	eax, [LastCluster]
   955 0000CCD0 0F8788FEFFFF        <1>         ja      return_uc_fat_stc
   956                              <1> 	
   957 0000CCD6 E951FEFFFF          <1> 	jmp     loc_fat_buffer_updated
   958                              <1> 
   959                              <1> loc_fat_sectors_rw_error1:
   960                              <1> 	;mov	byte [FAT_BuffValidData], 0
   961                              <1> 	; 23/10/2016 (15h -> 17)
   962                              <1> 	; 23/03/2016
   963 0000CCDB B811000000          <1> 	mov	eax, 17 ; Drive not ready or read error
   964 0000CCE0 8825[B26B0100]      <1> 	mov	[FAT_BuffValidData], ah ; 0
   965                              <1> 
   966                              <1> loc_fat_sectors_rw_error2:
   967                              <1> 	;mov	eax, error code
   968                              <1> 	;mov	edx, 0
   969 0000CCE6 8B0D[506E0100]      <1> 	mov	ecx, [ClusterValue]
   970 0000CCEC C3                  <1> 	retn
   971                              <1> 
   972                              <1> loc_uc_load_fat_sectors:
   973 0000CCED A3[B66B0100]        <1> 	mov	[FAT_BuffSector], eax
   974                              <1> 
   975                              <1> load_uc_fat_sectors_zero:
   976 0000CCF2 034660              <1> 	add	eax, [esi+LD_FATBegin]
   977 0000CCF5 BB001C0900          <1> 	mov	ebx, FAT_Buffer
   978 0000CCFA B903000000          <1> 	mov	ecx, 3
   979 0000CCFF E8EC350000          <1> 	call	disk_read
   980 0000CD04 72D5                <1> 	jc	short loc_fat_sectors_rw_error1
   981                              <1> 
   982 0000CD06 C605[B26B0100]01    <1>         mov     byte [FAT_BuffValidData], 1
   983 0000CD0D A1[AE6B0100]        <1> 	mov 	eax, [FAT_CurrentCluster]
   984 0000CD12 8B0D[506E0100]      <1> 	mov	ecx, [ClusterValue]
   985 0000CD18 E972FDFFFF          <1>         jmp     loc_update_cluster_check_fat_type
   986                              <1> 
   987                              <1> save_fat_buffer:
   988                              <1> 	; 15/10/2016
   989                              <1> 	; 01/03/2016
   990                              <1> 	; 22/02/2016 (TRDOS 386 =  TRDOS v2.0)
   991                              <1> 	; 11/08/2011
   992                              <1> 	; 09/02/2005 
   993                              <1> 	; INPUT ->
   994                              <1> 	;	None
   995                              <1> 	; OUTPUT ->
   996                              <1> 	;	cf = 0 -> OK.
   997                              <1> 	;	cf = 1 -> error code in AL (EAX)
   998                              <1> 	;
   999                              <1> 	;	EBX = FAT_Buffer address
  1000                              <1> 	;
  1001                              <1> 	; (EAX, EDX, ECX will be modified)
  1002                              <1> 
  1003                              <1> 	;cmp	byte [FAT_BuffValidData], 2 
  1004                              <1> 	;je	short loc_save_fat_buff
  1005                              <1> 
  1006                              <1> ;loc_save_fat_buffer_retn:
  1007                              <1> ;	xor	eax, eax
  1008                              <1> ;	retn
  1009                              <1> 
  1010                              <1> loc_save_fat_buff:
  1011 0000CD1D 31D2                <1> 	xor	edx, edx
  1012 0000CD1F 8A35[B36B0100]      <1> 	mov	dh, [FAT_BuffDrvName]
  1013 0000CD25 80FE41              <1> 	cmp	dh, 'A'
  1014 0000CD28 722E                <1> 	jb	short loc_save_fat_buffer_inv_data_retn
  1015 0000CD2A 80EE41              <1> 	sub	dh, 'A'
  1016 0000CD2D 56                  <1> 	push	esi ; *
  1017 0000CD2E BE00010900          <1>         mov     esi, Logical_DOSDisks
  1018 0000CD33 01D6                <1> 	add	esi, edx
  1019                              <1> 	
  1020 0000CD35 8A5603              <1> 	mov	dl, [esi+LD_FATType]
  1021 0000CD38 20D2                <1> 	and	dl, dl
  1022 0000CD3A 741B                <1> 	jz	short loc_save_fat_buffer_inv_data_pop_retn 
  1023                              <1> 
  1024 0000CD3C A1[B66B0100]        <1> 	mov	eax, [FAT_BuffSector]
  1025 0000CD41 80FA02              <1> 	cmp	dl, 2
  1026 0000CD44 770A                <1> 	ja	short loc_save_fat32_buff
  1027                              <1> 
  1028                              <1> loc_save_fat_12_16_buff:
  1029                              <1> 	; 01/03/2016
  1030                              <1> 	; TRDOS v1 has a FATal bug here!
  1031                              <1> 	; Correct code: mov dx, word ptr [FAT_BuffSector]+2
  1032                              <1> 	; (DX:AX in TRDOS v1 -> EAX in TRDOS v2)
  1033                              <1> 	;
  1034 0000CD46 0FB74E1C            <1> 	movzx	ecx, word [esi+LD_BPB+FATSecs] 
  1035 0000CD4A 29C1                <1> 	sub	ecx, eax
  1036                              <1> 	; TRDOS v1 has a bug here... ('pop esi' was forgotten!)
  1037                              <1> 	;jna	short loc_save_fat_buffer_inv_data_retn ; wrong addr!
  1038 0000CD4C 7609                <1> 	jna	short loc_save_fat_buffer_inv_data_pop_retn ; correct addr.
  1039 0000CD4E EB15                <1> 	jmp	short loc_save_fat_buffer_check_rs3
  1040                              <1> 
  1041                              <1> loc_save_fat32_buff:
  1042 0000CD50 8B4E2A              <1> 	mov	ecx, [esi+LD_BPB+FAT32_FAT_Size]
  1043 0000CD53 29C1                <1> 	sub	ecx, eax
  1044 0000CD55 770E                <1> 	ja	short loc_save_fat_buffer_check_rs3
  1045                              <1> 
  1046                              <1> loc_save_fat_buffer_inv_data_pop_retn:
  1047 0000CD57 5E                  <1> 	pop	esi ; *
  1048                              <1> loc_save_fat_buffer_inv_data_retn:
  1049 0000CD58 B80D000000          <1> 	mov	eax, 0Dh ; Invalid DATA
  1050 0000CD5D C3                  <1> 	retn
  1051                              <1> 
  1052                              <1> loc_save_fat_buff_remain_sectors_3:
  1053 0000CD5E B903000000          <1> 	mov	ecx, 3
  1054 0000CD63 EB05                <1> 	jmp	short loc_save_fat_buff_continue
  1055                              <1> 
  1056                              <1> loc_save_fat_buffer_check_rs3:
  1057 0000CD65 83F903              <1> 	cmp	ecx, 3
  1058 0000CD68 77F4                <1> 	ja	short loc_save_fat_buff_remain_sectors_3
  1059                              <1> 
  1060                              <1> loc_save_fat_buff_continue:
  1061 0000CD6A BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1062 0000CD6F 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1063 0000CD72 51                  <1> 	push	ecx
  1064 0000CD73 E869350000          <1> 	call	disk_write
  1065 0000CD78 59                  <1> 	pop	ecx
  1066 0000CD79 722B                <1> 	jc	short loc_save_FAT_buff_write_err
  1067                              <1> 	
  1068 0000CD7B 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1069 0000CD7F 7605                <1> 	jna	short loc_calc_2nd_fat12_16_addr
  1070                              <1> 
  1071                              <1> loc_calc_2nd_fat32_addr:
  1072 0000CD81 8B462A              <1> 	mov	eax, [esi+LD_BPB+FAT32_FAT_Size]
  1073 0000CD84 EB04                <1> 	jmp	short loc_calc_2nd_fat_addr
  1074                              <1> 
  1075                              <1> loc_calc_2nd_fat12_16_addr:
  1076 0000CD86 0FB7461C            <1> 	movzx	eax, word [esi+LD_BPB+FATSecs]
  1077                              <1> 
  1078                              <1> loc_calc_2nd_fat_addr:
  1079 0000CD8A 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1080 0000CD8D 0305[B66B0100]      <1> 	add	eax, [FAT_BuffSector]
  1081 0000CD93 BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1082                              <1> 	; ecx = 1 to 3
  1083 0000CD98 E844350000          <1> 	call	disk_write
  1084 0000CD9D 7207                <1> 	jc	short loc_save_FAT_buff_write_err
  1085                              <1>  	; Valid  buffer (1 = valid but do not save)
  1086 0000CD9F C605[B26B0100]01    <1> 	mov	byte [FAT_BuffValidData], 1
  1087                              <1> 
  1088                              <1> loc_save_FAT_buff_write_err:
  1089 0000CDA6 5E                  <1> 	pop	esi ; *
  1090 0000CDA7 BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1091                              <1> 	; 15/10/2016 (1Dh -> 18)
  1092                              <1> 	; 23/03/2016 (1Dh)
  1093 0000CDAC B812000000          <1> 	mov	eax, 18 ; Drive not ready or write error
  1094 0000CDB1 C3                  <1> 	retn
  1095                              <1> 
  1096                              <1> calculate_fat_freespace:
  1097                              <1> 	; 23/03/2016
  1098                              <1> 	; 02/03/2016
  1099                              <1> 	; 01/03/2016
  1100                              <1> 	; 29/02/2016
  1101                              <1> 	; 22/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1102                              <1> 	; 30/04/2011
  1103                              <1> 	; 03/04/2010
  1104                              <1> 	; 2005
  1105                              <1> 	; INPUT ->
  1106                              <1> 	;	EAX = Cluster count to be added or subtracted
  1107                              <1> 	; 	If BH = FFh, ESI = TR-DOS Logical Drive Description Table
  1108                              <1> 	; 	If BH < FFh, BH = TR-DOS Logical Drive Number
  1109                              <1> 	; 	BL: 
  1110                              <1> 	;	0 = Calculate, 1 = Add, 2 = Subtract, 3 = Get (Not Set/Calc)
  1111                              <1> 	; OUTPUT ->
  1112                              <1> 	;	EAX = Free Space in sectors
  1113                              <1> 	;	ESI = Logical Dos Drive Description Table address
  1114                              <1> 	;	BH = Logical Dos Drive Number (same with input value of BH)
  1115                              <1> 	;	BL = Type of operation (same with input value of BL)
  1116                              <1> 	;	ECX = 0 -> valid
  1117                              <1> 	;	ECX > 0 -> error or invalid
  1118                              <1> 	;	If EAX = FFFFFFFFh, it is 're-calculation needed'
  1119                              <1> 	;			          sign due to r/w error   
  1120                              <1> 
  1121 0000CDB2 66891D[566E0100]    <1> 	mov	[CFS_OPType], bx
  1122 0000CDB9 A3[586E0100]        <1> 	mov	[CFS_CC], eax
  1123                              <1> 	
  1124 0000CDBE 80FFFF              <1> 	cmp	bh, 0FFh
  1125 0000CDC1 740B                <1> 	je	short pass_calculate_freespace_get_drive_dt_offset
  1126                              <1> 
  1127                              <1> loc_calculate_freespace_get_drive_dt_offset:     
  1128 0000CDC3 31C0                <1> 	xor	eax, eax
  1129 0000CDC5 88FC                <1>         mov     ah, bh
  1130 0000CDC7 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1131 0000CDCC 01C6                <1>         add     esi, eax
  1132                              <1> 
  1133                              <1> pass_calculate_freespace_get_drive_dt_offset:
  1134 0000CDCE 08DB                <1> 	or	bl, bl
  1135 0000CDD0 7435                <1> 	jz	short loc_reset_fcc
  1136                              <1> 	
  1137                              <1> loc_get_free_sectors:
  1138 0000CDD2 8B4674              <1> 	mov	eax, [esi+LD_FreeSectors]
  1139                              <1> 
  1140                              <1> 	;xor	ecx, ecx
  1141                              <1> 	;dec	ecx ; 0FFFFFFFFh
  1142                              <1> 	;cmp	eax, ecx ; 29/02/2016
  1143                              <1> 	;je	short loc_get_free_sectors_retn ; recalculation is needed!
  1144                              <1> 	
  1145                              <1> 	; 23/03/2016
  1146 0000CDD5 8B4E70              <1> 	mov	ecx, [esi+LD_TotalSectors]
  1147 0000CDD8 39C1                <1> 	cmp	ecx, eax ; Total sectors must be greater than Free sectors !
  1148 0000CDDA 7707                <1> 	ja	short loc_get_free_sectors_check_optype
  1149                              <1> 	
  1150 0000CDDC 31C0                <1> 	xor	eax, eax
  1151 0000CDDE 48                  <1> 	dec	eax ; 0FFFFFFFFh  ; recalculation is needed!
  1152 0000CDDF 894674              <1> 	mov	[esi+LD_FreeSectors], eax ; reset (for recalculation)
  1153                              <1> 		
  1154                              <1> loc_get_free_sectors_retn:
  1155 0000CDE2 C3                  <1> 	retn
  1156                              <1> 	
  1157                              <1> loc_get_free_sectors_check_optype:
  1158 0000CDE3 80FB03              <1> 	cmp	bl, 3
  1159 0000CDE6 7203                <1> 	jb	short loc_set_fcc
  1160                              <1> 
  1161 0000CDE8 29C9                <1> 	sub	ecx, ecx ; 0
  1162                              <1> 
  1163 0000CDEA C3                  <1> 	retn	
  1164                              <1> 
  1165                              <1> loc_set_fcc:
  1166 0000CDEB 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1167 0000CDEF 0F87DF000000        <1>         ja      loc_update_FAT32_fs_info_fcc
  1168                              <1> 
  1169                              <1> 	;mov	eax, [esi+LD_FreeSectors]
  1170 0000CDF5 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  1171 0000CDF9 29D2                <1> 	sub	edx, edx
  1172 0000CDFB F7F1                <1> 	div	ecx
  1173                              <1> 	;or	dx, dx 
  1174                              <1> 	;	; DX -> Remain sectors < SecPerClust
  1175                              <1> 	;	; DX > 0 -> invalid free sector count
  1176                              <1> 	;jnz	short loc_reset_fcc 
  1177                              <1> 
  1178                              <1> ;pass_set_fcc_div32:
  1179 0000CDFD A3[CF6B0100]        <1> 	mov	[FreeClusterCount], eax
  1180 0000CE02 E988000000          <1>         jmp     loc_set_free_sectors_FAT12_FAT16
  1181                              <1> 
  1182                              <1> loc_reset_fcc:
  1183 0000CE07 31C0                <1> 	xor	eax, eax
  1184 0000CE09 A3[CF6B0100]        <1> 	mov	[FreeClusterCount], eax ; 0
  1185 0000CE0E 8B5678              <1> 	mov	edx, [esi+LD_Clusters]
  1186 0000CE11 42                  <1> 	inc	edx
  1187 0000CE12 8915[BE6B0100]      <1> 	mov	[LastCluster], edx
  1188                              <1> 
  1189 0000CE18 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1190 0000CE1C 7647                <1> 	jna	short loc_count_free_fat_clusters_0  
  1191                              <1> 
  1192 0000CE1E 48                  <1> 	dec	eax ; FFFFFFFFh
  1193 0000CE1F A3[606E0100]        <1> 	mov	[CFS_FAT32FC], eax
  1194                              <1> 
  1195                              <1> 	; 29/02/2016
  1196 0000CE24 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; reset
  1197 0000CE27 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; reset
  1198                              <1> 	
  1199 0000CE2A B802000000          <1> 	mov 	eax, 2
  1200                              <1> 
  1201                              <1> loc_count_fc_next_cluster_0:
  1202 0000CE2F 50                  <1> 	push	eax
  1203 0000CE30 E801F9FFFF          <1> 	call	get_next_cluster
  1204 0000CE35 7310                <1> 	jnc	short loc_check_fat32_ff_cluster
  1205 0000CE37 09C0                <1> 	or	eax, eax
  1206 0000CE39 741E                <1> 	jz	short pass_inc_cfs_fcc_0
  1207                              <1> 
  1208                              <1> loc_put_fcc_unknown_sign:
  1209 0000CE3B 58                  <1> 	pop	eax
  1210                              <1> 	; "Free count is Unknown" sign
  1211                              <1> 	;mov	dword [FreeClusterCount], 0FFFFFFFFh
  1212                              <1> 
  1213                              <1> 	; 29/02/2016
  1214                              <1> 	; Save Free Cluster Count value in FAT32 'BPB_Reserved' area
  1215                              <1> 	;mov	[esi+LD_BPB+BPB_Reserved], 0FFFFFFFFh ; unknown!
  1216 0000CE3C 8B15[606E0100]      <1> 	mov	edx, [CFS_FAT32FC] ; First Free Cluster
  1217                              <1> 	; Save First Free Cluster value in FAT32 'BPB_Reserved+4' area
  1218 0000CE42 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx
  1219                              <1> 	
  1220 0000CE45 EB7D                <1>         jmp     loc_put_fcc_invalid_sign
  1221                              <1> 
  1222                              <1> loc_check_fat32_ff_cluster:
  1223 0000CE47 09C0                <1> 	or	eax, eax
  1224 0000CE49 750E                <1> 	jnz	short pass_inc_cfs_fcc_0
  1225 0000CE4B 58                  <1> 	pop	eax
  1226 0000CE4C A3[606E0100]        <1> 	mov	[CFS_FAT32FC], eax
  1227                              <1> 	;mov	dword [FreeClusterCount], 1
  1228 0000CE51 FF05[CF6B0100]      <1> 	inc	dword [FreeClusterCount]
  1229 0000CE57 EB27                <1> 	jmp	short pass_inc_cfs_fcc_1
  1230                              <1> 
  1231                              <1> pass_inc_cfs_fcc_0:
  1232 0000CE59 58                  <1> 	pop	eax
  1233                              <1> 
  1234                              <1> pass_inc_cfs_fcc_0c:
  1235 0000CE5A 40                  <1> 	inc	eax ; add eax, 1
  1236 0000CE5B 3B05[BE6B0100]      <1> 	cmp	eax, [LastCluster]
  1237 0000CE61 76CC                <1> 	jna 	short loc_count_fc_next_cluster_0
  1238 0000CE63 EB6F                <1> 	jmp	short loc_update_FAT32_fs_info_fcc
  1239                              <1> 
  1240                              <1> loc_count_free_fat_clusters_0:
  1241                              <1> 	;mov	eax, 2
  1242 0000CE65 B002                <1> 	mov	al, 2
  1243                              <1> 
  1244                              <1> loc_count_fc_next_cluster:
  1245 0000CE67 50                  <1> 	push	eax
  1246 0000CE68 E8C9F8FFFF          <1> 	call	get_next_cluster
  1247 0000CE6D 720C                <1> 	jc	short loc_count_fcc_stc
  1248                              <1> 
  1249                              <1> loc_count_free_clusters_1:
  1250 0000CE6F 21C0                <1> 	and	eax, eax
  1251 0000CE71 750C                <1> 	jnz	short pass_inc_cfs_fcc
  1252                              <1> 
  1253 0000CE73 FF05[CF6B0100]      <1> 	inc	dword [FreeClusterCount]
  1254 0000CE79 EB04                <1> 	jmp	short pass_inc_cfs_fcc
  1255                              <1> 
  1256                              <1> loc_count_fcc_stc:
  1257 0000CE7B 09C0                <1> 	or	eax, eax
  1258 0000CE7D 75BC                <1> 	jnz	short loc_put_fcc_unknown_sign ; 29/02/2016
  1259                              <1> 
  1260                              <1> pass_inc_cfs_fcc:
  1261 0000CE7F 58                  <1> 	pop	eax
  1262                              <1> 
  1263                              <1> pass_inc_cfs_fcc_1:
  1264 0000CE80 40                  <1> 	inc	eax ; add eax, 1
  1265 0000CE81 3B05[BE6B0100]      <1> 	cmp	eax, [LastCluster]
  1266 0000CE87 76DE                <1> 	jna	short loc_count_fc_next_cluster
  1267                              <1> 
  1268                              <1> loc_set_free_sectors:
  1269 0000CE89 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1270 0000CE8D 7745                <1> 	ja	short loc_update_FAT32_fs_info_fcc
  1271                              <1> 
  1272                              <1> loc_set_free_sectors_FAT12_FAT16:
  1273 0000CE8F 803D[566E0100]00    <1> 	cmp	byte [CFS_OPType], 0
  1274 0000CE96 761C                <1> 	jna	short pass_FAT_add_sub_fcc
  1275 0000CE98 A1[586E0100]        <1> 	mov	eax, [CFS_CC]
  1276 0000CE9D 803D[566E0100]01    <1> 	cmp	byte [CFS_OPType], 1
  1277 0000CEA4 7708                <1> 	ja	short pass_FAT_add_fcc
  1278 0000CEA6 0105[CF6B0100]      <1> 	add 	[FreeClusterCount], eax
  1279 0000CEAC EB06                <1> 	jmp	short pass_FAT_add_sub_fcc
  1280                              <1> 
  1281                              <1> pass_FAT_add_fcc:
  1282 0000CEAE 2905[CF6B0100]      <1> 	sub	[FreeClusterCount], eax
  1283                              <1> 
  1284                              <1> pass_FAT_add_sub_fcc:
  1285 0000CEB4 0FB64613            <1> 	movzx	eax, byte [esi+LD_BPB+SecPerClust]
  1286 0000CEB8 8B15[CF6B0100]      <1> 	mov	edx, [FreeClusterCount]
  1287 0000CEBE F7E2                <1> 	mul	edx
  1288                              <1> 
  1289 0000CEC0 31C9                <1> 	xor	ecx, ecx 
  1290 0000CEC2 EB05                <1> 	jmp	short loc_cfs_retn_params
  1291                              <1> 
  1292                              <1> loc_put_fcc_invalid_sign:
  1293 0000CEC4 29C0                <1>        	sub	eax, eax ; 0
  1294 0000CEC6 48                  <1> 	dec	eax ; FFFFFFFFh
  1295                              <1> loc_fat32_ffc_recalc_needed:
  1296 0000CEC7 89C1                <1> 	mov	ecx, eax
  1297                              <1> 
  1298                              <1> loc_cfs_retn_params:
  1299 0000CEC9 894674              <1> 	mov 	[esi+LD_FreeSectors], eax
  1300 0000CECC 0FB71D[566E0100]    <1> 	movzx	ebx, word [CFS_OPType]
  1301 0000CED3 C3                  <1> 	retn
  1302                              <1> 
  1303                              <1> loc_update_FAT32_fs_info_fcc:
  1304                              <1> loc_check_fcc_FSINFO_op:
  1305                              <1> 	; 29/02/2016
  1306                              <1> 	; EAX = Free cluster count (before this update) ; value from disk
  1307                              <1> 	; EDX = First Free Cluster (before this update) ; value from disk
  1308 0000CED4 803D[566E0100]01    <1> 	cmp	byte [CFS_OPType], 1
  1309 0000CEDB 7221                <1> 	jb	short loc_cfs_FAT32_get_rcalc_parms ; 0 = recalculated
  1310 0000CEDD 7406                <1> 	je	short loc_check_fcc_FSINFO_op1 ; 1 = add
  1311                              <1> loc_check_fcc_FSINFO_op2: ; subtract
  1312 0000CEDF F71D[586E0100]      <1> 	neg	dword [CFS_CC] ; prepare to subtract ; 2 = sub (add negative)
  1313                              <1> loc_check_fcc_FSINFO_op1:
  1314                              <1> 	; 01/03/2016
  1315 0000CEE5 31D2                <1> 	xor	edx, edx ; 0
  1316 0000CEE7 4A                  <1> 	dec	edx ; 0FFFFFFFFh
  1317 0000CEE8 8B463A              <1> 	mov	eax, [esi+LD_BPB+BPB_Reserved]
  1318 0000CEEB 39D0                <1> 	cmp	eax, edx
  1319 0000CEED 73D5                <1> 	jnb	short loc_put_fcc_invalid_sign
  1320 0000CEEF 0305[586E0100]      <1>         add     eax, [CFS_CC] ; free cluster count on disk + current count
  1321 0000CEF5 72CD                <1> 	jc	short loc_put_fcc_invalid_sign
  1322                              <1> 	
  1323 0000CEF7 A3[CF6B0100]        <1> 	mov	[FreeClusterCount], eax
  1324 0000CEFC EB0E                <1> 	jmp	short loc_cfs_write_FSINFO_sector
  1325                              <1> 
  1326                              <1> loc_cfs_FAT32_get_rcalc_parms:
  1327 0000CEFE 8B15[606E0100]      <1> 	mov	edx, [CFS_FAT32FC]
  1328 0000CF04 A1[CF6B0100]        <1> 	mov	eax, [FreeClusterCount]
  1329 0000CF09 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx ; First Free Cluster
  1330                              <1> loc_cfs_write_FSINFO_sector:
  1331 0000CF0C 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count
  1332                              <1> 	; 01/03/2016
  1333 0000CF0F E8AA000000          <1> 	call	set_fat32_fsinfo_sector_parms
  1334 0000CF14 72AE                <1>         jc      short loc_put_fcc_invalid_sign
  1335                              <1> 
  1336                              <1> loc_set_FAT32_free_sectors:
  1337                              <1> 	; 29/02/2016
  1338                              <1> 	;mov	eax, [FreeClusterCount]
  1339                              <1> 	;mov	ecx, eax
  1340                              <1> 	;cmp	eax, 0FFFFFFFFh ; Invalid !
  1341                              <1> 	;je	short loc_cfs_retn_params
  1342                              <1> 	;
  1343 0000CF16 8B0D[CF6B0100]      <1> 	mov	ecx, [FreeClusterCount]
  1344 0000CF1C 0FB64613            <1> 	movzx	eax, byte [esi+LD_BPB+SecPerClust]
  1345 0000CF20 F7E1                <1> 	mul	ecx
  1346                              <1> 	; 29/02/2016
  1347 0000CF22 31C9                <1> 	xor	ecx, ecx ; 0
  1348 0000CF24 09D2                <1> 	or	edx, edx ; 0 ?
  1349 0000CF26 759C                <1>         jnz     loc_put_fcc_invalid_sign
  1350 0000CF28 394670              <1> 	cmp	[esi+LD_TotalSectors], eax ; Volume size in sectors
  1351 0000CF2B 7697                <1>         jna     short loc_put_fcc_invalid_sign
  1352                              <1> 	;
  1353                              <1> loc_set_FAT32_free_sectors_ok:
  1354 0000CF2D 31D2                <1> 	xor	edx, edx ; 0
  1355 0000CF2F EB98                <1>         jmp     short loc_cfs_retn_params 
  1356                              <1> 	;
  1357                              <1> 
  1358                              <1> get_last_cluster:
  1359                              <1> 	; 22/10/2016
  1360                              <1> 	; 27/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1361                              <1> 	; 12/06/2010 (DRV_FAT.ASM, 'proc_get_last_custer')
  1362                              <1> 	; 06/06/2010
  1363                              <1> 	; INPUT ->
  1364                              <1> 	;	EAX = First Cluster Number
  1365                              <1> 	; 	ESI = Logical Dos Drive Parameters Table
  1366                              <1> 	; OUTPUT ->
  1367                              <1> 	;	cf = 0 -> No Error, EAX is valid
  1368                              <1> 	;	cf = 1 -> EAX > 0 -> Error
  1369                              <1> 	;	EAX = Last Cluster Number
  1370                              <1> 	;       ECX = Previous Cluster -just before the last cluster-
  1371                              <1> 	;       ; 22/10/2016
  1372                              <1> 	;	[glc_index] = cluster index number of the last cluster	
  1373                              <1> 	;
  1374                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
  1375                              <1> 
  1376 0000CF31 89C1                <1> 	mov	ecx, eax
  1377                              <1> 
  1378 0000CF33 C705[686E0100]FFFF- <1> 	mov	dword [glc_index], 0FFFFFFFFh ; 22/10/2016	
  1378 0000CF3B FFFF                <1>
  1379                              <1> 
  1380                              <1> loc_glc_get_next_cluster_1:
  1381 0000CF3D 890D[646E0100]      <1> 	mov	[glc_prevcluster], ecx
  1382                              <1>  	; 22/10/2016
  1383 0000CF43 FF05[686E0100]      <1> 	inc	dword [glc_index]
  1384                              <1> 
  1385                              <1> loc_glc_get_next_cluster_2:
  1386 0000CF49 E8E8F7FFFF          <1> 	call	get_next_cluster
  1387                              <1> 	; ecx = current/previous cluster 
  1388                              <1> 	; eax = next/last cluster
  1389 0000CF4E 73ED                <1> 	jnc	short loc_glc_get_next_cluster_1
  1390                              <1> 
  1391 0000CF50 09C0                <1> 	or	eax, eax
  1392 0000CF52 7509                <1> 	jnz	short loc_glc_stc_retn
  1393                              <1> 
  1394                              <1> 	; ecx = previous cluster
  1395 0000CF54 89C8                <1>         mov	eax, ecx
  1396                              <1> 
  1397                              <1> 	; previous cluster becomes last cluster (ecx -> eax)
  1398                              <1> 	; previous of previous cluster becomes previous cluster (ecx)
  1399                              <1> 
  1400                              <1> loc_glc_prev_cluster_retn:
  1401 0000CF56 8B0D[646E0100]      <1> 	mov	ecx, [glc_prevcluster] 
  1402 0000CF5C C3                  <1> 	retn
  1403                              <1> 
  1404                              <1> loc_glc_stc_retn:
  1405 0000CF5D F5                  <1> 	cmc	;stc
  1406 0000CF5E EBF6                <1>         jmp	short loc_glc_prev_cluster_retn
  1407                              <1> 
  1408                              <1> truncate_cluster_chain:
  1409                              <1> 	; 01/03/2016
  1410                              <1> 	; 28/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1411                              <1> 	; 22/01/2011 (DRV_FAT.ASM, 'proc_truncate_cluster_chain')
  1412                              <1> 	; 11/09/2010
  1413                              <1> 	; INPUT ->
  1414                              <1> 	;	ESI = Logical dos drive description table address
  1415                              <1> 	;	EAX = First cluster to be truncated/unlinked 
  1416                              <1> 	; OUTPUT ->
  1417                              <1> 	;	ESI = Logical dos drive description table address
  1418                              <1> 	; 	ECX = Count of truncated/removed clusters
  1419                              <1> 	; 	CF = 0 -> EAX = Free sectors
  1420                              <1> 	; 	CF = 1 -> Error code in EAX (AL)
  1421                              <1> 
  1422                              <1> 	; NOTE: This procedure does not update lm date&time ! 
  1423                              <1> 
  1424                              <1> loc_truncate_cc:	
  1425 0000CF60 31C9                <1> 	xor	ecx, ecx ; mov ecx, 0
  1426                              <1> 	;mov	byte [FAT_BuffValidData], 0
  1427 0000CF62 890D[BA6B0100]      <1> 	mov	[FAT_ClusterCounter], ecx ; 0 ; reset
  1428                              <1> 
  1429                              <1> loc_tcc_unlink_clusters:
  1430 0000CF68 E8F3FAFFFF          <1> 	call	update_cluster
  1431                              <1> 	; EAX = Next Cluster
  1432                              <1> 	; ECX = Cluster Value
  1433                              <1> 	; Note:
  1434                              <1> 	; Returns count of unlinked clusters in
  1435                              <1> 	; dword ptr FAT_ClusterCounter
  1436 0000CF6D 73F9                <1> 	jnc short loc_tcc_unlink_clusters
  1437                              <1> 
  1438                              <1> pass_tcc_unlink_clusters:
  1439 0000CF6F A2[6F6E0100]        <1> 	mov	byte [TCC_FATErr], al
  1440 0000CF74 803D[B26B0100]02    <1> 	cmp	byte [FAT_BuffValidData], 2
  1441 0000CF7B 750E                <1> 	jne	short loc_tcc_calculate_FAT_freespace
  1442 0000CF7D E89BFDFFFF          <1> 	call	save_fat_buffer
  1443 0000CF82 7307                <1> 	jnc	short loc_tcc_calculate_FAT_freespace
  1444 0000CF84 A2[6F6E0100]        <1> 	mov	byte [TCC_FATErr], al ; Error
  1445                              <1> 	;mov	byte [FAT_BuffValidData], 0
  1446                              <1> 
  1447                              <1> 	; 01/03/2016
  1448 0000CF89 EB12                <1> 	jmp	short loc_tcc_recalculate_FAT_freespace
  1449                              <1> 
  1450                              <1> loc_tcc_calculate_FAT_freespace:
  1451 0000CF8B A1[BA6B0100]        <1> 	mov	eax, [FAT_ClusterCounter] ; signed (+-) number
  1452 0000CF90 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> ESI = Dos drv desc. table
  1453                              <1> 			   ; BL = 1 -> add cluster
  1454 0000CF94 E819FEFFFF          <1> 	call	calculate_fat_freespace
  1455 0000CF99 21C9                <1> 	and	ecx, ecx ; cx = 0 -> valid free sector count
  1456 0000CF9B 7409                <1> 	jz	short pass_truncate_cc_recalc_FAT_freespace
  1457                              <1> 
  1458                              <1> loc_tcc_recalculate_FAT_freespace:
  1459 0000CF9D 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate !
  1460 0000CFA1 E80CFEFFFF          <1> 	call	calculate_fat_freespace
  1461                              <1>               
  1462                              <1> loc_tcc_calculate_FAT_freespace_err:
  1463                              <1> pass_truncate_cc_recalc_FAT_freespace:
  1464 0000CFA6 8B0D[BA6B0100]      <1> 	mov	ecx, [FAT_ClusterCounter]
  1465                              <1> 
  1466 0000CFAC 803D[6F6E0100]00    <1> 	cmp	byte [TCC_FATErr], 0
  1467 0000CFB3 7608                <1> 	jna	short loc_tcc_unlink_clusters_retn
  1468                              <1> 
  1469                              <1> loc_tcc_unlink_clusters_error:
  1470 0000CFB5 0FB605[6F6E0100]    <1> 	movzx	eax, byte [TCC_FATErr]
  1471 0000CFBC F9                  <1> 	stc
  1472                              <1> loc_tcc_unlink_clusters_retn:
  1473 0000CFBD C3                  <1> 	retn
  1474                              <1> 
  1475                              <1> set_fat32_fsinfo_sector_parms:
  1476                              <1> 	; 15/10/2016
  1477                              <1> 	; 23/03/2016
  1478                              <1> 	; 29/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1479                              <1> 	; INPUT ->
  1480                              <1> 	;	ESI = Logical dos drive description table address
  1481                              <1> 	;	[esi+LD_BPB+BPB_Reserved] = Free Cluster Count
  1482                              <1> 	;	[esi+LD_BPB+BPB_Reserved+4] = First Free Cluster 
  1483                              <1> 	; OUTPUT ->
  1484                              <1> 	;	ESI = Logical dos drive description table address
  1485                              <1> 	; 	CF = 0 -> OK..
  1486                              <1> 	; 	CF = 1 -> Error code in EAX (AL)
  1487                              <1> 	;
  1488                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX)
  1489                              <1> 
  1490 0000CFBE E824000000          <1> 	call	get_fat32_fsinfo_sector_parms
  1491 0000CFC3 7221                <1> 	jc	short update_fat32_fsinfo_sector_retn
  1492                              <1> 
  1493 0000CFC5 8B463A              <1> 	mov	eax, [esi+LD_BPB+BPB_Reserved] ; Free Cluster Count
  1494 0000CFC8 8B563E              <1> 	mov	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free Cluster	
  1495                              <1> 
  1496                              <1>         ;mov	ebx, DOSBootSectorBuff
  1497 0000CFCB 8983E8010000        <1> 	mov	[ebx+488], eax
  1498 0000CFD1 8993EC010000        <1> 	mov	[ebx+492], edx	
  1499                              <1> 
  1500 0000CFD7 A1[5C6E0100]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC]
  1501 0000CFDC B901000000          <1> 	mov	ecx, 1
  1502 0000CFE1 E8FB320000          <1> 	call	disk_write
  1503                              <1> 	;jnc     short update_fat32_fsinfo_sector_retn
  1504                              <1> 
  1505                              <1> 	; 15/10/2016 (1Dh -> 18)
  1506                              <1> 	; 23/03/2016 (1Dh)
  1507                              <1> 	;mov	eax, 18 ; Drive not ready or write error
  1508                              <1> 
  1509                              <1> update_fat32_fsinfo_sector_retn:
  1510 0000CFE6 C3                  <1> 	retn
  1511                              <1> 
  1512                              <1> get_fat32_fsinfo_sector_parms:
  1513                              <1> 	; 15/10/2016
  1514                              <1> 	; 23/03/2016
  1515                              <1> 	; 01/03/2016
  1516                              <1> 	; 29/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1517                              <1> 	; INPUT ->
  1518                              <1> 	;	ESI = Logical dos drive description table address
  1519                              <1> 	; OUTPUT ->
  1520                              <1> 	;	ESI = Logical dos drive description table address
  1521                              <1> 	;	EBX = FSINFO sector buffer address (DOSBootSectorBuff)	
  1522                              <1> 	;	CF = 0 -> OK..
  1523                              <1> 	;	   EAX = FsInfo sector address
  1524                              <1> 	;	   ECX = Free cluster count
  1525                              <1> 	;	   EDX = First free cluster 	
  1526                              <1> 	;	CF = 1 -> Error code in AL (EAX)
  1527                              <1> 	;	   EBX = 0
  1528                              <1> 	;	
  1529                              <1> 	;	[CFS_FAT32FSINFOSEC] = FAT32 FSINFO sector address
  1530                              <1>         ;
  1531                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX)
  1532                              <1> 
  1533 0000CFE7 0FB74636            <1> 	movzx	eax, word [esi+LD_BPB+FAT32_FSInfoSec]
  1534 0000CFEB 03466C              <1> 	add	eax, [esi+LD_StartSector]
  1535 0000CFEE A3[5C6E0100]        <1> 	mov	[CFS_FAT32FSINFOSEC], eax
  1536                              <1> 	
  1537 0000CFF3 BB[AE690100]        <1>         mov     ebx, DOSBootSectorBuff
  1538 0000CFF8 B901000000          <1> 	mov	ecx, 1
  1539 0000CFFD E8EE320000          <1> 	call	disk_read
  1540 0000D002 7232                <1> 	jc	short loc_read_FAT32_fsinfo_sec_err
  1541                              <1> 
  1542 0000D004 BB[AE690100]        <1> 	mov	ebx, DOSBootSectorBuff
  1543                              <1> 
  1544 0000D009 813B52526141        <1> 	cmp	dword [ebx], 41615252h
  1545 0000D00F 751E                <1> 	jne	short loc_read_FAT32_fsinfo_sec_stc
  1546                              <1> 
  1547 0000D011 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
  1547 0000D01A 61                  <1>
  1548 0000D01B 7512                <1> 	jne	short loc_read_FAT32_fsinfo_sec_stc
  1549                              <1> 
  1550 0000D01D A1[5C6E0100]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC]
  1551 0000D022 8B8BE8010000        <1> 	mov	ecx, [ebx+488] ; free cluster count
  1552 0000D028 8B93EC010000        <1> 	mov	edx, [ebx+492] ; first (next) free cluster	
  1553                              <1> 
  1554 0000D02E C3                  <1> 	retn
  1555                              <1> 
  1556                              <1> loc_read_FAT32_fsinfo_sec_stc: 
  1557                              <1> 	; 15/10/2016 (0Bh -> 28)
  1558 0000D02F B81C000000          <1> 	mov	eax, 28 ; Invalid format!
  1559 0000D034 EB05                <1> 	jmp	short loc_read_FAT32_fsinfo_sec_stc_retn
  1560                              <1> 
  1561                              <1> loc_read_FAT32_fsinfo_sec_err:
  1562                              <1> 	; 15/10/2016 (15h -> 17)
  1563                              <1> 	; 23/03/2016 (15h)
  1564 0000D036 B811000000          <1> 	mov	eax, 17 ; Drive not ready or read error
  1565                              <1> 
  1566                              <1> loc_read_FAT32_fsinfo_sec_stc_retn:
  1567 0000D03B 29DB                <1> 	sub	ebx, ebx ; 0
  1568 0000D03D F9                  <1> 	stc
  1569 0000D03E C3                  <1> 	retn
  1570                              <1> 
  1571                              <1> add_new_cluster:
  1572                              <1> 	; 15/10/2016
  1573                              <1> 	; 16/05/2016
  1574                              <1> 	; 18/03/2016, 24/03/2016
  1575                              <1> 	; 11/03/2016 (TRDOS 386 =  TRDOS v2.0)
  1576                              <1> 	; 30/07/2011 (DRV_FAT.ASM)
  1577                              <1> 	; 11/09/2010
  1578                              <1> 	; INPUT ->
  1579                              <1> 	;	ESI = Logical dos drv desc. table address
  1580                              <1> 	;	EAX = Last cluster
  1581                              <1> 	; OUTPUT ->
  1582                              <1> 	;	ESI = Logical dos drv desc. table address
  1583                              <1> 	;	EAX = New Last cluster (next cluster)
  1584                              <1> 	;	cf = 1 -> error code in EAX (AL)
  1585                              <1> 	;	cf = 1 -> DX = sectors per cluster
  1586                              <1> 	;	ECX = Free sectors
  1587                              <1> 	; NOTE:
  1588                              <1> 	; This procedure does not update lm date&time !
  1589                              <1> 	;
  1590                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, EDI)
  1591                              <1> 	;
  1592                              <1> 
  1593 0000D03F A3[8C6F0100]        <1> 	mov	[FAT_anc_LCluster], eax
  1594                              <1> 	
  1595 0000D044 E844F9FFFF          <1> 	call	get_first_free_cluster
  1596 0000D049 720B                <1> 	jc	short loc_add_new_cluster_retn
  1597                              <1> 	; EAX >= 2 and EAX < FFFFFFFFh is valid
  1598                              <1> 
  1599 0000D04B 89C2                <1> 	mov	edx, eax
  1600                              <1> 
  1601 0000D04D 42                  <1> 	inc	edx
  1602                              <1> 	;jnz	short loc_add_new_cluster_check_ffc_eax
  1603 0000D04E 7516                <1> 	jnz	short loc_add_new_cluster_save_fcc
  1604                              <1> 
  1605                              <1> loc_add_new_cluster_no_disk_space_retn:
  1606 0000D050 B827000000          <1> 	mov	eax, 27h ; MSDOS err => insufficient disk space
  1607                              <1> loc_add_new_cluster_stc_retn:
  1608 0000D055 F9                  <1> 	stc
  1609                              <1> loc_add_new_cluster_retn:
  1610 0000D056 0FB65E13            <1> 	movzx	ebx, byte [esi+LD_BPB+SecPerClust]
  1611 0000D05A 8B4E74              <1> 	mov	ecx, [esi+LD_FreeSectors]
  1612                              <1> 	;xor	edx, edx
  1613                              <1> 	;stc
  1614 0000D05D C3                  <1> 	retn
  1615                              <1> 
  1616                              <1> loc_anc_invalid_format_stc_retn:
  1617 0000D05E F9                  <1> 	stc
  1618                              <1> loc_add_new_cluster_invalid_format_retn:
  1619                              <1> 	; 15/10/2016 (0Bh -> 28)
  1620 0000D05F B81C000000          <1> 	mov	eax, 28 ; Invalid format
  1621 0000D064 EBF0                <1> 	jmp	short loc_add_new_cluster_retn 
  1622                              <1> 
  1623                              <1> ;loc_add_new_cluster_check_ffc_eax:
  1624                              <1> ;	cmp	eax, 2
  1625                              <1> ;	jb	short loc_add_new_cluster_invalid_format_retn
  1626                              <1> 
  1627                              <1> loc_add_new_cluster_save_fcc:  
  1628 0000D066 A3[906F0100]        <1> 	mov	[FAT_anc_FFCluster], eax
  1629                              <1> 
  1630 0000D06B 83E802              <1> 	sub	eax, 2
  1631 0000D06E 0FB65E13            <1>         movzx   ebx, byte [esi+LD_BPB+SecPerClust]
  1632 0000D072 F7E3                <1> 	mul	ebx
  1633 0000D074 09D2                <1> 	or	edx, edx
  1634 0000D076 75E6                <1> 	jnz	short loc_anc_invalid_format_stc_retn
  1635                              <1> 
  1636                              <1> loc_add_new_cluster_allocate_cluster:
  1637                              <1> 	; 18/03/2016
  1638 0000D078 92                  <1> 	xchg	edx, eax ; eax = 0
  1639                              <1> 	; 16/05/2016
  1640                              <1> 	;cmp	[ClusterBuffer_Valid], al ; 0
  1641                              <1> 	;jna	short loc_anc_clear_cluster_buffer
  1642                              <1> 	;; 'copy' command, 
  1643                              <1> 	;; writing destination file clust after reading source file clust
  1644                              <1> 	;mov	[ClusterBuffer_Valid], al ; 0 ; reset
  1645                              <1> 	;jmp	short loc_add_new_cluster_write_nc_to_disk
  1646                              <1> 
  1647                              <1> loc_anc_clear_cluster_buffer:
  1648                              <1> 	; 11/03/2016
  1649                              <1> 	; Clear buffer
  1650 0000D079 BF00000700          <1> 	mov	edi, Cluster_Buffer ; 70000h (for current TRDOS 386 version)
  1651 0000D07E 89D9                <1> 	mov	ecx, ebx ; sector count
  1652 0000D080 C1E107              <1> 	shl	ecx, 7 ; 1 sector = 512 bytes -> 128 double words
  1653                              <1> 	;xor	eax, eax ; 0
  1654 0000D083 F3AB                <1> 	rep	stosd
  1655                              <1> 
  1656                              <1> loc_add_new_cluster_write_nc_to_disk:
  1657                              <1> 	; 11/03/2016
  1658                              <1> 	;xchg	eax, edx ; edx = 0, eax = sector offset
  1659 0000D085 89D0                <1> 	mov	eax, edx
  1660 0000D087 034668              <1>         add     eax, [esi+LD_DATABegin]
  1661 0000D08A 72D3                <1> 	jc	short loc_add_new_cluster_invalid_format_retn 
  1662                              <1> 		
  1663 0000D08C 89D9                <1> 	mov	ecx, ebx ; ECX = sectors per cluster (<256)
  1664 0000D08E BB00000700          <1> 	mov	ebx, Cluster_Buffer
  1665 0000D093 E849320000          <1> 	call	disk_write
  1666 0000D098 7307                <1> 	jnc	short loc_add_new_cluster_update_fat_nlc
  1667                              <1> 	
  1668                              <1> 	; 15/10/2016 (1Dh -> 18)
  1669 0000D09A B812000000          <1> 	mov	eax, 18 ; Write Error
  1670 0000D09F EBB4                <1> 	jmp	short loc_add_new_cluster_stc_retn
  1671                              <1> 
  1672                              <1> loc_add_new_cluster_update_fat_nlc:
  1673 0000D0A1 A1[906F0100]        <1> 	mov	eax, [FAT_anc_FFCluster]
  1674 0000D0A6 31C9                <1> 	xor	ecx, ecx
  1675 0000D0A8 890D[BA6B0100]      <1> 	mov	[FAT_ClusterCounter], ecx ; 0 ; reset
  1676 0000D0AE 49                  <1> 	dec	ecx ; 0FFFFFFFFh
  1677 0000D0AF E8ACF9FFFF          <1> 	call	update_cluster
  1678 0000D0B4 7304                <1> 	jnc	short loc_add_new_cluster_update_fat_plc
  1679 0000D0B6 09C0                <1> 	or	eax, eax ;EAX = 0 -> cluster value is 0 or eocc
  1680 0000D0B8 759B                <1> 	jnz	short loc_add_new_cluster_stc_retn
  1681                              <1> 
  1682                              <1> loc_add_new_cluster_update_fat_plc:
  1683 0000D0BA A1[8C6F0100]        <1> 	mov	eax, [FAT_anc_LCluster]
  1684 0000D0BF 8B0D[906F0100]      <1> 	mov	ecx, [FAT_anc_FFCluster]
  1685 0000D0C5 E896F9FFFF          <1> 	call	update_cluster
  1686 0000D0CA 7314                <1> 	jnc	short loc_add_new_cluster_save_fat_buffer
  1687 0000D0CC 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  1688 0000D0CE 7410                <1> 	jz	short loc_add_new_cluster_save_fat_buffer
  1689                              <1> 
  1690                              <1> loc_anc_save_fat_buffer_err_retn:
  1691                              <1> 	;cmp	byte [FAT_ClusterCounter], 1
  1692                              <1> 	;jb	short loc_add_new_cluster_retn
  1693                              <1> 
  1694 0000D0D0 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free space (BL = 0)
  1695                              <1> 			   ; (BH = FFh -> Use ESI as Drv Param. Tbl.)
  1696 0000D0D4 50                  <1> 	push	eax
  1697 0000D0D5 E8D8FCFFFF          <1> 	call	calculate_fat_freespace
  1698 0000D0DA 58                  <1> 	pop	eax
  1699 0000D0DB E975FFFFFF          <1>         jmp     loc_add_new_cluster_stc_retn
  1700                              <1> 
  1701                              <1> loc_add_new_cluster_save_fat_buffer:
  1702                              <1> 	;cmp	byte [FAT_BuffValidData], 2
  1703                              <1> 	;jne	short loc_add_new_cluster_calc_FAT_freespace 
  1704                              <1> 	;Byte [FAT_BuffValidData] =  2 
  1705 0000D0E0 E838FCFFFF          <1> 	call	save_fat_buffer
  1706 0000D0E5 72E9                <1> 	jc	short loc_anc_save_fat_buffer_err_retn
  1707                              <1> 
  1708                              <1> loc_add_new_cluster_calc_FAT_freespace:
  1709                              <1> 	;mov	eax, 1 ; Only one Cluster
  1710 0000D0E7 A1[BA6B0100]        <1> 	mov	eax, [FAT_ClusterCounter]
  1711 0000D0EC 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> ESI -> Dos drv desc. table
  1712                              <1> 		; BL = 1 -> add cluster
  1713 0000D0F0 B301                <1> 	mov	bl, 01h ; BL = 1 -> add clusters
  1714                              <1> 	; NOTE: EAX value will be added to Free Cluster Count
  1715                              <1> 	; (Free Cluster Count is decreased when EAX value is negative)
  1716 0000D0F2 E8BBFCFFFF          <1>         call    calculate_fat_freespace
  1717                              <1> 	;ECX = 0 -> no error, ECX > 0 -> error or invalid return
  1718 0000D0F7 21C9                <1> 	and	ecx, ecx ; ECX = 0 -> valid free sector count
  1719 0000D0F9 7409                <1> 	jz	short loc_add_new_cluster_return_cluster_number
  1720                              <1> 
  1721                              <1> loc_add_new_cluster_recalc_FAT_freespace:
  1722 0000D0FB 66BB00FF            <1> 	mov	bx, 0FF00h  ; recalculate free space
  1723 0000D0FF E8AEFCFFFF          <1>         call    calculate_fat_freespace
  1724                              <1> 	; cf = 0
  1725                              <1> loc_add_new_cluster_return_cluster_number:
  1726 0000D104 89C1                <1> 	mov	ecx, eax ; Free sector count
  1727 0000D106 A1[906F0100]        <1> 	mov	eax, [FAT_anc_FFCluster]
  1728 0000D10B 0FB65E13            <1> 	movzx	ebx, byte [esi+LD_BPB+SecPerClust]
  1729                              <1> 	;mov	edi, Cluster_Buffer
  1730 0000D10F 31D2                <1> 	xor	edx, edx
  1731 0000D111 C3                  <1>         retn
  1732                              <1> 
  1733                              <1> write_cluster:
  1734                              <1> 	; 15/10/2016
  1735                              <1> 	; 21/03/2016 (TRDOS 386 =  TRDOS v2.0)
  1736                              <1> 	;
  1737                              <1> 	; INPUT ->
  1738                              <1> 	;	EAX = Cluster Number (Sector index for SINGLIX FS)
  1739                              <1> 	;	ESI = Logical DOS Drive Description Table address
  1740                              <1> 	;	EBX = Cluster (File R/W) Buffer address (max. 64KB)
  1741                              <1> 	;	Only for SINGLIX FS:
  1742                              <1> 	;	EDX = File Number (The 1st FDT address) 
  1743                              <1> 	; OUTPUT ->
  1744                              <1> 	;	cf = 1 -> Cluster can not be written onto disk
  1745                              <1> 	;	    EAX > 0 -> Error number
  1746                              <1> 	;	cf = 0 -> Cluster has been written successfully
  1747                              <1> 	;
  1748                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
  1749                              <1> 	
  1750 0000D112 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+BPB_SecPerClust] 
  1751                              <1> 	; CL = 1 = [esi+LD_FS_Reserved2] ; SectPerClust for Singlix FS
  1752                              <1> 
  1753                              <1> write_file_sectors: ; 16/03/2016
  1754 0000D116 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  1755 0000D11A 761C                <1> 	jna	short write_fs_cluster
  1756                              <1> 
  1757                              <1> write_fat_file_sectors: 
  1758 0000D11C 83E802              <1> 	sub	eax, 2 ; Beginning cluster number is always 2
  1759 0000D11F 0FB65613            <1> 	movzx	edx, byte [esi+LD_BPB+BPB_SecPerClust] ; 18/03/2016 
  1760 0000D123 F7E2                <1> 	mul	edx
  1761 0000D125 034668              <1> 	add	eax, [esi+LD_DATABegin] ; absolute address of the cluster
  1762                              <1> 
  1763                              <1> 	; EAX = Disk sector address
  1764                              <1> 	; ECX = Sector count
  1765                              <1> 	; EBX = Buffer address
  1766                              <1> 	; (EDX = 0)
  1767                              <1> 	; ESI = Logical DOS drive description table address	
  1768                              <1> 
  1769 0000D128 E8B4310000          <1> 	call	disk_write
  1770 0000D12D 7306                <1> 	jnc	short wclust_retn
  1771                              <1> 	
  1772                              <1> 	; 15/10/2016 (1Dh -> 18)
  1773 0000D12F B812000000          <1> 	mov	eax, 18 ; Drive not ready or write error !
  1774 0000D134 C3                  <1> 	retn
  1775                              <1> 
  1776                              <1> wclust_retn:
  1777 0000D135 29C0                <1> 	sub	eax, eax ; 0
  1778 0000D137 C3                  <1> 	retn
  1779                              <1> 
  1780                              <1> write_fs_cluster:
  1781                              <1> 	; 21/03/2016 (TRDOS 386 =  TRDOS v2.0)
  1782                              <1> 	; Singlix FS
  1783                              <1> 	
  1784                              <1> 	; EAX = Cluster number is sector index number of the file (eax)
  1785                              <1> 	
  1786                              <1> 	; EDX = File number is the first File Descriptor Table address 
  1787                              <1> 	;	of the file. (Absolute address of the FDT).
  1788                              <1> 	
  1789                              <1> 	; eax = sector index (0 for the first sector)
  1790                              <1> 	; edx = FDT0 address
  1791                              <1> 		; 64 KB buffer = 128 sectors (limit) 
  1792 0000D138 B980000000          <1> 	mov	ecx, 128 ; maximum count of sectors (before eof) 
  1793 0000D13D E801000000          <1> 	call	write_fs_sectors
  1794 0000D142 C3                  <1> 	retn
  1795                              <1> 
  1796                              <1> write_fs_sectors:
  1797                              <1> 	; 21/03/2016 (TRDOS 386 =  TRDOS v2.0)
  1798 0000D143 F9                  <1> 	stc
  1799 0000D144 C3                  <1> 	retn
  1800                              <1> 
  1801                              <1> get_cluster_by_index:
  1802                              <1> 	; 29/04/2016 (TRDOS 386 =  TRDOS v2.0)
  1803                              <1> 	; INPUT ->
  1804                              <1> 	; 	EAX = Beginning cluster
  1805                              <1> 	; 	EDX = Sector index in disk/file section
  1806                              <1> 	;	      (Only for SINGLIX file system!)
  1807                              <1> 	; 	ECX = Cluster sequence number after the beginning cluster
  1808                              <1> 	; 	ESI = Logical DOS Drive Description Table address
  1809                              <1> 	; OUTPUT ->
  1810                              <1> 	;	EAX = Cluster number 
  1811                              <1> 	;	cf = 1 -> Error code in AL (EAX)
  1812                              <1> 	;
  1813                              <1> 	;(Modified registers: EAX, ECX, EBX, EDX)
  1814                              <1> 	;	
  1815 0000D145 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  1816 0000D149 721E                <1>         jb      short get_fs_section_by_index 
  1817                              <1> 
  1818 0000D14B 3B4E78              <1> 	cmp	ecx, [esi+LD_Clusters]
  1819 0000D14E 7207                <1> 	jb	short gcbi_1
  1820                              <1> gcbi_0:
  1821 0000D150 F9                  <1> 	stc
  1822 0000D151 B823000000          <1> 	mov	eax, 23h ; Cluster not available ! 
  1823                              <1> 			 ; MSDOS error code: FCB unavailable
  1824 0000D156 C3                  <1> 	retn
  1825                              <1> gcbi_1:
  1826 0000D157 51                  <1> 	push	ecx
  1827 0000D158 E8D9F5FFFF          <1> 	call	get_next_cluster
  1828 0000D15D 59                  <1> 	pop	ecx
  1829 0000D15E 7203                <1> 	jc	short gcbi_3
  1830 0000D160 E2F5                <1> 	loop	gcbi_1
  1831                              <1> gcbi_2:
  1832 0000D162 C3                  <1> 	retn
  1833                              <1> gcbi_3:
  1834 0000D163 09C0                <1> 	or	eax, eax
  1835 0000D165 74E9                <1> 	jz	short gcbi_0
  1836 0000D167 F5                  <1> 	cmc 	; stc
  1837 0000D168 C3                  <1> 	retn
  1838                              <1> 
  1839                              <1> get_fs_section_by_index:
  1840                              <1> 	; 29/04/2016 (TRDOS 386 =  TRDOS v2.0)
  1841                              <1> 	; INPUT ->
  1842                              <1> 	; 	EAX = Beginning FDT number/address
  1843                              <1> 	; 	EDX = Sector index in disk/file section
  1844                              <1> 	; 	ECX = Sector sequence number after the beginning FDT
  1845                              <1> 	; 	ESI = Logical DOS Drive Description Table address
  1846                              <1> 	; OUTPUT ->
  1847                              <1> 	; 	EAX = FDT number/address
  1848                              <1> 	; 	EDX = Sector index of the section (0,1,2,3,4...)
  1849                              <1> 	;	cf = 1 -> Error code in AL (EAX)
  1850                              <1> 	;
  1851                              <1> 	;(Modified registers: EAX, ECX, EBX, EDX)
  1852                              <1> 	;
  1853 0000D169 B8FFFFFFFF          <1> 	mov	eax, 0FFFFFFFFh
  1854 0000D16E C3                  <1> 	retn
  1855                              <1> 
  1856                              <1> get_last_section:
  1857                              <1> 	; 22/10/2016 (TRDOS 386 =  TRDOS v2.0)	
  1858                              <1> 	; INPUT ->
  1859                              <1> 	; 	EAX = (The 1st) FDT number/address
  1860                              <1> 	; 	ESI = Logical DOS Drive Description Table address
  1861                              <1> 	; OUTPUT ->
  1862                              <1> 	; 	EAX = FDT number/address of the last section
  1863                              <1> 	; 	EDX = Last sector of the section (0,1,2,3,4...)
  1864                              <1> 	;	[glc_index] = sector index number of the last sector
  1865                              <1> 	;		      (for file, not for the last section)  	
  1866                              <1> 	;		   	
  1867                              <1> 	;	cf = 1 -> Error code in AL (EAX)
  1868                              <1> 	;
  1869                              <1> 	;(Modified registers: EAX, ECX, EBX, EDX)
  1870                              <1> 	;
  1871 0000D16F B800000000          <1> 	mov	eax, 0
  1872 0000D174 BA00000000          <1> 	mov	edx, 0
  1873 0000D179 C3                  <1> 	retn
  3035                                  %include 'trdosk6.s' ; 24/01/2016
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.3) - MAIN PROGRAM : trdosk6.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 21/12/2020
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.15 (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> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    14                              <1> ; TRDOS2.ASM (09/11/2011)
    15                              <1> ; ----------------------------------------------------------------------------
    16                              <1> ; INT_21H.ASM (c) 2009-2011 Erdogan TAN  [14/11/2009] Last Update: 08/11/2011
    17                              <1> 
    18                              <1> sysent: ; < enter to system call >
    19                              <1> 	; 17/03/2017
    20                              <1> 	; 03/03/2017
    21                              <1> 	; 19/02/2017
    22                              <1> 	; 13/01/2017
    23                              <1> 	; 06/06/2016
    24                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
    25                              <1> 	; 16/04/2015 - 19/10/2015 (Retro UNIX 386 v1)
    26                              <1> 	; 10/04/2013 - 18/01/2014 (Retro UNIX 8086 v1)
    27                              <1> 	;
    28                              <1> 	; 'unkni' or 'sysent' is sytem entry from various traps. 
    29                              <1> 	; The trap type is determined and an indirect jump is made to 
    30                              <1> 	; the appropriate system call handler. If there is a trap inside
    31                              <1> 	; the system a jump to panic is made. All user registers are saved 
    32                              <1> 	; and u.sp points to the end of the users stack. The sys (trap)
    33                              <1> 	; instructor is decoded to get the the system code part (see
    34                              <1> 	; trap instruction in the PDP-11 handbook) and from this 
    35                              <1> 	; the indirect jump address is calculated. If a bad system call is
    36                              <1> 	; made, i.e., the limits of the jump table are exceeded, 'badsys'
    37                              <1> 	; is called. If the call is legitimate control passes to the
    38                              <1> 	; appropriate system routine.
    39                              <1> 	;
    40                              <1> 	; Calling sequence:
    41                              <1> 	;	Through a trap caused by any sys call outside the system.
    42                              <1> 	; Arguments:
    43                              <1> 	;	Arguments of particular system call.	
    44                              <1> 	; ...............................................................
    45                              <1> 	;	
    46                              <1> 	; Retro UNIX 8086 v1 modification: 
    47                              <1> 	;       System call number is in EAX register.
    48                              <1> 	;
    49                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
    50                              <1> 	;	registers depending of function details.
    51                              <1>   	;
    52                              <1> 	; 16/04/2015
    53 0000D17A 368925[5C030300]    <1>         mov     [ss:u.sp], esp ; Kernel stack points to return address
    54                              <1> 
    55                              <1> 	; save user registers
    56 0000D181 1E                  <1> 	push	ds
    57 0000D182 06                  <1> 	push	es
    58 0000D183 0FA0                <1> 	push	fs
    59 0000D185 0FA8                <1> 	push	gs
    60 0000D187 60                  <1> 	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
    61                              <1> 	;
    62                              <1> 	; ESPACE = [ss:u.sp] - esp ; 4*12 = 48 ; 17/09/2015 ; 06/06/2016
    63                              <1> 	; 	(ESPACE is size of space in kernel stack 
    64                              <1> 	;	for saving/restoring user registers.)
    65                              <1> 	;
    66 0000D188 50                  <1> 	push	eax ; 01/07/2015
    67 0000D189 66B81000            <1> 	mov     ax, KDATA
    68 0000D18D 8ED8                <1>         mov     ds, ax
    69 0000D18F 8EC0                <1>         mov     es, ax
    70 0000D191 8EE0                <1>         mov     fs, ax
    71 0000D193 8EE8                <1>         mov     gs, ax
    72 0000D195 A1[D8630100]        <1> 	mov	eax, [k_page_dir]
    73 0000D19A 0F22D8              <1> 	mov	cr3, eax
    74 0000D19D 58                  <1> 	pop	eax ; 01/07/2015
    75                              <1> 	; 19/10/2015
    76 0000D19E FC                  <1> 	cld
    77                              <1> 	;
    78 0000D19F FE05[5B030300]      <1> 	inc	byte [sysflg]
    79                              <1> 		; incb sysflg / indicate a system routine is in progress
    80 0000D1A5 FB                  <1>         sti 	; 18/01/2014
    81 0000D1A6 0F85DF9DFFFF        <1> 	jnz     panic ; 24/05/2013
    82                              <1> 		; beq 1f
    83                              <1> 		; jmp panic ; / called if trap inside system
    84                              <1> ;1:
    85                              <1> 	; 17/03/2017
    86 0000D1AC 80642438FE          <1> 	and	byte [esp+ESPACE+8], ~1 ; clear carry flag
    87                              <1> 
    88                              <1> 	; 16/04/2015
    89 0000D1B1 A3[64030300]        <1> 	mov	[u.r0], eax
    90 0000D1B6 8925[60030300]      <1> 	mov	[u.usp], esp ; kernel stack points to user's registers
    91                              <1> 
    92                              <1> 	; 13/01/2017 (TRDOS 386 Feaure only !)
    93 0000D1BC 803D[D4030300]00    <1> 	cmp	byte [u.t_lock], 0 ; timer interrupt lock ?
    94 0000D1C3 0F879D010000        <1> 	ja	sysrele		   ; yes, sys release only !!!
    95                              <1> 
    96                              <1> 		; mov $s.syst+2,clockp
    97                              <1> 		; mov r0,-(sp) / save user registers 
    98                              <1> 		; mov sp,u.r0 / pointer to bottom of users stack 
    99                              <1> 			   ; / in u.r0
   100                              <1> 		; mov r1,-(sp)
   101                              <1> 		; mov r2,-(sp)
   102                              <1> 		; mov r3,-(sp)
   103                              <1> 		; mov r4,-(sp)
   104                              <1> 		; mov r5,-(sp)
   105                              <1> 		; mov ac,-(sp) / "accumulator" register for extended
   106                              <1> 		             ; / arithmetic unit
   107                              <1> 		; mov mq,-(sp) / "multiplier quotient" register for the
   108                              <1> 		             ; / extended arithmetic unit
   109                              <1> 		; mov sc,-(sp) / "step count" register for the extended
   110                              <1> 		             ; / arithmetic unit
   111                              <1> 		; mov sp,u.sp / u.sp points to top of users stack
   112                              <1> 		; mov 18.(sp),r0 / store pc in r0
   113                              <1> 		; mov -(r0),r0 / sys inst in r0      10400xxx
   114                              <1> 		; sub $sys,r0 / get xxx code
   115 0000D1C9 C1E002              <1> 	shl	eax, 2
   116                              <1> 		; asl r0 / multiply by 2 to jump indirect in bytes
   117 0000D1CC 3DB8000000          <1> 	cmp	eax, end_of_syscalls - syscalls
   118                              <1> 		; cmp r0,$2f-1f / limit of table (35) exceeded
   119                              <1> 	;jnb	short badsys
   120                              <1> 		; bhis badsys / yes, bad system call
   121 0000D1D1 F5                  <1> 	cmc
   122 0000D1D2 9C                  <1> 	pushf	
   123 0000D1D3 50                  <1> 	push	eax
   124 0000D1D4 8B2D[5C030300]      <1>  	mov 	ebp, [u.sp] ; Kernel stack at the beginning of sys call
   125 0000D1DA B0FE                <1> 	mov	al, 0FEh ; 11111110b
   126 0000D1DC 1400                <1> 	adc	al, 0 ; al = al + cf
   127 0000D1DE 204508              <1> 	and	[ebp+8], al ; flags (reset carry flag)
   128                              <1> 		; bic $341,20.(sp) / set users processor priority to 0 
   129                              <1> 				 ; / and clear carry bit
   130 0000D1E1 5D                  <1> 	pop	ebp ; eax
   131 0000D1E2 9D                  <1> 	popf
   132 0000D1E3 0F8208020000        <1>         jc      badsys
   133 0000D1E9 A1[64030300]        <1> 	mov	eax, [u.r0]
   134                              <1> 	; system call registers: EAX, EDX, ECX, EBX, ESI, EDI
   135 0000D1EE FFA5[F4D10000]      <1> 	jmp	dword [ebp+syscalls]
   136                              <1> 		; jmp *1f(r0) / jump indirect thru table of addresses
   137                              <1> 		            ; / to proper system routine.
   138                              <1> syscalls: ; 1:
   139                              <1> 	; 31/12/2017
   140                              <1> 	; 28/02/2017
   141                              <1> 	; 20/02/2017
   142                              <1> 	; 19/02/2017
   143                              <1> 	; 15/10/2016
   144                              <1> 	; 20/05/2016
   145                              <1> 	; 19/05/2016
   146                              <1> 	; 16/05/2016
   147                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   148                              <1> 	; 21/09/2015
   149                              <1> 	; 01/07/2015
   150                              <1> 	; 16/04/2015 (32 bit address modification) 
   151 0000D1F4 [D5F10000]          <1> 	dd sysver	; 0 ; Get TRDOS 386 version number (v2.0)	
   152 0000D1F8 [53D40000]          <1> 	dd sysexit 	; 1
   153 0000D1FC [28D60000]          <1> 	dd sysfork 	; 2
   154 0000D200 [5BDA0000]          <1> 	dd sysread 	; 3
   155 0000D204 [7ADA0000]          <1> 	dd syswrite 	; 4
   156 0000D208 [11D80000]          <1> 	dd sysopen 	; 5
   157 0000D20C [32DA0000]          <1> 	dd sysclose 	; 6
   158 0000D210 [AAD50000]          <1> 	dd syswait 	; 7
   159 0000D214 [40D70000]          <1> 	dd syscreat 	; 8
   160 0000D218 [29000100]          <1> 	dd sysrename	; 9  ; TRDOS 386, Rename File (31/12/2017)
   161 0000D21C [A4FB0000]          <1> 	dd sysdelete	; 10 ; TRDOS 386, Delete File (29/12/2017)
   162 0000D220 [72E50000]          <1> 	dd sysexec 	; 11
   163 0000D224 [CEFC0000]          <1> 	dd syschdir 	; 12
   164 0000D228 [93FE0000]          <1> 	dd systime 	; 13 ; TRDOS 386, Get Sys Date&Time (30/12/2017)
   165 0000D22C [F4D90000]          <1> 	dd sysmkdir 	; 14
   166 0000D230 [02FD0000]          <1> 	dd syschmod 	; 15 ; TRDOS 386, Change Attributes (30/12/2017) 
   167 0000D234 [0BFC0000]          <1> 	dd sysrmdir 	; 16 ; TRDOS 386, Remove Directory (29/12/2017)
   168 0000D238 [4DE80000]          <1> 	dd sysbreak 	; 17
   169 0000D23C [E8FD0000]          <1> 	dd sysdrive 	; 18 ; TRDOS 386, Get/Set Current Drv (30/12/2017) 
   170 0000D240 [8EE80000]          <1> 	dd sysseek 	; 19
   171 0000D244 [A0E80000]          <1> 	dd systell 	; 20
   172 0000D248 [4A010100]          <1> 	dd sysmem 	; 21 ; TRDOS 386, Get Total&Free Mem (31/12/2017)
   173 0000D24C [80010100]          <1> 	dd sysprompt 	; 22 ; TRDOS 386, Change Cmd Prompt (31/12/2017)
   174 0000D250 [C2010100]          <1> 	dd syspath 	; 23 ; TRDOS 386, Get/Set Run Path (31/12/2017)
   175 0000D254 [2F020100]          <1> 	dd sysenv 	; 24 ; TRDOS 386, Get/Set Env Vars (31/12/2017)
   176 0000D258 [14FF0000]          <1> 	dd sysstime 	; 25 ; TRDOS 386, Set Sys Date&Time (30/12/2017)
   177 0000D25C [06E90000]          <1> 	dd sysquit 	; 26
   178 0000D260 [FAE80000]          <1> 	dd sysintr 	; 27
   179 0000D264 [37FE0000]          <1> 	dd sysdir 	; 28 ; TRDOS 386, Get Curr Drive&Dir (30/12/2017) 
   180 0000D268 [11DB0000]          <1> 	dd sysemt 	; 29
   181 0000D26C [72FE0000]          <1> 	dd sysldrvt	; 30 ; TRDOS 386, Get Logical DOS DDT (30/12/2017)
   182 0000D270 [C2DC0000]          <1> 	dd sysvideo 	; 31 ; TRDOS 386 Video Functions (16/05/2016)
   183 0000D274 [FF0B0100]          <1> 	dd sysaudio 	; 32 ; TRDOS 386 Audio Functions (16/05/2016)
   184 0000D278 [2ADB0000]          <1> 	dd systimer 	; 33 ; TRDOS 386 Timer Functions (18/05/2016)
   185 0000D27C [47E90000]          <1> 	dd syssleep 	; 34 ; Retro UNIX 8086 v1 feature only !
   186                              <1> 			     ; 11/06/2014
   187 0000D280 [76E90000]          <1> 	dd sysmsg	; 35 ; Retro UNIX 386 v1 feature only !
   188                              <1> 			     ; 01/07/2015
   189 0000D284 [93EA0000]          <1> 	dd sysgeterr	; 36 ; Retro UNIX 386 v1 feature only !
   190                              <1> 			     ; 21/09/2015 - get last error number
   191 0000D288 [7BFB0000]          <1> 	dd sysfpstat	; 37 ; TRDOS 386 FPU state option (28/02/2017)
   192 0000D28C [E4F10000]          <1> 	dd syspri 	; 38 ; change priority - TRDOS 386 (20/05/2016)
   193 0000D290 [66D30000]          <1> 	dd sysrele	; 39 ; TRDOS 386 (19/05/2016) (0 -> 39)
   194 0000D294 [17F30000]          <1> 	dd sysfff	; 40 ; Find First File - TRDOS 386 (15/10/2016)
   195 0000D298 [F6F30000]          <1> 	dd sysfnf	; 41 ; Find Next File - TRDOS 386 (15/10/2016)
   196 0000D29C [66FA0000]          <1> 	dd sysalloc	; 42 ; Allocate contiguous memory block/pages
   197                              <1> 			     ; TRDOS 386 (19/02/2017) DMA buff fuctions		
   198 0000D2A0 [24FB0000]          <1> 	dd sysdalloc	; 43 ; Deallocate contiguous memory block/pages
   199                              <1> 			     ; TRDOS 386 (19/02/2017) DMA buff fuctions
   200 0000D2A4 [5FFB0000]          <1> 	dd syscalbac	; 44 ; IRQ Callback and Signal Response Byte
   201                              <1> 			     ; service setup - TRDOS 386 (20/02/2017)
   202                              <1> 			     ; 28/08/2017 (20/08/2017)	
   203 0000D2A8 [90140100]          <1> 	dd sysdma	; 45 ; TRDOS 386 - (ISA) DMA service
   204                              <1> 	
   205                              <1> end_of_syscalls:
   206                              <1> 
   207                              <1> error:
   208                              <1> 	; 18/05/2016
   209                              <1> 	; 13/05/2016
   210                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   211                              <1> 	; 16/04/2015 - 17/09/2015 (Retro UNIX 386 v1)
   212                              <1> 	; 10/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
   213                              <1> 	;
   214                              <1> 	; 'error' merely sets the error bit off the processor status (c-bit)
   215                              <1> 	; then falls right into the 'sysret', 'sysrele' return sequence.
   216                              <1> 	;
   217                              <1> 	; INPUTS -> none
   218                              <1> 	; OUTPUTS ->
   219                              <1> 	;	processor status - carry (c) bit is set (means error)
   220                              <1> 	;
   221                              <1> 	; 26/05/2013 (Stack pointer must be reset here! 
   222                              <1> 	; 	      Because, jumps to error procedure
   223                              <1> 	;	      disrupts push-pop nesting balance)
   224                              <1> 	;
   225 0000D2AC 8B2D[5C030300]      <1> 	mov	ebp, [u.sp] ; interrupt (system call) return (iretd) address
   226 0000D2B2 804D0801            <1> 	or	byte [ebp+8], 1  ; set carry bit of flags register
   227                              <1> 				 ; (system call will return with cf = 1)
   228                              <1> 		; bis $1,20.(r1) / set c bit in processor status word below
   229                              <1> 		               ; / users stack
   230                              <1> 	; 17/09/2015
   231 0000D2B6 83ED30              <1> 	sub	ebp, ESPACE ; 48 ; total size of stack frame ('sysdefs.inc')
   232                              <1> 				 ; for saving/restoring user registers	
   233                              <1> 	;cmp	ebp, [u.usp]
   234                              <1> 	;je	short err0	
   235 0000D2B9 892D[60030300]      <1> 	mov	[u.usp], ebp
   236                              <1> ;err0:
   237                              <1> 	; 01/09/2015
   238 0000D2BF 8B25[60030300]      <1> 	mov	esp, [u.usp] 	    ; Retro Unix 8086 v1 modification!
   239                              <1> 				    ; 10/04/2013
   240                              <1> 				    ; (If an I/O error occurs during disk I/O,
   241                              <1> 				    ; related procedures will jump to 'error'
   242                              <1> 				    ; procedure directly without returning to 
   243                              <1> 				    ; the caller procedure. So, stack pointer
   244                              <1>                                     ; must be restored here.)
   245                              <1> 	; 13/05/2016
   246                              <1> 	; NOTE: (The last) error code is in 'u.error', it can be retrieved by
   247                              <1> 	;	'get last error' system call later. 	
   248                              <1> 
   249                              <1> 	; 03/09/2015 - 09/06/2015 - 07/08/2013
   250 0000D2C5 C605[C6030300]00    <1> 	mov 	byte [u.kcall], 0 ; namei_r, mkdir_w reset
   251                              <1> 
   252                              <1> sysret: ; < return from system call>
   253                              <1> 	; 01/03/2017
   254                              <1> 	; 28/02/2017
   255                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   256                              <1> 	; 16/04/2015 - 10/09/2015 (Retro UNIX 386 v1)
   257                              <1> 	; 10/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
   258                              <1> 	;
   259                              <1> 	; 'sysret' first checks to see if process is about to be 
   260                              <1> 	; terminated (u.bsys). If it is, 'sysexit' is called.
   261                              <1> 	; If not, following happens:	 
   262                              <1> 	; 	1) The user's stack pointer is restored.
   263                              <1> 	;	2) r1=0 and 'iget' is called to see if last mentioned
   264                              <1> 	;	   i-node has been modified. If it has, it is written out
   265                              <1> 	;	   via 'ppoke'.
   266                              <1> 	;	3) If the super block has been modified, it is written out
   267                              <1> 	;	   via 'ppoke'.				
   268                              <1> 	;	4) If the dismountable file system's super block has been
   269                              <1> 	;	   modified, it is written out to the specified device
   270                              <1> 	;	   via 'ppoke'.
   271                              <1> 	;	5) A check is made if user's time quantum (uquant) ran out
   272                              <1> 	;	   during his execution. If so, 'tswap' is called to give
   273                              <1> 	;	   another user a chance to run.
   274                              <1> 	;	6) 'sysret' now goes into 'sysrele'. 
   275                              <1> 	;	    (See 'sysrele' for conclusion.)		
   276                              <1> 	;
   277                              <1> 	; Calling sequence:
   278                              <1> 	;	jump table or 'br sysret'
   279                              <1> 	; Arguments: 
   280                              <1> 	;	-	
   281                              <1> 	; ...............................................................
   282                              <1> 	;	
   283                              <1> 	; ((AX=r1 for 'iget' input))
   284                              <1> 	;	
   285 0000D2CC 31C0                <1> 	xor	eax, eax ; 28/02/2017
   286                              <1> sysret0: ; 29/07/2015 (eax = 0, jump from sysexec)
   287 0000D2CE FEC0                <1> 	inc	al ; 04/05/2013
   288 0000D2D0 3805[B2030300]      <1> 	cmp	[u.bsys], al ; 1
   289                              <1> 		; tstb u.bsys / is a process about to be terminated because
   290 0000D2D6 0F8377010000        <1>         jnb     sysexit ; 04/05/2013
   291                              <1> 		; bne sysexit / of an error? yes, go to sysexit
   292                              <1> 	;mov	esp, [u.usp] ; 24/05/2013 (that is not needed here)
   293                              <1> 		; mov u.sp,sp / no point stack to users stack
   294 0000D2DC FEC8                <1> 	dec 	al ; mov ax, 0
   295                              <1> 		; clr r1 / zero r1 to check last mentioned i-node
   296 0000D2DE E8F72F0000          <1> 	call	iget
   297                              <1> 		; jsr r0,iget / if last mentioned i-node has been modified
   298                              <1> 		            ; / it is written out
   299                              <1> 	; 10/01/2017
   300                              <1> 	; 09/01/2017
   301                              <1> ;sysrele: ; < release >
   302                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   303                              <1> 	; 16/04/2015 - 14/10/2015 (Retro UNIX 386 v1)
   304                              <1> 	; 10/04/2013 - 07/03/2014 (Retro UNIX 8086 v1)
   305                              <1> 	;
   306                              <1> 	; 'sysrele' first calls 'tswap' if the time quantum for a user is
   307                              <1> 	;  zero (see 'sysret'). It then restores the user's registers and
   308                              <1> 	; turns off the system flag. It then checked to see if there is
   309                              <1> 	; an interrupt from the user by calling 'isintr'. If there is, 
   310                              <1> 	; the output gets flashed (see isintr) and interrupt action is
   311                              <1> 	; taken by a branch to 'intract'. If there is no interrupt from
   312                              <1> 	; the user, a rti is made.
   313                              <1> 	;
   314                              <1> 	; Calling sequence:
   315                              <1> 	;	Fall through a 'bne' in 'sysret' & ?
   316                              <1> 	; Arguments:
   317                              <1> 	;	-	
   318                              <1> 	; ...............................................................
   319                              <1> 	;	
   320                              <1> 	; 23/02/2014 (swapret)
   321                              <1> 	; 22/09/2013
   322                              <1> sysrel0: ;1:
   323 0000D2E3 803D[A8030300]00    <1> 	cmp	byte [u.quant], 0 ; 16/05/2013
   324                              <1> 		; tstb uquant / is the time quantum 0?
   325 0000D2EA 7705                <1>         ja      short swapret
   326                              <1> 		; bne 1f / no, don't swap it out
   327                              <1> sysrelease: ; 07/12/2013 (jump from 'clock')
   328 0000D2EC E8AC1D0000          <1> 	call	tswap
   329                              <1> 		; jsr r0,tswap / yes, swap it out
   330                              <1> 	
   331                              <1> ; Retro Unix 8086 v1 feature: return from 'swap' to 'swapret' address.
   332                              <1> swapret: ;1:
   333                              <1> 	; 10/09/2015
   334                              <1> 	; 01/09/2015
   335                              <1> 	; 14/05/2015
   336                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit, pm modifications)
   337                              <1> 	; 26/05/2013 (Retro UNIX 8086 v1)
   338                              <1> 	; cli
   339                              <1> 	; 24/07/2015
   340                              <1> 	;
   341                              <1> 	;; 'esp' must be already equal to '[u.usp]' here ! 
   342                              <1> 	;; mov	esp, [u.usp]
   343                              <1> 
   344                              <1> 	; 22/09/2013
   345 0000D2F1 E8E52F0000          <1> 	call	isintr
   346                              <1> 	; 20/10/2013
   347 0000D2F6 7405                <1> 	jz	short sysrel1
   348 0000D2F8 E83F010000          <1> 	call	intract
   349                              <1> 		; jsr r0,isintr / is there an interrupt from the user
   350                              <1> 		;     br intract / yes, output gets flushed, take interrupt
   351                              <1> 		               ; / action
   352                              <1> sysrel1:
   353 0000D2FD FA                  <1> 	cli	; 14/10/2015
   354                              <1> sysrel2:
   355                              <1> 	; 28/02/2017
   356                              <1> 	; Check if there is a (delayed) callback for current user/process
   357 0000D2FE A0[D7030300]        <1> 	mov	al, [u.irqwait]
   358 0000D303 240F                <1> 	and	al, 0Fh ; is there a waiting IRQ callback service ?
   359 0000D305 7444                <1> 	jz	short sysrel8 ; no
   360                              <1> 
   361                              <1> 	; Set return to IRQ callback service and return from the service
   362 0000D307 0FB6D8              <1> 	movzx	ebx, al
   363 0000D30A 883D[D7030300]      <1> 	mov 	[u.irqwait], bh ; 0 ; reset
   364 0000D310 8A9B[2A210100]      <1> 	mov	bl, [ebx+IRQenum] ; (available) IRQ index +1 (1 to 9)
   365                              <1> 	; 01/03/2017
   366 0000D316 FECB                <1> 	dec	bl ; IRQ index number, 0 to 8
   367 0000D318 7831                <1> 	js	short sysrel8 ; 0 -> FFh (not in use!?) 
   368                              <1> 	;
   369 0000D31A A0[B3030300]        <1> 	mov 	al, [u.uno] ; current process (user) number 
   370 0000D31F 3883[0A760100]      <1> 	cmp	[ebx+IRQ.owner], al
   371 0000D325 7524                <1> 	jne	short sysrel8 ; it is not the current user/process !?
   372 0000D327 F683[1C760100]01    <1> 	test	byte [ebx+IRQ.method], 1 ; callback ?
   373 0000D32E 741B                <1> 	jz	short sysrel8 ; not a callback method !?
   374                              <1> 
   375 0000D330 8B93[2E760100]      <1> 	mov	edx, [ebx+IRQ.addr] ; IRQ callback service address (virtual)
   376 0000D336 C605[D8030300]01    <1> 	mov	byte [u.r_lock], 1 ; IRQ callback service in progress flag
   377                              <1> 
   378 0000D33D E8031E0000          <1> 	call	wswap ; save user's registers & status 
   379                              <1> 		      ;	(for return from IRQ callback service)
   380                              <1> 
   381 0000D342 8B2D[5C030300]      <1> 	mov	ebp, [u.sp]; kernel's stack, points to EIP (user)
   382 0000D348 895500              <1> 	mov	[ebp], edx ; IRQ call back service address
   383                              <1> sysrel8:
   384 0000D34B FE0D[5B030300]      <1> 	dec	byte [sysflg]
   385                              <1> 		; decb sysflg / turn system flag off
   386                              <1> 	
   387 0000D351 A1[B8030300]        <1> 	mov	eax, [u.pgdir]	
   388 0000D356 0F22D8              <1> 	mov	cr3, eax  ; 1st PDE points to Kernel Page Table 0 (1st 4 MB)
   389                              <1> 			  ; (others are different than kernel page tables) 
   390                              <1> 	; 10/09/2015
   391 0000D359 61                  <1> 	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
   392                              <1> 		; mov (sp)+,sc / restore user registers
   393                              <1> 		; mov (sp)+,mq
   394                              <1> 		; mov (sp)+,ac
   395                              <1> 		; mov (sp)+,r5
   396                              <1> 		; mov (sp)+,r4
   397                              <1> 		; mov (sp)+,r3
   398                              <1> 		; mov (sp)+,r2
   399                              <1> 	;
   400 0000D35A A1[64030300]        <1> 	mov	eax, [u.r0]  ; ((return value in EAX))
   401 0000D35F 0FA9                <1> 	pop	gs
   402 0000D361 0FA1                <1> 	pop	fs
   403 0000D363 07                  <1> 	pop	es
   404 0000D364 1F                  <1> 	pop	ds
   405                              <1> 	;or	word [esp+8], 200h ; 22/01/2017 ; force enabling interrupts
   406 0000D365 CF                  <1> 	iretd	
   407                              <1> 		; rti / no, return from interrupt
   408                              <1> 
   409                              <1> sysrele:
   410                              <1> 	; 24/03/2017
   411                              <1> 	; 28/02/2017
   412                              <1> 	; 27/02/2017
   413                              <1> 	; 29/01/2017
   414                              <1> 	; 14/01/2017
   415                              <1> 	; 13/01/2017
   416                              <1> 	; 09/01/2017, 10/01/2017, 12/01/2017
   417                              <1> 	; Major modification for TRDOS 386 (CallBack return)
   418                              <1> 	;
   419                              <1> 	; 'sysrele' system call restores previously saved
   420                              <1> 	; registers and addresses of the process
   421                              <1> 	; (Main purpose -in TRDOS 386- is to return from
   422                              <1> 	; timer callback service routine in ring 3 -user mode-.)
   423                              <1> 	;
   424                              <1> 	; check if the process is in timer callback phase
   425 0000D366 803D[D4030300]00    <1> 	cmp	byte [u.t_lock], 0 ; TIMER INT LOCK
   426                              <1> 	;je	short sysrel0 ; classic (Retro UNIX 386 type) sysrele
   427 0000D36D 7734                <1> 	ja	short sysrel3
   428                              <1> 	; 27/02/2017
   429 0000D36F 803D[D8030300]00    <1> 	cmp	byte [u.r_lock], 0 ; IRQ callback lock	
   430 0000D376 0F8667FFFFFF        <1> 	jna	sysrel0 ; classic sysrele ; 24/03/2017
   431 0000D37C E859000000          <1> 	call	sysrel7
   432 0000D381 803D[D8030300]00    <1> 	cmp	byte [u.r_lock], 0 ; IRQ callback service lock
   433 0000D388 7628                <1> 	jna	short sysrel4
   434 0000D38A C605[D8030300]00    <1> 	mov	byte [u.r_lock], 0 ; reset
   435                              <1> 	;mov	byte [u.irqwait], 0 ; reset ; 28/02/2017
   436 0000D391 A0[D9030300]        <1> 	mov	al, [u.r_mode]
   437 0000D396 08C0                <1> 	or	al, al
   438 0000D398 7518                <1> 	jnz	short sysrel4
   439 0000D39A FEC8                <1> 	dec	al
   440 0000D39C A2[D9030300]        <1> 	mov	[u.r_mode], al ; 0FFh ; not necessary !?
   441 0000D3A1 EB32                <1> 	jmp	short sysrel6		
   442                              <1> sysrel3:
   443                              <1> 	; 27/02/2017
   444 0000D3A3 E832000000          <1> 	call	sysrel7
   445                              <1> 	; 14/01/2017
   446 0000D3A8 28C0                <1> 	sub	al, al
   447 0000D3AA 3805[D4030300]      <1> 	cmp	[u.t_lock], al ; 0 ; TIMER INT LOCK
   448 0000D3B0 770E                <1> 	ja	short sysrel5 ; yes
   449                              <1> sysrel4:
   450                              <1> 	; 29/01/2017
   451 0000D3B2 8B44241C            <1> 	mov	eax, [esp+28] ; eax
   452 0000D3B6 A3[64030300]        <1> 	mov	[u.r0], eax
   453 0000D3BB E93EFFFFFF          <1> 	jmp	sysrel2
   454                              <1> sysrel5:
   455 0000D3C0 A2[D4030300]        <1> 	mov	[u.t_lock], al ; 0 ; reset
   456 0000D3C5 A0[D5030300]        <1> 	mov	al, [u.t_mode]
   457 0000D3CA 20C0                <1> 	and	al, al
   458                              <1> 	;jnz	short sysrel2 ; 0FFh ; user mode
   459 0000D3CC 75E4                <1> 	jnz	short sysrel4 ; 29/01/2017
   460 0000D3CE FEC8                <1> 	dec	al
   461 0000D3D0 A2[D5030300]        <1> 	mov	[u.t_mode], al ; 0FFh ; not necessary !?
   462                              <1> sysrel6:
   463                              <1> 	; cpu will continue from the interrupted sytem call addr
   464 0000D3D5 61                  <1> 	popad		; edi, esi, ebp, esp, ebx, edx, ecx, eax
   465 0000D3D6 83C410              <1> 	add	esp, 16	; pass segment segisters: ds, es, fs, gs		
   466 0000D3D9 CF                  <1> 	iretd		; eip, cs, eflags
   467                              <1> 
   468                              <1> sysrel7:
   469 0000D3DA 0FB61D[B3030300]    <1> 	movzx	ebx, byte [u.uno] ; current process number
   470 0000D3E1 66C1E302            <1> 	shl	bx, 2
   471                              <1> 	;cmp	[ebx+p.tcb-4], eax ; 0 ; is there callback address ?
   472                              <1> 	;jna	short sysrel0 
   473                              <1> 	; yes, reset callback address then restore process registers 
   474                              <1> 	;mov	[ebx+p.tcb-4], eax ; 0 ; reset
   475 0000D3E5 8B83[BC000300]      <1> 	mov     eax, [ebx+p.upage-4] ; UPAGE address
   476 0000D3EB FA                  <1> 	cli	; disable interrupts till 'iretd'
   477 0000D3EC E98C1D0000          <1> 	jmp	rswap ; restore process 'u' structure
   478                              <1>  
   479                              <1> badsys:
   480                              <1> 	; 25/12/2016
   481                              <1> 	; 18/04/2016 (TRDOS 386 = TRDOS v2.0)
   482                              <1> 	; 17/04/2011 (TRDOS v1.0, 'IFC.ASM')
   483                              <1> 	; 03/02/2011 ('trdos_ifc_routine')
   484                              <1> 	;
   485                              <1> 	; 16/04/2015 (Retro UNIX 386 v1, 'badsys')
   486                              <1> 	; (EIP, EAX values will be shown on screen with error message)
   487                              <1> 	; (EIP = 'CD 40h' instruction address -INT 40h-)
   488                              <1> 	; (EAX = Function number)  
   489                              <1> 	;
   490 0000D3F1 FE05[B2030300]      <1> 	inc	byte [u.bsys]
   491                              <1> 	;
   492 0000D3F7 8B1D[5C030300]      <1> 	mov	ebx, [u.sp] ; esp at the beginning of 'sysent'
   493 0000D3FD 8B03                <1> 	mov	eax, [ebx] ; EIP (return address, not 'INT 30h' address)
   494 0000D3FF 83E802              <1> 	sub	eax, 2 ; CDh, ##h
   495 0000D402 E8D868FFFF          <1> 	call	dwordtohex
   496 0000D407 8915[031F0100]      <1> 	mov	[eip_str], edx
   497 0000D40D A3[071F0100]        <1> 	mov	[eip_str+4], eax
   498 0000D412 A1[64030300]        <1> 	mov	eax, [u.r0]
   499 0000D417 E8C368FFFF          <1> 	call	dwordtohex
   500 0000D41C 8915[F21E0100]      <1> 	mov	[eax_str], edx
   501 0000D422 A3[F61E0100]        <1> 	mov	[eax_str+4], eax
   502                              <1> 
   503 0000D427 66C705[E71E0100]34- <1> 	mov	word [int_num_str], SYSCALL_INT_NUM ; 25/12/2016
   503 0000D42F 30                  <1>
   504                              <1> 
   505 0000D430 BE[B91E0100]        <1> 	mov	esi, ifc_msg ; "invalid funtion call !" msg (trdosk9.s)
   506 0000D435 E8EB9AFFFF          <1> 	call	print_msg
   507                              <1> 
   508 0000D43A EB17                <1> 	jmp	sysexit
   509                              <1> 
   510                              <1> intract: ; / interrupt action
   511                              <1> 	; 14/10/2015
   512                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
   513                              <1> 	; 09/05/2013 - 07/12/2013 (Retro UNIX 8086 v1)
   514                              <1> 	;
   515                              <1> 	; Retro UNIX 8086 v1 modification !
   516                              <1> 	; (Process/task switching and quit routine by using
   517                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
   518                              <1> 	;
   519                              <1> 	; input -> 'u.quit'  (also value of 'u.intr' > 0)
   520                              <1> 	; output -> If value of 'u.quit' = FFFFh ('ctrl+brk' sign)
   521                              <1> 	;		'intract' will jump to 'sysexit'.
   522                              <1> 	;	    Intract will return to the caller 
   523                              <1> 	;		if value of 'u.quit' <> FFFFh. 	 
   524                              <1> 	; 14/10/2015
   525 0000D43C FB                  <1> 	sti
   526                              <1> 	; 07/12/2013	
   527 0000D43D 66FF05[AC030300]    <1> 	inc 	word [u.quit]
   528 0000D444 7408                <1> 	jz	short intrct0 ; FFFFh -> 0
   529 0000D446 66FF0D[AC030300]    <1> 	dec	word [u.quit]
   530                              <1> 	; 16/04/2015
   531 0000D44D C3                  <1> 	retn
   532                              <1> intrct0:	
   533 0000D44E 58                  <1> 	pop	eax ; call intract -> retn
   534                              <1> 	;
   535 0000D44F 31C0                <1> 	xor 	eax, eax
   536 0000D451 FEC0                <1> 	inc	al  ; mov ax, 1
   537                              <1> ;;;
   538                              <1> 	; UNIX v1 original 'intract' routine... 
   539                              <1> 	; / interrupt action
   540                              <1> 		;cmp *(sp),$rti / are you in a clock interrupt?
   541                              <1> 		; bne 1f / no, 1f
   542                              <1> 		; cmp (sp)+,(sp)+ / pop clock pointer
   543                              <1> 	; 1: / now in user area
   544                              <1> 		; mov r1,-(sp) / save r1
   545                              <1> 		; mov u.ttyp,r1 
   546                              <1> 			; / pointer to tty buffer in control-to r1
   547                              <1> 		; cmpb 6(r1),$177
   548                              <1> 			; / is the interrupt char equal to "del"
   549                              <1> 		; beq 1f / yes, 1f
   550                              <1> 		; clrb 6(r1) 
   551                              <1> 		        ; / no, clear the byte 
   552                              <1> 			; / (must be a quit character)
   553                              <1> 		; mov (sp)+,r1 / restore r1
   554                              <1> 		; clr u.quit / clear quit flag
   555                              <1> 		; bis $20,2(sp) 
   556                              <1> 		    	; / set trace for quit (sets t bit of 
   557                              <1> 			; / ps-trace trap)
   558                              <1> 		; rti   ;  / return from interrupt
   559                              <1> 	; 1: / interrupt char = del
   560                              <1> 		; clrb 6(r1) / clear the interrupt byte 
   561                              <1> 			   ; / in the buffer
   562                              <1> 		; mov (sp)+,r1 / restore r1
   563                              <1> 		; cmp u.intr,$core / should control be 
   564                              <1> 				; / transferred to loc core?
   565                              <1> 		; blo 1f
   566                              <1> 		; jmp *u.intr / user to do rti yes, 
   567                              <1> 				; / transfer to loc core
   568                              <1> 	; 1:
   569                              <1> 		; sys 1 / exit
   570                              <1> 
   571                              <1> sysexit: ; <terminate process>
   572                              <1> 	; 14/11/2017
   573                              <1> 	; 27/05/2017
   574                              <1> 	; 10/04/2017
   575                              <1> 	; 26/02/2017, 28/02/2017
   576                              <1> 	; 02/01/2017, 23/01/2017
   577                              <1> 	; 06/06/2016, 10/06/2016
   578                              <1> 	; 19/05/2016, 23/05/2016
   579                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   580                              <1> 	; 16/04/2015 - 01/09/2015 (Retro UNIX 386 v1)
   581                              <1> 	; 19/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
   582                              <1> 	;
   583                              <1> 	; 'sysexit' terminates a process. First each file that
   584                              <1> 	; the process has opened is closed by 'flose'. The process
   585                              <1> 	; status is then set to unused. The 'p.pid' table is then
   586                              <1> 	; searched to find children of the dying process. If any of
   587                              <1> 	; children are zombies (died by not waited for), they are
   588                              <1> 	; set free. The 'p.pid' table is then searched to find the
   589                              <1> 	; dying process's parent. When the parent is found, it is
   590                              <1> 	; checked to see if it is free or it is a zombie. If it is
   591                              <1> 	; one of these, the dying process just dies. If it is waiting
   592                              <1> 	; for a child process to die, it notified that it doesn't 
   593                              <1> 	; have to wait anymore by setting it's status from 2 to 1
   594                              <1> 	; (waiting to active). It is awakened and put on runq by
   595                              <1> 	; 'putlu'. The dying process enters a zombie state in which
   596                              <1> 	; it will never be run again but stays around until a 'wait'
   597                              <1> 	; is completed by it's parent process. If the parent is not
   598                              <1> 	; found, process just dies. This means 'swap' is called with
   599                              <1> 	; 'u.uno=0'. What this does is the 'wswap' is not called
   600                              <1> 	; to write out the process and 'rswap' reads the new process
   601                              <1> 	; over the one that dies..i.e., the dying process is 
   602                              <1> 	; overwritten and destroyed.	
   603                              <1>  	;
   604                              <1> 	; Calling sequence:
   605                              <1> 	;	sysexit or conditional branch.
   606                              <1> 	; Arguments:
   607                              <1> 	;	-	
   608                              <1> 	; ...............................................................
   609                              <1> 	;	
   610                              <1> 	; Retro UNIX 8086 v1 modification: 
   611                              <1> 	;       System call number (=1) is in EAX register.
   612                              <1> 	;
   613                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
   614                              <1> 	;       registers depending of function details.
   615                              <1> 	;
   616                              <1> 	; ('swap' procedure is mostly different than original UNIX v1.)
   617                              <1> 	;
   618                              <1> ; / terminate process
   619                              <1> 	; AX = 1
   620 0000D453 6648                <1> 	dec 	ax ; 0
   621 0000D455 66A3[AA030300]      <1> 	mov	[u.intr], ax ; 0
   622                              <1> 		; clr u.intr / clear interrupt control word
   623                              <1> 		; clr r1 / clear r1
   624                              <1> sysexit_0:
   625                              <1> 	; 23/01/2017
   626                              <1> 	; 02/01/2017
   627                              <1> 	; 10/06/2016
   628                              <1> 	; 06/06/2016
   629                              <1> 	; 23/05/2016
   630                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
   631                              <1> 	; Check and stop/clear timer event(s) of this (dying) process
   632                              <1> 	; if there is.
   633                              <1> 
   634                              <1> 	; 02/01/2017 
   635 0000D45B FA                  <1> 	cli	; disable interrupts
   636                              <1> 	; 23/01/2017 - reset timer frequency (to 18.2Hz)
   637 0000D45C B036                <1> 	mov	al, 00110110b ; 36h
   638 0000D45E E643                <1>  	out	43h, al
   639 0000D460 28C0                <1> 	sub	al, al ; 0
   640 0000D462 E640                <1> 	out	40h, al ; LB
   641 0000D464 E640                <1> 	out	40h, al ; HB
   642                              <1>  	; 
   643 0000D466 0FB61D[B3030300]    <1> 	movzx	ebx, byte [u.uno]
   644                              <1> 	;mov	bl, [u.uno] ; process number of dying process
   645 0000D46D 3883[FF000300]      <1> 	cmp	byte [ebx+p.timer-1], al ; 0
   646 0000D473 763A                <1> 	jna	short sysexit_12 ; no timer events for this process
   647 0000D475 8883[FF000300]      <1> 	mov	byte [ebx+p.timer-1], al ; 0 ; reset
   648                              <1> 	;mov	al, [timer_events]
   649                              <1> 	;or	al, al
   650                              <1>  	;jz	short sysexit_12 ; no timer events
   651                              <1> 	;mov	cl, al
   652 0000D47B 8A0D[6B700100]      <1> 	mov	cl, [timer_events] ; 14/11/2017
   653                              <1> 	;cli	; disable interrupts 
   654 0000D481 B410                <1> 	mov	ah, 16 ; number of available timer events
   655 0000D483 BE[60040300]        <1> 	mov	esi, timer_set ; beginning address of timer events
   656                              <1> sysexit_7:
   657 0000D488 8A06                <1> 	mov	al, [esi] ; process number (of timer event)
   658 0000D48A 38D8                <1> 	cmp	al, bl ; process number comparison
   659 0000D48C 7411                <1> 	je	short sysexit_10
   660 0000D48E 20C0                <1> 	and	al, al
   661 0000D490 7404                <1> 	jz	short sysexit_9
   662                              <1> sysexit_8:
   663 0000D492 FEC9                <1> 	dec	cl
   664 0000D494 7416                <1> 	jz	short sysexit_11
   665                              <1> sysexit_9:
   666 0000D496 FECC                <1> 	dec	ah
   667 0000D498 7415                <1> 	jz	short sysexit_12
   668 0000D49A 83C610              <1> 	add	esi, 16
   669 0000D49D EBE9                <1> 	jmp	short sysexit_7
   670                              <1> 
   671                              <1> sysexit_10:
   672                              <1> 	;mov	byte [esi], 0
   673 0000D49F 66C7060000          <1> 	mov	word [esi], 0
   674                              <1> 	;mov	dword [esi+12], 0
   675                              <1> 	;
   676 0000D4A4 FE0D[6B700100]      <1> 	dec	byte [timer_events] ; 02/01/2017
   677                              <1> 	;
   678 0000D4AA EBE6                <1> 	jmp	short sysexit_8
   679                              <1> 
   680                              <1> sysexit_11:
   681 0000D4AC 6629C0              <1> 	sub	ax, ax ; 0 ; 26/02/2017
   682                              <1> sysexit_12:
   683                              <1> 	; 26/02/2017 (Unlink IRQ callbacks belong to the user)
   684 0000D4AF 803D[D6030300]00    <1> 	cmp	byte [u.irqc], 0 ; Count of IRQ callbacks
   685 0000D4B6 7E2E                <1> 	jng	short sysexit_16 ; zero or invalid
   686                              <1> 	; 28/02/2017
   687                              <1> 	; clear IRQ callback flags (for 'sysrele' and 'sysret')
   688 0000D4B8 A2[D7030300]        <1> 	mov	[u.irqwait], al ; 0 ; force to clear waiting flag
   689 0000D4BD A2[D8030300]        <1> 	mov	[u.r_lock], al ; 0 ; force to clear busy flag
   690 0000D4C2 BE[0A760100]        <1> 	mov	esi, IRQ.owner
   691                              <1> sysexit_13:	
   692 0000D4C7 AC                  <1> 	lodsb
   693 0000D4C8 3A05[B3030300]      <1> 	cmp	al, [u.uno] ; owner  = current user ?
   694 0000D4CE 750C                <1> 	jne	short sysexit_14
   695 0000D4D0 C646FF00            <1> 	mov	byte [esi-1], 0 ; owner = 0 : Free
   696 0000D4D4 FE0D[D6030300]      <1> 	dec	byte [u.irqc]
   697 0000D4DA 7408                <1> 	jz	short sysexit_15
   698                              <1> sysexit_14:
   699 0000D4DC 81FE[12760100]      <1> 	cmp	esi, IRQ.owner + 8 ; the last IRQ index number ?
   700 0000D4E2 76E3                <1> 	jna	short sysexit_13 ; no
   701                              <1> sysexit_15:
   702 0000D4E4 30C0                <1> 	xor	al, al ; 0
   703                              <1> sysexit_16: ; 2:
   704 0000D4E6 FB                  <1> 	sti	; enable interrupts 
   705                              <1> 	;
   706                              <1> 	; AX = 0
   707                              <1> sysexit_1: ; 1:
   708                              <1> 	; AX = File descriptor
   709                              <1> 		; / r1 has file descriptor (index to u.fp list)
   710                              <1> 		; / Search the whole list
   711 0000D4E7 E87E120000          <1> 	call	fclose
   712                              <1> 		; jsr r0,fclose / close all files the process opened
   713                              <1> 	;; ignore error return
   714                              <1> 		; br .+2 / ignore error return
   715                              <1> 	;inc	ax
   716 0000D4EC FEC0                <1> 	inc	al
   717                              <1> 		; inc r1 / increment file descriptor
   718                              <1> 	;cmp	ax, 10
   719 0000D4EE 3C0A                <1> 	cmp	al, 10
   720                              <1> 		; cmp r1,$10. / end of u.fp list?
   721 0000D4F0 72F5                <1> 	jb	short sysexit_1
   722                              <1> 		; blt 1b / no, go back
   723                              <1> 	;movzx	ebx, byte [u.uno]
   724 0000D4F2 8A1D[B3030300]      <1> 	mov	bl, [u.uno] ; 02/01/2017
   725                              <1> 		; movb	u.uno,r1 / yes, move dying process's number to r1
   726 0000D4F8 88A3[AF000300]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE
   727                              <1> 		; clrb p.stat-1(r1) / free the process
   728                              <1> 	; 10/04/2017
   729 0000D4FE 381D[81760100]      <1> 	cmp	[audio_user], bl
   730 0000D504 7518                <1> 	jne	short sysexit_17
   731                              <1> 	; reset audio device (current) owner and 'initializated' flag
   732 0000D506 883D[81760100]      <1> 	mov	[audio_user], bh ; 0
   733                              <1> 	; 27/05/2017
   734 0000D50C 8B0D[6C760100]      <1> 	mov	ecx,  [audio_buffer]
   735 0000D512 09C9                <1> 	or	ecx, ecx
   736 0000D514 7408                <1> 	jz	short sysexit_17
   737                              <1> 	; 'deallocate_user_pages' is not necessary in sysexit !!!
   738                              <1> 	;push	ebx
   739                              <1> 	;mov	ebx, ecx
   740                              <1> 	;mov	ecx, [audio_buff_size]
   741                              <1> 	;call	deallocate_user_pages
   742                              <1> 	;; (Modified Registers -> EAX, EDX, ESI, EDI, EBX, ECX, EBP)
   743 0000D516 29C9                <1> 	sub	ecx, ecx
   744 0000D518 890D[6C760100]      <1> 	mov	[audio_buffer], ecx ; 0
   745                              <1> 	;pop	ebx
   746                              <1> sysexit_17:
   747                              <1> 	;shl	bx, 1
   748 0000D51E D0E3                <1> 	shl	bl, 1
   749                              <1> 		; asl r1 / use r1 for index into the below tables
   750 0000D520 668B8B[1E000300]    <1> 	mov	cx, [ebx+p.pid-2]
   751                              <1> 		; mov p.pid-2(r1),r3 / move dying process's name to r3
   752 0000D527 668B93[3E000300]    <1> 	mov	dx, [ebx+p.ppid-2]
   753                              <1> 		; mov p.ppid-2(r1),r4 / move its parents name to r4
   754                              <1> 	; xor 	bx, bx ; 0
   755 0000D52E 30DB                <1> 	xor	bl, bl ; 0
   756                              <1> 		; clr r2
   757 0000D530 31F6                <1> 	xor	esi, esi ; 0
   758                              <1> 		; clr r5 / initialize reg
   759                              <1> sysexit_2: ; 1:
   760                              <1> 	        ; / find children of this dying process, 
   761                              <1> 		; / if they are zombies, free them
   762                              <1> 	;add	bx, 2
   763 0000D532 80C302              <1> 	add	bl, 2
   764                              <1> 		; add $2,r2 / search parent process table 
   765                              <1> 		          ; / for dying process's name
   766 0000D535 66398B[3E000300]    <1> 	cmp	[ebx+p.ppid-2], cx
   767                              <1> 		; cmp p.ppid-2(r2),r3 / found it?
   768 0000D53C 7513                <1> 	jne	short sysexit_4
   769                              <1> 		; bne 3f / no
   770                              <1> 	;shr	bx, 1
   771 0000D53E D0EB                <1> 	shr	bl, 1
   772                              <1> 		; asr r2 / yes, it is a parent
   773 0000D540 80BB[AF000300]03    <1> 	cmp	byte [ebx+p.stat-1], 3 ; SZOMB
   774                              <1> 		; cmpb p.stat-1(r2),$3 / is the child of this 
   775                              <1> 				     ; / dying process a zombie
   776 0000D547 7506                <1> 	jne	short sysexit_3 
   777                              <1> 		; bne 2f / no
   778 0000D549 88A3[AF000300]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE
   779                              <1> 		; clrb p.stat-1(r2) / yes, free the child process
   780                              <1> sysexit_3: ; 2:
   781                              <1> 	;shr	bx, 1
   782 0000D54F D0E3                <1> 	shl	bl, 1
   783                              <1> 		; asl r2
   784                              <1> sysexit_4: ; 3:
   785                              <1> 		; / search the process name table 
   786                              <1> 		; / for the dying process's parent
   787 0000D551 663993[1E000300]    <1> 	cmp	[ebx+p.pid-2], dx
   788                              <1> 		; cmp p.pid-2(r2),r4 / found it?
   789 0000D558 7502                <1> 	jne	short sysexit_5
   790                              <1> 		; bne 3f / no
   791 0000D55A 89DE                <1> 	mov	esi, ebx
   792                              <1> 		; mov r2,r5 / yes, put index to p.pid table (parents
   793                              <1> 		          ; / process # x2) in r5
   794                              <1> sysexit_5: ; 3:
   795                              <1> 	;cmp	bx, nproc + nproc
   796 0000D55C 80FB20              <1> 	cmp	bl, nproc + nproc
   797                              <1> 		; cmp r2,$nproc+nproc / has whole table been searched?
   798 0000D55F 72D1                <1> 	jb	short sysexit_2
   799                              <1> 		; blt 1b / no, go back
   800                              <1> 		; mov r5,r1 / yes, r1 now has parents process # x2
   801 0000D561 21F6                <1> 	and	esi, esi ; r5=r1
   802 0000D563 7436                <1> 	jz	short sysexit_6
   803                              <1> 		; beq 2f / no parent has been found. 
   804                              <1> 		       ; / The process just dies
   805 0000D565 66D1EE              <1> 	shr	si, 1
   806                              <1> 		; asr r1 / set up index to p.stat
   807 0000D568 8A86[AF000300]      <1> 	mov	al, [esi+p.stat-1]
   808                              <1> 		; movb p.stat-1(r1),r2 / move status of parent to r2
   809 0000D56E 20C0                <1> 	and	al, al
   810 0000D570 7429                <1> 	jz	short sysexit_6
   811                              <1> 		; beq 2f / if its been freed, 2f
   812 0000D572 3C03                <1> 	cmp	al, 3
   813                              <1> 		; cmp r2,$3 / is parent a zombie?
   814 0000D574 7425                <1> 	je	short sysexit_6
   815                              <1> 		; beq 2f / yes, 2f
   816                              <1> 	; BH = 0
   817 0000D576 8A1D[B3030300]      <1> 	mov	bl, [u.uno]
   818                              <1> 		; movb u.uno,r3 / move dying process's number to r3
   819 0000D57C C683[AF000300]03    <1> 	mov	byte [ebx+p.stat-1], 3  ; SZOMB
   820                              <1> 		; movb $3,p.stat-1(r3) / make the process a zombie
   821 0000D583 3C01                <1> 	cmp	al, 1 ; SRUN
   822 0000D585 7414                <1> 	je	short sysexit_6
   823                              <1> 	;cmp	al, 2
   824                              <1> 		; cmp r2,$2 / is the parent waiting for 
   825                              <1> 			  ; / this child to die
   826                              <1> 	;jne	short sysexit_6	
   827                              <1> 		; bne 2f / yes, notify parent not to wait any more
   828                              <1> 	; p.stat = 2 --> waiting
   829                              <1> 	; p.stat = 4 --> sleeping
   830 0000D587 C686[AF000300]01    <1> 	mov	byte [esi+p.stat-1], 1 ; SRUN
   831                              <1> 	;dec	byte [esi+p.stat-1]
   832                              <1> 		; decb	p.stat-1(r1) / awaken it by putting it (parent)
   833 0000D58E 6689F0              <1> 	mov	ax, si ; r1  (process number in AL)
   834                              <1> 	; 
   835                              <1> 	;mov	ebx, runq + 4
   836                              <1> 		; mov $runq+4,r2 / on the runq
   837 0000D591 BB[54030300]        <1> 	mov	ebx, runq+2 ; normal run queue ; 02/01/2017
   838 0000D596 E81A1C0000          <1> 	call	putlu
   839                              <1> 		; jsr r0, putlu
   840                              <1> sysexit_6: 
   841                              <1> 		; / the process dies
   842 0000D59B C605[B3030300]00    <1> 	mov	byte [u.uno], 0
   843                              <1> 		; clrb u.uno / put zero as the process number, 
   844                              <1> 	           ; / so "swap" will
   845 0000D5A2 E8101B0000          <1> 	call	swap
   846                              <1> 		; jsr r0,swap / overwrite process with another process
   847                              <1> 
   848                              <1> hlt_sys:
   849                              <1> 	;sti
   850                              <1> hlts0:
   851 0000D5A7 F4                  <1> 	hlt
   852 0000D5A8 EBFD                <1> 	jmp	short hlts0
   853                              <1> 		; 0 / and thereby kill it; halt?
   854                              <1> 
   855                              <1> syswait: ; < wait for a processs to die >
   856                              <1> 	; 17/09/2015
   857                              <1> 	; 02/09/2015
   858                              <1> 	; 01/09/2015
   859                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
   860                              <1> 	; 24/05/2013 - 05/02/2014 (Retro UNIX 8086 v1)
   861                              <1> 	;
   862                              <1> 	; 'syswait' waits for a process die. 
   863                              <1> 	; It works in following way:
   864                              <1> 	;    1) From the parent process number, the parent's 
   865                              <1> 	; 	process name is found. The p.ppid table of parent
   866                              <1> 	;	names is then searched for this process name.
   867                              <1> 	;	If a match occurs, r2 contains child's process
   868                              <1> 	;	number. The child status is checked to see if it is
   869                              <1> 	;	a zombie, i.e; dead but not waited for (p.stat=3)
   870                              <1> 	;	If it is, the child process is freed and it's name
   871                              <1> 	;	is put in (u.r0). A return is then made via 'sysret'.
   872                              <1> 	;	If the child is not a zombie, nothing happens and
   873                              <1> 	;	the search goes on through the p.ppid table until
   874                              <1> 	;	all processes are checked or a zombie is found.
   875                              <1> 	;    2) If no zombies are found, a check is made to see if
   876                              <1> 	;	there are any children at all. If there are none,
   877                              <1> 	;	an error return is made. If there are, the parent's
   878                              <1> 	;	status is set to 2 (waiting for child to die),
   879                              <1> 	;	the parent is swapped out, and a branch to 'syswait'
   880                              <1> 	;	is made to wait on the next process.
   881                              <1> 	;
   882                              <1> 	; Calling sequence:
   883                              <1> 	;	?
   884                              <1> 	; Arguments:
   885                              <1> 	;	-
   886                              <1> 	; Inputs: - 
   887                              <1> 	; Outputs: if zombie found, it's name put in u.r0.	
   888                              <1> 	; ...............................................................
   889                              <1> 	;				
   890                              <1> 	
   891                              <1> ; / wait for a process to die
   892                              <1> 
   893                              <1> syswait_0:
   894 0000D5AA 0FB61D[B3030300]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
   895                              <1> 		; movb u.uno,r1 / put parents process number in r1
   896 0000D5B1 D0E3                <1> 	shl	bl, 1
   897                              <1> 	;shl	bx, 1
   898                              <1> 		; asl r1 / x2 to get index into p.pid table
   899 0000D5B3 668B83[1E000300]    <1> 	mov	ax, [ebx+p.pid-2]
   900                              <1> 		; mov p.pid-2(r1),r1 / get the name of this process
   901 0000D5BA 31F6                <1> 	xor	esi, esi
   902                              <1> 		; clr r2
   903 0000D5BC 31C9                <1> 	xor	ecx, ecx ; 30/10/2013
   904                              <1> 	;xor 	cl, cl
   905                              <1> 		; clr r3 / initialize reg 3
   906                              <1> syswait_1: ; 1:
   907 0000D5BE 6683C602            <1> 	add	si, 2
   908                              <1> 		; add $2,r2 / use r2 for index into p.ppid table
   909                              <1> 			  ; / search table of parent processes 
   910                              <1> 			  ; / for this process name
   911 0000D5C2 663B86[3E000300]    <1> 	cmp	ax, [esi+p.ppid-2]
   912                              <1> 		; cmp p.ppid-2(r2),r1 / r2 will contain the childs 
   913                              <1> 			            ; / process number
   914 0000D5C9 7535                <1> 	jne	short syswait_3
   915                              <1> 		;bne 3f / branch if no match of parent process name
   916                              <1> 	;inc	cx
   917 0000D5CB FEC1                <1> 	inc	cl
   918                              <1> 		;inc r3 / yes, a match, r3 indicates number of children
   919 0000D5CD 66D1EE              <1> 	shr	si, 1
   920                              <1> 		; asr r2 / r2/2 to get index to p.stat table
   921                              <1> 	; The possible states ('p.stat' values) of a process are:
   922                              <1> 	;	0 = free or unused
   923                              <1> 	;	1 = active
   924                              <1> 	;	2 = waiting for a child process to die
   925                              <1> 	;	3 = terminated, but not yet waited for (zombie).	
   926 0000D5D0 80BE[AF000300]03    <1> 	cmp	byte [esi+p.stat-1], 3 ; SZOMB, 05/02/2014
   927                              <1> 		; cmpb p.stat-1(r2),$3 / is the child process a zombie?
   928 0000D5D7 7524                <1> 	jne	short syswait_2
   929                              <1> 		; bne 2f / no, skip it
   930 0000D5D9 88BE[AF000300]      <1> 	mov	[esi+p.stat-1], bh ; 0
   931                              <1> 		; clrb p.stat-1(r2) / yes, free it
   932 0000D5DF 66D1E6              <1> 	shl	si, 1
   933                              <1> 		; asl r2 / r2x2 to get index into p.pid table
   934 0000D5E2 0FB786[1E000300]    <1> 	movzx	eax, word [esi+p.pid-2]
   935 0000D5E9 A3[64030300]        <1> 	mov	[u.r0], eax
   936                              <1> 		; mov p.pid-2(r2),*u.r0 
   937                              <1> 			      ; / put childs process name in (u.r0)
   938                              <1> 	;
   939                              <1> 	; Retro UNIX 386 v1 modification ! (17/09/2015)
   940                              <1> 	;
   941                              <1> 	; Parent process ID -p.ppid- field (of the child process)
   942                              <1> 	; must be cleared in order to prevent infinitive 'syswait'
   943                              <1> 	; system call loop from the application/program if it calls
   944                              <1> 	; 'syswait' again (mistakenly) while there is not a zombie
   945                              <1> 	; or running child process to wait. ('forktest.s', 17/09/2015)
   946                              <1> 	;
   947                              <1> 	; Note: syswait will return with error if there is not a
   948                              <1> 	;       zombie or running process to wait.	
   949                              <1> 	;
   950 0000D5EE 6629C0              <1> 	sub	ax, ax
   951 0000D5F1 668986[3E000300]    <1> 	mov 	[esi+p.ppid-2], ax ; 0 ; 17/09/2015
   952 0000D5F8 E9D1FCFFFF          <1> 	jmp	sysret0 ; ax = 0
   953                              <1> 	;
   954                              <1> 	;jmp	sysret
   955                              <1> 		; br sysret1 / return cause child is dead
   956                              <1> syswait_2: ; 2:
   957 0000D5FD 66D1E6              <1> 	shl	si, 1
   958                              <1> 		; asl r2 / r2x2 to get index into p.ppid table
   959                              <1> syswait_3: ; 3:
   960 0000D600 6683FE20            <1> 	cmp	si, nproc+nproc
   961                              <1> 		; cmp r2,$nproc+nproc / have all processes been checked?
   962 0000D604 72B8                <1> 	jb	short syswait_1
   963                              <1> 		; blt 1b / no, continue search
   964                              <1> 	;and	cx, cx
   965 0000D606 20C9                <1> 	and	cl, cl
   966                              <1> 		; tst r3 / one gets here if there are no children 
   967                              <1> 		       ; / or children that are still active
   968                              <1> 	; 30/10/2013
   969 0000D608 750B                <1> 	jnz	short syswait_4
   970                              <1> 	;jz	error
   971                              <1> 		; beq error1 / there are no children, error
   972 0000D60A 890D[64030300]      <1> 	mov	[u.r0], ecx ; 0
   973 0000D610 E997FCFFFF          <1> 	jmp	error
   974                              <1> syswait_4:
   975 0000D615 8A1D[B3030300]      <1> 	mov	bl, [u.uno]
   976                              <1> 		; movb u.uno,r1 / there are children so put 
   977                              <1> 			      ; / parent process number in r1
   978 0000D61B FE83[AF000300]      <1> 	inc	byte [ebx+p.stat-1] ; 2, SWAIT, 05/02/2014
   979                              <1> 		; incb p.stat-1(r1) / it is waiting for 
   980                              <1> 				  ; / other children to die
   981                              <1> 	; 04/11/2013
   982 0000D621 E8911A0000          <1> 	call	swap
   983                              <1> 		; jsr r0,swap / swap it out, because it's waiting
   984 0000D626 EB82                <1> 	jmp	syswait_0
   985                              <1> 		; br syswait / wait on next process
   986                              <1> 
   987                              <1> sysfork: ; < create a new process >
   988                              <1> 	; 02/01/2017 (TRDOS 386 modification)
   989                              <1> 	; 04/09/2015, 18/05/2015
   990                              <1> 	; 28/08/2015, 01/09/2015, 02/09/2015
   991                              <1> 	; 09/05/2015, 10/05/2015, 14/05/2015
   992                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 - Beginning)
   993                              <1> 	; 24/05/2013 - 14/02/2014 (Retro UNIX 8086 v1)
   994                              <1> 	;
   995                              <1> 	; 'sysfork' creates a new process. This process is referred
   996                              <1> 	; to as the child process. This new process core image is
   997                              <1> 	; a copy of that of the caller of 'sysfork'. The only
   998                              <1> 	; distinction is the return location and the fact that (u.r0)
   999                              <1> 	; in the old process (parent) contains the process id (p.pid)
  1000                              <1> 	; of the new process (child). This id is used by 'syswait'.
  1001                              <1> 	; 'sysfork' works in the following manner: 	
  1002                              <1> 	;    1) The process status table (p.stat) is searched to find
  1003                              <1> 	;	a process number that is unused. If none are found
  1004                              <1> 	;	an error occurs.
  1005                              <1> 	;    2) when one is found, it becomes the child process number
  1006                              <1> 	;	and it's status (p.stat) is set to active.
  1007                              <1> 	;    3) If the parent had a control tty, the interrupt 
  1008                              <1> 	;	character in that tty buffer is cleared.
  1009                              <1> 	;    4) The child process is put on the lowest priority run 
  1010                              <1> 	;	queue via 'putlu'.
  1011                              <1> 	;    5) A new process name is gotten from 'mpid' (actually 
  1012                              <1> 	;	it is a unique number) and is put in the child's unique
  1013                              <1> 	;	identifier; process id (p.pid).
  1014                              <1> 	;    6) The process name of the parent is then obtained and
  1015                              <1> 	;	placed in the unique identifier of the parent process
  1016                              <1> 	;	name is then put in 'u.r0'.	
  1017                              <1> 	;    7) The child process is then written out on disk by
  1018                              <1> 	;	'wswap',i.e., the parent process is copied onto disk
  1019                              <1> 	;	and the child is born. (The child process is written 
  1020                              <1> 	;	out on disk/drum with 'u.uno' being the child process
  1021                              <1> 	;	number.)
  1022                              <1> 	;    8) The parent process number is then restored to 'u.uno'.
  1023                              <1> 	;    9) The child process name is put in 'u.r0'.
  1024                              <1> 	;   10) The pc on the stack sp + 18 is incremented by 2 to
  1025                              <1> 	;	create the return address for the parent process.
  1026                              <1> 	;   11) The 'u.fp' list as then searched to see what files
  1027                              <1> 	;	the parent has opened. For each file the parent has
  1028                              <1> 	;	opened, the corresponding 'fsp' entry must be updated
  1029                              <1> 	;	to indicate that the child process also has opened
  1030                              <1> 	;	the file. A branch to 'sysret' is then made.	 			 				
  1031                              <1> 	;
  1032                              <1> 	; Calling sequence:
  1033                              <1> 	;	from shell ?
  1034                              <1> 	; Arguments:
  1035                              <1> 	;	-
  1036                              <1> 	; Inputs: -
  1037                              <1> 	; Outputs: *u.r0 - child process name
  1038                              <1> 	; ...............................................................
  1039                              <1> 	;	
  1040                              <1> 	; Retro UNIX 8086 v1 modification: 
  1041                              <1> 	;	AX = r0 = PID (>0) (at the return of 'sysfork')
  1042                              <1> 	;	= process id of child a parent process returns
  1043                              <1> 	;	= process id of parent when a child process returns
  1044                              <1> 	;
  1045                              <1> 	;       In original UNIX v1, sysfork is called and returns as
  1046                              <1> 	;	in following manner: (with an example: c library, fork)
  1047                              <1> 	;	
  1048                              <1> 	;	1:
  1049                              <1> 	;		sys	fork
  1050                              <1> 	;			br 1f  / child process returns here
  1051                              <1> 	;		bes	2f     / parent process returns here
  1052                              <1> 	;		/ pid of new process in r0
  1053                              <1> 	;		rts	pc
  1054                              <1> 	;	2: / parent process condionally branches here
  1055                              <1> 	;		mov	$-1,r0 / pid = -1 means error return
  1056                              <1> 	;		rts	pc
  1057                              <1> 	;
  1058                              <1> 	;	1: / child process brances here
  1059                              <1> 	;		clr	r0   / pid = 0 in child process
  1060                              <1> 	;		rts	pc
  1061                              <1> 	;
  1062                              <1> 	;	In UNIX v7x86 (386) by Robert Nordier (1999)
  1063                              <1> 	;		// pid = fork();
  1064                              <1> 	;		//
  1065                              <1> 	;		// pid == 0 in child process; 
  1066                              <1> 	;		// pid == -1 means error return
  1067                              <1> 	;		// in child, 
  1068                              <1> 	;		//	parents id is in par_uid if needed
  1069                              <1> 	;		
  1070                              <1> 	;		_fork:
  1071                              <1> 	;			mov	$.fork,eax
  1072                              <1> 	;			int	$0x30
  1073                              <1> 	;			jmp	1f
  1074                              <1> 	;			jnc	2f
  1075                              <1> 	;			jmp	cerror
  1076                              <1> 	;		1:
  1077                              <1> 	;			mov	eax,_par_uid
  1078                              <1> 	;			xor	eax,eax
  1079                              <1> 	;		2:
  1080                              <1> 	;			ret
  1081                              <1> 	;
  1082                              <1> 	;	In Retro UNIX 8086 v1,
  1083                              <1> 	;	'sysfork' returns in following manner:
  1084                              <1> 	;	
  1085                              <1> 	;		mov	ax, sys_fork
  1086                              <1> 	;		mov	bx, offset @f ; routine for child
  1087                              <1> 	;		int	20h
  1088                              <1> 	;		jc	error
  1089                              <1> 	;		
  1090                              <1> 	;	; Routine for parent process here (just after 'jc')
  1091                              <1> 	;		mov	word ptr [pid_of_child], ax
  1092                              <1> 	;		jmp	next_routine_for_parent	
  1093                              <1> 	;
  1094                              <1> 	;	@@: ; routine for child process here				
  1095                              <1> 	;		....	
  1096                              <1> 	;	NOTE: 'sysfork' returns to specified offset
  1097                              <1> 	;	       for child process by using BX input.
  1098                              <1> 	;	      (at first, parent process will return then 
  1099                              <1> 	;	      child process will return -after swapped in-
  1100                              <1> 	;	      'syswait' is needed in parent process
  1101                              <1> 	;	      if return from child process will be waited for.)
  1102                              <1> 	;	  				
  1103                              <1> 	
  1104                              <1> ; / create a new process
  1105                              <1> 	; EBX = return address for child process 
  1106                              <1> 	     ; (Retro UNIX 8086 v1 modification !)
  1107 0000D628 31F6                <1> 	xor 	esi, esi
  1108                              <1> 		; clr r1
  1109                              <1> sysfork_1: ; 1: / search p.stat table for unused process number
  1110 0000D62A 46                  <1> 	inc	esi
  1111                              <1> 		; inc r1
  1112 0000D62B 80BE[AF000300]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE, 05/02/2014
  1113                              <1> 		; tstb p.stat-1(r1) / is process active, unused, dead
  1114 0000D632 760B                <1> 	jna	short sysfork_2	
  1115                              <1> 		; beq 1f / it's unused so branch
  1116 0000D634 6683FE10            <1> 	cmp	si, nproc
  1117                              <1> 		; cmp r1,$nproc / all processes checked
  1118 0000D638 72F0                <1> 	jb	short sysfork_1
  1119                              <1> 		; blt 1b / no, branch back
  1120                              <1> 	;
  1121                              <1> 	; Retro UNIX 8086 v1. modification:
  1122                              <1> 	;	Parent process returns from 'sysfork' to address 
  1123                              <1> 	;	which is just after 'sysfork' system call in parent
  1124                              <1> 	;	process. Child process returns to address which is put
  1125                              <1> 	;	in BX register by parent process for 'sysfork'. 
  1126                              <1> 	;
  1127                              <1> 		;add $2,18.(sp) / add 2 to pc when trap occured, points
  1128                              <1> 		             ; / to old process return
  1129                              <1> 		; br error1 / no room for a new process
  1130 0000D63A E96DFCFFFF          <1> 	jmp	error
  1131                              <1> sysfork_2: ; 1:
  1132 0000D63F E8617FFFFF          <1> 	call	allocate_page
  1133 0000D644 0F8262FCFFFF        <1> 	jc	error
  1134 0000D64A 50                  <1> 	push	eax   ; UPAGE (user structure page) address
  1135                              <1> 	; Retro UNIX 386 v1 modification!
  1136 0000D64B E86481FFFF          <1> 	call	duplicate_page_dir
  1137                              <1> 		; EAX = New page directory 
  1138 0000D650 730B                <1> 	jnc	short sysfork_3
  1139 0000D652 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
  1140 0000D653 E82B81FFFF          <1> 	call 	deallocate_page
  1141 0000D658 E94FFCFFFF          <1> 	jmp	error
  1142                              <1> sysfork_3:
  1143                              <1> 	; Retro UNIX 386 v1 modification !
  1144 0000D65D 56                  <1> 	push	esi
  1145 0000D65E E8E21A0000          <1> 	call	wswap ; save current user (u) structure, user registers
  1146                              <1> 		      ; and interrupt return components (for IRET)
  1147 0000D663 8705[B8030300]      <1> 	xchg	eax, [u.pgdir] ; page directory of the child process
  1148 0000D669 A3[BC030300]        <1> 	mov	[u.ppgdir], eax ; page directory of the parent process
  1149 0000D66E 5E                  <1> 	pop	esi
  1150 0000D66F 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
  1151                              <1> 		; [u.usp] = esp
  1152 0000D670 89F7                <1> 	mov	edi, esi
  1153 0000D672 66C1E702            <1> 	shl	di, 2
  1154 0000D676 8987[BC000300]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
  1155 0000D67C A3[B4030300]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
  1156                              <1> 	; 28/08/2015
  1157 0000D681 0FB605[B3030300]    <1> 	movzx	eax, byte [u.uno] ; parent process number
  1158                              <1> 		; movb u.uno,-(sp) / save parent process number
  1159 0000D688 89C7                <1> 	mov	edi, eax
  1160 0000D68A 50                  <1>         push	eax ; ** 
  1161 0000D68B 8A87[7F000300]      <1> 	mov     al, [edi+p.ttyc-1] ; console tty (parent)
  1162                              <1> 	; 18/09/2015
  1163                              <1> 	;mov     [esi+p.ttyc-1], al ; set child's console tty
  1164                              <1> 	;mov     [esi+p.waitc-1], ah ; 0 ; reset child's wait channel
  1165 0000D691 668986[7F000300]    <1> 	mov     [esi+p.ttyc-1], ax ; al - set child's console tty
  1166                              <1> 				   ; ah - reset child's wait channel	
  1167 0000D698 89F0                <1> 	mov	eax, esi
  1168 0000D69A A2[B3030300]        <1> 	mov	[u.uno], al ; child process number
  1169                              <1> 		;movb r1,u.uno / set child process number to r1
  1170 0000D69F FE86[AF000300]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN, 05/02/2014
  1171                              <1> 		; incb p.stat-1(r1) / set p.stat entry for child 
  1172                              <1> 				; / process to active status
  1173                              <1> 		; mov u.ttyp,r2 / put pointer to parent process' 
  1174                              <1> 			      ; / control tty buffer in r2
  1175                              <1>                 ; beq 2f / branch, if no such tty assigned
  1176                              <1> 		; clrb 6(r2) / clear interrupt character in tty buffer
  1177                              <1> 	; 2:
  1178 0000D6A5 53                  <1> 	push	ebx  ; * return address for the child process
  1179                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
  1180                              <1> 	; (Retro UNIX 8086 v1 modification!)
  1181                              <1> 		; mov $runq+4,r2
  1182 0000D6A6 BB[54030300]        <1> 	mov	ebx, runq+2 ; normal run queue ; 02/01/2017  
  1183 0000D6AB E8051B0000          <1> 	call	putlu
  1184                              <1>  		; jsr r0,putlu / put child process on lowest priority 
  1185                              <1> 			   ; / run queue
  1186 0000D6B0 66D1E6              <1> 	shl	si, 1
  1187                              <1> 		; asl r1 / multiply r1 by 2 to get index 
  1188                              <1> 		       ; / into p.pid table
  1189 0000D6B3 66FF05[4E030300]    <1> 	inc	word [mpid]
  1190                              <1> 		; inc mpid / increment m.pid; get a new process name
  1191 0000D6BA 66A1[4E030300]      <1> 	mov	ax, [mpid]
  1192 0000D6C0 668986[1E000300]    <1> 	mov	[esi+p.pid-2], ax
  1193                              <1> 		;mov mpid,p.pid-2(r1) / put new process name 
  1194                              <1> 				    ; / in child process' name slot
  1195 0000D6C7 5A                  <1> 	pop	edx  ; * return address for the child process
  1196                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
  1197 0000D6C8 5B                  <1>   	pop	ebx  ; **
  1198                              <1> 	;mov	ebx, [esp] ; ** parent process number
  1199                              <1> 		; movb (sp),r2 / put parent process number in r2
  1200 0000D6C9 66D1E3              <1> 	shl 	bx, 1
  1201                              <1> 		;asl r2 / multiply by 2 to get index into below tables
  1202                              <1> 	;movzx eax, word [ebx+p.pid-2]
  1203 0000D6CC 668B83[1E000300]    <1> 	mov	ax, [ebx+p.pid-2]
  1204                              <1> 		; mov p.pid-2(r2),r2 / get process name of parent
  1205                              <1> 				   ; / process
  1206 0000D6D3 668986[3E000300]    <1> 	mov	[esi+p.ppid-2], ax
  1207                              <1> 		; mov r2,p.ppid-2(r1) / put parent process name 
  1208                              <1> 			  ; / in parent process slot for child
  1209 0000D6DA A3[64030300]        <1> 	mov	[u.r0], eax	
  1210                              <1> 		; mov r2,*u.r0 / put parent process name on stack 
  1211                              <1> 			     ; / at location where r0 was saved
  1212 0000D6DF 8B2D[5C030300]      <1> 	mov 	ebp, [u.sp] ; points to return address (EIP for IRET)
  1213 0000D6E5 895500              <1> 	mov	[ebp], edx ; *, CS:EIP -> EIP
  1214                              <1> 			   ; * return address for the child process
  1215                              <1> 		; mov $sysret1,-(sp) /
  1216                              <1> 		; mov sp,u.usp / contents of sp at the time when 
  1217                              <1> 			      ; / user is swapped out
  1218                              <1> 		; mov $sstack,sp / point sp to swapping stack space
  1219                              <1> 	; 04/09/2015 - 01/09/2015
  1220                              <1> 	; [u.usp] = esp
  1221 0000D6E8 68[CCD20000]        <1> 	push	sysret ; ***
  1222 0000D6ED 8925[60030300]      <1> 	mov	[u.usp], esp ; points to 'sysret' address (***)
  1223                              <1> 			     ; (for child process)	
  1224 0000D6F3 31C0                <1> 	xor 	eax, eax
  1225 0000D6F5 66A3[94030300]      <1> 	mov 	[u.ttyp], ax ; 0
  1226                              <1> 	;
  1227 0000D6FB E8451A0000          <1> 	call	wswap ; Retro UNIX 8086 v1 modification !
  1228                              <1> 		;jsr r0,wswap / put child process out on drum
  1229                              <1> 		;jsr r0,unpack / unpack user stack
  1230                              <1> 		;mov u.usp,sp / restore user stack pointer
  1231                              <1> 		; tst (sp)+ / bump stack pointer
  1232                              <1> 	; Retro UNIX 386 v1 modification !
  1233 0000D700 58                  <1> 	pop	eax ; ***
  1234 0000D701 66D1E3              <1> 	shl	bx, 1
  1235 0000D704 8B83[BC000300]      <1> 	mov     eax, [ebx+p.upage-4] ; UPAGE address ; 14/05/2015
  1236 0000D70A E86E1A0000          <1> 	call	rswap ; restore parent process 'u' structure, 
  1237                              <1> 		      ; registers and return address (for IRET)
  1238                              <1> 		;movb (sp)+,u.uno / put parent process number in u.uno
  1239 0000D70F 0FB705[4E030300]    <1>         movzx   eax, word [mpid]
  1240 0000D716 A3[64030300]        <1> 	mov	[u.r0], eax
  1241                              <1> 		; mov mpid,*u.r0 / put child process name on stack 
  1242                              <1> 			       ; / where r0 was saved
  1243                              <1> 		; add $2,18.(sp) / add 2 to pc on stack; gives parent
  1244                              <1> 			          ; / process return
  1245                              <1> 	;xor	ebx, ebx
  1246 0000D71B 31F6                <1> 	xor     esi, esi
  1247                              <1> 		;clr r1
  1248                              <1> sysfork_4: ; 1: / search u.fp list to find the files 
  1249                              <1> 	      ; / opened by the parent process
  1250                              <1> 	; 01/09/2015
  1251                              <1> 	;xor	bh, bh
  1252                              <1> 	;mov 	bl, [esi+u.fp]
  1253 0000D71D 8A86[6A030300]      <1> 	mov 	al, [esi+u.fp]
  1254                              <1> 		; movb u.fp(r1),r2 / get an open file for this process
  1255                              <1>         ;or      bl, bl
  1256 0000D723 08C0                <1> 	or	al, al
  1257 0000D725 740D                <1> 	jz	short sysfork_5	
  1258                              <1> 		; beq 2f / file has not been opened by parent, 
  1259                              <1> 		       ; / so branch
  1260 0000D727 B40A                <1> 	mov	ah, 10 ; Retro UNIX 386 v1 fsp structure size = 10 bytes
  1261 0000D729 F6E4                <1> 	mul	ah
  1262                              <1> 	;movzx	ebx, ax
  1263 0000D72B 6689C3              <1> 	mov	bx, ax
  1264                              <1> 	;shl     bx, 3
  1265                              <1> 		; asl r2 / multiply by 8
  1266                              <1>        		; asl r2 / to get index into fsp table
  1267                              <1>        		; asl r2
  1268 0000D72E FE83[4E010300]      <1>   	inc     byte [ebx+fsp-2]
  1269                              <1> 		; incb fsp-2(r2) / increment number of processes
  1270                              <1> 			     ; / using file, because child will now be
  1271                              <1> 			     ; / using this file
  1272                              <1> sysfork_5: ; 2:
  1273 0000D734 46                  <1>         inc     esi
  1274                              <1> 		; inc r1 / get next open file
  1275 0000D735 6683FE0A            <1>         cmp     si, 10
  1276                              <1> 		; cmp r1,$10. / 10. files is the maximum number which
  1277                              <1> 			  ; / can be opened
  1278 0000D739 72E2                <1> 	jb	short sysfork_4	
  1279                              <1> 		; blt 1b / check next entry
  1280 0000D73B E98CFBFFFF          <1> 	jmp	sysret
  1281                              <1> 		; br sysret1
  1282                              <1> 
  1283                              <1> syscreat: ; < create file >
  1284                              <1> 	; 13/11/2017
  1285                              <1> 	; 27/10/2016
  1286                              <1> 	; 25/10/2016, 26/10/2016
  1287                              <1> 	; 15/10/2016, 16/10/2016, 17/10/2016
  1288                              <1> 	; 10/10/2016 (TRDOS 386 = TRDOS v2.0) 
  1289                              <1> 	;	     -derived from INT_21H.ASM-
  1290                              <1> 	;            ("loc_INT21h_create_file")
  1291                              <1>         ; 	10/07/2011 (12/03/2011)
  1292                              <1>         ;	INT 21h Function AH = 3Ch
  1293                              <1>         ;	Create File
  1294                              <1>         ;	INPUT
  1295                              <1>         ;	   CX = Attributes
  1296                              <1>         ;          DS:DX= Address of zero terminaned path name
  1297                              <1>         ;
  1298                              <1> 	; 27/12/2015 (Retro UNIX 386 v1.1)
  1299                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1300                              <1> 	; 27/05/2013 (Retro UNIX 8086 v1)
  1301                              <1> 	;
  1302                              <1> 	; 'syscreat' called with two arguments; name and mode.
  1303                              <1> 	; u.namep points to name of the file and mode is put
  1304                              <1> 	; on the stack. 'namei' is called to get i-number of the file.		
  1305                              <1> 	; If the file aready exists, it's mode and owner remain 
  1306                              <1> 	; unchanged, but it is truncated to zero length. If the file
  1307                              <1> 	; did not exist, an i-node is created with the new mode via
  1308                              <1> 	; 'maknod' whether or not the file already existed, it is
  1309                              <1> 	; open for writing. The fsp table is then searched for a free
  1310                              <1> 	; entry. When a free entry is found, proper data is placed
  1311                              <1> 	; in it and the number of this entry is put in the u.fp list.
  1312                              <1> 	; The index to the u.fp (also know as the file descriptor)
  1313                              <1> 	; is put in the user's r0. 			
  1314                              <1> 	;
  1315                              <1> 	; Calling sequence:
  1316                              <1> 	;	syscreate; name; mode
  1317                              <1> 	; Arguments:
  1318                              <1> 	;	name - name of the file to be created
  1319                              <1> 	;	mode - mode of the file to be created
  1320                              <1> 	; Inputs: (arguments)
  1321                              <1> 	; Outputs: *u.r0 - index to u.fp list 
  1322                              <1> 	;		   (the file descriptor of new file)
  1323                              <1> 	; ...............................................................
  1324                              <1> 	;				
  1325                              <1> 	; Retro UNIX 8086 v1 modification: 
  1326                              <1> 	;       'syscreate' system call has two arguments; so,
  1327                              <1> 	;	* 1st argument, name is pointed to by BX register
  1328                              <1> 	;	* 2nd argument, mode is in CX register
  1329                              <1> 	;
  1330                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1331                              <1> 	;	to the user with the file descriptor/number 
  1332                              <1> 	;	(index to u.fp list).
  1333                              <1> 	;
  1334                              <1> 	;call	arg2
  1335                              <1> 	; * name - 'u.namep' points to address of file/path name
  1336                              <1> 	;          in the user's program segment ('u.segmnt')
  1337                              <1> 	;          with offset in BX register (as sysopen argument 1).
  1338                              <1> 	; * mode - sysopen argument 2 is in CX register 
  1339                              <1> 	;          which is on top of stack.
  1340                              <1> 	;
  1341                              <1> 	; TRDOS 386 (10/10/2016)
  1342                              <1> 	;	
  1343                              <1>         ; INPUT ->
  1344                              <1>         ;	   CL = File Attributes
  1345                              <1> 	;     	      bit 0 (1) - Read only file (R)
  1346                              <1> 	;             bit 1 (1) - Hidden file (H)
  1347                              <1>         ;             bit 2 (1) - System file (R)
  1348                              <1> 	;             bit 3 (1) - Volume label/name (V)
  1349                              <1>         ;             bit 4 (1) - Subdirectory (D)
  1350                              <1> 	;	      bit 5 (1) - File has been archived (A)	 	
  1351                              <1>         ;          EBX = Pointer to filename (ASCIIZ) -path-
  1352                              <1> 	;	
  1353                              <1> 	; OUTPUT ->
  1354                              <1> 	;          eax = File/Device Handle/Number (index) (AL)
  1355                              <1> 	;          cf = 1 -> Error code in AL
  1356                              <1> 	;
  1357                              <1> 	; Modified Registers: EAX (at the return of system call)
  1358                              <1> 	;  
  1359                              <1> 	; Note: If the file is existing and it has not any one
  1360                              <1> 	;	of S,H,R,V,D attributes, it will be truncated 
  1361                              <1> 	;	to zero length; otherwise, access error will be 
  1362                              <1> 	;	returned. 
  1363                              <1> 
  1364                              <1> sysmkdir_0:
  1365 0000D740 F6C108              <1> 	test	cl, 08h ; Volume name 
  1366 0000D743 740A                <1> 	jz	short syscreat_0
  1367                              <1> 
  1368                              <1> 	; Volume name or long name creation
  1369                              <1> 	; is not permitted (in TRDOS 386)!
  1370 0000D745 B80B000000          <1> 	mov	eax, ERR_FILE_ACCESS  ; 11 ; 'permission denied !'
  1371 0000D74A E926020000          <1>         jmp	sysopen_dev_err
  1372                              <1> 
  1373                              <1> syscreat_0:
  1374                              <1>         ;mov	[u.namep], ebx
  1375 0000D74F 51                  <1> 	push	ecx
  1376 0000D750 89DE                <1> 	mov	esi, ebx
  1377                              <1> 	; file name is forced, change directory as temporary
  1378                              <1> 	;mov	ax, 1
  1379                              <1> 	;mov	[FFF_Valid], ah ; 0 ; reset ; 17/10/2016
  1380                              <1> 	;call	set_working_path 
  1381 0000D752 E8BC2F0000          <1> 	call	set_working_path_x ; 17/10/2016	
  1382 0000D757 0F82D7000000        <1> 	jc	syscreat_err
  1383                              <1> 
  1384                              <1> 	; 16/10/2016
  1385 0000D75D 803D[8F700100]00    <1> 	cmp	byte [SWP_inv_fname], 0
  1386 0000D764 776C                <1> 	ja	short  syscreat_inv_fname ; invalid file name !
  1387                              <1> 
  1388                              <1> 	; Here, we have a valid path and also a valid file name
  1389                              <1> 	; (Working dir has been changed if the path
  1390                              <1> 	;  -file name string- had contained a dir name.)
  1391                              <1> 
  1392 0000D766 6631C0              <1> 	xor	ax, ax 
  1393                              <1> 	;mov	esi, FindFile_Name
  1394 0000D769 E8E3B6FFFF          <1> 	call	find_first_file
  1395 0000D76E 59                  <1> 	pop	ecx
  1396                              <1> 		; ESI = Directory Entry (FindFile_DirEntry) Location
  1397                              <1> 		; EDI = Directory Buffer Directory Entry Location
  1398                              <1> 		; EAX = File Size
  1399                              <1> 		;  BL = Attributes of The File/Directory
  1400                              <1> 		;  BH = Long Name Yes/No Status (>0 is YES)
  1401                              <1> 		;  DX > 0 : Ambiguous filename chars are used
  1402 0000D76F 7269                <1> 	jc	short syscreat_1 ; file not found (the good!) 
  1403                              <1> 				 ; or another error (the bad') 
  1404                              <1> 
  1405                              <1> 	; (& the uggly!) truncate file to zero length before open
  1406                              <1> 
  1407                              <1> 	;'*' and '?' already checked at 'set_working_path' stage
  1408                              <1> 	;and	dx, dx
  1409                              <1> 	;jnz	short sysmkdir_err ; permission denied 
  1410                              <1> 				   ; invalid filename chars
  1411                              <1> 
  1412                              <1> 	;test	cl, 10h ; subdirectory ?
  1413                              <1> 	;jnz	short sysmkdir_err	
  1414                              <1> 
  1415                              <1> 	; BL = File Attributes:	
  1416                              <1> 	;     	      bit 0 (1) - Read only file (R)
  1417                              <1> 	;             bit 1 (1) - Hidden file (H)
  1418                              <1>         ;             bit 2 (1) - System file (R)
  1419                              <1> 	;             bit 3 (1) - Volume label/name (V)
  1420                              <1>         ;             bit 4 (1) - Subdirectory (D)
  1421                              <1> 	;	      bit 5 (1) - File has been archived	 	
  1422                              <1> 
  1423                              <1> 	; * existing directory must not be truncated
  1424                              <1> 	;   (we don't know it is empty or not, at this stage) 
  1425                              <1> 	; * existing volume name (or a long name) can not be
  1426                              <1> 	;   re-created or truncated by 'syscreat' 	
  1427                              <1> 	; * A file with S, H, R attributes must not be truncated
  1428                              <1> 	;   (change attributes to normal, if you need truncate it)
  1429                              <1> 
  1430 0000D771 F6C31F              <1> 	test	bl, 00011111b  ; check attributes of existing file
  1431 0000D774 754E                <1> 	jnz	short sysmkdir_err
  1432                              <1> 
  1433                              <1> 	;; normal file, OK to continue...
  1434                              <1> 
  1435                              <1> 	; ESI = FindFile_DirEntry
  1436 0000D776 668B4614            <1> 	mov	ax, [esi+DirEntry_FstClusHI] ; 20
  1437 0000D77A C1E010              <1> 	shl	eax, 16 ; 13/11/2017
  1438 0000D77D 668B461A            <1> 	mov	ax, [esi+DirEntry_FstClusLO] ; 26 
  1439                              <1> 	; EAX = First cluster to be truncated/unlinked
  1440 0000D781 57                  <1> 	push	edi
  1441 0000D782 51                  <1> 	push	ecx
  1442 0000D783 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1443 0000D788 29C9                <1> 	sub	ecx, ecx
  1444 0000D78A 8A2D[9E640100]      <1> 	mov	ch, [Current_Drv]
  1445 0000D790 01CE                <1> 	add	esi, ecx
  1446                              <1> 	; ESI = Logical dos drive description table address
  1447 0000D792 E8C9F7FFFF          <1> 	call	truncate_cluster_chain
  1448 0000D797 59                  <1> 	pop	ecx
  1449 0000D798 5F                  <1> 	pop	edi
  1450 0000D799 7230                <1> 	jc	short syscreate_truncate_err
  1451                              <1> 
  1452                              <1> 	; 26/10/2016
  1453                              <1> 	; EDI = Directory entry address in directory buffer
  1454                              <1> 	; Update directory entry
  1455 0000D79B E848DCFFFF          <1> 	call	convert_current_date_time
  1456                              <1> 	; OUTPUT -> DX = Date in dos dir entry format
  1457                              <1>         ; 	    AX = Time in dos dir entry format	
  1458 0000D7A0 66894716            <1> 	mov	[edi+DirEntry_WrtTime], ax
  1459 0000D7A4 66895718            <1> 	mov	[edi+DirEntry_WrtDate], dx	
  1460 0000D7A8 66895712            <1> 	mov	[edi+DirEntry_LastAccDate], dx
  1461 0000D7AC 31C0                <1> 	xor	eax, eax ; file size = 0 
  1462 0000D7AE 89471C              <1> 	mov	[edi+DirEntry_FileSize], eax ; 0
  1463 0000D7B1 C605[C46B0100]02    <1> 	mov	byte [DirBuff_ValidData], 2 ; data changed sign	
  1464 0000D7B8 BE[906D0100]        <1> 	mov	esi, FindFile_DirEntry
  1465 0000D7BD B201                <1> 	mov	dl, 1 ; open file for writing
  1466 0000D7BF E9AA000000          <1> 	jmp	sysopen_2
  1467                              <1> 
  1468                              <1> sysmkdir_err:
  1469                              <1> 	; 1 = write, 2 = read & write, >2 = invalid
  1470 0000D7C4 B80B000000          <1>         mov	eax, ERR_FILE_ACCESS  ; 11 ; 'permission denied !'
  1471 0000D7C9 EB73                <1>         jmp	short sysopen_err
  1472                              <1> 
  1473                              <1> syscreate_truncate_err:
  1474 0000D7CB B812000000          <1> 	mov	eax, ERR_DRV_WRITE ; 18 ; 'disk write error !'
  1475 0000D7D0 EB6C                <1>         jmp	short sysopen_err
  1476                              <1> 
  1477                              <1> syscreat_inv_fname:  ; invalid file name chars 
  1478                              <1> 	; 16/10/2016
  1479 0000D7D2 B81A000000          <1> 	mov	eax, ERR_INV_FILE_NAME  ; 26 ; invalid file name chars 
  1480 0000D7D7 59                  <1> 	pop	ecx
  1481 0000D7D8 EB64                <1> 	jmp	sysopen_err
  1482                              <1> 
  1483                              <1> syscreat_1:
  1484                              <1> 	; Error code in EAX
  1485 0000D7DA 3C02                <1>         cmp	al, 02h ; 'File not found' error
  1486 0000D7DC 7560                <1>         jne	sysopen_err
  1487                              <1> 
  1488 0000D7DE F6C110              <1> 	test	cl, 10h ; Directory
  1489 0000D7E1 0F852C020000        <1> 	jnz	sysmkdir_2
  1490                              <1> 
  1491                              <1> syscreat_2:
  1492 0000D7E7 BE[806D0100]        <1> 	mov	esi, FindFile_Name 
  1493                              <1>         ;xor	edx, edx
  1494 0000D7EC 31C0                <1>         xor	eax, eax ; File Size  = 0
  1495 0000D7EE 31DB                <1> 	xor	ebx, ebx
  1496 0000D7F0 4B                  <1> 	dec 	ebx ; FFFFFFFFh -> create empty file 
  1497                              <1> 	            ;              (only for FAT fs) 
  1498                              <1> 	; CL = File Attributes
  1499 0000D7F1 E8F8EBFFFF          <1> 	call	create_file
  1500 0000D7F6 7246                <1> 	jc	sysopen_err
  1501                              <1> 		; EAX = New file's first cluster
  1502                              <1> 		; ESI = Logical Dos Drv Descr. Table Addr.
  1503                              <1> 		; EBX = offset CreateFile_Size
  1504                              <1> 		; ECX = Sectors per cluster (<256) 
  1505                              <1> 		; EDX = Directory entry index/number (<65536)
  1506                              <1> 	; 26/10/2016
  1507                              <1> 	;mov	esi, Directory_Buffer
  1508                              <1> 	;shl	dx, 5 ; *32
  1509                              <1> 	;add	esi, edx
  1510                              <1> 	;; esi = directory entry address in directory buffer
  1511                              <1> 
  1512                              <1> 	; Here, directory entry has been created but last
  1513                              <1> 	; modification date & time of the parent dir has not
  1514                              <1> 	; been updated, yet! 
  1515                              <1> 	; (Note: Directory and FAT buffers have been updated...)
  1516                              <1>  	
  1517 0000D7F8 E824DDFFFF          <1> 	call	update_parent_dir_lmdt ; now, it is OK too!
  1518                              <1> 
  1519                              <1> 	; 25/10/2016
  1520 0000D7FD 66B80018            <1> 	mov	ax, 1800h
  1521 0000D801 BE[806D0100]        <1> 	mov	esi, FindFile_Name
  1522 0000D806 E846B6FFFF          <1> 	call	find_first_file
  1523 0000D80B 7231                <1> 	jc	short sysopen_err
  1524                              <1> 
  1525                              <1> 	; Only possible error after here is 
  1526                              <1> 	; "too many open files !" error.
  1527                              <1> 	;
  1528                              <1> 	; If "syscreat" will return with that error,
  1529                              <1> 	; (the file has been created but it could not be opened)
  1530                              <1> 	; the user must retry to open this file again
  1531                              <1> 	; or must close another file before using 
  1532                              <1> 	; "sysopen" system call.
  1533                              <1> 
  1534 0000D80D B201                <1> 	mov	dl, 1 ; open file for writing
  1535                              <1> 	; ESI = Directory Entry (FindFile_DirEntry) Location
  1536                              <1> 	; EAX = File Size (= 0)
  1537 0000D80F EB5D                <1> 	jmp	short sysopen_2
  1538                              <1> 
  1539                              <1> sysopen: ;<open file>
  1540                              <1> 	; 26/10/2016
  1541                              <1> 	; 24/10/2016
  1542                              <1> 	; 17/10/2016
  1543                              <1> 	; 15/10/2016
  1544                              <1> 	; 06/10/2016, 07/10/2016, 08/10/2016
  1545                              <1> 	; 05/10/2016 (TRDOS 386 = TRDOS v2.0) 
  1546                              <1> 	;	     -derived from INT_21H.ASM-
  1547                              <1> 	;            ("loc_INT21h_open_file")
  1548                              <1>         ; 	26/02/2011 
  1549                              <1>         ;	INT 21h Function AH = 3Dh
  1550                              <1>         ;	Open File
  1551                              <1>         ;	INPUT
  1552                              <1>         ;	   AL= File Access Value
  1553                              <1> 	;     	     0- Open for reading
  1554                              <1> 	;            1- Open for writing
  1555                              <1>         ;            2- Open for reading and writing
  1556                              <1>         ;          DS:DX= Pointer to filename (ASCIIZ)
  1557                              <1>         ;
  1558                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1559                              <1> 	; 22/05/2013 - 27/05/2013 (Retro UNIX 8086 v1)
  1560                              <1> 	;
  1561                              <1> 	; 'sysopen' opens a file in following manner:
  1562                              <1> 	;    1) The second argument in a sysopen says whether to
  1563                              <1> 	;	open the file ro read (0) or write (>0).
  1564                              <1> 	;    2) I-node of the particular file is obtained via 'namei'.
  1565                              <1> 	;    3) The file is opened by 'iopen'.
  1566                              <1> 	;    4) Next housekeeping is performed on the fsp table
  1567                              <1> 	;	and the user's open file list - u.fp.
  1568                              <1> 	;	a) u.fp and fsp are scanned for the next available slot.
  1569                              <1> 	;	b) An entry for the file is created in the fsp table.
  1570                              <1> 	;	c) The number of this entry is put on u.fp list.
  1571                              <1> 	;	d) The file descriptor index to u.fp list is pointed
  1572                              <1> 	;	   to by u.r0.
  1573                              <1> 	;
  1574                              <1> 	; Calling sequence:
  1575                              <1> 	;	sysopen; name; mode
  1576                              <1> 	; Arguments:
  1577                              <1> 	;	name - file name or path name
  1578                              <1> 	;	mode - 0 to open for reading
  1579                              <1> 	;	       1 to open for writing
  1580                              <1> 	; Inputs: (arguments)
  1581                              <1> 	; Outputs: *u.r0 - index to u.fp list (the file descriptor)
  1582                              <1> 	;		  is put into r0's location on the stack.	
  1583                              <1> 	; ...............................................................
  1584                              <1> 	;				
  1585                              <1> 	; Retro UNIX 8086 v1 modification: 
  1586                              <1> 	;       'sysopen' system call has two arguments; so,
  1587                              <1> 	;	* 1st argument, name is pointed to by BX register
  1588                              <1> 	;	* 2nd argument, mode is in CX register
  1589                              <1> 	;
  1590                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1591                              <1> 	;	to the user with the file descriptor/number 
  1592                              <1> 	;	(index to u.fp list).
  1593                              <1> 	;
  1594                              <1> 	;call	arg2
  1595                              <1> 	; * name - 'u.namep' points to address of file/path name
  1596                              <1> 	;          in the user's program segment ('u.segmnt')
  1597                              <1> 	;          with offset in BX register (as sysopen argument 1).
  1598                              <1> 	; * mode - sysopen argument 2 is in CX register 
  1599                              <1> 	;          which is on top of stack.
  1600                              <1> 	;
  1601                              <1> 	; jsr r0,arg2 / get sys args into u.namep and on stack
  1602                              <1> 	;
  1603                              <1>        	; system call registers: ebx, ecx (through 'sysenter')
  1604                              <1> 	;
  1605                              <1> 	; TRDOS 386 (05/10/2016)
  1606                              <1> 	;	
  1607                              <1>         ; INPUT ->
  1608                              <1>         ;	   CL = File Access Value (Open Mode)
  1609                              <1> 	;     	      0 - Open file for reading
  1610                              <1> 	;             1 - Open file for writing
  1611                              <1>         ;             2 - Open device for reading
  1612                              <1> 	;	      3 - Open device for writing
  1613                              <1>         ;          EBX = Pointer to filename/devicename (ASCIIZ)
  1614                              <1> 	; OUTPUT ->
  1615                              <1> 	;          eax = File/Device Handle/Number (index) (AL)
  1616                              <1> 	;          cf = 1 -> Error code in AL
  1617                              <1> 	;
  1618                              <1> 	; Modified Registers: EAX (at the return of system call)
  1619                              <1> 	;  
  1620                              <1> 
  1621 0000D811 80F901              <1> 	cmp	cl, 1 ; read file (0), write file (1)
  1622 0000D814 7614                <1> 	jna	short sysopen_0
  1623                              <1> 
  1624 0000D816 80F903              <1> 	cmp	cl, 3
  1625 0000D819 0F8640010000        <1> 	jna	sysopen_device
  1626                              <1> 
  1627                              <1> 	; Invalid access code
  1628 0000D81F B817000000          <1> 	mov	eax, ERR_INV_PARAMETER
  1629 0000D824 0F874B010000        <1> 	ja	sysopen_dev_err
  1630                              <1> 
  1631                              <1> sysopen_0:
  1632                              <1> 	;mov	[u.namep], ebx
  1633 0000D82A 51                  <1> 	push	ecx
  1634 0000D82B 89DE                <1> 	mov	esi, ebx
  1635                              <1> 	; file name is forced, change directory as temporary
  1636                              <1> 	;mov	ax, 1
  1637                              <1> 	;mov	[FFF_Valid], ah ; 0 ; reset ; 17/10/2016
  1638                              <1> 	;call	set_working_path 
  1639 0000D82D E8E12E0000          <1> 	call	set_working_path_x ; 17/10/2016	
  1640 0000D832 731E                <1> 	jnc	short sysopen_1
  1641                              <1> 
  1642                              <1> syscreat_err: ; ecx = file attributes (for 'syscreat')
  1643 0000D834 59                  <1> 	pop	ecx ; open mode  
  1644 0000D835 21C0                <1> 	and	eax, eax  ; 0 -> Bad Path!  
  1645 0000D837 7505                <1> 	jnz	short sysopen_err
  1646                              <1> 	; eax = 0
  1647 0000D839 B80C000000          <1> 	mov	eax, ERR_DIR_NOT_FOUND ; Directory not found !
  1648                              <1> sysopen_err:
  1649 0000D83E A3[64030300]        <1> 	mov	[u.r0], eax
  1650 0000D843 A3[C8030300]        <1> 	mov	[u.error], eax
  1651 0000D848 E89B2F0000          <1> 	call 	reset_working_path
  1652 0000D84D E95AFAFFFF          <1> 	jmp	error
  1653                              <1> 
  1654                              <1> sysopen_1:
  1655                              <1> 	;mov	esi, FindFile_Name
  1656 0000D852 66B80018            <1>         mov	ax, 1800h ; Only files 
  1657 0000D856 E8F6B5FFFF          <1> 	call	find_first_file
  1658 0000D85B 5A                  <1> 	pop	edx
  1659 0000D85C 72E0                <1> 	jc	short sysopen_err ; eax = 2 (File not found !)
  1660                              <1> 
  1661                              <1> 	; check_open_file_attr_access_code
  1662                              <1> 
  1663 0000D85E F6C307              <1>         test	bl, 7  ; system, hidden, readonly 
  1664 0000D861 740B                <1>         jz	short sysopen_2
  1665                              <1> 
  1666 0000D863 20D2                <1> 	and	dl, dl ; 0 = read mode
  1667 0000D865 7407                <1> 	jz	short sysopen_2
  1668                              <1> 
  1669                              <1> 	; 1 = write, 2 = read & write, >2 = invalid
  1670 0000D867 B80B000000          <1>         mov	eax, ERR_FILE_ACCESS  ; 11 = 'permission denied !'
  1671 0000D86C EBD0                <1>         jmp	short sysopen_err
  1672                              <1> 
  1673                              <1> sysopen_2:
  1674                              <1> 	; esi = Directory Entry (FindFile_DirEntry) Location
  1675 0000D86E 89F3                <1> 	mov	ebx, esi
  1676 0000D870 31F6                <1>         xor     esi, esi ; 0
  1677 0000D872 31FF                <1>         xor     edi, edi ; 0
  1678                              <1> sysopen_3: ; scan the list of entries in fsp table
  1679 0000D874 80BE[6A030300]00    <1>         cmp     byte [esi+u.fp], 0
  1680 0000D87B 760F                <1>         jna     short sysopen_4 ; empty slot
  1681 0000D87D 6646                <1>         inc     si
  1682 0000D87F 6683FE0A            <1>         cmp     si, 10
  1683 0000D883 72EF                <1> 	jb	short sysopen_3
  1684                              <1> toomanyf:
  1685 0000D885 B80D000000          <1> 	mov	eax, ERR_TOO_MANY_FILES ; too many open files !
  1686 0000D88A EBB2                <1> 	jmp	short sysopen_err
  1687                              <1> 
  1688                              <1> sysopen_4: 
  1689 0000D88C 80BF[FE730100]00    <1>         cmp     byte [edi+OF_MODE], 0 ; Scan open files table 
  1690 0000D893 760A                <1> 	jna     short sysopen_5
  1691 0000D895 6647                <1> 	inc	di
  1692 0000D897 6683FF0A            <1> 	cmp     di, OPENFILES ; max. number of open files (=10)
  1693 0000D89B 72EF                <1> 	jb	short sysopen_4
  1694 0000D89D EBE6                <1> 	jmp	short toomanyf
  1695                              <1> 
  1696                              <1> sysopen_5:
  1697 0000D89F FEC2                <1> 	inc	dl
  1698 0000D8A1 8897[FE730100]      <1>         mov     [edi+OF_MODE], dl
  1699 0000D8A7 8A15[3E6D0100]      <1> 	mov	dl, [FindFile_Drv]
  1700 0000D8AD 8897[F4730100]      <1>         mov     [edi+OF_DRIVE], dl ; Logical DOS drive number
  1701 0000D8B3 66C1E702            <1> 	shl	di, 2 ; *4 (dword offset)
  1702                              <1> 
  1703 0000D8B7 8987[44740100]      <1> 	mov	[edi+OF_SIZE], eax ; File size in bytes
  1704                              <1> 
  1705 0000D8BD 668B4314            <1>         mov 	ax, [ebx+DirEntry_FstClusHI]
  1706 0000D8C1 C1E010              <1> 	shl	eax, 16
  1707 0000D8C4 668B431A            <1> 	mov 	ax, [ebx+DirEntry_FstClusLO]
  1708 0000D8C8 8987[CC730100]      <1> 	mov     [edi+OF_FCLUSTER], eax ; First cluster
  1709 0000D8CE 8987[E4740100]      <1> 	mov     [edi+OF_CCLUSTER], eax ; Current cluster
  1710                              <1> 
  1711 0000D8D4 31DB                <1>         xor	ebx, ebx
  1712 0000D8D6 899F[1C740100]      <1>         mov     [edi+OF_POINTER], ebx ; offset pointer (0)
  1713 0000D8DC 899F[0C750100]      <1>         mov     [edi+OF_CCINDEX], ebx ; cluster index (0)
  1714                              <1> 
  1715 0000D8E2 A1[B06D0100]        <1> 	mov	eax, [FindFile_DirFirstCluster]
  1716 0000D8E7 8987[6C740100]      <1> 	mov	[edi+OF_DIRFCLUSTER], eax
  1717                              <1> 
  1718 0000D8ED A1[B46D0100]        <1> 	mov	eax, [FindFile_DirCluster]
  1719 0000D8F2 8987[94740100]      <1> 	mov	[edi+OF_DIRCLUSTER], eax
  1720                              <1> 
  1721                              <1> 	; Get (& Save) Volume ID 
  1722                              <1> 	; Important for files of removable drives
  1723                              <1> 	; (In order to check the drive has same volume/disk)
  1724 0000D8F8 88D7                <1> 	mov	bh, dl
  1725 0000D8FA 81C300010900        <1>         add	ebx, Logical_DOSDisks
  1726 0000D900 8A4303              <1>         mov	al, [ebx+LD_FATType]
  1727 0000D903 3C01                <1>         cmp	al, 1
  1728 0000D905 7209                <1>         jb	short sysopen_6_fs
  1729 0000D907 3C02                <1>         cmp	al, 2
  1730 0000D909 770A                <1>         ja	short sysopen_6_fat32
  1731                              <1> sysopen_6_fat:
  1732 0000D90B 8B432D              <1>         mov	eax, [ebx+LD_BPB+VolumeID]
  1733 0000D90E EB08                <1>         jmp	short sysopen_7
  1734                              <1> sysopen_6_fs:
  1735 0000D910 8B4328              <1>         mov	eax, [ebx+LD_FS_VolumeSerial]
  1736 0000D913 EB03                <1>         jmp	short sysopen_7
  1737                              <1> sysopen_6_fat32:
  1738 0000D915 8B4349              <1>         mov	eax, [ebx+LD_BPB+FAT32_VolID]
  1739                              <1> sysopen_7:
  1740 0000D918 A3[94640100]        <1>         mov	[Current_VolSerial], eax
  1741                              <1> 
  1742 0000D91D 8987[BC740100]      <1> 	mov	[edi+OF_VOLUMEID], eax
  1743                              <1> 
  1744                              <1> 	; 24/10/2016
  1745 0000D923 66D1EF              <1> 	shr	di, 1 ; 4/2, word offset
  1746 0000D926 668B1D[B86D0100]    <1> 	mov	bx, [FindFile_DirEntryNumber]
  1747 0000D92D 66899F[34750100]    <1> 	mov	[edi+OF_DIRENTRY], bx
  1748                              <1> 
  1749 0000D934 31D2                <1> 	xor	edx, edx
  1750                              <1> 	;shr	di, 2 ; /4 (byte offset)
  1751 0000D936 66D1EF              <1> 	shr	di, 1 ; 2/2, byte offset
  1752 0000D939 8897[12740100]      <1> 	mov	byte [edi+OF_OPENCOUNT], dl ; 0
  1753 0000D93F 8897[08740100]      <1> 	mov	byte [edi+OF_STATUS], dl ; 0
  1754                              <1> 
  1755 0000D945 89FB                <1> 	mov	ebx, edi
  1756 0000D947 FEC3                <1> 	inc	bl
  1757                              <1> 
  1758 0000D949 889E[6A030300]      <1>         mov     [esi+u.fp], bl ; Open File Entry Number
  1759 0000D94F 8935[64030300]      <1> 	mov     [u.r0], esi ; move index to u.fp list 
  1760                              <1> 			    ; into eax on stack
  1761                              <1> 
  1762 0000D955 E88E2E0000          <1>         call 	reset_working_path
  1763                              <1>         
  1764 0000D95A E96DF9FFFF          <1> 	jmp	sysret
  1765                              <1> 
  1766                              <1> 	; (Retro UNIX 386 v1.0)
  1767                              <1> 	; 'fsp' table (10 bytes/entry)
  1768                              <1> 	; bit 15				   bit 0
  1769                              <1> 	; ---|-------------------------------------------
  1770                              <1> 	; r/w|		i-number of open file
  1771                              <1> 	; ---|-------------------------------------------
  1772                              <1> 	;		   device number
  1773                              <1> 	; -----------------------------------------------
  1774                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
  1775                              <1> 	; -----------------------------------------------
  1776                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
  1777                              <1> 	; ----------------------|------------------------
  1778                              <1> 	;  flag that says file 	| number of processes
  1779                              <1> 	;   has been deleted	| that have file open 
  1780                              <1> 	; ----------------------|------------------------
  1781                              <1> 
  1782                              <1> sysopen_device:
  1783                              <1> 	; 15/10/2016
  1784                              <1> 	; 08/10/2016
  1785                              <1> 	; 07/10/2016 (TRDOS 386 = TRDOS v2.0)
  1786 0000D95F 51                  <1> 	push	ecx ; open mode
  1787 0000D960 89E5                <1> 	mov	ebp, esp
  1788 0000D962 B910000000          <1> 	mov	ecx, 16 ; transfer length = 16 bytes 
  1789 0000D967 29CC                <1> 	sub	esp, ecx
  1790 0000D969 89E7                <1> 	mov	edi, esp ; destination address 
  1791 0000D96B 89DE                <1> 	mov 	esi, ebx ; dev name in user's memory space
  1792 0000D96D E869190000          <1> 	call	transfer_from_user_buffer
  1793 0000D972 7310                <1> 	jnc	short sysopen_dev_0
  1794                              <1> 	; eax = ERR_OUT_OF_MEMORY = 4 = ERR_MINOR_IM
  1795 0000D974 59                  <1> 	pop	ecx
  1796                              <1> sysopen_dev_err:
  1797 0000D975 A3[64030300]        <1> 	mov	[u.r0], eax
  1798 0000D97A A3[C8030300]        <1> 	mov	[u.error], eax
  1799 0000D97F E928F9FFFF          <1> 	jmp	error
  1800                              <1> sysopen_dev_0:
  1801 0000D984 89FE                <1> 	mov	esi, edi ; Device name addr (max. 16 bytes, ASCIIZ) 
  1802                              <1> 			 ; for example: "tty, TTY, /dev/tty"
  1803 0000D986 E803310000          <1> 	call	get_device_number
  1804 0000D98B 89EC                <1> 	mov	esp, ebp
  1805 0000D98D 59                  <1> 	pop	ecx
  1806 0000D98E 7307                <1> 	jnc	short sysopen_dev_1
  1807 0000D990 B818000000          <1> 	mov	eax, ERR_INV_DEV_NAME ; 24 ; 'invalid device name !'
  1808 0000D995 EBDE                <1> 	jmp	short sysopen_dev_err
  1809                              <1> sysopen_dev_1:
  1810                              <1> 	; eax = Device Number (AL)
  1811                              <1> 	;  cl = Open mode (2 = device read, 3 = device write)
  1812 0000D997 31DB                <1>         xor     ebx, ebx ; 0
  1813                              <1> sysopen_dev_2: ; scan the list of entries
  1814 0000D999 389B[6A030300]      <1>         cmp     [ebx+u.fp], bl ; 0
  1815 0000D99F 760E                <1>         jna     short sysopen_dev_3 ; empty slot
  1816 0000D9A1 FEC3                <1>         inc     bl
  1817 0000D9A3 80FB0A              <1>         cmp     bl, 10
  1818 0000D9A6 72F1                <1> 	jb	short sysopen_dev_2
  1819                              <1> 	;
  1820 0000D9A8 B80D000000          <1> 	mov	eax, ERR_TOO_MANY_FILES ; too many open files !
  1821 0000D9AD EBC6                <1> 	jmp	short sysopen_dev_err
  1822                              <1> sysopen_dev_3:
  1823 0000D9AF 891D[64030300]      <1> 	mov 	[u.r0], ebx ; File/Device index/handle/descriptor
  1824                              <1> 	; eax = device number (entry offset)
  1825 0000D9B5 8AA8[90710100]      <1> 	mov	ch, [eax+DEV_ACCESS] ; bit 0 = accessable by users
  1826                              <1> 				     ; bit 1 = read access perm
  1827                              <1> 				     ; bit 2 = write access perm
  1828                              <1> 				     ; bit 3 = IOCTL permit to users
  1829                              <1> 				     ; bit 4 = block device if set
  1830                              <1> 				     ; bit 5 = 16 bit or 1024 byte
  1831                              <1> 				     ; bit 6 = 32 bit or 2048 byte
  1832                              <1> 				     ; bit 7 = installable device drv
  1833 0000D9BB F6C501              <1> 	test 	ch, 1 ; accessable by normal users (except root)
  1834 0000D9BE 7510                <1> 	jnz	short sysopen_dev_4 ; yes, permission has been given
  1835 0000D9C0 803D[B0030300]00    <1> 	cmp	byte [u.uid], 0 ; root?
  1836 0000D9C7 7607                <1> 	jna	short sysopen_dev_4 ; superuser can open all devices
  1837                              <1> sysopen_dev_perm_err:
  1838 0000D9C9 B80B000000          <1> 	mov	eax, ERR_DEV_ACCESS  ; 11 = 'permission denied !'
  1839 0000D9CE EBA5                <1> 	jmp	short sysopen_dev_err
  1840                              <1> sysopen_dev_4:
  1841 0000D9D0 D0ED                <1> 	shr	ch, 1 ; result: 1 = read, 2 = write, 3 = r & w 
  1842 0000D9D2 FEC9                <1> 	dec	cl  ; result: 1 = read, 2 = write
  1843 0000D9D4 84E9                <1> 	test	cl, ch
  1844 0000D9D6 74F1                <1> 	jz	short sysopen_dev_perm_err 
  1845                              <1> 
  1846 0000D9D8 D0E5                <1> 	shl	ch, 1 ; bit 0 = 0
  1847                              <1> 	; eax = device number (entry offset)
  1848 0000D9DA E8CB310000          <1> 	call	device_open
  1849 0000D9DF 72E8                <1> 	jc	short sysopen_dev_perm_err 
  1850                              <1> 
  1851                              <1> 	; eax = device number (entry offset)
  1852 0000D9E1 0C80                <1> 	or	al, 80h ; set device bit (set bit 7 to 1)
  1853 0000D9E3 8B1D[64030300]      <1> 	mov	ebx, [u.r0]
  1854 0000D9E9 8883[6A030300]      <1> 	mov	[ebx+u.fp], al	; bit 7 (=1) points to device	
  1855                              <1> 	
  1856 0000D9EF E9D8F8FFFF          <1> 	jmp	sysret
  1857                              <1> 
  1858                              <1> sysmkdir: ; < make directory >
  1859                              <1> 	; 15/10/2016
  1860                              <1> 	; 10/10/2016 (TRDOS 386 = TRDOS v2.0) 
  1861                              <1> 	;	     -derived from INT_21H.ASM-
  1862                              <1> 	;            ("loc_INT21h_create_file")
  1863                              <1>         ; 	10/07/2011 (12/03/2011)
  1864                              <1>         ;	INT 21h Function AH = 3Ch
  1865                              <1>         ;	Create File
  1866                              <1>         ;	INPUT
  1867                              <1>         ;	   CX = Attributes
  1868                              <1>         ;          DS:DX= Address of zero terminaned path name
  1869                              <1>         ;
  1870                              <1>         ;
  1871                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1872                              <1> 	; 27/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  1873                              <1> 	;
  1874                              <1> 	; 'sysmkdir' creates an empty directory whose name is
  1875                              <1> 	; pointed to by arg 1. The mode of the directory is arg 2.	
  1876                              <1> 	; The special entries '.' and '..' are not present.
  1877                              <1> 	; Errors are indicated if the directory already exists or		
  1878                              <1> 	; user is not the super user. 
  1879                              <1> 	;
  1880                              <1> 	; Calling sequence:
  1881                              <1> 	;	sysmkdir; name; mode
  1882                              <1> 	; Arguments:
  1883                              <1> 	;	name - points to the name of the directory
  1884                              <1> 	;	mode - mode of the directory
  1885                              <1> 	; Inputs: (arguments)
  1886                              <1> 	; Outputs: -
  1887                              <1> 	;    (sets 'directory' flag to 1; 
  1888                              <1> 	;    'set user id on execution' and 'executable' flags to 0)
  1889                              <1> 	; ...............................................................
  1890                              <1> 	;				
  1891                              <1> 	; Retro UNIX 8086 v1 modification: 
  1892                              <1> 	;       'sysmkdir' system call has two arguments; so,
  1893                              <1> 	;	* 1st argument, name is pointed to by BX register
  1894                              <1> 	;	* 2nd argument, mode is in CX register
  1895                              <1> 	;
  1896                              <1> 	; TRDOS 386 (10/10/2016)
  1897                              <1> 	;	
  1898                              <1>         ; INPUT ->
  1899                              <1>         ;	   CL = Directory Attributes
  1900                              <1> 	;     	      bit 0 (1) - Read only file/dir (R)
  1901                              <1> 	;             bit 1 (1) - Hidden file/dir (H)
  1902                              <1>         ;             bit 2 (1) - System file/dir (R)
  1903                              <1> 	;             bit 3 (1) - Volume label/name (V)
  1904                              <1>         ;             bit 4 (1) - Subdirectory (D)
  1905                              <1> 	;	      bit 5 (1) - File/Dir has been archived (A)
  1906                              <1> 	;	   CX = 0 -> create normal directory	 	
  1907                              <1>         ;          EBX = Pointer to directory name (ASCIIZ) -path-
  1908                              <1> 	;	
  1909                              <1> 	; OUTPUT ->
  1910                              <1> 	;          eax = First cluster of the new directory
  1911                              <1> 	;          cf = 1 -> Error code in AL
  1912                              <1> 	;
  1913                              <1> 	; Modified Registers: EAX (at the return of system call)
  1914                              <1> 	;  
  1915                              <1> 	; Note: If the file or directory is existing
  1916                              <1> 	;	an access error will be returned. 
  1917                              <1> 
  1918 0000D9F4 6621C9              <1> 	and	cx, cx ; if cx = 0 -> create a normal subdir
  1919 0000D9F7 7413                <1> 	jz	short sysmkdir_1
  1920                              <1> 
  1921 0000D9F9 F6C110              <1> 	test	cl, 10h ; if dir flags set, also use other flags
  1922 0000D9FC 0F853EFDFFFF        <1> 	jnz	sysmkdir_0 ; jump to head of 'syscreat'
  1923                              <1> 
  1924                              <1> 	; CX has wrong flags
  1925 0000DA02 B817000000          <1> 	mov 	eax, ERR_INV_FLAGS
  1926 0000DA07 E969FFFFFF          <1> 	jmp	sysopen_dev_err
  1927                              <1> 
  1928                              <1> sysmkdir_1:
  1929 0000DA0C B110                <1> 	mov	cl, 10h ; set subdir flag and reset other flags
  1930 0000DA0E E92DFDFFFF          <1> 	jmp	sysmkdir_0 ; jump to head of 'syscreat'
  1931                              <1> sysmkdir_2: 
  1932                              <1> 	; jump from 'syscreat' ; from 'syscreat_1'
  1933                              <1> 	;  CL = Directory attributes/flags  
  1934 0000DA13 BE[806D0100]        <1> 	mov	esi, FindFile_Name 
  1935 0000DA18 E804D7FFFF          <1> 	call	make_sub_directory
  1936 0000DA1D 0F821BFEFFFF        <1> 	jc	sysopen_err       ; NOTE: Old type (TRDOS 8086)
  1937                              <1> 				  ; error codes must be modified
  1938                              <1> 				  ; for next TRDOS 386 versions
  1939                              <1> 				  ; (10/10/2016)
  1940                              <1> 				  ; Old (MSDOS type)
  1941                              <1> 				  ; error codes (2011):
  1942                              <1> 				  ;  2 = file not found
  1943                              <1> 				  ;  3 = directory not found
  1944                              <1> 				  ;  5 = access denied
  1945                              <1> 				  ; 12 = no more files
  1946                              <1> 			          ; 19 = disk write protected   
  1947                              <1> 				  ; 39 = insufficient disk space
  1948                              <1> 				  ; 'sysdefs.s' ; 10/10/2016  	
  1949                              <1> 	
  1950 0000DA23 A3[64030300]        <1> 	mov	[u.r0], eax ; New sub dir's first cluster
  1951                              <1> 
  1952 0000DA28 E8BB2D0000          <1>         call 	reset_working_path
  1953                              <1> 
  1954 0000DA2D E99AF8FFFF          <1> 	jmp	sysret	
  1955                              <1> 
  1956                              <1> sysclose: ;<close file>
  1957                              <1> 	; 06/10/2016 (TRDOS 386 = TRDOS v2.0) 
  1958                              <1> 	;
  1959                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1960                              <1> 	; 22/05/2013 - 26/05/2013 (Retro UNIX 8086 v1)
  1961                              <1> 	;
  1962                              <1> 	; 'sysclose', given a file descriptor in 'u.r0', closes the
  1963                              <1> 	; associated file. The file descriptor (index to 'u.fp' list)
  1964                              <1> 	; is put in r1 and 'fclose' is called.
  1965                              <1> 	;
  1966                              <1> 	; Calling sequence:
  1967                              <1> 	;	sysclose
  1968                              <1> 	; Arguments:
  1969                              <1> 	;	-  
  1970                              <1> 	; Inputs: *u.r0 - file descriptor
  1971                              <1> 	; Outputs: -
  1972                              <1> 	; ...............................................................
  1973                              <1> 	;				
  1974                              <1> 	; Retro UNIX 8086 v1 modification:
  1975                              <1> 	;	 The user/application program puts file descriptor
  1976                              <1> 	;        in BX register as 'sysclose' system call argument.
  1977                              <1> 	; 	 (argument transfer method 1)
  1978                              <1> 
  1979                              <1> 	; TRDOS 386 (06/10/2016)
  1980                              <1> 	;	
  1981                              <1>         ; INPUT ->
  1982                              <1>         ;	   EBX = File Handle/Number (file index) (AL)
  1983                              <1> 	; OUTPUT ->
  1984                              <1> 	;          cf = 0 -> EAX = 0
  1985                              <1> 	;          cf = 1 -> Error code in EAX (ERR_FILE_NOT_OPEN)
  1986                              <1> 	;
  1987                              <1> 	; Modified Registers: EAX (at the return of system call)
  1988                              <1> 	;  
  1989                              <1> 
  1990 0000DA32 89D8                <1> 	mov 	eax, ebx
  1991 0000DA34 31DB                <1> 	xor	ebx, ebx	
  1992 0000DA36 891D[64030300]      <1> 	mov	[u.r0], ebx ; 0  ; return value of EAX
  1993 0000DA3C E8290D0000          <1> 	call 	fclose
  1994 0000DA41 0F8385F8FFFF        <1> 	jnc	sysret
  1995 0000DA47 B80A000000          <1> 	mov	eax, ERR_FILE_NOT_OPEN ; file not open !
  1996 0000DA4C A3[C8030300]        <1> 	mov	[u.error], eax ;
  1997 0000DA51 A3[64030300]        <1> 	mov	[u.r0], eax ; ! invalid handle !
  1998 0000DA56 E951F8FFFF          <1> 	jmp	error
  1999                              <1> 
  2000                              <1> sysread: ; < read from file >
  2001                              <1> 	; 11/10/2016 (TRDOS 386 = TRDOS v2.0) 
  2002                              <1> 	;	     -derived from INT_21H.ASM-
  2003                              <1> 	;            ("loc_INT21h_read_file")
  2004                              <1>         ; 	13/03/2011 (05/03/2011)
  2005                              <1>         ;	INT 21h Function AH = 3Fh
  2006                              <1>         ;	Read from a File
  2007                              <1>         ;	INPUT
  2008                              <1> 	;	   BX = File Handle
  2009                              <1>         ;	   CX = Number of bytes to read
  2010                              <1>         ;          DS:DX= Buffer address
  2011                              <1>         ;
  2012                              <1> 	; Note: TRDOS 386 'sysread' has been derived from 
  2013                              <1> 	;	Retro UNIX 386 v1 'sysread', except a few 
  2014                              <1> 	;	code modifications.
  2015                              <1> 	;
  2016                              <1> 	; 13/05/2015 (Retro UNIX 386 v1)
  2017                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  2018                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
  2019                              <1> 	;
  2020                              <1> 	; 'sysread' is given a buffer to read into and the number of
  2021                              <1> 	; characters to be read. If finds the file from the file
  2022                              <1> 	; descriptor located in *u.r0 (r0). This file descriptor
  2023                              <1> 	; is returned from a successful open call (sysopen).
  2024                              <1> 	; The i-number of file is obtained via 'rw1' and the data
  2025                              <1> 	; is read into core via 'readi'.
  2026                              <1> 	;
  2027                              <1> 	; Calling sequence:
  2028                              <1> 	;	sysread; buffer; nchars
  2029                              <1> 	; Arguments:
  2030                              <1> 	;	buffer - location of contiguous bytes where 
  2031                              <1> 	;		 input will be placed.
  2032                              <1> 	;	nchars - number of bytes or characters to be read.
  2033                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
  2034                              <1> 	; Outputs: *u.r0 - number of bytes read.	
  2035                              <1> 	; ...............................................................
  2036                              <1> 	;				
  2037                              <1> 	; Retro UNIX 8086 v1 modification: 
  2038                              <1> 	;       'sysread' system call has three arguments; so,
  2039                              <1> 	;	* 1st argument, file descriptor is in BX register
  2040                              <1> 	;	* 2nd argument, buffer address/offset in CX register
  2041                              <1> 	;	* 3rd argument, number of bytes is in DX register
  2042                              <1> 	;
  2043                              <1> 	;	AX register (will be restored via 'u.r0') will return
  2044                              <1> 	;	to the user with number of bytes read. 
  2045                              <1> 	;
  2046                              <1> 	; TRDOS 386 (05/10/2016)
  2047                              <1> 	;	
  2048                              <1>         ; INPUT ->
  2049                              <1>         ;	   EBX = File handle (descriptor/index)
  2050                              <1> 	;	   ECX = Buffer address		
  2051                              <1>         ;          EDX = Number of bytes
  2052                              <1> 	; OUTPUT ->
  2053                              <1> 	;          EAX = Number of bytes have been read
  2054                              <1> 	;          cf = 1 -> Error code in AL
  2055                              <1> 	;
  2056                              <1> 	; Modified Registers: EAX (at the return of system call)
  2057                              <1> 	; 
  2058                              <1> 
  2059                              <1> 	; EBX = File descriptor
  2060 0000DA5B E8580D0000          <1> 	call	getf1 
  2061 0000DA60 7277                <1> 	jc	short device_read ; read data from device
  2062                              <1> 	; EAX = First cluster of the file
  2063                              <1> 
  2064 0000DA62 E83F000000          <1> 	call	rw1
  2065 0000DA67 730A                <1> 	jnc	short sysread_0
  2066                              <1> 
  2067 0000DA69 A3[64030300]        <1> 	mov	[u.r0], eax ; error code
  2068 0000DA6E E939F8FFFF          <1> 	jmp	error
  2069                              <1> 	 
  2070                              <1> sysread_0:
  2071 0000DA73 E84F130000          <1> 	call	readi
  2072 0000DA78 EB1D                <1> 	jmp	short rw0
  2073                              <1> 
  2074                              <1> syswrite: ; < write to file >
  2075                              <1> 	; 23/10/2016
  2076                              <1> 	; 11/10/2016 (TRDOS 386 = TRDOS v2.0) 
  2077                              <1> 	;	     -derived from INT_21H.ASM-
  2078                              <1> 	;            ("loc_INT21h_write_file")
  2079                              <1>         ; 	13/03/2011 (05/03/2011)
  2080                              <1>         ;	INT 21h Function AH = 40h
  2081                              <1>         ;	Write to a File
  2082                              <1>         ;	INPUT
  2083                              <1> 	;	   BX = File Handle
  2084                              <1>         ;	   CX = Number of bytes to write
  2085                              <1>         ;          DS:DX= Buffer address
  2086                              <1>         ;
  2087                              <1> 	; Note: TRDOS 386 'sysrwrite' has been derived from 
  2088                              <1> 	;	Retro UNIX 386 v1 'syswrite', except a few 
  2089                              <1> 	;	code modifications.
  2090                              <1> 	;
  2091                              <1> 
  2092                              <1> 	; 13/05/2015 (Retro UNIX 386 v1)
  2093                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  2094                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
  2095                              <1> 	;
  2096                              <1> 	; 'syswrite' is given a buffer to write onto an output file
  2097                              <1> 	; and the number of characters to write. If finds the file
  2098                              <1> 	; from the file descriptor located in *u.r0 (r0). This file 
  2099                              <1> 	; descriptor is returned from a successful open or create call
  2100                              <1> 	; (sysopen or syscreat). The i-number of file is obtained via
  2101                              <1> 	; 'rw1' and buffer is written on the output file via 'write'.
  2102                              <1> 	;
  2103                              <1> 	; Calling sequence:
  2104                              <1> 	;	syswrite; buffer; nchars
  2105                              <1> 	; Arguments:
  2106                              <1> 	;	buffer - location of contiguous bytes to be writtten.
  2107                              <1> 	;	nchars - number of characters to be written.
  2108                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
  2109                              <1> 	; Outputs: *u.r0 - number of bytes written.	
  2110                              <1> 	; ...............................................................
  2111                              <1> 	;				
  2112                              <1> 	; Retro UNIX 8086 v1 modification: 
  2113                              <1> 	;       'syswrite' system call has three arguments; so,
  2114                              <1> 	;	* 1st argument, file descriptor is in BX register
  2115                              <1> 	;	* 2nd argument, buffer address/offset in CX register
  2116                              <1> 	;	* 3rd argument, number of bytes is in DX register
  2117                              <1> 	;
  2118                              <1> 	;	AX register (will be restored via 'u.r0') will return
  2119                              <1> 	;	to the user with number of bytes written. 
  2120                              <1> 	;
  2121                              <1> 	; INPUT ->
  2122                              <1>         ;	   EBX = File handle (descriptor/index)
  2123                              <1> 	;	   ECX = Buffer address		
  2124                              <1>         ;          EDX = Number of bytes
  2125                              <1> 	; OUTPUT ->
  2126                              <1> 	;          EAX = Number of bytes have been written
  2127                              <1> 	;          cf = 1 -> Error code in AL
  2128                              <1> 	;
  2129                              <1> 	; Modified Registers: EAX (at the return of system call)
  2130                              <1> 	;  
  2131                              <1> 
  2132                              <1> 	; EBX = File descriptor
  2133 0000DA7A E8390D0000          <1> 	call	getf1 
  2134 0000DA7F 7274                <1> 	jc	short device_write ; write data to device
  2135                              <1> 	; EAX = First cluster of the file
  2136                              <1> 	; EBX = File number  (Open file number) ; 23/10/2016
  2137                              <1> 
  2138 0000DA81 E820000000          <1> 	call	rw1
  2139 0000DA86 730A                <1> 	jnc	short syswrite_0
  2140 0000DA88 A3[64030300]        <1> 	mov	[u.r0], eax ; error code
  2141 0000DA8D E91AF8FFFF          <1> 	jmp	error
  2142                              <1> 	 
  2143                              <1> syswrite_0:
  2144 0000DA92 E85C1A0000          <1> 	call	writei
  2145                              <1> rw0: ; 1:
  2146 0000DA97 A1[8C030300]        <1>         mov	eax, [u.nread]
  2147 0000DA9C A3[64030300]        <1> 	mov	[u.r0], eax
  2148 0000DAA1 E926F8FFFF          <1> 	jmp	sysret
  2149                              <1> 
  2150                              <1> rw1:	
  2151                              <1> 	; 11/10/2016 (TRDOS 386 = TRDOS v2.0) 
  2152                              <1> 	; 14/05/2015 (Retro UNIX 386 v1)
  2153                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  2154                              <1> 	; 23/05/2013 - 24/05/2013 (Retro UNIX 8086 v1)
  2155                              <1> 	; System call registers: ebx, ecx, edx (through 'sysenter')
  2156                              <1> 	;
  2157                              <1> 	; EBX = File descriptor
  2158                              <1> 	;call	getf1 ; calling point in 'getf' from 'rw1'
  2159                              <1> 	;jc	short device_rw ; read/write data from/to device
  2160                              <1> 	; EAX = First cluster of the file
  2161                              <1> 
  2162 0000DAA6 83F802              <1> 	cmp 	eax, 2
  2163 0000DAA9 7217                <1> 	jb	short rw2
  2164                              <1> 	;
  2165 0000DAAB 890D[84030300]      <1> 	mov	[u.base], ecx 	; buffer address/offset 
  2166                              <1> 				;(in the user's virtual memory space)
  2167 0000DAB1 8915[88030300]      <1> 	mov	[u.count], edx 
  2168                              <1> 
  2169 0000DAB7 C705[C8030300]0000- <1>         mov     dword [u.error], 0 ; reset the last error code
  2169 0000DABF 0000                <1>
  2170 0000DAC1 C3                  <1> 	retn
  2171                              <1> 
  2172                              <1> rw2:
  2173 0000DAC2 B80A000000          <1> 	mov	eax, ERR_FILE_NOT_OPEN ; file not open !
  2174 0000DAC7 A3[C8030300]        <1> 	mov	dword [u.error], eax
  2175 0000DACC C3                  <1> 	retn
  2176                              <1> rw3: 
  2177 0000DACD B80B000000          <1> 	mov	eax, ERR_FILE_ACCESS ; permission denied !
  2178 0000DAD2 A3[C8030300]        <1> 	mov	dword [u.error], eax
  2179 0000DAD7 F9                  <1> 	stc
  2180 0000DAD8 C3                  <1> 	retn
  2181                              <1> 
  2182                              <1> device_read:
  2183                              <1> 	; 11/10/2016 (TRDOS 386 = TRDOS v2.0)
  2184                              <1> 	; cl = DEV_OPENMODE ; open mode
  2185                              <1> 	; ch = DEV_ACCESS   ; access flags   
  2186                              <1> 	; al = DEV_DRIVER   ; device number (eax)
  2187                              <1> 
  2188 0000DAD9 F6C101              <1> 	test	cl, 1 ; 1 = read, 2 = write, 3 = read&write
  2189 0000DADC 74EF                <1> 	jz	short rw3
  2190                              <1> 
  2191 0000DADE 89C3                <1> 	mov	ebx, eax
  2192 0000DAE0 66C1E302            <1> 	shl	bx, 2 ; *4
  2193                              <1> 
  2194 0000DAE4 F6C580              <1> 	test	ch, 80h ; bit 7, installable device driver flag
  2195 0000DAE7 7406                <1> 	jz	short d_read_2 ; Kernel device
  2196                              <1> 	; installable device
  2197                              <1> d_read_1:
  2198 0000DAE9 FFA3[4C710100]      <1>         jmp	dword [ebx+IDEV_RADDR-4]
  2199                              <1> d_read_2:
  2200 0000DAEF FFA3[72200100]      <1> 	jmp	dword [ebx+KDEV_RADDR-4]
  2201                              <1> 
  2202                              <1> device_write:
  2203                              <1> 	; 11/10/2016 (TRDOS 386 = TRDOS v2.0)
  2204                              <1> 	; cl = DEV_OPENMODE ; open mode
  2205                              <1> 	; ch = DEV_ACCESS   ; access flags   
  2206                              <1> 	; al = DEV_DRIVER   ; device number (eax)
  2207                              <1> 
  2208 0000DAF5 F6C102              <1> 	test	cl, 2 ; 1 = read, 2 = write, 3 = read&write
  2209 0000DAF8 74D3                <1> 	jz	short rw3	
  2210                              <1> 
  2211 0000DAFA 89C3                <1> 	mov	ebx, eax
  2212 0000DAFC 66C1E302            <1> 	shl	bx, 2 ; *4
  2213                              <1> 
  2214 0000DB00 F6C580              <1> 	test	ch, 80h ; bit 7, installable device driver flag
  2215 0000DB03 7406                <1> 	jz	short d_write_2 ; Kernel device
  2216                              <1> 	; installable device
  2217                              <1> d_write_1:
  2218 0000DB05 FFA3[6C710100]      <1>         jmp	dword [ebx+IDEV_WADDR-4]
  2219                              <1> d_write_2:
  2220 0000DB0B FFA3[C2200100]      <1> 	jmp	dword [ebx+KDEV_WADDR-4]
  2221                              <1> 
  2222                              <1> 
  2223                              <1> sysemt: ; enable (or disable) multi tasking -time sharing-
  2224                              <1> 	;
  2225                              <1> 	; 23/05/2016 - TRDOS 386 (TRDOS v2.0)
  2226                              <1> 	; 14/05/2015 (Retro UNIX 386 v1)
  2227                              <1> 	; 10/12/2013 - 20/04/2014 (Retro UNIX 8086 v1)
  2228                              <1> 	;
  2229                              <1> 	; Retro UNIX 8086 v1 modification: 
  2230                              <1> 	;	'Enable Multi Tasking'  system call instead 
  2231                              <1> 	;	of 'Emulator Trap' in original UNIX v1 for PDP-11.
  2232                              <1> 	;
  2233                              <1> 	; Retro UNIX 8086 v1 feature only!
  2234                              <1> 	;	Using purpose: Kernel will start without time-out
  2235                              <1> 	;	(internal clock/timer) functionality.
  2236                              <1> 	;	Then etc/init will enable clock/timer for
  2237                              <1> 	;	multi tasking. 
  2238                              <1> 	;
  2239                              <1> 	; INPUT ->
  2240                              <1> 	;	BL = 0 -> disable multi tasking
  2241                              <1> 	;	BL > 1 -> enable multi tasking (time sharing) 
  2242                              <1> 	; OUTPUT ->
  2243                              <1> 	;	none	
  2244                              <1> 	;
  2245                              <1> 	;  Note: Multi tasking is disabled during system
  2246                              <1> 	;	 initialization, it must be enabled by using
  2247                              <1> 	;	 this system call. (Otherwise, running proces 
  2248                              <1> 	;	 will not be changed by another process within
  2249                              <1> 	;	 run time sequence/schedule, if running process
  2250                              <1> 	;	 will not 'release' itself. Only 'wakeup' procedure
  2251                              <1> 	;	 for waiting processes and programmed timer events
  2252                              <1> 	;	 for other processes can change running process 
  2253                              <1> 	;	 while multi tasking is disabled.) ** 23/05/2016 **
  2254                              <1> 
  2255 0000DB11 803D[B0030300]00    <1> 	cmp	byte [u.uid], 0 ; root ?
  2256                              <1> 	;ja	error
  2257 0000DB18 0F87D3F8FFFF        <1> 	ja	badsys ; 14/05/2015
  2258                              <1> 	;
  2259 0000DB1E FA                  <1> 	cli
  2260 0000DB1F 881D[6A700100]      <1> 	mov	[multi_tasking], bl ; 0 to disable, >0 to enable
  2261 0000DB25 E9A2F7FFFF          <1> 	jmp	sysret
  2262                              <1> 
  2263                              <1> systimer:
  2264                              <1> 	; 02/01/2017
  2265                              <1> 	; 21/12/2016
  2266                              <1> 	; 19/12/2016
  2267                              <1> 	; 10/12/2016 (callback)
  2268                              <1> 	; 10/06/2016
  2269                              <1> 	; 07/06/2016
  2270                              <1> 	; 06/06/2016
  2271                              <1> 	; 21/05/2016
  2272                              <1> 	; 19/05/2016
  2273                              <1> 	; 18/05/2016 - TRDOS 386 (TRDOS v2.0)
  2274                              <1> 	; (TRDOS 386 feature only!)
  2275                              <1> 	;
  2276                              <1> 	; (start or stop timer event(s))	
  2277                              <1> 	;
  2278                              <1> 	; INPUT ->
  2279                              <1> 	;	BL = Signal return byte (response byte)
  2280                              <1> 	;	     (Any requested value between 0 and 255)
  2281                              <1> 	;	     (Kernel will put it at the requested address)    	
  2282                              <1> 	;	BH = Time count unit
  2283                              <1> 	;	     0 = Stop timer event
  2284                              <1> 	;	     1 = 18.2 ticks per second
  2285                              <1> 	;	     2 = 10 milliseconds  		
  2286                              <1> 	;	     3 = 1 second (for real time clock interrupt) 	 
  2287                              <1> 	;	     4 = time/tick count in current time count unit
  2288                              <1> 	;	    // 10/12/2016			
  2289                              <1> 	;	    80h = Stop timer event (callback method)
  2290                              <1> 	;	    81h = 18.2 ticks per second, callback method
  2291                              <1> 	;	    82h = 10 milliseconds, callback method 	
  2292                              <1> 	;	    83h = 1 second (for RTC int), callback method 	
  2293                              <1> 	;	    84h = current time count unit, callback method
  2294                              <1> 	;
  2295                              <1> 	;	    Note: Only 03h or 83h will set real time clock
  2296                              <1> 	;		  (RTC) events (Others are for PIT events)! 	
  2297                              <1> 	;	
  2298                              <1> 	;	NOTE: If callback (user service) method is used,
  2299                              <1> 	;	    EDX will point to the return address (of service
  2300                              <1> 	;	    procedure) in user's space instead of signal 
  2301                              <1> 	;	    response byte address. (TRDOS 386 kernel will
  2302                              <1> 	;	    direct the cpu to that address -in user's space-
  2303                              <1> 	;	    at the return of system call or interrupt 
  2304                              <1> 	;	    just after the adjusted count/time is elapsed.)
  2305                              <1> 	;	    User's sevice routine must be ended with a
  2306                              <1> 	;	    'iret'. Normal return addresses from system 
  2307                              <1> 	;	    calls or and interrupts will be kept same except
  2308                              <1> 	;	    the timer returns. 			
  2309                              <1>      	;
  2310                              <1> 	;	BH = 0 -> Stop timer event
  2311                              <1> 	;	BL = Timer event number (1 to 255) if BH = 0     	
  2312                              <1> 	;	     If BL = 0, all timer events (which are belongs
  2313                              <1> 	;	      to running process) will be stopped 		    
  2314                              <1> 	;	ECX = Time/Tick count (depending on time count unit)
  2315                              <1> 	;	EDX = Signal return (Response) byte address
  2316                              <1> 	;	      (virtual address in user's memory space)
  2317                              <1> 	; OUTPUT ->
  2318                              <1> 	;	AL = Timer event number	(1 to 255) (max. value = 16)
  2319                              <1> 	;	IF BH Input = 0 & CF = 0 & AL = 0 -> 
  2320                              <1> 	;	     timer event(s) has/have been stopped/finished
  2321                              <1> 	;	CF = 1 & AL = 0 -> no timer setting space to set
  2322                              <1> 	;	CF = 1 & AL > 0 -> timer count unit is not usable
  2323                              <1> 	;
  2324                              <1> 	;	NOTE: To modify a time count for a user function,
  2325                              <1> 	;	      at first, current timer event must be stopped
  2326                              <1> 	;	      then a new timer event (which is related with
  2327                              <1> 	;	      same user function) must be started.
  2328                              <1> 	;		
  2329                              <1> 	;	      Signal return (response) byte may be used for 
  2330                              <1> 	;	      several purposes. Kernel will put this value 
  2331                              <1> 	;	      to requested address during timer interrupt,
  2332                              <1> 	;	      program/user can check this value to understand
  2333                              <1> 	;	      which event has been occurred and what is changed.
  2334                              <1> 	;	      (Multi timer events can share same signal address)
  2335                              <1> 	;	
  2336                              <1> 	;	NOTE: If the process is running while the time count
  2337                              <1> 	;	      is reached, kernel will put signal return (response)
  2338                              <1> 	;	      byte value at requested address during timer
  2339                              <1> 	;	      interrupt and the process will continue to run.
  2340                              <1> 	;	      Program/process must call (jump to) it's timer event
  2341                              <1> 	;	      function as required, for checking the timer event
  2342                              <1> 	;	      status via signal return (response) byte address. 
  2343                              <1> 	;
  2344                              <1> 	;	      If the process is not running (waiting or sleeping
  2345                              <1> 	;	      or released) while the time count is reached,
  2346                              <1> 	;	      it is restarted from where it left, to ensure
  2347                              <1> 	;	      proper multi media (video, audio, clock, timer)
  2348                              <1> 	;	      functionality.
  2349                              <1> 	;
  2350                              <1> 	;	      (It is better to use 'syswait' or 'syssleep',
  2351                              <1> 	;	      or 'sysrele' system call just after the timer
  2352                              <1> 	;	      function. Otherwise, timer events may block other
  2353                              <1> 	;	      processes which are not using timer events.)  	 		 			 		 	
  2354                              <1> 	;	     	      		 			
  2355                              <1> 	; Timer Event Structure: (max. 16 timer events, 16*16 bytes)
  2356                              <1> 	;       Owner:	        resb 1 ; 0 = free
  2357                              <1> 	;		  	       ;>0 = process number (u.uno)
  2358                              <1> 	;	Calback:	resb 1 ; 1 = callback, 0 = response byte
  2359                              <1> 	;	Interrupt:      resb 1 ; 0 = Timer interrupt (or none)
  2360                              <1> 	;		   	       ; 1 = Real Time Clock interrupt 
  2361                              <1> 	;	Response:       resb 1 ; 0 to 255, signal return value
  2362                              <1> 	;	Count Limit:	resd 1 ; count of ticks (total/set)
  2363                              <1> 	;	Current Count: 	resd 1 ; count of ticks (current)
  2364                              <1> 	;	Response Addr:  resd 1 ; response byte (pointer) address
  2365                              <1> 	;
  2366                              <1> 
  2367                              <1> 	; 19/12/2016 (timer callback)
  2368 0000DB2A C605[A8750100]00    <1> 	mov	byte [tcallback], 0 
  2369 0000DB31 C605[A9750100]00    <1> 	mov	byte [trtc], 0
  2370 0000DB38 C705[D0030300]0000- <1> 	mov	dword [u.tcb], 0 ; this is not necessary...
  2370 0000DB40 0000                <1>
  2371                              <1> 
  2372 0000DB42 80FF80              <1> 	cmp	bh, 80h
  2373 0000DB45 7225                <1> 	jb	short systimer_cb2
  2374 0000DB47 7704                <1> 	ja	short systimer_cb0
  2375                              <1> 
  2376 0000DB49 31D2                <1> 	xor	edx, edx ; 0, reset callback address
  2377 0000DB4B EB0B                <1> 	jmp	short systimer_cb1
  2378                              <1> 
  2379                              <1> systimer_cb0:
  2380 0000DB4D 80FF84              <1> 	cmp	bh, 84h	
  2381 0000DB50 7764                <1> 	ja	short systimer_5 ;  undefined, error
  2382                              <1> 
  2383                              <1> 	;mov	byte [tcallback], 1 ; 19/12/2016
  2384 0000DB52 FE05[A8750100]      <1> 	inc	byte [tcallback]
  2385                              <1> 
  2386                              <1> systimer_cb1:
  2387 0000DB58 0FB635[B3030300]    <1> 	movzx	esi, byte [u.uno] ; process number
  2388 0000DB5F 66C1E602            <1> 	shl	si, 2	
  2389 0000DB63 8996[0C010300]      <1> 	mov	[esi+p.tcb-4], edx ; set process timer callback address
  2390                              <1> 				   ; (overwrite prev value if it is set!)
  2391 0000DB69 80E77F              <1> 	and	bh, 7Fh
  2392                              <1> 
  2393                              <1> systimer_cb2:
  2394 0000DB6C 80FF02              <1> 	cmp	bh, 2
  2395 0000DB6F 7445                <1>         je      short systimer_5  ; only 18.2 ticks per second is usable
  2396                              <1> 				  ; 10 milliseconds (100 Hertz) timer 
  2397                              <1> 				  ; will be set later (18/05/2016)
  2398 0000DB71 774B                <1>         ja      short systimer_6 
  2399                              <1> 
  2400 0000DB73 20FF                <1> 	and	bh, bh
  2401 0000DB75 0F84BA000000        <1>         jz      systimer_9        ; stop timer event(s)
  2402                              <1> 
  2403                              <1> 	; bh = 1 (timer interrupt, 18.2 Hz, IBM PC/AT ROMBIOS default)
  2404                              <1> 
  2405                              <1> systimer_19:
  2406 0000DB7B B00A                <1> 	mov	al, 10 ; (*)
  2407                              <1> 
  2408                              <1> systimer_0:
  2409 0000DB7D B710                <1> 	mov	bh, 16
  2410                              <1> 	;
  2411 0000DB7F 383D[6B700100]      <1> 	cmp	[timer_events], bh ; 16 ; 07/06/2016
  2412 0000DB85 7319                <1> 	jnb 	short systimer_3  ; max. 16 timer events
  2413                              <1> 	;
  2414 0000DB87 50                  <1> 	push	eax ; (*)
  2415                              <1> 
  2416 0000DB88 BF[60040300]        <1> 	mov	edi, timer_set  ; beginning address of timer events
  2417                              <1> 				; setting space
  2418 0000DB8D 30C0                <1> 	xor	al, al ; 0
  2419                              <1> systimer_1:
  2420 0000DB8F FEC0                <1> 	inc	al
  2421 0000DB91 803F00              <1> 	cmp	byte [edi], 0 	; is it free space ?
  2422 0000DB94 7639                <1> 	jna	short systimer_7 ; yes
  2423 0000DB96 FECF                <1> 	dec	bh
  2424 0000DB98 7405                <1> 	jz	short systimer_2
  2425 0000DB9A 83C710              <1> 	add	edi, 16
  2426 0000DB9D EBF0                <1> 	jmp	short  systimer_1 ; next event space
  2427                              <1> 
  2428                              <1> systimer_2:
  2429 0000DB9F 58                  <1> 	pop	eax ; (*) discard
  2430                              <1> systimer_3:
  2431 0000DBA0 C605[64030300]00    <1> 	mov	byte [u.r0], 0
  2432                              <1> systimer_4:
  2433 0000DBA7 C705[C8030300]1B00- <1>         mov     dword [u.error], ERR_MISC
  2433 0000DBAF 0000                <1>
  2434                              <1>                                 ; one of miscellaneous/other errors
  2435 0000DBB1 E9F6F6FFFF          <1> 	jmp	error ; cf -> 1
  2436                              <1> 
  2437                              <1> systimer_5:
  2438 0000DBB6 883D[64030300]      <1> 	mov	[u.r0], bh ; Time count unit (=2 or >3)
  2439 0000DBBC EBE9                <1> 	jmp	short systimer_4 ; 07/06/2016
  2440                              <1> 
  2441                              <1> systimer_6:
  2442 0000DBBE 80FF04              <1> 	cmp	bh, 4
  2443 0000DBC1 77F3                <1>         ja      short systimer_5  ; undefined time count unit
  2444                              <1> 	;jb	short systimer_16	
  2445                              <1> 
  2446                              <1> 	;mov	al, 1	; default (use current timer unit)
  2447                              <1> 			; countdown value is in ECX ! 
  2448                              <1> 			; max. value of ecx = 4294967296/10
  2449                              <1>         ;jmp    short systimer_0
  2450                              <1> 	;jmp	short systimer_19	
  2451 0000DBC3 74B6                <1> 	je	short systimer_19
  2452                              <1> 
  2453                              <1> systimer_16:
  2454                              <1> 	; bh = 3
  2455                              <1> 	; timer event via real time clock interrupt
  2456                              <1> 	; interrupt/update frequency: 1 Hz (1 tick per second)
  2457                              <1> 	
  2458 0000DBC5 B0B6                <1> 	mov	al, 182 ; (*) ; 18.2 * 10
  2459 0000DBC7 FE05[A9750100]      <1> 	inc	byte [trtc] ; timer event via real time clock
  2460 0000DBCD EBAE                <1>         jmp     short systimer_0
  2461                              <1> 
  2462                              <1> systimer_7:
  2463 0000DBCF A2[64030300]        <1> 	mov	[u.r0], al ; timer event number
  2464                              <1> 	;
  2465                              <1> 	; edi = address of empty timer event area
  2466 0000DBD4 A0[B3030300]        <1> 	mov	al, [u.uno]
  2467 0000DBD9 FA                  <1> 	cli 	; disable interrupts 
  2468 0000DBDA AA                  <1> 	stosb	; process number
  2469 0000DBDB A0[A8750100]        <1> 	mov	al, [tcallback] ; timer callback flag
  2470 0000DBE0 AA                  <1> 	stosb 	; 1= callback method, 0= signal response byte method
  2471 0000DBE1 A0[A9750100]        <1> 	mov	al, [trtc] ; timer interrupt type
  2472 0000DBE6 AA                  <1> 	stosb	; 1= real time clock, 0= programmable interval timer
  2473 0000DBE7 88D8                <1> 	mov	al, bl ; Signal return (Response) value
  2474 0000DBE9 AA                  <1> 	stosb   ; response byte
  2475 0000DBEA 58                  <1> 	pop	eax ; (*) ; 10 or 182
  2476 0000DBEB 89D3                <1> 	mov	ebx, edx ; virtual address for response/signal byte
  2477 0000DBED F7E1                <1> 	mul	ecx
  2478                              <1> 	; (eax = 10 * count of 18.2 Hz timer ticks)
  2479                              <1> 	; (count down step = 10)
  2480 0000DBEF AB                  <1> 	stosd  ; count limit (reset value)
  2481 0000DBF0 AB                  <1> 	stosd  ; current count value
  2482                              <1> 
  2483                              <1> 	; 19/12/2016
  2484 0000DBF1 803D[A8750100]00    <1> 	cmp	byte [tcallback], 0 ; timer callback method ?
  2485 0000DBF8 7604                <1> 	jna	short systimer_17 ; no	
  2486 0000DBFA 89D8                <1> 	mov	eax, ebx ; virtual address for callback routine 
  2487 0000DBFC EB0D                <1> 	jmp	short systimer_18
  2488                              <1> 
  2489                              <1> systimer_17: ; signal response byte method
  2490                              <1> 	; ebx = virtual address
  2491                              <1> 	; [u.pgdir] = page directory's physical address
  2492                              <1> 	; 20/02/2017
  2493 0000DBFE FE05[AA750100]      <1> 	inc	 byte [no_page_swap] ; 1 
  2494                              <1> 			; Do not add this page to swap queue
  2495                              <1> 			; and remove it from swap queue if it is
  2496                              <1> 			; on the queue.
  2497 0000DC04 E8B180FFFF          <1> 	call	get_physical_addr
  2498 0000DC09 721A                <1> 	jc	short systimer_8 ; 07/06/2016
  2499                              <1> 	; eax = physical address of the virtual address in user's space
  2500                              <1> systimer_18:
  2501 0000DC0B AB                  <1> 	stosd	; response addr (physical) or callback addr (virtual)
  2502 0000DC0C FE05[6B700100]      <1> 	inc	byte [timer_events] ; 07/06/201
  2503                              <1> 	; 02/01/2017
  2504 0000DC12 0FB605[B3030300]    <1> 	movzx	eax, byte [u.uno]
  2505 0000DC19 FE80[FF000300]      <1> 	inc	byte [eax+p.timer-1]	
  2506                              <1> 	;
  2507 0000DC1F FB                  <1> 	sti 	; enable interrupts
  2508 0000DC20 E9A7F6FFFF          <1> 	jmp	sysret
  2509                              <1> 
  2510                              <1> systimer_8:
  2511                              <1> 	; 10/06/2016
  2512                              <1> 	; 07/06/2016
  2513 0000DC25 28C0                <1> 	sub	al, al ; 0
  2514 0000DC27 8847F4              <1> 	mov	[edi-12], al ; clear process number (free timer event)
  2515                              <1> 	;mov	dword [edi], eax ; 0
  2516 0000DC2A FB                  <1> 	sti
  2517 0000DC2B A2[64030300]        <1> 	mov	[u.r0], al ; 0
  2518 0000DC30 E977F6FFFF          <1> 	jmp	error
  2519                              <1> 
  2520                              <1> systimer_9:
  2521                              <1> 	; 10/06/2016
  2522                              <1> 	; 07/06/2016
  2523 0000DC35 28C0                <1> 	sub	al, al
  2524 0000DC37 A2[64030300]        <1> 	mov	byte [u.r0], al ; 0
  2525 0000DC3C 3805[6B700100]      <1> 	cmp     byte [timer_events], al ;  0
  2526 0000DC42 7631                <1> 	jna	short systimer_12
  2527                              <1> 
  2528                              <1> 	; Note: ecx and edx are undefined here
  2529                              <1> 	;	(for stop timer function)
  2530                              <1> 
  2531 0000DC44 BE[60040300]        <1> 	mov	esi, timer_set  ; beginning address of timer events
  2532                              <1> 				; setting space	 
  2533 0000DC49 A0[B3030300]        <1> 	mov	al, [u.uno]
  2534                              <1> 	
  2535 0000DC4E B710                <1> 	mov	bh, 16
  2536                              <1> 
  2537 0000DC50 08DB                <1> 	or	bl, bl
  2538 0000DC52 7544                <1> 	jnz	short systimer_15
  2539                              <1> 
  2540                              <1> 	; clear timer event areas belong to current process
  2541                              <1> 	; (for stopping all timer events belong to current process) 
  2542 0000DC54 FA                  <1> 	cli 	; disable interrupts
  2543                              <1> systimer_10:
  2544                              <1> 	; 10/06/2016
  2545                              <1> 	; 07/06/2016 	
  2546 0000DC55 8A26                <1> 	mov	ah, [esi]
  2547 0000DC57 08E4                <1> 	or	ah, ah ; 0 ?
  2548 0000DC59 7411                <1> 	jz	short systimer_11
  2549 0000DC5B 38C4                <1> 	cmp	ah, al ; is the process number (owner) same ?
  2550 0000DC5D 750D                <1>         jne     short systimer_11 ; no
  2551                              <1> 
  2552                              <1> 	;mov	byte [esi], 0
  2553 0000DC5F 66C7060000          <1> 	mov	word [esi], 0 ; clear
  2554                              <1> 	;mov	dword [esi+12], 0 ; clear
  2555                              <1> 
  2556 0000DC64 FE0D[6B700100]      <1> 	dec	byte [timer_events]
  2557 0000DC6A 7409                <1> 	jz	short systimer_12
  2558                              <1> 
  2559                              <1> systimer_11:
  2560 0000DC6C FECF                <1> 	dec	bh
  2561 0000DC6E 7405                <1> 	jz	short systimer_12
  2562 0000DC70 83C610              <1> 	add	esi, 16
  2563 0000DC73 EBE0                <1> 	jmp	short systimer_10
  2564                              <1> 
  2565                              <1> systimer_12:
  2566 0000DC75 0FB635[B3030300]    <1> 	movzx	esi, byte [u.uno]
  2567 0000DC7C 08DB                <1> 	or	bl, bl ; all timer events or one timer event ?
  2568 0000DC7E 740C                <1> 	jz	short systimer_13
  2569 0000DC80 8A9E[FF000300]      <1> 	mov	bl, [esi+p.timer-1]
  2570 0000DC86 20DB                <1> 	and	bl, bl	; previous number of timer events for the process
  2571 0000DC88 7408                <1> 	jz	short systimer_14
  2572 0000DC8A FECB                <1> 	dec	bl  ; previous number of timer events for the process - 1
  2573                              <1> systimer_13:
  2574 0000DC8C 889E[FF000300]      <1> 	mov	[esi+p.timer-1], bl ; 0 ; no timer events for process
  2575                              <1> systimer_14:
  2576 0000DC92 FB                  <1> 	sti	; enable interrupts
  2577 0000DC93 E934F6FFFF          <1> 	jmp	sysret
  2578                              <1> 
  2579                              <1> systimer_15:
  2580 0000DC98 38FB                <1> 	cmp	bl, bh ; 16
  2581 0000DC9A 0F8707FFFFFF        <1>         ja      systimer_4      ; max. 16 timer events !
  2582                              <1> 	;
  2583 0000DCA0 88DA                <1> 	mov	dl, bl
  2584 0000DCA2 FECA                <1> 	dec	dl  ; 16 -> 15 ... 1 -> 0 
  2585 0000DCA4 C0E204              <1> 	shl	dl, 4 ; * 16
  2586 0000DCA7 0FB6FA              <1> 	movzx	edi, dl
  2587 0000DCAA 01F7                <1> 	add	edi, esi ; timer_set 
  2588                              <1> 	
  2589 0000DCAC 3A07                <1> 	cmp	al, [edi] ; process number
  2590 0000DCAE 0F85F3FEFFFF        <1>         jne     systimer_4
  2591                              <1> 	
  2592                              <1> 	; same process ID
  2593 0000DCB4 FA                  <1> 	cli	; disable interrupts
  2594                              <1>  	; 10/06/2016 ; 02/01/2017
  2595                              <1> 	;mov	byte [edi], 0 
  2596 0000DCB5 66C7070000          <1> 	mov	word [edi], 0 ; clear
  2597                              <1> 	;mov	dword [edi+12], 0 ; clear
  2598 0000DCBA FE0D[6B700100]      <1> 	dec	byte [timer_events]
  2599 0000DCC0 EBB3                <1> 	jmp	short systimer_12
  2600                              <1> 
  2601                              <1> sysvideo: ; VIDEO DATA TRANSFER FUNCTIONS
  2602                              <1> 	; 21/12/2020
  2603                              <1> 	; 14/12/2020
  2604                              <1> 	; 12/12/2020
  2605                              <1> 	; 10/12/2020, 11/12/2020
  2606                              <1> 	; 03/12/2020, 04/12/2020
  2607                              <1> 	; 22/11/2020, 23/11/2020
  2608                              <1> 	; 21/11/2020 (TRDOS 386 v2.0.3)
  2609                              <1> 	; 12/05/2017
  2610                              <1> 	; 11/07/2016
  2611                              <1> 	; 13/06/2016
  2612                              <1> 	; 16/05/2016 - TRDOS 386 (TRDOS v2.0)
  2613                              <1> 	;
  2614                              <1> 	; VIDEO DATA TRANSFER FUNCTIONS:
  2615                              <1> 	;
  2616                              <1> 	; Inputs:
  2617                              <1> 	;	BH = 0 = VIDEO BIOS Mode 3, tty/text mode data transfers
  2618                              <1> 	;	     BL = 
  2619                              <1> 	;		Bits 0&1, Transfer direction
  2620                              <1> 	;	     	 	0 - System to system
  2621                              <1> 	;			1 - User to system
  2622                              <1> 	;			2 - System to user
  2623                              <1> 	;			3 - User to user (undefined)
  2624                              <1> 	;		Bits 2&3, Transfer Type
  2625                              <1> 	;			0 - Display page transfer	
  2626                              <1> 	;	     		1 - Display page window transfer
  2627                              <1> 	;	     		2 - Frame/Viewport/Window address transfer
  2628                              <1> 	;			3 - Window handle transfer (undefined)
  2629                              <1> 	;		; 23/11/2020
  2630                              <1> 	;		Bits 4..7 - Reserved, undefined (must be 0)
  2631                              <1> 	;
  2632                              <1> 	;	     /// BL = 0 -> System to system (display page) transfer
  2633                              <1> 	;		 CL = Source page 
  2634                              <1> 	;		 DL = Destination page
  2635                              <1> 	;	     /// BL = 1&2 -> user to system & system to user transfer
  2636                              <1> 	;		 ECX = User' buffer address
  2637                              <1> 	;		 DL = Video page
  2638                              <1> 	;	     /// BL = 5&6 -> user to system, system to user transfer 
  2639                              <1> 	;		(system window is in current/active display page)	 	 		
  2640                              <1> 	;		 ESI = User's buffer address
  2641                              <1> 	;		 ECX Low 16 bits = Top left column (X1 position)
  2642                              <1> 	;		 ECX High 16 bits = Top row (Y1 position)
  2643                              <1> 	;		 EDX Low 16 bits = Bottom right column (X2 position)
  2644                              <1> 	;		 EDX High 16 bits = Bottom row (Y2 position)
  2645                              <1>         ;                If BL = 5 ->
  2646                              <1> 	;		 EDI = Swap address (in user's memory space)
  2647                              <1> 	;		 (If swap address > 0, previous content of the window
  2648                              <1> 	;		 will be saved into swap area in user's memory space)		
  2649                              <1> 	;	     /// BL = 4 -> system to system transfer
  2650                              <1> 	;		 ESI = System's source buffer (video page) address
  2651                              <1> 	;		 ECX Low 16 bits = Top left column (X1 position)
  2652                              <1> 	;		 ECX High 16 bits = Top row (Y1 position)
  2653                              <1> 	;		 EDX Low 16 bits = Bottom right column (X2 position)
  2654                              <1> 	;		 EDX High 16 bits = Bottom row (Y2 position)
  2655                              <1> 	;		 EDI = System's destination buffer (video page) address
  2656                              <1> 	;		; 22/11/2020
  2657                              <1> 	;	     /// BL = 9&10 -> user to system, system to user transfer 
  2658                              <1> 	;		(system window is in current/active display page)	 	 		
  2659                              <1> 	;		 ESI = User's buffer address
  2660                              <1> 	;		  CX = offset in video page (char position in 80*25)
  2661                              <1> 	;		  DX = transfer count (character count, max. 80*25)
  2662                              <1>         ;                If BL = 5 ->
  2663                              <1> 	;		 EDI = Swap address (in user's memory space)
  2664                              <1> 	;		 (If swap address > 0, previous content of the window
  2665                              <1> 	;		 will be saved into swap area in user's memory space)	
  2666                              <1> 	;	     /// BL = 8 -> system to system transfer
  2667                              <1> 	;		 ESI = System's source buffer (video page) address
  2668                              <1> 	;		  CX = offset in video page (char position in 80*25)
  2669                              <1> 	;		  DX = transfer count (character count, max. 80*25)
  2670                              <1> 	;		 EDX High 16 bits = Bottom row (Y2 position)
  2671                              <1> 	;		 EDI = System's destination buffer (video page) address
  2672                              <1> 	;
  2673                              <1> 	;		; 23/11/2020 (major modification)
  2674                              <1> 	;		; 22/11/2020 (bugfixes and extensions)
  2675                              <1> 	;	BH = 1 = VGA Graphics (0A0000h) data transfers
  2676                              <1> 	;	     BL = 
  2677                              <1> 	;	     	x0h = Fill color (color in CL) (64K)
  2678                              <1> 	;		x1h = User to system display page transfer
  2679                              <1> 	;		x2h = System to user display page transfer
  2680                              <1> 	;		x3h = NOT bits in window (ECX, EDX)
  2681                              <1> 	;		x4h = Window copy (system to system)	
  2682                              <1> 	;	     	x5h = User to system window transfer
  2683                              <1> 	;	     	x6h = System to user window transfer
  2684                              <1> 	;		x7h = AND display page bytes with CL
  2685                              <1> 	;		x8h = OR display page bytes with CL
  2686                              <1> 	;		x9h = XOR display page bytes with CL
  2687                              <1> 	;		; 22/11/2020 (TRDOS v2.0.3)
  2688                              <1> 	;	        xAh = INC display page bytes
  2689                              <1> 	;	        xBh = DEC display page bytes
  2690                              <1> 	;	        xCh = NEG display page bytes
  2691                              <1> 	;	        xDh = NOT display page bytes
  2692                              <1> 	;
  2693                              <1> 	;		x = 0 -> screen width = 320
  2694                              <1> 	;		x = 1 -> screen width = 640
  2695                              <1> 	;		x = 2 -> screen width = 800
  2696                              <1> 	;
  2697                              <1> 	;	     /// BL = 0 -> Fill color (all screen pixels)
  2698                              <1> 	;		 CL = Color value, 
  2699                              <1> 	;		 If CH > 0, color in CL will be mixed with pixel color  
  2700                              <1> 	;	     /// BL = 1&2 -> user to system & system to user transfer
  2701                              <1> 	;		 ECX = User buffer
  2702                              <1> 	;	     /// BL = 5&6 -> user to system, system to user transfer 
  2703                              <1> 	;		(window in current display page and in current mode)		 		
  2704                              <1> 	;		 ESI = User's buffer address
  2705                              <1> 	;		 ECX Low 16 bits = Top left column (X1 position)
  2706                              <1> 	;		 ECX High 16 bits = Top row (Y1 position)
  2707                              <1> 	;		 EDX Low 16 bits = Bottom right column (X2 position)
  2708                              <1> 	;		 EDX High 16 bits = Bottom row (Y2 position)
  2709                              <1>        	;	     /// BL = 4 -> system to system (window) transfer 
  2710                              <1> 	;		 ESI = System's source buffer (video page) address
  2711                              <1> 	;		 ECX Low 16 bits = Top left column (X1 position)
  2712                              <1> 	;		 ECX High 16 bits = Top row (Y1 position)
  2713                              <1> 	;		 EDX Low 16 bits = Bottom right column (X2 position)
  2714                              <1> 	;		 EDX High 16 bits = Bottom row (Y2 position)
  2715                              <1> 	;		 EDI = System's destination buffer (video page) address
  2716                              <1> 	;	     /// BL = 3 -> NOT byte in display page/memory 
  2717                              <1> 	;		 ECX Low 16 bits = Top left column (X1 position)
  2718                              <1> 	;		 ECX High 16 bits = Top row (Y1 position)
  2719                              <1> 	;		 EDX Low 16 bits = Bottom right column (X2 position)
  2720                              <1> 	;		 EDX High 16 bits = Bottom row (Y2 position)
  2721                              <1> 	;
  2722                              <1> 	;	BH = 2 = Super VGA, LINEAR FRAME BUFFER data transfers
  2723                              <1> 	;	     BL = 
  2724                              <1> 	;	     	0 = Fill color (color in ECX) (Frame buffer size)
  2725                              <1> 	;		1 = User to system display page transfer
  2726                              <1> 	;		2 = System to user display page transfer
  2727                              <1> 	;		3 = NOT bits in window (ECX, EDX)
  2728                              <1> 	;		4 = Window copy (system to system)	
  2729                              <1> 	;	     	5 = User to system window transfer
  2730                              <1> 	;	     	6 = System to user window transfer
  2731                              <1> 	;		7 = AND display page bytes with ECX
  2732                              <1> 	;		8 = OR display page bytes with ECX
  2733                              <1> 	;		9 = XOR display page bytes with ECX
  2734                              <1> 	;		; 22/11/2020 (TRDOS v2.0.3)
  2735                              <1> 	;	       10 = INC display page bytes (color mask in CL) 
  2736                              <1> 	;	       11 = DEC display page bytes (color mask in CL)
  2737                              <1> 	;	       12 = NEG display page bytes (color mask in CL)
  2738                              <1> 	;	       13 = NOT display page bytes (color mask in CL)
  2739                              <1> 	;
  2740                              <1> 	;	     /// BL = 0 -> Fill color (all screen pixels)
  2741                              <1> 	;		 CL = Color value, 
  2742                              <1> 	;		 If CH > 0, color in CL will be mixed with pixel color 
  2743                              <1> 	;	     /// BL = 1&2 -> user to system & system to user transfer
  2744                              <1> 	;		 ECX = User buffer
  2745                              <1> 	;	     /// BL = 5&6 -> user to system, system to user transfer 
  2746                              <1> 	;		(window in current display page and in current mode)	 	 		
  2747                              <1> 	;		 ESI = User's buffer address
  2748                              <1> 	;		 ECX Low 16 bits = Top left column (X1 position)
  2749                              <1> 	;		 ECX High 16 bits = Top row (Y1 position)
  2750                              <1> 	;		 EDX Low 16 bits = Bottom right column (X2 position)
  2751                              <1> 	;		 EDX High 16 bits = Bottom row (Y2 position)
  2752                              <1> 	;	     /// BL = 4 -> system to system (window) transfer 
  2753                              <1> 	;		 ESI = System's source buffer (video page) address
  2754                              <1> 	;		 ECX Low 16 bits = Top left column (X1 position)
  2755                              <1> 	;		 ECX High 16 bits = Top row (Y1 position)
  2756                              <1> 	;		 EDX Low 16 bits = Bottom right column (X2 position)
  2757                              <1> 	;		 EDX High 16 bits = Bottom row (Y2 position)
  2758                              <1> 	;		 EDI = System's destination buffer (video page) address
  2759                              <1> 	;	     /// BL = 3 -> NOT byte in display page/memory 
  2760                              <1> 	;		 ECX Low 16 bits = Top left column (X1 position)
  2761                              <1> 	;		 ECX High 16 bits = Top row (Y1 position)
  2762                              <1> 	;		 EDX Low 16 bits = Bottom right column (X2 position)
  2763                              <1> 	;		 EDX High 16 bits = Bottom row (Y2 position)
  2764                              <1> 	;
  2765                              <1> 	;		Example: (21/11/2020)
  2766                              <1> 	;			esi = 0B0000h (window start value)
  2767                              <1> 	;			ecx = 00000000h (start at row 0, column 0) 
  2768                              <1> 	;			edx = 0018004Fh (end at row 24,column 79)
  2769                              <1> 	;			row count= 25, column count = 80
  2770                              <1> 	;			(end) byte offset = (80*2)*24+(79*2) = 3998	
  2771                              <1> 	;			end value of esi = 0B8F9Eh (last word of page)
  2772                              <1> 	;			(! end address is included to transfer !)
  2773                              <1> 	;			((just as line start and line end coordinates)) 
  2774                              <1> 	;
  2775                              <1> 	; Outputs:
  2776                              <1> 	;	EAX = transfer/byte count
  2777                              <1> 	;
  2778                              <1> 	;	NOTE: If the source or destination address passes out of
  2779                              <1> 	;	video pages (display memory limits), data will not be transferred
  2780                              <1> 	;	and EAX will return as 0.
  2781                              <1> 	;
  2782                              <1> 	; PIXEL READ/WRITE
  2783                              <1> 	;
  2784                              <1> 	;	BH = 3 = Read/Write pixel(s) -for all graphics modes-
  2785                              <1> 	;	     BL = 
  2786                              <1> 	;	     bits 0&1&2
  2787                              <1> 	;		0 = Read one pixel
  2788                              <1> 	;		1 = Write one pixel
  2789                              <1> 	;	     	2 = Read two pixels
  2790                              <1> 	;		3 = Write two pixels
  2791                              <1> 	;	     	4 = Read four pixels
  2792                              <1> 	;		5 = Write four pixels
  2793                              <1> 	;		6 - read one nibble (4 bits)
  2794                              <1> 	;		7 - write one nibble (4 bits)
  2795                              <1> 	;	     bit 3 - color mix option (1 = mix, 0 = overwrite)
  2796                              <1> 	;	     bit 4 - true color (dword color number) option
  2797                              <1> 	;		   (linear frame buffer address will be used)
  2798                              <1> 	;	     bit 5 - alpha byte will be written if bit 5 is 1			 	
  2799                              <1> 	;	     bit 6 - use CL if bit 6 is set (do not use ECX or CX)
  2800                              <1> 	;	     bit 7 - force/use linear frame buffer address
  2801                              <1> 	;		    (if bit 7&4 are 0, 0A0000h address will be used)		
  2802                              <1> 	;		
  2803                              <1> 	;	     CL = color for writing pixel(s) or
  2804                              <1>  	;	     ECX = color for writing pixel(s) in true color modes
  2805                              <1> 	;		  or ecx is used as separate color bytes for reading
  2806                              <1> 	;		  or writing 2 or 4 pixels in byte order
  2807                              <1> 	;		 (24 bit will be written for 24 bit true color modes)
  2808                              <1> 	;		 (alpha byte will be regarded for 32 bit true colors)
  2809                              <1> 	;		 (but alpha byte will not written if BL bit 5 is 0)
  2810                              <1> 	;
  2811                              <1> 	;	     EDX = Offset from start of video memory (0A0000h)
  2812                              <1> 	;		   or start of linear frame buffer
  2813                              <1> 	;		  (edx contains nibble offset if BL bits 1&2 are 1)
  2814                              <1> 	;		  (nibble read/write is used with low 4 bits of CL) 
  2815                              <1> 	;
  2816                              <1> 	; Outputs:
  2817                              <1> 	;	EAX = pixel color (according to BL and CL input)
  2818                              <1> 	;	
  2819                              <1> 	;
  2820                              <1> 	; DIRECT (STANDARD VGA/CGA) DISPLAY MEMORY ACCESS FUNCTIONS:
  2821                              <1> 	;
  2822                              <1> 	;	BH = 4 = CGA direct video memory (0B8000h, 32K) access
  2823                              <1> 	;		Page directory & page tables of the user's
  2824                              <1> 	;		program will be updated to direct access to
  2825                              <1> 	;		0B8000h (32K) video (CGA, color) memory; if
  2826                              <1> 	;		there is not a permission conflict or lock!  
  2827                              <1> 	;	        (User's program/process will have permission to
  2828                              <1> 	;		access locked display memory if the owner is
  2829                              <1> 	;		it's parent.)
  2830                              <1>         ;
  2831                              <1> 	;	    Screen width = 320	
  2832                              <1> 	;
  2833                              <1> 	;	BH = 5 = VGA direct video memory (0A0000h, 64K) access
  2834                              <1> 	;		Page directory & page tables of the user's
  2835                              <1> 	;		program will be updated to direct access to
  2836                              <1> 	;		0A0000h (64K) video (VGA) memory; if there is not
  2837                              <1> 	;		a permission conflict or lock!  
  2838                              <1> 	;	        (User's program/process will have permission to
  2839                              <1> 	;		access locked display memory if the owner is
  2840                              <1> 	;		it's parent.)
  2841                              <1> 	;	
  2842                              <1> 	;	    ; 23/11/2020		
  2843                              <1> 	;	    Screen width options = 320, 640, 800 
  2844                              <1> 	;			
  2845                              <1> 	; Outputs:
  2846                              <1> 	;	EAX = Display memory address for direct access
  2847                              <1> 	;	      0A0000h for VGA, 0B8000h for CGA	
  2848                              <1> 	;	(Display memory size: 32K for CGA, 64K for VGA)
  2849                              <1> 	; 	EAX = 0 if display page access permission has been denied. 
  2850                              <1> 	;	      (Locked!) 	
  2851                              <1> 	;	      	 	
  2852                              <1> 	; LINEAR FRAME BUFFER ACCESS FUNCTIONS:
  2853                              <1> 	;
  2854                              <1> 	;	BH = 6 = Linear Frame Buffer direct video memory access
  2855                              <1> 	;
  2856                              <1> 	;		Page directory & page tables of the user's
  2857                              <1> 	;		program will be updated to direct access to
  2858                              <1> 	;		the configured LFB (Linear Frame Buffer) address,
  2859                              <1> 	;		if there is not a permission conflict or lock!  
  2860                              <1> 	;	        (User's program/process will have permission to
  2861                              <1> 	;		access locked display memory if the owner is
  2862                              <1> 	;		it's parent.)
  2863                              <1> 	;
  2864                              <1> 	;	   ; 10/12/2020
  2865                              <1> 	;	   BL = 0FFh -> Direct LFB access for current video mode
  2866                              <1> 	;	   BL = XXh < 0FFh -> Direct LFB access
  2867                              <1> 	; 			      for VESA video mode 1XXh	
  2868                              <1> 	;		
  2869                              <1> 	;		Return: EAX = Linear Frame Buffer address
  2870                              <1> 	;			(EAX = 0 -> error)
  2871                              <1> 	;		     If EAX > 0
  2872                              <1> 	;			EDX = Frame Buffer Size in bytes
  2873                              <1> 	;		         BH = Requested Video Mode - 100h
  2874                              <1> 	;		              (VESA VBE video modes)	
  2875                              <1> 	;		         BL = bits per pixel
  2876                              <1> 	;			      8 = 256 colors, 8
  2877                              <1> 	;		             16 = 65536 colors, 5-6(G)-5 
  2878                              <1> 	;		             24 = RGB, 16M colors, 8-8-8
  2879                              <1> 	;		             32 = RGB + alpha bytes, 8-8-8-8
  2880                              <1> 	;		     If BH = 0FFh
  2881                              <1> 	;		        BL = VGA/CGA video mode (also EAX = 0)
  2882                              <1> 	;
  2883                              <1> 	;		** Function will return with EAX = 0 if the mode
  2884                              <1> 	;		is not a valid VESA VBE video mode as 1??h ** 	
  2885                              <1> 	;
  2886                              <1> 	;		ECX = Pixel resolution
  2887                              <1> 	;		      CX = Width (320, 640, 800, 1024, 1366, 1920)
  2888                              <1> 	;		      High 16 bits of ECX = Height 
  2889                              <1> 	;
  2890                              <1> 	; 	23/11/2020
  2891                              <1> 	; ***	GET VIDEO MODE & LINEAR FRAME BUFFER INFO   
  2892                              <1> 	;	(This function -7- also is used for VGA and CGA modes)
  2893                              <1> 	; 	
  2894                              <1> 	;	BH = 7 = Get Linear Frame Buffer info
  2895                              <1> 	;
  2896                              <1> 	;	   ; 10/12/2020
  2897                              <1> 	;	   BL = 0FFh -> Current video mode
  2898                              <1> 	;	   BL = XXh < 0FFh -> LFB info for specified video mode
  2899                              <1> 	; 			      as VESA VBE video mode 1XXh
  2900                              <1> 	;		Return:
  2901                              <1> 	;		EAX = Frame Buffer Address (0 = is not in use)
  2902                              <1> 	;		EDX = Frame Buffer Size in bytes
  2903                              <1> 	;		 BH = Requested Video Mode - 100h
  2904                              <1> 	;		     (VESA VBE video modes)	
  2905                              <1> 	;		 BL = bits per pixel
  2906                              <1> 	;			8 = 256 colors, 8
  2907                              <1> 	;		       16 = 65536 colors, 5-6(G)-5 
  2908                              <1> 	;		       24 = RGB, 16M colors, 8-8-8
  2909                              <1> 	;		       32 = RGB + alpha bytes, 8-8-8-8
  2910                              <1> 	;		If BH = 0FFh
  2911                              <1> 	;		   BL = VGA/CGA video mode (also EAX = 0)						
  2912                              <1> 	;
  2913                              <1> 	;		Note:	
  2914                              <1> 	;		Alpha byte will be used as virtual color index.
  2915                              <1> 	;		(32 bit pixel colors.. byte 0,1,2 rgb and 3 alpha)
  2916                              <1> 	;
  2917                              <1> 	;		** Function will return with EAX = 0 if the mode
  2918                              <1> 	;		is not a valid VESA VBE video mode as 1??h ** 	
  2919                              <1> 	;
  2920                              <1> 	;		ECX = Pixel resolution
  2921                              <1> 	;		      CX = Width (320, 640, 800, 1024, 1366, 1920)
  2922                              <1> 	;		      High 16 bits of ECX = Height  
  2923                              <1> 	;
  2924                              <1> 	;	NOTE: Each process will have it's own frame buffer
  2925                              <1> 	;	      address and resolution parameters in 'u' area.
  2926                              <1> 	;	      Then, if the current frame buffer & resolution
  2927                              <1> 	;	      is different, frame buffer r/w functions
  2928                              <1> 	;	      will use scale factor to convert process's
  2929                              <1>         ;             pixel coordinates to actual screen coordinates.                            
  2930                              <1> 	;	      resolution -> dimensional scale
  2931                              <1> 	;	      color size -> color scale
  2932                              <1> 	;	     * RGB (TRUE) colors to 256 colors conversion:	
  2933                              <1>         ;             TRUE Colors -> 8,8,8 (R,G,B; byte 0 is R)            
  2934                              <1> 	;	      256 colors -> 2,2,2,2 (R,G,B,L; bit 0&1 is R)
  2935                              <1> 	; 		  bit 6&7 -> luminosity base level (0,1,2,3)
  2936                              <1> 	;		  bit 4&5 -> blue level (0,1,2,3)
  2937                              <1> 	;		  bit 2%3 -> green level (0,1,2,3)
  2938                              <1> 	;		  bit 0&1 -> red level (0,1,2,3)
  2939                              <1> 	;	      Example: total red level : luminosity + red level   				
  2940                              <1> 	;	      Luminosity base level: 0 -> 16
  2941                              <1> 	;		 		     1 -> 32
  2942                              <1> 	;				     2 -> 64
  2943                              <1> 	;				     3 -> 128
  2944                              <1> 	;	      Color level:	
  2945                              <1> 	;				    0 -> 0
  2946                              <1> 	;				    1 -> luminosity level
  2947                              <1> 	;				    2 -> luminosity level + 64
  2948                              <1> 	;				    3 -> 255
  2949                              <1> 	;	     Luminosity base level = min (R,G,B)
  2950                              <1> 	;			if it is <16, it will be set to 16
  2951                              <1> 	;	     Color levels: Color values are fixed to (nearest) 
  2952                              <1> 	;		   one of all possible set level (step) values
  2953                              <1> 	;		   (according to luminosity base level); then
  2954                              <1> 	;		   color levels are set to R-L, G-L, B-L.
  2955                              <1> 	;	 For example: If luminosity base level is 32
  2956                              <1> 	;		  all possible set values are 0, 32, 96, 255. 	 			
  2957                              <1> 	;
  2958                              <1> 	;	    * RGB (TRUE) colors to 16 colors conversion:
  2959                              <1> 	;	    16 colors: R,B,G,L bits (4 bits)
  2960                              <1> 	;	    	   If any one of R,G,B >= 128 L = 1 		     	
  2961                              <1>  	;		   If max. value of (R,G,B) >= 32, it is 1
  2962                              <1> 	;		      else all color bits (R&G&B&L) are 0
  2963                              <1> 	;		   If the second value >= max. value / 2
  2964                              <1> 	;		      it is 1
  2965                              <1> 	;		   If third value value >= max. value / 2
  2966                              <1> 	;		      it is 1
  2967                              <1> 	;	    Example: R = 132, G = 64, B = 78
  2968                              <1> 	;		     L = 1, R = 1
  2969                              <1> 	;		     G < 66 --> G = 0
  2970                              <1> 	;		     B >= 66 --> B = 1
  2971                              <1> 	;
  2972                              <1> 	; 10/12/2020
  2973                              <1> 	; SET VIDEO MODE (& RETURN LFB INFO for VESA VBE VIDEO MODES) 	
  2974                              <1> 	;	
  2975                              <1> 	;	BH = 8 = Set Video Mode
  2976                              <1> 	;		
  2977                              <1> 	;		BL = Requested Video Mode (method)
  2978                              <1> 	;		If BL = 0FFh
  2979                              <1> 	;		   CX = VESA VBE Video Mode
  2980                              <1> 	;		   ; 11/12/2020
  2981                              <1> 	;		   If EDX > 0 -> LFB INFO (user) buffer addr	
  2982                              <1> 	;		If BL < 0FFh, it is VGA/CGA video mode and
  2983                              <1> 	;			CX & EDX will not be used
  2984                              <1> 	;
  2985                              <1> 	;	    NOTE: The last VESA VBE video mode is 11Bh but
  2986                              <1> 	;	    TRDOS 386 will permit to set video mode upto 11Fh.
  2987                              <1> 	;	    Above 11Fh, from 140h to 1FEh, it will be accepted
  2988                              <1> 	;	    as Bochs/Plex86 emulator video mode and it will be
  2989                              <1> 	;	    used only if [vbe3] = 2 and detected
  2990                              <1> 	;	    video bios is BOCHS/PLEX86/QEMU/VIRTUALBOX vbios.
  2991                              <1> 	;	 	  	 		 	
  2992                              <1> 	; Outputs:
  2993                              <1> 	;	EAX = Requested (Proper) video mode number + 1
  2994                              <1> 	;	      ("dec eax" by user will give requested video mode),
  2995                              <1> 	;
  2996                              <1> 	;	If BL input is 0FFh
  2997                              <1> 	;	   EDX = LFBINFO table/structure (in user's buffer addr)	
  2998                              <1> 	;	   EDX = 0 -> Invalid LFBINFO (do not use it)
  2999                              <1> 	;
  3000                              <1> 	;	EAX = 0 -> Error (but EDX will not be changed)
  3001                              <1> 	;
  3002                              <1> 	; 03/12/2020
  3003                              <1> 	; VESA VBE3 VIDEO BIOS (32 bit) PROTECTED MODE INTERFACE SETTINGS
  3004                              <1> 	;	
  3005                              <1> 	;	BH = 9 = set/get VBE3 Protected Mode Interface parameters
  3006                              <1> 	;		
  3007                              <1> 	;		BL = 0 - Get protected mode interface status
  3008                              <1> 	;			Return: AL = [pmi32] + 1 (AL = 1 or 2)
  3009                              <1> 	;		BL = 1 - Disable protected mode interface
  3010                              <1> 	;			([pmi32] = 0)
  3011                              <1> 	;		 	Return: AL = 1	
  3012                              <1> 	;		BL = 2 - Enable protected mode Interface
  3013                              <1> 	;			([pmi32] = 1)
  3014                              <1> 	;			Return: AL = 2
  3015                              <1> 	;
  3016                              <1> 	;		Bl > 2 : not implemented yet (03/12/2020)
  3017                              <1> 	;
  3018                              <1> 	;		If [vbe3] <> 3 --> AL = 0
  3019                              <1> 	;
  3020                              <1> 
  3021                              <1> 	; 16/05/2016
  3022 0000DCC2 31C0                <1> 	xor	eax, eax
  3023 0000DCC4 A3[64030300]        <1> 	mov	[u.r0], eax
  3024 0000DCC9 20FF                <1> 	and	bh, bh
  3025 0000DCCB 0F858A020000        <1> 	jnz	sysvideo_13 ; 11/07/2016
  3026                              <1> 
  3027                              <1> 	;; 21/11/2020 (TRDOS 386 v2.0.3)
  3028                              <1> 	;; tty/text mode transfers are only for video mode 3
  3029                              <1> 
  3030                              <1> 	; 22/11/2020
  3031                              <1> 	;cmp	byte [CRT_MODE], 3 ; 80x25 text, 16 colors
  3032                              <1> 	;jne	sysret ; invalid (nothing to do), [u.r0] = 0	
  3033                              <1> 	
  3034                              <1> 	; 23/11/2020
  3035                              <1> 	; bit 7,6,5,4 of BL are reserved and it must be 0
  3036                              <1> 	;	 	 for current 'sysvideo' version
  3037 0000DCD1 F6C3F0              <1> 	test	bl, 0F0h
  3038 0000DCD4 0F85F2F5FFFF        <1> 	jnz	sysret ; invalid (undefined) ! 
  3039                              <1> 
  3040                              <1> 	; Video mode 0, 80*25 text mode, CGA 16 colors  ; [CRT_MODE] = 3
  3041 0000DCDA 88DF                <1> 	mov	bh, bl
  3042 0000DCDC C0EF02              <1> 	shr	bh, 2 ; 4..7 -> 1, 8..11 -> 2, 12..15 -> 3
  3043                              <1> 	; 21/11/2020
  3044                              <1> 	;and	bh, bh
  3045 0000DCDF 0F8592000000        <1>         jnz	sysvideo_4  ; Display page window transfer etc.
  3046                              <1> 
  3047                              <1> 	; Display page (complete) transfer
  3048                              <1> 
  3049 0000DCE5 BF00800B00          <1> 	mov	edi, 0B8000h
  3050                              <1> 	; dl = display page number, destination
  3051 0000DCEA 66B80010            <1> 	mov	ax, 4096 ; 21/11/2020
  3052 0000DCEE 20D2                <1> 	and	dl, dl
  3053 0000DCF0 7413                <1> 	jz	short sysvideo_1
  3054 0000DCF2 80FA07              <1> 	cmp	dl, 7
  3055 0000DCF5 0F87D1F5FFFF        <1> 	ja	sysret ; invalid (nothing to do), [u.r0] = 0
  3056                              <1> sysvideo_0:
  3057                              <1> 	; page lenght = 4096 bytes (but page content is 80*25*2 bytes)
  3058 0000DCFB 81C700100000        <1> 	add	edi, 4096 ; 21//11/2020 ([CRT_LEN] = 1000h for mode 3)
  3059 0000DD01 FECA                <1> 	dec	dl
  3060 0000DD03 75F6                <1> 	jnz	short sysvideo_0	
  3061                              <1> sysvideo_1:	
  3062 0000DD05 80E303              <1> 	and	bl, 3
  3063 0000DD08 752A                <1> 	jnz	short sysvideo_2 ; user to system display page transfer
  3064                              <1> 	; cl = display page number, source
  3065 0000DD0A 80F907              <1> 	cmp	cl, 7
  3066 0000DD0D 0F87B9F5FFFF        <1> 	ja	sysret ; invalid (nothing to do), [u.r0] = 0
  3067                              <1> 	; system to system video/display page transfer (mode 0)
  3068                              <1> 	; 21/11/2020
  3069                              <1> 	;mov	esi, 0B8000h
  3070                              <1> 	;movzx	eax, cl
  3071                              <1> 	;mov	edx, 4096 ; [CRT_LEN] = 1000h for video mode 3
  3072                              <1> 	;mov	ecx, edx
  3073                              <1> 	;mul	edx
  3074                              <1> 	;add	esi, eax
  3075 0000DD13 0FB6F1              <1> 	movzx	esi, cl
  3076 0000DD16 66C1E60C            <1> 	shl	si, 12 ; * 4096
  3077 0000DD1A 81C600800B00        <1> 	add	esi, 0B8000h 
  3078                              <1> 
  3079                              <1> 	; 21/11/2020
  3080                              <1> 	;mov	ecx, 4096
  3081 0000DD20 89C1                <1> 	mov	ecx, eax ; 4096
  3082                              <1> 	;mov	[u.r0], ecx ; 4096 bytes
  3083 0000DD22 66890D[64030300]    <1> 	mov	[u.r0], cx
  3084                              <1> 
  3085 0000DD29 66C1E902            <1> 	shr	cx, 2 ; / 4
  3086 0000DD2D F3A5                <1> 	rep	movsd
  3087 0000DD2F E998F5FFFF          <1> 	jmp	sysret	
  3088                              <1> sysvideo_2:  
  3089 0000DD34 80FB02              <1> 	cmp	bl, 2
  3090 0000DD37 0F878FF5FFFF        <1>         ja      sysret; invalid (user to user), [u.r0] = 0
  3091 0000DD3D 721D                <1> 	jb	short sysvideo_3 ; user to system
  3092                              <1> 	; system to user video/display page transfer (mode 0)
  3093 0000DD3F 89FE                <1> 	mov	esi, edi
  3094 0000DD41 89CF                <1> 	mov	edi, ecx ; user buffer
  3095                              <1> 	; 21/11/2020
  3096 0000DD43 89C1                <1> 	mov	ecx, eax ; 4096
  3097 0000DD45 E847150000          <1> 	call	transfer_to_user_buffer ; fast transfer
  3098 0000DD4A 0F827CF5FFFF        <1> 	jc	sysret ; [u.r0] = 0
  3099                              <1> 	; 21/11/2020
  3100                              <1> 	;mov	[u.r0], ecx
  3101 0000DD50 66890D[64030300]    <1> 	mov	[u.r0], cx
  3102 0000DD57 E970F5FFFF          <1> 	jmp	sysret	
  3103                              <1> sysvideo_3: 
  3104                              <1> 	; user to system video/display page transfer (mode 0)	
  3105 0000DD5C 89CE                <1> 	mov	esi, ecx ; user buffer
  3106                              <1> 	; edi = video page address
  3107                              <1> 	; 21/11/2020
  3108 0000DD5E 89C1                <1> 	mov	ecx, eax ; 4096
  3109 0000DD60 E876150000          <1> 	call	transfer_from_user_buffer ; fast transfer
  3110 0000DD65 0F8261F5FFFF        <1> 	jc	sysret ; [u.r0] = 0
  3111                              <1> 	; 21/11/2020
  3112                              <1> 	;mov	[u.r0], ecx
  3113 0000DD6B 66890D[64030300]    <1> 	mov	[u.r0], cx
  3114 0000DD72 E955F5FFFF          <1> 	jmp	sysret
  3115                              <1> 
  3116                              <1> sysvideo_4:
  3117                              <1> 	; 23/11/2020 (TRDOS 386 v2.0.3)
  3118                              <1> 
  3119                              <1> 	; Display page window transfer etc.
  3120 0000DD77 80E303              <1> 	and	bl, 3
  3121 0000DD7A 0F85F7000000        <1>         jnz     sysvideo_9 ; user to system or system to user
  3122                              <1> 	; 21/11/2020
  3123                              <1> 	; system to system video/display page window transfer (mode 0)
  3124 0000DD80 81FE00800B00        <1> 	cmp	esi, 0B8000h	; source buffer address (system)
  3125 0000DD86 0F8240F5FFFF        <1> 	jb	sysret
  3126 0000DD8C 81FE00000C00        <1> 	cmp	esi, 0B8000h+(4096*8)
  3127 0000DD92 0F8334F5FFFF        <1> 	jnb	sysret
  3128 0000DD98 81FF00800B00        <1> 	cmp	edi, 0B8000h	; destination buffer address (system)	
  3129 0000DD9E 0F8228F5FFFF        <1> 	jb	sysret
  3130 0000DDA4 81FF00000C00        <1>         cmp     edi, 0B8000h+(4096*8)
  3131 0000DDAA 0F831CF5FFFF        <1> 	jnb	sysret
  3132                              <1> 	;
  3133 0000DDB0 51                  <1> 	push	ecx ; X1 and Y1 position - top left column, row
  3134 0000DDB1 0FB7C1              <1> 	movzx	eax, cx ; top left column
  3135                              <1> 	; 21/11/2020
  3136 0000DDB4 C1E910              <1> 	shr	ecx, 16 ; top row
  3137 0000DDB7 740E                <1> 	jz	short sysvideo_4_0 ; bypass following code
  3138 0000DDB9 52                  <1> 	push	edx ; X2 and Y2 position - bottom right column, row
  3139 0000DDBA 50                  <1> 	push	eax
  3140 0000DDBB 66B8A000            <1> 	mov	ax, 80*2 ; 80 colums, 160 bytes per row
  3141 0000DDBF F7E1                <1> 	mul	ecx
  3142                              <1> 		; eax = offset for start row number 
  3143 0000DDC1 01C6                <1> 	add	esi, eax
  3144 0000DDC3 01C7                <1> 	add	edi, eax
  3145 0000DDC5 58                  <1> 	pop	eax
  3146 0000DDC6 5A                  <1> 	pop	edx
  3147                              <1> sysvideo_4_0:
  3148 0000DDC7 66D1E0              <1> 	shl	ax, 1 ; * 2 ; convert start column number to offset
  3149 0000DDCA 7404                <1> 	jz	short sysvideo_4_1	
  3150 0000DDCC 01C6                <1> 	add	esi, eax
  3151 0000DDCE 01C7                <1> 	add	edi, eax
  3152                              <1> 		; esi = source page window start offset
  3153                              <1> 		; edi = destination page window start offset
  3154                              <1> sysvideo_4_1:
  3155 0000DDD0 59                  <1> 	pop	ecx
  3156                              <1> 	;mov	eax, 0B8000h+(80*25*2*8)
  3157                              <1> 	; 21/11/2020
  3158 0000DDD1 B800000C00          <1> 	mov	eax, 0B8000h+(4096*8)
  3159 0000DDD6 39C6                <1> 	cmp	esi, eax
  3160 0000DDD8 0F83EEF4FFFF        <1> 	jnb	sysret ; out of video page
  3161 0000DDDE 39C6                <1> 	cmp	esi, eax
  3162 0000DDE0 0F83E6F4FFFF        <1> 	jnb	sysret  ;out of video page	
  3163                              <1> 
  3164 0000DDE6 56                  <1> 	push	esi ; ****
  3165 0000DDE7 57                  <1> 	push	edi ; ***
  3166 0000DDE8 52                  <1> 	push	edx ; **
  3167 0000DDE9 51                  <1> 	push	ecx ; *
  3168 0000DDEA C1E910              <1> 	shr	ecx, 16 ; top row
  3169 0000DDED C1EA10              <1> 	shr	edx, 16 ; bottom row
  3170                              <1> 	; 21/11/2020
  3171                              <1> 	;cmp	ecx, 24 ; max. 25 rows
  3172 0000DDF0 6683F918            <1> 	cmp	cx, 24
  3173 0000DDF4 7778                <1> 	ja	short sysvideo_6 ; invalid, [u.r0] = 0
  3174                              <1> 	;cmp	edx, 24 ; max. 25 rows
  3175 0000DDF6 6683FA18            <1> 	cmp	dx, 24
  3176 0000DDFA 7772                <1> 	ja	short sysvideo_6 ; invalid, [u.r0] = 0		
  3177 0000DDFC 28CA                <1> 	sub	dl, cl ; end >= start
  3178 0000DDFE 726E                <1> 	jc	short sysvideo_6 ; invalid, [u.r0] = 0
  3179                              <1> 	; 21/11/2020
  3180 0000DE00 89D3                <1> 	mov	ebx, edx ; row count - 1
  3181 0000DE02 7415                <1> 	jz	short sysvideo_4_2
  3182 0000DE04 50                  <1> 	push	eax ; *****
  3183 0000DE05 B8A0000000          <1> 	mov	eax, 80*2 ; bytes per row
  3184 0000DE0A F7E3                <1> 	mul	ebx ; 21/11/2020
  3185                              <1> 		; eax = window end offset 
  3186                              <1> 		; (for the last row, before adding column bytes)
  3187 0000DE0C 01C6                <1> 	add	esi, eax
  3188 0000DE0E 01C7                <1> 	add	edi, eax
  3189 0000DE10 58                  <1> 	pop	eax ; ***** ; mode 3 video memory end (0C000h)
  3190 0000DE11 39C6                <1> 	cmp	esi, eax
  3191                              <1> 	;ja	short sysvideo_6 ; invalid, [u.r0] = 0
  3192 0000DE13 7359                <1> 	jnb	short sysvideo_6 ; 21/11/2020
  3193 0000DE15 39C7                <1> 	cmp	edi, eax
  3194                              <1> 	;ja	short sysvideo_6 ; invalid, [u.r0] = 0
  3195 0000DE17 7355                <1> 	jnb	short sysvideo_6 ; 21/11/2020
  3196                              <1> sysvideo_4_2:
  3197 0000DE19 59                  <1> 	pop	ecx ; *
  3198 0000DE1A 5A                  <1> 	pop	edx ; **
  3199 0000DE1B 81E1FFFF0000        <1> 	and	ecx, 0FFFFh
  3200 0000DE21 81E2FFFF0000        <1> 	and	edx, 0FFFFh
  3201                              <1> 	; 21/11/2020
  3202                              <1> 	;cmp	ecx, 79 ; max. 80 columns
  3203 0000DE27 6683F94F            <1> 	cmp	cx, 79
  3204 0000DE2B 7743                <1> 	ja	short sysvideo_7 ; invalid, [u.r0] = 0
  3205                              <1> 	;cmp	edx, 79 ; max. 80 columns
  3206 0000DE2D 6683FA4F            <1> 	cmp	dx, 79 
  3207 0000DE31 773D                <1> 	ja	short sysvideo_7 ; invalid, [u.r0] = 0
  3208 0000DE33 28CA                <1> 	sub	dl, cl
  3209 0000DE35 7639                <1> 	jna	short sysvideo_7 ; invalid, [u.r0] = 0
  3210                              <1> 	; 21/11/2020
  3211 0000DE37 740E                <1> 	jz	short sysvideo_4_3 
  3212                              <1> 	; edx = column count (width) - 1
  3213 0000DE39 D0E2                <1> 	shl	dl, 1 ; * 2 ; byte offset (in end row)
  3214 0000DE3B 01D6                <1> 	add	esi, edx
  3215 0000DE3D 01D7                <1> 	add	edi, edx
  3216                              <1> 		; esi = source page window end offset
  3217                              <1> 		; edi = destination page window end offset
  3218 0000DE3F 39C6                <1> 	cmp	esi, eax ; video memory end
  3219                              <1> 	;ja	short sysvideo_7
  3220 0000DE41 732D                <1> 	jnb	short sysvideo_7 ; 21/11/2020
  3221 0000DE43 39C7                <1> 	cmp	edi, eax ; video memory end
  3222                              <1> 	;ja	short sysvideo_7
  3223 0000DE45 7329                <1> 	jnb	short sysvideo_7 ; 21/11/2020
  3224                              <1> sysvideo_4_3:
  3225 0000DE47 5F                  <1> 	pop	edi ; ***
  3226 0000DE48 5E                  <1> 	pop	esi ; ****
  3227 0000DE49 FEC3                <1> 	inc	bl ; row count - 1 -> row count	
  3228 0000DE4B FEC2                <1> 	inc	dl ; column count
  3229 0000DE4D 88D7                <1> 	mov	bh, dl
  3230 0000DE4F D0E2                <1> 	shl	dl, 1 ; convert column count to byte offset
  3231                              <1> 	; 21/11/2020
  3232                              <1> 	; esi = source page window start offset
  3233                              <1> 	; edi = destination page window start offset
  3234 0000DE51 B8A0000000          <1> 	mov	eax, 80*2 ; bytes per row
  3235                              <1> 	; Note: 160 bytes per row (even if move count < 160)
  3236                              <1> sysvideo_5:	
  3237 0000DE56 88F9                <1> 	mov	cl, bh ; move/transfer -word- count per row
  3238 0000DE58 0115[64030300]      <1> 	add	[u.r0], edx ; transfer count in bytes
  3239 0000DE5E F366A5              <1> 	rep	movsw
  3240 0000DE61 01C6                <1> 	add	esi, eax ; + 160 bytes to next row
  3241 0000DE63 01C7                <1> 	add	edi, eax ; + 160 bytes to next row
  3242 0000DE65 FECB                <1> 	dec	bl ; remain count of rows
  3243 0000DE67 75ED                <1> 	jnz	short sysvideo_5
  3244 0000DE69 E95EF4FFFF          <1> 	jmp	sysret
  3245                              <1> 
  3246                              <1> sysvideo_6:
  3247 0000DE6E 59                  <1> 	pop	ecx ; *
  3248 0000DE6F 5A                  <1> 	pop	edx ; **
  3249                              <1> sysvideo_7:	
  3250 0000DE70 5F                  <1> 	pop	edi ; ***
  3251 0000DE71 5E                  <1> 	pop	esi ; ****
  3252 0000DE72 E955F4FFFF          <1> 	jmp	sysret
  3253                              <1> 
  3254                              <1> sysvideo_9:
  3255                              <1> 	; user to system or system to user window transfer
  3256 0000DE77 80FB02              <1> 	cmp	bl, 2
  3257 0000DE7A 0F874CF4FFFF        <1>         ja      sysret	; user to user transfer is invalid
  3258                              <1> 			; [u.r0] = 0
  3259                              <1> 
  3260 0000DE80 56                  <1> 	push	esi ; ****
  3261 0000DE81 57                  <1> 	push	edi ; ***
  3262 0000DE82 52                  <1> 	push	edx ; **
  3263 0000DE83 51                  <1> 	push	ecx ; *
  3264                              <1> 
  3265 0000DE84 C1E910              <1> 	shr	ecx, 16 ; top row
  3266 0000DE87 C1EA10              <1> 	shr	edx, 16 ; bottom row
  3267                              <1> 	
  3268                              <1> 	; 21/11/2020
  3269                              <1> 	;cmp	ecx, 24 ; max. 25 rows
  3270 0000DE8A 6683F918            <1> 	cmp	cx, 24
  3271 0000DE8E 77DE                <1> 	ja	short sysvideo_6 ; invalid, [u.r0] = 0
  3272                              <1> 	;cmp	edx, 24 ; max. 25 rows
  3273 0000DE90 6683FA18            <1> 	cmp	dx, 24
  3274 0000DE94 77D8                <1> 	ja	short sysvideo_6 ; invalid, [u.r0] = 0	
  3275 0000DE96 28CA                <1> 	sub	dl, cl
  3276 0000DE98 72D4                <1> 	jc	short sysvideo_6 ; invalid, [u.r0] = 0
  3277                              <1> 
  3278                              <1> 	;mov	ch, cl ; top row
  3279                              <1> 	;mov	cl, [ACTIVE_PAGE]
  3280                              <1> 
  3281                              <1> 	;mov	edi, 80*25*2 ; 4000
  3282                              <1> 	; 21/11/2020
  3283                              <1> 	;mov	edi, 4096 ; [CRT_LEN = 4096 for video mode 3 
  3284                              <1> 	;shl	edi, cl  ; ! wrong for page 2 to page 7 !
  3285                              <1> 	;;add	edi, 0B8000h - 80*25*2
  3286                              <1> 	;add	edi, 0B8000h - 1000h ; - 4096
  3287                              <1> 	
  3288                              <1> 	; 21/11/2020
  3289                              <1> 	;xor	eax, eax
  3290                              <1> 	;mov	edi, 0B8000h
  3291                              <1> 	;and	cl, cl ; is video page = 0 ?
  3292                              <1> 	;jz	short sysvideo_9_1 ; yes
  3293                              <1> 	; eax = 0
  3294                              <1> 
  3295                              <1> ;sysvideo_9_0:
  3296                              <1> 	;add	ax, 4096
  3297                              <1> 	;dec	cl
  3298                              <1> 	;jnz	short sysvideo_9_0
  3299                              <1> 	;add	edi, eax
  3300                              <1> 	;	; edi = video page start address
  3301                              <1> 
  3302                              <1> 	; 21/11/2020
  3303 0000DE9A BF00800B00          <1> 	mov	edi, 0B8000h
  3304 0000DE9F 803D[06640100]00    <1> 	cmp	byte [ACTIVE_PAGE], 0
  3305 0000DEA6 760C                <1> 	jna	short sysvideo_9_1
  3306                              <1> stsvideo_9_0:
  3307 0000DEA8 B010                <1> 	mov	al, 16 ; 4096/256
  3308 0000DEAA F625[06640100]      <1> 	mul	byte [ACTIVE_PAGE] 
  3309 0000DEB0 86E0                <1> 	xchg	ah, al ; * 256
  3310 0000DEB2 01C7                <1> 	add	edi, eax
  3311                              <1> 		; edi = video page start address
  3312                              <1> sysvideo_9_1:
  3313                              <1> 	; bl = transfer direction 
  3314                              <1> 	;     ( 1 = from user, 2 = to user)
  3315 0000DEB4 88D7                <1> 	mov	bh, dl ; row count - 1
  3316                              <1> 	;mov	dl, ch ; top row
  3317                              <1> 	; 21/11/2020
  3318 0000DEB6 08C9                <1> 	or	cl, cl ; top row number
  3319 0000DEB8 7408                <1> 	jz	short sysvideo_9_2
  3320                              <1> 
  3321                              <1> 	;mov	eax, 80*2
  3322 0000DEBA 66B8A000            <1> 	mov	ax, 80*2 ; 160, bytes per row
  3323 0000DEBE F7E1                <1> 	mul	ecx ; 22/11/2020
  3324 0000DEC0 01C7                <1> 	add	edi, eax
  3325                              <1> 		; edi = window start address for top row
  3326                              <1> sysvideo_9_2:
  3327 0000DEC2 59                  <1> 	pop	ecx ; *
  3328 0000DEC3 5A                  <1> 	pop	edx ; **
  3329 0000DEC4 81E1FFFF0000        <1> 	and	ecx, 0FFFFh
  3330 0000DECA 81E2FFFF0000        <1> 	and	edx, 0FFFFh
  3331                              <1> 	; 21/11/2020
  3332                              <1> 	;cmp	ecx, 79 ; max. 80 columns
  3333 0000DED0 6683F94F            <1> 	cmp	cx, 79
  3334 0000DED4 779A                <1> 	ja	short sysvideo_7 ; invalid, [u.r0] = 0
  3335                              <1> 	;cmp	edx, 79 ; max. 80 columns
  3336 0000DED6 6683FA4F            <1> 	cmp	dx, 79
  3337 0000DEDA 7794                <1> 	ja	short sysvideo_7 ; invalid, [u.r0] = 0
  3338                              <1> 	
  3339 0000DEDC 28CA                <1> 	sub	dl, cl
  3340 0000DEDE 7290                <1> 	jc	short sysvideo_7 ; invalid, [u.r0] = 0
  3341                              <1> 	
  3342 0000DEE0 08C9                <1> 	or	cl, cl ; left column 
  3343 0000DEE2 7404                <1> 	jz	short sysvideo_9_3 ; 0
  3344                              <1> 
  3345                              <1> 	; 21/11/2020
  3346 0000DEE4 D0E1                <1> 	shl	cl, 1  ; column * 2
  3347 0000DEE6 01CF                <1> 	add	edi, ecx
  3348                              <1> 		; edi = window start addr for top left column
  3349                              <1> sysvideo_9_3:
  3350 0000DEE8 88D1                <1> 	mov	cl, dl
  3351 0000DEEA FEC1                <1> 	inc	cl ; column count
  3352 0000DEEC D0E1                <1> 	shl	cl, 1 ; column count * 2
  3353                              <1> 		; ecx = tranfer count per row
  3354                              <1> 
  3355 0000DEEE 58                  <1> 	pop	eax ; *** (swap address)
  3356 0000DEEF 5E                  <1> 	pop	esi ; ****
  3357                              <1> 
  3358 0000DEF0 FEC7                <1> 	inc	bh  ; row count	
  3359                              <1> 	
  3360                              <1> 	;mov	edx, 80*2
  3361 0000DEF2 B2A0                <1> 	mov	dl, 80*2  ; bytes per row
  3362                              <1> 	;
  3363 0000DEF4 80FB01              <1> 	cmp	bl, 1 ; transfer direction
  3364 0000DEF7 7742                <1> 	ja	short sysvideo_11 ; system to user transfer
  3365                              <1> 
  3366                              <1> 	; user to system video/display page window transfer (mode 0)	
  3367 0000DEF9 21C0                <1> 	and	eax, eax ; swap address
  3368 0000DEFB 7420                <1> 	jz	short sysvideo_10 ; no window swap
  3369                              <1> 	; save previous window content in user's buffer (swap address)
  3370 0000DEFD 56                  <1> 	push	esi ; user buffer
  3371 0000DEFE 57                  <1> 	push	edi ; beginning address of the window
  3372                              <1> 	; 21/11/2020
  3373 0000DEFF 53                  <1> 	push	ebx ; save bh
  3374 0000DF00 89FE                <1> 	mov	esi, edi
  3375 0000DF02 89C7                <1> 	mov	edi, eax
  3376                              <1> sysvideo_9_4:
  3377 0000DF04 E888130000          <1> 	call	transfer_to_user_buffer ; fast transfer
  3378 0000DF09 7208                <1> 	jc	short sysvideo_9_5
  3379                              <1> 	; ecx = actual transfer count (must be same with input)
  3380 0000DF0B 01D6                <1> 	add	esi, edx ; next row address of (video page) window 
  3381 0000DF0D 01CF                <1> 	add	edi, ecx ; next row address of user's window
  3382                              <1> 		; Note: ecx may be less than row length of video page
  3383                              <1> 		; user's window uses offset according to window width
  3384 0000DF0F FECF                <1> 	dec	bh
  3385 0000DF11 75F1                <1> 	jnz	short sysvideo_9_4 ; repeat for next row
  3386                              <1> sysvideo_9_5:
  3387 0000DF13 5B                  <1> 	pop	ebx ; restore bh
  3388 0000DF14 5F                  <1> 	pop	edi
  3389 0000DF15 5E                  <1> 	pop	esi
  3390 0000DF16 7305                <1> 	jnc	short sysvideo_10
  3391 0000DF18 E9AFF3FFFF          <1> 	jmp	sysret ; [u.r0] = 0
  3392                              <1> sysvideo_10: 
  3393                              <1> 	; user to system video/display page window transfer (mode 0)	
  3394                              <1> 	; esi =	user buffer
  3395 0000DF1D E8B9130000          <1> 	call	transfer_from_user_buffer ; fast transfer
  3396 0000DF22 0F82A4F3FFFF        <1> 	jc	sysret
  3397                              <1> 	; ecx = actual transfer count (must be same with input)
  3398 0000DF28 010D[64030300]      <1> 	add	[u.r0], ecx ; actual transfer count
  3399 0000DF2E 01D7                <1> 	add	edi, edx ; next row address of (ivdeo page) window 
  3400 0000DF30 01CE                <1> 	add	esi, ecx ; next row address of user's window
  3401                              <1> 		; Note: ecx may be less than row length of video page
  3402                              <1> 		; user's window uses offset according to window width
  3403 0000DF32 FECF                <1> 	dec	bh
  3404 0000DF34 75E7                <1> 	jnz	short sysvideo_10 ; repeat for next row
  3405 0000DF36 E991F3FFFF          <1> 	jmp	sysret
  3406                              <1> 	
  3407                              <1> sysvideo_11:
  3408                              <1> 	; system to user video/display page window transfer (mode 0)
  3409 0000DF3B 87FE                <1> 	xchg	edi, esi
  3410                              <1> sysvideo_12:
  3411                              <1> 	; esi = beginning addr of the (screen, video page) window
  3412                              <1> 	; edi =	user's buffer	
  3413 0000DF3D E84F130000          <1> 	call	transfer_to_user_buffer ; fast transfer
  3414 0000DF42 0F8284F3FFFF        <1> 	jc	sysret
  3415                              <1> 	; ecx = actual transfer count (must be same with input)
  3416 0000DF48 010D[64030300]      <1> 	add	[u.r0], ecx
  3417 0000DF4E 01D6                <1> 	add	esi, edx ; next row (edx = 160)
  3418 0000DF50 01CF                <1> 	add	edi, ecx ; next row of the user's window 
  3419                              <1> 			 ; (ecx <= 160)
  3420 0000DF52 FECF                <1> 	dec	bh
  3421 0000DF54 75E7                <1> 	jnz	short sysvideo_12
  3422 0000DF56 E971F3FFFF          <1> 	jmp	sysret
  3423                              <1> 
  3424                              <1> sysvideo_13:
  3425 0000DF5B 80FF01              <1> 	cmp	bh, 1
  3426 0000DF5E 0F8781030000        <1>         ja      sysvideo_38 ; 23/11/2020
  3427                              <1> 
  3428                              <1> 	; 23/11/2020 (TRDOS 386 v2.0.3)
  3429                              <1> 	; (major modification, from mode 13h to all VGA modes,
  3430                              <1> 	;  except super VGA modes and liner frame buffer method)
  3431                              <1> 
  3432                              <1> 	; BH = 1 = VGA Graphics mode (0A0000h) data transfers
  3433                              <1> 
  3434                              <1> 	; 23/11/2020
  3435                              <1> 	; screen width will be saved into EBP register
  3436                              <1> 
  3437 0000DF64 88DC                <1> 	mov	ah, bl
  3438                              <1> 	;and	bl, 0Fh	
  3439 0000DF66 C0EC04              <1> 	shr	ah, 4
  3440 0000DF69 BD40010000          <1> 	mov	ebp, 320 ; 320*200, 320*240
  3441 0000DF6E 20E4                <1> 	and	ah, ah
  3442 0000DF70 7413                <1> 	jz	short sysvideo_13_0
  3443 0000DF72 66D1E5              <1> 	shl	bp, 1 ; 640*200, 640*400, 640*480
  3444 0000DF75 80FC02              <1> 	cmp	ah, 2
  3445 0000DF78 720B                <1> 	jb	short sysvideo_13_0		
  3446 0000DF7A 0F874CF3FFFF        <1> 	ja	sysret ; invalid
  3447                              <1> 	; 800*600
  3448 0000DF80 6681C5A000          <1> 	add	bp, 160 ; 800
  3449                              <1> 
  3450                              <1> sysvideo_13_0:
  3451                              <1> 
  3452                              <1> 	;; 21/11/2020 (TRDOS 386 v2.0.3)
  3453                              <1> 	;; VGA graphics mode transfers are only for video mode 13h
  3454                              <1> 
  3455                              <1> 	; 23/11/2020
  3456                              <1> 	;cmp	byte [CRT_MODE], 13h ; 320x200 graphics, 256 colors
  3457                              <1> 	;jne	sysret ; invalid (nothing to do), [u.r0] = 0 
  3458                              <1> 
  3459                              <1> 	;and	bl, bl
  3460 0000DF85 80E30F              <1> 	and	bl, 0Fh
  3461 0000DF88 755A                <1> 	jnz	short sysvideo_14
  3462                              <1> 
  3463                              <1> 	; BL = 0 = Fill color (color in CL) (32K)
  3464                              <1> 
  3465                              <1> 	; 22/11/2020
  3466                              <1> 	;mov	eax, 65536 ; in fact 320*200 pixel bytes (32000)
  3467                              <1> 	;mov	[u.r0], eax
  3468 0000DF8A C605[66030300]01    <1> 	mov	byte [u.r0+2], 1 ; 65536
  3469 0000DF91 BF00000A00          <1> 	mov	edi, 0A0000h
  3470                              <1> 
  3471 0000DF96 08ED                <1> 	or	ch, ch ; mix ?
  3472 0000DF98 7419                <1> 	jz	short sysvideo_13_2 ; no, overwrite
  3473                              <1> 	
  3474                              <1> 	; Mix current pixel colors with mixing (CL input) color
  3475 0000DF9A 89FE                <1> 	mov	esi, edi
  3476 0000DF9C 88CB                <1> 	mov	bl, cl ; mixing color 
  3477 0000DF9E 30E4                <1> 	xor	ah, ah
  3478 0000DFA0 B900000100          <1> 	mov	ecx, 65536
  3479                              <1> sysvideo_13_1:
  3480 0000DFA5 AC                  <1> 	lodsb
  3481 0000DFA6 00D8                <1> 	add	al, bl
  3482 0000DFA8 66D1E8              <1> 	shr	ax, 1 ; / 2
  3483 0000DFAB AA                  <1> 	stosb
  3484 0000DFAC E2F7                <1> 	loop	sysvideo_13_1
  3485 0000DFAE E919F3FFFF          <1> 	jmp	sysret	
  3486                              <1> 
  3487                              <1> 	; Overwrite pixel colors
  3488                              <1> sysvideo_13_2:
  3489 0000DFB3 88CD                <1> 	mov	ch, cl ; color
  3490 0000DFB5 6689C8              <1> 	mov	ax, cx
  3491 0000DFB8 C1E010              <1> 	shl	eax, 16
  3492 0000DFBB 6689C8              <1> 	mov	ax, cx
  3493 0000DFBE B9C2410000          <1> 	mov	ecx, 16834
  3494 0000DFC3 F3AB                <1> 	rep	stosd
  3495 0000DFC5 E902F3FFFF          <1> 	jmp	sysret
  3496                              <1> 
  3497                              <1> sysvideo_16:
  3498 0000DFCA 80FB02              <1> 	cmp	bl, 2	
  3499 0000DFCD 7737                <1> 	ja	short sysvideo_18
  3500                              <1> 	; 23/11/2020
  3501 0000DFCF 7213                <1> 	jb	short sysvideo_14
  3502                              <1> 
  3503 0000DFD1 89CF                <1> 	mov	edi, ecx ; user's buffer
  3504                              <1> 	; BL = 2 = system to user video/display page transfer
  3505                              <1> sysvideo_17:
  3506                              <1> 	; 22/11/2020
  3507 0000DFD3 BE00000A00          <1> 	mov	esi, 0A0000h
  3508 0000DFD8 B900000100          <1> 	mov	ecx, 65536
  3509 0000DFDD E8AF120000          <1> 	call	transfer_to_user_buffer ; fast transfer
  3510                              <1> 	;jc	sysret ; [u.r0] = 0
  3511                              <1> 	;mov	[u.r0], ecx ; actual transfer count (32768)
  3512                              <1> 	;jmp	sysret
  3513                              <1> 	; 23/11/2020
  3514 0000DFE2 EB11                <1> 	jmp	short sysvideo_15_0 	
  3515                              <1> 
  3516                              <1> sysvideo_14:
  3517                              <1> 	; 23/11/2020
  3518                              <1> 	;cmp	bl, 1
  3519                              <1> 	;ja	short sysvideo_16
  3520                              <1> 
  3521 0000DFE4 89CE                <1> 	mov	esi, ecx ; user's buffer
  3522                              <1> 	; BL = 1 = user to system video/display page transfer
  3523                              <1> sysvideo_15:
  3524                              <1> 	; 22/11/2020
  3525 0000DFE6 BF00000A00          <1> 	mov	edi, 0A0000h
  3526                              <1> 	; edi = video page address
  3527 0000DFEB B900000100          <1> 	mov	ecx, 65536
  3528 0000DFF0 E8E6120000          <1> 	call	transfer_from_user_buffer ; fast transfer
  3529                              <1> sysvideo_15_0:
  3530 0000DFF5 0F82D1F2FFFF        <1> 	jc	sysret ; [u.r0] = 0
  3531 0000DFFB 890D[64030300]      <1> 	mov	[u.r0], ecx ; actual transfer count (32768)		
  3532 0000E001 E9C6F2FFFF          <1> 	jmp	sysret
  3533                              <1> 
  3534                              <1> sysvideo_18:
  3535 0000E006 80FB03              <1> 	cmp	bl, 3
  3536 0000E009 0F8780000000        <1> 	ja	sysvideo_23
  3537                              <1> 
  3538                              <1> 	; BL = 3 = NOT bits in window (ECX, EDX)
  3539                              <1> 
  3540                              <1> 	; 22/11/2020
  3541 0000E00F BF00000A00          <1> 	mov	edi, 0A0000h
  3542 0000E014 89FE                <1> 	mov	esi, edi
  3543                              <1> 	
  3544                              <1> 	; 21/11/2020
  3545 0000E016 39CA                <1> 	cmp	edx, ecx ; bottom-right > top-left ?
  3546 0000E018 731E                <1> 	jnb	short sysvideo_20 ; window
  3547                              <1> 
  3548 0000E01A 09D2                <1> 	or	edx, edx
  3549 0000E01C 0F85AAF2FFFF        <1> 	jnz	sysret  ; invalid !
  3550                              <1> 
  3551                              <1> 	; full screen (update) ; edx = 0, ecx > 0
  3552                              <1> 	;mov	ecx, 66536
  3553                              <1> 	; 21/11/2020
  3554 0000E022 B900400000          <1> 	mov	ecx, 16384  ; dword 'NOT'
  3555 0000E027 66890D[64030300]    <1> 	mov	[u.r0], cx
  3556                              <1> sysvideo_19:
  3557                              <1> 	;not	byte [esi] ; NOT operation
  3558                              <1> 	;inc	esi
  3559 0000E02E F716                <1> 	not	dword [esi]
  3560 0000E030 AD                  <1> 	lodsd	; add esi, 4
  3561 0000E031 E2FB                <1> 	loop	sysvideo_19
  3562 0000E033 E994F2FFFF          <1> 	jmp	sysret
  3563                              <1> sysvideo_20:
  3564 0000E038 0FB7C2              <1> 	movzx	eax, dx ; bottom right column
  3565 0000E03B 6629C8              <1> 	sub	ax, cx  ; - top left column
  3566 0000E03E 0F8288F2FFFF        <1>         jb      sysret ; invalid
  3567 0000E044 6640                <1> 	inc	ax ; same column no == 1 column	 
  3568 0000E046 50                  <1> 	push	eax ; byte count per window row
  3569 0000E047 52                  <1> 	push	edx
  3570                              <1> 	;mov	ebx, 320 ; screen width
  3571                              <1> 	; 23/11/2020
  3572 0000E048 89EB                <1> 	mov	ebx, ebp ; 320,600,800
  3573 0000E04A 89C8                <1> 	mov	eax, ecx
  3574 0000E04C C1E810              <1> 	shr	eax, 16  ; top row
  3575 0000E04F F7E3                <1> 	mul	ebx
  3576 0000E051 6689CA              <1> 	mov	dx, cx ; top left column
  3577 0000E054 01D0                <1> 	add	eax, edx
  3578 0000E056 01C6                <1> 	add	esi, eax ; start address 
  3579 0000E058 59                  <1> 	pop	ecx ; edx
  3580 0000E059 89C8                <1> 	mov	eax, ecx
  3581 0000E05B C1E810              <1> 	shr	eax, 16 ; bottom row
  3582 0000E05E F7E3                <1> 	mul	ebx
  3583 0000E060 6689CA              <1> 	mov	dx, cx ; bottom right column
  3584 0000E063 01D0                <1> 	add	eax, edx
  3585 0000E065 01C7                <1> 	add	edi, eax ; stop address (included)
  3586 0000E067 5A                  <1> 	pop	edx ; byte count per window row
  3587 0000E068 81FFFFFF0A00        <1> 	cmp	edi, 0AFFFFh ; 22/11/2020
  3588 0000E06E 0F8758F2FFFF        <1> 	ja	sysret
  3589                              <1> 	; 21/11/2020
  3590 0000E074 29D3                <1> 	sub	ebx, edx ; screen width - window width
  3591 0000E076 4E                  <1> 	dec	esi 
  3592                              <1> sysvideo_21:
  3593                              <1> 	;push	esi
  3594 0000E077 89D1                <1> 	mov	ecx, edx ; window width (byte count)
  3595                              <1> sysvideo_22:
  3596 0000E079 46                  <1> 	inc	esi
  3597 0000E07A F616                <1> 	not	byte [esi]
  3598                              <1> 	;inc	esi
  3599 0000E07C E2FB                <1> 	loop	sysvideo_22
  3600                              <1> 	; 21/11/2020
  3601 0000E07E 0115[64030300]      <1> 	add	[u.r0], edx
  3602                              <1> 	;pop	esi ; 21/11/2020
  3603                              <1> 	;add	esi, ebx ; bytes per screen row (320)
  3604 0000E084 01DE                <1> 	add	esi, ebx ; add difference for next row
  3605                              <1> 	;
  3606 0000E086 39FE                <1> 	cmp	esi, edi ; stop address (included in loop)
  3607                              <1> 	;jna	short sysvideo_21
  3608 0000E088 72ED                <1> 	jb	short sysvideo_21
  3609 0000E08A E93DF2FFFF          <1> 	jmp	sysret
  3610                              <1> 
  3611                              <1> sysvideo_23:
  3612 0000E08F 80FB04              <1> 	cmp	bl, 4
  3613 0000E092 0F87A3000000        <1>         ja      sysvideo_26
  3614                              <1> 
  3615                              <1> 	; BL = 4 = window copy (system to system)
  3616                              <1> 
  3617                              <1> 	; 22/11/2020
  3618 0000E098 B800000A00          <1> 	mov	eax, 0A0000h
  3619 0000E09D 39C6                <1> 	cmp	esi, eax
  3620 0000E09F 0F8227F2FFFF        <1> 	jb	sysret
  3621 0000E0A5 39C7                <1> 	cmp	edi, eax
  3622 0000E0A7 0F821FF2FFFF        <1> 	jb	sysret
  3623                              <1> 	;add	ax, 0FFFFh
  3624 0000E0AD 66B8FFFF            <1> 	mov	ax, 0FFFFh ; 65535
  3625 0000E0B1 39C6                <1> 	cmp	esi, eax
  3626 0000E0B3 0F8713F2FFFF        <1> 	ja	sysret
  3627 0000E0B9 39C7                <1> 	cmp	edi, eax
  3628 0000E0BB 0F870BF2FFFF        <1> 	ja	sysret
  3629                              <1> 	
  3630 0000E0C1 39CA                <1> 	cmp	edx, ecx ; bottom-right > top-left ?
  3631 0000E0C3 731A                <1> 	jnb	short sysvideo_24 ; window
  3632                              <1> 
  3633 0000E0C5 09D2                <1> 	or	edx, edx
  3634 0000E0C7 0F85FFF1FFFF        <1> 	jnz	sysret  ; invalid !
  3635                              <1> 
  3636                              <1> 	; full screen copy ; edx = 0, ecx > 0
  3637 0000E0CD B900000100          <1> 	mov	ecx, 65536
  3638 0000E0D2 890D[64030300]      <1> 	mov	[u.r0], ecx
  3639 0000E0D8 F3A4                <1> 	rep	movsb
  3640 0000E0DA E9EDF1FFFF          <1> 	jmp	sysret
  3641                              <1> sysvideo_24:
  3642 0000E0DF 0FB7C2              <1> 	movzx	eax, dx ; bottom right column
  3643 0000E0E2 6629C8              <1> 	sub	ax, cx  ; - top left column
  3644 0000E0E5 0F82E1F1FFFF        <1>         jb      sysret ; invalid
  3645 0000E0EB 6640                <1> 	inc	ax ; same column no == 1 column	 
  3646 0000E0ED 50                  <1> 	push	eax ; byte count per window row
  3647                              <1> 	;
  3648 0000E0EE 52                  <1> 	push	edx
  3649                              <1> 	;mov	ebx, 320 ; screen width
  3650                              <1> 	; 23/11/2020
  3651 0000E0EF 89EB                <1> 	mov	ebx, ebp ; 320,600,800
  3652 0000E0F1 89C8                <1> 	mov	eax, ecx
  3653 0000E0F3 C1E810              <1> 	shr	eax, 16	; top row
  3654 0000E0F6 F7E3                <1> 	mul	ebx
  3655 0000E0F8 6689CA              <1> 	mov	dx, cx ; top left column
  3656 0000E0FB 01D0                <1> 	add	eax, edx
  3657 0000E0FD 01C7                <1> 	add	edi, eax ; start address 
  3658 0000E0FF 01C6                <1> 	add	esi, eax
  3659 0000E101 59                  <1> 	pop	ecx ; edx
  3660 0000E102 89C8                <1> 	mov	eax, ecx
  3661 0000E104 C1E810              <1> 	shr	eax, 16 ; bottom row
  3662 0000E107 F7E3                <1> 	mul	ebx
  3663 0000E109 6689CA              <1> 	mov	dx, cx ; bottom right column
  3664 0000E10C 01D0                <1> 	add	eax, edx
  3665 0000E10E 5A                  <1> 	pop	edx ; byte count per window row
  3666 0000E10F 0500000A00          <1> 	add	eax, 0A0000h
  3667 0000E114 3DFFFF0A00          <1> 	cmp	eax, 0AFFFFh
  3668 0000E119 0F87ADF1FFFF        <1> 	ja	sysret
  3669 0000E11F 57                  <1> 	push	edi ; start address 
  3670 0000E120 50                  <1> 	push	eax ; stop address (included)
  3671                              <1> 	; 21/11/2020
  3672 0000E121 29D3                <1> 	sub	ebx, edx ; screen width - window width
  3673                              <1> sysvideo_25:
  3674 0000E123 89D1                <1> 	mov	ecx, edx
  3675 0000E125 F3A4                <1> 	rep	movsb
  3676                              <1> 	; 21/11/2020
  3677 0000E127 0115[64030300]      <1> 	add	[u.r0], edx ; window width (byte count)
  3678                              <1> 	;or	ebx, ebx
  3679                              <1> 	;jz	short sysvideo_25_0
  3680 0000E12D 01DF                <1> 	add	edi, ebx ; add difference (for next row) 
  3681 0000E12F 01DE                <1> 	add	esi, ebx
  3682                              <1> ;sysvideo_25_0:
  3683 0000E131 3B3C24              <1> 	cmp	edi, [esp] ; stop addr (included in loop)
  3684 0000E134 76ED                <1> 	jna	short sysvideo_25
  3685                              <1> 	; 21/11/2020
  3686 0000E136 E98B000000          <1> 	jmp	sysvideo_28
  3687                              <1> 	;pop	ebx ; stop address
  3688                              <1> 	;pop	edi ; start address
  3689                              <1> 	;jmp	sysret
  3690                              <1> 
  3691                              <1> sysvideo_26:
  3692 0000E13B 80FB05              <1> 	cmp	bl, 5
  3693 0000E13E 0F8789000000        <1>         ja      sysvideo_29
  3694                              <1> 
  3695                              <1> 	; BL = 5 = window copy (user to system)
  3696                              <1> 
  3697                              <1> 	; 22/11/2020
  3698 0000E144 B800000A00          <1> 	mov	eax, 0A0000h
  3699 0000E149 39C7                <1> 	cmp	edi, eax
  3700 0000E14B 0F827BF1FFFF        <1> 	jb	sysret
  3701                              <1> 	;add	ax, 0FFFFh ; 65535
  3702 0000E151 66B8FFFF            <1> 	mov	ax, 0FFFFh
  3703 0000E155 39C7                <1> 	cmp	edi, eax
  3704 0000E157 0F876FF1FFFF        <1> 	ja	sysret
  3705                              <1> 
  3706                              <1> 	; 21/11/2020
  3707                              <1> 	; esi = user buffer (in user's memory space)
  3708 0000E15D 39CA                <1> 	cmp	edx, ecx ; bottom-right > top-left ?
  3709 0000E15F 730D                <1>       	jnb	short sysvideo_26_0 ; window
  3710                              <1> 
  3711 0000E161 09D2                <1> 	or	edx, edx
  3712 0000E163 0F8563F1FFFF        <1> 	jnz	sysret  ; invalid !
  3713                              <1> 
  3714                              <1> 	; full screen copy ; edx = 0, ecx > 0
  3715 0000E169 E978FEFFFF          <1> 	jmp	sysvideo_15 ; full screen copy
  3716                              <1> 
  3717                              <1> sysvideo_26_0:
  3718 0000E16E 0FB7C2              <1> 	movzx	eax, dx ; bottom right column
  3719 0000E171 6629C8              <1> 	sub	ax, cx  ; - top left column
  3720 0000E174 0F8252F1FFFF        <1>         jb      sysret ; invalid
  3721 0000E17A 6640                <1> 	inc	ax ; same column no == 1 column	 
  3722 0000E17C 50                  <1> 	push	eax ; byte count per window row
  3723                              <1> 
  3724 0000E17D 52                  <1> 	push	edx
  3725                              <1> 	;mov	ebx, 320 ; screen width
  3726                              <1> 	; 23/11/2020
  3727 0000E17E 89EB                <1> 	mov	ebx, ebp ; 320,600,800
  3728 0000E180 89C8                <1> 	mov	eax, ecx
  3729 0000E182 C1E810              <1> 	shr	eax, 16	; top row
  3730 0000E185 F7E3                <1> 	mul	ebx
  3731 0000E187 6689CA              <1> 	mov	dx, cx ; top left column
  3732 0000E18A 01D0                <1> 	add	eax, edx
  3733 0000E18C 01C7                <1> 	add	edi, eax ; start address 
  3734 0000E18E 59                  <1> 	pop	ecx ; edx
  3735 0000E18F 89C8                <1> 	mov	eax, ecx
  3736 0000E191 C1E810              <1> 	shr	eax, 16 ; bottom row
  3737 0000E194 F7E3                <1> 	mul	ebx
  3738 0000E196 6689CA              <1> 	mov	dx, cx ; bottom right column
  3739 0000E199 01D0                <1> 	add	eax, edx
  3740 0000E19B 5A                  <1> 	pop	edx ; byte count per window row
  3741 0000E19C 0500000A00          <1> 	add	eax, 0A0000h
  3742 0000E1A1 3DFFFF0A00          <1> 	cmp	eax, 0AFFFFh
  3743 0000E1A6 0F8720F1FFFF        <1> 	ja	sysret
  3744                              <1> 
  3745 0000E1AC 57                  <1> 	push	edi ; start address 
  3746 0000E1AD 50                  <1> 	push	eax ; stop address (included)
  3747                              <1> sysvideo_27:
  3748 0000E1AE 89D1                <1> 	mov	ecx, edx ; byte count
  3749                              <1> 	; user to system video/display page window transfer
  3750                              <1> 	; esi =	user buffer
  3751 0000E1B0 E826110000          <1> 	call	transfer_from_user_buffer ; fast transfer
  3752 0000E1B5 720F                <1> 	jc	short sysvideo_28
  3753                              <1> 		; ecx = actual transfer count (= ecx input) 
  3754 0000E1B7 010D[64030300]      <1> 	add	[u.r0], ecx
  3755 0000E1BD 01DF                <1> 	add	edi, ebx ; next row in video memory window
  3756 0000E1BF 01CE                <1> 	add	esi, ecx ; next window row in user's buffer
  3757 0000E1C1 3B3C24              <1> 	cmp	edi, [esp] ; stop addr (included in loop)
  3758 0000E1C4 76E8                <1> 	jna	short sysvideo_27
  3759                              <1> sysvideo_28:
  3760 0000E1C6 5B                  <1> 	pop	ebx ; stop address
  3761 0000E1C7 5F                  <1> 	pop	edi ; start address
  3762                              <1> 	; 21/11/2020
  3763 0000E1C8 E9FFF0FFFF          <1> 	jmp	sysret
  3764                              <1> 
  3765                              <1> sysvideo_29:
  3766 0000E1CD 80FB06              <1> 	cmp	bl, 6
  3767                              <1> 	;ja	sysvideo_32
  3768                              <1> 	; 21/11/2020
  3769 0000E1D0 0F878D000000        <1> 	ja	sysvideo_31
  3770                              <1> 
  3771                              <1> 	; BL = 6 = window copy (system to user)
  3772                              <1> 
  3773 0000E1D6 89F7                <1> 	mov	edi, esi ; user buffer
  3774                              <1> 
  3775                              <1> 	; 22/11/2020
  3776 0000E1D8 B800000A00          <1> 	mov	eax, 0A0000h
  3777 0000E1DD 39C6                <1> 	cmp	esi, eax
  3778 0000E1DF 0F82E7F0FFFF        <1> 	jb	sysret
  3779                              <1> 	;add	ax, 0FFFFh ; 65535
  3780 0000E1E5 66B8FFFF            <1> 	mov	ax, 0FFFFh
  3781 0000E1E9 39C6                <1> 	cmp	esi, eax
  3782 0000E1EB 0F87DBF0FFFF        <1> 	ja	sysret
  3783                              <1> 
  3784                              <1> 	; 21/11/2020
  3785                              <1> 	; edi = user buffer (in user's memory space)
  3786 0000E1F1 39CA                <1> 	cmp	edx, ecx ; bottom-right > top-left ?
  3787 0000E1F3 730D                <1>         jnb     short sysvideo_29_0
  3788                              <1> 	
  3789 0000E1F5 21D2                <1> 	and	edx, edx
  3790 0000E1F7 0F85CFF0FFFF        <1> 	jnz	sysret	; invalid !
  3791                              <1> 
  3792                              <1> 	; full screen copy  ; edx = 0, ecx > 0
  3793 0000E1FD E9D1FDFFFF          <1> 	jmp	sysvideo_17
  3794                              <1> 
  3795                              <1> sysvideo_29_0:
  3796 0000E202 0FB7C2              <1> 	movzx	eax, dx ; bottom right column
  3797 0000E205 6629C8              <1> 	sub	ax, cx  ; - top left column
  3798 0000E208 0F82BEF0FFFF        <1>         jb      sysret ; invalid
  3799 0000E20E 6640                <1> 	inc	ax ; same column no == 1 column	 
  3800 0000E210 50                  <1> 	push	eax ; byte count per window row
  3801                              <1> 
  3802 0000E211 52                  <1> 	push	edx
  3803                              <1> 	;mov	ebx, 320 ; screen width
  3804                              <1> 	; 23/11/2020
  3805 0000E212 89EB                <1> 	mov	ebx, ebp ; 320,600,800
  3806 0000E214 89C8                <1> 	mov	eax, ecx
  3807 0000E216 C1E810              <1> 	shr	eax, 16	; top row
  3808 0000E219 F7E3                <1> 	mul	ebx
  3809 0000E21B 6689CA              <1> 	mov	dx, cx ; top left column
  3810 0000E21E 01D0                <1> 	add	eax, edx
  3811 0000E220 01C6                <1> 	add	esi, eax ; start address 
  3812 0000E222 59                  <1> 	pop	ecx ; edx
  3813 0000E223 89C8                <1> 	mov	eax, ecx
  3814 0000E225 C1E810              <1> 	shr	eax, 16 ; bottom row
  3815 0000E228 F7E3                <1> 	mul	ebx
  3816 0000E22A 6689CA              <1> 	mov	dx, cx ; bottom right column
  3817 0000E22D 01D0                <1> 	add	eax, edx
  3818 0000E22F 5A                  <1> 	pop	edx ; byte count per window row
  3819 0000E230 0500000A00          <1> 	add	eax, 0A0000h
  3820 0000E235 3DFFFF0A00          <1> 	cmp	eax, 0AFFFFh
  3821 0000E23A 0F878CF0FFFF        <1> 	ja	sysret
  3822 0000E240 56                  <1> 	push	esi ; start address 
  3823 0000E241 50                  <1> 	push	eax ; stop address (included)
  3824                              <1> sysvideo_30:
  3825 0000E242 89D1                <1> 	mov	ecx, edx ; byte count
  3826                              <1> 	; user to system video/display page window transfer
  3827                              <1> 	; esi =	user buffer
  3828 0000E244 E848100000          <1> 	call	transfer_to_user_buffer ; fast transfer
  3829                              <1> 	;jc	short sysvideo_31
  3830 0000E249 0F8277FFFFFF        <1> 	jc	sysvideo_28  ; 21/11/2020
  3831 0000E24F 010D[64030300]      <1> 	add	[u.r0], ecx
  3832 0000E255 01DF                <1> 	add	edi, ebx ; next row
  3833 0000E257 01CE                <1> 	add	esi, ecx
  3834 0000E259 3B3C24              <1> 	cmp	edi, [esp] ; stop addr(included in loop)
  3835 0000E25C 76E4                <1> 	jna	short sysvideo_30
  3836                              <1> 	; 21//11/2020
  3837 0000E25E E963FFFFFF          <1> 	jmp	sysvideo_28
  3838                              <1> ;sysvideo_31:
  3839                              <1> 	;pop	ebx ; stop address
  3840                              <1> 	;pop	edi ; start address
  3841                              <1> 	;jmp	sysret
  3842                              <1> 
  3843                              <1> sysvideo_31:
  3844                              <1> 	; 21/11/2020 (TRDOS 386 v2.0.3)
  3845                              <1> 	; bl = 7, 8, 9, 10, 11, 12
  3846                              <1> 	; (bl > 12 is invalid for current kernel version)
  3847                              <1> 
  3848                              <1> 	; 23/11/2020
  3849 0000E263 80FB0D              <1> 	cmp	bl, 13
  3850 0000E266 0F8760F0FFFF        <1> 	ja	sysret
  3851                              <1> 
  3852                              <1> 	; 22/11/2020
  3853 0000E26C BE00000A00          <1> 	mov	esi, 0A0000h
  3854 0000E271 88C8                <1> 	mov	al, cl ; byte for and/or/xor 
  3855 0000E273 B900000100          <1> 	mov	ecx, 65536 ; byte count
  3856 0000E278 890D[64030300]      <1> 	mov	[u.r0], ecx ; return with
  3857                              <1> 			   ; byte count of display page
  3858                              <1> 			   ; (eax > 0 -> OK)	
  3859 0000E27E 80FB0A              <1> 	cmp	bl, 10
  3860 0000E281 722D                <1> 	jb	short sysvideo_32  ; 7, 8, 9
  3861 0000E283 7416                <1> 	je	short sysvideo_31_inc ; 10
  3862 0000E285 80FB0C              <1> 	cmp	bl, 12
  3863 0000E288 7218                <1> 	jb	short sysvideo_31_dec ; 11
  3864 0000E28A 741D                <1> 	je	short sysvideo_31_neg ; 12
  3865                              <1> 	; bl = 13
  3866 0000E28C B900400000          <1> 	mov	ecx, 16384
  3867                              <1> sysvideo_31_not:
  3868                              <1> 	;not	byte [esi]
  3869                              <1> 	;inc	esi
  3870 0000E291 F716                <1> 	not	dword [esi]
  3871 0000E293 AD                  <1> 	lodsd
  3872 0000E294 E2FB                <1> 	loop	sysvideo_31_not
  3873                              <1> sysvideo_31_ok:
  3874 0000E296 E931F0FFFF          <1> 	jmp	sysret
  3875                              <1> sysvideo_31_inc:
  3876 0000E29B FE06                <1> 	inc	byte [esi]
  3877 0000E29D 46                  <1> 	inc	esi
  3878 0000E29E E2FB                <1> 	loop	sysvideo_31_inc
  3879 0000E2A0 EBF4                <1> 	jmp	short sysvideo_31_ok
  3880                              <1> sysvideo_31_dec:
  3881 0000E2A2 FE0E                <1> 	dec	byte [esi]
  3882 0000E2A4 46                  <1> 	inc	esi
  3883 0000E2A5 E2FB                <1> 	loop	sysvideo_31_dec
  3884 0000E2A7 EBED                <1> 	jmp	short sysvideo_31_ok
  3885                              <1> sysvideo_31_neg:
  3886 0000E2A9 F61E                <1> 	neg	byte [esi]
  3887 0000E2AB 46                  <1> 	inc	esi
  3888 0000E2AC E2FB                <1> 	loop	sysvideo_31_neg
  3889 0000E2AE EBE6                <1> 	jmp	short sysvideo_31_ok
  3890                              <1> 
  3891                              <1> sysvideo_32:
  3892                              <1> 	; 22/11/2020
  3893                              <1> 	; bl = 7, 8, 9
  3894                              <1> 	; ecx = 65536 ; byte count
  3895 0000E2B0 B900400000          <1> 	mov	ecx, 16384 ; dword count
  3896 0000E2B5 88C4                <1> 	mov	ah, al
  3897 0000E2B7 6689C2              <1> 	mov	dx, ax
  3898 0000E2BA C1E210              <1> 	shl	edx, 16 
  3899 0000E2BD 6689C2              <1> 	mov	dx, ax
  3900                              <1> 
  3901                              <1> 	;cmp	bl, 7
  3902                              <1> 	;ja	short sysvideo_34
  3903                              <1> 
  3904                              <1> 	; 21/11/2020
  3905 0000E2C0 80FB08              <1> 	cmp	bl, 8
  3906 0000E2C3 740C                <1> 	je	short sysvideo_34
  3907 0000E2C5 7714                <1> 	ja	short sysvideo_36
  3908                              <1> 
  3909                              <1> 	; BL = 7 = AND display page bytes with CL
  3910                              <1> 
  3911                              <1> 	;mov	esi, 0A0000h
  3912                              <1> 	;mov	al, cl ; 21/11/2020
  3913                              <1> 	;mov	ecx, 65536
  3914                              <1> sysvideo_33:
  3915                              <1> 	;and	[esi], al
  3916                              <1> 	;inc	esi
  3917 0000E2C7 21D6                <1> 	and	esi, edx
  3918 0000E2C9 AD                  <1> 	lodsd
  3919 0000E2CA E2FB                <1> 	loop	sysvideo_33
  3920 0000E2CC E9FBEFFFFF          <1> 	jmp	sysret 
  3921                              <1> 
  3922                              <1> sysvideo_34:
  3923                              <1> 	; 21/11/2020
  3924                              <1> 	;cmp	bl, 8
  3925                              <1> 	;ja	short sysvideo_36
  3926                              <1> 
  3927                              <1> 	; BL = 8 = OR display page bytes with CL
  3928                              <1> 
  3929                              <1> 	;mov	esi, 0A0000h
  3930                              <1> 	;mov	al, cl ; 21/11/2020
  3931                              <1> 	;mov	ecx, 65536
  3932                              <1> sysvideo_35:
  3933                              <1> 	;or	[esi], al
  3934                              <1> 	;inc	esi
  3935 0000E2D1 09D6                <1> 	or	esi, edx
  3936 0000E2D3 AD                  <1> 	lodsd
  3937 0000E2D4 E2FB                <1> 	loop	sysvideo_35
  3938 0000E2D6 E9F1EFFFFF          <1> 	jmp	sysret	
  3939                              <1> 
  3940                              <1> sysvideo_36:
  3941                              <1> 	; 21/11/2020
  3942                              <1> 	;cmp	bl, 9
  3943                              <1>         ;ja	sysret ; nothing to do
  3944                              <1> 
  3945                              <1> 	; BL = 9 = XOR display page bytes with CL
  3946                              <1> 
  3947                              <1> 	;mov	esi, 0A0000h
  3948                              <1> 	;mov	al, cl ; 21/11/2020
  3949                              <1> 	;mov	ecx, 65536
  3950                              <1> sysvideo_37:
  3951                              <1> 	;xor	[esi], al
  3952                              <1> 	;inc	esi
  3953 0000E2DB 31D6                <1> 	xor	esi, edx
  3954 0000E2DD AD                  <1> 	lodsd
  3955 0000E2DE E2FB                <1> 	loop	sysvideo_37
  3956 0000E2E0 E9E7EFFFFF          <1> 	jmp	sysret
  3957                              <1> 
  3958                              <1> sysvideo_38:
  3959 0000E2E5 80FF02              <1> 	cmp	bh, 2
  3960 0000E2E8 7705                <1>         ja      short sysvideo_40
  3961                              <1> 
  3962                              <1> sysvideo_39:
  3963                              <1> 	; 23/11/2020
  3964                              <1> 	; BH = 2
  3965                              <1> 	; Super VGA, LINEAR FRAME BUFFER data transfers
  3966                              <1> 	; Not implemented for yet ! (11/07/2016)
  3967 0000E2EA E9DDEFFFFF          <1> 	jmp	sysret
  3968                              <1> 
  3969                              <1> ;sysvideo_39:
  3970                              <1> 	; 23/11/2020
  3971                              <1> 	; BH = 3
  3972                              <1> 	; PIXEL READ/WRITE
  3973                              <1> 	; Not implemented for yet ! (23/11/2020)
  3974                              <1> ;	jmp	sysret
  3975                              <1> 
  3976                              <1> sysvideo_40:
  3977                              <1> 	; 23/11/2020
  3978 0000E2EF 80FF04              <1> 	cmp	bh, 4
  3979 0000E2F2 72F6                <1> 	jb	short sysvideo_39 ; bh = 3, pixel r/w
  3980 0000E2F4 7721                <1> 	ja	short sysvideo_41
  3981                              <1> 	
  3982                              <1> 	; BH = 4
  3983                              <1> 	; Direct User Access for CGA video memory.
  3984                              <1> 	; Setup user's page tables for direct access to 0B8000h.
  3985                              <1> 	;
  3986                              <1> 	; Permission checks are not implemented yet !
  3987                              <1> 	; (11/07/2016)
  3988                              <1> 
  3989 0000E2F6 B800800B00          <1> 	mov	eax, 0B8000h
  3990 0000E2FB B908000000          <1> 	mov	ecx, 8 ; 8 pages (8*4K=32K)
  3991 0000E300 89C3                <1> 	mov	ebx, eax ; 12/05/2017 ; virtual = physical
  3992 0000E302 E8C57DFFFF          <1> 	call	direct_memory_access	
  3993 0000E307 0F82BFEFFFFF        <1> 	jc	sysret
  3994                              <1> 	; eax = 0B8000h if there is not an error
  3995 0000E30D A3[64030300]        <1> 	mov	[u.r0], eax
  3996 0000E312 E9B5EFFFFF          <1> 	jmp	sysret
  3997                              <1> 
  3998                              <1> sysvideo_41:
  3999                              <1> 	; 11/12/2020
  4000                              <1> 	; 10/12/2020
  4001                              <1> 	; 23/11/2020
  4002 0000E317 80FF06              <1> 	cmp	bh, 6
  4003 0000E31A 740B                <1> 	je	short sysvideo_41_0
  4004 0000E31C 0F82B9000000        <1> 	jb	sysvideo_42
  4005 0000E322 E912010000          <1> 	jmp	sysvideo_44 ; ja
  4006                              <1> 
  4007                              <1> sysvideo_41_0:
  4008                              <1> 	; BH = 6
  4009                              <1> 	; Direct User Access to Linear Frame Buffer.
  4010                              <1> 	; Setup user's page tables for direct access to LFB.
  4011                              <1> 	;
  4012                              <1> 	; Permission checks are not implemented yet !
  4013                              <1> 	; (10/12/2020)
  4014                              <1> 
  4015 0000E327 80FBFF              <1> 	cmp	bl, 0FFh ; current video mode
  4016 0000E32A 722C                <1> 	jb	short sysvideo_41_2 ; for desired video mode
  4017                              <1> 
  4018 0000E32C 381D[9A690000]      <1> 	cmp	[CRT_MODE], bl ; VESA VBE video mode ?
  4019 0000E332 750E                <1> 	jne	short sysvideo_41_1
  4020 0000E334 668B0D[9E110300]    <1> 	mov	cx, [video_mode]
  4021 0000E33B 6681E1FF01          <1> 	and	cx, 1FFh
  4022 0000E340 EB29                <1> 	jmp	short sysvideo_41_3
  4023                              <1> sysvideo_41_1:
  4024                              <1> 	; 11/12/2020
  4025 0000E342 88DF                <1> 	mov	bh, bl ; 0FFh
  4026 0000E344 8A1D[9A690000]      <1> 	mov	bl, [CRT_MODE] ; VGA/CGA video m1ode
  4027 0000E34A 8B2D[60030300]      <1> 	mov	ebp, [u.usp]  ; ebp points to user's registers
  4028 0000E350 895510              <1> 	mov	[ebp+16], edx ; return to user with EBX value 
  4029 0000E353 E974EFFFFF          <1> 	jmp	sysret ; return to user with EAX = 0
  4030                              <1> sysvideo_41_2:
  4031                              <1> 	; bl = VESA video mode - 100h
  4032 0000E358 B701                <1> 	mov	bh, 1 ; bx = 1XXh
  4033 0000E35A 53                  <1> 	push	ebx ; requested vesa video mode
  4034 0000E35B E8F655FFFF          <1> 	call	vbe_biosfn_return_current_mode
  4035 0000E360 59                  <1> 	pop	ecx ; requested vesa video mode
  4036 0000E361 6681E3FF01          <1> 	and	bx, 1FFh
  4037 0000E366 6639D9              <1> 	cmp	cx, bx
  4038 0000E369 7564                <1> 	jne	short sysvideo_41_8
  4039                              <1> sysvideo_41_3:
  4040 0000E36B 663B0D[AA110300]    <1> 	cmp	cx, [LFB_Info+LFBINFO.mode]
  4041 0000E372 755B                <1> 	jne	short sysvideo_41_8
  4042                              <1> sysvideo_41_4:
  4043                              <1> 	; 11/12/2020
  4044 0000E374 A1[AC110300]        <1> 	mov	eax, [LFB_Info+LFBINFO.LFB_addr]
  4045                              <1> 	; 21/12/2020
  4046 0000E379 09C0                <1> 	or	eax, eax
  4047 0000E37B 744D                <1> 	jz	short sysvideo_41_7
  4048                              <1> 	;
  4049 0000E37D 8B0D[B0110300]      <1> 	mov	ecx, [LFB_Info+LFBINFO.LFB_size] ; buff size
  4050 0000E383 89C3                <1> 	mov 	ebx, eax ; user's address = physical address
  4051                              <1> 	;push	ebx
  4052 0000E385 51                  <1> 	push	ecx
  4053                              <1> 	; 21/12/2020
  4054 0000E386 81C1FF0F0000        <1> 	add	ecx, 4095  ; PAGESIZE - 1
  4055                              <1> 	; 14/12/2020
  4056 0000E38C C1E90C              <1> 	shr	ecx, 12  ; convert bytes to pages
  4057 0000E38F E8387DFFFF          <1> 	call	direct_memory_access
  4058 0000E394 5A                  <1> 	pop	edx  ; linear frame buffer size in bytes
  4059                              <1> 	;pop	eax  ; linear frame buffer address (physical)
  4060 0000E395 7233                <1> 	jc	short sysvideo_41_7 ; [u.r0] = eax = 0
  4061                              <1> sysvideo_41_5:
  4062 0000E397 668B0D[B6110300]    <1> 	mov	cx, [LFB_Info+LFBINFO.Y_res] ; screen height
  4063 0000E39E C1E110              <1> 	shl	ecx, 16
  4064 0000E3A1 668B0D[B4110300]    <1> 	mov	cx,  [LFB_Info+LFBINFO.X_res] ; screen width
  4065 0000E3A8 31DB                <1> 	xor	ebx, ebx
  4066 0000E3AA 8A1D[B8110300]      <1> 	mov	bl, [LFB_Info+LFBINFO.bpp] ; bits per pixel
  4067 0000E3B0 8A3D[AA110300]      <1> 	mov	bh, [LFB_Info+LFBINFO.mode] ; XX part of 1XXh	
  4068 0000E3B6 8B2D[60030300]      <1> 	mov	ebp, [u.usp]  ; ebp points to user's registers
  4069 0000E3BC 895514              <1> 	mov	[ebp+20], edx ; return to user with EDX value 
  4070 0000E3BF 895D10              <1> 	mov	[ebp+16], ebx ; EBX
  4071 0000E3C2 894D18              <1> 	mov	[ebp+24], ecx ; ECX
  4072                              <1> sysvideo_41_6:
  4073 0000E3C5 A3[64030300]        <1> 	mov	[u.r0], eax ; LFB address
  4074                              <1> sysvideo_41_7:
  4075 0000E3CA E9FDEEFFFF          <1> 	jmp	sysret 
  4076                              <1> sysvideo_41_8:
  4077                              <1> 	; cx = mode
  4078                              <1> 	; 21/12/2020
  4079 0000E3CF 80CD40              <1> 	or	ch, 40h  ; Linear frame buffer flag	
  4080 0000E3D2 E8A153FFFF          <1> 	call	_vbe_biosfn_return_mode_info
  4081 0000E3D7 72F1                <1> 	jc	short sysvideo_41_7
  4082 0000E3D9 EB99                <1> 	jmp	short sysvideo_41_4
  4083                              <1> 	
  4084                              <1> sysvideo_42:
  4085                              <1> 	; BH = 5
  4086                              <1> 	; Direct User Access for VGA video memory.
  4087                              <1> 	; Setup user's page tables for direct access to 0A0000h.
  4088                              <1> 	;
  4089                              <1> 	; Permission checks are not implemented yet !
  4090                              <1> 	; (11/07/2016)
  4091                              <1> 
  4092 0000E3DB B800000A00          <1> 	mov	eax, 0A0000h
  4093 0000E3E0 B910000000          <1> 	mov	ecx, 16 ; 16 pages (16*4K=64K)
  4094 0000E3E5 89C3                <1> 	mov	ebx, eax ; 12/05/2017 ; virtual = physical
  4095 0000E3E7 E8E07CFFFF          <1> 	call	direct_memory_access	
  4096 0000E3EC 0F82DAEEFFFF        <1> 	jc	sysret
  4097                              <1> 	; eax = 0A0000h if there is not an error
  4098 0000E3F2 A3[64030300]        <1> 	mov	[u.r0], eax
  4099 0000E3F7 E9D0EEFFFF          <1> 	jmp	sysret
  4100                              <1> 
  4101                              <1> sysvideo_43:
  4102                              <1> 	; 12/12/2020
  4103                              <1> 	; 11/12/2020
  4104                              <1> 	; 23/11/2020
  4105                              <1> 	; BH = 7
  4106                              <1> 	; Get (Super/Extended VGA) mode
  4107                              <1> 	; and Linear Frame Buffer info.
  4108                              <1> 	
  4109                              <1> 	; 11/12/2020
  4110 0000E3FC 803D[9A690000]FF    <1> 	cmp	byte [CRT_MODE], 0FFh ; (extended mode?)
  4111                              <1> 	;jb	sysvideo_41_1	; not a VESA VBE mode
  4112                              <1> 	; 12/12/2020
  4113 0000E403 7305                <1> 	jnb	short sysvideo_43_0
  4114 0000E405 E938FFFFFF          <1> 	jmp	sysvideo_41_1
  4115                              <1> 
  4116                              <1> sysvideo_43_0:
  4117 0000E40A E84755FFFF          <1> 	call	vbe_biosfn_return_current_mode
  4118 0000E40F 6681E3FF01          <1> 	and	bx, 1FFh
  4119 0000E414 663B1D[AA110300]    <1> 	cmp	bx, [LFB_Info+LFBINFO.mode]
  4120 0000E41B 7510                <1> 	jne	short sysvideo_43_2
  4121                              <1> sysvideo_43_1:
  4122 0000E41D A1[AC110300]        <1> 	mov	eax, [LFB_Info+LFBINFO.LFB_addr]
  4123 0000E422 8B15[B0110300]      <1> 	mov	edx, [LFB_Info+LFBINFO.LFB_size]
  4124 0000E428 E96AFFFFFF          <1> 	jmp	sysvideo_41_5
  4125                              <1> sysvideo_43_2:
  4126 0000E42D E84653FFFF          <1> 	call	_vbe_biosfn_return_mode_info
  4127 0000E432 73E9                <1> 	jnc	short sysvideo_43_1
  4128 0000E434 E993EEFFFF          <1> 	jmp	sysret
  4129                              <1> 
  4130                              <1> sysvideo_44:
  4131                              <1> 	; 11/12/2020
  4132                              <1> 	; 23/11/2020
  4133 0000E439 80FF08              <1> 	cmp	bh, 8
  4134 0000E43C 72BE                <1> 	jb	short sysvideo_43 ; video mode & lfb info
  4135 0000E43E 0F8780000000        <1> 	ja	sysvideo_45 ; 12/12/2020
  4136                              <1> 
  4137                              <1> 	; BH = 8
  4138                              <1> 	; Set (Super/Extended VGA) mode & return LFB info
  4139                              <1> 	;
  4140                              <1> 	
  4141                              <1> 	; 11/12/2020
  4142 0000E444 80FBFF              <1> 	cmp	bl, 0FFh  ; CGA/VGA mode ?
  4143 0000E447 7318                <1> 	jnb	short sysvideo_44_1
  4144                              <1> 
  4145                              <1> 	;xor	ah, ah
  4146 0000E449 88D8                <1> 	mov	al, bl
  4147                              <1> sysvideo_44_0:
  4148 0000E44B E80933FFFF          <1> 	call	_int10h  ; uses vbe3 pmi32 option
  4149 0000E450 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh ; -1
  4150 0000E453 7459                <1> 	je	short sysvideo_44_3 ; error
  4151                              <1> 	
  4152                              <1> 	; 11/12/2020
  4153                              <1> 	; alternative (it does not use vbe3 pmi32)
  4154                              <1> 	;push	eax
  4155                              <1> 	;call	_set_mode
  4156                              <1> 	;pop	eax
  4157                              <1> 	;jc	short sysvideo_44_3
  4158                              <1> 	
  4159                              <1> 	;inc	eax
  4160 0000E455 FEC0                <1> 	inc	al
  4161                              <1> 	;mov	[u.r0], ax ; video mode + 1	
  4162 0000E457 A2[64030300]        <1> 	mov	[u.r0], al
  4163 0000E45C E96BEEFFFF          <1> 	jmp	sysret
  4164                              <1> 
  4165                              <1> sysvideo_44_1:
  4166                              <1> 	; cx = vesa video mode
  4167 0000E461 6689C8              <1> 	mov	ax, cx
  4168 0000E464 663D0001            <1> 	cmp	ax, 100h
  4169 0000E468 72E1                <1> 	jb	short sysvideo_44_0 ; VGA/CGA mode
  4170 0000E46A 663DFF01            <1> 	cmp	ax, 1FFh
  4171                              <1> 	;ja	short sysvideo_44_4 ; not valid
  4172 0000E46E 773E                <1> 	ja	short sysvideo_44_3
  4173 0000E470 50                  <1> 	push	eax
  4174 0000E471 6689C3              <1> 	mov	bx, ax
  4175 0000E474 66B8024F            <1> 	mov	ax, 4F02h
  4176                              <1> 
  4177                              <1> 	; simulate _int10h (int 31h) for func 4F02h
  4178                              <1> 	;pushfd
  4179                              <1> 	;push	cs
  4180                              <1> 	;push	sysvideo_44_1_retn 
  4181                              <1> 	;push	es ; *
  4182                              <1> 	;push	ds ; **	; SAVE WORK AND PARAMETER REGISTERS
  4183                              <1> 	;jmp	VBE_func
  4184                              <1> ;sysvideo_44_1_retn:	
  4185                              <1> 	
  4186 0000E478 E8DC32FFFF          <1> 	call	_int10h ; simulate int 10h (int 31h)
  4187                              <1> 
  4188 0000E47D 6683F84F            <1> 	cmp	ax, 004Fh
  4189 0000E481 58                  <1> 	pop	eax
  4190 0000E482 752A                <1> 	jne	short sysvideo_44_3 ; error
  4191                              <1> 	;pop	eax
  4192 0000E484 40                  <1> 	inc	eax
  4193 0000E485 A3[64030300]        <1> 	mov	[u.r0], eax ; video mode + 1
  4194 0000E48A 09D2                <1> 	or	edx, edx ; is LFBINFO requested by user ?	
  4195                              <1> 	;jz	short sysvideo_44_4
  4196 0000E48C 7420                <1> 	jz	short sysvideo_44_3 ; no
  4197                              <1> 
  4198                              <1> 	; 11/12/2020
  4199                              <1> 	; Check LFBINFO table/structure
  4200                              <1> 	; (it is set by vbe2 'vbe_biosfn_set_mode'
  4201                              <1> 	; but if vbe3 vbios pmi is in use,
  4202                              <1> 	; it will not set LFBINFO table)
  4203                              <1> 
  4204 0000E48E 52                  <1> 	push	edx
  4205 0000E48F 48                  <1> 	dec	eax  ; video mode
  4206 0000E490 BE[AA110300]        <1> 	mov	esi, LFB_Info
  4207 0000E495 663B06              <1> 	cmp	ax, [esi+LFBINFO.mode]
  4208 0000E498 7407                <1> 	je	short sysvideo_44_2
  4209                              <1> 
  4210 0000E49A E8D952FFFF          <1> 	call	_vbe_biosfn_return_mode_info
  4211                              <1> 	;jnc	short sysvideo_44_2
  4212 0000E49F 7212                <1> 	jc	short sysvideo_44_4 ; edx = 0	
  4213                              <1> 
  4214                              <1> 	;; clear LFBINFO table for invalidating	
  4215                              <1> 	;mov	ecx, LFBINFO.size ; 16
  4216                              <1> 	;mov	edi, esi ; LFB_Info table address
  4217                              <1> 	;xor	eax, eax
  4218                              <1> 	;rep	stosb
  4219                              <1> 
  4220                              <1> sysvideo_44_2:
  4221                              <1> 	;pop	ecx
  4222                              <1> 	;mov	edi, ecx ; user buffer
  4223 0000E4A1 5F                  <1> 	pop	edi
  4224 0000E4A2 B910000000          <1> 	mov	ecx, LFBINFO.size ; 16
  4225 0000E4A7 E8E50D0000          <1> 	call	transfer_to_user_buffer ; fast transfer
  4226 0000E4AC 7206                <1> 	jc	short sysvideo_44_5
  4227                              <1> 	
  4228                              <1> 	;jmp	sysret
  4229                              <1> sysvideo_44_3:	
  4230                              <1> 	;pop	eax ; [u.r0] = 0		
  4231                              <1> ;sysvideo_44_4:
  4232 0000E4AE E919EEFFFF          <1> 	jmp	sysret
  4233                              <1> 
  4234                              <1> sysvideo_44_4:
  4235 0000E4B3 5A                  <1> 	pop	edx
  4236                              <1> sysvideo_44_5:
  4237 0000E4B4 31D2                <1> 	xor	edx, edx ; 0
  4238                              <1> 	; edx = 0 -> invalid LFBINFO data
  4239 0000E4B6 8B2D[60030300]      <1> 	mov	ebp, [u.usp]  ; ebp points to user's registers
  4240 0000E4BC 895514              <1> 	mov	[ebp+20], edx ; return to user with EDX value 
  4241 0000E4BF E908EEFFFF          <1> 	jmp	sysret
  4242                              <1> 
  4243                              <1> sysvideo_45:
  4244                              <1> 	; 03/12/2020
  4245 0000E4C4 80FF0A              <1> 	cmp	bh, 10
  4246 0000E4C7 7205                <1> 	jb	short sysvideo_46 ; VESA VBE3 pmi parms
  4247                              <1> 
  4248                              <1> 	; 11/12/2020
  4249                              <1> 	;	
  4250                              <1> 	; BH > 9
  4251                              <1> 	;
  4252                              <1> 	; Not implemented yet !
  4253                              <1> 	; (23/11/2020)
  4254 0000E4C9 E9FEEDFFFF          <1> 	jmp	sysret
  4255                              <1> 
  4256                              <1> sysvideo_46:
  4257                              <1> 	; 04/12/2020
  4258                              <1> 	; 03/12/2020
  4259                              <1> 	; BH = 9
  4260                              <1> 	; Set/Get VESA VBE3 protected mode interface params
  4261                              <1> 
  4262 0000E4CE 803D[44090000]03    <1> 	cmp	byte [vbe3], 3
  4263 0000E4D5 751D                <1> 	jne	short sysvideo_49 ; not applicable if
  4264                              <1> 				; vbe3 compatible viode bios
  4265                              <1> 				; is not detected by kernel	
  4266 0000E4D7 80FB02              <1> 	cmp	bl, 2
  4267 0000E4DA 7718                <1> 	ja	short sysvideo_49 ; bl > 2 not implemented
  4268 0000E4DC 7208                <1> 	jb	short sysvideo_47
  4269 0000E4DE 8A1D[9C110300]      <1> 	mov	bl, [pmi32]; Video bios 32 bit PMI functions
  4270 0000E4E4 EB06                <1> 	jmp	short sysvideo_48
  4271                              <1> sysvideo_47:
  4272 0000E4E6 881D[9C110300]      <1> 	mov	[pmi32], bl ; 1 = enabled, 0 = disabled 
  4273                              <1> sysvideo_48:
  4274 0000E4EC FEC3                <1> 	inc	bl
  4275 0000E4EE 881D[64030300]      <1> 	mov	[u.r0], bl ; function result is return value 
  4276                              <1> sysvideo_49:
  4277 0000E4F4 E9D3EDFFFF          <1> 	jmp	sysret
  4278                              <1> 
  4279                              <1> mkdir:
  4280                              <1> 	; 04/12/2015 (14 byte directory names)
  4281                              <1> 	; 12/10/2015
  4282                              <1> 	; 17/06/2015 (Retro UNIX 386 v1 - Beginning)
  4283                              <1> 	; 29/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
  4284                              <1> 	;
  4285                              <1> 	; 'mkdir' makes a directory entry from the name pointed to
  4286                              <1> 	; by u.namep into the current directory.
  4287                              <1> 	;
  4288                              <1> 	; INPUTS ->
  4289                              <1> 	;    u.namep - points to a file name 
  4290                              <1> 	;	           that is about to be a directory entry.
  4291                              <1> 	;    ii - current directory's i-number.	
  4292                              <1> 	; OUTPUTS ->
  4293                              <1> 	;    u.dirbuf+2 - u.dirbuf+10 - contains file name. 
  4294                              <1> 	;    u.off - points to entry to be filled 
  4295                              <1> 	;	     in the current directory		
  4296                              <1> 	;    u.base - points to start of u.dirbuf.
  4297                              <1> 	;    r1 - contains i-number of current directory 
  4298                              <1> 	;	
  4299                              <1> 	; ((AX = R1)) output
  4300                              <1> 	;
  4301                              <1> 	;    (Retro UNIX Prototype : 11/11/2012, UNIXCOPY.ASM)
  4302                              <1>         ;    ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  4303                              <1> 	;
  4304                              <1> 
  4305                              <1> 	; 17/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
  4306 0000E4F9 31C0                <1> 	xor 	eax, eax
  4307 0000E4FB BF[9A030300]        <1> 	mov     edi, u.dirbuf+2
  4308 0000E500 89FE                <1> 	mov	esi, edi
  4309 0000E502 AB                  <1> 	stosd
  4310 0000E503 AB                  <1> 	stosd
  4311                              <1> 	; 04/12/2015 (14 byte directory names)
  4312 0000E504 AB                  <1> 	stosd
  4313 0000E505 66AB                <1> 	stosw
  4314                              <1> 		; jsr r0,copyz; u.dirbuf+2; u.dirbuf+10. / clear this
  4315 0000E507 89F7                <1> 	mov	edi, esi ; offset to u.dirbuf
  4316                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
  4317                              <1> 	;mov 	ebp, [u.namep]
  4318 0000E509 E80D030000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
  4319                              <1> 		; esi = physical address (page start + offset)
  4320                              <1> 		; ecx = byte count in the page (1 - 4096)
  4321                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
  4322                              <1> 		; mov u.namep,r2 / r2 points to name of directory entry
  4323                              <1> 		; mov $u.dirbuf+2,r3 / r3 points to u.dirbuf+2
  4324                              <1> mkdir_1: ; 1: 
  4325 0000E50E 45                  <1> 	inc	ebp ; 12/10/2015
  4326                              <1> 	;
  4327                              <1> 	; / put characters in the directory name in u.dirbuf+2 - u.dirbuf+10
  4328                              <1> 	 ; 01/08/2013
  4329 0000E50F AC                  <1> 	lodsb
  4330                              <1> 		; movb (r2)+,r1 / move character in name to r1
  4331 0000E510 20C0                <1> 	and 	al, al
  4332 0000E512 7427                <1> 	jz 	short mkdir_3 	  
  4333                              <1> 		; beq 1f / if null, done
  4334 0000E514 3C2F                <1> 	cmp	al, '/'
  4335                              <1> 		; cmp r1,$'/ / is it a "/"?
  4336 0000E516 7414                <1> 	je	short mkdir_err
  4337                              <1> 	;je	error
  4338                              <1> 		; beq error9 / yes, error
  4339                              <1> 	; 12/10/2015
  4340 0000E518 6649                <1> 	dec	cx
  4341 0000E51A 7505                <1> 	jnz	short mkdir_2
  4342                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
  4343 0000E51C E800030000          <1> 	call	trans_addr_nm ; convert virtual address to physical
  4344                              <1> 		; esi = physical address (page start + offset)
  4345                              <1> 		; ecx = byte count in the page
  4346                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
  4347                              <1> mkdir_2:
  4348 0000E521 81FF[A8030300]      <1> 	cmp     edi, u.dirbuf+16 ; ; 04/12/2015 (10 -> 16) 
  4349                              <1> 		; cmp r3,$u.dirbuf+10. / have we reached the last slot for
  4350                              <1> 				     ; / a char?
  4351 0000E527 74E5                <1> 	je	short mkdir_1
  4352                              <1> 		; beq 1b / yes, go back
  4353 0000E529 AA                  <1> 	stosb
  4354                              <1> 		; movb r1,(r3)+ / no, put the char in the u.dirbuf
  4355 0000E52A EBE2                <1> 	jmp 	short mkdir_1
  4356                              <1> 		; br 1b / get next char
  4357                              <1> mkdir_err:
  4358                              <1> 	; 17/06/2015
  4359 0000E52C C705[C8030300]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
  4359 0000E534 0000                <1>
  4360 0000E536 E971EDFFFF          <1> 	jmp	error
  4361                              <1> 
  4362                              <1> mkdir_3: ; 1:
  4363 0000E53B A1[78030300]        <1> 	mov	eax, [u.dirp]
  4364 0000E540 A3[80030300]        <1> 	mov	[u.off], eax
  4365                              <1> 		; mov u.dirp,u.off / pointer to empty current directory
  4366                              <1> 				 ; / slot to u.off
  4367                              <1> wdir: ; 29/04/2013
  4368 0000E545 C705[84030300]-     <1>         mov     dword [u.base], u.dirbuf
  4368 0000E54B [98030300]          <1>
  4369                              <1> 		; mov $u.dirbuf,u.base / u.base points to created file name
  4370 0000E54F C705[88030300]1000- <1>         mov     dword [u.count], 16 ; 04/12/2015 (10 -> 16) 
  4370 0000E557 0000                <1>
  4371                              <1> 		; mov $10.,u.count / u.count = 10
  4372 0000E559 66A1[51040300]      <1> 	mov	ax, [ii] 
  4373                              <1> 		; mov ii,r1 / r1 has i-number of current directory
  4374 0000E55F B201                <1> 	mov	dl, 1 ; owner flag mask ; RETRO UNIX 8086 v1 modification !
  4375 0000E561 E8791D0000          <1> 	call 	access
  4376                              <1> 		; jsr r0,access; 1 / get i-node and set its file up 
  4377                              <1> 				 ; / for writing
  4378                              <1> 	; AX = i-number of current directory
  4379                              <1> 	; 01/08/2013
  4380 0000E566 FE05[C6030300]      <1> 	inc     byte [u.kcall] ; the caller is 'mkdir' sign	
  4381 0000E56C E8820F0000          <1> 	call	writei
  4382                              <1> 		; jsr r0,writei / write into directory
  4383 0000E571 C3                  <1> 	retn	
  4384                              <1> 		; rts r0
  4385                              <1> 
  4386                              <1> sysexec:
  4387                              <1> 	; 18/11/2017
  4388                              <1> 	; 14/11/2017
  4389                              <1> 	; 13/11/2017
  4390                              <1> 	; 24/10/2016, 04/01/2017
  4391                              <1> 	; 24/04/2016 - TRDOS 386 (TRDOS v2.0)
  4392                              <1> 	; 23/06/2015 - 23/10/2015 (Retro UNIX 386 v1)
  4393                              <1> 	; 03/06/2013 - 06/12/2013 (Retro UNIX 8086 v1)
  4394                              <1> 	;
  4395                              <1> 	; 'sysexec' initiates execution of a file whose path name if
  4396                              <1> 	; pointed to by 'name' in the sysexec call. 
  4397                              <1> 	; 'sysexec' performs the following operations:
  4398                              <1> 	;    1. obtains i-number of file to be executed via 'namei'.
  4399                              <1> 	;    2. obtains i-node of file to be exceuted via 'iget'.
  4400                              <1> 	;    3. sets trap vectors to system routines.
  4401                              <1> 	;    4. loads arguments to be passed to executing file into
  4402                              <1> 	;	highest locations of user's core
  4403                              <1> 	;    5. puts pointers to arguments in locations immediately
  4404                              <1> 	;	following arguments.
  4405                              <1> 	;    6.	saves number of arguments in next location.
  4406                              <1> 	;    7. intializes user's stack area so that all registers
  4407                              <1> 	;	will be zeroed and the PS is cleared and the PC set
  4408                              <1> 	;	to core when 'sysret' restores registers 
  4409                              <1> 	;	and does an rti.
  4410                              <1> 	;    8. inializes u.r0 and u.sp
  4411                              <1> 	;    9. zeros user's core down to u.r0
  4412                              <1> 	;   10.	reads executable file from storage device into core
  4413                              <1> 	;	starting at location 'core'.
  4414                              <1> 	;   11.	sets u.break to point to end of user's code with
  4415                              <1> 	;	data area appended.
  4416                              <1> 	;   12.	calls 'sysret' which returns control at location
  4417                              <1> 	;	'core' via 'rti' instruction. 		  		
  4418                              <1> 	;
  4419                              <1> 	; Calling sequence:
  4420                              <1> 	;	sysexec; namep; argp
  4421                              <1> 	; Arguments:
  4422                              <1> 	;	namep - points to pathname of file to be executed
  4423                              <1> 	;	argp  - address of table of argument pointers
  4424                              <1> 	;	argp1... argpn - table of argument pointers
  4425                              <1> 	;	argp1:<...0> ... argpn:<...0> - argument strings
  4426                              <1> 	; Inputs: (arguments)
  4427                              <1> 	; Outputs: -	
  4428                              <1> 	; ...............................................................
  4429                              <1> 	;
  4430                              <1> 	; Retro UNIX 386 v1 modification: 
  4431                              <1> 	;	User application runs in it's own virtual space 
  4432                              <1> 	;	which is izolated from kernel memory (and other
  4433                              <1> 	;	memory pages) via 80386	paging in ring 3 
  4434                              <1> 	;	privilige mode. Virtual start address is always 0.
  4435                              <1> 	;	User's core memory starts at linear address 400000h
  4436                              <1> 	;	(the end of the 1st 4MB).
  4437                              <1> 	;
  4438                              <1> 	; Retro UNIX 8086 v1 modification: 
  4439                              <1> 	;	user/application segment and system/kernel segment
  4440                              <1> 	;	are different and sysenter/sysret/sysrele routines
  4441                              <1> 	;	are different (user's registers are saved to 
  4442                              <1> 	;	and then restored from system's stack.)
  4443                              <1> 	;
  4444                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
  4445                              <1> 	;	      arguments which were in these registers;
  4446                              <1> 	;	      but, it returns by putting the 1st argument
  4447                              <1> 	;	      in 'u.namep' and the 2nd argument
  4448                              <1> 	;	      on top of stack. (1st argument is offset of the
  4449                              <1> 	;	      file/path name in the user's program segment.)		 	
  4450                              <1> 	
  4451                              <1> 	;call	arg2
  4452                              <1> 	; * name - 'u.namep' points to address of file/path name
  4453                              <1> 	;          in the user's program segment ('u.segmnt')
  4454                              <1> 	;          with offset in BX register (as sysopen argument 1).
  4455                              <1> 	; * argp - sysexec argument 2 is in CX register 
  4456                              <1> 	;          which is on top of stack.
  4457                              <1> 	;
  4458                              <1> 		; jsr r0,arg2 / arg0 in u.namep,arg1 on top of stack
  4459                              <1> 
  4460                              <1> 	; 23/06/2015 (32 bit modifications)
  4461                              <1> 
  4462                              <1> 	;; 13/11/2017
  4463                              <1> 	;;mov	[u.namep], ebx ; argument 1
  4464                              <1>         ; 18/10/2015
  4465 0000E572 890D[4C040300]      <1> 	mov     [argv], ecx  ; * ; argument 2
  4466                              <1> 
  4467                              <1> 	; 13/11/2017
  4468 0000E578 89DE                <1> 	mov	esi, ebx
  4469 0000E57A E894210000          <1> 	call	set_working_path_x
  4470 0000E57F 7319                <1> 	jnc	short sysexec_0
  4471                              <1> 
  4472                              <1> 	;; 'bad command or file name'
  4473                              <1> 	;mov	eax, ERR_BAD_CMD_ARG ; 01h ; TRDOS 8086
  4474                              <1> 	
  4475                              <1> 	; 'file not found !' error
  4476 0000E581 B802000000          <1> 	mov	eax, ERR_NOT_FOUND ; 02h ; TRDOS 8086
  4477                              <1> sysexec_not_found_err:
  4478                              <1> sysexec_access_error:
  4479                              <1> sysexec_ext_error:
  4480 0000E586 A3[64030300]        <1> 	mov	[u.r0], eax
  4481 0000E58B A3[C8030300]        <1> 	mov	[u.error], eax
  4482 0000E590 E853220000          <1> 	call 	reset_working_path
  4483 0000E595 E912EDFFFF          <1> 	jmp	error
  4484                              <1> 
  4485                              <1> sysexec_0:
  4486                              <1> 	; 13/11/2017
  4487                              <1> 	;mov	esi, FindFile_Name
  4488 0000E59A 66B80018            <1>         mov	ax, 1800h ; Only files 
  4489 0000E59E E8AEA8FFFF          <1> 	call	find_first_file
  4490 0000E5A3 72E1                <1> 	jc	short sysexec_not_found_err ; eax = 2
  4491                              <1> 
  4492                              <1> 	; check_ file attributes
  4493                              <1> 	; (attribute bits = 00ADVSHR) ; 18h = Directory+Volume
  4494                              <1> 	; BL = Attributes byte
  4495                              <1> 	
  4496 0000E5A5 F6C306              <1>         test	bl, 6  ; system file or hidden file (S+H) 
  4497                              <1> 	;jz	short sysexec_0ext
  4498 0000E5A8 7417                <1> 	jz	short sysexec_1 ; yes
  4499                              <1> 
  4500                              <1> 	; 13/11/2017 
  4501                              <1> 	; /// TRDOS386 permission check for multiuser mode ///
  4502                              <1> 	; SYSTEM file or HIDDEN file !!
  4503                              <1> 	; (Only super user has permission to run this file.)
  4504                              <1> 	
  4505                              <1> 	; ([u.uid]=0 for super user or root in multiuser mode)  
  4506                              <1> 	; ([u.uid]=0 for any users in singleuser mode) 
  4507 0000E5AA 803D[B0030300]00    <1> 	cmp 	byte [u.uid], 0 ; Super User ([u.uid]=0) ?
  4508                              <1> 	;jna	short sysexec_0ext
  4509 0000E5B1 760E                <1> 	jna	short sysexec_1 ; yes 
  4510                              <1> 
  4511                              <1> 	; 'permission denied !' error  
  4512 0000E5B3 B80B000000          <1>         mov	eax, ERR_FILE_ACCESS  ; 11 = ERR_PERM_DENIED
  4513 0000E5B8 EBCC                <1>         jmp	short sysexec_access_error
  4514                              <1> 
  4515                              <1> sysexec_not_exf:
  4516                              <1> 	; 'not executable file !' error
  4517 0000E5BA B816000000          <1> 	mov	eax, ERR_NOT_EXECUTABLE
  4518 0000E5BF EBC5                <1> 	jmp	sysexec_ext_error
  4519                              <1> 
  4520                              <1> ;sysexec_0ext:
  4521                              <1> sysexec_1:
  4522                              <1> 	; 18/11/2017
  4523 0000E5C1 BE[806D0100]        <1> 	mov	esi, FindFile_Name
  4524                              <1> 	; 13/11/2017
  4525                              <1> 	; check program file name extension
  4526                              <1> 	; ('.PRG' for current TRDOS version)
  4527 0000E5C6 E829C3FFFF          <1> 	call	check_prg_filename_ext
  4528 0000E5CB 72ED                <1> 	jc	short sysexec_not_exf
  4529                              <1> 	
  4530                              <1> 	; 18/11/2017
  4531 0000E5CD 3C50                <1> 	cmp	al, 'P'
  4532 0000E5CF 75E9                <1> 	jne	short sysexec_not_exf	
  4533                              <1> 
  4534                              <1> 	; '.PRG' extension is OK.
  4535                              <1> 	; Only '.PRG' files are valid program files
  4536                              <1> 	; for current TRDOS 386 version.
  4537                              <1> 
  4538 0000E5D1 8B15[AC6D0100]      <1> 	mov	edx, [FindFile_DirEntry+DirEntry_FileSize]
  4539 0000E5D7 66A1[A46D0100]      <1> 	mov	ax, [FindFile_DirEntry+DirEntry_FstClusHI]
  4540 0000E5DD C1E010              <1> 	shl	eax, 16
  4541 0000E5E0 66A1[AA6D0100]      <1> 	mov	ax, [FindFile_DirEntry+DirEntry_FstClusLO]
  4542                              <1> 	; EAX = First Cluster number
  4543                              <1> 	; EDX = File Size
  4544                              <1> 
  4545 0000E5E6 A3[51040300]        <1> 	mov	[ii], eax
  4546 0000E5EB 8915[55040300]      <1> 	mov	[i.size], edx
  4547                              <1> 
  4548                              <1> ;sysexec_1:
  4549                              <1> 	; 13/11/2017 - TRDOS 386 (TRDOS v2.0)
  4550                              <1> 	; 24/06/2015 - 23/10/2015 (Retro UNIX 386 v1)
  4551                              <1>         ; Moving arguments to the end of [u.upage]
  4552                              <1> 	; (by regarding page borders in user's memory space)
  4553                              <1> 	;
  4554                              <1> 	; 10/10/2015
  4555                              <1> 	; 21/07/2015
  4556 0000E5F1 89E5                <1> 	mov	ebp, esp ; (**)
  4557                              <1> 	; 18/10/2015
  4558 0000E5F3 89EF                <1> 	mov 	edi, ebp
  4559 0000E5F5 B900010000          <1> 	mov 	ecx, MAX_ARG_LEN ; 256
  4560                              <1> 	;sub	edi, MAX_ARG_LEN ; 256
  4561 0000E5FA 29CF                <1> 	sub	edi, ecx
  4562 0000E5FC 89FC                <1> 	mov	esp, edi ; *!*
  4563 0000E5FE 31C0                <1> 	xor	eax, eax
  4564 0000E600 A3[8C030300]        <1> 	mov 	[u.nread], eax ; 0
  4565 0000E605 66A3[4A040300]      <1> 	mov	[argc], ax ; 0 ; 13/11/2017
  4566 0000E60B 49                  <1> 	dec	ecx ; 256 - 1
  4567 0000E60C 890D[88030300]      <1> 	mov 	[u.count], ecx ; MAX_ARG_LEN - 1 ; 255
  4568                              <1> 	;mov 	dword [u.count], MAX_ARG_LEN - 1 ; 255
  4569                              <1> sysexec_2:
  4570 0000E612 8B35[4C040300]      <1> 	mov	esi, [argv] ; 18/10/2015 
  4571 0000E618 E866000000          <1> 	call	get_argp
  4572 0000E61D B904000000          <1> 	mov	ecx, 4 ; mov ecx, 4
  4573                              <1> sysexec_3:
  4574 0000E622 21C0                <1> 	and	eax, eax
  4575 0000E624 0F846F050000        <1>         jz      sysexec_6
  4576                              <1> 	; 18/10/2015
  4577 0000E62A 010D[4C040300]      <1> 	add	[argv], ecx ; 4
  4578 0000E630 66FF05[4A040300]    <1> 	inc	word [argc]
  4579                              <1> 	;
  4580 0000E637 A3[84030300]        <1> 	mov	[u.base], eax
  4581                              <1>  	; 23/10/2015
  4582 0000E63C 66C705[C4030300]00- <1> 	mov	word [u.pcount], 0
  4582 0000E644 00                  <1>
  4583                              <1> sysexec_4:
  4584 0000E645 E8E70B0000          <1> 	call	cpass ; get a character from user's core memory
  4585 0000E64A 750E                <1>         jnz	short sysexec_5
  4586                              <1> 		; (max. 255 chars + null)
  4587                              <1> 	; 18/10/2015
  4588 0000E64C 28C0                <1> 	sub 	al, al
  4589 0000E64E AA                  <1> 	stosb
  4590 0000E64F FF05[8C030300]      <1> 	inc	dword [u.nread]
  4591 0000E655 E93F050000          <1> 	jmp	sysexec_6 ; 24/04/2016
  4592                              <1> sysexec_5:
  4593 0000E65A AA                  <1> 	stosb
  4594 0000E65B 20C0                <1> 	and 	al, al
  4595 0000E65D 75E6                <1> 	jnz	short sysexec_4
  4596 0000E65F B904000000          <1> 	mov	ecx, 4
  4597 0000E664 390D[48040300]      <1> 	cmp	[ncount], ecx ; 4
  4598 0000E66A 72A6                <1> 	jb	short sysexec_2
  4599 0000E66C 8B35[44040300]      <1> 	mov	esi, [nbase]
  4600 0000E672 010D[44040300]      <1> 	add	[nbase], ecx ; 4	
  4601 0000E678 66290D[48040300]    <1> 	sub	[ncount], cx 
  4602 0000E67F 8B06                <1> 	mov	eax, [esi]
  4603 0000E681 EB9F                <1> 	jmp	short sysexec_3
  4604                              <1> 
  4605                              <1> get_argp:
  4606                              <1> 	; 14/11/2017 - TRDOS 386 (TRDOS v2.0)
  4607                              <1> 	; 18/10/2015 (nbase, ncount)
  4608                              <1> 	; 21/07/2015
  4609                              <1> 	; 24/06/2015 (Retro UNIX 386 v1)
  4610                              <1> 	; Get (virtual) address of argument from user's core memory
  4611                              <1> 	;
  4612                              <1> 	; INPUT:
  4613                              <1> 	;	esi = virtual address of argument pointer
  4614                              <1> 	; OUTPUT:
  4615                              <1> 	;	eax = virtual address of argument
  4616                              <1> 	;
  4617                              <1> 	; Modified registers: EAX, EBX, ECX, EDX, ESI 
  4618                              <1> 	;
  4619 0000E683 833D[BC030300]00    <1>  	cmp     dword [u.ppgdir], 0 ; /etc/init ?
  4620                              <1> 				    ; (the caller is kernel)
  4621 0000E68A 7667                <1>         jna     short get_argpk 
  4622                              <1> 	;
  4623 0000E68C 89F3                <1>      	mov	ebx, esi
  4624 0000E68E E82776FFFF          <1> 	call	get_physical_addr ; get physical address
  4625 0000E693 0F8289000000        <1>         jc      get_argp_err
  4626 0000E699 A3[44040300]        <1> 	mov 	[nbase], eax ; physical address	
  4627 0000E69E 66890D[48040300]    <1> 	mov	[ncount], cx ; remain byte count in page (1-4096)
  4628 0000E6A5 B804000000          <1> 	mov	eax, 4 ; 21/07/2015
  4629 0000E6AA 6639C1              <1> 	cmp	cx, ax ; 4
  4630 0000E6AD 735D                <1> 	jnb	short get_argp2
  4631 0000E6AF 89F3                <1> 	mov	ebx, esi
  4632 0000E6B1 01CB                <1> 	add	ebx, ecx
  4633 0000E6B3 E80276FFFF          <1> 	call	get_physical_addr ; get physical address
  4634 0000E6B8 7268                <1> 	jc	short get_argp_err
  4635                              <1> 	;push	esi
  4636 0000E6BA 89C6                <1> 	mov	esi, eax
  4637 0000E6BC 66870D[48040300]    <1> 	xchg	cx, [ncount]
  4638 0000E6C3 8735[44040300]      <1> 	xchg	esi, [nbase]
  4639 0000E6C9 B504                <1> 	mov	ch, 4
  4640 0000E6CB 28CD                <1> 	sub	ch, cl
  4641                              <1> get_argp0:
  4642 0000E6CD AC                  <1> 	lodsb
  4643 0000E6CE 6650                <1> 	push	ax
  4644 0000E6D0 FEC9                <1> 	dec	cl
  4645 0000E6D2 75F9                <1>         jnz     short get_argp0
  4646 0000E6D4 8B35[44040300]      <1> 	mov	esi, [nbase]
  4647                              <1> 	; 21/07/2015
  4648 0000E6DA 0FB6C5              <1> 	movzx	eax, ch
  4649 0000E6DD 0105[44040300]      <1> 	add	[nbase], eax
  4650 0000E6E3 662905[48040300]    <1> 	sub	[ncount], ax
  4651                              <1> get_argp1:
  4652 0000E6EA AC                  <1> 	lodsb
  4653 0000E6EB FECD                <1> 	dec	ch
  4654 0000E6ED 7447                <1>         jz      short get_argp3
  4655 0000E6EF 6650                <1>         push	ax
  4656 0000E6F1 EBF7                <1> 	jmp     short get_argp1
  4657                              <1> get_argpk:
  4658                              <1> 	; Argument is in kernel's memory space
  4659 0000E6F3 66C705[48040300]00- <1> 	mov	word [ncount], PAGE_SIZE ; 4096
  4659 0000E6FB 10                  <1>
  4660 0000E6FC 8935[44040300]      <1> 	mov	[nbase], esi
  4661 0000E702 8305[44040300]04    <1> 	add	dword [nbase], 4
  4662 0000E709 8B06                <1> 	mov	eax, [esi] ; virtual addr. = physcal addr.
  4663 0000E70B C3                  <1> 	retn
  4664                              <1> get_argp2:
  4665                              <1> 	; 21/07/2015
  4666                              <1> 	;mov	eax, 4
  4667 0000E70C 8B15[44040300]      <1> 	mov 	edx, [nbase] ; 18/10/2015
  4668 0000E712 0105[44040300]      <1> 	add	[nbase], eax
  4669 0000E718 662905[48040300]    <1> 	sub	[ncount], ax
  4670                              <1> 	;
  4671 0000E71F 8B02                <1> 	mov	eax, [edx]
  4672 0000E721 C3                  <1> 	retn
  4673                              <1> get_argp_err:
  4674 0000E722 A3[C8030300]        <1> 	mov	[u.error], eax
  4675                              <1> 	; 14/11/2017
  4676 0000E727 B801000000          <1> 	mov	eax, ERR_BAD_CMD_ARG ; 01h ; TRDOS 8086
  4677 0000E72C A3[64030300]        <1> 	mov	[u.r0], eax
  4678 0000E731 E976EBFFFF          <1> 	jmp	error
  4679                              <1> get_argp3:
  4680 0000E736 B103                <1> 	mov	cl, 3
  4681                              <1> get_argp4:
  4682 0000E738 C1E008              <1> 	shl	eax, 8
  4683 0000E73B 665A                <1> 	pop	dx
  4684 0000E73D 88D0                <1> 	mov 	al, dl
  4685 0000E73F E2F7                <1>         loop    get_argp4
  4686                              <1> 	;pop	esi
  4687 0000E741 C3                  <1> 	retn	
  4688                              <1> 
  4689                              <1> sysstat: 
  4690                              <1> 	; 13/01/2017 - TRDOS 386 (TRDOS v2.0)
  4691                              <1> 	; temporary !
  4692 0000E742 B801000000          <1> 	mov	eax, ERR_INV_FNUMBER ; 'invalid function number !'
  4693 0000E747 A3[C8030300]        <1>         mov     [u.error], eax
  4694 0000E74C A3[64030300]        <1>         mov     [u.r0], eax 
  4695 0000E751 E956EBFFFF          <1> 	jmp	error
  4696                              <1> 
  4697                              <1> sysfstat: 
  4698                              <1> 	; 13/01/2017 - TRDOS 386 (TRDOS v2.0)
  4699                              <1> 	; temporary !
  4700 0000E756 B801000000          <1> 	mov	eax, ERR_INV_FNUMBER ; 'invalid function number !'
  4701 0000E75B A3[C8030300]        <1>         mov     [u.error], eax
  4702 0000E760 A3[64030300]        <1>         mov     [u.r0], eax 
  4703 0000E765 E942EBFFFF          <1> 	jmp	error
  4704                              <1> 
  4705                              <1> fclose:
  4706                              <1> 	; 06/10/2016 (TRDOS 386 = TRDOS v2.0)
  4707                              <1> 	;
  4708                              <1> 	; 18/06/2015 (Retro UNIX 386 v1 - Beginning)
  4709                              <1> 	;            (32 bit offset pointer modification)
  4710                              <1> 	; 19/04/2013 - 12/01/2014 (Retro UNIX 8086 v1)
  4711                              <1> 	;
  4712                              <1> 	; Given the file descriptor (index to the u.fp list)
  4713                              <1> 	; 'fclose' first gets the i-number of the file via 'getf'.
  4714                              <1> 	; If i-node is active (i-number > 0) the entry in 
  4715                              <1> 	; u.fp list is cleared. If all the processes that opened
  4716                              <1> 	; that file close it, then fsp etry is freed and the file
  4717                              <1> 	; is closed. If not a return is taken. 
  4718                              <1> 	; If the file has been deleted while open, 'anyi' is called
  4719                              <1> 	; to see anyone else has it open, i.e., see if it is appears
  4720                              <1> 	; in another entry in the fsp table. Upon return from 'anyi'
  4721                              <1> 	; a check is made to see if the file is special.	
  4722                              <1> 	;
  4723                              <1> 	; INPUTS ->
  4724                              <1> 	;    r1 - contains the file descriptor (value=0,1,2...)
  4725                              <1> 	;    u.fp - list of entries in the fsp table
  4726                              <1> 	;    fsp - table of entries (4 words/entry) of open files.	 
  4727                              <1> 	; OUTPUTS ->
  4728                              <1> 	;    r1 - contains the same file descriptor
  4729                              <1> 	;    r2 - contains i-number
  4730                              <1> 	;
  4731                              <1> 	; ((AX = R1))
  4732                              <1> 	; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))
  4733                              <1> 	;
  4734                              <1> 	; Retro UNIX 8086 v1 modification : CF = 1
  4735                              <1> 	;              if i-number of the file is 0. (error)  	
  4736                              <1> 	;
  4737                              <1> 	; TRDOS 386 (06/10/2016)
  4738                              <1> 	; 
  4739                              <1> 	; INPUT:
  4740                              <1> 	;	EAX = File Handle (File Descriptor, File Index)
  4741                              <1> 	;
  4742                              <1> 	; OUTPUT:
  4743                              <1> 	;	CF = 1 -> File not open !
  4744                              <1> 	;	CF = 0 -> OK!
  4745                              <1> 	;	     EBX = File Number (System)
  4746                              <1> 	;	     [cdev] = Logical DOS Drive Number
  4747                              <1> 	;	     EAX = File Handle/Number (user) 	
  4748                              <1> 	;
  4749                              <1> 	; Modified Registers: EBX
  4750                              <1> 
  4751 0000E76A 50                  <1> 	push	eax ; File handle
  4752                              <1> 	
  4753 0000E76B E846000000          <1> 	call	getf
  4754 0000E770 0F824B240000        <1> 	jc	device_close ; eax = device number
  4755                              <1> 
  4756 0000E776 80BB[FE730100]01    <1> 	cmp	byte [ebx+OF_MODE], 1 ; open mode ; 0 = empty entry
  4757 0000E77D 722E                <1> 	jb	short fclose_1	      ; 1 = read, 2 = write
  4758                              <1> 	
  4759 0000E77F 83F801              <1> 	cmp	eax, 1 ; is the first cluster number > 0
  4760 0000E782 7229                <1> 	jb	short fclose_1 ; no, this is empty entry
  4761                              <1> 
  4762                              <1> fclose_0:
  4763 0000E784 FE8B[12740100]      <1> 	dec	byte [ebx+OF_OPENCOUNT] ; decrement the number of processes 
  4764                              <1> 			                ; that have opened the file
  4765 0000E78A 7921                <1> 	jns	short fclose_1 ; jump if not negative (jump if bit 7 is 0)	 
  4766                              <1> 			; if all processes haven't closed the file, return
  4767                              <1> 	;
  4768                              <1> 	; eax ; First cluster
  4769 0000E78C 31C0                <1> 	xor	eax, eax ; 0
  4770 0000E78E 8883[FE730100]      <1> 	mov	[ebx+OF_MODE], al ; 0 = empty entry
  4771                              <1> 	;mov	[ebx+OF_STATUS], al ; 0 = empty entry
  4772 0000E794 66C1E302            <1> 	shl	bx, 2 
  4773 0000E798 8983[CC730100]      <1> 	mov	[ebx+OF_FCLUSTER], eax ; 0
  4774 0000E79E 8983[E4740100]      <1> 	mov	[ebx+OF_CCLUSTER], eax ; 0
  4775                              <1> 	;mov	[ebx+OF_CCINDEX], eax ; 0
  4776 0000E7A4 A3[74030300]        <1> 	mov	[u.fofp], eax ; 0
  4777 0000E7A9 66C1EB02            <1> 	shr	bx, 2
  4778                              <1> fclose_1: ; 1:
  4779 0000E7AD 58                  <1> 	pop	eax ; File handle (File Descriptor, File Index)
  4780 0000E7AE C680[6A030300]00    <1> 	mov	byte [eax+u.fp], 0 ; clear that entry in the u.fp list
  4781 0000E7B5 C3                  <1> 	retn
  4782                              <1> 
  4783                              <1> getf:
  4784                              <1> 	; 12/10/2016
  4785                              <1> 	; 11/10/2016
  4786                              <1> 	; 08/10/2016
  4787                              <1> 	; 06/10/2016 (TRDOS 386 = TRDOS v2.0)
  4788                              <1> 	; / get the device number and the i-number of an open file
  4789                              <1> 	; 13/05/2015
  4790                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  4791                              <1> 	; 19/04/2013 - 18/11/2013 (Retro UNIX 8086 v1)
  4792                              <1> 	;
  4793 0000E7B6 89C3                <1> 	mov	ebx, eax
  4794                              <1> getf1: 
  4795 0000E7B8 83FB0A              <1> 	cmp	ebx, 10
  4796 0000E7BB 730A                <1>         jnb	short getf2
  4797 0000E7BD 8A9B[6A030300]      <1> 	mov	bl, [ebx+u.fp]
  4798 0000E7C3 08DB                <1> 	or	bl, bl
  4799 0000E7C5 7503                <1> 	jnz	short getf3
  4800                              <1> getf2:
  4801                              <1> 	; 'File not open !' error (ax=0)
  4802 0000E7C7 29C0                <1> 	sub	eax, eax
  4803 0000E7C9 C3                  <1> 	retn
  4804                              <1> getf3:	
  4805 0000E7CA F6C380              <1> 	test	bl, 80h
  4806 0000E7CD 7530                <1> 	jnz	short getf5 ; device
  4807 0000E7CF FECB                <1> 	dec	bl ; 0 based
  4808 0000E7D1 8A83[F4730100]      <1> 	mov	al, [ebx+OF_DRIVE]
  4809 0000E7D7 A2[46030300]        <1> 	mov	[cdev], al
  4810 0000E7DC C0E302              <1> 	shl	bl, 2 ; *4 (dword offset)
  4811 0000E7DF 8B83[44740100]      <1> 	mov	eax, [ebx+OF_SIZE]
  4812 0000E7E5 A3[55040300]        <1> 	mov	[i.size], eax ; file size
  4813 0000E7EA 8D83[1C740100]      <1> 	lea	eax, [ebx+OF_POINTER] ;12/10/2016
  4814 0000E7F0 A3[74030300]        <1> 	mov	[u.fofp], eax
  4815 0000E7F5 8B83[CC730100]      <1> 	mov	eax, [ebx+OF_FCLUSTER]
  4816 0000E7FB C0EB02              <1> 	shr	bl, 2 ; /4 (byte offset) 
  4817                              <1> getf4:
  4818 0000E7FE C3                  <1> 	retn
  4819                              <1> getf5: 
  4820                              <1> 	; get device number
  4821 0000E7FF 80E37F              <1> 	and	bl, 7Fh ; 1 to 7Fh
  4822 0000E802 FECB                <1> 	dec	bl ; 0 based (0 to 7Eh)
  4823 0000E804 8A83[26720100]      <1> 	mov	al, [ebx+DEV_DRIVER]
  4824 0000E80A 8AAB[90710100]      <1> 	mov	ch, [ebx+DEV_ACCESS]
  4825 0000E810 8A8B[44720100]      <1> 	mov	cl, [ebx+DEV_OPENMODE]
  4826 0000E816 80E5FE              <1> 	and	ch, 0FEh ; reset bit 0 ; dev_close
  4827 0000E819 F9                  <1> 	stc ; cf = 1 
  4828 0000E81A C3                  <1> 	retn	
  4829                              <1> 
  4830                              <1> trans_addr_nmbp:
  4831                              <1> 	; 18/10/2015
  4832                              <1> 	; 12/10/2015
  4833 0000E81B 8B2D[7C030300]      <1> 	mov 	ebp, [u.namep]
  4834                              <1> trans_addr_nm: 
  4835                              <1> 	; Convert virtual (pathname) address to physical address
  4836                              <1> 	; (Retro UNIX 386 v1 feature only !)
  4837                              <1> 	; 18/10/2015
  4838                              <1> 	; 12/10/2015 (u.pnbase & u.pncount has been removed from code)
  4839                              <1> 	; 02/07/2015
  4840                              <1> 	; 17/06/2015
  4841                              <1> 	; 16/06/2015
  4842                              <1> 	;
  4843                              <1> 	; INPUTS: 
  4844                              <1> 	;	ebp = pathname address (virtual) ; [u.namep]
  4845                              <1> 	;	[u.pgdir] = user's page directory
  4846                              <1> 	; OUTPUT:
  4847                              <1> 	;       esi = physical address of the pathname
  4848                              <1> 	;	ecx = remain byte count in the page
  4849                              <1> 	;
  4850                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI)
  4851                              <1> 	;
  4852 0000E821 833D[BC030300]00    <1>         cmp     dword [u.ppgdir], 0  ; /etc/init ? (sysexec)
  4853 0000E828 7618                <1> 	jna	short trans_addr_nmk ; the caller is os kernel;
  4854                              <1> 				     ; it is already physical address
  4855 0000E82A 50                  <1>    	push	eax	
  4856 0000E82B 89EB                <1> 	mov	ebx, ebp ; [u.namep] ; pathname address (virtual)
  4857 0000E82D E88874FFFF          <1>        	call	get_physical_addr ; get physical address
  4858 0000E832 7204                <1> 	jc	short tr_addr_nm_err
  4859                              <1> 	; 18/10/2015
  4860                              <1> 	; eax = physical address 
  4861                              <1> 	; cx = remain byte count in page (1-4096) 
  4862                              <1> 		; 12/10/2015 (cx = [u.pncount])
  4863 0000E834 89C6                <1> 	mov	esi, eax ; 12/10/2015 (esi=[u.pnbase])
  4864 0000E836 58                  <1> 	pop	eax 
  4865 0000E837 C3                  <1> 	retn
  4866                              <1> 
  4867                              <1> tr_addr_nm_err:
  4868 0000E838 A3[C8030300]        <1> 	mov	[u.error], eax
  4869                              <1> 	;pop 	eax
  4870 0000E83D E96AEAFFFF          <1> 	jmp	error
  4871                              <1> 
  4872                              <1> trans_addr_nmk:
  4873                              <1> 	; 12/10/2015
  4874                              <1> 	; 02/07/2015
  4875 0000E842 8B35[7C030300]      <1> 	mov	esi, [u.namep]  ; [u.pnbase]
  4876 0000E848 66B90010            <1> 	mov	cx, PAGE_SIZE ; 4096 ; [u.pncount]
  4877 0000E84C C3                  <1> 	retn
  4878                              <1> 
  4879                              <1> 
  4880                              <1> sysbreak:
  4881                              <1> 	; 18/10/2015
  4882                              <1> 	; 07/10/2015
  4883                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  4884                              <1> 	; 20/06/2013 - 24/03/2014 (Retro UNIX 8086 v1)
  4885                              <1> 	;
  4886                              <1> 	; 'sysbreak' sets the programs break points. 
  4887                              <1> 	; It checks the current break point (u.break) to see if it is
  4888                              <1> 	; between "core" and the stack (sp). If it is, it is made an
  4889                              <1> 	; even address (if it was odd) and the area between u.break
  4890                              <1> 	; and the stack is cleared. The new breakpoint is then put
  4891                              <1> 	; in u.break and control is passed to 'sysret'.
  4892                              <1> 	;
  4893                              <1> 	; Calling sequence:
  4894                              <1> 	;	sysbreak; addr
  4895                              <1> 	; Arguments: -
  4896                              <1> 	;	
  4897                              <1> 	; Inputs: u.break - current breakpoint
  4898                              <1> 	; Outputs: u.break - new breakpoint 
  4899                              <1> 	;	area between old u.break and the stack (sp) is cleared.
  4900                              <1> 	; ...............................................................
  4901                              <1> 	;	
  4902                              <1> 	; Retro UNIX 8086 v1 modification:
  4903                              <1> 	;	The user/application program puts breakpoint address
  4904                              <1> 	;       in BX register as 'sysbreak' system call argument.
  4905                              <1> 	; 	(argument transfer method 1)
  4906                              <1> 	;
  4907                              <1> 	;  NOTE: Beginning of core is 0 in Retro UNIX 8086 v1 !
  4908                              <1> 	; 	((!'sysbreak' is not needed in Retro UNIX 8086 v1!))
  4909                              <1> 	;  NOTE:
  4910                              <1> 	; 	'sysbreak' clears extended part (beyond of previous
  4911                              <1> 	;	'u.break' address) of user's memory for original unix's
  4912                              <1> 	;	'bss' compatibility with Retro UNIX 8086 v1 (19/11/2013)
  4913                              <1> 
  4914                              <1> 		; mov u.break,r1 / move users break point to r1
  4915                              <1> 		; cmp r1,$core / is it the same or lower than core?
  4916                              <1> 		; blos 1f / yes, 1f
  4917                              <1> 	; 23/06/2015
  4918 0000E84D 8B2D[90030300]      <1> 	mov	ebp, [u.break] ; virtual address (offset)
  4919                              <1> 	;and	ebp, ebp
  4920                              <1> 	;jz	short sysbreak_3 
  4921                              <1> 	; Retro UNIX 386 v1 NOTE: u.break points to virtual address !!!
  4922                              <1> 	; (Even break point address is not needed for Retro UNIX 386 v1)
  4923 0000E853 8B15[5C030300]      <1> 	mov	edx, [u.sp] ; kernel stack at the beginning of sys call
  4924 0000E859 83C20C              <1> 	add	edx, 12 ; EIP -4-> CS -4-> EFLAGS -4-> ESP (user) 
  4925                              <1> 	; 07/10/2015
  4926 0000E85C 891D[90030300]      <1> 	mov	[u.break], ebx ; virtual address !!!
  4927                              <1> 	;
  4928 0000E862 3B1A                <1> 	cmp	ebx, [edx] ; compare new break point with 
  4929                              <1> 			   ; with top of user's stack (virtual!)
  4930 0000E864 7323                <1> 	jnb	short sysbreak_3
  4931                              <1> 		; cmp r1,sp / is it the same or higher 
  4932                              <1> 			  ; / than the stack?
  4933                              <1> 		; bhis 1f / yes, 1f
  4934 0000E866 89DE                <1> 	mov	esi, ebx
  4935 0000E868 29EE                <1> 	sub	esi, ebp ; new break point - old break point
  4936 0000E86A 761D                <1> 	jna	short sysbreak_3 
  4937                              <1> 	;push	ebx
  4938                              <1> sysbreak_1:
  4939 0000E86C 89EB                <1> 	mov	ebx, ebp  
  4940 0000E86E E84774FFFF          <1> 	call	get_physical_addr ; get physical address
  4941 0000E873 72C3                <1> 	jc	tr_addr_nm_err
  4942                              <1> 	; 18/10/2015
  4943 0000E875 89C7                <1> 	mov	edi, eax 
  4944 0000E877 29C0                <1> 	sub	eax, eax ; 0
  4945                              <1> 		 ; ECX = remain byte count in page (1-4096)
  4946 0000E879 39CE                <1> 	cmp	esi, ecx
  4947 0000E87B 7302                <1> 	jnb	short sysbreak_2
  4948 0000E87D 89F1                <1> 	mov	ecx, esi
  4949                              <1> sysbreak_2:
  4950 0000E87F 29CE                <1> 	sub	esi, ecx
  4951 0000E881 01CD                <1> 	add	ebp, ecx
  4952 0000E883 F3AA                <1> 	rep 	stosb
  4953 0000E885 09F6                <1> 	or	esi, esi
  4954 0000E887 75E3                <1> 	jnz	short sysbreak_1
  4955                              <1> 	;
  4956                              <1> 		; bit $1,r1 / is it an odd address
  4957                              <1> 		; beq 2f / no, its even
  4958                              <1> 		; clrb (r1)+ / yes, make it even
  4959                              <1> 	; 2: / clear area between the break point and the stack
  4960                              <1> 		; cmp r1,sp / is it higher or same than the stack
  4961                              <1> 		; bhis 1f / yes, quit
  4962                              <1> 		; clr (r1)+ / clear word
  4963                              <1> 		; br 2b / go back
  4964                              <1> 	;pop	ebx
  4965                              <1> sysbreak_3: ; 1:
  4966                              <1> 	;mov	[u.break], ebx ; virtual address !!!
  4967                              <1> 		; jsr r0,arg; u.break / put the "address" 
  4968                              <1> 			; / in u.break (set new break point)
  4969                              <1> 		; br sysret4 / br sysret
  4970 0000E889 E93EEAFFFF          <1> 	jmp	sysret
  4971                              <1> 
  4972                              <1> sysseek: ; / moves read write pointer in an fsp entry
  4973                              <1> 	; 06/11/2016 - TRDOS 386 (TRDOS v2.0)
  4974                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4975                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  4976                              <1> 	;
  4977                              <1> 	; 'sysseek' changes the r/w pointer of (3rd word of in an
  4978                              <1> 	; fsp entry) of an open file whose file descriptor is in u.r0.
  4979                              <1> 	; The file descriptor refers to a file open for reading or
  4980                              <1> 	; writing. The read (or write) pointer is set as follows:
  4981                              <1> 	;	* if 'ptrname' is 0, the pointer is set to offset.
  4982                              <1> 	;	* if 'ptrname' is 1, the pointer is set to its
  4983                              <1> 	;	  current location plus offset.
  4984                              <1> 	;	* if 'ptrname' is 2, the pointer is set to the
  4985                              <1> 	;	  size of file plus offset.
  4986                              <1> 	; The error bit (e-bit) is set for an undefined descriptor.
  4987                              <1> 	;
  4988                              <1> 	; Calling sequence:
  4989                              <1> 	;	sysseek; offset; ptrname
  4990                              <1> 	; Arguments:
  4991                              <1> 	;	offset - number of bytes desired to move 
  4992                              <1> 	;		 the r/w pointer
  4993                              <1> 	;	ptrname - a switch indicated above
  4994                              <1> 	;
  4995                              <1> 	; Inputs: r0 - file descriptor 
  4996                              <1> 	; Outputs: -
  4997                              <1> 	; ...............................................................
  4998                              <1> 	;	
  4999                              <1> 	; Retro UNIX 8086 v1 modification: 
  5000                              <1> 	;       'sysseek' system call has three arguments; so,
  5001                              <1> 	;	* 1st argument, file descriptor is in BX (BL) register
  5002                              <1> 	;	* 2nd argument, offset is in CX register
  5003                              <1> 	;	* 3rd argument, ptrname/switch is in DX (DL) register	
  5004                              <1> 
  5005 0000E88E E821000000          <1> 	call	seektell
  5006                              <1> 	; EAX = Current R/W pointer of the file
  5007                              <1> 	; EBX = [u.fofp]
  5008                              <1> 	; [u.base] = offset (ECX input)
  5009                              <1> 
  5010 0000E893 0305[84030300]      <1> 	add	eax, [u.base]
  5011 0000E899 8903                <1> 	mov	[ebx], eax
  5012 0000E89B E92CEAFFFF          <1> 	jmp	sysret
  5013                              <1> 
  5014                              <1> systell: ; / get the r/w pointer
  5015                              <1> 	; 06/11/2016 - TRDOS 386 (TRDOS v2.0) - temporary !-
  5016                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  5017                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  5018                              <1> 	;
  5019                              <1> 	; Retro UNIX 8086 v1 modification:
  5020                              <1> 	; ! 'systell' does not work in original UNIX v1,
  5021                              <1> 	; 	    it returns with error !
  5022                              <1> 	; Inputs: r0 - file descriptor 
  5023                              <1> 	; Outputs: r0 - file r/w pointer
  5024                              <1> 
  5025                              <1> 	;xor	ecx, ecx ; 0
  5026 0000E8A0 BA01000000          <1> 	mov	edx, 1 ; 05/08/2013
  5027                              <1> 	;call 	seektell
  5028 0000E8A5 E810000000          <1> 	call 	seektell0 ; 05/08/2013
  5029                              <1> 	;; 06/11/2016
  5030                              <1> 	;; mov	eax, [ebx]
  5031 0000E8AA A3[64030300]        <1> 	mov	[u.r0], eax
  5032 0000E8AF E918EAFFFF          <1> 	jmp	sysret
  5033                              <1> 
  5034                              <1> ; Original unix v1 'systell' system call:
  5035                              <1> 		; jsr r0,seektell
  5036                              <1> 		; br error4
  5037                              <1> 
  5038                              <1> seektell:
  5039                              <1> 	; 06/11/2016 - TRDOS 386 (TRDOS v2.0)
  5040                              <1> 	; 03/01/2016
  5041                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  5042                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  5043                              <1> 	;
  5044                              <1> 	; 'seektell' puts the arguments from sysseek and systell
  5045                              <1> 	; call in u.base and u.count. It then gets the i-number of
  5046                              <1> 	; the file from the file descriptor in u.r0 and by calling
  5047                              <1> 	; getf. The i-node is brought into core and then u.count
  5048                              <1> 	; is checked to see it is a 0, 1, or 2.
  5049                              <1> 	; If it is 0 - u.count stays the same
  5050                              <1> 	;          1 - u.count = offset (u.fofp)
  5051                              <1> 	;	   2 - u.count = i.size (size of file)
  5052                              <1> 	; 	 		
  5053                              <1> 	; !! Retro UNIX 8086 v1 modification:
  5054                              <1> 	;	Argument 1, file descriptor is in BX;
  5055                              <1> 	;	Argument 2, offset is in CX;
  5056                              <1> 	;	Argument 3, ptrname/switch is in DX register.	
  5057                              <1> 	;
  5058                              <1> 	; ((Return -> eax = base for offset (position= base+offset))
  5059                              <1> 	;
  5060 0000E8B4 890D[84030300]      <1> 	mov 	[u.base], ecx ; offset
  5061                              <1> seektell0:
  5062 0000E8BA 8915[88030300]      <1> 	mov 	[u.count], edx
  5063                              <1> 	; EBX = file descriptor (file number)
  5064 0000E8C0 E8F3FEFFFF          <1> 	call	getf1
  5065                              <1> 	; EAX = First cluster of the file
  5066                              <1> 	; EBX = File number (Open file number)
  5067                              <1> 	; [u.fofp] = Pointer to File pointer
  5068                              <1> 	; [i.size] = File size
  5069                              <1> 
  5070 0000E8C5 09C0                <1> 	or	eax, eax
  5071 0000E8C7 7514                <1> 	jnz	short seektell1
  5072                              <1> 
  5073 0000E8C9 B80A000000          <1> 	mov	eax, ERR_FILE_NOT_OPEN
  5074 0000E8CE A3[64030300]        <1> 	mov	[u.r0], eax 
  5075 0000E8D3 A3[C8030300]        <1> 	mov	dword [u.error], eax ; 'file not open !'
  5076 0000E8D8 E9CFE9FFFF          <1> 	jmp	error
  5077                              <1> 
  5078                              <1> seektell1:
  5079 0000E8DD 8B1D[74030300]      <1>         mov     ebx, [u.fofp]
  5080 0000E8E3 803D[88030300]01    <1> 	cmp	byte [u.count], 1
  5081 0000E8EA 7705                <1> 	ja	short seektell2
  5082 0000E8EC 7409                <1> 	je	short seektell3
  5083 0000E8EE 31C0                <1> 	xor	eax, eax
  5084 0000E8F0 C3                  <1> 	retn
  5085                              <1> 
  5086                              <1> seektell2:
  5087 0000E8F1 A1[55040300]        <1>         mov   	eax, [i.size]
  5088 0000E8F6 C3                  <1> 	retn
  5089                              <1> 
  5090                              <1> seektell3:
  5091 0000E8F7 8B03                <1> 	mov	eax, [ebx]
  5092 0000E8F9 C3                  <1> 	retn
  5093                              <1> 
  5094                              <1> sysintr: ; / set interrupt handling
  5095                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  5096                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
  5097                              <1> 	;
  5098                              <1> 	; 'sysintr' sets the interrupt handling value. It puts
  5099                              <1> 	; argument of its call in u.intr then branches into 'sysquit'
  5100                              <1> 	; routine. u.tty is checked if to see if a control tty exists.
  5101                              <1> 	; If one does the interrupt character in the tty buffer is
  5102                              <1> 	; cleared and 'sysret'is called. If one does not exits
  5103                              <1> 	; 'sysret' is just called.	
  5104                              <1> 	;
  5105                              <1> 	; Calling sequence:
  5106                              <1> 	;	sysintr; arg
  5107                              <1> 	; Argument:
  5108                              <1> 	;	arg - if 0, interrupts (ASCII DELETE) are ignored.
  5109                              <1> 	;	    - if 1, intterupts cause their normal result
  5110                              <1> 	;		 i.e force an exit.
  5111                              <1> 	;	    - if arg is a location within the program,
  5112                              <1> 	;		control is passed to that location when
  5113                              <1> 	;		an interrupt occurs.	
  5114                              <1> 	; Inputs: -
  5115                              <1> 	; Outputs: -
  5116                              <1> 	; ...............................................................
  5117                              <1> 	;	
  5118                              <1> 	; Retro UNIX 8086 v1 modification: 
  5119                              <1> 	;       'sysintr' system call sets u.intr to value of BX
  5120                              <1> 	;	then branches into sysquit.
  5121                              <1> 	;
  5122 0000E8FA 66891D[AA030300]    <1> 	mov	[u.intr], bx
  5123                              <1> 		; jsr r0,arg; u.intr / put the argument in u.intr
  5124                              <1> 		; br 1f / go into quit routine
  5125 0000E901 E9C6E9FFFF          <1> 	jmp	sysret
  5126                              <1> 
  5127                              <1> sysquit:
  5128                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  5129                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
  5130                              <1> 	;
  5131                              <1> 	; 'sysquit' turns off the quit signal. it puts the argument of
  5132                              <1> 	; the call in u.quit. u.tty is checked if to see if a control 
  5133                              <1> 	; tty exists. If one does the interrupt character in the tty
  5134                              <1> 	; buffer is cleared and 'sysret'is called. If one does not exits
  5135                              <1> 	; 'sysret' is just called.	
  5136                              <1> 	;
  5137                              <1> 	; Calling sequence:
  5138                              <1> 	;	sysquit; arg
  5139                              <1> 	; Argument:
  5140                              <1> 	;	arg - if 0, this call diables quit signals from the
  5141                              <1> 	;		typewriter (ASCII FS)
  5142                              <1> 	;	    - if 1, quits are re-enabled and cause execution to
  5143                              <1> 	;		cease and a core image to be produced.
  5144                              <1> 	;		 i.e force an exit.
  5145                              <1> 	;	    - if arg is an addres in the program,
  5146                              <1> 	;		a quit causes control to sent to that
  5147                              <1> 	;		location.	
  5148                              <1> 	; Inputs: -
  5149                              <1> 	; Outputs: -
  5150                              <1> 	; ...............................................................
  5151                              <1> 	;	
  5152                              <1> 	; Retro UNIX 8086 v1 modification: 
  5153                              <1> 	;       'sysquit' system call sets u.quit to value of BX
  5154                              <1> 	;	then branches into 'sysret'.
  5155                              <1> 	;
  5156 0000E906 66891D[AC030300]    <1> 	mov	[u.quit], bx
  5157 0000E90D E9BAE9FFFF          <1> 	jmp	sysret
  5158                              <1> 		; jsr r0,arg; u.quit / put argument in u.quit
  5159                              <1> 	;1:
  5160                              <1> 		; mov u.ttyp,r1 / move pointer to control tty buffer
  5161                              <1> 			      ; / to r1
  5162                              <1> 		; beq sysret4 / return to user
  5163                              <1> 		; clrb 6(r1) / clear the interrupt character 
  5164                              <1> 			   ; / in the tty buffer
  5165                              <1> 		; br sysret4 / return to user
  5166                              <1> 
  5167                              <1> anyi: 
  5168                              <1> 	; 06/10/2016 (TRDOS 386 = TRDOS v2.0)
  5169                              <1> 	; Major Modification!
  5170                              <1> 	; TRDOS 386 does not permit to delete a file while it is open 
  5171                              <1> 	; The role of 'anyi' procedure has beeen changed to ensure that.
  5172                              <1> 	; 	
  5173                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  5174                              <1> 	; 25/04/2013 (Retro UNIX 8086 v1)
  5175                              <1> 	;
  5176                              <1> 	; 'anyi' is called if a file deleted while open.
  5177                              <1> 	; "anyi" checks to see if someone else has opened this file.
  5178                              <1> 	;
  5179                              <1> 	; INPUTS ->
  5180                              <1> 	;    r1 - contains an i-number
  5181                              <1> 	;    fsp - start of table containing open files
  5182                              <1> 	;
  5183                              <1> 	; OUTPUTS ->
  5184                              <1> 	;    "deleted" flag set in fsp entry of another occurrence of
  5185                              <1> 	;	   this file and r2 points 1st word of this fsp entry.
  5186                              <1> 	;    if file not found - bit in i-node map is cleared
  5187                              <1> 	;    			 (i-node is freed)
  5188                              <1> 	;               all blocks related to i-node are freed
  5189                              <1> 	;	        all flags in i-node are cleared
  5190                              <1> 	; ((AX = R1)) input
  5191                              <1> 	;
  5192                              <1> 	;    (Retro UNIX Prototype : 02/12/2012, UNIXCOPY.ASM)
  5193                              <1>         ;    ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
  5194                              <1> 	;
  5195                              <1> 	; / r1 contains an i-number
  5196                              <1> 
  5197                              <1> 	; TRDOS 386 (06/10/2016)
  5198                              <1> 	; 
  5199                              <1> 	; INPUT:
  5200                              <1> 	;	EAX = First Cluster
  5201                              <1> 	;	 DL = Logical DOS Drive Number
  5202                              <1> 	;
  5203                              <1> 	; OUTPUT:
  5204                              <1> 	;	CF = 1 -> EBX = File Handle/Number/Index
  5205                              <1> 	;	CF = 0 -> EBX = 0
  5206                              <1> 	;
  5207                              <1> 	; Modified Registers: EBX
  5208                              <1> 
  5209 0000E912 31DB                <1> 	xor	ebx, ebx
  5210                              <1> anyi_0: 
  5211 0000E914 80BB[FE730100]00    <1> 	cmp	byte [ebx+OF_MODE], 0 ; 0 = empty entry
  5212 0000E91B 770A                <1> 	ja	short anyi_2 ; 1 (r), 2 (w) or 3 (r&w)
  5213                              <1> anyi_1:
  5214 0000E91D FEC3                <1> 	inc	bl
  5215 0000E91F 80FB0A              <1> 	cmp	bl, OPENFILES ; max. count of open files
  5216 0000E922 72F0                <1> 	jb	short anyi_0
  5217 0000E924 31C0                <1> 	xor	eax, eax
  5218 0000E926 C3                  <1> 	retn 
  5219                              <1> anyi_2:
  5220 0000E927 3A93[F4730100]      <1> 	cmp	dl, [ebx+OF_DRIVE]
  5221 0000E92D 75EE                <1> 	jne	short anyi_1
  5222 0000E92F 66C1E302            <1> 	shl	bx, 2 ; *4 (dword offset)
  5223 0000E933 3B83[CC730100]      <1> 	cmp	eax, [ebx+OF_FCLUSTER]
  5224 0000E939 7406                <1> 	je	short anyi_3
  5225 0000E93B 66C1EB02            <1> 	shr	bx, 2 ; /4 (byte offset)
  5226 0000E93F EBDC                <1> 	jmp	short anyi_1 	
  5227                              <1> anyi_3:
  5228 0000E941 66C1EB02            <1> 	shr	bx, 2 ; /4 (bytes offset) (index)
  5229 0000E945 F9                  <1> 	stc
  5230 0000E946 C3                  <1> 	retn
  5231                              <1> 
  5232                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS9.INC
  5233                              <1> ; Last Modification: 09/12/2015
  5234                              <1> 
  5235                              <1> syssleep:
  5236                              <1> 	; 29/06/2015 - (Retro UNIX 386 v1)
  5237                              <1> 	; 11/06/2014 - (Retro UNIX 8086 v1)
  5238                              <1> 	;
  5239                              <1> 	; Retro UNIX 8086 v1 feature only
  5240                              <1> 	; (INPUT -> none)
  5241                              <1> 	;
  5242 0000E947 0FB61D[B3030300]    <1> 	movzx	ebx, byte [u.uno] ; process number
  5243 0000E94E 8AA3[7F000300]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
  5244 0000E954 E887190000          <1> 	call	sleep
  5245 0000E959 E96EE9FFFF          <1> 	jmp	sysret
  5246                              <1> 
  5247                              <1> _vp_clr:
  5248                              <1> 	; Reset/Clear Video Page
  5249                              <1> 	;
  5250                              <1> 	; 30/06/2015 - (Retro UNIX 386 v1)
  5251                              <1> 	; 21/05/2013 - 30/10/2013(Retro UNIX 8086 v1) (U0.ASM)
  5252                              <1> 	;
  5253                              <1> 	; Retro UNIX 8086 v1 feature only !
  5254                              <1> 	;
  5255                              <1> 	; INPUTS -> 
  5256                              <1> 	;   BH = video page number	 
  5257                              <1> 	;
  5258                              <1> 	; OUTPUT ->
  5259                              <1> 	;   none
  5260                              <1> 	; ((Modified registers: eAX, BH, eCX, eDX, eSI, eDI))
  5261                              <1> 	;
  5262                              <1> 	; 04/12/2013
  5263 0000E95E 28C0                <1> 	sub	al, al
  5264                              <1> 	; al = 0 (clear video page)
  5265                              <1> 	; bh = video page ; 13/05/2016
  5266 0000E960 B407                <1> 	mov	ah, 07h
  5267                              <1> 	; ah = 7 (attribute/color)
  5268 0000E962 6631C9              <1> 	xor 	cx, cx ; 0, left upper column (cl) & row (cl)
  5269 0000E965 66BA4F18            <1> 	mov	dx, 184Fh ; right lower column & row (dl=24, dh=79)
  5270 0000E969 E8CF35FFFF          <1> 	call	_scroll_up
  5271                              <1> 	; bh = video page
  5272 0000E96E 6631D2              <1> 	xor	dx, dx ; 0 (cursor position) 
  5273 0000E971 E92139FFFF          <1> 	jmp 	_set_cpos
  5274                              <1> 
  5275                              <1> sysmsg:
  5276                              <1> 	; 07/12/2020
  5277                              <1> 	; 05/12/2020
  5278                              <1> 	; 13/05/2016
  5279                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  5280                              <1> 	; 01/07/2015 - 11/11/2015 (Retro UNIX 386 v1)
  5281                              <1> 	; Print user-application message on user's console tty
  5282                              <1> 	;
  5283                              <1> 	; Input -> EBX = Message address
  5284                              <1> 	;	   ECX = Message length (max. 255)
  5285                              <1> 	;	   DL = Color (IBM PC Rombios color attributes)
  5286                              <1> 	;
  5287 0000E976 81F9FF000000        <1> 	cmp	ecx, MAX_MSG_LEN ; 255
  5288 0000E97C 0F874AE9FFFF        <1> 	ja	sysret ; nothing to do with big message size
  5289 0000E982 08C9                <1> 	or	cl, cl
  5290 0000E984 0F8442E9FFFF        <1> 	jz	sysret
  5291 0000E98A 20D2                <1> 	and	dl, dl
  5292 0000E98C 7502                <1> 	jnz	short sysmsg0
  5293 0000E98E B207                <1> 	mov	dl, 07h ; default color
  5294                              <1> 		; (black background, light gray character) 
  5295                              <1> sysmsg0:
  5296 0000E990 891D[84030300]      <1> 	mov	[u.base], ebx
  5297 0000E996 8815[07640100]      <1> 	mov	[ccolor], dl ; color attributes
  5298 0000E99C 89E5                <1> 	mov	ebp, esp
  5299 0000E99E 31DB                <1> 	xor	ebx, ebx ; 0
  5300 0000E9A0 891D[8C030300]      <1> 	mov	[u.nread], ebx ; 0
  5301                              <1> 	;
  5302 0000E9A6 381D[C6030300]      <1> 	cmp	[u.kcall], bl ; 0
  5303 0000E9AC 776F                <1> 	ja	short sysmsgk ; Temporary (01/07/2015)
  5304                              <1> 	;
  5305 0000E9AE 890D[88030300]      <1> 	mov	[u.count], ecx
  5306                              <1> 	;inc	ecx ; + 00h ; ASCIIZ
  5307                              <1> 	;
  5308                              <1> 	; 07/12/2020
  5309                              <1> 	;add	ecx, 3
  5310 0000E9B4 6683C103            <1> 	add	cx, 3
  5311 0000E9B8 80E1FC              <1> 	and	cl, ~3  ; not 3
  5312                              <1> 	;
  5313 0000E9BB 29CC                <1> 	sub	esp, ecx
  5314 0000E9BD 89E7                <1> 	mov	edi, esp
  5315 0000E9BF 89E6                <1> 	mov	esi, esp
  5316 0000E9C1 66891D[C4030300]    <1> 	mov	[u.pcount], bx ; reset page (phy. addr.) counter
  5317                              <1> 	; 11/11/2015
  5318 0000E9C8 8A25[94030300]      <1> 	mov 	ah, [u.ttyp] ; recent open tty
  5319                              <1> 	; 0 = none
  5320 0000E9CE FECC                <1> 	dec	ah
  5321 0000E9D0 790C                <1> 	jns	short sysmsg1 
  5322 0000E9D2 8A1D[B3030300]      <1> 	mov	bl, [u.uno] ; process number	
  5323 0000E9D8 8AA3[7F000300]      <1> 	mov	ah, [ebx+p.ttyc-1] ; user's (process's) console tty
  5324                              <1> sysmsg1:
  5325 0000E9DE 8825[96030300]      <1> 	mov	[u.ttyn], ah
  5326                              <1> sysmsg2:
  5327 0000E9E4 E848080000          <1> 	call	cpass
  5328 0000E9E9 7416                <1> 	jz	short sysmsg5
  5329 0000E9EB AA                  <1> 	stosb
  5330 0000E9EC 20C0                <1> 	and	al, al
  5331 0000E9EE 75F4                <1> 	jnz	short sysmsg2
  5332                              <1> sysmsg3:
  5333 0000E9F0 80FC07              <1> 	cmp	ah, 7 ; tty number
  5334 0000E9F3 7711                <1> 	ja	short sysmsg6 ; serial port
  5335 0000E9F5 E83E000000          <1> 	call	print_cmsg ; 05/12/2020
  5336                              <1> sysmsg4:
  5337 0000E9FA 89EC                <1> 	mov	esp, ebp	
  5338 0000E9FC E9CBE8FFFF          <1> 	jmp	sysret
  5339                              <1> sysmsg5:
  5340 0000EA01 C60700              <1> 	mov	byte [edi], 0
  5341 0000EA04 EBEA                <1> 	jmp	short sysmsg3
  5342                              <1> sysmsg6:
  5343 0000EA06 8A06                <1> 	mov	al, [esi]
  5344 0000EA08 E8D1180000          <1> 	call	sndc
  5345 0000EA0D 72EB                <1> 	jc	short sysmsg4
  5346 0000EA0F 803E00              <1> 	cmp	byte [esi], 0  ; 0 is stop character
  5347 0000EA12 76E6                <1> 	jna	short sysmsg4
  5348 0000EA14 46                  <1> 	inc 	esi
  5349 0000EA15 8A25[96030300]      <1> 	mov	ah, [u.ttyn]
  5350 0000EA1B EBE9                <1> 	jmp	short sysmsg6
  5351                              <1> 
  5352                              <1> sysmsgk: ; Temporary (01/07/2015)
  5353                              <1> 	; The message has been sent by Kernel (ASCIIZ string)
  5354                              <1> 	; (ECX -character count- will not be considered)
  5355 0000EA1D 8B35[84030300]      <1> 	mov	esi, [u.base]
  5356 0000EA23 8A25[06640100]      <1> 	mov	ah, [ptty] ; present/current screen (video page)
  5357 0000EA29 8825[96030300]      <1> 	mov	[u.ttyn], ah
  5358 0000EA2F C605[C6030300]00    <1> 	mov	byte [u.kcall], 0
  5359 0000EA36 EBB8                <1> 	jmp	short sysmsg3
  5360                              <1> 	
  5361                              <1> print_cmsg: 
  5362                              <1> 	; 08/12/2020
  5363                              <1> 	; 07/12/2020
  5364                              <1> 	; 05/12/2020
  5365                              <1> 	; 18/11/2017
  5366                              <1> 	; 13/05/2016 - TRDOS 386 (TRDOS v2.0)
  5367                              <1> 	; 01/07/2015 (Retro UNIX 386 v1)
  5368                              <1> 	;
  5369                              <1> 	; print message (on user's console tty) 
  5370                              <1> 	;	with requested color
  5371                              <1> 	;
  5372                              <1> 	; INPUTS:
  5373                              <1> 	;	esi = message address
  5374                              <1> 	;	[u.ttyn] = tty number (0 to 7)
  5375                              <1> 	;	[ccolor] = color attributes (IBM PC BIOS colors)
  5376                              <1> 	;
  5377                              <1> 	; Modified registers: eax, ebx, ecx, edx, esi, edi
  5378                              <1> 	; (ebp must be preserved)
  5379                              <1> 
  5380                              <1> 	;mov	bh, ah
  5381 0000EA38 8A3D[96030300]      <1> 	mov	bh, [u.ttyn]
  5382 0000EA3E 8A1D[07640100]      <1> 	mov	bl, [ccolor] ; * ; 05/12/2020
  5383                              <1> 
  5384                              <1> 	; 05/12/2020
  5385 0000EA44 803D[9C110300]00    <1> 	cmp	byte [pmi32], 0 ; is vbios's 32 bit pmi enabled ?
  5386 0000EA4B 772E                <1> 	ja	short pcmsg5 ; yes
  5387                              <1> pcmsg1:
  5388                              <1> 	; 08/12/2020
  5389 0000EA4D 8A1D[07640100]      <1> 	mov	bl, [ccolor] ; * (video.s 'u11'&'beep' change BL)
  5390                              <1> 	
  5391 0000EA53 AC                  <1> 	lodsb
  5392 0000EA54 20C0                <1> 	and 	al, al  ; 0
  5393 0000EA56 743A                <1> 	jz 	short pcmsg2
  5394                              <1> pcmsg7:
  5395 0000EA58 56                  <1> 	push 	esi
  5396                              <1> 	;mov	bl, [ccolor] ; * (video.s 'u11'&'beep' change BL)
  5397                              <1> 	; 05/12/2020
  5398                              <1> 	;;mov	bh, [u.ttyn]
  5399                              <1> 	;call 	_write_tty
  5400                              <1> 	;pop	esi
  5401                              <1> 	;jmp	short pcmsg1
  5402                              <1> ;pcmsg2:
  5403                              <1> 	;retn
  5404                              <1> 
  5405                              <1> 	; 07/12/2020
  5406 0000EA59 803D[9A690000]03    <1> 	cmp     byte [CRT_MODE], 3
  5407 0000EA60 7708                <1> 	ja 	short pcmsg4
  5408                              <1> pcmsg3:
  5409 0000EA62 E8A937FFFF          <1> 	call	_write_tty_m3
  5410 0000EA67 5E                  <1> 	pop	esi
  5411 0000EA68 EBE3                <1> 	jmp	short pcmsg1
  5412                              <1> pcmsg4:
  5413 0000EA6A 803D[9A690000]07    <1>         cmp     byte [CRT_MODE], 7
  5414 0000EA71 76EF                <1> 	jna 	short pcmsg3
  5415 0000EA73 E8A644FFFF          <1> 	call	vga_write_teletype
  5416 0000EA78 5E                  <1> 	pop	esi
  5417 0000EA79 EBD2                <1> 	jmp	short pcmsg1
  5418                              <1> pcmsg5:
  5419                              <1> 	; 07/12/2020
  5420 0000EA7B 803D[9A690000]07    <1>         cmp     byte [CRT_MODE], 7
  5421 0000EA82 76C9                <1> 	jna 	short pcmsg1
  5422                              <1> 
  5423                              <1> 	; 05/12/2020
  5424                              <1> 	; writing message by using
  5425                              <1> 	; VESA VBE3 video bios protected mode interface
  5426                              <1> 	
  5427 0000EA84 B40E                <1> 	mov	ah, 0Eh
  5428                              <1> pcmsg6:
  5429 0000EA86 AC                  <1> 	lodsb
  5430 0000EA87 20C0                <1> 	and 	al, al  ; 0
  5431 0000EA89 7407                <1> 	jz 	short pcmsg2
  5432                              <1> 	; bh = video page
  5433                              <1> 	; ah = 0Eh 
  5434                              <1> 	; al = character
  5435                              <1> 	; bl = color
  5436 0000EA8B E8622FFFFF          <1> 	call	int10h_32bit_pmi
  5437 0000EA90 EBF4                <1> 	jmp	short pcmsg6
  5438                              <1> pcmsg2:
  5439 0000EA92 C3                  <1> 	retn
  5440                              <1> 
  5441                              <1> sysgeterr:
  5442                              <1> 	; 09/12/2015
  5443                              <1> 	; 21/09/2015 - (Retro UNIX 386 v1 feature only!)
  5444                              <1> 	; Get last error number or page fault count
  5445                              <1> 	; (for debugging)
  5446                              <1> 	;
  5447                              <1> 	; Input -> EBX = return type
  5448                              <1> 	;	   0 = last error code (which is in 'u.error')	
  5449                              <1> 	;	   FFFFFFFFh = page fault count for running process
  5450                              <1> 	;	   FFFFFFFEh = total page fault count
  5451                              <1> 	;	   1 .. FFFFFFFDh = undefined 
  5452                              <1> 	;
  5453                              <1> 	; Output -> EAX = last error number or page fault count
  5454                              <1> 	;	   (depending on EBX input)
  5455                              <1> 	; 	
  5456 0000EA93 21DB                <1> 	and 	ebx, ebx
  5457 0000EA95 750B                <1> 	jnz	short glerr_2
  5458                              <1> glerr_0:
  5459 0000EA97 A1[C8030300]        <1> 	mov	eax, [u.error]
  5460                              <1> glerr_1:
  5461 0000EA9C A3[64030300]        <1> 	mov	[u.r0], eax
  5462 0000EAA1 C3                  <1>  	retn
  5463                              <1> glerr_2:
  5464 0000EAA2 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0, FFFFFFFEh -> FFFFFFFFh
  5465 0000EAA3 74FD                <1> 	jz	short glerr_2 ; page fault count for process
  5466 0000EAA5 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0	
  5467 0000EAA6 75EF                <1> 	jnz	short glerr_0
  5468 0000EAA8 A1[80050300]        <1> 	mov	eax, [PF_Count] ; total page fault count
  5469 0000EAAD EBED                <1>         jmp     short glerr_1
  5470                              <1> glerr_3:
  5471 0000EAAF A1[CC030300]        <1> 	mov 	eax, [u.pfcount]
  5472 0000EAB4 EBE6                <1> 	jmp	short glerr_1
  5473                              <1> 
  5474                              <1> load_and_run_file:
  5475                              <1> 	; 18/11/2017
  5476                              <1> 	; 22/01/2017
  5477                              <1> 	; 04/01/2017, 07/01/2017
  5478                              <1> 	; 24/10/2016
  5479                              <1> 	; 24/04/2016, 02/05/2016, 03/05/2016, 06/05/2016
  5480                              <1> 	; 23/04/2016 (TRDOS 386 = TRDOS v2.0)
  5481                              <1> 	; 23/10/2015 (Retro UNIX 386 v1, 'sysexec')
  5482                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  5483                              <1> 	; 03/06/2013 - 06/12/2013 (Retro UNIX 8086 v1)
  5484                              <1> 	; EAX = First Cluster number
  5485                              <1> 	; EDX = File Size
  5486                              <1> 	; ESI = Argument list address
  5487                              <1> 	; [argc] = argument count
  5488                              <1> 	; [u.nread] = argument list length
  5489                              <1> 	; [esp] = return address to the caller (*)
  5490                              <1> 	;
  5491 0000EAB6 8935[4C040300]      <1> 	mov	[argv], esi
  5492 0000EABC 8915[55040300]      <1> 	mov	[i.size], edx
  5493 0000EAC2 A3[51040300]        <1> 	mov	[ii], eax
  5494                              <1> 
  5495                              <1> 	;sti	; 07/01/2017
  5496                              <1> 	;mov	eax, [k_page_dir]
  5497                              <1> 	;mov	[u.pgdir], eax
  5498 0000EAC7 31C0                <1> 	xor 	eax, eax ; clc ; *** ; 04/01/2017
  5499                              <1> 	;mov	[u.r0], eax ; 0 ; 07/01/2017
  5500                              <1> 
  5501                              <1> 	; 06/05/2016
  5502                              <1> 	; Set 'sysexit' return order to MainProg
  5503                              <1> 	;
  5504 0000EAC9 58                  <1> 	pop	eax ; * 'loc_load_and_run_file_8:' address
  5505                              <1> 	;; 22/01/2017
  5506                              <1> 	;;cli ; 07/01/2017
  5507 0000EACA 8B25[74630100]      <1> 	mov	esp, [tss.esp0]
  5508                              <1> 	;
  5509                              <1> 	; 'loc_load_run_file_8' address has 
  5510                              <1> 	; 'jmp loc_file_rw_restore_retn' instruction
  5511                              <1> 	; 'loc_file_rw_restore_retn:' will return to
  5512                              <1> 	; [mainprog_return_addr] 
  5513                              <1> 	; just after 'call command_interpreter'
  5514                              <1> 	;
  5515 0000EAD0 68[036F0000]        <1> 	push	_end_of_mainprog ; we must not return to here !
  5516 0000EAD5 FF35[58700100]      <1> 	push	dword [mainprog_return_addr]
  5517 0000EADB 89E5                <1> 	mov	ebp, esp ; **
  5518                              <1> 	;	
  5519 0000EADD 9C                  <1> 	pushfd  ; EFLAGS      ; IRETD ; ***
  5520 0000EADE 6A08                <1> 	push	KCODE ; cs    ; IRETD
  5521 0000EAE0 50                  <1> 	push	eax ; * (eip) ; IRETD
  5522 0000EAE1 8925[5C030300]      <1> 	mov	[u.sp], esp
  5523                              <1> 	;mov	byte [u.quant], time_count
  5524 0000EAE7 1E                  <1> 	push	ds
  5525 0000EAE8 06                  <1> 	push	es
  5526 0000EAE9 0FA0                <1> 	push	fs
  5527 0000EAEB 0FA8                <1> 	push	gs	
  5528                              <1> 	;mov	eax, [u.r0]
  5529 0000EAED 29C0                <1> 	sub	eax, eax
  5530 0000EAEF 60                  <1> 	pushad
  5531 0000EAF0 68[CCD20000]        <1> 	push	sysret
  5532                              <1> 	;push	sysrel1 ; 07/01/2017
  5533 0000EAF5 8925[60030300]      <1> 	mov	[u.usp], esp
  5534                              <1> 	;
  5535 0000EAFB E845060000          <1> 	call	wswap ; Save MainProg (process 1) 'u' structure
  5536                              <1> 		      ; and registers for return (from program)	
  5537 0000EB00 89EC                <1> 	mov	esp, ebp ; **
  5538                              <1> 	;;22/01/2017
  5539                              <1> 	;;sti ; 07/01/2017
  5540 0000EB02 50                  <1> 	push	eax  ; * 'loc_load_and_run_file_8:' address
  5541                              <1> 	;
  5542                              <1> 	;;; 02/05/2016
  5543                              <1> 	;;; Create a new process (parent: MainProg)	
  5544 0000EB03 31F6                <1> 	xor 	esi, esi
  5545                              <1> cnpm_1: ; search p.stat table for unused process number
  5546 0000EB05 46                  <1> 	inc	esi
  5547 0000EB06 80BE[AF000300]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE
  5548                              <1> 				; is process active, unused, dead
  5549 0000EB0D 760B                <1> 	jna	short cnpm_2	; it's unused so branch
  5550 0000EB0F 6683FE10            <1> 	cmp	si, nproc 	; all processes checked
  5551 0000EB13 72F0                <1> 	jb	short cnpm_1    ; no, branch back
  5552 0000EB15 E97184FFFF          <1> 	jmp	panic 
  5553                              <1> cnpm_2:
  5554 0000EB1A A1[B8030300]        <1> 	mov	eax, [u.pgdir] ; page directory of MainProg
  5555 0000EB1F A3[BC030300]        <1> 	mov	[u.ppgdir], eax ; parent's page directory
  5556 0000EB24 E87C6AFFFF          <1> 	call	allocate_page
  5557 0000EB29 0F825C84FFFF        <1> 	jc	panic
  5558                              <1> 	; EAX = UPAGE (user structure page) address
  5559 0000EB2F A3[B4030300]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
  5560 0000EB34 89F7                <1> 	mov	edi, esi
  5561 0000EB36 66C1E702            <1> 	shl	di, 2
  5562 0000EB3A 8987[BC000300]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
  5563 0000EB40 E8DA6AFFFF          <1> 	call	clear_page ; 03/05/2016
  5564                              <1> 	;movzx	eax, byte [p.ttyc] ; console tty (for MainProg)
  5565 0000EB45 6629C0              <1> 	sub	ax, ax ; 0
  5566 0000EB48 668986[7F000300]    <1> 	mov     [esi+p.ttyc-1], ax ; al - set child's console tty
  5567                              <1> 				   ; ah - reset child's wait channel	
  5568 0000EB4F 89F0                <1> 	mov	eax, esi
  5569 0000EB51 A2[B3030300]        <1> 	mov	[u.uno], al ; child process number
  5570 0000EB56 FE86[AF000300]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN
  5571 0000EB5C 66D1E6              <1> 	shl	si, 1 ; multiply si by 2 to get index into p.pid table
  5572 0000EB5F 66FF05[4E030300]    <1> 	inc	word [mpid] ; increment m.pid; get a new process name
  5573 0000EB66 66A1[4E030300]      <1> 	mov	ax, [mpid]
  5574 0000EB6C 668986[1E000300]    <1> 	mov	[esi+p.pid-2], ax ; put new process name 
  5575                              <1> 				  ; in child process' name slot
  5576                              <1> 	;mov	ax, [p.pid]  ; get process name of MainProg
  5577 0000EB73 66B80100            <1> 	mov	ax, 1
  5578 0000EB77 668986[3E000300]    <1> 	mov	[esi+p.ppid-2], ax ; put parent process name 
  5579                              <1> 			           ; in parent process slot for child
  5580 0000EB7E 6648                <1> 	dec	ax ; 0
  5581 0000EB80 66A3[94030300]      <1> 	mov 	[u.ttyp], ax ; 0
  5582                              <1> 	;;;
  5583 0000EB86 A1[51040300]        <1> 	mov 	eax,  [ii]
  5584                              <1> 	; Retro UNIX 386 v1, 'sysexec' (u2.s)
  5585 0000EB8B E84C170000          <1> 	call	iopen
  5586                              <1> 	; 06/06/2016
  5587 0000EB90 C605[A9030300]01    <1> 	mov	byte [u.pri], 1 ; normal priority
  5588                              <1> 	;
  5589 0000EB97 EB16                <1> 	jmp	short sysexec_7 ; 02/05/2016
  5590                              <1> 
  5591                              <1> sysexec_6:
  5592                              <1> 	; 19/11/2017
  5593                              <1> 	; 18/11/2017
  5594                              <1> 	; 14/11/2017
  5595                              <1> 	; 13/11/2017
  5596 0000EB99 8925[4C040300]      <1> 	mov	[argv], esp ; *!* ; start address of argument list 
  5597                              <1> 
  5598                              <1> 	; 04/01/2017
  5599                              <1> 	; 24/10/2016
  5600                              <1> 	;;02/05/2016
  5601                              <1> 	; 23/04/2016 (TRDOS 386)
  5602                              <1> 	; 18/10/2015 ('sysexec_6')
  5603                              <1> 	; 23/06/2015
  5604 0000EB9F A1[B8030300]        <1> 	mov	eax, [u.pgdir] ; physical address of page directory
  5605                              <1> 	;cmp 	eax, [k_page_dir] ; TRDOS MainProg ? 
  5606                              <1> 	;je	short sysexec_7
  5607                              <1> 	; 19/11/2017
  5608 0000EBA4 8B1D[BC030300]      <1> 	mov	ebx, [u.ppgdir] ; phy addr of the parent's page dir
  5609 0000EBAA E82F6BFFFF          <1> 	call	deallocate_page_dir
  5610                              <1> sysexec_7:
  5611 0000EBAF E85F6AFFFF          <1> 	call	make_page_dir
  5612 0000EBB4 0F82D183FFFF        <1> 	jc	panic  ; allocation error 
  5613                              <1> 		       ; after a deallocation would be nonsence !?
  5614                              <1> 	; 24/07/2015
  5615                              <1> 	; map kernel pages (1st 4MB) to PDE 0
  5616                              <1> 	;     of the user's page directory
  5617                              <1> 	;     (It is needed for interrupts!)
  5618                              <1> 	; 18/10/2015
  5619 0000EBBA 8B15[D8630100]      <1> 	mov	edx, [k_page_dir] ; Kernel's page directory
  5620 0000EBC0 8B02                <1> 	mov	eax, [edx] ; physical address of
  5621                              <1> 			   ; kernel's first page table (1st 4 MB)
  5622                              <1> 			   ; (PDE 0 of kernel's page directory)
  5623 0000EBC2 8B15[B8030300]      <1> 	mov 	edx, [u.pgdir]
  5624 0000EBC8 8902                <1> 	mov	[edx], eax ; PDE 0 (1st 4MB)
  5625                              <1> 	;
  5626                              <1> 	; 20/07/2015
  5627 0000EBCA BB00004000          <1> 	mov	ebx, CORE ; start address = 0 (virtual) + CORE
  5628                              <1> 	; 18/10/2015
  5629 0000EBCF BE[3C040300]        <1> 	mov	esi, pcore ; physical start address
  5630                              <1> sysexec_8:	
  5631 0000EBD4 B907000000          <1> 	mov	ecx, PDE_A_USER + PDE_A_WRITE + PDE_A_PRESENT
  5632 0000EBD9 E8536AFFFF          <1> 	call	make_page_table
  5633 0000EBDE 0F82A783FFFF        <1> 	jc	panic
  5634                              <1> 	;mov	ecx, PTE_A_USER + PTE_A_WRITE + PTE_A_PRESENT
  5635 0000EBE4 E8566AFFFF          <1> 	call	make_page ; make new page, clear and set the pte 
  5636 0000EBE9 0F829C83FFFF        <1> 	jc	panic
  5637                              <1> 	;
  5638 0000EBEF 8906                <1> 	mov	[esi], eax ; 24/06/2015
  5639                              <1> 	; ebx = virtual address (24/07/2015)
  5640 0000EBF1 E8EE6FFFFF          <1> 	call 	add_to_swap_queue
  5641                              <1> 	; 18/10/2015
  5642 0000EBF6 81FE[40040300]      <1> 	cmp	esi, ecore ; user's stack (last) page ?
  5643 0000EBFC 740C                <1> 	je	short sysexec_9 ; yes
  5644 0000EBFE BE[40040300]        <1> 	mov	esi, ecore  ; physical address of the last page 
  5645                              <1> 	; 20/07/2015
  5646 0000EC03 BB00F0FFFF          <1> 	mov	ebx, (ECORE - PAGE_SIZE) + CORE
  5647                              <1> 	; ebx = virtual end address + segment base address - 4K
  5648 0000EC08 EBCA                <1>         jmp     short sysexec_8
  5649                              <1> sysexec_9:
  5650                              <1> 	; 19/11/2017 
  5651                              <1> 	; 24/04/2016 (TRDOS 386 = TRDOS v2.0)
  5652                              <1> 	; 25/06/2015, 26/08/2015, 18/10/2015
  5653                              <1> 	; move arguments from kernel stack to [ecore]
  5654                              <1> 	; (argument list/line will be copied from kernel stack
  5655                              <1> 	; frame to the last (stack) page of user's core memory)
  5656                              <1> 	; 18/10/2015
  5657 0000EC0A 8B3D[40040300]      <1> 	mov	edi, [ecore]
  5658 0000EC10 81C700100000        <1> 	add	edi, PAGE_SIZE
  5659                              <1> 	; 19/11/2017
  5660 0000EC16 83EF04              <1> 	sub	edi, 4
  5661 0000EC19 C70700000000        <1> 	mov	dword [edi], 0 
  5662 0000EC1F 89FB                <1> 	mov	ebx, edi
  5663                              <1> 	;
  5664 0000EC21 0FB705[4A040300]    <1> 	movzx	eax, word [argc]
  5665 0000EC28 09C0                <1> 	or	eax, eax
  5666 0000EC2A 7445                <1> 	jz	short sysexec_13 ; 19/11/2017
  5667                              <1> 	;jnz	short sysexec_10
  5668                              <1> 	;mov 	ebx, edi
  5669                              <1> 	;sub	ebx, 4 
  5670                              <1> 	;mov	[ebx], eax ; 0
  5671                              <1> 	;jmp 	short sysexec_13
  5672                              <1> sysexec_10:
  5673 0000EC2C 8B0D[8C030300]      <1> 	mov	ecx, [u.nread]
  5674                              <1> 	; 13/11/2017
  5675                              <1> 	;mov	esi, TextBuffer ; 'load_and_execute_file'
  5676                              <1> 	;mov	esi, esp  	; 'sysexec'
  5677 0000EC32 8B35[4C040300]      <1> 	mov	esi, [argv] ; 24/04/2016 (TRDOS 386  = TRDOS v2.0)
  5678                              <1> 	;sub	edi, ecx ; page end address - argument list length
  5679 0000EC38 29CB                <1> 	sub	ebx, ecx ; 19/11/2017
  5680 0000EC3A 89C2                <1> 	mov	edx, eax
  5681 0000EC3C FEC2                <1> 	inc	dl ; argument count + 1 for argc value  
  5682 0000EC3E C0E202              <1> 	shl 	dl, 2  ; 4 * (argument count + 1)
  5683                              <1> 	;mov	ebx, edi
  5684 0000EC41 89DF                <1> 	mov	edi, ebx ; 19//11/2017
  5685 0000EC43 80E3FC              <1> 	and	bl, 0FCh ; 32 bit (dword) alignment
  5686 0000EC46 29D3                <1> 	sub 	ebx, edx
  5687 0000EC48 89FA                <1> 	mov	edx, edi
  5688 0000EC4A F3A4                <1> 	rep	movsb
  5689 0000EC4C 89D6                <1> 	mov 	esi, edx
  5690 0000EC4E 89DF                <1> 	mov 	edi, ebx
  5691 0000EC50 BA00F0BFFF          <1> 	mov	edx, ECORE - PAGE_SIZE ; virtual addr. of the last page
  5692 0000EC55 2B15[40040300]      <1> 	sub 	edx, [ecore] ; difference (virtual - physical) 
  5693 0000EC5B AB                  <1> 	stosd	; eax = argument count	
  5694                              <1> sysexec_11:
  5695 0000EC5C 89F0                <1> 	mov	eax, esi
  5696 0000EC5E 01D0                <1> 	add	eax, edx
  5697 0000EC60 AB                  <1> 	stosd  ; eax = virtual address
  5698                              <1> 	;dec	byte [argc]
  5699 0000EC61 66FF0D[4A040300]    <1> 	dec	word [argc] ; 14/11/2017
  5700 0000EC68 7407                <1> 	jz	short sysexec_13
  5701                              <1> sysexec_12:
  5702 0000EC6A AC                  <1> 	lodsb
  5703 0000EC6B 20C0                <1> 	and	al, al
  5704 0000EC6D 75FB                <1> 	jnz	short sysexec_12
  5705 0000EC6F EBEB                <1> 	jmp	short sysexec_11
  5706                              <1> sysexec_13:
  5707                              <1> 	; 24/10/2016
  5708                              <1> 	; 24/04/2016 - TRDOS 386 (TRDOS v2.0)
  5709                              <1> 	; 23/06/2015 - 19/10/2015 (Retro UNIX 386 v1, 'sysexec_13')
  5710                              <1> 	;
  5711                              <1> 	; moving arguments to [ecore] is OK here..
  5712                              <1> 	;
  5713                              <1> 	; ebx = beginning addres of argument list pointers
  5714                              <1> 		;	in user's stack
  5715 0000EC71 2B1D[40040300]      <1> 	sub 	ebx, [ecore]
  5716 0000EC77 81C300F0BFFF        <1> 	add     ebx, (ECORE - PAGE_SIZE)
  5717                              <1> 			; end of core - 4096 (last page)
  5718                              <1> 			; (virtual address)
  5719 0000EC7D 891D[4C040300]      <1> 	mov	[argv], ebx
  5720 0000EC83 891D[90030300]      <1> 	mov	[u.break], ebx ; available user memory
  5721                              <1> 	;
  5722 0000EC89 29C0                <1> 	sub	eax, eax
  5723 0000EC8B C705[88030300]2000- <1> 	mov	dword [u.count], 32 ; Executable file header size
  5723 0000EC93 0000                <1>
  5724 0000EC95 C705[74030300]-     <1> 	mov	dword [u.fofp], u.off
  5724 0000EC9B [80030300]          <1>
  5725 0000EC9F A3[80030300]        <1> 	mov	[u.off], eax ; 0
  5726 0000ECA4 A3[84030300]        <1> 	mov	[u.base], eax ; 0, start of user's core (virtual)
  5727                              <1> 	; 24/10/2016
  5728 0000ECA9 A0[9E640100]        <1> 	mov	al, [Current_Drv]
  5729 0000ECAE A2[46030300]        <1> 	mov	[cdev], al
  5730                              <1> 	;
  5731 0000ECB3 A1[51040300]        <1> 	mov	eax, [ii] ; Fist Cluster of the Program (PRG) file
  5732                              <1> 	; EAX = First cluster of the executable file
  5733 0000ECB8 E80A010000          <1> 	call	readi
  5734                              <1> 
  5735 0000ECBD 8B0D[90030300]      <1> 	mov	ecx, [u.break] ; top of user's stack (physical addr.)
  5736 0000ECC3 890D[88030300]      <1> 	mov	[u.count], ecx ; save for overrun check
  5737                              <1> 	;
  5738 0000ECC9 8B0D[8C030300]      <1> 	mov	ecx, [u.nread]
  5739 0000ECCF 890D[90030300]      <1> 	mov	[u.break], ecx ; virtual address (offset from start)
  5740 0000ECD5 80F920              <1> 	cmp	cl, 32
  5741 0000ECD8 7540                <1>         jne     short sysexec_15
  5742                              <1> 	;:
  5743                              <1> 	; Retro UNIX 386 v1 (32 bit) executable file header format
  5744 0000ECDA 8B35[3C040300]      <1> 	mov	esi, [pcore] ; start address of user's core memory 
  5745                              <1> 		             ; (phys. start addr. of the exec. file)
  5746 0000ECE0 AD                  <1> 	lodsd
  5747 0000ECE1 663DEB1E            <1> 	cmp	ax, 1EEBh ; EBH, 1Eh -> jump to +32
  5748 0000ECE5 7533                <1> 	jne	short sysexec_15
  5749 0000ECE7 AD                  <1> 	lodsd
  5750 0000ECE8 89C1                <1> 	mov	ecx, eax ; text (code) section size
  5751 0000ECEA AD                  <1> 	lodsd
  5752 0000ECEB 01C1                <1> 	add	ecx, eax ; + data section size (initialized data)
  5753 0000ECED 89CB                <1> 	mov	ebx, ecx
  5754 0000ECEF AD                  <1> 	lodsd	
  5755 0000ECF0 01C3                <1> 	add	ebx, eax ; + bss section size (for overrun checking)
  5756 0000ECF2 3B1D[88030300]      <1> 	cmp	ebx, [u.count]
  5757 0000ECF8 7711                <1> 	ja	short sysexec_14  ; program overruns stack !
  5758                              <1> 	;
  5759                              <1> 	; add bss section size to [u.break]
  5760 0000ECFA 0105[90030300]      <1> 	add 	[u.break], eax
  5761                              <1> 	;
  5762 0000ED00 83E920              <1> 	sub	ecx, 32  ; header size (already loaded)
  5763                              <1> 	;cmp	ecx, [u.count]
  5764                              <1> 	;jnb	short sysexec_16
  5765 0000ED03 890D[88030300]      <1> 	mov	[u.count], ecx ; required read count
  5766 0000ED09 EB29                <1> 	jmp	short sysexec_16
  5767                              <1> sysexec_14:
  5768                              <1> 	; insufficient (out of) memory
  5769 0000ED0B C705[C8030300]0400- <1> 	mov	dword [u.error], ERR_MINOR_IM ; 1
  5769 0000ED13 0000                <1>
  5770 0000ED15 E992E5FFFF          <1> 	jmp	error
  5771                              <1> sysexec_15:
  5772 0000ED1A 8B15[55040300]      <1>         mov	edx, [i.size] ; file size
  5773 0000ED20 29CA                <1> 	sub	edx, ecx ; file size - loaded bytes
  5774 0000ED22 7626                <1> 	jna	short sysexec_17 ; no need to next read
  5775 0000ED24 01D1                <1> 	add	ecx, edx ; [i.size]
  5776 0000ED26 3B0D[88030300]      <1> 	cmp	ecx, [u.count] ; overrun check (!)
  5777 0000ED2C 77DD                <1> 	ja	short sysexec_14
  5778 0000ED2E 8915[88030300]      <1> 	mov	[u.count], edx
  5779                              <1> sysexec_16:
  5780 0000ED34 A1[51040300]        <1> 	mov	eax, [ii] ; first cluster
  5781 0000ED39 E889000000          <1> 	call	readi
  5782 0000ED3E 8B0D[8C030300]      <1> 	mov	ecx, [u.nread]
  5783 0000ED44 010D[90030300]      <1> 	add	[u.break], ecx
  5784                              <1> sysexec_17:
  5785 0000ED4A A1[51040300]        <1> 	mov	eax, [ii] ; first cluster
  5786 0000ED4F E889150000          <1> 	call	iclose
  5787 0000ED54 31C0                <1> 	xor     eax, eax
  5788 0000ED56 FEC0                <1> 	inc	al
  5789 0000ED58 66A3[AA030300]      <1> 	mov	[u.intr], ax ; 1 (interrupt/time-out is enabled)
  5790 0000ED5E 66A3[AC030300]      <1> 	mov	[u.quit], ax ; 1 ('crtl+brk' signal is enabled) 
  5791 0000ED64 833D[BC030300]00    <1>         cmp	dword [u.ppgdir], 0  ; is the caller MainProg (kernel) ?
  5792 0000ED6B 770C                <1> 	ja	short sysexec_18 ; no, the caller is user process
  5793                              <1> 	; If the caller is kernel (MainProg), 'sysexec' will come here
  5794 0000ED6D 8B15[D8630100]      <1> 	mov	edx, [k_page_dir] ; kernel's page directory
  5795 0000ED73 8915[BC030300]      <1> 	mov	[u.ppgdir], edx ; next time 'sysexec' must not come here 
  5796                              <1> sysexec_18:
  5797                              <1> 	; 02/05/2016
  5798                              <1> 	; 24/04/2016 (TRDOS 386 = TRDOS v2.0)
  5799                              <1> 	; 18/10/2015 (Retro UNIX 386 v1)
  5800                              <1> 	; 05/08/2015
  5801                              <1> 	; 29/07/2015
  5802                              <1> 
  5803                              <1> ;	; **** arguments list test start - 19/11/2017
  5804                              <1> ;	mov	ebp, [argv]
  5805                              <1> ;	sub	ebp, ECORE - 4096
  5806                              <1> ;	add	ebp, [ecore]
  5807                              <1> ;
  5808                              <1> ;	mov	ebx, [ebp]
  5809                              <1> ;	mov	[argc], bx
  5810                              <1> ;	add	ebp, 4
  5811                              <1> ;	mov	byte [ccolor], 1Fh
  5812                              <1> ;_zx0:
  5813                              <1> ;	cmp	word [argc], 0
  5814                              <1> ;	jna	short _zx2	
  5815                              <1> ;_zx1:
  5816                              <1> ;	push	ebp
  5817                              <1> ;	mov	esi, [ebp]
  5818                              <1> ;
  5819                              <1> ;	sub	esi, ECORE - 4096
  5820                              <1> ;	add	esi, [ecore]
  5821                              <1> ;
  5822                              <1> ;	call	print_cmsg
  5823                              <1> ;
  5824                              <1> ;	dec	word [argc]
  5825                              <1> ;	jz	short _zx2
  5826                              <1> ;
  5827                              <1> ;	mov	al, '.'
  5828                              <1> ;	mov	bl, 07h
  5829                              <1> ;	mov	bh, [u.ttyn]
  5830                              <1> ;	call 	_write_tty 
  5831                              <1> ;
  5832                              <1> ;	pop	ebp
  5833                              <1> ;	add	ebp, 4
  5834                              <1> ;	jmp	short _zx1			
  5835                              <1> ;_zx2:
  5836                              <1> ;	pop	ebp
  5837                              <1> ;	mov	byte [ccolor], 07h
  5838                              <1> ;	mov	eax, 1
  5839                              <1> ;	; **** arguments list test stop
  5840                              <1> ;	Test result is OK! (there is not a wrong thing) - 19/11/2017
  5841                              <1> 
  5842 0000ED79 8B2D[4C040300]      <1> 	mov	ebp, [argv] ; user's stack pointer must point to argument
  5843                              <1> 			    ; list pointers (argument count)
  5844 0000ED7F FA                  <1> 	cli
  5845 0000ED80 8B25[74630100]      <1>         mov     esp, [tss.esp0] ; ring 0 (kernel) stack pointer
  5846                              <1> 	;mov   	esp, [u.sp] ; Restore Kernel stack
  5847                              <1> 			    ; for this process	 
  5848                              <1> 	;add	esp, 20 ; --> EIP, CS, EFLAGS, ESP, SS
  5849                              <1> 	;xor	eax, eax ; 0
  5850 0000ED86 FEC8                <1> 	dec	al ; eax = 0
  5851                              <1> 	;mov	edx, UDATA
  5852                              <1> 	; 18/11/2017
  5853 0000ED88 6A23                <1> 	push	UDATA ; user's stack segment
  5854                              <1> 	;push	edx
  5855 0000ED8A 55                  <1> 	push	ebp ; user's stack pointer
  5856                              <1> 		    ; (points to number of arguments)
  5857                              <1> 	
  5858                              <1> 	; 04/01/2017
  5859                              <1> 	; MainProg comes here while [sysflg]= 0FFh
  5860                              <1> 	; (but sysexec comes here while [sysflg]= 0)
  5861 0000ED8B C605[5B030300]00    <1> 	mov	byte [sysflg], 0 ; 04/01/2017
  5862                              <1> 				 ; (timer_int sysflg control)
  5863 0000ED92 FB                  <1> 	sti
  5864 0000ED93 9C                  <1> 	pushfd	; EFLAGS
  5865                              <1> 		; Set IF for enabling interrupts in user mode	
  5866                              <1> 	;or	dword [esp], 200h 
  5867                              <1> 	;
  5868                              <1> 	;mov	bx, UCODE
  5869                              <1> 	;push	bx ; user's code segment
  5870 0000ED94 6A1B                <1> 	push	UCODE
  5871                              <1> 	;push	0
  5872 0000ED96 50                  <1> 	push	eax ; EIP (=0) - start address -	
  5873 0000ED97 8925[5C030300]      <1> 	mov	[u.sp], esp ; 29/07/2015
  5874                              <1> 	; 05/08/2015
  5875                              <1> 	; Remedy of a General Protection Fault during 'iretd' is here !
  5876                              <1> 	; ('push dx' would cause to general protection fault, 
  5877                              <1> 	; after 'pop ds' etc.)
  5878                              <1> 	;
  5879                              <1> 	;; push dx ; ds (UDATA)
  5880                              <1> 	;; push dx ; es (UDATA)
  5881                              <1> 	;; push dx ; fs (UDATA)
  5882                              <1> 	;; push dx ; gs (UDATA)
  5883                              <1> 	;
  5884                              <1> 	; This is a trick to prevent general protection fault
  5885                              <1> 	; during 'iretd' intruction at the end of 'sysrele' (in u1.s):
  5886 0000ED9D 66BA2300            <1> 	mov	dx, UDATA ; 19/11/2017
  5887 0000EDA1 8EC2                <1> 	mov 	es, dx ; UDATA
  5888 0000EDA3 06                  <1> 	push 	es ; ds (UDATA)
  5889 0000EDA4 06                  <1> 	push 	es ; es (UDATA)
  5890 0000EDA5 06                  <1> 	push 	es ; fs (UDATA)
  5891 0000EDA6 06                  <1> 	push	es ; gs (UDATA)
  5892 0000EDA7 66BA1000            <1> 	mov	dx, KDATA
  5893 0000EDAB 8EC2                <1> 	mov	es, dx
  5894                              <1> 	;
  5895                              <1> 	;; pushad simulation
  5896 0000EDAD 89E5                <1> 	mov	ebp, esp ; esp before pushad
  5897 0000EDAF 50                  <1> 	push	eax ; eax (0)
  5898 0000EDB0 50                  <1> 	push	eax ; ecx (0)
  5899 0000EDB1 50                  <1> 	push	eax ; edx (0)
  5900 0000EDB2 50                  <1> 	push	eax ; ebx (0)
  5901 0000EDB3 55                  <1> 	push	ebp ; esp before pushad
  5902 0000EDB4 50                  <1> 	push	eax ; ebp (0)
  5903 0000EDB5 50                  <1> 	push	eax ; esi (0)		
  5904 0000EDB6 50                  <1> 	push	eax ; edi (0)	
  5905                              <1> 	;
  5906 0000EDB7 A3[64030300]        <1> 	mov	[u.r0], eax ; eax = 0
  5907 0000EDBC 8925[60030300]      <1> 	mov	[u.usp], esp
  5908                              <1> 
  5909                              <1> 	; 14/11/2017
  5910 0000EDC2 E907E5FFFF          <1> 	jmp	sysret0
  5911                              <1> 
  5912                              <1> ;	; 02/05/2016
  5913                              <1> ;	;inc	byte [sysflg] ; 0FFh -> 0
  5914                              <1> ;	;mov	byte [sysflg], 0 ; 04/01/2017
  5915                              <1> ;	movzx	ebx, byte [u.uno]
  5916                              <1> ;	shl	bl, 1 ; 13/11/2017 	
  5917                              <1> ;	cmp	word [ebx+p.ppid-2], 1 ; MainProg
  5918                              <1> ;	ja	sysret0 ; 03/05/2016
  5919                              <1> ;	push	sysret ; * 
  5920                              <1> ;	mov	[u.usp], esp
  5921                              <1> ;	call	wswap ; save child process 'u' structure and
  5922                              <1> ;		      ; registers
  5923                              <1> ;	add	dword [u.usp], 4 ; 03/05/2016 
  5924                              <1> ;sysexec_19: ; 02/05/2016
  5925                              <1> ;	retn ; * 'sysret' ; byte [sysflg] -> 0FFh
  5926                              <1> 
  5927                              <1> readi:
  5928                              <1> 	; 01/05/2016
  5929                              <1> 	; 25/04/2016 - TRDOS 386 (TRDOS v2.0)
  5930                              <1> 	; 20/05/2015 - Retro UNIX 386 v1
  5931                              <1> 	; 11/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  5932                              <1> 	;
  5933                              <1> 	; Reads from a file whose the first cluster number in EAX
  5934                              <1> 	; 
  5935                              <1> 	; INPUTS ->
  5936                              <1> 	;    EAX - First cluster number of the file
  5937                              <1> 	;    u.count - byte count user desires
  5938                              <1> 	;    u.base - points to user buffer
  5939                              <1> 	;    u.fofp - points to dword with current file offset
  5940                              <1> 	;    i.size - file size
  5941                              <1> 	;    cdev - logical dos drive number of the file
  5942                              <1> 	; OUTPUTS ->
  5943                              <1> 	;    u.count - cleared
  5944                              <1> 	;    u.nread - accumulates total bytes passed back
  5945                              <1> 	;
  5946                              <1> 	; ((EAX)) input/output
  5947                              <1> 	; (Retro UNIX Prototype : 14/12/2012 - 01/03/2013, UNIXCOPY.ASM)
  5948                              <1>         ; ((Modified registers: edx, ebx, ecx, esi, edi))  
  5949                              <1> 
  5950 0000EDC7 31D2                <1> 	xor	edx, edx ; 0
  5951 0000EDC9 8915[8C030300]      <1> 	mov 	[u.nread], edx ; 0
  5952 0000EDCF 668915[C4030300]    <1> 	mov	[u.pcount], dx ; 19/05/2015
  5953 0000EDD6 3915[88030300]      <1> 	cmp 	[u.count], edx ; 0
  5954 0000EDDC 7701                <1> 	ja 	short readi_1
  5955 0000EDDE C3                  <1> 	retn
  5956                              <1> readi_1:
  5957                              <1> dskr:
  5958                              <1> 	; 01/05/2016
  5959                              <1> 	; 25/04/2016 - TRDOS 386 (TRDOS v2.0)
  5960                              <1> 	; 24/05/2015 - 12/10/2015 (Retro UNIX 386 v1)
  5961                              <1> 	; 26/04/2013 - 03/08/2013 (Retro UNIX 8086 v1)
  5962                              <1> dskr_0:
  5963 0000EDDF 8B15[55040300]      <1>         mov	edx, [i.size]
  5964 0000EDE5 8B1D[74030300]      <1> 	mov	ebx, [u.fofp]
  5965 0000EDEB 2B13                <1> 	sub	edx, [ebx]
  5966 0000EDED 7647                <1> 	jna	short dskr_4
  5967                              <1> 	;
  5968 0000EDEF 50                  <1> 	push	eax ; 01/05/2016
  5969 0000EDF0 3B15[88030300]      <1> 	cmp     edx, [u.count] 
  5970 0000EDF6 7306                <1> 	jnb	short dskr_1
  5971 0000EDF8 8915[88030300]      <1> 	mov	[u.count], edx
  5972                              <1> dskr_1:
  5973                              <1> 	; EAX = First Cluster
  5974                              <1> 	; [Current_Drv] = Physical drive number 
  5975 0000EDFE E83B000000          <1> 	call	mget_r
  5976                              <1> 	; NOTE: in 'mget_r', relevant sector will be read in buffer
  5977                              <1> 	; if it is not already in buffer !
  5978 0000EE03 BB[8C050300]        <1> 	mov	ebx, readi_buffer
  5979 0000EE08 803D[C6030300]00    <1> 	cmp	byte [u.kcall], 0 ; the caller is 'namei' sign (=1)
  5980 0000EE0F 770F                <1> 	ja	short dskr_3	  ; zf=0 -> the caller is 'namei'
  5981 0000EE11 66833D[C4030300]00  <1> 	cmp	word [u.pcount], 0
  5982 0000EE19 7705                <1> 	ja	short dskr_3
  5983                              <1> dskr_2:
  5984                              <1> 	; [u.base] = virtual address to transfer (as destination address)
  5985 0000EE1B E894010000          <1> 	call	trans_addr_w ; translate virtual address to physical (w)
  5986                              <1> dskr_3:
  5987                              <1> 	; EBX (r5) = system (I/O) buffer address -physical-
  5988 0000EE20 E8F7010000          <1> 	call	sioreg
  5989 0000EE25 87F7                <1> 	xchg	esi, edi
  5990                              <1> 	; EDI = file (user data) offset
  5991                              <1> 	; ESI = sector (I/O) buffer offset
  5992                              <1> 	; ECX = byte count
  5993 0000EE27 F3A4                <1> 	rep	movsb
  5994                              <1> 	; eax = remain bytes in buffer
  5995                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
  5996 0000EE29 09C0                <1> 	or	eax, eax
  5997 0000EE2B 75EE                <1> 	jnz	short dskr_2 ; (page end before system buffer end!)		
  5998 0000EE2D 58                  <1> 	pop	eax  ; (first cluster number)
  5999 0000EE2E 390D[88030300]      <1> 	cmp	[u.count], ecx ; 0
  6000 0000EE34 77A9                <1> 	ja	short dskr_0
  6001                              <1> dskr_4:
  6002 0000EE36 C605[C6030300]00    <1> 	mov	byte [u.kcall], 0
  6003 0000EE3D C3                  <1> 	retn
  6004                              <1> 
  6005                              <1> mget_r:
  6006                              <1> 	; 24/10/2016
  6007                              <1> 	; 22/10/2016
  6008                              <1> 	; 12/10/2016
  6009                              <1> 	; 29/04/2016
  6010                              <1> 	; 25/04/2016 - TRDOS 386 (TRDOS v2.0)
  6011                              <1> 	; 03/06/2015 (Retro UNIX 386 v1, 'mget', u.5s)
  6012                              <1> 	; 22/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  6013                              <1> 	;
  6014                              <1> 	; Get existing or (allocate) a new disk block for file
  6015                              <1> 	; 
  6016                              <1> 	; INPUTS ->
  6017                              <1> 	;    [u.fofp] = file offset pointer
  6018                              <1> 	;    EAX = First Cluster
  6019                              <1> 	;    [cdev] = Logical dos drive number 	  
  6020                              <1> 	;    ([u.off] = file offset)
  6021                              <1> 	; OUTPUTS ->
  6022                              <1> 	;    EAX = logical sector number
  6023                              <1> 	;    ESI = Logical Dos Drive Description Table address	
  6024                              <1> 	;
  6025                              <1> 	; Modified registers: EDX, EBX, ECX, ESI, EDI
  6026                              <1> 
  6027 0000EE3E 8B35[74030300]      <1> 	mov     esi, [u.fofp]
  6028 0000EE44 8B1E                <1> 	mov	ebx, [esi] ; (u.off)
  6029                              <1> 
  6030 0000EE46 29C9                <1> 	sub	ecx, ecx
  6031 0000EE48 8A2D[46030300]      <1> 	mov	ch, [cdev]
  6032                              <1> 
  6033 0000EE4E BE00010900          <1> 	mov	esi, Logical_DOSDisks
  6034 0000EE53 01CE                <1> 	add	esi, ecx
  6035                              <1> 
  6036 0000EE55 380D[0C700100]      <1> 	cmp	[readi.valid], cl ; 0
  6037 0000EE5B 7649                <1> 	jna	short mget_r_0
  6038                              <1> 	
  6039 0000EE5D 3A2D[0D700100]      <1> 	cmp	ch, [readi.drv]
  6040 0000EE63 7541                <1> 	jne	short mget_r_0
  6041                              <1> 
  6042 0000EE65 3B05[20700100]      <1> 	cmp	eax, [readi.fclust]
  6043 0000EE6B 7565                <1> 	jne	short mget_r_3
  6044                              <1> 	
  6045 0000EE6D 89D8                <1> 	mov	eax, ebx ; file offset
  6046 0000EE6F 668B0D[14700100]    <1> 	mov	cx, [readi.bpc]
  6047 0000EE76 41                  <1> 	inc	ecx ; <= 65536
  6048 0000EE77 29D2                <1> 	sub	edx, edx
  6049 0000EE79 F7F1                <1> 	div	ecx
  6050                              <1> 
  6051 0000EE7B 8B3D[1C700100]      <1> 	mov	edi, [readi.c_index] ; cluster index
  6052                              <1> 
  6053 0000EE81 39F8                <1> 	cmp	eax, edi
  6054 0000EE83 757A                <1>         jne     short mget_r_4  ; (*)
  6055                              <1> 
  6056                              <1> 	; edx = byte offset in cluster (<= 65535)
  6057 0000EE85 668915[16700100]    <1> 	mov	[readi.offset], dx
  6058 0000EE8C 66C1EA09            <1> 	shr	dx, 9 ; / 512
  6059 0000EE90 8815[0F700100]      <1> 	mov	[readi.s_index], dl ; sector index in cluster (0 to spc -1)
  6060                              <1> 	
  6061 0000EE96 A1[18700100]        <1> 	mov	eax, [readi.cluster]  ; > 0 if [readi.valid] = 1
  6062 0000EE9B 8B15[24700100]      <1> 	mov	edx, [readi.fs_index]
  6063 0000EEA1 E99A000000          <1>         jmp     mget_r_7
  6064                              <1> 	
  6065                              <1> mget_r_0:
  6066 0000EEA6 882D[0D700100]      <1> 	mov	[readi.drv], ch ; physical drive number
  6067 0000EEAC 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  6068 0000EEB0 7707                <1> 	ja	short mget_r_1
  6069 0000EEB2 8A4E12              <1> 	mov	cl, [esi+LD_FS_BytesPerSec+1]
  6070 0000EEB5 D0E9                <1> 	shr	cl, 1 ;  ; 1 for 512 bytes, 4 for 2048 bytes
  6071 0000EEB7 EB03                <1> 	jmp	short mget_r_2	
  6072                              <1> mget_r_1:
  6073 0000EEB9 8A4E13              <1> 	mov	cl, [esi+LD_BPB+BPB_SecPerClust]
  6074                              <1> mget_r_2:
  6075 0000EEBC 880D[0E700100]      <1> 	mov	[readi.spc], cl  ; sectors per cluster
  6076                              <1> 	; NOTE: readi bytes per sector value is always 512 ! 
  6077 0000EEC2 66C1E109            <1> 	shl	cx, 9 ; * 512
  6078 0000EEC6 6649                <1> 	dec	cx ; bytes per cluster - 1
  6079 0000EEC8 66890D[14700100]    <1> 	mov	[readi.bpc], cx
  6080 0000EECF 6629C9              <1> 	sub	cx, cx
  6081                              <1> mget_r_3:
  6082 0000EED2 A3[20700100]        <1> 	mov	[readi.fclust], eax ; first cluster (or FDT address)
  6083 0000EED7 880D[0C700100]      <1> 	mov	[readi.valid], cl ; 0 
  6084                              <1> 	;mov	[readi.s_index], cl ; 0
  6085                              <1> 	;mov	[readi.offset], cx ; 0
  6086 0000EEDD 890D[1C700100]      <1> 	mov	[readi.c_index], ecx ; 0
  6087 0000EEE3 890D[18700100]      <1> 	mov	[readi.cluster], ecx ; 0
  6088 0000EEE9 890D[10700100]      <1> 	mov	[readi.sector], ecx ; 0
  6089                              <1> 	
  6090 0000EEEF 89D8                <1> 	mov	eax, ebx ; file offset
  6091 0000EEF1 668B0D[14700100]    <1> 	mov	cx, [readi.bpc]
  6092 0000EEF8 41                  <1> 	inc	ecx ; <= 65536
  6093 0000EEF9 29D2                <1> 	sub	edx, edx
  6094 0000EEFB F7F1                <1> 	div	ecx
  6095                              <1> 	;mov	edi, [readi.c_index] ; previous cluster index
  6096 0000EEFD 29FF                <1> 	sub	edi, edi
  6097                              <1> mget_r_4:
  6098 0000EEFF A3[1C700100]        <1> 	mov	[readi.c_index], eax ; cluster index
  6099                              <1> 	; edx = byte offset in cluster (<= 65535)
  6100 0000EF04 668915[16700100]    <1> 	mov	[readi.offset], dx
  6101 0000EF0B 66C1EA09            <1> 	shr	dx, 9 ; / 512
  6102 0000EF0F 8815[0F700100]      <1> 	mov	[readi.s_index], dl ; sector index in cluster (0 to spc -1)
  6103                              <1> 
  6104 0000EF15 89C1                <1> 	mov	ecx, eax ; current cluster index
  6105 0000EF17 A1[20700100]        <1> 	mov	eax, [readi.fclust]
  6106 0000EF1C 09C9                <1> 	or	ecx, ecx ; cluster index
  6107 0000EF1E 741B                <1> 	jz	short mget_r_6
  6108                              <1> 
  6109 0000EF20 39CF                <1> 	cmp	edi, ecx
  6110 0000EF22 7710                <1> 	ja	short mget_r_5 ; old cluster index is higher
  6111 0000EF24 8B15[18700100]      <1> 	mov	edx, [readi.cluster]
  6112 0000EF2A 21D2                <1> 	and	edx, edx
  6113 0000EF2C 7406                <1> 	jz	short mget_r_5
  6114                              <1> 	; valid 'readi' parameters (*)
  6115 0000EF2E 89D0                <1> 	mov	eax, edx
  6116 0000EF30 29F9                <1> 	sub	ecx, edi
  6117 0000EF32 740C                <1> 	jz	short mget_r_7
  6118                              <1> mget_r_5:
  6119                              <1> 	; EAX = Beginning cluster
  6120                              <1> 	; EDX = Sector index in disk/file section
  6121                              <1> 	;	(Only for SINGLIX file system!)
  6122                              <1> 	; ECX = Cluster sequence number after the beginning cluster
  6123                              <1> 	; ESI = Logical DOS Drive Description Table address
  6124 0000EF34 E80CE2FFFF          <1> 	call	get_cluster_by_index
  6125 0000EF39 724E                <1> 	jc	short mget_r_err
  6126                              <1> 	; EAX = Cluster number		
  6127                              <1> mget_r_6:
  6128 0000EF3B A3[18700100]        <1> 	mov	[readi.cluster], eax ; FDT number for Singlix File System
  6129                              <1> mget_r_7:
  6130 0000EF40 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  6131 0000EF44 765F                <1> 	jna	short mget_r_12
  6132                              <1> 
  6133 0000EF46 83E802              <1> 	sub	eax, 2
  6134 0000EF49 0FB615[0E700100]    <1> 	movzx	edx, byte [readi.spc]
  6135 0000EF50 F7E2                <1> 	mul	edx
  6136                              <1> 
  6137 0000EF52 034668              <1> 	add	eax, [esi+LD_DATABegin]
  6138 0000EF55 8A15[0F700100]      <1> 	mov	dl, [readi.s_index]
  6139 0000EF5B 01D0                <1> 	add	eax, edx
  6140                              <1> mget_r_8:
  6141                              <1> 	; eax = logical sector number
  6142 0000EF5D 803D[0C700100]00    <1> 	cmp	byte [readi.valid], 0
  6143 0000EF64 7608                <1> 	jna	short mget_r_9
  6144 0000EF66 3B05[10700100]      <1> 	cmp	eax, [readi.sector]
  6145 0000EF6C 7436                <1> 	je	short mget_r_11 ; sector is already in 'readi' buffer
  6146                              <1> mget_r_9:
  6147 0000EF6E A3[10700100]        <1> 	mov	[readi.sector], eax
  6148 0000EF73 BB[8C050300]        <1> 	mov	ebx, readi_buffer ; buffer address
  6149 0000EF78 B901000000          <1> 	mov	ecx, 1
  6150                              <1> 	; 29/04/2016
  6151                              <1> 	;xor	dl, dl
  6152                              <1> 
  6153                              <1> 	; EAX = Logical sector number
  6154                              <1> 	; ECX = Sector count
  6155                              <1> 	; EBX = Buffer address
  6156                              <1> 	; (EDX = 0)
  6157                              <1> 	; ESI = Logical DOS drive description table address	
  6158                              <1> 
  6159 0000EF7D E86E130000          <1> 	call	disk_read
  6160 0000EF82 7314                <1> 	jnc	short mget_r_10
  6161                              <1> 
  6162                              <1> 	; 22/10/2016 (15h -> 17)
  6163 0000EF84 B811000000          <1> 	mov	eax, 17 ; Drive not ready or read error !
  6164                              <1> mget_r_err:
  6165 0000EF89 A3[C8030300]        <1> 	mov	[u.error], eax
  6166                              <1> 	; 12/10/2016
  6167 0000EF8E A3[64030300]        <1> 	mov	[u.r0], eax
  6168 0000EF93 E914E3FFFF          <1> 	jmp	error
  6169                              <1> mget_r_10:
  6170 0000EF98 C605[0C700100]01    <1> 	mov	byte [readi.valid], 1 ; 24/10/2016
  6171 0000EF9F A1[10700100]        <1> 	mov	eax, [readi.sector]
  6172                              <1> mget_r_11:
  6173 0000EFA4 C3                  <1> 	retn
  6174                              <1> mget_r_12:
  6175                              <1> 	; EAX = FDT number
  6176                              <1> 	; EDX = Sector index from FDT sector (0,1,2,3,4...)
  6177 0000EFA5 40                  <1> 	inc	eax ; the first data sector in FS disk section	
  6178 0000EFA6 8915[24700100]      <1> 	mov	[readi.fs_index], edx
  6179 0000EFAC 01D0                <1> 	add	eax, edx
  6180 0000EFAE EBAD                <1> 	jmp	short mget_r_8
  6181                              <1> 
  6182                              <1> trans_addr_r:
  6183                              <1> 	; 12/10/2016
  6184                              <1> 	; 02/05/2016 - TRDOS 386 (TRDOS v2.0)
  6185                              <1> 	; Translate virtual address to physical address 
  6186                              <1> 	; for reading from user's memory space
  6187                              <1> 	; 04/06/2015 - 18/10/2015 (Retro UNIX 386 v1)
  6188                              <1> 
  6189 0000EFB0 31D2                <1> 	xor	edx, edx ; 0 (read access sign)
  6190 0000EFB2 EB04                <1> 	jmp 	short trans_addr_rw
  6191                              <1> 
  6192                              <1> trans_addr_w:
  6193                              <1> 	; 12/10/2016
  6194                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  6195                              <1> 	; Translate virtual address to physical address 
  6196                              <1> 	; for writing to user's memory space
  6197                              <1> 	; 04/06/2015 - 18/10/2015 (Retro UNIX 386 v1)
  6198                              <1> 	
  6199 0000EFB4 29D2                <1> 	sub	edx, edx
  6200 0000EFB6 FEC2                <1> 	inc	dl ; 1 (write access sign)
  6201                              <1> trans_addr_rw:
  6202 0000EFB8 50                  <1> 	push	eax
  6203 0000EFB9 53                  <1> 	push	ebx
  6204 0000EFBA 52                  <1> 	push 	edx ; r/w sign (in DL)
  6205                              <1> 	;
  6206 0000EFBB 8B1D[84030300]      <1> 	mov	ebx, [u.base]
  6207 0000EFC1 E8F46CFFFF          <1> 	call	get_physical_addr ; get physical address
  6208 0000EFC6 730F                <1> 	jnc	short passc_0
  6209 0000EFC8 A3[C8030300]        <1> 	mov	[u.error], eax
  6210 0000EFCD A3[64030300]        <1> 	mov	[u.r0], eax ; 12/10/2016
  6211                              <1> 	;pop	edx
  6212                              <1> 	;pop 	ebx
  6213                              <1> 	;pop	eax
  6214 0000EFD2 E9D5E2FFFF          <1> 	jmp	error
  6215                              <1> passc_0:
  6216 0000EFD7 F6C202              <1> 	test	dl, PTE_A_WRITE ; writable page
  6217 0000EFDA 5A                  <1> 	pop	edx
  6218 0000EFDB 751C                <1> 	jnz	short passc_1
  6219                              <1> 	
  6220 0000EFDD 20D2                <1> 	and 	dl, dl
  6221 0000EFDF 7418                <1> 	jz	short passc_1
  6222                              <1> 	; read only (duplicated) page -must be copied to a new page-
  6223                              <1> 	; EBX = linear address
  6224 0000EFE1 51                  <1> 	push 	ecx
  6225 0000EFE2 E86C69FFFF          <1> 	call 	copy_page
  6226 0000EFE7 59                  <1> 	pop	ecx
  6227 0000EFE8 721E                <1> 	jc	short passc_2
  6228 0000EFEA 50                  <1> 	push	eax ; physical address of the new/allocated page
  6229 0000EFEB E8F46BFFFF          <1> 	call	add_to_swap_queue	
  6230 0000EFF0 58                  <1> 	pop	eax
  6231 0000EFF1 81E3FF0F0000        <1> 	and 	ebx, PAGE_OFF ; 0FFFh
  6232                              <1> 	;mov 	ecx, PAGE_SIZE
  6233                              <1> 	;sub	ecx, ebx 
  6234 0000EFF7 01D8                <1> 	add	eax, ebx  
  6235                              <1> passc_1: 
  6236 0000EFF9 A3[C0030300]        <1> 	mov 	[u.pbase], eax ; physical address	
  6237 0000EFFE 66890D[C4030300]    <1> 	mov	[u.pcount], cx ; remain byte count in page (1-4096)
  6238 0000F005 5B                  <1> 	pop	ebx
  6239 0000F006 58                  <1> 	pop	eax
  6240 0000F007 C3                  <1> 	retn
  6241                              <1> passc_2:
  6242 0000F008 B804000000          <1> 	mov	eax, ERR_MINOR_IM ; "Insufficient memory !" error
  6243 0000F00D A3[64030300]        <1> 	mov	[u.r0], eax ; 12/10/2016
  6244 0000F012 A3[C8030300]        <1> 	mov	dword [u.error], eax
  6245                              <1> 	;pop 	ebx
  6246                              <1> 	;pop	eax
  6247 0000F017 E990E2FFFF          <1> 	jmp	error
  6248                              <1> 
  6249                              <1> sioreg: 
  6250                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  6251                              <1> 	; 19/05/2015 - 25/07/2015 (Retro UNIX 386 v1)
  6252                              <1> 	; 12/03/2013 - 22/07/2013 (Retro UNIX 8086 v1)
  6253                              <1> 	; INPUTS -> 
  6254                              <1> 	;     EBX = system buffer (data) address (r5)
  6255                              <1> 	;     [u.fofp] = pointer to file offset pointer
  6256                              <1> 	;     [u.base] = virtual address of the user buffer
  6257                              <1> 	;     [u.pbase] = physical address of the user buffer
  6258                              <1> 	;     [u.count] = byte count
  6259                              <1> 	;     [u.pcount] = byte count within page frame 			
  6260                              <1> 	; OUTPUTS -> 
  6261                              <1> 	;     ESI = user data offset (r1)
  6262                              <1> 	;     EDI = system (I/O) buffer offset (r2)
  6263                              <1> 	;     ECX = byte count (r3)
  6264                              <1> 	;     EAX = remain bytes after byte count within page frame
  6265                              <1> 	;	(If EAX > 0, transfer will continue from the next page)
  6266                              <1>         ;
  6267                              <1> 	; ((Modified registers:  EDX))
  6268                              <1>  
  6269 0000F01C 8B35[74030300]      <1>         mov     esi, [u.fofp]
  6270 0000F022 8B3E                <1>         mov     edi, [esi]
  6271 0000F024 89F9                <1> 	mov	ecx, edi
  6272 0000F026 81C900FEFFFF        <1> 	or	ecx, 0FFFFFE00h
  6273 0000F02C 81E7FF010000        <1> 	and	edi, 1FFh
  6274 0000F032 01DF                <1> 	add	edi, ebx ; EBX = system buffer (data) address
  6275 0000F034 F7D9                <1> 	neg	ecx
  6276 0000F036 3B0D[88030300]      <1> 	cmp	ecx, [u.count]
  6277 0000F03C 7606                <1> 	jna	short sioreg_0
  6278 0000F03E 8B0D[88030300]      <1> 	mov	ecx, [u.count]
  6279                              <1> sioreg_0:
  6280 0000F044 803D[C6030300]00    <1> 	cmp	byte [u.kcall], 0 
  6281 0000F04B 7613                <1> 	jna	short sioreg_1
  6282                              <1> 	 ; the caller is 'mkdir' or 'namei'
  6283 0000F04D A1[84030300]        <1> 	mov	eax, [u.base]
  6284 0000F052 A3[C0030300]        <1> 	mov 	[u.pbase], eax ; physical address = virtual address
  6285 0000F057 66890D[C4030300]    <1> 	mov	word [u.pcount], cx ; remain bytes in buffer (1 sector)
  6286 0000F05E EB0B                <1> 	jmp	short sioreg_2
  6287                              <1> sioreg_1:
  6288 0000F060 0FB715[C4030300]    <1> 	movzx	edx, word [u.pcount]
  6289 0000F067 39D1                <1> 	cmp	ecx, edx	
  6290 0000F069 772A                <1> 	ja	short sioreg_4 ; transfer count > [u.pcount]
  6291                              <1> sioreg_2: ; 2:
  6292 0000F06B 31C0                <1> 	xor 	eax, eax
  6293                              <1> sioreg_3:
  6294 0000F06D 010D[8C030300]      <1> 	add 	[u.nread], ecx
  6295 0000F073 290D[88030300]      <1> 	sub 	[u.count], ecx
  6296 0000F079 010D[84030300]      <1> 	add 	[u.base], ecx
  6297 0000F07F 010E                <1>         add 	[esi], ecx 
  6298 0000F081 8B35[C0030300]      <1> 	mov	esi, [u.pbase]
  6299 0000F087 66290D[C4030300]    <1> 	sub	[u.pcount], cx
  6300 0000F08E 010D[C0030300]      <1> 	add	[u.pbase], ecx
  6301 0000F094 C3                  <1>         retn
  6302                              <1> sioreg_4:
  6303                              <1> 	; transfer count > [u.pcount] 
  6304                              <1> 	; (ecx > edx)
  6305 0000F095 89C8                <1> 	mov	eax, ecx
  6306 0000F097 29D0                <1> 	sub	eax, edx ; remain bytes for 1 sector (block) transfer 
  6307 0000F099 89D1                <1> 	mov	ecx, edx ; current transfer count = [u.pcount]
  6308 0000F09B EBD0                <1> 	jmp	short sioreg_3
  6309                              <1> 
  6310                              <1> tswitch: ; Retro UNIX 386 v1
  6311                              <1> tswap:
  6312                              <1> 	; 16/01/2017
  6313                              <1> 	; 21/05/2016 - TRDOS 386 (TRDOS v2.0)
  6314                              <1> 	; 10/05/2015 - 01/09/2015 (Retro UNIX 386 v1)
  6315                              <1> 	; 14/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
  6316                              <1> 	; time out swap, called when a user times out.
  6317                              <1> 	; the user is put on the low priority queue.
  6318                              <1> 	; This is done by making a link from the last user
  6319                              <1> 	; on the low priority queue to him via a call to 'putlu'.
  6320                              <1> 	; then he is swapped out.
  6321                              <1> 
  6322                              <1> 	; TRDOS 386 (TRDOS v2.0) modification ->  ** 21/05/2016 **
  6323                              <1> 	;     * when a high priority (event) process will be stopped
  6324                              <1> 	;	(swapped out, swithched out/off), 'tswap/tswitch' will
  6325                              <1> 	;	not add it to a run queue. 
  6326                              <1> 	;	/// What for: Process may be already in a run queue, 
  6327                              <1> 	;	it is unspeficied state because process might be started
  6328                              <1> 	;	by a timer event which does not regard previous priority
  6329                              <1> 	;	level and run queue of the process (for fast executing!).
  6330                              <1> 	;	After the 'run for event', process will be sequenced
  6331                              <1> 	;	to run by it's actual run queue. ///
  6332                              <1> 	;
  6333                              <1> 	; Retro UNIX 386 v1 modification ->
  6334                              <1> 	;       swap (software task switch) is performed by changing
  6335                              <1> 	;	user's page directory (u.pgdir) instead of segment change
  6336                              <1> 	;	as in Retro UNIX 8086 v1.
  6337                              <1> 	;
  6338                              <1> 	; RETRO UNIX 8086 v1 modification ->
  6339                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  6340                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  6341                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  6342                              <1> 	;	compatibles was using 1MB segmented memory 
  6343                              <1> 	;	in 8086/8088 times.
  6344                              <1> 	;
  6345                              <1> 	; INPUTS ->
  6346                              <1> 	;    u.uno - users process number
  6347                              <1> 	;    runq+4 - lowest priority queue
  6348                              <1> 	; OUTPUTS ->
  6349                              <1> 	;    r0 - users process number
  6350                              <1> 	;    r2 - lowest priority queue address
  6351                              <1> 	;
  6352                              <1> 	; ((AX = R0, BX = R2)) output
  6353                              <1> 	; ((Modified registers: EDX, EBX, ECX, ESI, EDI))  	
  6354                              <1> 	;
  6355                              <1> 
  6356                              <1> 	NOTE:
  6357                              <1> 	;* [u.pri] priority level is specified by run queue which is process 
  6358                              <1> 	;  comes to run from.
  6359                              <1> 	;* Initial [u.pri] is 1 ('normal/regular') for programs 
  6360                              <1> 	;  (which are launched by MainProg or 'sysexec'), it is changed
  6361                              <1> 	;  to 2 ('high') by timer event, if program uses 'systimer' system call.
  6362                              <1> 	;* Program (Process) also can change it's running priority 
  6363                              <1> 	;  from 1 to 0 or up to 2 by using 'syspri' system call; but,
  6364                              <1> 	;  if program selects priority level 2 (high) for running, next time 
  6365                              <1> 	;  it is reduced to 1 (normal/regular) because 'syspri' adds this
  6366                              <1> 	;  program to 'run for normal' queue while running duration is a bit
  6367                              <1> 	;  protected from swap/switch out immediate, behalf of other high 
  6368                              <1> 	;  priority process in sequence. Program (with high priority) will not 
  6369                              <1> 	;  be swapped/switched out (by timer event) before it's time quantum 
  6370                              <1> 	;  will be elapsed, but, this will be temporary if program is not using 
  6371                              <1> 	;  timer event function.	  			 	
  6372                              <1> 
  6373                              <1> 	;For example:
  6374                              <1> 	;If a process frequently gets a timer event, it runs at high priority
  6375                              <1> 	;level but when it returns from running it returns to actual run queue,
  6376                              <1> 	;not to 'run for event' queue again.
  6377                              <1> 	;'tswap' will not change the sequence at return/stop(swap out) stage.
  6378                              <1> 	;But if priority level not high (=2, 'run for event'), 'tswap/tswitch'
  6379                              <1> 	;will add the stopping process to relevant run queue according to
  6380                              <1> 	;[u.pri] priority level.
  6381                              <1> 
  6382                              <1> 	; 16/01/2017
  6383 0000F09D BB[54030300]        <1> 	mov	ebx, runq+2 	; 'runq_normal' ; normal/regular priority
  6384                              <1> 	; 21/05/2016
  6385                              <1> 	;cmp	byte [u.pri], 2	; high priority (run for event) ?
  6386                              <1> 	;jnb	short swap
  6387                              <1> 	; 16/01/2017
  6388                              <1> 	; (Normal and also high/event priority processes will be added to
  6389                              <1> 	; normal priority run queue for ensuring circular running sequence!)
  6390                              <1> 	; (Timer interrupt or 'syspri' system call may change priority and run
  6391                              <1> 	; queue to high/event level.)
  6392 0000F0A2 803D[A9030300]00    <1> 	cmp	byte [u.pri], 0
  6393 0000F0A9 7702                <1> 	ja	short tswap_1	; normal priority run queue
  6394                              <1> 	;
  6395 0000F0AB 43                  <1> 	inc	ebx
  6396 0000F0AC 43                  <1> 	inc	ebx		; runq+4, 'runq_background', low priority
  6397                              <1> tswap_1:
  6398 0000F0AD A0[B3030300]        <1> 	mov 	al, [u.uno]
  6399                              <1> 	       	; movb u.uno,r1 / move users process number to r1
  6400                              <1> 		; mov  $runq+4,r2 
  6401                              <1> 			; / move lowest priority queue address to r2
  6402                              <1>       	; ebx = run queue
  6403 0000F0B2 E8FE000000          <1> 	call 	putlu
  6404                              <1> 		; jsr r0,putlu / create link from last user on Q to 
  6405                              <1> 		             ; / u.uno's user
  6406                              <1> 
  6407                              <1> switch: ; Retro UNIX 386 v1
  6408                              <1> swap:
  6409                              <1> 	; 02/01/2017
  6410                              <1> 	; 21/05/2016
  6411                              <1> 	; 20/05/2016
  6412                              <1> 	; 02/05/2016
  6413                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  6414                              <1> 	; 10/05/2015 - 02/09/2015 (Retro UNIX 386 v1)
  6415                              <1> 	; 14/04/2013 - 08/03/2014 (Retro UNIX 8086 v1)
  6416                              <1> 	;
  6417                              <1> 	; 'swap' is routine that controls the swapping of processes
  6418                              <1> 	; in and out of core.
  6419                              <1> 	;
  6420                              <1> 	; TRDOS 386 (TRDOS v2.0) modification ->  ** 20/05/2016 **
  6421                              <1> 	;     * 3 different priority level is applied 
  6422                              <1> 	;	(just as original unix v1)
  6423                              <1> 	;	1) high priority (event) run queue, 'runq_event'
  6424                              <1> 	;	2) normal priority (regular) run queue, 'runq_normal'
  6425                              <1> 	;	3) low priority (background) run queue, 'runq_backgroud'
  6426                              <1> 	;	'swap' code will run a process which has max. priority
  6427                              <1>         ;       (for earliest event at first)
  6428                              <1> 	;
  6429                              <1> 	; Retro UNIX 386 v1 modification ->
  6430                              <1> 	;       swap (software task switch) is performed by changing
  6431                              <1> 	;	user's page directory (u.pgdir) instead of segment change
  6432                              <1> 	;	as in Retro UNIX 8086 v1.
  6433                              <1> 	;
  6434                              <1> 	; RETRO UNIX 8086 v1 modification ->
  6435                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  6436                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  6437                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  6438                              <1> 	;	compatibles was using 1MB segmented memory 
  6439                              <1> 	;	in 8086/8088 times.
  6440                              <1> 	;
  6441                              <1> 	; INPUTS ->
  6442                              <1> 	;    runq table - contains processes to run.
  6443                              <1> 	;    p.link - contains next process in line to be run.
  6444                              <1> 	;    u.uno - process number of process in core	
  6445                              <1> 	;    s.stack - swap stack used as an internal stack for swapping.	
  6446                              <1> 	; OUTPUTS ->
  6447                              <1> 	;    (original unix v1 -> present process to its disk block)
  6448                              <1> 	;    (original unix v1 -> new process into core -> 
  6449                              <1> 	;	   Retro Unix 8086 v1 -> segment registers changed 
  6450                              <1> 	;	   for new process)
  6451                              <1> 	;    u.quant = 3 (Time quantum for a process)
  6452                              <1> 	; 	((INT 1Ch count down speed -> 18.2 times per second)	 	
  6453                              <1> 	;    RETRO UNIX 8086 v1 will use INT 1Ch (18.2 times per second)
  6454                              <1> 	;	 for now, it will swap the process if there is not
  6455                              <1> 	;	 a keyboard event (keystroke) (Int 15h, function 4Fh)
  6456                              <1> 	;	 or will count down from 3 to 0 even if there is a
  6457                              <1> 	;        keyboard event locking due to repetitive key strokes.
  6458                              <1> 	;	 u.quant will be reset to 3 for RETRO UNIX 8086 v1.
  6459                              <1> 	;
  6460                              <1> 	; ((Modified registers: EAX, EDX, EBX, ECX, ESI, EDI))  	
  6461                              <1> 
  6462                              <1> 	;NOTE:
  6463                              <1> 	;High priority queue is the first for selecting a process to run.
  6464                              <1> 	;If there is not a process in high priority level run queue,
  6465                              <1> 	;a process in normal priority run queue will be selected
  6466                              <1> 	;or a proces in low priority run queue will be selected if normal
  6467                              <1> 	;priority level run queue is empty.
  6468                              <1> 	
  6469                              <1> 	; 21/05/2016 -(3 priority levels, 3 run queues)
  6470 0000F0B7 BE[52030300]        <1> 	mov	esi, runq ; 'runq_event' ; high priority, 'run for event'
  6471 0000F0BC C605[68700100]03    <1> 	mov	byte [priority], 3 ; high priority + 1
  6472 0000F0C3 31DB                <1> 	xor	ebx, ebx ; 02/01/2017
  6473                              <1> swap_0: ; 1: / search runq table for highest priority process
  6474 0000F0C5 66AD                <1> 	lodsw  ; mov ax, [esi], add esi+2
  6475                              <1> 	;xor	ebx, ebx ; 02/05/2016
  6476 0000F0C7 6621C0              <1> 	and 	ax, ax ; are there any processes to run in this Q entry
  6477 0000F0CA 750E                <1> 	jnz	short swap_2 
  6478                              <1> 	; 21/05/2026
  6479                              <1> 	; runq_normal = runq+2, runq_background = runq+4
  6480 0000F0CC FE0D[68700100]      <1> 	dec	byte [priority] ; 3 -> 3, 2 -> 1, 1-> 0
  6481 0000F0D2 75F1                <1> 	jnz	short swap_0	
  6482                              <1> 	;cmp	esi, runq+6  ; if zero compare address to end of table
  6483                              <1> 	;jb	short swap_0 ; if not at end, go back
  6484                              <1> swap_1:
  6485                              <1> 	; 02/05/2016
  6486                              <1> 	; 29/04/2016 (TRDOS 386 = TRDOS v2.0)
  6487                              <1> 	; No user process to run...
  6488                              <1> 	; Run the kernel process... MainProg: Internal Command Interpreter  
  6489 0000F0D4 FEC0                <1> 	inc	al ; mov al, 1  ; process number of MainProg
  6490 0000F0D6 FEC3                <1> 	inc	bl ; mov bl, al ; 1
  6491 0000F0D8 EB1E                <1> 	jmp	short swap_4
  6492                              <1> swap_2:
  6493                              <1> 	; 21/05/2016
  6494 0000F0DA FE0D[68700100]      <1> 	dec	byte [priority] ; priority level of present user/process
  6495                              <1> 			        ; 0, 1, 2	   
  6496 0000F0E0 4E                  <1> 	dec	esi
  6497 0000F0E1 4E                  <1>         dec     esi
  6498                              <1> 	;
  6499 0000F0E2 88C3                <1> 	mov	bl, al
  6500 0000F0E4 38E0                <1> 	cmp	al, ah ; is there only 1 process in the queue to be run
  6501 0000F0E6 740A                <1> 	je	short swap_3 ; yes
  6502 0000F0E8 8AA3[9F000300]      <1> 	mov	ah, [ebx+p.link-1] 
  6503 0000F0EE 8826                <1>        	mov	[esi], ah ; move next process in line into run queue
  6504 0000F0F0 EB06                <1> 	jmp	short swap_4
  6505                              <1> swap_3: 
  6506 0000F0F2 6631D2              <1> 	xor	dx, dx
  6507 0000F0F5 668916              <1> 	mov	[esi], dx ; zero the entry; no processes on the Q
  6508                              <1> swap_4: 
  6509 0000F0F8 8A25[B3030300]      <1> 	mov 	ah, [u.uno]
  6510 0000F0FE 38C4                <1> 	cmp	ah, al ; is this process the same as the process in core?
  6511 0000F100 743B                <1>        	je	short swap_8 ; yes, don't have to swap
  6512 0000F102 08E4                <1> 	or	ah, ah  ; is the process # = 0
  6513 0000F104 740D                <1>        	jz	short swap_6 ; 'sysexit'
  6514                              <1> 	;cmp	ah, al ;is this process the same as the process in core?
  6515                              <1>        	;je	short swap_8 ; yes, don't have to swap
  6516 0000F106 8925[60030300]      <1> 	mov	[u.usp], esp ; return  address for 'syswait' & 'sleep'
  6517 0000F10C E834000000          <1> 	call	wswap   ; write out core to disk
  6518 0000F111 EB1C                <1> 	jmp 	short swap_7
  6519                              <1> swap_6:
  6520                              <1> 	; Deallocate memory pages belong to the process
  6521                              <1> 	; which is being terminated.
  6522                              <1> 	; (Retro UNIX 386 v1 modification !)
  6523                              <1> 	;
  6524 0000F113 53                  <1> 	push	ebx
  6525 0000F114 A1[B8030300]        <1> 	mov 	eax, [u.pgdir]  ; page directory of the process
  6526 0000F119 8B1D[BC030300]      <1> 	mov	ebx, [u.ppgdir] ; page directory of the parent process
  6527 0000F11F E8BA65FFFF          <1> 	call	deallocate_page_dir
  6528 0000F124 A1[B4030300]        <1> 	mov	eax, [u.upage] ; 'user' structure page of the process
  6529 0000F129 E85566FFFF          <1> 	call	deallocate_page
  6530 0000F12E 5B                  <1> 	pop	ebx
  6531                              <1> swap_7: 
  6532 0000F12F C0E302              <1> 	shl	bl, 2 ; * 4 
  6533 0000F132 8B83[BC000300]      <1> 	mov	eax, [ebx+p.upage-4] ; the 'u' page of the new process
  6534 0000F138 E840000000          <1> 	call	rswap ; read new process into core
  6535                              <1> swap_8: 
  6536                              <1> 	; Retro UNIX  8086 v1 modification !
  6537 0000F13D C605[A8030300]04    <1> 	mov	byte [u.quant], time_count 
  6538 0000F144 C3                  <1> 	retn
  6539                              <1> 
  6540                              <1> wswap:  ; < swap out, swap to disk >
  6541                              <1> 	; 28/02/2017 (fnsave)
  6542                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  6543                              <1> 	; 09/05/2015 (Retro UNIX 386 v1)
  6544                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
  6545                              <1> 	; 'wswap' writes out the process that is in core onto its 
  6546                              <1> 	; appropriate disk area.
  6547                              <1> 	;
  6548                              <1> 	; Retro UNIX 386 v1 modification ->
  6549                              <1> 	;       User (u) structure content and the user's register content
  6550                              <1> 	;	will be copied to the process's/user's UPAGE (a page for
  6551                              <1> 	;	saving 'u' structure and user registers for task switching).
  6552                              <1> 	;	u.usp - points to kernel stack address which contains
  6553                              <1> 	;		user's registers while entering system call.  
  6554                              <1> 	;	u.sp  - points to kernel stack address 
  6555                              <1> 	;		to return from system call -for IRET-.
  6556                              <1> 	;	[u.usp]+32+16 = [u.sp] 
  6557                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
  6558                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
  6559                              <1> 	;
  6560                              <1> 	; Retro UNIX 8086 v1 modification ->
  6561                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  6562                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  6563                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  6564                              <1> 	;	compatibles was using 1MB segmented memory 
  6565                              <1> 	;	in 8086/8088 times.
  6566                              <1> 	;
  6567                              <1> 	; INPUTS ->
  6568                              <1> 	;    u.break - points to end of program
  6569                              <1> 	;    u.usp - stack pointer at the moment of swap
  6570                              <1> 	;    core - beginning of process program		
  6571                              <1> 	;    ecore - end of core 	
  6572                              <1> 	;    user - start of user parameter area		
  6573                              <1> 	;    u.uno - user process number	
  6574                              <1> 	;    p.dska - holds block number of process	
  6575                              <1> 	; OUTPUTS ->
  6576                              <1> 	;    swp I/O queue
  6577                              <1> 	;    p.break - negative word count of process 
  6578                              <1> 	;    r1 - process disk address	
  6579                              <1> 	;    r2 - negative word count
  6580                              <1> 	;
  6581                              <1> 	; RETRO UNIX 8086 v1 input/output:
  6582                              <1> 	;
  6583                              <1> 	; INPUTS ->
  6584                              <1> 	;    u.uno - process number (to be swapped out)
  6585                              <1> 	; OUTPUTS ->
  6586                              <1> 	;    none
  6587                              <1> 	;
  6588                              <1> 	;   ((Modified registers: ECX, ESI, EDI))  
  6589                              <1> 	;
  6590                              <1> 
  6591                              <1> 	; 28/02/2017
  6592                              <1> 	;cmp	byte [multi_tasking], 0  ; Musti tasking mode ?
  6593                              <1> 	;jna	short wswp
  6594 0000F145 803D[DA030300]00    <1> 	cmp	byte [u.fpsave], 0 ; 28/02/2017
  6595 0000F14C 7606                <1> 	jna	short wswp
  6596 0000F14E DD35[DC030300]      <1> 	fnsave	[u.fpregs] ; save floating point registers (94 bytes)
  6597                              <1> wswp:
  6598 0000F154 8B3D[B4030300]      <1> 	mov	edi, [u.upage] ; process's user (u) structure page addr
  6599 0000F15A B938000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
  6600 0000F15F BE[5C030300]        <1> 	mov	esi, user ; active user (u) structure	
  6601 0000F164 F3A5                <1> 	rep	movsd
  6602                              <1> 	;
  6603 0000F166 8B35[60030300]      <1> 	mov	esi, [u.usp] ; esp (system stack pointer, 
  6604                              <1> 			     ;      points to user registers)
  6605 0000F16C 8B0D[5C030300]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
  6606                              <1> 			     ; (for IRET)
  6607                              <1> 			     ; [u.sp] -> EIP (user)
  6608                              <1> 			     ; [u.sp+4]-> CS (user)
  6609                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
  6610                              <1> 			     ; [u.sp+12] -> ESP (user)
  6611                              <1> 			     ; [u.sp+16] -> SS (user)	
  6612 0000F172 29F1                <1> 	sub	ecx, esi     ; required space for user registers
  6613 0000F174 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
  6614                              <1> 			     ; (for IRET) 	
  6615 0000F177 C1E902              <1> 	shr	ecx, 2	     		
  6616 0000F17A F3A5                <1> 	rep	movsd
  6617 0000F17C C3                  <1> 	retn
  6618                              <1> 
  6619                              <1> rswap:  ; < swap in, swap from disk >
  6620                              <1> 	; 28/02/2017 (frstor)
  6621                              <1> 	; 15/01/2017
  6622                              <1> 	; 14/01/2017
  6623                              <1> 	; 21/05/2016
  6624                              <1> 	; 03/05/2016
  6625                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  6626                              <1> 	; 09/05/2015 - 15/09/2015 (Retro UNIX 386 v1)
  6627                              <1> 	; 26/05/2013 - 08/03/2014 (Retro UNIX 8086 v1)
  6628                              <1> 	; 'rswap' reads a process whose number is in r1, 
  6629                              <1> 	; from disk into core.
  6630                              <1> 	;
  6631                              <1> 	; Retro UNIX 386 v1 modification ->
  6632                              <1> 	;       User (u) structure content and the user's register content
  6633                              <1> 	;	will be restored from process's/user's UPAGE (a page for
  6634                              <1> 	;	saving 'u' structure and user registers for task switching).
  6635                              <1> 	;	u.usp - points to kernel stack address which contains
  6636                              <1> 	;		user's registers while entering system call.  
  6637                              <1> 	;	u.sp  - points to kernel stack address 
  6638                              <1> 	;		to return from system call -for IRET-.
  6639                              <1> 	;	[u.usp]+32+16 = [u.sp] 
  6640                              <1> 	;	[u.usp] -> edi, esi, ebp, esp (= [u.usp]+32), ebx, 
  6641                              <1> 	;		edx, ecx, eax, gs, fs, es, ds, -> [u.sp].
  6642                              <1> 	;
  6643                              <1> 	; RETRO UNIX 8086 v1 modification ->
  6644                              <1> 	;       'swap to disk' is replaced with 'change running segment'
  6645                              <1> 	;	according to 8086 cpu (x86 real mode) architecture.
  6646                              <1> 	;	pdp-11 was using 64KB uniform memory while IBM PC
  6647                              <1> 	;	compatibles was using 1MB segmented memory 
  6648                              <1> 	;	in 8086/8088 times.
  6649                              <1> 	;
  6650                              <1> 	; INPUTS ->
  6651                              <1> 	;    r1 - process number of process to be read in
  6652                              <1> 	;    p.break - negative of word count of process 
  6653                              <1> 	;    p.dska - disk address of the process		
  6654                              <1> 	;    u.emt - determines handling of emt's 	
  6655                              <1> 	;    u.ilgins - determines handling of illegal instructions		
  6656                              <1> 	; OUTPUTS ->
  6657                              <1> 	;    8 = (u.ilgins)
  6658                              <1> 	;    24 = (u.emt)
  6659                              <1> 	;    swp - bit 10 is set to indicate read 
  6660                              <1> 	;		(bit 15=0 when reading is done)	
  6661                              <1> 	;    swp+2 - disk block address
  6662                              <1> 	;    swp+4 - negative word count 	
  6663                              <1> 	;      ((swp+6 - address of user structure)) 
  6664                              <1> 	;
  6665                              <1> 	; RETRO UNIX 8086 v1 input/output:
  6666                              <1> 	;
  6667                              <1> 	; INPUTS ->
  6668                              <1> 	;    AL	- new process number (to be swapped in)	 
  6669                              <1> 	; OUTPUTS ->
  6670                              <1> 	;    none
  6671                              <1> 	;
  6672                              <1> 	;   ((Modified registers: EAX, ECX, ESI, EDI, ESP)) 
  6673                              <1> 	;
  6674                              <1> 	; Retro UNIX 386 v1 - modification ! 14/05/2015
  6675 0000F17D 89C6                <1> 	mov	esi, eax  ; process's user (u) structure page addr
  6676 0000F17F B938000000          <1> 	mov	ecx, (U_SIZE + 3) / 4
  6677 0000F184 BF[5C030300]        <1> 	mov	edi, user ; active user (u) structure	
  6678 0000F189 F3A5                <1> 	rep	movsd
  6679 0000F18B 58                  <1> 	pop	eax	; 'rswap' return address
  6680                              <1> 	; 
  6681                              <1> 	;cli
  6682 0000F18C 8B3D[60030300]      <1> 	mov	edi, [u.usp] ; esp (system stack pointer, 
  6683                              <1> 			     ;     points to user registers)
  6684 0000F192 89FC                <1> 	mov	esp, edi     ; 14/01/2017
  6685 0000F194 8B0D[5C030300]      <1> 	mov	ecx, [u.sp]  ; return address from the system call
  6686                              <1> 			     ; (for IRET)
  6687                              <1> 			     ; [u.sp] -> EIP (user)
  6688                              <1> 			     ; [u.sp+4]-> CS (user)
  6689                              <1> 			     ; [u.sp+8] -> EFLAGS (user)
  6690                              <1> 			     ; [u.sp+12] -> ESP (user)
  6691                              <1> 			     ; [u.sp+16] -> SS (user)		
  6692 0000F19A 29F9                <1> 	sub	ecx, edi     ; required space for user registers
  6693 0000F19C 83C114              <1> 	add	ecx, 20	     ; +5 dwords to return from system call
  6694                              <1> 			     ; (for IRET) 	
  6695 0000F19F C1E902              <1> 	shr	ecx, 2	       		
  6696 0000F1A2 F3A5                <1> 	rep	movsd
  6697                              <1> 	;mov	esp, [u.usp] ; 15/09/2015
  6698                              <1> 	;sti
  6699                              <1> 	; 28/02/2017
  6700                              <1> 	;cmp	byte [multi_tasking], 0  ; Musti tasking mode ?
  6701                              <1> 	;jna	short rswp_retn
  6702 0000F1A4 803D[DA030300]00    <1> 	cmp	byte [u.fpsave], 0
  6703 0000F1AB 7606                <1> 	jna	short rswp_retn
  6704 0000F1AD DD25[DC030300]      <1> 	frstor	[u.fpregs] ; restore floating point regs (94 bytes)
  6705                              <1> rswp_retn:
  6706 0000F1B3 50                  <1> 	push	eax	; 'rswap' return address
  6707 0000F1B4 C3                  <1> 	retn
  6708                              <1> 
  6709                              <1> putlu: 
  6710                              <1> 	; 20/05/2016
  6711                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  6712                              <1> 	; 10/05/2015 - 12/09/2015 (Retro UNIX 386 v1)
  6713                              <1> 	; 15/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
  6714                              <1> 	; 'putlu' is called with a process number in r1 and a pointer
  6715                              <1> 	; to lowest priority Q (runq+4) in r2. A link is created from
  6716                              <1> 	; the last process on the queue to process in r1 by putting
  6717                              <1> 	; the process number in r1 into the last process's link.
  6718                              <1> 	;
  6719                              <1> 	; INPUTS ->
  6720                              <1> 	;    r1 - user process number
  6721                              <1> 	;    r2 - points to lowest priority queue 
  6722                              <1> 	;    p.dska - disk address of the process		
  6723                              <1> 	;    u.emt - determines handling of emt's 	
  6724                              <1> 	;    u.ilgins - determines handling of illegal instructions		
  6725                              <1> 	; OUTPUTS ->
  6726                              <1> 	;    r3 - process number of last process on the queue upon
  6727                              <1> 	;	  entering putlu
  6728                              <1> 	;    p.link-1 + r3 - process number in r1
  6729                              <1> 	;    r2 - points to lowest priority queue
  6730                              <1> 	;
  6731                              <1> 	; ((Modified registers: EDX, EBX)) 
  6732                              <1> 	;
  6733                              <1> 	; / r1 = user process no.; r2 points to lowest priority queue
  6734                              <1> 
  6735                              <1> 	; EBX = r2
  6736                              <1> 	; EAX = r1 (AL=r1b)
  6737                              <1> 
  6738                              <1> 	; 20/05/2016
  6739                              <1> 	; AL = process number (1 to 16) // Retro UNIX 8086, 386 v1 // 
  6740                              <1> 	;     (max. 16 processes available for current kernel version) 
  6741                              <1> 	; EBX = run queue address ; 20/05/2016 (TRDOS 386)
  6742                              <1> 		; which is one of following addresses:
  6743                              <1> 		;  1) 'runq_event' high priority run queue	 	
  6744                              <1> 		;  2) 'runq_normal' normal/regular priority run queue
  6745                              <1> 		;  3) 'runq_background' low priority run queue
  6746                              <1> 
  6747                              <1> 	;mov	ebx, runq
  6748 0000F1B5 0FB613              <1> 	movzx  	edx, byte [ebx]
  6749 0000F1B8 43                  <1> 	inc	ebx
  6750 0000F1B9 20D2                <1> 	and	dl, dl
  6751                              <1> 		; tstb (r2)+ / is queue empty?
  6752 0000F1BB 740A                <1>        	jz	short putlu_1
  6753                              <1> 		; beq 1f / yes, branch
  6754 0000F1BD 8A13                <1> 	mov 	dl, [ebx] ; 12/09/2015
  6755                              <1> 		; movb (r2),r3 / no, save the "last user" process number
  6756                              <1> 			     ; / in r3
  6757 0000F1BF 8882[9F000300]      <1>        	mov	[edx+p.link-1], al
  6758                              <1> 		; movb r1,p.link-1(r3) / put pointer to user on 
  6759                              <1> 			     ; / "last users" link
  6760 0000F1C5 EB03                <1> 	jmp	short putlu_2
  6761                              <1> 		; br 2f /
  6762                              <1> putlu_1: ; 1:
  6763 0000F1C7 8843FF              <1> 	mov	[ebx-1], al
  6764                              <1>        		; movb r1,-1(r2) / user is only user; 
  6765                              <1> 			    ; / put process no. at beginning and at end
  6766                              <1> putlu_2: ; 2: 
  6767 0000F1CA 8803                <1> 	mov	[ebx], al
  6768                              <1>        		; movb r1,(r2) / user process in r1 is now the last entry
  6769                              <1> 			     ; / on the queue
  6770 0000F1CC 88C2                <1> 	mov	dl, al
  6771 0000F1CE 88B2[9F000300]      <1>         mov     [edx+p.link-1], dh ; 0
  6772                              <1> 		; dec r2 / restore r2
  6773 0000F1D4 C3                  <1>         retn
  6774                              <1> 		; rts r0
  6775                              <1> 
  6776                              <1> sysver:
  6777                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
  6778 0000F1D5 C705[64030300]0002- <1> 	mov	dword [u.r0], 200h ; AH = major version, AL = minor version 
  6778 0000F1DD 0000                <1>
  6779 0000F1DF E9E8E0FFFF          <1> 	jmp	sysret
  6780                              <1> 
  6781                              <1> 
  6782                              <1> syspri: ; change running priority (of the process)
  6783                              <1> 	; 21/05/2016
  6784                              <1> 	; 20/05/2026 - TRDOS 386 (TRDOS v2.0)
  6785                              <1> 	; INPUT ->
  6786                              <1> 	;	BL = priority level
  6787                              <1> 	;	   0 = low running priority (running on background)
  6788                              <1> 	;	   1 = normal/regular priority (running as regular)
  6789                              <1> 	;	   2 = high/event priority (running for event)
  6790                              <1> 	;	   >2 = invalid, it will accepted as 2 (event)
  6791                              <1> 	;	   0FFh = get/return current running priority only	
  6792                              <1> 	; OUTPUT -> 	
  6793                              <1> 	;	* if current [u.pri] < 2
  6794                              <1> 	;	  if BL input < 0FFh ->
  6795                              <1> 	;	     [u.pri] is updated as in BL input (0,1,2)
  6796                              <1> 	;	  if BL input = 0FFh -> AL = [u.pri] (current)
  6797                              <1> 	;	      
  6798                              <1> 	;	* if current [u.pri] = 2
  6799                              <1> 	;	  if BL input < 0FFh -> cf = 1 & AL = 2
  6800                              <1> 	;	  if BL input = 0FFh -> cf = 0 & AL = 2  
  6801                              <1> 	;	
  6802                              <1> 	;	NOTE: 	
  6803                              <1> 	;	If [u.pri] = 2, it can not be changed to 1 or 0;
  6804                              <1> 	;	because, run queue of the running process is unspecified
  6805                              <1> 	;	at this	stage. Process might be started by a timer event
  6806                              <1> 	;	or priority might be changed to high by previous
  6807                              <1> 	;	'syspri' system	call. In both cases, the process is in
  6808                              <1> 	;	'runq_normal' or 'runq_background' queue.
  6809                              <1> 	;	As result of this fact, when the [u.quant] time quantum
  6810                              <1> 	;	of the process is elapsed or 'sysrele' system call is
  6811                              <1> 	;	instructed by the process, 'tswap' ('tswitch') procedure
  6812                              <1> 	;	will be called (to 'swap' or 'switch' out the procedure)
  6813                              <1> 	;	and it will not call 'putlu' to add the (stopping)
  6814                              <1> 	;	process to relevant run queue when [u.pri] = 2.
  6815                              <1> 	;	(Otherwise, it would be possible to add process to
  6816                              <1> 	;	a run queue while it is already in a run queue, wrongly.)
  6817                              <1>   	;
  6818                              <1> 	;	If [u.pri]< 2, 'tswap/tswitch' procedure will call 
  6819                              <1> 	;	'putlu' to add process to relevant run queue
  6820                              <1> 	;	according to [u.pri] value. ('runq_normal' for 1, 
  6821                              <1> 	;	'runq_background' for 0).
  6822                              <1> 	;
  6823                              <1> 	;	If BL input >= 2 and < 0FFh while [u.pri] < 2,
  6824                              <1> 	;	process will be added to 'runq_normal' queue and
  6825                              <1> 	;	[u.pri] will be set to 2. (in 'syspri' system call)
  6826                              <1> 	;
  6827                              <1> 
  6828 0000F1E4 29C0                <1> 	sub	eax, eax ; 0
  6829 0000F1E6 A3[C8030300]        <1> 	mov	[u.error], eax
  6830                              <1> 
  6831 0000F1EB A0[A9030300]        <1> 	mov	al, [u.pri]
  6832 0000F1F0 A3[64030300]        <1> 	mov	[u.r0], eax
  6833                              <1> 
  6834 0000F1F5 FEC3                <1> 	inc	bl
  6835 0000F1F7 0F84CFE0FFFF        <1> 	jz	sysret ; 0FFh -> 0, get priority level
  6836                              <1> 	
  6837 0000F1FD 3C02                <1> 	cmp	al, 2
  6838 0000F1FF 0F83A7E0FFFF        <1> 	jnb	error ; CF = 1 & AL = 2 (& last error = 0)
  6839                              <1> 
  6840 0000F205 FECB                <1> 	dec	bl
  6841 0000F207 80FB02              <1> 	cmp	bl, 2
  6842 0000F20A 7602                <1> 	jna	short syspri_1
  6843 0000F20C B302                <1> 	mov	bl, 2
  6844                              <1> syspri_1:
  6845 0000F20E 881D[A9030300]      <1> 	mov	[u.pri], bl
  6846 0000F214 80FB02              <1> 	cmp	bl, 2
  6847 0000F217 0F82AFE0FFFF        <1>         jb      sysret
  6848                              <1> 
  6849                              <1> 	; here...
  6850                              <1> 	; Priority of current process has been changed to high
  6851                              <1> 	; ('run for event') but current process will be added to
  6852                              <1> 	; 'run as normal' queue. ('run for event' high priority
  6853                              <1> 	; queue is under control of timer -& RTC- interrupt only!) 
  6854                              <1> 	;
  6855                              <1> 	; (Otherwise, process can fall into black hole!
  6856                              <1> 	; e.g. if it is not in waiting list and it has not got 
  6857                              <1> 	; a timer event and it is not in a run queue!
  6858                              <1> 	; Because, when [u.pri] is 2, 'tswap/tswitch' will not 
  6859                              <1> 	; add the stopping process to a run queue.)
  6860                              <1> 
  6861 0000F21D A0[B3030300]        <1> 	mov	al, [u.uno]
  6862 0000F222 BB[54030300]        <1> 	mov	ebx, runq_normal ; normal priority !
  6863                              <1> 				 ; [u.pri] is set to high
  6864                              <1> 				 ; but 'runq_event' queue is set
  6865                              <1> 				 ; only by the kernel's timer
  6866                              <1> 				 ; event function (timer interrupt). 
  6867 0000F227 E889FFFFFF          <1> 	call	putlu
  6868 0000F22C E99BE0FFFF          <1> 	jmp	sysret
  6869                              <1> 
  6870                              <1> cpass: ; / get next character from user area of core and put it in AL (r1)
  6871                              <1> 	; 02/05/2016 - TRDOS 386 (TRDOS v2.0)
  6872                              <1> 	; 19/05/2015 - 18/10/2015 (Retro UNIX 386 v1)
  6873                              <1> 	; 14/08/2013 - 20/09/2013 (Retro UNIX 8086 v1)
  6874                              <1> 	; INPUTS -> 
  6875                              <1> 	;     [u.base] = virtual address in user area
  6876                              <1> 	;     [u.count] = byte count (max.)
  6877                              <1> 	;     [u.pcount] = byte count in page (0 = reset)		
  6878                              <1> 	; OUTPUTS -> 
  6879                              <1> 	;     AL = the character which is pointed by [u.base]
  6880                              <1> 	;     zf = 1 -> transfer count has been completed	
  6881                              <1>         ;
  6882                              <1> 	; ((Modified registers:  EAX, EDX, ECX))
  6883                              <1> 	;
  6884 0000F231 833D[88030300]00    <1> 	cmp 	dword [u.count], 0  ; have all the characters been transferred
  6885                              <1> 			    	    ; i.e., u.count, # of chars. left
  6886 0000F238 763F                <1> 	jna	short cpass_3	    ; to be transferred = 0?) yes, branch
  6887 0000F23A FF0D[88030300]      <1> 	dec	dword [u.count]	    ; no, decrement u.count
  6888                              <1>         ; 19/05/2015 
  6889                              <1> 	;(Retro UNIX 386 v1 - translation from user's virtual address
  6890                              <1> 	;		      to physical address
  6891 0000F240 66833D[C4030300]00  <1> 	cmp	word [u.pcount], 0 ; byte count in page = 0 (initial value)
  6892                              <1> 			     ; 1-4095 --> use previous physical base address
  6893                              <1> 			     ; in [u.pbase]
  6894 0000F248 770E                <1> 	ja	short cpass_1
  6895 0000F24A 833D[BC030300]00    <1> 	cmp     dword [u.ppgdir], 0 ; is the caller os kernel
  6896 0000F251 7427                <1>         je      short cpass_k       ; (sysexec, '/etc/init') ?  (MainProg)
  6897 0000F253 E858FDFFFF          <1> 	call	trans_addr_r
  6898                              <1> cpass_1:
  6899 0000F258 66FF0D[C4030300]    <1> 	dec	word [u.pcount]
  6900                              <1> cpass_2: 
  6901 0000F25F 8B15[C0030300]      <1> 	mov	edx, [u.pbase]
  6902 0000F265 8A02                <1> 	mov	al, [edx]	; take the character pointed to 
  6903                              <1> 				; by u.base and put it in r1
  6904 0000F267 FF05[8C030300]      <1> 	inc	dword [u.nread] ; increment no. of bytes transferred
  6905 0000F26D FF05[84030300]      <1> 	inc	dword [u.base]  ; increment the buffer address to point to the
  6906                              <1> 			        ; next byte
  6907 0000F273 FF05[C0030300]      <1> 	inc	dword [u.pbase]
  6908                              <1> cpass_3:
  6909 0000F279 C3                  <1> 	retn
  6910                              <1> cpass_k:
  6911                              <1> 	; 02/07/2015
  6912                              <1> 	; The caller is os kernel 
  6913                              <1> 	; (get sysexec arguments from kernel's memory space)
  6914 0000F27A 8B1D[84030300]      <1> 	mov	ebx, [u.base]
  6915 0000F280 66C705[C4030300]00- <1>         mov     word [u.pcount], PAGE_SIZE ; 4096
  6915 0000F288 10                  <1>
  6916 0000F289 891D[C0030300]      <1> 	mov	[u.pbase], ebx
  6917 0000F28F EBCE                <1> 	jmp	short cpass_2
  6918                              <1> 
  6919                              <1> transfer_to_user_buffer: ; fast transfer
  6920                              <1> 	; 27/05/2016
  6921                              <1> 	; 16/05/2016 - TRDOS 386 (TRDOS v2.0)
  6922                              <1> 	;
  6923                              <1> 	; INPUT ->
  6924                              <1> 	;	ESI = source address in system space
  6925                              <1> 	;	EDI = user's buffer address
  6926                              <1> 	;	ECX = transfer (byte) count
  6927                              <1> 	;	[u.pgdir] = user's page directory
  6928                              <1> 	; OUTPUT ->
  6929                              <1> 	;	ECX = actual transfer count
  6930                              <1> 	;	cf = 1 -> error
  6931                              <1> 	;	[u.count] = remain byte count
  6932                              <1> 	;
  6933                              <1> 	; Modified registers: eax, ecx
  6934                              <1> 	;
  6935                              <1> 
  6936 0000F291 21C9                <1> 	and	ecx, ecx
  6937 0000F293 743B                <1> 	jz	short ttub_4
  6938                              <1> 
  6939 0000F295 890D[88030300]      <1> 	mov	[u.count], ecx
  6940                              <1> 	
  6941 0000F29B 57                  <1> 	push	edi
  6942 0000F29C 56                  <1> 	push	esi
  6943 0000F29D 53                  <1> 	push	ebx
  6944 0000F29E 52                  <1> 	push	edx
  6945 0000F29F 51                  <1> 	push	ecx
  6946                              <1> 
  6947 0000F2A0 89FB                <1> 	mov	ebx, edi
  6948 0000F2A2 81C300004000        <1> 	add	ebx, CORE ; 27/05/2016
  6949                              <1> ttub_1:
  6950                              <1> 	; ebx = virtual (linear) address
  6951                              <1> 	; [u.pgdir] = user's page directory
  6952 0000F2A8 E8136AFFFF          <1>        	call	get_physical_addr_x ; get physical address
  6953 0000F2AD 7222                <1> 	jc	short ttub_5
  6954                              <1> 	; eax = physical address 
  6955                              <1> 	; ecx = remain byte count in page (1-4096)
  6956 0000F2AF 89C7                <1> 	mov	edi, eax
  6957 0000F2B1 A1[88030300]        <1> 	mov	eax, [u.count]
  6958 0000F2B6 39C1                <1> 	cmp	ecx, eax
  6959 0000F2B8 7602                <1> 	jna	short ttub_2
  6960 0000F2BA 89C1                <1> 	mov	ecx, eax
  6961                              <1> ttub_2:	
  6962 0000F2BC 29C8                <1> 	sub	eax, ecx
  6963 0000F2BE 01CB                <1> 	add	ebx, ecx
  6964 0000F2C0 F3A4                <1> 	rep	movsb
  6965 0000F2C2 A3[88030300]        <1> 	mov	[u.count], eax
  6966 0000F2C7 09C0                <1> 	or	eax, eax
  6967 0000F2C9 75DD                <1> 	jnz	short ttub_1
  6968                              <1> ttub_retn:
  6969                              <1> tfub_retn:
  6970 0000F2CB 59                  <1> 	pop	ecx ; transfer count = actual transfer count
  6971                              <1> ttub_3:
  6972 0000F2CC 5A                  <1> 	pop	edx
  6973 0000F2CD 5B                  <1> 	pop	ebx
  6974 0000F2CE 5E                  <1> 	pop	esi
  6975 0000F2CF 5F                  <1> 	pop	edi
  6976                              <1> ttub_4:
  6977 0000F2D0 C3                  <1> 	retn
  6978                              <1> ttub_5:
  6979 0000F2D1 59                  <1> 	pop	ecx
  6980 0000F2D2 2B0D[88030300]      <1> 	sub	ecx, [u.count] ; actual transfer count
  6981 0000F2D8 F9                  <1> 	stc
  6982 0000F2D9 EBF1                <1> 	jmp	short ttub_3
  6983                              <1> 
  6984                              <1> transfer_from_user_buffer: ; fast transfer
  6985                              <1> 	; 27/05/2016
  6986                              <1> 	; 16/05/2016 - TRDOS 386 (TRDOS v2.0)
  6987                              <1> 	;
  6988                              <1> 	; INPUT ->
  6989                              <1> 	;	ESI = user's buffer address
  6990                              <1> 	;	EDI = destination address in system space
  6991                              <1> 	;	ECX = transfer (byte) count
  6992                              <1> 	;	[u.pgdir] = user's page directory
  6993                              <1> 	; OUTPUT ->
  6994                              <1> 	;	ecx = actual transfer count
  6995                              <1> 	;	cf = 1 -> error
  6996                              <1> 	;	[u.count] = remain byte count
  6997                              <1> 	;
  6998                              <1> 	; Modified registers: eax, ecx
  6999                              <1> 	;
  7000                              <1> 
  7001 0000F2DB 21C9                <1> 	and	ecx, ecx
  7002                              <1> 	;jz	short tfub_4
  7003 0000F2DD 74F1                <1> 	jz	short ttub_4
  7004                              <1> 
  7005 0000F2DF 890D[88030300]      <1> 	mov	[u.count], ecx
  7006                              <1> 	
  7007 0000F2E5 57                  <1> 	push	edi
  7008 0000F2E6 56                  <1> 	push	esi
  7009 0000F2E7 53                  <1> 	push	ebx
  7010 0000F2E8 52                  <1> 	push	edx
  7011 0000F2E9 51                  <1> 	push	ecx
  7012                              <1> 
  7013 0000F2EA 89F3                <1> 	mov	ebx, esi
  7014 0000F2EC 81C300004000        <1> 	add	ebx, CORE ; 27/05/2016
  7015                              <1> tfub_1:
  7016                              <1> 	; ebx = virtual (linear) address
  7017                              <1> 	; [u.pgdir] = user's page directory
  7018 0000F2F2 E8C969FFFF          <1>        	call	get_physical_addr_x ; get physical address
  7019                              <1> 	;jc	short tfub_5
  7020 0000F2F7 72D8                <1> 	jc	short ttub_5
  7021                              <1> 	; eax = physical address 
  7022                              <1> 	; ecx = remain byte count in page (1-4096)
  7023 0000F2F9 89C6                <1> 	mov	esi, eax
  7024 0000F2FB A1[88030300]        <1> 	mov	eax, [u.count]
  7025 0000F300 39C1                <1> 	cmp	ecx, eax
  7026 0000F302 7602                <1> 	jna	short tfub_2
  7027 0000F304 89C1                <1> 	mov	ecx, eax
  7028                              <1> tfub_2:	
  7029 0000F306 29C8                <1> 	sub	eax, ecx
  7030 0000F308 01CB                <1> 	add	ebx, ecx
  7031 0000F30A F3A4                <1> 	rep	movsb
  7032 0000F30C A3[88030300]        <1> 	mov	[u.count], eax
  7033 0000F311 09C0                <1> 	or	eax, eax
  7034 0000F313 75DD                <1> 	jnz	short tfub_1
  7035                              <1> 
  7036 0000F315 EBB4                <1> 	jmp	short tfub_retn
  7037                              <1> 
  7038                              <1> ;tfub_retn:
  7039                              <1> ;	pop	ecx ; transfer count = actual transfer count
  7040                              <1> ;tfub_3:
  7041                              <1> ;	pop	edx
  7042                              <1> ;	pop	ebx
  7043                              <1> ;	pop	esi
  7044                              <1> ;	pop	edi
  7045                              <1> ;tfub_4:
  7046                              <1> ;	retn
  7047                              <1> ;tfub_5:
  7048                              <1> ;	pop	ecx
  7049                              <1> ;	sub	ecx, [u.count] ; actual transfer count
  7050                              <1> ;	stc
  7051                              <1> ;	jmp	short tfub_3
  7052                              <1> 
  7053                              <1> sysfff: ; <Find First File>
  7054                              <1> 	; 17/10/2016
  7055                              <1> 	; 16/10/2016
  7056                              <1> 	; 15/10/2016 TRDOS 386 (TRDOS v2.0) feature only ! 
  7057                              <1> 	;           -derived from TRDOS v1.0, INT_21H.ASM-
  7058                              <1> 	;            ("loc_INT21h_find_first_file")
  7059                              <1> 	; TRDOS 8086 (v1.0)
  7060                              <1>         ; 	07/08/2011 
  7061                              <1>         ;	Find First File
  7062                              <1> 	;	INPUT:
  7063                              <1>         ;	    CX= Attributes
  7064                              <1>         ;	    DS:DX= Pointer to filename
  7065                              <1> 	;	MSDOS OUTPUT:
  7066                              <1> 	;	    DTA: (Default address: PSP offset 80h)
  7067                              <1> 	;	    Offset  Descrription
  7068                              <1> 	;	    0	    Reserved for use find next file
  7069                              <1> 	;	    21	    Attribute of file found
  7070                              <1> 	;	    22	    Time stamp of file
  7071                              <1> 	;	    24	    Date stamp of file
  7072                              <1> 	;	    26	    File size in bytes
  7073                              <1> 	;	    30	    Filename and extension (zero terminated)
  7074                              <1> 	;	If cf = 1:
  7075                              <1> 	;	    Error Codes: (in AX)
  7076                              <1> 	;	    	2 - File not found
  7077                              <1> 	;	       18 - No more files  			
  7078                              <1>         ;
  7079                              <1> 	; TRDOS 386 (v2.0) 
  7080                              <1> 	; 15/10/2016
  7081                              <1> 	;	
  7082                              <1>         ; INPUT ->
  7083                              <1>         ;	   CL = File attributes
  7084                              <1> 	;     	      bit 0 (1) - Read only file (R)
  7085                              <1> 	;             bit 1 (1) - Hidden file (H)
  7086                              <1>         ;             bit 2 (1) - System file (R)
  7087                              <1> 	;             bit 3 (1) - Volume label/name (V)
  7088                              <1>         ;             bit 4 (1) - Subdirectory (D)
  7089                              <1> 	;	      bit 5 (1) - File has been archived (A)
  7090                              <1> 	;	   CH = 0 -> Return basic parameters (24 bytes)
  7091                              <1> 	;	   CH > 0 -> Return FindFile structure/table (128 bytes)
  7092                              <1>         ;          EBX = Pointer to filename (ASCIIZ) -path-
  7093                              <1> 	;	   EDX = File parameters buffer address
  7094                              <1> 	;		(buffer size = 24 bytes if CH input = 0)
  7095                              <1> 	;		(buffer size = 128 bytes if CH input > 0)
  7096                              <1> 	;		 
  7097                              <1> 	; OUTPUT ->
  7098                              <1> 	;	   EAX = 0 if CH input > 0
  7099                              <1> 	;	   EAX = First cluster number of file if CH input = 0	
  7100                              <1> 	;	   EDX = File parameters table/structure address
  7101                              <1> 	;	   Basic Parameters:
  7102                              <1> 	;		Offset  Description
  7103                              <1> 	;		------	---------------
  7104                              <1> 	;		0	File Attributes
  7105                              <1> 	;		1	Ambiguous filename chars are used sign
  7106                              <1> 	;			(0 = filename fits exactly with request)
  7107                              <1> 	;			(>0 = ambiguous filename chars are used)
  7108                              <1> 	;	      	2	Time stamp of file
  7109                              <1> 	;		4	Date stamp of file
  7110                              <1> 	;		6	File size in bytes
  7111                              <1> 	;		10	Short Filename (ASCIIZ, max. 13 bytes)
  7112                              <1> 	;		23	Longname Length (1-255) if existing 
  7113                              <1> 	;  
  7114                              <1> 	;          cf = 1 -> Error code in AL
  7115                              <1> 	;
  7116                              <1> 	; Modified Registers: EAX (at the return of system call)
  7117                              <1> 	;  
  7118                              <1> 	; TR-DOS FindFile (FFF) Structure (128 bytes):
  7119                              <1> 	; 09/10/2011 (DIR.ASM) - 10/02/2016 (trdoskx.s)
  7120                              <1> 	;	
  7121                              <1> 	; Offset	Parameter		Size
  7122                              <1> 	; ------	------------------	-------- 
  7123                              <1> 	; 0		FindFile_Drv		1 byte
  7124                              <1> 	; 1		FindFile_Directory	65 bytes
  7125                              <1> 	; 66		FindFile_Name		13 bytes
  7126                              <1> 	; 79		FindFile_LongNameEntryLength 1 byte
  7127                              <1> 	;Above 80 bytes form
  7128                              <1> 	;TR-DOS Source/Destination File FullName Format/Structure
  7129                              <1> 	; 80		FindFile_AttributesMask 1 word
  7130                              <1> 	; 82		FindFile_DirEntry	32 bytes (*)
  7131                              <1> 	; 114		FindFile_DirFirstCluster 1 double word
  7132                              <1> 	; 118		FindFile_DirCluster	1 double word
  7133                              <1> 	; 122		FindFile_DirEntryNumber 1 word
  7134                              <1> 	; 124		FindFile_MatchCounter	1 word
  7135                              <1> 	; 126		FindFile_Reserved	1 word
  7136                              <1>    	; (*) MS-DOS, FAT 12-16-32 classic directory entry (32 bytes)
  7137                              <1> 
  7138                              <1> 	;mov	[u.namep], ebx
  7139                              <1> 	; 16/10/2016
  7140 0000F317 8915[88700100]      <1> 	mov	[FFF_UBuffer], edx
  7141 0000F31D 66890D[8D700100]    <1> 	mov	[FFF_Attrib], cx ; [FFF_RType] = ch
  7142                              <1> 		    ; Attributes in CL, return data type in CH
  7143 0000F324 89DE                <1> 	mov	esi, ebx
  7144                              <1> 	; file name is forced, change directory as temporary
  7145                              <1> 	;mov	ax, 1
  7146                              <1> 	;mov	[FFF_Valid], ah ; 0 ; reset ; 17/10/2016
  7147                              <1> 	;call	set_working_path 
  7148 0000F326 E8E8130000          <1> 	call	set_working_path_x ; 17/10/2016	
  7149 0000F32B 731D                <1> 	jnc	short sysfff_0
  7150                              <1>  
  7151 0000F32D 21C0                <1> 	and	eax, eax  ; 0 -> Bad Path!  
  7152 0000F32F 7505                <1> 	jnz	short sysfff_err
  7153                              <1> 
  7154                              <1> 	; eax = 0
  7155 0000F331 B80C000000          <1> 	mov	eax, ERR_DIR_NOT_FOUND ; Directory not found !
  7156                              <1> sysfff_err:
  7157 0000F336 A3[64030300]        <1> 	mov	[u.r0], eax
  7158 0000F33B A3[C8030300]        <1> 	mov	[u.error], eax
  7159 0000F340 E8A3140000          <1>         call 	reset_working_path
  7160 0000F345 E962DFFFFF          <1> 	jmp	error
  7161                              <1> 
  7162                              <1> sysfff_0:
  7163                              <1> 	;sub	ah, ah ; ah = 0
  7164 0000F34A 8A0424              <1> 	mov	al, [esp]
  7165 0000F34D 08C0                <1> 	or	al, al
  7166 0000F34F 7412                <1> 	jz	short sysfff_2
  7167 0000F351 B410                <1> 	mov	ah, 10h
  7168 0000F353 A808                <1> 	test	al, 08h
  7169 0000F355 7503                <1> 	jnz	short sysfff_1
  7170 0000F357 80CC08              <1> 	or	ah, 08h
  7171                              <1> sysfff_1:
  7172 0000F35A 2410                <1> 	and	al, 10h ; Directory
  7173 0000F35C 7405                <1> 	jz	short sysfff_2
  7174 0000F35E 80E408              <1> 	and	ah, 08h
  7175 0000F361 30C0                <1> 	xor	al, al ; When a directory is searched,
  7176                              <1> 		       ; filename will be returned even if
  7177                              <1> 		       ; it is not a directory!
  7178                              <1> 		       ; Because: (in order to prevent
  7179                              <1> 		       ; creating a dir with existing file name)
  7180                              <1> 		       ; Dir and file names must not be same!
  7181                              <1> 		       ; (return attribute must be checked)  	  	 	
  7182                              <1> sysfff_2:
  7183                              <1> 	; AX = Attributes mask 
  7184                              <1> 		; AL = AND mask (result must be equal to AL)
  7185                              <1> 		; AH = Negative AND mask (result must be ZERO)			
  7186                              <1>  	; ESI = FindFile_Name address
  7187                              <1> 
  7188 0000F363 E8E99AFFFF          <1> 	call	find_first_file
  7189 0000F368 72CC                <1> 	jc	short sysfff_err ; eax = 2 (File not found !)
  7190                              <1> 
  7191                              <1> 	; ESI = Directory Entry (FindFile_DirEntry) Location
  7192                              <1> 	; EDI = Directory Buffer Directory Entry Location
  7193                              <1> 	; EAX = File Size
  7194                              <1> 	;  BL = Attributes of The File/Directory
  7195                              <1> 	;  BH = Long Name Yes/No Status (>0 is YES)
  7196                              <1> 	;  DX > 0 : Ambiguous filename chars are used
  7197                              <1> 
  7198                              <1> sysfff_3:
  7199                              <1> 	; 16/10/2016
  7200 0000F36A 668B0D[8D700100]    <1> 	mov	cx, [FFF_Attrib]
  7201                              <1> 	; Attribs in CL, return data type in CH
  7202                              <1> 
  7203                              <1> 	;or	cl, cl
  7204                              <1> 	;jz	short sysfff_4 ; 0 = No filter
  7205 0000F371 80F1FF              <1> 	xor	cl, 0FFh
  7206 0000F374 20D9                <1> 	and	cl, bl
  7207 0000F376 7409                <1> 	jz	short sysfff_4
  7208                              <1> 
  7209                              <1> 	;mov	eax, 2 ; 'file not found !' error
  7210                              <1> 	;jmp	short sysfff_err_1
  7211                              <1> 
  7212                              <1> 	; 16/10/2016
  7213 0000F378 E8839BFFFF          <1> 	call	find_next_file
  7214 0000F37D 72B7                <1> 	jc	short sysfff_err ; eax = 12 (no more files !)
  7215 0000F37F EBE9                <1> 	jmp	short sysfff_3
  7216                              <1> 
  7217                              <1> sysfff_4:
  7218 0000F381 20ED                <1> 	and	ch, ch ; [FFF_RType]
  7219 0000F383 7412                <1> 	jz	short sysfff_5
  7220 0000F385 B980000000          <1> 	mov	ecx, 128 ; ; transfer length
  7221 0000F38A 880D[8C700100]      <1> 	mov	[FFF_Valid], cl
  7222                              <1> sysfnf_11:
  7223 0000F390 BE[3E6D0100]        <1> 	mov	esi, FindFile_Drv
  7224 0000F395 EB44                <1> 	jmp	short sysfff_6	
  7225                              <1> sysfff_5:
  7226                              <1> 	;mov	esi, FindFile_DirEntry
  7227 0000F397 B918000000          <1> 	mov	ecx, 24  ; transfer length
  7228 0000F39C 880D[8C700100]      <1> 	mov	[FFF_Valid], cl
  7229                              <1> sysfnf_12:
  7230 0000F3A2 BF[48750100]        <1> 	mov	edi, DTA ; FFF data transfer address
  7231                              <1> 	;mov	al, [esi+DirEntry_Attr] ; 11
  7232 0000F3A7 88D8                <1> 	mov	al, bl ; File/Dir Attributes
  7233 0000F3A9 887F17              <1> 	mov	[edi+23], bh ; Longname length (0= none)
  7234 0000F3AC AA                  <1> 	stosb
  7235 0000F3AD 88D0                <1> 	mov	al, dl ; DL is for '?'
  7236 0000F3AF 00F0                <1> 	add	al, dh ; DH is for '*'
  7237                              <1> 	; AL > 0 if ambiguous file name wildcards are used
  7238 0000F3B1 AA                  <1> 	stosb
  7239 0000F3B2 8B4616              <1> 	mov	eax, [esi+DirEntry_WrtTime] ; 22	
  7240 0000F3B5 AB                  <1>         stosd	; DirEntry_WrtTime & DirEntry_WrtDate
  7241 0000F3B6 8B461C              <1>         mov	eax, [esi+DirEntry_FileSize] ; 28
  7242 0000F3B9 AB                  <1>         stosd
  7243 0000F3BA 668B4614            <1> 	mov	ax, [esi+DirEntry_FstClusHI] ; 20
  7244 0000F3BE 66C1E010            <1> 	shl	ax, 16
  7245 0000F3C2 668B461A            <1> 	mov	ax, [esi+DirEntry_FstClusLO] ; 26 
  7246 0000F3C6 A3[64030300]        <1> 	mov	[u.r0], eax ; First Cluster
  7247                              <1> 
  7248                              <1>         ;mov	esi, FindFile_DirEntry
  7249 0000F3CB E855140000          <1> 	call	get_file_name
  7250                              <1> 
  7251 0000F3D0 8A0D[8C700100]      <1> 	mov	cl, [FFF_Valid]
  7252 0000F3D6 BE[48750100]        <1>        	mov	esi, DTA ; FFF data transfer address
  7253                              <1> sysfff_6:
  7254 0000F3DB 8B3D[88700100]      <1> 	mov	edi, [FFF_UBuffer] ; user's buffer address (edx)
  7255 0000F3E1 E8ABFEFFFF          <1> 	call	transfer_to_user_buffer
  7256                              <1> 
  7257 0000F3E6 890D[64030300]      <1> 	mov	[u.r0], ecx ; actual transfer count
  7258 0000F3EC E8F7130000          <1>         call 	reset_working_path
  7259 0000F3F1 E9D6DEFFFF          <1> 	jmp	sysret
  7260                              <1> 
  7261                              <1> sysfnf: ; <Find Next File>
  7262                              <1> 	; 16/10/2016 TRDOS 386 (TRDOS v2.0) feature only ! 
  7263                              <1> 	;           -derived from TRDOS v1.0, INT_21H.ASM-
  7264                              <1> 	;            ("loc_INT21h_find_next_file")
  7265                              <1> 	; TRDOS 8086 (v1.0)
  7266                              <1>         ; 	07/08/2011 
  7267                              <1>         ;	Find First File
  7268                              <1> 	;	INPUT:
  7269                              <1>         ;	    none
  7270                              <1> 	;	MSDOS OUTPUT:
  7271                              <1> 	;	    DTA: (Default address: PSP offset 80h)
  7272                              <1> 	;	    Offset  Descrription
  7273                              <1> 	;	    0	    Reserved for use find next file
  7274                              <1> 	;	    21	    Attribute of file found
  7275                              <1> 	;	    22	    Time stamp of file
  7276                              <1> 	;	    24	    Date stamp of file
  7277                              <1> 	;	    26	    File size in bytes
  7278                              <1> 	;	    30	    Filename and extension (zero terminated)
  7279                              <1> 	;	If cf = 1:
  7280                              <1> 	;	    Error Codes: (in AX)
  7281                              <1> 	;	       18 - No more files  			
  7282                              <1>         ;
  7283                              <1> 	; TRDOS 386 (v2.0) 
  7284                              <1> 	; 16/10/2016
  7285                              <1> 	;	
  7286                              <1>         ; INPUT ->
  7287                              <1>        	; 	   none
  7288                              <1> 	; OUTPUT ->
  7289                              <1> 	;	   EAX = 0 if CH input of 'Find First File' > 0
  7290                              <1> 	;	   EAX = First cluster number of file
  7291                              <1> 	;		 if CH input of 'Find First File' = 0	
  7292                              <1> 	;	   EDX = File parameters table/structure address
  7293                              <1> 	;
  7294                              <1> 	;          cf = 1 -> Error code in AL
  7295                              <1> 	;
  7296                              <1>  	; Modified Registers: EAX (at the return of system call)	
  7297                              <1> 
  7298                              <1> 	;	
  7299                              <1> 	; Note: If byte [FFF_Valid] = 0
  7300                              <1> 	;	'sysfnf' will return with 'no more files' error.
  7301                              <1> 	;	If byte [FFF_Valid] = 24
  7302                              <1> 	;	'sysfnf' will return with 32 bytes basic parameters
  7303                              <1> 	;	at the address which is in EDX.
  7304                              <1> 	;	If byte [FFF_Valid] = 128
  7305                              <1> 	;	'sysfnf' will return with 128 bytes Find File 
  7306                              <1> 	;	Structure/Table at the address which is in EDX.
  7307                              <1> 	
  7308 0000F3F6 803D[8C700100]00    <1> 	cmp	byte [FFF_Valid], 0
  7309 0000F3FD 7714                <1> 	ja	short stsfnf_0
  7310                              <1>  	; 'no more files !' error 
  7311 0000F3FF B80C000000          <1> 	mov	eax, ERR_NO_MORE_FILES ; 12
  7312 0000F404 A3[64030300]        <1> 	mov	[u.r0], eax
  7313 0000F409 A3[C8030300]        <1> 	mov	[u.error], eax
  7314 0000F40E E999DEFFFF          <1> 	jmp	error
  7315                              <1> stsfnf_0:
  7316                              <1> 	;cmp	byte [FFF_Valid], 128
  7317                              <1> 	;je	short stsfnf_1
  7318                              <1> 	;cmp	byte [FFF_Valid], 24
  7319                              <1> 	;je	short stsfnf_1
  7320                              <1> 	;mov	[FFF_Valid], 24 ; Default
  7321                              <1> stsfnf_1:
  7322 0000F413 0FB61D[9E640100]    <1> 	movzx	ebx, byte [Current_Drv]
  7323 0000F41A 66891D[92700100]    <1> 	mov	[SWP_DRV], bx
  7324 0000F421 8A15[3E6D0100]      <1> 	mov	dl, [FindFile_Drv]
  7325 0000F427 38DA                <1> 	cmp	dl, bl
  7326 0000F429 750B                <1> 	jne	short stsfnf_2
  7327 0000F42B 86FB                <1> 	xchg	bh, bl
  7328 0000F42D BE00010900          <1> 	mov	esi, Logical_DOSDisks
  7329 0000F432 01DE                <1> 	add	esi, ebx
  7330 0000F434 EB0D                <1> 	jmp	short sysfnf_3
  7331                              <1> 
  7332                              <1> stsfnf_2:
  7333 0000F436 FE05[93700100]      <1> 	inc	byte [SWP_DRV_chg]
  7334                              <1> 
  7335 0000F43C E86D86FFFF          <1> 	call	change_current_drive
  7336 0000F441 7245                <1> 	jc	short sysfnf_err_1 ; read error ! 
  7337                              <1> 				   ; (do not stop, because
  7338                              <1> 				   ; we don't have a
  7339                              <1> 				   ; 'no more files'
  7340                              <1> 				   ; -file not found- error,	
  7341                              <1> 				   ; next sysfnf system call
  7342                              <1> 				   ; may solve the problem,
  7343                              <1> 				   ; after re-placing the disk)				
  7344                              <1> sysfnf_3:
  7345 0000F443 A1[B46D0100]        <1> 	mov	eax, [FindFile_DirCluster]
  7346 0000F448 21C0                <1> 	and	eax, eax
  7347 0000F44A 7550                <1> 	jnz	short sysfnf_6
  7348                              <1>         
  7349 0000F44C 803D[9D640100]02    <1> 	cmp	byte [Current_FATType], 2
  7350 0000F453 772C                <1> 	ja	short sysfnf_err_0 ; invalid, we neeed to stop !?
  7351 0000F455 803D[9D640100]01    <1> 	cmp	byte [Current_FATType], 1
  7352 0000F45C 7223                <1> 	jb	short sysfnf_err_0 ; invalid, we neeed to stop !?
  7353                              <1> 
  7354 0000F45E 3805[C46B0100]      <1> 	cmp	byte [DirBuff_ValidData], al ; 0
  7355 0000F464 7608                <1> 	jna	short sysfnf_4 
  7356                              <1> 
  7357 0000F466 3B05[C96B0100]      <1> 	cmp	eax, [DirBuff_Cluster] ; 0 ?
  7358 0000F46C 745E                <1> 	je	short sysfnf_9
  7359                              <1> 
  7360                              <1> 	;cmp	byte [Current_Dir_Level], 0
  7361                              <1>         ;ja	short sysfnf_4  
  7362                              <1>         ;jna	short sysfnf_9 
  7363                              <1> 
  7364                              <1> sysfnf_4:
  7365 0000F46E FE05[93700100]      <1> 	inc	byte [SWP_DRV_chg]
  7366 0000F474 E818D4FFFF          <1> 	call 	load_FAT_root_directory
  7367 0000F479 7351                <1> 	jnc	short sysfnf_9
  7368                              <1> 	; eax = error code (17, 'drv not ready or read error')
  7369 0000F47B EB0B                <1> 	jmp	short sysfnf_err_1 ; read error ! (no FNF stop)
  7370                              <1> 				   ; (if you want, try again, 
  7371                              <1> 				   ;  after re-placing the disk)
  7372                              <1> sysfnf_5:	
  7373 0000F47D 3C0C                <1> 	cmp	al, 12 ; 'no more files' error
  7374 0000F47F 7507                <1> 	jne	short sysfnf_err_1 ; (no FNF stop -sysfnf will try
  7375                              <1> 				   ;  to read the directory again,
  7376                              <1> 				   ;  if the user calls sysfnf
  7377                              <1> 				   ;  just after this error return-)
  7378                              <1> 	; (FNF stop -sysfnf will not try
  7379                              <1> 	;  to read the directory again-)	
  7380                              <1> 
  7381                              <1> sysfnf_err_0:
  7382 0000F481 C605[8C700100]00    <1> 	mov	byte [FFF_Valid], 0 ; FNF stop sign
  7383                              <1> sysfnf_err_1:
  7384 0000F488 A3[64030300]        <1> 	mov	[u.r0], eax
  7385 0000F48D A3[C8030300]        <1> 	mov	[u.error], eax
  7386 0000F492 E851130000          <1> 	call	reset_working_path
  7387 0000F497 E910DEFFFF          <1> 	jmp	error
  7388                              <1> 	  
  7389                              <1> sysfnf_6:
  7390 0000F49C 803D[C46B0100]00    <1> 	cmp	byte [DirBuff_ValidData], 0
  7391 0000F4A3 7608                <1> 	jna	short sysfnf_7
  7392                              <1> 
  7393 0000F4A5 3B05[C96B0100]      <1> 	cmp	eax, [DirBuff_Cluster]
  7394 0000F4AB 741F                <1> 	je	short sysfnf_9
  7395                              <1> 
  7396                              <1> sysfnf_7:
  7397 0000F4AD FE05[93700100]      <1> 	inc	byte [SWP_DRV_chg]
  7398 0000F4B3 803D[9D640100]01    <1> 	cmp	byte [Current_FATType], 1
  7399 0000F4BA 7309                <1> 	jnb	short sysfnf_8
  7400                              <1> 
  7401                              <1> 	; Singlix (TRFS) File System 
  7402                              <1> 	; (access via compatibility buffer)
  7403 0000F4BC E898D4FFFF          <1> 	call	load_FS_sub_directory
  7404 0000F4C1 7309                <1> 	jnc	short sysfnf_9
  7405                              <1> 
  7406 0000F4C3 EBC3                <1> 	jmp	short sysfnf_err_1 ; read error (no FNF stop)
  7407                              <1> 
  7408                              <1> sysfnf_8:
  7409 0000F4C5 E852D4FFFF          <1> 	call	load_FAT_sub_directory	 
  7410 0000F4CA 72BC                <1> 	jc	short sysfnf_err_1 ; read error (no FNF stop)
  7411                              <1> 
  7412                              <1> sysfnf_9:
  7413 0000F4CC E82F9AFFFF          <1> 	call	find_next_file
  7414 0000F4D1 72AA                <1> 	jc	short sysfnf_5
  7415                              <1> 
  7416 0000F4D3 A0[8D700100]        <1> 	mov	al, [FFF_Attrib]
  7417                              <1> 	;or	al, al
  7418                              <1> 	;jz	short sysfnf_10 ; 0 = No filter
  7419 0000F4D8 34FF                <1> 	xor	al, 0FFh
  7420 0000F4DA 20D8                <1> 	and	al, bl
  7421 0000F4DC 75EE                <1> 	jnz	short sysfnf_9 ; search for next file until
  7422                              <1> 			       ; an error return from
  7423                              <1> 			       ; find_next_file procedure	
  7424                              <1> sysfnf_10:
  7425 0000F4DE 0FB60D[8C700100]    <1>         movzx	ecx, byte [FFF_Valid]
  7426 0000F4E5 80F980              <1> 	cmp	cl, 128 ; complete FindFile structure/table 
  7427 0000F4E8 0F84A2FEFFFF        <1> 	je	sysfnf_11
  7428                              <1> 	;cmp	cl, 24  ; basic parameters
  7429                              <1> 	;je	sysfnf_12       
  7430 0000F4EE E9AFFEFFFF          <1> 	jmp	sysfnf_12
  7431                              <1> 
  7432                              <1> writei:
  7433                              <1> 	; 26/10/2016
  7434                              <1> 	; 25/10/2016
  7435                              <1> 	; 23/10/2016
  7436                              <1> 	; 22/10/2016
  7437                              <1> 	; 19/10/2016 - TRDOS 386 (TRDOS v2.0)
  7438                              <1> 	; 19/05/2015 - 20/05/2015 (Retro UNIX 386 v1)
  7439                              <1> 	; 12/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  7440                              <1> 	;
  7441                              <1> 	; Write data to file with first cluster number in EAX
  7442                              <1> 	; 
  7443                              <1> 	; INPUTS ->
  7444                              <1> 	;    EAX - First cluster number of the file
  7445                              <1> 	;    EBX - File number (Open file index number)
  7446                              <1> 	;    u.count - byte count to be written
  7447                              <1> 	;    u.base - points to user buffer
  7448                              <1> 	;    u.fofp - points to dword with current file offset
  7449                              <1> 	;    i.size - file size
  7450                              <1> 	;    cdev - logical dos drive number of the file
  7451                              <1> 	; OUTPUTS ->
  7452                              <1> 	;    u.count - cleared
  7453                              <1> 	;    u.nread - accumulates total bytes passed back
  7454                              <1> 	;    i.size - new file size (if file byte offset overs file size)
  7455                              <1> 	;    u.fofp - points to u.off (with new offset value)	
  7456                              <1> 	;
  7457                              <1> 	; (Retro UNIX Prototype : 11/11/2012 - 18/11/2012, UNIXCOPY.ASM)
  7458                              <1> 	; ((Modified registers: eax, edx, ebx, ecx, esi, edi, ebp)) 	
  7459                              <1> 
  7460 0000F4F3 31C9                <1> 	xor	ecx, ecx
  7461 0000F4F5 890D[8C030300]      <1> 	mov 	[u.nread], ecx  ; 0
  7462 0000F4FB 66890D[C4030300]    <1> 	mov	[u.pcount], cx ; 19/05/2015
  7463 0000F502 390D[88030300]      <1> 	cmp 	[u.count], ecx
  7464 0000F508 7701                <1> 	ja 	short writei_1 
  7465 0000F50A C3                  <1> 	retn
  7466                              <1> writei_1:
  7467 0000F50B 881D[4C700100]      <1> 	mov	[writei.ofn], bl ; Open file number
  7468 0000F511 880D[87700100]      <1> 	mov	[setfmod], cl ; 0 ; reset 'update lm date&time' sign
  7469                              <1> dskw_0: 
  7470                              <1> 	; 26/10/2016
  7471                              <1> 	; 22/10/2016, 23/10/2016, 25/10/2016
  7472                              <1> 	; 19/10/2016 - TRDOS 386 (TRDOS v2.0)
  7473                              <1> 	; 31/05/2015 - 25/07/2015 (Retro UNIX 386 v1)
  7474                              <1> 	; 26/04/2013 - 20/09/2013 (Retro UNIX 8086 v1)
  7475                              <1> 	;
  7476                              <1> 	; 01/08/2013 (mkdir_w check)
  7477 0000F517 E8D7000000          <1>  	call	mget_w
  7478                              <1> 	; eax = sector/block number
  7479                              <1> 
  7480 0000F51C 8B1D[74030300]      <1> 	mov     ebx, [u.fofp]
  7481 0000F522 8B13                <1> 	mov	edx, [ebx]
  7482 0000F524 81E2FF010000        <1> 	and	edx, 1FFh  ; / test the lower 9 bits of the file offset
  7483 0000F52A 750C                <1> 	jnz	short dskw_1 ; / if its non-zero, branch
  7484                              <1> 			     ; if zero, file offset = 0,
  7485                              <1> 		       	     ; / 512, 1024,...(i.e., start of new block)
  7486 0000F52C 813D[88030300]0002- <1> 	cmp	dword [u.count], 512
  7486 0000F534 0000                <1>
  7487                              <1> 				; / if zero, is there enough data to fill
  7488                              <1> 				; / an entire block? (i.e., no. of
  7489 0000F536 7337                <1> 	jnb	short dskw_2 ; / bytes to be written greater than 512.? 
  7490                              <1> 			     ; / Yes, branch. Don't have to read block
  7491                              <1> dskw_1: ; in as no past info. is to be saved 
  7492                              <1> 	; (the entire block will be overwritten).
  7493                              <1> 	; 23/10/2016
  7494                              <1> 
  7495 0000F538 BB[94070300]        <1> 	mov	ebx, writei_buffer
  7496                              <1> 	; esi = logical dos drive description table address
  7497                              <1> 	; eax = sector number
  7498                              <1> 	; ebx = buffer address (in kernel's memory space)
  7499                              <1> 	; ecx = sector count
  7500 0000F53D B901000000          <1> 	mov	ecx, 1
  7501 0000F542 E8A90D0000          <1> 	call	disk_read
  7502                              <1> 	;call	dskrd 	; / no, must retain old info.. 
  7503                              <1> 		       	; / Hence, read block 'r1' into an I/O buffer
  7504 0000F547 7326                <1> 	jnc	short dskw_2
  7505                              <1> 
  7506                              <1> 	; disk read error
  7507 0000F549 B811000000          <1> 	mov	eax, 17 ; drive not ready or READ ERROR !
  7508                              <1> dskw_err: ; jump from disk write error
  7509 0000F54E A3[64030300]        <1> 	mov	[u.r0], eax
  7510 0000F553 A3[C8030300]        <1> 	mov	[u.error], eax
  7511                              <1> 
  7512 0000F558 803D[87700100]00    <1> 	cmp	byte [setfmod], 0
  7513 0000F55F 0F8647DDFFFF        <1> 	jna	error
  7514                              <1> 
  7515 0000F565 E8AF030000          <1> 	call	update_file_lmdt ; update last modif. date&time of the file
  7516                              <1> 	;mov	byte [setfmod], 0	
  7517                              <1> 
  7518 0000F56A E93DDDFFFF          <1> 	jmp	error
  7519                              <1> 
  7520                              <1> dskw_2: ; 3:
  7521                              <1> 	; 23/10/2016
  7522 0000F56F C605[28700100]01    <1> 	mov	byte [writei.valid], 1 ; writei buffer contains valid data
  7523 0000F576 56                  <1> 	push	esi ; logical dos drive description table address
  7524                              <1> 	; EAX (r1) = block/sector number
  7525                              <1> 	;call	wslot
  7526                              <1> 		; jsr r0,wslot / set write and inhibit bits in I/O queue, 
  7527                              <1> 			   ; / proc. status=0, r5 points to 1st word of data
  7528 0000F577 803D[C6030300]00    <1> 	cmp	byte [u.kcall], 0
  7529 0000F57E 770F                <1> 	ja	short dskw_4 ; zf=0 -> the caller is 'mkdir'
  7530                              <1> 	;
  7531 0000F580 66833D[C4030300]00  <1> 	cmp	word [u.pcount], 0
  7532 0000F588 7705                <1> 	ja	short dskw_4
  7533                              <1> dskw_3:
  7534                              <1> 	; [u.base] = virtual address to transfer (as source address)
  7535 0000F58A E821FAFFFF          <1> 	call	trans_addr_r ; translate virtual address to physical (r)
  7536                              <1> dskw_4:
  7537 0000F58F BB[94070300]        <1> 	mov	ebx, writei_buffer
  7538                              <1> 	; EBX (r5) = system (I/O) buffer address
  7539 0000F594 E883FAFFFF          <1> 	call	sioreg
  7540                              <1> 	; ESI = file (user data) offset
  7541                              <1> 	; EDI = sector (I/O) buffer offset
  7542                              <1> 	; ECX = byte count
  7543                              <1> 	;
  7544 0000F599 F3A4                <1>   	rep	movsb
  7545                              <1> 	; 25/07/2015
  7546                              <1> 	; eax = remain bytes in buffer
  7547                              <1>         ;       (check if remain bytes in the buffer > [u.pcount])
  7548 0000F59B 09C0                <1> 	or	eax, eax
  7549 0000F59D 75EB                <1> 	jnz	short dskw_3 ; (page end before system buffer end!)	
  7550                              <1> 
  7551                              <1> 	; 23/10/2016
  7552 0000F59F B101                <1> 	mov	cl, 1
  7553 0000F5A1 5E                  <1> 	pop	esi
  7554 0000F5A2 A1[2C700100]        <1> 	mov	eax, [writei.sector]
  7555                              <1> 	; esi = logical dos drive description table address
  7556                              <1> 	; eax = sector number
  7557                              <1> 	; ebx = writei buffer address
  7558                              <1> 	; ecx = sector count
  7559 0000F5A7 E8350D0000          <1> 	call	disk_write ; / yes, write the block
  7560 0000F5AC 7307                <1> 	jnc	short dskw_5
  7561                              <1> 
  7562 0000F5AE B812000000          <1> 	mov	eax, 18 ; drive not ready or WRITE ERROR !
  7563 0000F5B3 EB99                <1> 	jmp	short dskw_err
  7564                              <1> 
  7565                              <1> dskw_5:
  7566                              <1> 	; 26/10/2016
  7567 0000F5B5 0FB61D[4C700100]    <1> 	movzx	ebx, byte [writei.ofn] ; open file number
  7568 0000F5BC C0E302              <1> 	shl	bl, 2 ; *4
  7569 0000F5BF 8B83[1C740100]      <1> 	mov	eax, [ebx+OF_POINTER]
  7570 0000F5C5 3B83[44740100]      <1> 	cmp	eax, [ebx+OF_SIZE]
  7571 0000F5CB 7606                <1> 	jna	short dskw_6
  7572 0000F5CD 8983[44740100]      <1> 	mov	[ebx+OF_SIZE], eax
  7573                              <1> dskw_6:
  7574                              <1> 	;shr	bl, 2
  7575 0000F5D3 833D[88030300]00    <1>         cmp     dword [u.count], 0 ; / any more data to write?
  7576 0000F5DA 760A                <1> 	jna	short dskw_7
  7577 0000F5DC A1[3C700100]        <1> 	mov	eax, [writei.fclust]
  7578 0000F5E1 E931FFFFFF          <1> 	jmp	dskw_0 ; / yes, branch
  7579                              <1> dskw_7:
  7580                              <1>  	; update last modif. date&time of the file
  7581                              <1> 	; (also updates file size as OF_SIZE)
  7582 0000F5E6 E82E030000          <1> 	call	update_file_lmdt
  7583                              <1> 	;mov	byte [setfmod], 0	
  7584                              <1> 
  7585                              <1> 	; 03/08/2013
  7586 0000F5EB C605[C6030300]00    <1> 	mov	byte [u.kcall], 0
  7587                              <1> 	; 23/10/2016
  7588                              <1> 	;mov	eax, [writei.fclust]
  7589 0000F5F2 C3                  <1> 	retn
  7590                              <1> 
  7591                              <1> mget_w:
  7592                              <1> 	; 02/11/2016
  7593                              <1> 	; 01/11/2016
  7594                              <1> 	; 23/10/2016, 31/10/2016
  7595                              <1> 	; 22/10/2016 - TRDOS 386 (TRDOS v2.0)
  7596                              <1> 	; 03/06/2015 (Retro UNIX 386 v1, 'mget', u.5s)
  7597                              <1> 	; 22/03/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  7598                              <1> 	;
  7599                              <1> 	; Get existing or (allocate) a new disk block for file
  7600                              <1> 	; 
  7601                              <1> 	; INPUTS ->
  7602                              <1> 	;    [u.fofp] = file offset pointer
  7603                              <1> 	;    [i.size] = file size
  7604                              <1> 	;    [u.count] = byte count	 
  7605                              <1> 	;    EAX = First cluster
  7606                              <1> 	;    [cdev] = Logical dos drive number 	  
  7607                              <1> 	;    [writei.ofn] = File Number
  7608                              <1> 	;		   (Open file index, 0 based)
  7609                              <1> 	;    ([u.off] = file offset)
  7610                              <1> 	; OUTPUTS ->
  7611                              <1> 	;    EAX = logical sector number
  7612                              <1> 	;    ESI = Logical Dos Drive Description Table address
  7613                              <1> 	;
  7614                              <1> 	; Modified registers: EDX, EBX, ECX, ESI, EDI, EBP  
  7615                              <1> 
  7616 0000F5F3 8B35[74030300]      <1>         mov     esi, [u.fofp]
  7617 0000F5F9 8B2E                <1> 	mov	ebp, [esi] ; u.off (or EBX*4+OF_POINTER)
  7618                              <1> 
  7619 0000F5FB 29C9                <1> 	sub	ecx, ecx
  7620 0000F5FD 8A2D[46030300]      <1> 	mov	ch, [cdev]
  7621                              <1> 
  7622 0000F603 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  7623 0000F608 01CE                <1> 	add	esi, ecx
  7624                              <1> 
  7625                              <1> 	; 31/10/2016
  7626 0000F60A 89C3                <1> 	mov	ebx, eax ; First Cluster or FDT address
  7627                              <1> 
  7628 0000F60C 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  7629 0000F610 0F86DD010000        <1> 	jna	mget_w_14 ; Singlix FS
  7630                              <1> 
  7631 0000F616 0FB74611            <1> 	movzx	eax, word [esi+LD_BPB+BytesPerSec]
  7632 0000F61A 0FB65613            <1> 	movzx	edx, byte [esi+LD_BPB+SecPerClust]
  7633 0000F61E 8815[2A700100]      <1> 	mov	[writei.spc], dl  ; sectors per cluster
  7634 0000F624 F7E2                <1> 	mul	edx
  7635                              <1> 	; edx = 0
  7636                              <1> 	; eax = bytes per cluster (<= 65536)
  7637                              <1> 
  7638                              <1> 	; 02/11/2016
  7639 0000F626 89C1                <1> 	mov	ecx, eax
  7640 0000F628 48                  <1> 	dec	eax
  7641 0000F629 66A3[30700100]      <1> 	mov	[writei.bpc], ax	
  7642                              <1> 	
  7643 0000F62F 89E8                <1> 	mov	eax, ebp
  7644 0000F631 0305[88030300]      <1> 	add	eax, [u.count] ; next file position
  7645 0000F637 3B05[55040300]      <1> 	cmp	eax, [i.size] ; <= file size ?
  7646 0000F63D 0F86FC000000        <1> 	jna	mget_w_4 ; no
  7647                              <1> 
  7648 0000F643 F7F1                <1> 	div	ecx
  7649 0000F645 A3[38700100]        <1> 	mov	[writei.c_index], eax ; cluster index
  7650                              <1> 	; edx = byte offset in cluster (<= 65535)
  7651                              <1> 	;mov	[writei.offset], dx
  7652                              <1> 	;shr	dx, 9 ; / 512
  7653                              <1> 	;mov	[writei.s_index], dl ; sector index in cluster (0 to spc -1)
  7654                              <1> 
  7655 0000F64A 29D2                <1> 	sub	edx, edx ; 01/11/2016
  7656 0000F64C 8915[2C700100]      <1> 	mov 	[writei.sector], edx ; 0
  7657 0000F652 668915[32700100]    <1> 	mov	[writei.offset], dx  ; byte offset in cluster 
  7658 0000F659 8815[2B700100]      <1> 	mov	[writei.s_index], dl ; sector index in cluster (0 to spc -1)
  7659                              <1> 
  7660 0000F65F 89D8                <1> 	mov	eax, ebx ; First Cluster
  7661                              <1> 
  7662                              <1> 	; is this the 1st mget_w or a next mget_w call ? (by 'writei')
  7663 0000F661 3815[28700100]      <1> 	cmp	byte [writei.valid], dl ; 0 
  7664 0000F667 7624                <1> 	jna	short mget_w_0
  7665                              <1> 
  7666 0000F669 8815[28700100]      <1> 	mov 	byte [writei.valid], dl ; 0 ; reset ('writei' will set it) 
  7667                              <1> 
  7668 0000F66F 3B05[3C700100]      <1> 	cmp	eax, [writei.fclust]
  7669 0000F675 7516                <1> 	jne	short mget_w_0
  7670                              <1> 
  7671 0000F677 8A0D[46030300]      <1> 	mov	cl, [cdev]
  7672 0000F67D 3A0D[29700100]      <1> 	cmp	cl, [writei.drv]
  7673 0000F683 7508                <1> 	jne	short mget_w_0
  7674                              <1>  	; [writei.l_clust] & [writei.l_index] are valid, 
  7675                              <1> 	;  we don't need to get last cluster & last cluster index
  7676 0000F685 8B0D[48700100]      <1> 	mov	ecx, [writei.l_index]
  7677 0000F68B EB64                <1> 	jmp	short mget_w_2
  7678                              <1> mget_w_0:
  7679 0000F68D A3[3C700100]        <1> 	mov	[writei.fclust], eax ; first cluster
  7680                              <1> 	; edx = 0
  7681 0000F692 A3[34700100]        <1> 	mov	[writei.cluster], eax ; first cluster ; 01/11/2016
  7682 0000F697 8915[40700100]      <1> 	mov 	[writei.fs_index], edx ; 0 ; curret cluster index
  7683                              <1> 
  7684                              <1> 	; FAT file system (FAT12, FAT16, FAT32)
  7685 0000F69D E88FD8FFFF          <1> 	call	get_last_cluster
  7686 0000F6A2 0F822B010000        <1> 	jc	mget_w_err ; eax = error code
  7687                              <1> 		
  7688 0000F6A8 A3[44700100]        <1> 	mov	[writei.lclust], eax ; last cluster
  7689                              <1> 
  7690 0000F6AD 8B0D[686E0100]      <1> 	mov	ecx, [glc_index] ; last cluster index
  7691 0000F6B3 890D[48700100]      <1> 	mov	[writei.l_index], ecx
  7692                              <1> 
  7693 0000F6B9 A0[4C700100]        <1> 	mov	al, [writei.ofn]
  7694 0000F6BE FEC0                <1> 	inc	al
  7695 0000F6C0 A2[87700100]        <1> 	mov	[setfmod], al ; update lm date&time sign
  7696                              <1> 
  7697                              <1> mget_w_1:
  7698 0000F6C5 3B0D[38700100]      <1> 	cmp	ecx, [writei.c_index]  ; last cluster index
  7699 0000F6CB 7324                <1> 	jnb	short mget_w_2 ; 01/11/2016
  7700                              <1> 
  7701 0000F6CD A1[44700100]        <1> 	mov	eax, [writei.lclust]
  7702                              <1> 	; EAX = Last cluster
  7703 0000F6D2 E868D9FFFF          <1> 	call	add_new_cluster
  7704 0000F6D7 0F82F6000000        <1> 	jc	mget_w_err ; eax = error code
  7705                              <1> 	; edx = 0
  7706 0000F6DD A3[44700100]        <1> 	mov	[writei.lclust], eax ; (new) last cluster
  7707 0000F6E2 8B0D[48700100]      <1> 	mov	ecx, [writei.l_index]
  7708 0000F6E8 41                  <1> 	inc	ecx ; add 1 to last cluster index
  7709 0000F6E9 890D[48700100]      <1> 	mov	[writei.l_index], ecx ; current last cluster index
  7710                              <1> 
  7711 0000F6EF EBD4                <1> 	jmp	short mget_w_1
  7712                              <1> 
  7713                              <1> mget_w_2:
  7714 0000F6F1 89E9                <1> 	mov	ecx, ebp
  7715 0000F6F3 030D[88030300]      <1> 	add	ecx, [u.count]
  7716 0000F6F9 890D[55040300]      <1> 	mov	[i.size], ecx ; save new file size
  7717                              <1> 	;sub	edx, edx ; 0
  7718                              <1> 
  7719 0000F6FF A0[46030300]        <1> 	mov	al, [cdev]
  7720 0000F704 A2[29700100]        <1> 	mov	[writei.drv], al ; physical drive number
  7721                              <1> 	; edx = 0
  7722 0000F709 89E8                <1> 	mov	eax, ebp ; file offset
  7723 0000F70B 0FB70D[30700100]    <1> 	movzx	ecx, word [writei.bpc] ; bytes per cluster - 1
  7724 0000F712 41                  <1> 	inc	ecx ; bytes per cluster
  7725 0000F713 F7F1                <1> 	div	ecx
  7726                              <1> 	; edx = byte offset in cluster (<= 65535)
  7727                              <1> 	; eax = cluster index
  7728 0000F715 A3[38700100]        <1> 	mov	[writei.c_index], eax
  7729 0000F71A 668915[32700100]    <1> 	mov	[writei.offset], dx
  7730 0000F721 66C1EA09            <1> 	shr	dx, 9 ; / 512
  7731 0000F725 8815[2B700100]      <1> 	mov	[writei.s_index], dl ; sector index in cluster (0 to spc -1)
  7732                              <1> 
  7733                              <1> mget_w_3:
  7734 0000F72B 3B05[48700100]      <1> 	cmp	eax, [writei.l_index] ; last cluster index
  7735 0000F731 752A                <1> 	jne	short mget_w_5
  7736                              <1> 
  7737 0000F733 A3[40700100]        <1> 	mov	[writei.fs_index], eax ; cluster index (for next check)
  7738 0000F738 A1[44700100]        <1> 	mov	eax, [writei.lclust] ; last cluster
  7739 0000F73D EB60                <1> 	jmp	short mget_w_10
  7740                              <1> 
  7741                              <1> mget_w_4: ; 02/11/2016
  7742                              <1> 	; eax = next file position
  7743 0000F73F 2B05[88030300]      <1> 	sub	eax, [u.count] ; current file position
  7744                              <1> 	; edx = 0
  7745                              <1> 	; ecx = bytes per cluster
  7746 0000F745 F7F1                <1> 	div	ecx
  7747 0000F747 A3[38700100]        <1> 	mov	[writei.c_index], eax ; cluster index
  7748 0000F74C 668915[32700100]    <1> 	mov	[writei.offset], dx
  7749 0000F753 66C1EA09            <1> 	shr	dx, 9 ; / 512
  7750 0000F757 8815[2B700100]      <1> 	mov	[writei.s_index], dl ; sector index in cluster (0 to spc -1)
  7751                              <1> 
  7752                              <1> mget_w_5:
  7753 0000F75D 21C0                <1> 	and	eax, eax ; 0 = First Cluster's index number
  7754 0000F75F 750C                <1> 	jnz	short mget_w_6
  7755                              <1> 
  7756 0000F761 A3[40700100]        <1> 	mov	[writei.fs_index], eax ; cluster index (for next check)
  7757 0000F766 A1[3C700100]        <1> 	mov	eax, [writei.fclust] ; first cluster
  7758 0000F76B EB32                <1> 	jmp	short mget_w_10
  7759                              <1> 
  7760                              <1> mget_w_6:
  7761 0000F76D 3B05[40700100]      <1> 	cmp	eax, [writei.fs_index] ; current cluster index (>0)
  7762 0000F773 7507                <1> 	jne	short mget_w_7
  7763 0000F775 A1[34700100]        <1> 	mov	eax, [writei.cluster] ; current cluster 
  7764 0000F77A EB3A                <1> 	jmp	short mget_w_11
  7765                              <1> 
  7766                              <1> mget_w_7:
  7767 0000F77C 89C1                <1> 	mov	ecx, eax
  7768 0000F77E 2B0D[40700100]      <1> 	sub	ecx, [writei.fs_index]
  7769 0000F784 730D                <1> 	jnc	short mget_w_8
  7770                              <1> 	; get cluster by index from the first cluster
  7771 0000F786 A1[3C700100]        <1> 	mov	eax, [writei.fclust]
  7772 0000F78B 8B0D[38700100]      <1> 	mov	ecx, [writei.c_index]
  7773 0000F791 EB05                <1> 	jmp	short mget_w_9
  7774                              <1> 
  7775                              <1> mget_w_8:
  7776 0000F793 A1[34700100]        <1> 	mov	eax, [writei.cluster] ; beginning cluster
  7777                              <1> 	; ecx = cluster sequence number after the beginning cluster
  7778                              <1> 	; sub	edx, edx ; 0
  7779                              <1> 
  7780                              <1> mget_w_9:
  7781                              <1> 	; EAX = Beginning cluster
  7782                              <1> 	; EDX = Sector index in disk/file section
  7783                              <1> 	;	(Only for SINGLIX file system!)
  7784                              <1> 	; ECX = Cluster sequence number after the beginning cluster
  7785                              <1> 	; ESI = Logical DOS Drive Description Table address
  7786 0000F798 E8A8D9FFFF          <1> 	call	get_cluster_by_index
  7787 0000F79D 7234                <1> 	jc	short mget_w_err ; error code in EAX
  7788                              <1> 	; EAX = Cluster number		
  7789                              <1> mget_w_10:
  7790 0000F79F A3[34700100]        <1> 	mov	[writei.cluster], eax ; FDT number for Singlix File System
  7791                              <1> 
  7792 0000F7A4 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  7793 0000F7A8 7638                <1> 	jna	short mget_w_13
  7794                              <1> 	; 01/11/2016
  7795 0000F7AA 8B15[38700100]      <1> 	mov	edx, [writei.c_index]
  7796 0000F7B0 8915[40700100]      <1> 	mov	[writei.fs_index], edx
  7797                              <1> mget_w_11:
  7798 0000F7B6 83E802              <1> 	sub	eax, 2
  7799 0000F7B9 0FB615[2A700100]    <1> 	movzx	edx, byte [writei.spc]
  7800 0000F7C0 F7E2                <1> 	mul	edx
  7801                              <1> 
  7802 0000F7C2 034668              <1> 	add	eax, [esi+LD_DATABegin]
  7803 0000F7C5 8A15[2B700100]      <1> 	mov	dl, [writei.s_index]
  7804 0000F7CB 01D0                <1> 	add	eax, edx
  7805                              <1> mget_w_12:
  7806 0000F7CD A3[2C700100]        <1> 	mov	[writei.sector], eax
  7807                              <1> 	;; buffer validation must be done in writei
  7808                              <1> 	;;mov	byte [writei.valid], 1 
  7809 0000F7D2 C3                  <1> 	retn
  7810                              <1> 
  7811                              <1> mget_w_err:
  7812 0000F7D3 A3[C8030300]        <1> 	mov	[u.error], eax
  7813 0000F7D8 A3[64030300]        <1> 	mov	[u.r0], eax
  7814 0000F7DD E9CADAFFFF          <1> 	jmp	error
  7815                              <1> 
  7816                              <1> mget_w_13:
  7817                              <1> 	; EAX = FDT number (Current Section)
  7818                              <1> 	; EDX = Sector index from the first section (0,1,2,3,4...)
  7819 0000F7E2 2B15[40700100]      <1> 	sub	edx, [writei.fs_index]	
  7820                              <1> 	; EDX = Sector index from current section
  7821 0000F7E8 8915[40700100]      <1> 	mov	[writei.fs_index], edx
  7822 0000F7EE 40                  <1> 	inc	eax ; the first data sector in FS disk section	
  7823 0000F7EF 01D0                <1> 	add	eax, edx
  7824 0000F7F1 EBDA                <1> 	jmp	short mget_w_12
  7825                              <1> 
  7826                              <1> mget_w_14:
  7827 0000F7F3 8A4E12              <1> 	mov	cl, [esi+LD_FS_BytesPerSec+1]
  7828 0000F7F6 D0E9                <1> 	shr	cl, 1 ;  ; 1 for 512 bytes, 4 for 2048 bytes
  7829 0000F7F8 880D[2A700100]      <1> 	mov	[writei.spc], cl  ; sectors per cluster
  7830                              <1> 	; NOTE: writei bytes per sector value is always 512 ! 
  7831 0000F7FE 66C705[30700100]00- <1> 	mov	word [writei.bpc], 512
  7831 0000F806 02                  <1>
  7832                              <1> 
  7833 0000F807 89E9                <1> 	mov	ecx, ebp
  7834 0000F809 030D[88030300]      <1> 	add	ecx, [u.count] ; next file position
  7835 0000F80F 3B0D[55040300]      <1> 	cmp	ecx, [i.size] ; <= file size ?
  7836 0000F815 0F86C8000000        <1> 	jna	mget_w_19 ; no
  7837                              <1> 
  7838 0000F81B 29D2                <1> 	sub	edx, edx ; 0
  7839 0000F81D 8915[2C700100]      <1> 	mov 	[writei.sector], edx ; 0
  7840 0000F823 668915[32700100]    <1> 	mov	[writei.offset], dx  ; byte offset in cluster 
  7841 0000F82A 8815[2B700100]      <1> 	mov	[writei.s_index], dl ; sector index in cluster (0 to spc -1)
  7842                              <1> 
  7843 0000F830 C1E909              <1> 	shr	ecx, 9 ; 1 cluster = 512 bytes
  7844 0000F833 890D[38700100]      <1> 	mov	[writei.c_index], ecx ; section/cluster index
  7845                              <1> 	
  7846 0000F839 89D8                <1> 	mov	eax, ebx ; FDT number (First FDT address)
  7847                              <1> 
  7848                              <1> 	; is this the 1st mget_w or a next mget_w call ? (by 'writei')
  7849 0000F83B 3815[28700100]      <1> 	cmp	byte [writei.valid], dl ; 0 
  7850 0000F841 7624                <1> 	jna	short mget_w_15
  7851                              <1> 
  7852 0000F843 8815[28700100]      <1> 	mov 	byte [writei.valid], dl ; 0 ; reset ('writei' will set it) 
  7853                              <1> 
  7854 0000F849 3B05[3C700100]      <1> 	cmp	eax, [writei.fclust]
  7855 0000F84F 7516                <1> 	jne	short mget_w_15
  7856                              <1> 
  7857 0000F851 8A0D[46030300]      <1> 	mov	cl, [cdev]
  7858 0000F857 3A0D[29700100]      <1> 	cmp	cl, [writei.drv]
  7859 0000F85D 7508                <1> 	jne	short mget_w_15
  7860                              <1>  	; [writei.l_clust] & [writei.l_index] are valid, 
  7861                              <1> 	;  we don't need to get last cluster & last cluster index
  7862 0000F85F 8B0D[48700100]      <1> 	mov	ecx, [writei.l_index]
  7863 0000F865 EB49                <1> 	jmp	short mget_w_17
  7864                              <1> mget_w_15:
  7865 0000F867 A3[3C700100]        <1> 	mov	[writei.fclust], eax ; first section (FDT number)
  7866                              <1> 	; edx = 0
  7867 0000F86C 8915[34700100]      <1> 	mov	[writei.cluster], edx ; 0 ; current section
  7868 0000F872 8915[40700100]      <1> 	mov 	[writei.fs_index], edx ; 0 ; curret section index
  7869                              <1> 
  7870                              <1> 	; eax = FDT number (section 0 header address)
  7871 0000F878 E8F2D8FFFF          <1> 	call	get_last_section
  7872 0000F87D 0F8250FFFFFF        <1> 	jc	mget_w_err ; eax = error code
  7873                              <1> 
  7874 0000F883 8915[40700100]      <1> 	mov 	[writei.fs_index], edx ; sector index in last section
  7875                              <1> 		
  7876 0000F889 A3[44700100]        <1> 	mov	[writei.lclust], eax ; last section address
  7877                              <1> 
  7878 0000F88E 8B0D[686E0100]      <1> 	mov	ecx, [glc_index] ; last section index
  7879 0000F894 890D[48700100]      <1> 	mov	[writei.l_index], ecx
  7880                              <1> 
  7881 0000F89A A0[4C700100]        <1> 	mov	al, [writei.ofn]
  7882 0000F89F FEC0                <1> 	inc	al
  7883 0000F8A1 A2[87700100]        <1> 	mov	[setfmod], al ; update lm date&time sign
  7884                              <1> 
  7885                              <1> mget_w_16:
  7886                              <1> 	; edx = (existing) last section (sector) index
  7887 0000F8A6 8B0D[38700100]      <1> 	mov	ecx, [writei.c_index] ; final section (sector) index
  7888 0000F8AC 29D1                <1> 	sub	ecx, edx
  7889 0000F8AE 7633                <1> 	jna	short mget_w_19
  7890                              <1> 	 ; ecx = sector count
  7891                              <1> mget_w_17:
  7892 0000F8B0 A1[44700100]        <1> 	mov	eax, [writei.lclust]
  7893                              <1> 	; ESI = Logical dos drv desc. table address
  7894                              <1>         ; EAX = Last section
  7895                              <1>         ; (ECX = 0 for directory) 
  7896                              <1>         ; ECX = sector count (except FDT)
  7897 0000F8B5 E878CEFFFF          <1> 	call	add_new_fs_section
  7898 0000F8BA 7312                <1> 	jnc	short mget_w_18
  7899                              <1> 
  7900                              <1> 	; If error number = 27h (insufficient disk space)
  7901                              <1> 	; it is needed to check free consequent sectors
  7902                              <1> 	; (1 data sector at least and +1 section header sector) 
  7903                              <1> 
  7904 0000F8BC 83F827              <1> 	cmp	eax, 27h
  7905 0000F8BF 0F850EFFFFFF        <1> 	jne	mget_w_err ; eax = error code
  7906                              <1> 
  7907                              <1> 	; ecx = count of free consequent sectors
  7908                              <1> 	; ecx must be > 1 (1 data + 1 header sector)
  7909 0000F8C5 49                  <1> 	dec	ecx
  7910 0000F8C6 0F8407FFFFFF        <1> 	jz	mget_w_err
  7911 0000F8CC EBE2                <1> 	jmp	short mget_w_17
  7912                              <1> 
  7913                              <1> mget_w_18:
  7914 0000F8CE A3[44700100]        <1> 	mov	[writei.lclust], eax ; (new) last section
  7915                              <1> 	; ecx = sector count (except section header)
  7916 0000F8D3 8B15[48700100]      <1> 	mov	edx, [writei.l_index]
  7917 0000F8D9 01CA                <1> 	add	edx, ecx ; add sector count to index
  7918 0000F8DB 8915[48700100]      <1> 	mov	[writei.l_index], edx
  7919 0000F8E1 EBC3                <1> 	jmp	short mget_w_16
  7920                              <1> 
  7921                              <1> mget_w_19:
  7922 0000F8E3 89E9                <1> 	mov	ecx, ebp
  7923 0000F8E5 030D[88030300]      <1> 	add	ecx, [u.count]
  7924 0000F8EB 890D[55040300]      <1> 	mov	[i.size], ecx ; save new file size
  7925                              <1> 	;sub	edx, edx ; 0
  7926                              <1> 
  7927 0000F8F1 A0[46030300]        <1> 	mov	al, [cdev]
  7928 0000F8F6 A2[29700100]        <1> 	mov	[writei.drv], al ; physical drive number
  7929                              <1> 	; edx = 0
  7930 0000F8FB 89E8                <1> 	mov	eax, ebp ; file offset
  7931 0000F8FD 89C2                <1> 	mov	edx, eax
  7932                              <1> 	; 1 cluster = 512 bytes (for Singlix FS)
  7933 0000F8FF C1E809              <1> 	shr	eax, 9  ; / 512
  7934 0000F902 81E2FF010000        <1> 	and	edx, 1FFh
  7935                              <1> 	; edx = byte offset in cluster/sector (<= 511)
  7936                              <1> 	; eax = section (sector/cluster) index
  7937 0000F908 A3[38700100]        <1> 	mov	[writei.c_index], eax
  7938 0000F90D 668915[32700100]    <1> 	mov	[writei.offset], dx
  7939                              <1> 	;mov	byte [writei.s_index], 0 ; sector index in cluster
  7940 0000F914 E912FEFFFF          <1> 	jmp	mget_w_3
  7941                              <1> 
  7942                              <1> update_file_lmdt: ; & update file size
  7943                              <1> 	; 26/10/2016
  7944                              <1> 	; 24/10/2016
  7945                              <1> 	; 23/10/2016
  7946                              <1> 	; 22/10/2016 - TRDOS 386 (TRDOS v2.0)
  7947                              <1> 	;
  7948                              <1> 	; Update last modification date&time of file
  7949                              <1> 	; (call from syswrite -> writei)
  7950                              <1> 	; ((also updates file size)) // 26/10/2016
  7951                              <1> 	; 
  7952                              <1> 	; INPUT:
  7953                              <1> 	;      byte [setfmod] = open file number
  7954                              <1> 	; OUTPUT:
  7955                              <1> 	;      cf = 0 -> success !
  7956                              <1> 	;      cf = 1 -> lmdt update has been failed! 	 
  7957                              <1> 	;
  7958                              <1> 	; Modified registers: eax, ebx, ecx, edx, esi, edi       				
  7959                              <1> 	;
  7960                              <1> 
  7961                              <1> 	;cmp	byte [setfmod], 0
  7962                              <1> 	;jna	short uflmdt_2 ; nothing to do
  7963                              <1> 
  7964 0000F919 31C0                <1> 	xor	eax, eax
  7965                              <1> 
  7966 0000F91B 0FB61D[87700100]    <1> 	movzx	ebx, byte [setfmod]
  7967 0000F922 FECB                <1> 	dec	bl ; open file index number (0 based)
  7968                              <1> 
  7969 0000F924 8AA3[F4730100]      <1> 	mov	ah, [ebx+OF_DRIVE]
  7970 0000F92A BE00010900          <1> 	mov	esi, Logical_DOSDisks
  7971 0000F92F 01C6                <1> 	add	esi, eax
  7972 0000F931 C0E302              <1> 	shl	bl, 2 ; *4	
  7973 0000F934 8B8B[CC730100]      <1> 	mov	ecx, [ebx+OF_FCLUSTER] ; first cluster
  7974 0000F93A 8B93[94740100]      <1> 	mov	edx, [ebx+OF_DIRCLUSTER] ; dir cluster
  7975                              <1> 
  7976 0000F940 D0EB                <1> 	shr	bl, 1 ; /2
  7977 0000F942 0FB7BB[34750100]    <1> 	movzx	edi, word [ebx+OF_DIRENTRY]
  7978                              <1> 	
  7979 0000F949 803D[C46B0100]01    <1> 	cmp	byte [DirBuff_ValidData], 1
  7980 0000F950 726E                <1> 	jb	short uflmdt_4
  7981                              <1> 
  7982 0000F952 A0[C26B0100]        <1> 	mov	al, [DirBuff_DRV]
  7983 0000F957 2C41                <1> 	sub	al, 'A'	
  7984 0000F959 38E0                <1> 	cmp	al, ah
  7985 0000F95B 7563                <1> 	jne	short uflmdt_4 ; different drive
  7986 0000F95D 8A4603              <1> 	mov	al, [esi+LD_FATType] 
  7987 0000F960 3A05[C36B0100]      <1> 	cmp	al, [DirBuff_FATType]
  7988 0000F966 755B                <1> 	jne	short uflmdt_5 ; different FS type
  7989 0000F968 3B15[C96B0100]      <1> 	cmp	edx, [DirBuff_Cluster]
  7990 0000F96E 7553                <1> 	jne	short uflmdt_5 ; different cluster
  7991                              <1> 
  7992                              <1> uflmdt_1:
  7993                              <1> 	; Directory buffer is ready here!
  7994                              <1> 	; OF_FCLUSTER must be compared/verified
  7995 0000F970 BE00000800          <1> 	mov	esi, Directory_Buffer
  7996 0000F975 66C1E705            <1> 	shl	di, 5 ; dir entry index * 32
  7997 0000F979 01FE                <1> 	add	esi, edi ; offset
  7998                              <1> 	;
  7999 0000F97B F6460B18            <1> 	test	byte [esi+DirEntry_Attr], 18h ; Vol & Dir
  8000 0000F97F 750F                <1> 	jnz	short uflmdt_2 ; not a valid file !
  8001 0000F981 668B4614            <1> 	mov	ax, [esi+DirEntry_FstClusHI]
  8002 0000F985 C1E010              <1> 	shl	eax, 16
  8003 0000F988 668B461A            <1> 	mov	ax, [esi+DirEntry_FstClusLO]
  8004 0000F98C 39C8                <1> 	cmp	eax, ecx ; same first cluster ?
  8005 0000F98E 7407                <1> 	je	short uflmdt_3 ; yes, it is OK !!!	
  8006                              <1> 
  8007                              <1> uflmdt_2:	
  8008                              <1> 	; save directory buffer if has modified/changed sign
  8009                              <1> 	; (It is good to save dir buff even if the searched
  8010                              <1> 	; directory entry is not found !?)
  8011 0000F990 E8F1BAFFFF          <1> 	call	save_directory_buffer
  8012 0000F995 F9                  <1> 	stc	; update failed
  8013 0000F996 C3                  <1> 	retn
  8014                              <1> 	
  8015                              <1> uflmdt_3:
  8016                              <1> 	; Update directory entry
  8017                              <1> 	; 26/10/2016
  8018 0000F997 D0E3                <1> 	shl	bl, 1 ; *2 
  8019 0000F999 8B83[44740100]      <1> 	mov	eax, [ebx+OF_SIZE] ; file size
  8020 0000F99F 89461C              <1> 	mov	[esi+DirEntry_FileSize], eax
  8021                              <1> 	;
  8022 0000F9A2 E841BAFFFF          <1> 	call	convert_current_date_time
  8023                              <1> 	; OUTPUT -> DX = Date in dos dir entry format
  8024                              <1>         ; 	    AX = Time in dos dir entry format	
  8025 0000F9A7 66894616            <1> 	mov	[esi+DirEntry_WrtTime], ax
  8026 0000F9AB 66895618            <1> 	mov	[esi+DirEntry_WrtDate], dx	
  8027 0000F9AF 66895612            <1> 	mov	[esi+DirEntry_LastAccDate], dx
  8028 0000F9B3 C605[C46B0100]02    <1> 	mov	byte [DirBuff_ValidData], 2
  8029 0000F9BA E8C7BAFFFF          <1> 	call	save_directory_buffer
  8030 0000F9BF C3                  <1> 	retn
  8031                              <1> 
  8032                              <1> uflmdt_4:
  8033                              <1> 	; Directory buffer sector read&write
  8034                              <1> 	; 23/10/2016
  8035                              <1> 	;
  8036 0000F9C0 8A4603              <1> 	mov	al, [esi+LD_FATType]
  8037                              <1> uflmdt_5:
  8038 0000F9C3 BB[9C090300]        <1> 	mov	ebx, rw_buffer ; Common r/w sector buffer addr
  8039                              <1> 		
  8040 0000F9C8 20C0                <1> 	and	al, al ; 0 = Singlix FS
  8041 0000F9CA 0F8492000000        <1> 	jz	uflmdt_11
  8042                              <1> 
  8043 0000F9D0 21D2                <1> 	and	edx, edx
  8044 0000F9D2 7521                <1> 	jnz	short uflmdt_9
  8045                              <1> 
  8046 0000F9D4 3C02                <1> 	cmp	al, 2  ; 3 = FAT32
  8047 0000F9D6 771A                <1> 	ja	short uflmdt_8
  8048                              <1> 
  8049 0000F9D8 89F8                <1> 	mov	eax, edi ; directory entry index number
  8050 0000F9DA 66C1E804            <1> 	shr	ax, 4 ; 16 entries per sector	 
  8051 0000F9DE 034664              <1> 	add	eax, [esi+LD_ROOTBegin]
  8052                              <1> 	; eax = root directory sector
  8053                              <1> uflmdt_6:
  8054 0000F9E1 50                  <1> 	push	eax ; * ; disk sector address
  8055 0000F9E2 51                  <1> 	push	ecx ; first cluster	
  8056 0000F9E3 B901000000          <1> 	mov	ecx, 1
  8057                              <1> 	; ecx = sector count
  8058 0000F9E8 E803090000          <1> 	call	disk_read
  8059 0000F9ED 59                  <1> 	pop	ecx
  8060 0000F9EE 731A                <1> 	jnc	short uflmdt_10
  8061 0000F9F0 58                  <1> 	pop	eax ; *
  8062                              <1> uflmdt_7:
  8063 0000F9F1 C3                  <1> 	retn	
  8064                              <1> 
  8065                              <1> uflmdt_8:
  8066 0000F9F2 8B5632              <1> 	mov	edx, [esi+LD_BPB+FAT32_RootFClust]
  8067                              <1> uflmdt_9:
  8068 0000F9F5 83FA02              <1> 	cmp	edx, 2
  8069 0000F9F8 72F7                <1> 	jb	short uflmdt_7 ; invalid, nothing to do
  8070                              <1> 
  8071 0000F9FA 83EA02              <1> 	sub	edx, 2
  8072 0000F9FD 89D0                <1> 	mov	eax, edx
  8073 0000F9FF 0FB65613            <1> 	movzx	edx, byte [esi+LD_BPB+SecPerClust]
  8074 0000FA03 F7E2                <1> 	mul	edx
  8075 0000FA05 034668              <1> 	add	eax, [esi+LD_DATABegin]
  8076                              <1> 	; eax = sub directory (data) sector 
  8077 0000FA08 EBD7                <1> 	jmp	short uflmdt_6
  8078                              <1> 
  8079                              <1> uflmdt_10:
  8080                              <1> 	; Directory sector buffer is ready here!
  8081                              <1> 	; OF_FCLUSTER must be compared/verified
  8082                              <1> 	; edi = dir entry index number (<= 2047)
  8083 0000FA0A 6683E70F            <1> 	and	di, 0Fh ; 16 entries per sector
  8084 0000FA0E 66C1E705            <1> 	shl	di, 5 ; dir entry index * 32
  8085 0000FA12 81C7[9C090300]      <1> 	add	edi, rw_buffer
  8086                              <1> 	;
  8087 0000FA18 F6470B18            <1> 	test	byte [edi+DirEntry_Attr], 18h ; Vol & Dir
  8088 0000FA1C 0F856EFFFFFF        <1> 	jnz	uflmdt_2 ; not a valid file !
  8089 0000FA22 668B5714            <1> 	mov	dx, [edi+DirEntry_FstClusHI]
  8090 0000FA26 C1E210              <1> 	shl	edx, 16
  8091 0000FA29 668B571A            <1> 	mov	dx, [edi+DirEntry_FstClusLO]
  8092 0000FA2D 39CA                <1> 	cmp	edx, ecx ; same first cluster ?
  8093 0000FA2F 0F855BFFFFFF        <1> 	jne	uflmdt_2 ; no !?
  8094                              <1> 
  8095                              <1> 	; Update directory entry
  8096 0000FA35 E8AEB9FFFF          <1> 	call	convert_current_date_time
  8097                              <1> 	; OUTPUT -> DX = Date in dos dir entry format
  8098                              <1>         ; 	    AX = Time in dos dir entry format	
  8099 0000FA3A 66894716            <1> 	mov	[edi+DirEntry_WrtTime], ax
  8100 0000FA3E 66895718            <1> 	mov	[edi+DirEntry_WrtDate], dx	
  8101 0000FA42 66895712            <1> 	mov	[edi+DirEntry_LastAccDate], dx
  8102                              <1> 	
  8103 0000FA46 58                  <1> 	pop	eax ; *
  8104                              <1> 
  8105 0000FA47 BB[9C090300]        <1> 	mov	ebx, rw_buffer ; Common r/w sector buffer addr
  8106 0000FA4C B901000000          <1> 	mov	ecx, 1
  8107                              <1> 	; esi = logical dos description table address
  8108                              <1> 	; eax = disk sector number/address (LBA)
  8109                              <1> 	; ecx = sector count
  8110                              <1> 	; ebx = buffer address
  8111 0000FA51 E88B080000          <1> 	call	disk_write
  8112 0000FA56 0F8234FFFFFF        <1> 	jc	uflmdt_2
  8113                              <1> 	
  8114                              <1> 	; save directory buffer if has modified/changed sign
  8115 0000FA5C E825BAFFFF          <1> 	call	save_directory_buffer
  8116 0000FA61 C3                  <1> 	retn
  8117                              <1> 
  8118                              <1> uflmdt_11:
  8119                              <1> 	; 24/10/2016
  8120                              <1> 	; Update last modification date & time of a file
  8121                              <1> 	; on a disk with Singlix File System.
  8122                              <1> 	;
  8123                              <1> 	; (Method: Read the FDT -File Description Table-
  8124                              <1> 	; sector of the file and update the lmdt data fields,
  8125                              <1> 	; then write FDT sector to the disk.
  8126                              <1> 	; /// It is easy but there is compatibility buffer
  8127                              <1> 	; method also for changing directory entry data and
  8128                              <1> 	; also there are some programming issues for Singlix
  8129                              <1> 	; file system (TRFS), which are not completed yet!)
  8130                              <1> 	;
  8131                              <1> 	; Not ready yet ! (24/10/2016)
  8132                              <1> 	; /// Temporary code for error return ! ///
  8133 0000FA62 31C0                <1> 	xor	eax, eax
  8134 0000FA64 F9                  <1> 	stc
  8135 0000FA65 C3                  <1> 	retn
  8136                              <1> 
  8137                              <1> sysalloc:
  8138                              <1> 	; 14/10/2017
  8139                              <1> 	; 20/08/2017, 01/09/2017
  8140                              <1> 	; 20/02/2017, 04/03/2017, 15/05/2017
  8141                              <1> 	; 19/02/2017 - TRDOS 386 (TRDOS v2.0)
  8142                              <1> 	; (TRDOS 386 feature only!)
  8143                              <1> 	;
  8144                              <1> 	; Allocate Contiguous Memory Block/Pages (for user)
  8145                              <1> 	; (System call for DMA Buffer allocation etc.)	
  8146                              <1> 	;
  8147                              <1> 	; INPUT ->
  8148                              <1> 	;	EBX = Virtual address (for user)
  8149                              <1> 	;	     (Physical memory block/aperture
  8150                              <1> 	;	     will be mapped to this virtual address) 
  8151                              <1> 	;	ECX = Byte Count
  8152                              <1> 	;	     (will be rounded up to page border)
  8153                              <1> 	;	If ECX = 0
  8154                              <1> 	;	    System call will return with an error (cf=1)
  8155                              <1> 	;	    but ECX will contain maximum size of
  8156                              <1> 	;	    available memory aperture and physical
  8157                              <1> 	;	    (beginning) address of that aperture
  8158                              <1> 	;	    (which have maximum size) will be in EAX.
  8159                              <1> 	;	EDX = Upper limit of the requested physical memory
  8160                              <1> 	;	      block/pages.
  8161                              <1> 	;	     (The last byte address of the memory aperture 
  8162                              <1> 	;	      must not be equal to or above this limit.)	
  8163                              <1> 	;	If EDX = 0
  8164                              <1> 	; 	   there is NOLIMIT !
  8165                              <1> 	;	If EDX = 0FFFFFFFFh (-1) 
  8166                              <1> 	;	   ESI = Lower Limit !
  8167                              <1> 	;		(Beginning of the block must not be 'less'
  8168                              <1> 	;		than this.) (Must be equal to or above...)
  8169                              <1> 	;	   EDI = Upper Limit !
  8170                              <1> 	;		(End of the block must be !less! than this)
  8171                              <1> 	;		(The last byte addr of the memory aperture 
  8172                              <1> 	;		must not be equal to or above this limit.)
  8173                              <1> 	;
  8174                              <1> 	; OUTPUT ->
  8175                              <1> 	;	If CF = 0
  8176                              <1> 	;	EAX = Physical address of the allocated memory block
  8177                              <1> 	;	ECX = Allocated bytes (as rounded up to page borders)
  8178                              <1> 	;	EBX = Virtual address (as rounded up)
  8179                              <1> 	;	IF CF = 1
  8180                              <1> 	;	    Requested (size of) Memory block could not be 
  8181                              <1> 	;	    allocated to the user!	
  8182                              <1> 	;	IF CF = 1 & EAX = 0 (Insufficient memory error!)
  8183                              <1> 	;	   ECX = Total number of free bytes
  8184                              <1> 	;	         (not size of available contiguous bytes!)		 	
  8185                              <1> 	;	If CF = 1 & EAX > 0
  8186                              <1> 	;	   there is not a memory aperture with requested size
  8187                              <1> 	;	   but total free mem is not less than requested size.
  8188                              <1> 	;	   EAX = Physical addr of available memory aperture
  8189                              <1> 	;	   	 with max size 
  8190                              <1> 	;	        (but it doesn't fit to the conditions!) 	
  8191                              <1> 	;	   ECX = Size of available memory aperture in bytes.
  8192                              <1> 	;	If CF = 1 -> EAX = 0FFFFFFFFh	
  8193                              <1> 	;	   Conditions/Parameters are wrong !		 		
  8194                              <1> 	;	   ECX is same with input value.
  8195                              <1> 	;
  8196                              <1> 	; Note:	Previously allocated pages will be deallocated if
  8197                              <1> 	;       new allocation conditions are met.
  8198                              <1> 	;
  8199                              <1> 	; Note: u.break control may be included in future versions	
  8200                              <1> 	;
  8201                              <1> 
  8202 0000FA66 31C0                <1> 	xor	eax, eax ; 0
  8203                              <1> 	; 14/10/2017
  8204 0000FA68 4A                  <1> 	dec	edx ; is there a limit ?
  8205 0000FA69 7810                <1> 	js	short sysalloc_1 ;  0 -> 0FFFFFFFFh -> NO LIMIT
  8206 0000FA6B 42                  <1> 	inc	edx ; > 0
  8207                              <1> 	; Check upper address limit
  8208                              <1> 	;(round up to page borders)
  8209 0000FA6C 81C1FF0F0000        <1> 	add	ecx, PAGE_SIZE-1 ; 4095
  8210 0000FA72 6681E100F0          <1> 	and	cx, ~PAGE_OFF ; not 4095
  8211 0000FA77 39CA                <1> 	cmp	edx, ecx ; upper limit - block size
  8212 0000FA79 7224                <1> 	jb	short sysalloc_err
  8213                              <1> sysalloc_1:
  8214                              <1> 	; EAX = Beginning address (physical)
  8215                              <1> 	; EAX = 0 -> Allocate mem block from the 1st proper aperture	
  8216                              <1> 	; ECX = Number of bytes to be allocated		
  8217 0000FA7B E8CF63FFFF          <1> 	call	allocate_memory_block
  8218 0000FA80 721D                <1> 	jc	short sysalloc_err
  8219                              <1> 	; 01/09/2017
  8220 0000FA82 29C2                <1> 	sub	edx, eax ; upper limit address - beginning address
  8221 0000FA84 760F                <1> 	jna	short sysalloc_3 ; begin addr not less than the limit
  8222 0000FA86 39CA                <1> 	cmp	edx, ecx
  8223 0000FA88 720B                <1> 	jb	short sysalloc_3 ; end address overs the limit
  8224                              <1> sysalloc_2:	
  8225                              <1> 	; EAX = Beginning (physical) addr of the allocated mem block
  8226                              <1> 	; ECX = Num of allocated bytes (rounded up to page borders) 
  8227 0000FA8A 50                  <1> 	push	eax ; * ; 04/03/2017	
  8228                              <1> 	; Here, requested contiquous memory pages have been allocated
  8229                              <1> 	; on Memory Allocation Table but user's page directory 
  8230                              <1> 	; and page tables have not been updated yet!
  8231 0000FA8B 51                  <1> 	push	ecx ; **
  8232                              <1> 	; ebx = virtual address (will be rounded up to page border)
  8233                              <1> 	; ecx = number of bytes to be deallocated
  8234                              <1> 	;	will be adjusted to ebx+ecx round down - ebx round up
  8235 0000FA8C E81967FFFF          <1> 	call	deallocate_user_pages 
  8236 0000FA91 731F                <1> 	jnc	short sysalloc_4 ; EAX = Deallocated memory bytes
  8237 0000FA93 59                  <1> 	pop	ecx ; **
  8238 0000FA94 58                  <1> 	pop	eax ; *
  8239                              <1> sysalloc_3:
  8240                              <1> 	; error !
  8241                              <1> 	; restore Memory Allocation Table Content
  8242 0000FA95 E8C265FFFF          <1> 	call	deallocate_memory_block
  8243 0000FA9A 31C0                <1> 	xor	eax, eax ; 0
  8244 0000FA9C 48                  <1> 	dec	eax ; 0FFFFFFFFh ; 15/05/2017
  8245 0000FA9D EB09                <1> 	jmp	short sysalloc_wrong
  8246                              <1> sysalloc_err:
  8247 0000FA9F 8B2D[60030300]      <1> 	mov	ebp, [u.usp]  ; ebp points to user's registers
  8248 0000FAA5 894D18              <1> 	mov	[ebp+24], ecx ; return to user with ecx value 
  8249                              <1> sysalloc_wrong:
  8250                              <1> 	; eax = 0FFFFFFFFh
  8251 0000FAA8 A3[64030300]        <1> 	mov	[u.r0], eax
  8252 0000FAAD E9FAD7FFFF          <1> 	jmp	error
  8253                              <1> sysalloc_4:
  8254 0000FAB2 8B2D[60030300]      <1> 	mov	ebp, [u.usp]  ; ebp points to user's registers
  8255 0000FAB8 894518              <1> 	mov	[ebp+24], eax ; return to user with ecx value 
  8256 0000FABB 895D10              <1> 	mov	[ebp+16], ebx ; new value of ebx (rounded up)
  8257 0000FABE 89C1                <1> 	mov	ecx, eax ; byte count (from 'deallocate_user_pages')
  8258 0000FAC0 5A                  <1> 	pop	edx ; ** ; discard (another) byte count
  8259 0000FAC1 58                  <1> 	pop	eax ; *
  8260 0000FAC2 A3[64030300]        <1> 	mov	[u.r0], eax ; physical address
  8261                              <1> 	
  8262 0000FAC7 51                  <1> 	push	ecx ; 20/08/2017
  8263                              <1> 	;
  8264                              <1> 	; Write newly allocated contiguous (physical) pages
  8265                              <1> 	; on page dir and page tables of current user/process	
  8266                              <1> 	; as PRESENT, USER, WRITABLE
  8267                              <1> 	; (then clear allocated pages)
  8268 0000FAC8 E8D267FFFF          <1> 	call	allocate_user_pages
  8269                              <1> 	;jnc	sysret ; OK! return to process with success...
  8270                              <1> 
  8271                              <1> 	; 20/08/2017 ('sysdma' modification)
  8272 0000FACD 59                  <1> 	pop	ecx
  8273 0000FACE A1[64030300]        <1> 	mov	eax, [u.r0]   ; physical address (of the block)
  8274                              <1> 
  8275 0000FAD3 721D                <1> 	jc	short sysalloc_6
  8276                              <1> 
  8277 0000FAD5 833D[9C7A0100]FF    <1> 	cmp	dword [dma_addr], 0FFFFFFFFh ; -1	
  8278 0000FADC 0F82EAD7FFFF        <1> 	jb	sysret
  8279                              <1> 
  8280 0000FAE2 A3[9C7A0100]        <1> 	mov	[dma_addr], eax ; save dma address for sysdma
  8281 0000FAE7 890D[A07A0100]      <1> 	mov	[dma_size], ecx ; save dma buff size for sysdma
  8282                              <1> 
  8283 0000FAED E9DAD7FFFF          <1> 	jmp	sysret
  8284                              <1> 		
  8285                              <1> sysalloc_6:
  8286                              <1> 	;
  8287                              <1> 	; unexpected error ! insufficient memory !? conflict !?
  8288                              <1> 	; (!!?there is not a free page for a new page table?!!)
  8289                              <1> 	; We need to terminate process with error message !!!  
  8290                              <1> 	;
  8291 0000FAF2 8B2D[60030300]      <1> 	mov	ebp, [u.usp]  ; ebp points to user's registers
  8292 0000FAF8 8B4D18              <1> 	mov	ecx, [ebp+24] ; byte count
  8293                              <1> 	
  8294                              <1> 	; 20/08/2017
  8295                              <1> 	;mov	eax, [u.r0]   ; physical address (of the block)
  8296                              <1> 	
  8297                              <1> 	;
  8298                              <1> 	; restore Memory Allocation Table Content
  8299 0000FAFB E85C65FFFF          <1> 	call	deallocate_memory_block
  8300                              <1> 	;
  8301 0000FB00 803D[9A690000]03    <1> 	cmp	byte [CRT_MODE], 3 ; 80x25 text mode?
  8302 0000FB07 7407                <1> 	je	short sysalloc_7 ; yes
  8303                              <1> 	; Current mode is VGA (or CGA graphics) mode,
  8304                              <1> 	; We need to return to text mode for displaying
  8305                              <1> 	; error message just before 'sysexit'.  
  8306 0000FB09 B003                <1> 	mov	al, 3
  8307 0000FB0B E8581FFFFF          <1> 	call	_set_mode
  8308                              <1> sysalloc_7:
  8309 0000FB10 BE[571B0100]        <1> 	mov	esi, beep_Insufficient_Memory ; error message
  8310 0000FB15 E80B74FFFF          <1> 	call	print_msg ; print/display the message
  8311 0000FB1A B801000000          <1> 	mov	eax, 1 ; ax=1 is needed for 'sysexit' procedure
  8312 0000FB1F E92FD9FFFF          <1> 	jmp	sysexit ; and terminate the process !
  8313                              <1> 
  8314                              <1> sysdalloc:
  8315                              <1> 	; 19/02/2017 - TRDOS 386 (TRDOS v2.0)
  8316                              <1> 	; (TRDOS 386 feature only!)
  8317                              <1> 	;
  8318                              <1> 	; Deallocate Memory Block/Pages (for user)
  8319                              <1> 	; (Complementary call for sysalloc.)	
  8320                              <1> 	;
  8321                              <1> 	; INPUT ->
  8322                              <1> 	;	EBX = Virtual address (for user)
  8323                              <1> 	;	      (will be rounded up to page border)
  8324                              <1> 	;	ECX = Byte Count
  8325                              <1> 	;	     (will be adjusted to page borders)
  8326                              <1> 	;	If ICX = 0
  8327                              <1> 	;	   nothing to do
  8328                              <1> 	;	If EBX + ECX > User's ESP
  8329                              <1> 	;	   nothing to do		
  8330                              <1> 	; 
  8331                              <1> 	; Note: u.break control may be included in future versions	
  8332                              <1> 	;
  8333                              <1> 	; OUTPUT ->
  8334                              <1> 	;	If CF = 0
  8335                              <1> 	;	   EAX = Deallocated memory bytes
  8336                              <1> 	;	   EBX = Virtual address (as rounded up)	
  8337                              <1> 	;	IF CF = 1
  8338                              <1> 	;	   EAX = 0
  8339                              <1> 	;
  8340                              <1> 	; Note:	Main purpose of this call is to deallocate/release
  8341                              <1> 	;	previously allocated (physically) contiguous memory
  8342                              <1> 	;	pages but beginning (virtual) address may not be
  8343                              <1> 	;	followed by physically contiguous pages. So, this
  8344                              <1> 	;	system call will deallocate user's virtually
  8345                              <1> 	;	contiguous memory pages. Also, there is not any
  8346                              <1> 	;	objections to use this system call without sysalloc
  8347                              <1> 	;	system call; only possible objection is to lost data
  8348                              <1> 	;	within user's memory space, if the beginning address
  8349                              <1> 	;	and size is not proper.
  8350                              <1> 	;
  8351                              <1> 	; Note: Empty page tables will not be deallocated!!!
  8352                              <1> 	;       (they will be deallocated at process termination)
  8353                              <1> 	;
  8354                              <1> 	; Note: When the program terminates itself or when it is 
  8355                              <1> 	;	terminated by operating system kernel, all allocated
  8356                              <1> 	;	memory pages will be deallocated during termination
  8357                              <1> 	;	stage. So, 'sysdalloc' is not necessary except 
  8358                              <1> 	;	forgiving memory block to other programs/processes.
  8359                              <1> 	;	
  8360 0000FB24 8B15[5C030300]      <1> 	mov	edx, [u.sp]
  8361 0000FB2A 8B420C              <1> 	mov	eax, [edx+12] ; user's stack pointer
  8362 0000FB2D 29C8                <1> 	sub	eax, ecx ; esp - byte count
  8363 0000FB2F 24FC                <1> 	and	al, 0FCh ; dword alignment
  8364 0000FB31 39D8                <1> 	cmp	eax, ebx
  8365 0000FB33 7220                <1> 	jb	short sysdalloc_err ; deallocation overlaps with stack 	
  8366                              <1> 
  8367 0000FB35 31C0                <1> 	xor	eax, eax
  8368 0000FB37 21C9                <1> 	and	ecx, ecx
  8369 0000FB39 7407                <1> 	jz	short sysdalloc_2
  8370                              <1> 	
  8371 0000FB3B E86A66FFFF          <1> 	call	deallocate_user_pages
  8372 0000FB40 7213                <1> 	jc	short sysdalloc_err
  8373                              <1> 
  8374                              <1> sysdalloc_2:
  8375 0000FB42 A3[64030300]        <1> 	mov	[u.r0], eax
  8376 0000FB47 8B2D[60030300]      <1> 	mov	ebp, [u.usp]
  8377 0000FB4D 895D10              <1> 	mov	[ebp+16], ebx ; new value of ebx
  8378 0000FB50 E977D7FFFF          <1> 	jmp	sysret
  8379                              <1> 
  8380                              <1> sysdalloc_err:
  8381 0000FB55 A3[64030300]        <1> 	mov	[u.r0], eax ; 0
  8382 0000FB5A E94DD7FFFF          <1> 	jmp	error
  8383                              <1> 
  8384                              <1> syscalbac:
  8385                              <1> 	; SYS CALLBACK
  8386                              <1> 	; 03/08/2020
  8387                              <1> 	; 16/04/2017
  8388                              <1> 	; 14/04/2017
  8389                              <1> 	; 13/04/2017
  8390                              <1> 	; 28/02/2017
  8391                              <1> 	; 26/02/2017
  8392                              <1> 	; 24/02/2017
  8393                              <1> 	; 21/02/2017 - TRDOS 386 (TRDOS v2.0)
  8394                              <1> 	; (TRDOS 386 feature only!)
  8395                              <1> 	;
  8396                              <1> 	; Link or unlink IRQ callback service to/from user (ring 3)	
  8397                              <1> 	;
  8398                              <1> 	; INPUT ->
  8399                              <1> 	;	BL = IRQ number (Hardware interrupt request number)
  8400                              <1> 	;	     (0 t0 15 but IRQ 0,1,2,6,8,14,15 are prohibited)
  8401                              <1> 	;	     IRQ numbers 3,4,5,7,9,10,11,12,13 are valid
  8402                              <1> 	;	     (numbers >15 are invalid)
  8403                              <1> 	;
  8404                              <1> 	;	BH = 0 = Unlink IRQ (in BL) from user (ring 3) service
  8405                              <1> 	;	     1 = Link IRQ by using Signal Response Byte method
  8406                              <1> 	;	     2 = Link IRQ by using Callback service method 		
  8407                              <1> 	;	     3 = Link IRQ by using Auto Increment S.R.B. method 	
  8408                              <1> 	;	    >3 = invalid 
  8409                              <1> 	;	
  8410                              <1> 	;	CL = Signal Return/Response Byte value 
  8411                              <1> 	;
  8412                              <1> 	;	If BH = 3, kernel will put a counter value  ; 03/08/2020
  8413                              <1> 	;	          (into the S.R.B. addr)
  8414                              <1> 	;		  between 0 to 255. (start value = CL+1)
  8415                              <1> 	;	
  8416                              <1> 	;	NOTE: counter value, for example: even and odd numbers
  8417                              <1> 	;	      may be used for -audio- DMA buffer switch 
  8418                              <1> 	;	      within double buffer method, etc. 		
  8419                              <1> 	;
  8420                              <1> 	;	EDX = Signal return (Response) byte address
  8421                              <1> 	;	       		  - or -
  8422                              <1> 	;	      Interrupt/Callback service/routine address
  8423                              <1> 	; 	
  8424                              <1> 	;	      (virtual address in user's memory space)
  8425                              <1> 	;
  8426                              <1> 	; OUTPUT ->
  8427                              <1> 	;	CF = 0 & EAX = 0 -> Successful setting
  8428                              <1> 	;	CF = 1 & EAX > 0 -> IRQ is prohibited or locked 
  8429                              <1> 	;			by another process
  8430                              <1> 	;		 eax = ERR_PERM_DENIED -> prohibited or locked
  8431                              <1> 	;		 eax = ERR_INV_PARAMETER -> 
  8432                              <1> 	;		       invalid parameter/option or bad address
  8433                              <1> 	;
  8434                              <1> 	;	NOTE: Timer callbacks are set by using 'systimer'
  8435                              <1> 	;	      system call (IRQ 0, PIT and IRQ 8, RTC)
  8436                              <1> 	;
  8437                              <1> 	;	      Direct keyboard access is performed by using
  8438                              <1> 	;	      Keyboard Interrupt (INT 32h)	 	
  8439                              <1> 	;	
  8440                              <1> 	;	      It is prohibited here because:
  8441                              <1> 	;		1) Signal Response Byte method has not advantage
  8442                              <1> 	;		   against INT 32h, function AH = 1. Also,
  8443                              <1> 	;		   keyboard service interrupt will return with
  8444                              <1> 	;		   ascii and scan codes (AL, AH) while
  8445                              <1> 	;		   SRB method has only 1 byte space for ascii code
  8446                              <1> 	;		   or scan code. One byte signal response is used 
  8447                              <1> 	;		   for ensuring very simple and very fast
  8448                              <1> 	;		   virtual to physical memory address conversion
  8449                              <1> 	;		   without any memory page crossover risk. 
  8450                              <1> 	;		   (Otherwise double page conversion or word 
  8451                              <1> 	;		   alignment would be needed.)
  8452                              <1> 	;		2) Badly written user code (callback code)
  8453                              <1> 	;		   can prevent keyboard and timesharing functions
  8454                              <1> 	;		   of the operating system via continuous and long
  8455                              <1> 	;		   keyboard event handling by callback service.
  8456                              <1> 	;		   (It can cause to lose immediate keystroke 
  8457                              <1> 	;		   response from hardware to user.)
  8458                              <1> 	;		3) If user will check any keyboard events, 'getkey'
  8459                              <1> 	;		   (or 'getchar') must have more priority than other
  8460                              <1> 	;		   (video etc.) events because only control ability
  8461                              <1> 	;		   on a procedural infinite loop is a keyboard or
  8462                              <1> 	;		   mouse event. So user can use keyboard function
  8463                              <1> 	;		   at the end or at the beginning of a loop.
  8464                              <1> 	;		   In this case, INT 32h is used for that purpose
  8465                              <1> 	;		   and timer interrupt etc. callbacks can be used
  8466                              <1> 	;		   for dynamic and synchronized data refresh/transfer
  8467                              <1> 	;		   while cpu is in a static loop (without polling).
  8468                              <1> 	;		   Keyboard Int callback is not more useful because 
  8469                              <1> 	;		   already a manual check (a key is pressed or not)
  8470                              <1> 	;		   can be performed (via INT 32h, AH = 1) efficiently
  8471                              <1> 	;		   in a loop to prevent a locked infinitive loop.
  8472                              <1> 	;
  8473                              <1> 	;	    Disk IRQs (6,14,15) have been phohibited from ring 3 
  8474                              <1> 	;	    callback because, disk operations (file system services
  8475                              <1> 	;	    etc.) are independent from user program, for fast disk r/w.
  8476                              <1> 	;	    They are not more useful at ring 3 while they are in use
  8477                              <1> 	;	    by standard diskio functions which are mandatory part of 
  8478                              <1> 	;	    (monolithic) OS kernel and mainprog command interpreter.
  8479                              <1> 	;	    INT 33h diskio functions are enough for user level disk
  8480                              <1> 	;	    r/w.				
  8481                              <1> 	;
  8482                              <1> 	; TRDOS 386 - IRQ CALLBACK structures (parameters):
  8483                              <1> 	;	
  8484                              <1> 	;	   [u.irqlock] = 1 word, IRQ flags (0-15) that indicates
  8485                              <1> 	;			which IRQs are locked by (that) user.
  8486                              <1> 	;		        Lock and unlock (by user) will change
  8487                              <1> 	;			these flags or 'terminate process' (sysexit)
  8488                              <1> 	;			will clear these flags and unlock those IRQs.
  8489                              <1> 	;			               
  8490                              <1> 	;		   	Bit 0 is for IRQ 0 and Bit 15 is for IRQ 15
  8491                              <1> 	;
  8492                              <1> 	;	   IRQ(x).owner	 : 1 byte, user, [u.uno], 0 = free (unlocked)	
  8493                              <1> 	;
  8494                              <1> 	;	   IRQ(x).method : 1 byte for callback method & status
  8495                              <1> 	;			   0 = Signal Response Byte method
  8496                              <1> 	;			   1 = Callback service method
  8497                              <1> 	;			   >1 = invalid for current 'syscalback'.
  8498                              <1> 	;			or(+) 80h = IRQ is in use by system (ring 0)
  8499                              <1> 	;			            function (audio etc.) or
  8500                              <1> 	;			   	    a device driver.	   	
  8501                              <1> 	;			(system function will ignore the lock/owner)
  8502                              <1> 	;
  8503                              <1> 	;	   IRQ(x).srb	: 1 byte, Signal Return/Response byte value
  8504                              <1> 	;			  (a fixed value by user or a counter value
  8505                              <1> 	;			 from 0 to 255, which is increased by every
  8506                              <1> 	;			 interrupt just before putting it into 
  8507                              <1> 	;			 the Signal Response byte address
  8508                              <1> 	;			 (This is not used in callback serv method)
  8509                              <1> 	;	    	  
  8510                              <1> 	;	   IRQ(x).addr	: 1 dword
  8511                              <1> 	;			  Signal Response Byte address (physical)
  8512                              <1> 	;			  		-or-
  8513                              <1> 	;			  Callback service address (virtual)
  8514                              <1> 	;
  8515                              <1> 	;	   IRQ(x).dev	: 1 byte
  8516                              <1> 	;			  0 = Default device or kernel function
  8517                              <1> 	;			  		-or-
  8518                              <1> 	;			  1-255 = Assigned device driver number
  8519                              <1> 	;
  8520                              <1> 	;	   (x) = 3,4,5,7,9,10,11,12,13
  8521                              <1> 	;
  8522                              <1> 	;	
  8523                              <1> 	;	NOTE: If user's process/program calls the kernel (INT 40h)
  8524                              <1> 	;	      while it is already running in a (ring 3) callback
  8525                              <1> 	;	      service, kernel will force (convert) system call to
  8526                              <1> 	;	      'sysrele' (sys release). So, this feature provides
  8527                              <1> 	;	      easy and simple usage of callback services without
  8528                              <1> 	;	      falling into deepless <please 'callback me' then 
  8529                              <1> 	;	      let me 'callback you'> cycles! (User must return
  8530                              <1> 	;	      from callback service by using 'sysrele' system
  8531                              <1> 	;	      call, without a significant delay. Otherwise user
  8532                              <1> 	;	      process/program may be late to catch the next event
  8533                              <1> 	;	      within same callback purpose.	    		 	
  8534                              <1> 	;
  8535                              <1> 
  8536 0000FB5F 30C0                <1> 	xor	al, al ; the caller is 'syscalbac' sign/flag
  8537 0000FB61 E865180000          <1>  	call	set_irq_callback_service
  8538                              <1> 	; 16/04/2017
  8539 0000FB66 A3[64030300]        <1> 	mov	[u.r0], eax
  8540 0000FB6B 0F835BD7FFFF        <1> 	jnc	sysret
  8541 0000FB71 A3[C8030300]        <1> 	mov	dword [u.error], eax
  8542 0000FB76 E931D7FFFF          <1> 	jmp	error
  8543                              <1> 
  8544                              <1> sysfpstat:
  8545                              <1> 	; 28/02/2017 - TRDOS 386 (TRDOS v2.0)
  8546                              <1> 	; (TRDOS 386 feature only!)
  8547                              <1> 	;
  8548                              <1> 	; Set or reset FPU registers save/restore option (for user)
  8549                              <1> 	;	       (during software task switching, wswap-rswap)
  8550                              <1> 	;
  8551                              <1> 	; INPUT ->
  8552                              <1> 	;	BL = 0 -> reset
  8553                              <1> 	;	BL = 1 -> set (FPU register will be saved and restored)
  8554                              <1> 	;	
  8555                              <1> 	; OUTPUT ->
  8556                              <1> 	;	cf = 0 -> no error, FPU is ready... 
  8557                              <1> 	;		  (EAX = 0)
  8558                              <1> 	;	Cf = 1 -> error, 80387 FPU is not ready !
  8559                              <1> 	;		  (EAX = 0FFFFFFFFh)
  8560                              <1> 
  8561 0000FB7B 31C0                <1> 	xor	eax, eax
  8562 0000FB7D 803D[94700100]00    <1> 	cmp	byte [fpready], 0
  8563 0000FB84 7613                <1> 	jna	short sysfpstat_err	
  8564                              <1> 
  8565 0000FB86 80E301              <1> 	and	bl, 1 ; use BIT 0 only !
  8566 0000FB89 881D[DA030300]      <1> 	mov	[u.fpsave], bl
  8567 0000FB8F A3[64030300]        <1> 	mov	[u.r0], eax ; 0
  8568 0000FB94 E933D7FFFF          <1> 	jmp	sysret	 	
  8569                              <1> 
  8570                              <1> sysfpstat_err:
  8571 0000FB99 48                  <1> 	dec 	eax ; 0FFFFFFFFh
  8572 0000FB9A A3[64030300]        <1> 	mov 	[u.r0], eax ; -1
  8573 0000FB9F E908D7FFFF          <1> 	jmp 	error
  8574                              <1> 
  8575                              <1> sysdelete: ; Delete (Remove, Unlink) File
  8576                              <1> 	; 29/12/2017 (TRDOS 386 = TRDOS v2.0) 
  8577                              <1> 	;	
  8578                              <1>         ; INPUT ->
  8579                              <1>         ;          EBX = File name (ASCIIZ string) address
  8580                              <1> 	; OUTPUT ->
  8581                              <1> 	;          cf = 0 -> eax = 0
  8582                              <1> 	;          cf = 1 -> Error code in AL
  8583                              <1> 	;
  8584                              <1> 	; Modified Registers: EAX (at the return of system call)
  8585                              <1> 	;   
  8586                              <1> 
  8587 0000FBA4 89DE                <1> 	mov	esi, ebx
  8588                              <1> 	; file name is forced, change directory as temporary
  8589                              <1> 	;mov	ax, 1
  8590                              <1> 	;mov	[FFF_Valid], ah ; 0 ; reset
  8591                              <1> 	;call	set_working_path 
  8592 0000FBA6 E8680B0000          <1> 	call	set_working_path_x
  8593 0000FBAB 731D                <1> 	jnc	short sysdelete_1
  8594                              <1> 
  8595 0000FBAD 21C0                <1> 	and	eax, eax  ; 0 -> Bad Path!  
  8596 0000FBAF 7505                <1> 	jnz	short sysdelete_err
  8597                              <1> 	; eax = 0
  8598                              <1> sysdelete_path_err:
  8599 0000FBB1 B813000000          <1> 	mov	eax, ERR_INV_PATH_NAME ; 'bad path name !'
  8600                              <1> sysdelete_err:
  8601 0000FBB6 A3[64030300]        <1> 	mov	[u.r0], eax
  8602 0000FBBB A3[C8030300]        <1> 	mov	[u.error], eax
  8603 0000FBC0 E8230C0000          <1> 	call 	reset_working_path
  8604 0000FBC5 E9E2D6FFFF          <1> 	jmp	error
  8605                              <1> sysdelete_1:
  8606                              <1> 	;mov	esi, FindFile_Name
  8607 0000FBCA 66B80018            <1> 	mov	ax, 1800h ; Only files
  8608 0000FBCE E87E92FFFF          <1> 	call	find_first_file
  8609 0000FBD3 72E1                <1> 	jc	short sysdelete_err
  8610                              <1> sysdelete_2:
  8611                              <1> 	; check file attributes
  8612                              <1> 
  8613                              <1> 	;test	bl, 17 ; system, hidden, readonly, directory
  8614 0000FBD5 F6C307              <1>         test	bl, 7 ; system, hidden, readonly 
  8615 0000FBD8 7407                <1>         jz	short sysdelete_3
  8616                              <1> 
  8617 0000FBDA B80B000000          <1>         mov	eax, ERR_FILE_ACCESS ; 11 = 'permission denied !'
  8618 0000FBDF EBD5                <1>         jmp	short sysdelete_err
  8619                              <1> sysdelete_3:
  8620 0000FBE1 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  8621 0000FBE4 7407                <1> 	jz	short sysdelete_4
  8622 0000FBE6 B81A000000          <1> 	mov	eax, ERR_INV_FILE_NAME ; 26 = 'invalid file name !'
  8623 0000FBEB EBC9                <1>         jmp	short sysdelete_err
  8624                              <1> sysdelete_4:
  8625                              <1> 	;mov	bh, [LongName_EntryLength]
  8626 0000FBED 883D[066E0100]      <1> 	mov	[DelFile_LNEL], bh ; Long name entry length (if > 0)
  8627                              <1> 	; edi = Directory Entry Offset (DirBuff)
  8628                              <1> 	; esi = Directory Entry (FFF Structure)
  8629 0000FBF3 E8D6BBFFFF          <1> 	call	remove_file
  8630 0000FBF8 72BC                <1> 	jc	short sysdelete_err
  8631                              <1> sysrmdir_5:
  8632 0000FBFA 31C0                <1> 	xor	eax, eax ; 0
  8633 0000FBFC A3[64030300]        <1> 	mov	[u.r0], eax
  8634                              <1> 	;mov	[u.error], eax
  8635 0000FC01 E8E20B0000          <1> 	call 	reset_working_path
  8636 0000FC06 E9C1D6FFFF          <1> 	jmp	sysret
  8637                              <1> 
  8638                              <1> 
  8639                              <1> sysrmdir: ; Remove (Unlink) Directory
  8640                              <1> 	; 29/12/2017 (TRDOS 386 = TRDOS v2.0) 
  8641                              <1> 	;	
  8642                              <1>         ; INPUT ->
  8643                              <1>         ;          EBX = Pointer to directory name
  8644                              <1> 	; OUTPUT ->
  8645                              <1> 	;          cf = 0 -> eax = 0
  8646                              <1> 	;          cf = 1 -> Error code in AL
  8647                              <1> 	;
  8648                              <1> 	; Modified Registers: EAX (at the return of system call)
  8649                              <1> 	;  
  8650                              <1> 
  8651 0000FC0B 803D[B3030300]00    <1> 	cmp	byte [u.uno], 0  ; root (super user) ?
  8652 0000FC12 7614                <1> 	jna	short sysrmdir_0
  8653                              <1> 
  8654                              <1> 	;mov	dword [u.r0], ERR_PERM_DENIED
  8655 0000FC14 B80B000000          <1> 	mov	eax, ERR_PERM_DENIED ; ERR_NOT_SUPERUSER
  8656 0000FC19 A3[64030300]        <1> 	mov	[u.r0], eax
  8657 0000FC1E A3[C8030300]        <1> 	mov	[u.error], eax
  8658 0000FC23 E984D6FFFF          <1> 	jmp	error
  8659                              <1> 
  8660                              <1> sysrmdir_0:
  8661 0000FC28 89DE                <1> 	mov	esi, ebx
  8662                              <1> 	; file name is forced, change directory as temporary
  8663                              <1> 	;mov	ax, 1
  8664                              <1> 	;mov	[FFF_Valid], ah ; 0 ; reset
  8665                              <1> 	;call	set_working_path 
  8666 0000FC2A E8E40A0000          <1> 	call	set_working_path_x
  8667 0000FC2F 731D                <1> 	jnc	short sysrmdir_1
  8668                              <1> 
  8669 0000FC31 21C0                <1> 	and	eax, eax  ; 0 -> Bad Path!  
  8670 0000FC33 7505                <1> 	jnz	short sysrmdir_err
  8671                              <1> 	; eax = 0
  8672                              <1> sysrmdir_not_found:
  8673 0000FC35 B80C000000          <1> 	mov	eax, ERR_DIR_NOT_FOUND ; Directory not found !
  8674                              <1> sysrmdir_err:
  8675 0000FC3A A3[64030300]        <1> 	mov	[u.r0], eax
  8676 0000FC3F A3[C8030300]        <1> 	mov	[u.error], eax
  8677 0000FC44 E89F0B0000          <1> 	call 	reset_working_path
  8678 0000FC49 E95ED6FFFF          <1> 	jmp	error
  8679                              <1> sysrmdir_1:
  8680                              <1> 	;mov	esi, FindFile_Name
  8681 0000FC4E 66B81008            <1> 	mov	ax, 0810h ; Only directories
  8682 0000FC52 E8FA91FFFF          <1> 	call	find_first_file
  8683 0000FC57 7306                <1> 	jnc	short sysrmdir_2
  8684                              <1> 
  8685                              <1> 	; eax = 2 (File not found !)
  8686 0000FC59 3C02                <1> 	cmp	al, 2 ; ERR_NOT_FOUND
  8687 0000FC5B 74D8                <1> 	je	short sysrmdir_not_found
  8688 0000FC5D EBDB                <1> 	jmp	short sysrmdir_err
  8689                              <1> sysrmdir_2:
  8690                              <1> 	; check directory attributes
  8691                              <1> 
  8692 0000FC5F F6C307              <1>         test	bl, 7 ; system, hidden, readonly 
  8693 0000FC62 7407                <1>         jz	short sysrmdir_3
  8694                              <1> 
  8695 0000FC64 B80B000000          <1>         mov	eax, ERR_DIR_ACCESS ; 11 = 'permission denied !'
  8696 0000FC69 EBCF                <1>         jmp	short sysrmdir_err
  8697                              <1> sysrmdir_3:
  8698 0000FC6B 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  8699 0000FC6E 7407                <1> 	jz	short sysrmdir_4
  8700                              <1> 	;mov	eax, ERR_NOT_DIR ; 'not a valid directory !'
  8701 0000FC70 B813000000          <1> 	mov	eax, ERR_INV_PATH_NAME ; 'bad path name !'
  8702 0000FC75 EBC3                <1>         jmp	short sysrmdir_err
  8703                              <1> sysrmdir_4:
  8704                              <1> 	;mov	bh, [LongName_EntryLength]
  8705 0000FC77 883D[066E0100]      <1> 	mov	[DelFile_LNEL], bh ; Long name entry length (if > 0)
  8706                              <1> 	; edi = Directory Entry Offset (DirBuff)
  8707                              <1> 	; esi = Directory Entry (FFF Structure)
  8708 0000FC7D E8A498FFFF          <1> 	call	delete_sub_directory
  8709 0000FC82 0F8372FFFFFF        <1> 	jnc	sysrmdir_5
  8710                              <1> ;	jc	short sysrmdir_6
  8711                              <1> ;
  8712                              <1> ;	xor	eax, eax ; 0
  8713                              <1> ;sysrmdir_5:
  8714                              <1> ;	mov	[u.r0], eax
  8715                              <1> ;	;mov	[u.error], eax
  8716                              <1> ;	call 	reset_working_path
  8717                              <1> ;	jmp	sysret
  8718                              <1> sysrmdir_6:
  8719 0000FC88 A3[64030300]        <1> 	mov	[u.r0], eax
  8720 0000FC8D A3[C8030300]        <1> 	mov	[u.error], eax
  8721                              <1> 
  8722 0000FC92 09C0                <1> 	or	eax, eax ; EAX = 0 -> Directory not empty!
  8723 0000FC94 741C                <1> 	jz	short sysrmdir_9
  8724                              <1> 
  8725                              <1> 	; EAX > 0 -> Error code in AL (or AX or EAX)
  8726                              <1> 
  8727 0000FC96 833D[BA6B0100]01    <1> 	cmp	dword [FAT_ClusterCounter], 1
  8728 0000FC9D 7209                <1> 	jb	short sysrmdir_8
  8729                              <1> sysrmdir_7:
  8730                              <1> 	; ESI = Logical DOS Drive Description Table address	
  8731 0000FC9F 66BB00FF            <1> 	mov	bx, 0FF00h ; BH = FFh -> use ESI for Drive parameters
  8732                              <1> 	           ; BL = 0 -> Recalculate free cluster count
  8733 0000FCA3 E80AD1FFFF          <1> 	call	calculate_fat_freespace	
  8734                              <1> sysrmdir_8:
  8735 0000FCA8 E83B0B0000          <1> 	call 	reset_working_path
  8736 0000FCAD E9FAD5FFFF          <1> 	jmp	error
  8737                              <1> 
  8738                              <1> sysrmdir_9:
  8739 0000FCB2 A1[BA6B0100]        <1> 	mov	eax, [FAT_ClusterCounter]
  8740 0000FCB7 09C0                <1> 	or	eax, eax ; 0 ?
  8741 0000FCB9 0F847BFFFFFF        <1> 	jz	sysrmdir_err
  8742                              <1> 	; ESI = Logical DOS Drive Description Table address	
  8743 0000FCBF 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> use ESI for Drive parameters
  8744                              <1> 	           ; BL = 1 -> add free clusters
  8745 0000FCC3 E8EAD0FFFF          <1> 	call	calculate_fat_freespace
  8746 0000FCC8 09C9                <1> 	or	ecx, ecx
  8747 0000FCCA 74DC                <1>         jz	short sysrmdir_8 ; ecx = 0 -> OK
  8748                              <1> 	; ecx > 0 -> Error (Recalculation is needed)
  8749 0000FCCC EBD1                <1> 	jmp	short sysrmdir_7
  8750                              <1> 
  8751                              <1> 
  8752                              <1> syschdir: ; Change Current (Working) Drive & Directory (for user)
  8753                              <1> 	; 30/12/2017 (TRDOS 386 = TRDOS v2.0) 
  8754                              <1> 	;	
  8755                              <1>         ; INPUT ->
  8756                              <1>         ;          EBX = Directory name (ASCIIZ string) address
  8757                              <1> 	; OUTPUT ->
  8758                              <1> 	;          cf = 0 -> eax = 0
  8759                              <1> 	;          cf = 1 -> Error code in AL
  8760                              <1> 	;
  8761                              <1> 	; Modified Registers: EAX (at the return of system call)
  8762                              <1> 	;
  8763                              <1> 	; NOTE: If drive name is not included, only the working
  8764                              <1> 	; directory (for user, not for drive/OS) will be chanded.
  8765                              <1> 	; If there is a drive name (as A:, B:, C:, D: etc.)
  8766                              <1> 	; at the beginning of the ASCIIZ (directory) string,
  8767                              <1> 	; working drive and working directory (for user) 
  8768                              <1> 	; will be changed together.
  8769                              <1> 	; (When the program is terminated, MainProg -internal 
  8770                              <1> 	; shell- will reset working directory to the previous
  8771                              <1> 	; -current- logical drive's current directory again.) 	
  8772                              <1>   
  8773 0000FCCE 89DE                <1> 	mov	esi, ebx
  8774                              <1> 	; file name is not forced, change directory as temporary
  8775 0000FCD0 31C0                <1> 	xor	eax, eax
  8776                              <1> 	;mov	[FFF_Valid], ah ; 0 ; reset
  8777                              <1> 	;call	set_working_path 
  8778 0000FCD2 E8400A0000          <1> 	call	set_working_path_xx
  8779 0000FCD7 731D                <1> 	jnc	short syschdir_ok
  8780 0000FCD9 21C0                <1> 	and	eax, eax  ; 0 -> Bad Path!  
  8781 0000FCDB 7505                <1> 	jnz	short syschdir_err
  8782                              <1> 	; eax = 0
  8783                              <1> syschdir_not_found:
  8784 0000FCDD B80C000000          <1> 	mov	eax, ERR_DIR_NOT_FOUND ; Directory not found !
  8785                              <1> syschdir_err:
  8786 0000FCE2 A3[64030300]        <1> 	mov	[u.r0], eax
  8787 0000FCE7 A3[C8030300]        <1> 	mov	[u.error], eax
  8788 0000FCEC E8F70A0000          <1> 	call 	reset_working_path
  8789 0000FCF1 E9B6D5FFFF          <1> 	jmp	error
  8790                              <1> syschdir_ok:
  8791 0000FCF6 31C0                <1> 	xor	eax, eax ; 0
  8792 0000FCF8 A3[64030300]        <1> 	mov	[u.r0], eax
  8793                              <1> 	;mov	[u.error], eax
  8794 0000FCFD E9CAD5FFFF          <1> 	jmp	sysret
  8795                              <1> 
  8796                              <1> 
  8797                              <1> syschmod: ; Get & Change File (or Directory) Attributes
  8798                              <1> 	; 30/12/2017 (TRDOS 386 = TRDOS v2.0) 
  8799                              <1> 	;	
  8800                              <1>         ; INPUT ->
  8801                              <1>         ;          EBX = File/Directory (ASCIIZ) name address
  8802                              <1> 	;	    CL = New attributes (if CL < 40h)
  8803                              <1> 	;	    CL >= 40h -> Get File Attributes		
  8804                              <1> 	; OUTPUT ->
  8805                              <1> 	;          cf = 0 -> EAX = File attributes (in AL)
  8806                              <1> 	;          cf = 1 -> Error code in AL
  8807                              <1> 	;
  8808                              <1> 	; Modified Registers: EAX (at the return of system call)
  8809                              <1> 	;  
  8810                              <1> 	; MSDOS File Attributes:    (bit value of attrib byte)
  8811                              <1> 	;	ATTR_READ_ONLY	=	01h  (bit 0, 'R')
  8812                              <1> 	;	ATTR_HIDDEN	=	02h  (bit 1, 'H')
  8813                              <1> 	;	ATTR_SYSTEM	=	04h  (bit 2, 'S')
  8814                              <1> 	;	ATTR_VOLUME_ID	=	08h  (bit 3)
  8815                              <1> 	;	ATTR_DIRECTORY	=	10h  (bit 4)
  8816                              <1> 	;	ATTR_ARCHIVE	=	20h  (bit 5, 'A')
  8817                              <1> 	;	ATTR_LONG_NAME	=	ATTR_READONLY |
  8818                              <1> 	;				ATTR_HIDDEN |
  8819                              <1> 	;				ATTR_SYSTEM |
  8820                              <1> 	;				ATTR_VOLUME_ID				
  8821                              <1> 	;	The upper two bits of attributes must be 0.
  8822                              <1> 
  8823                              <1> 	; Note:	* If ATTR_DIRECTORY is set, only directory names
  8824                              <1> 	;	  will be searched (and S,H,R,A attributeds of 
  8825                              <1> 	;	  the directory will be changed.)
  8826                              <1> 	;	* If ATTR_VOLUME_ID is set, 'syschmod' system call
  8827                              <1> 	;	  will return with 'permission denied' error.
  8828                              <1> 	;	* If ATTR_DIRECTORY is not set, only file names
  8829                              <1> 	;	  will be searched (and S,H,R,A attributes of the
  8830                              <1> 	;	  file will be changed.)
  8831                              <1> 	;
  8832                              <1> 	; (Ony Super User can change S,H,R attributes.) 
  8833                              <1> 
  8834 0000FD02 80F940              <1> 	cmp	cl, 40h	
  8835 0000FD05 7327                <1> 	jnb	short syschmod_0
  8836                              <1> 
  8837 0000FD07 F6C108              <1> 	test	cl, 08h ; ATTR_VOLUME_ID
  8838 0000FD0A 750E                <1> 	jnz	short syschmod_perm_err
  8839                              <1> 
  8840 0000FD0C 803D[B3030300]00    <1> 	cmp	byte [u.uno], 0  ; root (super user) ?
  8841 0000FD13 7619                <1> 	jna	short syschmod_0
  8842                              <1> 
  8843                              <1> 	; Not super user..
  8844 0000FD15 F6C107              <1> 	test	cl, 07h	; S,H,R attributes
  8845 0000FD18 7414                <1> 	jz	short syschmod_0
  8846                              <1> 
  8847                              <1> syschmod_perm_err:
  8848                              <1> 	;mov	dword [u.r0], ERR_PERM_DENIED
  8849 0000FD1A B80B000000          <1> 	mov	eax, ERR_PERM_DENIED ; 'permission denied !'
  8850 0000FD1F A3[64030300]        <1> 	mov	[u.r0], eax
  8851 0000FD24 A3[C8030300]        <1> 	mov	[u.error], eax
  8852 0000FD29 E97ED5FFFF          <1> 	jmp	error
  8853                              <1> 
  8854                              <1> syschmod_0:
  8855 0000FD2E 880D[546E0100]      <1> 	mov	[Attributes], cl
  8856 0000FD34 89DE                <1> 	mov	esi, ebx
  8857                              <1> 	; file name is forced, change directory as temporary
  8858                              <1> 	;mov	ax, 1
  8859                              <1> 	;mov	[FFF_Valid], ah ; 0 ; reset
  8860                              <1> 	;call	set_working_path 
  8861 0000FD36 E8D8090000          <1> 	call	set_working_path_x
  8862 0000FD3B 731D                <1> 	jnc	short syschmod_1
  8863 0000FD3D 21C0                <1> 	and	eax, eax  ; 0 -> Bad Path!  
  8864 0000FD3F 7505                <1> 	jnz	short syschmod_err
  8865                              <1> 	; eax = 0
  8866                              <1> syschmod_path_not_found:
  8867 0000FD41 B813000000          <1> 	mov	eax, ERR_INV_PATH_NAME ; 'Bad path name !'
  8868                              <1> syschmod_err:
  8869 0000FD46 A3[64030300]        <1> 	mov	[u.r0], eax
  8870 0000FD4B A3[C8030300]        <1> 	mov	[u.error], eax
  8871 0000FD50 E8930A0000          <1> 	call 	reset_working_path
  8872 0000FD55 E952D5FFFF          <1> 	jmp	error
  8873                              <1> syschmod_1:
  8874 0000FD5A B008                <1> 	mov	al, 08h ; Except volume labels (& long names)
  8875 0000FD5C A0[546E0100]        <1> 	mov	al, [Attributes]
  8876 0000FD61 2410                <1> 	and	al, 10h ;
  8877                              <1> 	;mov	esi, FindFile_Name
  8878                              <1> 	;mov	ax, 1800h ; Only files
  8879                              <1> 	;mov	ax, 0810h ; Only directories
  8880 0000FD63 E8E990FFFF          <1> 	call	find_first_file
  8881                              <1> 	;jnc	short syschmod_2
  8882 0000FD68 72DC                <1> 	jc	short syschmod_err
  8883                              <1> 
  8884                              <1> 	;; eax = 2 (File not found !)
  8885                              <1> 	;cmp	al, 2 ; ERR_NOT_FOUND
  8886                              <1> 	;jne	short syschmod_err
  8887                              <1> 
  8888                              <1> 	;and	byte [Attributes], 10h
  8889                              <1> 	;jz	short syschmod_err
  8890                              <1> 
  8891                              <1> 	;; Directory not found !
  8892                              <1> 	;mov	al, 3 ; ERR_PATH_NOT_FOUND
  8893                              <1> 	;jmp	short syschmod_err
  8894                              <1> 
  8895                              <1> syschmod_2:
  8896 0000FD6A 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  8897 0000FD6D 7407                <1> 	jz	short syschmod_3
  8898 0000FD6F B81A000000          <1> 	mov	eax, ERR_INV_FILE_NAME ; 'invalid file name !'
  8899 0000FD74 EBD0                <1>         jmp	short syschmod_err
  8900                              <1> syschmod_3:
  8901                              <1> 	; EDI = Directory buffer entry offset/address
  8902                              <1> 	; BL = File (or Directory) Attributes 
  8903                              <1> 	; mov	bl, [EDI+0Bh]
  8904                              <1> 
  8905                              <1> 	; check directory attributes
  8906 0000FD76 8A3D[546E0100]      <1> 	mov	bh, [Attributes] ; new attributes
  8907 0000FD7C 80FF40              <1> 	cmp	bh, 40h  ;>=40 -> get file/directory attributes
  8908 0000FD7F 732D                <1> 	jnb	short syschmod_6
  8909                              <1> 
  8910                              <1> 	; set file/directory attributes
  8911 0000FD81 F6C307              <1> 	test	bl, 7 ; system, hidden, readonly 
  8912 0000FD84 7409                <1>         jz	short syschmod_4
  8913                              <1> 
  8914 0000FD86 803D[B3030300]00    <1> 	cmp	byte [u.uno], 0  ; root (super user) ?
  8915 0000FD8D 778B                <1> 	ja	short syschmod_perm_err
  8916                              <1> syschmod_4:
  8917 0000FD8F 66817F0CA101        <1> 	cmp	word [edi+DirEntry_NTRes], 01A1h ; Singlix FS
  8918 0000FD95 7424                <1> 	je	short syschmod_7
  8919                              <1> 
  8920 0000FD97 887F0B              <1> 	mov	[edi+0Bh], bh    ; Attributes (New!)
  8921                              <1> 
  8922 0000FD9A C605[C46B0100]02    <1> 	mov	byte [DirBuff_ValidData], 2 ; modified sign
  8923                              <1> 					    ; to force write	
  8924 0000FDA1 E8E0B6FFFF          <1> 	call 	save_directory_buffer
  8925 0000FDA6 729E                <1> 	jc	short syschmod_err
  8926                              <1> 
  8927                              <1> syschmod_5:
  8928 0000FDA8 8A1D[546E0100]      <1> 	mov	bl, [Attributes]
  8929                              <1> syschmod_6:
  8930 0000FDAE 0FB6C3              <1> 	movzx	eax, bl
  8931 0000FDB1 A3[64030300]        <1> 	mov	[u.r0], eax
  8932                              <1> 	;mov	dword [u.error], 0
  8933 0000FDB6 E911D5FFFF          <1> 	jmp	sysret
  8934                              <1> 
  8935                              <1> syschmod_7:
  8936 0000FDBB 29C0                <1> 	sub	eax, eax
  8937 0000FDBD 8A25[C26B0100]      <1>         mov     ah, [DirBuff_DRV]
  8938 0000FDC3 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  8939 0000FDC8 01C6                <1>         add     esi, eax
  8940 0000FDCA 807E04A1            <1>         cmp     byte [esi+LD_FSType], 0A1h
  8941 0000FDCE 7307                <1> 	jnc	short syschmod_8
  8942 0000FDD0 B01D                <1> 	mov	al, ERR_INV_DATA ; 29 = Invalid Data
  8943 0000FDD2 E96FFFFFFF          <1> 	jmp	syschmod_err
  8944                              <1> 
  8945                              <1> syschmod_8:
  8946                              <1> 	; BH = New MS-DOS File Attributes
  8947 0000FDD7 88F8                <1> 	mov	al, bh ; File/Directory Attributes
  8948 0000FDD9 30E4                <1> 	xor	ah, ah ; Attributes in MS-DOS format sign	  
  8949 0000FDDB E8CFA1FFFF          <1> 	call	change_fs_file_attributes
  8950 0000FDE0 0F8260FFFFFF        <1> 	jc	syschmod_err
  8951 0000FDE6 EBC0                <1> 	jmp	short syschmod_5
  8952                              <1> 
  8953                              <1> 
  8954                              <1> sysdrive: ; Get/Set Current (Working) Drive (for user)
  8955                              <1> 	; 30/12/2017 (TRDOS 386 = TRDOS v2.0) 
  8956                              <1> 	;	
  8957                              <1>         ; INPUT ->
  8958                              <1>         ;          BL = Logical DOS Drive number (0=A: ... 2=C:)
  8959                              <1> 	;	   If BL = 0FFh -> Get Current Drive 	
  8960                              <1> 	; OUTPUT ->
  8961                              <1> 	;          cf = 0 -> 
  8962                              <1> 	;		   AL = Current Drive number	
  8963                              <1> 	;		   AH = The Last Logical DOS Drive no.
  8964                              <1> 	;          cf = 1 -> Error code in AL
  8965                              <1> 	;
  8966                              <1> 	; Modified Registers: EAX (at the return of system call)
  8967                              <1> 	;
  8968                              <1> 	; NOTE: If the requested logical dos drive is ready, 
  8969                              <1> 	;	it's current current directory will be the user's
  8970                              <1> 	;	(program's) current directory.
  8971                              <1> 	;	(When the program is terminated, MainProg -internal 
  8972                              <1> 	;	shell- will reset the previous -current- logical drive
  8973                              <1> 	;       as current drive again).	
  8974                              <1>   
  8975 0000FDE8 80FBFF              <1> 	cmp	bl, 0FFh
  8976 0000FDEB 7435                <1> 	je	short sysdrive_ok
  8977 0000FDED 3A1D[F5170100]      <1> 	cmp	bl, [Last_DOS_DiskNo]
  8978 0000FDF3 771E                <1> 	ja	short sysdrive_err	
  8979                              <1> 
  8980                              <1> 	; Save current drive and reset mode
  8981                              <1> 	; for 'reset_working_path' procedure (for MainProg)
  8982 0000FDF5 30C0                <1> 	xor	al, al
  8983 0000FDF7 66A3[90700100]      <1> 	mov	[SWP_Mode], ax ; ah = 0
  8984 0000FDFD A0[9E640100]        <1> 	mov	al, [Current_Drv]
  8985 0000FE02 FEC4                <1> 	inc	ah ; mov ah, 1
  8986 0000FE04 66A3[92700100]      <1> 	mov	[SWP_DRV], ax 
  8987                              <1> 
  8988 0000FE0A 88DA                <1> 	mov	dl, bl
  8989 0000FE0C E89D7CFFFF          <1> 	call	change_current_drive
  8990 0000FE11 730F                <1> 	jnc	short sysdrive_ok
  8991                              <1> sysdrive_err:
  8992 0000FE13 C705[64030300]0F00- <1> 	mov	dword [u.r0], ERR_DRV_NOT_RDY ; 'drive not ready !'
  8992 0000FE1B 0000                <1>
  8993 0000FE1D E98AD4FFFF          <1> 	jmp	error
  8994                              <1> sysdrive_ok:
  8995 0000FE22 A0[9E640100]        <1> 	mov	al, [Current_Drv]
  8996 0000FE27 8A25[F5170100]      <1> 	mov	ah, [Last_DOS_DiskNo]
  8997 0000FE2D A3[64030300]        <1> 	mov	[u.r0], eax
  8998 0000FE32 E995D4FFFF          <1> 	jmp	sysret
  8999                              <1> 
  9000                              <1> 
  9001                              <1> sysdir: ; Get Current (Working) Drive & Directory (for user)
  9002                              <1> 	; 30/12/2017 (TRDOS 386 = TRDOS v2.0) 
  9003                              <1> 	;	
  9004                              <1>         ; INPUT ->
  9005                              <1>         ;          EBX = Current directory name buffer address
  9006                              <1> 	;		(Buffer length = 92 bytes)
  9007                              <1> 	; OUTPUT ->
  9008                              <1> 	;          AL = Current drive (0=A: .. 2=C:)
  9009                              <1> 	;	   If CF = 1 -> AL = error code
  9010                              <1> 	;
  9011                              <1> 	; Modified Registers: EAX (at the return of system call)
  9012                              <1> 	;
  9013                              <1> 	; Note: Required directory name buffer length may be 
  9014                              <1> 	;	<= 92 bytes for current TRDOS 386 version.
  9015                              <1> 	;	(7*12 name chars + 7 slash + 0)
  9016                              <1> 
  9017 0000FE37 89E5                <1> 	mov	ebp, esp
  9018 0000FE39 83EC60              <1> 	sub	esp, 96
  9019 0000FE3C 53                  <1> 	push	ebx ; User's buffer address
  9020 0000FE3D 30D2                <1> 	xor	dl, dl ; 0 = current drive
  9021 0000FE3F E866ABFFFF          <1>   	call	get_current_directory
  9022 0000FE44 72CD                <1> 	jc	short sysdrive_err ; 'drive not ready !' error
  9023 0000FE46 89E6                <1> 	mov	esi, esp ; System's buffer address
  9024 0000FE48 5F                  <1> 	pop	edi  ; User's buffer address
  9025                              <1> 	; ecx = transfer (byte) count (<=92)
  9026 0000FE49 E843F4FFFF          <1> 	call	transfer_to_user_buffer
  9027 0000FE4E 89EC                <1> 	mov	esp, ebp
  9028 0000FE50 730F                <1> 	jnc	short sysdir_ok
  9029                              <1> sysdir_err:
  9030 0000FE52 C705[64030300]2E00- <1> 	mov	dword [u.r0], ERR_BUFFER  ; 'buffer error !'
  9030 0000FE5A 0000                <1>
  9031 0000FE5C E94BD4FFFF          <1> 	jmp	error
  9032                              <1> sysdir_ok:	
  9033 0000FE61 8A0D[9E640100]      <1> 	mov	cl, [Current_Drv]
  9034 0000FE67 890D[64030300]      <1> 	mov	[u.r0], ecx
  9035 0000FE6D E95AD4FFFF          <1> 	jmp	sysret
  9036                              <1> 
  9037                              <1> 
  9038                              <1> sysldrvt: ; Get copy of Logical DOS Drive Description Table
  9039                              <1> 	; 30/12/2017 (TRDOS 386 = TRDOS v2.0) 
  9040                              <1> 	;	
  9041                              <1>         ; INPUT ->
  9042                              <1> 	;	    BL = Logical DOS drive number (zero based)	
  9043                              <1>         ;          ECX = Logical DOS drv desc table buffer addr
  9044                              <1> 	;		(Buffer length = 256 bytes)
  9045                              <1> 	; OUTPUT ->
  9046                              <1> 	;          cf = 0 -> 
  9047                              <1> 	;		   AL = Current Drive number	
  9048                              <1> 	;		   AH = The Last Logical DOS Drive no.
  9049                              <1> 	;          cf = 1 -> Error code in AL
  9050                              <1> 	;		   AH = The Last Logical DOS Drive no.
  9051                              <1> 	;
  9052                              <1> 	; Modified Registers: EAX (at the return of system call)
  9053                              <1> 	;
  9054                              <1> 	; Note: Required description table buffer length is
  9055                              <1> 	;	256 bytes for current TRDOS 386 version.
  9056                              <1> 	
  9057 0000FE72 89CF                <1> 	mov	edi, ecx ; Destination address (user space)
  9058 0000FE74 88DC                <1> 	mov	ah, bl
  9059 0000FE76 30C0                <1> 	xor	al, al
  9060 0000FE78 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  9061 0000FE7D 01C6                <1> 	add	esi, eax ; Source address (system space)	 
  9062 0000FE7F B900010000          <1> 	mov	ecx, 256 ; Byte count 
  9063                              <1> 			 ; Logical Dos Drv Desc Table size
  9064 0000FE84 E808F4FFFF          <1> 	call	transfer_to_user_buffer
  9065 0000FE89 72C7                <1> 	jc	short sysdir_err
  9066 0000FE8B 8A2D[F5170100]      <1> 	mov	ch, [Last_DOS_DiskNo]
  9067 0000FE91 EBCE                <1> 	jmp	short sysdir_ok
  9068                              <1> 
  9069                              <1> 
  9070                              <1> systime: ; Get System Date&Time
  9071                              <1> 	; 30/12/2017 (TRDOS 386 = TRDOS v2.0) 
  9072                              <1> 	;	
  9073                              <1>         ; INPUT -> BL =
  9074                              <1> 	;	    0 = Get Date&Time in Unix/Epoch format
  9075                              <1> 	;	    1 = Get Time in MSDOS format
  9076                              <1> 	;	    2 = Get Date in MSDOS format
  9077                              <1> 	;	    3 = Get Date&Time in MSDOS format
  9078                              <1> 	;	    4 & other values =
  9079                              <1> 	;		System timer ticks will be returned
  9080                              <1> 	;		in EAX and Carry Flag will be set.
  9081                              <1> 	;		(CF will not be set if BL = 4)	 	
  9082                              <1> 	; OUTPUT ->
  9083                              <1> 	;	For BL input = 3
  9084                              <1> 	;          EAX = Current Time (RTC)
  9085                              <1> 	;		AL = Second (DL in MSDOS)
  9086                              <1> 	;		AH = Minute (CL in MSDOS)
  9087                              <1> 	;	   	HW of EAX = Hour (CH in MSDOS)	
  9088                              <1> 	;	   EDX = Current System Date (RTC)
  9089                              <1> 	;		DL = Day (DL in MSDOS)
  9090                              <1> 	;		DH = Month (DH in MSDOS)
  9091                              <1> 	;		HW of EDX = Year (CX in MSDOS)	
  9092                              <1> 	;
  9093                              <1> 	;	For BL input = 2
  9094                              <1> 	;	   EAX = Current System Date (RTC)
  9095                              <1> 	;		DL = Day (DL in MSDOS)
  9096                              <1> 	;		DH = Month (DH in MSDOS)
  9097                              <1> 	;		HW of EDX = Year (CX in MSDOS)
  9098                              <1> 	;
  9099                              <1> 	;	For BL input = 1
  9100                              <1> 	;          EAX = Current Time (RTC)
  9101                              <1> 	;		AL = Second (DL in MSDOS)
  9102                              <1> 	;		AH = Minute (CL in MSDOS)
  9103                              <1> 	;	   	HW of EAX = Hour (CH in MSDOS)	
  9104                              <1> 	;
  9105                              <1> 	;	For BL input = 0
  9106                              <1> 	;          EAX = Unix (Epoch) Time Ticks/Seconds
  9107                              <1> 	;
  9108                              <1> 	;	For BL input  = 4
  9109                              <1> 	;	   EAX = System timer ticks
  9110                              <1> 	;
  9111                              <1> 	;	If CF = 1 (for other values of BL input)
  9112                              <1> 	;	   EAX = System timer ticks (no error code!)	
  9113                              <1> 	;		
  9114                              <1> 	; Modified Registers: EAX, (EDX)
  9115                              <1> 	;		 (at the return of system call)
  9116                              <1> 	;
  9117                              <1> 
  9118 0000FE93 20DB                <1> 	and	bl, bl
  9119 0000FE95 750F                <1> 	jnz	short systime_1
  9120 0000FE97 E80272FFFF          <1> 	call	epoch
  9121                              <1> systime_0:
  9122 0000FE9C A3[64030300]        <1> 	mov	[u.r0], eax
  9123 0000FEA1 E926D4FFFF          <1> 	jmp	sysret
  9124                              <1> systime_1:
  9125 0000FEA6 80FB04              <1> 	cmp	bl, 4
  9126 0000FEA9 7211                <1> 	jb	short systime_2
  9127 0000FEAB A1[58640100]        <1> 	mov	eax, [TIMER_LH] ; 18.2 Hz timer ticks
  9128                              <1> 				; Note: [TIMER_LH] may be set
  9129                              <1> 				; to wrong timer value due to
  9130                              <1> 				; program functions.
  9131                              <1> 				; (This value must not be
  9132                              <1> 				; accepted as [TIMER_LH]/18.2
  9133                              <1> 				; seconds since the midnight.)
  9134 0000FEB0 76EA                <1> 	jna	short systime_0
  9135 0000FEB2 A3[64030300]        <1> 	mov	[u.r0], eax	
  9136 0000FEB7 E9F0D3FFFF          <1> 	jmp	error ; cf = 1 & [u.r0] = eax = timer ticks 
  9137                              <1> 
  9138                              <1> systime_2:
  9139                              <1> 	;push	ebx
  9140 0000FEBC E83F71FFFF          <1> 	call	get_rtc_date_time
  9141                              <1> 	;pop	ebx
  9142 0000FEC1 F6C301              <1> 	test	bl, 1
  9143 0000FEC4 7429                <1> 	jz	short systime_4
  9144 0000FEC6 30E4                <1> 	xor	ah, ah
  9145 0000FEC8 A0[A2600100]        <1> 	mov	al, [hour]
  9146 0000FECD 88C2                <1> 	mov	dl, al
  9147 0000FECF C1E010              <1> 	shl	eax, 16
  9148 0000FED2 A0[A6600100]        <1> 	mov	al, [second]
  9149 0000FED7 8A25[A4600100]      <1> 	mov	ah, [minute]
  9150 0000FEDD F6C302              <1> 	test	bl, 2
  9151 0000FEE0 74BA                <1> 	jz	short systime_0
  9152                              <1> 	; Check time & date match risk 
  9153                              <1> 	; (23:59:59 may cause to wrong
  9154                              <1> 	; date -new day with previous date-...)
  9155 0000FEE2 80FA17              <1> 	cmp	dl, 23
  9156 0000FEE5 7206                <1> 	jb	short systime_3
  9157 0000FEE7 663D3B3B            <1> 	cmp	ax, (59*256)+59 ; if hour is 23:59:59
  9158 0000FEEB 73CF                <1> 	jnb	short systime_2 ; wait for 1 second
  9159                              <1> systime_3:
  9160                              <1> 	; eax = time
  9161 0000FEED 89C6                <1> 	mov	esi, eax
  9162                              <1> systime_4:	
  9163 0000FEEF 66A1[9C600100]      <1> 	mov	ax, [year]
  9164 0000FEF5 C1E010              <1> 	shl	eax, 16
  9165 0000FEF8 A0[A0600100]        <1> 	mov	al, [day]
  9166 0000FEFD 8A25[9E600100]      <1> 	mov	ah, [month]
  9167                              <1> 	; eax = date
  9168 0000FF03 80E301              <1> 	and	bl, 1
  9169 0000FF06 7494                <1> 	jz	short systime_0
  9170 0000FF08 96                  <1> 	xchg	esi, eax
  9171                              <1> 	; eax = time, esi = date
  9172 0000FF09 8B2D[60030300]      <1> 	mov	ebp, [u.usp]  ; EBP points to user's registers
  9173                              <1> 	; (user) edx <-- (system) esi
  9174 0000FF0F 897514              <1> 	mov	[ebp+20], esi ; return to user with EDX value 
  9175 0000FF12 EB88                <1> 	jmp	short systime_0
  9176                              <1> 
  9177                              <1> 
  9178                              <1> sysstime: ; Set System Date&Time
  9179                              <1> 	; 31/12/2017
  9180                              <1> 	; 30/12/2017 (TRDOS 386 = TRDOS v2.0) 
  9181                              <1> 	;	
  9182                              <1>         ; INPUT -> BL =
  9183                              <1> 	;	    0 = Set Date&Time in Unix/Epoch format
  9184                              <1> 	;	    1 = Set Time in MSDOS format
  9185                              <1> 	;	    2 = Set Date in MSDOS format
  9186                              <1> 	;	    3 = Set Date&Time in MSDOS format
  9187                              <1> 	;	    4 = Set System Timer (Ticks)
  9188                              <1> 	;	    5 = Convert/Save current time to/as
  9189                              <1> 	;		18.2 Hz system timer ticks
  9190                              <1> 	;	    6 = Convert MSDOS Date&Time to UNIX format
  9191                              <1> 	;		without setting system date&time ; (test)
  9192                              <1> 	;	    7 = Convert UNIX Date&Time to MSDOS format
  9193                              <1> 	;		without setting system date&time ; (test)
  9194                              <1> 	;	   8-0FFh = invalid !
  9195                              <1> 	;	  ECX = Time (or Timer) value in selected format  	
  9196                              <1> 	;	  EDX = Date value in MSDOS format if BL=2,3,6	
  9197                              <1> 	; 	
  9198                              <1> 	; OUTPUT ->
  9199                              <1> 	;	If CF = 0 ->
  9200                              <1> 	;          EAX = Set value
  9201                              <1> 	;	If CF = 1 -> (invalid BL input)
  9202                              <1> 	;	   EAX = Ticks count [TIMER_LH]	
  9203                              <1> 	;
  9204                              <1> 
  9205 0000FF14 20DB                <1> 	and	bl, bl ; 0
  9206 0000FF16 7511                <1> 	jnz	short sysstime_0
  9207 0000FF18 89C8                <1> 	mov	eax, ecx
  9208 0000FF1A E80972FFFF          <1> 	call	convert_from_epoch
  9209 0000FF1F E8B572FFFF          <1> 	call	set_rtc_date_time
  9210 0000FF24 E9A3D3FFFF          <1> 	jmp	sysret
  9211                              <1> sysstime_0:
  9212 0000FF29 80FB08              <1> 	cmp	bl, 8
  9213 0000FF2C 722D                <1> 	jb	short sysstime_1
  9214                              <1> 	; invalid input (>7)
  9215 0000FF2E A1[58640100]        <1> 	mov	eax, [TIMER_LH] ; 18.2 Hz timer ticks
  9216                              <1> 				; Note: [TIMER_LH] may be set
  9217                              <1> 				; to wrong timer value due to
  9218                              <1> 				; program functions.
  9219                              <1> 				; (This value must not be
  9220                              <1> 				; accepted as [TIMER_LH]/18.2
  9221                              <1> 				; seconds since the midnight.)
  9222 0000FF33 A3[64030300]        <1> 	mov	[u.r0], eax	
  9223 0000FF38 E96FD3FFFF          <1> 	jmp	error ; cf = 1 & [u.r0] = eax = timer ticks 
  9224                              <1> 
  9225                              <1> sysstime_8:	
  9226                              <1> 	; BL = 7
  9227 0000FF3D 89C8                <1> 	mov	eax, ecx ; seconds since 1/1/1970 00:00:00
  9228 0000FF3F E8E471FFFF          <1> 	call	convert_from_epoch
  9229 0000FF44 30E4                <1> 	xor	ah, ah
  9230 0000FF46 A0[A2600100]        <1> 	mov	al, [hour]
  9231 0000FF4B C1E010              <1> 	shl	eax, 16
  9232 0000FF4E A0[A6600100]        <1> 	mov	al, [second]
  9233 0000FF53 8A25[A4600100]      <1> 	mov	ah, [minute]
  9234 0000FF59 EB92                <1> 	jmp	short systime_3
  9235                              <1> 
  9236                              <1> sysstime_1:
  9237 0000FF5B 80FB04              <1> 	cmp	bl, 4
  9238 0000FF5E 743F                <1> 	je	short sysstime_2 ; set system timer ticks	
  9239 0000FF60 80FB05              <1> 	cmp	bl, 5
  9240 0000FF63 754B                <1> 	jne	short sysstime_4
  9241                              <1> 	; convert current time to system timer ticks (18.2Hz)
  9242 0000FF65 E89670FFFF          <1> 	call	get_rtc_date_time
  9243 0000FF6A 0FB60D[A2600100]    <1> 	movzx	ecx, byte [hour]
  9244 0000FF71 B8100E0000          <1> 	mov	eax, 60*60 ; 1 hour = 3600 seconds
  9245 0000FF76 F7E1                <1> 	mul	ecx
  9246 0000FF78 89C3                <1> 	mov	ebx, eax	
  9247 0000FF7A B13C                <1> 	mov	cl, 60  ; 1 minute = 60 seconds
  9248 0000FF7C 0FB605[A4600100]    <1> 	movzx	eax, byte [minute]
  9249 0000FF83 F7E1                <1> 	mul	ecx
  9250 0000FF85 01D8                <1> 	add	eax, ebx  
  9251 0000FF87 8A0D[A6600100]      <1> 	mov	cl, [second]
  9252 0000FF8D 01C8                <1> 	add	eax, ecx
  9253 0000FF8F B1B6                <1> 	mov	cl, 182
  9254 0000FF91 F7E1                <1> 	mul	ecx
  9255 0000FF93 83C009              <1> 	add	eax, 9
  9256 0000FF96 83D200              <1> 	adc	edx, 0
  9257 0000FF99 B10A                <1> 	mov	cl, 10
  9258 0000FF9B F7F1                <1> 	div	ecx
  9259                              <1> 	; eax = ((182*seconds)+9)/10
  9260 0000FF9D 89C1                <1> 	mov	ecx, eax
  9261                              <1> sysstime_2:
  9262 0000FF9F 890D[58640100]      <1> 	mov	[TIMER_LH], ecx ; 18.2 * seconds
  9263                              <1> sysstime_3:
  9264 0000FFA5 890D[64030300]      <1> 	mov	[u.r0], ecx
  9265 0000FFAB E91CD3FFFF          <1> 	jmp	sysret
  9266                              <1> sysstime_4:
  9267 0000FFB0 80FB06              <1> 	cmp	bl, 6
  9268 0000FFB3 7788                <1> 	ja	short sysstime_8
  9269                              <1> 
  9270 0000FFB5 890D[64030300]      <1> 	mov	[u.r0], ecx
  9271                              <1> 
  9272 0000FFBB 880D[A6600100]      <1> 	mov	[second], cl
  9273 0000FFC1 882D[A4600100]      <1> 	mov	[minute], ch
  9274 0000FFC7 C1E910              <1> 	shr	ecx, 16
  9275 0000FFCA 880D[A2600100]      <1> 	mov	[hour], cl
  9276                              <1> 	; BL = 1,2,3,6
  9277 0000FFD0 80FB01              <1> 	cmp	bl, 1
  9278 0000FFD3 762A                <1> 	jna	short sysstime_5
  9279                              <1> 	; BL = 2,3,6
  9280 0000FFD5 8815[A0600100]      <1> 	mov	[day], dl
  9281 0000FFDB 8835[9E600100]      <1> 	mov	[month], dh
  9282 0000FFE1 C1EA10              <1> 	shr	edx, 16
  9283 0000FFE4 668915[9C600100]    <1> 	mov	[year], dx
  9284 0000FFEB 80E303              <1> 	and	bl, 3
  9285 0000FFEE 742D                <1> 	jz	short sysstime_7 ; 6
  9286                              <1> 	; BL = 2,3
  9287 0000FFF0 F6C301              <1> 	test	bl, 1
  9288 0000FFF3 7419                <1> 	jz	short sysstime_6 ; 2
  9289                              <1> 	; BL = 3
  9290 0000FFF5 E8DF71FFFF          <1> 	call	set_rtc_date_time
  9291 0000FFFA E9CDD2FFFF          <1> 	jmp	sysret
  9292                              <1> sysstime_5:
  9293                              <1> 	; BL = 1
  9294 0000FFFF E81672FFFF          <1> 	call	set_time_bcd
  9295 00010004 E8A264FFFF          <1> 	call	set_rtc_time
  9296 00010009 E9BED2FFFF          <1> 	jmp	sysret	
  9297                              <1> sysstime_6:
  9298                              <1> 	; BL = 2
  9299 0001000E E8DA71FFFF          <1> 	call	set_date_bcd
  9300 00010013 E80265FFFF          <1> 	call	set_rtc_date
  9301 00010018 E9AFD2FFFF          <1> 	jmp	sysret
  9302                              <1> sysstime_7:
  9303                              <1> 	; BL = 6
  9304                              <1> 	; [year], [month], [day], 
  9305                              <1> 	; [hour], [minute], [second]
  9306 0001001D E88170FFFF          <1> 	call	convert_to_epoch
  9307 00010022 89C1                <1> 	mov	ecx, eax ; seconds since 1/1/1970 00:00:00
  9308 00010024 E97CFFFFFF          <1> 	jmp	sysstime_3
  9309                              <1> 
  9310                              <1> sysrename: ; Rename File (or Directory)
  9311                              <1> 	; 31/12/2017 (TRDOS 386 = TRDOS v2.0) 
  9312                              <1> 	;	
  9313                              <1>         ; INPUT ->
  9314                              <1>         ;          EBX = File/Directory (ASCIIZ) name address
  9315                              <1> 	;	   ECX = New name (in same dir, no path name)			
  9316                              <1> 	; OUTPUT ->
  9317                              <1> 	;          cf = 0 -> EAX = 0
  9318                              <1> 	;          cf = 1 -> Error code in AL
  9319                              <1> 
  9320 00010029 803D[B3030300]00    <1> 	cmp	byte [u.uno], 0  ; root (super user) ?
  9321 00010030 7614                <1> 	jna	short sysrename_0
  9322                              <1> 
  9323                              <1> sysrename_perm_err:
  9324                              <1> 	;mov	dword [u.r0], ERR_PERM_DENIED
  9325 00010032 B80B000000          <1> 	mov	eax, ERR_PERM_DENIED ; 'permission denied !'
  9326 00010037 A3[64030300]        <1> 	mov	[u.r0], eax
  9327 0001003C A3[C8030300]        <1> 	mov	[u.error], eax
  9328 00010041 E966D2FFFF          <1> 	jmp	error
  9329                              <1> 
  9330                              <1> sysrename_0:
  9331 00010046 51                  <1> 	push	ecx ; new file name address (in user space)
  9332 00010047 89DE                <1> 	mov	esi, ebx
  9333                              <1> 	; file name is forced, change directory as temporary
  9334                              <1> 	;mov	ax, 1
  9335                              <1> 	;mov	[FFF_Valid], ah ; 0 ; reset
  9336                              <1> 	;call	set_working_path 
  9337 00010049 E8C5060000          <1> 	call	set_working_path_x
  9338 0001004E 731E                <1> 	jnc	short sysrename_1
  9339 00010050 21C0                <1> 	and	eax, eax  ; 0 -> Bad Path!  
  9340 00010052 7505                <1> 	jnz	short sysrename_err
  9341                              <1> 	; eax = 0
  9342                              <1> sysrename_path_not_found:
  9343 00010054 B813000000          <1> 	mov	eax, ERR_INV_PATH_NAME ; 'Bad path name !'
  9344                              <1> sysrename_err:
  9345 00010059 59                  <1> 	pop	ecx ; new file name address (in user space)
  9346                              <1> sysrename_error:
  9347 0001005A A3[64030300]        <1> 	mov	[u.r0], eax
  9348 0001005F A3[C8030300]        <1> 	mov	[u.error], eax
  9349 00010064 E87F070000          <1> 	call 	reset_working_path
  9350 00010069 E93ED2FFFF          <1> 	jmp	error
  9351                              <1> sysrename_1:
  9352 0001006E B008                <1> 	mov	al, 08h ; Except volume labels (& long names)
  9353 00010070 A0[546E0100]        <1> 	mov	al, [Attributes]
  9354 00010075 2410                <1> 	and	al, 10h ;
  9355                              <1> 	;mov	esi, FindFile_Name
  9356                              <1> 	;mov	ax, 1800h ; Only files
  9357                              <1> 	;mov	ax, 0810h ; Only directories
  9358 00010077 66B80008            <1> 	mov	ax, 0800h ; Find File or Directory
  9359 0001007B E8D18DFFFF          <1> 	call	find_first_file
  9360                              <1> 	;jnc	short sysrename_2
  9361 00010080 72D7                <1> 	jc	short sysrename_err
  9362                              <1> sysrename_2:
  9363                              <1> 	; ESI = Directory Entry (FindFile_DirEntry) Location
  9364                              <1> 	; EDI = Directory Buffer Directory Entry Location
  9365                              <1> 	; EAX = File Size
  9366                              <1> 	;  BL = Attributes of The File/Directory
  9367                              <1> 	;  BH = Long Name Yes/No Status (>0 is YES)
  9368                              <1> 	;  DX > 0 : Ambiguous filename chars are used
  9369                              <1> 
  9370 00010082 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  9371 00010085 7407                <1> 	jz	short sysrename_3
  9372 00010087 B81A000000          <1> 	mov	eax, ERR_INV_FILE_NAME ; 'invalid file name !'
  9373 0001008C EBCB                <1>         jmp	short sysrename_err
  9374                              <1> sysrename_3:
  9375                              <1> 	; EDI = Directory buffer entry offset/address
  9376                              <1> 	; BL = File (or Directory) Attributes 
  9377                              <1> 	; mov	bl, [EDI+0Bh]
  9378                              <1> 
  9379 0001008E 5A                  <1> 	pop	edx ; new file name address (in user space)
  9380                              <1> 
  9381                              <1> 	; check file/directory attributes
  9382 0001008F F6C307              <1> 	test	bl, 7 ; system, hidden, readonly 
  9383 00010092 759E                <1>         jnz	short sysrename_perm_err
  9384                              <1> sysrename_4:
  9385 00010094 66817F0CA101        <1> 	cmp	word [edi+DirEntry_NTRes], 01A1h ; Singlix FS
  9386 0001009A 7496                <1> 	je	short sysrename_perm_err ; -temporary!-
  9387                              <1> 
  9388                              <1> 	; save old file name & file info (FFF structure)
  9389 0001009C BE[3E6D0100]        <1> 	mov	esi, FindFile_Drv
  9390 000100A1 BF[846E0100]        <1> 	mov	edi, SourceFile_Drv
  9391 000100A6 B920000000          <1> 	mov	ecx, 128/4
  9392 000100AB F3A5                <1> 	rep	movsd
  9393                              <1> 
  9394 000100AD 89D6                <1> 	mov	esi, edx ; new file name address (in user space)
  9395 000100AF BF[046F0100]        <1> 	mov	edi, DestinationFile_Drv
  9396 000100B4 E869AFFFFF          <1> 	call	parse_path_name
  9397 000100B9 729F                <1> 	jc	short sysrename_error ; eax = 1 (Bad file name)
  9398                              <1> 
  9399                              <1> 	; same drive ? 
  9400 000100BB A0[3E6D0100]        <1> 	mov	al, [FindFile_Drv]
  9401 000100C0 3A05[046F0100]      <1> 	cmp	al, [DestinationFile_Drv]
  9402                              <1> 	;jne	short sysrename_perm_err ; Permission denied
  9403 000100C6 7509                <1> 	jne	short sysrename_5 ; Bad file name
  9404                              <1>  
  9405                              <1> 	; no path name !? (rename file in same directory)
  9406 000100C8 803D[056F0100]20    <1> 	cmp	byte [DestinationFile_Directory], 20h
  9407 000100CF 7607                <1> 	jna	short sysrename_6
  9408                              <1> sysrename_5:
  9409 000100D1 B801000000          <1> 	mov	eax, ERR_BAD_CMD_ARG ; 1 = Bad file name 
  9410                              <1> 				     ; (Bad argument)
  9411 000100D6 EB82                <1> 	jmp	short sysrename_error
  9412                              <1> sysrename_6:
  9413 000100D8 803D[466F0100]20    <1> 	cmp	byte [DestinationFile_Name], 20h
  9414 000100DF 76F0                <1> 	jna	short sysrename_5
  9415                              <1> 
  9416 000100E1 BE[466F0100]        <1> 	mov	esi, DestinationFile_Name
  9417 000100E6 E82491FFFF          <1> 	call	check_filename ; is it a valid msdos file name?
  9418 000100EB 0F8269FFFFFF        <1> 	jc	sysrename_error ; 26 = ERR_INV_FILE_NAME 
  9419                              <1> 	
  9420                              <1> 	;mov	esi, DestinationFile_Name
  9421 000100F1 66B80008            <1> 	mov	ax, 0800h ; Find File or Directory
  9422 000100F5 E8578DFFFF          <1> 	call	find_first_file
  9423 000100FA 720A                <1> 	jc	short sysrename_7
  9424                              <1> 	
  9425 000100FC B80E000000          <1> 	mov	eax, ERR_FILE_EXISTS  ; file already exists !
  9426 00010101 E954FFFFFF          <1> 	jmp	sysrename_error	
  9427                              <1> sysrename_7:
  9428                              <1> 	; eax = 2 (File not found !)
  9429 00010106 3C02                <1> 	cmp	al, 2 ; ERR_NOT_FOUND
  9430 00010108 0F854CFFFFFF        <1> 	jne	sysrename_error
  9431                              <1> 
  9432                              <1> 	; 31/12/2017
  9433                              <1> 	; Following code is also part of 'rename_file' in
  9434                              <1> 	; 'trdosk3.s' (MainProg's 'rename' command) ; 13/11/2017
  9435 0001010E BE[466F0100]        <1> 	mov	esi, DestinationFile_Name ; (Rename_NewName)
  9436 00010113 668B0D[FE6E0100]    <1> 	mov	cx, [SourceFile_DirEntryNumber] 
  9437 0001011A 66A1[EA6E0100]      <1> 	mov	ax, [SourceFile_DirEntry+20] ; First Cluster, HW 
  9438 00010120 C1E010              <1> 	shl	eax, 16
  9439 00010123 66A1[F06E0100]      <1> 	mov	ax, [SourceFile_DirEntry+26] ; First Cluster, LW 
  9440 00010129 0FB61D[D36E0100]    <1>   	movzx	ebx, byte [SourceFile_LongNameEntryLength]  
  9441 00010130 E835B7FFFF          <1>    	call	rename_directory_entry
  9442 00010135 0F821FFFFFFF        <1> 	jc	sysrename_error
  9443                              <1> 	;xor	eax, eax
  9444 0001013B A3[64030300]        <1> 	mov	[u.r0], eax ; 0
  9445                              <1> 	;mov	[u.error], eax
  9446 00010140 E8A3060000          <1> 	call 	reset_working_path
  9447 00010145 E982D1FFFF          <1> 	jmp	sysret
  9448                              <1> 
  9449                              <1> sysmem: ; Get Total&Free Memory amount 
  9450                              <1> 	; 31/12/2017 (TRDOS 386 = TRDOS v2.0) 
  9451                              <1> 	;	
  9452                              <1>         ; INPUT -> 
  9453                              <1> 	;	none	
  9454                              <1> 	; OUTPUT ->
  9455                              <1> 	;	EAX = Total memory count (in bytes)
  9456                              <1> 	;	EBX = Virtually available memory amount (in bytes)
  9457                              <1> 	;	      = 4GB - CORE (4MB)	
  9458                              <1> 	;	ECX = Free memory count (in bytes)
  9459                              <1> 	;	EDX = Calculated free memory count (in bytes)
  9460                              <1> 	
  9461 0001014A A1[DC630100]        <1> 	mov	eax, [memory_size] ; in pages
  9462 0001014F C1E00C              <1> 	shl	eax, 12		   ; in bytes
  9463 00010152 A3[64030300]        <1> 	mov	[u.r0], eax
  9464 00010157 E8C23BFFFF          <1> 	call	calc_free_mem
  9465                              <1> 	; edx = calculated free pages
  9466                              <1> 	; ecx = 0
  9467 0001015C 8B2D[60030300]      <1> 	mov	ebp, [u.usp]  ; EBP points to user's registers
  9468 00010162 C745100000C0FF      <1> 	mov	dword [ebp+16], ECORE ; EBX (for user)
  9469                              <1> 				; 0FFC00000h ; 4GB - 4MB
  9470 00010169 C1E20C              <1> 	shl	edx, 12
  9471 0001016C 895514              <1> 	mov	[ebp+20], edx ; EDX (for user)
  9472 0001016F 8B0D[E0630100]      <1> 	mov 	ecx, [free_pages]
  9473 00010175 C1E10C              <1> 	shl	ecx, 12	; free bytes
  9474 00010178 894D18              <1> 	mov	[ebp+24], ecx ; ECX (for user)
  9475                              <1> 	;mov	[free_pages], edx	
  9476 0001017B E94CD1FFFF          <1> 	jmp	sysret
  9477                              <1> 
  9478                              <1> sysprompt:
  9479                              <1> 	; Set TRDOS 386 Command Interpreter (MainProg) prompt 
  9480                              <1> 	; 31/12/2017 (TRDOS 386 = TRDOS v2.0) 
  9481                              <1> 	;	
  9482                              <1>         ; INPUT -> 
  9483                              <1> 	;	EBX = 0 -> use default prompt
  9484                              <1> 	;	EBX > 0 -> prompt string (ASCIIZ) address
  9485                              <1> 	;		  (Max. 11 characters except ZERO tail)	
  9486                              <1> 	; OUTPUT ->
  9487                              <1> 	;	(EAX = 0)
  9488                              <1> 	;	CF = 0 -> Successful
  9489                              <1> 	;	CF = 1 -> Failed
  9490                              <1> 
  9491 00010180 21DB                <1> 	and	ebx, ebx
  9492 00010182 750A                <1> 	jnz	short sysprompt_0
  9493                              <1> 
  9494 00010184 E8CC86FFFF          <1> 	call	default_command_prompt ; '['+'TRDOS'+']'
  9495 00010189 E93ED1FFFF          <1> 	jmp	sysret
  9496                              <1> 
  9497                              <1> sysprompt_0:
  9498 0001018E 31C0                <1> 	xor	eax, eax
  9499 00010190 A3[64030300]        <1> 	mov	[u.r0], eax 
  9500 00010195 89DE                <1> 	mov	esi, ebx
  9501 00010197 B90C000000          <1> 	mov	ecx, 12
  9502 0001019C 89E5                <1> 	mov	ebp, esp
  9503 0001019E 29CC                <1> 	sub	esp, ecx
  9504 000101A0 49                  <1> 	dec	ecx ; 11
  9505 000101A1 89E7                <1> 	mov	edi, esp
  9506 000101A3 E833F1FFFF          <1> 	call	transfer_from_user_buffer
  9507 000101A8 7211                <1> 	jc	short sysprompt_err
  9508 000101AA 803E20              <1> 	cmp	byte [esi], 20h
  9509 000101AD 760C                <1> 	jna	short sysprompt_err
  9510 000101AF E8B386FFFF          <1> 	call	set_command_prompt
  9511 000101B4 89EC                <1> 	mov	esp, ebp
  9512 000101B6 E911D1FFFF          <1> 	jmp	sysret
  9513                              <1> sysprompt_err:
  9514                              <1> syspath_err:
  9515 000101BB 89EC                <1> 	mov	esp, ebp
  9516 000101BD E9EAD0FFFF          <1> 	jmp	error
  9517                              <1> 
  9518                              <1> syspath:
  9519                              <1> 	; Get/Set Run Path
  9520                              <1> 	; 31/12/2017 (TRDOS 386 = TRDOS v2.0) 
  9521                              <1> 	;	
  9522                              <1>         ; INPUT -> 
  9523                              <1> 	;	EBX = 0 -> get path (to buffer address in ECX)
  9524                              <1> 	;	EBX > 0 -> set path
  9525                              <1> 	;	    EBX = Path string buffer address (ASCIIZ)
  9526                              <1> 	;	    	  (Path description except 'PATH=')
  9527                              <1> 	;	ECX = Buffer address (if EBX = 0)
  9528                              <1> 	;	      (ECX will not be used if EBX > 0)	
  9529                              <1> 	;	DL = Buffer size (0 = 256 byte)	
  9530                              <1> 	;
  9531                              <1> 	; OUTPUT ->
  9532                              <1> 	;	CF = 0 -> Successful (EAX = String length)
  9533                              <1> 	;	CF = 1 -> Failed (EAX = 0)
  9534                              <1> 	;
  9535                              <1> 	; NOTE: 'PATH=' or 'PATH' must be excluded
  9536                              <1> 	;  (It must not be at the beginning of the string.)
  9537                              <1> 
  9538 000101C2 89E5                <1> 	mov	ebp, esp
  9539 000101C4 81EC00010000        <1> 	sub	esp, 256
  9540 000101CA 89E7                <1> 	mov	edi, esp
  9541                              <1> 
  9542 000101CC 31C0                <1> 	xor	eax, eax
  9543 000101CE A3[64030300]        <1> 	mov	[u.r0], eax 
  9544                              <1> 	
  9545 000101D3 21DB                <1> 	and	ebx, ebx
  9546 000101D5 752E                <1> 	jnz	short syspath_0
  9547                              <1> 
  9548                              <1> 	; EBX = 0 -> get run path
  9549 000101D7 89CB                <1> 	mov	ebx, ecx ; buffer addr (in user's mem space)
  9550 000101D9 BE[C2180100]        <1> 	mov	esi, Cmd_Path  ; 'PATH' address
  9551 000101DE 0FB6CA              <1> 	movzx	ecx, dl
  9552 000101E1 80E901              <1> 	sub	cl, 1 ; 0 -> 255, 1 -> 0
  9553 000101E4 6683D101            <1> 	adc	cx, 1 ; 255 -> 256, 0 -> 1
  9554                              <1> 	; EDI = Output buffer 
  9555                              <1> 	; CX = Buffer length
  9556                              <1> 	; AL = 0 -> use ASCIIZ word in [ESI]
  9557                              <1> 	; ESI = 'PATH' address (with zero tail)
  9558 000101E8 E8AE9EFFFF          <1> 	call	get_environment_string
  9559 000101ED 72CC                <1> 	jc	short syspath_err
  9560 000101EF 89DF                <1> 	mov	edi, ebx ; User's buffer address
  9561 000101F1 89E6                <1> 	mov	esi, esp 
  9562                              <1> 	; EDI = User's buffer address
  9563                              <1> 	; ECX = transfer (byte) count
  9564 000101F3 E899F0FFFF          <1> 	call	transfer_to_user_buffer
  9565 000101F8 72C1                <1> 	jc	short syspath_err
  9566 000101FA 890D[64030300]      <1> 	mov	[u.r0], ecx 
  9567 00010200 E9C7D0FFFF          <1> 	jmp	sysret
  9568                              <1> 
  9569                              <1> syspath_0:
  9570 00010205 89DE                <1> 	mov	esi, ebx
  9571 00010207 0FB6CA              <1> 	movzx	ecx, dl
  9572 0001020A 80E901              <1> 	sub	cl, 1 ; 0 -> 255, 1 -> 0
  9573 0001020D 6683D101            <1> 	adc	cx, 1 ; 255 -> 256, 0 -> 1
  9574 00010211 E8C5F0FFFF          <1> 	call	transfer_from_user_buffer
  9575 00010216 72A3                <1> 	jc	short syspath_err
  9576                              <1> 	;(*) 'PATH=' will be added to 
  9577                              <1> 	;         the head of the string
  9578 00010218 83EC08              <1> 	sub	esp, 8 ;(*)
  9579 0001021B 89FE                <1> 	mov	esi, edi ;(*)
  9580 0001021D E85D9EFFFF          <1> 	call	set_path_x ;(*)
  9581 00010222 7297                <1> 	jc	short syspath_err
  9582 00010224 8915[64030300]      <1> 	mov	[u.r0], edx ; run path string length
  9583 0001022A E99DD0FFFF          <1> 	jmp	sysret	
  9584                              <1> 
  9585                              <1> sysenv:
  9586                              <1> 	; Get/Set Environment Variables
  9587                              <1> 	; 31/12/2017 (TRDOS 386 = TRDOS v2.0) 
  9588                              <1> 	;	
  9589                              <1>         ; INPUT -> 
  9590                              <1> 	;	EBX = 0 -> get (all) environment variables
  9591                              <1> 	;	      (Required Buffer length = 512 bytes)
  9592                              <1> 	;	EBX > 0 -> set (one) environment variable
  9593                              <1> 	;	      (If there is not a '=' after
  9594                              <1> 	;	      the environment variable name, it will
  9595                              <1> 	;	      accepted as 'get environment variable'.) 
  9596                              <1> 	;	       EBX = Buffer address
  9597                              <1> 	;	ECX = Buffer address (if EBX = 0)
  9598                              <1> 	;	      (ECX will not be used if EBX > 0)	
  9599                              <1> 	;	      (Note: Buffer size is 512 bytes.)	
  9600                              <1> 	;	DL = Buffer size (0 = 256 byte)
  9601                              <1> 	;	     (For one envrionment variable)		
  9602                              <1> 	;
  9603                              <1> 	; OUTPUT ->
  9604                              <1> 	;	(EAX = 0)
  9605                              <1> 	;	CF = 0 -> Successful (EAX = String length)
  9606                              <1> 	;	CF = 1 -> Failed (EAX = 0)
  9607                              <1> 	;
  9608                              <1> 	; Note: Environment variable name, for example,
  9609                              <1> 	;	'PATH=' must be included at the beginning
  9610                              <1> 	;	of the environment string. If the variable
  9611                              <1> 	;	name is as 'PATH' but it is not as 'PATH='
  9612                              <1> 	;	the variable string (row) will be returned.
  9613                              <1> 	;	If variable name is as 'PATH=' but there is
  9614                              <1> 	;	not a following text after the variable name,
  9615                              <1> 	;	the environment variable will be reset/deleted.
  9616                              <1> 
  9617 0001022F 89E5                <1> 	mov	ebp, esp
  9618 00010231 81EC00020000        <1> 	sub	esp, 512
  9619 00010237 89E7                <1> 	mov	edi, esp
  9620                              <1> 
  9621 00010239 31C0                <1> 	xor	eax, eax
  9622 0001023B A3[64030300]        <1> 	mov	[u.r0], eax 
  9623                              <1> 	
  9624 00010240 21DB                <1> 	and	ebx, ebx
  9625 00010242 7524                <1> 	jnz	short sysenv_0
  9626                              <1> 
  9627                              <1> 	; EBX = 0 -> get (all) environment variables
  9628 00010244 89EC                <1> 	mov	esp, ebp
  9629 00010246 BE00300900          <1> 	mov	esi, Env_Page  ; Environment page
  9630 0001024B 89CF                <1> 	mov	edi, ecx ; buffer addr (in user's mem space)
  9631 0001024D B900020000          <1> 	mov	ecx, 512
  9632 00010252 E83AF0FFFF          <1> 	call	transfer_to_user_buffer
  9633 00010257 0F824FD0FFFF        <1> 	jc	error
  9634 0001025D 890D[64030300]      <1> 	mov	[u.r0], ecx 
  9635 00010263 E964D0FFFF          <1> 	jmp	sysret
  9636                              <1> 
  9637                              <1> sysenv_0:
  9638 00010268 89DE                <1> 	mov	esi, ebx ; * ; user's buffer address
  9639 0001026A 0FB6CA              <1> 	movzx	ecx, dl
  9640 0001026D 80E901              <1> 	sub	cl, 1 ; 0 -> 255, 1 -> 0
  9641 00010270 6683D101            <1> 	adc	cx, 1 ; 255 -> 256, 0 -> 1
  9642 00010274 E862F0FFFF          <1> 	call	transfer_from_user_buffer
  9643 00010279 723F                <1> 	jc	short sysenv_err
  9644 0001027B 89FE                <1> 	mov	esi, edi
  9645 0001027D 8A06                <1> 	mov	al, [esi]
  9646 0001027F 3C20                <1> 	cmp	al, 20h
  9647 00010281 7637                <1> 	jna	short sysenv_err
  9648 00010283 3C3D                <1> 	cmp	al, '='
  9649 00010285 7433                <1> 	je	short sysenv_err
  9650 00010287 56                  <1> 	push	esi
  9651                              <1> sysenv_1:
  9652 00010288 46                  <1> 	inc	esi
  9653 00010289 803E3D              <1> 	cmp	byte [esi], '='
  9654 0001028C 7433                <1> 	je	short sysenv_3
  9655 0001028E 803E20              <1> 	cmp	byte [esi], 20h
  9656 00010291 73F5                <1> 	jnb	short sysenv_1
  9657 00010293 C60600              <1> 	mov	byte [esi], 0 
  9658 00010296 5E                  <1> 	pop	esi
  9659                              <1> 	; EDI = Output buffer 
  9660                              <1> 	; CX = Buffer length
  9661 00010297 30C0                <1> 	xor	al, al
  9662                              <1> 	; AL = 0 -> use ASCIIZ word in [ESI]
  9663                              <1> 	; ESI = Environment variable name address
  9664 00010299 E8FD9DFFFF          <1> 	call	get_environment_string
  9665 0001029E 721A                <1> 	jc	short sysenv_err
  9666 000102A0 89DF                <1> 	mov	edi, ebx ; * ; user's buffer address
  9667 000102A2 89C1                <1> 	mov	ecx, eax ; String length
  9668 000102A4 89E6                <1> 	mov	esi, esp 
  9669                              <1> 	; ESI = system buffer address
  9670                              <1> 	; EDI = User's buffer address
  9671                              <1> 	; ECX = transfer (byte) count
  9672 000102A6 E8E6EFFFFF          <1> 	call	transfer_to_user_buffer
  9673 000102AB 720D                <1> 	jc	short sysenv_err
  9674 000102AD 890D[64030300]      <1> 	mov	[u.r0], ecx ; transfer (byte) count
  9675                              <1> sysenv_2:
  9676 000102B3 89EC                <1> 	mov	esp, ebp
  9677 000102B5 E912D0FFFF          <1> 	jmp	sysret
  9678                              <1> sysenv_err:
  9679 000102BA 89EC                <1> 	mov	esp, ebp
  9680 000102BC E9EBCFFFFF          <1> 	jmp	error
  9681                              <1> sysenv_3:
  9682 000102C1 46                  <1> 	inc	esi
  9683 000102C2 803E20              <1> 	cmp	byte [esi], 20h
  9684 000102C5 73FA                <1> 	jnb	short sysenv_3
  9685 000102C7 C60600              <1> 	mov	byte [esi], 0	
  9686 000102CA 5E                  <1> 	pop	esi
  9687 000102CB E88E9EFFFF          <1> 	call	set_environment_string
  9688 000102D0 72E8                <1> 	jc	short sysenv_err
  9689 000102D2 8915[64030300]      <1> 	mov	[u.r0], edx
  9690 000102D8 EBD9                <1> 	jmp	short sysenv_2
  9691                              <1> 
  9692                              <1> 
  9693                              <1> ; temporary - 24/01/2016
  9694                              <1> 
  9695                              <1> iget:
  9696 000102DA C3                  <1> 	retn
  9697                              <1> isintr:
  9698 000102DB C3                  <1> 	retn
  9699                              <1> iopen:
  9700 000102DC C3                  <1> 	retn
  9701                              <1> iclose:
  9702 000102DD C3                  <1> 	retn
  9703                              <1> sndc:
  9704 000102DE C3                  <1> 	retn
  9705                              <1> access:
  9706 000102DF C3                  <1> 	retn
  9707                              <1> sleep:
  9708 000102E0 C3                  <1> 	retn
  3036                                  %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 000102E1 807E0500            <1> 	cmp	byte [esi+LD_LBAYes], 0
    20 000102E5 777B                <1>         ja      short lba_write
    21                              <1> 
    22                              <1> chs_write:
    23                              <1> 	; 25/02/2016
    24                              <1> 	; 23/02/2016
    25 000102E7 C605[8D6C0100]03    <1> 	mov	byte [disk_rw_op], 3 ; CHS write
    26 000102EE 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 000102F0 807E0500            <1> 	cmp	byte [esi+LD_LBAYes], 0
    47 000102F4 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 000102F6 C605[8D6C0100]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 000102FD C605[8E6C0100]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 00010304 50                  <1> 	push	eax			; Linear sector #
    80 00010305 51                  <1> 	push	ecx			; # of FAT/FILE/DIR sectors
    81                              <1>                 
    82 00010306 0FB74E1E            <1> 	movzx	ecx, word [esi+LD_BPB+SecPerTrack]
    83                              <1> 	;movzx	ecx, byte [disk_rw_spt] ; 23/02/2016
    84 0001030A 29D2                <1> 	sub	edx, edx
    85 0001030C 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 0001030E 6689D1              <1> 	mov	cx, dx			; Sector (zero based)
    90 00010311 6641                <1> 	inc	cx			; To make it 1 based
    91 00010313 6651                <1> 	push	cx
    92 00010315 668B4E20            <1> 	mov	cx, [esi+LD_BPB+Heads]
    93 00010319 6629D2              <1> 	sub	dx, dx
    94 0001031C F7F1                <1> 	div	ecx			; Convert track to head & cyl
    95                              <1> 	; eax (ax) = cylinder, dx (dl) = head (max. FFh)
    96 0001031E 88D6                <1> 	mov	dh, dl
    97 00010320 6659                <1> 	pop	cx			; AX=Cyl, DH=Head, CX=Sector
    98 00010322 8A5602              <1> 	mov	dl, [esi+LD_PhyDrvNo]
    99                              <1> 
   100 00010325 88C5                <1> 	mov	ch, al			; NOTE: max. 1023 cylinders !                   
   101 00010327 C0CC02              <1> 	ror	ah, 2			; Rotate 2 bits right
   102 0001032A 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 0001032C B001                <1> 	mov	al, 1 ; 25/02/2016
   113 0001032E 8A25[8D6C0100]      <1> 	mov	ah, [disk_rw_op]  ; 02h = chs read, 03h = chs write 
   114                              <1> 	;
   115 00010334 E8C148FFFF          <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 00010339 8825[8F6C0100]      <1> 	mov	[disk_rw_err], ah
   122                              <1> 	
   123 0001033F 59                  <1> 	pop	ecx
   124 00010340 58                  <1> 	pop	eax
   125 00010341 7314                <1> 	jnc	short chs_read_ok
   126                              <1> 
   127 00010343 803D[8F6C0100]09    <1> 	cmp	byte [disk_rw_err], 09h ; DMA crossed 64K segment boundary
   128 0001034A 7408                <1> 	je	short chs_read_error_retn
   129                              <1>              
   130 0001034C FE0D[8E6C0100]      <1> 	dec	byte [retry_count]
   131 00010352 75B0                <1> 	jnz	short chs_read_retry
   132                              <1> 
   133                              <1> chs_read_error_retn:
   134 00010354 F9                  <1> 	stc
   135                              <1> 	;retn
   136 00010355 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 00010357 40                  <1> 	inc	eax ; next sector
   154 00010358 81C300020000        <1> 	add	ebx, 512
   155 0001035E E29D                <1> 	loop	chs_read_next_sector
   156 00010360 EB5E                <1> 	jmp	short update_drv_error_byte
   157                              <1> 
   158                              <1> lba_write:
   159                              <1> 	; 23/02/2016
   160 00010362 C605[8D6C0100]1C    <1> 	mov	byte [disk_rw_op], 1Ch ; LBA write
   161 00010369 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 0001036B C605[8D6C0100]1B    <1> 	mov	byte [disk_rw_op], 1Bh ; LBA read
   185                              <1> 
   186                              <1> lba_rw:
   187                              <1> 	; 17/02/2016
   188 00010372 57                  <1> 	push	edi
   189                              <1> 
   190 00010373 890D[906C0100]      <1> 	mov	[sector_count], ecx ; total sector (read) count
   191                              <1> 
   192 00010379 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 0001037C 81F900010000        <1> 	cmp	ecx, 256
   197 00010382 7605                <1> 	jna	short lba_read_rsc
   198 00010384 B900010000          <1> 	mov	ecx, 256 ; 17/02/2016
   199                              <1> lba_read_rsc:
   200 00010389 290D[906C0100]      <1> 	sub	[sector_count], ecx ; remain sectors
   201                              <1> 
   202 0001038F 89CF                <1> 	mov	edi, ecx 
   203 00010391 89C1                <1> 	mov	ecx, eax ; sector number/address
   204                              <1> 
   205 00010393 C605[8E6C0100]04    <1> 	mov	byte [retry_count], 4
   206                              <1> lba_read_retry:
   207 0001039A 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 0001039C 8A25[8D6C0100]      <1> 	mov	ah, [disk_rw_op] ; 1Bh = LBA read, 1Ch = LBA write
   217 000103A2 E85348FFFF          <1> 	call	int13h
   218                              <1> 	; al = ? (changed)
   219                              <1> 	; ah = error code
   220 000103A7 8825[8F6C0100]      <1> 	mov	[disk_rw_err], ah
   221 000103AD 7334                <1> 	jnc	short lba_read_ok
   222 000103AF 80FC80              <1> 	cmp	ah, 80h ; time out?
   223 000103B2 740A                <1>         je      short lba_read_stc_retn
   224 000103B4 FE0D[8E6C0100]      <1> 	dec	byte [retry_count]
   225 000103BA 7FDE                <1> 	jg	short lba_read_retry
   226 000103BC 743A                <1> 	jz	short lba_read_reset
   227                              <1> 	; sf =  1
   228                              <1> 
   229                              <1> lba_read_stc_retn:
   230 000103BE F9                  <1> 	stc
   231                              <1> lba_read_retn:
   232 000103BF 5F                  <1> 	pop	edi
   233                              <1> 
   234                              <1> update_drv_error_byte:
   235 000103C0 9C                  <1> 	pushf
   236 000103C1 53                  <1> 	push	ebx
   237 000103C2 6651                <1> 	push	cx
   238                              <1> 	;or	ecx, ecx
   239                              <1> 	;jz	short udrv_errb0
   240 000103C4 8A0D[8F6C0100]      <1> 	mov	cl, [disk_rw_err]
   241                              <1> udrv_errb0:
   242 000103CA 0FB65E02            <1> 	movzx	ebx, byte [esi+LD_PhyDrvNo]
   243 000103CE 80FB02              <1> 	cmp	bl, 2
   244 000103D1 7203                <1>         jb      short udrv_errb1
   245 000103D3 80EB7E              <1> 	sub	bl, 7Eh
   246                              <1> 	;cmp	bl, 5
   247                              <1> 	;ja	short udrv_errb2	
   248                              <1> udrv_errb1:
   249 000103D6 81C3[21680000]      <1>         add     ebx, drv.error ; 13/02/2016
   250 000103DC 880B                <1> 	mov	[ebx], cl ; error code
   251                              <1> udrv_errb2:
   252 000103DE 6659                <1> 	pop	cx
   253 000103E0 5B                  <1> 	pop	ebx
   254 000103E1 9D                  <1> 	popf
   255 000103E2 C3                  <1> 	retn
   256                              <1> 
   257                              <1> lba_read_ok:
   258 000103E3 89C8                <1> 	mov	eax, ecx ; sector number
   259 000103E5 01F8                <1> 	add	eax, edi ; sector number (next)
   260 000103E7 C1E709              <1> 	shl	edi, 9 ; sector count * 512
   261 000103EA 01FB                <1> 	add	ebx, edi ; next buffer offset
   262                              <1> 
   263 000103EC 8B0D[906C0100]      <1> 	mov	ecx, [sector_count] ; remaining sectors
   264 000103F2 09C9                <1> 	or	ecx, ecx
   265 000103F4 7586                <1> 	jnz	short lba_read_next
   266 000103F6 EBC7                <1> 	jmp	short lba_read_retn
   267                              <1> 
   268                              <1> lba_read_reset:
   269 000103F8 B40D                <1> 	mov	ah, 0Dh ; Alternate reset
   270 000103FA E8FB47FFFF          <1>         call	int13h
   271                              <1> 	; al = ? (changed)
   272                              <1> 	; ah = error code
   273 000103FF 7399                <1> 	jnc	short lba_read_retry
   274 00010401 EBBC                <1> 	jmp	short lba_read_retn
  3037                                  %include 'trdosk8.s' ; 24/01/2016
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.2) - MAIN PROGRAM : trdosk8.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 03/08/2020
     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> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    14                              <1> ; TRDOS2.ASM (09/11/2011)
    15                              <1> ; ----------------------------------------------------------------------------
    16                              <1> ; DIR.ASM (c) 2004-2011 Erdogan TAN  [07/01/2004] Last Update: 09/10/2011
    17                              <1> 
    18                              <1> set_run_sequence:
    19                              <1> 	; 23/12/2016
    20                              <1> 	; 10/06/2016
    21                              <1> 	; 22/05/2016
    22                              <1> 	; 20/05/2016
    23                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
    24                              <1> 	; TRDOS 386 feature only !
    25                              <1> 	;
    26                              <1> 	; INPUT ->
    27                              <1> 	;	AL = process number (next process)
    28                              <1> 	;
    29                              <1> 	;	this process must be added to run sequence
    30                              <1> 	;
    31                              <1> 	;	[u.pri] = priority of present process
    32                              <1> 	;
    33                              <1> 	;	DL = priority (queue)
    34                              <1> 	;	     0 = background (low) ; run on background 
    35                              <1> 	;	     1 = regular (normal) ; run as regular
    36                              <1> 	;	     2 = event (high)     ; run for event
    37                              <1> 	;
    38                              <1> 	;	1) If the requested process is already running:
    39                              <1> 	;	   a) If present priority is high ([u.pri]=2) 
    40                              <1> 	;	      and requested priority is also high, 
    41                              <1> 	;	      there is nothing to do! Because it has been
    42                              <1> 	;	      done already (before this attempt).		 	
    43                              <1> 	;	   b) If present priority is high ([u.pri]=2)
    44                              <1> 	;	      and requested priority is not high, there is
    45                              <1> 	;	      nothing to do! Because, it's current
    46                              <1> 	;	      run queue is unspecified, here. (It may be in
    47                              <1> 	;	      a waiting list or in a run queue; if the new
    48                              <1> 	;	      priority would be used to add it to relavant
    49                              <1>         ;             run queue, this would be wrong, unnecessary
    50                              <1> 	;	      and destabilizing duplication!)
    51                              <1> 	;	   c) If present priority is not high ([u.pri]<2)
    52                              <1>         ;             and requested priority is high (event),
    53                              <1> 	;	      process will be added to present priority's
    54                              <1> 	;	      run queue and then, priority will be changed
    55                              <1> 	;	      to high ([u.pri]=2).
    56                              <1> 	;	   d) If present priority is not high ([u.pri]<2)
    57                              <1> 	;	      and requested priority is not high, [u.pri]
    58                              <1> 	;	      value will be changed. There is nothing to do
    59                              <1> 	;	      in addition. (The new priority value will be
    60                              <1> 	;	      used by 'tswap/tswitch' procedure at 'sysret'
    61                              <1> 	;	      or 'sysrele' stage.)
    62                              <1> 	;
    63                              <1> 	;	2) If the requested process is not running:
    64                              <1> 	;	   a) If requested priority of the requested
    65                              <1> 	;	      (next) process is high (event) and priority
    66                              <1> 	;	      of present process is not high, the requested
    67                              <1> 	;	      process will be added to ('runq_event') high
    68                              <1> 	;	      priority run queue and then present (running)
    69                              <1> 	;	      process will be stopped (swapped/switched out)
    70                              <1> 	;	      immediately if it is in user mode, or it's 
    71                              <1> 	;	      [u.quant] value will be reset to 0 and (then) 
    72                              <1> 	;	      it will be stopped at 'sysret' stage.			
    73                              <1> 	;	   b) If requested priority of the requested
    74                              <1> 	;	      (next) process is high (event) and priority
    75                              <1> 	;	      of present process is also high, the requested
    76                              <1> 	;	      process will be added to ('runq_event') high
    77                              <1> 	;	      priority run queue and present (running) 
    78                              <1> 	;	      process will be allowed to run until it's 
    79                              <1> 	;	      time quantum will be elapsed ([u.quant]=0).	
    80                              <1> 	;	   c) If requested priority of the requested
    81                              <1> 	;	      (next) process is not high ('run for event'), 
    82                              <1> 	;	      there is nothing to do. Because, it's current
    83                              <1> 	;	      run queue is unspecified, here. (It may be in
    84                              <1> 	;	      a waiting list or in a run queue; if the new
    85                              <1> 	;	      priority would be used to add it to relavant
    86                              <1>         ;             run queue, this would be wrong, unnecessary
    87                              <1> 	;	      and destabilizing duplication!) 
    88                              <1> 	;
    89                              <1> 	; OUTPUT ->
    90                              <1> 	;	none
    91                              <1> 	;
    92                              <1> 	;	[u.pri] = priority of present process
    93                              <1> 	;
    94                              <1> 	;	cf = 1, if the request could not be fulfilled.
    95                              <1> 	;			 	     	  
    96                              <1> 	;	NOTE: 
    97                              <1>         ;          * Processes in 'run as regular' queue can run
    98                              <1> 	;	     if there is no process in 'run for event' queue
    99                              <1> 	;	     ('run for event' processes have higher priority)	 		 
   100                              <1> 	;	   * When [u.quant] time quantum of a process is
   101                              <1> 	;	     elapsed, it's high priority ('run for event')
   102                              <1> 	;	     status will be disabled, it can be run in sequence
   103                              <1> 	;	     of it's actual run queue.
   104                              <1> 	;	   * A 'run on background' process will always be 
   105                              <1> 	;	     sequenced in 'run on background' (low priority)
   106                              <1> 	;	     queue, it can run only when other priority queues
   107                              <1> 	;	     are empty. (idle time processes, e.g. printing)  	 	
   108                              <1> 	;
   109                              <1> 	; Modified registers: eax, ebx, edx
   110                              <1> 	;
   111                              <1> 
   112                              <1> srunseq_0:
   113 00010403 3A05[B3030300]      <1>         cmp     al, [u.uno]     ; same process ?
   114 00010409 750C                <1> 	jne	short srunseq_2 ; no
   115                              <1> 
   116 0001040B 8A25[A9030300]      <1> 	mov	ah, [u.pri] 	; present/current priority
   117 00010411 80FC02              <1> 	cmp	ah, 2       	; 'run for event' priority level
   118 00010414 7221                <1> 	jb	short srunseq_6 ; no
   119                              <1> 
   120                              <1> srunseq_1:
   121                              <1> 	; there is nothing to do!
   122 00010416 C3                  <1> 	retn
   123                              <1> 
   124                              <1> srunseq_2:
   125                              <1> 	;;this not necessary ! 23/12/2016
   126                              <1>         ;;cmp	al, nproc	; number of processes = 16 
   127                              <1> 	;;jnb	short srunseq_5	; error ! invalid process number 
   128                              <1> 
   129                              <1> 	; dl = priority
   130 00010417 80FA02              <1> 	cmp	dl, 2 		; event queue
   131 0001041A 72FA                <1> 	jb	short srunseq_1 ; requested process is not present
   132                              <1> 				; process and priority of requested
   133                              <1> 				; process is not high (event), 
   134                              <1> 				; there is nothing to do!
   135                              <1> 	
   136                              <1> 	; requested process is not present process
   137                              <1> 	; & priority of requested process is high
   138 0001041C 3A15[A9030300]      <1> 	cmp	dl, [u.pri] 	; priority of present process
   139 00010422 7606                <1> 	jna	short srunseq_3 ; is high, also
   140                              <1> 	;
   141                              <1> 	; present process will be swapped/switched out
   142 00010424 FE05[69700100]      <1> 	inc	byte [p_change] ; 1
   143                              <1> 
   144                              <1> srunseq_3:
   145                              <1> 	; add process to 'runq_event' queue for new event
   146 0001042A BB[52030300]        <1> 	mov	ebx, runq_event ; high priority run queue
   147                              <1> 
   148                              <1> srunseq_4:
   149                              <1> 	; al = process number
   150                              <1> 	; ebx = run queue
   151 0001042F E881EDFFFF          <1> 	call	putlu
   152 00010434 C3                  <1> 	retn
   153                              <1> 
   154                              <1> srunseq_5:
   155 00010435 F5                  <1> 	cmc
   156 00010436 C3                  <1> 	retn
   157                              <1> 
   158                              <1> srunseq_6:
   159                              <1> 	; present priority of the process is not high
   160                              <1> 	
   161 00010437 8815[A9030300]      <1> 	mov	[u.pri], dl ; new priority 
   162                              <1> 			    ; (will be used by 'tswap')
   163                              <1> 
   164 0001043D 80FA02              <1> 	cmp	dl, 2 		; high priority ?
   165 00010440 72F3                <1> 	jb	short srunseq_5 ; no, there is nothing to do
   166                              <1> 				; in addition
   167                              <1> 
   168                              <1> 	; process must be added to relevant run queue, here!
   169                              <1> 	; (new priority is high/event priority and process
   170                              <1> 	; will not be added to a run queue by 'tswap')
   171                              <1> 
   172 00010442 BB[54030300]        <1> 	mov	ebx, runq_normal ; 'run as regular' queue
   173                              <1> 
   174 00010447 20E4                <1> 	and	ah, ah  ;  previous value of [u.pri]
   175 00010449 75E4                <1> 	jnz	short srunseq_4
   176                              <1> 
   177 0001044B 43                  <1> 	inc	ebx
   178 0001044C 43                  <1> 	inc	ebx
   179                              <1> 	; ebx = runq_background ; 'run on backgroud' queue 
   180                              <1> 
   181 0001044D EBE0                <1> 	jmp	short srunseq_4
   182                              <1> clock:
   183                              <1> 	; 23/05/2016
   184                              <1> 	; 22/05/2016
   185                              <1> 	; 20/05/2016
   186                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
   187                              <1> 	; 14/05/2015 - 14/10/2015 (Retro UNIX 386 v1)
   188                              <1> 	; 07/12/2013 - 10/04/2014 (Retro UNIX 8086 v1)
   189                              <1> 
   190 0001044F 803D[A8030300]00    <1> 	cmp	byte [u.quant], 0
   191 00010456 772C                <1> 	ja	short clk_1
   192                              <1> 	;
   193 00010458 803D[B3030300]01    <1> 	cmp     byte [u.uno], 1 ; /etc/init ? (for Retro UNIX 8086 & 386 v1)
   194                              <1> 				; MainProg (Kernel's Command Interpreter)
   195                              <1> 				; for TRDOS 386.
   196 0001045F 7623                <1> 	jna	short clk_1 ; yes, do not swap out
   197                              <1> 	;
   198 00010461 803D[5B030300]FF    <1> 	cmp     byte [sysflg], 0FFh ; user or system space ?
   199 00010468 7520                <1> 	jne	short clk_2 	    ; system space (sysflg <> 0FFh)
   200                              <1> 	;
   201 0001046A 66833D[AA030300]00  <1> 	cmp	word [u.intr], 0
   202 00010472 7616                <1> 	jna	short clk_2
   203                              <1> 	;
   204                              <1> 	; 23/05/2016
   205 00010474 803D[6A700100]00    <1> 	cmp	byte [multi_tasking], 0
   206 0001047B 760D                <1> 	jna	short clk_2
   207                              <1> 	;
   208 0001047D FE05[69700100]      <1> 	inc	byte [p_change] ; it is time to change running process	
   209 00010483 C3                  <1> 	retn
   210                              <1> clk_1:
   211 00010484 FE0D[A8030300]      <1> 	dec	byte [u.quant]
   212                              <1> clk_2:
   213 0001048A C3                  <1> 	retn   ; return to (hardware) timer interrupt routine
   214                              <1> 
   215                              <1> ; 12/10/2017
   216                              <1> ; 15/01/2017
   217                              <1> ; 14/01/2017
   218                              <1> ; 07/01/2017
   219                              <1> ; 02/01/2017
   220                              <1> ; 17/08/2016
   221                              <1> ; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   222                              <1> int34h:  ; #IOCTL# (I/O port access support for ring 3)
   223                              <1> ; 23/05/2016
   224                              <1> 	; 20/06/2016
   225                              <1> 	; 29/04/2016 - TRDOS 386 (TRDOS v2.0)
   226                              <1> 	;
   227                              <1> 	; INPUT ->
   228                              <1> 	;	AH = 0 -> read port  (physical IO port) -byte-
   229                              <1> 	;	AH = 1 -> write port (physical IO port) -byte-
   230                              <1> 	;		AL = data byte
   231                              <1> 	;	AH = 2 -> read port  (physical IO port) -word-
   232                              <1> 	;	AH = 3 -> write port (physical IO port) -word-
   233                              <1> 	;		BX = data word
   234                              <1> 	;	AH = 4 -> read port  (physical IO port) -dword-
   235                              <1> 	;	AH = 5 -> write port (physical IO port) -dword-
   236                              <1> 	;		EBX = data dword
   237                              <1> 	;	; 12/10/2017
   238                              <1> 	;	AH = 6 -> read port (physical IO port) twice -byte-
   239                              <1> 	;	AH = 7 -> write port (physical IO port) twice -byte-
   240                              <1> 	;		BX = data word	
   241                              <1> 	;
   242                              <1> 	;	DX = Port number (<= 0FFFFh)
   243                              <1> 	;
   244                              <1> 	; OUTPUT ->
   245                              <1> 	;	AL = data byte (in al, dx)
   246                              <1> 	;	AX = data word (in ax, dx)
   247                              <1> 	;	EAX = data dword (in eax, dx)
   248                              <1> 	;
   249                              <1> 	;	(ECX = actual TRANSFER COUNT for string functions)
   250                              <1> 	;
   251                              <1> 	;
   252                              <1> 	; Modified registers: EAX
   253                              <1> 	;
   254                              <1> 
   255                              <1> 	;cmp	ah, 5
   256                              <1> 	;ja	short int34h_5 ; invalid function !
   257                              <1> 
   258                              <1> 	; 12/10/2017
   259 0001048B 80FC07              <1> 	cmp	ah, 7
   260 0001048E 7743                <1> 	ja	short int34h_5 ; invalid function !
   261                              <1> 
   262                              <1> 	;; 15/01/2017
   263                              <1> 	; 14/01/2017
   264                              <1> 	; 02/01/2017
   265                              <1> 	;;mov	byte [ss:intflg], 34h	; IOCTL interrupt 
   266 00010490 FB                  <1> 	sti
   267                              <1> 	
   268                              <1> 	;sti	; enable interrupts
   269 00010491 80642408FE          <1> 	and	byte [esp+8], 11111110b	; clear carry bit of eflags register
   270                              <1> 
   271 00010496 80FC01              <1> 	cmp	ah, 1
   272 00010499 7205                <1> 	jb	short int34h_0
   273 0001049B 7705                <1> 	ja	short int34h_1
   274                              <1> 
   275 0001049D EE                  <1> 	out	dx, al
   276                              <1> 	;iretd
   277 0001049E EB01                <1> 	jmp short int34h_iret
   278                              <1> 
   279                              <1> int34h_0:
   280 000104A0 EC                  <1> 	in	al, dx
   281                              <1> 	;iretd
   282                              <1> int34h_iret:
   283                              <1> 	;cli	; 07/01/2017
   284                              <1> 	;; 15/01/2017
   285                              <1> 	;;mov	byte [ss:intflg], 0 ; reset
   286 000104A1 CF                  <1> 	iretd 
   287                              <1> 
   288                              <1> int34h_1:
   289 000104A2 F6C401              <1> 	test	ah, 1
   290 000104A5 7516                <1> 	jnz	short int34h_3 ; out
   291                              <1> 
   292                              <1> 	; in
   293 000104A7 80FC02              <1> 	cmp	ah, 2
   294 000104AA 7707                <1> 	ja	short int34h_2
   295                              <1> 
   296 000104AC 6689D8              <1> 	mov	ax, bx
   297 000104AF 66ED                <1> 	in	ax, dx
   298                              <1> 	;iretd
   299 000104B1 EBEE                <1> 	jmp	short int34h_iret
   300                              <1> 
   301                              <1> int34h_2:
   302 000104B3 80FC04              <1> 	cmp	ah, 4
   303 000104B6 772C                <1> 	ja	short int34h_7	; 12/10/2017
   304                              <1> 	; ah = 4
   305 000104B8 89D8                <1> 	mov	eax, ebx
   306 000104BA ED                  <1> 	in	eax, dx
   307                              <1> 	;iretd
   308 000104BB EBE4                <1> 	jmp	short int34h_iret
   309                              <1> 
   310                              <1> int34h_3:
   311 000104BD 80FC03              <1> 	cmp	ah, 3
   312 000104C0 7707                <1> 	ja	short int34h_4
   313                              <1> 
   314 000104C2 6689D8              <1> 	mov	ax, bx
   315 000104C5 66EF                <1> 	out	dx, ax
   316                              <1> 	;iretd
   317 000104C7 EBD8                <1> 	jmp	short int34h_iret
   318                              <1> 
   319                              <1> int34h_4:
   320 000104C9 80FC05              <1> 	cmp	ah, 5
   321 000104CC 770B                <1> 	ja	short int34h_6	; 12/10/2017
   322                              <1> 	; ah = 5
   323 000104CE 89D8                <1> 	mov	eax, ebx
   324 000104D0 EF                  <1> 	out	dx, eax
   325                              <1> 	;iretd
   326 000104D1 EBCE                <1> 	jmp	short int34h_iret
   327                              <1> 
   328                              <1> int34h_5:
   329 000104D3 804C240801          <1> 	or	byte [esp+8], 1	; set carry bit of eflags register
   330 000104D8 CF                  <1> 	iretd
   331                              <1> 
   332                              <1> 	; 12/10/2017
   333                              <1> int34h_6:
   334 000104D9 6689D8              <1> 	mov	ax, bx
   335 000104DC EE                  <1> 	out	dx, al
   336 000104DD EB00                <1> 	jmp	short $+2
   337 000104DF 86E0                <1> 	xchg	ah, al
   338 000104E1 EE                  <1> 	out	dx, al
   339                              <1> 	;xchg	al, ah
   340                              <1> 	;iretd
   341 000104E2 EB06                <1> 	jmp	short int34h_8
   342                              <1> int34h_7:
   343 000104E4 EC                  <1> 	in	al, dx
   344 000104E5 EB00                <1> 	jmp	short $+2
   345 000104E7 88C4                <1> 	mov	ah, al
   346 000104E9 EC                  <1> 	in	al, dx
   347                              <1> int34h_8:
   348 000104EA 86C4                <1> 	xchg	al, ah
   349 000104EC CF                  <1> 	iretd
   350                              <1> 			
   351                              <1> 
   352                              <1> INT4Ah:
   353                              <1> 	; 24/01/2016
   354                              <1> 	; this procedure will be called by 'RTC_INT' (in 'timer.s')
   355 000104ED C3                  <1> 	retn
   356                              <1> 
   357                              <1> ; u0.s
   358                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS0.INC
   359                              <1> ; Last Modification: 20/11/2015
   360                              <1> 
   361                              <1> com2_int:
   362                              <1> 	; 07/11/2015 
   363                              <1> 	; 24/10/2015
   364                              <1> 	; 23/10/2015
   365                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
   366                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
   367                              <1> 	; < serial port 2 interrupt handler >
   368                              <1> 	;
   369 000104EE 890424              <1> 	mov 	[esp], eax ; overwrite call return address
   370                              <1> 	;push	eax
   371 000104F1 66B80900            <1> 	mov	ax, 9
   372 000104F5 EB07                <1> 	jmp	short comm_int
   373                              <1> com1_int:
   374                              <1> 	; 07/11/2015
   375                              <1> 	; 24/10/2015
   376 000104F7 890424              <1> 	mov 	[esp], eax ; overwrite call return address
   377                              <1> 	; 23/10/2015
   378                              <1> 	;push	eax
   379 000104FA 66B80800            <1> 	mov	ax, 8
   380                              <1> comm_int:
   381                              <1> 	; 20/11/2015
   382                              <1> 	; 18/11/2015
   383                              <1> 	; 17/11/2015
   384                              <1> 	; 16/11/2015
   385                              <1> 	; 09/11/2015
   386                              <1> 	; 08/11/2015
   387                              <1> 	; 07/11/2015
   388                              <1> 	; 06/11/2015 (serial4.asm, 'serial')	
   389                              <1> 	; 01/11/2015
   390                              <1> 	; 26/10/2015
   391                              <1> 	; 23/10/2015
   392 000104FE 53                  <1> 	push	ebx
   393 000104FF 56                  <1> 	push	esi
   394 00010500 57                  <1> 	push	edi
   395 00010501 1E                  <1> 	push 	ds
   396 00010502 06                  <1> 	push 	es
   397                              <1> 	; 18/11/2015
   398 00010503 0F20DB              <1> 	mov	ebx, cr3
   399 00010506 53                  <1> 	push	ebx ; ****
   400                              <1> 	;
   401 00010507 51                  <1> 	push	ecx ; ***
   402 00010508 52                  <1> 	push	edx ; **
   403                              <1> 	;
   404 00010509 BB10000000          <1> 	mov	ebx, KDATA
   405 0001050E 8EDB                <1> 	mov	ds, bx
   406 00010510 8EC3                <1> 	mov	es, bx
   407                              <1> 	;
   408 00010512 8B0D[D8630100]      <1> 	mov	ecx, [k_page_dir]
   409 00010518 0F22D9              <1> 	mov	cr3, ecx
   410                              <1> 	; 20/11/2015
   411                              <1> 	; Interrupt identification register
   412 0001051B 66BAFA02            <1> 	mov	dx, 2FAh ; COM2
   413                              <1> 	;
   414 0001051F 3C08                <1> 	cmp 	al, 8 
   415 00010521 7702                <1> 	ja 	short com_i0
   416                              <1> 	;
   417                              <1> 	; 20/11/2015
   418                              <1> 	; 17/11/2015
   419                              <1> 	; 16/11/2015
   420                              <1> 	; 15/11/2015
   421                              <1> 	; 24/10/2015
   422                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
   423                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
   424                              <1> 	; < serial port 1 interrupt handler >
   425                              <1> 	;
   426 00010523 FEC6                <1> 	inc	dh ; 3FAh ; COM1 Interrupt id. register
   427                              <1> com_i0:
   428                              <1> 	;push	eax ; *
   429                              <1> 	; 07/11/2015
   430 00010525 A2[42640100]        <1> 	mov 	byte [ccomport], al
   431                              <1> 	; 09/11/2015
   432 0001052A 0FB7D8              <1> 	movzx	ebx, ax ; 8 or 9
   433                              <1> 	; 17/11/2015
   434                              <1>  	; reset request for response status
   435 0001052D 88A3[38640100]      <1> 	mov	[ebx+req_resp-8], ah ; 0
   436                              <1> 	;
   437                              <1> 	; 20/11/2015
   438 00010533 EC                  <1> 	in	al, dx		; read interrupt id. register
   439 00010534 EB00                <1> 	JMP	$+2	   	; I/O DELAY
   440 00010536 2404                <1> 	and	al, 4		; received data available?	
   441 00010538 7470                <1> 	jz	short com_eoi	; (transmit. holding reg. empty)
   442                              <1> 	;
   443                              <1> 	; 20/11/2015
   444 0001053A 80EA02              <1> 	sub	dl, 3FAh-3F8h	; data register (3F8h, 2F8h)
   445 0001053D EC                  <1> 	in	al, dx     	; read character
   446                              <1> 	;JMP	$+2	   	; I/O DELAY
   447                              <1> 	; 08/11/2015
   448                              <1> 	; 07/11/2015
   449 0001053E 89DE                <1> 	mov	esi, ebx 
   450 00010540 89DF                <1> 	mov	edi, ebx
   451 00010542 81C6[3C640100]      <1> 	add 	esi, rchar - 8 ; points to last received char
   452 00010548 81C7[3E640100]      <1> 	add	edi, schar - 8 ; points to last sent char
   453 0001054E 8806                <1> 	mov	[esi], al ; received char (current char)
   454                              <1> 	; query
   455 00010550 20C0                <1> 	and	al, al
   456 00010552 7527                <1> 	jnz	short com_i2
   457                              <1>    	; response
   458                              <1> 	; 17/11/2015
   459                              <1> 	; set request for response status
   460 00010554 FE83[38640100]      <1>         inc     byte [ebx+req_resp-8] ; 1 
   461                              <1> 	;
   462 0001055A 6683C205            <1> 	add	dx, 3FDh-3F8h	; (3FDh, 2FDh)
   463 0001055E EC                  <1> 	in	al, dx	   	; read line status register 
   464 0001055F EB00                <1> 	JMP	$+2	   	; I/O DELAY
   465 00010561 2420                <1> 	and	al, 20h	   	; transmitter holding reg. empty?
   466 00010563 7445                <1> 	jz	short com_eoi 	; no
   467 00010565 B0FF                <1> 	mov 	al, 0FFh   	; response			
   468 00010567 6683EA05            <1> 	sub	dx, 3FDh-3F8h 	; data port (3F8h, 2F8h)
   469 0001056B EE                  <1> 	out	dx, al	   	; send on serial port
   470                              <1> 	; 17/11/2015
   471 0001056C 803F00              <1> 	cmp 	byte [edi], 0   ; query ? (schar)
   472 0001056F 7502                <1> 	jne 	short com_i1    ; no
   473 00010571 8807                <1> 	mov	[edi], al 	; 0FFh (responded)
   474                              <1> com_i1:
   475                              <1> 	; 17/11/2015
   476                              <1> 	; reset request for response status (again)
   477 00010573 FE8B[38640100]      <1>         dec     byte [ebx+req_resp-8] ; 0 
   478 00010579 EB2F                <1> 	jmp	short com_eoi
   479                              <1> com_i2:	
   480                              <1> 	; 08/11/2015
   481 0001057B 3CFF                <1> 	cmp 	al, 0FFh	; (response ?)
   482 0001057D 7417                <1> 	je	short com_i3	; (check for response signal)
   483                              <1> 	; 07/11/2015
   484 0001057F 3C04                <1> 	cmp	al, 04h	; EOT
   485 00010581 751C                <1> 	jne	short com_i4	
   486                              <1> 	; EOT = 04h (End of Transmit) - 'CTRL + D'
   487                              <1> 	;(an EOT char is supposed as a ctrl+brk from the terminal)
   488                              <1> 	; 08/11/2015
   489                              <1> 		; ptty -> tty 0 to 7 (pseudo screens)
   490 00010583 861D[06640100]      <1> 	xchg	bl, [ptty]  ; tty number (8 or 9)
   491 00010589 E8226AFFFF          <1> 	call 	ctrlbrk
   492 0001058E 861D[06640100]      <1> 	xchg	[ptty], bl ; (restore ptty value and BL value)
   493                              <1> 	;mov	al, 04h ; EOT
   494                              <1> 	; 08/11/2015
   495 00010594 EB09                <1> 	jmp	short com_i4	
   496                              <1> com_i3:
   497                              <1> 	; 08/11/2015
   498                              <1> 	; If 0FFh has been received just after a query
   499                              <1> 	; (schar, ZERO), it is a response signal.
   500                              <1> 	; 17/11/2015
   501 00010596 803F00              <1>         cmp     byte [edi], 0 ; query ? (schar)
   502 00010599 7704                <1> 	ja	short com_i4 ; no
   503                              <1> 	; reset query status (schar)
   504 0001059B 8807                <1> 	mov	[edi], al ; 0FFh
   505 0001059D FEC0                <1> 	inc	al ; 0
   506                              <1> com_i4:
   507                              <1> 	; 27/07/2014
   508                              <1> 	; 09/07/2014
   509 0001059F D0E3                <1> 	shl	bl, 1	
   510 000105A1 81C3[08640100]      <1> 	add	ebx, ttychr
   511                              <1> 	; 23/07/2014 (always overwrite)
   512                              <1> 	;;cmp	word [ebx], 0
   513                              <1> 	;;ja	short com_eoi
   514                              <1> 	;
   515 000105A7 668903              <1> 	mov	[ebx], ax   ; Save ascii code
   516                              <1> 			    ; scan code = 0
   517                              <1> com_eoi:
   518                              <1> 	;mov	al, 20h
   519                              <1> 	;out	20h, al	   ; end of interrupt
   520                              <1> 	;
   521                              <1> 	; 07/11/2015
   522                              <1>       	;pop	eax ; *
   523 000105AA A0[42640100]        <1> 	mov	al, byte [ccomport] ; current COM port
   524                              <1> 	 ; al = tty number (8 or 9)
   525 000105AF E85E010000          <1>         call	wakeup
   526                              <1> com_iret:
   527                              <1> 	; 23/10/2015
   528 000105B4 5A                  <1> 	pop	edx ; **
   529 000105B5 59                  <1> 	pop	ecx ; ***
   530                              <1> 	; 18/11/2015
   531                              <1> 	;pop	eax ; ****
   532                              <1> 	;mov	cr3, eax
   533                              <1> 	;jmp	iiret
   534 000105B6 E9E007FFFF          <1> 	jmp	iiretp
   535                              <1> 
   536                              <1> ;iiretp: ; 01/09/2015
   537                              <1> ;	; 28/08/2015
   538                              <1> ;	pop	eax ; (*) page directory
   539                              <1> ;	mov	cr3, eax
   540                              <1> ;iiret:
   541                              <1> ;	; 22/08/2014
   542                              <1> ;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
   543                              <1> ;	out	20h, al	; 8259 PORT
   544                              <1> ;	;
   545                              <1> ;	pop	es
   546                              <1> ;	pop	ds
   547                              <1> ;	pop	edi
   548                              <1> ;	pop	esi
   549                              <1> ;	pop	ebx ; 29/08/2014
   550                              <1> ;	pop 	eax
   551                              <1> ;	iretd
   552                              <1> 
   553                              <1> sp_init:
   554                              <1> 	; 07/11/2015
   555                              <1> 	; 29/10/2015
   556                              <1> 	; 26/10/2015
   557                              <1> 	; 23/10/2015
   558                              <1> 	; 29/06/2015
   559                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - 115200 baud)
   560                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1 - 9600 baud)
   561                              <1> 	; Initialization of Serial Port Communication Parameters
   562                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
   563                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
   564                              <1> 	;
   565                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
   566                              <1> 	;
   567                              <1> 	; INPUT:  (29/06/2015)
   568                              <1> 	;	AL = 0 for COM1
   569                              <1> 	;	     1 for COM2
   570                              <1> 	;	AH = Communication parameters	
   571                              <1> 	;
   572                              <1> 	;  (*) Communication parameters (except BAUD RATE):
   573                              <1> 	;	Bit	4	3	2	1	0
   574                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
   575                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
   576                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
   577                              <1> 	;		11 = even
   578                              <1> 	;  Baud rate setting bits: (29/06/2015)
   579                              <1> 	;		Retro UNIX 386 v1 feature only !
   580                              <1> 	;	Bit	7    6    5  | Baud rate
   581                              <1> 	;		------------------------
   582                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
   583                              <1> 	;		0    0    1  | 9600 (12)
   584                              <1> 	;		0    1    0  | 19200 (6) 
   585                              <1> 	;		0    1	  1  | 38400 (3) 
   586                              <1> 	;		1    0	  0  | 14400 (8)
   587                              <1> 	;		1    0	  1  | 28800 (4)
   588                              <1> 	;		1    1    0  | 57600 (2)
   589                              <1> 	;		1    1    1  | 115200 (1) 	
   590                              <1> 	
   591                              <1> 	; References:	
   592                              <1> 	; (1) IBM PC-XT Model 286 BIOS Source Code
   593                              <1> 	;     RS232.ASM --- 10/06/1985 COMMUNICATIONS BIOS (RS232)
   594                              <1> 	; (2) Award BIOS 1999 - ATORGS.ASM
   595                              <1> 	; (3) http://wiki.osdev.org/Serial_Ports
   596                              <1> 	;
   597                              <1> 	; Set communication parameters for COM1 (= 03h)	
   598                              <1> 	;
   599 000105BB BB[3E640100]        <1> 	mov	ebx, com1p		; COM1 parameters  
   600 000105C0 66BAF803            <1> 	mov	dx, 3F8h		; COM1
   601                              <1> 	 ; 29/10/2015
   602 000105C4 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
   603 000105C8 E86F000000          <1> 	call	sp_i3	; call A4	
   604 000105CD A880                <1> 	test	al, 80h
   605 000105CF 7410                <1> 	jz	short sp_i0 ; OK..
   606                              <1> 		; Error !
   607                              <1> 	;mov	dx, 3F8h
   608 000105D1 80EA05              <1> 	sub	dl, 5 ; 3FDh -> 3F8h
   609 000105D4 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
   610 000105D8 E85F000000          <1> 	call	sp_i3	; call A4	
   611 000105DD A880                <1> 	test	al, 80h
   612 000105DF 7508                <1> 	jnz	short sp_i1
   613                              <1> sp_i0:
   614                              <1>         ; (Note: Serial port interrupts will be disabled here...)	
   615                              <1>         ; (INT 14h initialization code disables interrupts.)
   616                              <1> 	;
   617 000105E1 C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
   618 000105E4 E8DC000000          <1> 	call	sp_i5 ; 29/06/2015
   619                              <1> sp_i1:
   620 000105E9 43                  <1> 	inc	ebx
   621 000105EA 66BAF802            <1> 	mov	dx, 2F8h		; COM2
   622                              <1> 	 ; 29/10/2015
   623 000105EE 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
   624 000105F2 E845000000          <1> 	call	sp_i3	; call A4	
   625 000105F7 A880                <1> 	test	al, 80h
   626 000105F9 7410                <1> 	jz	short sp_i2 ; OK..
   627                              <1> 		; Error !
   628                              <1> 	;mov	dx, 2F8h
   629 000105FB 80EA05              <1> 	sub	dl, 5 ; 2FDh -> 2F8h
   630 000105FE 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
   631 00010602 E835000000          <1> 	call	sp_i3	; call A4	
   632 00010607 A880                <1> 	test	al, 80h
   633 00010609 7530                <1> 	jnz	short sp_i7
   634                              <1> sp_i2:
   635 0001060B C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
   636                              <1> sp_i6:
   637                              <1> 	;; COM2 - enabling IRQ 3
   638                              <1> 	; 07/11/2015
   639                              <1> 	; 26/10/2015
   640 0001060E 9C                  <1> 	pushf
   641 0001060F FA                  <1> 	cli
   642                              <1> 	;
   643 00010610 66BAFC02            <1> 	mov	dx, 2FCh   		; modem control register
   644 00010614 EC                  <1> 	in	al, dx 	   		; read register
   645 00010615 EB00                <1> 	JMP	$+2	   		; I/O DELAY
   646 00010617 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
   647 00010619 EE                  <1> 	out	dx, al     		; write back to register
   648 0001061A EB00                <1> 	JMP	$+2	   		; I/O DELAY
   649 0001061C 66BAF902            <1> 	mov	dx, 2F9h   		; interrupt enable register
   650 00010620 EC                  <1> 	in	al, dx     		; read register
   651 00010621 EB00                <1> 	JMP	$+2	   		; I/O DELAY
   652                              <1> 	;or	al, 1      		; receiver data interrupt enable and
   653 00010623 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
   654 00010625 EE                  <1> 	out	dx, al 	   		; write back to register
   655 00010626 EB00                <1> 	JMP	$+2        		; I/O DELAY
   656 00010628 E421                <1> 	in	al, 21h    		; read interrupt mask register
   657 0001062A EB00                <1> 	JMP	$+2	   		; I/O DELAY
   658 0001062C 24F7                <1> 	and	al, 0F7h   		; enable IRQ 3 (COM2)
   659 0001062E E621                <1> 	out	21h, al    		; write back to register
   660                              <1> 	;
   661                              <1> 	; 23/10/2015
   662 00010630 B8[EE040100]        <1> 	mov 	eax, com2_int
   663 00010635 A3[0D070100]        <1> 	mov	[com2_irq3], eax
   664                              <1> 	; 26/10/2015
   665 0001063A 9D                  <1> 	popf	
   666                              <1> sp_i7:
   667 0001063B C3                  <1> 	retn
   668                              <1> 
   669                              <1> sp_i3:
   670                              <1> ;A4:  	;-----	INITIALIZE THE COMMUNICATIONS PORT
   671                              <1> 	; 28/10/2015
   672 0001063C FEC2                <1> 	inc	dl	; 3F9h (2F9h)	; 3F9h, COM1 Interrupt enable register 
   673 0001063E B000                <1> 	mov	al, 0
   674 00010640 EE                  <1> 	out	dx, al			; disable serial port interrupt
   675 00010641 EB00                <1> 	JMP	$+2			; I/O DELAY
   676 00010643 80C202              <1> 	add	dl, 2 	; 3FBh (2FBh)	; COM1 Line control register (3FBh)
   677 00010646 B080                <1> 	mov	al, 80h			
   678 00010648 EE                  <1> 	out	dx, al			; SET DLAB=1 ; divisor latch access bit
   679                              <1> 	;-----	SET BAUD RATE DIVISOR
   680                              <1> 	; 26/10/2015
   681 00010649 80EA03              <1> 	sub 	dl, 3   ; 3F8h (2F8h)	; register for least significant byte
   682                              <1> 					; of the divisor value
   683 0001064C 88C8                <1> 	mov	al, cl	; 1
   684 0001064E EE                  <1> 	out	dx, al			; 1 = 115200 baud (Retro UNIX 386 v1)
   685                              <1> 					; 2 = 57600 baud
   686                              <1> 					; 3 = 38400 baud
   687                              <1> 					; 6 = 19200 baud
   688                              <1> 					; 12 = 9600 baud (Retro UNIX 8086 v1)
   689 0001064F EB00                <1> 	JMP	$+2			; I/O DELAY
   690 00010651 28C0                <1> 	sub	al, al
   691 00010653 FEC2                <1> 	inc	dl      ; 3F9h (2F9h)	; register for most significant byte
   692                              <1> 					; of the divisor value
   693 00010655 EE                  <1> 	out	dx, al ; 0
   694 00010656 EB00                <1> 	JMP	$+2			; I/O DELAY
   695                              <1> 	;	
   696 00010658 88E8                <1> 	mov	al, ch ; 3		; 8 data bits, 1 stop bit, no parity
   697                              <1> 	;and	al, 1Fh ; Bits 0,1,2,3,4	
   698 0001065A 80C202              <1> 	add	dl, 2	; 3FBh (2FBh)	; Line control register
   699 0001065D EE                  <1> 	out	dx, al			
   700 0001065E EB00                <1> 	JMP	$+2			; I/O DELAY
   701                              <1> 	; 29/10/2015
   702 00010660 FECA                <1> 	dec 	dl 	; 3FAh (2FAh)	; FIFO Control register (16550/16750)
   703 00010662 30C0                <1> 	xor	al, al			; 0
   704 00010664 EE                  <1> 	out	dx, al			; Disable FIFOs (reset to 8250 mode)
   705 00010665 EB00                <1> 	JMP	$+2	
   706                              <1> sp_i4:
   707                              <1> ;A18:	;-----	COMM PORT STATUS ROUTINE
   708                              <1> 	; 29/06/2015 (line status after modem status)
   709 00010667 80C204              <1> 	add	dl, 4	; 3FEh (2FEh)	; Modem status register
   710                              <1> sp_i4s:
   711 0001066A EC                  <1> 	in	al, dx			; GET MODEM CONTROL STATUS
   712 0001066B EB00                <1> 	JMP	$+2			; I/O DELAY
   713 0001066D 88C4                <1> 	mov	ah, al			; PUT IN (AH) FOR RETURN
   714 0001066F FECA                <1> 	dec	dl	; 3FDh (2FDh)	; POINT TO LINE STATUS REGISTER
   715                              <1> 					; dx = 3FDh for COM1, 2FDh for COM2
   716 00010671 EC                  <1> 	in	al, dx			; GET LINE CONTROL STATUS
   717                              <1> 	; AL = Line status, AH = Modem status
   718 00010672 C3                  <1> 	retn
   719                              <1> 
   720                              <1> sp_status:
   721                              <1> 	; 29/06/2015
   722                              <1> 	; 27/06/2015 (Retro UNIX 386 v1)
   723                              <1> 	; Get serial port status
   724 00010673 66BAFE03            <1> 	mov	dx, 3FEh		; Modem status register (COM1)
   725 00010677 28C6                <1> 	sub	dh, al			; dh = 2 for COM2 (al = 1)
   726                              <1> 					; dx = 2FEh for COM2
   727 00010679 EBEF                <1> 	jmp	short sp_i4s
   728                              <1> 
   729                              <1> sp_setp: ; Set serial port communication parameters
   730                              <1> 	; 07/11/2015
   731                              <1> 	; 29/10/2015
   732                              <1> 	; 29/06/2015
   733                              <1> 	; Retro UNIX 386 v1 feature only !	
   734                              <1> 	;
   735                              <1> 	; INPUT:
   736                              <1> 	;	AL = 0 for COM1
   737                              <1> 	;	     1 for COM2
   738                              <1> 	;	AH = Communication parameters (*)
   739                              <1> 	; OUTPUT:
   740                              <1> 	;	CL = Line status
   741                              <1> 	;	CH = Modem status
   742                              <1> 	;   If cf = 1 -> Error code in [u.error]
   743                              <1> 	;		 'invalid parameter !' 
   744                              <1> 	;		 	 or
   745                              <1> 	;		 'device not ready !' error
   746                              <1> 	;	
   747                              <1> 	;  (*) Communication parameters (except BAUD RATE):
   748                              <1> 	;	Bit	4	3	2	1	0
   749                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
   750                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
   751                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
   752                              <1> 	;		11 = even
   753                              <1> 	;  Baud rate setting bits: (29/06/2015)
   754                              <1> 	;		Retro UNIX 386 v1 feature only !
   755                              <1> 	;	Bit	7    6    5  | Baud rate
   756                              <1> 	;		------------------------
   757                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
   758                              <1> 	;		0    0    1  | 9600 (12)
   759                              <1> 	;		0    1    0  | 19200 (6) 
   760                              <1> 	;		0    1	  1  | 38400 (3) 
   761                              <1> 	;		1    0	  0  | 14400 (8)
   762                              <1> 	;		1    0	  1  | 28800 (4)
   763                              <1> 	;		1    1    0  | 57600 (2)
   764                              <1> 	;		1    1    1  | 115200 (1) 
   765                              <1> 	;
   766                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
   767                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
   768                              <1> 	;
   769                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
   770                              <1> 	;
   771 0001067B 66BAF803            <1> 	mov	dx, 3F8h
   772 0001067F BB[3E640100]        <1> 	mov	ebx, com1p ; COM1 control byte offset
   773 00010684 3C01                <1> 	cmp	al, 1
   774 00010686 776B                <1> 	ja 	short sp_invp_err
   775 00010688 7203                <1> 	jb	short sp_setp1 ;  COM1 (AL = 0)
   776 0001068A FECE                <1> 	dec	dh ; 2F8h
   777 0001068C 43                  <1> 	inc	ebx ; COM2 control byte offset
   778                              <1> sp_setp1:
   779                              <1> 	; 29/10/2015
   780 0001068D 8823                <1> 	mov	[ebx], ah
   781 0001068F 0FB6CC              <1> 	movzx 	ecx, ah
   782 00010692 C0E905              <1> 	shr	cl, 5 ; -> baud rate index
   783 00010695 80E41F              <1> 	and	ah, 1Fh ; communication parameters except baud rate
   784 00010698 8A81[02070100]      <1> 	mov	al, [ecx+b_div_tbl]
   785 0001069E 6689C1              <1> 	mov	cx, ax
   786 000106A1 E896FFFFFF          <1> 	call	sp_i3
   787 000106A6 6689C1              <1> 	mov	cx, ax ; CL = Line status, CH = Modem status
   788 000106A9 A880                <1> 	test	al, 80h
   789 000106AB 740F                <1> 	jz	short sp_setp2
   790 000106AD C603E3              <1>         mov     byte [ebx], 0E3h ; Reset to initial value (11100011b)
   791                              <1> stp_dnr_err:
   792 000106B0 C705[C8030300]0F00- <1> 	mov	dword [u.error], ERR_DEV_NOT_RDY ; 'device not ready !'
   792 000106B8 0000                <1>
   793                              <1> 	; CL = Line status, CH = Modem status
   794 000106BA F9                  <1> 	stc
   795 000106BB C3                  <1> 	retn
   796                              <1> sp_setp2:
   797 000106BC 80FE02              <1> 	cmp	dh, 2 ; COM2 (2F?h)
   798 000106BF 0F8649FFFFFF        <1>         jna     sp_i6 
   799                              <1> 		      ; COM1 (3F?h)
   800                              <1> sp_i5: 
   801                              <1> 	; 07/11/2015
   802                              <1> 	; 26/10/2015
   803                              <1> 	; 29/06/2015
   804                              <1> 	;
   805                              <1> 	;; COM1 - enabling IRQ 4
   806 000106C5 9C                  <1> 	pushf
   807 000106C6 FA                  <1> 	cli
   808 000106C7 66BAFC03            <1> 	mov	dx, 3FCh   		; modem control register
   809 000106CB EC                  <1> 	in	al, dx 	   		; read register
   810 000106CC EB00                <1> 	JMP	$+2			; I/O DELAY
   811 000106CE 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
   812 000106D0 EE                  <1> 	out	dx, al     		; write back to register
   813 000106D1 EB00                <1> 	JMP	$+2			; I/O DELAY
   814 000106D3 66BAF903            <1> 	mov	dx, 3F9h   		; interrupt enable register
   815 000106D7 EC                  <1> 	in	al, dx     		; read register
   816 000106D8 EB00                <1> 	JMP	$+2			; I/O DELAY
   817                              <1> 	;or	al, 1      		; receiver data interrupt enable and
   818 000106DA 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
   819 000106DC EE                  <1> 	out	dx, al 	   		; write back to register
   820 000106DD EB00                <1> 	JMP	$+2        		; I/O DELAY
   821 000106DF E421                <1> 	in	al, 21h    		; read interrupt mask register
   822 000106E1 EB00                <1> 	JMP	$+2			; I/O DELAY
   823 000106E3 24EF                <1> 	and	al, 0EFh   		; enable IRQ 4 (COM1)
   824 000106E5 E621                <1> 	out	21h, al    		; write back to register
   825                              <1> 	;
   826                              <1> 	; 23/10/2015
   827 000106E7 B8[F7040100]        <1> 	mov 	eax, com1_int
   828 000106EC A3[09070100]        <1> 	mov	[com1_irq4], eax
   829                              <1> 	; 26/10/2015
   830 000106F1 9D                  <1> 	popf
   831 000106F2 C3                  <1> 	retn
   832                              <1> 
   833                              <1> sp_invp_err:
   834 000106F3 C705[C8030300]1700- <1> 	mov	dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
   834 000106FB 0000                <1>
   835 000106FD 31C9                <1> 	xor	ecx, ecx
   836 000106FF 49                  <1> 	dec	ecx ; 0FFFFh
   837 00010700 F9                  <1> 	stc
   838 00010701 C3                  <1> 	retn
   839                              <1> 
   840                              <1> ; 29/10/2015
   841                              <1> b_div_tbl: ; Baud rate divisor table (115200/divisor)
   842 00010702 010C0603080401      <1> 	db 1, 12, 6, 3, 8, 4, 1
   843                              <1> 
   844                              <1> 
   845                              <1> ; 23/10/2015
   846                              <1> com1_irq4:
   847 00010709 [11070100]          <1> 	dd dummy_retn
   848                              <1> com2_irq3:
   849 0001070D [11070100]          <1> 	dd dummy_retn
   850                              <1> 
   851                              <1> dummy_retn:
   852 00010711 C3                  <1> 	retn
   853                              <1> 
   854                              <1> wakeup:
   855                              <1> 	; 24/01/2016
   856 00010712 C3                  <1> 	retn
   857                              <1> 
   858                              <1> set_working_path_x:
   859                              <1> 		; 17/10/2016 (TRDOS 386 - FFF & FNF)
   860 00010713 66B80100            <1> 		mov	ax, 1 
   861                              <1> 			; File name is needed/forced (AL=1)
   862                              <1> 			; Change directory as temporary (AH=0)	
   863                              <1> 
   864                              <1> set_working_path_xx: ; 30/12/2017 (syschdir)
   865                              <1> 		; This is needed for preventing wrong Find Next File
   866                              <1> 		; system call after sysopen, syscreate, sysmkdir etc. 
   867                              <1> 		; Find Next File must immediate follow Find First File)
   868                              <1> 
   869 00010717 8825[8C700100]      <1> 		mov	[FFF_Valid], ah ; 0 ; reset ; 17/10/2016
   870                              <1> 
   871                              <1> set_working_path:
   872                              <1> 		; 16/10/2016
   873                              <1> 		; 12/10/2016
   874                              <1> 		; 10/10/2016
   875                              <1> 		; 05/10/2016 - TRDOS 386 (TRDOS v2.0)
   876                              <1> 		;
   877                              <1> 		; TRDOS v1.0 (DIR.ASM, "proc_set_working_path")
   878                              <1>                 ; 27/01/2011 - 08/02/2011 
   879                              <1> 		; Set/Changes current drive, directory and file
   880                              <1> 		; depending on command tail
   881                              <1> 		; (procedure is derivated from CMD_INTR.ASM 
   882                              <1> 		; file or dir locating code of internal commands)
   883                              <1> 		; (This procedure is prepared for INT 21H file/dir 
   884                              <1> 		; functions and also to get compact code for 
   885                              <1> 		; internal mainprog -command interpreter- commands)
   886                              <1> 		; 
   887                              <1> 		; INPUT: DS:SI -> Command tail (ASCIIZ string)
   888                              <1> 		; AL = 0 -> any, AL > 0 -> file name is forced
   889                              <1> 		; AH = CD -> Change directory permanently 
   890                              <1> 		; AH <> CD -> Change directory as temporary    
   891                              <1> 		; 
   892                              <1> 		; OUTPUT: ES=DS, FindFile structure has been set
   893                              <1> 		;        RUN_CDRV points previous current drive  
   894                              <1> 		;        DS:SI = FindFile structure address
   895                              <1> 		;        (DS=CS)       
   896                              <1> 		;        AX, BX, CX, DX, DI will be changed
   897                              <1> 		;   cf = 1 -> Error code in AX (AL)
   898                              <1> 		;        stc & AX = 0 -> Bad command or path name 
   899                              <1> 		; -----------------------------------------------
   900                              <1> 		;
   901                              <1> 		; TRDOS 386 (05/10/2016)
   902                              <1> 		; INPUT:
   903                              <1> 		;	ESI = File/Directory Path (ASCIIZ string)
   904                              <1> 		;             address in user's memory space
   905                              <1> 		;       AL = 0 -> any
   906                              <1> 		;       AL > 0 -> file name is forced
   907                              <1> 		;       AH = CD -> change directory as permanent
   908                              <1> 		;       AH <> CD -> change directory as temporary
   909                              <1> 		; 
   910                              <1> 		; OUTPUT:
   911                              <1> 		;	FindFile structure has been set
   912                              <1> 		;       RUN_CDRV points previous current drive  
   913                              <1> 		;       ESI = FindFile_Name address ; 12/10/2016
   914                              <1> 		;
   915                              <1> 		;       cf = 1 -> Error code in EAX (AL)
   916                              <1> 		;       stc & EAX = 0 -> Bad command or path name
   917                              <1> 		;  
   918                              <1> 		; Modified registers: EAX, EBX, ECX, EDX, ESI, EDI
   919                              <1> 
   920 0001071D 66A3[90700100]      <1> 		mov	[SWP_Mode], ax
   921 00010723 A0[9E640100]        <1> 		mov	al, [Current_Drv]
   922 00010728 30E4                <1> 		xor	ah, ah
   923 0001072A 66A3[92700100]      <1> 		mov	[SWP_DRV], ax
   924                              <1> 
   925                              <1> 		; TRDOS 386 ring 3 (user's page directory)
   926                              <1> 		; to ring 0 (kernel's page directory) 
   927                              <1> 		; transfer modifications (05/10/2016).
   928                              <1> 
   929 00010730 55                  <1> 		push	ebp
   930 00010731 89E5                <1> 		mov	ebp, esp
   931                              <1> 		
   932 00010733 B980000000          <1> 		mov	ecx, 128 ; maximum path length = 128 bytes
   933 00010738 29CC                <1> 		sub	esp, ecx ; reserve 128 bytes (buffer) on stack
   934 0001073A 89E7                <1> 		mov	edi, esp ; destination address (kernel space)
   935                              <1> 		; esi = source address (virtual, in user's memory space)
   936 0001073C E89AEBFFFF          <1> 		call	transfer_from_user_buffer
   937 00010741 720A                <1> 		jc	short loc_swp_xor_retn 
   938                              <1> 		
   939 00010743 89E6                <1> 		mov	esi, esp ; temporary buffer (the path) on stack
   940                              <1> loc_swp_fchar:
   941 00010745 8A06                <1> 		mov	al, [esi]
   942 00010747 3C20                <1> 		cmp	al, 20h
   943 00010749 7711                <1> 		ja	short loc_swp_parse_path_name
   944 0001074B 740C                <1> 		je	short loc_swp_fchar_next
   945                              <1> 
   946                              <1> loc_swp_xor_retn:
   947 0001074D 31C0                <1> 		xor	eax, eax
   948 0001074F F9                  <1> 		stc
   949                              <1> loc_swp_retn:
   950 00010750 89EC                <1> 		mov	esp, ebp
   951 00010752 5D                  <1> 		pop	ebp
   952                              <1> 
   953                              <1> 		;mov	esi, FindFile_Drv
   954 00010753 BE[806D0100]        <1> 		mov	esi, FindFile_Name ; 12/10/2016
   955 00010758 C3                  <1> 		retn 
   956                              <1> 
   957                              <1> loc_swp_fchar_next:
   958 00010759 46                  <1> 		inc	esi
   959 0001075A EBE9                <1> 		jmp	short loc_swp_fchar  
   960                              <1> 
   961                              <1> loc_swp_parse_path_name:
   962 0001075C BF[3E6D0100]        <1> 		mov	edi, FindFile_Drv
   963 00010761 E8BCA8FFFF          <1> 		call	parse_path_name
   964 00010766 72E8                <1> 		jc	short loc_swp_retn
   965                              <1> 
   966                              <1> loc_swp_checkfile_name:
   967 00010768 803D[90700100]00    <1> 		cmp	byte [SWP_Mode], 0
   968 0001076F 761E                <1> 		jna	short loc_swp_drv
   969                              <1> 
   970                              <1> 		; 10/10/2016 (valid file name checking)
   971 00010771 BE[806D0100]        <1> 		mov	esi, FindFile_Name
   972 00010776 803E20              <1> 		cmp	byte [esi], 20h
   973 00010779 76D2                <1> 		jna	short loc_swp_xor_retn
   974                              <1> 
   975                              <1> 		; 16/10/2016
   976 0001077B C605[8F700100]00    <1> 		mov	byte [SWP_inv_fname], 0 ; reset 
   977                              <1> 		; esi = file name address (ASCIIZ)
   978 00010782 E8888AFFFF          <1> 		call	check_filename
   979 00010787 7306                <1> 		jnc	short loc_swp_drv
   980                              <1> 
   981 00010789 FE05[8F700100]      <1> 		inc	byte [SWP_inv_fname] ; set 	
   982                              <1> loc_swp_drv:
   983 0001078F 8A35[9E640100]      <1> 		mov	dh, [Current_Drv]
   984                              <1>                ;mov	[RUN_CDRV], dh
   985                              <1> 
   986 00010795 8A15[3E6D0100]      <1> 		mov	dl, [FindFile_Drv]
   987                              <1>                ;cmp	dl, dh
   988 0001079B 3A15[9E640100]      <1> 		cmp	dl, [Current_Drv]
   989 000107A1 740D                <1> 		je	short loc_swp_change_directory
   990                              <1> 
   991 000107A3 FE05[93700100]      <1> 		inc	byte [SWP_DRV_chg]
   992 000107A9 E80073FFFF          <1> 		call	change_current_drive
   993 000107AE 72A0                <1> 		jc	short loc_swp_retn ; eax = error code
   994                              <1> 		; eax = 0
   995                              <1> 
   996                              <1> loc_swp_change_directory:
   997 000107B0 803D[3F6D0100]21    <1> 		cmp	byte [FindFile_Directory], 21h
   998 000107B7 F5                  <1> 		cmc
   999 000107B8 7396                <1> 		jnc	short loc_swp_retn
  1000                              <1> 
  1001 000107BA FE05[93700100]      <1> 		inc	byte [SWP_DRV_chg]
  1002 000107C0 FE05[F6170100]      <1> 		inc	byte [Restore_CDIR]
  1003 000107C6 BE[3F6D0100]        <1> 		mov	esi, FindFile_Directory
  1004 000107CB 8A25[91700100]      <1> 		mov	ah, [SWP_Mode+1] 
  1005 000107D1 E836A2FFFF          <1> 		call	change_current_directory
  1006 000107D6 0F8274FFFFFF        <1> 		jc	loc_swp_retn ; eax = error code
  1007                              <1> 
  1008                              <1> loc_swp_change_prompt_dir_string:
  1009                              <1> 		; esi = PATH_Array
  1010                              <1> 		; eax = Current Directory First Cluster
  1011                              <1> 		; edi = Logical DOS Drive Description Table	
  1012 000107DC E850A1FFFF          <1> 		call	change_prompt_dir_str 
  1013 000107E1 29C0                <1> 		sub	eax, eax ; 0
  1014 000107E3 E968FFFFFF          <1> 		jmp	loc_swp_retn 
  1015                              <1> 
  1016                              <1> reset_working_path:
  1017                              <1> 		; 06/10/2016 - TRDOS 386 (TRDOS v2.0)
  1018                              <1> 		;
  1019                              <1> 		; TRDOS v1.0 (DIR.ASM, "proc_reset_working_path")
  1020                              <1> 		; 05/02/2011 - 08/02/2011 
  1021                              <1> 		;
  1022                              <1> 		; Restores current drive and directory 
  1023                              <1> 		; 
  1024                              <1> 		; INPUT: none
  1025                              <1> 		; OUTPUT: DL = SWP_DRV, EAX = 0 -> OK
  1026                              <1> 		;
  1027                              <1> 		;    AX = 0 -> ESI = Logical Dos Drv Desc. Table
  1028                              <1> 		;
  1029                              <1> 		;    EAX, EBX, ECX, EDX, ESI, EDI will be changed
  1030                              <1> 		;
  1031                              <1> 
  1032                              <1>   
  1033 000107E8 31C0                <1> 		xor	eax, eax
  1034 000107EA 48                  <1> 		dec	eax 
  1035                              <1> 
  1036 000107EB 668B15[92700100]    <1> 		mov	dx, [SWP_DRV]
  1037 000107F2 08F6                <1> 		or	dh, dh
  1038 000107F4 742E                <1> 		jz	short loc_rwp_return
  1039                              <1> 
  1040 000107F6 3A15[9E640100]      <1> 		cmp	dl, [Current_Drv]
  1041 000107FC 7407                <1> 		je	short loc_rwp_restore_cdir
  1042                              <1> loc_rwp_restore_cdrv:
  1043 000107FE E8AB72FFFF          <1> 		call	change_current_drive 
  1044 00010803 EB10                <1> 		jmp	short loc_rwp_restore_ok
  1045                              <1> loc_rwp_restore_cdir:
  1046 00010805 31DB                <1> 		xor	ebx, ebx
  1047 00010807 88D7                <1> 		mov	bh, dl
  1048 00010809 BE00010900          <1> 		mov	esi, Logical_DOSDisks
  1049 0001080E 01DE                <1> 		add	esi, ebx
  1050                              <1> 
  1051 00010810 E85073FFFF          <1> 		call	restore_current_directory
  1052                              <1> 
  1053                              <1> loc_rwp_restore_ok:
  1054 00010815 668B15[92700100]    <1> 		mov	dx, [SWP_DRV]
  1055 0001081C 31C0                <1> 		xor	eax, eax  
  1056 0001081E 66A3[93700100]      <1> 		mov	[SWP_DRV_chg], ax
  1057                              <1> loc_rwp_return:
  1058 00010824 C3                  <1> 		retn
  1059                              <1> 
  1060                              <1> get_file_name:
  1061                              <1> 		; 15/10/2016 - TRDOS 386 (TRDOS v2.0)
  1062                              <1> 		; Convert file name 
  1063                              <1> 		;	from directory entry format
  1064                              <1>                 ; 	to (8.3) dot file name format 
  1065                              <1> 		;
  1066                              <1> 		; TRDOS v1.0 (DIR.ASM, "get_file_name")
  1067                              <1>                 ; 2005 - 09/10/2011 	
  1068                              <1> 		; INPUT: 
  1069                              <1> 		;	DS:SI -> Directory Entry Format File Name
  1070                              <1> 		;       ES:DI -> DOS Dot File Name Address
  1071                              <1> 		; OUTPUT:
  1072                              <1> 		;	DS:SI -> DOS Dot File Name Address
  1073                              <1>                 ;	ES:DI -> Directory Entry Format File Name
  1074                              <1> 		;	
  1075                              <1> 		; TRDOS 386 (15/10/2016)
  1076                              <1> 		; INPUT:
  1077                              <1> 		;	ESI = File name addr in dir entry format
  1078                              <1> 		;	EDI = Dot file name address (destination)
  1079                              <1> 		; OUTPUT: 
  1080                              <1> 		;	File name is converted and moved
  1081                              <1> 		;	to destination (as 8.3 dot filename)
  1082                              <1> 		;  
  1083                              <1> 		; Modified registers: EAX, ECX
  1084                              <1> 
  1085                              <1>                 ; 2005 (TRDOS 8086) - 2016 (TRDOS 386)
  1086                              <1>                             
  1087 00010825 57                  <1> 		push	edi
  1088 00010826 56                  <1> 		push	esi
  1089 00010827 AC                  <1> 		lodsb
  1090 00010828 3C20                <1> 		cmp	al, 20h
  1091 0001082A 762A                <1> 		jna	short pass_gfn_ext
  1092 0001082C 56                  <1> 		push	esi
  1093 0001082D AA                  <1> 		stosb
  1094 0001082E B907000000          <1> 		mov	ecx, 7
  1095                              <1> loc_gfn_next_char:
  1096 00010833 AC                  <1> 		lodsb
  1097 00010834 3C20                <1> 		cmp	al, 20h
  1098 00010836 7603                <1> 		jna	short pass_gfn_fn
  1099 00010838 AA                  <1> 		stosb
  1100 00010839 E2F8                <1> 		loop	loc_gfn_next_char
  1101                              <1> pass_gfn_fn:
  1102 0001083B 5E                  <1> 		pop	esi
  1103 0001083C 83C607              <1> 		add	esi, 7
  1104 0001083F AC                  <1> 		lodsb
  1105 00010840 3C20                <1> 		cmp	al, 20h
  1106 00010842 7612                <1> 		jna	short pass_gfn_ext
  1107 00010844 B42E                <1> 		mov	ah, '.'
  1108 00010846 86E0                <1> 		xchg	ah, al
  1109 00010848 66AB                <1> 		stosw
  1110 0001084A AC                  <1> 		lodsb
  1111 0001084B 3C20                <1> 		cmp	al, 20h
  1112 0001084D 7607                <1> 		jna	short pass_gfn_ext
  1113 0001084F AA                  <1> 		stosb
  1114 00010850 AC                  <1> 		lodsb
  1115 00010851 3C20                <1> 		cmp	al, 20h
  1116 00010853 7601                <1> 		jna	short pass_gfn_ext
  1117 00010855 AA                  <1> 		stosb
  1118                              <1> pass_gfn_ext:		
  1119 00010856 30C0                <1> 		xor	al, al
  1120 00010858 AA                  <1> 		stosb
  1121 00010859 5E                  <1> 		pop	esi
  1122 0001085A 5F                  <1> 		pop	edi
  1123 0001085B C3                  <1> 		retn
  1124                              <1> 
  1125                              <1> set_hardware_int_vector:
  1126                              <1> 		; 18/03/2017
  1127                              <1> 		; 03/03/2017
  1128                              <1> 		; 28/02/2017 - TRDOS 386 (TRDOS v2.0)
  1129                              <1> 		;
  1130                              <1> 		; SET/RESET HARDWARE INTERRUPT GATE
  1131                              <1> 		;
  1132                              <1> 		; Changes interrupt gate descriptor table
  1133                              <1> 		; (without changing default interrupt list)
  1134                              <1> 		;
  1135                              <1> 		; INPUT:
  1136                              <1> 		;	AL = IRQ number (0 to 15)
  1137                              <1> 		;	AH > 0 -> set
  1138                              <1> 		;	AH = 0 -> reset
  1139                              <1> 		;	
  1140                              <1> 		; Modified registers: eax, ebx, edx, edi 
  1141                              <1> 		;
  1142                              <1> 		
  1143 0001085C C0E002              <1> 		shl	al, 2 ; IRQ number * 4
  1144 0001085F 0FB6D8              <1> 		movzx	ebx, al
  1145                              <1> 
  1146 00010862 08E4                <1> 		or	ah, ah
  1147 00010864 7508                <1> 		jnz	short shintv_1 ; set (for user call service)
  1148                              <1> 		
  1149                              <1> 		; 18/03/2017
  1150 00010866 81C3[F4210100]      <1> 		add	ebx, IRQ_list ; reset to default interrupt list
  1151 0001086C EB06                <1> 		jmp	short shintv_2
  1152                              <1> shintv_1:
  1153 0001086E 81C3[95080100]      <1> 		add	ebx, IRQ_u_list
  1154                              <1> shintv_2:	
  1155 00010874 8B13                <1> 		mov	edx, [ebx] ; IRQ handler address
  1156                              <1> 		
  1157                              <1> 		; 03/03/2017
  1158 00010876 D0E0                <1> 		shl	al, 1 ; IRQ number * 8 
  1159                              <1> 		; 18/03/2017
  1160 00010878 0FB6F8              <1> 		movzx	edi, al 
  1161 0001087B 81C7[F0610100]      <1> 		add	edi, idt + (8*32) ; IRQ 0 offset = idt + 256
  1162                              <1> 		
  1163 00010881 89D0                <1> 		mov	eax, edx ; IRQ handler address
  1164 00010883 BB00000800          <1> 		mov	ebx, 80000h
  1165                              <1> 
  1166                              <1> 		;mov	edx, eax
  1167 00010888 66BA008E            <1> 		mov	dx, 8E00h
  1168 0001088C 6689C3              <1> 		mov	bx, ax
  1169 0001088F 89D8                <1> 		mov	eax, ebx ; /* selector = 0x0008 = cs */
  1170                              <1>        			         ; /* interrupt gate - dpl=0, present */
  1171 00010891 AB                  <1> 		stosd	; selector & offset bits 0-15 	
  1172 00010892 8917                <1> 		mov	[edi], edx ; attributes & offset bits 16-23
  1173                              <1> 
  1174 00010894 C3                  <1> 		retn
  1175                              <1> IRQ_u_list:
  1176                              <1> 		; 28/02/2017
  1177 00010895 [46090000]          <1> 		dd	timer_int
  1178 00010899 [BE100000]          <1> 		dd	kb_int
  1179 0001089D [280B0000]          <1> 		dd	irq2
  1180 000108A1 [D5080100]          <1> 		dd	IRQ_service3
  1181 000108A5 [DF080100]          <1> 		dd	IRQ_service4
  1182 000108A9 [E9080100]          <1> 		dd	IRQ_service5
  1183 000108AD [A44B0000]          <1> 		dd	fdc_int	
  1184 000108B1 [F3080100]          <1> 		dd	IRQ_service7
  1185 000108B5 [B10A0000]          <1> 		dd	rtc_int
  1186 000108B9 [FD080100]          <1> 		dd	IRQ_service9
  1187 000108BD [07090100]          <1> 		dd	IRQ_service10
  1188 000108C1 [11090100]          <1> 		dd	IRQ_service11
  1189 000108C5 [1B090100]          <1> 		dd	IRQ_service12
  1190 000108C9 [25090100]          <1> 		dd	IRQ_service13
  1191 000108CD [58550000]          <1> 		dd	hdc1_int
  1192 000108D1 [7F550000]          <1> 		dd	hdc2_int
  1193                              <1> 
  1194                              <1> 		; 03/03/2017
  1195                              <1> 		; 27/02/2017
  1196                              <1> IRQ_service3:
  1197 000108D5 36C605[56760100]03  <1> 		mov	byte [ss:IRQnum], 3
  1198 000108DD EB4E                <1> 		jmp	short IRQ_service
  1199                              <1> IRQ_service4:
  1200 000108DF 36C605[56760100]04  <1> 		mov	byte [ss:IRQnum], 4
  1201 000108E7 EB44                <1> 		jmp	short IRQ_service
  1202                              <1> IRQ_service5:
  1203 000108E9 36C605[56760100]05  <1> 		mov	byte [ss:IRQnum], 5
  1204 000108F1 EB3A                <1> 		jmp	short IRQ_service
  1205                              <1> IRQ_service7:
  1206 000108F3 36C605[56760100]07  <1> 		mov	byte [ss:IRQnum], 7
  1207 000108FB EB30                <1> 		jmp	short IRQ_service
  1208                              <1> IRQ_service9:
  1209 000108FD 36C605[56760100]09  <1> 		mov	byte [ss:IRQnum], 9
  1210 00010905 EB26                <1> 		jmp	short IRQ_service
  1211                              <1> IRQ_service10:
  1212 00010907 36C605[56760100]0A  <1> 		mov	byte [ss:IRQnum], 10
  1213 0001090F EB1C                <1> 		jmp	short IRQ_service
  1214                              <1> IRQ_service11:
  1215 00010911 36C605[56760100]0B  <1> 		mov	byte [ss:IRQnum], 11
  1216 00010919 EB12                <1> 		jmp	short IRQ_service
  1217                              <1> IRQ_service12:
  1218 0001091B 36C605[56760100]0C  <1> 		mov	byte [ss:IRQnum], 12
  1219 00010923 EB08                <1> 		jmp	short IRQ_service
  1220                              <1> IRQ_service13:
  1221 00010925 36C605[56760100]0D  <1> 		mov	byte [ss:IRQnum], 13
  1222                              <1> 		;jmp	short IRQ_service
  1223                              <1> IRQ_service:
  1224                              <1> 		; 13/06/2017
  1225                              <1> 		; 11/06/2017
  1226                              <1> 		; 10/06/2017
  1227                              <1> 		; 01/03/2017, 04/03/2017
  1228                              <1> 		; 27/02/2017, 28/02/2017
  1229 0001092D 1E                  <1> 		push	ds
  1230 0001092E 06                  <1> 		push	es
  1231 0001092F 0FA0                <1> 		push	fs
  1232 00010931 0FA8                <1> 		push	gs
  1233                              <1> 
  1234 00010933 60                  <1> 		pushad	; eax,ecx,edx,ebx,esp,ebp,esi,edi
  1235 00010934 66B91000            <1> 		mov     cx, KDATA
  1236 00010938 8ED9                <1>         	mov     ds, cx
  1237 0001093A 8EC1                <1>         	mov     es, cx
  1238 0001093C 8EE1                <1>         	mov     fs, cx
  1239 0001093E 8EE9                <1>         	mov     gs, cx
  1240                              <1> 
  1241 00010940 0F20D8              <1> 		mov	eax, cr3
  1242 00010943 A3[52760100]        <1> 		mov	[IRQ_cr3], eax
  1243                              <1> 
  1244 00010948 A1[D8630100]        <1> 		mov	eax, [k_page_dir]
  1245 0001094D 0F22D8              <1> 		mov	cr3, eax 
  1246                              <1> 
  1247 00010950 A0[56760100]        <1> 		mov	al, [IRQnum]
  1248                              <1> 
  1249                              <1> 		;mov	cl, [sysflg]
  1250                              <1> 		;mov	[u.r_mode], cl  ; system (0) or user mode (FFh) 
  1251                              <1> IRQsrv_0:
  1252 00010955 0FB6D8              <1> 		movzx	ebx, al
  1253 00010958 8A9B[2A210100]      <1> 		mov	bl, [ebx+IRQenum] ; IRQ (available) index number + 1
  1254                              <1> 		; 01/03/2017
  1255 0001095E FECB                <1> 		dec	bl  ; IRQ index number, 0 to 8
  1256 00010960 0F8807010000        <1> 		js	IRQsrv_5 ; not available to use here!?
  1257                              <1> 		;		 
  1258 00010966 80BB[1C760100]80    <1> 		cmp	byte [ebx+IRQ.method], 80h ; using by a dev or kernel? 
  1259 0001096D 7205                <1> 		jb	short IRQsrv_1 ; no
  1260                              <1> 
  1261                              <1> 		; If the IRQ service is already owned by TRDOS 386 kernel
  1262                              <1> 		;	 or a Device driver
  1263                              <1> 		; we need to call 'dev_IRQ_service'
  1264                              <1> 
  1265                              <1> 		; IRQ number in AL
  1266 0001096F E866020000          <1> 		call	dev_IRQ_service	 ; IRQ service for device drivers	
  1267                              <1> 		; IRQ number in AL
  1268                              <1> IRQsrv_1:		
  1269                              <1> 		; check user callback service status
  1270                              <1> 		; AL = IRQ number
  1271                              <1> 		; EBX = IRQ (Available) Index number
  1272                              <1> 
  1273 00010974 A2[D7030300]        <1> 		mov	[u.irqwait], al ; set waiting IRQ flag
  1274                              <1> 
  1275 00010979 8A83[0A760100]      <1> 		mov	al, [ebx+IRQ.owner]
  1276 0001097F 20C0                <1> 		and	al, al
  1277 00010981 0F84E6000000        <1> 		jz	IRQsrv_5 ; it is not owned by a user/proc
  1278                              <1> 
  1279                              <1> 		; 03/03/2017
  1280 00010987 89DA                <1> 		mov	edx, ebx
  1281 00010989 C0E202              <1> 		shl	dl, 2
  1282 0001098C 8B92[2E760100]      <1> 		mov	edx, [edx+IRQ.addr] ; S.R.B. or Callback service addr
  1283                              <1> 		
  1284 00010992 8AA3[1C760100]      <1> 		mov	ah, [ebx+IRQ.method]
  1285 00010998 F6C401              <1> 		test	ah, 1
  1286 0001099B 7534                <1> 		jnz	short IRQsrv_4 ; Callback service method
  1287                              <1> 
  1288                              <1> 		; Signal Response Byte method
  1289                              <1> 		;mov	edx, [edx+IRQ.addr] ; Signal Response Byte address
  1290                              <1> 		;			    ; (Physical address, non-swappable) 	
  1291 0001099D 80E402              <1> 		and	ah, 2 ; bit 1, (S.R.B.) counter (auto increment) method
  1292 000109A0 8AA3[25760100]      <1> 		mov	ah, [ebx+IRQ.srb] ; Signal Response Byte value
  1293 000109A6 7408                <1> 		jz	short IRQsrv_2 ; fixed S.R.B. value
  1294                              <1> 		; counter method (auto increment)
  1295 000109A8 FEC4                <1> 		inc	ah
  1296 000109AA 88A3[25760100]      <1> 		mov	[ebx+IRQ.srb], ah ; next (count) number
  1297                              <1> IRQsrv_2:
  1298 000109B0 8822                <1> 		mov	[edx], ah ; put S.R.B. val to the user's S.R.B. addr
  1299 000109B2 C605[D7030300]00    <1> 		mov	byte [u.irqwait], 0 ; clear waiting IRQ flag
  1300                              <1> 
  1301 000109B9 3A05[B3030300]      <1> 		cmp	al, [u.uno]
  1302 000109BF 0F84A8000000        <1> 		je	IRQsrv_5 ; the owner is current user/process
  1303                              <1> IRQsrv_3:
  1304                              <1> 		; the owner is not current user/process
  1305                              <1> 		; AL = process number
  1306 000109C5 B202                <1> 		mov	dl, 2 ; priority, 2 = event (high)	
  1307 000109C7 E837FAFFFF          <1> 		call	set_run_sequence
  1308                              <1> 
  1309                              <1> 		; [u.irqwait] = waiting IRQ number for callback service
  1310                              <1> 
  1311 000109CC E99C000000          <1> 		jmp	IRQsrv_5
  1312                              <1> IRQsrv_4:
  1313 000109D1 3A05[B3030300]      <1> 		cmp	al, [u.uno]  ; is the owner is current user/process?
  1314 000109D7 75EC                <1> 		jne	short IRQsrv_3 ; no !
  1315                              <1> 
  1316                              <1> 		; Check if an IRQ callback service already in progress
  1317 000109D9 803D[D8030300]00    <1> 		cmp	byte [u.r_lock], 0
  1318 000109E0 0F8787000000        <1> 		ja	IRQsrv_5 ; nothing to do !  
  1319                              <1> 				     ; (we need to complete prev callback)
  1320 000109E6 803D[D4030300]00    <1> 		cmp	byte [u.t_lock], 0
  1321 000109ED 777E                <1> 		ja	short IRQsrv_5 ; nothing to do !  
  1322                              <1> 				     ; (we need to complete timer callback)
  1323                              <1> 
  1324                              <1> 		; 04/03/2017
  1325 000109EF C605[D7030300]00    <1> 		mov	byte [u.irqwait], 0 ; reset/clear waiting IRQ flag
  1326                              <1> 
  1327 000109F6 FE05[D8030300]      <1> 		inc	byte [u.r_lock] ; 'IRQ callback service in progress' flag
  1328                              <1> 
  1329 000109FC 8A0D[5B030300]      <1> 		mov	cl, [sysflg]   ; (system call) mode flag (kernel/user)
  1330 00010A02 880D[D9030300]      <1> 		mov	[u.r_mode], cl ; system mode (0) or user mode (FFh)
  1331                              <1> 
  1332                              <1> 		; 
  1333 00010A08 8B2D[74630100]      <1> 		mov	ebp, [tss.esp0] ; kernel stack address (for ring 0)
  1334 00010A0E 83ED14              <1> 		sub	ebp, 20		; eip, cs, eflags, esp, ss
  1335 00010A11 892D[5C030300]      <1> 	 	mov	[u.sp], ebp
  1336 00010A17 8925[60030300]      <1> 		mov	[u.usp], esp
  1337                              <1> 
  1338                              <1> 		;or	word [ebp+8], 200h ; 22/01/2017, force enabling interrupts
  1339                              <1> 
  1340 00010A1D 8B44241C            <1> 		mov	eax, [esp+28] ; pushed eax
  1341 00010A21 A3[64030300]        <1> 		mov	[u.r0], eax
  1342                              <1> 
  1343 00010A26 E81AE7FFFF          <1> 		call	wswap ; save user's registers & status
  1344                              <1> 
  1345                              <1> 		; software int is in ring 0 but IRQ handler must return to ring 3
  1346                              <1> 		; so, ring 3 return address and stack registers
  1347                              <1> 		; (eip, cs, eflags, esp, ss) 
  1348                              <1> 		; must be copied to IRQ handler return
  1349                              <1> 		; eip will be replaced by callback service routine address
  1350                              <1> 
  1351 00010A2B C605[5B030300]FF    <1> 		mov	byte [sysflg], 0FFh ; user mode
  1352                              <1> 
  1353                              <1> 		; system mode (system call)
  1354                              <1> 		;mov	ebp, [u.sp] ; EIP (u), CS (UCODE), EFLAGS (u),
  1355                              <1> 				    ; ESP (u), SS (UDATA)
  1356                              <1> 
  1357 00010A32 8B4510              <1> 		mov	eax, [ebp+16]	; SS (UDATA)
  1358 00010A35 89E6                <1> 		mov	esi, esp
  1359 00010A37 50                  <1> 		push	eax
  1360 00010A38 50                  <1> 		push	eax
  1361 00010A39 89E7                <1> 		mov	edi, esp
  1362 00010A3B 893D[60030300]      <1> 		mov	[u.usp], edi
  1363 00010A41 B908000000          <1> 		mov	ecx, ((ESPACE/4) - 4) ; except DS, ES, FS, GS
  1364 00010A46 F3A5                <1> 		rep	movsd
  1365 00010A48 B104                <1> 		mov	cl, 4	
  1366 00010A4A F3AB                <1> 		rep	stosd
  1367 00010A4C 893D[5C030300]      <1> 		mov	[u.sp], edi
  1368 00010A52 89EE                <1> 		mov	esi, ebp
  1369 00010A54 B105                <1> 		mov	cl, 5 ; EIP (u), CS (UCODE), EFLAGS (u), ESP (u), SS (UDATA)
  1370 00010A56 F3A5                <1> 		rep	movsd
  1371                              <1> 		;
  1372                              <1> 
  1373 00010A58 8B0D[B8030300]      <1> 		mov	ecx, [u.pgdir]
  1374 00010A5E 890D[52760100]      <1> 		mov	[IRQ_cr3], ecx
  1375                              <1> 
  1376                              <1> set_IRQ_callback_addr:
  1377                              <1> 		;
  1378                              <1> 		; This routine sets return address
  1379                              <1> 		; to start of user's interrupt
  1380                              <1> 		; service (callback) address
  1381                              <1> 		;
  1382                              <1> 		; INPUT:
  1383                              <1> 		;	EDX = callback routine/service address
  1384                              <1> 		;	      (virtual, not physical address!)	
  1385                              <1> 		;	[u.sp] = kernel stack, points to
  1386                              <1> 		;		 user's EIP,CS,EFLAGS,ESP,SS
  1387                              <1> 		;		 registers.
  1388                              <1> 		; OUTPUT:
  1389                              <1> 		;	EIP (user) = callback (service) address
  1390                              <1> 		;	CS (user) = UCODE
  1391                              <1> 		;	EFLAGS (user) = flags before callback 	 
  1392                              <1> 		;       ESP (user) = ESP-4 (user, before callback) 
  1393                              <1> 		;	[ESP](user) = EIP (user) before callback
  1394                              <1> 		;
  1395                              <1> 		; Note: If CPU was in user mode while entering 
  1396                              <1> 		;	the timer interrupt service routine,
  1397                              <1> 		;	'IRET' will get return to callback routine
  1398                              <1> 		;	immediately. If CPU was in system/kernel mode  
  1399                              <1> 		;	'iret' will get return to system call and
  1400                              <1> 		;	then, callback routine will be return address
  1401                              <1> 		;	from system call. (User's callback/service code
  1402                              <1> 		;	will be able to return to normal return address
  1403                              <1> 		;	via a 'sysrele' system call at the end.) 
  1404                              <1> 		;
  1405                              <1> 		; Note: User's IRQ callback service code must be ended
  1406                              <1> 		;	with a 'sysrele' system call !
  1407                              <1> 		;
  1408                              <1> 		;	For example:
  1409                              <1> 		;
  1410                              <1> 		;	audio_IRQ_callback:
  1411                              <1> 		;	    ...	 
  1412                              <1> 		;	    <load DMA buffer with audio data>
  1413                              <1> 		;	    ...
  1414                              <1> 		;	    mov eax, 39 ; 'sysrele'
  1415                              <1> 		;	    int 40h ; TRDOS 386 system call (interrupt)		
  1416                              <1> 		;
  1417                              <1> 		
  1418                              <1> 		;mov	edx, [edx+IRQ.addr] ; Callback service address
  1419                              <1> 		;			    ; (Virtual address)
  1420                              <1> 		
  1421 00010A64 8B2D[5C030300]      <1> 		mov	ebp, [u.sp]; kernel's stack, points to EIP (user)
  1422 00010A6A 895500              <1> 		mov	[ebp], edx
  1423                              <1> IRQsrv_5:
  1424                              <1> 		; EOI & return
  1425                              <1> 		; 01/08/2020
  1426                              <1> 		; 11/06/2017
  1427                              <1> 		; 10/06/2017 
  1428                              <1> 		;mov	al, [IRQnum]
  1429 00010A6D B020                <1> 		mov	al, 20h ; 01/08/2020
  1430 00010A6F FA                  <1> 		cli
  1431                              <1> 		;cmp	al, 7
  1432 00010A70 803D[56760100]07    <1> 		cmp	byte [IRQnum], 7 ; 01/08/2020	
  1433 00010A77 7602                <1> 		jna	short IRQsrv_6
  1434                              <1> 		;
  1435                              <1> 		;;mov	al, EOI	; end of interrupt
  1436                              <1> 		;mov	al, 20h ; 01/08/2020
  1437                              <1> 		;cli		; disable interrupts till stack cleared
  1438                              <1> 		;out	INTB00, al ; For controll2 #2
  1439 00010A79 E6A0                <1> 		out	0A0h, al
  1440                              <1> IRQsrv_6:
  1441                              <1> 		;mov	byte [IRQnum], 0 ; reset
  1442                              <1> 		;;mov	al, EOI	; end of interrupt
  1443                              <1> 		;mov	al, 20h ; 01/08/2020
  1444                              <1> 		;cli		; disable interrupts till stack cleared
  1445                              <1> 		;out	INTA00, al ; end of interrupt to 8259 - 1
  1446 00010A7B E620                <1> 		out	20h, al	
  1447                              <1> IRQsrv_7:	
  1448                              <1> 		;; 13/06/2017
  1449                              <1> 		;or	word [ebp+8], 200h ; force enabling interrupts
  1450                              <1> 		;
  1451 00010A7D 8B0D[52760100]      <1> 		mov 	ecx, [IRQ_cr3]	; previous content of cr3 register
  1452 00010A83 0F22D9              <1>  		mov	cr3, ecx	; restore cr3 register content
  1453                              <1> 		;
  1454 00010A86 61                  <1> 		popad ; edi,esi,ebp,(icrement esp by 4),ebx,edx,ecx,eax
  1455                              <1> 		;
  1456 00010A87 0FA9                <1> 		pop	gs
  1457 00010A89 0FA1                <1> 		pop	fs
  1458 00010A8B 07                  <1> 		pop	es
  1459 00010A8C 1F                  <1> 		pop	ds
  1460                              <1> 		;
  1461 00010A8D CF                  <1> 		iretd	; return from interrupt
  1462                              <1> 
  1463                              <1> get_device_number:
  1464                              <1> 		; 08/10/2016
  1465                              <1> 		; 07/10/2016 - TRDOS 386 (TRDOS v2.0)
  1466                              <1> 		;
  1467                              <1> 		; This procedure compares name of requested
  1468                              <1> 		; device with kernel device names and
  1469                              <1> 		; installable device names. If names match, 
  1470                              <1> 		; the relevant device index (entry) number 
  1471                              <1> 		; will be returned the caller (sysopen) 
  1472                              <1> 		; for the requested device.
  1473                              <1> 		;
  1474                              <1> 		; NOTE: Installable device drivers must
  1475                              <1> 		; be loaded before using 'sysopen'
  1476                              <1> 		; (opendev) system call.
  1477                              <1> 		;
  1478                              <1> 		; INPUT:
  1479                              <1> 		;    ESI = device name address (ASCIIZ)
  1480                              <1> 		;         (in kernel's memory space)  
  1481                              <1>    		;    max name length = 8 without '/dev/')
  1482                              <1> 		;    Device name will be capitalized 
  1483                              <1> 		;    and if there is, '/dev/' will be
  1484                              <1> 		;    removed from name before comparising)
  1485                              <1> 		;
  1486                              <1> 		; OUTPUT:
  1487                              <1> 		;    cf = 0 -> 
  1488                              <1> 		;      EAX (AL) = device entry/index number 	 	
  1489                              <1> 		;    cf = 1 -> device not found (installed)
  1490                              <1> 		;	       or invalid device name
  1491                              <1> 		;	       (AL=0)
  1492                              <1> 		;    device_name = device name address (asciiz)
  1493                              <1> 			;
  1494                              <1> 		; Modified registers: EAX, EBX, ESI, EDI
  1495                              <1> 
  1496 00010A8E BF[95700100]        <1> 		mov	edi, device_name
  1497 00010A93 E805010000          <1> 		call 	lodsb_capitalize
  1498 00010A98 88C4                <1> 		mov	ah, al
  1499 00010A9A 3C2F                <1> 		cmp	al, '/'
  1500 00010A9C 750E                <1> 		jne	short gdn_1
  1501 00010A9E BF[95700100]        <1> 		mov	edi, device_name
  1502 00010AA3 E8F5000000          <1> 		call 	lodsb_capitalize
  1503                              <1> gdn_0:
  1504 00010AA8 20C0                <1> 		and	al, al ; 0 ?
  1505 00010AAA 7420                <1> 		jz	short gdn_err ; null name after '/'
  1506                              <1> gdn_1:
  1507 00010AAC 3C44                <1> 		cmp	al, 'D'
  1508 00010AAE 7517                <1> 		jne	short gdn_2
  1509 00010AB0 E8E8000000          <1> 		call 	lodsb_capitalize
  1510 00010AB5 3C45                <1> 		cmp	al, 'E'
  1511 00010AB7 750E                <1> 		jne	short gdn_2
  1512 00010AB9 E8DF000000          <1> 		call 	lodsb_capitalize
  1513 00010ABE 3C56                <1> 		cmp	al, 'V'
  1514 00010AC0 7505                <1> 		jne	short gdn_2			
  1515 00010AC2 AC                  <1> 		lodsb
  1516 00010AC3 3C2F                <1> 		cmp	al, '/'
  1517 00010AC5 740D                <1> 		je	short gdn_4
  1518                              <1> gdn_2:
  1519 00010AC7 80FC2F              <1> 		cmp	ah, '/'
  1520 00010ACA 750F                <1> 		jne	short gdn_5
  1521                              <1> gdn_err:		
  1522                              <1> 		; invalid device name or device not found
  1523 00010ACC 31C0                <1> 		xor	eax, eax ; 0
  1524 00010ACE F9                  <1> 		stc
  1525 00010ACF C3                  <1> 		retn
  1526                              <1> gdn_3:
  1527 00010AD0 3C2F                <1> 		cmp	al, '/'
  1528 00010AD2 7507                <1> 		jne	short gdn_5
  1529                              <1> gdn_4:
  1530 00010AD4 BF[95700100]        <1> 		mov	edi, device_name
  1531 00010AD9 EB04                <1> 		jmp	short gdn_6
  1532                              <1> gdn_5:
  1533 00010ADB 3C00                <1> 		cmp	al, 0
  1534 00010ADD 7419                <1> 		je	short gdn_7
  1535                              <1> gdn_6:
  1536 00010ADF E8B9000000          <1> 		call lodsb_capitalize
  1537 00010AE4 81FF[9D700100]      <1> 		cmp	edi, device_name + 8
  1538 00010AEA 72E4                <1> 		jb	short gdn_3
  1539 00010AEC 3C00                <1> 		cmp	al, 0
  1540 00010AEE 75DC                <1> 		jne	short gdn_err
  1541 00010AF0 81FF[96700100]      <1> 		cmp	edi, device_name + 1
  1542 00010AF6 76D4                <1> 		jna	short gdn_err ; null name after '/'
  1543                              <1> gdn_7:
  1544 00010AF8 AA                  <1> 		stosb
  1545                              <1> 		; zero padding ("NAME",0,0,0,0)
  1546 00010AF9 81FF[9D700100]      <1> 		cmp	edi, device_name + 8
  1547 00010AFF 72F7                <1> 		jb	short gdn_7
  1548                              <1> gdn_8:
  1549                              <1> 		; search for kernel device names
  1550 00010B01 BE[95700100]        <1> 		mov	esi, device_name 
  1551 00010B06 BF[101F0100]        <1> 		mov	edi, KDEV_NAME
  1552 00010B0B 31C0                <1> 		xor	eax, eax
  1553                              <1> gdn_9:
  1554 00010B0D A7                  <1> 		cmpsd	
  1555 00010B0E 7505                <1> 		jne	short gdn_10
  1556 00010B10 A7                  <1> 		cmpsd
  1557 00010B11 7503                <1> 		jne	short gdn_11
  1558 00010B13 EB2B                <1> 		jmp	short gdn_17 ; match
  1559                              <1> gdn_10:
  1560 00010B15 A7                  <1> 		cmpsd  ; add esi, 4 & add edi, 4
  1561                              <1> gdn_11:
  1562 00010B16 BE[95700100]        <1> 		mov	esi, device_name
  1563 00010B1B FEC0                <1> 		inc	al
  1564 00010B1D 3C16                <1> 		cmp	al, NumOfKernelDevNames
  1565 00010B1F 72EC                <1> 		jb	short gdn_9
  1566                              <1> gdn_12:
  1567                              <1> 		; search for installable device names
  1568                              <1> 		; esi = offset device_name 
  1569 00010B21 BF[C0700100]        <1> 		mov	edi, IDEV_NAME
  1570 00010B26 28C0                <1> 		sub	al, al ; 0
  1571                              <1> gdn_13:
  1572 00010B28 A7                  <1> 		cmpsd	
  1573 00010B29 7505                <1> 		jne	short gdn_14
  1574 00010B2B A7                  <1> 		cmpsd
  1575 00010B2C 7503                <1> 		jne	short gdn_15
  1576 00010B2E EB3F                <1> 		jmp	short gdn_19 ; match
  1577                              <1> gdn_14:
  1578 00010B30 A7                  <1> 		cmpsd  ; add esi, 4 & add edi, 4
  1579                              <1> gdn_15:
  1580 00010B31 BE[95700100]        <1> 		mov	esi, device_name
  1581 00010B36 FEC0                <1> 		inc	al
  1582 00010B38 3C08                <1> 		cmp	al, NumOfInstallableDevices
  1583 00010B3A 72EC                <1> 		jb	short gdn_13
  1584                              <1> 
  1585                              <1> gdn_16: 	; error: invalid device name (not found) !
  1586 00010B3C 30C0                <1> 		xor	al, al
  1587 00010B3E F9                  <1> 		stc
  1588 00010B3F C3                  <1> 		retn
  1589                              <1> 
  1590                              <1> gdn_17:		; name match (with one of kernel device names)
  1591                              <1> 		;
  1592                              <1> 		; convert KDEV_NAME index to 
  1593                              <1> 		; KDEV_NUMBER index
  1594                              <1> 		; (different names are used for same devices)
  1595                              <1> 		; (example: "COM1" & "TTY8" = device number 18) 
  1596 00010B40 89C3                <1> 		mov	ebx, eax ; < 256
  1597 00010B42 8A83[C01F0100]      <1> 		mov	al, [KDEV_NUMBER+ebx]
  1598                              <1> 
  1599                              <1> 		; check if empty dev entry in the list
  1600 00010B48 80B8[44720100]00    <1> 		cmp	byte [DEV_OPENMODE+eax], 0
  1601 00010B4F 771B                <1> 		ja	short gdn_18 ; it must be already set
  1602                              <1> 
  1603                              <1> 		; (re)set device name and access flags
  1604                              <1> 		; (remain open work will be easy after that)
  1605                              <1> 		; (NOTE: here, data will be copied to bss section)
  1606 00010B51 88C3                <1> 		mov	bl, al
  1607 00010B53 83EF08              <1> 		sub	edi, 8 ; kernel device name address (data)
  1608 00010B56 66C1E302            <1> 		shl	bx, 2 
  1609 00010B5A 89BB[62720100]      <1> 		mov	[DEV_NAME_PTR+ebx], edi ; (all) device names
  1610 00010B60 8A98[16210100]      <1> 		mov	bl, [KDEV_ACCESS+eax] ; kernel dev list (data)
  1611 00010B66 8898[90710100]      <1> 		mov	[DEV_ACCESS+eax], bl ; (all) device list (bss)
  1612                              <1> gdn_18:
  1613 00010B6C FEC0                <1> 		inc	al ; 1 to NumOfKernelDevNames (<=7Fh)
  1614                              <1> 		; eax = device index/entry number
  1615 00010B6E C3                  <1> 		retn		
  1616                              <1> 
  1617                              <1> gdn_19:		; name match (with one of installable device names)
  1618                              <1> 		;
  1619                              <1> 		; al = 0 to NumOfInstallableDevices - 1 (<=7Fh)
  1620                              <1> 
  1621 00010B6F 89C3                <1> 		mov	ebx, eax
  1622 00010B71 80C316              <1> 		add	bl, NumOfKernelDevices 	; < NUMOFDEVICES	
  1623                              <1> 
  1624                              <1> 		; check if empty dev entry in the list
  1625 00010B74 80BB[44720100]00    <1> 		cmp	byte [DEV_OPENMODE+ebx], 0
  1626 00010B7B 771D                <1> 		ja	short gdn_20 ; it must be already set
  1627                              <1> 
  1628                              <1> 		; (re)set device name and access flags
  1629                              <1> 		; (remain open work will be easy after that)
  1630 00010B7D 83EF08              <1> 		sub	edi, 8 ; installable device name address
  1631 00010B80 66C1E302            <1> 		shl	bx, 2 ;*4
  1632 00010B84 89BB[62720100]      <1> 		mov	[DEV_NAME_PTR+ebx], edi ; (all) device names
  1633 00010B8A 66C1EB02            <1> 		shr	bx, 2
  1634 00010B8E 8A80[08710100]      <1> 		mov	al, [IDEV_FLAGS+eax] ; installable dev list
  1635 00010B94 8883[90710100]      <1> 		mov	[DEV_ACCESS+ebx], al ; (all) device list
  1636                              <1> gdn_20:	
  1637 00010B9A 88D8                <1> 		mov	al, bl
  1638                              <1> 		; eax = device index/entry number ; < NUMOFDEVICES  
  1639 00010B9C C3                  <1> 		retn
  1640                              <1> 
  1641                              <1> lodsb_capitalize:
  1642                              <1> 	; 07/10/2016 - TRDOS 386 (TRDOS v2.0)
  1643                              <1> 	; INPUT -> [esi] = character
  1644                              <1> 	;          edi = destination
  1645                              <1> 	; OUTPUT -> AL contains capitalized character
  1646                              <1> 	;	   esi = esi+1
  1647                              <1> 	;	   edi = edi+1	
  1648                              <1> 	; 
  1649 00010B9D AC                  <1> 	lodsb	
  1650 00010B9E 3C61                <1> 	cmp al, 61h
  1651 00010BA0 7206                <1>      	jb  short lodsb_cap_retn
  1652 00010BA2 3C7A                <1>      	cmp al, 7Ah
  1653 00010BA4 7702                <1>      	ja  short lodsb_cap_retn
  1654 00010BA6 24DF                <1>      	and al, 0DFh
  1655                              <1> lodsb_cap_retn:
  1656 00010BA8 AA                  <1> 	stosb
  1657 00010BA9 C3                  <1> 	retn
  1658                              <1> 
  1659                              <1> device_open:
  1660                              <1> 	; 08/10/2016 - TRDOS 386 (TRDOS v2.0)
  1661                              <1> 	; Complete device opening work for sysopen (device)
  1662                              <1> 	;
  1663                              <1> 	; INPUT -> 
  1664                              <1> 	;	EAX = Device Number (AL)
  1665                              <1> 	;        CL = Open mode (1 = read, 2 = write)
  1666                              <1> 	;	 CH = Device access byte (bit 0 = 0)		
  1667                              <1> 	; OUTPUT ->
  1668                              <1> 	;	EAX = Device Number	
  1669                              <1> 	;	CF = 0 -> device has been opened
  1670                              <1> 	;	CF = 1 -> device could not be opened
  1671                              <1> 	;
  1672                              <1> 	;  Modified registers: ebx, (edx, ecx, esi, edi, ebp)
  1673                              <1> 	;
  1674                              <1> 
  1675 00010BAA 89C3                <1> 	mov	ebx, eax
  1676 00010BAC 66C1E302            <1> 	shl	bx, 2 ; *4
  1677                              <1> 
  1678 00010BB0 F6C580              <1> 	test	ch, 80h ; bit 7, installable device driver flag
  1679 00010BB3 7406                <1> 	jz	short d_open_2 ; Kernel device
  1680                              <1> 	; installable device
  1681                              <1> d_open_1:
  1682 00010BB5 FFA3[0C710100]      <1>         jmp	dword [ebx+IDEV_OADDR-4]
  1683                              <1> d_open_2:
  1684 00010BBB FFA3[D21F0100]      <1> 	jmp	dword [ebx+KDEV_OADDR-4]
  1685                              <1> 
  1686                              <1> device_close:
  1687                              <1> 	; 08/10/2016 - TRDOS 386 (TRDOS v2.0)
  1688                              <1> 	; Complete device closing work for sysclose (device)
  1689                              <1> 	;
  1690                              <1> 	; INPUT -> 
  1691                              <1> 	;	EAX = Device Number (AL)
  1692                              <1> 	;        CL = Open mode (1 = read, 2 = write)
  1693                              <1> 	;	 CH = Device access byte (bit 0 = 0)		
  1694                              <1> 	; OUTPUT ->
  1695                              <1> 	;	EAX = Device Number	
  1696                              <1> 	;	CF = 0 -> device has been closed
  1697                              <1> 	;	CF = 1 -> device could not be closed
  1698                              <1> 	;
  1699                              <1> 	; Modified registers: ebx, (edx, ecx, esi, edi, ebp)
  1700                              <1> 	;
  1701                              <1> 
  1702 00010BC1 89C3                <1> 	mov	ebx, eax
  1703 00010BC3 66C1E302            <1> 	shl	bx, 2 ; *4
  1704                              <1> 
  1705 00010BC7 F6C580              <1> 	test	ch, 80h ; bit 7, installable device driver flag
  1706 00010BCA 7406                <1> 	jz	short d_close_2 ; Kernel device
  1707                              <1> 	; installable device
  1708                              <1> d_close_1:
  1709 00010BCC FFA3[2C710100]      <1>         jmp	dword [ebx+IDEV_CADDR-4]
  1710                              <1> d_close_2:
  1711 00010BD2 FFA3[22200100]      <1> 	jmp	dword [ebx+KDEV_CADDR-4]	
  1712                              <1> 
  1713                              <1> rnull:
  1714                              <1> 	; 07/10/2016 - TRDOS 386 (TRDOS v2.0)
  1715                              <1> 	; read null (read from null device)
  1716 00010BD8 C3                  <1> 	retn
  1717                              <1> 
  1718                              <1> wnull:
  1719                              <1> 	; 07/10/2016 - TRDOS 386 (TRDOS v2.0)
  1720                              <1> 	; write null (write to null device)
  1721 00010BD9 C3                  <1> 	retn
  1722                              <1> 
  1723                              <1> dev_IRQ_service:
  1724                              <1> 	; 12/05/2017
  1725                              <1> 	; 13/04/2017
  1726                              <1> 	; 27/02/2017 - TRDOS 386 (TRDOS v2.0)
  1727                              <1> 	; INPUT ->
  1728                              <1> 	;	AL = IRQ Number (0 to 15)
  1729                              <1> 	;	
  1730 00010BDA 53                  <1> 	push	ebx
  1731 00010BDB 0FB6D8              <1> 	movzx	ebx, al
  1732 00010BDE C0E302              <1> 	shl	bl, 2 ; * 4	
  1733 00010BE1 8B9B[CA750100]      <1> 	mov	ebx, [ebx+DEV_INT_HNDLR]
  1734 00010BE7 21DB                <1> 	and 	ebx, ebx
  1735 00010BE9 7404                <1>         jz	short dIRQ_s_retn
  1736 00010BEB 50                  <1> 	push	eax
  1737                              <1> 
  1738 00010BEC FFD3                <1> 	call	ebx
  1739                              <1> 
  1740 00010BEE 58                  <1> 	pop	eax
  1741                              <1> dIRQ_s_retn:
  1742 00010BEF 5B                  <1> 	pop	ebx
  1743 00010BF0 C3                  <1> 	retn		
  1744                              <1> 
  1745                              <1> 
  1746                              <1> set_dev_IRQ_service:
  1747                              <1> 	; 13/04/2017 - TRDOS 386 (TRDOS v2.0)
  1748                              <1> 	;
  1749                              <1> 	; Set Device Interrupt Service
  1750                              <1> 	;
  1751                              <1> 	; INPUT ->
  1752                              <1> 	;	AL = IRQ Number
  1753                              <1> 	;	EBX = Hardware Interrupt Service Address
  1754                              <1> 	;
  1755                              <1> 	; Note: There is not a validation check here
  1756                              <1> 	;	because this procedure is called by
  1757                              <1> 	;	TRDOS 386 kernel !
  1758                              <1> 	;       (Even if a device driver does not exist
  1759                              <1> 	;	this setting may be used by sysaudio
  1760                              <1> 	;	and other system calls for hardware
  1761                              <1> 	;	components which use IRQ method for I/O.)
  1762                              <1> 	;
  1763                              <1> 	;push	esi
  1764 00010BF1 0FB6F0              <1> 	movzx	esi, al
  1765 00010BF4 66C1E602            <1> 	shl	si, 2 ; * 4	
  1766 00010BF8 899E[CA750100]      <1> 	mov	[esi+DEV_INT_HNDLR], ebx
  1767                              <1> 	;pop	esi
  1768 00010BFE C3                  <1> 	retn		
  1769                              <1> 	
  1770                              <1> 
  1771                              <1> sysaudio: ; AUDIO FUNCTIONS
  1772                              <1> 	; 28/07/2020
  1773                              <1> 	; 27/07/2020
  1774                              <1> 	; 10/10/2017
  1775                              <1> 	; 22/06/2017
  1776                              <1> 	; 28/05/2017, 04/06/2017, 05/06/2017, 10/06/2017
  1777                              <1> 	; 01/05/2017, 12/05/2017, 15/05/2017, 20/05/2017
  1778                              <1> 	; 21/04/2017, 22/04/2017, 23/04/2017, 24/04/2017
  1779                              <1> 	; 10/04/2017, 13/04/2017, 14/04/2017, 16/04/2017
  1780                              <1> 	; 03/04/2017 (VIA VT8237R)
  1781                              <1> 	; 01/04/2016 (trdosk6.s -> tdosk8.s)
  1782                              <1> 	; 16/05/2016 - TRDOS 386 (TRDOS v2.0)
  1783                              <1> 	;
  1784                              <1> 	; Inputs:
  1785                              <1> 	;
  1786                              <1> 	;	BH = 0 -> Beep (PC Speaker)
  1787                              <1> 	;	     BL = Duration Counter (1 for 1/64 second)
  1788                              <1> 	;	     CX = Frequency Divisor (1193180/Frequency)
  1789                              <1> 	;		 (1331 for 886 Hz)
  1790                              <1> 	;
  1791                              <1> 	;	01/04/2017	
  1792                              <1> 	;
  1793                              <1> 	; 	BH = 1 -> DETECT (& ENABLE) AUDIO DEVICE
  1794                              <1> 	;	     BL = 0 : PC SPEAKER
  1795                              <1> 	;		  1 : SOUND BLASTER 16
  1796                              <1> 	;		  2 : INTEL AC'97
  1797                              <1> 	;		  3 : VIA VT8237R (VT8233)			 				
  1798                              <1> 	;		  4 : INTEL HDA
  1799                              <1> 	;	      5-FEh : unknown/invalid
  1800                              <1> 	;	        ; 04/06/2017
  1801                              <1> 	;		FFh : Get current audio device id
  1802                              <1> 	;
  1803                              <1> 	; 	BH = 2 -> ALLOCATE AUDIO BUFFER (for user)
  1804                              <1> 	;		ECX = Audio Buffer Size (must be equal to
  1805                              <1> 	;		      the half of DMA buffer size) 
  1806                              <1> 	;		EDX = Virtual Address of the buffer
  1807                              <1> 	;		      (This is not DMA buffer!)
  1808                              <1> 	;
  1809                              <1> 	;	BH = 3 -> INITIALIZE AUDIO DEVICE
  1810                              <1> 	;	     BL = 0,2 -> for Signal Response Byte	 	
  1811                              <1> 	;	     	CL = Signal Response Byte Value (fixed)
  1812                              <1> 	;				if BL = 0
  1813                              <1> 	;	             auto increment of S.R.B. value
  1814                              <1> 	;			 	if BL = 2
  1815                              <1> 	;	        EDX = Signal Response (Return) Byte Address
  1816                              <1> 	;	     	   			
  1817                              <1> 	;	     BL = 1 for CallBack Method	 	
  1818                              <1> 	;	    	EDX = CallBack Service Address (Virtual)
  1819                              <1> 	;
  1820                              <1> 	;	     BL > 2 -> invalid function	
  1821                              <1> 	;
  1822                              <1> 	;	    (Audio buffer must be allocated before
  1823                              <1> 	;	     initialization.) 		
  1824                              <1> 	;
  1825                              <1> 	;	BH = 4 -> START TO PLAY
  1826                              <1> 	;	     BL = Mode
  1827                              <1> 	;		  Bit 0 = mono/stereo (1 = stereo)		
  1828                              <1> 	;		  Bit 1 = 8 bit / 16 bit (1 = 16 bit)
  1829                              <1> 	;	     CX = Sampling Rate (Hz)
  1830                              <1> 	;
  1831                              <1> 	;	BH = 5 -> PAUSE
  1832                              <1> 	;	     BL = Any
  1833                              <1> 	;
  1834                              <1> 	;	BH = 6 -> CONTINUE TO PLAY
  1835                              <1> 	;	     BL = Any
  1836                              <1> 	;
  1837                              <1> 	;	BH = 7 -> STOP
  1838                              <1> 	;	     BL = Any
  1839                              <1> 	;
  1840                              <1> 	;	BH = 8 -> RESET 
  1841                              <1> 	;	     BL = Any
  1842                              <1> 	;
  1843                              <1> 	;	BH = 9 -> CANCEL (CALLBACK or S.R.B. SERVICE)
  1844                              <1> 	;	     BL = Any	
  1845                              <1> 	;	
  1846                              <1> 	;	BH = 10 -> DEALLOCATE AUDIO BUFFER (for user)
  1847                              <1> 	;	     BL = Any
  1848                              <1> 	;
  1849                              <1> 	;	BH = 11 -> SET VOLUME LEVEL
  1850                              <1> 	;	     BL: (Bit 0 to 6)
  1851                              <1> 	;		  0 = Master (Playback, Lineout) volume
  1852                              <1> 	;	     CL = Left Channel Volume
  1853                              <1> 	;	     CH = Right Channel Volume
  1854                              <1> 	;	
  1855                              <1> 	;	     Note: If BL >= 80h (Bit 7 of BL is set),
  1856                              <1> 	;	     volume level will be set for next playing
  1857                              <1> 	;	     (actual volume level will not be changed
  1858                              <1> 	;	     immediately)	
  1859                              <1> 	;
  1860                              <1> 	;	BH = 12 -> DISABLE AUDIO DEVICE
  1861                              <1> 	;	     (reset audio device and unlink dma buffer)	
  1862                              <1> 	;	     BL = Any	  		  	  	
  1863                              <1> 	;
  1864                              <1> 	;    	12/05/2017
  1865                              <1> 	;	BH = 13 -> MAP DMA BUFFER TO USER
  1866                              <1> 	;	    (for direct access to system's dma buffer)
  1867                              <1> 	;
  1868                              <1> 	;	     ECX = map size in bytes 
  1869                              <1> 	;		  (will be rounded up to page borders)
  1870                              <1> 	;	     EDX = Virtual Address of the buffer
  1871                              <1> 	;		  (Will be rounded up to page borders)
  1872                              <1> 	;
  1873                              <1> 	;	05/06/2017	
  1874                              <1> 	;    	04/06/2017
  1875                              <1> 	;	BH = 14 -> GET AUDIO DEVICE INFO
  1876                              <1> 	;	     BL: 0 = Audio Controller Info
  1877                              <1> 	;	       > 0 = Invalid for now! 
  1878                              <1> 	;
  1879                              <1> 	;	22/06/2017	
  1880                              <1> 	;	BH = 15 -> GET CURRENT SOUND DATA (for graphics)
  1881                              <1> 	;	     BL: 0 -> PCM OUT data
  1882                              <1> 	;	       > 0 -> Invalid for now! 
  1883                              <1> 	;	     ECX = 0 -> Get DMA Buffer Pointer
  1884                              <1> 	;		 EDX = Not Used
  1885                              <1> 	;	     ECX > 0 -> Byte count for buffer (EDX)	 	
  1886                              <1> 	;	         EDX = Buffer Address (Virtual)	
  1887                              <1> 	;
  1888                              <1> 	;	10/10/2017	
  1889                              <1> 	;	BH = 16 -> UPDATE DMA BUFFER DATA
  1890                              <1> 	;		   (by using the Audio Buffer content)
  1891                              <1> 	;	     BL = 0 : Update dma half buffer in sequence
  1892                              <1> 	;		      (automatic destination)	
  1893                              <1> 	;		  1 : Update 1st half of the dma buffer
  1894                              <1> 	;		  2 : Update 2nd half of the dma buffer
  1895                              <1> 	;		  3-FEh: Invalid!
  1896                              <1> 	;		  FFh = Get current flag value
  1897                              <1> 	;			(Half buffer number -1)
  1898                              <1> 	;
  1899                              <1> 	;
  1900                              <1> 	; Outputs:
  1901                              <1> 	;
  1902                              <1> 	;	For BH = 0 -> Beep
  1903                              <1> 	;	    None
  1904                              <1> 	;
  1905                              <1> 	;	01/04/2017
  1906                              <1> 	;
  1907                              <1> 	; 	For BH = 1 -> DETECT (& ENABLE) AUDIO DEVICE
  1908                              <1> 	;	    AH = 0 : PC SPEAKER
  1909                              <1> 	;		 1 : SOUND BLASTER 16
  1910                              <1> 	;		 2 : INTEL AC'97
  1911                              <1> 	;		 3 : VIA VT8237R (VT8233)			 				
  1912                              <1> 	;		 4 : INTEL HDA
  1913                              <1> 	;	      5-FFh : unknown/invalid
  1914                              <1> 	;	    AL = mode status
  1915                              <1> 	;		 bit 0 = mono /stereo (1 = stereo)
  1916                              <1> 	;		 bit 1 = 8 bit / 16 bit ( 1 = 16 bit)
  1917                              <1> 	;	    04/06/2017
  1918                              <1> 	;	    EBX = PCI DEVICE/VENDOR ID (if >0)
  1919                              <1> 	;		 (BX = VENDOR ID) 
  1920                              <1> 	;	    (if CF = 1 -> Error code in EAX)
  1921                              <1> 	;
  1922                              <1> 	; 	For BH = 2 -> ALLOCATE AUDIO BUFFER (for user)
  1923                              <1> 	;	    EAX = Physical Address of the buffer
  1924                              <1> 	;	    (if CF = 1 -> Error code in EAX)
  1925                              <1> 	;
  1926                              <1> 	;	For BH = 3 -> INITIALIZE AUDIO DEVICE
  1927                              <1> 	;	    (if CF = 1 -> Error code in EAX)
  1928                              <1> 	;
  1929                              <1> 	;	For BH = 4 -> START TO PLAY
  1930                              <1> 	;	    none (if CF = 1 -> Error code in EAX)	
  1931                              <1> 	;
  1932                              <1> 	;	For BH = 5 -> PAUSE
  1933                              <1> 	;	    none (if CF = 1 -> Error code in EAX)	
  1934                              <1> 	;
  1935                              <1> 	;	For BH = 6 -> CONTINUE TO PLAY
  1936                              <1> 	;	    none (if CF = 1 -> Error code in EAX)	
  1937                              <1> 	;
  1938                              <1> 	;	For BH = 7 -> STOP
  1939                              <1> 	;	    none (if CF = 1 -> Error code in EAX)
  1940                              <1> 	;
  1941                              <1> 	;	For BH = 8 -> RESET 
  1942                              <1> 	;	    none (if CF = 1 -> Error code in EAX)
  1943                              <1> 	;
  1944                              <1> 	;	For BH = 9 -> CANCEL (CALLBACK or S.R.B. SERVICE)
  1945                              <1> 	;	    none (if CF = 1 -> Error code in EAX)
  1946                              <1> 	;	
  1947                              <1> 	;	For BH = 10 -> DEALLOCATE AUDIO BUFFER (for user)
  1948                              <1> 	;	    none (if CF = 1 -> Error code in EAX)
  1949                              <1> 	;
  1950                              <1> 	;	For BH = 11 -> SET VOLUME LEVEL
  1951                              <1> 	;	    none (if CF = 1 -> Error code in EAX)
  1952                              <1> 	;
  1953                              <1> 	;	For BH = 12 -> DISABLE AUDIO DEVICE
  1954                              <1> 	;	    none (if CF = 1 -> Error code in EAX)
  1955                              <1> 	; 
  1956                              <1> 	;    	12/05/2017
  1957                              <1> 	;	For BH = 13 -> MAP DMA BUFFER TO USER
  1958                              <1> 	;	    EAX = Physical Address of the buffer
  1959                              <1> 	;	    (if CF = 1 -> Error code in EAX)	
  1960                              <1> 	;
  1961                              <1> 	;    	04/06/2017
  1962                              <1> 	;	For BH = 14 -> GET AUDIO DEVICE INFO
  1963                              <1> 	;	(for BL = 0) ; 05/06/2017	
  1964                              <1> 	;	    EAX = IRQ Number in AL
  1965                              <1> 	;		  Audio Device Number in AH 
  1966                              <1> 	;	    EBX = DEV/VENDOR ID
  1967                              <1> 	;		 (DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV)
  1968                              <1> 	;	    ECX = BUS/DEV/FN 
  1969                              <1> 	;		 (00000000BBBBBBBBDDDDDFFF00000000)
  1970                              <1> 	;	    EDX = NABMBAR/NAMBAR (for AC97)
  1971                              <1> 	;		  (Low word, DX = NAMBAR address)
  1972                              <1> 	;	    EDX = Base IO Addr (DX) for SB16 & VT8233	  			  		
  1973                              <1> 	;	    (if CF = 1 -> Error code in EAX)	
  1974                              <1> 	;	                 (ERR_DEV_NOT_RDY = 15)  
  1975                              <1> 	;
  1976                              <1> 	;	22/06/2017	
  1977                              <1> 	;	For BH = 15 -> GET CURRENT SOUND DATA
  1978                              <1> 	;			 (for graphics)
  1979                              <1> 	;	(for BL = 0)
  1980                              <1> 	;	 If ECX input is 0 
  1981                              <1> 	;	    EAX = DMA Buffer Current Position (Offset)
  1982                              <1> 	;	 If ECX input >  0
  1983                              <1> 	;	    EAX = Actual transfer count 		 	
  1984                              <1> 	;	    (Sound samples will be copied from 
  1985                              <1> 	;	     Current DMA Buffer Position to EDX
  1986                              <1> 	;	     virtual address as EAX bytes.)
  1987                              <1> 	;	 ((If CF = 1 ->  Error code in EAX))
  1988                              <1> 	;
  1989                              <1> 	;
  1990                              <1> 	;	10/10/2017	
  1991                              <1> 	;	For BH = 16 -> UPDATE DMA BUFFER DATA
  1992                              <1> 	;	    EAX = 0, if the updated (or current)
  1993                              <1> 	;		     half buffer is DMA half buffer 1
  1994                              <1> 	;	    EAX = 1, if the updated (or current)
  1995                              <1> 	; 		     half buffer is DMA half buffer 2 	  	
  1996                              <1> 	;	    (If CF = 1 -> Error code in EAX)	
  1997                              <1> 	;	
  1998                              <1> 
  1999 00010BFF 80FF11              <1> 	cmp	bh, AUDIO1L/4
  2000 00010C02 0F83C4C6FFFF        <1> 	jnb	sysret
  2001                              <1> 
  2002 00010C08 C0E702              <1> 	shl	bh, 2 ; *4	
  2003 00010C0B 0FB6F7              <1> 	movzx	esi, bh
  2004                              <1> 
  2005                              <1> 	; 22/04/2017
  2006 00010C0E 31C0                <1> 	xor	eax, eax
  2007 00010C10 A3[64030300]        <1> 	mov	[u.r0], eax  ; 0
  2008                              <1> 		
  2009 00010C15 FF96[200C0100]      <1> 	call	dword [esi+AUDIO1]
  2010                              <1> 	;jc	error
  2011 00010C1B E9ACC6FFFF          <1> 	jmp	sysret	
  2012                              <1> 
  2013 00010C20 [F0220000]          <1> AUDIO1:	dd	beep ; FUNCTION = 0 (bl = Duration Counter
  2014                              <1> 		     ; 		     cx = Frequency Divisor
  2015 00010C24 [640C0100]          <1> 	dd	soundc_detect
  2016 00010C28 [000D0100]          <1> 	dd	sound_alloc
  2017 00010C2C [BE0D0100]          <1> 	dd	soundc_init
  2018 00010C30 [760F0100]          <1> 	dd	sound_play
  2019 00010C34 [12100100]          <1> 	dd	sound_pause
  2020 00010C38 [3C100100]          <1> 	dd	sound_continue
  2021 00010C3C [66100100]          <1> 	dd	sound_stop
  2022 00010C40 [8F100100]          <1> 	dd	soundc_reset
  2023 00010C44 [C0100100]          <1> 	dd	soundc_cancel
  2024 00010C48 [E6100100]          <1> 	dd	sound_dalloc
  2025 00010C4C [11110100]          <1> 	dd	sound_volume
  2026 00010C50 [63110100]          <1> 	dd	soundc_disable
  2027 00010C54 [D5110100]          <1> 	dd	sound_dma_map
  2028 00010C58 [44120100]          <1> 	dd	soundc_info
  2029 00010C5C [A3120100]          <1> 	dd	sound_data
  2030 00010C60 [50130100]          <1> 	dd	sound_update
  2031                              <1> 	
  2032                              <1> AUDIO1L	EQU	$ - AUDIO1
  2033                              <1> 
  2034                              <1> soundc_detect:
  2035                              <1> 	; FUNCTION = 1
  2036                              <1> 	; bl = Audio device type number 
  2037                              <1> 	; (0= pc speaker, 1 = sound blaster 16, 2 = intel ac97
  2038                              <1> 	;  3= via vt823x, 4 = intel HDA, 0FFh= any)
  2039                              <1> 	
  2040                              <1> 	; 04/06/2017
  2041 00010C64 8A25[59760100]      <1> 	mov	ah, [audio_device]
  2042 00010C6A 80FBFF              <1> 	cmp	bl, 0FFh ; get current audio device id
  2043 00010C6D 7408                <1> 	je	short sysaudio0
  2044                              <1> 
  2045 00010C6F 20E4                <1> 	and	ah, ah
  2046 00010C71 741E                <1> 	jz	short soundc_get_dev
  2047                              <1> 
  2048 00010C73 38DC                <1> 	cmp	ah, bl
  2049 00010C75 7567                <1> 	jne	short soundc_dev_err
  2050                              <1> 
  2051                              <1> sysaudio0:	
  2052 00010C77 A0[5A760100]        <1> 	mov	al, [audio_mode]
  2053                              <1> sysaudio1:
  2054 00010C7C A3[64030300]        <1> 	mov	[u.r0], eax
  2055 00010C81 8B1D[64760100]      <1> 	mov	ebx, [audio_vendor] ; (DEVICE/VENDOR ID)
  2056 00010C87 8B2D[60030300]      <1> 	mov	ebp, [u.usp]
  2057 00010C8D 895D10              <1> 	mov	[ebp+16], ebx  ; ebx
  2058 00010C90 C3                  <1> 	retn
  2059                              <1> 
  2060                              <1> soundc_get_dev:
  2061                              <1> 	; 28/05/2017
  2062                              <1> 	; 03/04/2017, 24/04/2017
  2063 00010C91 C605[58760100]00    <1> 	mov	byte [audio_pci], 0
  2064 00010C98 80FB03              <1> 	cmp	bl, 3 ; VIA VT8233 (VT8237R) Audio Controller & AC97 Codec
  2065                              <1> 	;jne	short soundc_get_dev_sb
  2066                              <1> 	; 28/05/2017
  2067 00010C9B 7220                <1> 	jb	short soundc_get_dev_sb
  2068 00010C9D 773F                <1> 	ja	short soundc_dev_err  ; temporary (28/05/2017)
  2069                              <1> 	;  		
  2070 00010C9F E86D180000          <1> 	call	DetectVT8233
  2071 00010CA4 7238                <1> 	jc	short soundc_dev_err
  2072                              <1> 	; eax = 0
  2073                              <1> 
  2074                              <1> 	;mov	ebx, [audio_vendor]
  2075                              <1> 	; ebx = DEVICE/VENDOR ID
  2076                              <1> 	;	DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV
  2077                              <1> 
  2078 00010CA6 B003                <1> 	mov	al, 3  ; VIA VT8237R (VT3233) Audio Controller
  2079 00010CA8 88C4                <1> 	mov	ah, al
  2080                              <1> 
  2081                              <1> soundc_get_pci_dev_ok: ; 28/05/2017
  2082 00010CAA FE05[58760100]      <1> 	inc	byte [audio_pci] ; = 1
  2083                              <1> soundc_get_dev_ok:
  2084                              <1> 	
  2085                              <1> soundc_get_dev_sb16_ok:
  2086 00010CB0 A2[59760100]        <1> 	mov	[audio_device], al
  2087 00010CB5 8825[5A760100]      <1> 	mov	[audio_mode], ah ; stereo (bit0), 16 bit (bit1) capability	
  2088 00010CBB EBBF                <1> 	jmp	short sysaudio1
  2089                              <1> 
  2090                              <1> soundc_get_dev_sb:
  2091                              <1> 	; 24/04/2017
  2092 00010CBD 80FB01              <1> 	cmp	bl, 1 ; Sound Blaster 16
  2093 00010CC0 750E                <1> 	jne	short soundc_get_dev_ich ; 28/05/2017
  2094                              <1> 	;
  2095 00010CC2 E86E1D0000          <1> 	call	DetectSB
  2096 00010CC7 7215                <1> 	jc	short soundc_dev_err
  2097 00010CC9 B801030000          <1> 	mov	eax, 0301h ; Sound Blaster 16
  2098 00010CCE EBE0                <1> 	jmp	short soundc_get_dev_sb16_ok
  2099                              <1> 
  2100                              <1> soundc_get_dev_ich:
  2101                              <1> 	; 28/05/2017
  2102                              <1> 	;cmp	bl, 2 ; Intel AC'97 Audio Controller (ICH)
  2103                              <1> 	;jne	short soundc_dev_err ; Temporary  (28/05/2017)
  2104                              <1> 	;			     ; (Here will be modified just after
  2105                              <1> 	;			     ; new sound card code will be ready!)  	
  2106 00010CD0 E82F180000          <1> 	call	DetectICH
  2107 00010CD5 7207                <1> 	jc	short soundc_dev_err
  2108                              <1> 	;
  2109 00010CD7 B802030000          <1> 	mov	eax, 0302h ; AC'97 (ICH)
  2110 00010CDC EBCC                <1> 	jmp	short soundc_get_pci_dev_ok
  2111                              <1> 
  2112                              <1> soundc_dev_err:
  2113 00010CDE B80F000000          <1> 	mov	eax, ERR_DEV_NOT_RDY ; Device not ready !
  2114 00010CE3 EB0C                <1> 	jmp	short sysaudio_err
  2115                              <1> 
  2116                              <1> sound_buff_error:
  2117 00010CE5 B82E000000          <1> 	mov	eax, ERR_BUFFER ; Buffer error !
  2118 00010CEA EB05                <1> 	jmp	short sysaudio_err
  2119                              <1> 
  2120                              <1> soundc_respond_err:
  2121                              <1> 	; ERR_TIME_OUT ; 'time out !' error	
  2122 00010CEC B819000000          <1> 	mov	eax, ERR_DEV_NOT_RESP ; 'device not responding !' error
  2123                              <1> sysaudio_err:
  2124 00010CF1 A3[64030300]        <1> 	mov	[u.r0], eax
  2125 00010CF6 A3[C8030300]        <1> 	mov	[u.error], eax
  2126 00010CFB E9ACC5FFFF          <1> 	jmp	error
  2127                              <1> 
  2128                              <1> sound_alloc:
  2129                              <1> 	; FUNCTION =  2
  2130                              <1> 	; ecx = audio buffer size (in bytes)
  2131                              <1> 	; edx = audio buffer address (virtual)
  2132                              <1> 	; 27/07/2020
  2133                              <1> 	; 28/05/2017
  2134                              <1> 	; 01/05/2017, 15/05/2017
  2135                              <1> 	; 21/04/2017, 24/04/2017
  2136 00010D00 803D[58760100]00    <1> 	cmp	byte [audio_pci], 0
  2137 00010D07 7708                <1> 	ja	short snd_alloc_0
  2138                              <1> 	; Max. 64KB DMA buffer !!!
  2139 00010D09 81F900800000        <1> 	cmp	ecx, 32768
  2140 00010D0F 77D4                <1> 	ja	short sound_buff_error
  2141                              <1> snd_alloc_0:
  2142                              <1> 	; 15/05/2017
  2143 00010D11 81F900100000        <1> 	cmp	ecx, 4096 ; PAGE_SIZE
  2144 00010D17 72CC                <1> 	jb	short sound_buff_error
  2145                              <1> 	;
  2146 00010D19 A1[6C760100]        <1> 	mov	eax, [audio_buffer] ; audio buffer address (current)
  2147 00010D1E 09C0                <1> 	or	eax, eax
  2148 00010D20 7445                <1> 	jz	short snd_alloc_2
  2149                              <1> 	; audio buffer exists !
  2150 00010D22 8A1D[B3030300]      <1> 	mov	bl, [u.uno]
  2151 00010D28 3A1D[81760100]      <1> 	cmp	bl, [audio_user]
  2152 00010D2E 0F85FC000000        <1> 	jne	sndc_owner_error ; not owner !
  2153 00010D34 39D0                <1> 	cmp	eax, edx ; same virtual buffer address ?
  2154 00010D36 7508                <1> 	jne	short snd_alloc_1
  2155 00010D38 3B0D[74760100]      <1> 	cmp	ecx, [audio_buff_size]
  2156 00010D3E 746C                <1> 	je	short snd_alloc_3 ; Nothing to do !
  2157                              <1> 				  ; Buffer has been set already!
  2158                              <1> snd_alloc_1:
  2159 00010D40 51                  <1> 	push	ecx
  2160 00010D41 52                  <1> 	push	edx
  2161 00010D42 89C3                <1> 	mov	ebx, eax ; audio buffer address (current)
  2162 00010D44 8B0D[74760100]      <1> 	mov	ecx, [audio_buff_size]
  2163 00010D4A E85B54FFFF          <1> 	call	deallocate_user_pages
  2164 00010D4F 5A                  <1> 	pop	edx
  2165 00010D50 59                  <1> 	pop	ecx
  2166 00010D51 31C0                <1> 	xor	eax, eax ; 0
  2167 00010D53 A3[6C760100]        <1> 	mov	[audio_buffer], eax  ; 0
  2168 00010D58 A3[70760100]        <1>  	mov	[audio_p_buffer], eax  ; 0
  2169 00010D5D A3[74760100]        <1>  	mov	[audio_buff_size], eax
  2170 00010D62 A2[81760100]        <1> 	mov	[audio_user], al ; 0
  2171                              <1> snd_alloc_2:
  2172 00010D67 89D3                <1> 	mov	ebx, edx
  2173                              <1> 	; 01/05/2017
  2174 00010D69 BA00F0FFFF          <1> 	mov	edx, ~PAGE_OFF ; truncating page offsets
  2175                              <1> 			       ; for aligning to page borders	
  2176                              <1> 	;and	eax, edx
  2177 00010D6E 21D3                <1> 	and	ebx, edx
  2178 00010D70 21D1                <1> 	and	ecx, edx
  2179                              <1> 	; 15/05/2017
  2180                              <1> 	; EAX = Beginning address (physical)
  2181                              <1> 	; EAX = 0 -> Allocate mem block from the 1st proper aperture	
  2182                              <1> 	; ECX = Number of bytes to be allocated		
  2183 00010D72 E8D850FFFF          <1> 	call	allocate_memory_block
  2184 00010D77 0F8268FFFFFF        <1> 	jc	sound_buff_error
  2185                              <1> 	; EAX = Physical address of the allocated memory block
  2186                              <1> 	; ECX = Allocated bytes (as truncated to page border)
  2187                              <1> 	; EBX = Virtual address (as truncated to page border)
  2188 00010D7D 50                  <1> 	push	eax
  2189 00010D7E 53                  <1> 	push	ebx
  2190 00010D7F 51                  <1> 	push	ecx
  2191 00010D80 E81A55FFFF          <1> 	call	allocate_user_pages
  2192 00010D85 59                  <1> 	pop	ecx
  2193 00010D86 5B                  <1> 	pop	ebx
  2194 00010D87 58                  <1> 	pop	eax
  2195 00010D88 722A                <1> 	jc	short snd_alloc_4  ; insufficient memory, buff error
  2196                              <1> 	; eax = physical address of the user's audio buffer
  2197                              <1> 	; ebx = virtual address of the user's audio buffer
  2198                              <1> 	; ecx = buffer size (in bytes)
  2199 00010D8A A3[70760100]        <1> 	mov	[audio_p_buffer], eax
  2200 00010D8F 891D[6C760100]      <1> 	mov	[audio_buffer], ebx
  2201 00010D95 890D[74760100]      <1>  	mov	[audio_buff_size], ecx
  2202 00010D9B 8A15[B3030300]      <1> 	mov	dl, [u.uno]
  2203 00010DA1 8815[81760100]      <1> 	mov	[audio_user], dl
  2204 00010DA7 A3[64030300]        <1> 	mov	[u.r0], eax
  2205                              <1> snd_alloc_3:
  2206                              <1> 	; 27/07/2020
  2207 00010DAC C605[80760100]00    <1> 	mov	byte [audio_flag], 0 ; clear dma half buffer flag
  2208                              <1> 	;	
  2209 00010DB3 C3                  <1> 	retn
  2210                              <1> snd_alloc_4:
  2211                              <1> 	; 15/05/2017
  2212                              <1> 	; EAX = Beginning address (physical)
  2213                              <1> 	; ECX = Number of bytes to be deallocated
  2214 00010DB4 E8A352FFFF          <1> 	call	deallocate_memory_block
  2215 00010DB9 E927FFFFFF          <1> 	jmp	sound_buff_error  ; insufficient memory, buff error
  2216                              <1> 
  2217                              <1> soundc_init:
  2218                              <1> 	; FUNCTION = 3 
  2219                              <1> 	; bl = method (0= s.r.b., 1= callback, 2= auto incr s.r.b.)
  2220                              <1> 	; cl = signal response byte (initial or fixed) value
  2221                              <1> 	; edx = signal response byte or callback address
  2222                              <1> 	; 27/07/2020
  2223                              <1> 	; 28/05/2017
  2224                              <1> 	; 12/05/2017, 20/05/2017
  2225                              <1> 	; 22/04/2017, 23/04/2017, 24/04/2017
  2226                              <1> 	; 13/04/2017, 14/04/2017, 16/04/2017, 21/04/2017
  2227                              <1> 	; 03/04/2017, 10/04/2017
  2228                              <1> 
  2229 00010DBE A0[59760100]        <1> 	mov	al, [audio_device]
  2230 00010DC3 20C0                <1> 	and	al, al
  2231 00010DC5 7549                <1> 	jnz	short sndc_init_6
  2232                              <1> 	;
  2233 00010DC7 C605[58760100]00    <1> 	mov	byte [audio_pci], 0
  2234 00010DCE 52                  <1> 	push	edx
  2235 00010DCF 53                  <1> 	push	ebx
  2236 00010DD0 51                  <1> 	push	ecx
  2237 00010DD1 E85F1C0000          <1> 	call	DetectSB
  2238 00010DD6 7213                <1> 	jc	short sndc_init_8
  2239 00010DD8 66B80103            <1> 	mov	ax, 0301h ; Sound Blaster 16
  2240 00010DDC EB1E                <1> 	jmp	short sndc_init_7
  2241                              <1> 
  2242                              <1> sndc_init_11:
  2243                              <1> 	; 28/05/2017
  2244 00010DDE E821170000          <1> 	call	DetectICH ; Detect AC'97 (ICH) Audio Controller
  2245 00010DE3 7217                <1> 	jc	short sndc_init_7
  2246 00010DE5 66B80203            <1> 	mov	ax, 0302h ; Intel AC'97 Audio Device
  2247 00010DE9 EB0B                <1> 	jmp	short sndc_init_12 ; (PCI device)
  2248                              <1> 
  2249                              <1> sndc_init_8:
  2250 00010DEB E821170000          <1> 	call	DetectVT8233
  2251                              <1> 	;jc	short sndc_init_7
  2252 00010DF0 72EC                <1> 	jc	sndc_init_11 ; 28/05/2017
  2253                              <1> 	; eax = 0
  2254 00010DF2 B003                <1> 	mov	al, 3	; VIA VT8237R (VT3233) Audio Controller
  2255 00010DF4 88C4                <1> 	mov	ah, al
  2256                              <1> 
  2257                              <1> sndc_init_12:
  2258 00010DF6 FE05[58760100]      <1> 	inc	byte [audio_pci] ; = 1
  2259                              <1> sndc_init_7:
  2260 00010DFC 59                  <1> 	pop	ecx
  2261 00010DFD 5B                  <1> 	pop	ebx
  2262 00010DFE 5A                  <1> 	pop	edx
  2263 00010DFF 0F82D9FEFFFF        <1> 	jc	soundc_dev_err
  2264                              <1> 	;
  2265 00010E05 A2[59760100]        <1> 	mov	[audio_device], al
  2266 00010E0A 8825[5A760100]      <1> 	mov	[audio_mode], ah ; stereo (bit0), 16 bit (bit1) capability
  2267                              <1> 
  2268                              <1> sndc_init_6:
  2269 00010E10 833D[6C760100]00    <1> 	cmp	dword [audio_buffer], 0
  2270 00010E17 0F86C8FEFFFF        <1> 	jna	sound_buff_error
  2271                              <1> 
  2272 00010E1D A0[B3030300]        <1> 	mov	al, [u.uno]
  2273 00010E22 8A25[81760100]      <1> 	mov	ah, [audio_user]
  2274 00010E28 08E4                <1> 	or	ah, ah
  2275 00010E2A 7418                <1> 	jz	short sndc_init0
  2276 00010E2C 38E0                <1> 	cmp	al, ah
  2277 00010E2E 7419                <1> 	je	short sndc_init1
  2278                              <1> 
  2279                              <1> sndc_owner_error:
  2280 00010E30 B80B000000          <1> 	mov	eax, ERR_NOT_OWNER ; 'permission denied !' error
  2281                              <1> sndc_perm_error:
  2282 00010E35 A3[64030300]        <1> 	mov	[u.r0], eax
  2283 00010E3A A3[C8030300]        <1> 	mov	[u.error], eax
  2284 00010E3F E968C4FFFF          <1> 	jmp	error
  2285                              <1> sndc_init0:
  2286 00010E44 A2[81760100]        <1> 	mov	[audio_user], al
  2287                              <1> sndc_init1:
  2288 00010E49 8915[84760100]      <1> 	mov	[audio_cb_addr], edx
  2289 00010E4F 881D[82760100]      <1> 	mov	[audio_cb_mode], bl
  2290 00010E55 880D[83760100]      <1> 	mov	[audio_srb], cl
  2291                              <1> 
  2292                              <1> 	; 27/07/2020
  2293                              <1> 	;mov	byte [audio_flag], 0  ; clear dma half buffer flag
  2294                              <1> 
  2295                              <1> 	; 24/04/2017
  2296 00010E5B 803D[59760100]03    <1> 	cmp	byte [audio_device], 3 ; VT8233 (VT8237R)
  2297 00010E62 7438                <1> 	je	short sndc_init_9
  2298                              <1> 	;ja	short soundc_respond_err ; temporary (28/05/2017)
  2299 00010E64 803D[59760100]01    <1> 	cmp	byte [audio_device], 1 ; SB 16
  2300 00010E6B 7510                <1> 	jne	short sndc_init_13
  2301 00010E6D BB[5A2C0100]        <1> 	mov	ebx, sb16_int_handler
  2302                              <1> 	; Note: 'SbInit' is at 'Start to Play' stage
  2303                              <1> 	; 20/05/2017
  2304 00010E72 66C705[8E760100]08- <1> 	mov	word [audio_master_volume], 0808h ; 2/8
  2304 00010E7A 08                  <1>
  2305 00010E7B EB3F                <1> 	jmp	short sndc_init_10
  2306                              <1> sndc_init_13:
  2307                              <1> 	; 28/05/2017
  2308 00010E7D 803D[59760100]02    <1> 	cmp	byte [audio_device], 2 ; AC 97 (ICH)	
  2309 00010E84 0F8562FEFFFF        <1> 	jne	soundc_respond_err ; temporary (28/05/2017)
  2310                              <1> 
  2311 00010E8A E8201F0000          <1> 	call	ac97_codec_config
  2312 00010E8F 0F8257FEFFFF        <1> 	jc	soundc_respond_err ; codec error !
  2313                              <1> 
  2314 00010E95 BB[962F0100]        <1> 	mov	ebx, ac97_int_handler
  2315 00010E9A EB20                <1> 	jmp	short sndc_init_10	
  2316                              <1> 
  2317                              <1> sndc_init_9:
  2318                              <1> 	;call	reset_codec
  2319                              <1> 	;; eax = 1
  2320                              <1> 	;call	codec_io_w16 ; w32
  2321 00010E9C E8E7170000          <1> 	call	init_codec ; 28/05/2017
  2322 00010EA1 0F8245FEFFFF        <1> 	jc	soundc_respond_err ; codec error !
  2323                              <1> 
  2324 00010EA7 E80E1A0000          <1> 	call	channel_reset
  2325                              <1> 
  2326                              <1> 	; setup the Codec (actually mixer registers) 
  2327 00010EAC E82E190000          <1>         call    codec_config  ; unmute codec, set rates.
  2328 00010EB1 0F8235FEFFFF        <1> 	jc	soundc_respond_err ; codec error !
  2329                              <1> 
  2330 00010EB7 BB[4C280100]        <1> 	mov	ebx, vt8233_int_handler
  2331                              <1> sndc_init_10:
  2332                              <1> 	; 13/04/2017
  2333 00010EBC A0[5B760100]        <1> 	mov	al, [audio_intr] ; IRQ number	
  2334 00010EC1 E82BFDFFFF          <1> 	call	set_dev_IRQ_service
  2335                              <1> 
  2336                              <1> 	; SETUP (audio) INTERRUPT CALLBACK SERVICE
  2337 00010EC6 8A1D[5B760100]      <1> 	mov	bl, [audio_intr] ; IRQ number
  2338 00010ECC 8A3D[82760100]      <1> 	mov	bh, [audio_cb_mode]
  2339 00010ED2 FEC7                <1> 	inc	bh  ; 1 = Signal Response Byte method (fixed value)
  2340                              <1> 		    ; 2 = Callback service method
  2341                              <1> 		    ; 3 = Auto Increment S.R.B. method 	
  2342 00010ED4 8A0D[83760100]      <1> 	mov	cl, [audio_srb]
  2343 00010EDA 8B15[84760100]      <1> 	mov	edx, [audio_cb_addr]
  2344 00010EE0 A0[81760100]        <1> 	mov	al, [audio_user]
  2345                              <1> 	; 14/04/2017
  2346 00010EE5 E8E1040000          <1>  	call	set_irq_callback_service
  2347                              <1> 	; 16/04/2017
  2348 00010EEA A3[64030300]        <1> 	mov	[u.r0], eax
  2349                              <1> 	;jnc	sysret
  2350 00010EEF 7316                <1> 	jnc	short sndc_init2 ; 21/04/2017
  2351                              <1> 	;
  2352 00010EF1 A3[C8030300]        <1> 	mov	dword [u.error], eax
  2353                              <1> 
  2354 00010EF6 A0[5B760100]        <1> 	mov	al, [audio_intr] ; IRQ number	
  2355 00010EFB 31DB                <1> 	xor	ebx, ebx ; reset IRQ handler address
  2356 00010EFD E8EFFCFFFF          <1> 	call	set_dev_IRQ_service
  2357                              <1> 
  2358 00010F02 E9A5C3FFFF          <1> 	jmp	error
  2359                              <1> 
  2360                              <1> sndc_init2:
  2361                              <1> 	; 21/04/2017
  2362 00010F07 8B0D[74760100]      <1> 	mov	ecx, [audio_buff_size] ; audio buffer size
  2363 00010F0D D1E1                <1> 	shl	ecx, 1 ; *2
  2364 00010F0F A1[78760100]        <1> 	mov	eax, [audio_dma_buff]
  2365 00010F14 21C0                <1> 	and	eax, eax
  2366 00010F16 7415                <1> 	jz	short sndc_init3
  2367                              <1> 
  2368 00010F18 8B15[7C760100]      <1> 	mov	edx, [audio_dmabuff_size] ; dma buffer size
  2369 00010F1E 39D1                <1> 	cmp	ecx, edx
  2370 00010F20 744D                <1> 	je	short sndc_init5
  2371                              <1> 
  2372 00010F22 87CA                <1> 	xchg	ecx, edx
  2373 00010F24 E83351FFFF          <1> 	call	deallocate_memory_block
  2374 00010F29 87D1                <1> 	xchg	edx, ecx
  2375 00010F2B 31C0                <1> 	xor	eax, eax
  2376                              <1> sndc_init3:
  2377                              <1> 	; 12/05/2017
  2378 00010F2D 803D[59760100]01    <1> 	cmp	byte [audio_device], 1 ; SB 16
  2379 00010F34 7515                <1> 	jne	short sndc_init4
  2380 00010F36 C705[78760100]-     <1> 	mov	dword [audio_dma_buff], sb16_dma_buffer
  2380 00010F3C [00000200]          <1>
  2381 00010F40 C705[7C760100]0000- <1> 	mov	dword [audio_dmabuff_size], 65536
  2381 00010F48 0100                <1>
  2382                              <1> 	;xor	eax, eax
  2383                              <1> 	;mov	[u.r0], eax ; 0 = no error, successful
  2384 00010F4A C3                  <1> 	retn 
  2385                              <1> 
  2386                              <1> sndc_init4:
  2387                              <1> 	; EAX = Beginning address (physical)
  2388                              <1> 	; EAX = 0 -> Allocate mem block from the 1st proper aperture	
  2389                              <1> 	; ECX = Number of bytes to be allocated	(>0)	
  2390 00010F4B E8FF4EFFFF          <1> 	call	allocate_memory_block
  2391 00010F50 0F828FFDFFFF        <1> 	jc	sound_buff_error
  2392                              <1> 
  2393                              <1> 	; set dma buffer address and size parameters
  2394 00010F56 A3[78760100]        <1> 	mov	[audio_dma_buff], eax ; dma buffer address
  2395 00010F5B 890D[7C760100]      <1> 	mov	[audio_dmabuff_size], ecx ; dma buffer size
  2396                              <1> ;	; EAX = Beginning (physical) addr of the allocated mem block
  2397                              <1> ;	; ECX = Num of allocated bytes (rounded up to page borders)
  2398                              <1> ;	cmp	byte [audio_pci], 0 ; AC97 audio controller ?
  2399                              <1> ;	ja	short sndc_init4
  2400                              <1> ;
  2401                              <1> ;	; Sound Blaster 16 uses classic DMA
  2402                              <1> ;	mov	edx, eax
  2403                              <1> ;	add	edx, ecx
  2404                              <1> ;	cmp	edx, 1000000h ; 1st 16 MB
  2405                              <1> ;	jna	short sndc_init4
  2406                              <1> ;
  2407                              <1> ;	; error !
  2408                              <1> ;	; restore Memory Allocation Table Content
  2409                              <1> ;	; EAX = Beginning address (physical)
  2410                              <1> ;	; ECX = Number of bytes to be deallocated
  2411                              <1> ;	call	deallocate_memory_block
  2412                              <1> ;	; reset dma buffer address and size parameters
  2413                              <1> ;	xor	eax, eax ; 0
  2414                              <1> ;	mov	[audio_dma_buff], eax ; 0
  2415                              <1> ;	mov	[audio_dmabuff_size], ecx ; 0
  2416                              <1> ;	jmp	sound_buff_error				
  2417                              <1> ;
  2418                              <1> ;sndc_init4:
  2419 00010F61 803D[59760100]03    <1> 	cmp	byte [audio_device], 3
  2420                              <1> 	;jne	short sndc_init5
  2421 00010F68 7506                <1> 	jne	short sndc_init14 ; 28/05/2017
  2422 00010F6A E88C190000          <1> 	call	set_vt8233_bdl	
  2423                              <1> sndc_init5:
  2424                              <1> 	;sub	eax, eax ; 0
  2425                              <1> 	;mov	[u.r0], eax ; 0 = no error, successful
  2426 00010F6F C3                  <1> 	retn
  2427                              <1> sndc_init14:
  2428 00010F70 E8531F0000          <1> 	call	set_ac97_bdl
  2429                              <1> 	;jmp	short sndc_init5
  2430 00010F75 C3                  <1> 	retn
  2431                              <1> 
  2432                              <1> sound_play:
  2433                              <1> 	; FUNCTION = 4 
  2434                              <1> 	; bl = Mode 
  2435                              <1> 	;      bit 0 = mono/stereo (1 = stereo)		
  2436                              <1> 	;      bit 1 = 8 bit / 16 bit (1 = 16 bit)
  2437                              <1> 	; cx = Sampling Rate (Hz)
  2438                              <1> 
  2439                              <1> 	; 13/06/2017
  2440                              <1> 	; Note: Even if Mode bits are not 11b,
  2441                              <1> 	; 	AC'97 Audio Controller (&Codec)
  2442                              <1> 	;	will play audio samples as 16 bit, stereo
  2443                              <1> 	;	samples.
  2444                              <1> 	;	(Program must fill the audio buffer
  2445                              <1> 	;	as required; 8 bit samples must be converted
  2446                              <1> 	;	to 16 bit samples and mono samples must be
  2447                              <1> 	;	converted to stereo samples...)
  2448                              <1> 	; 
  2449                              <1> 	; 28/07/2020
  2450                              <1> 	; 27/07/2020	 	
  2451                              <1> 	; 28/05/2017
  2452                              <1> 	; 15/05/2017, 20/05/2017
  2453                              <1> 	; 21/04/2017, 24/04/2017
  2454                              <1> 	; ... device check at first
  2455 00010F76 A0[59760100]        <1> 	mov	al, [audio_device]
  2456 00010F7B 08C0                <1> 	or	al, al ; 0 ; pc speaker or invalid 
  2457 00010F7D 0F846713FFFF        <1> 	jz	beeper_gfx ; 'video.s' ; temporary !
  2458                              <1> ;	cmp	al, 3 ; VIA VT 8237R (vt8233)
  2459                              <1> ;	je	short snd_play_1
  2460                              <1> ;	cmp	al, 1 ; SB 16
  2461                              <1> ;	jne	soundc_dev_err ; temporary !
  2462                              <1> ;snd_play_0:
  2463                              <1> 	; ... buffer & (buffer) owner check at second
  2464 00010F83 833D[6C760100]00    <1> 	cmp	dword [audio_buffer], 0
  2465 00010F8A 0F8655FDFFFF        <1> 	jna	sound_buff_error
  2466 00010F90 A0[B3030300]        <1> 	mov	al, [u.uno]
  2467 00010F95 3A05[81760100]      <1> 	cmp	al, [audio_user]
  2468 00010F9B 0F858FFEFFFF        <1> 	jne	sndc_owner_error
  2469                              <1> 
  2470 00010FA1 66890D[8A760100]    <1> 	mov	[audio_freq], cx ; sample frequency (Hertz)
  2471 00010FA8 88D8                <1> 	mov	al, bl
  2472 00010FAA 2401                <1> 	and	al, 1 ; mono/stereo (1= stereo)
  2473 00010FAC FEC0                <1> 	inc	al ; channels
  2474 00010FAE A2[89760100]        <1> 	mov	[audio_stmo], al ; sound channels (1 or 2)
  2475 00010FB3 B008                <1> 	mov	al, 8
  2476 00010FB5 F6C302              <1> 	test	bl, 2 ; bits per sample (1= 16 bit)
  2477 00010FB8 7402                <1> 	jz	short snd_play_bps
  2478 00010FBA D0E0                <1> 	shl	al, 1  
  2479                              <1> snd_play_bps:	
  2480 00010FBC A2[88760100]        <1> 	mov	[audio_bps], al
  2481                              <1> 
  2482                              <1> 	; Transfer ring 3 (user's) audio buffer content to dma buffer
  2483 00010FC1 8B3D[78760100]      <1> 	mov	edi, [audio_dma_buff] ; dma buffer (ring 0)
  2484 00010FC7 09FF                <1> 	or	edi, edi
  2485 00010FC9 0F8416FDFFFF        <1> 	jz	sound_buff_error
  2486                              <1> 
  2487                              <1> 	; 27/07/2020
  2488                              <1> 
  2489 00010FCF 8B35[70760100]      <1> 	mov	esi, [audio_p_buffer] ; physical address (ring 3)
  2490                              <1> 	;mov	ecx, [audio_buff_size] ; 15/05/2017
  2491 00010FD5 8B0D[7C760100]      <1> 	mov	ecx, [audio_dmabuff_size] ; 27/07/2020
  2492                              <1> 	;or	ecx, ecx 
  2493                              <1> 	;jz	sound_buff_error
  2494                              <1> 	; 28/07/2020
  2495 00010FDB D1E9                <1> 	shr	ecx, 1  ; dma half buffer size
  2496                              <1> 
  2497 00010FDD 8035[80760100]01    <1> 	xor	byte [audio_flag], 1 ;  0 -> 1, 1 -> 0
  2498 00010FE4 7502                <1> 	jnz	short snd_play_0 ; [audio_flag] = 1
  2499                              <1> 				 ; fill dma half buffer 1
  2500                              <1> 	; [audio_flag] = 0
  2501                              <1> 	
  2502                              <1> 	; fill dma half buffer 2
  2503 00010FE6 01CF                <1> 	add	edi, ecx
  2504                              <1> 
  2505                              <1> snd_play_0:
  2506                              <1> 	;rep	movsb
  2507 00010FE8 C1E902              <1> 	shr	ecx, 2  ; convert byte count to dword count
  2508 00010FEB F3A5                <1> 	rep	movsd
  2509                              <1> 
  2510                              <1> 	; here, if [audio_flag] = 0, interrupt handler will update
  2511                              <1> 				; dma half buffer 2 
  2512                              <1> 				; (user's audio buffer data will be 
  2513                              <1> 				; copied into dma half buffer 2) 
  2514                              <1> 	;; 20/05/2017
  2515                              <1> 	;mov	byte [audio_flag], 1 ; next half (on next time)
  2516                              <1> 
  2517                              <1> 	; 24/04/2017
  2518 00010FED A0[59760100]        <1> 	mov	al, [audio_device]
  2519 00010FF2 3C03                <1> 	cmp	al, 3 ; VT8233 (VT8237R) 
  2520 00010FF4 7410                <1> 	je	short snd_play_1
  2521 00010FF6 3C01                <1> 	cmp	al, 1 ; Sound Blaster 16
  2522 00010FF8 7512                <1> 	jne	short snd_play_2  ; 28/05/2017
  2523 00010FFA E8041B0000          <1> 	call	SbInit_play
  2524 00010FFF 0F82E7FCFFFF        <1> 	jc	soundc_respond_err
  2525 00011005 C3                  <1> 	retn
  2526                              <1> 
  2527                              <1> snd_play_1:	
  2528 00011006 E827190000          <1> 	call	vt8233_start_play
  2529 0001100B C3                  <1> 	retn
  2530                              <1> 
  2531                              <1> snd_play_2:
  2532                              <1> 	; 28/05/2017
  2533                              <1> 	;cmp	al, 2 ; AC'97
  2534                              <1> 	;jne	short snd_play_3
  2535                              <1> 
  2536 0001100C E8EB1E0000          <1> 	call	ac97_start_play
  2537 00011011 C3                  <1> 	retn
  2538                              <1> 
  2539                              <1> ;snd_play_3:
  2540                              <1> ;	;call	hda_start_play
  2541                              <1> ;	retn
  2542                              <1> 
  2543                              <1> sound_pause:
  2544                              <1> 	; FUNCTION = 5
  2545                              <1> 	; Pause
  2546                              <1> 	; 28/05/2017
  2547                              <1> 	; 24/04/2017
  2548                              <1> 	; 22/04/2017
  2549 00011012 E814030000          <1> 	call	snd_dev_check
  2550 00011017 7275                <1> 	jc	short snd_nothing ; temporary.
  2551 00011019 E81A030000          <1> 	call	snd_buf_check
  2552 0001101E 726E                <1> 	jc	short snd_nothing ; temporary.
  2553 00011020 A0[59760100]        <1> 	mov	al, [audio_device]
  2554 00011025 3C03                <1> 	cmp	al, 3 ; VIA VT 8237R (vt8233)
  2555 00011027 7409                <1> 	je	short snd_pause_1
  2556 00011029 3C01                <1> 	cmp	al, 1 ; Sound Blaster 16
  2557 0001102B 750A                <1> 	jne	short snd_pause_2 ; 28/05/2017
  2558 0001102D E9AF1C0000          <1> 	jmp	sb16_pause
  2559                              <1> snd_pause_1:
  2560 00011032 E9B4190000          <1> 	jmp	vt8233_pause
  2561                              <1> snd_pause_2:
  2562                              <1> 	; 28/05/2017
  2563                              <1> 	;cmp	al, 2 ; AC'97
  2564                              <1> 	;jne	short snd_nothing ; temporary.
  2565 00011037 E94E200000          <1> 	jmp	ac97_pause
  2566                              <1> 
  2567                              <1> sound_continue:
  2568                              <1> 	; FUNCTION = 6
  2569                              <1> 	; Continue to play
  2570                              <1> 	; 28/05/2017
  2571                              <1> 	; 22/04/2017
  2572 0001103C E8EA020000          <1> 	call	snd_dev_check
  2573 00011041 724B                <1> 	jc	short snd_nothing ; temporary.
  2574 00011043 E8F0020000          <1> 	call	snd_buf_check
  2575 00011048 7244                <1> 	jc	short snd_nothing ; temporary.
  2576 0001104A A0[59760100]        <1> 	mov	al, [audio_device]
  2577 0001104F 3C03                <1> 	cmp	al, 3 ; VIA VT 8237R (vt8233)
  2578 00011051 7409                <1> 	je	short snd_cont_1
  2579 00011053 3C01                <1> 	cmp	al, 1 ; Sound Blaster 16
  2580 00011055 750A                <1> 	jne	short snd_cont_2 ; 28/05/2017
  2581 00011057 E9A81C0000          <1> 	jmp	sb16_continue
  2582                              <1> snd_cont_1:
  2583 0001105C E93B190000          <1> 	jmp	vt8233_play
  2584                              <1> snd_cont_2:
  2585                              <1> 	; 28/05/2017
  2586                              <1> 	;cmp	al, 2 ; AC'97
  2587                              <1> 	;jne	short snd_nothing ; temporary.
  2588 00011061 E9EC1E0000          <1> 	jmp	ac97_play
  2589                              <1> 
  2590                              <1> sound_stop:
  2591                              <1> 	; FUNCTION = 7
  2592                              <1> 	; Stop playing
  2593                              <1> 	; 28/05/2017
  2594                              <1> 	; 24/05/2017
  2595                              <1> 	; 21/04/2017, 22/04/2017, 24/04/2017
  2596 00011066 E8C0020000          <1> 	call	snd_dev_check
  2597 0001106B 7221                <1> 	jc	short snd_nothing ; temporary.
  2598                              <1> 	;call	snd_buf_check
  2599 0001106D E8CF020000          <1> 	call	snd_user_check ; 24/05/2017
  2600 00011072 721A                <1> 	jc	short snd_nothing ; temporary.	
  2601                              <1> 	
  2602 00011074 A0[59760100]        <1> 	mov	al, [audio_device]
  2603 00011079 3C03                <1> 	cmp	al, 3 ; VIA VT 8237R (vt8233)
  2604 0001107B 0F8471180000        <1> 	je	vt8233_stop
  2605                              <1> 	; 28/05/2017
  2606                              <1> 	;ja	short snd_nothing
  2607 00011081 3C01                <1> 	cmp	al, 1 ; Sound Blaster 16
  2608 00011083 0F849E1C0000        <1> 	je	sb16_stop
  2609                              <1> 	;cmp	al, 2 
  2610                              <1> 	;je	short ac97_stop
  2611 00011089 E9CE1F0000          <1> 	jmp	ac97_stop ; temporary.
  2612                              <1> 	;jmp	hda_stop
  2613                              <1> 
  2614                              <1> snd_nothing:
  2615                              <1> 	; 21/04/2017
  2616 0001108E C3                  <1> 	retn
  2617                              <1> 
  2618                              <1> soundc_reset:
  2619                              <1> 	; FUNCTION = 8
  2620                              <1> 	; Reset Audio Controller
  2621                              <1> 	; 28/05/2017
  2622                              <1> 	; 22/04/2017
  2623 0001108F E897020000          <1> 	call	snd_dev_check
  2624 00011094 72F8                <1> 	jc	snd_nothing ; temporary.
  2625 00011096 E89D020000          <1> 	call	snd_buf_check
  2626 0001109B 72F1                <1> 	jc	snd_nothing ; temporary.	
  2627                              <1> 	
  2628 0001109D A0[59760100]        <1> 	mov	al, [audio_device]
  2629 000110A2 3C03                <1> 	cmp	al, 3 ; VIA VT 8237R (vt8233)
  2630 000110A4 0F844D190000        <1> 	je	vt8233_reset
  2631 000110AA 77E2                <1> 	ja	short snd_nothing ; temporary.
  2632                              <1> 	;ja	hda_reset	
  2633 000110AC 3C01                <1> 	cmp	al, 1 ; Sound Blaster 16
  2634 000110AE 0F8527200000        <1> 	jne	ac97_reset	
  2635 000110B4 E8C01C0000          <1> 	call	sb16_reset
  2636 000110B9 0F822DFCFFFF        <1> 	jc	soundc_respond_err
  2637 000110BF C3                  <1> 	retn
  2638                              <1> 
  2639                              <1> soundc_cancel:
  2640                              <1> 	; FUNCTION = 9
  2641                              <1> 	; Cancel audio callback service
  2642                              <1> 	; 22/04/2017
  2643 000110C0 A0[81760100]        <1> 	mov	al, [audio_user]	
  2644 000110C5 3A05[B3030300]      <1> 	cmp	al, [u.uno]
  2645 000110CB 75C1                <1> 	jne	short snd_nothing
  2646                              <1> 	; RESET (audio) INTERRUPT CALLBACK SERVICE
  2647 000110CD 8A1D[5B760100]      <1> 	mov	bl, [audio_intr] ; IRQ number
  2648 000110D3 A0[B3030300]        <1> 	mov	al, [u.uno]
  2649 000110D8 28FF                <1> 	sub	bh, bh ; 0 ; unlink IRQ from user service
  2650 000110DA E8EC020000          <1>  	call	set_irq_callback_service
  2651 000110DF 0F8250FDFFFF        <1> 	jc	sndc_perm_error ; 'permission denied' error
  2652 000110E5 C3                  <1> 	retn
  2653                              <1> 
  2654                              <1> sound_dalloc:
  2655                              <1> 	; FUNCTION = 10
  2656                              <1> 	; Deallocate (ring 3) audio buffer
  2657                              <1> 	; 22/04/2017
  2658 000110E6 A0[81760100]        <1> 	mov	al, [audio_user]	
  2659 000110EB 3A05[B3030300]      <1> 	cmp	al, [u.uno]
  2660 000110F1 759B                <1> 	jne	short snd_nothing
  2661 000110F3 8B1D[6C760100]      <1> 	mov	ebx, [audio_buffer]
  2662                              <1> 	;or	ebx, ebx
  2663                              <1> 	;jz	short snd_nothing
  2664 000110F9 8B0D[74760100]      <1> 	mov	ecx, [audio_buff_size]
  2665 000110FF E8A650FFFF          <1> 	call	deallocate_user_pages
  2666 00011104 31C0                <1> 	xor	eax, eax
  2667 00011106 A3[6C760100]        <1> 	mov	[audio_buffer], eax ; 0
  2668 0001110B A2[81760100]        <1> 	mov	[audio_user], al ; 0
  2669 00011110 C3                  <1> 	retn
  2670                              <1> 
  2671                              <1> sound_volume:
  2672                              <1> 	; FUNCTION = 11
  2673                              <1> 	; Set sound volume level
  2674                              <1> 	; 28/05/2017
  2675                              <1> 	; 20/05/2017
  2676                              <1> 	; 22/04/2017, 24/04/2017
  2677                              <1> 	; bl = component (0 = master/playback/lineout volume)
  2678                              <1> 	; cl = left channel volume level (0 to 31)
  2679                              <1> 	; ch = right channel volume level (0 to 31)
  2680                              <1> 
  2681 00011111 80FB80              <1> 	cmp	bl, 80h
  2682 00011114 720E                <1> 	jb	short snd_vol_1
  2683 00011116 0F8772FFFFFF        <1> 	ja	snd_nothing ; temporary.
  2684                              <1> 	; Set volume level for next play (BL>= 80h)
  2685 0001111C 66890D[8E760100]    <1> 	mov	[audio_master_volume], cx
  2686 00011123 C3                  <1> 	retn
  2687                              <1> snd_vol_1:
  2688                              <1> 	; set volume level immediate (BL< 80h)
  2689 00011124 80FB00              <1> 	cmp	bl, 0
  2690 00011127 0F8761FFFFFF        <1> 	ja	snd_nothing ; temporary.
  2691                              <1> 
  2692 0001112D E8F9010000          <1> 	call	snd_dev_check
  2693 00011132 0F8256FFFFFF        <1> 	jc	snd_nothing ; temporary.
  2694 00011138 E8FB010000          <1> 	call	snd_buf_check
  2695 0001113D 0F824BFFFFFF        <1> 	jc	snd_nothing ; temporary.	
  2696                              <1> 
  2697 00011143 A0[59760100]        <1> 	mov	al, [audio_device]
  2698 00011148 3C03                <1> 	cmp	al, 3 ; VIA VT 8237R (vt8233)
  2699 0001114A 0F84C0180000        <1> 	je	vt8233_volume
  2700                              <1> 	; 28/05/2017
  2701 00011150 0F8738FFFFFF        <1> 	ja	snd_nothing ; temporary.
  2702                              <1> 	;ja	hda_volume	
  2703                              <1> 	; Sound Blaster 16
  2704 00011156 3C01                <1> 	cmp	al, 1 ; SB 16
  2705 00011158 0F844E1B0000        <1> 	je	sb16_volume
  2706 0001115E E90B1E0000          <1> 	jmp	ac97_volume
  2707                              <1> 
  2708                              <1> soundc_disable:
  2709                              <1> 	; FUNCTION = 12 
  2710                              <1> 	; Disable audio device (and unlink DMA memory)
  2711                              <1> 	; 28/05/2017
  2712                              <1> 	; 24/05/2017
  2713                              <1> 	; 22/04/2017
  2714 00011163 E8C3010000          <1> 	call	snd_dev_check
  2715 00011168 0F8270FBFFFF        <1> 	jc	soundc_dev_err ; temporary.
  2716                              <1> 	;call	snd_buf_check
  2717                              <1> 	;jc	sndc_owner_error ; temporary.
  2718                              <1> 
  2719 0001116E A0[59760100]        <1> 	mov	al, [audio_device]
  2720 00011173 3C03                <1> 	cmp	al, 3 ; VIA VT 8237R (vt8233)
  2721 00011175 7418                <1> 	je	short snd_disable_1
  2722 00011177 0F8711FFFFFF        <1> 	ja	snd_nothing ; temporary.
  2723 0001117D 3C01                <1> 	cmp	al, 1 ; Sound Blaster 16
  2724 0001117F 7507                <1> 	jne	short snd_disable_0
  2725 00011181 E8A11B0000          <1> 	call	sb16_stop
  2726 00011186 EB0C                <1> 	jmp	short snd_disable_2
  2727                              <1> snd_disable_0:
  2728 00011188 E8CF1E0000          <1> 	call	ac97_stop
  2729 0001118D EB05                <1> 	jmp	short snd_disable_2
  2730                              <1> snd_disable_1:
  2731 0001118F E85E170000          <1> 	call	vt8233_stop
  2732                              <1> snd_disable_2:
  2733 00011194 A0[5B760100]        <1> 	mov	al, [audio_intr]
  2734 00011199 29DB                <1> 	sub	ebx, ebx ; 0 = reset
  2735 0001119B E851FAFFFF          <1> 	call	set_dev_IRQ_service
  2736                              <1> 
  2737                              <1> 	;mov	al, [audio_intr]
  2738 000111A0 28E4                <1> 	sub	ah, ah ; 0 = reset
  2739 000111A2 E8B5F6FFFF          <1> 	call	set_hardware_int_vector
  2740                              <1> 
  2741 000111A7 31C0                <1> 	xor	eax, eax
  2742 000111A9 A2[59760100]        <1> 	mov	byte [audio_device], al
  2743 000111AE A2[5B760100]        <1> 	mov	byte [audio_intr], al
  2744 000111B3 8705[78760100]      <1> 	xchg	eax, [audio_dma_buff]
  2745                              <1> 	; 24/05/2017
  2746                              <1> 	;or	eax, eax
  2747                              <1> 	;jz	short snd_disable_3
  2748                              <1> 	;cmp	eax, sb16_dma_buffer ; default DMA buffer
  2749                              <1> 	;je	short snd_disable_3
  2750 000111B9 803D[58760100]00    <1> 	cmp	byte [audio_pci], 0 ; AC97 audio controller ?
  2751 000111C0 7612                <1> 	jna	short snd_disable_3
  2752 000111C2 C605[58760100]00    <1> 	mov	byte [audio_pci], 0
  2753                              <1> 	;sub	ecx, ecx
  2754                              <1> 	;xchg	ecx, [audio_dmabuff_size]
  2755 000111C9 8B0D[7C760100]      <1> 	mov	ecx, [audio_dmabuff_size]
  2756 000111CF E8884EFFFF          <1> 	call	deallocate_memory_block
  2757                              <1> snd_disable_3:
  2758 000111D4 C3                  <1> 	retn
  2759                              <1> 
  2760                              <1> sound_dma_map:
  2761                              <1> 	; FUNCTION = 13 
  2762                              <1> 	; Map audio dma buff addr to user's buffer addr
  2763                              <1> 	; 12/05/2017
  2764 000111D5 21C9                <1> 	and	ecx, ecx
  2765 000111D7 0F8408FBFFFF        <1> 	jz	sound_buff_error
  2766 000111DD 803D[59760100]01    <1> 	cmp	byte [audio_device], 1
  2767 000111E4 7229                <1> 	jb	short snd_dma_map_1
  2768                              <1> snd_dma_map_0:
  2769 000111E6 A1[78760100]        <1> 	mov	eax, [audio_dma_buff]
  2770 000111EB 21C0                <1> 	and	eax, eax
  2771 000111ED 7420                <1> 	jz	short snd_dma_map_1
  2772                              <1> 	;
  2773 000111EF 8A1D[81760100]      <1> 	mov	bl, [audio_user]
  2774 000111F5 08DB                <1> 	or	bl, bl
  2775 000111F7 7416                <1> 	jz	short snd_dma_map_1
  2776 000111F9 3A1D[B3030300]      <1> 	cmp	bl, [u.uno]
  2777 000111FF 0F852BFCFFFF        <1> 	jne	sndc_owner_error
  2778                              <1> 	;
  2779 00011205 8B1D[7C760100]      <1> 	mov	ebx, [audio_dmabuff_size]
  2780 0001120B 21DB                <1> 	and	ebx, ebx
  2781 0001120D 750A                <1> 	jnz	short snd_dma_map_2
  2782                              <1> snd_dma_map_1:
  2783 0001120F B8[00000200]        <1> 	mov	eax, sb16_dma_buffer
  2784 00011214 BB00000100          <1> 	mov	ebx, 65536
  2785                              <1> snd_dma_map_2:	
  2786 00011219 81C1FF0F0000        <1> 	add	ecx, PAGE_SIZE-1 ; 4095
  2787 0001121F 6681E100F0          <1> 	and	cx, ~PAGE_OFF ; not 4095
  2788 00011224 39D9                <1> 	cmp	ecx, ebx
  2789 00011226 0F87B9FAFFFF        <1> 	ja	sound_buff_error
  2790 0001122C 50                  <1> 	push	eax
  2791 0001122D 89D3                <1> 	mov	ebx, edx
  2792 0001122F C1E90C              <1> 	shr	ecx, 12 ; byte count to page count
  2793                              <1> 	; eax = physical address of (audio) dma buffer
  2794                              <1> 	; ebx = virtual address of (audio) dma buffer (user's pgdir) 
  2795                              <1> 	; ecx = page count (>0)
  2796 00011232 E8954EFFFF          <1> 	call	direct_memory_access
  2797 00011237 58                  <1> 	pop	eax
  2798 00011238 0F82A7FAFFFF        <1> 	jc	sound_buff_error
  2799 0001123E A3[64030300]        <1> 	mov	[u.r0], eax
  2800 00011243 C3                  <1> 	retn
  2801                              <1> 
  2802                              <1> soundc_info:
  2803                              <1> 	; FUNCTION = 14 
  2804                              <1> 	; Get Audio Controller Info
  2805                              <1> 	; 10/06/2017
  2806                              <1> 	; 05/06/2017
  2807 00011244 20DB                <1> 	and	bl, bl ; 0
  2808 00011246 740A                <1> 	jz	short sndc_info_0
  2809                              <1> 	; invalid parameter !
  2810 00011248 B817000000          <1> 	mov	eax, ERR_INV_PARAMETER ; 23
  2811                              <1> ;sndc_inf_error:
  2812                              <1> ;	mov	[u.r0], eax
  2813                              <1> ;	mov	[u.error], eax
  2814                              <1> ;	jmp	error
  2815 0001124D E99FFAFFFF          <1> 	jmp	sysaudio_err
  2816                              <1> 
  2817                              <1> sndc_info_0:
  2818 00011252 E8D4000000          <1> 	call	snd_dev_check
  2819 00011257 0F8281FAFFFF        <1> 	jc	soundc_dev_err
  2820                              <1> 
  2821 0001125D 8B1D[64760100]      <1> 	mov	ebx, [audio_vendor]
  2822 00011263 8B0D[60760100]      <1> 	mov	ecx, [audio_dev_id]
  2823                              <1> 	;mov	al,  [audio_device]
  2824 00011269 3C02                <1> 	cmp	al, 2 ; AC'97 (ICH)
  2825 0001126B 7513                <1> 	jne	short sndc_info_1
  2826                              <1> 	; Intel AC97 (ICH) Audio Controller (=2)	
  2827 0001126D 668B15[92760100]    <1> 	mov	dx, [NABMBAR]
  2828 00011274 C1E210              <1> 	shl	edx, 16
  2829 00011277 668B15[90760100]    <1> 	mov	dx, [NAMBAR]
  2830 0001127E EB07                <1> 	jmp	short sndc_info_2
  2831                              <1> sndc_info_1:
  2832                              <1> 	; 05/06/2017
  2833                              <1> 	; Note: Intel HDA code (here) is not ready yet!
  2834                              <1> 	; !!! SB16 or VT8233 (VT8237R) !!!
  2835 00011280 0FB715[5E760100]    <1> 	movzx	edx, word [audio_io_base]	
  2836                              <1> sndc_info_2:
  2837 00011287 88C4                <1> 	mov	ah, al ;  [audio_device]
  2838 00011289 A0[5B760100]        <1> 	mov	al, [audio_intr] 
  2839                              <1> 
  2840                              <1> 	; EAX = IRQ Number in AL
  2841                              <1> 	;	Audio Device Number in AH 
  2842                              <1> 	; EBX = DEV/VENDOR ID
  2843                              <1> 	;	(DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV)
  2844                              <1> 	; ECX = BUS/DEV/FN 
  2845                              <1> 	;	(00000000BBBBBBBBDDDDDFFF00000000)
  2846                              <1> 	; EDX = NABMBAR/NAMBAR (for AC97)
  2847                              <1> 	;	(Low word, DX = NAMBAR address)
  2848                              <1> 	; EDX = Base IO Addr (DX) for SB16 & VT8233
  2849                              <1> 
  2850                              <1> 	; 10/06/2017
  2851 0001128E A3[64030300]        <1> 	mov	[u.r0], eax
  2852 00011293 8B2D[60030300]      <1> 	mov	ebp, [u.usp]
  2853 00011299 895D10              <1> 	mov	[ebp+16], ebx  ; ebx
  2854 0001129C 895514              <1> 	mov	[ebp+20], edx  ; edx
  2855 0001129F 894D18              <1> 	mov	[ebp+24], ecx  ; ecx
  2856                              <1>   			  		
  2857 000112A2 C3                  <1>  	retn
  2858                              <1> 
  2859                              <1> sound_data:
  2860                              <1> 	; FUNCTION = 15 
  2861                              <1> 	; Get Current Sound data for graphics
  2862                              <1> 	; 22/06/2017
  2863                              <1> 	;
  2864 000112A3 E883000000          <1> 	call	snd_dev_check
  2865 000112A8 0F8230FAFFFF        <1> 	jc	soundc_dev_err ; Device not ready !
  2866                              <1> 
  2867 000112AE 80FB00              <1> 	cmp	bl, 0
  2868 000112B1 760A                <1> 	jna	short sound_data_0
  2869                              <1> 
  2870                              <1> 	; Only PCM OUT buffer data is valid for now!
  2871 000112B3 B817000000          <1> 	mov	eax, ERR_INV_PARAMETER  ; 23
  2872 000112B8 E934FAFFFF          <1> 	jmp	sysaudio_err
  2873                              <1> 
  2874                              <1> sound_data_0:
  2875 000112BD A1[78760100]        <1> 	mov	eax, [audio_dma_buff]
  2876 000112C2 09C0                <1> 	or	eax, eax
  2877 000112C4 0F841BFAFFFF        <1> 	jz	sound_buff_error
  2878                              <1> 
  2879 000112CA 803D[59760100]04    <1> 	cmp	byte [audio_device], 4 ; Intel HDA
  2880 000112D1 744F                <1> 	je	short sound_data_4 ; temporary ! (22/06/2017)
  2881                              <1> 
  2882 000112D3 21C9                <1> 	and	ecx, ecx
  2883                              <1> 	;jnz	short sound_data_1 ; sample tranfer
  2884                              <1> 	
  2885                              <1> 	; Return only DMA Buffer pointer/offset... 
  2886                              <1> 	; (If DMA Buffer has been mapped to user's
  2887                              <1> 	;  memory space; program can get graphics
  2888                              <1> 	;  data by using only this pointer value.)
  2889                              <1> 	   	
  2890                              <1> 	;call	get_dma_buffer_offset
  2891                              <1> 	;; eax = DMA buffer offset
  2892                              <1> 	;;	(!not half buffer offset!)
  2893                              <1> 	;mov	[u.r0], eax
  2894                              <1> 	;retn
  2895                              <1> 
  2896 000112D5 0F84781F0000        <1> 	jz	get_dma_buffer_offset	
  2897                              <1> 	
  2898                              <1> sound_data_1:
  2899                              <1> 	;mov	eax, [audio_dmabuff_size]
  2900                              <1> 	;shr	eax, 1 ; half buffer size
  2901                              <1> 	;cmp	ecx, eax
  2902                              <1> 	;ja	short sound_buff_error	
  2903                              <1> 
  2904 000112DB 3B0D[7C760100]      <1> 	cmp	ecx, [audio_dmabuff_size]
  2905 000112E1 0F87FEF9FFFF        <1> 	ja	sound_buff_error
  2906                              <1> 
  2907 000112E7 89D0                <1> 	mov	eax, edx
  2908 000112E9 25FF0F0000          <1> 	and	eax, PAGE_OFF ; 4095 (0FFFh)
  2909 000112EE 81F900100000        <1> 	cmp	ecx, 4096
  2910 000112F4 7605                <1> 	jna	short sound_data_2
  2911 000112F6 B900100000          <1> 	mov	ecx, 4096 ; max. 1 page
  2912                              <1> sound_data_2:
  2913 000112FB 01C8                <1> 	add	eax, ecx
  2914 000112FD 3D00100000          <1> 	cmp	eax, 4096
  2915 00011302 7606                <1> 	jna	short sound_data_3
  2916 00011304 6625FF0F            <1> 	and	ax, PAGE_OFF ; 4095 (0FFFh)
  2917 00011308 29C1                <1> 	sub	ecx, eax
  2918                              <1> 	; here, ECX has been adjusted to fit 
  2919                              <1> 	;	in page border..  (<= 4096, >0)
  2920                              <1> sound_data_3:
  2921 0001130A 51                  <1> 	push	ecx
  2922 0001130B 52                  <1> 	push	edx
  2923 0001130C 89D3                <1> 	mov	ebx, edx 
  2924 0001130E E8A749FFFF          <1> 	call	get_physical_addr
  2925 00011313 5A                  <1> 	pop	edx
  2926 00011314 59                  <1> 	pop	ecx
  2927 00011315 0F82CAF9FFFF        <1> 	jc	sound_buff_error	
  2928                              <1> 	
  2929                              <1> 	; eax = physical address of user's buffer
  2930 0001131B 89C3                <1> 	mov	ebx, eax  
  2931                              <1> 	; ecx = byte (transfer) count
  2932                              <1> 	;call	get_current_sound_data
  2933                              <1> 	;retn
  2934 0001131D E98E1E0000          <1> 	jmp	get_current_sound_data
  2935                              <1> 
  2936                              <1> sound_data_4:
  2937                              <1> 	; Intel HDA code is not ready yet !
  2938                              <1> 	; 22/06/2017
  2939 00011322 31C0                <1> 	xor	eax, eax
  2940 00011324 48                  <1> 	dec	eax
  2941 00011325 A3[64030300]        <1> 	mov	[u.r0], eax ; 0FFFFFFFFh
  2942 0001132A C3                  <1> 	retn 
  2943                              <1> 
  2944                              <1> snd_dev_check:
  2945                              <1> 	; 10/06/2017
  2946                              <1> 	; 05/06/2017
  2947                              <1> 	; 24/05/2017
  2948                              <1> 	; 22/04/2017
  2949                              <1> 	; 21/04/2017
  2950                              <1> 	; ... device check at first
  2951 0001132B A0[59760100]        <1> 	mov	al, [audio_device]
  2952 00011330 3C01                <1> 	cmp	al, 1 ; SB 16
  2953 00011332 7203                <1> 	jb	short snd_dev_chk_retn ; error !
  2954                              <1> 	;cmp	al, 4 ; Intel HDA
  2955                              <1> 	;ja	short snd_dbchk_stc ; invalid !
  2956                              <1> 	; 10/06/2017
  2957 00011334 3C05                <1> 	cmp	al, 5
  2958 00011336 F5                  <1> 	cmc
  2959                              <1> snd_dev_chk_retn:
  2960 00011337 C3                  <1> 	retn
  2961                              <1> 
  2962                              <1> snd_buf_check:
  2963                              <1> 	; 10/06/2017
  2964                              <1> 	; 22/04/2017
  2965                              <1> 	; 21/04/2017
  2966                              <1> 	; ... buffer & (buffer) owner check at second
  2967 00011338 833D[6C760100]00    <1> 	cmp	dword [audio_buffer], 0
  2968 0001133F 760D                <1> 	jna	short snd_dbchk_stc
  2969                              <1> snd_user_check:
  2970 00011341 A0[B3030300]        <1> 	mov	al, [u.uno]
  2971 00011346 3A05[81760100]      <1> 	cmp	al, [audio_user]
  2972                              <1> 	;jne	short snd_dbchk_stc
  2973                              <1> 	;retn
  2974 0001134C 74E9                <1> 	je	short snd_dev_chk_retn
  2975                              <1> 
  2976                              <1> snd_dbchk_stc:
  2977 0001134E F9                  <1> 	stc
  2978 0001134F C3                  <1> 	retn
  2979                              <1> 
  2980                              <1> sound_update:
  2981                              <1> 	; FUNCTION = 16 
  2982                              <1> 	; bl = 
  2983                              <1> 	;    0 = automatic (sequental) update (with flag switch!)
  2984                              <1> 	;    1 = update dma half buffer 1 (without flag switch!)		
  2985                              <1> 	;    2 = update dma half buffer 2 (without flag switch!)
  2986                              <1> 	;  FFh = get current flag value	
  2987                              <1> 	;      0 = dma half buffer 1 (will be played next)
  2988                              <1> 	;      1 = dma half buffer 2 (will be played next)
  2989                              <1> 	
  2990                              <1> 	; 10/10/2017
  2991                              <1> 	
  2992                              <1> 	; ... device check at first
  2993 00011350 A0[59760100]        <1> 	mov	al, [audio_device]
  2994 00011355 08C0                <1> 	or	al, al ; 0 ; pc speaker or invalid 
  2995 00011357 0F8481F9FFFF        <1> 	jz	soundc_dev_err
  2996                              <1> 
  2997                              <1> 	; ... buffer & (buffer) owner check at second
  2998 0001135D 833D[6C760100]00    <1> 	cmp	dword [audio_buffer], 0
  2999 00011364 0F867BF9FFFF        <1> 	jna	sound_buff_error
  3000 0001136A A0[B3030300]        <1> 	mov	al, [u.uno]
  3001 0001136F 3A05[81760100]      <1> 	cmp	al, [audio_user]
  3002 00011375 0F85B5FAFFFF        <1> 	jne	sndc_owner_error
  3003                              <1> 
  3004                              <1> 	; Transfer ring 3 (user's) audio buffer content to dma buffer
  3005 0001137B 8B3D[78760100]      <1> 	mov	edi, [audio_dma_buff] ; dma buffer (ring 0)
  3006 00011381 09FF                <1> 	or	edi, edi
  3007 00011383 0F845CF9FFFF        <1> 	jz	sound_buff_error
  3008 00011389 8B35[70760100]      <1> 	mov	esi, [audio_p_buffer] ; physical address (ring 3)
  3009 0001138F 8B0D[74760100]      <1> 	mov	ecx, [audio_buff_size]
  3010                              <1> 	
  3011                              <1> 	;movzx	eax, byte [audio_flag]
  3012 00011395 A0[80760100]        <1> 	mov	al, [audio_flag]
  3013                              <1> 
  3014 0001139A FEC3                <1> 	inc	bl
  3015 0001139C 7427                <1> 	jz	short snd_update_3 ; bl = 0FFh
  3016 0001139E FECB                <1> 	dec	bl 
  3017 000113A0 7411                <1> 	jz	short snd_update_0 ; bl = 0
  3018                              <1> 
  3019 000113A2 80FB02              <1> 	cmp	bl, 2
  3020 000113A5 7417                <1> 	je	short snd_update_1 ; dma half buffer 2
  3021 000113A7 7217                <1> 	jb	short snd_update_2 ; dma half buffer 1
  3022                              <1>  
  3023                              <1> 	; invalid parameter !
  3024 000113A9 B817000000          <1> 	mov	eax, ERR_INV_PARAMETER ; 23
  3025                              <1> ;	mov	[u.r0], eax
  3026                              <1> ;	mov	[u.error], eax
  3027                              <1> ;	jmp	error
  3028 000113AE E93EF9FFFF          <1> 	jmp	sysaudio_err
  3029                              <1> 	
  3030                              <1> snd_update_0:
  3031 000113B3 8035[80760100]01    <1> 	xor	byte [audio_flag], 1 ; update flag !!!
  3032 000113BA 3C01                <1> 	cmp	al, 1
  3033 000113BC 7202                <1> 	jb	short snd_update_2 ; dma half buffer 1
  3034                              <1> snd_update_1:
  3035                              <1> 	; dma half buffer 2
  3036 000113BE 01CF                <1> 	add	edi, ecx
  3037                              <1> snd_update_2:
  3038                              <1> 	;rep	movsb
  3039 000113C0 C1E902              <1> 	shr	ecx, 2
  3040 000113C3 F3A5                <1> 	rep	movsd
  3041                              <1> snd_update_3:
  3042 000113C5 A3[64030300]        <1> 	mov	[u.r0], eax
  3043                              <1> 
  3044 000113CA C3                  <1> 	retn
  3045                              <1> 	
  3046                              <1> set_irq_callback_service:
  3047                              <1> 	; 03/08/2020
  3048                              <1> 	; 10/06/2017
  3049                              <1> 	; 12/05/2017
  3050                              <1> 	; 24/04/2017
  3051                              <1> 	; 22/04/2017
  3052                              <1> 	; caller: 'syscalbac' or 'sysaudio' or ...
  3053                              <1> 	; 13/04/2017, 14/04/2017, 17/04/2017
  3054                              <1> 	; 24/02/2017, 26/02/2017, 28/02/2017
  3055                              <1> 	; 21/02/2017 - TRDOS 386 (TRDOS v2.0)
  3056                              <1> 	;
  3057                              <1> 	; Link or unlink IRQ callback service to/from user (ring 3)	
  3058                              <1> 	;
  3059                              <1> 	; INPUT ->
  3060                              <1> 	;	If AL = 0, the caller is 'syscalbac';
  3061                              <1> 	;	   otherwise, the caller is 'sysaudio' or ...
  3062                              <1> 	;	   (AL = user number) 
  3063                              <1> 	; 	 
  3064                              <1> 	;	BL = IRQ number (Hardware interrupt request number)
  3065                              <1> 	;	     (0 t0 15 but IRQ 0,1,2,6,8,14,15 are prohibited)
  3066                              <1> 	;	     IRQ numbers 3,4,5,7,9,10,11,12,13 are valid
  3067                              <1> 	;	     (numbers >15 are invalid)
  3068                              <1> 	;
  3069                              <1> 	;	BH = 0 = Unlink IRQ (in BL) from user (ring 3) service
  3070                              <1> 	;	     1 = Link IRQ by using Signal Response Byte method
  3071                              <1> 	;	     2 = Link IRQ by using Callback service method 		
  3072                              <1> 	;	     3 = Link IRQ by using Auto Increment S.R.B. method 	
  3073                              <1> 	;	    >3 = invalid 
  3074                              <1> 	;		 (syscallback version will return to user) 	
  3075                              <1> 	;	
  3076                              <1> 	;	CL = Signal Return/Response Byte value 
  3077                              <1> 	;
  3078                              <1> 	;	If BH = 3, kernel will put a counter value ; 03/08/2020
  3079                              <1> 	;	          (into the S.R.B. addr)
  3080                              <1> 	;		  between 0 to 255. (start value = CL+1)
  3081                              <1> 	;	
  3082                              <1> 	;	NOTE: counter value, for example: even and odd numbers
  3083                              <1> 	;	      may be used for -audio- DMA buffer switch 
  3084                              <1> 	;	      within double buffer method, etc. 		
  3085                              <1> 	;
  3086                              <1> 	;	EDX = Signal return (Response) byte address
  3087                              <1> 	;	       		  - or -
  3088                              <1> 	;	      Interrupt/Callback service/routine address
  3089                              <1> 	; 	
  3090                              <1> 	;	      (virtual address in user's memory space)
  3091                              <1> 	;
  3092                              <1> 	; OUTPUT ->
  3093                              <1> 	;	CF = 0 & EAX = 0 -> Successful setting
  3094                              <1> 	;	CF = 1 & EAX > 0 -> IRQ is prohibited or locked 
  3095                              <1> 	;			by another process
  3096                              <1> 	;		 eax = ERR_PERM_DENIED -> prohibited or locked
  3097                              <1> 	;		 eax = ERR_INV_PARAMETER -> 
  3098                              <1> 	;		       invalid parameter/option or bad address
  3099                              <1> 	;
  3100                              <1> 	; TRDOS 386 - IRQ CALLBACK structures (parameters):
  3101                              <1> 	;	
  3102                              <1> 	;	   [u.irqlock] = 1 word, IRQ flags (0-15) that indicates
  3103                              <1> 	;			which IRQs are locked by (that) user.
  3104                              <1> 	;		        Lock and unlock (by user) will change
  3105                              <1> 	;			these flags or 'terminate process' (sysexit)
  3106                              <1> 	;			will clear these flags and unlock those IRQs.
  3107                              <1> 	;			               
  3108                              <1> 	;		   	Bit 0 is for IRQ 0 and Bit 15 is for IRQ 15
  3109                              <1> 	;
  3110                              <1> 	;	   IRQ(x).owner	 : 1 byte, user, [u.uno], 0 = free (unlocked)	
  3111                              <1> 	;
  3112                              <1> 	;	   IRQ(x).method : 1 byte for callback method & status
  3113                              <1> 	;			   0 = Signal Response Byte method
  3114                              <1> 	;			   1 = Callback service method
  3115                              <1> 	;			   >1 = invalid for current 'syscalback'.
  3116                              <1> 	;			or(+) 80h = IRQ is in use by system (ring 0)
  3117                              <1> 	;			            function (audio etc.) or
  3118                              <1> 	;			   	    a device driver.	   	
  3119                              <1> 	;			(system function will ignore the lock/owner)
  3120                              <1> 	;
  3121                              <1> 	;	   IRQ(x).srb	: 1 byte, Signal Return/Response byte value
  3122                              <1> 	;			  (a fixed value by user or a counter value
  3123                              <1> 	;			 from 0 to 255, which is increased by every
  3124                              <1> 	;			 interrupt just before putting it into 
  3125                              <1> 	;			 the Signal Response byte address
  3126                              <1> 	;			 (This is not used in callback serv method)
  3127                              <1> 	;	    	  
  3128                              <1> 	;	   IRQ(x).addr	: 1 dword
  3129                              <1> 	;			  Signal Response Byte address (physical)
  3130                              <1> 	;			  		-or-
  3131                              <1> 	;			  Callback service address (virtual)
  3132                              <1> 	;
  3133                              <1> 	;	   IRQ(x).dev	: 1 byte
  3134                              <1> 	;			  0 = Default device or kernel function
  3135                              <1> 	;			  		-or-
  3136                              <1> 	;			  1-255 = Assigned device driver number
  3137                              <1> 	;
  3138                              <1> 	;	   (x) = 3,4,5,7,9,10,11,12,13
  3139                              <1> 	;
  3140                              <1> 	
  3141 000113CB 80FB0F              <1> 	cmp	bl, 15
  3142 000113CE 7729                <1> 	ja	short scbs_2
  3143                              <1> 	
  3144 000113D0 80FF03              <1> 	cmp	bh, 3
  3145 000113D3 7724                <1> 	ja	short scbs_2  ; invalid parameter
  3146                              <1> 
  3147 000113D5 0FB6FB              <1> 	movzx	edi, bl ; save IRQ number
  3148                              <1> 
  3149                              <1> 		;  IRQ 0,1,2,6,8,14,15 are prohibited
  3150                              <1> 	;IRQenum: ; 'trdosk9.s'
  3151                              <1> 	;	db  0,0,0,1,2,3,0,4,0,5,6,7,8,9,0,0
  3152                              <1> 
  3153 000113D8 0FB6B7[2A210100]    <1> 	movzx	esi, byte [edi+IRQenum] ; IRQ availability 
  3154                              <1> 					; enumeration/index
  3155                              <1> 	;dec	esi
  3156 000113DF 664E                <1> 	dec	si
  3157 000113E1 780F                <1> 	js	short scbs_1 ;  0 -> 0FFFFh  
  3158                              <1> 
  3159                              <1> 	; ESI = IRQ callback parameters index number (0 to 8)
  3160                              <1> 
  3161 000113E3 08FF                <1> 	or	bh, bh
  3162 000113E5 7419                <1> 	jz	short scbs_4 ; unlink the IRQ (in BL)
  3163                              <1> 
  3164 000113E7 FECF                <1> 	dec	bh
  3165                              <1> 	; bh = method (0 = signal response byte, 1 = callback)
  3166                              <1> 	;	      (2 = auto increment of signal response byte) 
  3167                              <1> 
  3168 000113E9 80BE[0A760100]00    <1> 	cmp	byte [esi+IRQ.owner], 0 ; locked ?
  3169 000113F0 7637                <1> 	jna	short scbs_6	; no... OK...	
  3170                              <1> 
  3171                              <1> scbs_1:
  3172                              <1> 	; permission denied (prohibited IRQ)
  3173 000113F2 B80B000000          <1> 	mov	eax, ERR_PERM_DENIED
  3174 000113F7 F9                  <1> 	stc
  3175 000113F8 C3                  <1> 	retn
  3176                              <1> scbs_2:
  3177 000113F9 F9                  <1> 	stc
  3178                              <1> scbs_3:
  3179 000113FA B817000000          <1> 	mov	eax, ERR_INV_PARAMETER
  3180 000113FF C3                  <1> 	retn
  3181                              <1> 
  3182                              <1> scbs_4: ; unlink the requested IRQ (if it belongs to current user)
  3183                              <1> 	; 10/06/2017
  3184                              <1> 	; 22/04/2017
  3185                              <1> 	; 14/04/2017
  3186                              <1> 	; If AL = 0 -> The caller is 'syscalbac'
  3187 00011400 8AA6[0A760100]      <1> 	mov	ah, [esi+IRQ.owner]
  3188 00011406 3A25[B3030300]      <1> 	cmp	ah, [u.uno]
  3189 0001140C 75E4                <1> 	jne	short scbs_1
  3190                              <1> 
  3191 0001140E FE0D[D6030300]      <1> 	dec	byte [u.irqc] ; decrease IRQ count (in use)
  3192                              <1> 
  3193                              <1> 	;sub	ah, ah
  3194                              <1> 	;mov	[esi+IRQ.owner], ah ; 0 ; free !!!
  3195                              <1> 	;and	byte [esi+IRQ.method], 80h
  3196                              <1> 	;mov	[esi+IRQ.srb], ah ; 0
  3197                              <1> 	;mov	[esi+IRQ.dev], ah ; 0
  3198                              <1> 	;mov	dword [esi+IRQ.addr], 0
  3199                              <1> 	;mov	dword [u.r0], 0
  3200                              <1> 
  3201                              <1> 	;mov	byte [esi+IRQ.owner], 0
  3202                              <1> 
  3203                              <1> 	; 22/04/2017
  3204 00011414 29C0                <1> 	sub	eax, eax
  3205 00011416 8886[0A760100]      <1> 	mov	[esi+IRQ.owner], al ; 0
  3206                              <1> 	; 10/06/2017
  3207 0001141C 8686[1C760100]      <1> 	xchg	al, [esi+IRQ.method]
  3208 00011422 2480                <1> 	and	al, 80h
  3209 00011424 745E                <1> 	jz	short scbs_12 
  3210                              <1> 	; Audio device must be disabled -later- ! ([IRQ.medhod] = 80h)
  3211                              <1> 
  3212                              <1> ;	cmp	byte [esi+IRQ.method], 80h ; device drv or kernel extension ?
  3213                              <1> ;	jb	short scbs_12 ; bh = 0 reset to default IRQ handler
  3214                              <1> ;
  3215                              <1> ;	and	al, al
  3216                              <1> ;	jz	short  scbs_5  ; the caller is 'syscalbac'
  3217                              <1> ;	; The caller is 'sysaudio' or ...
  3218 00011426 30C0                <1> 	xor	al, al
  3219                              <1> ;	mov	[esi+IRQ.method], al ; 0 ; reset kernel extension flag
  3220                              <1> ;scbs_5:
  3221                              <1> ;	sub	ah, ah
  3222                              <1> 	;mov	[u.r0], eax ; 0
  3223 00011428 C3                  <1> 	retn	
  3224                              <1> 
  3225                              <1> scbs_6:
  3226                              <1> 	; 14/04/2017
  3227 00011429 20C0                <1> 	and	al, al
  3228 0001142B 7405                <1> 	jz	short scbs_7  ; the caller is 'syscalbac'
  3229                              <1> 	; AL = user number ([u.uno] or [audio.user] or ...)
  3230                              <1> 	; The caller is 'sysaudio' or ...
  3231                              <1> 	;	
  3232                              <1> 	; bh = method (0 = signal response byte, 1 = callback)
  3233                              <1> 	;	      (2 = auto increment of signal response byte) 
  3234                              <1> 
  3235 0001142D 80CF80              <1> 	or	bh, 80h		; Kernel extension flag !
  3236 00011430 EB0A                <1> 	jmp	short scbs_8
  3237                              <1> scbs_7:	
  3238 00011432 8A86[1C760100]      <1> 	mov	al, [esi+IRQ.method] ; >= 80h = kernel is using this IRQ
  3239 00011438 2480                <1> 	and	al, 80h ; use only bit 7 (kernel function flag)
  3240 0001143A 08C7                <1> 	or	bh, al		 ; method 
  3241                              <1> 				 ; 0 = signal response byte, 1 = callback
  3242                              <1> 				 ; 2 = auto increment of s.r.b.
  3243                              <1> scbs_8:
  3244 0001143C A0[B3030300]        <1> 	mov	al, [u.uno] ; user (process) number (1 to 16)
  3245 00011441 8886[0A760100]      <1> 	mov	[esi+IRQ.owner], al ; lock the IRQ for user
  3246 00011447 88BE[1C760100]      <1> 	mov	[esi+IRQ.method], bh
  3247                              <1> 
  3248                              <1> ;	test	bh, 1
  3249                              <1> ;	jnz	short scbs_9 	 ; Callback method, CX will not be used 
  3250                              <1> ;			
  3251                              <1> ;	test	bh, 2		 ; use auto increment (counter) method
  3252                              <1> ;	jz	short scbs_10	 ; (count can be used for buffer switch)
  3253                              <1> ;scbs_9:
  3254                              <1> ;	xor	ecx, ecx ; 0
  3255                              <1> scbs_10:			      	
  3256                              <1> 	;mov	[esi+IRQ.method], bh
  3257 0001144D 888E[25760100]      <1> 	mov	[esi+IRQ.srb], cl
  3258 00011453 C686[13760100]00    <1> 	mov	byte [esi+IRQ.dev], 0 ; device number is always 0 
  3259                              <1> 				 ; for this system call
  3260                              <1> 	;test	bh, 1
  3261 0001145A 80E701              <1> 	and	bh, 1 ; 17/04/2017
  3262 0001145D 7513                <1> 	jnz	short scbs_11	 ; callback method, use virtual address 
  3263                              <1> 
  3264 0001145F 53                  <1> 	push	ebx ; IRQ number (in BL)
  3265 00011460 89D3                <1> 	mov	ebx, edx
  3266                              <1> 	; ebx = virtual address
  3267                              <1> 	; [u.pgdir] = page directory's physical address
  3268 00011462 FE05[AA750100]      <1> 	inc	 byte [no_page_swap] ; 1 
  3269                              <1> 			; Do not add this page to swap queue
  3270                              <1> 			; and remove it from swap queue if it is
  3271                              <1> 			; on the queue.
  3272 00011468 E84D48FFFF          <1> 	call	get_physical_addr
  3273 0001146D 5B                  <1> 	pop	ebx
  3274 0001146E 728A                <1> 	jc	scbs_3 ; invalid address !
  3275                              <1> 	; eax = physical address of the virtual address in user's space
  3276 00011470 89C2                <1> 	mov	edx, eax
  3277                              <1> scbs_11:
  3278 00011472 66C1E602            <1> 	shl	si, 2		; byte (index) to dword (offset)
  3279 00011476 8996[2E760100]      <1> 	mov	[esi+IRQ.addr], edx
  3280                              <1> 
  3281 0001147C FE05[D6030300]      <1> 	inc	byte [u.irqc]	; increase IRQ (in use) count
  3282                              <1> 
  3283 00011482 FEC7                <1> 	inc	 bh ; 17/04/2017
  3284                              <1> 	; bh > 0 -> set to requested IRQ handler (IRQ_u_list)
  3285                              <1> scbs_12:
  3286 00011484 88D8                <1> 	mov	al, bl ; IRQ number
  3287 00011486 88FC                <1> 	mov	ah, bh ; 0 = reset, >0 = set
  3288 00011488 E8CFF3FFFF          <1> 	call	set_hardware_int_vector
  3289                              <1> 
  3290 0001148D 31C0                <1> 	xor	eax, eax
  3291                              <1> 	;mov 	[u.r0], eax ; 0	
  3292                              <1> 
  3293 0001148F C3                  <1> 	retn	; return with success (cf=0, eax=0)
  3294                              <1> 
  3295                              <1> 
  3296                              <1> sysdma: ; DMA FUNCTIONS
  3297                              <1> 	; 02/09/2017
  3298                              <1> 	; 28/08/2017
  3299                              <1> 	; 20/08/2017 - TRDOS 386 (TRDOS v2.0)
  3300                              <1> 	;
  3301                              <1> 	; Inputs:
  3302                              <1> 	;	BH = 0 -> Allocate DMA buffer
  3303                              <1> 	;	   BL = 0 -> Use the system's default DMA
  3304                              <1> 	;		     (SB16) Buffer
  3305                              <1> 	;	        Buffer Size (max.) = 65536 bytes
  3306                              <1> 	;	   BL > 0 -> Allocate (a new) DMA buffer
  3307                              <1>  	;	   ECX = DMA Buffer Size in bytes (<=128KB)
  3308                              <1> 	;	   EDX = Virtual Address of DMA buffer 	
  3309                              <1> 	;		
  3310                              <1> 	;	BH = 1 -> Initialize (Start) DMA service
  3311                              <1> 	;	     BL, bit 0 to 3 = Channel Number (0 to 7)	
  3312                              <1> 	;	     BL, bit 7 = Auto Initialized Mode 
  3313                              <1> 	;			(If bit 7 is set)
  3314                              <1> 	;		 bit 6 = Record (read) mode (0= playback)
  3315                              <1> 	;	     ECX = byte count (0 = use dma buffer size)
  3316                              <1> 	;	     EDX = physical buffer address
  3317                              <1> 	;	     	   (0 = use dma buffer -start- address)		
  3318                              <1> 	;
  3319                              <1> 	;	BH = 2 -> Get Current DMA Buffer Offset
  3320                              <1> 	;	     BL = DMA channel number	
  3321                              <1> 	;		
  3322                              <1> 	;	BH = 3 -> Get Current DMA count down value
  3323                              <1> 	;	     BL = DMA channel number (0 tO 7)	
  3324                              <1> 	;
  3325                              <1> 	;	BH = 4 -> Get Current DMA channel (in progress)
  3326                              <1> 	;
  3327                              <1> 	;	BH = 5 -> Get System's Default DMA Buffer Address
  3328                              <1> 	;
  3329                              <1> 	;	BH = 6 -> Get Current DMA Buffer Address	
  3330                              <1> 	;
  3331                              <1> 	;	BH = 7 -> Stop DMA service
  3332                              <1> 	;
  3333                              <1> 	;
  3334                              <1> 	; Outputs:
  3335                              <1> 	;
  3336                              <1> 	;	For BH = 0 ; Allocate DMA buffer
  3337                              <1> 	;	    EAX = Physical address of DMA buffer
  3338                              <1> 	;	    ECX = Allocated buffer size in bytes
  3339                              <1> 	;		  - page count * 4096 -
  3340                              <1> 	;		  (may be bigger than requested)	
  3341                              <1> 	;	    If BL input > 0,
  3342                              <1> 	;	       'sysalloc:' system call will be used with
  3343                              <1>   	;	       EBX (for 'sysalloc') = EDX (for 'sysdma')
  3344                              <1> 	;	       ECX is same, byte count (buffer size)
  3345                              <1> 	;	       EDX = 1024*1024*16 ; 16 MB upper limit	 		        	 
  3346                              <1> 	;	    If BL input = 0,
  3347                              <1> 	;	       Default DMA buffer (SB16 buffer) will be
  3348                              <1> 	;	       checked and if it is free, it's address
  3349                              <1> 	;	       will be returned in EAX and it's size
  3350                              <1> 	;	       will be returned in ECX (as 65536)
  3351                              <1> 	;
  3352                              <1> 	;	    If CF = 1, error code is in EAX
  3353                              <1> 	;	       EAX = -1 ; DMA buffer allocation error! 		
  3354                              <1> 	;	       EAX = 11 ; 'Permission Denied' error !
  3355                              <1> 	;
  3356                              <1> 	;	       Note: 'sysalloc' error return method
  3357                              <1> 	;		      will be applied if BL input > 0 !		
  3358                              <1> 	;
  3359                              <1> 	; 	 For BH = 1 ; Initialize (Start) DMA
  3360                              <1> 	;	     EAX = 0 (Successful)	
  3361                              <1> 	;	     If CF = 1, error code is in EAX
  3362                              <1> 	;
  3363                              <1> 	; 	 For BH = 2 ; Get Current DMA Buffer Offset
  3364                              <1> 	;	     EAX = DMA Buffer Offset (in bytes)
  3365                              <1> 	;	     ;
  3366                              <1> 	;	      AX = DMA buffer offset
  3367                              <1> 	;	     EAX bits 16 to 23 = Page register value
  3368                              <1> 	;		   	
  3369                              <1> 	; 	 For BH = 3 ; Get Current DMA count down value
  3370                              <1> 	;	     EAX = Count down value (remain bytes)
  3371                              <1> 	;	
  3372                              <1> 	;	 For BH = 4 ; Get Current DMA channel (in progress)
  3373                              <1> 	;	     EAX = DMA channel number (0 to 7)
  3374                              <1> 	;		AH = 0 if the owner is the caller process
  3375                              <1> 	;		AH > 0 if the dma channel is in use by
  3376                              <1> 	;		       another user/process
  3377                              <1> 	;	     EAX = -1 (0FFFFFFFFh) 
  3378                              <1> 	;		    if DMA service is not in use	    		
  3379                              <1> 	;	 	    (stopped or not initialized/started)	
  3380                              <1> 	;
  3381                              <1> 	;	 For BH = 5 ; Get System's Default DMA Buff Addr
  3382                              <1> 	;	     EAX = Default DMA Buffer Address (Physical)
  3383                              <1> 	;		 = offset 'sb16_dma_buffer:'	
  3384                              <1> 	;	     ECX = Buffer size
  3385                              <1> 	;		 = 65536 
  3386                              <1> 	;
  3387                              <1> 	;	 For BH = 6 ; Get Current DMA Buffer Address
  3388                              <1> 	;	     EAX = Current DMA buffer address (Physical)
  3389                              <1> 	;	     ECX = Current DMA buffer size (setting value)	   		  	 		
  3390                              <1> 	;	     Note: These values are for current dma channel
  3391                              <1> 	;		   settings for the user/process
  3392                              <1> 	;	     ** For now (for current TRDOS 386 version)
  3393                              <1> 	;		only one user/process can use only one
  3394                              <1> 	;		dma channel & one dma buffer at same time
  3395                              <1> 	;		(no multi tasking on DMA service) !!! **
  3396                              <1> 	;	     (Once, current DMA user must stop it's own DMA
  3397                              <1> 	;	      DMA service, than another user/program 
  3398                              <1> 	;	      can use DMA service with same dma channel 
  3399                              <1> 	;	      or with another DMA channel.)	 			      		
  3400                              <1> 	;
  3401                              <1> 	;	 For BH = 7 ; Stop DMA service (for current user
  3402                              <1> 	;	     and current DMA channel)	
  3403                              <1> 	;	     EAX = 0 ; successful
  3404                              <1> 	;	     CF = 1 & EAX > 0 (= -1) -> Error		
  3405                              <1> 
  3406 00011490 80FF07              <1> 	cmp	bh, 7
  3407 00011493 7612                <1> 	jna	short sysdma_0
  3408                              <1> 
  3409                              <1> sysdma_err:
  3410 00011495 31C0                <1> 	xor	eax, eax
  3411 00011497 48                  <1> 	dec	eax ; -1
  3412                              <1> sysdma_perm_err:
  3413 00011498 A3[64030300]        <1> 	mov	[u.r0], eax
  3414 0001149D A3[C8030300]        <1> 	mov	[u.error], eax ; DMA service error !
  3415 000114A2 E905BEFFFF          <1> 	jmp	error
  3416                              <1> 
  3417                              <1> sysdma_0:
  3418 000114A7 08FF                <1> 	or	bh, bh
  3419 000114A9 0F85BA000000        <1> 	jnz	sysdma_1
  3420                              <1> 	
  3421 000114AF 20DB                <1> 	and	bl, bl
  3422 000114B1 7416                <1> 	jz	short sysdma_01
  3423                              <1> 
  3424                              <1> 	; redirect system call to 'sysalloc'
  3425 000114B3 89D3                <1> 	mov	ebx, edx ; virtual address of DMA buffer
  3426                              <1> 	;ecx = Buffer size in bytes
  3427                              <1> 	; DMA buffer address <= 16MB upper limit
  3428 000114B5 BA00000001          <1> 	mov	edx, 1024*1024*16 ; 16MB limit for DMA buff
  3429                              <1> 
  3430 000114BA C705[9C7A0100]FFFF- <1> 	mov	dword [dma_addr], 0FFFFFFFFh ; -1
  3430 000114C2 FFFF                <1>
  3431                              <1> 
  3432 000114C4 E99DE5FFFF          <1> 	jmp	sysalloc
  3433                              <1> 
  3434                              <1> sysdma_01:
  3435 000114C9 B8[00000200]        <1> 	mov	eax, sb16_dma_buffer
  3436                              <1> 
  3437 000114CE 803D[59760100]01    <1> 	cmp	byte [audio_device], 1
  3438 000114D5 722A                <1> 	jb	short sysdma_03
  3439                              <1> 
  3440 000114D7 3B05[78760100]      <1> 	cmp	eax, [audio_dma_buff]
  3441 000114DD 7507                <1> 	jne	short sysdma_02
  3442                              <1> 
  3443                              <1> sysdma_0_err:
  3444 000114DF B80B000000          <1> 	mov	eax, ERR_PERM_DENIED
  3445 000114E4 EBB2                <1> 	jmp	short sysdma_perm_err
  3446                              <1> 
  3447                              <1> sysdma_02:
  3448                              <1> 	; Only one user is permitted for audio/dma functions
  3449                              <1> 
  3450 000114E6 833D[78760100]00    <1> 	cmp	dword [audio_dma_buff], 0
  3451 000114ED 7612                <1> 	jna	short sysdma_03
  3452                              <1> 
  3453 000114EF 8A1D[81760100]      <1> 	mov	bl, [audio_user]
  3454 000114F5 08DB                <1> 	or	bl, bl
  3455 000114F7 7408                <1> 	jz	short sysdma_03
  3456                              <1> 
  3457 000114F9 3A1D[B3030300]      <1> 	cmp	bl, [u.uno]
  3458 000114FF 75DE                <1> 	jne	short sysdma_0_err
  3459                              <1> 
  3460                              <1> sysdma_03: 
  3461 00011501 8A1D[997A0100]      <1> 	mov	bl, [dma_user]
  3462 00011507 20DB                <1> 	and	bl, bl
  3463 00011509 750E                <1> 	jnz	short sysdma_04
  3464                              <1> 	
  3465 0001150B 8A1D[B3030300]      <1> 	mov	bl, [u.uno]
  3466 00011511 881D[997A0100]      <1> 	mov	[dma_user], bl
  3467                              <1> 
  3468 00011517 EB15                <1> 	jmp	short sysdma_05
  3469                              <1> 
  3470                              <1> sysdma_04:
  3471 00011519 8B35[9C7A0100]      <1> 	mov	esi, [dma_addr]
  3472 0001151F 21F6                <1> 	and	esi, esi
  3473 00011521 740B                <1> 	jz	short sysdma_05
  3474                              <1> 
  3475 00011523 46                  <1> 	inc	esi ; -1 -> 0
  3476 00011524 7408                <1> 	jz	short sysdma_05
  3477                              <1> 
  3478 00011526 3A1D[B3030300]      <1> 	cmp	bl, [u.uno]
  3479 0001152C 75B1                <1> 	jne	short sysdma_0_err
  3480                              <1> 	
  3481                              <1> sysdma_05:
  3482                              <1> 	; edx = virtual address (user's buffer address)
  3483                              <1> 	; 
  3484 0001152E 81F900000100        <1> 	cmp	ecx, 65536   ; byte count (buffer size)
  3485 00011534 0F875BFFFFFF        <1> 	ja	sysdma_err	
  3486                              <1> 	;
  3487 0001153A 81C1FF0F0000        <1> 	add	ecx, PAGE_SIZE-1 ; 4095
  3488 00011540 6681E100F0          <1> 	and	cx, ~PAGE_OFF ; not 4095
  3489                              <1> 	;cmp	ecx, 65536
  3490                              <1> 	;ja	sysdma_err ;
  3491 00011545 51                  <1> 	push	ecx	; buffer size (allocated pages * 4096) 
  3492 00011546 50                  <1> 	push	eax	; offset sb16_dma_buffer
  3493 00011547 89D3                <1> 	mov	ebx, edx
  3494 00011549 C1E90C              <1> 	shr	ecx, 12 ; byte count to page count
  3495                              <1> 	; eax = physical address of (audio) dma buffer
  3496                              <1> 	; ebx = virtual address of (audio) dma buffer (user's pgdir) 
  3497                              <1> 	; ecx = page count (>0)
  3498 0001154C E87B4BFFFF          <1> 	call	direct_memory_access
  3499 00011551 58                  <1> 	pop	eax
  3500 00011552 59                  <1> 	pop	ecx
  3501 00011553 0F823CFFFFFF        <1> 	jc	sysdma_err
  3502                              <1> 
  3503 00011559 A3[9C7A0100]        <1> 	mov	[dma_addr], eax
  3504 0001155E 890D[A07A0100]      <1> 	mov	[dma_size], ecx ; dma buffer size (in bytes)
  3505                              <1> 
  3506                              <1> 	;mov	[u.r0], eax ; DMA Buffer Address (Physical)
  3507                              <1> 
  3508                              <1> 	;mov	ebp, [u.usp]  ; ebp points to user's registers
  3509                              <1> 	;mov	[ebp+24], ecx ; return to user with ecx value
  3510                              <1> 
  3511                              <1> 	;jmp	sysret
  3512                              <1> 
  3513                              <1> 	; 28/08/2017
  3514 00011564 E9C4000000          <1> 	jmp	sysdma_51
  3515                              <1> 
  3516                              <1> sysdma_1:
  3517 00011569 80FF01              <1> 	cmp	bh, 1
  3518 0001156C 0F87A6000000        <1> 	ja	sysdma_5
  3519                              <1> 
  3520 00011572 F6C340              <1> 	test	bl, 40h	; record (read) mode -BL, bit 6-
  3521 00011575 0F851AFFFFFF        <1> 	jnz	sysdma_err ; not ready yet!
  3522                              <1> 
  3523 0001157B A1[9C7A0100]        <1> 	mov	eax, [dma_addr] ; physical address of dma buffer
  3524 00011580 21C0                <1> 	and	eax, eax
  3525 00011582 0F840DFFFFFF        <1> 	jz	sysdma_err
  3526                              <1> 
  3527 00011588 09D2                <1> 	or	edx, edx
  3528 0001158A 7504                <1> 	jnz	short sysdma_11
  3529                              <1> 
  3530 0001158C 89C2                <1> 	mov	edx, eax
  3531 0001158E EB08                <1> 	jmp	short sysdma_12	
  3532                              <1> sysdma_11:
  3533 00011590 39C2                <1> 	cmp	edx, eax
  3534 00011592 0F82FDFEFFFF        <1> 	jb	sysdma_err
  3535                              <1> sysdma_12:
  3536 00011598 21C9                <1> 	and	ecx, ecx
  3537 0001159A 7508                <1> 	jnz	short sysdma_13
  3538                              <1> 
  3539 0001159C 8B0D[A07A0100]      <1> 	mov	ecx, [dma_size]
  3540 000115A2 EB0C                <1> 	jmp	short sysdma_14
  3541                              <1> sysdma_13:
  3542 000115A4 3B0D[A07A0100]      <1> 	cmp	ecx, [dma_size]
  3543 000115AA 0F87E5FEFFFF        <1> 	ja	sysdma_err
  3544                              <1> sysdma_14:
  3545 000115B0 89C6                <1> 	mov	esi, eax
  3546 000115B2 0335[A07A0100]      <1> 	add	esi, [dma_size]
  3547                              <1> 
  3548 000115B8 89D0                <1> 	mov	eax, edx
  3549 000115BA 01C8                <1> 	add	eax, ecx
  3550 000115BC 0F82D3FEFFFF        <1> 	jc	sysdma_err ; 02/09/2017	
  3551                              <1> 		
  3552 000115C2 39F0                <1> 	cmp	eax, esi
  3553 000115C4 0F87CBFEFFFF        <1> 	ja	sysdma_err
  3554                              <1> 
  3555 000115CA 8B3D[78760100]      <1> 	mov	edi, [audio_dma_buff]
  3556 000115D0 8B35[9C7A0100]      <1> 	mov	esi, [dma_addr]
  3557                              <1> 
  3558 000115D6 09FF                <1> 	or	edi, edi
  3559 000115D8 7424                <1> 	jz	short sysdma_16
  3560                              <1> 	
  3561 000115DA 803D[59760100]01    <1> 	cmp	byte [audio_device], 1
  3562 000115E1 7208                <1> 	jb	short sysdma_15
  3563                              <1> 
  3564                              <1> 	; Sound Blaster 16
  3565 000115E3 39FE                <1> 	cmp	esi, edi
  3566 000115E5 0F84F4FEFFFF        <1> 	je	sysdma_0_err ; permmission denied !
  3567                              <1> 
  3568                              <1> sysdma_15:
  3569 000115EB C605[9B7A0100]48    <1> 	mov	byte [dma_mode], 48h ; single mode playback	
  3570                              <1> 
  3571 000115F2 F6C380              <1> 	test	bl, 80h ; DMA mode - BL, bit 7, auto init -
  3572 000115F5 7407                <1> 	jz	short sysdma_16	
  3573                              <1> 	; Auto initialized playback (write) mode
  3574 000115F7 8005[9B7A0100]10    <1> 	add	byte [dma_mode], 10h ; = 58h
  3575                              <1> sysdma_16:
  3576 000115FE 80E307              <1> 	and	bl, 07h
  3577 00011601 881D[9A7A0100]      <1> 	mov	[dma_channel], bl
  3578 00011607 8915[A47A0100]      <1> 	mov	[dma_start], edx
  3579 0001160D 890D[A87A0100]      <1> 	mov	[dma_count], ecx
  3580                              <1> 	 
  3581                              <1> 	; 28/08/2017
  3582                              <1> 	;call	dma_init
  3583                              <1> 	;jmp	sysret
  3584 00011613 E94B010000          <1> 	jmp	dma_init
  3585                              <1> 
  3586                              <1> sysdma_5:
  3587 00011618 80FF05              <1> 	cmp	bh, 5
  3588 0001161B 7223                <1> 	jb	short sysdma_3
  3589 0001161D 0F87CE000000        <1> 	ja	sysdma_6	
  3590                              <1> 
  3591                              <1> 	; Get the system's default dma buffer addr and size
  3592 00011623 B8[00000200]        <1> 	mov	eax, sb16_dma_buffer
  3593 00011628 B900000100          <1> 	mov	ecx, 65536 ; Buffer size in bytes
  3594                              <1> 
  3595                              <1> sysdma_51:
  3596                              <1> 	; 0 = there is not a dma buffer (in use or available)
  3597 0001162D A3[64030300]        <1> 	mov	[u.r0], eax
  3598                              <1> 
  3599 00011632 8B2D[60030300]      <1> 	mov	ebp, [u.usp]  ; ebp points to user's registers
  3600 00011638 894D18              <1> 	mov	[ebp+24], ecx ; return to user with ecx value
  3601                              <1> 
  3602 0001163B E98CBCFFFF          <1> 	jmp	sysret
  3603                              <1> 
  3604                              <1> sysdma_3:
  3605 00011640 80FF03              <1> 	cmp	bh, 3
  3606 00011643 7231                <1> 	jb	short sysdma_2
  3607 00011645 776B                <1> 	ja	short sysdma_4
  3608                              <1> 
  3609                              <1> 	; Get current dma count down value (remain bytes)
  3610                              <1> 	; 28/08/2017
  3611 00011647 0FB635[9A7A0100]    <1> 	movzx	esi, byte [dma_channel]
  3612 0001164E 0FB696[62210100]    <1> 	movzx	edx, byte [dma_flip+esi]
  3613 00011655 EE                  <1> 	out	dx, al			; flip-flop clear
  3614 00011656 8A96[42210100]      <1> 	mov	dl, [dma_cnt+esi] ; dma count register addr
  3615 0001165C EC                  <1> 	in	al, dx
  3616 0001165D 0FB6D8              <1> 	movzx	ebx, al	
  3617 00011660 EC                  <1> 	in	al, dx
  3618 00011661 88C7                <1> 	mov     bh, al
  3619                              <1> 	
  3620 00011663 6683FE04            <1> 	cmp	si, 4 ; channel number ?
  3621 00011667 7202                <1> 	jb	short sysdma_31 ; 8 bit dma channel
  3622                              <1> 
  3623 00011669 D1E3                <1> 	shl	ebx, 1	; word count to byte count
  3624                              <1> 
  3625                              <1> sysdma_31:
  3626 0001166B 891D[64030300]      <1> 	mov	[u.r0], ebx
  3627                              <1> 
  3628 00011671 E956BCFFFF          <1> 	jmp	sysret	
  3629                              <1> 
  3630                              <1> sysdma_2:
  3631                              <1> 	; Get current dma buffer offset (& page)
  3632                              <1> 	; 28/08/2017
  3633 00011676 0FB635[9A7A0100]    <1> 	movzx	esi, byte [dma_channel]
  3634 0001167D 0FB696[62210100]    <1> 	movzx	edx, byte [dma_flip+esi]
  3635 00011684 EE                  <1> 	out	dx, al			; flip-flop clear
  3636 00011685 8A96[3A210100]      <1> 	mov	dl, [dma_adr+esi]
  3637 0001168B EC                  <1> 	in	al, dx			; get dma position
  3638 0001168C 0FB6D8              <1> 	movzx	ebx, al
  3639 0001168F EC                  <1> 	in	al, dx			
  3640 00011690 88C7                <1> 	mov	bh, al
  3641                              <1> 
  3642 00011692 6683FE04            <1> 	cmp	si, 4 ; channel number ?
  3643 00011696 7202                <1> 	jb	short sysdma_21 ; 8 bit dma channel
  3644                              <1> 
  3645 00011698 D1E3                <1> 	shl	ebx, 1	; word offset to byte offset
  3646                              <1> 
  3647                              <1> sysdma_21:
  3648 0001169A 891D[64030300]      <1> 	mov	[u.r0], ebx
  3649                              <1> 
  3650 000116A0 8A96[4A210100]      <1> 	mov	dl, [dma_page+esi]
  3651 000116A6 EC                  <1> 	in	al, dx			; get dma page
  3652                              <1> 
  3653                              <1> 	;add	[u.ro+2], al
  3654 000116A7 0805[66030300]      <1> 	or	[u.r0+2], al
  3655                              <1> 
  3656 000116AD E91ABCFFFF          <1> 	jmp	sysret
  3657                              <1> 
  3658                              <1> sysdma_4:
  3659                              <1> 	; Get current DMA channel number
  3660                              <1> 	; 28/08/2017
  3661 000116B2 8A25[997A0100]      <1> 	mov	ah, [dma_user]
  3662 000116B8 20E4                <1> 	and	ah, ah
  3663 000116BA 750F                <1> 	jnz	short sysdma_42
  3664                              <1> 
  3665                              <1> sysdma_41:	
  3666                              <1> 	; Not a valid dma channel (in use)
  3667 000116BC C705[64030300]FFFF- <1> 	mov	dword [u.r0], -1 ; 0FFFFFFFFh
  3667 000116C4 FFFF                <1>
  3668 000116C6 E901BCFFFF          <1> 	jmp	sysret
  3669                              <1> 
  3670                              <1> sysdma_42:
  3671 000116CB 8B35[9C7A0100]      <1> 	mov	esi, [dma_addr]
  3672 000116D1 21F6                <1> 	and	esi, esi
  3673 000116D3 74E7                <1> 	jz	short sysdma_41
  3674                              <1> 
  3675 000116D5 46                  <1> 	inc	esi ; -1 -> 0
  3676 000116D6 74E4                <1> 	jz	short sysdma_41
  3677                              <1> 
  3678 000116D8 A0[9A7A0100]        <1> 	mov	al, [dma_channel]
  3679                              <1> 
  3680 000116DD 3A25[B3030300]      <1> 	cmp	ah, [u.uno]
  3681 000116E3 7502                <1> 	jne	short sysdma_43
  3682                              <1> 
  3683 000116E5 30E4                <1> 	xor	ah, ah ; DMA channel in use by current user
  3684                              <1> 
  3685                              <1> sysdma_43:
  3686 000116E7 A3[64030300]        <1> 	mov	[u.r0], eax ; AL = dma channel number
  3687                              <1> 			    ; AH > 0 if the the channel
  3688                              <1> 			    ; in use by another user/process
  3689 000116EC E9DBBBFFFF          <1> 	jmp	sysret
  3690                              <1> 
  3691                              <1> sysdma_6:
  3692 000116F1 80FF06              <1> 	cmp	bh, 6
  3693 000116F4 7710                <1> 	ja	short sysdma_7
  3694                              <1> 
  3695                              <1> 	; 28/08/2017
  3696                              <1> 	; Get current DMA buffer addr and size
  3697 000116F6 A1[9C7A0100]        <1> 	mov	eax, [dma_addr] ; dma buffer address
  3698 000116FB 8B0D[A07A0100]      <1> 	mov	ecx, [dma_size] ; dma buffer size (in bytes)
  3699                              <1> 
  3700 00011701 E927FFFFFF          <1> 	jmp	sysdma_51
  3701                              <1> 
  3702                              <1> sysdma_7:
  3703                              <1> 	; DMA service STOP
  3704 00011706 A0[B3030300]        <1> 	mov	al, [u.uno]
  3705 0001170B 3A05[997A0100]      <1> 	cmp	al, [dma_user]
  3706 00011711 751D                <1> 	jne	short sysdma_72
  3707                              <1> 	
  3708 00011713 28C0                <1> 	sub	al, al ; 0
  3709                              <1> 
  3710 00011715 A2[997A0100]        <1> 	mov	[dma_user], al ; clear user
  3711                              <1> 
  3712 0001171A 8605[9B7A0100]      <1> 	xchg	al, [dma_mode]
  3713 00011720 20C0                <1> 	and	al, al
  3714                              <1> 	;jz	short sysdma_err
  3715 00011722 7527                <1> 	jnz	short sysdma_73	
  3716                              <1> 
  3717                              <1> sysdma_71:
  3718 00011724 31C0                <1> 	xor	eax, eax
  3719 00011726 A3[64030300]        <1> 	mov	[u.r0], eax; 0
  3720 0001172B E99CBBFFFF          <1> 	jmp	sysret
  3721                              <1> 
  3722                              <1> sysdma_72:
  3723                              <1> 	; 28/08/2017
  3724 00011730 803D[997A0100]00    <1> 	cmp	byte [dma_user], 0
  3725 00011737 76EB                <1> 	jna	short sysdma_71 ; Nothing to do !
  3726                              <1> 
  3727 00011739 833D[9C7A0100]00    <1> 	cmp	dword [dma_addr], 0
  3728 00011740 0F8799FDFFFF        <1> 	ja	sysdma_0_err
  3729                              <1> 	
  3730 00011746 A2[997A0100]        <1> 	mov	[dma_user], al ; reset to current user
  3731                              <1> 
  3732                              <1> sysdma_73:
  3733                              <1> 	; 28/08/2017
  3734 0001174B 0FB635[9A7A0100]    <1> 	movzx	esi, byte [dma_channel]
  3735 00011752 0FB696[52210100]    <1> 	movzx	edx, byte [dma_mask+esi]
  3736 00011759 A0[9A7A0100]        <1> 	mov	al, [dma_channel]
  3737 0001175E 0C04                <1> 	or	al, 4
  3738 00011760 EE                  <1> 	out	dx, al
  3739                              <1> 
  3740 00011761 EBC1                <1> 	jmp	short sysdma_71
  3741                              <1> 
  3742                              <1> dma_init:
  3743                              <1> 	; 28/08/2017
  3744                              <1> 	; 20/08/2017
  3745                              <1> 	; DMA initialization
  3746                              <1> 	; 14/08/2017
  3747                              <1> 	; 03/08/2017, 06/08/2017, 08/08/2017
  3748                              <1> 	; 02/07/2017, 13/07/2017, 16/07/2017, 30/07/2017
  3749                              <1> 	; (Derived from 'DMA_INIT' procedure in SB16MOD.ASM)
  3750                              <1> 	; Modified for TRDOS 386 DMA buffer allocation & initialization !
  3751                              <1> 
  3752 00011763 8B1D[A47A0100]      <1> 	mov	ebx, [dma_start]
  3753 00011769 8B0D[A87A0100]      <1> 	mov	ecx, [dma_count]
  3754                              <1> 
  3755 0001176F 0FB635[9A7A0100]    <1> 	movzx	esi, byte [dma_channel]
  3756                              <1> 
  3757 00011776 6683FE04            <1> 	cmp	si, 4
  3758 0001177A 7205                <1> 	jb	short gdmi1
  3759                              <1> 	; 08/08/2017
  3760 0001177C 66D1E9              <1> 	shr	cx, 1 ; word count
  3761 0001177F D1EB                <1> 	shr	ebx, 1 ; convert byte offset to word offset
  3762                              <1> gdmi1:
  3763                              <1> 	;mov	[dma_poff], bx ; 08/08/2017
  3764 00011781 6649                <1> 	dec	cx			; dma size = block size - 1
  3765                              <1> 	
  3766 00011783 0FB696[52210100]    <1> 	movzx	edx, byte [dma_mask+esi] ; 30/07/2017
  3767 0001178A A0[9A7A0100]        <1> 	mov	al, [dma_channel]
  3768 0001178F 0C04                <1> 	or	al, 4
  3769 00011791 EE                  <1> 	out	dx, al			; dma channel mask
  3770                              <1> 
  3771 00011792 30C0                <1> 	xor	al, al ; 0 ; any value ! 08/08/2017
  3772 00011794 8A96[62210100]      <1> 	mov	dl, [dma_flip+esi]
  3773 0001179A EE                  <1> 	out	dx, al			; flip-flop clear
  3774                              <1> 	
  3775 0001179B 8A96[5A210100]      <1> 	mov	dl, [dma_mod+esi]
  3776 000117A1 A0[9A7A0100]        <1> 	mov	al, [dma_channel]  ; 13/07/2017
  3777 000117A6 2403                <1> 	and	al, 3
  3778                              <1> 	; 08/08/2017
  3779 000117A8 0A05[9B7A0100]      <1> 	or	al, [dma_mode] ; 58h    ; dma mode for SB16
  3780 000117AE EE                  <1> 	out	dx, al			
  3781                              <1> 
  3782 000117AF 8A96[3A210100]      <1> 	mov	dl, [dma_adr+esi]	
  3783 000117B5 88D8                <1> 	mov	al, bl			
  3784 000117B7 EE                  <1> 	out	dx, al			; offset low
  3785                              <1> 
  3786 000117B8 88F8                <1> 	mov	al, bh
  3787 000117BA EE                  <1> 	out	dx, al			; offset high
  3788                              <1> 
  3789 000117BB 8A96[42210100]      <1> 	mov	dl, [dma_cnt+esi]
  3790 000117C1 88C8                <1> 	mov	al, cl
  3791 000117C3 EE                  <1> 	out	dx, al			; size low
  3792                              <1> 
  3793 000117C4 88E8                <1> 	mov	al, ch
  3794 000117C6 EE                  <1> 	out	dx, al			; size high
  3795                              <1> 
  3796 000117C7 8A96[4A210100]      <1> 	mov	dl, [dma_page+esi]
  3797                              <1> 	; 14/08/2017 
  3798 000117CD 6683FE04            <1> 	cmp	si, 4
  3799 000117D1 7305                <1> 	jnb	short gdmi2
  3800 000117D3 C1EB10              <1> 	shr	ebx, 16
  3801 000117D6 EB06                <1> 	jmp	short gdmi3
  3802                              <1> gdmi2:
  3803                              <1> 	; 09/08/2017
  3804 000117D8 C1EB0F              <1> 	shr	ebx, 15	 ; complete 16 bit shift
  3805 000117DB 80E3FE              <1> 	and	bl, 0FEh ; clear bit 0 (not necessary)
  3806                              <1> gdmi3:	
  3807 000117DE 88D8                <1> 	mov	al, bl
  3808 000117E0 EE                  <1> 	out	dx, al			; page			
  3809                              <1> 	
  3810 000117E1 8A96[52210100]      <1> 	mov	dl, [dma_mask+esi]
  3811 000117E7 A0[9A7A0100]        <1> 	mov	al, [dma_channel]  ; 13/07/2017
  3812 000117EC 2403                <1> 	and	al, 3
  3813 000117EE EE                  <1> 	out	dx, al			; dma channel unmask
  3814                              <1> 
  3815                              <1> 	;retn
  3816                              <1> 	; 28/08/2017
  3817 000117EF E9D8BAFFFF          <1> 	jmp	sysret
  3818                              <1> 
  3819                              <1> otty:
  3820                              <1> sret:
  3821                              <1> ocvt:
  3822                              <1> ctty:
  3823                              <1> cret:
  3824                              <1> ccvt:
  3825                              <1> rtty:
  3826                              <1> wtty:
  3827                              <1> rmem:
  3828                              <1> wmem:
  3829                              <1> rfd:
  3830                              <1> rhd:
  3831                              <1> wfd:
  3832                              <1> whd:
  3833                              <1> rlpt:
  3834                              <1> wlpt:
  3835                              <1> rcvt:
  3836                              <1> xmtt:
  3837 000117F4 C3                  <1> 	retn
  3038                                  %include 'trdosk9.s' ; 04/01/2016
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.3) - INITIALIZED DATA : trdosk9.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 22/12/2020
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 04/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; ----------------------------------------------------------------------------
     9                              <1> ; Assembler: NASM version 2.15 (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 000117F5 01                  <1> 		db 1 ; A: = 0 & B: = 1
    22                              <1> 
    23                              <1> Restore_CDIR:	
    24 000117F6 FF                  <1> 		db 0FFh ; Initial value -> any number except 0
    25                              <1> 
    26                              <1> msg_CRLF_temp:  
    27 000117F7 070D0A00            <1> 		db 07h, 0Dh, 0Ah, 0
    28                              <1> 
    29                              <1> Magic_Bytes:
    30 000117FB 04                  <1> 		db 4
    31 000117FC 01                  <1> 		db 1
    32                              <1> mainprog_Version:
    33 000117FD 07                  <1> 		db 7
    34 000117FE 5B5452444F535D204D- <1> 		db "[TRDOS] Main Program v2.0.221220"
    34 00011807 61696E2050726F6772- <1>
    34 00011810 616D2076322E302E32- <1>
    34 00011819 3231323230          <1>
    35 0001181E 0D0A                <1> 		db 0Dh, 0Ah
    36 00011820 286329204572646F67- <1> 		db "(c) Erdogan Tan 2005-2020"
    36 00011829 616E2054616E203230- <1>
    36 00011832 30352D32303230      <1>
    37 00011839 0D0A00              <1> 		db 0Dh, 0Ah, 0
    38                              <1> 
    39                              <1> MainProgCfgFile: ; 14/04/2016
    40 0001183C 4D41494E50524F472E- <1> 		db "MAINPROG.CFG", 0
    40 00011845 43464700            <1>
    41                              <1> 
    42                              <1> TRDOSPromptLabel:
    43 00011849 5452444F53          <1> 		db "TRDOS"
    44 0001184E 00                  <1> 		db 0
    45 0001184F 00<rept>            <1>                 times 5 db 0
    46 00011854 00                  <1> 		db 0
    47                              <1> 
    48                              <1> ; INTERNAL COMMANDS
    49                              <1> Command_List:
    50 00011855 44495200            <1> Cmd_Dir:	db "DIR", 0
    51 00011859 434400              <1> Cmd_Cd:		db "CD", 0
    52 0001185C 433A00              <1> Cmd_Drive:	db "C:", 0
    53 0001185F 56455200            <1> Cmd_Ver:	db "VER", 0
    54 00011863 4558495400          <1> Cmd_Exit:	db "EXIT", 0
    55 00011868 50524F4D505400      <1> Cmd_Prompt:	db "PROMPT", 0
    56 0001186F 564F4C554D4500      <1> Cmd_Volume:	db "VOLUME", 0
    57 00011876 4C4F4E474E414D4500  <1> Cmd_LongName:	db "LONGNAME", 0
    58 0001187F 4441544500          <1> Cmd_Date:	db "DATE", 0
    59 00011884 54494D4500          <1> Cmd_Time:	db "TIME", 0
    60 00011889 52554E00            <1> Cmd_Run:	db "RUN", 0
    61 0001188D 53455400            <1> Cmd_Set:	db "SET", 0 
    62 00011891 434C5300            <1> Cmd_Cls:	db "CLS", 0
    63 00011895 53484F5700          <1> Cmd_Show:	db "SHOW", 0
    64 0001189A 44454C00            <1> Cmd_Del:	db "DEL", 0
    65 0001189E 41545452494200      <1> Cmd_Attrib:	db "ATTRIB", 0
    66 000118A5 52454E414D4500      <1> Cmd_Rename:	db "RENAME", 0
    67 000118AC 524D44495200        <1> Cmd_Rmdir:	db "RMDIR", 0
    68 000118B2 4D4B44495200        <1> Cmd_Mkdir:	db "MKDIR", 0
    69 000118B8 434F505900          <1> Cmd_Copy:	db "COPY", 0
    70 000118BD 4D4F564500          <1> Cmd_Move:	db "MOVE", 0
    71 000118C2 5041544800          <1> Cmd_Path:	db "PATH", 0
    72 000118C7 4D454D00            <1> Cmd_Mem:	db "MEM", 0
    73 000118CB 00                  <1> 		db 0
    74 000118CC 46494E4400          <1> Cmd_Find:	db "FIND", 0
    75 000118D1 4543484F00          <1> Cmd_Echo:	db "ECHO", 0
    76 000118D6 2A00                <1> Cmd_Remark:	db "*", 0
    77 000118D8 3F00                <1> Cmd_Help:	db "?", 0
    78 000118DA 44455649434500      <1> Cmd_Device:	db "DEVICE", 0
    79 000118E1 4445564C49535400    <1> Cmd_DevList:	db "DEVLIST", 0
    80 000118E9 434844495200        <1> Cmd_Chdir:	db "CHDIR", 0
    81 000118EF 4245455000          <1> Cmd_Beep:	db "BEEP", 0
    82                              <1> 		
    83 000118F4 00                  <1> 		db 0
    84                              <1> 
    85                              <1> ; 15/02/2016 (FILE.ASM, 09/10/2011)
    86                              <1> invalid_fname_chars:
    87 000118F5 222728292A2B2C2F    <1> 		db 22h, 27h, 28h, 29h, 2Ah, 2Bh, 2Ch, 2Fh
    88 000118FD 3A3B3C3D3E3F40      <1> 		db 3Ah, 3Bh, 3Ch, 3Dh, 3Eh, 3Fh, 40h
    89 00011904 5B5C5D5E60          <1> 		db 5Bh, 5Ch, 5Dh, 5Eh, 60h
    90                              <1> sizeInvFnChars  equ ($ - invalid_fname_chars)                
    91                              <1> ;
    92                              <1> 
    93                              <1> Msg_Enter_Date:
    94 00011909 456E746572206E6577- <1>                 db 'Enter new date (dd-mm-yy): '
    94 00011912 206461746520286464- <1>
    94 0001191B 2D6D6D2D7979293A20  <1>
    95 00011924 00                  <1>                 db 0
    96                              <1> Msg_Show_Date:
    97 00011925 43757272656E742064- <1>                 db   'Current date is '
    97 0001192E 61746520697320      <1>
    98 00011935 30                  <1> Day:            db   '0'
    99 00011936 30                  <1> 		db   '0'
   100 00011937 2F                  <1>                 db   '/'
   101 00011938 30                  <1> Month:          db   '0'
   102 00011939 30                  <1> 		db   '0'
   103 0001193A 2F                  <1>                 db   '/'
   104 0001193B 30                  <1> Century:        db   '0'
   105 0001193C 30                  <1>                 db   '0'
   106 0001193D 30                  <1> Year:           db   '0'
   107 0001193E 30                  <1> 		db   '0'
   108 0001193F 0D0A00              <1>                 db   0Dh, 0Ah, 0
   109                              <1> 
   110                              <1> Msg_Enter_Time:
   111 00011942 456E746572206E6577- <1> 		db 'Enter new time: '
   111 0001194B 2074696D653A20      <1>
   112 00011952 00                  <1> 		db 0
   113                              <1> Msg_Show_Time:
   114 00011953 43757272656E742074- <1> 		db   'Current time is '
   114 0001195C 696D6520697320      <1>
   115 00011963 30                  <1> Hour:           db   '0'
   116 00011964 30                  <1> 		db   '0'
   117 00011965 3A                  <1> 		db   ':'
   118 00011966 30                  <1> Minute:         db   '0'
   119 00011967 30                  <1> 		db   '0'
   120 00011968 3A                  <1> 		db   ':'
   121 00011969 30                  <1> Second:         db   '0'
   122 0001196A 30                  <1> 		db   '0'
   123 0001196B 0D0A00              <1> 		db   0Dh, 0Ah, 0
   124                              <1> 
   125                              <1> ;VolSize_Unit1:   dd 0
   126                              <1> ;VolSize_Unit2:   dd 0
   127                              <1> 
   128                              <1> VolSize_KiloBytes:
   129 0001196E 206B696C6F62797465- <1> 		db " kilobytes", 0Dh, 0Ah, 0
   129 00011977 730D0A00            <1>
   130                              <1> VolSize_Bytes:
   131 0001197B 2062797465730D0A00  <1> 		db " bytes", 0Dh, 0Ah, 0
   132                              <1> Volume_in_drive:
   133 00011984 0D0A                <1> 		db 0Dh, 0Ah
   134                              <1> Vol_FS_Name:
   135 00011986 54522046533120      <1> 		db "TR FS1 "
   136 0001198D 566F6C756D6520696E- <1> 		db "Volume in drive "
   136 00011996 20647269766520      <1>
   137 0001199D 30                  <1> Vol_Drv_Name:   db 30h
   138 0001199E 3A                  <1> 		db ":"
   139 0001199F 20697320            <1> 		db " is "
   140 000119A3 0D0A00              <1> 		db 0Dh, 0Ah, 0
   141                              <1> Dir_Drive_Str:
   142 000119A6 54522D444F53204472- <1>                 db "TR-DOS Drive "
   142 000119AF 69766520            <1>
   143                              <1> Dir_Drive_Name:
   144 000119B3 303A                <1>                 db "0:"
   145 000119B5 0D0A                <1>                 db  0Dh, 0Ah
   146                              <1> Vol_Str_Header:
   147 000119B7 566F6C756D65204E61- <1>                 db "Volume Name: "
   147 000119C0 6D653A20            <1>
   148                              <1> Vol_Name:
   149 000119C4 00<rept>            <1> 		times 64 db 0
   150 00011A04 00                  <1> 		db 0
   151                              <1> Vol_Serial_Header:
   152 00011A05 0D0A                <1> 		db 0Dh, 0Ah
   153 00011A07 566F6C756D65205365- <1> 		db "Volume Serial No: "
   153 00011A10 7269616C204E6F3A20  <1>
   154                              <1> Vol_Serial1:
   155 00011A19 30303030            <1> 		db "0000"
   156 00011A1D 2D                  <1> 		db "-"
   157                              <1> Vol_Serial2:
   158 00011A1E 30303030            <1> 		db "0000"
   159 00011A22 0D0A00              <1> 		db 0Dh, 0Ah, 0
   160                              <1> 
   161                              <1> ;Vol_Tot_Sec_Str_Start:
   162                              <1> ;		dd 0
   163                              <1> Vol_Total_Sector_Header:
   164 00011A25 0D0A                <1> 		db 0Dh, 0Ah
   165 00011A27 566F6C756D65205369- <1> 		db "Volume Size : ", 0
   165 00011A30 7A65203A2000        <1>
   166                              <1> ;Vol_Tot_Sec_Str: 
   167                              <1> ;		db "0000000000"
   168                              <1> ;Vol_Tot_Sec_Str_End:
   169                              <1> ;		db 0
   170                              <1> ;Vol_Free_Sectors_Str_Start:
   171                              <1> ;		dd 0
   172                              <1> Vol_Free_Sectors_Header:
   173 00011A36 467265652053706163- <1> 		db "Free Space  : ", 0
   173 00011A3F 6520203A2000        <1>
   174                              <1> ;Vol_Free_Sectors_Str:
   175                              <1> ;		db "0000000000"
   176                              <1> ;Vol_Free_Sectors_Str_End:
   177                              <1> ;		db 0
   178                              <1> 
   179                              <1> Dir_Str_Header:
   180 00011A45 4469726563746F7279- <1>                 db "Directory: "
   180 00011A4E 3A20                <1>
   181 00011A50 2F                  <1> Dir_Str_Root:   db "/"
   182 00011A51 00<rept>            <1> Dir_Str:        times 64 db 0
   183 00011A91 00000000            <1>                 dd 0
   184 00011A95 00                  <1>                 db 0
   185                              <1> 
   186                              <1> Msg_Bad_Command:
   187 00011A96 42616420636F6D6D61- <1>                 db "Bad command or file name!"
   187 00011A9F 6E64206F722066696C- <1>
   187 00011AA8 65206E616D6521      <1>
   188 00011AAF 0D0A00              <1>                 db 0Dh, 0Ah, 0
   189                              <1> 
   190                              <1> msgl_drv_not_ready: 
   191 00011AB2 070D0A              <1> 		db 07h, 0Dh, 0Ah
   192                              <1> 
   193                              <1> ; CMD_INTR.ASM - 09/11/2011 - Messages
   194                              <1> 
   195                              <1> Msg_Not_Ready_Read_Err:
   196 00011AB5 4472697665206E6F74- <1>                 db "Drive not ready or read error!"
   196 00011ABE 207265616479206F72- <1>
   196 00011AC7 207265616420657272- <1>
   196 00011AD0 6F7221              <1>
   197 00011AD3 0D0A00              <1>                 db 0Dh, 0Ah, 0
   198                              <1> 
   199                              <1> Msg_Not_Ready_Write_Err:
   200 00011AD6 4472697665206E6F74- <1>                 db "Drive not ready or write error!"
   200 00011ADF 207265616479206F72- <1>
   200 00011AE8 207772697465206572- <1>
   200 00011AF1 726F7221            <1>
   201 00011AF5 0D0A00              <1>                 db 0Dh, 0Ah, 0
   202                              <1> 
   203                              <1> Msg_Dir_Not_Found:
   204 00011AF8 4469726563746F7279- <1>                 db "Directory not found!"
   204 00011B01 206E6F7420666F756E- <1>
   204 00011B0A 6421                <1>
   205 00011B0C 0D0A00              <1>                 db 0Dh, 0Ah, 0
   206                              <1> 
   207                              <1> Msg_File_Not_Found:
   208 00011B0F 46696C65206E6F7420- <1>                 db "File not found!"
   208 00011B18 666F756E6421        <1>
   209 00011B1E 0D0A00              <1>                 db 0Dh, 0Ah, 0
   210                              <1> 
   211                              <1> Msg_File_Directory_Not_Found:
   212 00011B21 46696C65206F722064- <1>                 db "File or directory not found!"
   212 00011B2A 69726563746F727920- <1>
   212 00011B33 6E6F7420666F756E64- <1>
   212 00011B3C 21                  <1>
   213 00011B3D 0D0A00              <1>                 db 0Dh, 0Ah, 0
   214                              <1> 
   215                              <1> Msg_LongName_Not_Found:
   216 00011B40 4C6F6E67206E616D65- <1>                 db "Long name not found!"
   216 00011B49 206E6F7420666F756E- <1>
   216 00011B52 6421                <1>
   217 00011B54 0D0A00              <1>                 db 0Dh, 0Ah, 0
   218                              <1> 
   219                              <1> beep_Insufficient_Memory: ; 20/02/2017
   220 00011B57 0D0A                <1> 		db 0Dh, 0Ah
   221 00011B59 07                  <1> 		db 07h
   222                              <1> Msg_Insufficient_Memory:
   223 00011B5A 496E73756666696369- <1>                 db "Insufficient memory!"
   223 00011B63 656E74206D656D6F72- <1>
   223 00011B6C 7921                <1>
   224 00011B6E 0D0A00              <1>                 db 0Dh, 0Ah, 0
   225                              <1> 
   226                              <1> Msg_Error_Code:
   227 00011B71 436F6D6D616E642066- <1>                 db 'Command failed! Error code : '
   227 00011B7A 61696C656421204572- <1>
   227 00011B83 726F7220636F646520- <1>
   227 00011B8C 3A20                <1>
   228 00011B8E 303068              <1> error_code_hex: db '00h'
   229 00011B91 0A0A00              <1>                 db 0Ah, 0Ah, 0
   230                              <1> 
   231                              <1> align 2
   232                              <1> 
   233                              <1> ; 10/02/2016
   234                              <1> ; DIR.ASM - 09/10/2011
   235                              <1> 
   236 00011B94 3C4449523E20202020- <1> Type_Dir:       db '<DIR>     ' ; 10 bytes
   236 00011B9D 20                  <1>
   237                              <1> 
   238                              <1> File_Name:
   239 00011B9E 20<rept>            <1>                 times 12 db 20h
   240 00011BAA 20                  <1> 		db 20h
   241                              <1> Dir_Or_FileSize:
   242 00011BAB 20<rept>            <1>                 times 10 db 20h
   243 00011BB5 20                  <1> 		db 20h
   244                              <1> File_Attribute:
   245 00011BB6 20202020            <1> 		dd 20202020h
   246 00011BBA 20                  <1> 		db 20h
   247                              <1> File_Day:
   248 00011BBB 3030                <1>                 db '0','0'
   249 00011BBD 2F                  <1> 		db '/'
   250                              <1> File_Month:
   251 00011BBE 3030                <1>                 db '0','0'
   252 00011BC0 2F                  <1> 		db '/'
   253                              <1> File_Year:
   254 00011BC1 30303030            <1>                 db '0','0','0','0'
   255 00011BC5 20                  <1> 		db 20h
   256                              <1> File_Hour:
   257 00011BC6 3030                <1>                 db '0','0'
   258 00011BC8 3A                  <1> 		db ':'
   259                              <1> File_Minute:
   260 00011BC9 3030                <1>                 db '0','0'
   261 00011BCB 00                  <1> 		db 0
   262                              <1> 
   263                              <1> Decimal_File_Count_Header:
   264 00011BCC 0D0A                <1> 		db 0Dh, 0Ah
   265                              <1> Decimal_File_Count:
   266 00011BCE 00<rept>            <1> 		times 6 db 0
   267                              <1> 
   268 00011BD4 2066696C6528732920- <1> str_files:	db " file(s) & "
   268 00011BDD 2620                <1>
   269                              <1> Decimal_Dir_Count: 
   270 00011BDF 00<rept>            <1> 		times 6 db 0
   271                              <1> str_dirs:       
   272 00011BE5 206469726563746F72- <1> 		db " directory(s) "
   272 00011BEE 7928732920          <1>
   273 00011BF3 0D0A00              <1> 		db 0Dh, 0Ah, 0
   274                              <1> 
   275 00011BF6 206279746528732920- <1> str_bytes:	db " byte(s) in file(s)"
   275 00011BFF 696E2066696C652873- <1>
   275 00011C08 29                  <1>
   276 00011C09 0D0A00              <1> 		db 0Dh, 0Ah, 0
   277                              <1> 
   278                              <1> ; CMD_INTR.ASM - 09/11/2011
   279                              <1> ; 07/10/2010
   280                              <1> Msg_invalid_name_chars:
   281 00011C0C 496E76616C69642066- <1>                 db "Invalid file or directory name characters!"
   281 00011C15 696C65206F72206469- <1>
   281 00011C1E 726563746F7279206E- <1>
   281 00011C27 616D65206368617261- <1>
   281 00011C30 637465727321        <1>
   282 00011C36 0D0A00              <1>         	db 0Dh, 0Ah, 0
   283                              <1> ; 21/02/2016
   284 00011C39 46696C65206F722064- <1> Msg_Name_Exists: db "File or directory name exists!"
   284 00011C42 69726563746F727920- <1>
   284 00011C4B 6E616D652065786973- <1>
   284 00011C54 747321              <1>
   285 00011C57 0D0A00              <1>                 db 0Dh, 0Ah, 0
   286                              <1> Msg_DoYouWantMkdir:
   287 00011C5A 446F20796F75207761- <1>                 db "Do you want to make directory ", 0
   287 00011C63 6E7420746F206D616B- <1>
   287 00011C6C 65206469726563746F- <1>
   287 00011C75 72792000            <1>
   288 00011C79 2028592F4E29203F20- <1> Msg_YesNo:      db " (Y/N) ? ", 0  
   288 00011C82 00                  <1>
   289 00011C83 000D0A00            <1> Y_N_nextline:	db 0, 0Dh, 0Ah, 0 
   290 00011C87 4F4B2E0D0A00        <1> Msg_OK:		db "OK.", 0Dh, 0Ah, 0
   291                              <1> 
   292                              <1> ; 27/02/2016
   293                              <1> Msg_DoYouWantRmDir:
   294 00011C8D 446F20796F75207761- <1>                 db "Do you want to delete directory ", 0
   294 00011C96 6E7420746F2064656C- <1>
   294 00011C9F 657465206469726563- <1>
   294 00011CA8 746F72792000        <1>
   295                              <1> Msg_Dir_Not_Empty:
   296 00011CAE 4469726563746F7279- <1>                 db "Directory not empty!"
   296 00011CB7 206E6F7420656D7074- <1>
   296 00011CC0 7921                <1>
   297 00011CC2 0D0A00              <1>                 db 0Dh, 0Ah, 0
   298                              <1> 
   299                              <1> Msg_DoYouWantDelete:
   300 00011CC5 446F20796F75207761- <1>                 db "Do you want to delete file ",0
   300 00011CCE 6E7420746F2064656C- <1>
   300 00011CD7 6574652066696C6520- <1>
   300 00011CE0 00                  <1>
   301                              <1> 
   302 00011CE1 44656C657465642E2E- <1> Msg_Deleted:    db "Deleted...", 0Dh, 0Ah, 0
   302 00011CEA 2E0D0A00            <1>
   303                              <1> 
   304                              <1> Msg_Permission_Denied:
   305 00011CEE 07                  <1>                 db 7
   306 00011CEF 5065726D697373696F- <1>                 db "Permission denied!", 0Dh, 0Ah, 0
   306 00011CF8 6E2064656E69656421- <1>
   306 00011D01 0D0A00              <1>
   307                              <1> 
   308                              <1> ; 04/03/2016
   309 00011D04 4E657720            <1> Msg_New:        db "New "
   310 00011D08 00                  <1>                 db 0
   311                              <1> Str_Attributes:
   312 00011D09 417474726962757465- <1>                 db "Attributes : "
   312 00011D12 73203A20            <1>
   313 00011D16 4E4F524D414C        <1> Attr_Chars:     db "NORMAL"
   314 00011D1C 00                  <1>                 db 0
   315                              <1> 
   316                              <1> ; 06/03/2016
   317                              <1> ; CMD_INTR.ASM - 16/11/2010 
   318                              <1> Msg_DoYouWantRename:
   319 00011D1D 446F20796F75207761- <1>                 db "Do you want to rename ", 0
   319 00011D26 6E7420746F2072656E- <1>
   319 00011D2F 616D652000          <1>
   320 00011D34 66696C652000        <1> Rename_File:    db "file ", 0
   321 00011D3A 6469726563746F7279- <1> Rename_Directory: db "directory ", 0
   321 00011D43 2000                <1>
   322 00011D45 00<rept>            <1> Rename_OldName: times 13 db 0
   323 00011D52 20617320            <1> Msg_File_rename_as: db " as "
   324 00011D56 00<rept>            <1> Rename_NewName: times 13 db 0
   325                              <1> 
   326                              <1> ; 08/03/2016
   327                              <1> ; CMD_INTR.ASM - 01/08/2010 - 23/04/2011
   328                              <1> msg_not_same_drv:
   329 00011D63 4E6F742073616D6520- <1>                 db "Not same drive!" 
   329 00011D6C 647269766521        <1>
   330 00011D72 0D0A00              <1>                 db 0Dh, 0Ah, 0 
   331                              <1> 
   332                              <1> Msg_DoYouWantMoveFile:
   333 00011D75 446F20796F75207761- <1>                 db "Do you want to move file", 0
   333 00011D7E 6E7420746F206D6F76- <1>
   333 00011D87 652066696C6500      <1>
   334                              <1> 
   335                              <1> msg_insufficient_disk_space:
   336 00011D8E 496E73756666696369- <1>                 db "Insufficient disk space!" 
   336 00011D97 656E74206469736B20- <1>
   336 00011DA0 737061636521        <1>
   337 00011DA6 0D0A00              <1>                 db 0Dh, 0Ah, 0
   338                              <1> 
   339                              <1> ; 01/08/2010
   340                              <1> msg_source_file: 
   341 00011DA9 0D0A536F7572636520- <1> 		db 0Dh, 0Ah, "Source file name      :   "
   341 00011DB2 66696C65206E616D65- <1>
   341 00011DBB 2020202020203A2020- <1>
   341 00011DC4 20                  <1>
   342                              <1> msg_source_file_drv: 
   343 00011DC5 203A00              <1> 		db " :", 0
   344                              <1> msg_destination_file: 
   345 00011DC8 0D0A44657374696E61- <1> 		db 0Dh, 0Ah, "Destination file name :   "
   345 00011DD1 74696F6E2066696C65- <1>
   345 00011DDA 206E616D65203A2020- <1>
   345 00011DE3 20                  <1>
   346                              <1> msg_destination_file_drv: 
   347 00011DE4 203A00              <1> 		db " :", 0
   348                              <1> msg_copy_nextline: 
   349 00011DE7 0D0A00              <1> 		db 0Dh, 0Ah, 0
   350                              <1> 
   351                              <1> ; 15/03/2016
   352                              <1> ; CMD_INTR.ASM
   353                              <1> 
   354                              <1> Msg_DoYouWantOverWriteFile:
   355 00011DEA 446F20796F75207761- <1>                 db "Do you want to overwrite file ",0
   355 00011DF3 6E7420746F206F7665- <1>
   355 00011DFC 727772697465206669- <1>
   355 00011E05 6C652000            <1>
   356                              <1>   
   357                              <1> Msg_DoYouWantCopyFile:
   358 00011E09 446F20796F75207761- <1>                 db "Do you want to copy file",0
   358 00011E12 6E7420746F20636F70- <1>
   358 00011E1B 792066696C6500      <1>
   359                              <1> 
   360                              <1> Msg_read_file_error_before_EOF:
   361 00011E22 46696C652072656164- <1> 		db "File reading error! (before EOF)"
   361 00011E2B 696E67206572726F72- <1>
   361 00011E34 2120286265666F7265- <1>
   361 00011E3D 20454F4629          <1>
   362 00011E42 0A0A00              <1> 		db 0Ah, 0Ah, 0
   363                              <1> 
   364                              <1> ; 18/03/2016
   365                              <1> ; TRDOS 386 (v2.0) mainprog copy procedure
   366                              <1> msg_reading:
   367 00011E45 52656164696E672E2E- <1> 		db "Reading... ", 0
   367 00011E4E 2E2000              <1>
   368                              <1> msg_writing:
   369 00011E51 57726974696E672E2E- <1> 		db "Writing... ", 0
   369 00011E5A 2E2000              <1>
   370                              <1> percentagestr:
   371 00011E5D 2020202500          <1> 		db "   %", 0  ; "  0%" .. "100%"
   372                              <1> ; 11/04/2016
   373                              <1> Msg_No_Set_Space:
   374 00011E62 496E73756666696369- <1>                 db "Insufficient environment space!"
   374 00011E6B 656E7420656E766972- <1>
   374 00011E74 6F6E6D656E74207370- <1>
   374 00011E7D 61636521            <1>
   375 00011E81 0D0A00              <1>                 db 0Dh, 0Ah, 0
   376                              <1> ; 18/04/2016
   377                              <1> isc_msg:	
   378 00011E84 0D0A                <1> 		db 0Dh, 0Ah
   379 00011E86 494E56414C49442053- <1> 		db "INVALID SYSTEM CALL", 0
   379 00011E8F 595354454D2043414C- <1>
   379 00011E98 4C00                <1>
   380                              <1> usi_msg:
   381 00011E9A 0D0A                <1> 		db 0Dh, 0Ah
   382 00011E9C 554E444546494E4544- <1> 		db "UNDEFINED SOFTWARE INTERRUPT", 0
   382 00011EA5 20534F465457415245- <1>
   382 00011EAE 20494E544552525550- <1>
   382 00011EB7 5400                <1>
   383                              <1> ifc_msg:
   384 00011EB9 0D0A                <1> 		db 0Dh, 0Ah
   385 00011EBB 494E56414C49442046- <1> 		db "INVALID FUNCTION CALL"
   385 00011EC4 554E4354494F4E2043- <1>
   385 00011ECD 414C4C              <1>
   386                              <1> inv_msg_for_trdos_v2:
   387 00011ED0 20                  <1> 		db 20h
   388 00011ED1 666F72205452444F53- <1> 		db "for TRDOS v2!"
   388 00011EDA 20763221            <1>
   389 00011EDE 07                  <1> 		db 07h
   390 00011EDF 0D0A                <1> 		db 0Dh, 0Ah
   391 00011EE1 0D0A                <1> 		db 0Dh, 0Ah
   392 00011EE3 494E5420            <1> 		db "INT "
   393 00011EE7 303068              <1> int_num_str:	db "00h"
   394 00011EEA 0D0A                <1> 		db 0Dh, 0Ah
   395 00011EEC 454158203A20        <1> 		db "EAX : "
   396 00011EF2 303030303030303068- <1> eax_str:	db "00000000h", 0Dh, 0Ah
   396 00011EFB 0D0A                <1>
   397 00011EFD 454950203A20        <1> 		db "EIP : "
   398 00011F03 303030303030303068- <1> eip_str:	db "00000000h", 0Dh, 0Ah, 0
   398 00011F0C 0D0A00              <1>
   399                              <1> 
   400                              <1> ; 07/10/2016
   401                              <1> ; Device names & parameters (for kernel devices)
   402                              <1> 
   403 00011F0F 90                  <1> align 2
   404                              <1> KDEV_NAME:
   405 00011F10 5454590000000000    <1> 		db 'TTY',0,0,0,0,0 ; 1
   406 00011F18 4D454D0000000000    <1> 		db 'MEM',0,0,0,0,0 ; 2
   407 00011F20 4644300000000000    <1> 		db 'FD0',0,0,0,0,0 ; 3
   408 00011F28 4644310000000000    <1> 		db 'FD1',0,0,0,0,0 ; 4
   409 00011F30 4844300000000000    <1> 		db 'HD0',0,0,0,0,0 ; 5
   410 00011F38 4844310000000000    <1> 		db 'HD1',0,0,0,0,0 ; 6
   411 00011F40 4844320000000000    <1> 		db 'HD2',0,0,0,0,0 ; 7
   412 00011F48 4844330000000000    <1> 		db 'HD3',0,0,0,0,0 ; 8
   413 00011F50 4C50540000000000    <1> 		db 'LPT',0,0,0,0,0 ; 9
   414 00011F58 5454593000000000    <1> 		db 'TTY0',0,0,0,0 ; 10
   415 00011F60 5454593100000000    <1> 		db 'TTY1',0,0,0,0 ; 11
   416 00011F68 5454593200000000    <1> 		db 'TTY2',0,0,0,0 ; 12
   417 00011F70 5454593300000000    <1> 		db 'TTY3',0,0,0,0 ; 13
   418 00011F78 5454593400000000    <1> 		db 'TTY4',0,0,0,0 ; 14
   419 00011F80 5454593500000000    <1> 		db 'TTY5',0,0,0,0 ; 15
   420 00011F88 5454593600000000    <1> 		db 'TTY6',0,0,0,0 ; 16
   421 00011F90 5454593700000000    <1> 		db 'TTY7',0,0,0,0 ; 17
   422 00011F98 5454593800000000    <1> 		db 'TTY8',0,0,0,0 ; 18
   423 00011FA0 5454593900000000    <1> 		db 'TTY9',0,0,0,0 ; 19
   424 00011FA8 434F4D3100000000    <1> 		db 'COM1',0,0,0,0 ; 18
   425 00011FB0 434F4D3200000000    <1> 		db 'COM2',0,0,0,0 ; 19
   426                              <1> 		;db 'CONSOLE',0	  ; 1
   427                              <1> 		;db 'PRINTER',0   ; 9
   428                              <1> 		;db 'CDROM'	  ; 20
   429                              <1> 		;db 'CDROM0'	  ; 20
   430                              <1> 		;db 'CDROM1'	  ; 21		
   431                              <1> 		;db 'DVD'	  ; 22
   432                              <1> 		;db 'DVD0'	  ; 22
   433                              <1> 		;db 'DVD1'	  ; 23		
   434                              <1> 		;db 'USB'	  ; 24
   435                              <1> 		;db 'USB0'	  ; 24
   436                              <1> 		;db 'USB1'	  ; 25
   437                              <1> 		;db 'USB2'	  ; 26
   438                              <1> 		;db 'USB3'        ; 27
   439                              <1> 		;db 'KEYBOARD'	  ; 1	
   440                              <1> 		;db 'MOUSE'	  ; 28
   441                              <1> 		;db 'SOUND'	  ; 29
   442                              <1> 		;db 'VGA',0,0,0,0 ; 30
   443                              <1> 		;db 'CGA',0,0,0,0 ; 31
   444                              <1> 		;db 'AUDIO',0,0,0 ; 29
   445                              <1> 		;db 'VIDEO',0,0,0 ; 32
   446                              <1> 		;db 'MUSIC',0,0,0 ; 33
   447                              <1> 		;db 'ETHERNET'	  ; 34 		
   448                              <1> 		;db 'SD0',0,0,0,0,0 ; 35
   449                              <1> 		;db 'SD1',0,0,0,0,0 ; 36
   450                              <1> 		;db 'SD2',0,0,0,0,0 ; 37
   451                              <1> 		;db 'SD3',0,0,0,0,0 ; 38
   452                              <1> 		;db 'SATA0'	  ; 35
   453                              <1> 		;db 'SATA1'	  ; 36
   454                              <1> 		;db 'SATA2'        ; 37
   455                              <1> 		;db 'SATA3'        ; 38
   456                              <1> 		;db 'PATA0',0,0,0  ; 5
   457                              <1> 		;db 'PATA1',0,0,0  ; 6
   458                              <1> 		;db 'PATA2',0,0,0  ; 7
   459                              <1> 		;db 'PATA3',0,0,0  ; 8
   460                              <1> 		;db 'WIRELESS'	  ; 39
   461                              <1> 		;db 'HDMI',0,0,0,0 ; 40
   462 00011FB8 4E554C4C00000000    <1> 		db 'NULL',0,0,0,0 ; 0
   463                              <1> 
   464                              <1> NumOfKernelDevNames equ ($-KDEV_NAME) / 8 ; 20 (07/10/2016)
   465                              <1> 
   466                              <1> KDEV_NUMBER:
   467 00011FC0 010203040506070809  <1> 		db 1,2,3,4,5,6,7,8,9
   468 00011FC9 0A0B0C0D0E0F101112- <1> 		db 10,11,12,13,14,15,16,17,18,19
   468 00011FD2 13                  <1>
   469 00011FD3 121300              <1> 		db 18,19,0
   470                              <1> 
   471                              <1> NumOfKernelDevices equ $ - KDEV_NUMBER
   472                              <1> 
   473                              <1> KDEV_OADDR:
   474 00011FD6 [F4170100]          <1> 		dd otty ;tty  ; 1
   475 00011FDA [F4170100]          <1> 		dd sret ;mem  ; 2
   476 00011FDE [F4170100]          <1>  		dd sret ;fd0  ; 3
   477 00011FE2 [F4170100]          <1>  		dd sret ;fd1  ; 4
   478 00011FE6 [F4170100]          <1>  		dd sret ;hd0  ; 5
   479 00011FEA [F4170100]          <1>  		dd sret ;hd1  ; 6
   480 00011FEE [F4170100]          <1>  		dd sret ;hd2  ; 7
   481 00011FF2 [F4170100]          <1>  		dd sret ;hd3  ; 8
   482 00011FF6 [F4170100]          <1>  		dd sret ;lpt  ; 9
   483 00011FFA [F4170100]          <1>  		dd ocvt ;tty0 ; 10
   484 00011FFE [F4170100]          <1> 		dd ocvt ;tty1 ; 11
   485 00012002 [F4170100]          <1>  		dd ocvt ;tty2 ; 12
   486 00012006 [F4170100]          <1>  		dd ocvt ;tty3 ; 13
   487 0001200A [F4170100]          <1>  		dd ocvt ;tty4 ; 14
   488 0001200E [F4170100]          <1>  		dd ocvt ;tty5 ; 15
   489 00012012 [F4170100]          <1>  		dd ocvt ;tty6 ; 16
   490 00012016 [F4170100]          <1>  		dd ocvt ;tty7 ; 17
   491 0001201A [F4170100]          <1>  		dd ocvt ;tty8 ; 18
   492 0001201E [F4170100]          <1>  		dd ocvt ;tty9 ; 19
   493                              <1>  		;dd ocvt ;com1 ; 18
   494                              <1>  		;dd ocvt ;com2 ; 19
   495 00012022 [F4170100]          <1> 		dd sret ;null ; 20  
   496                              <1> KDEV_CADDR:
   497 00012026 [F4170100]          <1> 		dd ctty ;tty  ; 1
   498 0001202A [F4170100]          <1> 		dd cret ;mem  ; 2
   499 0001202E [F4170100]          <1>  		dd cret ;fd0  ; 3
   500 00012032 [F4170100]          <1>  		dd cret ;fd1  ; 4
   501 00012036 [F4170100]          <1>  		dd cret ;hd0  ; 5
   502 0001203A [F4170100]          <1>  		dd cret ;hd1  ; 6
   503 0001203E [F4170100]          <1>  		dd cret ;hd2  ; 7
   504 00012042 [F4170100]          <1>  		dd cret ;hd3  ; 8
   505 00012046 [F4170100]          <1>  		dd cret ;lpt  ; 9
   506 0001204A [F4170100]          <1>  		dd ocvt ;tty0 ; 10
   507 0001204E [F4170100]          <1> 		dd ccvt ;tty1 ; 11
   508 00012052 [F4170100]          <1>  		dd ccvt ;tty2 ; 12
   509 00012056 [F4170100]          <1>  		dd ccvt ;tty3 ; 13
   510 0001205A [F4170100]          <1>  		dd ccvt ;tty4 ; 14
   511 0001205E [F4170100]          <1>  		dd ccvt ;tty5 ; 15
   512 00012062 [F4170100]          <1>  		dd ccvt ;tty6 ; 16
   513 00012066 [F4170100]          <1>  		dd ccvt ;tty7 ; 17
   514 0001206A [F4170100]          <1>  		dd ccvt ;tty8 ; 18
   515 0001206E [F4170100]          <1>  		dd ccvt ;tty9 ; 19
   516                              <1>  		;dd ccvt ;com1 ; 18
   517                              <1>  		;dd ccvt ;com2 ; 19
   518 00012072 [F4170100]          <1> 		dd cret ;null ; 20
   519                              <1> 
   520                              <1> KDEV_RADDR:
   521 00012076 [F4170100]          <1> 		dd rtty ;tty  ; 1
   522 0001207A [F4170100]          <1> 		dd rmem ;mem  ; 2
   523 0001207E [F4170100]          <1>  		dd rfd  ;fd0  ; 3
   524 00012082 [F4170100]          <1>  		dd rfd  ;fd1  ; 4
   525 00012086 [F4170100]          <1>  		dd rhd  ;hd0  ; 5
   526 0001208A [F4170100]          <1>  		dd rhd  ;hd1  ; 6
   527 0001208E [F4170100]          <1>  		dd rhd  ;hd2  ; 7
   528 00012092 [F4170100]          <1>  		dd rhd  ;hd3  ; 8
   529 00012096 [F4170100]          <1>  		dd rlpt ;lpt  ; 9
   530 0001209A [F4170100]          <1>  		dd rcvt ;tty0 ; 10
   531 0001209E [F4170100]          <1> 		dd rcvt ;tty1 ; 11
   532 000120A2 [F4170100]          <1>  		dd rcvt ;tty2 ; 12
   533 000120A6 [F4170100]          <1>  		dd rcvt ;tty3 ; 13
   534 000120AA [F4170100]          <1>  		dd rcvt ;tty4 ; 14
   535 000120AE [F4170100]          <1>  		dd rcvt ;tty5 ; 15
   536 000120B2 [F4170100]          <1>  		dd rcvt ;tty6 ; 16
   537 000120B6 [F4170100]          <1>  		dd rcvt ;tty7 ; 17
   538 000120BA [F4170100]          <1>  		dd rcvt ;tty8 ; 18
   539 000120BE [F4170100]          <1>  		dd rcvt ;tty9 ; 19
   540                              <1>  		;dd rcvt ;com1 ; 18
   541                              <1>  		;dd rcvt ;com2 ; 19
   542 000120C2 [D80B0100]          <1> 		dd rnull ;null ; 20  
   543                              <1> KDEV_WADDR:
   544 000120C6 [F4170100]          <1> 		dd wtty ;tty  ; 1
   545 000120CA [F4170100]          <1> 		dd wmem ;mem  ; 2
   546 000120CE [F4170100]          <1>  		dd wfd  ;fd0  ; 3
   547 000120D2 [F4170100]          <1>  		dd wfd  ;fd1  ; 4
   548 000120D6 [F4170100]          <1>  		dd whd  ;hd0  ; 5
   549 000120DA [F4170100]          <1>  		dd whd  ;hd1  ; 6
   550 000120DE [F4170100]          <1>  		dd whd  ;hd2  ; 7
   551 000120E2 [F4170100]          <1>  		dd whd  ;hd3  ; 8
   552 000120E6 [F4170100]          <1>  		dd wlpt ;lpt  ; 9
   553 000120EA [F4170100]          <1>  		dd xmtt ;tty0 ; 10
   554 000120EE [F4170100]          <1> 		dd xmtt ;tty1 ; 11
   555 000120F2 [F4170100]          <1>  		dd xmtt ;tty2 ; 12
   556 000120F6 [F4170100]          <1>  		dd xmtt ;tty3 ; 13
   557 000120FA [F4170100]          <1>  		dd xmtt ;tty4 ; 14
   558 000120FE [F4170100]          <1>  		dd xmtt ;tty5 ; 15
   559 00012102 [F4170100]          <1>  		dd xmtt ;tty6 ; 16
   560 00012106 [F4170100]          <1>  		dd xmtt ;tty7 ; 17
   561 0001210A [F4170100]          <1>  		dd xmtt ;tty8 ; 18
   562 0001210E [F4170100]          <1>  		dd xmtt ;tty9 ; 19
   563                              <1>  		;dd xmtt ;com1 ; 18
   564                              <1>  		;dd xmtt ;com2 ; 19
   565 00012112 [D90B0100]          <1> 		dd wnull ;null ; 20  
   566                              <1> 
   567                              <1> ; DEV_ACCESS bits:
   568                              <1> 	; bit 0 = accessable by normal users
   569                              <1> 	; bit 1 = read access permission
   570                              <1> 	; bit 2 = write access permission
   571                              <1> 	; bit 3 = IOCTL permission to users
   572                              <1> 	; bit 4 = block device if it is set
   573                              <1> 	; bit 5 = 16 bit or 1024 byte data
   574                              <1> 	; bit 6 = 32 bit or 2048 byte data
   575                              <1> 	; bit 7 = installable device driver	
   576                              <1> 
   577                              <1> KDEV_ACCESS: ; 08/10/2016
   578 00012116 07                  <1> 		db  00000111b	; tty, 1
   579 00012117 07                  <1> 		db  00000111b	; mem, 2	
   580 00012118 8F                  <1> 		db  10001111b	; fd0, 3	
   581 00012119 8F                  <1> 		db  10001111b	; fd1, 4
   582 0001211A 8F                  <1> 		db  10001111b	; hd0, 5
   583 0001211B 8F                  <1> 		db  10001111b	; hd1, 6
   584 0001211C 8F                  <1> 		db  10001111b	; hd2, 7
   585 0001211D 8F                  <1> 		db  10001111b	; hd3, 8
   586 0001211E 07                  <1> 		db  00000111b   ; lpt, 9
   587 0001211F 07                  <1> 		db  00000111b	; tty0, 10
   588 00012120 07                  <1> 		db  00000111b	; tty1, 11
   589 00012121 07                  <1> 		db  00000111b	; tty2, 12
   590 00012122 07                  <1> 		db  00000111b	; tty3, 13
   591 00012123 07                  <1> 		db  00000111b	; tty4, 14
   592 00012124 07                  <1> 		db  00000111b	; tty5, 15
   593 00012125 07                  <1> 		db  00000111b	; tty6, 16
   594 00012126 07                  <1> 		db  00000111b	; tty7, 17
   595 00012127 07                  <1> 		db  00000111b	; tty8, 18
   596 00012128 07                  <1> 		db  00000111b	; tty9, 19
   597                              <1> 		;db 00000111b	; com1, 18
   598                              <1> 		;db 00000111b	; com2, 19
   599 00012129 00                  <1> 		db  00000000b   ; null, 0
   600                              <1> 
   601                              <1> ; 07/10/2016
   602                              <1> NumOfInstallableDevices equ 8
   603                              <1> NUMIDEV		equ NumOfInstallableDevices ; 8
   604                              <1> NUMOFDEVICES	equ NumOfKernelDevices + NumOfInstallableDevices
   605                              <1> 
   606                              <1> ; 26/02/2017
   607                              <1> ; IRQ Callback (& Signal Response Byte) service availibity
   608                              <1> ; 'syscalbac'
   609                              <1> ; ***************************************************
   610                              <1> ; IRQ 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
   611                              <1> ; --- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   612                              <1> ; --- 00 00 00 01 02 03 00 04 00 05 06 07 08 09 00 00
   613                              <1> ; ***************************************************
   614                              <1> IRQenum:
   615 0001212A 000000010203000400- <1> 	db  0,0,0,1,2,3,0,4,0,5,6,7,8,9,0,0
   615 00012133 05060708090000      <1>
   616                              <1> 
   617                              <1> ; 28/08/2017
   618                              <1> ; 20/08/2017
   619                              <1> ; DMA Registers (for 'sysdma')
   620                              <1> ; 02/07/2017 (sb16mod.s)
   621 0001213A 00020406C0C4C8CC    <1> dma_adr:	db 0,2,4,6,0C0h,0C4h,0C8h,0CCh
   622 00012142 01030507C2C6CACE    <1> dma_cnt:	db 1,3,5,7,0C2h,0C6h,0CAh,0CEh
   623 0001214A 878381828F8B898A    <1> dma_page:	db 87h,83h,81h,82h,8Fh,8Bh,89h,8Ah ; 03/08/2017
   624 00012152 0A0A0A0AD4D4D4D4    <1> dma_mask:	db 0Ah,0Ah,0Ah,0Ah,0D4h,0D4h,0D4h,0D4h
   625 0001215A 0B0B0B0BD6D6D6D6    <1> dma_mod:	db 0Bh,0Bh,0Bh,0Bh,0D6h,0D6h,0D6h,0D6h
   626 00012162 0C0C0C0CD8D8D8D8    <1> dma_flip:	db 0Ch,0Ch,0Ch,0Ch,0D8h,0D8h,0D8h,0D8h	
  3039                                  
  3040                                  ; 27/08/2014
  3041                                  scr_row:
  3042 0001216A E0810B00                	dd 0B8000h + 0A0h + 0A0h + 0A0h ; Row 3
  3043                                  scr_col:
  3044 0001216E 00000000                	dd 0
  3045                                  
  3046 00012172 90<rept>                Align 4
  3047                                  	; 15/04/2016
  3048                                  	; TRDOS 386 (TRDOS v2.0)
  3049                                  
  3050                                  	; 21/08/2014
  3051                                  ilist:
  3052                                  	;times 	32 dd cpu_except ; INT 0 to INT 1Fh
  3053                                  	;
  3054                                  	; Exception list
  3055                                  	; 25/08/2014	
  3056 00012174 [D20B0000]              	dd	exc0	; 0h,  Divide-by-zero Error
  3057 00012178 [D90B0000]              	dd	exc1	
  3058 0001217C [E00B0000]              	dd 	exc2	
  3059 00012180 [E70B0000]              	dd	exc3	
  3060 00012184 [EB0B0000]              	dd	exc4	
  3061 00012188 [EF0B0000]              	dd	exc5	
  3062 0001218C [F30B0000]              	dd 	exc6	; 06h,  Invalid Opcode
  3063 00012190 [F70B0000]              	dd	exc7	
  3064 00012194 [FB0B0000]              	dd	exc8	
  3065 00012198 [FF0B0000]              	dd	exc9	
  3066 0001219C [030C0000]              	dd 	exc10	
  3067 000121A0 [070C0000]              	dd	exc11
  3068 000121A4 [0B0C0000]              	dd	exc12
  3069 000121A8 [0F0C0000]              	dd	exc13	; 0Dh, General Protection Fault
  3070 000121AC [130C0000]              	dd 	exc14	; 0Eh, Page Fault
  3071 000121B0 [170C0000]              	dd	exc15
  3072 000121B4 [1B0C0000]              	dd	exc16
  3073 000121B8 [1F0C0000]              	dd	exc17
  3074 000121BC [230C0000]              	dd 	exc18
  3075 000121C0 [270C0000]              	dd	exc19
  3076 000121C4 [2B0C0000]              	dd 	exc20
  3077 000121C8 [2F0C0000]              	dd	exc21
  3078 000121CC [330C0000]              	dd	exc22
  3079 000121D0 [370C0000]              	dd	exc23
  3080 000121D4 [3B0C0000]              	dd 	exc24
  3081 000121D8 [3F0C0000]              	dd	exc25
  3082 000121DC [430C0000]              	dd	exc26
  3083 000121E0 [470C0000]              	dd	exc27
  3084 000121E4 [4B0C0000]              	dd 	exc28
  3085 000121E8 [4F0C0000]              	dd	exc29
  3086 000121EC [530C0000]              	dd 	exc30
  3087 000121F0 [570C0000]              	dd	exc31
  3088                                  IRQ_list: ; 28/02/2017 ('syscalbac')
  3089                                  	; Interrupt list
  3090 000121F4 [46090000]              	dd	timer_int	; INT 20h
  3091                                  		;dd	irq0	
  3092 000121F8 [BE100000]              	dd	kb_int		; 24/01/2016
  3093                                  		;dd	irq1
  3094 000121FC [280B0000]              	dd	irq2
  3095                                  		; COM2 int
  3096 00012200 [2C0B0000]              	dd	irq3
  3097                                  		; COM1 int
  3098 00012204 [370B0000]              	dd	irq4
  3099 00012208 [420B0000]              	dd	irq5
  3100                                  ;DISKETTE_INT: ;06/02/2015
  3101 0001220C [A44B0000]              	dd	fdc_int		; 16/02/2015, IRQ 6 handler	
  3102                                  		;dd	irq6
  3103                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  3104                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  3105 00012210 [B10E0000]              	dd	default_irq7	; 25/02/2015
  3106                                  		;dd	irq7
  3107                                  ; Real Time Clock Interrupt
  3108 00012214 [B10A0000]              	dd	rtc_int		; 23/02/2015, IRQ 8 handler
  3109                                  		;dd	irq8	; INT 28h
  3110 00012218 [520B0000]              	dd	irq9
  3111 0001221C [560B0000]              	dd	irq10
  3112 00012220 [5A0B0000]              	dd	irq11
  3113 00012224 [5E0B0000]              	dd	irq12
  3114 00012228 [620B0000]              	dd	irq13
  3115                                  ;HDISK_INT1:  ;06/02/2015 	
  3116 0001222C [58550000]              	dd	hdc1_int 	; 21/02/2015, IRQ 14 handler		
  3117                                  		;dd	irq14
  3118                                  ;HDISK_INT2:  ;06/02/2015
  3119 00012230 [7F550000]              	dd	hdc2_int 	; 21/02/2015, IRQ 15 handler		
  3120                                  		;dd	irq15	; INT 2Fh
  3121                                  		; 14/08/2015
  3122                                  	;dd	sysent		; INT 30h (system calls)
  3123                                  
  3124                                  	; 15/04/2016
  3125                                  	; TRDOS 386(TRDOS v2.0) Software Interrupts
  3126                                  
  3127 00012234 [91220100]              	dd	int30h		; Reserved for
  3128                                  				; !!! Retro UNIX (RUNIX) !!!
  3129                                  				; !!! SINGLIX !!! System Calls
  3130 00012238 [B1170000]              	dd	int31h		; Video BIOS (IBM PC/AT, Int 10h)
  3131 0001223C [DD0E0000]              	dd	int32h		; Keyboard Functions (IBM PC/AT, Int 16h)
  3132 00012240 [5C4C0000]              	dd	int33h		; DISK I/O (IBM PC/AT, Int 13h)
  3133 00012244 [8B040100]              	dd	int34h		; #IOCTL# (I/O port access support for ring 3)
  3134 00012248 [10640000]              	dd	int35h		; Time/Date Functions (IBM PC/AT, Int 1Ah)
  3135 0001224C [650D0000]              	dd	ignore_int	; INT 36h : Timer Functions	
  3136 00012250 [650D0000]              	dd	ignore_int	; INT 37h	
  3137 00012254 [650D0000]              	dd	ignore_int	; INT 38h
  3138 00012258 [650D0000]              	dd	ignore_int	; INT 39h
  3139 0001225C [650D0000]              	dd	ignore_int	; INT 3Ah	
  3140 00012260 [650D0000]              	dd	ignore_int	; INT 3Bh
  3141 00012264 [650D0000]              	dd	ignore_int	; INT 3Ch
  3142 00012268 [650D0000]              	dd	ignore_int	; INT 3Dh	
  3143 0001226C [650D0000]              	dd	ignore_int	; INT 3Eh
  3144 00012270 [650D0000]              	dd	ignore_int	; INT 3Fh
  3145 00012274 [7AD10000]              	dd	sysent		; INT 40h : !!! TRDOS 386 System Calls !!!
  3146                                  	;dd	ignore_int
  3147 00012278 00000000                	dd	0
  3148                                  
  3149                                  ; 20/08/2014
  3150                                    ; /* This is the default interrupt "handler" :-) */ 
  3151                                    ; Linux v0.12 (head.s)
  3152                                  int_msg:
  3153 0001227C 556E6B6E6F776E2069-     	db "Unknown interrupt ! ", 0
  3153 00012285 6E7465727275707420-
  3153 0001228E 212000             
  3154                                  
  3155                                  ; 15/04/2016
  3156                                  ; TRDOS 386 (TRDOS v2.0)
  3157                                  
  3158                                  ; 29/04/2016
  3159                                  int30h:
  3160                                  trdos_isc_routine:
  3161                                  	; 02/05/2016
  3162                                  	; 01/05/2016
  3163                                  	; 29/04/2016
  3164                                  	; 18/04/2016
  3165                                  	; 15/04/2016 (TRDOS 386 = TRDOS v2.0)
  3166                                  	; 17/04/2011 (TRDOS v1.0, 'IFC.ASM')
  3167                                  	; 03/02/2011 ('trdos_ifc_routine')
  3168                                  	;
  3169 00012291 8B1C24                  	mov	ebx, [esp] ; EIP (next)
  3170 00012294 83EB02                  	sub	ebx, 2 ; EIP (CD ##h)
  3171                                  
  3172 00012297 89C1                    	mov	ecx, eax
  3173 00012299 8A4301                  	mov	al, [ebx+1] ; CDh ##h
  3174                                  
  3175 0001229C 66BA1000                	mov	dx, KDATA
  3176 000122A0 8EDA                    	mov	ds, dx
  3177 000122A2 8EC2                    	mov	es, dx
  3178                                  
  3179 000122A4 FC                      	cld
  3180 000122A5 8B15[D8630100]          	mov	edx, [k_page_dir]
  3181 000122AB 0F22DA                  	mov	cr3, edx
  3182                                  
  3183 000122AE E8EC19FFFF              	call	bytetohex
  3184 000122B3 66A3[E71E0100]          	mov	[int_num_str], ax
  3185                                  
  3186 000122B9 89D8                    	mov	eax, ebx ; EIP
  3187 000122BB E81F1AFFFF              	call	dwordtohex
  3188 000122C0 8915[031F0100]          	mov	[eip_str], edx
  3189 000122C6 A3[071F0100]            	mov	[eip_str+4], eax
  3190                                  
  3191 000122CB 89C8                    	mov	eax, ecx
  3192 000122CD E80D1AFFFF              	call	dwordtohex
  3193 000122D2 8915[F21E0100]          	mov	[eax_str], edx
  3194 000122D8 A3[F61E0100]            	mov	[eax_str+4], eax 	
  3195                                  
  3196 000122DD 43                      	inc	ebx
  3197 000122DE 8A03                    	mov	al, [ebx] ; Interrupt number
  3198                                  
  3199                                  trdos_isc_handler:
  3200 000122E0 80FE30                  	cmp	dh, 30h ; Retro UNIX, SINGLIX System calls
  3201 000122E3 7507                    	jne	short trdos_usi_handler
  3202 000122E5 BE[841E0100]            	mov	esi, isc_msg
  3203 000122EA EB05                    	jmp	short loc_write_inv_system_call_msg
  3204                                  
  3205                                  trdos_usi_handler:
  3206 000122EC BE[9A1E0100]            	mov	esi, usi_msg
  3207                                  
  3208                                  loc_write_inv_system_call_msg:
  3209 000122F1 E82F4CFFFF              	call	print_msg
  3210                                  	; 29/04/2016
  3211 000122F6 BE[D01E0100]            	mov	esi, inv_msg_for_trdos_v2
  3212 000122FB E8254CFFFF              	call	print_msg
  3213                                  
  3214                                  loc_ifc_terminate_process:
  3215                                  	; u.uno = process number
  3216                                  	; 29/04/2016
  3217                                  
  3218                                  	; 02/05/2016
  3219 00012300 FE05[5B030300]          	inc	byte [sysflg] ; 0FFh -> 0
  3220                                  
  3221 00012306 B801000000              	mov	eax, 1
  3222 0001230B E943B1FFFF              	jmp	sysexit
  3223                                  
  3224                                  ; 07/03/2015
  3225                                  ; Temporary Code
  3226                                  display_disks:
  3227 00012310 803D[CE670000]00        	cmp 	byte [fd0_type], 0
  3228 00012317 7605                    	jna 	short ddsks1
  3229 00012319 E87D000000              	call	pdskm
  3230                                  ddsks1:
  3231 0001231E 803D[CF670000]00        	cmp	byte [fd1_type], 0
  3232 00012325 760C                    	jna	short ddsks2
  3233 00012327 C605[6B240100]31        	mov	byte [dskx], '1'
  3234 0001232E E868000000              	call	pdskm
  3235                                  ddsks2:
  3236 00012333 803D[D0670000]00        	cmp	byte [hd0_type], 0
  3237 0001233A 7654                    	jna	short ddsk6
  3238 0001233C 66C705[69240100]68-     	mov	word [dsktype], 'hd'
  3238 00012344 64                 
  3239 00012345 C605[6B240100]30        	mov	byte [dskx], '0'
  3240 0001234C E84A000000              	call	pdskm
  3241                                  ddsks3:
  3242 00012351 803D[D1670000]00        	cmp	byte [hd1_type], 0
  3243 00012358 7636                    	jna	short ddsk6
  3244 0001235A C605[6B240100]31        	mov	byte [dskx], '1'
  3245 00012361 E835000000              	call	pdskm
  3246                                  ddsks4:
  3247 00012366 803D[D2670000]00        	cmp	byte [hd2_type], 0
  3248 0001236D 7621                    	jna	short ddsk6
  3249 0001236F C605[6B240100]32        	mov	byte [dskx], '2'
  3250 00012376 E820000000              	call	pdskm
  3251                                  ddsks5:
  3252 0001237B 803D[D3670000]00        	cmp	byte [hd3_type], 0
  3253 00012382 760C                    	jna	short ddsk6
  3254 00012384 C605[6B240100]33        	mov	byte [dskx], '3'
  3255 0001238B E80B000000              	call	pdskm
  3256                                  ddsk6:
  3257 00012390 BE[93240100]            	mov	esi, nextline
  3258 00012395 E806000000              	call	pdskml
  3259                                  pdskm_ok:
  3260 0001239A C3                      	retn
  3261                                  pdskm:
  3262 0001239B BE[67240100]            	mov	esi, dsk_ready_msg
  3263                                  pdskml:	
  3264 000123A0 AC                      	lodsb
  3265 000123A1 08C0                    	or	al, al
  3266 000123A3 74F5                    	jz	short pdskm_ok
  3267 000123A5 56                      	push	esi
  3268                                  	; 13/05/2016
  3269 000123A6 BB07000000                      mov     ebx, 7  ; Black background, 
  3270                                  			; light gray forecolor
  3271                                  			; Video page 0 (bh=0)
  3272 000123AB E84DFEFEFF              	call	_write_tty
  3273 000123B0 5E                      	pop	esi
  3274 000123B1 EBED                    	jmp	short pdskml
  3275                                  
  3276 000123B3 90                      Align 2
  3277                                  	; 21/08/2014
  3278                                  exc_msg:
  3279 000123B4 435055206578636570-     	db "CPU exception ! "
  3279 000123BD 74696F6E202120     
  3280                                  excnstr: 		; 25/08/2014
  3281 000123C4 3F3F68202045495020-     	db "??h", "  EIP : "
  3281 000123CD 3A20               
  3282                                  EIPstr: ; 29/08/2014
  3283 000123CF 00<rept>                	times 12 db 0
  3284                                  
  3285                                  	; 23/02/2015
  3286                                  	; 25/08/2014
  3287                                  ;scounter:
  3288                                  ;	db 5
  3289                                  ;	db 19
  3290                                  
  3291                                  ; 06/11/2014
  3292                                  ; Memory Information message
  3293                                  ; 14/08/2015
  3294                                  msg_memory_info:
  3295 000123DB 07                      	db	07h
  3296 000123DC 0D0A                    	db	0Dh, 0Ah
  3297                                  	;db 	"MEMORY ALLOCATION INFO", 0Dh, 0Ah, 0Dh, 0Ah
  3298 000123DE 546F74616C206D656D-     	db	"Total memory : "
  3298 000123E7 6F7279203A20       
  3299                                  mem_total_b_str: ; 10 digits
  3300 000123ED 303030303030303030-     	db	"0000000000 bytes", 0Dh, 0Ah
  3300 000123F6 302062797465730D0A 
  3301 000123FF 202020202020202020-     	db	"               ", 20h, 20h, 20h
  3301 00012408 202020202020202020 
  3302                                  mem_total_p_str: ; 7 digits
  3303 00012411 303030303030302070-     	db	"0000000 pages", 0Dh, 0Ah
  3303 0001241A 616765730D0A       
  3304 00012420 0D0A                    	db 	0Dh, 0Ah
  3305 00012422 46726565206D656D6F-     	db	"Free memory  : "
  3305 0001242B 727920203A20       
  3306                                  free_mem_b_str:  ; 10 digits
  3307 00012431 3F3F3F3F3F3F3F3F3F-     	db	"?????????? bytes", 0Dh, 0Ah
  3307 0001243A 3F2062797465730D0A 
  3308 00012443 202020202020202020-     	db	"               ", 20h, 20h, 20h
  3308 0001244C 202020202020202020 
  3309                                  free_mem_p_str:  ; 7 digits
  3310 00012455 3F3F3F3F3F3F3F2070-     	db	"??????? pages", 0Dh, 0Ah
  3310 0001245E 616765730D0A       
  3311 00012464 0D0A00                  	db	0Dh, 0Ah, 0
  3312                                  
  3313                                  dsk_ready_msg:
  3314 00012467 0D0A                    	db 	0Dh, 0Ah
  3315                                  dsktype:
  3316 00012469 6664                    	db	'fd'
  3317                                  dskx:
  3318 0001246B 30                      	db	'0'
  3319 0001246C 20                      	db	20h
  3320 0001246D 697320524541445920-     	db 	'is READY ...'
  3320 00012476 2E2E2E             
  3321 00012479 00                      	db 	0
  3322                                  
  3323                                  setup_error_msg:
  3324 0001247A 0D0A                    	db 0Dh, 0Ah
  3325 0001247C 4469736B2053657475-     	db 'Disk Setup Error !' 
  3325 00012485 70204572726F722021 
  3326 0001248E 0D0A00                  	db 0Dh, 0Ah,0
  3327                                  
  3328                                  next2line: ; 08/02/2016
  3329 00012491 0D0A                    	db	0Dh, 0Ah
  3330                                  nextline:
  3331 00012493 0D0A00                  	db 	0Dh, 0Ah, 0
  3332                                  
  3333                                  ; temporary
  3334                                  ; 19/12/2020
  3335                                  msg_lfb_addr:
  3336                                  	;db	0Dh, 0Ah
  3337 00012496 4C696E656172206672-     	db	"Linear frame buffer at "
  3337 0001249F 616D65206275666665-
  3337 000124A8 7220617420         
  3338                                  lfb_addr_str: ; 8 (hex) digits
  3339 000124AD 303030303030303068-     	db	"00000000h", 0Dh, 0Ah
  3339 000124B6 0D0A               
  3340 000124B8 0D0A00                  	db	0Dh, 0Ah, 0
  3341                                  
  3342                                  ; KERNEL - SYSINIT Messages
  3343                                  ; 24/08/2015
  3344                                  ; 13/04/2015 - (Retro UNIX 386 v1 Beginning)
  3345                                  ; 14/07/2013
  3346                                  ;kernel_init_err_msg:
  3347                                  ;	db 0Dh, 0Ah
  3348                                  ;	db 07h
  3349                                  ;	db 'Kernel initialization ERROR !'
  3350                                  ;	db 0Dh, 0Ah, 0 
  3351                                  
  3352                                  ;welcome_msg: 
  3353                                  ;	db 0Dh, 0Ah
  3354                                  ;	db 07h
  3355                                  ;	db 'Welcome to TRDOS 386 Operating System !'
  3356                                  ;	db 0Dh, 0Ah
  3357                                  ;	db 'by Erdogan Tan - 31/12/2017 (v2.0.0)'
  3358                                  ;	db 0Dh, 0Ah, 0
  3359                                  
  3360                                  panic_msg:
  3361 000124BB 0D0A07                  	db 0Dh, 0Ah, 07h
  3362 000124BE 4552524F523A204B65-     	db 'ERROR: Kernel Panic !'
  3362 000124C7 726E656C2050616E69-
  3362 000124D0 632021             
  3363 000124D3 0D0A00                  	db 0Dh, 0Ah, 0
  3364                                  
  3365                                  ;msgl_drv_not_ready: 
  3366                                  ;	db 07h, 0Dh, 0Ah
  3367                                  ;       db 'Drive not ready or read error !'
  3368                                  ;       db 0Dh, 0Ah, 0
  3369                                  
  3370                                  starting_msg:
  3371 000124D6 5475726B6973682052-     	db "Turkish Rational DOS v2.0 [22/12/2020] ...", 0
  3371 000124DF 6174696F6E616C2044-
  3371 000124E8 4F532076322E30205B-
  3371 000124F1 32322F31322F323032-
  3371 000124FA 305D202E2E2E00     
  3372                                  NextLine:
  3373 00012501 0D0A00                  	db 0Dh, 0Ah, 0
  3374                                  
  3375                                  %include 'audio.s' ; 03/04/2017
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.2 - audio.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 01/09/2020
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 03/04/2017
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ****************************************************************************
    10                              <1> 
    11                              <1> ; AUDIO CONTROLLER & CODEC DEFINITIONS & CODE FOR TRDOS 386
    12                              <1> 
    13                              <1> ;=============================================================================
    14                              <1> ;               EQUATES
    15                              <1> ;=============================================================================
    16                              <1> 
    17                              <1> ; PCI EQUATES
    18                              <1> 
    19                              <1> BIT0  EQU 1
    20                              <1> BIT1  EQU 2
    21                              <1> BIT2  EQU 4
    22                              <1> BIT3  EQU 8
    23                              <1> BIT4  EQU 10h
    24                              <1> BIT5  EQU 20h
    25                              <1> BIT6  EQU 40h
    26                              <1> BIT7  EQU 80h
    27                              <1> BIT8  EQU 100h
    28                              <1> BIT9  EQU 200h
    29                              <1> BIT10 EQU 400h
    30                              <1> BIT11 EQU 800h
    31                              <1> BIT12 EQU 1000h
    32                              <1> BIT13 EQU 2000h
    33                              <1> BIT14 EQU 4000h
    34                              <1> BIT15 EQU 8000h
    35                              <1> BIT16 EQU 10000h
    36                              <1> BIT17 EQU 20000h
    37                              <1> BIT18 EQU 40000h
    38                              <1> BIT19 EQU 80000h
    39                              <1> BIT20 EQU 100000h
    40                              <1> BIT21 EQU 200000h
    41                              <1> BIT22 EQU 400000h
    42                              <1> BIT23 EQU 800000h
    43                              <1> BIT24 EQU 1000000h
    44                              <1> BIT25 EQU 2000000h
    45                              <1> BIT26 EQU 4000000h
    46                              <1> BIT27 EQU 8000000h
    47                              <1> BIT28 EQU 10000000h
    48                              <1> BIT29 EQU 20000000h
    49                              <1> BIT30 EQU 40000000h
    50                              <1> BIT31 EQU 80000000h
    51                              <1> NOT_BIT31 EQU 7FFFFFFFh
    52                              <1> 
    53                              <1> ; PCI equates
    54                              <1> ; PCI function address (PFA)
    55                              <1> ; bit 31 = 1
    56                              <1> ; bit 23:16 = bus number     (0-255)
    57                              <1> ; bit 15:11 = device number  (0-31)
    58                              <1> ; bit 10:8 = function number (0-7)
    59                              <1> ; bit 7:0 = register number  (0-255)
    60                              <1> 
    61                              <1> IO_ADDR_MASK    EQU     0FFFEh	; mask off bit 0 for reading BARs
    62                              <1> PCI_INDEX_PORT  EQU     0CF8h
    63                              <1> PCI_DATA_PORT   EQU     0CFCh
    64                              <1> PCI32           EQU     BIT31	; bitflag to signal 32bit access
    65                              <1> PCI16           EQU     BIT30	; bitflag for 16bit access
    66                              <1> NOT_PCI32_PCI16	EQU	03FFFFFFFh ; NOT BIT31+BIT30 ; 19/03/2017
    67                              <1> 
    68                              <1> PCI_FN0         EQU     0 << 8
    69                              <1> PCI_FN1         EQU     1 << 8
    70                              <1> PCI_FN2         EQU     2 << 8
    71                              <1> PCI_FN3         EQU     3 << 8
    72                              <1> PCI_FN4         EQU     4 << 8
    73                              <1> PCI_FN5         EQU     5 << 8
    74                              <1> PCI_FN6         EQU     6 << 8
    75                              <1> PCI_FN7         EQU     7 << 8
    76                              <1> 
    77                              <1> PCI_CMD_REG	EQU	04h	; reg 04, command reg
    78                              <1> IO_ENA		EQU	BIT0	; i/o decode enable
    79                              <1> MEM_ENA		EQU	BIT1	; memory decode enable
    80                              <1> BM_ENA		EQU     BIT2	; bus master enable
    81                              <1> 
    82                              <1> ; VIA VT8233 EQUATES
    83                              <1> 
    84                              <1> VIA_VID		equ 1106h	; VIA's PCI vendor ID
    85                              <1> VT8233_DID      equ 3059h	; VT8233 (VT8235) device ID
    86                              <1> 		
    87                              <1> PCI_IO_BASE          equ 10h
    88                              <1> AC97_INT_LINE        equ 3Ch
    89                              <1> VIA_ACLINK_CTRL      equ 41h
    90                              <1> VIA_ACLINK_STAT      equ 40h
    91                              <1> VIA_ACLINK_C00_READY equ 01h ; primary codec ready
    92                              <1> 	
    93                              <1> VIA_REG_AC97	     equ 80h ; dword
    94                              <1> 
    95                              <1> VIA_ACLINK_CTRL_ENABLE	equ   80h ; 0: disable, 1: enable
    96                              <1> VIA_ACLINK_CTRL_RESET	equ   40h ; 0: assert, 1: de-assert
    97                              <1> VIA_ACLINK_CTRL_SYNC	equ   20h ; 0: release SYNC, 1: force SYNC hi
    98                              <1> VIA_ACLINK_CTRL_VRA	equ   08h ; 0: disable VRA, 1: enable VRA
    99                              <1> VIA_ACLINK_CTRL_PCM	equ   04h ; 0: disable PCM, 1: enable PCM
   100                              <1> 					; 3D Audio Channel slots 3/4
   104                              <1> VIA_ACLINK_CTRL_INIT	equ  (VIA_ACLINK_CTRL_ENABLE +                               VIA_ACLINK_CTRL_RESET +                               VIA_ACLINK_CTRL_PCM +                               VIA_ACLINK_CTRL_VRA)
   105                              <1> 
   106                              <1> CODEC_AUX_VOL		equ   04h
   107                              <1> VIA_REG_AC97_BUSY	equ   01000000h ;(1<<24) 
   108                              <1> VIA_REG_AC97_CMD_SHIFT	equ   10h ; 16
   109                              <1> VIA_REG_AC97_PRIMARY_VALID equ 02000000h ;(1<<25)
   110                              <1> VIA_REG_AC97_READ	equ   00800000h ;(1<<23)
   111                              <1> VIA_REG_AC97_CODEC_ID_SHIFT   equ  1Eh ; 30
   112                              <1> VIA_REG_AC97_CODEC_ID_PRIMARY equ  0
   113                              <1> VIA_REG_AC97_DATA_SHIFT equ   0
   114                              <1> VIADEV_PLAYBACK         equ   0
   115                              <1> VIA_REG_OFFSET_STATUS   equ   0    ;; byte - channel status
   116                              <1> VIA_REG_OFFSET_CONTROL  equ   01h  ;; byte - channel control
   117                              <1> VIA_REG_CTRL_START	equ   80h  ;; WO
   118                              <1> VIA_REG_CTRL_TERMINATE  equ   40h  ;; WO
   119                              <1> VIA_REG_CTRL_PAUSE      equ   08h  ;; RW
   120                              <1> VIA_REG_CTRL_RESET      equ   01h  ;; RW - probably reset? undocumented
   121                              <1> VIA_REG_OFFSET_STOP_IDX equ   08h  ;; dword - stop index, channel type, sample rate
   122                              <1> VIA8233_REG_TYPE_16BIT  equ   200000h ;; RW
   123                              <1> VIA8233_REG_TYPE_STEREO equ   100000h ;; RW
   124                              <1> VIA_REG_OFFSET_CURR_INDEX equ 0Fh ;; byte - channel current index (for via8233 only)
   125                              <1> VIA_REG_OFFSET_TABLE_PTR equ  04h  ;; dword - channel table pointer
   126                              <1> VIA_REG_OFFSET_CURR_PTR equ   04h  ;; dword - channel current pointer
   127                              <1> VIA_REG_OFS_PLAYBACK_VOLUME_L equ  02h ;; byte
   128                              <1> VIA_REG_OFS_PLAYBACK_VOLUME_R equ  03h ;; byte
   129                              <1> VIA_REG_CTRL_AUTOSTART	equ   20h
   130                              <1> VIA_REG_CTRL_INT_EOL	equ   02h
   131                              <1> VIA_REG_CTRL_INT_FLAG	equ   01h
   134                              <1> VIA_REG_CTRL_INT	equ  (VIA_REG_CTRL_INT_FLAG +                               VIA_REG_CTRL_INT_EOL +                               VIA_REG_CTRL_AUTOSTART)
   135                              <1> 
   136                              <1> VIA_REG_STAT_STOP_IDX	equ   10h    ;; RO ; 27/07/2020
   137                              <1> 				     ; current index = stop index
   138                              <1> VIA_REG_STAT_STOPPED	equ   04h    ;; RWC
   139                              <1> VIA_REG_STAT_EOL	equ   02h    ;; RWC
   140                              <1> VIA_REG_STAT_FLAG	equ   01h    ;; RWC
   141                              <1> VIA_REG_STAT_ACTIVE	equ   80h    ;; RO
   142                              <1> ; 28/11/2016
   143                              <1> VIA_REG_STAT_LAST	equ   40h    ;; RO
   144                              <1> VIA_REG_STAT_TRIGGER_QUEUED equ 08h  ;; RO
   145                              <1> VIA_REG_CTRL_INT_STOP	equ   04h  ; Interrupt on Current Index = Stop Index
   146                              <1> 		   		   ; and End of Block
   147                              <1> 
   148                              <1> VIA_REG_OFFSET_CURR_COUNT equ 0Ch ;; dword - channel current count, index
   149                              <1> 
   150                              <1> PORTB		EQU	061h
   151                              <1> REFRESH_STATUS	EQU	010h	; Refresh signal status
   152                              <1> 
   153                              <1> ; AC97 Codec registers.
   154                              <1> 
   155                              <1> ; 22/07/2020
   156                              <1> ; REALTEK ALC655 and ADI SOUNDMAX AD1980 CODEC MIXER REGISTERS
   157                              <1> 
   158                              <1> ; each codec/mixer register is 16bits
   159                              <1> 
   160                              <1> CODEC_RESET_REG                 equ     00h	; reset codec
   161                              <1> CODEC_MASTER_VOL_REG            equ     02h	; master volume
   162                              <1> CODEC_HP_VOL_REG                equ     04h	; headphone volume ; AD1980
   163                              <1> CODEC_MASTER_MONO_VOL_REG       equ     06h	; master mono volume (mono-out)
   164                              <1> ;CODEC_MASTER_TONE_REG          equ     08h	; master tone (R+L) ; (not used)
   165                              <1> CODEC_PCBEEP_VOL_REG            equ     0Ah	; PC beep volume ; ALC655
   166                              <1> CODEC_PHONE_VOL_REG             equ     0Ch	; phone volume
   167                              <1> CODEC_MIC_VOL_REG               equ     0Eh	; mic volume
   168                              <1> CODEC_LINE_IN_VOL_REG           equ     10h	; line in volume
   169                              <1> CODEC_CD_VOL_REG                equ     12h	; CD volume
   170                              <1> ;CODEC_VID_VOL_REG              equ     14h	; video volume ; (not used)
   171                              <1> CODEC_AUX_VOL_REG               equ     16h	; aux volume
   172                              <1> CODEC_PCM_OUT_REG               equ     18h	; PCM out volume
   173                              <1> CODEC_RECORD_SELECT_REG         equ     1Ah	; record select
   174                              <1> CODEC_RECORD_VOL_REG            equ     1Ch	; record volume (record gain)
   175                              <1> ;CODEC_RECORD_MIC_VOL_REG       equ     1Eh	; record mic volume ; (not used)
   176                              <1> CODEC_GP_REG                    equ     20h	; general purpose
   177                              <1> ;CODEC_3D_CONTROL_REG           equ     22h	; 3D control
   178                              <1> ;;CODEC_AUDIO_INT_PAGING_REG    equ	24h	; audio int & paging ; (not used) 
   179                              <1> CODEC_POWER_CTRL_REG            equ     26h	; power down control
   180                              <1> CODEC_EXT_AUDIO_REG             equ     28h	; extended audio ID
   181                              <1> CODEC_EXT_AUDIO_CTRL_REG        equ     2Ah	; extended audio status/control
   182                              <1> CODEC_PCM_FRONT_DACRATE_REG     equ     2Ch	; PCM front sample rate
   183                              <1> CODEC_PCM_SURND_DACRATE_REG     equ     2Eh	; PCM surround sample rate
   184                              <1> CODEC_PCM_LFE_DACRATE_REG       equ     30h	; PCM Center/LFE sample rate
   185                              <1> CODEC_LR_ADCRATE_REG            equ     32h	; PCM input sample rate
   186                              <1> CODEC_MIC_ADCRATE_REG           equ     34h	; mic in sample rate  ; AD1980
   187                              <1> CODEC_PCM_LFE_VOL_REG           equ     36h	; PCM Center/LFE volume
   188                              <1> CODEC_PCM_SURND_VOL_REG         equ     38h	; PCM surround volume
   189                              <1> ;CODEC_SPDIF_CTRL_REG           equ     3Ah	; S/PDIF control
   190                              <1> ; 22/07/2020
   191                              <1> CODEC_MISC_CRTL_BITS_REG	equ	76h	; misc control bits ; AD1980
   192                              <1> ;	
   193                              <1> CODEC_VENDOR_ID1		equ	7Ch	; REALTEK: 414Ch, ADI: 4144h	
   194                              <1> CODEC_VENDOR_ID2		equ	7Eh	; REALTEK: 4760h, ADI: 5370h	
   195                              <1> 
   196                              <1> ; VT8233 SGD bits (21/04/2017)
   197                              <1> FLAG	EQU BIT30
   198                              <1> EOL	EQU BIT31
   199                              <1> 
   200                              <1> ; INTEL ICH EQUATES
   201                              <1> ; 28/05/2017
   202                              <1> INTEL_VID	equ	8086h	; Intel's PCI vendor ID
   203                              <1> ICH_DID		equ	2415h	; ICH (82801AA) device ID
   204                              <1> NAMBAR_REG      equ	10h	; native audio mixer Base Address Register
   205                              <1> NABMBAR_REG     equ	14h	; native audio bus mastering Base Addr Reg
   206                              <1> 
   207                              <1> PI_CR_REG       equ     0Bh     ; PCM in Control Register
   208                              <1> PO_CR_REG	equ     1Bh     ; PCM out Control Register
   209                              <1> MC_CR_REG	equ     2Bh     ; MIC in Control Register
   210                              <1> 
   211                              <1> PI_SR_REG	equ     6       ; PCM in Status register
   212                              <1> PO_SR_REG	equ     16h     ; PCM out Status register
   213                              <1> MC_SR_REG	equ     26h     ; MIC in Status register
   214                              <1> 
   215                              <1> IOCE 		equ     BIT4    ; interrupt on complete enable.
   216                              <1> FEIFE		equ     BIT3    ; set if you want an interrupt to fire
   217                              <1> LVBIE		equ     BIT2    ; last valid buffer interrupt enable.
   218                              <1> RR 		equ     BIT1    ; reset registers. Nukes all regs
   219                              <1>                                 ; except bits 4:2 of this register.
   220                              <1>                                 ; Only set this bit if BIT 0 is 0
   221                              <1> RPBM		equ     BIT0    ; Run/Pause
   222                              <1> 				; set this bit to start the codec!
   223                              <1> 
   224                              <1> PI_BDBAR_REG	equ     0       ; PCM in buffer descriptor BAR
   225                              <1> PO_BDBAR_REG	equ     10h     ; PCM out buffer descriptor BAR
   226                              <1> MC_BDBAR_REG	equ     20h     ; MIC in buffer descriptor BAR
   227                              <1> 
   228                              <1> PI_CIV_REG	equ     4       ; PCM in current Index value (RO)
   229                              <1> PO_CIV_REG	equ     14h     ; PCM out current Index value (RO)
   230                              <1> MC_CIV_REG 	equ     24h     ; MIC in current Index value (RO)
   231                              <1> 
   232                              <1> PI_LVI_REG	equ     5       ; PCM in Last Valid Index
   233                              <1> PO_LVI_REG	equ     15h     ; PCM out Last Valid Index
   234                              <1> MC_LVI_REG	equ     25h     ; MIC in Last Valid Index
   235                              <1> 
   236                              <1> IOC		equ     BIT31	; Fire an interrupt whenever this
   237                              <1>                 		; buffer is complete.
   238                              <1> BUP		equ     BIT30	; Buffer Underrun Policy.
   239                              <1> 
   240                              <1> GLOB_CNT_REG	equ     2Ch     ; Global Control Register
   241                              <1> GLOB_STS_REG	equ     30h     ; Global Status register (RO)
   242                              <1> 
   243                              <1> CTRL_ST_CREADY	equ   BIT8+BIT9+BIT28 ; Primary Codec Ready
   244                              <1> 
   245                              <1> CODEC_REG_POWERDOWN   equ 26h
   246                              <1> CODEC_REG_ST          equ 26h
   247                              <1> 
   248                              <1> ; 22/06/2017
   249                              <1> PO_PICB_REG	equ 18h	; PCM Out Position In Current Buffer Register
   250                              <1> 
   251                              <1> ;=============================================================================
   252                              <1> ;               CODE
   253                              <1> ;=============================================================================
   254                              <1> 
   255                              <1> ; CODE for INTEL ICH AC'97 AUDIO CONTROLLER
   256                              <1> 
   257                              <1> DetectICH:
   258                              <1> 	; 10/06/2017
   259                              <1> 	; 05/06/2017
   260                              <1> 	; 29/05/2017
   261                              <1> 	; 28/05/2017
   262 00012504 B886801524          <1> 	mov     eax, (ICH_DID << 16) + INTEL_VID
   263 00012509 E876000000          <1>         call    pciFindDevice
   264 0001250E 730D                <1>         jnc     short d_ac97_1
   265                              <1> d_ac97_0:
   266                              <1> ; couldn't find the audio device!
   267 00012510 C3                  <1> 	retn
   268                              <1> 
   269                              <1> ; CODE for VIA VT8233 AUDIO CONTROLLER
   270                              <1> 
   271                              <1> DetectVT8233:
   272                              <1> 	; 10/06/2017
   273                              <1> 	; 05/06/2017
   274                              <1> 	; 29/05/2017
   275                              <1> 	; 03/04/2017
   276 00012511 B806115930          <1> 	mov     eax, (VT8233_DID << 16) + VIA_VID
   277 00012516 E869000000          <1>         call    pciFindDevice
   278                              <1> ;       jnc     short d_vt8233_0
   279                              <1> ; couldn't find the audio device!
   280                              <1> ;	retn
   281 0001251B 72F3                <1> 	jc	short d_ac97_0  ; 28/05/2017
   282                              <1> d_vt8233_0:
   283                              <1> 	; 24/03/2017 ('player.asm')
   284                              <1> 	; 12/11/2016 
   285                              <1> 	; Erdogan Tan - 8/11/2016
   286                              <1> 	; References: Kolibrios - vt823x.asm (2016)
   287                              <1> 	;	      VIA VT8235 V-Link South Bridge (VT8235-VIA.PDF)(2002)
   288                              <1> 	;	      lowlevel.eu - AC97 (2016)
   289                              <1> 	;	      .wav player for DOS by Jeff Leyda (2002) -this file-
   290                              <1> 	;	      Linux kernel - via82xx.c (2016)
   291                              <1> d_ac97_1:
   292                              <1> 	; eax = BUS/DEV/FN
   293                              <1> 	;	00000000BBBBBBBBDDDDDFFF00000000
   294                              <1> 	; edx = DEV/VENDOR
   295                              <1> 	;	DDDDDDDDDDDDDDDDVVVVVVVVVVVVVVVV
   296                              <1> 
   297 0001251D A3[60760100]        <1> 	mov	[audio_dev_id], eax
   298 00012522 8915[64760100]      <1> 	mov	[audio_vendor], edx
   299                              <1> 
   300                              <1> 	; init controller
   301 00012528 B004                <1> 	mov	al, PCI_CMD_REG ; command register (04h)
   302 0001252A E8E2000000          <1> 	call	pciRegRead32
   303                              <1> 
   304                              <1> 	; eax = BUS/DEV/FN/REG
   305                              <1> 	; edx = STATUS/COMMAND
   306                              <1> 	; 	SSSSSSSSSSSSSSSSCCCCCCCCCCCCCCCC
   307 0001252F 8915[68760100]      <1> 	mov	[audio_stats_cmd], edx
   308                              <1> 
   309 00012535 B010                <1> 	mov	al, PCI_IO_BASE ; IO base address register (10h)
   310                              <1> 	;mov	al, NAMBAR_REG	; Native Audio Mixer BAR (10h)
   311 00012537 E8D5000000          <1> 	call	pciRegRead32
   312                              <1> 
   313 0001253C 66813D[64760100]86- <1> 	cmp	word [audio_vendor], 8086h ; AC'97 ?
   313 00012544 80                  <1>
   314 00012545 751F                <1> 	jne	short d_vt8233_1
   315                              <1> 
   316 00012547 6683E2FE            <1> 	and	dx, 0FFFEh ; Audio Codec IO_ADDR_MASK
   317 0001254B 668915[90760100]    <1> 	mov	[NAMBAR], dx
   318                              <1> 
   319 00012552 B014                <1> 	mov	al, NABMBAR_REG ; Native Audio Bus Mastering BAR (14h)
   320 00012554 E8B8000000          <1> 	call	pciRegRead32	
   321                              <1> 
   322 00012559 6683E2C0            <1> 	and	dx, 0FFC0h ; Audio Controller IO_ADDR_MASK
   323 0001255D 668915[92760100]    <1> 	mov	[NABMBAR], dx
   324                              <1>         ;mov	[audio_io_base], dx
   325                              <1> 	
   326 00012564 EB0B                <1> 	jmp	short d_ac97_2
   327                              <1> 
   328                              <1> d_vt8233_1:
   329 00012566 6683E2C0            <1> 	and     dx, 0FFC0h ; Audio Controller IO_ADDR_MASK 
   330 0001256A 668915[5E760100]    <1>         mov     [audio_io_base], dx
   331                              <1> 
   332                              <1> d_ac97_2:
   333                              <1> 	; 10/06/2017
   334 00012571 B03C                <1> 	mov	al, AC97_INT_LINE ; Interrupt Line Register (3Ch)
   335                              <1> 	;call	pciRegRead32
   336 00012573 E886000000          <1> 	call	pciRegRead8
   337                              <1> 
   338                              <1> 	;and 	edx, 0FFh
   339 00012578 6681E2FF00          <1> 	and	dx, 0FFh
   340                              <1> 
   341 0001257D 8815[5B760100]      <1>   	mov     [audio_intr], dl
   342                              <1> 
   343 00012583 C3                  <1> 	retn
   344                              <1> 
   345                              <1> 	;; (Note: Interrupts are already enabled by TRDOS 386 kernel!)
   346                              <1> 	;mov	cx, dx
   347                              <1> 	
   348                              <1> 	;in	al, 0A1h ; irq 8-15
   349                              <1> 	;mov	ah, al
   350                              <1> 	;in	al, 21h  ; irq 0-7 
   351                              <1> 	;btr	ax, dx	 ; unmask ; 17/03/2017
   352                              <1> 	;;bts	ax, dx   ; MASK interrupt ; 10/06/2017 
   353                              <1> 	;out	21h, al  ; irq <= 7
   354                              <1> 	;mov	al, ah
   355                              <1> 	;out	0A1h, al ; irq > 7
   356                              <1> 	;
   357                              <1> 	
   358                              <1> 	; 10/06/2017
   359                              <1> 	; === Intel ICH I/O Controller Hub Datasheet, Section 8.1.16 ===
   360                              <1> 	; PRQ[n]_ROUT Register (61h, PRQB) Bit 7:
   361                              <1> 	; Interrupt Routing Enable (IRQEN).
   362                              <1> 	; 0 = The corresponding PIRQ is routed to one of the ISA-compatible
   363                              <1> 	;     interrupts specified in bits[3:0].
   364                              <1> 	; 1 = The PIRQ is not routed to the 8259.
   365                              <1> 	; Note: If the PIRQ is intended to cause an interrupt to the ICHs 
   366                              <1> 	;	integrated I/O APIC, then this bit should be set to 0 and 
   367                              <1> 	;	the APIC_EN bit should be set to 1. 
   368                              <1> 	;	The IRQEN must be set to 0 and the PIRQ routed to 
   369                              <1> 	;	an 8259 interrupt via the IRQ Routing filed (bits[3:0).
   370                              <1> 	;	The corresponding 8259 interrupt must be masked via the 
   371                              <1> 	;	appropriated bit in the 8259s OCW1 (Interrupt Mask)
   372                              <1> 	;	register. The IOAPIC must then be enabled by setting 
   373                              <1> 	;	the APIC_EN bit in the GEN_CNTL register.
   374                              <1> 
   375                              <1> 	;mov	eax, 0F861h  ; D31:F0
   376                              <1> 		;AL=61h : PIRQ[B] Routing Control Reg, LPC interface
   377                              <1> 	;;mov	dl, [audio_intr]
   378                              <1> 	;call	pciRegWrite8
   379                              <1> 	;;mov	al, 0D0h ; General Control Register (GEN_CTL)
   380                              <1> 	;;call	pciRegRead32
   381                              <1> 	;;or	edx, 100h ; Bit 8, APIC_EN (Enable I/O APIC) 
   382                              <1> 	;;;call	pciRegWrite32
   383                              <1> 	;;and	edx, ~100h
   384                              <1> 	;;call	pciRegWrite32 ; ; Bit 8, APIC_EN (Disable I/O APIC) 
   385                              <1> 	;
   386                              <1> 
   387                              <1> 	;mov	dx, 4D1h	; 8259 ELCR2
   388                              <1>     	;in	al, dx
   389                              <1> 	;mov	ah, al
   390                              <1> 	;;mov	dx, 4D0h 	; 8259 ELCR1
   391                              <1> 	;dec	dl
   392                              <1> 	;in	al, dx
   393                              <1> 	;bts	ax, cx
   394                              <1> 	;;mov	dx, 4D0h
   395                              <1> 	;out	dx, al		; set level-triggered mode
   396                              <1> 	;mov	al, ah ; 29/05/2017
   397                              <1> 	;;mov	dx, 4D1h
   398                              <1> 	;inc	dl
   399                              <1> 	;out	dx, al		; set level-triggered mode
   400                              <1> 
   401                              <1> 	;xor	eax, eax ; 0
   402                              <1> 
   403                              <1> 	;retn
   404                              <1> 
   405                              <1> ; CODE for PCI
   406                              <1> 
   407                              <1> pciFindDevice:
   408                              <1> 	; 03/04/2017 ('pci.asm', 20/03/2017)
   409                              <1> 	;
   410                              <1> 	; scan through PCI space looking for a device+vendor ID
   411                              <1> 	;
   412                              <1> 	; Entry: EAX=Device+Vendor ID
   413                              <1> 	;
   414                              <1> 	; Exit: EAX=PCI address if device found
   415                              <1> 	;	 EDX=Device+Vendor ID
   416                              <1> 	;        CY clear if found, set if not found. EAX invalid if CY set.
   417                              <1> 	;
   418                              <1> 	; Destroys: ebx, esi, edi, cl
   419                              <1> 	;
   420                              <1> 
   421                              <1> 	;push	ecx
   422 00012584 50                  <1> 	push	eax
   423                              <1> 	;push	esi
   424                              <1> 	;push	edi
   425                              <1> 
   426 00012585 89C6                <1>         mov     esi, eax                ; save off vend+device ID
   427 00012587 BF00FFFF7F          <1>         mov     edi, (80000000h - 100h) ; start with bus 0, dev 0 func 0
   428                              <1> 
   429                              <1> nextPCIdevice:
   430 0001258C 81C700010000        <1>         add     edi, 100h
   431 00012592 81FF00F8FF80        <1>         cmp     edi, 80FFF800h		; scanned all devices?
   432 00012598 F9                  <1>         stc
   433 00012599 740C                <1>         je      short PCIScanExit       ; not found
   434                              <1> 
   435 0001259B 89F8                <1>         mov     eax, edi                ; read PCI registers
   436 0001259D E86F000000          <1>         call    pciRegRead32
   437 000125A2 39F2                <1>         cmp     edx, esi                ; found device?
   438 000125A4 75E6                <1>         jne     short nextPCIdevice
   439 000125A6 F8                  <1>         clc
   440                              <1> 
   441                              <1> PCIScanExit:
   442 000125A7 9C                  <1> 	pushf
   443 000125A8 B8FFFFFF7F          <1> 	mov	eax, NOT_BIT31 	; 19/03/2017
   444 000125AD 21F8                <1> 	and	eax, edi	; return only bus/dev/fn #
   445 000125AF 9D                  <1> 	popf
   446                              <1> 
   447                              <1> 	;pop	edi
   448                              <1> 	;pop	esi
   449 000125B0 5A                  <1> 	pop	edx
   450                              <1> 	;pop	ecx
   451 000125B1 C3                  <1> 	retn
   452                              <1> 
   453                              <1> pciRegRead:
   454                              <1> 	; 03/04/2017 ('pci.asm', 20/03/2017)
   455                              <1> 	;
   456                              <1> 	; 8/16/32bit PCI reader
   457                              <1> 	;
   458                              <1> 	; Entry: EAX=PCI Bus/Device/fn/register number
   459                              <1> 	;           BIT30 set if 32 bit access requested
   460                              <1> 	;           BIT29 set if 16 bit access requested
   461                              <1> 	;           otherwise defaults to 8 bit read
   462                              <1> 	;
   463                              <1> 	; Exit:  DL,DX,EDX register data depending on requested read size
   464                              <1> 	;
   465                              <1> 	; Note1: this routine is meant to be called via pciRegRead8,
   466                              <1> 	;	 pciRegread16 or pciRegRead32, listed below.
   467                              <1> 	;
   468                              <1> 	; Note2: don't attempt to read 32 bits of data from a non dword
   469                              <1> 	;	 aligned reg number. Likewise, don't do 16 bit reads from
   470                              <1> 	;	 non word aligned reg #
   471                              <1> 	
   472 000125B2 53                  <1> 	push	ebx
   473 000125B3 51                  <1> 	push	ecx
   474 000125B4 89C3                <1>         mov     ebx, eax		; save eax, dh
   475 000125B6 88F1                <1>         mov     cl, dh
   476                              <1> 
   477 000125B8 25FFFFFF3F          <1>         and     eax, NOT_PCI32_PCI16	; clear out data size request
   478 000125BD 0D00000080          <1>         or      eax, BIT31		; make a PCI access request
   479 000125C2 24FC                <1>         and     al, ~3 ; NOT 3		; force index to be dword
   480                              <1> 
   481 000125C4 66BAF80C            <1>         mov     dx, PCI_INDEX_PORT
   482 000125C8 EF                  <1>         out	dx, eax			; write PCI selector
   483                              <1> 	
   484 000125C9 66BAFC0C            <1>         mov     dx, PCI_DATA_PORT
   485 000125CD 88D8                <1>         mov     al, bl
   486 000125CF 2403                <1>         and     al, 3			; figure out which port to
   487 000125D1 00C2                <1>         add     dl, al			; read to
   488                              <1> 
   489 000125D3 F7C3000000C0        <1> 	test    ebx, PCI32+PCI16
   490 000125D9 7507                <1>         jnz     short _pregr0
   491 000125DB EC                  <1> 	in	al, dx			; return 8 bits of data
   492 000125DC 88C2                <1>         mov	dl, al
   493 000125DE 88CE                <1> 	mov     dh, cl			; restore dh for 8 bit read
   494 000125E0 EB12                <1> 	jmp	short _pregr2
   495                              <1> _pregr0:	
   496 000125E2 F7C300000080        <1> 	test    ebx, PCI32
   497 000125E8 7507                <1>         jnz	short _pregr1
   498 000125EA 66ED                <1> 	in	ax, dx
   499 000125EC 6689C2              <1>         mov     dx, ax			; return 16 bits of data
   500 000125EF EB03                <1> 	jmp	short _pregr2
   501                              <1> _pregr1:
   502 000125F1 ED                  <1> 	in	eax, dx			; return 32 bits of data
   503 000125F2 89C2                <1> 	mov	edx, eax
   504                              <1> _pregr2:
   505 000125F4 89D8                <1> 	mov     eax, ebx		; restore eax
   506 000125F6 25FFFFFF3F          <1>         and     eax, NOT_PCI32_PCI16	; clear out data size request
   507 000125FB 59                  <1> 	pop	ecx
   508 000125FC 5B                  <1> 	pop	ebx
   509 000125FD C3                  <1> 	retn
   510                              <1> 
   511                              <1> pciRegRead8:
   512 000125FE 25FFFFFF3F          <1>         and     eax, NOT_PCI32_PCI16	; set up 8 bit read size
   513 00012603 EBAD                <1>         jmp     short pciRegRead	; call generic PCI access
   514                              <1> 
   515                              <1> pciRegRead16:
   516 00012605 25FFFFFF3F          <1>         and     eax, NOT_PCI32_PCI16	; set up 16 bit read size
   517 0001260A 0D00000040          <1>         or      eax, PCI16		; call generic PCI access
   518 0001260F EBA1                <1>         jmp     short pciRegRead
   519                              <1> 
   520                              <1> pciRegRead32:
   521 00012611 25FFFFFF3F          <1>         and     eax, NOT_PCI32_PCI16	; set up 32 bit read size
   522 00012616 0D00000080          <1>         or      eax, PCI32		; call generic PCI access
   523 0001261B EB95                <1>         jmp     pciRegRead
   524                              <1> 
   525                              <1> pciRegWrite:
   526                              <1> 	; 03/04/2017 ('pci.asm', 29/11/2016)
   527                              <1> 	;
   528                              <1> 	; 8/16/32bit PCI writer
   529                              <1> 	;
   530                              <1> 	; Entry: EAX=PCI Bus/Device/fn/register number
   531                              <1> 	;           BIT31 set if 32 bit access requested
   532                              <1> 	;           BIT30 set if 16 bit access requested
   533                              <1> 	;           otherwise defaults to 8bit read
   534                              <1> 	;        DL/DX/EDX data to write depending on size
   535                              <1> 	;
   536                              <1> 	; Note1: this routine is meant to be called via pciRegWrite8, 
   537                              <1> 	;	 pciRegWrite16 or pciRegWrite32 as detailed below.
   538                              <1> 	;
   539                              <1> 	; Note2: don't attempt to write 32bits of data from a non dword
   540                              <1> 	;	 aligned reg number. Likewise, don't do 16 bit writes from
   541                              <1> 	;	 non word aligned reg #
   542                              <1> 
   543 0001261D 53                  <1> 	push	ebx
   544 0001261E 51                  <1> 	push	ecx
   545 0001261F 89C3                <1>         mov     ebx, eax		; save eax, edx
   546 00012621 89D1                <1>         mov     ecx, edx
   547 00012623 25FFFFFF3F          <1> 	and     eax, NOT_PCI32_PCI16	; clear out data size request
   548 00012628 0D00000080          <1>         or      eax, BIT31		; make a PCI access request
   549 0001262D 24FC                <1>         and     al, ~3 ; NOT 3		; force index to be dword
   550                              <1> 
   551 0001262F 66BAF80C            <1>         mov     dx, PCI_INDEX_PORT
   552 00012633 EF                  <1>         out	dx, eax			; write PCI selector
   553                              <1> 	
   554 00012634 66BAFC0C            <1>         mov     dx, PCI_DATA_PORT
   555 00012638 88D8                <1>         mov     al, bl
   556 0001263A 2403                <1>         and     al, 3			; figure out which port to
   557 0001263C 00C2                <1>         add     dl, al			; write to
   558                              <1> 
   559 0001263E F7C3000000C0        <1> 	test    ebx, PCI32+PCI16
   560 00012644 7505                <1>         jnz     short _pregw0
   561 00012646 88C8                <1> 	mov	al, cl 			; put data into al
   562 00012648 EE                  <1> 	out	dx, al
   563 00012649 EB12                <1> 	jmp	short _pregw2
   564                              <1> _pregw0:
   565 0001264B F7C300000080        <1> 	test    ebx, PCI32
   566 00012651 7507                <1>         jnz     short _pregw1
   567 00012653 6689C8              <1> 	mov	ax, cx			; put data into ax
   568 00012656 66EF                <1> 	out	dx, ax
   569 00012658 EB03                <1> 	jmp	short _pregw2
   570                              <1> _pregw1:
   571 0001265A 89C8                <1> 	mov	eax, ecx		; put data into eax 		
   572 0001265C EF                  <1> 	out	dx, eax
   573                              <1> _pregw2:
   574 0001265D 89D8                <1>         mov     eax, ebx		; restore eax
   575 0001265F 25FFFFFF3F          <1>         and     eax, NOT_PCI32_PCI16	; clear out data size request
   576 00012664 89CA                <1>         mov     edx, ecx		; restore dx
   577 00012666 59                  <1> 	pop	ecx
   578 00012667 5B                  <1> 	pop	ebx
   579 00012668 C3                  <1> 	retn
   580                              <1> 
   581                              <1> pciRegWrite8:
   582 00012669 25FFFFFF3F          <1>         and     eax, NOT_PCI32_PCI16	; set up 8 bit write size
   583 0001266E EBAD                <1>         jmp	short pciRegWrite	; call generic PCI access
   584                              <1> 
   585                              <1> pciRegWrite16:
   586 00012670 25FFFFFF3F          <1>         and     eax, NOT_PCI32_PCI16	; set up 16 bit write size
   587 00012675 0D00000040          <1>         or      eax, PCI16		; call generic PCI access
   588 0001267A EBA1                <1>         jmp	short pciRegWrite
   589                              <1> 
   590                              <1> pciRegWrite32:
   591 0001267C 25FFFFFF3F          <1>         and     eax, NOT_PCI32_PCI16	; set up 32 bit write size
   592 00012681 0D00000080          <1>         or      eax, PCI32		; call generic PCI access
   593 00012686 EB95                <1>         jmp	pciRegWrite
   594                              <1> 
   595                              <1> init_codec:
   596                              <1> 	; 05/06/2017
   597                              <1> 	; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
   598                              <1> 	;
   599 00012688 A1[60760100]        <1> 	mov	eax, [audio_dev_id]	
   600 0001268D B041                <1> 	mov	al, VIA_ACLINK_CTRL
   601 0001268F E86AFFFFFF          <1> 	call	pciRegRead8
   602                              <1> 	; ?
   603 00012694 B040                <1> 	mov	al, VIA_ACLINK_STAT
   604 00012696 E863FFFFFF          <1> 	call	pciRegRead8
   605 0001269B F6C201              <1> 	test	dl, VIA_ACLINK_C00_READY
   606 0001269E 7508                <1>         jnz     short _codec_ready_1
   607 000126A0 E80E000000          <1> 	call	reset_codec
   608 000126A5 7306                <1> 	jnc	short _codec_ready_2 ; eax = 1
   609 000126A7 C3                  <1> 	retn
   610                              <1> _codec_ready_1:
   611 000126A8 B801000000          <1> 	mov	eax, 1
   612                              <1> _codec_ready_2:
   613 000126AD E886000000          <1> 	call	codec_io_w16
   614                              <1> detect_codec:
   615 000126B2 C3                  <1> 	retn
   616                              <1> 
   617                              <1> reset_codec:
   618                              <1> 	; 16/04/2017
   619                              <1> 	; 23/03/2017 
   620                              <1> 	; ('codec.asm')
   621                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
   622 000126B3 A1[60760100]        <1> 	mov	eax, [audio_dev_id]
   623 000126B8 B041                <1>  	mov	al, VIA_ACLINK_CTRL
   624 000126BA B2E0                <1>        	mov	dl, VIA_ACLINK_CTRL_ENABLE + VIA_ACLINK_CTRL_RESET + VIA_ACLINK_CTRL_SYNC
   625 000126BC E8A8FFFFFF          <1> 	call	pciRegWrite8
   626                              <1> 
   627 000126C1 E849000000          <1> 	call	delay_100ms 	; wait 100 ms
   628                              <1> _rc_cold:
   629 000126C6 E814000000          <1>         call    cold_reset
   630 000126CB 7301                <1>         jnc     short _reset_codec_ok
   631                              <1> 	
   632                              <1> 	; 16/04/2017
   633                              <1>         ;xor     eax, eax         ; timeout error
   634                              <1>        	;stc
   635 000126CD C3                  <1> 	retn
   636                              <1> 
   637                              <1> _reset_codec_ok:
   638                              <1> 	; 01/09/2020
   639                              <1> 	; 15/08/2020
   640                              <1> 	; 27/07/2020
   641                              <1> 	; also reset codec by using index control register 0 of AD1980 or ALC655
   642                              <1> 	; (to fix line out -2 channels audio playing- problem on AD1980 codec)  
   643                              <1> 
   644 000126CE 29C0                <1> 	sub	eax, eax
   645 000126D0 BA00000000          <1> 	mov	edx, CODEC_RESET_REG ; 00h ; Reset register
   646 000126D5 E8CA000000          <1> 	call	codec_write
   647                              <1> 
   648                              <1> 	;sub	eax, eax
   649                              <1> 	; 01/09/2020
   650                              <1> 	; 15/08/2020
   651                              <1> 	; AD1980 BugFix
   652                              <1> 	; (set HPSEL -headphone amp to be driven from mixer- and
   653                              <1> 	;      CLDIS - center and LFE disable- bits)	
   654                              <1> 	;mov	eax, 0C00h ; HPSEL = bit 10, CLDIS = bit 11 ; 01/09/2020
   655                              <1>  	;mov	edx, CODEC_MISC_CRTL_BITS_REG ; 76h ; Misc Ctrl Bits ; AD1980
   656                              <1> 	;call	codec_write
   657                              <1> 
   658 000126DA 31C0                <1>         xor     eax, eax
   659                              <1>         ;mov	al, VIA_ACLINK_C00_READY ; 1
   660 000126DC FEC0                <1>         inc	al
   661 000126DE C3                  <1> 	retn
   662                              <1> 
   663                              <1> cold_reset:
   664                              <1> 	; 16/04/2017
   665                              <1> 	; 23/03/2017
   666                              <1> 	; ('codec.asm')
   667                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
   668                              <1> 	;mov	eax, [audio_dev_id]
   669                              <1> 	;mov	al, VIA_ACLINK_CTRL
   670 000126DF 30D2                <1> 	xor	dl, dl ; 0
   671 000126E1 E883FFFFFF          <1> 	call	pciRegWrite8
   672                              <1> 
   673 000126E6 E824000000          <1> 	call	delay_100ms 	; wait 100 ms
   674                              <1> 
   675                              <1> 	;; ACLink on, deassert ACLink reset, VSR, SGD data out
   676                              <1>         ;; note - FM data out has trouble with non VRA codecs !!
   677                              <1>         
   678                              <1> 	;mov	eax, [audio_dev_id]
   679                              <1> 	;mov	al, VIA_ACLINK_CTRL
   680 000126EB B2CC                <1> 	mov	dl, VIA_ACLINK_CTRL_INIT
   681 000126ED E877FFFFFF          <1> 	call	pciRegWrite8
   682                              <1> 
   683 000126F2 B910000000          <1> 	mov	ecx, 16	; total 2s
   684                              <1> 
   685                              <1> _crst_wait:
   686                              <1> 	;mov	eax, [audio_dev_id]
   687 000126F7 B040                <1> 	mov	al, VIA_ACLINK_STAT
   688 000126F9 E800FFFFFF          <1> 	call	pciRegRead8	
   689                              <1> 
   690 000126FE F6C201              <1>         test    dl, VIA_ACLINK_C00_READY
   691 00012701 750B                <1>         jnz     short _crst_ok
   692                              <1> 
   693 00012703 51                  <1> 	push	ecx
   694 00012704 E806000000          <1> 	call	delay_100ms
   695 00012709 59                  <1> 	pop	ecx
   696                              <1> 
   697 0001270A 49                  <1>         dec     ecx
   698 0001270B 75EA                <1>         jnz     short _crst_wait
   699                              <1> 
   700                              <1> _crst_fail:
   701 0001270D F9                  <1>         stc
   702                              <1> _crst_ok:
   703 0001270E C3                  <1> 	retn
   704                              <1> 
   705                              <1> delay_100ms:
   706                              <1> 	; 29/05/2017
   707                              <1> 	; 24/03/2017 ('codec.asm')
   708                              <1> 	; wait 100 ms
   709 0001270F B990010000          <1> 	mov	ecx, 400  ; 400*0.25ms
   710                              <1> _delay_x_ms:
   711 00012714 E803000000          <1> 	call	delay1_4ms
   712 00012719 E2F9                <1>         loop	_delay_x_ms
   713 0001271B C3                  <1> 	retn
   714                              <1> 
   715                              <1> ;       delay1_4ms - Delay for 1/4 millisecond.
   716                              <1> ;	    1mS = 1000us
   717                              <1> ;       Entry:
   718                              <1> ;         None
   719                              <1> ;       Exit:
   720                              <1> ;	  None
   721                              <1> ;
   722                              <1> ;       Modified:
   723                              <1> ;         None
   724                              <1> ;
   725                              <1> 
   726                              <1> 	; 29/05/2017
   727                              <1> 	; 23/04/2017
   728                              <1> 	; 05/03/2017 (TRDOS 386)
   729                              <1> 	; ('UTILS.ASM')
   730                              <1> delay1_4ms:
   731 0001271C 50                  <1>         push    eax 
   732 0001271D 51                  <1>         push    ecx
   733 0001271E B110                <1>         mov	cl, 16		; close enough.
   734                              <1> 
   735 00012720 E461                <1> 	in	al, PORTB ; 61h
   736                              <1> 		
   737 00012722 2410                <1> 	and	al, REFRESH_STATUS ; 10h
   738 00012724 88C5                <1> 	mov	ch, al		; Start toggle state
   739                              <1> _d4ms1:	
   740 00012726 E461                <1> 	in	al, PORTB	; Read system control port
   741                              <1> 	
   742 00012728 2410                <1> 	and	al, REFRESH_STATUS ; Refresh toggles 15.085 microseconds
   743 0001272A 38C5                <1> 	cmp	ch, al
   744 0001272C 74F8                <1> 	je	short _d4ms1	; Wait for state change
   745                              <1> 
   746 0001272E 88C5                <1> 	mov	ch, al		; Update with new state
   747 00012730 FEC9                <1> 	dec	cl
   748 00012732 75F2                <1> 	jnz	short _d4ms1
   749                              <1> 
   750 00012734 F8                  <1> 	clc	; 29/05/2017
   751                              <1> 
   752 00012735 59                  <1>         pop     ecx
   753 00012736 58                  <1>         pop     eax
   754 00012737 C3                  <1>         retn
   755                              <1> 
   756                              <1> ; 10/04/2017 (TRDOS 386)
   757                              <1> ; 12/11/2016
   758                              <1> 
   759                              <1> codec_io_w16: ;w32
   760                              <1> 	; ('codec.asm')
   761 00012738 668B15[5E760100]    <1>         mov	dx, [audio_io_base]
   762 0001273F 6681C28000          <1>         add     dx, VIA_REG_AC97
   763 00012744 EF                  <1> 	out	dx, eax
   764 00012745 C3                  <1>         retn
   765                              <1> 
   766                              <1> codec_io_r16: ;r32
   767                              <1> 	; ('codec.asm')
   768 00012746 668B15[5E760100]    <1>         mov     dx, [audio_io_base]
   769 0001274D 6681C28000          <1>         add     dx, VIA_REG_AC97
   770 00012752 ED                  <1>         in	eax, dx
   771 00012753 C3                  <1>         retn
   772                              <1> 
   773                              <1> ctrl_io_w8:
   774                              <1> 	; ('codec.asm')
   775 00012754 660315[5E760100]    <1>         add     dx, [audio_io_base]
   776 0001275B EE                  <1>         out	dx, al
   777 0001275C C3                  <1>         retn
   778                              <1> 
   779                              <1> ctrl_io_r8:
   780                              <1> 	; ('codec.asm')
   781 0001275D 660315[5E760100]    <1>         add     dx, [audio_io_base]
   782 00012764 EC                  <1>         in	al, dx
   783 00012765 C3                  <1>         retn
   784                              <1> 
   785                              <1> ctrl_io_w32:
   786                              <1> 	; ('codec.asm')
   787 00012766 660315[5E760100]    <1>         add     dx, [audio_io_base]
   788 0001276D EF                  <1>         out	dx, eax
   789 0001276E C3                  <1>         retn
   790                              <1> 
   791                              <1> ctrl_io_r32:
   792                              <1> 	; ('codec.asm')
   793 0001276F 660315[5E760100]    <1>         add	dx, [audio_io_base]
   794 00012776 ED                  <1> 	in	eax, dx
   795 00012777 C3                  <1>         retn
   796                              <1> 
   797                              <1> codec_read:
   798                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
   799                              <1>         ; Use only primary codec.
   800                              <1>         ; eax = register
   801 00012778 C1E010              <1>         shl     eax, VIA_REG_AC97_CMD_SHIFT
   802 0001277B 0D00008002          <1>         or      eax, VIA_REG_AC97_PRIMARY_VALID + VIA_REG_AC97_READ
   803                              <1> 
   804 00012780 E8B3FFFFFF          <1> 	call    codec_io_w16
   805                              <1> 
   806                              <1>       	; codec_valid
   807 00012785 E831000000          <1> 	call	codec_check_ready
   808 0001278A 7301                <1>         jnc	short _cr_ok
   809                              <1> 
   810 0001278C C3                  <1> 	retn
   811                              <1> 
   812                              <1> _cr_ok:
   813                              <1> 	; wait 25 ms
   814 0001278D B950000000          <1> 	mov	ecx, 80 ; (100*0.25 ms)
   815                              <1> _cr_wloop:
   816 00012792 E885FFFFFF          <1> 	call	delay1_4ms
   817 00012797 E2F9                <1> 	loop	_cr_wloop
   818                              <1> 
   819 00012799 E8A8FFFFFF          <1>         call    codec_io_r16
   820 0001279E 25FFFF0000          <1>         and     eax, 0FFFFh
   821 000127A3 C3                  <1>         retn
   822                              <1> 
   823                              <1> codec_write:
   824                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
   825                              <1>         ; Use only primary codec.
   826                              <1>         
   827                              <1> 	; eax = data (volume)
   828                              <1> 	; edx = register (mixer register)
   829                              <1> 	
   830 000127A4 C1E210              <1> 	shl     edx, VIA_REG_AC97_CMD_SHIFT
   831                              <1> 
   832 000127A7 C1E000              <1>         shl     eax, VIA_REG_AC97_DATA_SHIFT ; shl eax, 0
   833 000127AA 09C2                <1>         or      edx, eax
   834                              <1> 
   835 000127AC B800000000          <1>         mov     eax, VIA_REG_AC97_CODEC_ID_PRIMARY
   836 000127B1 C1E01E              <1>         shl     eax, VIA_REG_AC97_CODEC_ID_SHIFT
   837 000127B4 09D0                <1>         or      eax, edx
   838                              <1> 
   839 000127B6 E87DFFFFFF          <1>         call    codec_io_w16
   840                              <1>         ;mov    [codec.regs+esi], ax
   841                              <1> 
   842                              <1>         ;call	codec_check_ready
   843                              <1>        	;retn
   844                              <1> 	;jmp	short _codec_check_ready	
   845                              <1> 
   846                              <1> codec_check_ready:
   847                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
   848                              <1> 
   849                              <1> _codec_check_ready:
   850 000127BB B914000000          <1> 	mov	ecx, 20	; total 2s
   851                              <1> _ccr_wait:
   852 000127C0 51                  <1> 	push	ecx
   853                              <1> 
   854 000127C1 E880FFFFFF          <1>         call    codec_io_r16
   855 000127C6 A900000001          <1>         test    eax, VIA_REG_AC97_BUSY
   856 000127CB 740B                <1>         jz      short _ccr_ok
   857                              <1> 
   858 000127CD E83DFFFFFF          <1> 	call	delay_100ms
   859                              <1> 
   860 000127D2 59                  <1> 	pop	ecx
   861                              <1> 
   862 000127D3 49                  <1> 	dec     ecx
   863 000127D4 75EA                <1>         jnz     short _ccr_wait
   864                              <1> 
   865 000127D6 F9                  <1>         stc
   866 000127D7 C3                  <1>         retn
   867                              <1> 
   868                              <1> _ccr_ok:
   869 000127D8 59                  <1> 	pop	ecx
   870 000127D9 25FFFF0000          <1> 	and     eax, 0FFFFh
   871 000127DE C3                  <1>         retn
   872                              <1> 
   873                              <1> codec_config:
   874                              <1> 	; 10/06/2017
   875                              <1> 	; 29/05/2017
   876                              <1> 	; 24/04/2017
   877                              <1> 	; 21/04/2017
   878                              <1> 	; 16/04/2017 (TRDOS 386 Kernel) 
   879                              <1> 	; 15/11/2016 ('codec.asm', 'player.com')
   880                              <1> 	; 14/11/2016
   881                              <1> 	; 12/11/2016 - Erdogan Tan
   882                              <1> 	;	     (Ref: KolibriOS, 'setup_codec', codec.inc)
   883                              <1> 
   884 000127DF B802020000          <1> 	mov     eax, 0202h
   885 000127E4 66A3[8E760100]      <1> 	mov	[audio_master_volume], ax
   886 000127EA 66B81F1F            <1> 	mov	ax, 1F1Fh ; 31,31
   887 000127EE BA02000000          <1> 	mov	edx, CODEC_MASTER_VOL_REG ; 02h ; Line Out
   888 000127F3 E8ACFFFFFF          <1> 	call	codec_write
   889                              <1> 	;jc	short cconfig_error
   890                              <1> 
   891                              <1>  	;mov    eax, 0202h
   892 000127F8 66B80202            <1> 	mov     ax, 0202h
   893 000127FC BA18000000          <1> 	mov	edx, CODEC_PCM_OUT_REG ; 18h ; Wave Output (Stereo)
   894 00012801 E89EFFFFFF          <1> 	call	codec_write
   895                              <1> 	;jc	short cconfig_error
   896                              <1>       
   897                              <1>  	;mov    eax, 0202h
   898 00012806 66B80202            <1> 	mov	ax, 0202h
   899 0001280A BA04000000          <1> 	mov	edx, CODEC_AUX_VOL ; 04h ; CODEC_HP_VOL_REG ; HeadPhone
   900 0001280F E890FFFFFF          <1> 	call	codec_write
   901                              <1> 	;jc	short cconfig_error
   902                              <1> 
   903                              <1>  	;mov    eax, 08h
   904                              <1>         ;mov    ax,  08h
   905 00012814 66B80880            <1> 	mov	ax, 8008h ; Mute
   906 00012818 BA0C000000          <1> 	mov	edx, 0Ch  ; AC97_PHONE_VOL ; TAD Input (Mono)
   907 0001281D E882FFFFFF          <1> 	call	codec_write
   908                              <1> 	;jc	short cconfig_error
   909                              <1> 
   910                              <1>  	;mov    eax, 0808h
   911 00012822 66B80808            <1>         mov     ax,  0808h
   912 00012826 BA10000000          <1>         mov	edx, CODEC_LINE_IN_VOL_REG ; 10h ; Line Input (Stereo)	
   913 0001282B E874FFFFFF          <1> 	call	codec_write
   914                              <1> 	;jc	short cconfig_error
   915                              <1> 
   916                              <1>  	;mov    eax, 0808h
   917 00012830 66B80808            <1> 	mov     ax,  0808h
   918 00012834 BA12000000          <1>         mov	edx, CODEC_CD_VOL_REG ; 12h ; CR Input (Stereo)
   919 00012839 E866FFFFFF          <1> 	call	codec_write
   920                              <1> 	;jc	short cconfig_error
   921                              <1> 
   922                              <1>  	;mov    eax, 0808h
   923 0001283E 66B80808            <1> 	mov     ax,  0808h
   924 00012842 BA16000000          <1>         mov	edx, CODEC_AUX_VOL_REG ; 16h ; Aux Input (Stereo)
   925                              <1> 	;call	codec_write
   926                              <1> 	;;jc	short cconfig_error
   927 00012847 E958FFFFFF          <1> 	jmp	codec_write ; 10/06/2017
   928                              <1> 
   929                              <1> ;	; Extended Audio Status (2Ah)
   930                              <1> ;	mov	eax, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah 
   931                              <1> ;	call	codec_read
   932                              <1> ;	and     eax, 0FFFFh - 2		; clear DRA (BIT1)
   933                              <1> ;	;or     eax, 1			; set VRA (BIT0)
   934                              <1> ;	or	eax, 5  	; VRA (BIT0) & S/PDIF (BIT2) ; 14/11/2016
   935                              <1> ;	mov	edx, CODEC_EXT_AUDIO_CTRL_REG
   936                              <1> ;	call	codec_write
   937                              <1> ;	;jc	short cconfig_error
   938                              <1> ;
   939                              <1> ;set_sample_rate:
   940                              <1> ;	;movzx	eax, word [audio_freq]
   941                              <1> ;	mov	ax, [audio_freq]
   942                              <1> ;	mov	edx, CODEC_PCM_FRONT_DACRATE_REG ; 2Ch ; PCM Front DAC Rate
   943                              <1> ;	;call	codec_write
   944                              <1> ;	;retn
   945                              <1> ;	jmp	codec_write
   946                              <1> 	
   947                              <1> ;cconfig_error:
   948                              <1> ;	retn
   949                              <1> 
   950                              <1> vt8233_int_handler:
   951                              <1> 	; 27/07/2020
   952                              <1> 	; 22/07/2020
   953                              <1> 	; Interrupt Handler for VIA VT8237R Audio Controller
   954                              <1> 	; Note: called by 'dev_IRQ_service'
   955                              <1> 	; 14/10/2017 
   956                              <1> 	; 09/10/2017, 10/10/2017, 12/10/2017
   957                              <1> 	; 13/06/2017
   958                              <1> 	; 21/04/2017 (TRDOS 386 kernel, 'audio.s')
   959                              <1> 	; 24/03/2017 - 'PLAYER.COM' ('player.asm') 
   960                              <1> 
   961                              <1> 	;push	eax ; * must be saved !
   962                              <1> 	;push	edx
   963                              <1> 	;push	ecx
   964                              <1> 	;push	ebx ; * must be saved !
   965                              <1> 	;push	esi
   966                              <1> 	;push	edi
   967                              <1> 
   968                              <1> 	;cmp	byte [audio_busy], 1
   969                              <1> 	;jnb	short _ih0 ; 09/10/2017
   970                              <1> 
   971                              <1> 	;mov	byte [audio_flag_eol], 0
   972                              <1> 
   973 0001284C 66BA0000            <1>         mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STATUS
   974 00012850 E808FFFFFF          <1>         call    ctrl_io_r8
   975                              <1> 
   976 00012855 A880                <1> 	test    al, VIA_REG_STAT_ACTIVE
   977 00012857 7417                <1>         jz      short _ih0 ; 09/10/2017
   978                              <1> 
   979 00012859 2407                <1>         and     al, VIA_REG_STAT_EOL + VIA_REG_STAT_FLAG + VIA_REG_STAT_STOPPED
   980 0001285B A2[8D760100]        <1> 	mov	[audio_flag_eol], al
   981 00012860 740E                <1>         jz	short _ih0 ; 09/10/2017
   982                              <1> 
   983                              <1> 	; 09/10/2017
   984                              <1> 	;mov	byte [audio_busy], 1
   985                              <1> 
   986 00012862 803D[8C760100]01    <1> 	cmp	byte [audio_play_cmd], 1
   987 00012869 7315                <1> 	jnb	short _ih1 ; 10/10/2017
   988                              <1> 
   989 0001286B E84A000000          <1> 	call	channel_reset
   990                              <1> _ih0:
   991                              <1> 	; 09/10/2017
   992 00012870 A0[8D760100]        <1>         mov     al, [audio_flag_eol]   ;; ack ;;
   993 00012875 66BA0000            <1>         mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STATUS
   994 00012879 E8D6FEFFFF          <1>         call    ctrl_io_w8
   995 0001287E EB39                <1> 	jmp	short _ih4
   996                              <1> _ih1:
   997                              <1> vt8233_tuneLoop:
   998 00012880 A0[8D760100]        <1>         mov     al, [audio_flag_eol]   ;; ack ;;
   999 00012885 66BA0000            <1>         mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STATUS
  1000 00012889 E8C6FEFFFF          <1>         call    ctrl_io_w8
  1001                              <1> 
  1002                              <1> 	; 22/07/2020
  1003                              <1> 	;; 12/10/2017
  1004                              <1> 	;mov	byte [audio_flag], 0 ; Reset	
  1005                              <1> 
  1006                              <1> 	; 10/10/2017
  1007                              <1> 	; 09/10/2017
  1008                              <1> 	;test	byte [audio_flag_eol], VIA_REG_STAT_FLAG
  1009                              <1> 	;jz	short _ih2 ; EOL
  1010                              <1> 
  1011                              <1> 	; 22/07/2020
  1012                              <1> 	; 14/10/2017
  1013                              <1> 	;test	byte [audio_flag_eol], VIA_REG_STAT_EOL
  1014                              <1> 	;jnz	short _ih2 ; EOL
  1015                              <1> 	;		   ; (Half Buffer 2 has been completed 
  1016                              <1> 	;		   ; and Half Buffer 1 will be played.)
  1017                              <1> 	
  1018                              <1> 	; FLAG  
  1019                              <1> 	; (Half Buffer 1 has been completed 
  1020                              <1> 	;  and Half Buffer 2 will be played.)
  1021                              <1> 
  1022                              <1> 	; 14/10/2017
  1023                              <1> 	;; (Continue to play.)
  1024                              <1> 	;mov	al, VIA_REG_CTRL_INT
  1025                              <1>        	;or	al, VIA_REG_CTRL_START
  1026                              <1>        	;mov	dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CONTROL
  1027                              <1>         ;call	ctrl_io_w8
  1028                              <1> 	; 12/10/2017
  1029                              <1> 	;mov	byte [audio_flag], 1 
  1030                              <1> 
  1031                              <1> 	; 22/07/2020
  1032                              <1> 	;inc	byte [audio_flag] ; = 1
  1033                              <1> _ih2: 
  1034                              <1> 	; 10/10/2017
  1035 0001288E 8B3D[78760100]      <1> 	mov	edi, [audio_dma_buff]
  1036 00012894 8B0D[7C760100]      <1> 	mov	ecx, [audio_dmabuff_size]
  1037 0001289A D1E9                <1> 	shr	ecx, 1 ; dma buff size / 2 = half buffer size
  1038                              <1> 	
  1039                              <1> 	; 22/07/2020
  1040                              <1> 	; 12/10/2017
  1041                              <1> 	;cmp	byte [audio_flag], 0
  1042                              <1> 	;ja	short _ih3 ; Playing Half Buffer 2 (Current: FLAG)
  1043                              <1> 	
  1044                              <1> 	; 27/07/2020
  1045                              <1> 	; 22/07/2020
  1046 0001289C F605[80760100]01    <1> 	test	byte [audio_flag], 1  ; Current flag value
  1047 000128A3 7402                <1> 	jz	short _ih3 ; Half Buffer 1 must be filled
  1048                              <1> 
  1049                              <1> 	; Half Buffer 2 must be filled
  1050 000128A5 01CF                <1> 	add	edi, ecx
  1051                              <1> _ih3:
  1052                              <1> 	; Update half buffer 2 while playing half buffer 1
  1053                              <1> 	; Update half buffer 1 while playing half buffer 2
  1054                              <1> 
  1055 000128A7 8B35[70760100]      <1> 	mov	esi, [audio_p_buffer] ; phy addr of audio buff
  1056 000128AD C1E902              <1> 	shr	ecx, 2 ; half buff size / 4
  1057 000128B0 F3A5                <1> 	rep	movsd
  1058                              <1> 
  1059                              <1> 	; switch flag value ;
  1060 000128B2 8035[80760100]01    <1> 	xor	byte [audio_flag], 1
  1061                              <1> 	; 12/10/2017
  1062                              <1> 	; [audio_flag] = 0 : Playing dma half buffer 2
  1063                              <1> 			   ; Next buffer (to update) is dma half buff 1
  1064                              <1> 	; 	       = 1 : Playing dma half buffer 1
  1065                              <1> 			   ; Next buffer (to update) is dma half buff 2
  1066                              <1> _ih4:	
  1067                              <1> 	; 28/05/2017
  1068                              <1> 	;mov	byte [audio_busy], 0 ; 09/10/2017
  1069                              <1> 	;
  1070                              <1> 	;pop	edi
  1071                              <1> 	;pop	esi
  1072                              <1> 	;pop	ebx ; * must be restored !
  1073                              <1> 	;pop	ecx
  1074                              <1> 	;pop	edx
  1075                              <1> 	;pop	eax ; * must be restored !
  1076                              <1> 
  1077 000128B9 C3                  <1> 	retn
  1078                              <1> 
  1079                              <1> channel_reset:
  1080                              <1> 	; 24/06/2017
  1081                              <1> 	; 29/05/2017
  1082                              <1> 	; 23/03/2017
  1083                              <1> 	; 14/11/2016 - Erdogan Tan
  1084                              <1> 	; 12/11/2016 - Erdogan Tan (Ref: KolibriOS, vt823x.asm)
  1085 000128BA BA01000000          <1>         mov	edx, VIA_REG_OFFSET_CONTROL
  1086                              <1>         ;mov	eax, VIA_REG_CTRL_PAUSE + VIA_REG_CTRL_TERMINATE + VIA_REG_CTRL_RESET
  1087 000128BF B848000000          <1>         mov	eax, VIA_REG_CTRL_PAUSE + VIA_REG_CTRL_TERMINATE ; 24/06/2017       
  1088 000128C4 E88BFEFFFF          <1> 	call    ctrl_io_w8
  1089                              <1> 
  1090                              <1>         ;mov	edx, VIA_REG_OFFSET_CONTROL
  1091                              <1>         ;call   ctrl_io_r8
  1092                              <1> 
  1093                              <1> 	; wait for 50 ms
  1094 000128C9 B9A0000000          <1> 	mov	ecx, 160 ; (200*0.25 ms) ; 29/05/2017	
  1095                              <1> _ch_rst_wait:
  1096 000128CE E849FEFFFF          <1> 	call	delay1_4ms
  1097 000128D3 49                  <1> 	dec	ecx
  1098 000128D4 75F8                <1> 	jnz	short _ch_rst_wait     
  1099                              <1> 
  1100                              <1>         ; disable interrupts
  1101 000128D6 BA01000000          <1>         mov	edx, VIA_REG_OFFSET_CONTROL
  1102 000128DB 31C0                <1>         xor     eax, eax
  1103 000128DD E872FEFFFF          <1>         call    ctrl_io_w8
  1104                              <1> 
  1105                              <1>         ; clear interrupts
  1106 000128E2 BA00000000          <1>         mov	edx, VIA_REG_OFFSET_STATUS
  1107 000128E7 B803000000          <1> 	mov	eax, 3
  1108 000128EC E863FEFFFF          <1>         call	ctrl_io_w8
  1109                              <1> 
  1110                              <1> 	;mov	edx, VIA_REG_OFFSET_CURR_PTR
  1111                              <1> 	;xor	eax, eax
  1112                              <1> 	;call	ctrl_io_w32
  1113                              <1> 
  1114 000128F1 C3                  <1>         retn	
  1115                              <1> 
  1116                              <1> vt8233_stop: ; 22/04/2017
  1117 000128F2 C605[8C760100]00    <1> 	mov	byte [audio_play_cmd], 0 ; stop !
  1118                              <1> _tlp2:
  1119                              <1> 	; 24/06/2017
  1120                              <1>         ; finished with song, stop everything
  1121                              <1> 	;mov	al, VIA_REG_CTRL_INT
  1122                              <1>         ;or	al, VIA_REG_CTRL_TERMINATE
  1123                              <1> 	;mov	dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CONTROL
  1124                              <1>         ;call	ctrl_io_w8
  1125                              <1> 
  1126                              <1>         ;call	channel_reset
  1127                              <1> 	;retn
  1128                              <1> 
  1129 000128F9 EBBF                <1> 	jmp	short channel_reset
  1130                              <1> 
  1131                              <1> set_vt8233_bdl: ; Set VT8237R Buffer Descriptor List
  1132                              <1> 	; 22/07/2020 - TRDOS 386 v2.0.2
  1133                              <1> 	; 28/05/2017
  1134                              <1> 	; 21/04/2017 (TRDOS 386 kernel, 'audio.s')
  1135                              <1> 	; 24/03/2017 - 'PLAYER.COM' ('via_wav.asm' - 29/11/2016) 
  1136                              <1> 	
  1137                              <1> 	; eax = dma buffer address = [audio_DMA_buff]
  1138                              <1> 	; ecx = dma buffer buffer size = [audio_dmabuff_size]
  1139                              <1> 
  1140 000128FB D1E9                <1> 	shr	ecx, 1 ; dma half buffer size
  1141 000128FD 89CE                <1> 	mov	esi, ecx
  1142                              <1> 
  1143 000128FF BF[94760100]        <1>         mov     edi, audio_bdl_buff	; get BDL address
  1144 00012904 B910000000          <1>         mov     ecx, 32 / 2		; make 32 entries in BDL
  1145                              <1> 
  1146 00012909 EB05                <1> 	jmp	short s_vt8233_bdl1 
  1147                              <1> 
  1148                              <1> s_vt8233_bdl0:
  1149                              <1> 	; set buffer descriptor 0 to start of data file in memory
  1150                              <1> 
  1151 0001290B A1[78760100]        <1>  	mov	eax, [audio_dma_buff]	; Physical address of DMA buffer
  1152                              <1>  
  1153                              <1> s_vt8233_bdl1:
  1154 00012910 AB                  <1> 	stosd				; store dmabuffer1 address
  1155                              <1> 
  1156 00012911 89C2                <1> 	mov	edx, eax
  1157                              <1> 
  1158                              <1> ; VIA VT8235.PDF: (Page 110) (Erdogan Tan, 29/11/2016)
  1159                              <1> 	;
  1160                              <1> 	; 	Audio SGD Table Format
  1161                              <1> 	;	-------------------------------
  1162                              <1> 	;	63   62    61-56    55-32  31-0
  1163                              <1> 	;	--   --   --------  -----  ----
  1164                              <1> 	;	EOL FLAG -reserved- Base   Base
  1165                              <1> 	;		    	    Count  Address
  1166                              <1> 	;		            [23:0] [31:0]
  1167                              <1> 	;	EOL: End Of Link. 
  1168                              <1> 	;	     1 indicates this block is the last of the link.
  1169                              <1> 	;	     If the channel Interrupt on EOL bit is set, then
  1170                              <1> 	;	     an interrupt is generated at the end of the transfer.
  1171                              <1> 	;
  1172                              <1> 	;	FLAG: Block Flag. If set, transfer pauses at the end of this
  1173                              <1> 	;	      block. If the channel Interrupt on FLAG bit is set,
  1174                              <1> 	;	      then an interrupt is generated at the end of this block.
  1175                              <1> 
  1176 00012913 89F0                <1> 	mov	eax, esi ; DMA half buffer size
  1177 00012915 01C2                <1> 	add	edx, eax
  1178 00012917 0D00000040          <1> 	or	eax, FLAG
  1179                              <1> 	;or	eax, EOL
  1180 0001291C AB                  <1> 	stosd
  1181                              <1> 
  1182                              <1> ; 2nd buffer:
  1183                              <1> 
  1184 0001291D 89D0                <1>         mov	eax, edx ; Physical address of the 2nd half of DMA buffer	
  1185 0001291F AB                  <1> 	stosd		 ; store dmabuffer2 address
  1186                              <1> 
  1187                              <1> ; set length to [audio_dmabuff_size]/2
  1188                              <1> ; Set control (bits 31:16) to BUP, bits 15:0=number of samples
  1189                              <1> ; 
  1190 00012920 89F0                <1> 	mov	eax, esi ; DMA half buffer size
  1191                              <1> 	; 22/07/2020
  1192                              <1> 	;or	eax, EOL
  1193 00012922 0D00000040          <1> 	or	eax, FLAG
  1194 00012927 AB                  <1> 	stosd
  1195                              <1> 
  1196 00012928 E2E1                <1> 	loop    s_vt8233_bdl0
  1197                              <1> 
  1198                              <1> 	; 22/07/2020
  1199 0001292A 814FFC00000080      <1> 	or	dword [edi-4], EOL
  1200                              <1> 	
  1201 00012931 C3                  <1> 	retn
  1202                              <1> 
  1203                              <1> vt8233_start_play:
  1204                              <1> 	; 01/09/2020 
  1205                              <1> 	; 22/07/2020 
  1206                              <1> 	; start to play audio data via VT8233 audio controller
  1207                              <1> 	; 13/06/2017
  1208                              <1> 	; 10/06/2017
  1209                              <1> 	; 24/04/2017 
  1210                              <1> 	; 21/04/2017 (TRDOS 386 kernel, 'audio.s')
  1211                              <1> 	; 24/03/2017 - 'PLAYER.COM' ('via_wav.asm' - 29/11/2016) 
  1212                              <1> 	; write buffer descriptor list address
  1213                              <1> 
  1214                              <1> 	; Extended Audio Status (2Ah)
  1215 00012932 B82A000000          <1> 	mov	eax, CODEC_EXT_AUDIO_CTRL_REG ; 2Ah 
  1216 00012937 E83CFEFFFF          <1> 	call	codec_read
  1217 0001293C 25FDFF0000          <1> 	and     eax, 0FFFFh - 2		; clear DRA (BIT1)
  1218                              <1> 	;or     eax, 1			; set VRA (BIT0)
  1219                              <1> 	;or	eax, 5  	; VRA (BIT0) & S/PDIF (BIT2) ; 14/11/2016
  1220 00012941 0C05                <1> 	or	al, 5
  1221                              <1> 	; 01/09/2020	
  1222                              <1> 	;or	eax, 3805h ; AD1980 (PRK, PRJ, PRI = 1 .. only front DAC)
  1223                              <1> 	; 01/09/2020
  1224                              <1> 	;mov	edx, CODEC_EXT_AUDIO_CTRL_REG
  1225                              <1> 	;cmp	word [audio_freq], 0BB80h ; 48 kHz
  1226                              <1> 	;jne	short set_extd_audio_status_1
  1227                              <1> 	;and	al, 0FEh ; disable VRA bit (set sample rate to 48000 Hz)
  1228                              <1> 	;jmp	short set_extd_audio_status_2
  1229                              <1> ;set_extd_audio_status_1:
  1230 00012943 BA2A000000          <1> 	mov	edx, CODEC_EXT_AUDIO_CTRL_REG
  1231 00012948 E857FEFFFF          <1> 	call	codec_write
  1232                              <1> 	;jc	short cconfig_error
  1233                              <1> 
  1234                              <1> set_sample_rate:
  1235                              <1> 	;movzx	eax, word [audio_freq]
  1236 0001294D 66A1[8A760100]      <1> 	mov	ax, [audio_freq]
  1237 00012953 BA2C000000          <1> 	mov	edx, CODEC_PCM_FRONT_DACRATE_REG ; 2Ch ; PCM Front DAC Rate
  1238                              <1> ;set_extd_audio_status_2:
  1239 00012958 E847FEFFFF          <1> 	call	codec_write
  1240                              <1> 
  1241                              <1> 	; 01/09/2020
  1242                              <1> 	; set AD1980 MCB register (Index 76h) to 0C00h
  1243                              <1> 	; (CLDIS, HPSEL)
  1244                              <1> 	;mov	ax, 0C00h
  1245                              <1> 	;mov	edx, CODEC_MISC_CRTL_BITS_REG ; 76h 
  1246                              <1> 	;			; Miscellaneous Control Bit Register
  1247                              <1> 	;call	codec_write
  1248                              <1> 	;
  1249                              <1> 
  1250 0001295D B8[94760100]        <1>         mov	eax, audio_bdl_buff
  1251                              <1>   
  1252                              <1> 	; 12/11/2016 - Erdogan Tan 
  1253                              <1> 	; (Ref: KolibriOS, vt823x.asm, 'create_primary_buff')
  1254 00012962 BA04000000          <1> 	mov	edx, VIADEV_PLAYBACK + VIA_REG_OFFSET_TABLE_PTR
  1255 00012967 E8FAFDFFFF          <1>         call	ctrl_io_w32
  1256                              <1> 
  1257                              <1> 	;call	codec_check_ready
  1258                              <1> 
  1259 0001296C 66BA0200            <1>   	mov	dx, VIADEV_PLAYBACK + VIA_REG_OFS_PLAYBACK_VOLUME_L
  1260                              <1>         ;mov	eax, 2	; 31
  1261 00012970 B01F                <1> 	mov	al, 31
  1262 00012972 2A05[8E760100]      <1>         sub	al, [audio_master_volume_l]
  1263 00012978 E8D7FDFFFF          <1> 	call	ctrl_io_w8
  1264                              <1> 
  1265                              <1> 	;call	codec_check_ready
  1266                              <1> 
  1267 0001297D 66BA0300            <1>         mov     dx, VIADEV_PLAYBACK + VIA_REG_OFS_PLAYBACK_VOLUME_R
  1268                              <1>         ;mov	ax, 2	; 31
  1269 00012981 B01F                <1> 	mov	al, 31
  1270 00012983 2A05[8F760100]      <1>         sub	al, [audio_master_volume_r]
  1271 00012989 E8C6FDFFFF          <1> 	call    ctrl_io_w8
  1272                              <1> 
  1273                              <1> 	;call	codec_check_ready
  1274                              <1> ;
  1275                              <1> ;
  1276                              <1> ; All set. Let's play some music.
  1277                              <1> ;
  1278                              <1> ;
  1279                              <1>        	;mov    dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STOP_IDX
  1280                              <1>         ;mov    ax, VIA8233_REG_TYPE_16BIT or VIA8233_REG_TYPE_STEREO or 0xfffff or 0xff000000
  1281                              <1>         ;call   ctrl_io_w32
  1282                              <1> 
  1283                              <1> 	;call	codec_check_ready
  1284                              <1> 
  1285                              <1> 	; 08/12/2016
  1286                              <1> 	; 07/10/2016
  1287                              <1>         ;;mov    al, 1
  1288                              <1>         ;mov	al, 31
  1289                              <1> 	; 22/07/2020
  1290 0001298E B0FF                <1> 	mov	al, 0FFh
  1291 00012990 E813000000          <1> 	call    set_VT8233_LastValidIndex
  1292                              <1> 
  1293 00012995 C605[8C760100]01    <1> 	mov	byte [audio_play_cmd], 1 ; play command (do not stop) !
  1294                              <1> 
  1295                              <1> 	; 22/07/2020
  1296                              <1> 	;mov	byte [audio_flag], 0  ; clear half buffer flag
  1297                              <1> 
  1298                              <1> vt8233_play: ; continue to play
  1299                              <1> 	; 22/04/2017
  1300                              <1> 	;mov	al, VIA_REG_CTRL_INT
  1301                              <1>        	;or	al, VIA_REG_CTRL_START
  1302                              <1>         ;;mov	al, VIA_REG_CTRL_AUTOSTART + VIA_REG_CTRL_START
  1303                              <1> 	; 22/07/2020	
  1304 0001299C B0A1                <1> 	mov	al, VIA_REG_CTRL_AUTOSTART + VIA_REG_CTRL_START + VIA_REG_CTRL_INT_FLAG
  1305                              <1> 
  1306 0001299E 66BA0100            <1> 	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CONTROL
  1307 000129A2 E8ADFDFFFF          <1>         call    ctrl_io_w8
  1308                              <1> 	;call	codec_check_ready
  1309                              <1> 	;retn
  1310                              <1> 	;jmp	codec_check_ready
  1311 000129A7 C3                  <1> 	retn
  1312                              <1> 
  1313                              <1> ;input AL = index # to stop on
  1314                              <1> set_VT8233_LastValidIndex:
  1315                              <1> 	; 23/07/2020
  1316                              <1> 	; 10/06/2017
  1317                              <1> 	; 21/04/2017 (TRDOS 386 kernel, 'audio.s')
  1318                              <1> 	; 24/03/2017 - 'PLAYER.COM' ('via_wav.asm' - 29/11/2016) 
  1319                              <1> 	; 19/11/2016
  1320                              <1> 	; 14/11/2016 - Erdogan Tan (Ref: VIA VT8235.PDF, Page 110)
  1321                              <1> 	; 12/11/2016 - Erdogan Tan
  1322                              <1> 	; (Ref: KolibriOS, vt823x.asm, 'create_primary_buff')
  1323                              <1> 	;push	edx
  1324                              <1> 	;push	ax
  1325 000129A8 50                  <1> 	push	eax ; 23/07/2020
  1326                              <1> 	;push	ecx
  1327 000129A9 0FB705[8A760100]    <1> 	movzx	eax, word [audio_freq] ; Hertz
  1328 000129B0 BA00001000          <1> 	mov	edx, 100000h ; 2^20 = 1048576
  1329 000129B5 F7E2                <1> 	mul	edx
  1330 000129B7 B980BB0000          <1> 	mov	ecx, 48000	
  1331 000129BC F7F1                <1> 	div	ecx
  1332                              <1> 	;and	eax, 0FFFFFh
  1333                              <1> 	;pop	ecx
  1334                              <1> 	;pop	dx 
  1335 000129BE 5A                  <1> 	pop	edx ; 23/07/2020
  1336 000129BF C1E218              <1> 	shl	edx, 24  ; STOP Index Setting: Bit 24 to 31
  1337 000129C2 09D0                <1> 	or	eax, edx
  1338                              <1> 	; 19/11/2016
  1339 000129C4 803D[88760100]10    <1> 	cmp	byte [audio_bps], 16
  1340 000129CB 7505                <1> 	jne	short sLVI_1
  1341 000129CD 0D00002000          <1> 	or	eax, VIA8233_REG_TYPE_16BIT
  1342                              <1> sLVI_1:
  1343 000129D2 803D[89760100]02    <1> 	cmp	byte [audio_stmo], 2
  1344 000129D9 7505                <1> 	jne	short sLVI_2
  1345 000129DB 0D00001000          <1> 	or	eax, VIA8233_REG_TYPE_STEREO
  1346                              <1> sLVI_2:
  1347 000129E0 BA08000000          <1> 	mov     edx, VIADEV_PLAYBACK + VIA_REG_OFFSET_STOP_IDX
  1348 000129E5 E87CFDFFFF          <1>         call    ctrl_io_w32
  1349                              <1> 	;call	codec_check_ready
  1350                              <1> 	;pop	edx
  1351 000129EA C3                  <1> 	retn
  1352                              <1> 
  1353                              <1> vt8233_pause: ; pause
  1354                              <1> 	; 10/06/2017
  1355                              <1> 	; 22/04/2017
  1356                              <1> 	;mov     al, VIA_REG_CTRL_INT
  1357                              <1>         ;or      al, VIA_REG_CTRL_PAUSE
  1358                              <1> 	; 23/07/2020
  1359 000129EB B029                <1> 	mov	al, VIA_REG_CTRL_PAUSE+VIA_REG_CTRL_INT_FLAG+VIA_REG_CTRL_AUTOSTART
  1360                              <1> 	
  1361 000129ED 66BA0100            <1> 	mov     dx, VIADEV_PLAYBACK + VIA_REG_OFFSET_CONTROL
  1362 000129F1 E85EFDFFFF          <1>         call    ctrl_io_w8
  1363                              <1> 	;call	codec_check_ready
  1364                              <1> 	;retn
  1365                              <1> 	;jmp	codec_check_ready
  1366 000129F6 C3                  <1> 	retn
  1367                              <1> 
  1368                              <1> vt8233_reset: 
  1369                              <1> 	; 22/04/2017
  1370                              <1> 	; reset VT8237R (vt8233) Audio Controller
  1371                              <1> 	;cmp	byte [audio_play_cmd], 1
  1372                              <1> 	;jna	short vt8233_rst_0
  1373 000129F7 C605[8C760100]00    <1> 	mov	byte [audio_play_cmd], 0 ; stop !
  1374                              <1> vt8233_rst_0:
  1375 000129FE E8B0FCFFFF          <1> 	call	reset_codec
  1376 00012A03 720A                <1> 	jc	short vt8233_rst_1 ; codec error !
  1377                              <1> 	; eax = 1
  1378 00012A05 E82EFDFFFF          <1> 	call	codec_io_w16 ; w32
  1379 00012A0A E8ABFEFFFF          <1> 	call	channel_reset
  1380                              <1> vt8233_rst_1:
  1381 00012A0F C3                  <1> 	retn
  1382                              <1> 
  1383                              <1> vt8233_volume:
  1384                              <1> 	; set VT8237R (vt8233) sound volume level
  1385                              <1> 	; 24/04/2017
  1386                              <1> 	; 22/04/2017
  1387                              <1> 	; bl = component (0 = master/playback/lineout volume)
  1388                              <1> 	; cl = left channel volume level (0 to 31)
  1389                              <1> 	; ch = right channel volume level (0 to 31)
  1390                              <1> 
  1391 00012A10 08DB                <1> 	or	bl, bl
  1392 00012A12 7520                <1> 	jnz	short vt8233_vol_1 ; temporary !
  1393 00012A14 66B81F1F            <1> 	mov	ax, 1F1Fh ; 31,31
  1394 00012A18 38C1                <1> 	cmp	cl, al
  1395 00012A1A 7718                <1> 	ja	short vt8233_vol_1 ; temporary !
  1396 00012A1C 38E5                <1> 	cmp	ch, ah
  1397 00012A1E 7714                <1> 	ja	short vt8233_vol_1 ; temporary !
  1398 00012A20 66890D[8E760100]    <1> 	mov	[audio_master_volume], cx
  1399 00012A27 6629C8              <1> 	sub	ax, cx
  1400 00012A2A BA02000000          <1> 	mov	edx, CODEC_MASTER_VOL_REG ; 02h ; Line Out
  1401 00012A2F E870FDFFFF          <1> 	call	codec_write
  1402                              <1> vt8233_vol_1:
  1403 00012A34 C3                  <1> 	retn
  1404                              <1> 
  1405                              <1> ; CODE for SOUND BLASTER 16
  1406                              <1> 
  1407                              <1> DetectSB:
  1408                              <1> 	; 24/04/2017
  1409                              <1> 	;pushad
  1410                              <1> ScanPort:
  1411 00012A35 66BB1002            <1> 	mov     bx, 210h	; start scanning ports
  1412                              <1> 				; 210h, 220h, .. 260h
  1413                              <1> ResetDSP:       
  1414 00012A39 6689DA              <1> 	mov     dx, bx		; try to reset the DSP.
  1415 00012A3C 6683C206            <1> 	add     dx, 06h
  1416 00012A40 B001                <1> 	mov	al, 1
  1417 00012A42 EE                  <1> 	out	dx, al
  1418                              <1> 
  1419 00012A43 EC                  <1> 	in	al, dx
  1420 00012A44 EC                  <1> 	in	al, dx
  1421 00012A45 EC                  <1> 	in	al, dx
  1422 00012A46 EC                  <1> 	in	al, dx
  1423                              <1> 
  1424 00012A47 30C0                <1> 	xor     al, al
  1425 00012A49 EE                  <1> 	out	dx, al
  1426                              <1> 
  1427 00012A4A 6683C208            <1> 	add     dx, 08h
  1428 00012A4E 66B96400            <1> 	mov	cx, 100
  1429                              <1> WaitID:
  1430 00012A52 EC                  <1> 	in	al, dx
  1431 00012A53 08C0                <1> 	or      al, al
  1432 00012A55 7804                <1> 	js      short GetID
  1433 00012A57 E2F9                <1> 	loop    WaitID
  1434 00012A59 EB0F                <1> 	jmp     short NextPort
  1435                              <1> GetID:          
  1436 00012A5B 6683EA04            <1> 	sub     dx, 04h
  1437 00012A5F EC                  <1> 	in	al, dx
  1438 00012A60 3CAA                <1> 	cmp     al, 0AAh
  1439 00012A62 7413                <1> 	je      short Found
  1440 00012A64 6683C204            <1> 	add     dx, 04h
  1441 00012A68 E2E8                <1> 	loop    WaitID
  1442                              <1> NextPort:
  1443 00012A6A 6683C310            <1> 	add     bx, 10h		; if not response,
  1444 00012A6E 6681FB6002          <1> 	cmp     bx, 260h	; try the next port.
  1445 00012A73 76C4                <1> 	jbe     short ResetDSP
  1446 00012A75 F9                  <1> 	stc
  1447 00012A76 C3                  <1> 	retn
  1448                              <1> Found:
  1449 00012A77 66891D[5E760100]    <1> 	mov     [audio_io_base], bx	; SB Port Address Found!
  1450                              <1> ScanIRQ:
  1451                              <1> SetIrqs:
  1452 00012A7E 28C0                <1> 	sub 	al, al ; 0
  1453 00012A80 A2[56760100]        <1> 	mov 	[IRQnum], al ; reset
  1454 00012A85 A2[5B760100]        <1> 	mov	[audio_intr], al ; reset
  1455                              <1> 
  1456                              <1> 	; ah > 0 -> set IRQ vector
  1457                              <1> 	; al = IRQ number
  1458                              <1> 	;mov	ax, 103h ; IRQ 3
  1459                              <1> 	;call	set_hardware_int_vector
  1460                              <1> 	;mov	ax, 104h ; IRQ 4
  1461                              <1> 	;call	set_hardware_int_vector
  1462 00012A8A 66B80501            <1> 	mov	ax, 105h ; IRQ 5
  1463 00012A8E E8C9DDFFFF          <1> 	call	set_hardware_int_vector
  1464 00012A93 66B80701            <1> 	mov	ax, 107h ; IRQ 7
  1465 00012A97 E8C0DDFFFF          <1> 	call	set_hardware_int_vector
  1466                              <1> 
  1467 00012A9C 668B15[5E760100]    <1> 	mov     dx, [audio_io_base] ; tells to the SB to
  1468 00012AA3 6683C20C            <1> 	add     dx, 0Ch		    ; generate a IRQ!
  1469                              <1> WaitSb:
  1470 00012AA7 EC                  <1> 	in	al, dx
  1471 00012AA8 08C0                <1> 	or      al, al
  1472 00012AAA 78FB                <1> 	js      short WaitSb
  1473 00012AAC B0F2                <1> 	mov     al, 0F2h
  1474 00012AAE EE                  <1> 	out	dx, al
  1475                              <1> 
  1476 00012AAF 31C9                <1> 	xor     ecx, ecx	; wait until IRQ level
  1477                              <1> WaitIRQ: 
  1478 00012AB1 A0[56760100]        <1> 	mov	al, [IRQnum]
  1479 00012AB6 3C00                <1> 	cmp     al, 0 ; is changed or timeout.
  1480 00012AB8 7706                <1> 	ja	short IrqOk
  1481 00012ABA 6649                <1> 	dec	cx
  1482 00012ABC 75F3                <1> 	jnz	short WaitIRQ
  1483 00012ABE EB15                <1> 	jmp	short RestoreIrqs
  1484                              <1> IrqOk:
  1485 00012AC0 A2[5B760100]        <1> 	mov	[audio_intr], al ; set   
  1486 00012AC5 668B15[5E760100]    <1> 	mov     dx, [audio_io_base]
  1487 00012ACC 6683C20E            <1> 	add     dx, 0Eh
  1488 00012AD0 EC                  <1> 	in	al, dx	; SB acknowledge.
  1489 00012AD1 B020                <1> 	mov	al, 20h
  1490 00012AD3 E620                <1> 	out	20h, al	; Hardware acknowledge.
  1491                              <1> 
  1492                              <1> RestoreIrqs:
  1493                              <1> 	; ah = 0 -> reset IRQ vector
  1494                              <1> 	; al = IRQ number
  1495                              <1> 	;mov	ax, 3 ; IRQ 3
  1496                              <1> 	;call	set_hardware_int_vector
  1497                              <1> 	;mov	ax, 4 ; IRQ 4
  1498                              <1> 	;call	set_hardware_int_vector
  1499 00012AD5 66B80500            <1> 	mov	ax, 5 ; IRQ 5
  1500 00012AD9 E87EDDFFFF          <1> 	call	set_hardware_int_vector
  1501 00012ADE 66B80700            <1> 	mov	ax, 7 ; IRQ 7
  1502 00012AE2 E875DDFFFF          <1> 	call	set_hardware_int_vector
  1503                              <1> 
  1504 00012AE7 31D2                <1> 	xor	edx, edx
  1505 00012AE9 8915[60760100]      <1> 	mov	[audio_dev_id], edx ; 0
  1506 00012AEF 8915[64760100]      <1> 	mov	[audio_vendor], edx ; 0
  1507 00012AF5 8915[68760100]      <1> 	mov	[audio_stats_cmd], edx ; 0
  1508                              <1> 
  1509                              <1> 	;popad
  1510                              <1> 
  1511 00012AFB 803D[5B760100]01    <1> 	cmp     byte [audio_intr], 1 ; IRQ level was changed?
  1512                              <1> 	
  1513 00012B02 C3                  <1> 	retn
  1514                              <1> 
  1515                              <1> %macro	SbOut	1
  1516                              <1> %%Wait:
  1517                              <1> 	in	al, dx
  1518                              <1> 	or	al, al
  1519                              <1> 	js	short %%Wait
  1520                              <1> 	mov	al, %1
  1521                              <1> 	out	dx, al
  1522                              <1> %endmacro
  1523                              <1> 
  1524                              <1> SbInit_play:
  1525                              <1> 	; 22/10/2017
  1526                              <1> 	; 20/10/2017
  1527                              <1> 	; 06/10/2017
  1528                              <1> 	; 13/07/2017, 09/08/2017
  1529                              <1> 	; 24/04/2017, 15/05/2017, 24/06/2017
  1530                              <1> 	;pushad
  1531                              <1> SetBuffer:
  1532                              <1> 	;mov	byte [DmaFlag], 0
  1533                              <1> 
  1534 00012B03 8B1D[78760100]      <1> 	mov	ebx, [audio_dma_buff] ; physical addr of DMA buff
  1535 00012B09 89DF                <1> 	mov	edi, ebx
  1536 00012B0B 8B0D[7C760100]      <1> 	mov     ecx, [audio_dmabuff_size]
  1537                              <1> 
  1538 00012B11 803D[88760100]10    <1> 	cmp	byte [audio_bps], 16
  1539 00012B18 7531                <1> 	jne	short sbInit_0 ; set 8 bit DMA buffer
  1540                              <1> 	
  1541                              <1> 	; 09/08/2017
  1542                              <1> 	; convert byte count to word count
  1543 00012B1A D1E9                <1> 	shr	ecx, 1
  1544 00012B1C 49                  <1> 	dec	ecx ; word count - 1
  1545                              <1> 	; convert byte offset to word offset
  1546 00012B1D D1EB                <1> 	shr	ebx, 1
  1547                              <1> 
  1548                              <1> 	; 16 bit DMA buffer setting (DMA channel 5)
  1549 00012B1F B005                <1> 	mov     al, 05h  ; set mask bit for channel 5  (4+1)
  1550 00012B21 E6D4                <1> 	out	0D4h, al
  1551                              <1> 	
  1552 00012B23 30C0                <1> 	xor     al, al   ; stops all DMA processes on selected channel
  1553 00012B25 E6D8                <1> 	out	0D8h, al ; clear selected channel register
  1554                              <1> 
  1555 00012B27 88D8                <1> 	mov     al, bl	 ; byte 0 of DMA buffer offset in words (physical) 
  1556 00012B29 E6C4                <1> 	out	0C4h, al ; DMA channel 5 port number
  1557                              <1> 
  1558 00012B2B 88F8                <1> 	mov     al, bh   ; byte 1 of DMA buffer offset in words (physical)   
  1559 00012B2D E6C4                <1> 	out	0C4h, al
  1560                              <1> 	
  1561                              <1> 	; 09/08/2017
  1562 00012B2F C1EB0F              <1> 	shr	ebx, 15	 ; complete 16 bit shift
  1563 00012B32 80E3FE              <1> 	and	bl, 0FEh ; clear bit 0 (not necessary, it will be ignored)
  1564                              <1> 
  1565 00012B35 88D8                <1> 	mov     al, bl   ; byte 2 of DMA buffer address (physical) 
  1566 00012B37 E68B                <1> 	out	8Bh, al  ; page register port addr for channel 5 ; 13/07/2017
  1567                              <1> 
  1568 00012B39 88C8                <1> 	mov     al, cl   ; low byte of DMA count - 1
  1569 00012B3B E6C6                <1> 	out	0C6h, al ; count register port addr for channel 1
  1570                              <1> 
  1571 00012B3D 88E8                <1> 	mov     al, ch   ; high byte of DMA count - 1
  1572 00012B3F E6C6                <1> 	out	0C6h, al
  1573                              <1> 
  1574                              <1> 	; channel 5, read, autoinitialized, single mode
  1575                              <1> 	;mov	al, 49h
  1576 00012B41 B059                <1> 	mov	al, 59h  ; 06/10/2017 
  1577 00012B43 E6D6                <1> 	out	0D6h, al ; DMA mode register port address
  1578                              <1> 
  1579 00012B45 B001                <1> 	mov     al, 01h  ; clear mask bit for channel 1
  1580 00012B47 E6D4                <1> 	out	0D4h, al ; DMA mask register port address
  1581                              <1> 
  1582 00012B49 EB28                <1> 	jmp	short ClearBuffer
  1583                              <1> 
  1584                              <1> sbInit_0:    
  1585 00012B4B 49                  <1> 	dec     ecx ; 09/08/2017
  1586                              <1> 
  1587                              <1> 	; 8 bit DMA buffer setting (DMA channel 1)
  1588 00012B4C B005                <1> 	mov     al, 05h ; set mask bit for channel 1  (4+1)
  1589 00012B4E E60A                <1> 	out	0Ah, al ; DMA mask register
  1590                              <1> 
  1591 00012B50 30C0                <1> 	xor     al, al  ; stops all DMA processes on selected channel
  1592 00012B52 E60C                <1> 	out	0Ch, al ; clear selected channel register
  1593                              <1> 
  1594 00012B54 88D8                <1> 	mov     al, bl	; byte 0 of DMA buffer address (physical)   
  1595 00012B56 E602                <1> 	out	02h, al ; DMA channel 1 port number
  1596                              <1> 
  1597 00012B58 88F8                <1> 	mov     al, bh  ; byte 1 of DMA buffer address (physical)   
  1598 00012B5A E602                <1> 	out	02h, al
  1599                              <1> 
  1600 00012B5C C1EB10              <1> 	shr	ebx, 16
  1601                              <1> 
  1602 00012B5F 88D8                <1> 	mov     al, bl  ; byte 2 of DMA buffer address (physical)   
  1603 00012B61 E683                <1> 	out	83h, al ; page register port addr for channel 1
  1604                              <1> 
  1605 00012B63 88C8                <1> 	mov     al, cl  ; low byte of DMA count - 1
  1606 00012B65 E603                <1> 	out	03h, al ; count register port addr for channel 1
  1607                              <1> 
  1608 00012B67 88E8                <1> 	mov     al, ch  ; high byte of DMA count - 1
  1609 00012B69 E603                <1> 	out	03h, al
  1610                              <1> 
  1611                              <1> 	; channel 1, read, autoinitialized, single mode
  1612                              <1> 	;mov	al, 49h
  1613 00012B6B B059                <1> 	mov	al, 59h ; 06/10/2017 
  1614 00012B6D E60B                <1> 	out	0Bh, al ; DMA mode register port address
  1615                              <1> 
  1616 00012B6F B001                <1> 	mov     al, 01h ; clear mask bit for channel 1
  1617 00012B71 E60A                <1> 	out	0Ah, al ; DMA mask register port address
  1618                              <1> 
  1619                              <1> ClearBuffer:
  1620                              <1> 	;;mov	edi, [audio_dma_buff]
  1621                              <1> 	;;mov	ecx, [audio_dmabuff_size]
  1622                              <1> 	;inc	ecx
  1623                              <1> 	;mov     al, 80h
  1624                              <1> 	;;cld
  1625                              <1> 	;rep     stosb
  1626                              <1> SetIrq:
  1627                              <1> 	;mov	ebx, SbIrqhandler
  1628                              <1> 	;mov	al, [audio_intr] ; IRQ number	
  1629                              <1> 	;call	set_dev_IRQ_service
  1630                              <1> 	;; SETUP (audio) INTERRUPT CALLBACK SERVICE
  1631                              <1> 	;mov	bl, [audio_intr] ; IRQ number
  1632                              <1> 	;mov	bh, [audio_cb_mode]
  1633                              <1> 	;inc	bh  ; 1 = Signal Response Byte method (fixed value)
  1634                              <1> 	;	    ; 2 = Callback service method
  1635                              <1> 	;	    ; 3 = Auto Increment S.R.B. method 	
  1636                              <1> 	;mov	cl, [audio_srb]
  1637                              <1> 	;mov	edx, [audio_cb_addr]
  1638                              <1> 	;mov	al, [audio_user]
  1639                              <1>  	;call	set_irq_callback_service
  1640                              <1> ResetDsp:
  1641 00012B73 668B15[5E760100]    <1> 	mov     dx, [audio_io_base]
  1642 00012B7A 6683C206            <1> 	add     dx, 06h
  1643 00012B7E B001                <1> 	mov     al, 1
  1644 00012B80 EE                  <1> 	out	dx, al
  1645                              <1> 
  1646 00012B81 EC                  <1> 	in	al, dx
  1647 00012B82 EC                  <1> 	in	al, dx
  1648 00012B83 EC                  <1> 	in	al, dx
  1649 00012B84 EC                  <1> 	in	al, dx
  1650                              <1> 
  1651 00012B85 30C0                <1> 	xor     al, al
  1652 00012B87 EE                  <1> 	out	dx, al
  1653                              <1> 
  1654 00012B88 66B96400            <1> 	mov     cx, 100
  1655 00012B8C 28E4                <1> 	sub	ah, ah ; 0
  1656                              <1> WaitId:         
  1657 00012B8E 668B15[5E760100]    <1> 	mov     dx, [audio_io_base]
  1658 00012B95 6683C20E            <1> 	add     dx, 0Eh
  1659 00012B99 EC                  <1> 	in	al, dx
  1660 00012B9A 08C0                <1> 	or      al, al
  1661 00012B9C 7807                <1> 	js      short sb_GetId
  1662 00012B9E E2EE                <1> 	loop    WaitId
  1663 00012BA0 E9B4000000          <1> 	jmp     sb_Exit
  1664                              <1> sb_GetId:
  1665 00012BA5 668B15[5E760100]    <1> 	mov     dx, [audio_io_base]
  1666 00012BAC 6683C20A            <1> 	add     dx, 0Ah
  1667 00012BB0 EC                  <1> 	in	al, dx
  1668 00012BB1 3CAA                <1> 	cmp     al, 0AAh
  1669 00012BB3 7407                <1> 	je      short SbOk
  1670 00012BB5 E2D7                <1> 	loop    WaitId
  1671 00012BB7 E99D000000          <1> 	jmp	sb_Exit
  1672                              <1> SbOk:
  1673 00012BBC 668B15[5E760100]    <1> 	mov     dx, [audio_io_base]
  1674 00012BC3 6683C20C            <1> 	add     dx, 0Ch
  1675                              <1> 	SbOut   0D1h ; Turn on speaker
  1675                              <2> %%Wait:
  1675 00012BC7 EC                  <2>  in al, dx
  1675 00012BC8 08C0                <2>  or al, al
  1675 00012BCA 78FB                <2>  js short %%Wait
  1675 00012BCC B0D1                <2>  mov al, %1
  1675 00012BCE EE                  <2>  out dx, al
  1676                              <1> 	SbOut   41h ; 8 bit or 16 bit transfer
  1676                              <2> %%Wait:
  1676 00012BCF EC                  <2>  in al, dx
  1676 00012BD0 08C0                <2>  or al, al
  1676 00012BD2 78FB                <2>  js short %%Wait
  1676 00012BD4 B041                <2>  mov al, %1
  1676 00012BD6 EE                  <2>  out dx, al
  1677 00012BD7 668B1D[8A760100]    <1> 	mov	bx, [audio_freq] ; sampling rate (Hz)
  1678                              <1> 	SbOut	bh ; sampling rate high byte
  1678                              <2> %%Wait:
  1678 00012BDE EC                  <2>  in al, dx
  1678 00012BDF 08C0                <2>  or al, al
  1678 00012BE1 78FB                <2>  js short %%Wait
  1678 00012BE3 88F8                <2>  mov al, %1
  1678 00012BE5 EE                  <2>  out dx, al
  1679                              <1> 	SbOut	bl ; sampling rate low byte
  1679                              <2> %%Wait:
  1679 00012BE6 EC                  <2>  in al, dx
  1679 00012BE7 08C0                <2>  or al, al
  1679 00012BE9 78FB                <2>  js short %%Wait
  1679 00012BEB 88D8                <2>  mov al, %1
  1679 00012BED EE                  <2>  out dx, al
  1680                              <1> 
  1681                              <1> 	; 22/05/2017
  1682 00012BEE E8C0000000          <1> 	call	sb16_volume_initial ; 15/05/2017
  1683                              <1> 	; 20/05/2017
  1684                              <1> 	;call	sb16_volume
  1685                              <1> 
  1686                              <1> StartDma:  
  1687                              <1> 	; autoinitialized mode
  1688 00012BF3 803D[88760100]10    <1> 	cmp	byte [audio_bps], 16 ; 16 bit samples
  1689 00012BFA 7411                <1> 	je	short sb_play_1
  1690                              <1> 	; 8 bit samples
  1691 00012BFC 66BBC600            <1> 	mov	bx, 0C6h ; 8 bit output (0C6h)
  1692 00012C00 803D[89760100]02    <1> 	cmp	byte [audio_stmo], 2 ; 1 = mono, 2 = stereo
  1693 00012C07 7214                <1> 	jb	short sb_play_2
  1694 00012C09 B720                <1> 	mov	bh, 20h	; 8 bit stereo (20h)
  1695 00012C0B EB10                <1> 	jmp	short sb_play_2
  1696                              <1> sb_play_1:
  1697                              <1> 	; 16 bit samples
  1698 00012C0D 66BBB610            <1> 	mov	bx, 10B6h ; 16 bit output (0B6h)
  1699 00012C11 803D[89760100]02    <1> 	cmp	byte [audio_stmo], 2 ; 1 = mono, 2 = stereo
  1700 00012C18 7203                <1> 	jb	short sb_play_2
  1701 00012C1A 80C720              <1> 	add	bh, 20h	; 16 bit stereo (30h)
  1702                              <1> sb_play_2:     
  1703                              <1> 	; PCM output (8/16 bit mono autoinitialized transfer)
  1704                              <1> 	SbOut   bl ; bCommand
  1704                              <2> %%Wait:
  1704 00012C1D EC                  <2>  in al, dx
  1704 00012C1E 08C0                <2>  or al, al
  1704 00012C20 78FB                <2>  js short %%Wait
  1704 00012C22 88D8                <2>  mov al, %1
  1704 00012C24 EE                  <2>  out dx, al
  1705                              <1> 	SbOut	bh ; bMode
  1705                              <2> %%Wait:
  1705 00012C25 EC                  <2>  in al, dx
  1705 00012C26 08C0                <2>  or al, al
  1705 00012C28 78FB                <2>  js short %%Wait
  1705 00012C2A 88F8                <2>  mov al, %1
  1705 00012C2C EE                  <2>  out dx, al
  1706 00012C2D 8B1D[7C760100]      <1> 	mov	ebx, [audio_dmabuff_size]  ; 15/05/2017
  1707 00012C33 D1EB                <1> 	shr	ebx, 1 ; half buffer size
  1708                              <1> 	; 20/10/2017	
  1709 00012C35 803D[88760100]10    <1> 	cmp	byte [audio_bps], 16 ; 16 bit DMA
  1710 00012C3C 7502                <1> 	jne	short sb_play_3
  1711 00012C3E D1EB                <1> 	shr	ebx, 1 ; byte count to word count
  1712                              <1> sb_play_3: 
  1713 00012C40 664B                <1> 	dec	bx  ; wBlkSize is one less than the actual size 
  1714                              <1> 	SbOut   bl
  1714                              <2> %%Wait:
  1714 00012C42 EC                  <2>  in al, dx
  1714 00012C43 08C0                <2>  or al, al
  1714 00012C45 78FB                <2>  js short %%Wait
  1714 00012C47 88D8                <2>  mov al, %1
  1714 00012C49 EE                  <2>  out dx, al
  1715                              <1> 	SbOut   bh
  1715                              <2> %%Wait:
  1715 00012C4A EC                  <2>  in al, dx
  1715 00012C4B 08C0                <2>  or al, al
  1715 00012C4D 78FB                <2>  js short %%Wait
  1715 00012C4F 88F8                <2>  mov al, %1
  1715 00012C51 EE                  <2>  out dx, al
  1716                              <1> 
  1717 00012C52 C605[8C760100]01    <1> 	mov	byte [audio_play_cmd], 1 ; playing !
  1718                              <1> 
  1719                              <1> 	;; Set Voice and master volumes
  1720                              <1> 	;mov	dx, [audio_io_base]
  1721                              <1> 	;add	dl, 4 ; Mixer chip Register Address Port
  1722                              <1> 	;SbOut	30h   ; select Master Volume Register (L)
  1723                              <1> 	;inc	dl    ; Mixer chip Register Data Port
  1724                              <1> 	;SbOut	0F8h  ; Max. volume value is 31 (31*8)
  1725                              <1> 	;dec	dl
  1726                              <1> 	;SbOut	31h   ; select Master Volume Register (R)
  1727                              <1> 	;inc	dl
  1728                              <1> 	;SbOut	0F8h  ; Max. volume value is 31 (31*8)
  1729                              <1> 	;dec	dl
  1730                              <1> 	;SbOut	32h   ; select Voice Volume Register (L)
  1731                              <1> 	;inc	dl
  1732                              <1> 	;SbOut	0F8h  ; Max. volume value is 31 (31*8)
  1733                              <1> 	;dec	dl
  1734                              <1> 	;SbOut	33h   ; select Voice Volume Register (R)
  1735                              <1> 	;inc	dl
  1736                              <1> 	;SbOut	0F8h  ; Max. volume value is 31 (31*8)	
  1737                              <1> 	;;
  1738                              <1> 	;dec	dl
  1739                              <1> 	;SbOut	44h   ; select Treble Register (L)
  1740                              <1> 	;inc	dl
  1741                              <1> 	;SbOut	0F0h  ; Max. Treble value is 15 (15*16)
  1742                              <1> 	;dec	dl
  1743                              <1> 	;SbOut	45h   ; select Treble Register (R)
  1744                              <1> 	;inc	dl
  1745                              <1> 	;SbOut	0F0h  ; Max. Treble value is 15 (15*16)
  1746                              <1> 	;dec	dl
  1747                              <1> 	;SbOut	46h   ; select Bass Register (L)
  1748                              <1> 	;inc	dl
  1749                              <1> 	;SbOut	0F0h  ; Max. Bass value is 15 (15*16)
  1750                              <1> 	;dec	dl
  1751                              <1> 	;SbOut	47h   ; select Bass Register (R)
  1752                              <1> 	;inc	dl
  1753                              <1> 	;SbOut	0F0h  ; Max. Bass value is 15 (15*16)	
  1754                              <1> 
  1755                              <1> sb_Exit:           
  1756                              <1> 	;popad
  1757 00012C59 C3                  <1> 	retn
  1758                              <1> 
  1759                              <1> sb16_int_handler:
  1760                              <1> 	; Interrupt Handler for Sound Blaster 16 Audio Card
  1761                              <1> 	; Note: called by 'dev_IRQ_service'
  1762                              <1> 	; 20/10/2017
  1763                              <1> 	; 12/10/2017
  1764                              <1> 	; 10/10/2017 
  1765                              <1> 	; 12/05/2017, 09/10/2017
  1766                              <1> 	; 24/04/2017 (TRDOS 386 kernel, 'audio.s')
  1767                              <1> 	; 10/03/2017 - 'PLAYWAV.PRG' ('playwav.s') 
  1768                              <1> 
  1769                              <1> 	;push	eax ; * must be saved !
  1770                              <1> 	;push	ebx ; * must be saved !
  1771                              <1> 	;push	ecx
  1772                              <1> 	;push	edx
  1773                              <1> 	;push	esi
  1774                              <1> 	;push	edi
  1775                              <1> 
  1776 00012C5A 668B15[5E760100]    <1> 	mov     dx, [audio_io_base]
  1777                              <1> 	; 20/10/2017
  1778 00012C61 80C20F              <1> 	add     dl, 0Fh ; 2xFh (DSP 16 bit intr ack)
  1779 00012C64 803D[88760100]10    <1> 	cmp	byte [audio_bps], 16
  1780 00012C6B 7402                <1> 	je	short sb_irq_16bit_ack
  1781                              <1> sb_irq_8bit_ack:
  1782 00012C6D FECA                <1> 	dec	dl  ; 2xEh (DSP 8 bit intr ack)
  1783                              <1> sb_irq_16bit_ack:
  1784 00012C6F EC                  <1> 	in	al, dx
  1785                              <1> 
  1786                              <1> 	;cmp	byte [audio_busy], 0
  1787                              <1> 	;ja	short sb_irq_h3
  1788                              <1> 
  1789                              <1> 	;mov	byte [audio_busy], 1
  1790                              <1> 
  1791 00012C70 803D[8C760100]01    <1> 	cmp	byte [audio_play_cmd], 1
  1792 00012C77 7307                <1> 	jnb	short sb_irq_h1
  1793                              <1> sb_irq_h0:
  1794 00012C79 E8A9000000          <1> 	call	sb16_stop
  1795 00012C7E EB2B                <1> 	jmp	short sb_irq_h3
  1796                              <1> sb_irq_h1:
  1797                              <1> 	;call	sb16_tuneloop
  1798                              <1> 	; 09/10/2017
  1799                              <1> sb16_tuneloop:
  1800 00012C80 8B3D[78760100]      <1> 	mov	edi, [audio_dma_buff]
  1801 00012C86 8B0D[7C760100]      <1> 	mov	ecx, [audio_dmabuff_size]
  1802 00012C8C D1E9                <1> 	shr	ecx, 1 ; dma buff size / 2 = half buffer size
  1803                              <1> 
  1804                              <1> 	; 22/05/2017
  1805 00012C8E F605[80760100]01    <1> 	test	byte [audio_flag], 1  ; Current flag value
  1806 00012C95 7402                <1> 	jz	short sb_tlp1 ; EOL (Half Buffer 1 must be filled)
  1807                              <1> 	; FLAG (Half Buffer 2 must be filled)
  1808 00012C97 01CF                <1> 	add	edi, ecx
  1809                              <1> 	; 15/05/2017
  1810                              <1> sb_tlp1: 
  1811 00012C99 8B35[70760100]      <1> 	mov	esi, [audio_p_buffer] ; phy addr of audio buff
  1812                              <1> 	;rep	movsb
  1813 00012C9F C1E902              <1> 	shr	ecx, 2 ; half buff size / 4
  1814 00012CA2 F3A5                <1> 	rep	movsd 
  1815                              <1> 	;retn
  1816                              <1> 
  1817                              <1> 	; 10/10/2017
  1818                              <1> 	; switch flag value
  1819 00012CA4 8035[80760100]01    <1> 	xor	byte [audio_flag], 1
  1820                              <1> 
  1821                              <1> 	; 12/10/2017
  1822                              <1> 	; [audio_flag] = 0 : Playing dma half buffer 2 (odd intr count)
  1823                              <1> 			   ; Next buffer (to update) is dma half buff 1
  1824                              <1> 	; 	       = 1 : Playing dma half buffer 1 (even intr count)
  1825                              <1> 			   ; Next buffer (to update) is dma half buff 2
  1826                              <1> 
  1827                              <1> sb_irq_h3:
  1828                              <1> 	;mov	byte [audio_busy], 0
  1829                              <1> 
  1830                              <1> 	;pop	edi
  1831                              <1> 	;pop	esi
  1832                              <1> 	;pop	edx
  1833                              <1> 	;pop	ecx
  1834                              <1> 	;pop	ebx ; * must be restored !
  1835                              <1> 	;pop	eax ; * must be restored !
  1836                              <1> 	
  1837 00012CAB C3                  <1> 	retn
  1838                              <1> 
  1839                              <1> sb16_volume:
  1840                              <1> 	; 22/10/2017
  1841                              <1> 	; mov [audio_master_volume_l], cl 
  1842                              <1> 	; mov [audio_master_volume_h], ch 
  1843 00012CAC 66890D[8E760100]    <1> 	mov	[audio_master_volume], cx
  1844                              <1> sb16_volume_initial:
  1845 00012CB3 6652                <1> 	push	dx ; DX (port address) must be saved
  1846 00012CB5 668B15[5E760100]    <1> 	mov	dx, [audio_io_base]
  1847 00012CBC 6683C204            <1> 	add	dx, 4 ; Mixer chip address port
  1848 00012CC0 B022                <1> 	mov	al, 22h ; master volume
  1849 00012CC2 EE                  <1> 	out	dx, al
  1850 00012CC3 6642                <1> 	inc	dx
  1851 00012CC5 8A25[8E760100]      <1> 	mov	ah, [audio_master_volume_l]
  1852 00012CCB C0EC02              <1> 	shr	ah, 2 ; 32 -> 8 level
  1853 00012CCE C0E405              <1> 	shl	ah, 5 ; bit 5 to 7
  1854 00012CD1 A0[8F760100]        <1> 	mov	al, [audio_master_volume_r]	
  1855 00012CD6 C0E802              <1> 	shr	al, 2 ; 32 -> 8 level
  1856                              <1> 	;and	al, 0Fh
  1857 00012CD9 D0E0                <1> 	shl	al, 1 ; bit 1 to 3
  1858 00012CDB 08E0                <1> 	or	al, ah
  1859 00012CDD EE                  <1> 	out	dx, al
  1860 00012CDE 665A                <1> 	pop	dx ; DX (port address) must be restored
  1861 00012CE0 C3                  <1> 	retn
  1862                              <1> 
  1863                              <1> sb16_pause:
  1864 00012CE1 668B15[5E760100]    <1> 	mov	dx, [audio_io_base]
  1865 00012CE8 6683C20C            <1> 	add	dx, 0Ch ; Command & Data Port
  1866 00012CEC 803D[88760100]10    <1> 	cmp	byte [audio_bps], 16 ; 16 bit samples
  1867 00012CF3 7404                <1> 	je	short sb_pause_1
  1868                              <1> 	; 8 bit samples
  1869 00012CF5 B3D0                <1> 	mov	bl, 0D0h ; 8 bit DMA mode
  1870 00012CF7 EB02                <1> 	jmp	short sb_pause_2
  1871                              <1> sb_pause_1:
  1872                              <1> 	; 16 bit samples
  1873 00012CF9 B3D5                <1> 	mov	bl, 0D5h ; 16 bit DMA mode
  1874                              <1> sb_pause_2:     
  1875                              <1> 	SbOut   bl ; bCommand
  1875                              <2> %%Wait:
  1875 00012CFB EC                  <2>  in al, dx
  1875 00012CFC 08C0                <2>  or al, al
  1875 00012CFE 78FB                <2>  js short %%Wait
  1875 00012D00 88D8                <2>  mov al, %1
  1875 00012D02 EE                  <2>  out dx, al
  1876                              <1> sb_pause_3:
  1877 00012D03 C3                  <1> 	retn
  1878                              <1> 
  1879                              <1> sb16_continue:
  1880 00012D04 668B15[5E760100]    <1> 	mov	dx, [audio_io_base]
  1881 00012D0B 6683C20C            <1> 	add	dx, 0Ch ; Command & Data Port
  1882 00012D0F 803D[88760100]10    <1> 	cmp	byte [audio_bps], 16 ; 16 bit samples
  1883 00012D16 7404                <1> 	je	short sb_cont_1
  1884                              <1> 	; 8 bit samples
  1885 00012D18 B3D4                <1> 	mov	bl, 0D4h ; 8 bit DMA mode
  1886 00012D1A EB02                <1> 	jmp	short sb_cont_2
  1887                              <1> sb_cont_1:
  1888                              <1> 	; 16 bit samples
  1889 00012D1C B3D6                <1> 	mov	bl, 0D6h ; 16 bit DMA mode
  1890                              <1> sb_cont_2:     
  1891                              <1> 	SbOut   bl ; bCommand
  1891                              <2> %%Wait:
  1891 00012D1E EC                  <2>  in al, dx
  1891 00012D1F 08C0                <2>  or al, al
  1891 00012D21 78FB                <2>  js short %%Wait
  1891 00012D23 88D8                <2>  mov al, %1
  1891 00012D25 EE                  <2>  out dx, al
  1892                              <1> sb_cont_3:
  1893 00012D26 C3                  <1> 	retn
  1894                              <1> 
  1895                              <1> sb16_stop:
  1896                              <1> 	; 24/04/2017
  1897 00012D27 803D[8C760100]00    <1> 	cmp	byte [audio_play_cmd], 0
  1898 00012D2E 7648                <1> 	jna	short sb16_stop_4
  1899                              <1> 
  1900                              <1> 	; 22/05/2017
  1901 00012D30 668B15[5E760100]    <1> 	mov	dx, [audio_io_base]
  1902 00012D37 6683C20C            <1> 	add	dx, 0Ch
  1903                              <1> 
  1904 00012D3B B3D9                <1> 	mov	bl, 0D9h ; exit auto-initialize 16 bit transfer
  1905                              <1> 	; stop  autoinitialized DMA transfer mode 
  1906 00012D3D 803D[88760100]10    <1> 	cmp	byte [audio_bps], 16 ; 16 bit samples
  1907 00012D44 7402                <1> 	je	short sb16_stop_1
  1908                              <1> 	;mov	bl, 0DAh ; exit auto-initialize 8 bit transfer
  1909 00012D46 FEC3                <1> 	inc	bl
  1910                              <1> sb16_stop_1:
  1911                              <1> 	SbOut	bl ; exit auto-initialize transfer command
  1911                              <2> %%Wait:
  1911 00012D48 EC                  <2>  in al, dx
  1911 00012D49 08C0                <2>  or al, al
  1911 00012D4B 78FB                <2>  js short %%Wait
  1911 00012D4D 88D8                <2>  mov al, %1
  1911 00012D4F EE                  <2>  out dx, al
  1912                              <1> 
  1913 00012D50 30C0                <1> 	xor     al, al ; stops all DMA processes on selected channel
  1914                              <1> 
  1915 00012D52 803D[88760100]10    <1> 	cmp	byte [audio_bps], 16 ; 16 bit samples
  1916 00012D59 7404                <1> 	je	short sb16_stop_2
  1917 00012D5B E60C                <1> 	out	0Ch, al ; clear selected channel register
  1918 00012D5D EB02                <1> 	jmp	short sb16_stop_3
  1919                              <1> 
  1920                              <1> sb16_stop_2:
  1921 00012D5F E6D8                <1> 	out	0D8h, al ; clear selected channel register
  1922                              <1> 
  1923                              <1> sb16_stop_3:
  1924 00012D61 C605[8C760100]00    <1> 	mov	byte [audio_play_cmd], 0 ; stop !
  1925                              <1> SbDone:
  1926                              <1> 	;mov	dx, [audio_io_base]
  1927                              <1> 	;add	dx, 0Ch
  1928                              <1> 	SbOut   0D0h
  1928                              <2> %%Wait:
  1928 00012D68 EC                  <2>  in al, dx
  1928 00012D69 08C0                <2>  or al, al
  1928 00012D6B 78FB                <2>  js short %%Wait
  1928 00012D6D B0D0                <2>  mov al, %1
  1928 00012D6F EE                  <2>  out dx, al
  1929                              <1> 	SbOut   0D3h
  1929                              <2> %%Wait:
  1929 00012D70 EC                  <2>  in al, dx
  1929 00012D71 08C0                <2>  or al, al
  1929 00012D73 78FB                <2>  js short %%Wait
  1929 00012D75 B0D3                <2>  mov al, %1
  1929 00012D77 EE                  <2>  out dx, al
  1930                              <1> sb16_stop_4:
  1931 00012D78 C3                  <1> 	retn
  1932                              <1> 
  1933                              <1> sb16_reset:
  1934                              <1> 	; 24/04/2017      
  1935 00012D79 668B15[5E760100]    <1> 	mov     dx, [audio_io_base] ; try to reset the DSP.
  1936 00012D80 6683C206            <1> 	add     dx, 06h
  1937 00012D84 B001                <1> 	mov	al, 1
  1938 00012D86 EE                  <1> 	out	dx, al
  1939                              <1> 
  1940 00012D87 EC                  <1> 	in	al, dx
  1941 00012D88 EC                  <1> 	in	al, dx
  1942 00012D89 EC                  <1> 	in	al, dx
  1943 00012D8A EC                  <1> 	in	al, dx
  1944                              <1> 
  1945 00012D8B 30C0                <1> 	xor     al, al
  1946 00012D8D EE                  <1> 	out	dx, al
  1947                              <1> 
  1948 00012D8E 6683C208            <1> 	add     dx, 08h
  1949 00012D92 66B96400            <1> 	mov	cx, 100
  1950                              <1> sbrstWaitID:
  1951 00012D96 EC                  <1> 	in	al, dx
  1952 00012D97 08C0                <1> 	or      al, al
  1953 00012D99 7804                <1> 	js      short sbrstGetID
  1954 00012D9B E2F9                <1> 	loop    sbrstWaitID
  1955 00012D9D F9                  <1> 	stc
  1956 00012D9E C3                  <1> 	retn
  1957                              <1> sbrstGetID:          
  1958 00012D9F 6683EA04            <1> 	sub     dx, 04h
  1959 00012DA3 EC                  <1> 	in	al, dx
  1960 00012DA4 3CAA                <1> 	cmp     al, 0AAh
  1961 00012DA6 7406                <1> 	je      short sb_rst_retn
  1962 00012DA8 6683C204            <1> 	add     dx, 04h
  1963 00012DAC E2E8                <1> 	loop    sbrstWaitID
  1964                              <1> sb_rst_retn:
  1965 00012DAE C3                  <1> 	retn
  1966                              <1> 
  1967                              <1> ac97_codec_config:
  1968                              <1> 	; 10/06/2017
  1969                              <1> 	; 05/06/2017
  1970                              <1> 	; 29/05/2017
  1971                              <1> 	; 28/05/2017 (TRDOS 386, 'audio.s')
  1972                              <1> 	; 07/11/2016 (Erdogan Tan)
  1973                              <1> 	; Derived from 'codecConfig' procedure in 'CODEC.ASM'
  1974                              <1> 	; .wav player for DOS by Jeff Leyda (02/09/2002)
  1975                              <1> 
  1976                              <1> 	;; 'PLAYER.ASM'
  1977                              <1> 	;; get ICH base address regs for mixer and bus master
  1978                              <1> 
  1979                              <1> init_ac97_controller: ; 10/06/2017
  1980 00012DAF A1[60760100]        <1> 	mov	eax, [audio_dev_id]
  1981                              <1>         ;mov	al, NAMBAR_REG
  1982                              <1>         ;;call  pciRegRead16			; read PCI registers 10-11
  1983                              <1>         ;call	pciRegRead32
  1984                              <1> 	;and	dx, IO_ADDR_MASK 		; mask off BIT0
  1985                              <1> 	;;and	edx, IO_ADDR_MASK 
  1986                              <1> 
  1987                              <1>         ;mov	[NAMBAR], dx			; save audio mixer base addr
  1988                              <1> 
  1989                              <1>         ;mov    al, NABMBAR_REG
  1990                              <1>         ;;call	pciRegRead16
  1991                              <1>         ;call	pciRegRead32
  1992                              <1> 	;and	dx, 0FFC0h ; IO_ADDR_MASK
  1993                              <1> 	;;and	edx, 0FFC0h
  1994                              <1> 
  1995                              <1>         ;mov    [NABMBAR], dx			; save bus master base addr
  1996                              <1> 
  1997                              <1> 	;mov	eax, [audio_dev_id]
  1998 00012DB4 B004                <1>         mov     al, PCI_CMD_REG
  1999                              <1>         ;call	pciRegRead8			; read PCI command register
  2000 00012DB6 E84AF8FFFF          <1>         call	pciRegRead16
  2001 00012DBB 80CA05              <1> 	or      dl, IO_ENA+BM_ENA               ; enable IO and bus master
  2002                              <1>         ;call 	pciRegWrite8
  2003 00012DBE E8ADF8FFFF          <1> 	call	pciRegWrite16
  2004                              <1> 
  2005                              <1> 	; 'CODEC.ASM'
  2006                              <1> 
  2007                              <1> 	; enable codec, unmute stuff, set output rate
  2008                              <1> ;	; entry: [audio_freq] = desired sample rate
  2009                              <1> 		
  2010                              <1> ;	mov    	dx, [NAMBAR]               	
  2011                              <1> ;	add    	dx, CODEC_EXT_AUDIO_CTRL_REG  	; 2Ah  	  
  2012                              <1> ;	in     	ax, dx
  2013                              <1> ;	or	ax, 1
  2014                              <1> ;	out	dx, ax 				; Enable variable rate audio
  2015                              <1> 
  2016                              <1> ;       ;call    delay1_4ms
  2017                              <1> ;       ;call    delay1_4ms
  2018                              <1> ;       ;call    delay1_4ms
  2019                              <1> ;       ;call    delay1_4ms
  2020                              <1> 
  2021                              <1> ;	mov	ax, [audio_freq]		; sample rate
  2022                              <1> 
  2023                              <1> ;	mov    	dx, [NAMBAR]               	
  2024                              <1> ;	add    	dx, CODEC_PCM_FRONT_DACRATE_REG	; 2Ch  	  
  2025                              <1> ;	out	dx, ax 				; out sample rate
  2026                              <1> 		
  2027                              <1> ;       ;call	delay1_4ms
  2028                              <1> ;       ;call	delay1_4ms
  2029                              <1> ;       ;call	delay1_4ms
  2030                              <1> ;       ;call	delay1_4ms
  2031                              <1> 
  2032                              <1> 	;mov	dx, [NAMBAR]			; mixer base address
  2033                              <1>         ;add	dx, CODEC_RESET_REG  		; reset register
  2034                              <1>         ;mov	ax, 42
  2035                              <1> 	;out	dx, ax                          ; reset
  2036                              <1> 
  2037                              <1> 	;mov    dx, [NABMBAR]			; bus master base address
  2038                              <1>         ;add	dx, GLOB_STS_REG
  2039                              <1>         ;mov	ax, 2
  2040                              <1> 	;out	dx, ax                         
  2041                              <1> 
  2042 00012DC3 E847F9FFFF          <1>         call    delay_100ms ; 29/05/2017
  2043                              <1> 
  2044                              <1> init_ac97_codec:
  2045                              <1> 	; 10/06/2017
  2046                              <1> 	; 29/05/2017
  2047                              <1> 	; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm)
  2048                              <1> 	;	
  2049 00012DC8 66BA2C00            <1> 	mov	dx, GLOB_CNT_REG ; 2Ch
  2050 00012DCC 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2051 00012DD3 ED                  <1> 	in	eax, dx
  2052                              <1> 	; ?
  2053 00012DD4 66BA3000            <1> 	mov	dx, GLOB_STS_REG ; 30h
  2054 00012DD8 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2055 00012DDF ED                  <1> 	in	eax, dx
  2056                              <1> 
  2057 00012DE0 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh ; -1
  2058 00012DE3 744B                <1> 	je	short init_ac97_codec_err1
  2059                              <1> 
  2060 00012DE5 A900030010          <1> 	test	eax, CTRL_ST_CREADY
  2061 00012DEA 7507                <1> 	jnz	short _ac97_codec_ready
  2062                              <1> 
  2063 00012DEC E8EF020000          <1> 	call	reset_ac97_codec
  2064 00012DF1 723E                <1> 	jc	short init_ac97_codec_err2
  2065                              <1> 
  2066                              <1> _ac97_codec_ready:
  2067 00012DF3 668B15[90760100]    <1> 	mov	dx, [NAMBAR]
  2068                              <1> 	;add	dx, 0 ; ac_reg_0 ; reset register
  2069 00012DFA 66EF                <1> 	out	dx, ax
  2070                              <1> 
  2071 00012DFC 31C0                <1> 	xor	eax, eax ; 0
  2072 00012DFE 668B15[90760100]    <1> 	mov	dx, [NAMBAR]
  2073 00012E05 6683C226            <1> 	add	dx, CODEC_REG_POWERDOWN	
  2074 00012E09 66EF                <1> 	out	dx, ax
  2075                              <1> 
  2076                              <1> 	; 10/06/2017
  2077                              <1> 	; 29/05/2017
  2078                              <1> 	; wait for 1 second
  2079 00012E0B B9E8030000          <1> 	mov	ecx, 1000 ; 1000*0.25ms = 1s
  2080                              <1> _ac97_codec_rloop:
  2081 00012E10 E807F9FFFF          <1> 	call	delay1_4ms
  2082 00012E15 E802F9FFFF          <1> 	call	delay1_4ms
  2083 00012E1A E8FDF8FFFF          <1> 	call	delay1_4ms
  2084 00012E1F E8F8F8FFFF          <1> 	call	delay1_4ms
  2085                              <1> 	;mov	dx, [NAMBAR]
  2086                              <1> 	;add	dx, CODEC_REG_POWERDOWN
  2087 00012E24 66ED                <1> 	in	ax, dx	
  2088 00012E26 6683E00F            <1> 	and	ax, 0Fh
  2089 00012E2A 3C0F                <1> 	cmp	al, 0Fh
  2090 00012E2C 7404                <1> 	je	short _ac97_codec_init_ok
  2091 00012E2E E2E0                <1> 	loop	_ac97_codec_rloop 
  2092                              <1> 
  2093                              <1> init_ac97_codec_err1:
  2094 00012E30 F9                  <1> 	stc
  2095                              <1> init_ac97_codec_err2:
  2096 00012E31 C3                  <1> 	retn
  2097                              <1> 
  2098                              <1> _ac97_codec_init_ok:
  2099 00012E32 B002                <1>         mov     al, 2 ; force set 16-bit 2-channel PCM
  2100 00012E34 66BA2C00            <1> 	mov	dx, GLOB_CNT_REG ; 2Ch
  2101 00012E38 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2102 00012E3F EF                  <1> 	out	dx, eax
  2103                              <1> 
  2104                              <1> 	;call	delay1_4ms
  2105                              <1> 
  2106                              <1> 	; 10/06/2017
  2107 00012E40 E849020000          <1> 	call 	reset_ac97_controller
  2108                              <1> 
  2109                              <1> ;	call 	setup_ac97_codec
  2110                              <1> ;
  2111                              <1> ;detect_ac97_codec:
  2112                              <1> ;	retn
  2113                              <1> 
  2114                              <1> setup_ac97_codec:
  2115                              <1> 	; 22/07/2020
  2116                              <1> 	; 10/06/2017
  2117                              <1> 	; 29/05/2017
  2118 00012E45 B802020000          <1> 	mov     eax, 0202h
  2119 00012E4A 66A3[8E760100]      <1> 	mov	[audio_master_volume], ax
  2120 00012E50 66B81F1F            <1> 	mov	ax, 1F1Fh ; 31, 31
  2121                              <1> 	
  2122 00012E54 668B15[90760100]    <1>   	mov     dx, [NAMBAR]
  2123 00012E5B 6683C202            <1>   	add     dx, CODEC_MASTER_VOL_REG	;02h 
  2124 00012E5F 6631C0              <1>   	xor	ax, ax 	; volume attenuation = 0 (max. volume)
  2125 00012E62 66EF                <1>   	out     dx, ax
  2126                              <1>  
  2127 00012E64 668B15[90760100]    <1>   	mov     dx, [NAMBAR]
  2128 00012E6B 6683C206            <1>   	add     dx, CODEC_MASTER_MONO_VOL_REG	;06h 
  2129                              <1> 	;xor	ax, ax
  2130 00012E6F 66EF                <1>   	out     dx, ax
  2131                              <1> 
  2132 00012E71 668B15[90760100]    <1>   	mov     dx, [NAMBAR]
  2133 00012E78 6683C20A            <1>   	add     dx, CODEC_PCBEEP_VOL_REG	;0Ah 
  2134                              <1>   	;xor    ax, ax
  2135 00012E7C 66EF                <1>   	out     dx, ax
  2136                              <1> 
  2137 00012E7E 668B15[90760100]    <1>   	mov     dx, [NAMBAR]
  2138 00012E85 6683C218            <1>   	add     dx, CODEC_PCM_OUT_REG		;18h 
  2139                              <1>   	;xor    ax, ax
  2140 00012E89 66EF                <1>   	out     dx, ax
  2141                              <1> 
  2142 00012E8B 66B80880            <1> 	mov     ax, 8008h ; Mute
  2143 00012E8F 668B15[90760100]    <1>   	mov     dx, [NAMBAR]
  2144                              <1> 	; 22/07/2020
  2145 00012E96 6683C20C            <1> 	add	dx, CODEC_PHONE_VOL_REG		;0Ch
  2146                              <1> 				 ; AC97_PHONE_VOL ; TAD Input (Mono)
  2147 00012E9A 66EF                <1>   	out     dx, ax
  2148                              <1> 
  2149 00012E9C 66B80808            <1>         mov	ax, 0808h
  2150 00012EA0 668B15[90760100]    <1>   	mov     dx, [NAMBAR]
  2151 00012EA7 6683C210            <1>         add	dx, CODEC_LINE_IN_VOL_REG ;10h ; Line Input (Stereo)	
  2152 00012EAB 66EF                <1>   	out     dx, ax
  2153                              <1> 
  2154                              <1> 	;mov	ax, 0808h
  2155 00012EAD 668B15[90760100]    <1>   	mov     dx, [NAMBAR]
  2156 00012EB4 6683C212            <1>         add	dx, CODEC_CD_VOL_REG ;12h ; CR Input (Stereo)
  2157 00012EB8 66EF                <1>   	out     dx, ax
  2158                              <1> 
  2159                              <1> 	;mov	ax, 0808h
  2160 00012EBA 668B15[90760100]    <1>   	mov     dx, [NAMBAR]
  2161 00012EC1 6683C216            <1>         add	dx, CODEC_AUX_VOL_REG ;16h ; Aux Input (Stereo)
  2162 00012EC5 66EF                <1>   	out     dx, ax
  2163                              <1> 
  2164                              <1>         ;call    delay1_4ms
  2165                              <1>         ;call    delay1_4ms
  2166                              <1>         ;call    delay1_4ms
  2167                              <1>         ;call    delay1_4ms
  2168                              <1> 
  2169                              <1> detect_ac97_codec:
  2170 00012EC7 C3                  <1>         retn
  2171                              <1> 
  2172                              <1> set_ac97_bdl: ; Set AC97 (ICH) Buffer Descriptor List
  2173                              <1> 	; 17/06/2017
  2174                              <1> 	; 11/06/2017
  2175                              <1> 	; 28/05/2017
  2176                              <1> 	; eax = dma buffer address = [audio_DMA_buff]
  2177                              <1> 	; ecx = dma buffer buffer size = [audio_dmabuff_size]
  2178                              <1> 
  2179 00012EC8 D1E9                <1> 	shr	ecx, 1 ; dma half buffer size
  2180 00012ECA 89CE                <1> 	mov	esi, ecx
  2181                              <1> 
  2182 00012ECC BF[94760100]        <1>         mov     edi, audio_bdl_buff	; get BDL address
  2183 00012ED1 B910000000          <1>         mov     ecx, 32 / 2		; make 32 entries in BDL
  2184                              <1> 
  2185 00012ED6 EB05                <1> 	jmp	short s_ac97_bdl1 
  2186                              <1> 
  2187                              <1> s_ac97_bdl0:
  2188                              <1> 	; set buffer descriptor 0 to start of data file in memory
  2189                              <1> 
  2190 00012ED8 A1[78760100]        <1>  	mov	eax, [audio_dma_buff]	; Physical address of DMA buffer
  2191                              <1>  
  2192                              <1> s_ac97_bdl1:
  2193 00012EDD AB                  <1> 	stosd				; store dmabuffer1 address
  2194                              <1> 
  2195 00012EDE 89C2                <1> 	mov	edx, eax
  2196                              <1> 
  2197                              <1> ;
  2198                              <1> ; Buffer Descriptors List
  2199                              <1> ; As stated earlier, each buffer descriptor list is a set of (up to) 32 
  2200                              <1> ; descriptors, each 8 bytes in length. Bytes 0-3 of a descriptor entry point
  2201                              <1> ; to a chunk of memory to either play from or record to. Bytes 4-7 of an
  2202                              <1> ; entry describe various control things detailed below.
  2203                              <1> ; 
  2204                              <1> ; Buffer pointers must always be aligned on a Dword boundry.
  2205                              <1> ;
  2206                              <1> ;
  2207                              <1> 
  2208                              <1> ;IOC                     equ     BIT31	; Fire an interrupt whenever this
  2209                              <1>                                         ; buffer is complete.
  2210                              <1> 
  2211                              <1> ;BUP                     equ     BIT30  ; Buffer Underrun Policy.
  2212                              <1>                                         ; if this buffer is the last buffer
  2213                              <1>                                         ; in a playback, fill the remaining
  2214                              <1>                                         ; samples with 0 (silence) or not.
  2215                              <1>                                         ; It's a good idea to set this to 1
  2216                              <1>                                         ; for the last buffer in playback,
  2217                              <1>                                         ; otherwise you're likely to get a lot
  2218                              <1>                                         ; of noise at the end of the sound.
  2219                              <1> 
  2220                              <1> ;
  2221                              <1> ; Bits 15:0 contain the length of the buffer, in number of samples, which
  2222                              <1> ; are 16 bits each, coupled in left and right pairs, or 32bits each.
  2223                              <1> ; Luckily for us, that's the same format as .wav files.
  2224                              <1> ;
  2225                              <1> ; A value of FFFF is 65536 samples. Running at 44.1Khz, that's just about
  2226                              <1> ; 1.5 seconds of sample time. FFFF * 32bits is 1FFFFh bytes or 128k of data.
  2227                              <1> ;
  2228                              <1> ; A value of 0 in these bits means play no samples.
  2229                              <1> ;
  2230                              <1> 
  2231 00012EE0 89F0                <1> 	mov	eax, esi ; DMA half buffer size
  2232 00012EE2 01C2                <1> 	add	edx, eax
  2233 00012EE4 D1E8                <1> 	shr	eax, 1 ; count of 16 bit samples
  2234                              <1> 	;or	eax, IOC+BUP
  2235 00012EE6 0D00000080          <1> 	or	eax, IOC ; 11/06/2017
  2236 00012EEB AB                  <1> 	stosd
  2237                              <1> 
  2238                              <1> ; 2nd buffer:
  2239                              <1> 
  2240 00012EEC 89D0                <1>         mov	eax, edx ; Physical address of the 2nd half of DMA buffer	
  2241 00012EEE AB                  <1> 	stosd		 ; store dmabuffer2 address
  2242                              <1> 
  2243                              <1> ; set length to [audio_dmabuff_size]/2
  2244                              <1> ; Set control (bits 31:16) to BUP, bits 15:0=number of samples
  2245                              <1> ; 
  2246 00012EEF 89F0                <1> 	mov	eax, esi ; DMA half buffer size
  2247 00012EF1 D1E8                <1> 	shr	eax, 1 ; count of 16 bit samples
  2248                              <1> 	;or	eax, IOC+BUP
  2249 00012EF3 0D00000080          <1> 	or	eax, IOC ; 11/06/2017
  2250 00012EF8 AB                  <1> 	stosd
  2251                              <1> 
  2252 00012EF9 E2DD                <1> 	loop    s_ac97_bdl0
  2253                              <1> 	
  2254 00012EFB C3                  <1> 	retn
  2255                              <1> 
  2256                              <1> ac97_start_play:  
  2257                              <1> 	; 28/05/2017
  2258                              <1> 	; Derived from 'playWav' procedure in 'ICHWAV.ASM'
  2259                              <1> 	; .wav player for DOS by Jeff Leyda (02/09/2002)
  2260                              <1> 
  2261                              <1> 	; set output rate
  2262                              <1> 	; entry: [audio_freq] = desired sample rate
  2263                              <1> 		
  2264 00012EFC 668B15[90760100]    <1> 	mov    	dx, [NAMBAR]               	
  2265 00012F03 6683C22A            <1> 	add    	dx, CODEC_EXT_AUDIO_CTRL_REG  	; 2Ah  	  
  2266 00012F07 66ED                <1> 	in     	ax, dx
  2267 00012F09 6683C801            <1> 	or	ax, 1
  2268 00012F0D 66EF                <1> 	out	dx, ax 				; Enable variable rate audio
  2269                              <1> 
  2270                              <1>        ;call    delay1_4ms
  2271                              <1>        ;call    delay1_4ms
  2272                              <1>        ;call    delay1_4ms
  2273                              <1>        ;call    delay1_4ms
  2274                              <1> 
  2275 00012F0F 66A1[8A760100]      <1> 	mov	ax, [audio_freq]		; sample rate
  2276                              <1> 
  2277 00012F15 668B15[90760100]    <1> 	mov    	dx, [NAMBAR]               	
  2278 00012F1C 6683C22C            <1> 	add    	dx, CODEC_PCM_FRONT_DACRATE_REG	; 2Ch  	  
  2279 00012F20 66EF                <1> 	out	dx, ax 				; out sample rate
  2280                              <1> 		
  2281                              <1>        ;call    delay1_4ms
  2282                              <1>        ;call    delay1_4ms
  2283                              <1>        ;call    delay1_4ms
  2284                              <1>        ;call    delay1_4ms
  2285                              <1> 
  2286                              <1> ;
  2287                              <1> ; register reset the DMA engine. This may cause a pop noise on the output
  2288                              <1> ; lines when the device is reset. Prolly a better idea to mute output, then
  2289                              <1> ; reset.
  2290                              <1> ;
  2291 00012F22 668B15[92760100]    <1>         mov     dx, [NABMBAR]
  2292 00012F29 6683C21B            <1>         add     dx, PO_CR_REG                  ; set pointer to Cntl reg
  2293 00012F2D B002                <1>         mov     al, RR                         ; set reset
  2294 00012F2F EE                  <1>         out     dx, al                         ; self clearing bit
  2295                              <1> ;
  2296                              <1> ;	mov	edi, audio_bdl_buff
  2297                              <1> ;	mov	edx, [audio_dmabuff_size]
  2298                              <1> ;	shr	edx, 1
  2299                              <1> ;	mov	ecx, 32/2
  2300                              <1> ;ac97_set_bdl_buffer:
  2301                              <1> ;	; 1st half of DMA buffer
  2302                              <1> ;	mov	eax, [audio_dma_buff]
  2303                              <1> ;	push	eax
  2304                              <1> ;	stosd
  2305                              <1> ;	mov	eax, edx ; dma buffer size / 2
  2306                              <1> ;	or	eax, IOC+BUP
  2307                              <1> ;	stosd
  2308                              <1> ;	pop	eax
  2309                              <1> ;	; 2nd half of DMA buffer
  2310                              <1> ;	add	eax, edx
  2311                              <1> ;	stosd
  2312                              <1> ;	mov	eax, edx ; dma buffer size / 2
  2313                              <1> ;	or	eax, IOC+BUP
  2314                              <1> ;	stosd
  2315                              <1> ;	loop	ac97_set_bdl_buffer
  2316                              <1>  	
  2317                              <1> ; tell the DMA engine where to find our list of Buffer Descriptors.
  2318                              <1> ; this 32bit value is a flat mode memory offset (ie no segment:offset)
  2319                              <1> ;
  2320                              <1> ; write NABMBAR+10h with offset of buffer descriptor list
  2321                              <1> ;
  2322 00012F30 B8[94760100]        <1>         mov	eax, audio_bdl_buff
  2323 00012F35 668B15[92760100]    <1> 	mov	dx, [NABMBAR]
  2324 00012F3C 6683C210            <1> 	add	dx, PO_BDBAR_REG
  2325 00012F40 EF                  <1> 	out	dx, eax
  2326                              <1> ;
  2327                              <1> ; All set. Let's play some music.
  2328                              <1> ;
  2329                              <1> ;
  2330 00012F41 B81F000000          <1> 	mov	eax, 31
  2331 00012F46 E816000000          <1> 	call    set_ac97_LastValidIndex
  2332                              <1> 
  2333 00012F4B C605[8C760100]01    <1> 	mov	byte [audio_play_cmd], 1 ; play command (do not stop) !
  2334                              <1> 
  2335                              <1> ac97_play: ; continue to play (after pause)
  2336                              <1> 	; 11/06/2017
  2337                              <1> 	; 29/05/2017
  2338                              <1> 	; 28/05/2017
  2339 00012F52 668B15[92760100]    <1>         mov     dx, [NABMBAR]
  2340 00012F59 6683C21B            <1>         add     dx, PO_CR_REG		; PCM out control register
  2341 00012F5D B011                <1>         mov	al, IOCE+RPBM ; 29/05/2017
  2342                              <1>         ;mov	al, 1Dh ; (Ref: KolibriOS, intelac97.asm, 'play:')
  2343 00012F5F EE                  <1> 	out     dx, al			; set start!
  2344                              <1> 
  2345                              <1> 	;mov	byte [audio_play_cmd], 1 ; play command (do not stop) !
  2346                              <1> 
  2347 00012F60 C3                  <1> 	retn
  2348                              <1> 
  2349                              <1> ;input AL = index # to stop on
  2350                              <1> set_ac97_LastValidIndex:
  2351                              <1> 	; 28/05/2017
  2352                              <1> 	; Derived from 'setLastValidIndex' procedure in 'ICHWAV.ASM'
  2353                              <1> 	; .wav player for DOS by Jeff Leyda (02/09/2002)
  2354 00012F61 668B15[92760100]    <1> 	mov	dx, [NABMBAR]
  2355 00012F68 6683C215            <1> 	add	dx, PO_LVI_REG
  2356 00012F6C EE                  <1>         out     dx, al
  2357                              <1> 	;mov	[audio_lvi], al ; for ac97_int_handler
  2358 00012F6D C3                  <1> 	retn
  2359                              <1> 
  2360                              <1> ac97_volume:
  2361                              <1> 	; 28/05/2017
  2362                              <1> 	; bl = component (0 = master/playback/lineout volume)
  2363                              <1> 	; cl = left channel volume level (0 to 31)
  2364                              <1> 	; ch = right channel volume level (0 to 31)
  2365                              <1> 
  2366 00012F6E 08DB                <1> 	or	bl, bl
  2367 00012F70 7523                <1> 	jnz	short ac97_vol_1 ; temporary !
  2368 00012F72 66B81F1F            <1> 	mov	ax, 1F1Fh ; 31,31
  2369 00012F76 38C1                <1> 	cmp	cl, al
  2370 00012F78 771B                <1> 	ja	short ac97_vol_1 ; temporary !
  2371 00012F7A 38E5                <1> 	cmp	ch, ah
  2372 00012F7C 7717                <1> 	ja	short ac97_vol_1 ; temporary !
  2373 00012F7E 66890D[8E760100]    <1> 	mov	[audio_master_volume], cx
  2374 00012F85 6629C8              <1> 	sub	ax, cx
  2375 00012F88 668B15[90760100]    <1>   	mov     dx, [NAMBAR]
  2376 00012F8F 6683C202            <1>   	add     dx, CODEC_MASTER_VOL_REG  ; 02h ; Line Out 
  2377 00012F93 66EF                <1>   	out     dx, ax
  2378                              <1> ac97_vol_1:
  2379 00012F95 C3                  <1> 	retn
  2380                              <1> 
  2381                              <1> ac97_int_handler:
  2382                              <1> 	; 12/10/2017
  2383                              <1> 	; 10/10/2017
  2384                              <1> 	; 09/10/2017
  2385                              <1> 	; 13/06/2017, 13/06/2017
  2386                              <1> 	; 10/06/2017, 11/06/2017
  2387                              <1> 	; Interrupt Handler for AC97 (ICH) Audio Controller
  2388                              <1> 	; Note: called by 'dev_IRQ_service' 
  2389                              <1> 	; 28/05/2017
  2390                              <1> 
  2391                              <1> 	;push	eax ; * must be saved !
  2392                              <1> 	;push	edx
  2393                              <1> 	;push	ecx
  2394                              <1> 	;push	ebx ; * must be saved !
  2395                              <1> 	;push	esi
  2396                              <1> 	;push	edi
  2397                              <1> 
  2398                              <1> 	;cmp	byte [audio_busy], 1
  2399                              <1> 	;jnb	_ac97_ih2	; busy !
  2400                              <1> 
  2401 00012F96 66BA3000            <1>         mov     dx, GLOB_STS_REG
  2402 00012F9A 660315[92760100]    <1>         add	dx, [NABMBAR]
  2403 00012FA1 ED                  <1> 	in	eax, dx
  2404                              <1> 
  2405 00012FA2 83F8FF              <1>         cmp     eax, 0FFFFFFFFh ; -1
  2406 00012FA5 0F849A000000        <1>         je      _ac97_ih3 ; exit
  2407                              <1> 
  2408 00012FAB A940000000          <1>         test    eax, 40h ; PCM Out Interrupt
  2409 00012FB0 750E                <1>         jnz     short _ac97_ih0
  2410                              <1> 
  2411 00012FB2 85C0                <1> 	test	eax, eax
  2412 00012FB4 0F848B000000        <1> 	jz	_ac97_ih3 ; exit
  2413                              <1> 
  2414                              <1>  	;mov	dx, GLOB_STS_REG
  2415                              <1>         ;add	dx, [NABMBAR]
  2416 00012FBA EF                  <1> 	out	dx, eax
  2417                              <1> 
  2418 00012FBB E985000000          <1> 	jmp	_ac97_ih3 ; exit
  2419                              <1> 
  2420                              <1> _ac97_ih0:
  2421 00012FC0 50                  <1> 	push	eax
  2422                              <1> 	; 09/10/2017
  2423 00012FC1 803D[8C760100]01    <1> 	cmp	byte [audio_play_cmd], 1
  2424 00012FC8 727C                <1> 	jb	short _ac97_ih4 ; stop command !
  2425                              <1> 
  2426                              <1> 	;mov	byte [audio_busy], 1
  2427                              <1> 
  2428                              <1> 	;mov	al, 10h
  2429                              <1> 	;mov	dx, PO_CR_REG
  2430                              <1>         ;add	dx, [NABMBAR]
  2431                              <1> 	;out	dx, al
  2432                              <1> 
  2433 00012FCA 66B81C00            <1> 	mov	ax, 1Ch ; FIFOE(=16)+BCIS(=8)+LVBCI(=4)
  2434 00012FCE 66BA1600            <1> 	mov	dx, PO_SR_REG
  2435 00012FD2 660315[92760100]    <1>         add	dx, [NABMBAR]
  2436 00012FD9 66EF                <1> 	out	dx, ax
  2437                              <1> 
  2438 00012FDB 66BA1400            <1> 	mov	dx, PO_CIV_REG
  2439 00012FDF 660315[92760100]    <1>         add	dx, [NABMBAR]
  2440 00012FE6 EC                  <1> 	in	al, dx
  2441                              <1> 
  2442                              <1> 	;cmp	al, [audio_civ] ; [audio_flag]
  2443                              <1> 	;je	short _ac97_ih2
  2444                              <1> 
  2445 00012FE7 A2[8D760100]        <1> 	mov	[audio_civ], al
  2446 00012FEC FEC8                <1> 	dec	al
  2447                              <1> 	;inc	al ; 11/06/2017
  2448 00012FEE 241F                <1> 	and	al, 1Fh
  2449                              <1> 
  2450 00012FF0 66BA1500            <1>         mov     dx, PO_LVI_REG
  2451 00012FF4 660315[92760100]    <1>         add	dx, [NABMBAR]
  2452 00012FFB EE                  <1>         out	dx, al
  2453                              <1> 
  2454                              <1> 	; 12/10/2017
  2455 00012FFC A0[8D760100]        <1> 	mov	al, [audio_civ]
  2456 00013001 FEC0                <1> 	inc	al
  2457 00013003 2401                <1> 	and	al, 1
  2458 00013005 A2[80760100]        <1> 	mov	[audio_flag], al 
  2459                              <1> 	;; [audio_flag] : 0 = Buffer 1, 1 = Buffer 2
  2460                              <1> 	;
  2461 0001300A 58                  <1> 	pop	eax
  2462                              <1> 	;
  2463 0001300B 83E040              <1> 	and     eax, 40h
  2464 0001300E 668B15[92760100]    <1>         mov	dx, [NABMBAR]
  2465 00013015 6683C230            <1> 	add	dx, GLOB_STS_REG
  2466 00013019 EF                  <1> 	out	dx, eax
  2467                              <1> 
  2468                              <1> 	;; 13/06/2017
  2469                              <1> 	;mov	al, 11h ; IOCE + RPBM
  2470                              <1> 	;mov	dx, PO_CR_REG
  2471                              <1>         ;add	dx, [NABMBAR]
  2472                              <1> 	;out	dx, al
  2473                              <1> 
  2474                              <1> ac97_tuneloop:
  2475                              <1> 	; 09/10/2017
  2476 0001301A 8B3D[78760100]      <1> 	mov	edi, [audio_dma_buff]
  2477 00013020 8B0D[7C760100]      <1> 	mov	ecx, [audio_dmabuff_size]
  2478 00013026 D1E9                <1> 	shr	ecx, 1 ; dma buff size / 2 = half buffer size
  2479                              <1> 
  2480                              <1> 	; 12/10/2017
  2481 00013028 803D[80760100]00    <1> 	cmp 	byte [audio_flag], 0
  2482 0001302F 7702                <1> 	ja	short _ac97_ih1  ; Playing Half Buffer 2 (Current: FLAG)
  2483                              <1> 	; Playing Half Buffer 1 (Current: EOL)	
  2484 00013031 01CF                <1> 	add	edi, ecx
  2485                              <1> _ac97_ih1: 
  2486                              <1> 	; Update half buffer 2 while playing half buffer 1 (next: FLAG)
  2487                              <1> 	; Update half buffer 1 while playing half buffer 2 (next: EOL)
  2488                              <1> 
  2489 00013033 8B35[70760100]      <1> 	mov	esi, [audio_p_buffer] ; phy addr of audio buff
  2490 00013039 C1E902              <1> 	shr	ecx, 2 ; half buff size / 4
  2491 0001303C F3A5                <1> 	rep	movsd 
  2492                              <1> 
  2493                              <1> 	; 10/10/2017
  2494                              <1> 	; switch flag value
  2495 0001303E 8035[80760100]01    <1> 	xor	byte [audio_flag], 1
  2496                              <1> 	; 12/10/2017
  2497                              <1> 	; [audio_flag] = 0 : Playing dma half buffer 2 (even index value)
  2498                              <1> 			   ; Next buffer (to update) is dma half buff 1
  2499                              <1> 	; 	       = 1 : Playing dma half buffer 1 (odd index value)
  2500                              <1> 			   ; Next buffer (to update) is dma half buff 2
  2501                              <1> 
  2502                              <1> _ac97_ih2:
  2503                              <1> 	;mov	byte [audio_busy], 0
  2504                              <1> _ac97_ih3:
  2505                              <1> 	;pop	edi
  2506                              <1> 	;pop	esi
  2507                              <1> 	;pop	ebx ; * must be restored !
  2508                              <1> 	;pop	ecx
  2509                              <1> 	;pop	edx
  2510                              <1> 	;pop	eax ; * must be restored !
  2511                              <1> 
  2512 00013045 C3                  <1> 	retn
  2513                              <1> 
  2514                              <1> _ac97_ih4:
  2515                              <1> 	; 09/10/2017
  2516 00013046 E818000000          <1> 	call	_ac97_stop
  2517                              <1> 	;
  2518 0001304B 58                  <1> 	pop	eax
  2519                              <1> 	;
  2520 0001304C 83E040              <1> 	and     eax, 40h
  2521 0001304F 668B15[92760100]    <1>         mov	dx, [NABMBAR]
  2522 00013056 6683C230            <1> 	add	dx, GLOB_STS_REG
  2523 0001305A EF                  <1> 	out	dx, eax
  2524                              <1> 
  2525                              <1> 	;; 13/06/2017
  2526                              <1> 	;mov	al, 11h ; IOCE + RPBM
  2527                              <1> 	;dx, PO_CR_REG
  2528                              <1>         ;add	dx, [NABMBAR]
  2529                              <1> 	;out	dx, al
  2530                              <1> 
  2531                              <1> 	; 10/10/2017
  2532                              <1> 	;jmp	short _ac97_ih3  ; exit
  2533 0001305B C3                  <1> 	retn
  2534                              <1> 
  2535                              <1> ac97_stop: 
  2536                              <1> 	; 28/05/2017
  2537 0001305C C605[8C760100]00    <1> 	mov	byte [audio_play_cmd], 0 ; stop !
  2538                              <1> _ac97_stop: ; 09/10/2017
  2539                              <1> 	; 29/05/2017
  2540                              <1> 	;mov	dx, [NABMBAR]
  2541                              <1> 	;add	dx, PO_CR_REG
  2542                              <1> 	;mov	al, 0
  2543                              <1> 	;out	dx, al
  2544                              <1> 
  2545                              <1> 	; 11/06/2017
  2546 00013063 30C0                <1> 	xor	al, al ; 0
  2547 00013065 E813000000          <1> 	call	ac97_po_cmd
  2548                              <1> 
  2549                              <1> 	; (Ref: KolibriOS, intelac97.asm, 'stop:')
  2550                              <1> 	; Clear FIFOE, BCIS, LVBCI (Ref: Intel ICH hub manual)
  2551 0001306A 66B81C00            <1> 	mov     ax, 1Ch
  2552 0001306E 668B15[92760100]    <1> 	mov     dx, [NABMBAR]
  2553 00013075 6683C216            <1> 	add     dx, PO_SR_REG
  2554 00013079 66EF                <1> 	out     dx, ax
  2555                              <1> 
  2556                              <1> 	;retn
  2557                              <1> 
  2558                              <1> 	; 11/06/2017
  2559 0001307B B002                <1> 	mov     al, RR
  2560                              <1> ac97_po_cmd:
  2561                              <1> 	 ;11/06/2017
  2562                              <1> 	; 29/05/2017
  2563 0001307D 668B15[92760100]    <1> 	mov     dx, [NABMBAR]
  2564 00013084 6683C21B            <1>         add     dx, PO_CR_REG		; PCM out control register
  2565 00013088 EE                  <1> 	out	dx, al
  2566 00013089 C3                  <1> 	retn
  2567                              <1> 
  2568                              <1> ac97_pause:
  2569                              <1> 	; 11/06/2017
  2570                              <1> 	; 29/05/2017
  2571 0001308A B010                <1> 	mov 	al, IOCE
  2572 0001308C EBEF                <1> 	jmp	short ac97_po_cmd
  2573                              <1> 
  2574                              <1> reset_ac97_controller:
  2575                              <1> 	; 10/06/2017
  2576                              <1> 	; 29/05/2017
  2577                              <1> 	; 28/05/2017
  2578                              <1> 	; reset AC97 audio controller registers
  2579 0001308E 31C0                <1> 	xor     eax, eax
  2580 00013090 66BA0B00            <1>         mov	dx, PI_CR_REG
  2581 00013094 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2582 0001309B EE                  <1> 	out     dx, al
  2583                              <1> 
  2584 0001309C 66BA1B00            <1>         mov     dx, PO_CR_REG
  2585 000130A0 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2586 000130A7 EE                  <1> 	out     dx, al
  2587                              <1> 
  2588 000130A8 66BA2B00            <1>         mov     dx, MC_CR_REG
  2589 000130AC 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2590 000130B3 EE                  <1> 	out     dx, al
  2591                              <1> 
  2592 000130B4 B002                <1>         mov     al, RR
  2593 000130B6 66BA0B00            <1>         mov     dx, PI_CR_REG
  2594 000130BA 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2595 000130C1 EE                  <1> 	out     dx, al
  2596                              <1> 
  2597 000130C2 66BA1B00            <1>         mov     dx, PO_CR_REG
  2598 000130C6 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2599 000130CD EE                  <1> 	out     dx, al
  2600                              <1> 
  2601 000130CE 66BA2B00            <1>         mov     dx, MC_CR_REG
  2602 000130D2 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2603 000130D9 EE                  <1> 	out     dx, al
  2604                              <1> 
  2605 000130DA C3                  <1> 	retn
  2606                              <1> 
  2607                              <1> ac97_reset:
  2608                              <1> 	; 10/06/2017
  2609                              <1> 	; 29/05/2017
  2610                              <1> 	; 28/05/2017
  2611 000130DB E8AEFFFFFF          <1> 	call	reset_ac97_controller
  2612                              <1> 	; 29/05/2017
  2613                              <1> 	;jmp	reset_ac97_codec
  2614                              <1> reset_ac97_codec:
  2615                              <1> 	; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm)
  2616 000130E0 66BA2C00            <1> 	mov	dx, GLOB_CNT_REG ; 2Ch
  2617 000130E4 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2618 000130EB ED                  <1> 	in	eax, dx
  2619                              <1> 
  2620 000130EC A902000000          <1> 	test	eax, 2
  2621 000130F1 7407                <1> 	jz	short _r_ac97codec_cold	
  2622                              <1> 
  2623 000130F3 E80F000000          <1> 	call	warm_ac97codec_reset
  2624 000130F8 7308                <1> 	jnc	short _r_ac97codec_ok
  2625                              <1> _r_ac97codec_cold:
  2626 000130FA E83D000000          <1>         call    cold_ac97codec_reset
  2627 000130FF 7301                <1>         jnc     short _r_ac97codec_ok
  2628                              <1> 	
  2629                              <1> 	; 16/04/2017
  2630                              <1>         ;xor     eax, eax         ; timeout error
  2631                              <1>        	;stc
  2632 00013101 C3                  <1> 	retn
  2633                              <1> 
  2634                              <1> _r_ac97codec_ok:
  2635 00013102 31C0                <1>         xor     eax, eax
  2636                              <1>         ;mov	al, VIA_ACLINK_C00_READY ; 1
  2637 00013104 FEC0                <1>         inc	al
  2638 00013106 C3                  <1> 	retn
  2639                              <1> 
  2640                              <1> warm_ac97codec_reset:
  2641                              <1> 	; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm)
  2642 00013107 B806000000          <1>         mov     eax, 6
  2643 0001310C 66BA2C00            <1> 	mov	dx, GLOB_CNT_REG ; 2Ch
  2644 00013110 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2645 00013117 EF                  <1> 	out	dx, eax
  2646                              <1> 
  2647 00013118 B90A000000          <1> 	mov	ecx, 10	; total 1s
  2648                              <1> _warm_ac97c_rst_wait:
  2649 0001311D 51                  <1> 	push	ecx
  2650 0001311E E8ECF5FFFF          <1> 	call	delay_100ms
  2651 00013123 59                  <1> 	pop	ecx
  2652                              <1> 
  2653 00013124 66BA3000            <1> 	mov	dx, GLOB_STS_REG ; 30h
  2654 00013128 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2655 0001312F ED                  <1> 	in	eax, dx
  2656                              <1> 
  2657 00013130 A900030010          <1> 	test	eax, CTRL_ST_CREADY
  2658 00013135 7504                <1> 	jnz	short _warm_ac97c_rst_ok
  2659                              <1> 
  2660 00013137 49                  <1>         dec     ecx
  2661 00013138 75E3                <1>         jnz     short _warm_ac97c_rst_wait
  2662                              <1> 
  2663                              <1> _warm_ac97c_rst_fail:
  2664 0001313A F9                  <1>         stc
  2665                              <1> _warm_ac97c_rst_ok:
  2666 0001313B C3                  <1> 	retn
  2667                              <1> 
  2668                              <1> cold_ac97codec_reset:
  2669                              <1> 	; 28/05/2017 - Erdogan Tan (Ref: KolibriOS, intelac97.asm)
  2670 0001313C B802000000          <1>         mov     eax, 2
  2671 00013141 66BA2C00            <1> 	mov	dx, GLOB_CNT_REG ; 2Ch
  2672 00013145 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2673 0001314C EF                  <1> 	out	dx, eax
  2674                              <1> 
  2675 0001314D E8BDF5FFFF          <1> 	call	delay_100ms 	; wait 100 ms
  2676 00013152 E8B8F5FFFF          <1> 	call	delay_100ms 	; wait 100 ms
  2677 00013157 E8B3F5FFFF          <1> 	call	delay_100ms 	; wait 100 ms
  2678 0001315C E8AEF5FFFF          <1> 	call	delay_100ms 	; wait 100 ms
  2679                              <1> 
  2680 00013161 B910000000          <1> 	mov	ecx, 16	; total 20*100 ms = 2s
  2681                              <1> _cold_ac97c_rst_wait:
  2682 00013166 66BA3000            <1> 	mov	dx, GLOB_STS_REG ; 30h
  2683 0001316A 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2684 00013171 ED                  <1> 	in	eax, dx
  2685                              <1> 
  2686 00013172 A900030010          <1> 	test	eax, CTRL_ST_CREADY
  2687 00013177 750B                <1> 	jnz	short _cold_ac97c_rst_ok
  2688                              <1> 
  2689 00013179 51                  <1> 	push	ecx
  2690 0001317A E890F5FFFF          <1> 	call	delay_100ms
  2691 0001317F 59                  <1> 	pop	ecx
  2692                              <1> 
  2693 00013180 49                  <1>         dec     ecx
  2694 00013181 75E3                <1>         jnz     short _cold_ac97c_rst_wait
  2695                              <1> 
  2696                              <1> _cold_ac97c_rst_fail:
  2697 00013183 F9                  <1>         stc
  2698                              <1> _cold_ac97c_rst_ok:
  2699 00013184 C3                  <1> 	retn
  2700                              <1> 
  2701                              <1> sb16_current_sound_data:
  2702                              <1> 	; 20/08/2017
  2703                              <1> 	; 24/06/2017
  2704                              <1> 	; 22/06/2017
  2705                              <1> 	; get current sound (PCM out) data for graphics
  2706                              <1> 	; (for Sound Blaster 16)
  2707                              <1> 	; ebx = Physical address (on page boundary)
  2708                              <1> 	; ecx = Byte count
  2709                              <1> 	; [audio_buff_size]
  2710                              <1> 
  2711                              <1> 	;;mov	edi, [audio_buff_size]
  2712                              <1> 	;mov	edi, [audio_dmabuff_size]
  2713                              <1> 	;mov	esi, [audio_dma_buff]
  2714 00013185 39CF                <1> 	cmp	edi, ecx
  2715 00013187 7302                <1> 	jnb	short sb16_gcd_0
  2716 00013189 89F9                <1> 	mov	ecx, edi
  2717                              <1> sb16_gcd_0:
  2718                              <1> 	; 20/08/2017
  2719 0001318B 803D[88760100]10    <1> 	cmp	byte [audio_bps], 16
  2720 00013192 750F                <1> 	jne	short sb16_gcd_1 ; 8 bit DMA channel
  2721 00013194 E4C6                <1> 	in	al, 0C6h ; DMA channel 5 count register
  2722 00013196 88C2                <1> 	mov	dl, al	
  2723 00013198 E4C6                <1> 	in	al, 0C6h
  2724 0001319A 88C6                <1> 	mov     dh, al
  2725 0001319C 0FB7C2              <1> 	movzx	eax, dx
  2726 0001319F D1E0                <1> 	shl	eax, 1 ; word count -> byte count
  2727 000131A1 EB4E                <1> 	jmp	short sb16_gcd_2	
  2728                              <1> sb16_gcd_1:
  2729 000131A3 E403                <1> 	in	al, 03h ; DMA channel 1 count register
  2730 000131A5 88C2                <1> 	mov	dl, al	
  2731 000131A7 E403                <1> 	in	al, 03h
  2732 000131A9 88C6                <1> 	mov     dh, al
  2733 000131AB 0FB7C2              <1> 	movzx	eax, dx
  2734 000131AE EB41                <1> 	jmp	short sb16_gcd_2
  2735                              <1> ;sb16_gcd_2:	
  2736                              <1> ;	cmp	eax, ecx
  2737                              <1> ;	jnb	short sb16_gcd_3 
  2738                              <1> ;	; remain count < graphics bytes
  2739                              <1> ;	mov	eax, ecx ; fix remain count to data size
  2740                              <1> ;sb16_gcd_3:	
  2741                              <1> ;	sub	edi, eax
  2742                              <1> ;	jna	short sb16_gcd_4
  2743                              <1> ;	add	esi, edi ; dma buffer offset
  2744                              <1> ;sb16_gcd_4:
  2745                              <1> ;	mov	edi, ebx ; buffer address (for graphics) 
  2746                              <1> ;	mov	[u.r0], ecx
  2747                              <1> ;	rep	movsb
  2748                              <1> ;	retn
  2749                              <1> 
  2750                              <1> get_current_sound_data:
  2751                              <1> 	; 24/06/2017
  2752                              <1> 	; 22/06/2017
  2753                              <1> 	; get current sound (PCM out) data for graphics
  2754                              <1> 	;
  2755                              <1> 	; ebx = Physical address (on page boundary)
  2756                              <1> 	; ecx = Byte count
  2757                              <1> 	; [audio_buff_size]
  2758                              <1> 
  2759                              <1> 	;mov	edi, [audio_buff_size]
  2760 000131B0 8B3D[7C760100]      <1> 	mov	edi, [audio_dmabuff_size]
  2761 000131B6 8B35[78760100]      <1> 	mov	esi, [audio_dma_buff]
  2762 000131BC 803D[59760100]02    <1> 	cmp	byte [audio_device], 2
  2763 000131C3 72C0                <1> 	jb	short sb16_current_sound_data ; = 1
  2764 000131C5 D1EF                <1> 	shr	edi, 1
  2765 000131C7 39CF                <1> 	cmp	edi, ecx
  2766 000131C9 7302                <1> 	jnb	short gcd_0
  2767 000131CB 89F9                <1> 	mov	ecx, edi
  2768                              <1> gcd_0:
  2769 000131CD 803D[59760100]03    <1> 	cmp	byte [audio_device], 3
  2770 000131D4 7232                <1> 	jb	short ac97_current_sound_data ; = 2
  2771                              <1> 	; = 3
  2772                              <1> vt8233_current_sound_data:
  2773                              <1> 	; 22/06/2017
  2774                              <1> 	; 21/06/2017
  2775                              <1> 	; get current sound (PCM out) data for graphics
  2776                              <1> 	; (for VT 8233, VT 8237R)
  2777                              <1> 	; ebx = Physical address (on page boundary)
  2778                              <1> 	; ecx = Byte count
  2779                              <1> 	; [audio_buff_size]
  2780                              <1> 	
  2781                              <1> 	;;mov	edi, [audio_buff_size]
  2782                              <1> 	;mov	edi, [audio_dmabuff_size]
  2783                              <1> 	;mov	esi, [audio_dma_buff]
  2784                              <1> 	;shr	edi, 1
  2785                              <1> 	;cmp	edi, ecx
  2786                              <1> 	;jnb	short vt8233_gcd_1
  2787                              <1> 	;mov	ecx, edi
  2788                              <1> vt8233_gcd_1:
  2789 000131D6 BA0C000000          <1> 	mov	edx, VIA_REG_OFFSET_CURR_COUNT
  2790 000131DB E88FF5FFFF          <1> 	call	ctrl_io_r32
  2791 000131E0 89C2                <1> 	mov	edx, eax ; remain count (bits 23-0),
  2792                              <1> 			 ; SGD index (bits 31-24) 
  2793 000131E2 81E200000001        <1> 	and	edx, 1000000h ; SGD index (0 = 1st half)
  2794 000131E8 7402                <1> 	jz	short vt8233_gcd_2
  2795                              <1> 	; the second half of DMA buffer
  2796 000131EA 01FE                <1> 	add	esi, edi 
  2797                              <1> vt8233_gcd_2:	
  2798 000131EC 25FFFFFF00          <1> 	and	eax, 0FFFFFFh ; bits 23-0
  2799                              <1> ac97_gcd_2:
  2800                              <1> sb16_gcd_2:
  2801 000131F1 39C8                <1> 	cmp	eax, ecx
  2802 000131F3 7302                <1> 	jnb	short vt8233_gcd_3 
  2803                              <1> 	; remain count < graphics bytes
  2804 000131F5 89C8                <1> 	mov	eax, ecx ; fix remain count to data size
  2805                              <1> vt8233_gcd_3:
  2806 000131F7 29C7                <1> 	sub	edi, eax
  2807 000131F9 7602                <1> 	jna	short vt8233_gcd_4
  2808 000131FB 01FE                <1> 	add	esi, edi ; dma buffer offset
  2809                              <1> vt8233_gcd_4:
  2810 000131FD 89DF                <1> 	mov	edi, ebx ; buffer address (for graphics) 
  2811 000131FF 890D[64030300]      <1> 	mov	[u.r0], ecx
  2812 00013205 F3A4                <1> 	rep	movsb
  2813                              <1> vt8233_gcd_5:
  2814 00013207 C3                  <1> 	retn
  2815                              <1> 
  2816                              <1> ac97_current_sound_data:
  2817                              <1> 	; 23/06/2017
  2818                              <1> 	; 22/06/2017
  2819                              <1> 	; get current sound (PCM out) data for graphics
  2820                              <1> 	; (for AC'97, ICH)
  2821                              <1> 	; ebx = Physical address (on page boundary)
  2822                              <1> 	; ecx = Byte count
  2823                              <1> 	; [audio_buff_size]
  2824                              <1> 	
  2825                              <1> 	;;mov	edi, [audio_buff_size]
  2826                              <1> 	;mov	edi, [audio_dmabuff_size]
  2827                              <1> 	;mov	esi, [audio_dma_buff]
  2828                              <1> 	;shr	edi, 1
  2829                              <1> 	;cmp	edi, ecx
  2830                              <1> 	;jnb	short ac97_gcd_0
  2831                              <1> 	;mov	ecx, edi
  2832                              <1> ac97_gcd_0:
  2833 00013208 66BA1400            <1> 	mov	dx, PO_CIV_REG ; Position In Current Buff Reg
  2834 0001320C 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2835 00013213 EC                  <1> 	in	al, dx ; current index value
  2836 00013214 A801                <1> 	test	al, 1
  2837 00013216 7402                <1> 	jz	short ac97_gcd_1
  2838 00013218 01FE                <1> 	add	esi, edi
  2839                              <1> ac97_gcd_1:
  2840 0001321A 31C0                <1> 	xor	eax, eax
  2841 0001321C 66BA1800            <1> 	mov	dx, PO_PICB_REG ; Position In Current Buff Reg
  2842 00013220 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2843 00013227 66ED                <1> 	in	ax, dx ; remain dwords
  2844 00013229 C1E002              <1> 	shl	eax, 2 ; remain bytes ; 23/06/2017 
  2845 0001322C EBC3                <1> 	jmp	short ac97_gcd_2
  2846                              <1> ;	cmp	eax, ecx
  2847                              <1> ;	jnb	short ac97_gcd_2 
  2848                              <1> ;	; remain count < graphics bytes
  2849                              <1> ;	mov	eax, ecx ; fix remain count to data size
  2850                              <1> ;ac97_gcd_2:	
  2851                              <1> ;	sub	edi, eax
  2852                              <1> ;	jna	short ac97_gcd_3
  2853                              <1> ;	add	esi, edi ; dma buffer offset
  2854                              <1> ;ac97_gcd_3:
  2855                              <1> ;	mov	edi, ebx ; buffer address (for graphics) 
  2856                              <1> ;	mov	[u.r0], ecx
  2857                              <1> ;	rep	movsb
  2858                              <1> ;	retn
  2859                              <1> 
  2860                              <1> sb16_get_dma_buff_off:
  2861                              <1> 	; 28/10/2017
  2862                              <1> 	; 24/06/2017
  2863                              <1> 	; 22/06/2017
  2864                              <1> 	; get current (PCM OUT DMA buffer) pointer
  2865                              <1> 	; (for Sound Blaster 16)
  2866                              <1> 
  2867                              <1> 	;mov	ecx, [audio_dmabuff_size]
  2868                              <1> 	;xor	ebx, ebx
  2869                              <1> 	;shr	ecx, 1
  2870                              <1> sb16_gdmabo_0:
  2871                              <1> 	; 28/10/2017
  2872 0001322E 803D[88760100]10    <1> 	cmp	byte [audio_bps], 16
  2873 00013235 750F                <1> 	jne	short sb16_gdmabo_1 ; 8 bit DMA channel
  2874                              <1> 	; 16 bit DMA channel
  2875 00013237 E4C6                <1> 	in	al, 0C6h ; DMA channel 5 count register
  2876 00013239 88C2                <1> 	mov	dl, al	
  2877 0001323B E4C6                <1> 	in	al, 0C6h
  2878 0001323D 88C6                <1> 	mov     dh, al
  2879 0001323F 0FB7C2              <1> 	movzx	eax, dx
  2880 00013242 D1E0                <1> 	shl	eax, 1 ; word count -> byte count
  2881 00013244 EB3D                <1> 	jmp	short sb16_gdmabo_2	
  2882                              <1> sb16_gdmabo_1:
  2883 00013246 E403                <1> 	in	al, 03h ; DMA channel 1 count register
  2884 00013248 88C2                <1> 	mov	dl, al	
  2885 0001324A E403                <1> 	in	al, 03h
  2886 0001324C 88C6                <1> 	mov     dh, al
  2887 0001324E 0FB7C2              <1> 	movzx	eax, dx
  2888 00013251 EB30                <1> 	jmp	short sb16_gdmabo_2
  2889                              <1> 
  2890                              <1> get_dma_buffer_offset:
  2891                              <1> 	; 24/06/2017
  2892                              <1> 	; 22/06/2017
  2893                              <1> 	; get current sound (PCM out) data for graphics
  2894                              <1> 	;
  2895                              <1> 	; ebx = Physical address (on page boundary)
  2896                              <1> 	; ecx = Byte count
  2897                              <1> 	; [audio_buff_size]
  2898                              <1> 
  2899 00013253 8B0D[7C760100]      <1> 	mov	ecx, [audio_dmabuff_size]
  2900 00013259 31DB                <1> 	xor	ebx, ebx
  2901                              <1> gdmabo_0:
  2902 0001325B 803D[59760100]02    <1> 	cmp	byte [audio_device], 2
  2903 00013262 72CA                <1> 	jb	short sb16_get_dma_buff_off
  2904 00013264 742A                <1> 	je	short ac97_get_dma_buff_off
  2905                              <1> 
  2906                              <1> vt8233_get_dma_buff_off:
  2907                              <1> 	; 24/06/2017
  2908                              <1> 	; 22/06/2017
  2909                              <1> 	; get current (PCM OUT DMA buffer) pointer
  2910                              <1> 	; (for VT 8233, VT 8237R)
  2911                              <1> 	
  2912                              <1> 	;mov	ecx, [audio_dmabuff_size]
  2913                              <1> 	;xor	ebx, ebx
  2914 00013266 D1E9                <1> 	shr	ecx, 1
  2915                              <1> vt8233_gdmabo_0:
  2916 00013268 BA0C000000          <1> 	mov	edx, VIA_REG_OFFSET_CURR_COUNT
  2917 0001326D E8FDF4FFFF          <1> 	call	ctrl_io_r32
  2918 00013272 89C2                <1> 	mov	edx, eax ; remain count (bits 23-0),
  2919                              <1> 			 ; SGD index (bits 31-24) 
  2920 00013274 81E200000001        <1> 	and	edx, 1000000h ; SGD index (0 = 1st half)
  2921 0001327A 7402                <1> 	jz	short vt8233_gdmabo_1
  2922                              <1> 	; the second half of DMA buffer
  2923 0001327C 89CB                <1> 	mov	ebx, ecx 
  2924                              <1> vt8233_gdmabo_1:	
  2925 0001327E 25FFFFFF00          <1> 	and	eax, 0FFFFFFh ; bits 23-0
  2926                              <1> sb16_gdmabo_2:
  2927                              <1> ac97_gdmabo_2:
  2928 00013283 29C1                <1> 	sub	ecx, eax
  2929 00013285 7602                <1> 	jna	short vt8233_gdmabo_2
  2930 00013287 01CB                <1> 	add	ebx, ecx ; dma buffer offset
  2931                              <1> vt8233_gdmabo_2:
  2932 00013289 891D[64030300]      <1> 	mov	[u.r0], ebx
  2933 0001328F C3                  <1> 	retn
  2934                              <1> 
  2935                              <1> ac97_get_dma_buff_off:
  2936                              <1> 	; 24/06/2017
  2937                              <1> 	; 22/06/2017
  2938                              <1> 	; get current (PCM OUT DMA buffer) pointer
  2939                              <1> 	; (for AC'97, ICH)
  2940                              <1> 	; ebx = Physical address (on page boundary)
  2941                              <1> 	; ecx = Byte count
  2942                              <1> 	; [audio_buff_size]
  2943                              <1> 	
  2944                              <1> 	;mov	ecx, [audio_dmabuff_size]
  2945                              <1> 	;xor	ebx, ebx
  2946 00013290 D1E9                <1> 	shr	ecx, 1
  2947                              <1> ac97_gdmabo_0:
  2948 00013292 66BA1400            <1> 	mov	dx, PO_CIV_REG ; Position In Current Buff Reg
  2949 00013296 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2950 0001329D EC                  <1> 	in	al, dx ; current index value
  2951 0001329E A801                <1> 	test	al, 1
  2952 000132A0 7402                <1> 	jz	short ac97_gdmabo_1
  2953 000132A2 89CB                <1> 	mov	ebx, ecx
  2954                              <1> ac97_gdmabo_1:
  2955 000132A4 31C0                <1> 	xor	eax, eax
  2956 000132A6 66BA1800            <1> 	mov	dx, PO_PICB_REG ; Position In Current Buff Reg
  2957 000132AA 660315[92760100]    <1> 	add	dx, [NABMBAR]
  2958 000132B1 66ED                <1> 	in	ax, dx ; remain dwords
  2959 000132B3 EBCE                <1> 	jmp	short ac97_gdmabo_2
  3376                                  
  3377 000132B5 90<rept>                align 4
  3378                                  
  3379                                  %include 'vgadata.s' ; 04/07/2016
     1                              <1> ; ****************************************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.3 - vgadata.s  (palette and font data)
     3                              <1> ; -----------------------------------------------------------------------------
     4                              <1> ; Last Update: 25/11/2020
     5                              <1> ; -----------------------------------------------------------------------------
     6                              <1> ; Beginning: 16/01/2016
     7                              <1> ; -----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.15 (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 'Plex86/Bochs VGABios' source code, vgabios-0.7a (2011)
    14                              <1> ; by the LGPL VGABios Developers Team (2001-2008), 'vgatables.h'
    15                              <1> ;
    16                              <1> ; Oracle VirtualBox 5.0.24 VGABios Source Code 
    17                              <1> ; ('vgabios.c', 'vgatables.h', 'vgafonts.h', 'vgarom.asm')
    18                              <1> ;
    19                              <1> ; Palette and font data in assembly language format:
    20                              <1> ; 'VBoxVgaBiosAlternative.asm'
    21                              <1> 
    22                              <1> ; ****************************************************************************************************
    23                              <1> 
    24                              <1> ; 25/11/2020 (TRDOS 386 v2.0.3)
    25                              <1> ; ('vgatables.h' - 30/12/2019 - vruppert)
    26                              <1>  
    27                              <1> ; 04/07/2016
    28                              <1> ; COLOR DATA
    29                              <1> 
    30                              <1> palette0: ; (63+1)*3
    31 000132B8 000000000000000000- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
    31 000132C1 00000000000000      <1>
    32 000132C8 00000000000000002A- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah
    32 000132D1 2A2A2A2A2A2A2A      <1>
    33 000132D8 2A2A2A2A2A2A2A2A2A- <1>     db  02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah
    33 000132E1 2A2A2A2A2A2A2A      <1>
    34 000132E8 2A2A2A2A2A2A2A2A2A- <1>     db  02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah
    34 000132F1 2A2A2A2A2A2A2A      <1>
    35 000132F8 2A2A2A2A2A2A2A2A3F- <1>     db  02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh
    35 00013301 3F3F3F3F3F3F3F      <1>
    36 00013308 3F3F3F3F3F3F3F3F3F- <1>     db  03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh
    36 00013311 3F3F3F3F3F3F3F      <1>
    37 00013318 000000000000000000- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
    37 00013321 00000000000000      <1>
    38 00013328 00000000000000002A- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah
    38 00013331 2A2A2A2A2A2A2A      <1>
    39 00013338 2A2A2A2A2A2A2A2A2A- <1>     db  02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah
    39 00013341 2A2A2A2A2A2A2A      <1>
    40 00013348 2A2A2A2A2A2A2A2A2A- <1>     db  02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah
    40 00013351 2A2A2A2A2A2A2A      <1>
    41 00013358 2A2A2A2A2A2A2A2A3F- <1>     db  02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 02ah, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh
    41 00013361 3F3F3F3F3F3F3F      <1>
    42 00013368 3F3F3F3F3F3F3F3F3F- <1>     db  03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh, 03fh
    42 00013371 3F3F3F3F3F3F3F      <1>
    43                              <1> palette1: ; (63+1)*3	
    44 00013378 00000000002A002A00- <1>     db  000h, 000h, 000h, 000h, 000h, 02ah, 000h, 02ah, 000h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 02ah
    44 00013381 002A2A2A00002A      <1>
    45 00013388 002A2A15002A2A2A00- <1>     db  000h, 02ah, 02ah, 015h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 000h, 000h, 000h, 02ah, 000h, 02ah
    45 00013391 000000002A002A      <1>
    46 00013398 00002A2A2A00002A00- <1>     db  000h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 02ah, 000h, 02ah, 02ah, 015h, 000h, 02ah, 02ah, 02ah
    46 000133A1 2A2A15002A2A2A      <1>
    47 000133A8 15151515153F153F15- <1>     db  015h, 015h, 015h, 015h, 015h, 03fh, 015h, 03fh, 015h, 015h, 03fh, 03fh, 03fh, 015h, 015h, 03fh
    47 000133B1 153F3F3F15153F      <1>
    48 000133B8 153F3F3F153F3F3F15- <1>     db  015h, 03fh, 03fh, 03fh, 015h, 03fh, 03fh, 03fh, 015h, 015h, 015h, 015h, 015h, 03fh, 015h, 03fh
    48 000133C1 151515153F153F      <1>
    49 000133C8 15153F3F3F15153F15- <1>     db  015h, 015h, 03fh, 03fh, 03fh, 015h, 015h, 03fh, 015h, 03fh, 03fh, 03fh, 015h, 03fh, 03fh, 03fh
    49 000133D1 3F3F3F153F3F3F      <1>
    50 000133D8 00000000002A002A00- <1>     db  000h, 000h, 000h, 000h, 000h, 02ah, 000h, 02ah, 000h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 02ah
    50 000133E1 002A2A2A00002A      <1>
    51 000133E8 002A2A15002A2A2A00- <1>     db  000h, 02ah, 02ah, 015h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 000h, 000h, 000h, 02ah, 000h, 02ah
    51 000133F1 000000002A002A      <1>
    52 000133F8 00002A2A2A00002A00- <1>     db  000h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 02ah, 000h, 02ah, 02ah, 015h, 000h, 02ah, 02ah, 02ah
    52 00013401 2A2A15002A2A2A      <1>
    53 00013408 15151515153F153F15- <1>     db  015h, 015h, 015h, 015h, 015h, 03fh, 015h, 03fh, 015h, 015h, 03fh, 03fh, 03fh, 015h, 015h, 03fh
    53 00013411 153F3F3F15153F      <1>
    54 00013418 153F3F3F153F3F3F15- <1>     db  015h, 03fh, 03fh, 03fh, 015h, 03fh, 03fh, 03fh, 015h, 015h, 015h, 015h, 015h, 03fh, 015h, 03fh
    54 00013421 151515153F153F      <1>
    55 00013428 15153F3F3F15153F15- <1>     db  015h, 015h, 03fh, 03fh, 03fh, 015h, 015h, 03fh, 015h, 03fh, 03fh, 03fh, 015h, 03fh, 03fh, 03fh
    55 00013431 3F3F3F153F3F3F      <1>
    56                              <1> palette2: ; (63+1)*3
    57 00013438 00000000002A002A00- <1>     db  000h, 000h, 000h, 000h, 000h, 02ah, 000h, 02ah, 000h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 02ah
    57 00013441 002A2A2A00002A      <1>
    58 00013448 002A2A2A002A2A2A00- <1>     db  000h, 02ah, 02ah, 02ah, 000h, 02ah, 02ah, 02ah, 000h, 000h, 015h, 000h, 000h, 03fh, 000h, 02ah
    58 00013451 001500003F002A      <1>
    59 00013458 15002A3F2A00152A00- <1>     db  015h, 000h, 02ah, 03fh, 02ah, 000h, 015h, 02ah, 000h, 03fh, 02ah, 02ah, 015h, 02ah, 02ah, 03fh
    59 00013461 3F2A2A152A2A3F      <1>
    60 00013468 00150000152A003F00- <1>     db  000h, 015h, 000h, 000h, 015h, 02ah, 000h, 03fh, 000h, 000h, 03fh, 02ah, 02ah, 015h, 000h, 02ah
    60 00013471 003F2A2A15002A      <1>
    61 00013478 152A2A3F002A3F2A00- <1>     db  015h, 02ah, 02ah, 03fh, 000h, 02ah, 03fh, 02ah, 000h, 015h, 015h, 000h, 015h, 03fh, 000h, 03fh
    61 00013481 151500153F003F      <1>
    62 00013488 15003F3F2A15152A15- <1>     db  015h, 000h, 03fh, 03fh, 02ah, 015h, 015h, 02ah, 015h, 03fh, 02ah, 03fh, 015h, 02ah, 03fh, 03fh
    62 00013491 3F2A3F152A3F3F      <1>
    63 00013498 15000015002A152A00- <1>     db  015h, 000h, 000h, 015h, 000h, 02ah, 015h, 02ah, 000h, 015h, 02ah, 02ah, 03fh, 000h, 000h, 03fh
    63 000134A1 152A2A3F00003F      <1>
    64 000134A8 002A3F2A003F2A2A15- <1>     db  000h, 02ah, 03fh, 02ah, 000h, 03fh, 02ah, 02ah, 015h, 000h, 015h, 015h, 000h, 03fh, 015h, 02ah
    64 000134B1 001515003F152A      <1>
    65 000134B8 15152A3F3F00153F00- <1>     db  015h, 015h, 02ah, 03fh, 03fh, 000h, 015h, 03fh, 000h, 03fh, 03fh, 02ah, 015h, 03fh, 02ah, 03fh
    65 000134C1 3F3F2A153F2A3F      <1>
    66 000134C8 15150015152A153F00- <1>     db  015h, 015h, 000h, 015h, 015h, 02ah, 015h, 03fh, 000h, 015h, 03fh, 02ah, 03fh, 015h, 000h, 03fh
    66 000134D1 153F2A3F15003F      <1>
    67 000134D8 152A3F3F003F3F2A15- <1>     db  015h, 02ah, 03fh, 03fh, 000h, 03fh, 03fh, 02ah, 015h, 015h, 015h, 015h, 015h, 03fh, 015h, 03fh
    67 000134E1 151515153F153F      <1>
    68 000134E8 15153F3F3F15153F15- <1>     db  015h, 015h, 03fh, 03fh, 03fh, 015h, 015h, 03fh, 015h, 03fh, 03fh, 03fh, 015h, 03fh, 03fh, 03fh
    68 000134F1 3F3F3F153F3F3F      <1>
    69                              <1> palette3: ; 256*3
    70 000134F8 00000000002A002A00- <1>     db  000h, 000h, 000h, 000h, 000h, 02ah, 000h, 02ah, 000h, 000h, 02ah, 02ah, 02ah, 000h, 000h, 02ah
    70 00013501 002A2A2A00002A      <1>
    71 00013508 002A2A15002A2A2A15- <1>     db  000h, 02ah, 02ah, 015h, 000h, 02ah, 02ah, 02ah, 015h, 015h, 015h, 015h, 015h, 03fh, 015h, 03fh
    71 00013511 151515153F153F      <1>
    72 00013518 15153F3F3F15153F15- <1>     db  015h, 015h, 03fh, 03fh, 03fh, 015h, 015h, 03fh, 015h, 03fh, 03fh, 03fh, 015h, 03fh, 03fh, 03fh
    72 00013521 3F3F3F153F3F3F      <1>
    73 00013528 000000050505080808- <1>     db  000h, 000h, 000h, 005h, 005h, 005h, 008h, 008h, 008h, 00bh, 00bh, 00bh, 00eh, 00eh, 00eh, 011h
    73 00013531 0B0B0B0E0E0E11      <1>
    74 00013538 11111414141818181C- <1>     db  011h, 011h, 014h, 014h, 014h, 018h, 018h, 018h, 01ch, 01ch, 01ch, 020h, 020h, 020h, 024h, 024h
    74 00013541 1C1C2020202424      <1>
    75 00013548 242828282D2D2D3232- <1>     db  024h, 028h, 028h, 028h, 02dh, 02dh, 02dh, 032h, 032h, 032h, 038h, 038h, 038h, 03fh, 03fh, 03fh
    75 00013551 323838383F3F3F      <1>
    76 00013558 00003F10003F1F003F- <1>     db  000h, 000h, 03fh, 010h, 000h, 03fh, 01fh, 000h, 03fh, 02fh, 000h, 03fh, 03fh, 000h, 03fh, 03fh
    76 00013561 2F003F3F003F3F      <1>
    77 00013568 002F3F001F3F00103F- <1>     db  000h, 02fh, 03fh, 000h, 01fh, 03fh, 000h, 010h, 03fh, 000h, 000h, 03fh, 010h, 000h, 03fh, 01fh
    77 00013571 00003F10003F1F      <1>
    78 00013578 003F2F003F3F002F3F- <1>     db  000h, 03fh, 02fh, 000h, 03fh, 03fh, 000h, 02fh, 03fh, 000h, 01fh, 03fh, 000h, 010h, 03fh, 000h
    78 00013581 001F3F00103F00      <1>
    79 00013588 003F00003F10003F1F- <1>     db  000h, 03fh, 000h, 000h, 03fh, 010h, 000h, 03fh, 01fh, 000h, 03fh, 02fh, 000h, 03fh, 03fh, 000h
    79 00013591 003F2F003F3F00      <1>
    80 00013598 2F3F001F3F00103F1F- <1>     db  02fh, 03fh, 000h, 01fh, 03fh, 000h, 010h, 03fh, 01fh, 01fh, 03fh, 027h, 01fh, 03fh, 02fh, 01fh
    80 000135A1 1F3F271F3F2F1F      <1>
    81 000135A8 3F371F3F3F1F3F3F1F- <1>     db  03fh, 037h, 01fh, 03fh, 03fh, 01fh, 03fh, 03fh, 01fh, 037h, 03fh, 01fh, 02fh, 03fh, 01fh, 027h
    81 000135B1 373F1F2F3F1F27      <1>
    82 000135B8 3F1F1F3F271F3F2F1F- <1>     db  03fh, 01fh, 01fh, 03fh, 027h, 01fh, 03fh, 02fh, 01fh, 03fh, 037h, 01fh, 03fh, 03fh, 01fh, 037h
    82 000135C1 3F371F3F3F1F37      <1>
    83 000135C8 3F1F2F3F1F273F1F1F- <1>     db  03fh, 01fh, 02fh, 03fh, 01fh, 027h, 03fh, 01fh, 01fh, 03fh, 01fh, 01fh, 03fh, 027h, 01fh, 03fh
    83 000135D1 3F1F1F3F271F3F      <1>
    84 000135D8 2F1F3F371F3F3F1F37- <1>     db  02fh, 01fh, 03fh, 037h, 01fh, 03fh, 03fh, 01fh, 037h, 03fh, 01fh, 02fh, 03fh, 01fh, 027h, 03fh
    84 000135E1 3F1F2F3F1F273F      <1>
    85 000135E8 2D2D3F312D3F362D3F- <1>     db  02dh, 02dh, 03fh, 031h, 02dh, 03fh, 036h, 02dh, 03fh, 03ah, 02dh, 03fh, 03fh, 02dh, 03fh, 03fh
    85 000135F1 3A2D3F3F2D3F3F      <1>
    86 000135F8 2D3A3F2D363F2D313F- <1>     db  02dh, 03ah, 03fh, 02dh, 036h, 03fh, 02dh, 031h, 03fh, 02dh, 02dh, 03fh, 031h, 02dh, 03fh, 036h
    86 00013601 2D2D3F312D3F36      <1>
    87 00013608 2D3F3A2D3F3F2D3A3F- <1>     db  02dh, 03fh, 03ah, 02dh, 03fh, 03fh, 02dh, 03ah, 03fh, 02dh, 036h, 03fh, 02dh, 031h, 03fh, 02dh
    87 00013611 2D363F2D313F2D      <1>
    88 00013618 2D3F2D2D3F312D3F36- <1>     db  02dh, 03fh, 02dh, 02dh, 03fh, 031h, 02dh, 03fh, 036h, 02dh, 03fh, 03ah, 02dh, 03fh, 03fh, 02dh
    88 00013621 2D3F3A2D3F3F2D      <1>
    89 00013628 3A3F2D363F2D313F00- <1>     db  03ah, 03fh, 02dh, 036h, 03fh, 02dh, 031h, 03fh, 000h, 000h, 01ch, 007h, 000h, 01ch, 00eh, 000h
    89 00013631 001C07001C0E00      <1>
    90 00013638 1C15001C1C001C1C00- <1>     db  01ch, 015h, 000h, 01ch, 01ch, 000h, 01ch, 01ch, 000h, 015h, 01ch, 000h, 00eh, 01ch, 000h, 007h
    90 00013641 151C000E1C0007      <1>
    91 00013648 1C00001C07001C0E00- <1>     db  01ch, 000h, 000h, 01ch, 007h, 000h, 01ch, 00eh, 000h, 01ch, 015h, 000h, 01ch, 01ch, 000h, 015h
    91 00013651 1C15001C1C0015      <1>
    92 00013658 1C000E1C00071C0000- <1>     db  01ch, 000h, 00eh, 01ch, 000h, 007h, 01ch, 000h, 000h, 01ch, 000h, 000h, 01ch, 007h, 000h, 01ch
    92 00013661 1C00001C07001C      <1>
    93 00013668 0E001C15001C1C0015- <1>     db  00eh, 000h, 01ch, 015h, 000h, 01ch, 01ch, 000h, 015h, 01ch, 000h, 00eh, 01ch, 000h, 007h, 01ch
    93 00013671 1C000E1C00071C      <1>
    94 00013678 0E0E1C110E1C150E1C- <1>     db  00eh, 00eh, 01ch, 011h, 00eh, 01ch, 015h, 00eh, 01ch, 018h, 00eh, 01ch, 01ch, 00eh, 01ch, 01ch
    94 00013681 180E1C1C0E1C1C      <1>
    95 00013688 0E181C0E151C0E111C- <1>     db  00eh, 018h, 01ch, 00eh, 015h, 01ch, 00eh, 011h, 01ch, 00eh, 00eh, 01ch, 011h, 00eh, 01ch, 015h
    95 00013691 0E0E1C110E1C15      <1>
    96 00013698 0E1C180E1C1C0E181C- <1>     db  00eh, 01ch, 018h, 00eh, 01ch, 01ch, 00eh, 018h, 01ch, 00eh, 015h, 01ch, 00eh, 011h, 01ch, 00eh
    96 000136A1 0E151C0E111C0E      <1>
    97 000136A8 0E1C0E0E1C110E1C15- <1>     db  00eh, 01ch, 00eh, 00eh, 01ch, 011h, 00eh, 01ch, 015h, 00eh, 01ch, 018h, 00eh, 01ch, 01ch, 00eh
    97 000136B1 0E1C180E1C1C0E      <1>
    98 000136B8 181C0E151C0E111C14- <1>     db  018h, 01ch, 00eh, 015h, 01ch, 00eh, 011h, 01ch, 014h, 014h, 01ch, 016h, 014h, 01ch, 018h, 014h
    98 000136C1 141C16141C1814      <1>
    99 000136C8 1C1A141C1C141C1C14- <1>     db  01ch, 01ah, 014h, 01ch, 01ch, 014h, 01ch, 01ch, 014h, 01ah, 01ch, 014h, 018h, 01ch, 014h, 016h
    99 000136D1 1A1C14181C1416      <1>
   100 000136D8 1C14141C16141C1814- <1>     db  01ch, 014h, 014h, 01ch, 016h, 014h, 01ch, 018h, 014h, 01ch, 01ah, 014h, 01ch, 01ch, 014h, 01ah
   100 000136E1 1C1A141C1C141A      <1>
   101 000136E8 1C14181C14161C1414- <1>     db  01ch, 014h, 018h, 01ch, 014h, 016h, 01ch, 014h, 014h, 01ch, 014h, 014h, 01ch, 016h, 014h, 01ch
   101 000136F1 1C14141C16141C      <1>
   102 000136F8 18141C1A141C1C141A- <1>     db  018h, 014h, 01ch, 01ah, 014h, 01ch, 01ch, 014h, 01ah, 01ch, 014h, 018h, 01ch, 014h, 016h, 01ch
   102 00013701 1C14181C14161C      <1>
   103 00013708 000010040010080010- <1>     db  000h, 000h, 010h, 004h, 000h, 010h, 008h, 000h, 010h, 00ch, 000h, 010h, 010h, 000h, 010h, 010h
   103 00013711 0C001010001010      <1>
   104 00013718 000C10000810000410- <1>     db  000h, 00ch, 010h, 000h, 008h, 010h, 000h, 004h, 010h, 000h, 000h, 010h, 004h, 000h, 010h, 008h
   104 00013721 00001004001008      <1>
   105 00013728 00100C001010000C10- <1>     db  000h, 010h, 00ch, 000h, 010h, 010h, 000h, 00ch, 010h, 000h, 008h, 010h, 000h, 004h, 010h, 000h
   105 00013731 00081000041000      <1>
   106 00013738 001000001004001008- <1>     db  000h, 010h, 000h, 000h, 010h, 004h, 000h, 010h, 008h, 000h, 010h, 00ch, 000h, 010h, 010h, 000h
   106 00013741 00100C00101000      <1>
   107 00013748 0C1000081000041008- <1>     db  00ch, 010h, 000h, 008h, 010h, 000h, 004h, 010h, 008h, 008h, 010h, 00ah, 008h, 010h, 00ch, 008h
   107 00013751 08100A08100C08      <1>
   108 00013758 100E08101008101008- <1>     db  010h, 00eh, 008h, 010h, 010h, 008h, 010h, 010h, 008h, 00eh, 010h, 008h, 00ch, 010h, 008h, 00ah
   108 00013761 0E10080C10080A      <1>
   109 00013768 100808100A08100C08- <1>     db  010h, 008h, 008h, 010h, 00ah, 008h, 010h, 00ch, 008h, 010h, 00eh, 008h, 010h, 010h, 008h, 00eh
   109 00013771 100E081010080E      <1>
   110 00013778 10080C10080A100808- <1>     db  010h, 008h, 00ch, 010h, 008h, 00ah, 010h, 008h, 008h, 010h, 008h, 008h, 010h, 00ah, 008h, 010h
   110 00013781 100808100A0810      <1>
   111 00013788 0C08100E081010080E- <1>     db  00ch, 008h, 010h, 00eh, 008h, 010h, 010h, 008h, 00eh, 010h, 008h, 00ch, 010h, 008h, 00ah, 010h
   111 00013791 10080C10080A10      <1>
   112 00013798 0B0B100C0B100D0B10- <1>     db  00bh, 00bh, 010h, 00ch, 00bh, 010h, 00dh, 00bh, 010h, 00fh, 00bh, 010h, 010h, 00bh, 010h, 010h
   112 000137A1 0F0B10100B1010      <1>
   113 000137A8 0B0F100B0D100B0C10- <1>     db  00bh, 00fh, 010h, 00bh, 00dh, 010h, 00bh, 00ch, 010h, 00bh, 00bh, 010h, 00ch, 00bh, 010h, 00dh
   113 000137B1 0B0B100C0B100D      <1>
   114 000137B8 0B100F0B10100B0F10- <1>     db  00bh, 010h, 00fh, 00bh, 010h, 010h, 00bh, 00fh, 010h, 00bh, 00dh, 010h, 00bh, 00ch, 010h, 00bh
   114 000137C1 0B0D100B0C100B      <1>
   115 000137C8 0B100B0B100C0B100D- <1>     db  00bh, 010h, 00bh, 00bh, 010h, 00ch, 00bh, 010h, 00dh, 00bh, 010h, 00fh, 00bh, 010h, 010h, 00bh
   115 000137D1 0B100F0B10100B      <1>
   116 000137D8 0F100B0D100B0C1000- <1>     db  00fh, 010h, 00bh, 00dh, 010h, 00bh, 00ch, 010h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   116 000137E1 00000000000000      <1>
   117 000137E8 000000000000000000- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   117 000137F1 00000000000000      <1>
   118                              <1> 
   119                              <1> 
   120                              <1> ; 04/07/2016
   121                              <1> ; FONT DATA
   122                              <1> 
   123                              <1> CRT_CHAR_GEN:
   124                              <1> vgafont8: 
   125 000137F8 00000000000000007E- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 07eh, 081h, 0a5h, 081h, 0bdh, 099h, 081h, 07eh
   125 00013801 81A581BD99817E      <1>
   126 00013808 7EFFDBFFC3E7FF7E6C- <1>     db  07eh, 0ffh, 0dbh, 0ffh, 0c3h, 0e7h, 0ffh, 07eh, 06ch, 0feh, 0feh, 0feh, 07ch, 038h, 010h, 000h
   126 00013811 FEFEFE7C381000      <1>
   127 00013818 10387CFE7C38100038- <1>     db  010h, 038h, 07ch, 0feh, 07ch, 038h, 010h, 000h, 038h, 07ch, 038h, 0feh, 0feh, 07ch, 038h, 07ch
   127 00013821 7C38FEFE7C387C      <1>
   128 00013828 1010387CFE7C387C00- <1>     db  010h, 010h, 038h, 07ch, 0feh, 07ch, 038h, 07ch, 000h, 000h, 018h, 03ch, 03ch, 018h, 000h, 000h
   128 00013831 00183C3C180000      <1>
   129 00013838 FFFFE7C3C3E7FFFF00- <1>     db  0ffh, 0ffh, 0e7h, 0c3h, 0c3h, 0e7h, 0ffh, 0ffh, 000h, 03ch, 066h, 042h, 042h, 066h, 03ch, 000h
   129 00013841 3C664242663C00      <1>
   130 00013848 FFC399BDBD99C3FF0F- <1>     db  0ffh, 0c3h, 099h, 0bdh, 0bdh, 099h, 0c3h, 0ffh, 00fh, 007h, 00fh, 07dh, 0cch, 0cch, 0cch, 078h
   130 00013851 070F7DCCCCCC78      <1>
   131 00013858 3C6666663C187E183F- <1>     db  03ch, 066h, 066h, 066h, 03ch, 018h, 07eh, 018h, 03fh, 033h, 03fh, 030h, 030h, 070h, 0f0h, 0e0h
   131 00013861 333F303070F0E0      <1>
   132 00013868 7F637F636367E6C099- <1>     db  07fh, 063h, 07fh, 063h, 063h, 067h, 0e6h, 0c0h, 099h, 05ah, 03ch, 0e7h, 0e7h, 03ch, 05ah, 099h
   132 00013871 5A3CE7E73C5A99      <1>
   133 00013878 80E0F8FEF8E0800002- <1>     db  080h, 0e0h, 0f8h, 0feh, 0f8h, 0e0h, 080h, 000h, 002h, 00eh, 03eh, 0feh, 03eh, 00eh, 002h, 000h
   133 00013881 0E3EFE3E0E0200      <1>
   134 00013888 183C7E18187E3C1866- <1>     db  018h, 03ch, 07eh, 018h, 018h, 07eh, 03ch, 018h, 066h, 066h, 066h, 066h, 066h, 000h, 066h, 000h
   134 00013891 66666666006600      <1>
   135 00013898 7FDBDB7B1B1B1B003E- <1>     db  07fh, 0dbh, 0dbh, 07bh, 01bh, 01bh, 01bh, 000h, 03eh, 063h, 038h, 06ch, 06ch, 038h, 0cch, 078h
   135 000138A1 63386C6C38CC78      <1>
   136 000138A8 000000007E7E7E0018- <1>     db  000h, 000h, 000h, 000h, 07eh, 07eh, 07eh, 000h, 018h, 03ch, 07eh, 018h, 07eh, 03ch, 018h, 0ffh
   136 000138B1 3C7E187E3C18FF      <1>
   137 000138B8 183C7E181818180018- <1>     db  018h, 03ch, 07eh, 018h, 018h, 018h, 018h, 000h, 018h, 018h, 018h, 018h, 07eh, 03ch, 018h, 000h
   137 000138C1 1818187E3C1800      <1>
   138 000138C8 00180CFE0C18000000- <1>     db  000h, 018h, 00ch, 0feh, 00ch, 018h, 000h, 000h, 000h, 030h, 060h, 0feh, 060h, 030h, 000h, 000h
   138 000138D1 3060FE60300000      <1>
   139 000138D8 0000C0C0C0FE000000- <1>     db  000h, 000h, 0c0h, 0c0h, 0c0h, 0feh, 000h, 000h, 000h, 024h, 066h, 0ffh, 066h, 024h, 000h, 000h
   139 000138E1 2466FF66240000      <1>
   140 000138E8 00183C7EFFFF000000- <1>     db  000h, 018h, 03ch, 07eh, 0ffh, 0ffh, 000h, 000h, 000h, 0ffh, 0ffh, 07eh, 03ch, 018h, 000h, 000h
   140 000138F1 FFFF7E3C180000      <1>
   141 000138F8 000000000000000030- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 030h, 078h, 078h, 030h, 030h, 000h, 030h, 000h
   141 00013901 78783030003000      <1>
   142 00013908 6C6C6C00000000006C- <1>     db  06ch, 06ch, 06ch, 000h, 000h, 000h, 000h, 000h, 06ch, 06ch, 0feh, 06ch, 0feh, 06ch, 06ch, 000h
   142 00013911 6CFE6CFE6C6C00      <1>
   143 00013918 307CC0780CF8300000- <1>     db  030h, 07ch, 0c0h, 078h, 00ch, 0f8h, 030h, 000h, 000h, 0c6h, 0cch, 018h, 030h, 066h, 0c6h, 000h
   143 00013921 C6CC183066C600      <1>
   144 00013928 386C3876DCCC760060- <1>     db  038h, 06ch, 038h, 076h, 0dch, 0cch, 076h, 000h, 060h, 060h, 0c0h, 000h, 000h, 000h, 000h, 000h
   144 00013931 60C00000000000      <1>
   145 00013938 183060606030180060- <1>     db  018h, 030h, 060h, 060h, 060h, 030h, 018h, 000h, 060h, 030h, 018h, 018h, 018h, 030h, 060h, 000h
   145 00013941 30181818306000      <1>
   146 00013948 00663CFF3C66000000- <1>     db  000h, 066h, 03ch, 0ffh, 03ch, 066h, 000h, 000h, 000h, 030h, 030h, 0fch, 030h, 030h, 000h, 000h
   146 00013951 3030FC30300000      <1>
   147 00013958 000000000030306000- <1>     db  000h, 000h, 000h, 000h, 000h, 030h, 030h, 060h, 000h, 000h, 000h, 0fch, 000h, 000h, 000h, 000h
   147 00013961 0000FC00000000      <1>
   148 00013968 000000000030300006- <1>     db  000h, 000h, 000h, 000h, 000h, 030h, 030h, 000h, 006h, 00ch, 018h, 030h, 060h, 0c0h, 080h, 000h
   148 00013971 0C183060C08000      <1>
   149 00013978 7CC6CEDEF6E67C0030- <1>     db  07ch, 0c6h, 0ceh, 0deh, 0f6h, 0e6h, 07ch, 000h, 030h, 070h, 030h, 030h, 030h, 030h, 0fch, 000h
   149 00013981 7030303030FC00      <1>
   150 00013988 78CC0C3860CCFC0078- <1>     db  078h, 0cch, 00ch, 038h, 060h, 0cch, 0fch, 000h, 078h, 0cch, 00ch, 038h, 00ch, 0cch, 078h, 000h
   150 00013991 CC0C380CCC7800      <1>
   151 00013998 1C3C6CCCFE0C1E00FC- <1>     db  01ch, 03ch, 06ch, 0cch, 0feh, 00ch, 01eh, 000h, 0fch, 0c0h, 0f8h, 00ch, 00ch, 0cch, 078h, 000h
   151 000139A1 C0F80C0CCC7800      <1>
   152 000139A8 3860C0F8CCCC7800FC- <1>     db  038h, 060h, 0c0h, 0f8h, 0cch, 0cch, 078h, 000h, 0fch, 0cch, 00ch, 018h, 030h, 030h, 030h, 000h
   152 000139B1 CC0C1830303000      <1>
   153 000139B8 78CCCC78CCCC780078- <1>     db  078h, 0cch, 0cch, 078h, 0cch, 0cch, 078h, 000h, 078h, 0cch, 0cch, 07ch, 00ch, 018h, 070h, 000h
   153 000139C1 CCCC7C0C187000      <1>
   154 000139C8 003030000030300000- <1>     db  000h, 030h, 030h, 000h, 000h, 030h, 030h, 000h, 000h, 030h, 030h, 000h, 000h, 030h, 030h, 060h
   154 000139D1 30300000303060      <1>
   155 000139D8 183060C06030180000- <1>     db  018h, 030h, 060h, 0c0h, 060h, 030h, 018h, 000h, 000h, 000h, 0fch, 000h, 000h, 0fch, 000h, 000h
   155 000139E1 00FC0000FC0000      <1>
   156 000139E8 6030180C1830600078- <1>     db  060h, 030h, 018h, 00ch, 018h, 030h, 060h, 000h, 078h, 0cch, 00ch, 018h, 030h, 000h, 030h, 000h
   156 000139F1 CC0C1830003000      <1>
   157 000139F8 7CC6DEDEDEC0780030- <1>     db  07ch, 0c6h, 0deh, 0deh, 0deh, 0c0h, 078h, 000h, 030h, 078h, 0cch, 0cch, 0fch, 0cch, 0cch, 000h
   157 00013A01 78CCCCFCCCCC00      <1>
   158 00013A08 FC66667C6666FC003C- <1>     db  0fch, 066h, 066h, 07ch, 066h, 066h, 0fch, 000h, 03ch, 066h, 0c0h, 0c0h, 0c0h, 066h, 03ch, 000h
   158 00013A11 66C0C0C0663C00      <1>
   159 00013A18 F86C6666666CF800FE- <1>     db  0f8h, 06ch, 066h, 066h, 066h, 06ch, 0f8h, 000h, 0feh, 062h, 068h, 078h, 068h, 062h, 0feh, 000h
   159 00013A21 6268786862FE00      <1>
   160 00013A28 FE6268786860F0003C- <1>     db  0feh, 062h, 068h, 078h, 068h, 060h, 0f0h, 000h, 03ch, 066h, 0c0h, 0c0h, 0ceh, 066h, 03eh, 000h
   160 00013A31 66C0C0CE663E00      <1>
   161 00013A38 CCCCCCFCCCCCCC0078- <1>     db  0cch, 0cch, 0cch, 0fch, 0cch, 0cch, 0cch, 000h, 078h, 030h, 030h, 030h, 030h, 030h, 078h, 000h
   161 00013A41 30303030307800      <1>
   162 00013A48 1E0C0C0CCCCC7800E6- <1>     db  01eh, 00ch, 00ch, 00ch, 0cch, 0cch, 078h, 000h, 0e6h, 066h, 06ch, 078h, 06ch, 066h, 0e6h, 000h
   162 00013A51 666C786C66E600      <1>
   163 00013A58 F06060606266FE00C6- <1>     db  0f0h, 060h, 060h, 060h, 062h, 066h, 0feh, 000h, 0c6h, 0eeh, 0feh, 0feh, 0d6h, 0c6h, 0c6h, 000h
   163 00013A61 EEFEFED6C6C600      <1>
   164 00013A68 C6E6F6DECEC6C60038- <1>     db  0c6h, 0e6h, 0f6h, 0deh, 0ceh, 0c6h, 0c6h, 000h, 038h, 06ch, 0c6h, 0c6h, 0c6h, 06ch, 038h, 000h
   164 00013A71 6CC6C6C66C3800      <1>
   165 00013A78 FC66667C6060F00078- <1>     db  0fch, 066h, 066h, 07ch, 060h, 060h, 0f0h, 000h, 078h, 0cch, 0cch, 0cch, 0dch, 078h, 01ch, 000h
   165 00013A81 CCCCCCDC781C00      <1>
   166 00013A88 FC66667C6C66E60078- <1>     db  0fch, 066h, 066h, 07ch, 06ch, 066h, 0e6h, 000h, 078h, 0cch, 0e0h, 070h, 01ch, 0cch, 078h, 000h
   166 00013A91 CCE0701CCC7800      <1>
   167 00013A98 FCB4303030307800CC- <1>     db  0fch, 0b4h, 030h, 030h, 030h, 030h, 078h, 000h, 0cch, 0cch, 0cch, 0cch, 0cch, 0cch, 0fch, 000h
   167 00013AA1 CCCCCCCCCCFC00      <1>
   168 00013AA8 CCCCCCCCCC783000C6- <1>     db  0cch, 0cch, 0cch, 0cch, 0cch, 078h, 030h, 000h, 0c6h, 0c6h, 0c6h, 0d6h, 0feh, 0eeh, 0c6h, 000h
   168 00013AB1 C6C6D6FEEEC600      <1>
   169 00013AB8 C6C66C38386CC600CC- <1>     db  0c6h, 0c6h, 06ch, 038h, 038h, 06ch, 0c6h, 000h, 0cch, 0cch, 0cch, 078h, 030h, 030h, 078h, 000h
   169 00013AC1 CCCC7830307800      <1>
   170 00013AC8 FEC68C183266FE0078- <1>     db  0feh, 0c6h, 08ch, 018h, 032h, 066h, 0feh, 000h, 078h, 060h, 060h, 060h, 060h, 060h, 078h, 000h
   170 00013AD1 60606060607800      <1>
   171 00013AD8 C06030180C06020078- <1>     db  0c0h, 060h, 030h, 018h, 00ch, 006h, 002h, 000h, 078h, 018h, 018h, 018h, 018h, 018h, 078h, 000h
   171 00013AE1 18181818187800      <1>
   172 00013AE8 10386CC60000000000- <1>     db  010h, 038h, 06ch, 0c6h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0ffh
   172 00013AF1 000000000000FF      <1>
   173 00013AF8 303018000000000000- <1>     db  030h, 030h, 018h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 078h, 00ch, 07ch, 0cch, 076h, 000h
   173 00013B01 00780C7CCC7600      <1>
   174 00013B08 E060607C6666DC0000- <1>     db  0e0h, 060h, 060h, 07ch, 066h, 066h, 0dch, 000h, 000h, 000h, 078h, 0cch, 0c0h, 0cch, 078h, 000h
   174 00013B11 0078CCC0CC7800      <1>
   175 00013B18 1C0C0C7CCCCC760000- <1>     db  01ch, 00ch, 00ch, 07ch, 0cch, 0cch, 076h, 000h, 000h, 000h, 078h, 0cch, 0fch, 0c0h, 078h, 000h
   175 00013B21 0078CCFCC07800      <1>
   176 00013B28 386C60F06060F00000- <1>     db  038h, 06ch, 060h, 0f0h, 060h, 060h, 0f0h, 000h, 000h, 000h, 076h, 0cch, 0cch, 07ch, 00ch, 0f8h
   176 00013B31 0076CCCC7C0CF8      <1>
   177 00013B38 E0606C766666E60030- <1>     db  0e0h, 060h, 06ch, 076h, 066h, 066h, 0e6h, 000h, 030h, 000h, 070h, 030h, 030h, 030h, 078h, 000h
   177 00013B41 00703030307800      <1>
   178 00013B48 0C000C0C0CCCCC78E0- <1>     db  00ch, 000h, 00ch, 00ch, 00ch, 0cch, 0cch, 078h, 0e0h, 060h, 066h, 06ch, 078h, 06ch, 0e6h, 000h
   178 00013B51 60666C786CE600      <1>
   179 00013B58 703030303030780000- <1>     db  070h, 030h, 030h, 030h, 030h, 030h, 078h, 000h, 000h, 000h, 0cch, 0feh, 0feh, 0d6h, 0c6h, 000h
   179 00013B61 00CCFEFED6C600      <1>
   180 00013B68 0000F8CCCCCCCC0000- <1>     db  000h, 000h, 0f8h, 0cch, 0cch, 0cch, 0cch, 000h, 000h, 000h, 078h, 0cch, 0cch, 0cch, 078h, 000h
   180 00013B71 0078CCCCCC7800      <1>
   181 00013B78 0000DC66667C60F000- <1>     db  000h, 000h, 0dch, 066h, 066h, 07ch, 060h, 0f0h, 000h, 000h, 076h, 0cch, 0cch, 07ch, 00ch, 01eh
   181 00013B81 0076CCCC7C0C1E      <1>
   182 00013B88 0000DC766660F00000- <1>     db  000h, 000h, 0dch, 076h, 066h, 060h, 0f0h, 000h, 000h, 000h, 07ch, 0c0h, 078h, 00ch, 0f8h, 000h
   182 00013B91 007CC0780CF800      <1>
   183 00013B98 10307C303034180000- <1>     db  010h, 030h, 07ch, 030h, 030h, 034h, 018h, 000h, 000h, 000h, 0cch, 0cch, 0cch, 0cch, 076h, 000h
   183 00013BA1 00CCCCCCCC7600      <1>
   184 00013BA8 0000CCCCCC78300000- <1>     db  000h, 000h, 0cch, 0cch, 0cch, 078h, 030h, 000h, 000h, 000h, 0c6h, 0d6h, 0feh, 0feh, 06ch, 000h
   184 00013BB1 00C6D6FEFE6C00      <1>
   185 00013BB8 0000C66C386CC60000- <1>     db  000h, 000h, 0c6h, 06ch, 038h, 06ch, 0c6h, 000h, 000h, 000h, 0cch, 0cch, 0cch, 07ch, 00ch, 0f8h
   185 00013BC1 00CCCCCC7C0CF8      <1>
   186 00013BC8 0000FC983064FC001C- <1>     db  000h, 000h, 0fch, 098h, 030h, 064h, 0fch, 000h, 01ch, 030h, 030h, 0e0h, 030h, 030h, 01ch, 000h
   186 00013BD1 3030E030301C00      <1>
   187 00013BD8 1818180018181800E0- <1>     db  018h, 018h, 018h, 000h, 018h, 018h, 018h, 000h, 0e0h, 030h, 030h, 01ch, 030h, 030h, 0e0h, 000h
   187 00013BE1 30301C3030E000      <1>
   188 00013BE8 76DC00000000000000- <1>     db  076h, 0dch, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 010h, 038h, 06ch, 0c6h, 0c6h, 0feh, 000h
   188 00013BF1 10386CC6C6FE00      <1>
   189 00013BF8 78CCC0CC78180C7800- <1>     db  078h, 0cch, 0c0h, 0cch, 078h, 018h, 00ch, 078h, 000h, 0cch, 000h, 0cch, 0cch, 0cch, 07eh, 000h
   189 00013C01 CC00CCCCCC7E00      <1>
   190 00013C08 1C0078CCFCC078007E- <1>     db  01ch, 000h, 078h, 0cch, 0fch, 0c0h, 078h, 000h, 07eh, 0c3h, 03ch, 006h, 03eh, 066h, 03fh, 000h
   190 00013C11 C33C063E663F00      <1>
   191 00013C18 CC00780C7CCC7E00E0- <1>     db  0cch, 000h, 078h, 00ch, 07ch, 0cch, 07eh, 000h, 0e0h, 000h, 078h, 00ch, 07ch, 0cch, 07eh, 000h
   191 00013C21 00780C7CCC7E00      <1>
   192 00013C28 3030780C7CCC7E0000- <1>     db  030h, 030h, 078h, 00ch, 07ch, 0cch, 07eh, 000h, 000h, 000h, 078h, 0c0h, 0c0h, 078h, 00ch, 038h
   192 00013C31 0078C0C0780C38      <1>
   193 00013C38 7EC33C667E603C00CC- <1>     db  07eh, 0c3h, 03ch, 066h, 07eh, 060h, 03ch, 000h, 0cch, 000h, 078h, 0cch, 0fch, 0c0h, 078h, 000h
   193 00013C41 0078CCFCC07800      <1>
   194 00013C48 E00078CCFCC07800CC- <1>     db  0e0h, 000h, 078h, 0cch, 0fch, 0c0h, 078h, 000h, 0cch, 000h, 070h, 030h, 030h, 030h, 078h, 000h
   194 00013C51 00703030307800      <1>
   195 00013C58 7CC6381818183C00E0- <1>     db  07ch, 0c6h, 038h, 018h, 018h, 018h, 03ch, 000h, 0e0h, 000h, 070h, 030h, 030h, 030h, 078h, 000h
   195 00013C61 00703030307800      <1>
   196 00013C68 C6386CC6FEC6C60030- <1>     db  0c6h, 038h, 06ch, 0c6h, 0feh, 0c6h, 0c6h, 000h, 030h, 030h, 000h, 078h, 0cch, 0fch, 0cch, 000h
   196 00013C71 300078CCFCCC00      <1>
   197 00013C78 1C00FC607860FC0000- <1>     db  01ch, 000h, 0fch, 060h, 078h, 060h, 0fch, 000h, 000h, 000h, 07fh, 00ch, 07fh, 0cch, 07fh, 000h
   197 00013C81 007F0C7FCC7F00      <1>
   198 00013C88 3E6CCCFECCCCCE0078- <1>     db  03eh, 06ch, 0cch, 0feh, 0cch, 0cch, 0ceh, 000h, 078h, 0cch, 000h, 078h, 0cch, 0cch, 078h, 000h
   198 00013C91 CC0078CCCC7800      <1>
   199 00013C98 00CC0078CCCC780000- <1>     db  000h, 0cch, 000h, 078h, 0cch, 0cch, 078h, 000h, 000h, 0e0h, 000h, 078h, 0cch, 0cch, 078h, 000h
   199 00013CA1 E00078CCCC7800      <1>
   200 00013CA8 78CC00CCCCCC7E0000- <1>     db  078h, 0cch, 000h, 0cch, 0cch, 0cch, 07eh, 000h, 000h, 0e0h, 000h, 0cch, 0cch, 0cch, 07eh, 000h
   200 00013CB1 E000CCCCCC7E00      <1>
   201 00013CB8 00CC00CCCC7C0CF8C3- <1>     db  000h, 0cch, 000h, 0cch, 0cch, 07ch, 00ch, 0f8h, 0c3h, 018h, 03ch, 066h, 066h, 03ch, 018h, 000h
   201 00013CC1 183C66663C1800      <1>
   202 00013CC8 CC00CCCCCCCC780018- <1>     db  0cch, 000h, 0cch, 0cch, 0cch, 0cch, 078h, 000h, 018h, 018h, 07eh, 0c0h, 0c0h, 07eh, 018h, 018h
   202 00013CD1 187EC0C07E1818      <1>
   203 00013CD8 386C64F060E6FC00CC- <1>     db  038h, 06ch, 064h, 0f0h, 060h, 0e6h, 0fch, 000h, 0cch, 0cch, 078h, 0fch, 030h, 0fch, 030h, 030h
   203 00013CE1 CC78FC30FC3030      <1>
   204 00013CE8 F8CCCCFAC6CFC6C70E- <1>     db  0f8h, 0cch, 0cch, 0fah, 0c6h, 0cfh, 0c6h, 0c7h, 00eh, 01bh, 018h, 03ch, 018h, 018h, 0d8h, 070h
   204 00013CF1 1B183C1818D870      <1>
   205 00013CF8 1C00780C7CCC7E0038- <1>     db  01ch, 000h, 078h, 00ch, 07ch, 0cch, 07eh, 000h, 038h, 000h, 070h, 030h, 030h, 030h, 078h, 000h
   205 00013D01 00703030307800      <1>
   206 00013D08 001C0078CCCC780000- <1>     db  000h, 01ch, 000h, 078h, 0cch, 0cch, 078h, 000h, 000h, 01ch, 000h, 0cch, 0cch, 0cch, 07eh, 000h
   206 00013D11 1C00CCCCCC7E00      <1>
   207 00013D18 00F800F8CCCCCC00FC- <1>     db  000h, 0f8h, 000h, 0f8h, 0cch, 0cch, 0cch, 000h, 0fch, 000h, 0cch, 0ech, 0fch, 0dch, 0cch, 000h
   207 00013D21 00CCECFCDCCC00      <1>
   208 00013D28 3C6C6C3E007E000038- <1>     db  03ch, 06ch, 06ch, 03eh, 000h, 07eh, 000h, 000h, 038h, 06ch, 06ch, 038h, 000h, 07ch, 000h, 000h
   208 00013D31 6C6C38007C0000      <1>
   209 00013D38 30003060C0CC780000- <1>     db  030h, 000h, 030h, 060h, 0c0h, 0cch, 078h, 000h, 000h, 000h, 000h, 0fch, 0c0h, 0c0h, 000h, 000h
   209 00013D41 0000FCC0C00000      <1>
   210 00013D48 000000FC0C0C0000C3- <1>     db  000h, 000h, 000h, 0fch, 00ch, 00ch, 000h, 000h, 0c3h, 0c6h, 0cch, 0deh, 033h, 066h, 0cch, 00fh
   210 00013D51 C6CCDE3366CC0F      <1>
   211 00013D58 C3C6CCDB376FCF0318- <1>     db  0c3h, 0c6h, 0cch, 0dbh, 037h, 06fh, 0cfh, 003h, 018h, 018h, 000h, 018h, 018h, 018h, 018h, 000h
   211 00013D61 18001818181800      <1>
   212 00013D68 003366CC6633000000- <1>     db  000h, 033h, 066h, 0cch, 066h, 033h, 000h, 000h, 000h, 0cch, 066h, 033h, 066h, 0cch, 000h, 000h
   212 00013D71 CC663366CC0000      <1>
   213 00013D78 228822882288228855- <1>     db  022h, 088h, 022h, 088h, 022h, 088h, 022h, 088h, 055h, 0aah, 055h, 0aah, 055h, 0aah, 055h, 0aah
   213 00013D81 AA55AA55AA55AA      <1>
   214 00013D88 DB77DBEEDB77DBEE18- <1>     db  0dbh, 077h, 0dbh, 0eeh, 0dbh, 077h, 0dbh, 0eeh, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h
   214 00013D91 18181818181818      <1>
   215 00013D98 18181818F818181818- <1>     db  018h, 018h, 018h, 018h, 0f8h, 018h, 018h, 018h, 018h, 018h, 0f8h, 018h, 0f8h, 018h, 018h, 018h
   215 00013DA1 18F818F8181818      <1>
   216 00013DA8 36363636F636363600- <1>     db  036h, 036h, 036h, 036h, 0f6h, 036h, 036h, 036h, 000h, 000h, 000h, 000h, 0feh, 036h, 036h, 036h
   216 00013DB1 000000FE363636      <1>
   217 00013DB8 0000F818F818181836- <1>     db  000h, 000h, 0f8h, 018h, 0f8h, 018h, 018h, 018h, 036h, 036h, 0f6h, 006h, 0f6h, 036h, 036h, 036h
   217 00013DC1 36F606F6363636      <1>
   218 00013DC8 363636363636363600- <1>     db  036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 000h, 000h, 0feh, 006h, 0f6h, 036h, 036h, 036h
   218 00013DD1 00FE06F6363636      <1>
   219 00013DD8 3636F606FE00000036- <1>     db  036h, 036h, 0f6h, 006h, 0feh, 000h, 000h, 000h, 036h, 036h, 036h, 036h, 0feh, 000h, 000h, 000h
   219 00013DE1 363636FE000000      <1>
   220 00013DE8 1818F818F800000000- <1>     db  018h, 018h, 0f8h, 018h, 0f8h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0f8h, 018h, 018h, 018h
   220 00013DF1 000000F8181818      <1>
   221 00013DF8 181818181F00000018- <1>     db  018h, 018h, 018h, 018h, 01fh, 000h, 000h, 000h, 018h, 018h, 018h, 018h, 0ffh, 000h, 000h, 000h
   221 00013E01 181818FF000000      <1>
   222 00013E08 00000000FF18181818- <1>     db  000h, 000h, 000h, 000h, 0ffh, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 01fh, 018h, 018h, 018h
   222 00013E11 1818181F181818      <1>
   223 00013E18 00000000FF00000018- <1>     db  000h, 000h, 000h, 000h, 0ffh, 000h, 000h, 000h, 018h, 018h, 018h, 018h, 0ffh, 018h, 018h, 018h
   223 00013E21 181818FF181818      <1>
   224 00013E28 18181F181F18181836- <1>     db  018h, 018h, 01fh, 018h, 01fh, 018h, 018h, 018h, 036h, 036h, 036h, 036h, 037h, 036h, 036h, 036h
   224 00013E31 36363637363636      <1>
   225 00013E38 363637303F00000000- <1>     db  036h, 036h, 037h, 030h, 03fh, 000h, 000h, 000h, 000h, 000h, 03fh, 030h, 037h, 036h, 036h, 036h
   225 00013E41 003F3037363636      <1>
   226 00013E48 3636F700FF00000000- <1>     db  036h, 036h, 0f7h, 000h, 0ffh, 000h, 000h, 000h, 000h, 000h, 0ffh, 000h, 0f7h, 036h, 036h, 036h
   226 00013E51 00FF00F7363636      <1>
   227 00013E58 363637303736363600- <1>     db  036h, 036h, 037h, 030h, 037h, 036h, 036h, 036h, 000h, 000h, 0ffh, 000h, 0ffh, 000h, 000h, 000h
   227 00013E61 00FF00FF000000      <1>
   228 00013E68 3636F700F736363618- <1>     db  036h, 036h, 0f7h, 000h, 0f7h, 036h, 036h, 036h, 018h, 018h, 0ffh, 000h, 0ffh, 000h, 000h, 000h
   228 00013E71 18FF00FF000000      <1>
   229 00013E78 36363636FF00000000- <1>     db  036h, 036h, 036h, 036h, 0ffh, 000h, 000h, 000h, 000h, 000h, 0ffh, 000h, 0ffh, 018h, 018h, 018h
   229 00013E81 00FF00FF181818      <1>
   230 00013E88 00000000FF36363636- <1>     db  000h, 000h, 000h, 000h, 0ffh, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 03fh, 000h, 000h, 000h
   230 00013E91 3636363F000000      <1>
   231 00013E98 18181F181F00000000- <1>     db  018h, 018h, 01fh, 018h, 01fh, 000h, 000h, 000h, 000h, 000h, 01fh, 018h, 01fh, 018h, 018h, 018h
   231 00013EA1 001F181F181818      <1>
   232 00013EA8 000000003F36363636- <1>     db  000h, 000h, 000h, 000h, 03fh, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 0ffh, 036h, 036h, 036h
   232 00013EB1 363636FF363636      <1>
   233 00013EB8 1818FF18FF18181818- <1>     db  018h, 018h, 0ffh, 018h, 0ffh, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 0f8h, 000h, 000h, 000h
   233 00013EC1 181818F8000000      <1>
   234 00013EC8 000000001F181818FF- <1>     db  000h, 000h, 000h, 000h, 01fh, 018h, 018h, 018h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
   234 00013ED1 FFFFFFFFFFFFFF      <1>
   235 00013ED8 00000000FFFFFFFFF0- <1>     db  000h, 000h, 000h, 000h, 0ffh, 0ffh, 0ffh, 0ffh, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h
   235 00013EE1 F0F0F0F0F0F0F0      <1>
   236 00013EE8 0F0F0F0F0F0F0F0FFF- <1>     db  00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 0ffh, 0ffh, 0ffh, 0ffh, 000h, 000h, 000h, 000h
   236 00013EF1 FFFFFF00000000      <1>
   237 00013EF8 000076DCC8DC760000- <1>     db  000h, 000h, 076h, 0dch, 0c8h, 0dch, 076h, 000h, 000h, 078h, 0cch, 0f8h, 0cch, 0f8h, 0c0h, 0c0h
   237 00013F01 78CCF8CCF8C0C0      <1>
   238 00013F08 00FCCCC0C0C0C00000- <1>     db  000h, 0fch, 0cch, 0c0h, 0c0h, 0c0h, 0c0h, 000h, 000h, 0feh, 06ch, 06ch, 06ch, 06ch, 06ch, 000h
   238 00013F11 FE6C6C6C6C6C00      <1>
   239 00013F18 FCCC603060CCFC0000- <1>     db  0fch, 0cch, 060h, 030h, 060h, 0cch, 0fch, 000h, 000h, 000h, 07eh, 0d8h, 0d8h, 0d8h, 070h, 000h
   239 00013F21 007ED8D8D87000      <1>
   240 00013F28 00666666667C60C000- <1>     db  000h, 066h, 066h, 066h, 066h, 07ch, 060h, 0c0h, 000h, 076h, 0dch, 018h, 018h, 018h, 018h, 000h
   240 00013F31 76DC1818181800      <1>
   241 00013F38 FC3078CCCC7830FC38- <1>     db  0fch, 030h, 078h, 0cch, 0cch, 078h, 030h, 0fch, 038h, 06ch, 0c6h, 0feh, 0c6h, 06ch, 038h, 000h
   241 00013F41 6CC6FEC66C3800      <1>
   242 00013F48 386CC6C66C6CEE001C- <1>     db  038h, 06ch, 0c6h, 0c6h, 06ch, 06ch, 0eeh, 000h, 01ch, 030h, 018h, 07ch, 0cch, 0cch, 078h, 000h
   242 00013F51 30187CCCCC7800      <1>
   243 00013F58 00007EDBDB7E000006- <1>     db  000h, 000h, 07eh, 0dbh, 0dbh, 07eh, 000h, 000h, 006h, 00ch, 07eh, 0dbh, 0dbh, 07eh, 060h, 0c0h
   243 00013F61 0C7EDBDB7E60C0      <1>
   244 00013F68 3860C0F8C060380078- <1>     db  038h, 060h, 0c0h, 0f8h, 0c0h, 060h, 038h, 000h, 078h, 0cch, 0cch, 0cch, 0cch, 0cch, 0cch, 000h
   244 00013F71 CCCCCCCCCCCC00      <1>
   245 00013F78 00FC00FC00FC000030- <1>     db  000h, 0fch, 000h, 0fch, 000h, 0fch, 000h, 000h, 030h, 030h, 0fch, 030h, 030h, 000h, 0fch, 000h
   245 00013F81 30FC303000FC00      <1>
   246 00013F88 603018306000FC0018- <1>     db  060h, 030h, 018h, 030h, 060h, 000h, 0fch, 000h, 018h, 030h, 060h, 030h, 018h, 000h, 0fch, 000h
   246 00013F91 3060301800FC00      <1>
   247 00013F98 0E1B1B181818181818- <1>     db  00eh, 01bh, 01bh, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 0d8h, 0d8h, 070h
   247 00013FA1 18181818D8D870      <1>
   248 00013FA8 303000FC0030300000- <1>     db  030h, 030h, 000h, 0fch, 000h, 030h, 030h, 000h, 000h, 076h, 0dch, 000h, 076h, 0dch, 000h, 000h
   248 00013FB1 76DC0076DC0000      <1>
   249 00013FB8 386C6C380000000000- <1>     db  038h, 06ch, 06ch, 038h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 018h, 018h, 000h, 000h, 000h
   249 00013FC1 00001818000000      <1>
   250 00013FC8 00000000180000000F- <1>     db  000h, 000h, 000h, 000h, 018h, 000h, 000h, 000h, 00fh, 00ch, 00ch, 00ch, 0ech, 06ch, 03ch, 01ch
   250 00013FD1 0C0C0CEC6C3C1C      <1>
   251 00013FD8 786C6C6C6C00000070- <1>     db  078h, 06ch, 06ch, 06ch, 06ch, 000h, 000h, 000h, 070h, 018h, 030h, 060h, 078h, 000h, 000h, 000h
   251 00013FE1 18306078000000      <1>
   252 00013FE8 00003C3C3C3C000000- <1>     db  000h, 000h, 03ch, 03ch, 03ch, 03ch, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   252 00013FF1 00000000000000      <1>
   253                              <1> vgafont14:
   254 00013FF8 000000000000000000- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   254 00014001 00000000000000      <1>
   255 00014008 7E81A58181BD99817E- <1>     db  07eh, 081h, 0a5h, 081h, 081h, 0bdh, 099h, 081h, 07eh, 000h, 000h, 000h, 000h, 000h, 07eh, 0ffh
   255 00014011 00000000007EFF      <1>
   256 00014018 DBFFFFC3E7FF7E0000- <1>     db  0dbh, 0ffh, 0ffh, 0c3h, 0e7h, 0ffh, 07eh, 000h, 000h, 000h, 000h, 000h, 000h, 06ch, 0feh, 0feh
   256 00014021 000000006CFEFE      <1>
   257 00014028 FEFE7C381000000000- <1>     db  0feh, 0feh, 07ch, 038h, 010h, 000h, 000h, 000h, 000h, 000h, 000h, 010h, 038h, 07ch, 0feh, 07ch
   257 00014031 000010387CFE7C      <1>
   258 00014038 381000000000000018- <1>     db  038h, 010h, 000h, 000h, 000h, 000h, 000h, 000h, 018h, 03ch, 03ch, 0e7h, 0e7h, 0e7h, 018h, 018h
   258 00014041 3C3CE7E7E71818      <1>
   259 00014048 3C0000000000183C7E- <1>     db  03ch, 000h, 000h, 000h, 000h, 000h, 018h, 03ch, 07eh, 0ffh, 0ffh, 07eh, 018h, 018h, 03ch, 000h
   259 00014051 FFFF7E18183C00      <1>
   260 00014058 00000000000000183C- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 018h, 03ch, 03ch, 018h, 000h, 000h, 000h, 000h, 000h
   260 00014061 3C180000000000      <1>
   261 00014068 FFFFFFFFFFE7C3C3E7- <1>     db  0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0e7h, 0c3h, 0c3h, 0e7h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 000h, 000h
   261 00014071 FFFFFFFFFF0000      <1>
   262 00014078 00003C664242663C00- <1>     db  000h, 000h, 03ch, 066h, 042h, 042h, 066h, 03ch, 000h, 000h, 000h, 000h, 0ffh, 0ffh, 0ffh, 0ffh
   262 00014081 000000FFFFFFFF      <1>
   263 00014088 C399BDBD99C3FFFFFF- <1>     db  0c3h, 099h, 0bdh, 0bdh, 099h, 0c3h, 0ffh, 0ffh, 0ffh, 0ffh, 000h, 000h, 01eh, 00eh, 01ah, 032h
   263 00014091 FF00001E0E1A32      <1>
   264 00014098 78CCCCCC7800000000- <1>     db  078h, 0cch, 0cch, 0cch, 078h, 000h, 000h, 000h, 000h, 000h, 03ch, 066h, 066h, 066h, 03ch, 018h
   264 000140A1 003C6666663C18      <1>
   265 000140A8 7E181800000000003F- <1>     db  07eh, 018h, 018h, 000h, 000h, 000h, 000h, 000h, 03fh, 033h, 03fh, 030h, 030h, 030h, 070h, 0f0h
   265 000140B1 333F30303070F0      <1>
   266 000140B8 E000000000007F637F- <1>     db  0e0h, 000h, 000h, 000h, 000h, 000h, 07fh, 063h, 07fh, 063h, 063h, 063h, 067h, 0e7h, 0e6h, 0c0h
   266 000140C1 63636367E7E6C0      <1>
   267 000140C8 000000001818DB3CE7- <1>     db  000h, 000h, 000h, 000h, 018h, 018h, 0dbh, 03ch, 0e7h, 03ch, 0dbh, 018h, 018h, 000h, 000h, 000h
   267 000140D1 3CDB1818000000      <1>
   268 000140D8 000080C0E0F8FEF8E0- <1>     db  000h, 000h, 080h, 0c0h, 0e0h, 0f8h, 0feh, 0f8h, 0e0h, 0c0h, 080h, 000h, 000h, 000h, 000h, 000h
   268 000140E1 C0800000000000      <1>
   269 000140E8 02060E3EFE3E0E0602- <1>     db  002h, 006h, 00eh, 03eh, 0feh, 03eh, 00eh, 006h, 002h, 000h, 000h, 000h, 000h, 000h, 018h, 03ch
   269 000140F1 0000000000183C      <1>
   270 000140F8 7E1818187E3C180000- <1>     db  07eh, 018h, 018h, 018h, 07eh, 03ch, 018h, 000h, 000h, 000h, 000h, 000h, 066h, 066h, 066h, 066h
   270 00014101 00000066666666      <1>
   271 00014108 666600666600000000- <1>     db  066h, 066h, 000h, 066h, 066h, 000h, 000h, 000h, 000h, 000h, 07fh, 0dbh, 0dbh, 0dbh, 07bh, 01bh
   271 00014111 007FDBDBDB7B1B      <1>
   272 00014118 1B1B1B000000007CC6- <1>     db  01bh, 01bh, 01bh, 000h, 000h, 000h, 000h, 07ch, 0c6h, 060h, 038h, 06ch, 0c6h, 0c6h, 06ch, 038h
   272 00014121 60386CC6C66C38      <1>
   273 00014128 0CC67C000000000000- <1>     db  00ch, 0c6h, 07ch, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0feh, 0feh, 0feh, 000h
   273 00014131 000000FEFEFE00      <1>
   274 00014138 00000000183C7E1818- <1>     db  000h, 000h, 000h, 000h, 018h, 03ch, 07eh, 018h, 018h, 018h, 07eh, 03ch, 018h, 07eh, 000h, 000h
   274 00014141 187E3C187E0000      <1>
   275 00014148 0000183C7E18181818- <1>     db  000h, 000h, 018h, 03ch, 07eh, 018h, 018h, 018h, 018h, 018h, 018h, 000h, 000h, 000h, 000h, 000h
   275 00014151 18180000000000      <1>
   276 00014158 1818181818187E3C18- <1>     db  018h, 018h, 018h, 018h, 018h, 018h, 07eh, 03ch, 018h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   276 00014161 00000000000000      <1>
   277 00014168 180CFE0C1800000000- <1>     db  018h, 00ch, 0feh, 00ch, 018h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 030h, 060h
   277 00014171 00000000003060      <1>
   278 00014178 FE6030000000000000- <1>     db  0feh, 060h, 030h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0c0h, 0c0h, 0c0h
   278 00014181 00000000C0C0C0      <1>
   279 00014188 FE0000000000000000- <1>     db  0feh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 028h, 06ch, 0feh, 06ch, 028h, 000h
   279 00014191 00286CFE6C2800      <1>
   280 00014198 000000000000001038- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 010h, 038h, 038h, 07ch, 07ch, 0feh, 0feh, 000h, 000h
   280 000141A1 387C7CFEFE0000      <1>
   281 000141A8 0000000000FEFE7C7C- <1>     db  000h, 000h, 000h, 000h, 000h, 0feh, 0feh, 07ch, 07ch, 038h, 038h, 010h, 000h, 000h, 000h, 000h
   281 000141B1 38381000000000      <1>
   282 000141B8 000000000000000000- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   282 000141C1 00000000000000      <1>
   283 000141C8 183C3C3C1818001818- <1>     db  018h, 03ch, 03ch, 03ch, 018h, 018h, 000h, 018h, 018h, 000h, 000h, 000h, 000h, 066h, 066h, 066h
   283 000141D1 00000000666666      <1>
   284 000141D8 240000000000000000- <1>     db  024h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 06ch, 06ch, 0feh, 06ch
   284 000141E1 0000006C6CFE6C      <1>
   285 000141E8 6C6CFE6C6C00000018- <1>     db  06ch, 06ch, 0feh, 06ch, 06ch, 000h, 000h, 000h, 018h, 018h, 07ch, 0c6h, 0c2h, 0c0h, 07ch, 006h
   285 000141F1 187CC6C2C07C06      <1>
   286 000141F8 86C67C181800000000- <1>     db  086h, 0c6h, 07ch, 018h, 018h, 000h, 000h, 000h, 000h, 000h, 0c2h, 0c6h, 00ch, 018h, 030h, 066h
   286 00014201 00C2C60C183066      <1>
   287 00014208 C60000000000386C6C- <1>     db  0c6h, 000h, 000h, 000h, 000h, 000h, 038h, 06ch, 06ch, 038h, 076h, 0dch, 0cch, 0cch, 076h, 000h
   287 00014211 3876DCCCCC7600      <1>
   288 00014218 000000303030600000- <1>     db  000h, 000h, 000h, 030h, 030h, 030h, 060h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   288 00014221 00000000000000      <1>
   289 00014228 00000C183030303030- <1>     db  000h, 000h, 00ch, 018h, 030h, 030h, 030h, 030h, 030h, 018h, 00ch, 000h, 000h, 000h, 000h, 000h
   289 00014231 180C0000000000      <1>
   290 00014238 30180C0C0C0C0C1830- <1>     db  030h, 018h, 00ch, 00ch, 00ch, 00ch, 00ch, 018h, 030h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   290 00014241 00000000000000      <1>
   291 00014248 663CFF3C6600000000- <1>     db  066h, 03ch, 0ffh, 03ch, 066h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 018h, 018h
   291 00014251 00000000001818      <1>
   292 00014258 7E1818000000000000- <1>     db  07eh, 018h, 018h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   292 00014261 00000000000000      <1>
   293 00014268 181818300000000000- <1>     db  018h, 018h, 018h, 030h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0feh, 000h, 000h, 000h
   293 00014271 000000FE000000      <1>
   294 00014278 000000000000000000- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 018h, 018h, 000h
   294 00014281 00000000181800      <1>
   295 00014288 0000000002060C1830- <1>     db  000h, 000h, 000h, 000h, 002h, 006h, 00ch, 018h, 030h, 060h, 0c0h, 080h, 000h, 000h, 000h, 000h
   295 00014291 60C08000000000      <1>
   296 00014298 00007CC6CEDEF6E6C6- <1>     db  000h, 000h, 07ch, 0c6h, 0ceh, 0deh, 0f6h, 0e6h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h, 000h
   296 000142A1 C67C0000000000      <1>
   297 000142A8 18387818181818187E- <1>     db  018h, 038h, 078h, 018h, 018h, 018h, 018h, 018h, 07eh, 000h, 000h, 000h, 000h, 000h, 07ch, 0c6h
   297 000142B1 00000000007CC6      <1>
   298 000142B8 060C183060C6FE0000- <1>     db  006h, 00ch, 018h, 030h, 060h, 0c6h, 0feh, 000h, 000h, 000h, 000h, 000h, 07ch, 0c6h, 006h, 006h
   298 000142C1 0000007CC60606      <1>
   299 000142C8 3C0606C67C00000000- <1>     db  03ch, 006h, 006h, 0c6h, 07ch, 000h, 000h, 000h, 000h, 000h, 00ch, 01ch, 03ch, 06ch, 0cch, 0feh
   299 000142D1 000C1C3C6CCCFE      <1>
   300 000142D8 0C0C1E0000000000FE- <1>     db  00ch, 00ch, 01eh, 000h, 000h, 000h, 000h, 000h, 0feh, 0c0h, 0c0h, 0c0h, 0fch, 006h, 006h, 0c6h
   300 000142E1 C0C0C0FC0606C6      <1>
   301 000142E8 7C00000000003860C0- <1>     db  07ch, 000h, 000h, 000h, 000h, 000h, 038h, 060h, 0c0h, 0c0h, 0fch, 0c6h, 0c6h, 0c6h, 07ch, 000h
   301 000142F1 C0FCC6C6C67C00      <1>
   302 000142F8 00000000FEC6060C18- <1>     db  000h, 000h, 000h, 000h, 0feh, 0c6h, 006h, 00ch, 018h, 030h, 030h, 030h, 030h, 000h, 000h, 000h
   302 00014301 30303030000000      <1>
   303 00014308 00007CC6C6C67CC6C6- <1>     db  000h, 000h, 07ch, 0c6h, 0c6h, 0c6h, 07ch, 0c6h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h, 000h
   303 00014311 C67C0000000000      <1>
   304 00014318 7CC6C6C67E06060C78- <1>     db  07ch, 0c6h, 0c6h, 0c6h, 07eh, 006h, 006h, 00ch, 078h, 000h, 000h, 000h, 000h, 000h, 000h, 018h
   304 00014321 00000000000018      <1>
   305 00014328 180000001818000000- <1>     db  018h, 000h, 000h, 000h, 018h, 018h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 018h, 018h, 000h
   305 00014331 00000000181800      <1>
   306 00014338 000018183000000000- <1>     db  000h, 000h, 018h, 018h, 030h, 000h, 000h, 000h, 000h, 000h, 006h, 00ch, 018h, 030h, 060h, 030h
   306 00014341 00060C18306030      <1>
   307 00014348 180C06000000000000- <1>     db  018h, 00ch, 006h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 07eh, 000h, 000h, 07eh, 000h
   307 00014351 00007E00007E00      <1>
   308 00014358 000000000000603018- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 060h, 030h, 018h, 00ch, 006h, 00ch, 018h, 030h, 060h, 000h
   308 00014361 0C060C18306000      <1>
   309 00014368 000000007CC6C60C18- <1>     db  000h, 000h, 000h, 000h, 07ch, 0c6h, 0c6h, 00ch, 018h, 018h, 000h, 018h, 018h, 000h, 000h, 000h
   309 00014371 18001818000000      <1>
   310 00014378 00007CC6C6DEDEDEDC- <1>     db  000h, 000h, 07ch, 0c6h, 0c6h, 0deh, 0deh, 0deh, 0dch, 0c0h, 07ch, 000h, 000h, 000h, 000h, 000h
   310 00014381 C07C0000000000      <1>
   311 00014388 10386CC6C6FEC6C6C6- <1>     db  010h, 038h, 06ch, 0c6h, 0c6h, 0feh, 0c6h, 0c6h, 0c6h, 000h, 000h, 000h, 000h, 000h, 0fch, 066h
   311 00014391 0000000000FC66      <1>
   312 00014398 66667C666666FC0000- <1>     db  066h, 066h, 07ch, 066h, 066h, 066h, 0fch, 000h, 000h, 000h, 000h, 000h, 03ch, 066h, 0c2h, 0c0h
   312 000143A1 0000003C66C2C0      <1>
   313 000143A8 C0C0C2663C00000000- <1>     db  0c0h, 0c0h, 0c2h, 066h, 03ch, 000h, 000h, 000h, 000h, 000h, 0f8h, 06ch, 066h, 066h, 066h, 066h
   313 000143B1 00F86C66666666      <1>
   314 000143B8 666CF80000000000FE- <1>     db  066h, 06ch, 0f8h, 000h, 000h, 000h, 000h, 000h, 0feh, 066h, 062h, 068h, 078h, 068h, 062h, 066h
   314 000143C1 66626878686266      <1>
   315 000143C8 FE0000000000FE6662- <1>     db  0feh, 000h, 000h, 000h, 000h, 000h, 0feh, 066h, 062h, 068h, 078h, 068h, 060h, 060h, 0f0h, 000h
   315 000143D1 6878686060F000      <1>
   316 000143D8 000000003C66C2C0C0- <1>     db  000h, 000h, 000h, 000h, 03ch, 066h, 0c2h, 0c0h, 0c0h, 0deh, 0c6h, 066h, 03ah, 000h, 000h, 000h
   316 000143E1 DEC6663A000000      <1>
   317 000143E8 0000C6C6C6C6FEC6C6- <1>     db  000h, 000h, 0c6h, 0c6h, 0c6h, 0c6h, 0feh, 0c6h, 0c6h, 0c6h, 0c6h, 000h, 000h, 000h, 000h, 000h
   317 000143F1 C6C60000000000      <1>
   318 000143F8 3C181818181818183C- <1>     db  03ch, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 03ch, 000h, 000h, 000h, 000h, 000h, 01eh, 00ch
   318 00014401 00000000001E0C      <1>
   319 00014408 0C0C0C0CCCCC780000- <1>     db  00ch, 00ch, 00ch, 00ch, 0cch, 0cch, 078h, 000h, 000h, 000h, 000h, 000h, 0e6h, 066h, 06ch, 06ch
   319 00014411 000000E6666C6C      <1>
   320 00014418 786C6C66E600000000- <1>     db  078h, 06ch, 06ch, 066h, 0e6h, 000h, 000h, 000h, 000h, 000h, 0f0h, 060h, 060h, 060h, 060h, 060h
   320 00014421 00F06060606060      <1>
   321 00014428 6266FE0000000000C6- <1>     db  062h, 066h, 0feh, 000h, 000h, 000h, 000h, 000h, 0c6h, 0eeh, 0feh, 0feh, 0d6h, 0c6h, 0c6h, 0c6h
   321 00014431 EEFEFED6C6C6C6      <1>
   322 00014438 C60000000000C6E6F6- <1>     db  0c6h, 000h, 000h, 000h, 000h, 000h, 0c6h, 0e6h, 0f6h, 0feh, 0deh, 0ceh, 0c6h, 0c6h, 0c6h, 000h
   322 00014441 FEDECEC6C6C600      <1>
   323 00014448 00000000386CC6C6C6- <1>     db  000h, 000h, 000h, 000h, 038h, 06ch, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 06ch, 038h, 000h, 000h, 000h
   323 00014451 C6C66C38000000      <1>
   324 00014458 0000FC6666667C6060- <1>     db  000h, 000h, 0fch, 066h, 066h, 066h, 07ch, 060h, 060h, 060h, 0f0h, 000h, 000h, 000h, 000h, 000h
   324 00014461 60F00000000000      <1>
   325 00014468 7CC6C6C6C6D6DE7C0C- <1>     db  07ch, 0c6h, 0c6h, 0c6h, 0c6h, 0d6h, 0deh, 07ch, 00ch, 00eh, 000h, 000h, 000h, 000h, 0fch, 066h
   325 00014471 0E00000000FC66      <1>
   326 00014478 66667C6C6666E60000- <1>     db  066h, 066h, 07ch, 06ch, 066h, 066h, 0e6h, 000h, 000h, 000h, 000h, 000h, 07ch, 0c6h, 0c6h, 060h
   326 00014481 0000007CC6C660      <1>
   327 00014488 380CC6C67C00000000- <1>     db  038h, 00ch, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h, 000h, 07eh, 07eh, 05ah, 018h, 018h, 018h
   327 00014491 007E7E5A181818      <1>
   328 00014498 18183C0000000000C6- <1>     db  018h, 018h, 03ch, 000h, 000h, 000h, 000h, 000h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h
   328 000144A1 C6C6C6C6C6C6C6      <1>
   329 000144A8 7C0000000000C6C6C6- <1>     db  07ch, 000h, 000h, 000h, 000h, 000h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 06ch, 038h, 010h, 000h
   329 000144B1 C6C6C66C381000      <1>
   330 000144B8 00000000C6C6C6C6D6- <1>     db  000h, 000h, 000h, 000h, 0c6h, 0c6h, 0c6h, 0c6h, 0d6h, 0d6h, 0feh, 07ch, 06ch, 000h, 000h, 000h
   330 000144C1 D6FE7C6C000000      <1>
   331 000144C8 0000C6C66C3838386C- <1>     db  000h, 000h, 0c6h, 0c6h, 06ch, 038h, 038h, 038h, 06ch, 0c6h, 0c6h, 000h, 000h, 000h, 000h, 000h
   331 000144D1 C6C60000000000      <1>
   332 000144D8 666666663C1818183C- <1>     db  066h, 066h, 066h, 066h, 03ch, 018h, 018h, 018h, 03ch, 000h, 000h, 000h, 000h, 000h, 0feh, 0c6h
   332 000144E1 0000000000FEC6      <1>
   333 000144E8 8C183060C2C6FE0000- <1>     db  08ch, 018h, 030h, 060h, 0c2h, 0c6h, 0feh, 000h, 000h, 000h, 000h, 000h, 03ch, 030h, 030h, 030h
   333 000144F1 0000003C303030      <1>
   334 000144F8 303030303C00000000- <1>     db  030h, 030h, 030h, 030h, 03ch, 000h, 000h, 000h, 000h, 000h, 080h, 0c0h, 0e0h, 070h, 038h, 01ch
   334 00014501 0080C0E070381C      <1>
   335 00014508 0E060200000000003C- <1>     db  00eh, 006h, 002h, 000h, 000h, 000h, 000h, 000h, 03ch, 00ch, 00ch, 00ch, 00ch, 00ch, 00ch, 00ch
   335 00014511 0C0C0C0C0C0C0C      <1>
   336 00014518 3C00000010386CC600- <1>     db  03ch, 000h, 000h, 000h, 010h, 038h, 06ch, 0c6h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   336 00014521 00000000000000      <1>
   337 00014528 000000000000000000- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0ffh, 000h
   337 00014531 0000000000FF00      <1>
   338 00014538 303018000000000000- <1>     db  030h, 030h, 018h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   338 00014541 00000000000000      <1>
   339 00014548 000000780C7CCCCC76- <1>     db  000h, 000h, 000h, 078h, 00ch, 07ch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h, 000h, 0e0h, 060h
   339 00014551 0000000000E060      <1>
   340 00014558 60786C6666667C0000- <1>     db  060h, 078h, 06ch, 066h, 066h, 066h, 07ch, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 07ch
   340 00014561 0000000000007C      <1>
   341 00014568 C6C0C0C67C00000000- <1>     db  0c6h, 0c0h, 0c0h, 0c6h, 07ch, 000h, 000h, 000h, 000h, 000h, 01ch, 00ch, 00ch, 03ch, 06ch, 0cch
   341 00014571 001C0C0C3C6CCC      <1>
   342 00014578 CCCC76000000000000- <1>     db  0cch, 0cch, 076h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 07ch, 0c6h, 0feh, 0c0h, 0c6h
   342 00014581 00007CC6FEC0C6      <1>
   343 00014588 7C0000000000386C64- <1>     db  07ch, 000h, 000h, 000h, 000h, 000h, 038h, 06ch, 064h, 060h, 0f0h, 060h, 060h, 060h, 0f0h, 000h
   343 00014591 60F0606060F000      <1>
   344 00014598 0000000000000076CC- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 076h, 0cch, 0cch, 0cch, 07ch, 00ch, 0cch, 078h, 000h
   344 000145A1 CCCC7C0CCC7800      <1>
   345 000145A8 0000E060606C766666- <1>     db  000h, 000h, 0e0h, 060h, 060h, 06ch, 076h, 066h, 066h, 066h, 0e6h, 000h, 000h, 000h, 000h, 000h
   345 000145B1 66E60000000000      <1>
   346 000145B8 18180038181818183C- <1>     db  018h, 018h, 000h, 038h, 018h, 018h, 018h, 018h, 03ch, 000h, 000h, 000h, 000h, 000h, 006h, 006h
   346 000145C1 00000000000606      <1>
   347 000145C8 000E0606060666663C- <1>     db  000h, 00eh, 006h, 006h, 006h, 006h, 066h, 066h, 03ch, 000h, 000h, 000h, 0e0h, 060h, 060h, 066h
   347 000145D1 000000E0606066      <1>
   348 000145D8 6C786C66E600000000- <1>     db  06ch, 078h, 06ch, 066h, 0e6h, 000h, 000h, 000h, 000h, 000h, 038h, 018h, 018h, 018h, 018h, 018h
   348 000145E1 00381818181818      <1>
   349 000145E8 18183C000000000000- <1>     db  018h, 018h, 03ch, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0ech, 0feh, 0d6h, 0d6h, 0d6h
   349 000145F1 0000ECFED6D6D6      <1>
   350 000145F8 C60000000000000000- <1>     db  0c6h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0dch, 066h, 066h, 066h, 066h, 066h, 000h
   350 00014601 DC666666666600      <1>
   351 00014608 000000000000007CC6- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 07ch, 0c6h, 0c6h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h
   351 00014611 C6C6C67C000000      <1>
   352 00014618 0000000000DC666666- <1>     db  000h, 000h, 000h, 000h, 000h, 0dch, 066h, 066h, 066h, 07ch, 060h, 060h, 0f0h, 000h, 000h, 000h
   352 00014621 7C6060F0000000      <1>
   353 00014628 00000076CCCCCC7C0C- <1>     db  000h, 000h, 000h, 076h, 0cch, 0cch, 0cch, 07ch, 00ch, 00ch, 01eh, 000h, 000h, 000h, 000h, 000h
   353 00014631 0C1E0000000000      <1>
   354 00014638 00DC76666060F00000- <1>     db  000h, 0dch, 076h, 066h, 060h, 060h, 0f0h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 07ch
   354 00014641 0000000000007C      <1>
   355 00014648 C6701CC67C00000000- <1>     db  0c6h, 070h, 01ch, 0c6h, 07ch, 000h, 000h, 000h, 000h, 000h, 010h, 030h, 030h, 0fch, 030h, 030h
   355 00014651 00103030FC3030      <1>
   356 00014658 30361C000000000000- <1>     db  030h, 036h, 01ch, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0cch, 0cch, 0cch, 0cch, 0cch
   356 00014661 0000CCCCCCCCCC      <1>
   357 00014668 760000000000000000- <1>     db  076h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 066h, 066h, 066h, 066h, 03ch, 018h, 000h
   357 00014671 666666663C1800      <1>
   358 00014678 00000000000000C6C6- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 0c6h, 0c6h, 0d6h, 0d6h, 0feh, 06ch, 000h, 000h, 000h
   358 00014681 D6D6FE6C000000      <1>
   359 00014688 0000000000C66C3838- <1>     db  000h, 000h, 000h, 000h, 000h, 0c6h, 06ch, 038h, 038h, 06ch, 0c6h, 000h, 000h, 000h, 000h, 000h
   359 00014691 6CC60000000000      <1>
   360 00014698 000000C6C6C6C67E06- <1>     db  000h, 000h, 000h, 0c6h, 0c6h, 0c6h, 0c6h, 07eh, 006h, 00ch, 0f8h, 000h, 000h, 000h, 000h, 000h
   360 000146A1 0CF80000000000      <1>
   361 000146A8 00FECC183066FE0000- <1>     db  000h, 0feh, 0cch, 018h, 030h, 066h, 0feh, 000h, 000h, 000h, 000h, 000h, 00eh, 018h, 018h, 018h
   361 000146B1 0000000E181818      <1>
   362 000146B8 701818180E00000000- <1>     db  070h, 018h, 018h, 018h, 00eh, 000h, 000h, 000h, 000h, 000h, 018h, 018h, 018h, 018h, 000h, 018h
   362 000146C1 00181818180018      <1>
   363 000146C8 181818000000000070- <1>     db  018h, 018h, 018h, 000h, 000h, 000h, 000h, 000h, 070h, 018h, 018h, 018h, 00eh, 018h, 018h, 018h
   363 000146D1 1818180E181818      <1>
   364 000146D8 70000000000076DC00- <1>     db  070h, 000h, 000h, 000h, 000h, 000h, 076h, 0dch, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   364 000146E1 00000000000000      <1>
   365 000146E8 00000000000010386C- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 010h, 038h, 06ch, 0c6h, 0c6h, 0feh, 000h, 000h, 000h, 000h
   365 000146F1 C6C6FE00000000      <1>
   366 000146F8 00003C66C2C0C0C266- <1>     db  000h, 000h, 03ch, 066h, 0c2h, 0c0h, 0c0h, 0c2h, 066h, 03ch, 00ch, 006h, 07ch, 000h, 000h, 000h
   366 00014701 3C0C067C000000      <1>
   367 00014708 CCCC00CCCCCCCCCC76- <1>     db  0cch, 0cch, 000h, 0cch, 0cch, 0cch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h, 00ch, 018h, 030h
   367 00014711 000000000C1830      <1>
   368 00014718 007CC6FEC0C67C0000- <1>     db  000h, 07ch, 0c6h, 0feh, 0c0h, 0c6h, 07ch, 000h, 000h, 000h, 000h, 010h, 038h, 06ch, 000h, 078h
   368 00014721 000010386C0078      <1>
   369 00014728 0C7CCCCC7600000000- <1>     db  00ch, 07ch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h, 000h, 0cch, 0cch, 000h, 078h, 00ch, 07ch
   369 00014731 00CCCC00780C7C      <1>
   370 00014738 CCCC76000000006030- <1>     db  0cch, 0cch, 076h, 000h, 000h, 000h, 000h, 060h, 030h, 018h, 000h, 078h, 00ch, 07ch, 0cch, 0cch
   370 00014741 1800780C7CCCCC      <1>
   371 00014748 7600000000386C3800- <1>     db  076h, 000h, 000h, 000h, 000h, 038h, 06ch, 038h, 000h, 078h, 00ch, 07ch, 0cch, 0cch, 076h, 000h
   371 00014751 780C7CCCCC7600      <1>
   372 00014758 0000000000003C6660- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 03ch, 066h, 060h, 066h, 03ch, 00ch, 006h, 03ch, 000h, 000h
   372 00014761 663C0C063C0000      <1>
   373 00014768 0010386C007CC6FEC0- <1>     db  000h, 010h, 038h, 06ch, 000h, 07ch, 0c6h, 0feh, 0c0h, 0c6h, 07ch, 000h, 000h, 000h, 000h, 000h
   373 00014771 C67C0000000000      <1>
   374 00014778 CCCC007CC6FEC0C67C- <1>     db  0cch, 0cch, 000h, 07ch, 0c6h, 0feh, 0c0h, 0c6h, 07ch, 000h, 000h, 000h, 000h, 060h, 030h, 018h
   374 00014781 00000000603018      <1>
   375 00014788 007CC6FEC0C67C0000- <1>     db  000h, 07ch, 0c6h, 0feh, 0c0h, 0c6h, 07ch, 000h, 000h, 000h, 000h, 000h, 066h, 066h, 000h, 038h
   375 00014791 00000066660038      <1>
   376 00014798 181818183C00000000- <1>     db  018h, 018h, 018h, 018h, 03ch, 000h, 000h, 000h, 000h, 018h, 03ch, 066h, 000h, 038h, 018h, 018h
   376 000147A1 183C6600381818      <1>
   377 000147A8 18183C000000006030- <1>     db  018h, 018h, 03ch, 000h, 000h, 000h, 000h, 060h, 030h, 018h, 000h, 038h, 018h, 018h, 018h, 018h
   377 000147B1 18003818181818      <1>
   378 000147B8 3C00000000C6C61038- <1>     db  03ch, 000h, 000h, 000h, 000h, 0c6h, 0c6h, 010h, 038h, 06ch, 0c6h, 0c6h, 0feh, 0c6h, 0c6h, 000h
   378 000147C1 6CC6C6FEC6C600      <1>
   379 000147C8 0000386C3800386CC6- <1>     db  000h, 000h, 038h, 06ch, 038h, 000h, 038h, 06ch, 0c6h, 0c6h, 0feh, 0c6h, 0c6h, 000h, 000h, 000h
   379 000147D1 C6FEC6C6000000      <1>
   380 000147D8 18306000FE66607C60- <1>     db  018h, 030h, 060h, 000h, 0feh, 066h, 060h, 07ch, 060h, 066h, 0feh, 000h, 000h, 000h, 000h, 000h
   380 000147E1 66FE0000000000      <1>
   381 000147E8 0000CC76367ED8D86E- <1>     db  000h, 000h, 0cch, 076h, 036h, 07eh, 0d8h, 0d8h, 06eh, 000h, 000h, 000h, 000h, 000h, 03eh, 06ch
   381 000147F1 00000000003E6C      <1>
   382 000147F8 CCCCFECCCCCCCE0000- <1>     db  0cch, 0cch, 0feh, 0cch, 0cch, 0cch, 0ceh, 000h, 000h, 000h, 000h, 010h, 038h, 06ch, 000h, 07ch
   382 00014801 000010386C007C      <1>
   383 00014808 C6C6C6C67C00000000- <1>     db  0c6h, 0c6h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h, 000h, 0c6h, 0c6h, 000h, 07ch, 0c6h, 0c6h
   383 00014811 00C6C6007CC6C6      <1>
   384 00014818 C6C67C000000006030- <1>     db  0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h, 060h, 030h, 018h, 000h, 07ch, 0c6h, 0c6h, 0c6h, 0c6h
   384 00014821 18007CC6C6C6C6      <1>
   385 00014828 7C000000003078CC00- <1>     db  07ch, 000h, 000h, 000h, 000h, 030h, 078h, 0cch, 000h, 0cch, 0cch, 0cch, 0cch, 0cch, 076h, 000h
   385 00014831 CCCCCCCCCC7600      <1>
   386 00014838 00000060301800CCCC- <1>     db  000h, 000h, 000h, 060h, 030h, 018h, 000h, 0cch, 0cch, 0cch, 0cch, 0cch, 076h, 000h, 000h, 000h
   386 00014841 CCCCCC76000000      <1>
   387 00014848 0000C6C600C6C6C6C6- <1>     db  000h, 000h, 0c6h, 0c6h, 000h, 0c6h, 0c6h, 0c6h, 0c6h, 07eh, 006h, 00ch, 078h, 000h, 000h, 0c6h
   387 00014851 7E060C780000C6      <1>
   388 00014858 C6386CC6C6C6C66C38- <1>     db  0c6h, 038h, 06ch, 0c6h, 0c6h, 0c6h, 0c6h, 06ch, 038h, 000h, 000h, 000h, 000h, 0c6h, 0c6h, 000h
   388 00014861 00000000C6C600      <1>
   389 00014868 C6C6C6C6C6C67C0000- <1>     db  0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h, 018h, 018h, 03ch, 066h, 060h
   389 00014871 000018183C6660      <1>
   390 00014878 60663C181800000000- <1>     db  060h, 066h, 03ch, 018h, 018h, 000h, 000h, 000h, 000h, 038h, 06ch, 064h, 060h, 0f0h, 060h, 060h
   390 00014881 386C6460F06060      <1>
   391 00014888 60E6FC000000000066- <1>     db  060h, 0e6h, 0fch, 000h, 000h, 000h, 000h, 000h, 066h, 066h, 03ch, 018h, 07eh, 018h, 07eh, 018h
   391 00014891 663C187E187E18      <1>
   392 00014898 1800000000F8CCCCF8- <1>     db  018h, 000h, 000h, 000h, 000h, 0f8h, 0cch, 0cch, 0f8h, 0c4h, 0cch, 0deh, 0cch, 0cch, 0c6h, 000h
   392 000148A1 C4CCDECCCCC600      <1>
   393 000148A8 0000000E1B1818187E- <1>     db  000h, 000h, 000h, 00eh, 01bh, 018h, 018h, 018h, 07eh, 018h, 018h, 018h, 018h, 0d8h, 070h, 000h
   393 000148B1 18181818D87000      <1>
   394 000148B8 0018306000780C7CCC- <1>     db  000h, 018h, 030h, 060h, 000h, 078h, 00ch, 07ch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h, 00ch
   394 000148C1 CC76000000000C      <1>
   395 000148C8 18300038181818183C- <1>     db  018h, 030h, 000h, 038h, 018h, 018h, 018h, 018h, 03ch, 000h, 000h, 000h, 000h, 018h, 030h, 060h
   395 000148D1 00000000183060      <1>
   396 000148D8 007CC6C6C6C67C0000- <1>     db  000h, 07ch, 0c6h, 0c6h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h, 018h, 030h, 060h, 000h, 0cch
   396 000148E1 000018306000CC      <1>
   397 000148E8 CCCCCCCC7600000000- <1>     db  0cch, 0cch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h, 000h, 076h, 0dch, 000h, 0dch, 066h, 066h
   397 000148F1 0076DC00DC6666      <1>
   398 000148F8 66666600000076DC00- <1>     db  066h, 066h, 066h, 000h, 000h, 000h, 076h, 0dch, 000h, 0c6h, 0e6h, 0f6h, 0feh, 0deh, 0ceh, 0c6h
   398 00014901 C6E6F6FEDECEC6      <1>
   399 00014908 C6000000003C6C6C3E- <1>     db  0c6h, 000h, 000h, 000h, 000h, 03ch, 06ch, 06ch, 03eh, 000h, 07eh, 000h, 000h, 000h, 000h, 000h
   399 00014911 007E0000000000      <1>
   400 00014918 000000386C6C38007C- <1>     db  000h, 000h, 000h, 038h, 06ch, 06ch, 038h, 000h, 07ch, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   400 00014921 00000000000000      <1>
   401 00014928 0000303000303060C6- <1>     db  000h, 000h, 030h, 030h, 000h, 030h, 030h, 060h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h, 000h
   401 00014931 C67C0000000000      <1>
   402 00014938 00000000FEC0C0C000- <1>     db  000h, 000h, 000h, 000h, 0feh, 0c0h, 0c0h, 0c0h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   402 00014941 00000000000000      <1>
   403 00014948 0000FE060606000000- <1>     db  000h, 000h, 0feh, 006h, 006h, 006h, 000h, 000h, 000h, 000h, 000h, 0c0h, 0c0h, 0c6h, 0cch, 0d8h
   403 00014951 0000C0C0C6CCD8      <1>
   404 00014958 3060DC860C183E0000- <1>     db  030h, 060h, 0dch, 086h, 00ch, 018h, 03eh, 000h, 000h, 0c0h, 0c0h, 0c6h, 0cch, 0d8h, 030h, 066h
   404 00014961 C0C0C6CCD83066      <1>
   405 00014968 CE9E3E060600000018- <1>     db  0ceh, 09eh, 03eh, 006h, 006h, 000h, 000h, 000h, 018h, 018h, 000h, 018h, 018h, 03ch, 03ch, 03ch
   405 00014971 180018183C3C3C      <1>
   406 00014978 180000000000000036- <1>     db  018h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 036h, 06ch, 0d8h, 06ch, 036h, 000h, 000h, 000h
   406 00014981 6CD86C36000000      <1>
   407 00014988 000000000000D86C36- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 0d8h, 06ch, 036h, 06ch, 0d8h, 000h, 000h, 000h, 000h, 000h
   407 00014991 6CD80000000000      <1>
   408 00014998 114411441144114411- <1>     db  011h, 044h, 011h, 044h, 011h, 044h, 011h, 044h, 011h, 044h, 011h, 044h, 011h, 044h, 055h, 0aah
   408 000149A1 441144114455AA      <1>
   409 000149A8 55AA55AA55AA55AA55- <1>     db  055h, 0aah, 055h, 0aah, 055h, 0aah, 055h, 0aah, 055h, 0aah, 055h, 0aah, 0ddh, 077h, 0ddh, 077h
   409 000149B1 AA55AADD77DD77      <1>
   410 000149B8 DD77DD77DD77DD77DD- <1>     db  0ddh, 077h, 0ddh, 077h, 0ddh, 077h, 0ddh, 077h, 0ddh, 077h, 018h, 018h, 018h, 018h, 018h, 018h
   410 000149C1 77181818181818      <1>
   411 000149C8 181818181818181818- <1>     db  018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 0f8h
   411 000149D1 181818181818F8      <1>
   412 000149D8 181818181818181818- <1>     db  018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 0f8h, 018h, 0f8h, 018h, 018h
   412 000149E1 1818F818F81818      <1>
   413 000149E8 181818183636363636- <1>     db  018h, 018h, 018h, 018h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 0f6h, 036h, 036h, 036h, 036h
   413 000149F1 3636F636363636      <1>
   414 000149F8 363600000000000000- <1>     db  036h, 036h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0feh, 036h, 036h, 036h, 036h, 036h, 036h
   414 00014A01 FE363636363636      <1>
   415 00014A08 0000000000F818F818- <1>     db  000h, 000h, 000h, 000h, 000h, 0f8h, 018h, 0f8h, 018h, 018h, 018h, 018h, 018h, 018h, 036h, 036h
   415 00014A11 18181818183636      <1>
   416 00014A18 363636F606F6363636- <1>     db  036h, 036h, 036h, 0f6h, 006h, 0f6h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h
   416 00014A21 36363636363636      <1>
   417 00014A28 363636363636363636- <1>     db  036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 000h, 000h, 000h, 000h, 000h, 0feh
   417 00014A31 360000000000FE      <1>
   418 00014A38 06F636363636363636- <1>     db  006h, 0f6h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 0f6h, 006h, 0feh
   418 00014A41 36363636F606FE      <1>
   419 00014A48 000000000000363636- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 0feh, 000h, 000h
   419 00014A51 36363636FE0000      <1>
   420 00014A58 000000001818181818- <1>     db  000h, 000h, 000h, 000h, 018h, 018h, 018h, 018h, 018h, 0f8h, 018h, 0f8h, 000h, 000h, 000h, 000h
   420 00014A61 F818F800000000      <1>
   421 00014A68 000000000000000000- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0f8h, 018h, 018h, 018h, 018h, 018h, 018h
   421 00014A71 F8181818181818      <1>
   422 00014A78 181818181818181F00- <1>     db  018h, 018h, 018h, 018h, 018h, 018h, 018h, 01fh, 000h, 000h, 000h, 000h, 000h, 000h, 018h, 018h
   422 00014A81 00000000001818      <1>
   423 00014A88 1818181818FF000000- <1>     db  018h, 018h, 018h, 018h, 018h, 0ffh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   423 00014A91 00000000000000      <1>
   424 00014A98 000000FF1818181818- <1>     db  000h, 000h, 000h, 0ffh, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h
   424 00014AA1 18181818181818      <1>
   425 00014AA8 181F18181818181800- <1>     db  018h, 01fh, 018h, 018h, 018h, 018h, 018h, 018h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0ffh
   425 00014AB1 000000000000FF      <1>
   426 00014AB8 000000000000181818- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 0ffh, 018h, 018h
   426 00014AC1 18181818FF1818      <1>
   427 00014AC8 181818181818181818- <1>     db  018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 01fh, 018h, 01fh, 018h, 018h, 018h, 018h
   427 00014AD1 1F181F18181818      <1>
   428 00014AD8 181836363636363636- <1>     db  018h, 018h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 037h, 036h, 036h, 036h, 036h, 036h, 036h
   428 00014AE1 37363636363636      <1>
   429 00014AE8 363636363637303F00- <1>     db  036h, 036h, 036h, 036h, 036h, 037h, 030h, 03fh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   429 00014AF1 00000000000000      <1>
   430 00014AF8 0000003F3037363636- <1>     db  000h, 000h, 000h, 03fh, 030h, 037h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h
   430 00014B01 36363636363636      <1>
   431 00014B08 36F700FF0000000000- <1>     db  036h, 0f7h, 000h, 0ffh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0ffh
   431 00014B11 000000000000FF      <1>
   432 00014B18 00F736363636363636- <1>     db  000h, 0f7h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 037h, 030h, 037h
   432 00014B21 36363636373037      <1>
   433 00014B28 363636363636000000- <1>     db  036h, 036h, 036h, 036h, 036h, 036h, 000h, 000h, 000h, 000h, 000h, 0ffh, 000h, 0ffh, 000h, 000h
   433 00014B31 0000FF00FF0000      <1>
   434 00014B38 000000003636363636- <1>     db  000h, 000h, 000h, 000h, 036h, 036h, 036h, 036h, 036h, 0f7h, 000h, 0f7h, 036h, 036h, 036h, 036h
   434 00014B41 F700F736363636      <1>
   435 00014B48 36361818181818FF00- <1>     db  036h, 036h, 018h, 018h, 018h, 018h, 018h, 0ffh, 000h, 0ffh, 000h, 000h, 000h, 000h, 000h, 000h
   435 00014B51 FF000000000000      <1>
   436 00014B58 36363636363636FF00- <1>     db  036h, 036h, 036h, 036h, 036h, 036h, 036h, 0ffh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   436 00014B61 00000000000000      <1>
   437 00014B68 000000FF00FF181818- <1>     db  000h, 000h, 000h, 0ffh, 000h, 0ffh, 018h, 018h, 018h, 018h, 018h, 018h, 000h, 000h, 000h, 000h
   437 00014B71 18181800000000      <1>
   438 00014B78 000000FF3636363636- <1>     db  000h, 000h, 000h, 0ffh, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h
   438 00014B81 36363636363636      <1>
   439 00014B88 363F00000000000018- <1>     db  036h, 03fh, 000h, 000h, 000h, 000h, 000h, 000h, 018h, 018h, 018h, 018h, 018h, 01fh, 018h, 01fh
   439 00014B91 181818181F181F      <1>
   440 00014B98 000000000000000000- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 01fh, 018h, 01fh, 018h, 018h
   440 00014BA1 00001F181F1818      <1>
   441 00014BA8 181818180000000000- <1>     db  018h, 018h, 018h, 018h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 03fh, 036h, 036h, 036h, 036h
   441 00014BB1 00003F36363636      <1>
   442 00014BB8 363636363636363636- <1>     db  036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 0ffh, 036h, 036h, 036h, 036h, 036h, 036h
   442 00014BC1 FF363636363636      <1>
   443 00014BC8 1818181818FF18FF18- <1>     db  018h, 018h, 018h, 018h, 018h, 0ffh, 018h, 0ffh, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h
   443 00014BD1 18181818181818      <1>
   444 00014BD8 1818181818F8000000- <1>     db  018h, 018h, 018h, 018h, 018h, 0f8h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   444 00014BE1 00000000000000      <1>
   445 00014BE8 0000001F1818181818- <1>     db  000h, 000h, 000h, 01fh, 018h, 018h, 018h, 018h, 018h, 018h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
   445 00014BF1 18FFFFFFFFFFFF      <1>
   446 00014BF8 FFFFFFFFFFFFFFFF00- <1>     db  0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0ffh
   446 00014C01 000000000000FF      <1>
   447 00014C08 FFFFFFFFFFFFF0F0F0- <1>     db  0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h
   447 00014C11 F0F0F0F0F0F0F0      <1>
   448 00014C18 F0F0F0F00F0F0F0F0F- <1>     db  0f0h, 0f0h, 0f0h, 0f0h, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh
   448 00014C21 0F0F0F0F0F0F0F      <1>
   449 00014C28 0F0FFFFFFFFFFFFFFF- <1>     db  00fh, 00fh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   449 00014C31 00000000000000      <1>
   450 00014C38 000000000076DCD8D8- <1>     db  000h, 000h, 000h, 000h, 000h, 076h, 0dch, 0d8h, 0d8h, 0dch, 076h, 000h, 000h, 000h, 000h, 000h
   450 00014C41 DC760000000000      <1>
   451 00014C48 00007CC6FCC6C6FCC0- <1>     db  000h, 000h, 07ch, 0c6h, 0fch, 0c6h, 0c6h, 0fch, 0c0h, 0c0h, 040h, 000h, 000h, 000h, 0feh, 0c6h
   451 00014C51 C040000000FEC6      <1>
   452 00014C58 C6C0C0C0C0C0C00000- <1>     db  0c6h, 0c0h, 0c0h, 0c0h, 0c0h, 0c0h, 0c0h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0feh, 06ch
   452 00014C61 0000000000FE6C      <1>
   453 00014C68 6C6C6C6C6C00000000- <1>     db  06ch, 06ch, 06ch, 06ch, 06ch, 000h, 000h, 000h, 000h, 000h, 0feh, 0c6h, 060h, 030h, 018h, 030h
   453 00014C71 00FEC660301830      <1>
   454 00014C78 60C6FE000000000000- <1>     db  060h, 0c6h, 0feh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 07eh, 0d8h, 0d8h, 0d8h, 0d8h
   454 00014C81 00007ED8D8D8D8      <1>
   455 00014C88 700000000000000066- <1>     db  070h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 066h, 066h, 066h, 066h, 07ch, 060h, 060h, 0c0h
   455 00014C91 6666667C6060C0      <1>
   456 00014C98 00000000000076DC18- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 076h, 0dch, 018h, 018h, 018h, 018h, 018h, 000h, 000h, 000h
   456 00014CA1 18181818000000      <1>
   457 00014CA8 00007E183C6666663C- <1>     db  000h, 000h, 07eh, 018h, 03ch, 066h, 066h, 066h, 03ch, 018h, 07eh, 000h, 000h, 000h, 000h, 000h
   457 00014CB1 187E0000000000      <1>
   458 00014CB8 386CC6C6FEC6C66C38- <1>     db  038h, 06ch, 0c6h, 0c6h, 0feh, 0c6h, 0c6h, 06ch, 038h, 000h, 000h, 000h, 000h, 000h, 038h, 06ch
   458 00014CC1 0000000000386C      <1>
   459 00014CC8 C6C6C66C6C6CEE0000- <1>     db  0c6h, 0c6h, 0c6h, 06ch, 06ch, 06ch, 0eeh, 000h, 000h, 000h, 000h, 000h, 01eh, 030h, 018h, 00ch
   459 00014CD1 0000001E30180C      <1>
   460 00014CD8 3E6666663C00000000- <1>     db  03eh, 066h, 066h, 066h, 03ch, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 07eh, 0dbh, 0dbh
   460 00014CE1 000000007EDBDB      <1>
   461 00014CE8 7E0000000000000003- <1>     db  07eh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 003h, 006h, 07eh, 0dbh, 0dbh, 0f3h, 07eh, 060h
   461 00014CF1 067EDBDBF37E60      <1>
   462 00014CF8 C000000000001C3060- <1>     db  0c0h, 000h, 000h, 000h, 000h, 000h, 01ch, 030h, 060h, 060h, 07ch, 060h, 060h, 030h, 01ch, 000h
   462 00014D01 607C6060301C00      <1>
   463 00014D08 00000000007CC6C6C6- <1>     db  000h, 000h, 000h, 000h, 000h, 07ch, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 000h, 000h, 000h
   463 00014D11 C6C6C6C6000000      <1>
   464 00014D18 000000FE0000FE0000- <1>     db  000h, 000h, 000h, 0feh, 000h, 000h, 0feh, 000h, 000h, 0feh, 000h, 000h, 000h, 000h, 000h, 000h
   464 00014D21 FE000000000000      <1>
   465 00014D28 0018187E18180000FF- <1>     db  000h, 018h, 018h, 07eh, 018h, 018h, 000h, 000h, 0ffh, 000h, 000h, 000h, 000h, 000h, 030h, 018h
   465 00014D31 00000000003018      <1>
   466 00014D38 0C060C1830007E0000- <1>     db  00ch, 006h, 00ch, 018h, 030h, 000h, 07eh, 000h, 000h, 000h, 000h, 000h, 00ch, 018h, 030h, 060h
   466 00014D41 0000000C183060      <1>
   467 00014D48 30180C007E00000000- <1>     db  030h, 018h, 00ch, 000h, 07eh, 000h, 000h, 000h, 000h, 000h, 00eh, 01bh, 01bh, 018h, 018h, 018h
   467 00014D51 000E1B1B181818      <1>
   468 00014D58 181818181818181818- <1>     db  018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 0d8h, 0d8h
   468 00014D61 1818181818D8D8      <1>
   469 00014D68 700000000000001818- <1>     db  070h, 000h, 000h, 000h, 000h, 000h, 000h, 018h, 018h, 000h, 07eh, 000h, 018h, 018h, 000h, 000h
   469 00014D71 007E0018180000      <1>
   470 00014D78 00000000000076DC00- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 076h, 0dch, 000h, 076h, 0dch, 000h, 000h, 000h, 000h, 000h
   470 00014D81 76DC0000000000      <1>
   471 00014D88 00386C6C3800000000- <1>     db  000h, 038h, 06ch, 06ch, 038h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   471 00014D91 00000000000000      <1>
   472 00014D98 000000001818000000- <1>     db  000h, 000h, 000h, 000h, 018h, 018h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   472 00014DA1 00000000000000      <1>
   473 00014DA8 000000180000000000- <1>     db  000h, 000h, 000h, 018h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 00fh, 00ch, 00ch, 00ch, 00ch
   473 00014DB1 00000F0C0C0C0C      <1>
   474 00014DB8 0CEC6C3C1C00000000- <1>     db  00ch, 0ech, 06ch, 03ch, 01ch, 000h, 000h, 000h, 000h, 0d8h, 06ch, 06ch, 06ch, 06ch, 06ch, 000h
   474 00014DC1 D86C6C6C6C6C00      <1>
   475 00014DC8 0000000000000070D8- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 070h, 0d8h, 030h, 060h, 0c8h, 0f8h, 000h, 000h, 000h
   475 00014DD1 3060C8F8000000      <1>
   476 00014DD8 00000000000000007C- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 07ch, 07ch, 07ch, 07ch, 07ch, 07ch, 000h, 000h
   476 00014DE1 7C7C7C7C7C0000      <1>
   477 00014DE8 000000000000000000- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   477 00014DF1 00000000000000      <1>
   478                              <1> vgafont16:
   479 00014DF8 000000000000000000- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   479 00014E01 00000000000000      <1>
   480 00014E08 00007E81A58181BD99- <1>     db  000h, 000h, 07eh, 081h, 0a5h, 081h, 081h, 0bdh, 099h, 081h, 081h, 07eh, 000h, 000h, 000h, 000h
   480 00014E11 81817E00000000      <1>
   481 00014E18 00007EFFDBFFFFC3E7- <1>     db  000h, 000h, 07eh, 0ffh, 0dbh, 0ffh, 0ffh, 0c3h, 0e7h, 0ffh, 0ffh, 07eh, 000h, 000h, 000h, 000h
   481 00014E21 FFFF7E00000000      <1>
   482 00014E28 000000006CFEFEFEFE- <1>     db  000h, 000h, 000h, 000h, 06ch, 0feh, 0feh, 0feh, 0feh, 07ch, 038h, 010h, 000h, 000h, 000h, 000h
   482 00014E31 7C381000000000      <1>
   483 00014E38 0000000010387CFE7C- <1>     db  000h, 000h, 000h, 000h, 010h, 038h, 07ch, 0feh, 07ch, 038h, 010h, 000h, 000h, 000h, 000h, 000h
   483 00014E41 38100000000000      <1>
   484 00014E48 000000183C3CE7E7E7- <1>     db  000h, 000h, 000h, 018h, 03ch, 03ch, 0e7h, 0e7h, 0e7h, 018h, 018h, 03ch, 000h, 000h, 000h, 000h
   484 00014E51 18183C00000000      <1>
   485 00014E58 000000183C7EFFFF7E- <1>     db  000h, 000h, 000h, 018h, 03ch, 07eh, 0ffh, 0ffh, 07eh, 018h, 018h, 03ch, 000h, 000h, 000h, 000h
   485 00014E61 18183C00000000      <1>
   486 00014E68 000000000000183C3C- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 018h, 03ch, 03ch, 018h, 000h, 000h, 000h, 000h, 000h, 000h
   486 00014E71 18000000000000      <1>
   487 00014E78 FFFFFFFFFFFFE7C3C3- <1>     db  0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0e7h, 0c3h, 0c3h, 0e7h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
   487 00014E81 E7FFFFFFFFFFFF      <1>
   488 00014E88 00000000003C664242- <1>     db  000h, 000h, 000h, 000h, 000h, 03ch, 066h, 042h, 042h, 066h, 03ch, 000h, 000h, 000h, 000h, 000h
   488 00014E91 663C0000000000      <1>
   489 00014E98 FFFFFFFFFFC399BDBD- <1>     db  0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0c3h, 099h, 0bdh, 0bdh, 099h, 0c3h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
   489 00014EA1 99C3FFFFFFFFFF      <1>
   490 00014EA8 00001E0E1A3278CCCC- <1>     db  000h, 000h, 01eh, 00eh, 01ah, 032h, 078h, 0cch, 0cch, 0cch, 0cch, 078h, 000h, 000h, 000h, 000h
   490 00014EB1 CCCC7800000000      <1>
   491 00014EB8 00003C666666663C18- <1>     db  000h, 000h, 03ch, 066h, 066h, 066h, 066h, 03ch, 018h, 07eh, 018h, 018h, 000h, 000h, 000h, 000h
   491 00014EC1 7E181800000000      <1>
   492 00014EC8 00003F333F30303030- <1>     db  000h, 000h, 03fh, 033h, 03fh, 030h, 030h, 030h, 030h, 070h, 0f0h, 0e0h, 000h, 000h, 000h, 000h
   492 00014ED1 70F0E000000000      <1>
   493 00014ED8 00007F637F63636363- <1>     db  000h, 000h, 07fh, 063h, 07fh, 063h, 063h, 063h, 063h, 067h, 0e7h, 0e6h, 0c0h, 000h, 000h, 000h
   493 00014EE1 67E7E6C0000000      <1>
   494 00014EE8 0000001818DB3CE73C- <1>     db  000h, 000h, 000h, 018h, 018h, 0dbh, 03ch, 0e7h, 03ch, 0dbh, 018h, 018h, 000h, 000h, 000h, 000h
   494 00014EF1 DB181800000000      <1>
   495 00014EF8 0080C0E0F0F8FEF8F0- <1>     db  000h, 080h, 0c0h, 0e0h, 0f0h, 0f8h, 0feh, 0f8h, 0f0h, 0e0h, 0c0h, 080h, 000h, 000h, 000h, 000h
   495 00014F01 E0C08000000000      <1>
   496 00014F08 0002060E1E3EFE3E1E- <1>     db  000h, 002h, 006h, 00eh, 01eh, 03eh, 0feh, 03eh, 01eh, 00eh, 006h, 002h, 000h, 000h, 000h, 000h
   496 00014F11 0E060200000000      <1>
   497 00014F18 0000183C7E1818187E- <1>     db  000h, 000h, 018h, 03ch, 07eh, 018h, 018h, 018h, 07eh, 03ch, 018h, 000h, 000h, 000h, 000h, 000h
   497 00014F21 3C180000000000      <1>
   498 00014F28 000066666666666666- <1>     db  000h, 000h, 066h, 066h, 066h, 066h, 066h, 066h, 066h, 000h, 066h, 066h, 000h, 000h, 000h, 000h
   498 00014F31 00666600000000      <1>
   499 00014F38 00007FDBDBDB7B1B1B- <1>     db  000h, 000h, 07fh, 0dbh, 0dbh, 0dbh, 07bh, 01bh, 01bh, 01bh, 01bh, 01bh, 000h, 000h, 000h, 000h
   499 00014F41 1B1B1B00000000      <1>
   500 00014F48 007CC660386CC6C66C- <1>     db  000h, 07ch, 0c6h, 060h, 038h, 06ch, 0c6h, 0c6h, 06ch, 038h, 00ch, 0c6h, 07ch, 000h, 000h, 000h
   500 00014F51 380CC67C000000      <1>
   501 00014F58 0000000000000000FE- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0feh, 0feh, 0feh, 0feh, 000h, 000h, 000h, 000h
   501 00014F61 FEFEFE00000000      <1>
   502 00014F68 0000183C7E1818187E- <1>     db  000h, 000h, 018h, 03ch, 07eh, 018h, 018h, 018h, 07eh, 03ch, 018h, 07eh, 000h, 000h, 000h, 000h
   502 00014F71 3C187E00000000      <1>
   503 00014F78 0000183C7E18181818- <1>     db  000h, 000h, 018h, 03ch, 07eh, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 000h, 000h, 000h, 000h
   503 00014F81 18181800000000      <1>
   504 00014F88 000018181818181818- <1>     db  000h, 000h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 07eh, 03ch, 018h, 000h, 000h, 000h, 000h
   504 00014F91 7E3C1800000000      <1>
   505 00014F98 0000000000180CFE0C- <1>     db  000h, 000h, 000h, 000h, 000h, 018h, 00ch, 0feh, 00ch, 018h, 000h, 000h, 000h, 000h, 000h, 000h
   505 00014FA1 18000000000000      <1>
   506 00014FA8 00000000003060FE60- <1>     db  000h, 000h, 000h, 000h, 000h, 030h, 060h, 0feh, 060h, 030h, 000h, 000h, 000h, 000h, 000h, 000h
   506 00014FB1 30000000000000      <1>
   507 00014FB8 000000000000C0C0C0- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 0c0h, 0c0h, 0c0h, 0feh, 000h, 000h, 000h, 000h, 000h, 000h
   507 00014FC1 FE000000000000      <1>
   508 00014FC8 00000000002466FF66- <1>     db  000h, 000h, 000h, 000h, 000h, 024h, 066h, 0ffh, 066h, 024h, 000h, 000h, 000h, 000h, 000h, 000h
   508 00014FD1 24000000000000      <1>
   509 00014FD8 000000001038387C7C- <1>     db  000h, 000h, 000h, 000h, 010h, 038h, 038h, 07ch, 07ch, 0feh, 0feh, 000h, 000h, 000h, 000h, 000h
   509 00014FE1 FEFE0000000000      <1>
   510 00014FE8 00000000FEFE7C7C38- <1>     db  000h, 000h, 000h, 000h, 0feh, 0feh, 07ch, 07ch, 038h, 038h, 010h, 000h, 000h, 000h, 000h, 000h
   510 00014FF1 38100000000000      <1>
   511 00014FF8 000000000000000000- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   511 00015001 00000000000000      <1>
   512 00015008 0000183C3C3C181818- <1>     db  000h, 000h, 018h, 03ch, 03ch, 03ch, 018h, 018h, 018h, 000h, 018h, 018h, 000h, 000h, 000h, 000h
   512 00015011 00181800000000      <1>
   513 00015018 006666662400000000- <1>     db  000h, 066h, 066h, 066h, 024h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   513 00015021 00000000000000      <1>
   514 00015028 0000006C6CFE6C6C6C- <1>     db  000h, 000h, 000h, 06ch, 06ch, 0feh, 06ch, 06ch, 06ch, 0feh, 06ch, 06ch, 000h, 000h, 000h, 000h
   514 00015031 FE6C6C00000000      <1>
   515 00015038 18187CC6C2C07C0606- <1>     db  018h, 018h, 07ch, 0c6h, 0c2h, 0c0h, 07ch, 006h, 006h, 086h, 0c6h, 07ch, 018h, 018h, 000h, 000h
   515 00015041 86C67C18180000      <1>
   516 00015048 00000000C2C60C1830- <1>     db  000h, 000h, 000h, 000h, 0c2h, 0c6h, 00ch, 018h, 030h, 060h, 0c6h, 086h, 000h, 000h, 000h, 000h
   516 00015051 60C68600000000      <1>
   517 00015058 0000386C6C3876DCCC- <1>     db  000h, 000h, 038h, 06ch, 06ch, 038h, 076h, 0dch, 0cch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h
   517 00015061 CCCC7600000000      <1>
   518 00015068 003030306000000000- <1>     db  000h, 030h, 030h, 030h, 060h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   518 00015071 00000000000000      <1>
   519 00015078 00000C183030303030- <1>     db  000h, 000h, 00ch, 018h, 030h, 030h, 030h, 030h, 030h, 030h, 018h, 00ch, 000h, 000h, 000h, 000h
   519 00015081 30180C00000000      <1>
   520 00015088 000030180C0C0C0C0C- <1>     db  000h, 000h, 030h, 018h, 00ch, 00ch, 00ch, 00ch, 00ch, 00ch, 018h, 030h, 000h, 000h, 000h, 000h
   520 00015091 0C183000000000      <1>
   521 00015098 0000000000663CFF3C- <1>     db  000h, 000h, 000h, 000h, 000h, 066h, 03ch, 0ffh, 03ch, 066h, 000h, 000h, 000h, 000h, 000h, 000h
   521 000150A1 66000000000000      <1>
   522 000150A8 000000000018187E18- <1>     db  000h, 000h, 000h, 000h, 000h, 018h, 018h, 07eh, 018h, 018h, 000h, 000h, 000h, 000h, 000h, 000h
   522 000150B1 18000000000000      <1>
   523 000150B8 000000000000000000- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 018h, 018h, 018h, 030h, 000h, 000h, 000h
   523 000150C1 18181830000000      <1>
   524 000150C8 00000000000000FE00- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 0feh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   524 000150D1 00000000000000      <1>
   525 000150D8 000000000000000000- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 018h, 018h, 000h, 000h, 000h, 000h
   525 000150E1 00181800000000      <1>
   526 000150E8 0000000002060C1830- <1>     db  000h, 000h, 000h, 000h, 002h, 006h, 00ch, 018h, 030h, 060h, 0c0h, 080h, 000h, 000h, 000h, 000h
   526 000150F1 60C08000000000      <1>
   527 000150F8 00003C66C3C3DBDBC3- <1>     db  000h, 000h, 03ch, 066h, 0c3h, 0c3h, 0dbh, 0dbh, 0c3h, 0c3h, 066h, 03ch, 000h, 000h, 000h, 000h
   527 00015101 C3663C00000000      <1>
   528 00015108 000018387818181818- <1>     db  000h, 000h, 018h, 038h, 078h, 018h, 018h, 018h, 018h, 018h, 018h, 07eh, 000h, 000h, 000h, 000h
   528 00015111 18187E00000000      <1>
   529 00015118 00007CC6060C183060- <1>     db  000h, 000h, 07ch, 0c6h, 006h, 00ch, 018h, 030h, 060h, 0c0h, 0c6h, 0feh, 000h, 000h, 000h, 000h
   529 00015121 C0C6FE00000000      <1>
   530 00015128 00007CC606063C0606- <1>     db  000h, 000h, 07ch, 0c6h, 006h, 006h, 03ch, 006h, 006h, 006h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   530 00015131 06C67C00000000      <1>
   531 00015138 00000C1C3C6CCCFE0C- <1>     db  000h, 000h, 00ch, 01ch, 03ch, 06ch, 0cch, 0feh, 00ch, 00ch, 00ch, 01eh, 000h, 000h, 000h, 000h
   531 00015141 0C0C1E00000000      <1>
   532 00015148 0000FEC0C0C0FC0606- <1>     db  000h, 000h, 0feh, 0c0h, 0c0h, 0c0h, 0fch, 006h, 006h, 006h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   532 00015151 06C67C00000000      <1>
   533 00015158 00003860C0C0FCC6C6- <1>     db  000h, 000h, 038h, 060h, 0c0h, 0c0h, 0fch, 0c6h, 0c6h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   533 00015161 C6C67C00000000      <1>
   534 00015168 0000FEC606060C1830- <1>     db  000h, 000h, 0feh, 0c6h, 006h, 006h, 00ch, 018h, 030h, 030h, 030h, 030h, 000h, 000h, 000h, 000h
   534 00015171 30303000000000      <1>
   535 00015178 00007CC6C6C67CC6C6- <1>     db  000h, 000h, 07ch, 0c6h, 0c6h, 0c6h, 07ch, 0c6h, 0c6h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   535 00015181 C6C67C00000000      <1>
   536 00015188 00007CC6C6C67E0606- <1>     db  000h, 000h, 07ch, 0c6h, 0c6h, 0c6h, 07eh, 006h, 006h, 006h, 00ch, 078h, 000h, 000h, 000h, 000h
   536 00015191 060C7800000000      <1>
   537 00015198 000000001818000000- <1>     db  000h, 000h, 000h, 000h, 018h, 018h, 000h, 000h, 000h, 018h, 018h, 000h, 000h, 000h, 000h, 000h
   537 000151A1 18180000000000      <1>
   538 000151A8 000000001818000000- <1>     db  000h, 000h, 000h, 000h, 018h, 018h, 000h, 000h, 000h, 018h, 018h, 030h, 000h, 000h, 000h, 000h
   538 000151B1 18183000000000      <1>
   539 000151B8 000000060C18306030- <1>     db  000h, 000h, 000h, 006h, 00ch, 018h, 030h, 060h, 030h, 018h, 00ch, 006h, 000h, 000h, 000h, 000h
   539 000151C1 180C0600000000      <1>
   540 000151C8 00000000007E00007E- <1>     db  000h, 000h, 000h, 000h, 000h, 07eh, 000h, 000h, 07eh, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   540 000151D1 00000000000000      <1>
   541 000151D8 0000006030180C060C- <1>     db  000h, 000h, 000h, 060h, 030h, 018h, 00ch, 006h, 00ch, 018h, 030h, 060h, 000h, 000h, 000h, 000h
   541 000151E1 18306000000000      <1>
   542 000151E8 00007CC6C60C181818- <1>     db  000h, 000h, 07ch, 0c6h, 0c6h, 00ch, 018h, 018h, 018h, 000h, 018h, 018h, 000h, 000h, 000h, 000h
   542 000151F1 00181800000000      <1>
   543 000151F8 0000007CC6C6DEDEDE- <1>     db  000h, 000h, 000h, 07ch, 0c6h, 0c6h, 0deh, 0deh, 0deh, 0dch, 0c0h, 07ch, 000h, 000h, 000h, 000h
   543 00015201 DCC07C00000000      <1>
   544 00015208 000010386CC6C6FEC6- <1>     db  000h, 000h, 010h, 038h, 06ch, 0c6h, 0c6h, 0feh, 0c6h, 0c6h, 0c6h, 0c6h, 000h, 000h, 000h, 000h
   544 00015211 C6C6C600000000      <1>
   545 00015218 0000FC6666667C6666- <1>     db  000h, 000h, 0fch, 066h, 066h, 066h, 07ch, 066h, 066h, 066h, 066h, 0fch, 000h, 000h, 000h, 000h
   545 00015221 6666FC00000000      <1>
   546 00015228 00003C66C2C0C0C0C0- <1>     db  000h, 000h, 03ch, 066h, 0c2h, 0c0h, 0c0h, 0c0h, 0c0h, 0c2h, 066h, 03ch, 000h, 000h, 000h, 000h
   546 00015231 C2663C00000000      <1>
   547 00015238 0000F86C6666666666- <1>     db  000h, 000h, 0f8h, 06ch, 066h, 066h, 066h, 066h, 066h, 066h, 06ch, 0f8h, 000h, 000h, 000h, 000h
   547 00015241 666CF800000000      <1>
   548 00015248 0000FE666268786860- <1>     db  000h, 000h, 0feh, 066h, 062h, 068h, 078h, 068h, 060h, 062h, 066h, 0feh, 000h, 000h, 000h, 000h
   548 00015251 6266FE00000000      <1>
   549 00015258 0000FE666268786860- <1>     db  000h, 000h, 0feh, 066h, 062h, 068h, 078h, 068h, 060h, 060h, 060h, 0f0h, 000h, 000h, 000h, 000h
   549 00015261 6060F000000000      <1>
   550 00015268 00003C66C2C0C0DEC6- <1>     db  000h, 000h, 03ch, 066h, 0c2h, 0c0h, 0c0h, 0deh, 0c6h, 0c6h, 066h, 03ah, 000h, 000h, 000h, 000h
   550 00015271 C6663A00000000      <1>
   551 00015278 0000C6C6C6C6FEC6C6- <1>     db  000h, 000h, 0c6h, 0c6h, 0c6h, 0c6h, 0feh, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 000h, 000h, 000h, 000h
   551 00015281 C6C6C600000000      <1>
   552 00015288 00003C181818181818- <1>     db  000h, 000h, 03ch, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 03ch, 000h, 000h, 000h, 000h
   552 00015291 18183C00000000      <1>
   553 00015298 00001E0C0C0C0C0CCC- <1>     db  000h, 000h, 01eh, 00ch, 00ch, 00ch, 00ch, 00ch, 0cch, 0cch, 0cch, 078h, 000h, 000h, 000h, 000h
   553 000152A1 CCCC7800000000      <1>
   554 000152A8 0000E666666C78786C- <1>     db  000h, 000h, 0e6h, 066h, 066h, 06ch, 078h, 078h, 06ch, 066h, 066h, 0e6h, 000h, 000h, 000h, 000h
   554 000152B1 6666E600000000      <1>
   555 000152B8 0000F0606060606060- <1>     db  000h, 000h, 0f0h, 060h, 060h, 060h, 060h, 060h, 060h, 062h, 066h, 0feh, 000h, 000h, 000h, 000h
   555 000152C1 6266FE00000000      <1>
   556 000152C8 0000C3E7FFFFDBC3C3- <1>     db  000h, 000h, 0c3h, 0e7h, 0ffh, 0ffh, 0dbh, 0c3h, 0c3h, 0c3h, 0c3h, 0c3h, 000h, 000h, 000h, 000h
   556 000152D1 C3C3C300000000      <1>
   557 000152D8 0000C6E6F6FEDECEC6- <1>     db  000h, 000h, 0c6h, 0e6h, 0f6h, 0feh, 0deh, 0ceh, 0c6h, 0c6h, 0c6h, 0c6h, 000h, 000h, 000h, 000h
   557 000152E1 C6C6C600000000      <1>
   558 000152E8 00007CC6C6C6C6C6C6- <1>     db  000h, 000h, 07ch, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   558 000152F1 C6C67C00000000      <1>
   559 000152F8 0000FC6666667C6060- <1>     db  000h, 000h, 0fch, 066h, 066h, 066h, 07ch, 060h, 060h, 060h, 060h, 0f0h, 000h, 000h, 000h, 000h
   559 00015301 6060F000000000      <1>
   560 00015308 00007CC6C6C6C6C6C6- <1>     db  000h, 000h, 07ch, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0d6h, 0deh, 07ch, 00ch, 00eh, 000h, 000h
   560 00015311 D6DE7C0C0E0000      <1>
   561 00015318 0000FC6666667C6C66- <1>     db  000h, 000h, 0fch, 066h, 066h, 066h, 07ch, 06ch, 066h, 066h, 066h, 0e6h, 000h, 000h, 000h, 000h
   561 00015321 6666E600000000      <1>
   562 00015328 00007CC6C660380C06- <1>     db  000h, 000h, 07ch, 0c6h, 0c6h, 060h, 038h, 00ch, 006h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   562 00015331 C6C67C00000000      <1>
   563 00015338 0000FFDB9918181818- <1>     db  000h, 000h, 0ffh, 0dbh, 099h, 018h, 018h, 018h, 018h, 018h, 018h, 03ch, 000h, 000h, 000h, 000h
   563 00015341 18183C00000000      <1>
   564 00015348 0000C6C6C6C6C6C6C6- <1>     db  000h, 000h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   564 00015351 C6C67C00000000      <1>
   565 00015358 0000C3C3C3C3C3C3C3- <1>     db  000h, 000h, 0c3h, 0c3h, 0c3h, 0c3h, 0c3h, 0c3h, 0c3h, 066h, 03ch, 018h, 000h, 000h, 000h, 000h
   565 00015361 663C1800000000      <1>
   566 00015368 0000C3C3C3C3C3DBDB- <1>     db  000h, 000h, 0c3h, 0c3h, 0c3h, 0c3h, 0c3h, 0dbh, 0dbh, 0ffh, 066h, 066h, 000h, 000h, 000h, 000h
   566 00015371 FF666600000000      <1>
   567 00015378 0000C3C3663C18183C- <1>     db  000h, 000h, 0c3h, 0c3h, 066h, 03ch, 018h, 018h, 03ch, 066h, 0c3h, 0c3h, 000h, 000h, 000h, 000h
   567 00015381 66C3C300000000      <1>
   568 00015388 0000C3C3C3663C1818- <1>     db  000h, 000h, 0c3h, 0c3h, 0c3h, 066h, 03ch, 018h, 018h, 018h, 018h, 03ch, 000h, 000h, 000h, 000h
   568 00015391 18183C00000000      <1>
   569 00015398 0000FFC3860C183060- <1>     db  000h, 000h, 0ffh, 0c3h, 086h, 00ch, 018h, 030h, 060h, 0c1h, 0c3h, 0ffh, 000h, 000h, 000h, 000h
   569 000153A1 C1C3FF00000000      <1>
   570 000153A8 00003C303030303030- <1>     db  000h, 000h, 03ch, 030h, 030h, 030h, 030h, 030h, 030h, 030h, 030h, 03ch, 000h, 000h, 000h, 000h
   570 000153B1 30303C00000000      <1>
   571 000153B8 00000080C0E070381C- <1>     db  000h, 000h, 000h, 080h, 0c0h, 0e0h, 070h, 038h, 01ch, 00eh, 006h, 002h, 000h, 000h, 000h, 000h
   571 000153C1 0E060200000000      <1>
   572 000153C8 00003C0C0C0C0C0C0C- <1>     db  000h, 000h, 03ch, 00ch, 00ch, 00ch, 00ch, 00ch, 00ch, 00ch, 00ch, 03ch, 000h, 000h, 000h, 000h
   572 000153D1 0C0C3C00000000      <1>
   573 000153D8 10386CC60000000000- <1>     db  010h, 038h, 06ch, 0c6h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   573 000153E1 00000000000000      <1>
   574 000153E8 000000000000000000- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 0ffh, 000h, 000h
   574 000153F1 00000000FF0000      <1>
   575 000153F8 303018000000000000- <1>     db  030h, 030h, 018h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   575 00015401 00000000000000      <1>
   576 00015408 0000000000780C7CCC- <1>     db  000h, 000h, 000h, 000h, 000h, 078h, 00ch, 07ch, 0cch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h
   576 00015411 CCCC7600000000      <1>
   577 00015418 0000E06060786C6666- <1>     db  000h, 000h, 0e0h, 060h, 060h, 078h, 06ch, 066h, 066h, 066h, 066h, 07ch, 000h, 000h, 000h, 000h
   577 00015421 66667C00000000      <1>
   578 00015428 00000000007CC6C0C0- <1>     db  000h, 000h, 000h, 000h, 000h, 07ch, 0c6h, 0c0h, 0c0h, 0c0h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   578 00015431 C0C67C00000000      <1>
   579 00015438 00001C0C0C3C6CCCCC- <1>     db  000h, 000h, 01ch, 00ch, 00ch, 03ch, 06ch, 0cch, 0cch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h
   579 00015441 CCCC7600000000      <1>
   580 00015448 00000000007CC6FEC0- <1>     db  000h, 000h, 000h, 000h, 000h, 07ch, 0c6h, 0feh, 0c0h, 0c0h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   580 00015451 C0C67C00000000      <1>
   581 00015458 0000386C6460F06060- <1>     db  000h, 000h, 038h, 06ch, 064h, 060h, 0f0h, 060h, 060h, 060h, 060h, 0f0h, 000h, 000h, 000h, 000h
   581 00015461 6060F000000000      <1>
   582 00015468 000000000076CCCCCC- <1>     db  000h, 000h, 000h, 000h, 000h, 076h, 0cch, 0cch, 0cch, 0cch, 0cch, 07ch, 00ch, 0cch, 078h, 000h
   582 00015471 CCCC7C0CCC7800      <1>
   583 00015478 0000E060606C766666- <1>     db  000h, 000h, 0e0h, 060h, 060h, 06ch, 076h, 066h, 066h, 066h, 066h, 0e6h, 000h, 000h, 000h, 000h
   583 00015481 6666E600000000      <1>
   584 00015488 000018180038181818- <1>     db  000h, 000h, 018h, 018h, 000h, 038h, 018h, 018h, 018h, 018h, 018h, 03ch, 000h, 000h, 000h, 000h
   584 00015491 18183C00000000      <1>
   585 00015498 00000606000E060606- <1>     db  000h, 000h, 006h, 006h, 000h, 00eh, 006h, 006h, 006h, 006h, 006h, 006h, 066h, 066h, 03ch, 000h
   585 000154A1 06060666663C00      <1>
   586 000154A8 0000E06060666C7878- <1>     db  000h, 000h, 0e0h, 060h, 060h, 066h, 06ch, 078h, 078h, 06ch, 066h, 0e6h, 000h, 000h, 000h, 000h
   586 000154B1 6C66E600000000      <1>
   587 000154B8 000038181818181818- <1>     db  000h, 000h, 038h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 03ch, 000h, 000h, 000h, 000h
   587 000154C1 18183C00000000      <1>
   588 000154C8 0000000000E6FFDBDB- <1>     db  000h, 000h, 000h, 000h, 000h, 0e6h, 0ffh, 0dbh, 0dbh, 0dbh, 0dbh, 0dbh, 000h, 000h, 000h, 000h
   588 000154D1 DBDBDB00000000      <1>
   589 000154D8 0000000000DC666666- <1>     db  000h, 000h, 000h, 000h, 000h, 0dch, 066h, 066h, 066h, 066h, 066h, 066h, 000h, 000h, 000h, 000h
   589 000154E1 66666600000000      <1>
   590 000154E8 00000000007CC6C6C6- <1>     db  000h, 000h, 000h, 000h, 000h, 07ch, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   590 000154F1 C6C67C00000000      <1>
   591 000154F8 0000000000DC666666- <1>     db  000h, 000h, 000h, 000h, 000h, 0dch, 066h, 066h, 066h, 066h, 066h, 07ch, 060h, 060h, 0f0h, 000h
   591 00015501 66667C6060F000      <1>
   592 00015508 000000000076CCCCCC- <1>     db  000h, 000h, 000h, 000h, 000h, 076h, 0cch, 0cch, 0cch, 0cch, 0cch, 07ch, 00ch, 00ch, 01eh, 000h
   592 00015511 CCCC7C0C0C1E00      <1>
   593 00015518 0000000000DC766660- <1>     db  000h, 000h, 000h, 000h, 000h, 0dch, 076h, 066h, 060h, 060h, 060h, 0f0h, 000h, 000h, 000h, 000h
   593 00015521 6060F000000000      <1>
   594 00015528 00000000007CC66038- <1>     db  000h, 000h, 000h, 000h, 000h, 07ch, 0c6h, 060h, 038h, 00ch, 0c6h, 07ch, 000h, 000h, 000h, 000h
   594 00015531 0CC67C00000000      <1>
   595 00015538 0000103030FC303030- <1>     db  000h, 000h, 010h, 030h, 030h, 0fch, 030h, 030h, 030h, 030h, 036h, 01ch, 000h, 000h, 000h, 000h
   595 00015541 30361C00000000      <1>
   596 00015548 0000000000CCCCCCCC- <1>     db  000h, 000h, 000h, 000h, 000h, 0cch, 0cch, 0cch, 0cch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h
   596 00015551 CCCC7600000000      <1>
   597 00015558 0000000000C3C3C3C3- <1>     db  000h, 000h, 000h, 000h, 000h, 0c3h, 0c3h, 0c3h, 0c3h, 066h, 03ch, 018h, 000h, 000h, 000h, 000h
   597 00015561 663C1800000000      <1>
   598 00015568 0000000000C3C3C3DB- <1>     db  000h, 000h, 000h, 000h, 000h, 0c3h, 0c3h, 0c3h, 0dbh, 0dbh, 0ffh, 066h, 000h, 000h, 000h, 000h
   598 00015571 DBFF6600000000      <1>
   599 00015578 0000000000C3663C18- <1>     db  000h, 000h, 000h, 000h, 000h, 0c3h, 066h, 03ch, 018h, 03ch, 066h, 0c3h, 000h, 000h, 000h, 000h
   599 00015581 3C66C300000000      <1>
   600 00015588 0000000000C6C6C6C6- <1>     db  000h, 000h, 000h, 000h, 000h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 07eh, 006h, 00ch, 0f8h, 000h
   600 00015591 C6C67E060CF800      <1>
   601 00015598 0000000000FECC1830- <1>     db  000h, 000h, 000h, 000h, 000h, 0feh, 0cch, 018h, 030h, 060h, 0c6h, 0feh, 000h, 000h, 000h, 000h
   601 000155A1 60C6FE00000000      <1>
   602 000155A8 00000E181818701818- <1>     db  000h, 000h, 00eh, 018h, 018h, 018h, 070h, 018h, 018h, 018h, 018h, 00eh, 000h, 000h, 000h, 000h
   602 000155B1 18180E00000000      <1>
   603 000155B8 000018181818001818- <1>     db  000h, 000h, 018h, 018h, 018h, 018h, 000h, 018h, 018h, 018h, 018h, 018h, 000h, 000h, 000h, 000h
   603 000155C1 18181800000000      <1>
   604 000155C8 0000701818180E1818- <1>     db  000h, 000h, 070h, 018h, 018h, 018h, 00eh, 018h, 018h, 018h, 018h, 070h, 000h, 000h, 000h, 000h
   604 000155D1 18187000000000      <1>
   605 000155D8 000076DC0000000000- <1>     db  000h, 000h, 076h, 0dch, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   605 000155E1 00000000000000      <1>
   606 000155E8 0000000010386CC6C6- <1>     db  000h, 000h, 000h, 000h, 010h, 038h, 06ch, 0c6h, 0c6h, 0c6h, 0feh, 000h, 000h, 000h, 000h, 000h
   606 000155F1 C6FE0000000000      <1>
   607 000155F8 00003C66C2C0C0C0C2- <1>     db  000h, 000h, 03ch, 066h, 0c2h, 0c0h, 0c0h, 0c0h, 0c2h, 066h, 03ch, 00ch, 006h, 07ch, 000h, 000h
   607 00015601 663C0C067C0000      <1>
   608 00015608 0000CC0000CCCCCCCC- <1>     db  000h, 000h, 0cch, 000h, 000h, 0cch, 0cch, 0cch, 0cch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h
   608 00015611 CCCC7600000000      <1>
   609 00015618 000C1830007CC6FEC0- <1>     db  000h, 00ch, 018h, 030h, 000h, 07ch, 0c6h, 0feh, 0c0h, 0c0h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   609 00015621 C0C67C00000000      <1>
   610 00015628 0010386C00780C7CCC- <1>     db  000h, 010h, 038h, 06ch, 000h, 078h, 00ch, 07ch, 0cch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h
   610 00015631 CCCC7600000000      <1>
   611 00015638 0000CC0000780C7CCC- <1>     db  000h, 000h, 0cch, 000h, 000h, 078h, 00ch, 07ch, 0cch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h
   611 00015641 CCCC7600000000      <1>
   612 00015648 0060301800780C7CCC- <1>     db  000h, 060h, 030h, 018h, 000h, 078h, 00ch, 07ch, 0cch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h
   612 00015651 CCCC7600000000      <1>
   613 00015658 00386C3800780C7CCC- <1>     db  000h, 038h, 06ch, 038h, 000h, 078h, 00ch, 07ch, 0cch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h
   613 00015661 CCCC7600000000      <1>
   614 00015668 000000003C66606066- <1>     db  000h, 000h, 000h, 000h, 03ch, 066h, 060h, 060h, 066h, 03ch, 00ch, 006h, 03ch, 000h, 000h, 000h
   614 00015671 3C0C063C000000      <1>
   615 00015678 0010386C007CC6FEC0- <1>     db  000h, 010h, 038h, 06ch, 000h, 07ch, 0c6h, 0feh, 0c0h, 0c0h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   615 00015681 C0C67C00000000      <1>
   616 00015688 0000C600007CC6FEC0- <1>     db  000h, 000h, 0c6h, 000h, 000h, 07ch, 0c6h, 0feh, 0c0h, 0c0h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   616 00015691 C0C67C00000000      <1>
   617 00015698 00603018007CC6FEC0- <1>     db  000h, 060h, 030h, 018h, 000h, 07ch, 0c6h, 0feh, 0c0h, 0c0h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   617 000156A1 C0C67C00000000      <1>
   618 000156A8 000066000038181818- <1>     db  000h, 000h, 066h, 000h, 000h, 038h, 018h, 018h, 018h, 018h, 018h, 03ch, 000h, 000h, 000h, 000h
   618 000156B1 18183C00000000      <1>
   619 000156B8 00183C660038181818- <1>     db  000h, 018h, 03ch, 066h, 000h, 038h, 018h, 018h, 018h, 018h, 018h, 03ch, 000h, 000h, 000h, 000h
   619 000156C1 18183C00000000      <1>
   620 000156C8 006030180038181818- <1>     db  000h, 060h, 030h, 018h, 000h, 038h, 018h, 018h, 018h, 018h, 018h, 03ch, 000h, 000h, 000h, 000h
   620 000156D1 18183C00000000      <1>
   621 000156D8 00C60010386CC6C6FE- <1>     db  000h, 0c6h, 000h, 010h, 038h, 06ch, 0c6h, 0c6h, 0feh, 0c6h, 0c6h, 0c6h, 000h, 000h, 000h, 000h
   621 000156E1 C6C6C600000000      <1>
   622 000156E8 386C3800386CC6C6FE- <1>     db  038h, 06ch, 038h, 000h, 038h, 06ch, 0c6h, 0c6h, 0feh, 0c6h, 0c6h, 0c6h, 000h, 000h, 000h, 000h
   622 000156F1 C6C6C600000000      <1>
   623 000156F8 18306000FE66607C60- <1>     db  018h, 030h, 060h, 000h, 0feh, 066h, 060h, 07ch, 060h, 060h, 066h, 0feh, 000h, 000h, 000h, 000h
   623 00015701 6066FE00000000      <1>
   624 00015708 00000000006E3B1B7E- <1>     db  000h, 000h, 000h, 000h, 000h, 06eh, 03bh, 01bh, 07eh, 0d8h, 0dch, 077h, 000h, 000h, 000h, 000h
   624 00015711 D8DC7700000000      <1>
   625 00015718 00003E6CCCCCFECCCC- <1>     db  000h, 000h, 03eh, 06ch, 0cch, 0cch, 0feh, 0cch, 0cch, 0cch, 0cch, 0ceh, 000h, 000h, 000h, 000h
   625 00015721 CCCCCE00000000      <1>
   626 00015728 0010386C007CC6C6C6- <1>     db  000h, 010h, 038h, 06ch, 000h, 07ch, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   626 00015731 C6C67C00000000      <1>
   627 00015738 0000C600007CC6C6C6- <1>     db  000h, 000h, 0c6h, 000h, 000h, 07ch, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   627 00015741 C6C67C00000000      <1>
   628 00015748 00603018007CC6C6C6- <1>     db  000h, 060h, 030h, 018h, 000h, 07ch, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   628 00015751 C6C67C00000000      <1>
   629 00015758 003078CC00CCCCCCCC- <1>     db  000h, 030h, 078h, 0cch, 000h, 0cch, 0cch, 0cch, 0cch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h
   629 00015761 CCCC7600000000      <1>
   630 00015768 0060301800CCCCCCCC- <1>     db  000h, 060h, 030h, 018h, 000h, 0cch, 0cch, 0cch, 0cch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h
   630 00015771 CCCC7600000000      <1>
   631 00015778 0000C60000C6C6C6C6- <1>     db  000h, 000h, 0c6h, 000h, 000h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 07eh, 006h, 00ch, 078h, 000h
   631 00015781 C6C67E060C7800      <1>
   632 00015788 00C6007CC6C6C6C6C6- <1>     db  000h, 0c6h, 000h, 07ch, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   632 00015791 C6C67C00000000      <1>
   633 00015798 00C600C6C6C6C6C6C6- <1>     db  000h, 0c6h, 000h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   633 000157A1 C6C67C00000000      <1>
   634 000157A8 0018187EC3C0C0C0C3- <1>     db  000h, 018h, 018h, 07eh, 0c3h, 0c0h, 0c0h, 0c0h, 0c3h, 07eh, 018h, 018h, 000h, 000h, 000h, 000h
   634 000157B1 7E181800000000      <1>
   635 000157B8 00386C6460F0606060- <1>     db  000h, 038h, 06ch, 064h, 060h, 0f0h, 060h, 060h, 060h, 060h, 0e6h, 0fch, 000h, 000h, 000h, 000h
   635 000157C1 60E6FC00000000      <1>
   636 000157C8 0000C3663C18FF18FF- <1>     db  000h, 000h, 0c3h, 066h, 03ch, 018h, 0ffh, 018h, 0ffh, 018h, 018h, 018h, 000h, 000h, 000h, 000h
   636 000157D1 18181800000000      <1>
   637 000157D8 00FC66667C62666F66- <1>     db  000h, 0fch, 066h, 066h, 07ch, 062h, 066h, 06fh, 066h, 066h, 066h, 0f3h, 000h, 000h, 000h, 000h
   637 000157E1 6666F300000000      <1>
   638 000157E8 000E1B1818187E1818- <1>     db  000h, 00eh, 01bh, 018h, 018h, 018h, 07eh, 018h, 018h, 018h, 018h, 018h, 0d8h, 070h, 000h, 000h
   638 000157F1 181818D8700000      <1>
   639 000157F8 0018306000780C7CCC- <1>     db  000h, 018h, 030h, 060h, 000h, 078h, 00ch, 07ch, 0cch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h
   639 00015801 CCCC7600000000      <1>
   640 00015808 000C18300038181818- <1>     db  000h, 00ch, 018h, 030h, 000h, 038h, 018h, 018h, 018h, 018h, 018h, 03ch, 000h, 000h, 000h, 000h
   640 00015811 18183C00000000      <1>
   641 00015818 00183060007CC6C6C6- <1>     db  000h, 018h, 030h, 060h, 000h, 07ch, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   641 00015821 C6C67C00000000      <1>
   642 00015828 0018306000CCCCCCCC- <1>     db  000h, 018h, 030h, 060h, 000h, 0cch, 0cch, 0cch, 0cch, 0cch, 0cch, 076h, 000h, 000h, 000h, 000h
   642 00015831 CCCC7600000000      <1>
   643 00015838 000076DC00DC666666- <1>     db  000h, 000h, 076h, 0dch, 000h, 0dch, 066h, 066h, 066h, 066h, 066h, 066h, 000h, 000h, 000h, 000h
   643 00015841 66666600000000      <1>
   644 00015848 76DC00C6E6F6FEDECE- <1>     db  076h, 0dch, 000h, 0c6h, 0e6h, 0f6h, 0feh, 0deh, 0ceh, 0c6h, 0c6h, 0c6h, 000h, 000h, 000h, 000h
   644 00015851 C6C6C600000000      <1>
   645 00015858 003C6C6C3E007E0000- <1>     db  000h, 03ch, 06ch, 06ch, 03eh, 000h, 07eh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   645 00015861 00000000000000      <1>
   646 00015868 00386C6C38007C0000- <1>     db  000h, 038h, 06ch, 06ch, 038h, 000h, 07ch, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   646 00015871 00000000000000      <1>
   647 00015878 0000303000303060C0- <1>     db  000h, 000h, 030h, 030h, 000h, 030h, 030h, 060h, 0c0h, 0c6h, 0c6h, 07ch, 000h, 000h, 000h, 000h
   647 00015881 C6C67C00000000      <1>
   648 00015888 000000000000FEC0C0- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 0feh, 0c0h, 0c0h, 0c0h, 0c0h, 000h, 000h, 000h, 000h, 000h
   648 00015891 C0C00000000000      <1>
   649 00015898 000000000000FE0606- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 0feh, 006h, 006h, 006h, 006h, 000h, 000h, 000h, 000h, 000h
   649 000158A1 06060000000000      <1>
   650 000158A8 00C0C0C2C6CC183060- <1>     db  000h, 0c0h, 0c0h, 0c2h, 0c6h, 0cch, 018h, 030h, 060h, 0ceh, 09bh, 006h, 00ch, 01fh, 000h, 000h
   650 000158B1 CE9B060C1F0000      <1>
   651 000158B8 00C0C0C2C6CC183066- <1>     db  000h, 0c0h, 0c0h, 0c2h, 0c6h, 0cch, 018h, 030h, 066h, 0ceh, 096h, 03eh, 006h, 006h, 000h, 000h
   651 000158C1 CE963E06060000      <1>
   652 000158C8 00001818001818183C- <1>     db  000h, 000h, 018h, 018h, 000h, 018h, 018h, 018h, 03ch, 03ch, 03ch, 018h, 000h, 000h, 000h, 000h
   652 000158D1 3C3C1800000000      <1>
   653 000158D8 0000000000366CD86C- <1>     db  000h, 000h, 000h, 000h, 000h, 036h, 06ch, 0d8h, 06ch, 036h, 000h, 000h, 000h, 000h, 000h, 000h
   653 000158E1 36000000000000      <1>
   654 000158E8 0000000000D86C366C- <1>     db  000h, 000h, 000h, 000h, 000h, 0d8h, 06ch, 036h, 06ch, 0d8h, 000h, 000h, 000h, 000h, 000h, 000h
   654 000158F1 D8000000000000      <1>
   655 000158F8 114411441144114411- <1>     db  011h, 044h, 011h, 044h, 011h, 044h, 011h, 044h, 011h, 044h, 011h, 044h, 011h, 044h, 011h, 044h
   655 00015901 44114411441144      <1>
   656 00015908 55AA55AA55AA55AA55- <1>     db  055h, 0aah, 055h, 0aah, 055h, 0aah, 055h, 0aah, 055h, 0aah, 055h, 0aah, 055h, 0aah, 055h, 0aah
   656 00015911 AA55AA55AA55AA      <1>
   657 00015918 DD77DD77DD77DD77DD- <1>     db  0ddh, 077h, 0ddh, 077h, 0ddh, 077h, 0ddh, 077h, 0ddh, 077h, 0ddh, 077h, 0ddh, 077h, 0ddh, 077h
   657 00015921 77DD77DD77DD77      <1>
   658 00015928 181818181818181818- <1>     db  018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h
   658 00015931 18181818181818      <1>
   659 00015938 18181818181818F818- <1>     db  018h, 018h, 018h, 018h, 018h, 018h, 018h, 0f8h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h
   659 00015941 18181818181818      <1>
   660 00015948 1818181818F818F818- <1>     db  018h, 018h, 018h, 018h, 018h, 0f8h, 018h, 0f8h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h
   660 00015951 18181818181818      <1>
   661 00015958 36363636363636F636- <1>     db  036h, 036h, 036h, 036h, 036h, 036h, 036h, 0f6h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h
   661 00015961 36363636363636      <1>
   662 00015968 00000000000000FE36- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 0feh, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h
   662 00015971 36363636363636      <1>
   663 00015978 0000000000F818F818- <1>     db  000h, 000h, 000h, 000h, 000h, 0f8h, 018h, 0f8h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h
   663 00015981 18181818181818      <1>
   664 00015988 3636363636F606F636- <1>     db  036h, 036h, 036h, 036h, 036h, 0f6h, 006h, 0f6h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h
   664 00015991 36363636363636      <1>
   665 00015998 363636363636363636- <1>     db  036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h
   665 000159A1 36363636363636      <1>
   666 000159A8 0000000000FE06F636- <1>     db  000h, 000h, 000h, 000h, 000h, 0feh, 006h, 0f6h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h
   666 000159B1 36363636363636      <1>
   667 000159B8 3636363636F606FE00- <1>     db  036h, 036h, 036h, 036h, 036h, 0f6h, 006h, 0feh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   667 000159C1 00000000000000      <1>
   668 000159C8 36363636363636FE00- <1>     db  036h, 036h, 036h, 036h, 036h, 036h, 036h, 0feh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   668 000159D1 00000000000000      <1>
   669 000159D8 1818181818F818F800- <1>     db  018h, 018h, 018h, 018h, 018h, 0f8h, 018h, 0f8h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   669 000159E1 00000000000000      <1>
   670 000159E8 00000000000000F818- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 0f8h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h
   670 000159F1 18181818181818      <1>
   671 000159F8 181818181818181F00- <1>     db  018h, 018h, 018h, 018h, 018h, 018h, 018h, 01fh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   671 00015A01 00000000000000      <1>
   672 00015A08 18181818181818FF00- <1>     db  018h, 018h, 018h, 018h, 018h, 018h, 018h, 0ffh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   672 00015A11 00000000000000      <1>
   673 00015A18 00000000000000FF18- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 0ffh, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h
   673 00015A21 18181818181818      <1>
   674 00015A28 181818181818181F18- <1>     db  018h, 018h, 018h, 018h, 018h, 018h, 018h, 01fh, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h
   674 00015A31 18181818181818      <1>
   675 00015A38 00000000000000FF00- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 0ffh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   675 00015A41 00000000000000      <1>
   676 00015A48 18181818181818FF18- <1>     db  018h, 018h, 018h, 018h, 018h, 018h, 018h, 0ffh, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h
   676 00015A51 18181818181818      <1>
   677 00015A58 18181818181F181F18- <1>     db  018h, 018h, 018h, 018h, 018h, 01fh, 018h, 01fh, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h
   677 00015A61 18181818181818      <1>
   678 00015A68 363636363636363736- <1>     db  036h, 036h, 036h, 036h, 036h, 036h, 036h, 037h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h
   678 00015A71 36363636363636      <1>
   679 00015A78 363636363637303F00- <1>     db  036h, 036h, 036h, 036h, 036h, 037h, 030h, 03fh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   679 00015A81 00000000000000      <1>
   680 00015A88 00000000003F303736- <1>     db  000h, 000h, 000h, 000h, 000h, 03fh, 030h, 037h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h
   680 00015A91 36363636363636      <1>
   681 00015A98 3636363636F700FF00- <1>     db  036h, 036h, 036h, 036h, 036h, 0f7h, 000h, 0ffh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   681 00015AA1 00000000000000      <1>
   682 00015AA8 0000000000FF00F736- <1>     db  000h, 000h, 000h, 000h, 000h, 0ffh, 000h, 0f7h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h
   682 00015AB1 36363636363636      <1>
   683 00015AB8 363636363637303736- <1>     db  036h, 036h, 036h, 036h, 036h, 037h, 030h, 037h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h
   683 00015AC1 36363636363636      <1>
   684 00015AC8 0000000000FF00FF00- <1>     db  000h, 000h, 000h, 000h, 000h, 0ffh, 000h, 0ffh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   684 00015AD1 00000000000000      <1>
   685 00015AD8 3636363636F700F736- <1>     db  036h, 036h, 036h, 036h, 036h, 0f7h, 000h, 0f7h, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h
   685 00015AE1 36363636363636      <1>
   686 00015AE8 1818181818FF00FF00- <1>     db  018h, 018h, 018h, 018h, 018h, 0ffh, 000h, 0ffh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   686 00015AF1 00000000000000      <1>
   687 00015AF8 36363636363636FF00- <1>     db  036h, 036h, 036h, 036h, 036h, 036h, 036h, 0ffh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   687 00015B01 00000000000000      <1>
   688 00015B08 0000000000FF00FF18- <1>     db  000h, 000h, 000h, 000h, 000h, 0ffh, 000h, 0ffh, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h
   688 00015B11 18181818181818      <1>
   689 00015B18 00000000000000FF36- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 0ffh, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h
   689 00015B21 36363636363636      <1>
   690 00015B28 363636363636363F00- <1>     db  036h, 036h, 036h, 036h, 036h, 036h, 036h, 03fh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   690 00015B31 00000000000000      <1>
   691 00015B38 18181818181F181F00- <1>     db  018h, 018h, 018h, 018h, 018h, 01fh, 018h, 01fh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   691 00015B41 00000000000000      <1>
   692 00015B48 00000000001F181F18- <1>     db  000h, 000h, 000h, 000h, 000h, 01fh, 018h, 01fh, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h
   692 00015B51 18181818181818      <1>
   693 00015B58 000000000000003F36- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 03fh, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h
   693 00015B61 36363636363636      <1>
   694 00015B68 36363636363636FF36- <1>     db  036h, 036h, 036h, 036h, 036h, 036h, 036h, 0ffh, 036h, 036h, 036h, 036h, 036h, 036h, 036h, 036h
   694 00015B71 36363636363636      <1>
   695 00015B78 1818181818FF18FF18- <1>     db  018h, 018h, 018h, 018h, 018h, 0ffh, 018h, 0ffh, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h
   695 00015B81 18181818181818      <1>
   696 00015B88 18181818181818F800- <1>     db  018h, 018h, 018h, 018h, 018h, 018h, 018h, 0f8h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   696 00015B91 00000000000000      <1>
   697 00015B98 000000000000001F18- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 01fh, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h
   697 00015BA1 18181818181818      <1>
   698 00015BA8 FFFFFFFFFFFFFFFFFF- <1>     db  0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
   698 00015BB1 FFFFFFFFFFFFFF      <1>
   699 00015BB8 00000000000000FFFF- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh
   699 00015BC1 FFFFFFFFFFFFFF      <1>
   700 00015BC8 F0F0F0F0F0F0F0F0F0- <1>     db  0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h, 0f0h
   700 00015BD1 F0F0F0F0F0F0F0      <1>
   701 00015BD8 0F0F0F0F0F0F0F0F0F- <1>     db  00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh, 00fh
   701 00015BE1 0F0F0F0F0F0F0F      <1>
   702 00015BE8 FFFFFFFFFFFFFF0000- <1>     db  0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 0ffh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   702 00015BF1 00000000000000      <1>
   703 00015BF8 000000000076DCD8D8- <1>     db  000h, 000h, 000h, 000h, 000h, 076h, 0dch, 0d8h, 0d8h, 0d8h, 0dch, 076h, 000h, 000h, 000h, 000h
   703 00015C01 D8DC7600000000      <1>
   704 00015C08 000078CCCCCCD8CCC6- <1>     db  000h, 000h, 078h, 0cch, 0cch, 0cch, 0d8h, 0cch, 0c6h, 0c6h, 0c6h, 0cch, 000h, 000h, 000h, 000h
   704 00015C11 C6C6CC00000000      <1>
   705 00015C18 0000FEC6C6C0C0C0C0- <1>     db  000h, 000h, 0feh, 0c6h, 0c6h, 0c0h, 0c0h, 0c0h, 0c0h, 0c0h, 0c0h, 0c0h, 000h, 000h, 000h, 000h
   705 00015C21 C0C0C000000000      <1>
   706 00015C28 00000000FE6C6C6C6C- <1>     db  000h, 000h, 000h, 000h, 0feh, 06ch, 06ch, 06ch, 06ch, 06ch, 06ch, 06ch, 000h, 000h, 000h, 000h
   706 00015C31 6C6C6C00000000      <1>
   707 00015C38 000000FEC660301830- <1>     db  000h, 000h, 000h, 0feh, 0c6h, 060h, 030h, 018h, 030h, 060h, 0c6h, 0feh, 000h, 000h, 000h, 000h
   707 00015C41 60C6FE00000000      <1>
   708 00015C48 00000000007ED8D8D8- <1>     db  000h, 000h, 000h, 000h, 000h, 07eh, 0d8h, 0d8h, 0d8h, 0d8h, 0d8h, 070h, 000h, 000h, 000h, 000h
   708 00015C51 D8D87000000000      <1>
   709 00015C58 000000006666666666- <1>     db  000h, 000h, 000h, 000h, 066h, 066h, 066h, 066h, 066h, 07ch, 060h, 060h, 0c0h, 000h, 000h, 000h
   709 00015C61 7C6060C0000000      <1>
   710 00015C68 0000000076DC181818- <1>     db  000h, 000h, 000h, 000h, 076h, 0dch, 018h, 018h, 018h, 018h, 018h, 018h, 000h, 000h, 000h, 000h
   710 00015C71 18181800000000      <1>
   711 00015C78 0000007E183C666666- <1>     db  000h, 000h, 000h, 07eh, 018h, 03ch, 066h, 066h, 066h, 03ch, 018h, 07eh, 000h, 000h, 000h, 000h
   711 00015C81 3C187E00000000      <1>
   712 00015C88 000000386CC6C6FEC6- <1>     db  000h, 000h, 000h, 038h, 06ch, 0c6h, 0c6h, 0feh, 0c6h, 0c6h, 06ch, 038h, 000h, 000h, 000h, 000h
   712 00015C91 C66C3800000000      <1>
   713 00015C98 0000386CC6C6C66C6C- <1>     db  000h, 000h, 038h, 06ch, 0c6h, 0c6h, 0c6h, 06ch, 06ch, 06ch, 06ch, 0eeh, 000h, 000h, 000h, 000h
   713 00015CA1 6C6CEE00000000      <1>
   714 00015CA8 00001E30180C3E6666- <1>     db  000h, 000h, 01eh, 030h, 018h, 00ch, 03eh, 066h, 066h, 066h, 066h, 03ch, 000h, 000h, 000h, 000h
   714 00015CB1 66663C00000000      <1>
   715 00015CB8 00000000007EDBDBDB- <1>     db  000h, 000h, 000h, 000h, 000h, 07eh, 0dbh, 0dbh, 0dbh, 07eh, 000h, 000h, 000h, 000h, 000h, 000h
   715 00015CC1 7E000000000000      <1>
   716 00015CC8 00000003067EDBDBF3- <1>     db  000h, 000h, 000h, 003h, 006h, 07eh, 0dbh, 0dbh, 0f3h, 07eh, 060h, 0c0h, 000h, 000h, 000h, 000h
   716 00015CD1 7E60C000000000      <1>
   717 00015CD8 00001C3060607C6060- <1>     db  000h, 000h, 01ch, 030h, 060h, 060h, 07ch, 060h, 060h, 060h, 030h, 01ch, 000h, 000h, 000h, 000h
   717 00015CE1 60301C00000000      <1>
   718 00015CE8 0000007CC6C6C6C6C6- <1>     db  000h, 000h, 000h, 07ch, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 0c6h, 000h, 000h, 000h, 000h
   718 00015CF1 C6C6C600000000      <1>
   719 00015CF8 00000000FE0000FE00- <1>     db  000h, 000h, 000h, 000h, 0feh, 000h, 000h, 0feh, 000h, 000h, 0feh, 000h, 000h, 000h, 000h, 000h
   719 00015D01 00FE0000000000      <1>
   720 00015D08 0000000018187E1818- <1>     db  000h, 000h, 000h, 000h, 018h, 018h, 07eh, 018h, 018h, 000h, 000h, 0ffh, 000h, 000h, 000h, 000h
   720 00015D11 0000FF00000000      <1>
   721 00015D18 00000030180C060C18- <1>     db  000h, 000h, 000h, 030h, 018h, 00ch, 006h, 00ch, 018h, 030h, 000h, 07eh, 000h, 000h, 000h, 000h
   721 00015D21 30007E00000000      <1>
   722 00015D28 0000000C1830603018- <1>     db  000h, 000h, 000h, 00ch, 018h, 030h, 060h, 030h, 018h, 00ch, 000h, 07eh, 000h, 000h, 000h, 000h
   722 00015D31 0C007E00000000      <1>
   723 00015D38 00000E1B1B18181818- <1>     db  000h, 000h, 00eh, 01bh, 01bh, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h
   723 00015D41 18181818181818      <1>
   724 00015D48 1818181818181818D8- <1>     db  018h, 018h, 018h, 018h, 018h, 018h, 018h, 018h, 0d8h, 0d8h, 0d8h, 070h, 000h, 000h, 000h, 000h
   724 00015D51 D8D87000000000      <1>
   725 00015D58 000000001818007E00- <1>     db  000h, 000h, 000h, 000h, 018h, 018h, 000h, 07eh, 000h, 018h, 018h, 000h, 000h, 000h, 000h, 000h
   725 00015D61 18180000000000      <1>
   726 00015D68 000000000076DC0076- <1>     db  000h, 000h, 000h, 000h, 000h, 076h, 0dch, 000h, 076h, 0dch, 000h, 000h, 000h, 000h, 000h, 000h
   726 00015D71 DC000000000000      <1>
   727 00015D78 00386C6C3800000000- <1>     db  000h, 038h, 06ch, 06ch, 038h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   727 00015D81 00000000000000      <1>
   728 00015D88 000000000000001818- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 018h, 018h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   728 00015D91 00000000000000      <1>
   729 00015D98 000000000000000018- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 018h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   729 00015DA1 00000000000000      <1>
   730 00015DA8 000F0C0C0C0C0CEC6C- <1>     db  000h, 00fh, 00ch, 00ch, 00ch, 00ch, 00ch, 0ech, 06ch, 06ch, 03ch, 01ch, 000h, 000h, 000h, 000h
   730 00015DB1 6C3C1C00000000      <1>
   731 00015DB8 00D86C6C6C6C6C0000- <1>     db  000h, 0d8h, 06ch, 06ch, 06ch, 06ch, 06ch, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   731 00015DC1 00000000000000      <1>
   732 00015DC8 0070D83060C8F80000- <1>     db  000h, 070h, 0d8h, 030h, 060h, 0c8h, 0f8h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   732 00015DD1 00000000000000      <1>
   733 00015DD8 000000007C7C7C7C7C- <1>     db  000h, 000h, 000h, 000h, 07ch, 07ch, 07ch, 07ch, 07ch, 07ch, 07ch, 000h, 000h, 000h, 000h, 000h
   733 00015DE1 7C7C0000000000      <1>
   734 00015DE8 000000000000000000- <1>     db  000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
   734 00015DF1 00000000000000      <1>
   735                              <1> vgafont14alt:
   736 00015DF8 1D000000002466FF66- <1>     db  01dh, 000h, 000h, 000h, 000h, 024h, 066h, 0ffh, 066h, 024h, 000h, 000h, 000h, 000h, 000h, 022h
   736 00015E01 24000000000022      <1>
   737 00015E08 006363632200000000- <1>     db  000h, 063h, 063h, 063h, 022h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 02bh, 000h
   737 00015E11 00000000002B00      <1>
   738 00015E18 0000181818FF181818- <1>     db  000h, 000h, 018h, 018h, 018h, 0ffh, 018h, 018h, 018h, 000h, 000h, 000h, 000h, 02dh, 000h, 000h
   738 00015E21 000000002D0000      <1>
   739 00015E28 00000000FF00000000- <1>     db  000h, 000h, 000h, 000h, 0ffh, 000h, 000h, 000h, 000h, 000h, 000h, 000h, 04dh, 000h, 000h, 0c3h
   739 00015E31 0000004D0000C3      <1>
   740 00015E38 E7FFDBC3C3C3C3C300- <1>     db  0e7h, 0ffh, 0dbh, 0c3h, 0c3h, 0c3h, 0c3h, 0c3h, 000h, 000h, 000h, 054h, 000h, 000h, 0ffh, 0dbh
   740 00015E41 0000540000FFDB      <1>
   741 00015E48 9918181818183C0000- <1>     db  099h, 018h, 018h, 018h, 018h, 018h, 03ch, 000h, 000h, 000h, 056h, 000h, 000h, 0c3h, 0c3h, 0c3h
   741 00015E51 00560000C3C3C3      <1>
   742 00015E58 C3C3C3663C18000000- <1>     db  0c3h, 0c3h, 0c3h, 066h, 03ch, 018h, 000h, 000h, 000h, 057h, 000h, 000h, 0c3h, 0c3h, 0c3h, 0c3h
   742 00015E61 570000C3C3C3C3      <1>
   743 00015E68 DBDBFF666600000058- <1>     db  0dbh, 0dbh, 0ffh, 066h, 066h, 000h, 000h, 000h, 058h, 000h, 000h, 0c3h, 0c3h, 066h, 03ch, 018h
   743 00015E71 0000C3C3663C18      <1>
   744 00015E78 3C66C3C30000005900- <1>     db  03ch, 066h, 0c3h, 0c3h, 000h, 000h, 000h, 059h, 000h, 000h, 0c3h, 0c3h, 0c3h, 066h, 03ch, 018h
   744 00015E81 00C3C3C3663C18      <1>
   745 00015E88 18183C0000005A0000- <1>     db  018h, 018h, 03ch, 000h, 000h, 000h, 05ah, 000h, 000h, 0ffh, 0c3h, 086h, 00ch, 018h, 030h, 061h
   745 00015E91 FFC3860C183061      <1>
   746 00015E98 C3FF0000006D000000- <1>     db  0c3h, 0ffh, 000h, 000h, 000h, 06dh, 000h, 000h, 000h, 000h, 000h, 0e6h, 0ffh, 0dbh, 0dbh, 0dbh
   746 00015EA1 0000E6FFDBDBDB      <1>
   747 00015EA8 DB0000007600000000- <1>     db  0dbh, 000h, 000h, 000h, 076h, 000h, 000h, 000h, 000h, 000h, 0c3h, 0c3h, 0c3h, 066h, 03ch, 018h
   747 00015EB1 00C3C3C3663C18      <1>
   748 00015EB8 000000770000000000- <1>     db  000h, 000h, 000h, 077h, 000h, 000h, 000h, 000h, 000h, 0c3h, 0c3h, 0dbh, 0dbh, 0ffh, 066h, 000h
   748 00015EC1 C3C3DBDBFF6600      <1>
   749 00015EC8 000091000000006E3B- <1>     db  000h, 000h, 091h, 000h, 000h, 000h, 000h, 06eh, 03bh, 01bh, 07eh, 0d8h, 0dch, 077h, 000h, 000h
   749 00015ED1 1B7ED8DC770000      <1>
   750 00015ED8 009B0018187EC3C0C0- <1>     db  000h, 09bh, 000h, 018h, 018h, 07eh, 0c3h, 0c0h, 0c0h, 0c3h, 07eh, 018h, 018h, 000h, 000h, 000h
   750 00015EE1 C37E1818000000      <1>
   751 00015EE8 9D0000C3663C18FF18- <1>     db  09dh, 000h, 000h, 0c3h, 066h, 03ch, 018h, 0ffh, 018h, 0ffh, 018h, 018h, 000h, 000h, 000h, 09eh
   751 00015EF1 FF18180000009E      <1>
   752 00015EF8 00FC66667C62666F66- <1>     db  000h, 0fch, 066h, 066h, 07ch, 062h, 066h, 06fh, 066h, 066h, 0f3h, 000h, 000h, 000h, 0f1h, 000h
   752 00015F01 66F3000000F100      <1>
   753 00015F08 00181818FF18181800- <1>     db  000h, 018h, 018h, 018h, 0ffh, 018h, 018h, 018h, 000h, 0ffh, 000h, 000h, 000h, 0f6h, 000h, 000h
   753 00015F11 FF000000F60000      <1>
   754 00015F18 18180000FF00001818- <1>     db  018h, 018h, 000h, 000h, 0ffh, 000h, 000h, 018h, 018h, 000h, 000h, 000h, 000h
   754 00015F21 00000000            <1>
   755                              <1> vgafont16alt:
   756 00015F25 1D00000000002466FF- <1>     db  01dh, 000h, 000h, 000h, 000h, 000h, 024h, 066h, 0ffh, 066h, 024h, 000h, 000h, 000h, 000h, 000h
   756 00015F2E 66240000000000      <1>
   757 00015F35 003000003C66C3C3DB- <1>     db  000h, 030h, 000h, 000h, 03ch, 066h, 0c3h, 0c3h, 0dbh, 0dbh, 0c3h, 0c3h, 066h, 03ch, 000h, 000h
   757 00015F3E DBC3C3663C0000      <1>
   758 00015F45 00004D0000C3E7FFFF- <1>     db  000h, 000h, 04dh, 000h, 000h, 0c3h, 0e7h, 0ffh, 0ffh, 0dbh, 0c3h, 0c3h, 0c3h, 0c3h, 0c3h, 000h
   758 00015F4E DBC3C3C3C3C300      <1>
   759 00015F55 000000540000FFDB99- <1>     db  000h, 000h, 000h, 054h, 000h, 000h, 0ffh, 0dbh, 099h, 018h, 018h, 018h, 018h, 018h, 018h, 03ch
   759 00015F5E 1818181818183C      <1>
   760 00015F65 00000000560000C3C3- <1>     db  000h, 000h, 000h, 000h, 056h, 000h, 000h, 0c3h, 0c3h, 0c3h, 0c3h, 0c3h, 0c3h, 0c3h, 066h, 03ch
   760 00015F6E C3C3C3C3C3663C      <1>
   761 00015F75 1800000000570000C3- <1>     db  018h, 000h, 000h, 000h, 000h, 057h, 000h, 000h, 0c3h, 0c3h, 0c3h, 0c3h, 0c3h, 0dbh, 0dbh, 0ffh
   761 00015F7E C3C3C3C3DBDBFF      <1>
   762 00015F85 666600000000580000- <1>     db  066h, 066h, 000h, 000h, 000h, 000h, 058h, 000h, 000h, 0c3h, 0c3h, 066h, 03ch, 018h, 018h, 03ch
   762 00015F8E C3C3663C18183C      <1>
   763 00015F95 66C3C3000000005900- <1>     db  066h, 0c3h, 0c3h, 000h, 000h, 000h, 000h, 059h, 000h, 000h, 0c3h, 0c3h, 0c3h, 066h, 03ch, 018h
   763 00015F9E 00C3C3C3663C18      <1>
   764 00015FA5 1818183C000000005A- <1>     db  018h, 018h, 018h, 03ch, 000h, 000h, 000h, 000h, 05ah, 000h, 000h, 0ffh, 0c3h, 086h, 00ch, 018h
   764 00015FAE 0000FFC3860C18      <1>
   765 00015FB5 3060C1C3FF00000000- <1>     db  030h, 060h, 0c1h, 0c3h, 0ffh, 000h, 000h, 000h, 000h, 06dh, 000h, 000h, 000h, 000h, 000h, 0e6h
   765 00015FBE 6D0000000000E6      <1>
   766 00015FC5 FFDBDBDBDBDB000000- <1>     db  0ffh, 0dbh, 0dbh, 0dbh, 0dbh, 0dbh, 000h, 000h, 000h, 000h, 076h, 000h, 000h, 000h, 000h, 000h
   766 00015FCE 00760000000000      <1>
   767 00015FD5 C3C3C3C3663C180000- <1>     db  0c3h, 0c3h, 0c3h, 0c3h, 066h, 03ch, 018h, 000h, 000h, 000h, 000h, 077h, 000h, 000h, 000h, 000h
   767 00015FDE 00007700000000      <1>
   768 00015FE5 00C3C3C3DBDBFF6600- <1>     db  000h, 0c3h, 0c3h, 0c3h, 0dbh, 0dbh, 0ffh, 066h, 000h, 000h, 000h, 000h, 078h, 000h, 000h, 000h
   768 00015FEE 00000078000000      <1>
   769 00015FF5 0000C3663C183C66C3- <1>     db  000h, 000h, 0c3h, 066h, 03ch, 018h, 03ch, 066h, 0c3h, 000h, 000h, 000h, 000h, 091h, 000h, 000h
   769 00015FFE 00000000910000      <1>
   770 00016005 0000006E3B1B7ED8DC- <1>     db  000h, 000h, 000h, 06eh, 03bh, 01bh, 07eh, 0d8h, 0dch, 077h, 000h, 000h, 000h, 000h, 09bh, 000h
   770 0001600E 77000000009B00      <1>
   771 00016015 18187EC3C0C0C0C37E- <1>     db  018h, 018h, 07eh, 0c3h, 0c0h, 0c0h, 0c0h, 0c3h, 07eh, 018h, 018h, 000h, 000h, 000h, 000h, 09dh
   771 0001601E 1818000000009D      <1>
   772 00016025 0000C3663C18FF18FF- <1>     db  000h, 000h, 0c3h, 066h, 03ch, 018h, 0ffh, 018h, 0ffh, 018h, 018h, 018h, 000h, 000h, 000h, 000h
   772 0001602E 18181800000000      <1>
   773 00016035 9E00FC66667C62666F- <1>     db  09eh, 000h, 0fch, 066h, 066h, 07ch, 062h, 066h, 06fh, 066h, 066h, 066h, 0f3h, 000h, 000h, 000h
   773 0001603E 666666F3000000      <1>
   774 00016045 00AB00C0C0C2C6CC18- <1>     db  000h, 0abh, 000h, 0c0h, 0c0h, 0c2h, 0c6h, 0cch, 018h, 030h, 060h, 0ceh, 09bh, 006h, 00ch, 01fh
   774 0001604E 3060CE9B060C1F      <1>
   775 00016055 0000AC00C0C0C2C6CC- <1>     db  000h, 000h, 0ach, 000h, 0c0h, 0c0h, 0c2h, 0c6h, 0cch, 018h, 030h, 066h, 0ceh, 096h, 03eh, 006h
   775 0001605E 183066CE963E06      <1>
   776 00016065 06000000            <1>     db  006h, 000h, 000h, 000h
  3380                                  
  3381                                  ; 20/11/2020
  3382                                  vbe2_bochs_vbios:
  3383                                  ;	db "BOCHS/QEMU"
  3384 00016069 424F4348532F51454D-     	db "BOCHS/QEMU/VIRTUALBOX"  ; 26/11/2020
  3384 00016072 552F5649525455414C-
  3384 0001607B 424F58             
  3385                                  ;vbe_vnumber equ vbe2_bochs_vbios + 28 ; "3" or "2"
  3386                                  ; 26/11/2020
  3387                                  vbe_vnumber equ vbe2_bochs_vbios + 30 ; "3" or "2"
  3388                                  ; 15/11/2020
  3389                                  vesa_vbe3_bios_msg:
  3390                                  	;db " VESA VBE version 3 Video BIOS ..."
  3391 0001607E 205645534120564245-     	db " VESA VBE3 Video BIOS ..." ; 26/11/2020
  3391 00016087 3320566964656F2042-
  3391 00016090 494F53202E2E2E     
  3392 00016097 0D0A0D0A00              	db 0Dh, 0Ah, 0Dh, 0Ah, 0
  3393                                  
  3394                                  align 2
  3395                                  
  3396                                  ; EPOCH Variables
  3397                                  ; 13/04/2015 - Retro UNIX 386 v1 Beginning
  3398                                  ; 09/04/2013 epoch variables
  3399                                  ; Retro UNIX 8086 v1 Prototype: UNIXCOPY.ASM, 10/03/2013
  3400                                  ;
  3401 0001609C B207                    year: 	dw 1970
  3402 0001609E 0100                    month: 	dw 1
  3403 000160A0 0100                    day: 	dw 1
  3404 000160A2 0000                    hour: 	dw 0
  3405 000160A4 0000                    minute: dw 0
  3406 000160A6 0000                    second: dw 0
  3407                                  
  3408                                  DMonth:
  3409 000160A8 0000                    	dw 0
  3410 000160AA 1F00                    	dw 31
  3411 000160AC 3B00                    	dw 59
  3412 000160AE 5A00                    	dw 90
  3413 000160B0 7800                    	dw 120
  3414 000160B2 9700                    	dw 151
  3415 000160B4 B500                    	dw 181
  3416 000160B6 D400                    	dw 212
  3417 000160B8 F300                    	dw 243
  3418 000160BA 1101                    	dw 273
  3419 000160BC 3001                    	dw 304
  3420 000160BE 4E01                    	dw 334
  3421                                  
  3422                                  ; 15/11/2020
  3423 000160C0 00                      db	0
  3424                                  kernel_version_msg: ; 20/11/2020
  3425 000160C1 5452444F5320283338-     db	"TRDOS (386) Kernel v2.0.3 by Erdogan Tan"
  3425 000160CA 3629204B65726E656C-
  3425 000160D3 2076322E302E332062-
  3425 000160DC 79204572646F67616E-
  3425 000160E5 2054616E           
  3426 000160E9 00                      db	0
  3427                                  
  3428                                  ; 20/02/2017
  3429                                  KERNELFSIZE  equ $  ; 04/07/2016
  3430                                  
  3431                                  bss_start:
  3432                                  
  3433                                  ABSOLUTE bss_start
  3434                                  
  3435 000160EA <res 00000006>          alignb 8 ; 25/12/2016
  3436                                  
  3437                                  	; 15/04/2016
  3438                                  	; TRDOS 386 (TRDOS v2.0)
  3439                                  	; 	80 interrupts 	
  3440                                  	; 11/03/2015
  3441                                  	; Interrupt Descriptor Table (20/08/2014)
  3442                                  idt:
  3443                                  	;resb	64*8 ; INT 0 to INT 3Fh
  3444                                  	; 15/04/2016
  3445 000160F0 <res 00000280>          	resb	80*8 ; INT 0 to INT 4Fh
  3446                                  
  3447                                  idt_end:
  3448                                  
  3449                                  ;alignb 4
  3450                                  
  3451                                  task_state_segment:
  3452                                  	; 24/03/2015
  3453 00016370 <res 00000002>          tss.link:   resw 1
  3454 00016372 <res 00000002>          	    resw 1
  3455                                  ; tss offset 4	
  3456 00016374 <res 00000004>          tss.esp0:   resd 1
  3457 00016378 <res 00000002>          tss.ss0:    resw 1
  3458 0001637A <res 00000002>          	    resw 1	
  3459 0001637C <res 00000004>          tss.esp1:   resd 1
  3460 00016380 <res 00000002>          tss.ss1:    resw 1
  3461 00016382 <res 00000002>          	    resw 1 	
  3462 00016384 <res 00000004>          tss.esp2:   resd 1
  3463 00016388 <res 00000002>          tss.ss2:    resw 1
  3464 0001638A <res 00000002>          	    resw 1
  3465                                  ; tss offset 28
  3466 0001638C <res 00000004>          tss.CR3:    resd 1
  3467 00016390 <res 00000004>          tss.eip:    resd 1
  3468 00016394 <res 00000004>          tss.eflags: resd 1
  3469                                  ; tss offset 40
  3470 00016398 <res 00000004>          tss.eax:    resd 1		 		
  3471 0001639C <res 00000004>          tss.ecx:    resd 1
  3472 000163A0 <res 00000004>          tss.edx:    resd 1
  3473 000163A4 <res 00000004>          tss.ebx:    resd 1
  3474 000163A8 <res 00000004>          tss.esp:    resd 1
  3475 000163AC <res 00000004>          tss.ebp:    resd 1
  3476 000163B0 <res 00000004>          tss.esi:    resd 1
  3477 000163B4 <res 00000004>          tss.edi:    resd 1
  3478                                  ; tss offset 72
  3479 000163B8 <res 00000002>          tss.ES:     resw 1
  3480 000163BA <res 00000002>          	    resw 1	
  3481 000163BC <res 00000002>          tss.CS:	    resw 1
  3482 000163BE <res 00000002>          	    resw 1
  3483 000163C0 <res 00000002>          tss.SS:	    resw 1
  3484 000163C2 <res 00000002>          	    resw 1
  3485 000163C4 <res 00000002>          tss.DS:	    resw 1
  3486 000163C6 <res 00000002>          	    resw 1
  3487 000163C8 <res 00000002>          tss.FS:	    resw 1
  3488 000163CA <res 00000002>          	    resw 1
  3489 000163CC <res 00000002>          tss.GS:	    resw 1
  3490 000163CE <res 00000002>          	    resw 1		
  3491 000163D0 <res 00000002>          tss.LDTR:   resw 1
  3492 000163D2 <res 00000002>          	    resw 1
  3493                                  ; tss offset 100		
  3494 000163D4 <res 00000002>          	    resw 1		
  3495 000163D6 <res 00000002>          tss.IOPB:   resw 1
  3496                                  ; tss offset 104 
  3497                                  tss_end:
  3498                                  
  3499 000163D8 <res 00000004>          k_page_dir:  resd 1 ; Kernel's (System) Page Directory address
  3500                                  		    ; (Physical address = Virtual address)	 	
  3501 000163DC <res 00000004>          memory_size: resd 1 ; memory size in pages
  3502 000163E0 <res 00000004>          free_pages:  resd 1 ; number of free pages		
  3503 000163E4 <res 00000004>          next_page:   resd 1 ; offset value in M.A.T. for
  3504                                  		    ; first free page search
  3505 000163E8 <res 00000004>          last_page:   resd 1 ; offset value in M.A.T. which
  3506                                  		    ; next free page search will be
  3507                                  		    ; stopped after it. (end of M.A.T.)
  3508 000163EC <res 00000004>          first_page:  resd 1 ; offset value in M.A.T. which
  3509                                  		    ; first free page search
  3510                                  		    ; will be started on it. (for user)
  3511 000163F0 <res 00000004>          mat_size:    resd 1 ; Memory Allocation Table size in pages
  3512                                  
  3513                                  ; 20/11/2020
  3514                                  ;vbe2bios:    resw 1 ; VBE2 video bios ID (bochs/qemu)
  3515                                  ;		    ; (0B0C4h or 0B0C5h for bochs/plex86 vgabios)				
  3516                                  
  3517                                  ; 02/09/2014 (Retro UNIX 386 v1)
  3518                                  ; 04/12/2013 (Retro UNIX 8086 v1)
  3519 000163F4 <res 00000002>          CRT_START:   resw 1 	  ; starting address in regen buffer
  3520                                  			  ; NOTE: active page only	
  3521 000163F6 <res 00000010>          CURSOR_POSN: resw 8 ; cursor positions for video pages
  3522                                  ACTIVE_PAGE: 
  3523 00016406 <res 00000001>          ptty: 	     resb 1 ; current tty
  3524                                  ; 01/07/2015 - 29/01/2016
  3525 00016407 <res 00000001>          ccolor:	     resb 1 ; current color attribute
  3526                                  ; 26/10/2015
  3527                                  ; 07/09/2014
  3528 00016408 <res 00000014>          ttychr:      resw ntty+2 ; Character buffer (multiscreen)
  3529                                  
  3530                                  ; 18/05/2015 (03/06/2013 - Retro UNIX 8086 v1 feature only!)
  3531 0001641C <res 00000004>          p_time:      resd 1     ; present time (for systime & sysmdate)
  3532                                  
  3533                                  ; 18/05/2015 (16/08/2013 - Retro UNIX 8086 v1 feature only !)
  3534                                  ; (open mode locks for pseudo TTYs)
  3535                                  ; [ major tty locks (return error in any conflicts) ]
  3536 00016420 <res 00000014>          ttyl:        resw ntty+2 ; opening locks for TTYs.
  3537                                  
  3538                                  ; 15/04/2015 (Retro UNIX 386 v1)
  3539                                  ; 22/09/2013 (Retro UNIX 8086 v1)
  3540 00016434 <res 0000000A>          wlist:       resb ntty+2 ; wait channel list (0 to 9 for TTYs)
  3541                                  ; 15/04/2015 (Retro UNIX 386 v1)
  3542                                  ;; 12/07/2014 -> sp_init set comm. parameters as 0E3h
  3543                                  ;; 0 means serial port is not available 
  3544                                  ;;comprm: ; 25/06/2014
  3545 0001643E <res 00000001>          com1p:       resb 1  ;;0E3h
  3546 0001643F <res 00000001>          com2p:       resb 1  ;;0E3h
  3547                                  
  3548                                  ; 17/11/2015
  3549                                  ; request for response (from the terminal)	
  3550 00016440 <res 00000002>          req_resp:    resw 1 			
  3551                                  ; 07/11/2015
  3552 00016442 <res 00000001>          ccomport:    resb 1 ; current COM (serial) port
  3553                                  		    ; (0= COM1, 1= COM2)
  3554                                  ; 09/11/2015
  3555 00016443 <res 00000001>          comqr:	     resb 1 ; 'query or response' sign (u9.s, 'sndc')
  3556                                  ; 07/11/2015
  3557 00016444 <res 00000002>          rchar:	     resw 1 ; last received char for COM 1 and COM 2		
  3558 00016446 <res 00000002>          schar:	     resw 1 ; last sent char for COM 1 and COM 2
  3559                                  
  3560                                  ; 22/08/2014 (RTC)
  3561                                  ; (Packed BCD)
  3562 00016448 <res 00000001>          time_seconds: resb 1
  3563 00016449 <res 00000001>          time_minutes: resb 1
  3564 0001644A <res 00000001>          time_hours:   resb 1
  3565 0001644B <res 00000001>          date_wday:    resb 1
  3566 0001644C <res 00000001>          date_day:     resb 1
  3567 0001644D <res 00000001>          date_month:   resb 1			
  3568 0001644E <res 00000001>          date_year:    resb 1
  3569 0001644F <res 00000001>          date_century: resb 1
  3570                                  
  3571                                  ; 24/01/2016
  3572 00016450 <res 00000004>          RTC_LH:	       resd 1
  3573 00016454 <res 00000001>          RTC_WAIT_FLAG: resb 1
  3574 00016455 <res 00000001>          USER_FLAG:     resb 1
  3575                                  ; 19/05/2016
  3576                                  ;RTC_second:
  3577 00016456 <res 00000001>          RTC_2Hz:       resb 1 ;  from 2Hz interrupt to 1Hz timer event function	
  3578                                  
  3579                                  %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 00016457 <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 00016458 <res 00000002>      <1> TIMER_LOW:      resw	1               ; LOW WORD OF TIMER COUNT
    31 0001645A <res 00000002>      <1> TIMER_HIGH:     resw	1               ; HIGH WORD OF TIMER COUNT
    32 0001645C <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 0001645D <res 00000001>      <1> SEEK_STATUS:	resb	1
    39 0001645E <res 00000001>      <1> MOTOR_STATUS:	resb	1
    40 0001645F <res 00000001>      <1> MOTOR_COUNT:	resb	1
    41 00016460 <res 00000001>      <1> DSKETTE_STATUS:	resb	1
    42 00016461 <res 00000007>      <1> NEC_STATUS:	resb	7
    43                              <1> 
    44                              <1> ;----------------------------------------
    45                              <1> ;	ADDITIONAL MEDIA DATA		:
    46                              <1> ;----------------------------------------
    47                              <1> 
    48 00016468 <res 00000001>      <1> LASTRATE:	resb 	1
    49 00016469 <res 00000001>      <1> HF_STATUS:	resb 	1
    50 0001646A <res 00000001>      <1> HF_ERROR:	resb 	1
    51 0001646B <res 00000001>      <1> HF_INT_FLAG:	resb 	1
    52 0001646C <res 00000001>      <1> HF_CNTRL:	resb 	1
    53 0001646D <res 00000004>      <1> DSK_STATE:	resb 	4
    54 00016471 <res 00000002>      <1> DSK_TRK:	resb 	2
    55                              <1> 
    56                              <1> ;----------------------------------------
    57                              <1> ;	FIXED DISK DATA AREAS		:
    58                              <1> ;----------------------------------------
    59                              <1> 
    60 00016473 <res 00000001>      <1> DISK_STATUS1:	resb 	1		; FIXED DISK STATUS
    61 00016474 <res 00000001>      <1> HF_NUM:		resb 	1		; COUNT OF FIXED DISK DRIVES
    62 00016475 <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 00016476 <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 00016478 <res 00000004>      <1> HDPM_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
    73 0001647C <res 00000004>      <1> HDPS_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
    74 00016480 <res 00000004>      <1> HDSM_TBL_VEC:	resd	1 		; Secondary master disk param. tbl. pointer
    75 00016484 <res 00000004>      <1> HDSS_TBL_VEC:	resd	1		; Secondary slave disk param. tbl. pointer
    76                              <1> 
    77                              <1> ; 03/01/2015
    78 00016488 <res 00000001>      <1> LBAMode:     	resb	1
    79                              <1> 
    80                              <1> ; *****************************************************************************
  3580                                  
  3581                                  ;;; Real Mode Data (10/07/2015 - BSS)
  3582                                  
  3583                                  ;alignb 2
  3584                                  
  3585                                  ; 10/01/2016
  3586                                  %include 'trdoskx.s'	; UNINITIALIZED KERNEL (Logical Drive & FS) DATA
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.2) - UNINITIALIZED DATA : trdoskx.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 30/08/2020
     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 00016489 <res 00000003>      <1> alignb 4
    20                              <1> 
    21                              <1> ; MAINPROG.ASM
    22 0001648C <res 00000004>      <1> MainProgCfg_FileSize:   resd 1 ; 14/04/2016
    23 00016490 <res 00000004>      <1> MainProgCfg_LineOffset: resd 1 ; 14/04/2016
    24                              <1> 
    25 00016494 <res 00000004>      <1> Current_VolSerial: resd 1
    26                              <1> 
    27 00016498 <res 00000004>      <1> Current_Dir_FCluster: resd 1
    28                              <1> 
    29 0001649C <res 00000001>      <1> Current_Dir_Level: resb 1
    30 0001649D <res 00000001>      <1> Current_FATType: resb 1
    31 0001649E <res 00000001>      <1> Current_Drv: resb 1
    32 0001649F <res 00000001>      <1> Current_Dir_Drv:   resb 1 ; '?'
    33 000164A0 <res 00000001>      <1>                    resb 1 ; ':'
    34 000164A1 <res 00000001>      <1> Current_Dir_Root:  resb 1 ; '/' 
    35 000164A2 <res 0000005A>      <1> Current_Directory: resb 90
    36 000164FC <res 00000001>      <1> End_Of_Current_Dir_Str: resb 1
    37 000164FD <res 00000001>      <1> Current_Dir_StrLen: resb 1   
    38                              <1> 
    39 000164FE <res 00000001>      <1> CursorColumn: 	resb 1
    40 000164FF <res 00000001>      <1> CmdArgStart:    resb 1
    41                              <1> 
    42                              <1> ; 03/02/2016
    43 00016500 <res 0000004E>      <1> Remark:		resb 78
    44                              <1> 
    45 0001654E <res 00000050>      <1> CommandBuffer: 	resb 80
    46                              <1> 
    47 0001659E <res 00000100>      <1> TextBuffer:	resb 256
    48                              <1> 
    49                              <1> MasterBootBuff:
    50 0001669E <res 000001BE>      <1> MasterBootCode: resb 1BEh
    51 0001685C <res 00000040>      <1> PartitionTable: resb 64
    52 0001689C <res 00000002>      <1> MBIDCode: resw 1
    53                              <1> 
    54                              <1> PTable_Buffer:
    55 0001689E <res 00000040>      <1> PTable_hd0: resb 64
    56 000168DE <res 00000040>      <1> PTable_hd1: resb 64
    57 0001691E <res 00000040>      <1> PTable_hd2: resb 64
    58 0001695E <res 00000040>      <1> PTable_hd3: resb 64
    59                              <1> ; 15/07/2020
    60                              <1> ;PTable_ep0: resb 64
    61                              <1> ;PTable_ep1: resb 64
    62                              <1> ;PTable_ep2: resb 64
    63                              <1> ;PTable_ep3: resb 64
    64                              <1> 
    65                              <1> ; 13/08/2020
    66 0001699E <res 00000001>      <1> scount: resb 1 ; 16/05/2016 (diskio.s, 'int33h:')
    67 0001699F <res 00000001>      <1> 	resb 1
    68 000169A0 <res 00000001>      <1> 	resb 1
    69 000169A1 <res 00000001>      <1> 	resb 1
    70                              <1> 	
    71 000169A2 <res 00000001>      <1> HD_LBA_yes: resb 1
    72 000169A3 <res 00000001>      <1> PP_Counter: resb 1
    73 000169A4 <res 00000001>      <1> EP_Counter: resb 1
    74                              <1> ; 13/08/2020
    75 000169A5 <res 00000001>      <1> LD_Counter: resb 1
    76                              <1> 
    77                              <1> ; 30/08/2020
    78 000169A6 <res 00000004>      <1> MBR_EP_StartSector: resd 1 
    79                              <1> 		; Extd partition start sector as in MBR
    80 000169AA <res 00000004>      <1> EP_StartSector: resd 1 ; next extd partition start sector
    81                              <1> 	; 15/07/2020	
    82                              <1>                 ;resd 1
    83                              <1>                 ;resd 1
    84                              <1> 
    85                              <1> ; 20/07/2020
    86 000169AE <res 00000200>      <1> DOSBootSectorBuff: resb 512
    87                              <1> ; 15/07/2020
    88                              <1> ;DOSBootSectorBuff: resb 446 ; 1BEh
    89                              <1> ;MiniPartitionTable: resb 64 ;  40h
    90                              <1> ;MiniPartitionMagic: resw  1 ;  02h 		
    91                              <1> 
    92                              <1> FAT_BuffDescriptor:
    93 00016BAE <res 00000004>      <1> FAT_CurrentCluster: resd 1
    94 00016BB2 <res 00000001>      <1> FAT_BuffValidData: resb 1
    95 00016BB3 <res 00000001>      <1> FAT_BuffDrvName: resb 1
    96 00016BB4 <res 00000002>      <1> FAT_BuffOffset: resw 1
    97 00016BB6 <res 00000004>      <1> FAT_BuffSector: resd 1
    98                              <1> 
    99 00016BBA <res 00000004>      <1> FAT_ClusterCounter: resd 1
   100 00016BBE <res 00000004>      <1> LastCluster: resd 1
   101                              <1> 
   102                              <1> ; 16/05/2016
   103                              <1> ;; 18/03/2016 (TRDOS v2.0)
   104                              <1> ;ClusterBuffer_Valid: resb 1
   105                              <1> 
   106                              <1> Dir_BuffDescriptor:
   107 00016BC2 <res 00000001>      <1> DirBuff_DRV: resb 1
   108 00016BC3 <res 00000001>      <1> DirBuff_FATType: resb 1
   109 00016BC4 <res 00000001>      <1> DirBuff_ValidData: resb 1
   110 00016BC5 <res 00000002>      <1> DirBuff_CurrentEntry: resw 1
   111 00016BC7 <res 00000002>      <1> DirBuff_LastEntry: resw 1
   112 00016BC9 <res 00000004>      <1> DirBuff_Cluster: resd 1 
   113 00016BCD <res 00000002>      <1> DirBuffer_Size: resw 1
   114                              <1> ;DirBuff_EntryCounter: resw 1
   115                              <1> 
   116                              <1> ; 01/02/2016
   117                              <1> ; these are on (real mode) segment 8000h and later
   118                              <1> ; FAT_Buffer:	resb 1536 ; 3 sectors
   119                              <1> ; Dir_Buffer:	resb 512*32
   120                              <1> ; Logical_DOSDisks:  resb 6656 ; 26 * 256 bytes
   121                              <1> 
   122                              <1> ; 18/01/2016
   123                              <1> 
   124 00016BCF <res 00000004>      <1> FreeClusterCount: resd 1
   125                              <1> 
   126 00016BD3 <res 00000004>      <1> VolSize_Unit1:   resd 1
   127 00016BD7 <res 00000004>      <1> VolSize_Unit2:   resd 1
   128                              <1> 
   129 00016BDB <res 00000004>      <1> Vol_Tot_Sec_Str_Start:	    resd 1
   130 00016BDF <res 0000000A>      <1> Vol_Tot_Sec_Str: 	    resb 10
   131 00016BE9 <res 00000001>      <1> Vol_Tot_Sec_Str_End:	    resb 1
   132 00016BEA <res 00000001>      <1> resb 1
   133 00016BEB <res 00000004>      <1> Vol_Free_Sectors_Str_Start: resd 1
   134 00016BEF <res 0000000A>      <1> Vol_Free_Sectors_Str:	    resb 10				
   135 00016BF9 <res 00000001>      <1> Vol_Free_Sectors_Str_End:   resb 1
   136                              <1> 
   137                              <1> ; 10/02/2016
   138 00016BFA <res 00000001>      <1> RUN_CDRV: resb 1 ; CMD_INTR.ASM  ; 09/11/2011
   139                              <1> 
   140                              <1> ; 24/01/2016
   141 00016BFB <res 00000080>      <1> PATH_Array:     resb 128 ; DIR.ASM ; 09/10/2011
   142                              <1> ; 06/02/2016
   143 00016C7B <res 00000004>      <1> CCD_DriveDT:	resd 1 ; DIR.ASM ; (word)
   144 00016C7F <res 00000001>      <1> CCD_Level:	resb 1 ; DIR.ASM
   145 00016C80 <res 00000001>      <1> Last_Dir_Level:	resb 1 ; DIR.ASM
   146                              <1> ;
   147 00016C81 <res 00000002>      <1> CDLF_AttributesMask: resw 1 ; DIR.ASM
   148 00016C83 <res 00000004>      <1> CDLF_FNAddress:	resd 1 ; DIR.ASM (word)
   149 00016C87 <res 00000002>      <1> CDLF_DEType:	resw 1 ; DIR.ASM
   150                              <1> ;
   151 00016C89 <res 00000001>      <1> CD_COMMAND:	resb 1 ; DIR.ASM
   152                              <1> 
   153 00016C8A <res 00000002>      <1> alignb 4
   154                              <1> 
   155                              <1> ; 29/01/2016
   156 00016C8C <res 00000001>      <1> Program_Exit:	resb 1 ; CMD_INTR.ASM  ; 09/11/2011
   157                              <1> 
   158                              <1> ;alignb 4
   159                              <1> ; 23/02/2016
   160 00016C8D <res 00000001>      <1> disk_rw_op:	resb 1 ;  0 = disk read, 1 = disk write
   161                              <1> ;disk_rw_spt:	resb 1 ; sectors per track (<= 63) /// (<256)
   162                              <1> ; 31/01/2016
   163 00016C8E <res 00000001>      <1> retry_count: 	resb 1 ; DISK_IO.ASM ; 20/07/2011 (CHS_RetryCount)
   164 00016C8F <res 00000001>      <1> disk_rw_err: 	resb 1 ; DISK_IO.ASM ; (Disk_IO_err_code)
   165 00016C90 <res 00000004>      <1> sector_count:	resd 1 ; DISK_IO.ASM ; (Disk_RW_SectorCount)
   166                              <1> 
   167                              <1> ; 06/02/2016 (long name)
   168 00016C94 <res 00000002>      <1> FDE_AttrMask:	   resw 1 ; DIR.ASM
   169 00016C96 <res 00000002>      <1> AmbiguousFileName: resw 1 ; DIR.ASM
   170 00016C98 <res 00000001>      <1> PreviousAttr:	   resb 1 ; DIR.ASM
   171                              <1> ;	
   172 00016C99 <res 00000001>      <1> LongNameFound:   resb 1	  ; DIR.ASM
   173 00016C9A <res 00000001>      <1> LFN_EntryLength: resb 1   ; DIR.ASM
   174 00016C9B <res 00000001>      <1> LFN_CheckSum:    resb 1   ; DIR.ASM
   175 00016C9C <res 00000084>      <1> LongFileName:    resb 132 ; DIR.ASM
   176                              <1> 
   177                              <1> ;PATH_Array_Ptr: resw 1 ; DIR.ASM
   178 00016D20 <res 00000001>      <1> PATH_CDLevel:	 resb 1 ; DIR.ASM
   179 00016D21 <res 00000001>      <1> PATH_Level:	 resb 1 ; DIR.ASM
   180                              <1> 
   181                              <1> ; 07/02/2016
   182 00016D22 <res 0000000D>      <1> Dir_File_Name:	resb 13 ; DIR.ASM ; 09/10/2011
   183                              <1> 
   184                              <1> ; 10/02/2016
   185 00016D2F <res 0000000D>      <1> Dir_Entry_Name:	resb 13 ; DIR.ASM
   186                              <1> 
   187                              <1> alignb 2
   188                              <1> 
   189 00016D3C <res 00000002>      <1> AttributesMask: resw 1 ; CMD_INTR.ASM ; 09/11/2011
   190                              <1> 
   191                              <1> ; 10/02/2016 (128 bytes -> 126 bytes)
   192                              <1> ; 08/02/2016
   193                              <1> ;FFF Structure (128 bytes) ; DIR.ASM ; 09/10/2011
   194 00016D3E <res 00000001>      <1> FindFile_Drv:		  resb 1
   195 00016D3F <res 00000041>      <1> FindFile_Directory:	  resb 65
   196 00016D80 <res 0000000D>      <1> FindFile_Name:		  resb 13
   197                              <1> FindFile_LongNameEntryLength:
   198 00016D8D <res 00000001>      <1> FindFile_LongNameYes: 	  resb 1 ; Sign for longname procedures
   199                              <1> ;Above 80 bytes form
   200                              <1> ;TR-DOS Source/Destination File FullName Format/Structure
   201 00016D8E <res 00000002>      <1> FindFile_AttributesMask:  resw 1
   202 00016D90 <res 00000020>      <1> FindFile_DirEntry:	  resb 32
   203 00016DB0 <res 00000004>      <1> FindFile_DirFirstCluster: resd 1
   204 00016DB4 <res 00000004>      <1> FindFile_DirCluster:	  resd 1
   205 00016DB8 <res 00000002>      <1> FindFile_DirEntryNumber:  resw 1
   206 00016DBA <res 00000002>      <1> FindFile_MatchCounter:	  resw 1
   207 00016DBC <res 00000002>      <1> FindFile_Reserved:	  resw 1 ; 06/03/2016
   208                              <1> 
   209 00016DBE <res 00000004>      <1> First_Path_Pos: resd 1	; DIR.ASM ; 09/10/2011
   210 00016DC2 <res 00000004>      <1> Last_Slash_Pos: resd 1	; DIR.ASM 
   211                              <1> 
   212                              <1> ; 10/02/2016
   213 00016DC6 <res 00000002>      <1> File_Count:     resw 1 	; DIR.ASM ; 09/10/2011
   214 00016DC8 <res 00000002>      <1> Dir_Count:      resw 1
   215 00016DCA <res 00000004>      <1> Total_FSize:    resd 1
   216 00016DCE <res 00000004>      <1> TFS_Dec_Begin:  resd 1
   217 00016DD2 <res 0000000A>      <1>                 resb 10
   218 00016DDC <res 00000001>      <1> TFS_Dec_End:    resb 1
   219                              <1> 
   220 00016DDD <res 00000001>      <1> PrintDir_RowCounter: resb 1
   221                              <1> 
   222 00016DDE <res 00000002>      <1> alignb 4
   223                              <1> ; 15/02/2015 ('show' command variables)
   224 00016DE0 <res 00000004>      <1> Show_FDT:	resd 1
   225 00016DE4 <res 00000004>      <1> Show_LDDDT:	resd 1
   226 00016DE8 <res 00000004>      <1> Show_Cluster:	resd 1
   227 00016DEC <res 00000004>      <1> Show_FileSize:	resd 1
   228 00016DF0 <res 00000004>      <1> Show_FilePointer: resd 1
   229 00016DF4 <res 00000002>      <1> Show_ClusterPointer: resw 1
   230 00016DF6 <res 00000002>      <1> Show_ClusterSize: resw 1
   231 00016DF8 <res 00000001>      <1> Show_RowCount:	resb 1
   232                              <1> 
   233 00016DF9 <res 00000003>      <1> alignb 4
   234                              <1> ; 21/02/2016
   235 00016DFC <res 00000004>      <1> DelFile_FNPointer:	resd 1 ; ; CMD_INTR.ASM (word) ; 09/11/2011
   236                              <1> ; 27/02/2016
   237                              <1> ; DIR.ASM (09/10/2011)
   238 00016E00 <res 00000004>      <1> DelFile_FCluster:	resd 1
   239 00016E04 <res 00000002>      <1> DelFile_EntryCounter:	resw 1
   240 00016E06 <res 00000001>      <1> DelFile_LNEL:		resb 1
   241 00016E07 <res 00000001>      <1> resb 1
   242                              <1> 
   243                              <1> ; DIR.ASM
   244 00016E08 <res 00000004>      <1> mkdir_DirName_Offset: 	resd 1
   245 00016E0C <res 00000004>      <1> mkdir_FFCluster:	resd 1
   246 00016E10 <res 00000004>      <1> mkdir_LastDirCluster:	resd 1
   247 00016E14 <res 00000004>      <1> mkdir_FreeSectors:	resd 1
   248 00016E18 <res 00000002>      <1> mkdir_attrib:		resw 1 
   249 00016E1A <res 00000001>      <1> mkdir_SecPerClust:	resb 1
   250 00016E1B <res 00000001>      <1> mkdir_add_new_cluster:	resb 1
   251 00016E1C <res 0000000D>      <1> mkdir_Name:		resb 13
   252 00016E29 <res 00000002>      <1> resw 1 ; 01/03/2016
   253                              <1> ; 27/02/2016
   254 00016E2B <res 00000001>      <1> RmDir_MultiClusters:	resb 1  
   255 00016E2C <res 00000004>      <1> RmDir_DirEntryOffset:	resd 1 ; 01/03/2016 (word -> dword)
   256 00016E30 <res 00000004>      <1> RmDir_ParentDirCluster: resd 1
   257 00016E34 <res 00000004>      <1> RmDir_DirLastCluster:   resd 1
   258 00016E38 <res 00000004>      <1> RmDir_PreviousCluster:  resd 1
   259                              <1> ; 22/02/2016
   260 00016E3C <res 00000001>      <1> UPDLMDT_CDirLevel:	resb 1
   261 00016E3D <res 00000004>      <1> UPDLMDT_CDirFCluster:	resd 1
   262                              <1> 	
   263 00016E41 <res 00000003>      <1> alignb 4
   264                              <1> ; DRV_FAT.ASM ; 21/08/2011
   265 00016E44 <res 00000004>      <1> gffc_next_free_cluster:  resd 1
   266 00016E48 <res 00000004>      <1> gffc_first_free_cluster: resd 1
   267 00016E4C <res 00000004>      <1> gffc_last_free_cluster:  resd 1
   268                              <1> 
   269                              <1> ;29/04/2016
   270                              <1> Cluster_Index: ; resd 1
   271                              <1> ; 22/02/2016
   272 00016E50 <res 00000004>      <1> ClusterValue:	resd 1
   273                              <1> ; 04/03/2016
   274 00016E54 <res 00000001>      <1> Attributes:	resb 1 
   275                              <1> ;;CFS_error:  resb 1 ;; 01/03/2016
   276 00016E55 <res 00000001>      <1> resb 1
   277 00016E56 <res 00000001>      <1> CFS_OPType: resb 1
   278 00016E57 <res 00000001>      <1> CFS_Drv:    resb 1
   279 00016E58 <res 00000004>      <1> CFS_CC:	    resd 1
   280 00016E5C <res 00000004>      <1> CFS_FAT32FSINFOSEC: resd 1
   281 00016E60 <res 00000004>      <1> CFS_FAT32FC: resd 1
   282                              <1> 
   283                              <1> ; 27/02/2016
   284                              <1> ;alignb 4
   285 00016E64 <res 00000004>      <1> glc_prevcluster: resd 1 ; DRV_FAT.ASM (21/08/2011)
   286                              <1> ; 22/10/2016
   287 00016E68 <res 00000004>      <1> glc_index:	 resd 1 ;  Last Cluster Index (22/10/2016)	
   288                              <1> 
   289                              <1> ; DIR.ASM
   290 00016E6C <res 00000002>      <1> DLN_EntryNumber: resw 1
   291 00016E6E <res 00000001>      <1> DLN_40h:	 resb 1
   292                              <1> ; 28/02/2016
   293 00016E6F <res 00000001>      <1> TCC_FATErr:	 resb 1 ; DRV_FAT.ASM
   294                              <1> 
   295                              <1> alignb 4
   296                              <1> ; DIR.ASM (09/10/2011)
   297 00016E70 <res 00000002>      <1> LCDE_EntryIndex: resw 1 ; LCDE_EntryOffset
   298 00016E72 <res 00000002>      <1> LCDE_ClusterSN:  resw 1
   299 00016E74 <res 00000004>      <1> LCDE_Cluster: 	 resd 1
   300 00016E78 <res 00000004>      <1> LCDE_ByteOffset: resd 1
   301                              <1> 
   302                              <1> ;alignb4
   303                              <1> ; 06/03/2016 (word -> dword)
   304                              <1> ; CMD_INTR.ASM (01/08/2010)
   305 00016E7C <res 00000004>      <1> SourceFilePath:	     resd 1
   306 00016E80 <res 00000004>      <1> DestinationFilePath: resd 1
   307                              <1> 
   308                              <1> ;alignb 4
   309                              <1> ; 06/03/2016
   310                              <1> ; FILE.ASM (09/10/2011)
   311                              <1> ;Source File Structure (same with 'Find File' Structure)
   312 00016E84 <res 00000001>      <1> SourceFile_Drv:			resb 1
   313 00016E85 <res 00000041>      <1> SourceFile_Directory:		resb 65
   314 00016EC6 <res 0000000D>      <1> SourceFile_Name:		resb 13
   315                              <1> SourceFile_LongNameEntryLength: 
   316 00016ED3 <res 00000001>      <1> SourceFile_LongNameYes:		resb 1 ; Sign for longname procedures
   317                              <1> ;Above 80 bytes
   318                              <1> ;is TR-DOS Source File FullName Format/Structure
   319 00016ED4 <res 00000002>      <1> SourceFile_AttributesMask:	resw 1
   320 00016ED6 <res 00000020>      <1> SourceFile_DirEntry:		resb 32
   321 00016EF6 <res 00000004>      <1> SourceFile_DirFirstCluster:	resd 1
   322 00016EFA <res 00000004>      <1> SourceFile_DirCluster:		resd 1
   323 00016EFE <res 00000002>      <1> SourceFile_DirEntryNumber:	resw 1
   324 00016F00 <res 00000002>      <1> SourceFile_MatchCounter:	resw 1
   325                              <1> ; 16/03/2016
   326 00016F02 <res 00000001>      <1> SourceFile_SecPerClust:		resb 1
   327 00016F03 <res 00000001>      <1> SourceFile_Reserved:		resb 1
   328                              <1> ; Above is 128 bytes
   329                              <1> 
   330                              <1> ;Destination File Structure (same with 'Find File' Structure)
   331 00016F04 <res 00000001>      <1> DestinationFile_Drv:		resb 1
   332 00016F05 <res 00000041>      <1> DestinationFile_Directory: 	resb 65
   333 00016F46 <res 0000000D>      <1> DestinationFile_Name:		resb 13
   334                              <1> DestinationFile_LongNameEntryLength:
   335 00016F53 <res 00000001>      <1> DestinationFile_LongNameYes:	resb 1 ; Sign for longname procedures
   336                              <1> ;Above 80 bytes
   337                              <1> ;is TR-DOS Destination File FullName Format/Structure
   338 00016F54 <res 00000002>      <1> DestinationFile_AttributesMask: resw 1
   339 00016F56 <res 00000020>      <1> DestinationFile_DirEntry:	resb 32
   340 00016F76 <res 00000004>      <1> DestinationFile_DirFirstCluster: resd 1
   341 00016F7A <res 00000004>      <1> DestinationFile_DirCluster:	resd 1
   342 00016F7E <res 00000002>      <1> DestinationFile_DirEntryNumber: resw 1
   343 00016F80 <res 00000002>      <1> DestinationFile_MatchCounter:	resw 1
   344                              <1> ; 16/03/2016
   345 00016F82 <res 00000001>      <1> DestinationFile_SecPerClust:	resb 1
   346 00016F83 <res 00000001>      <1> DestinationFile_Reserved:	resb 1
   347                              <1> ; Above is 128 bytes
   348                              <1> 
   349                              <1> ; 24/04/2016
   350 00016F84 <res 00000002>      <1> resw 1
   351                              <1> 
   352                              <1> ; 10/03/2016
   353                              <1> ; FILE.ASM
   354 00016F86 <res 00000001>      <1> move_cmd_phase:	   resb 1
   355 00016F87 <res 00000001>      <1> msftdf_sf_df_drv:  resb 1
   356 00016F88 <res 00000004>      <1> msftdf_drv_offset: resd 1
   357                              <1> 
   358                              <1> ; 11/03/2016
   359                              <1> ; DRV_FAT.ASM (21/08/2011)
   360 00016F8C <res 00000004>      <1> FAT_anc_LCluster:  resd 1
   361 00016F90 <res 00000004>      <1> FAT_anc_FFCluster: resd 1
   362                              <1> 
   363                              <1> ;alignb 4
   364                              <1> 
   365                              <1> ; 14/03/2016
   366                              <1> ; TRDOS 386 = TRDOS v2.0 feature only !
   367                              <1> ; 'allocate_memory_block' in 'memory.s'
   368 00016F94 <res 00000004>      <1> mem_ipg_count:	resd 1 ; page count (for contiguous allocation)
   369 00016F98 <res 00000004>      <1> mem_pg_count:	resd 1 ; page count (for count down)
   370 00016F9C <res 00000004>      <1> mem_aperture:	resd 1 ; contiguous free pages (current)
   371 00016FA0 <res 00000004>      <1> mem_max_aperture: resd 1 ; maximum value of contiguous free pages
   372 00016FA4 <res 00000004>      <1> mem_pg_pos:	resd 1 ; mem. position (page #) of current aperture
   373 00016FA8 <res 00000004>      <1> mem_max_pg_pos: resd 1 ; mem. position (page #) of max. aperture
   374                              <1> 
   375                              <1> ; 15/03/2016
   376                              <1> ; FILE.ASM ('copy_source_file_to_destination_file')
   377 00016FAC <res 00000001>      <1> copy_cmd_phase:       resb 1
   378 00016FAD <res 00000001>      <1> csftdf_rw_err:	      resb 1
   379 00016FAE <res 00000001>      <1> DestinationFileFound: resb 1
   380 00016FAF <res 00000001>      <1> csftdf_cdrv: 	      resb 1
   381 00016FB0 <res 00000004>      <1> csftdf_filesize:      resd 1
   382                              <1> ; TRDOS386 (TRDOS v2.0)
   383 00016FB4 <res 00000004>      <1> csftdf_sf_mem_addr:   resd 1
   384 00016FB8 <res 00000004>      <1> csftdf_sf_mem_bsize:  resd 1
   385                              <1> ;
   386                              <1> 
   387 00016FBC <res 00000004>      <1> csftdf_sf_cluster:    resd 1 ; 16/03/2016
   388 00016FC0 <res 00000004>      <1> csftdf_df_cluster:    resd 1
   389                              <1> ; 16/03/2016
   390 00016FC4 <res 00000004>      <1> csftdf_r_size:        resd 1
   391 00016FC8 <res 00000004>      <1> csftdf_w_size:        resd 1
   392 00016FCC <res 00000004>      <1> csftdf_sf_rbytes:     resd 1
   393 00016FD0 <res 00000004>      <1> csftdf_df_wbytes:     resd 1
   394 00016FD4 <res 00000001>      <1> csftdf_percentage:    resb 1
   395                              <1> ; 17/03/2016
   396 00016FD5 <res 00000001>      <1> csftdf_videopage:     resb 1
   397 00016FD6 <res 00000002>      <1> csftdf_cursorpos:     resw 1
   398 00016FD8 <res 00000004>      <1> csftdf_sf_drv_dt:     resd 1
   399 00016FDC <res 00000004>      <1> csftdf_df_drv_dt:     resd 1
   400                              <1> 
   401                              <1> ; 21/03/2016
   402                              <1> ; 20/03/2016
   403                              <1> ; FILE.ASM
   404 00016FE0 <res 00000004>      <1> createfile_Name_Offset:  resd 1
   405 00016FE4 <res 00000004>      <1> createfile_FreeSectors:  resd 1 
   406 00016FE8 <res 00000004>      <1> createfile_size:         resd 1
   407 00016FEC <res 00000004>      <1> createfile_FFCluster:    resd 1 ; 11/03/2016
   408 00016FF0 <res 00000004>      <1> createfile_LastDirCluster: resd 1
   409 00016FF4 <res 00000004>      <1> createfile_Cluster:      resd 1
   410 00016FF8 <res 00000004>      <1> createfile_PCluster:     resd 1
   411 00016FFC <res 00000001>      <1> createfile_attrib:	 resb 1
   412 00016FFD <res 00000001>      <1> createfile_SecPerClust:  resb 1
   413 00016FFE <res 00000002>      <1> createfile_DirIndex:     resw 1
   414 00017000 <res 00000004>      <1> createfile_CCount:	 resd 1
   415 00017004 <res 00000002>      <1> createfile_BytesPerSec:	 resw 1 ; 23/03/2016
   416 00017006 <res 00000001>      <1> createfile_wfc:	         resb 1
   417 00017007 <res 00000001>      <1> createfile_UpdatePDir:	 resb 1 ; 31/03/2016
   418                              <1> 
   419                              <1> ;alignb 4
   420                              <1> 
   421                              <1> ; 11/04/2016
   422 00017008 <res 00000002>      <1> env_var_length:	   resw 1
   423                              <1> 
   424 0001700A <res 00000002>      <1> alignb 4
   425                              <1> 
   426                              <1> ; 25/04/2016
   427 0001700C <res 00000001>      <1> readi.valid:	resb 1 ; valid data (>0 = valid for readi)
   428 0001700D <res 00000001>      <1> readi.drv:	resb 1 ; drive number (0, 1,2,3,4..)
   429 0001700E <res 00000001>      <1> readi.spc:	resb 1 ; sectors per cluster for 'readi' drive
   430 0001700F <res 00000001>      <1> readi.s_index:  resb 1 ; sector index in current cluster (buffer)
   431 00017010 <res 00000004>      <1> readi.sector:	resd 1 ; current disk sector
   432 00017014 <res 00000002>      <1> readi.bpc:	resw 1 ; bytes per cluster - 1
   433 00017016 <res 00000002>      <1> readi.offset:	resw 1 ; byte offset in cluster buffer
   434 00017018 <res 00000004>      <1> readi.cluster:  resd 1 ; current cluster number
   435 0001701C <res 00000004>      <1> readi.c_index:	resd 1 ; cluster index of the current cluster (0,1,2,3..)
   436 00017020 <res 00000004>      <1> readi.fclust:	resd 1 ; first cluster of the current cluster
   437 00017024 <res 00000004>      <1> readi.fs_index: resd 1 ; sector index in disk/file section (for Singlix FS)
   438                              <1> ;readi.buffer:	resd 1 ; readi sector buffer address
   439                              <1> 
   440                              <1> ;alignb 4
   441                              <1> 
   442 00017028 <res 00000001>      <1> writei.valid:	resb 1 ; valid data (>0 = valid for writei)
   443 00017029 <res 00000001>      <1> writei.drv:	resb 1 ; drive number (0, 1,2,3,4..)
   444 0001702A <res 00000001>      <1> writei.spc:	resb 1 ; sectors per cluster for 'writei' drive
   445 0001702B <res 00000001>      <1> writei.s_index: resb 1 ; sector index in current cluster (buffer)
   446 0001702C <res 00000004>      <1> writei.sector:	resd 1 ; current disk sector
   447 00017030 <res 00000002>      <1> writei.bpc:	resw 1 ; bytes per cluster - 1
   448 00017032 <res 00000002>      <1> writei.offset:	resw 1 ; byte offset in cluster buffer
   449 00017034 <res 00000004>      <1> writei.cluster: resd 1 ; current cluster number
   450 00017038 <res 00000004>      <1> writei.c_index:	resd 1 ; cluster index of the current cluster (0,1,2,3..)
   451 0001703C <res 00000004>      <1> writei.fclust:  resd 1 ; first cluster of the current cluster
   452 00017040 <res 00000004>      <1> writei.fs_index: resd 1 ; sector index in disk/file section (for Singlix FS)
   453                              <1> ;writei.buffer:	resd 1 ; writei sector buffer address
   454 00017044 <res 00000004>      <1> writei.lclust:	resd 1 ; writei last cluster (mget_w) ; 23/10/2016
   455 00017048 <res 00000004>      <1> writei.l_index:	resd 1 ; writei last cluster index (mget_w) ; 23/10/2016
   456 0001704C <res 00000001>      <1> writei.ofn:	resb 1 ; open file number (to be written) ; 23/10/2016
   457                              <1> 
   458 0001704D <res 00000003>      <1> alignb 4
   459                              <1> 
   460                              <1> ; 29/04/2016
   461 00017050 <res 00000004>      <1> Run_CDirFC:	resd 1
   462 00017054 <res 00000001>      <1> Run_Auto_Path:	resb 1
   463 00017055 <res 00000001>      <1> Run_Manual_Path: resb 1 ; 0 -> auto path sequence needed
   464 00017056 <res 00000001>      <1> EXE_ID:		resb 1	
   465 00017057 <res 00000001>      <1> EXE_dot:	resb 1
   466                              <1> 
   467                              <1> ; 06/05/2016
   468 00017058 <res 00000004>      <1> mainprog_return_addr: resd 1
   469 0001705C <res 00000004>      <1> last_error:	resd 1  ; this will be used to return error code to MainProg
   470                              <1> 			; 'lasterror' keyword will be used later to get the
   471                              <1> 			; last error code/number/status.
   472                              <1> ; 12/05/2016
   473 00017060 <res 00000004>      <1> video_eax:	resd 1  ; eax return value of video function
   474                              <1> 
   475                              <1> ; 01/06/2016
   476 00017064 <res 00000004>      <1> user_buffer:	resd 1  ; 'diskio.s' (INT 33h, Function 08h, floppy disk type)
   477                              <1> 
   478                              <1> ; 21/05/2016 - TRDOS 386 ('swap/switch', 'rswap', [u.pri])
   479 00017068 <res 00000001>      <1> priority:	resb 1  ; running priority level of process (0,1,2)
   480                              <1> 			; (run queue which is process comes from)
   481                              <1> ; 22/05/2016 - TRDOS 386 ('set_run_sequence', 'rtc_int', 'u_timer')
   482 00017069 <res 00000001>      <1> p_change:	resb 1  ; process change status (for timer events)
   483                              <1> ; 23/05/2016 - TRDOS 386 ('clock')
   484 0001706A <res 00000001>      <1> multi_tasking:	resb 1   ; Multi Tasking status (0 = disabled, >0 = enabled)
   485                              <1> 			; (EBX will return with user buffer addr or disk type)
   486                              <1> ; 07/06/2016
   487 0001706B <res 00000001>      <1> timer_events:	resb 1  ; number of (active) timer events, <= 16		
   488                              <1> 
   489                              <1> ; 24/06/2016
   490 0001706C <res 00000001>      <1> w_str_cmd:	resb 1	; WRITE_STRING command (0,1,2,3) ; video.s
   491 0001706D <res 00000001>      <1> p_crt_mode:	resb 1  ; previous video mode (=3 or 0), backup mark/sign
   492                              <1> ; 26/06/2016
   493 0001706E <res 00000001>      <1> p_crt_page:	resb 1  ; previous active page (for 'set_mode')
   494                              <1> ; 04/07/2016
   495 0001706F <res 00000001>      <1> noclearmem:	resb 1  ; if set, 'SET MODE' (INT 31h) function (AH = 4)
   496                              <1> 			; will not clear the video memory
   497                              <1> 			; (usable for graphics modes only)
   498                              <1> alignb 2
   499 00017070 <res 00000002>      <1> CRT_LEN:	resw 1  ; length of regen buffer in bytes
   500 00017072 <res 00000010>      <1> cursor_pposn:	resw 8  ; cursor positions backup
   501                              <1> 
   502                              <1> ; 10/07/2016 ('VGA_FONT_SETUP', INT 43H address for x86 real mode bios)
   503 00017082 <res 00000004>      <1> VGA_INT43H:	resd 1	; 0 = default (not configured by user)
   504                              <1> 			; 0FFFFFFFFh = user defined fonts
   505                              <1> 			; address:
   506                              <1> 			; 	vgafont8
   507                              <1> 			; 	vgafont16
   508                              <1> 			; 	vgafont14
   509                              <1> 
   510                              <1> ; 25/07/2016
   511 00017086 <res 00000001>      <1> VGA_MTYPE:	resb 1  ; 0=CTEXT,1=MTEXT,2=CGA,3=PLANAR1,4=PLANAR4,5=LINEAR 
   512                              <1> 
   513                              <1> ; 23/10/2016
   514 00017087 <res 00000001>      <1> setfmod		resb 1	; update last modification date&time sign (if >0)
   515                              <1> 			; (it is Open File Number + 1, if > 0)
   516                              <1> alignb 4
   517                              <1> 
   518                              <1> ; 16/10/2016
   519 00017088 <res 00000004>      <1> FFF_UBuffer:	resd 1  ; User's buffer address for FFF & FNF system calls 
   520                              <1> ; 15/10/2016
   521 0001708C <res 00000001>      <1> FFF_Valid:	resb 1  ; Find First File Structure validation byte
   522                              <1> 			; 0  = invalid (Find Next File can't use FFF struct)
   523                              <1> 			; >0 = valid, return type for FFF and Find Next File
   524                              <1> 			; 24 = basic parameters, 24 bytes
   525                              <1> 			; 128 = entire FFF structure/table, 128 bytes
   526                              <1> ; 16/10/2016 (FFF_Attrib: resw 1)
   527 0001708D <res 00000001>      <1> FFF_Attrib:	resb 1	; Find First File attributes for Find Next File (LB)
   528 0001708E <res 00000001>      <1> FFF_RType:	resb 1  ; FFF return type (0 = Basic, >0 = complete) (HB)
   529                              <1> ; 16/10/2016 - 05/10/2016 (Set Working Path)
   530 0001708F <res 00000001>      <1> SWP_inv_fname:	resb 1	; Set Working Path - Invalid File Name
   531 00017090 <res 00000002>      <1> SWP_Mode:	resw 1	; Set Working Path - Mode
   532 00017092 <res 00000001>      <1> SWP_DRV:	resb 1	; Set Working Path - Drive	
   533 00017093 <res 00000001>      <1> SWP_DRV_chg:	resb 1	; Set Working Path - Drive Change
   534                              <1> 
   535                              <1> ; 27/02/2017
   536 00017094 <res 00000001>      <1> fpready:	resb 1	; '80387 fpu is ready' flag	
   537                              <1> 
   538                              <1> ; 08/10/2016
   539 00017095 <res 00000009>      <1> device_name:    resb 9  ; capitalized (and zero padded) device canem 
   540                              <1> 			; (example: "TTY0",0,0,0,0,0")
   541                              <1> 
   542 0001709E <res 00000002>      <1> alignb 4
   543                              <1> 
   544                              <1> ; 08/10/2016
   545                              <1> ; 07/10/2016
   546                              <1> ; Table of kernel devices (which do not use installable device drivers)
   547                              <1> ; has been coded into KERNEL (trdosk9.s) 
   548                              <1> ; 07/10/2016
   549                              <1> ; 8 installable device drivers available to install (NUMIDEV)
   550 000170A0 <res 00000020>      <1> IDEV_PGDIR: resd NUMIDEV
   551                              <1> 			; Page directories of installable device drivers
   552                              <1> 			;
   553                              <1> 			; Note: Virtual start address is always 400000h
   554                              <1> 			; (end of the 1st 4MB). [org 400000h]
   555                              <1> 			; Segments: KCODE, KDATA
   556                              <1> 			; Method: call 400000h (after changing page dir) 	
   557                              <1> 			; Query code located at the start (400000h).
   558                              <1> 			; Query code returns with
   559                              <1> 			;   eax = device type and driver version
   560                              <1> 			;         AL = Device Type minor
   561                              <1> 			;         AH = Device Type major
   562                              <1> 			;         Byte 16-23 : Version minor
   563                              <1> 			;	  Byte 24-31 : Version major - 1
   564                              <1> 			;		       (0:0 -> 1.0)
   565                              <1> 			;   ebx = initialization code address
   566                              <1> 			;   ecx = configuration table address
   567                              <1> 			;   edx = description table address
   568                              <1> 			;   esi = device (default) name address (ASCIIZ)
   569                              <1> 			;	 (name has "/DEV/" prefix)		
   570                              <1> 			;   edi = dispatch table address
   571                              <1> 			;        (for calling kernel-device functions)
   572                              <1> 			;   ebp = address table address
   573                              <1> 			; Initialization code returns with
   574                              <1> 			;   eax = open code address
   575                              <1> 			;   ecx = close code address 
   576                              <1> 			;   ebx = read code address
   577                              <1> 			;   edx = write code address 	
   578                              <1> 			;   esi = IOCTL code address
   579                              <1> 			;   edi = dispatch table address
   580                              <1> 			;   ebp = address table address
   581                              <1> 			; Address Table:
   582                              <1> 			;    Offset 0  : open code address
   583                              <1> 			;    Offset 4  : read code address
   584                              <1> 			;    Offset 8  : write code address
   585                              <1> 			;    Offset 12 : close code address
   586                              <1> 			;    Offset 16 : IOCTL code address
   587                              <1> 			;    Offset 20 : initialization code address
   588                              <1> 			;    Offset 24 : description table address
   589                              <1> 			;    Offset 28 : configuration table address
   590                              <1> 			;    Offset 32 : device name address
   591                              <1> 			;    Offset 36 : dispatch table address
   592                              <1> 			;          (for calling kernel-device functions)
   593                              <1> 
   594 000170C0 <res 00000040>      <1> IDEV_NAME:  resb 8*NUMIDEV 
   595                              <1> 			; 8 byte names of installable device drivers
   596                              <1> 
   597 00017100 <res 00000008>      <1> IDEV_TYPE:  resb NUMIDEV ; Driver type of installable device drivers
   598 00017108 <res 00000008>      <1> IDEV_FLAGS: resb NUMIDEV ; Device access parameters for installable
   599                              <1>                          ; device drivers (These values are set while
   600                              <1> 			 ; the device driver is being loaded.)
   601 00017110 <res 00000020>      <1> IDEV_OADDR: resd NUMIDEV ; open function addr for installable dev driver
   602 00017130 <res 00000020>      <1> IDEV_CADDR: resd NUMIDEV ; close function addr for installable dev driver
   603 00017150 <res 00000020>      <1> IDEV_RADDR: resd NUMIDEV ; read function addr for installable dev driver
   604 00017170 <res 00000020>      <1> IDEV_WADDR: resd NUMIDEV ; write function addr for installable dev driver
   605                              <1> 	
   606                              <1> ; 08/10/2016	
   607                              <1> ; 07/10/2016
   608                              <1> ; Device Open and Access parameters
   609 00017190 <res 0000001E>      <1> DEV_ACCESS:	 resb NUMOFDEVICES   ; bit 0 = accessable by normal users
   610                              <1> 				     ; bit 1 = read access permission
   611                              <1> 				     ; bit 2 = write access permission
   612                              <1> 				     ; bit 3 = IOCTL permission to users
   613                              <1> 				     ; bit 4 = block device if it is set	
   614                              <1> 				     ; bit 5 = 16 bit or 1024 byte data
   615                              <1> 				     ; bit 6 = 32 bit or 2048 byte data
   616                              <1> 				     ; bit 7 = installable device driver
   617 000171AE <res 0000001E>      <1> DEV_R_OWNER:	 resb NUMOFDEVICES   ; Reading owner no (u.uid) of devices		
   618 000171CC <res 0000001E>      <1> DEV_R_OPENCOUNT: resb NUMOFDEVICES   ; Reading open count 
   619 000171EA <res 0000001E>      <1> DEV_W_OWNER:	 resb NUMOFDEVICES   ; Writing owner no (u.uid) of devices		
   620 00017208 <res 0000001E>      <1> DEV_W_OPENCOUNT: resb NUMOFDEVICES   ; Writing open count
   621 00017226 <res 0000001E>      <1> DEV_DRIVER:	 resb NUMOFDEVICES   ; device driver number (1 to 7Fh)
   622                              <1> 				     ; *if bit 7 is set (80 to FFh)
   623                              <1> 				     ; *if it is installable device driver
   624                              <1> 				     ; *index (0 to 7Fh)
   625                              <1> 				     ; otherwise it is kernel device index
   626 00017244 <res 0000001E>      <1> DEV_OPENMODE:	 resb NUMOFDEVICES   ; 1 = read mode
   627                              <1> 				     ; 2 = write mode
   628                              <1> 				     ; 3 = read & write 	  
   629                              <1> 				     ; 0 = not open (free)		
   630 00017262 <res 00000078>      <1> DEV_NAME_PTR:    resd NUMOFDEVICES   ; pointers to name addresses of drivers
   631                              <1> 				     ; Address base: KDEV_NAME+		
   632                              <1> 				     ; or IDEV_NAME+
   633 000172DA <res 00000078>      <1> DEV_R_POINTER:	 resd NUMOFDEVICES   ; reading pointer, writing pointer	
   634 00017352 <res 00000078>      <1> DEV_W_POINTER:	 resd NUMOFDEVICES   ; sector number if block device
   635                              <1> 				     ; character offset if char device
   636 000173CA <res 00000002>      <1> alignb 4
   637                              <1> 
   638                              <1> ; 06/10/2016
   639                              <1> ; Open File Parameters
   640 000173CC <res 00000028>      <1> OF_FCLUSTER:	resd OPENFILES  ; First clusters of open files
   641 000173F4 <res 0000000A>      <1> OF_DRIVE:	resb OPENFILES  ; Logical DOS drive numbers of open files 
   642 000173FE <res 0000000A>      <1> OF_MODE:	resb OPENFILES  ; Open mode (1 = read, 2 = write, 3 = r&w) 
   643 00017408 <res 0000000A>      <1> OF_STATUS:	resb OPENFILES  ; (bit 0 = read, bit 1 = write)
   644 00017412 <res 0000000A>      <1> OF_OPENCOUNT:	resb OPENFILES  ; Open counts of open files
   645 0001741C <res 00000028>      <1> OF_POINTER:	resd OPENFILES	; File seek/read/write pointer
   646 00017444 <res 00000028>      <1> OF_SIZE:	resd OPENFILES	; File sizes of open files (in bytes)
   647 0001746C <res 00000028>      <1> OF_DIRFCLUSTER:	resd OPENFILES  ; Directory First Clusters of open files
   648 00017494 <res 00000028>      <1> OF_DIRCLUSTER:	resd OPENFILES  ; Directory (Entry) Clusters of open files
   649 000174BC <res 00000028>      <1> OF_VOLUMEID:	resd OPENFILES  ; Vol ID for removable drives of open files
   650 000174E4 <res 00000028>      <1> OF_CCLUSTER:	resd OPENFILES  ; Current clusters of open files
   651 0001750C <res 00000028>      <1> OF_CCINDEX:	resd OPENFILES  ; Cluster index numbers of current clusters
   652                              <1> ; 24/10/2016
   653 00017534 <res 00000014>      <1> OF_DIRENTRY:	resw OPENFILES  ; Directory entry index no. in dir cluster 
   654                              <1> 				; Sector index = entry index / 16
   655                              <1> ;alignb 2
   656                              <1> 
   657 00017548 <res 00000060>      <1> DTA:		resd 24		; Find First File data transfer area
   658                              <1> 
   659                              <1> ; 19/12/2016
   660 000175A8 <res 00000001>      <1> tcallback:	resb 1		; Timer callback method flag for 'systimer'
   661 000175A9 <res 00000001>      <1> trtc:		resb 1		; Timer interrupt type flag for 'systimer'
   662                              <1> ; 20/02/2017
   663 000175AA <res 00000001>      <1> no_page_swap:	resb 1		; Swap lock for Signal Response Byte pages 
   664                              <1> ;;15/01/2017
   665                              <1> ; 02/01/2017
   666                              <1> ;;intflg:	resb 1		; software interrupt in progress signal
   667                              <1> 				; (for timer interrupt)
   668                              <1> 
   669 000175AB <res 00000001>      <1> alignb 4
   670                              <1> ; 13/04/2017
   671 000175AC <res 0000001E>      <1> DEV_INTR:	resb NUMOFDEVICES ; Device Interrupt (IRQ) number + 1	
   672                              <1> 				; (0= not available, 1= IRQ 0, 16= IRQ 15)
   673 000175CA <res 00000040>      <1> DEV_INT_HNDLR:	resd 16		; Device Interrupt Handler addr, if > 0 	
   674                              <1> 
   675                              <1> 
   676                              <1> ;alignb 4
   677                              <1> 
   678                              <1> ; 26/02/2017 ; IRQ Callback parameters ('syscalbac')
   679                              <1> ;Index: ; 0 to 8
   680                              <1> ;	0 = IRQ3, 1 = IRQ4, 2 = IRQ5, 3 = IRQ7
   681                              <1> ;	4 = IRQ9, 5 = IRQ10, 6 = IRQ11, 7 = IRQ12, 8 = IRQ13  
   682 0001760A <res 00000009>      <1> IRQ.owner:	resb 9		; owner, 0 = free, >0 = [u.uno]
   683 00017613 <res 00000009>      <1> IRQ.dev:	resb 9		; 0 = default/kernel, >0 = device number
   684 0001761C <res 00000009>      <1> IRQ.method:	resb 9 		; 0 = Signal Response Byte, 1 = Callback
   685 00017625 <res 00000009>      <1> IRQ.srb:	resb 9 		; Signal Response/Return Byte value
   686 0001762E <res 00000024>      <1> IRQ.addr:	resd 9		; Rignal Response Byte address (physical)
   687                              <1> 				; or Callback service address (virtual)
   688                              <1> ; 28/02/2017
   689 00017652 <res 00000004>      <1> IRQ_cr3:	resd 1		; for saving cr3 register in IRQ handler
   690 00017656 <res 00000001>      <1> IRQnum:		resb 1		; IRQ number for IRQ handler (trdosk8.s)
   691                              <1> 
   692                              <1> ; 10/04/2017
   693                              <1> ; 03/04/2017
   694                              <1> ; UNINITIALIZED AUDIO DATA
   695 00017657 <res 00000001>      <1> alignb 4
   696 00017658 <res 00000001>      <1> audio_pci:	resb 1
   697 00017659 <res 00000001>      <1> audio_device:	resb 1
   698 0001765A <res 00000001>      <1> audio_mode:	resb 1
   699 0001765B <res 00000001>      <1> audio_intr:	resb 1
   700 0001765C <res 00000001>      <1> audio_busy:	resb 1  ; Busy flag for audio irq ; 21/04/2017
   701 0001765D <res 00000001>      <1> audio_reserved: resb 1
   702 0001765E <res 00000002>      <1> audio_io_base:	resw 1 	; Base I/O address of audio device
   703 00017660 <res 00000004>      <1> audio_dev_id:	resd 1	; BUS/DEV/FN ; 00000000BBBBBBBBDDDDDFFF00000000
   704 00017664 <res 00000004>      <1> audio_vendor:	resd 1
   705 00017668 <res 00000004>      <1> audio_stats_cmd: resd 1
   706                              <1> ;
   707 0001766C <res 00000004>      <1> audio_buffer:	resd 1	; virtual address of user's audio buffer
   708 00017670 <res 00000004>      <1> audio_p_buffer:	resd 1	; Physical address of user's audio buffer
   709 00017674 <res 00000004>      <1> audio_buff_size: resd 1 ; user's audio buffer size (half buffer size) 
   710 00017678 <res 00000004>      <1> audio_dma_buff: resd 1  ; dma buffer address
   711 0001767C <res 00000004>      <1> audio_dmabuff_size: resd 1 ; dma buffer size (2 * half buffer size)
   712 00017680 <res 00000001>      <1> audio_flag:	resb 1  ; dma buffer flag (1st half = 0, 2nd half = 1)
   713 00017681 <res 00000001>      <1> audio_user:	resb 1	; user number of the owner
   714 00017682 <res 00000001>      <1> audio_cb_mode:	resb 1	; 0 = signal response byte method
   715                              <1> 			; 1 = callback method
   716                              <1> 			; 2 = s.r.b. method with auto increment
   717 00017683 <res 00000001>      <1> audio_srb:	resb 1	; signal response byte value
   718 00017684 <res 00000004>      <1> audio_cb_addr:	resd 1  ; callback service address or s.r.b. address
   719                              <1> 			; (s.r.b. addr is physical, cbs addr is virtual)
   720                              <1> 
   721 00017688 <res 00000001>      <1> audio_bps:	resb 1  ; selected mode: 8 bit, 16 bit
   722 00017689 <res 00000001>      <1> audio_stmo:	resb 1	; selected mode: mono /stereo
   723 0001768A <res 00000002>      <1> audio_freq: 	resw 1	; sampling rate
   724                              <1> 
   725                              <1> ; 21/04/2017
   726 0001768C <res 00000001>      <1> audio_play_cmd: resb 1  ; Play/Stop command (1 = play, 0 = stop)
   727                              <1> audio_civ: ; 28/05/2017 ; Current Buffer Index (AC'97)
   728 0001768D <res 00000001>      <1> audio_flag_eol:	resb 1  ; End of Link status (vt8233, EOL/FLAG)
   729                              <1> 
   730                              <1> audio_master_volume:
   731 0001768E <res 00000001>      <1> audio_master_volume_l: resb 1 ; sound volume (lineout) left channel
   732 0001768F <res 00000001>      <1> audio_master_volume_r: resb 1 ; sound volume (lineout) right channel
   733                              <1> 
   734                              <1> alignb 4
   735                              <1> ; 28/05/2017
   736                              <1> ; AC'97 Audio Controller Base Adress Registers
   737 00017690 <res 00000002>      <1> NAMBAR:		resw 1	; Native Audio Mixer Base Address
   738 00017692 <res 00000002>      <1> NABMBAR:	resw 1	; Native Audio Bus Mastering Base Address
   739                              <1> 	
   740                              <1> ;alignb 4
   741                              <1> ; 21/04/2017
   742 00017694 <res 00000400>      <1> audio_bdl_buff:	resd 32*8  ; VT8233 (AC97) BDL Buffer Size
   743                              <1> ; 12/05/2017
   744 00017A94 <res 00000004>      <1> base_addr:	resd 1	; 'direct_memory_access' (memory.s)
   745                              <1> 
   746                              <1> ; 28/08/2017
   747                              <1> ; 20/08/2017
   748 00017A98 <res 00000001>      <1> 		resb 1  ;
   749 00017A99 <res 00000001>      <1> dma_user:	resb 1	; user number for sysdma
   750 00017A9A <res 00000001>      <1> dma_channel:	resb 1	; dma channel for sysdma
   751 00017A9B <res 00000001>      <1> dma_mode:	resb 1  ; dma mode for sysdma	
   752 00017A9C <res 00000004>      <1> dma_addr:	resd 1	; dma buffer physical addr for sysdma
   753 00017AA0 <res 00000004>      <1> dma_size:	resd 1  ; dma buffer size (in bytes) for sysdma
   754 00017AA4 <res 00000004>      <1> dma_start:	resd 1  ; dma start address for sysdma
   755 00017AA8 <res 00000004>      <1> dma_count:	resd 1  ; dma count (in bytes) for sysdma 
   756                              <1> 
   757 00017AAC <res 00008554>      <1> alignb 65536
   758                              <1> ; 09/08/2017
   759                              <1> ; 12/05/2017
   760 00020000 <res 00010000>      <1> sb16_dma_buffer: resb 65536 ; DMA buffer for sb16 audio playing.
  3587                                  ; 24/01/2016
  3588                                  %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: 28/02/2017
     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 00030000 <res 00000002>      <1> 	i.flgs:	 resw 1
    37 00030002 <res 00000001>      <1> 	i.nlks:	 resb 1
    38 00030003 <res 00000001>      <1> 	i.uid:	 resb 1
    39                              <1>         ;i.size:  resw 1 ; size
    40 00030004 <res 00000002>      <1> 	resw 1 ; 29/04/2016
    41 00030006 <res 00000010>      <1> 	i.dskp:	 resw 8 ; 16 bytes
    42 00030016 <res 00000004>      <1> 	i.ctim:	 resd 1
    43 0003001A <res 00000004>      <1> 	i.mtim:	 resd 1
    44 0003001E <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> 	; 19/12/2016
    50                              <1> 	; 21/05/2016
    51                              <1> 	; 19/05/2016 - TRDOS 386 (TRDOS v2.0)
    52                              <1> 	; 06/05/2015 - Retro UNIX 386 v1
    53                              <1> 	; 11/03/2013 - 05/02/2014 (Retro UNIX 8086 v1)
    54                              <1> 	;Derived from UNIX v1 source code 'proc' structure (ux).
    55                              <1> 	;p.
    56                              <1> 	
    57 00030020 <res 00000020>      <1>         p.pid:   resw nproc
    58 00030040 <res 00000020>      <1>         p.ppid:  resw nproc
    59 00030060 <res 00000020>      <1>         p.break: resw nproc
    60 00030080 <res 00000010>      <1>         p.ttyc:  resb nproc ; console tty in Retro UNIX 8086 v1.
    61 00030090 <res 00000010>      <1> 	p.waitc: resb nproc ; waiting channel in Retro UNIX 8086 v1.
    62 000300A0 <res 00000010>      <1> 	p.link:	 resb nproc
    63 000300B0 <res 00000010>      <1> 	p.stat:	 resb nproc
    64                              <1> 
    65                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 feature only !) 
    66 000300C0 <res 00000040>      <1> 	p.upage: resd nproc ; Physical address of the process's
    67                              <1> 			    ; 'user' structure
    68                              <1> 	; 21/05/2016	
    69                              <1> 	; 19/05/2016 (TRDOS 386 feature only!)
    70 00030100 <res 00000010>      <1> 	p.timer: resb nproc ; number of timer events of the processs
    71                              <1> 
    72                              <1> 	; 19/12/2016
    73 00030110 <res 00000040>      <1> 	p.tcb:	resd nproc ; timer callback service address (if > 0)
    74                              <1> 			  		 			 	  
    75                              <1> P_SIZE	equ $ - process
    76                              <1> 
    77                              <1> ; fsp table (original UNIX v1)
    78                              <1> ;
    79                              <1> ;Entry
    80                              <1> ;          15                                      0
    81                              <1> ;  1     |---|---------------------------------------|
    82                              <1> ;        |r/w|       i-number of open file           |
    83                              <1> ;        |---|---------------------------------------| 
    84                              <1> ;        |               device number               |
    85                              <1> ;        |-------------------------------------------|
    86                              <1> ;    (*) | offset pointer, i.e., r/w pointer to file |
    87                              <1> ;        |-------------------------------------------| 
    88                              <1> ;        |  flag that says    | number of processes  |
    89                              <1> ;        |   file deleted     | that have file open  |
    90                              <1> ;        |-------------------------------------------| 
    91                              <1> ;  2     |                                           |
    92                              <1> ;        |-------------------------------------------| 
    93                              <1> ;        |                                           |
    94                              <1> ;        |-------------------------------------------|
    95                              <1> ;        |                                           |
    96                              <1> ;        |-------------------------------------------|
    97                              <1> ;        |                                           |
    98                              <1> ;        |-------------------------------------------| 
    99                              <1> ;  3     |                                           | 
   100                              <1> ;        |                                           |  
   101                              <1> ;
   102                              <1> ; (*) Retro UNIX 386 v1 modification: 32 bit offset pointer 
   103                              <1> 
   104                              <1> 
   105                              <1> ; 15/04/2015
   106 00030150 <res 000001F4>      <1> fsp:	 resb nfiles * 10 ; 11/05/2015 (8 -> 10)
   107 00030344 <res 00000002>      <1> idev:	 resw 1 ; device number is 1 byte in Retro UNIX 8086 v1 !
   108 00030346 <res 00000002>      <1> cdev:    resw 1 ; device number is 1 byte in Retro UNIX 8086 v1 !
   109                              <1> ; 18/05/2015
   110                              <1> ; 26/04/2013 device/drive parameters (Retro UNIX 8086 v1 feature only!)
   111                              <1> ; 'UNIX' device numbers (as in 'cdev' and 'u.cdrv')
   112                              <1> ;	0 -> root device (which has Retro UNIX 8086 v1 file system)
   113                              <1> ; 	1 -> mounted device (which has Retro UNIX 8086 v1 file system)
   114                              <1> ; 'Retro UNIX 8086 v1' device numbers: (for disk I/O procedures)
   115                              <1> ;	0 -> fd0 (physical drive, floppy disk 1), physical drive number = 0
   116                              <1> ;	1 -> fd1 (physical drive, floppy disk 2), physical drive number = 1
   117                              <1> ;	2 -> hd0 (physical drive, hard disk 1), physical drive number = 80h
   118                              <1> ;	3 -> hd1 (physical drive, hard disk 2), physical drive number = 81h
   119                              <1> ;	4 -> hd2 (physical drive, hard disk 3), physical drive number = 82h
   120                              <1> ;	5 -> hd3 (physical drive, hard disk 4), physical drive number = 83h
   121 00030348 <res 00000001>      <1> rdev:	 resb 1 ; root device number ; Retro UNIX 8086 v1 feature only!
   122                              <1> 	        ; as above, for physical drives numbers in following table
   123 00030349 <res 00000001>      <1> mdev:	 resb 1 ; mounted device number ; Retro UNIX 8086 v1 feature only!
   124                              <1> ; 15/04/2015
   125 0003034A <res 00000001>      <1> active:	 resb 1 
   126 0003034B <res 00000001>      <1> 	 resb 1 ; 09/06/2015
   127 0003034C <res 00000002>      <1> mnti:	 resw 1
   128 0003034E <res 00000002>      <1> mpid:	 resw 1
   129 00030350 <res 00000002>      <1> rootdir: resw 1
   130                              <1> 
   131                              <1> ; 21/05/2016 - TRDOS 386 (TRDOS v2.0) - priority levels, 3 run queues 
   132                              <1> runq:
   133 00030352 <res 00000002>      <1> runq_event:	 resw 1 ; high priority, 'run for event'            ; 2
   134 00030354 <res 00000002>      <1> runq_normal:	 resw 1 ; normal/regular priority, 'run as reqular' ; 1
   135 00030356 <res 00000002>      <1> runq_background: resw 1 ; low priority, 'run on background'         ; 0
   136                              <1> ;
   137 00030358 <res 00000001>      <1> imod:	 resb 1
   138 00030359 <res 00000001>      <1> smod:	 resb 1
   139 0003035A <res 00000001>      <1> mmod:	 resb 1
   140 0003035B <res 00000001>      <1> sysflg:	 resb 1
   141                              <1> 
   142                              <1> alignb 4
   143                              <1> 
   144                              <1> user:
   145                              <1> 	; 13/01/2017
   146                              <1> 	; 19/12/2016
   147                              <1> 	; 21/05/2016 - TRDOS 386 (TRDOS v2.0) 
   148                              <1> 	; 	       [u.pri] usage method modification
   149                              <1> 	; 04/12/2015 
   150                              <1> 	; 18/10/2015
   151                              <1> 	; 12/10/2015
   152                              <1> 	; 21/09/2015
   153                              <1> 	; 24/07/2015
   154                              <1> 	; 16/06/2015
   155                              <1> 	; 09/06/2015
   156                              <1> 	; 11/05/2015
   157                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit modifications)
   158                              <1> 	; 10/10/2013
   159                              <1> 	; 11/03/2013. 
   160                              <1> 	;Derived from UNIX v1 source code 'user' structure (ux).
   161                              <1> 	;u.
   162                              <1> 
   163 0003035C <res 00000004>      <1> 	u.sp:	  resd 1 ; esp (kernel stack at the beginning of 'sysent')
   164 00030360 <res 00000004>      <1> 	u.usp:	  resd 1 ; esp (kernel stack points to user's registers)
   165 00030364 <res 00000004>      <1> 	u.r0:	  resd 1 ; eax
   166 00030368 <res 00000002>      <1> 	u.cdir:	  resw 1
   167 0003036A <res 0000000A>      <1> 	u.fp:	  resb 10
   168 00030374 <res 00000004>      <1> 	u.fofp:	  resd 1
   169 00030378 <res 00000004>      <1> 	u.dirp:	  resd 1
   170 0003037C <res 00000004>      <1> 	u.namep:  resd 1
   171 00030380 <res 00000004>      <1> 	u.off:	  resd 1
   172 00030384 <res 00000004>      <1> 	u.base:	  resd 1
   173 00030388 <res 00000004>      <1> 	u.count:  resd 1
   174 0003038C <res 00000004>      <1> 	u.nread:  resd 1
   175 00030390 <res 00000004>      <1> 	u.break:  resd 1 ; break
   176 00030394 <res 00000002>      <1> 	u.ttyp:	  resw 1 
   177                              <1> 	; 10/01/2017 (TRDOS 386, relocation and dword alignment)
   178                              <1> 	; tty number (rtty, rcvt, wtty)
   179 00030396 <res 00000001>      <1> 	u.ttyn:	  resb 1 ; 28/07/2013 - Retro Unix 8086 v1 feature only !
   180 00030397 <res 00000001>      <1> 	u.resb:   resb 1 ; 10/01/2017 (TRDOS 386, temporary)
   181 00030398 <res 00000010>      <1> 	u.dirbuf: resb 16 ; 04/12/2015 (10 -> 16) 
   182                              <1> 	;u.pri:	  resw 1 ; 14/02/2014
   183 000303A8 <res 00000001>      <1> 	u.quant:  resb 1 ; Retro UNIX 8086 v1 Feature only ! (uquant)
   184 000303A9 <res 00000001>      <1> 	u.pri:	  resb 1 ; Modification: 21/05/2016 (priority levels: 0, 1, 2)
   185 000303AA <res 00000002>      <1> 	u.intr:	  resw 1
   186 000303AC <res 00000002>      <1> 	u.quit:	  resw 1
   187                              <1> 	;u.emt:	  resw 1 ; 10/10/2013
   188                              <1> 	;u.ilgins: resw 1 ; 10/01/2017
   189 000303AE <res 00000002>      <1> 	u.cdrv:	  resw 1 ; cdev
   190 000303B0 <res 00000001>      <1> 	u.uid:	  resb 1 ; uid
   191 000303B1 <res 00000001>      <1> 	u.ruid:	  resb 1
   192 000303B2 <res 00000001>      <1> 	u.bsys:	  resb 1
   193 000303B3 <res 00000001>      <1> 	u.uno:	  resb 1
   194 000303B4 <res 00000004>      <1>         u.upage:  resd 1 ; 16/04/2015 - Retro Unix 386 v1 feature only !
   195 000303B8 <res 00000004>      <1> 	u.pgdir:  resd 1 ; 09/03/2015 (page dir addr of process)
   196 000303BC <res 00000004>      <1> 	u.ppgdir: resd 1 ; 06/05/2015 (page dir addr of the parent process)
   197 000303C0 <res 00000004>      <1> 	u.pbase:  resd 1 ; 20/05/2015 (physical base/transfer address)
   198 000303C4 <res 00000002>      <1> 	u.pcount: resw 1 ; 20/05/2015 (byte -transfer- count for page)
   199                              <1> 	;u.pncount: resw 1 
   200                              <1> 		; 16/06/2015 (byte -transfer- count for page, 'namei', 'mkdir')
   201                              <1> 	;u.pnbase:  resd 1 
   202                              <1> 		; 16/06/2015 (physical base/transfer address, 'namei', 'mkdir')
   203                              <1> 			 ; 09/06/2015
   204 000303C6 <res 00000001>      <1> 	u.kcall:  resb 1 ; The caller is 'namei' (dskr) or 'mkdir' (dskw) sign		
   205 000303C7 <res 00000001>      <1> 	u.brwdev: resb 1 ; Block device number for direct I/O (bread & bwrite)
   206                              <1> 			 ; 24/07/2015 - 24/06/2015
   207                              <1> 	;u.args:  resd 1 ; arguments list (line) offset from start of [u.upage]
   208                              <1> 			 ; (arg list/line is from offset [u.args] to 4096 in [u.upage])
   209                              <1> 			 ; ([u.args] points to argument count -argc- address offset)
   210                              <1>  			 ; 24/06/2015	  	
   211                              <1> 	;u.core:  resd 1 ; physical start address of user's memory space (for sys exec)
   212                              <1> 	;u.ecore: resd 1 ; physical end address of user's memory space (for sys exec)
   213                              <1> 	; last error number
   214 000303C8 <res 00000004>      <1> 	u.error:  resd 1 ; 28/07/2013 - 09/03/2015 
   215                              <1> 		        ; Retro UNIX 8086/386 v1 feature only!
   216                              <1> 			; 21/09/2015 (debugging - page fault analyze)
   217 000303CC <res 00000004>      <1> 	u.pfcount: resd 1 ; page fault count for (this) process (for sys geterr)
   218                              <1> 		; 19/12/2016 (TRDOS 386)	
   219 000303D0 <res 00000004>      <1> 	u.tcb:	  resd 1 ; Timer callback address/flag which will be used by timer int
   220                              <1> 		; 13/01/2017 (TRDOS 386)
   221 000303D4 <res 00000001>      <1> 	u.t_lock: resb 1 ; Timer interrupt (callback) lock (unlocked by 'sysrele')
   222 000303D5 <res 00000001>      <1> 	u.t_mode: resb 1 ; running mode during timer interrupt (0= system, 0FFh= user)
   223                              <1> 		; 26/02/2017 (TRDOS 386)
   224 000303D6 <res 00000001>      <1> 	u.irqc:	  resb 1  ; Count of IRQ callback services (IRQs in use)
   225                              <1> 		; 28/02/2017 (TRDOS 386) 
   226 000303D7 <res 00000001>      <1> 	u.irqwait: resb 1 ; IRQ waiting for callback service flag (IRQ number, If > 0)
   227 000303D8 <res 00000001>      <1> 	u.r_lock:  resb 1 ; 'IRQ callback service is in progress' flag (IRQ lock)
   228 000303D9 <res 00000001>      <1> 	u.r_mode:  resb 1 ; running mode during hadware interrupt	
   229                              <1> 		; 27/02/2017 (TRDOS 386) 
   230 000303DA <res 00000001>      <1> 	u.fpsave: resb 1  ; TRDOS 386, 'save/restore FPU registers' flag
   231 000303DB <res 00000001>      <1> alignb 4
   232 000303DC <res 0000005E>      <1> 	u.fpregs: resb 94 ; 94 byte area for saving and restoring FPU registers	
   233                              <1> 
   234 0003043A <res 00000002>      <1> alignb 4
   235                              <1> 
   236                              <1> U_SIZE	equ $ - user
   237                              <1> 
   238                              <1> ; 18/10/2015 - Retro UNIX 386 v1 (local variables for 'namei' and 'sysexec')
   239 0003043C <res 00000004>      <1> pcore:  resd 1  ; physical start address of user's memory space (for sys exec)
   240 00030440 <res 00000004>      <1> ecore:  resd 1  ; physical address of user's stack/last page (for sys exec)
   241 00030444 <res 00000004>      <1> nbase:	resd 1	; physical base address for 'namei' & 'sysexec'
   242 00030448 <res 00000002>      <1> ncount: resw 1	; remain byte count in page for 'namei' & 'sysexec'
   243 0003044A <res 00000002>      <1> argc:	resw 1	; argument count for 'sysexec'
   244 0003044C <res 00000004>      <1> argv:	resd 1	; argument list (recent) address for 'sysexec'
   245                              <1> 
   246                              <1> ; 03/06/2015 - Retro UNIX 386 v1 Beginning
   247                              <1> ; 07/04/2013 - 31/07/2013 - Retro UNIX 8086 v1
   248 00030450 <res 00000001>      <1> rw: 	 resb 1 ;; Read/Write sign (iget)
   249                              <1> 
   250                              <1> ;alignb 4
   251                              <1> 
   252                              <1> ; 24/04/2016
   253 00030451 <res 00000004>      <1> ii:		resd 1 ; first cluster of the program file
   254 00030455 <res 00000004>      <1> i.size:		resd 1 ; size of the program file
  3589                                  
  3590 00030459 <res 00000003>          alignb 4
  3591                                  
  3592                                  ; 23/05/2016 (TRDOS 386)
  3593                                  ; 14/10/2015 (Retro UNIX 386 v1, 'unix386.s')
  3594 0003045C <res 00000004>          cr3reg:	 resd 1  ; cr3 register content at the beginning of the timer
  3595                                  		 ; (or RTC) interrupt handler.
  3596                                  
  3597                                  ; 10/12/2016 (callback)
  3598                                  ; 10/06/2016
  3599                                  ; 19/05/2016
  3600                                  ; 18/05/2016 - TRDOS 386 feature only !
  3601 00030460 <res 00000100>          timer_set: resd 16*4   ; 256 bytes memory space for 16 timer events
  3602                                  	; Timer Event Structure: (max. 16 timer events, 16*16 bytes)
  3603                                  	;       Owner:	        resb 1 ; 0 = free
  3604                                  	;		  	       ;>0 = process number (u.uno)
  3605                                  	;	Callback:	resb 1 ; 0 = response byte address (phy)
  3606                                  	;				 1 = callback address (virtual)				
  3607                                  	;	Interrupt:      resb 1 ; 0 = Timer interrupt (or none)
  3608                                  	;		   	       ; 1 = Real Time Clock interrupt 
  3609                                  	;	Response:       resb 1 ; 0 to 255, signal return value
  3610                                  	;	Count Limit:	resd 1 ; count of ticks (total/set)
  3611                                  	;	Current Count: 	resd 1 ; count of ticks (current)
  3612                                  	;	Response Addr:  resd 1 ; response byte (pointer) address
  3613                                  	;			       ; (or callback -user service- address)	
  3614                                  
  3615                                  ;; Memory (swap) Data (11/03/2015)
  3616                                  ; 09/03/2015
  3617 00030560 <res 00000002>          swpq_count: resw 1 ; count of pages on the swap queue
  3618 00030562 <res 00000004>          swp_drv:    resd 1 ; logical drive description table address of the swap drive/disk
  3619 00030566 <res 00000004>          swpd_size:  resd 1 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
  3620 0003056A <res 00000004>          swpd_free:  resd 1 ; free page blocks (4096 bytes) on swap disk/drive (logical)
  3621 0003056E <res 00000004>          swpd_next:  resd 1 ; next free page block
  3622 00030572 <res 00000004>          swpd_last:  resd 1 ; last swap page block	
  3623                                  
  3624 00030576 <res 00000002>          alignb 4
  3625                                  
  3626                                  ; 10/07/2015
  3627                                  ; 28/08/2014
  3628 00030578 <res 00000004>          error_code:	resd 1
  3629                                  ; 29/08/2014
  3630 0003057C <res 00000004>          FaultOffset: 	resd 1
  3631                                  ; 21/09/2015
  3632 00030580 <res 00000004>          PF_Count:	resd 1	; total page fault count
  3633                                  		       	; (for debugging - page fault analyze)
  3634                                  		 	; 'page_fault_handler' (memory.inc)
  3635                                  			; 'sysgeterr' (u9.s)
  3636                                  
  3637                                  ; 29/04/2016 (TRDOS 386 = TRDOS v2.0)
  3638                                  ; 22/08/2015 (Retro UNIX 386 v1)
  3639                                  buffer: 
  3640 00030584 <res 00000008>          	resb	8 
  3641                                  readi_buffer:
  3642 0003058C <res 00000200>          	resb 	512
  3643 0003078C <res 00000008>          	resb	8
  3644                                  writei_buffer:
  3645 00030794 <res 00000200>          	resb	512	
  3646                                  ; 24/10/2016
  3647 00030994 <res 00000008>          	resb	8 
  3648                                  rw_buffer:
  3649 0003099C <res 00000800>          	resb 	2048  ; general purposed, r/w sector buffer
  3650                                  
  3651                                  %if 1
  3652                                  ; 28/11/2020
  3653 0003119C <res 00000001>          pmi32:		resb 1	; (>0) use VESA VBE3 protected mode calls 
  3654 0003119D <res 00000001>          vbe_mode_x:	resb 1  ; VESA VBE3 video bios mode set options
  3655 0003119E <res 00000002>          video_mode:	resw 1	; VESA VBE3 video mode (with option flags)
  3656                                  ; 30/11/2020
  3657 000311A0 <res 00000004>          vbe3bios_addr:	resd 1	; new (writable mem) address of VBE3 bios
  3658                                  ; 02/12/2020
  3659 000311A4 <res 00000004>          pmid_addr:	resd 1	; PMInfoBlock ('PMID') linear address
  3660                                  ; 06/12/2020
  3661 000311A8 <res 00000002>          mode3stbufsize: resw 1	; video mode 03h video regs/dac/bios state
  3662                                  			; block size in bytes
  3663                                  %endif
  3664                                  
  3665                                  %if 1
  3666                                  ; 10/12/2020
  3667                                  LFB_Info:
  3668 000311AA <res 00000010>          		resb 16	; Linear Frame Buffer info block
  3669                                  
  3670                                  ;24/11/2020 - TRDOS 386 v2.0.3
  3671                                  ; BOCHS/PLEX86 VESA VBE3 MODE INFO extension to TRDOS 386 v2 kernel	
  3672                                  MODE_INFO_LIST:
  3673 000311BA <res 00000044>          		resb 68	; mode + 66 byte VESA vbe3 mode info (4F01h) 
  3674                                  %endif
  3675                                  
  3676                                  bss_end:
  3677                                  
  3678                                  ; 27/12/2013
  3679                                  _end:  ; end of kernel code
