     1                                  ; ****************************************************************************
     2                                  ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Last Update: 06/03/2016
     5                                  ; ----------------------------------------------------------------------------
     6                                  ; Beginning: 04/01/2016
     7                                  ; ----------------------------------------------------------------------------
     8                                  ; Assembler: NASM version 2.11 (trdos386.s)
     9                                  ; ----------------------------------------------------------------------------
    10                                  ; Turkish Rational DOS
    11                                  ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
    12                                  ;
    13                                  ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                                  ; unix386.s (03/01/2016)
    15                                  ;
    16                                  ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    17                                  ; TRDOS2.ASM (09/11/2011)
    18                                  ; 
    19                                  ; Derived from 'IBM PC-XT-286' BIOS source code (1986) 
    20                                  ; ****************************************************************************
    21                                  
    22                                  KLOAD	equ 10000h ; Kernel loading address
    23                                  	; NOTE: Retro UNIX 8086 v1 /boot code loads kernel at 1000h:0000h 
    24                                  KCODE	equ 08h	; Code segment descriptor (ring 0)
    25                                  KDATA	equ 10h	; Data segment descriptor (ring 0)
    26                                  ; 19/03/2015
    27                                  UCODE	equ 1Bh ; 18h + 3h  (ring 3)
    28                                  UDATA	equ 23h ; 20h + 3h  (ring 3)
    29                                  ; 24/03/2015
    30                                  TSS	equ 28h	; Task state segment descriptor (ring 0)
    31                                  ; 19/03/2015
    32                                  CORE	equ 400000h  ; Start of USER's virtual/linear address space 
    33                                  		     ; (at the end of the 1st 4MB)
    34                                  ECORE	equ 0FFC00000h ; End of USER's virtual address space (4GB - 4MB)
    35                                  		     ; ULIMIT = (ECORE/4096) - 1 = 0FFBFFh (in GDT)
    36                                  
    37                                  ; 27/12/2013
    38                                  KEND    equ KLOAD + 65536 ; (28/12/2013) (end of kernel space)
    39                                  
    40                                  ; IBM PC/AT BIOS ----- 10/06/85 (postequ.inc)
    41                                  ;--------- CMOS TABLE LOCATION ADDRESS'S -------------------------------------
    42                                  CMOS_SECONDS	EQU	00H		; SECONDS (BCD)
    43                                  CMOS_SEC_ALARM	EQU	01H		; SECONDS ALARM (BCD)
    44                                  CMOS_MINUTES	EQU	02H		; MINUTES (BCD)
    45                                  CMOS_MIN_ALARM	EQU	03H		; MINUTES ALARM (BCD) 	
    46                                  CMOS_HOURS	EQU	04H		; HOURS (BCD
    47                                  CMOS_HR_ALARM	EQU	005H		; HOURS ALARM   (BCD)
    48                                  CMOS_DAY_WEEK	EQU	06H		; DAY OF THE WEEK  (BCD)
    49                                  CMOS_DAY_MONTH	EQU	07H		; DAY OF THE MONTH (BCD) 
    50                                  CMOS_MONTH	EQU	08H		; MONTH (BCD)
    51                                  CMOS_YEAR	EQU	09H		; YEAR (TWO DIGITS) (BCD)
    52                                  CMOS_CENTURY	EQU	32H		; DATE CENTURY BYTE (BCD)
    53                                  CMOS_REG_A	EQU	0AH		; STATUS REGISTER A
    54                                  CMOS_REG_B	EQU	00BH		; STATUS REGISTER B  ALARM
    55                                  CMOS_REG_C	EQU	00CH		; STATUS REGISTER C  FLAGS
    56                                  CMOS_REG_D	EQU	0DH		; STATUS REGISTER D  BATTERY
    57                                  CMOS_SHUT_DOWN	EQU	0FH		; SHUTDOWN STATUS COMMAND BYTE
    58                                  ;----------------------------------------
    59                                  ;	CMOS EQUATES FOR THIS SYSTEM	;
    60                                  ;-----------------------------------------------------------------------------
    61                                  CMOS_PORT	EQU	070H		; I/O ADDRESS OF CMOS ADDRESS PORT
    62                                  CMOS_DATA	EQU	071H		; I/O ADDRESS OF CMOS DATA PORT
    63                                  NMI		EQU	10000000B	; DISABLE NMI INTERRUPTS MASK -
    64                                  					; HIGH BIT OF CMOS LOCATION ADDRESS
    65                                  
    66                                  ; Memory Allocation Table Address
    67                                  ; 05/11/2014
    68                                  ; 31/10/2014
    69                                  MEM_ALLOC_TBL	equ	100000h		; Memory Allocation Table at the end of
    70                                  					; the 1st 1 MB memory space.
    71                                  					; (This address must be aligned
    72                                  					;  on 128 KB boundary, if it will be
    73                                  					;  changed later.)
    74                                  					; ((lower 17 bits of 32 bit M.A.T.
    75                                  					;   address must be ZERO)).
    76                                  					; ((((Reason: 32 bit allocation 
    77                                  					;     instructions, dword steps)))
    78                                  					; (((byte >> 12 --> page >> 5)))  
    79                                  ;04/11/2014	
    80                                  PDE_A_PRESENT	equ	1		; Present flag for PDE
    81                                  PDE_A_WRITE	equ 	2		; Writable (write permission) flag
    82                                  PDE_A_USER	equ	4		; User (non-system/kernel) page flag
    83                                  ;
    84                                  PTE_A_PRESENT	equ	1		; Present flag for PTE (bit 0)
    85                                  PTE_A_WRITE	equ 	2		; Writable (write permission) flag (bit 1)
    86                                  PTE_A_USER	equ	4		; User (non-system/kernel) page flag (bit 2)
    87                                  PTE_A_ACCESS    equ	32		; Accessed flag (bit 5) ; 09/03/2015
    88                                  
    89                                  ; 17/02/2015 (unix386.s)
    90                                  ; 10/12/2014 - 30/12/2014 (0B000h -> 9000h) (dsectrm2.s)
    91                                  DPT_SEGM equ 09000h  ; FDPT segment (EDD v1.1, EDD v3)
    92                                  ;
    93                                  HD0_DPT	 equ 0	    ; Disk parameter table address for hd0
    94                                  HD1_DPT	 equ 32	    ; Disk parameter table address for hd1
    95                                  HD2_DPT	 equ 64	    ; Disk parameter table address for hd2
    96                                  HD3_DPT	 equ 96	    ; Disk parameter table address for hd3
    97                                  
    98                                  
    99                                  ; FDPT (Phoenix, Enhanced Disk Drive Specification v1.1, v3.0)
   100                                  ;      (HDPT: Programmer's Guide to the AMIBIOS, 1993)
   101                                  ;
   102                                  FDPT_CYLS	equ 0 ; 1 word, number of cylinders
   103                                  FDPT_HDS	equ 2 ; 1 byte, number of heads
   104                                  FDPT_TT		equ 3 ; 1 byte, A0h = translated FDPT with logical values
   105                                  		      ; otherwise it is standard FDPT with physical values 	
   106                                  FDPT_PCMP	equ 5 ; 1 word, starting write precompensation cylinder
   107                                  		      ; (obsolete for IDE/ATA drives)
   108                                  FDPT_CB		equ 8 ; 1 byte, drive control byte
   109                                  			; Bits 7-6 : Enable or disable retries (00h = enable)
   110                                  			; Bit 5	: 1 = Defect map is located at last cyl. + 1
   111                                  			; Bit 4 : Reserved. Always 0
   112                                  			; Bit 3 : Set to 1 if more than 8 heads
   113                                  			; Bit 2-0 : Reserved. Alsways 0
   114                                  FDPT_LZ		equ 12 ; 1 word, landing zone (obsolete for IDE/ATA drives)
   115                                  FDPT_SPT	equ 14 ; 1 byte, sectors per track
   116                                  
   117                                  ; Floppy Drive Parameters Table (Programmer's Guide to the AMIBIOS, 1993)
   118                                  ; (11 bytes long) will be used by diskette handler/bios
   119                                  ; which is derived from IBM PC-AT BIOS (DISKETTE.ASM, 21/04/1986).
   120                                  
   121                                  ; 01/02/2016
   122                                  Logical_DOSDisks equ 90000h + 100h ; 26* 256 = 6656 bytes
   123                                  Directory_Buffer equ 80000h ; max = 64K Bytes
   124                                  FAT_Buffer	 equ 91C00h ; 1536 bytes (3 sectors)
   125                                  ; 15/02/2016
   126                                  Cluster_Buffer	 equ 70000h ; max = 64K Bytes ; buffer for file read & write				 	  		 	  
   127                                  
   128                                  [BITS 16]       ; We need 16-bit intructions for Real mode
   129                                  
   130                                  [ORG 0] 
   131                                  	; 12/11/2014
   132                                  	; Save boot drive number (that is default root drive)
   133 00000000 8816[BAA2]              	mov	[boot_drv], dl ; physical drv number
   134                                  
   135                                  	; Determine installed memory
   136                                  	; 31/10/2014
   137                                  	;
   138 00000004 B801E8                  	mov	ax, 0E801h ; Get memory size 
   139 00000007 CD15                    	int	15h	   ; for large configurations
   140 00000009 7308                    	jnc	short chk_ms
   141 0000000B B488                    	mov	ah, 88h    ; Get extended memory size 
   142 0000000D CD15                    	int	15h
   143                                  	;	   
   144                                  	;mov	al, 17h	; Extended memory (1K blocks) low byte
   145                                  	;out	70h, al ; select CMOS register
   146                                  	;in	al, 71h ; read data (1 byte)
   147                                  	;mov	cl, al
   148                                  	;mov	al, 18h ; Extended memory (1K blocks) high byte
   149                                  	;out	70h, al ; select CMOS register
   150                                  	;in	al, 71h ; read data (1 byte)
   151                                  	;mov	ch, al
   152                                   	;      
   153 0000000F 89C1                    	mov	cx, ax
   154 00000011 31D2                    	xor	dx, dx
   155                                  chk_ms:
   156 00000013 890E[44A5]              	mov	[mem_1m_1k], cx
   157 00000017 8916[46A5]              	mov	[mem_16m_64k], dx
   158                                  	; 05/11/2014
   159                                  	;and	dx, dx
   160                                  	;jz	short L2
   161 0000001B 81F90004                        cmp     cx, 1024
   162 0000001F 7315                    	jnb	short L0
   163                                  		 ; insufficient memory_error	
   164                                  		 ; Minimum 2 MB memory is needed... 
   165                                  	; 05/11/2014
   166                                  	; (real mode error printing)
   167 00000021 FB                      	sti
   168 00000022 BE[D3A3]                	mov	si, msg_out_of_memory
   169 00000025 BB0700                  	mov	bx, 7
   170 00000028 B40E                    	mov	ah, 0Eh	; write tty
   171                                  oom_1:
   172 0000002A AC                      	lodsb
   173 0000002B 08C0                    	or	al, al
   174 0000002D 7404                    	jz	short oom_2
   175 0000002F CD10                    	int	10h
   176 00000031 EBF7                    	jmp	short oom_1
   177                                  oom_2:
   178 00000033 F4                              hlt
   179 00000034 EBFD                    	jmp	short oom_2
   180                                  
   181                                  L0:
   182                                  %include 'diskinit.s' ; 07/03/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - diskinit.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 04/02/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Turkish Rational DOS
    11                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ; diskinit.inc (10/07/2015)
    15                              <1> ;
    16                              <1> ; Derived from 'IBM PC-XT-286' BIOS source code (1986) 
    17                              <1> ; ****************************************************************************
    18                              <1> 
    19                              <1> ; Retro UNIX 386 v1 Kernel - DISKINIT.INC
    20                              <1> ; Last Modification: 10/07/2015
    21                              <1> 
    22                              <1> ; DISK I/O SYSTEM INITIALIZATION - Erdogan Tan (Retro UNIX 386 v1 project)
    23                              <1> 
    24                              <1> ; ///////// DISK I/O SYSTEM STRUCTURE INITIALIZATION ///////////////
    25                              <1> 
    26                              <1> 	; 10/12/2014 - 02/02/2015 - dsectrm2.s
    27                              <1> ;L0:
    28                              <1> 	; 12/11/2014 (Retro UNIX 386 v1 - beginning)
    29                              <1> 	; Detecting disk drives... (by help of ROM-BIOS)
    30 00000036 BA7F00              <1> 	mov	dx, 7Fh
    31                              <1> L1:	
    32 00000039 FEC2                <1> 	inc	dl
    33 0000003B B441                <1> 	mov	ah, 41h ; Check extensions present
    34                              <1> 			; Phoenix EDD v1.1 - EDD v3
    35 0000003D BBAA55              <1> 	mov	bx, 55AAh
    36 00000040 CD13                <1> 	int 	13h
    37 00000042 721A                <1> 	jc	short L2
    38                              <1> 
    39 00000044 81FB55AA            <1> 	cmp	bx, 0AA55h
    40 00000048 7514                <1> 	jne	short L2
    41 0000004A FE06[BDA2]          <1> 	inc	byte [hdc]	; count of hard disks (EDD present)
    42 0000004E 8816[BCA2]          <1>         mov     [last_drv], dl  ; last hard disk number
    43 00000052 BB[40A2]            <1> 	mov	bx, hd0_type - 80h
    44 00000055 01D3                <1> 	add	bx, dx	 
    45 00000057 880F                <1> 	mov	[bx], cl ; Interface support bit map in CX
    46                              <1> 			 ; Bit 0 - 1, Fixed disk access subset ready
    47                              <1> 			 ; Bit 1 - 1, Drv locking and ejecting ready
    48                              <1> 			 ; Bit 2 - 1, Enhanced Disk Drive Support
    49                              <1>                          ;            (EDD) ready (DPTE ready)
    50                              <1> 			 ; Bit 3 - 1, 64bit extensions are present
    51                              <1>                          ;            (EDD-3)
    52                              <1> 			 ; Bit 4 to 15 - 0, Reserved
    53 00000059 80FA83              <1> 	cmp	dl, 83h	 ; drive number < 83h
    54 0000005C 72DB                <1> 	jb	short L1
    55                              <1> L2:
    56                              <1> 	; 23/11/2014
    57                              <1> 	; 19/11/2014
    58 0000005E 30D2                <1> 	xor	dl, dl  ; 0
    59                              <1> 	; 04/02/2016 (esi -> si)
    60 00000060 BE[BEA2]            <1> 	mov	si, fd0_type
    61                              <1> L3:
    62                              <1> 	; 14/01/2015
    63 00000063 8816[BBA2]          <1> 	mov	[drv], dl
    64                              <1> 	;
    65 00000067 B408                <1> 	mov 	ah, 08h ; Return drive parameters
    66 00000069 CD13                <1> 	int	13h	
    67 0000006B 7210                <1> 	jc	short L4
    68                              <1> 		; BL = drive type (for floppy drives)
    69                              <1> 		; DL = number of floppy drives
    70                              <1> 		;		
    71                              <1> 		; ES:DI = Address of DPT from BIOS
    72                              <1> 		;
    73 0000006D 881C                <1> 	mov	[si], bl ;  Drive type
    74                              <1> 			; 4 = 1.44 MB, 80 track, 3 1/2"
    75                              <1> 	; 14/01/2015
    76 0000006F E8A202              <1> 	call	set_disk_parms
    77                              <1> 	; 10/12/2014
    78 00000072 81FE[BEA2]          <1> 	cmp	si, fd0_type
    79 00000076 7705                <1> 	ja	short L4
    80 00000078 46                  <1> 	inc	si ; fd1_type
    81 00000079 B201                <1> 	mov	dl, 1
    82 0000007B EBE6                <1> 	jmp	short L3
    83                              <1> L4:
    84                              <1> 	; Older BIOS (INT 13h, AH = 48h is not available)
    85 0000007D B27F                <1> 	mov	dl, 7Fh
    86                              <1> 	; 24/12/2014 (Temporary)
    87 0000007F 803E[BDA2]00        <1> 	cmp	byte [hdc], 0 ; EDD present or not ?	
    88 00000084 0F879000            <1>         ja      L10       ; yes, all fixed disk operations
    89                              <1> 			  ; will be performed according to
    90                              <1> 			  ; present EDD specification
    91                              <1> L6:
    92 00000088 FEC2                <1> 	inc 	dl
    93 0000008A 8816[BBA2]          <1>         mov     [drv], dl
    94 0000008E 8816[BCA2]          <1>         mov     [last_drv], dl ; 14/01/2015
    95 00000092 B408                <1> 	mov 	ah, 08h ; Return drive parameters
    96 00000094 CD13                <1> 	int	13h	; (conventional function)
    97 00000096 0F828201            <1>         jc      L13	; fixed disk drive not ready
    98 0000009A 8816[BDA2]          <1>         mov     [hdc], dl ; number of drives
    99                              <1> 	;; 14/01/2013
   100                              <1> 	;;push	cx
   101 0000009E E87302              <1> 	call	set_disk_parms
   102                              <1> 	;;pop	cx
   103                              <1> 	;
   104                              <1> 	;;and	cl, 3Fh	 ; sectors per track (bits 0-6)
   105 000000A1 8A16[BBA2]          <1>         mov     dl, [drv]
   106 000000A5 BB0401              <1> 	mov	bx, 65*4 ; hd0 parameters table (INT 41h)	
   107 000000A8 80FA80              <1> 	cmp	dl, 80h
   108 000000AB 7603                <1> 	jna	short L7
   109 000000AD 83C314              <1> 	add	bx, 5*4	 ; hd1 parameters table (INT 46h)
   110                              <1> L7:	
   111 000000B0 31C0                <1> 	xor	ax, ax
   112 000000B2 8ED8                <1> 	mov	ds, ax
   113 000000B4 8B37                <1>         mov     si, [bx]
   114 000000B6 8B4702              <1>         mov     ax, [bx+2] 
   115 000000B9 8ED8                <1> 	mov	ds, ax
   116 000000BB 3A4C0E              <1>         cmp     cl, [si+FDPT_SPT] ; sectors per track 
   117 000000BE 0F855601            <1>         jne     L12 ; invalid FDPT
   118 000000C2 BF0000              <1> 	mov	di, HD0_DPT
   119 000000C5 80FA80              <1> 	cmp	dl, 80h
   120 000000C8 7603                <1> 	jna	short L8
   121 000000CA BF2000              <1> 	mov	di, HD1_DPT 
   122                              <1> L8:
   123                              <1> 	; 30/12/2014
   124 000000CD B80090              <1> 	mov	ax, DPT_SEGM
   125 000000D0 8EC0                <1> 	mov	es, ax
   126                              <1> 	; 24/12/2014
   127 000000D2 B90800              <1> 	mov	cx, 8
   128 000000D5 F3A5                <1> 	rep	movsw  ; copy 16 bytes to the kernel's DPT location
   129 000000D7 8CC8                <1> 	mov	ax, cs
   130 000000D9 8ED8                <1> 	mov	ds, ax
   131                              <1> 	; 02/02/2015
   132 000000DB 8A0E[BBA2]          <1>         mov     cl, [drv]
   133 000000DF 88CB                <1> 	mov	bl, cl
   134 000000E1 B8F001              <1> 	mov	ax, 1F0h
   135 000000E4 80E301              <1> 	and	bl, 1
   136 000000E7 7406                <1> 	jz	short L9
   137 000000E9 C0E304              <1> 	shl	bl, 4
   138 000000EC 2D8000              <1> 	sub	ax, 1F0h-170h
   139                              <1> L9:
   140 000000EF AB                  <1> 	stosw	; I/O PORT Base Address (1F0h, 170h)
   141 000000F0 050602              <1> 	add	ax, 206h
   142 000000F3 AB                  <1> 	stosw	; CONTROL PORT Address (3F6h, 376h)	
   143 000000F4 88D8                <1> 	mov	al, bl
   144 000000F6 04A0                <1> 	add	al, 0A0h
   145 000000F8 AA                  <1> 	stosb	; Device/Head Register upper nibble
   146                              <1> 	;
   147 000000F9 FE06[BBA2]          <1> 	inc	byte [drv]
   148 000000FD BB[40A2]            <1> 	mov	bx, hd0_type - 80h
   149 00000100 01CB                <1> 	add	bx, cx
   150 00000102 800F80              <1>         or      byte [bx], 80h  ; present sign (when lower nibble is 0)
   151 00000105 A0[BDA2]            <1> 	mov	al, [hdc]
   152 00000108 FEC8                <1> 	dec	al
   153 0000010A 0F840E01            <1>         jz      L13
   154 0000010E 80FA80              <1> 	cmp	dl, 80h
   155 00000111 0F8673FF            <1>         jna     L6
   156 00000115 E90401              <1>         jmp     L13
   157                              <1> L10:
   158 00000118 FEC2                <1> 	inc 	dl
   159                              <1> 	; 25/12/2014
   160 0000011A 8816[BBA2]          <1> 	mov	[drv], dl
   161 0000011E B408                <1> 	mov 	ah, 08h ; Return drive parameters
   162 00000120 CD13                <1> 	int	13h	; (conventional function)
   163 00000122 0F82F600            <1>         jc      L13
   164                              <1> 	; 14/01/2015
   165 00000126 8A16[BBA2]          <1> 	mov	dl, [drv]
   166 0000012A 52                  <1> 	push	dx
   167 0000012B 51                  <1> 	push	cx
   168 0000012C E8E501              <1> 	call	set_disk_parms
   169 0000012F 59                  <1> 	pop	cx
   170 00000130 5A                  <1> 	pop	dx
   171                              <1> 	; 04/02/2016 (esi -> si)
   172 00000131 BE[98C4]            <1> 	mov	si, _end ; 30 byte temporary buffer address 	
   173                              <1> 			 ; at the '_end' of kernel.
   174 00000134 C7041E00            <1> 	mov	word [si], 30
   175 00000138 B448                <1> 	mov	ah, 48h	 ; Get drive parameters (EDD function)
   176 0000013A CD13                <1> 	int	13h
   177 0000013C 0F82DC00            <1>         jc      L13
   178                              <1> 	; 04/02/2016 (ebx -> bx)
   179                              <1> 	; 14/01/2015
   180 00000140 29DB                <1> 	sub	bx, bx
   181 00000142 88D3                <1> 	mov	bl, dl
   182 00000144 80EB80              <1> 	sub	bl, 80h
   183 00000147 81C3[C0A2]          <1> 	add	bx, hd0_type
   184 0000014B 8A07                <1> 	mov 	al, [bx]
   185 0000014D 0C80                <1> 	or	al, 80h
   186 0000014F 8807                <1> 	mov 	[bx], al	
   187 00000151 81EB[BEA2]          <1> 	sub	bx, hd0_type - 2 ; 15/01/2015
   188 00000155 81C3[0AA3]          <1> 	add	bx, drv.status
   189 00000159 8807                <1> 	mov	[bx], al
   190                              <1> 	; 04/02/2016 (eax -> ax)
   191 0000015B 8B4410              <1> 	mov	ax, [si+16]
   192 0000015E 854412              <1> 	test	ax, [si+18]
   193 00000161 7412                <1> 	jz	short L10_A0h 
   194                              <1> 			; 'CHS only' disks on EDD system 
   195                              <1> 			;  are reported with ZERO disk size
   196 00000163 81EB[0AA3]          <1> 	sub	bx, drv.status
   197 00000167 C1E302              <1> 	shl	bx, 2
   198 0000016A 81C3[EEA2]          <1> 	add	bx, drv.size ; disk size (in sectors)
   199 0000016E 8907                <1> 	mov	[bx], ax
   200 00000170 8B4412              <1> 	mov	ax, [si+18]
   201 00000173 8907                <1> 	mov	[bx], ax
   202                              <1> 
   203                              <1> L10_A0h: ; Jump here to fix a ZERO (LBA) disk size problem 
   204                              <1> 	 ; for CHS disks (28/02/2015)
   205                              <1> 	; 30/12/2014
   206 00000175 BF0000              <1> 	mov	di, HD0_DPT
   207 00000178 88D0                <1> 	mov	al, dl
   208 0000017A 83E003              <1> 	and 	ax, 3
   209 0000017D C0E005              <1> 	shl	al, 5 ; *32
   210 00000180 01C7                <1> 	add 	di, ax
   211 00000182 B80090              <1> 	mov	ax, DPT_SEGM
   212 00000185 8EC0                <1> 	mov	es, ax
   213                              <1> 	;
   214 00000187 88E8                <1> 	mov	al, ch	; max. cylinder number (bits 0-7)
   215 00000189 88CC                <1> 	mov	ah, cl	
   216 0000018B C0EC06              <1> 	shr	ah, 6	; max. cylinder number (bits 8-9)
   217 0000018E 40                  <1>  	inc	ax	; logical cylinders (limit 1024)
   218 0000018F AB                  <1> 	stosw		
   219 00000190 88F0                <1> 	mov	al, dh	; max. head number
   220 00000192 FEC0                <1> 	inc	al
   221 00000194 AA                  <1> 	stosb		; logical heads (limits 256)
   222 00000195 B0A0                <1> 	mov	al, 0A0h ; Indicates translated table
   223 00000197 AA                  <1> 	stosb
   224 00000198 8A440C              <1> 	mov	al, [si+12]
   225 0000019B AA                  <1> 	stosb		 ; physical sectors per track
   226 0000019C 31C0                <1>  	xor	ax, ax
   227                              <1> 	;dec	ax	 ; 02/01/2015 
   228 0000019E AB                  <1> 	stosw		 ; precompensation (obsolete)
   229                              <1> 	;xor	al, al	 ; 02/01/2015	
   230 0000019F AA                  <1> 	stosb		 ; reserved
   231 000001A0 B008                <1> 	mov	al, 8	 ; drive control byte
   232                              <1> 		         ; (do not disable retries, 
   233                              <1> 			 ; more than 8 heads)
   234 000001A2 AA                  <1> 	stosb
   235 000001A3 8B4404              <1> 	mov	ax, [si+4]
   236 000001A6 AB                  <1> 	stosw		 ; physical number of cylinders	
   237                              <1> 	;push	ax	 ; 02/01/2015
   238 000001A7 8A4408              <1> 	mov	al, [si+8]
   239 000001AA AA                  <1> 	stosb		 ; physical num. of heads (limit 16)
   240 000001AB 29C0                <1> 	sub 	ax, ax
   241                              <1> 	;pop	ax	 ; 02/01/2015	
   242 000001AD AB                  <1> 	stosw		 ; landing zone (obsolete)
   243 000001AE 88C8                <1> 	mov	al, cl	 ; logical sectors per track (limit 63)
   244 000001B0 243F                <1> 	and 	al, 3Fh	
   245 000001B2 AA                  <1> 	stosb
   246                              <1> 	;sub	al, al	 ; checksum
   247                              <1> 	;stosb
   248                              <1> 	;
   249 000001B3 83C61A              <1> 	add	si, 26   ; (BIOS) DPTE address pointer
   250 000001B6 AD                  <1> 	lodsw
   251 000001B7 50                  <1> 	push	ax	 ; (BIOS) DPTE offset
   252 000001B8 AD                  <1> 	lodsw
   253 000001B9 50                  <1> 	push	ax	 ; (BIOS) DPTE segment
   254                              <1> 	;
   255                              <1> 	; checksum calculation
   256 000001BA 89FE                <1> 	mov	si, di
   257 000001BC 06                  <1> 	push	es
   258 000001BD 1F                  <1> 	pop	ds
   259                              <1> 	;mov	cx, 16
   260 000001BE B90F00              <1> 	mov 	cx, 15
   261 000001C1 29CE                <1> 	sub	si, cx
   262 000001C3 30E4                <1> 	xor	ah, ah
   263                              <1> 	;del	cl
   264                              <1> L11:		
   265 000001C5 AC                  <1> 	lodsb
   266 000001C6 00C4                <1> 	add	ah, al
   267 000001C8 E2FB                <1> 	loop	L11
   268                              <1> 	;
   269 000001CA 88E0                <1> 	mov	al, ah
   270 000001CC F6D8                <1> 	neg	al	; -x+x = 0
   271 000001CE AA                  <1> 	stosb		; put checksum in byte 15 of the tbl
   272                              <1> 	;
   273 000001CF 1F                  <1> 	pop	ds	; (BIOS) DPTE segment
   274 000001D0 5E                  <1> 	pop	si	; (BIOS) DPTE offset	
   275                              <1> 	;
   276                              <1> 	; 23/02/2015
   277 000001D1 57                  <1> 	push	di
   278                              <1> 	; ES:DI points to DPTE (FDPTE) location
   279                              <1> 	;mov	cx, 8
   280 000001D2 B108                <1> 	mov	cl, 8
   281 000001D4 F3A5                <1> 	rep	movsw	
   282                              <1> 	;
   283                              <1> 	; 23/02/2015
   284                              <1> 	; (P)ATA drive and LBA validation
   285                              <1> 	; (invalidating SATA drives and setting
   286                              <1> 	; CHS type I/O for old type fixed disks)
   287 000001D6 5B                  <1> 	pop	bx
   288 000001D7 8CC8                <1> 	mov	ax, cs
   289 000001D9 8ED8                <1> 	mov	ds, ax
   290 000001DB 268B07              <1> 	mov	ax, [es:bx]
   291 000001DE 3DF001              <1> 	cmp	ax, 1F0h
   292 000001E1 7418                <1> 	je	short L11a
   293 000001E3 3D7001              <1> 	cmp	ax, 170h
   294 000001E6 7413                <1> 	je	short L11a
   295                              <1> 	; invalidation 
   296                              <1> 	; (because base port address is not 1F0h or 170h)
   297 000001E8 30FF                <1> 	xor	bh, bh
   298 000001EA 88D3                <1> 	mov	bl, dl
   299 000001EC 80EB80              <1> 	sub	bl, 80h
   300 000001EF C687[C0A2]00        <1> 	mov	byte [bx+hd0_type], 0 ; not a valid disk drive !		
   301 000001F4 808F[0CA3]F0        <1>         or      byte [bx+drv.status+2], 0F0h ; (failure sign)
   302 000001F9 EB14                <1> 	jmp	short L11b
   303                              <1> L11a:	
   304                              <1> 	; LBA validation
   305 000001FB 268A4704            <1> 	mov	al, [es:bx+4] ; Head register upper nibble
   306 000001FF A840                <1> 	test	al, 40h ; LBA bit (bit 6)
   307 00000201 750C                <1> 	jnz	short L11b ; LBA type I/O is OK! (E0h or F0h)
   308                              <1> 	; force CHS type I/O for this drive (A0h or B0h)
   309 00000203 28FF                <1> 	sub	bh, bh
   310 00000205 88D3                <1> 	mov	bl, dl
   311 00000207 80EB80              <1> 	sub	bl, 80h ; 26/02/2015
   312 0000020A 80A7[0CA3]FE        <1>         and     byte [bx+drv.status+2], 0FEh ; clear bit 0
   313                              <1> 				; bit 0 = LBA ready bit
   314                              <1> 	; 'diskio' procedure will check this bit !
   315                              <1> L11b:
   316 0000020F 3A16[BCA2]          <1> 	cmp	dl, [last_drv] ; 25/12/2014
   317 00000213 7307                <1>         jnb     short L13
   318 00000215 E900FF              <1>         jmp     L10
   319                              <1> L12:
   320                              <1> 	; Restore data registers
   321 00000218 8CC8                <1> 	mov	ax, cs
   322 0000021A 8ED8                <1> 	mov	ds, ax	
   323                              <1> L13:
   324                              <1> 	; 13/12/2014
   325 0000021C 0E                  <1> 	push	cs
   326 0000021D 07                  <1> 	pop	es
   327                              <1> L14:
   328 0000021E B411                <1> 	mov 	ah, 11h
   329 00000220 CD16                <1> 	int 	16h
   330 00000222 7406                <1> 	jz 	short L15 ; no keys in keyboard buffer
   331 00000224 B010                <1> 	mov	al, 10h
   332 00000226 CD16                <1> 	int 	16h
   333 00000228 EBF4                <1> 	jmp 	short L14
   334                              <1> L15:
   335                              <1> ; //////
   336                              <1> 	; 24/11/2014
   337                              <1> 	; 19/11/2014
   338                              <1> 	; 14/11/2014
   339                              <1> 	; Temporary code for disk searching code check
   340                              <1> 	;
   341                              <1> 	; This code will show existing (usable) drives and also
   342                              <1> 	; will show EDD interface support status for hard disks		
   343                              <1> 	; (If status bit 7 is 1, Identify Device info is ready,
   344                              <1> 	; no need to get it again in protected mode...) 
   345                              <1> 	;	
   346                              <1> 	; 13/11/2014
   347 0000022A BB0700              <1> 	mov	bx, 7
   348 0000022D B40E                <1> 	mov	ah, 0Eh
   349 0000022F A0[BEA2]            <1> 	mov	al, [fd0_type]
   350 00000232 20C0                <1> 	and	al, al
   351 00000234 743D                <1> 	jz	short L15a
   352 00000236 88C2                <1> 	mov	dl, al
   353 00000238 B046                <1> 	mov	al, 'F'
   354 0000023A CD10                <1> 	int 	10h
   355 0000023C B044                <1> 	mov	al, 'D'
   356 0000023E CD10                <1> 	int 	10h
   357 00000240 B030                <1> 	mov	al, '0'
   358 00000242 CD10                <1> 	int 	10h
   359 00000244 B020                <1> 	mov	al, ' '
   360 00000246 CD10                <1> 	int	10h
   361 00000248 E8B200              <1> 	call	L15c
   362 0000024B B020                <1> 	mov	al, ' '
   363 0000024D CD10                <1> 	int	10h
   364                              <1> 	;
   365 0000024F A0[BFA2]            <1> 	mov	al, [fd1_type]
   366 00000252 20C0                <1> 	and	al, al
   367 00000254 741D                <1> 	jz	short L15a
   368 00000256 88C2                <1> 	mov	dl, al
   369 00000258 B046                <1> 	mov	al, 'F'
   370 0000025A CD10                <1> 	int 	10h
   371 0000025C B044                <1> 	mov	al, 'D'
   372 0000025E CD10                <1> 	int 	10h
   373 00000260 B031                <1> 	mov	al, '1'
   374 00000262 CD10                <1> 	int 	10h
   375 00000264 B020                <1> 	mov	al, ' '
   376 00000266 CD10                <1> 	int	10h
   377 00000268 E89200              <1> 	call	L15c
   378 0000026B B020                <1> 	mov	al, ' '
   379 0000026D CD10                <1> 	int	10h
   380 0000026F B020                <1> 	mov	al, ' '
   381 00000271 CD10                <1> 	int	10h
   382                              <1> L15a:
   383 00000273 A0[C0A2]            <1> 	mov	al, [hd0_type]
   384 00000276 20C0                <1> 	and	al, al
   385 00000278 7479                <1> 	jz	short L15b
   386 0000027A 88C2                <1> 	mov	dl, al
   387 0000027C B048                <1> 	mov	al, 'H'
   388 0000027E CD10                <1> 	int 	10h
   389 00000280 B044                <1> 	mov	al, 'D'
   390 00000282 CD10                <1> 	int 	10h
   391 00000284 B030                <1> 	mov	al, '0'
   392 00000286 CD10                <1> 	int 	10h
   393 00000288 B020                <1> 	mov	al, ' '
   394 0000028A CD10                <1> 	int 	10h
   395 0000028C E86E00              <1> 	call	L15c
   396 0000028F B020                <1> 	mov	al, ' '
   397 00000291 CD10                <1> 	int	10h
   398                              <1> 	;
   399 00000293 A0[C1A2]            <1> 	mov	al, [hd1_type]
   400 00000296 20C0                <1> 	and	al, al
   401 00000298 7459                <1> 	jz	short L15b
   402 0000029A 88C2                <1> 	mov	dl, al
   403 0000029C B048                <1> 	mov	al, 'H'
   404 0000029E CD10                <1> 	int 	10h
   405 000002A0 B044                <1> 	mov	al, 'D'
   406 000002A2 CD10                <1> 	int 	10h
   407 000002A4 B031                <1> 	mov	al, '1'
   408 000002A6 CD10                <1> 	int 	10h
   409 000002A8 B020                <1> 	mov	al, ' '
   410 000002AA CD10                <1> 	int 	10h
   411 000002AC E84E00              <1> 	call	L15c
   412 000002AF B020                <1> 	mov	al, ' '
   413 000002B1 CD10                <1> 	int	10h
   414                              <1> 	;
   415 000002B3 A0[C2A2]            <1> 	mov	al, [hd2_type]
   416 000002B6 20C0                <1> 	and	al, al
   417 000002B8 7439                <1> 	jz	short L15b
   418 000002BA 88C2                <1> 	mov	dl, al
   419 000002BC B048                <1> 	mov	al, 'H'
   420 000002BE CD10                <1> 	int 	10h
   421 000002C0 B044                <1> 	mov	al, 'D'
   422 000002C2 CD10                <1> 	int 	10h
   423 000002C4 B032                <1> 	mov	al, '2'
   424 000002C6 CD10                <1> 	int 	10h
   425 000002C8 B020                <1> 	mov	al, ' '
   426 000002CA CD10                <1> 	int 	10h
   427 000002CC E82E00              <1> 	call	L15c
   428 000002CF B020                <1> 	mov	al, ' '
   429 000002D1 CD10                <1> 	int	10h
   430                              <1> 	;
   431 000002D3 A0[C3A2]            <1> 	mov	al, [hd3_type]
   432 000002D6 20C0                <1> 	and	al, al
   433 000002D8 7419                <1> 	jz	short L15b
   434 000002DA 88C2                <1> 	mov	dl, al
   435 000002DC B048                <1> 	mov	al, 'H'
   436 000002DE CD10                <1> 	int 	10h
   437 000002E0 B044                <1> 	mov	al, 'D'
   438 000002E2 CD10                <1> 	int 	10h
   439 000002E4 B033                <1> 	mov	al, '3'
   440 000002E6 CD10                <1> 	int 	10h
   441 000002E8 B020                <1> 	mov	al, ' '
   442 000002EA CD10                <1> 	int 	10h
   443 000002EC E80E00              <1> 	call	L15c
   444 000002EF B020                <1> 	mov	al, ' '
   445 000002F1 CD10                <1> 	int	10h
   446                              <1> 	;
   447                              <1> L15b:
   448 000002F3 B00D                <1> 	mov	al, 0Dh
   449 000002F5 CD10                <1> 	int 	10h	
   450 000002F7 B00A                <1> 	mov	al, 0Ah
   451 000002F9 CD10                <1> 	int 	10h
   452                              <1> 	;;xor	ah, ah
   453                              <1> 	;;int 	16h	
   454                              <1> 	;
   455 000002FB EB77                <1>         jmp     L16  ; jmp short L16
   456                              <1>         ;
   457                              <1> L15c:
   458 000002FD 88D6                <1> 	mov	dh, dl
   459 000002FF C0EE04              <1> 	shr	dh, 4
   460 00000302 80C630              <1> 	add	dh, 30h
   461 00000305 80E20F              <1> 	and	dl, 15
   462 00000308 80C230              <1> 	add	dl, 30h
   463 0000030B 88F0                <1> 	mov	al, dh
   464 0000030D CD10                <1> 	int	10h
   465 0000030F 88D0                <1> 	mov	al, dl
   466 00000311 CD10                <1> 	int	10h
   467 00000313 C3                  <1> 	retn
   468                              <1> 	;
   469                              <1> 	; end of temporary code for disk searching code check
   470                              <1> 
   471                              <1> ; //////
   472                              <1> 
   473                              <1> set_disk_parms:
   474                              <1> 	; 04/02/2016 (ebx -> bx)
   475                              <1> 	; 10/07/2015
   476                              <1> 	; 14/01/2015
   477                              <1> 	;push	bx
   478 00000314 28FF                <1> 	sub	bh, bh
   479 00000316 8A1E[BBA2]          <1> 	mov	bl, [drv]
   480 0000031A 80FB80              <1> 	cmp	bl, 80h
   481 0000031D 7203                <1> 	jb	short sdp0
   482 0000031F 80EB7E              <1> 	sub	bl, 7Eh
   483                              <1> sdp0:	
   484 00000322 81C3[0AA3]          <1> 	add	bx, drv.status
   485 00000326 C60780              <1>   	mov	byte [bx], 80h ; 'Present' flag
   486                              <1> 	;
   487 00000329 88E8                <1> 	mov	al, ch ; last cylinder (bits 0-7)
   488 0000032B 88CC                <1> 	mov	ah, cl ; 
   489 0000032D C0EC06              <1> 	shr	ah, 6  ; last cylinder (bits 8-9)
   490 00000330 81EB[0AA3]          <1> 	sub	bx, drv.status
   491 00000334 D0E3                <1> 	shl	bl, 1
   492 00000336 81C3[C4A2]          <1> 	add	bx, drv.cylinders
   493 0000033A 40                  <1> 	inc	ax  ; convert max. cyl number to cyl count		
   494 0000033B 8907                <1> 	mov	[bx], ax
   495 0000033D 50                  <1> 	push	ax ; ** cylinders
   496 0000033E 81EB[C4A2]          <1> 	sub	bx, drv.cylinders
   497 00000342 81C3[D2A2]          <1> 	add	bx, drv.heads
   498 00000346 30E4                <1> 	xor	ah, ah
   499 00000348 88F0                <1> 	mov	al, dh ; heads
   500 0000034A 40                  <1> 	inc	ax
   501 0000034B 8907                <1> 	mov	[bx], ax
   502 0000034D 81EB[D2A2]          <1>         sub     bx, drv.heads
   503 00000351 81C3[E0A2]          <1>         add     bx, drv.spt
   504 00000355 30ED                <1> 	xor	ch, ch
   505 00000357 80E13F              <1> 	and	cl, 3Fh	; sectors (bits 0-6)
   506 0000035A 890F                <1> 	mov	[bx], cx
   507 0000035C 81EB[E0A2]          <1>         sub     bx, drv.spt
   508 00000360 D1E3                <1> 	shl	bx, 1
   509 00000362 81C3[EEA2]          <1> 	add	bx, drv.size ; disk size (in sectors)
   510                              <1> 	; LBA size = cylinders * heads * secpertrack
   511 00000366 F7E1                <1> 	mul	cx 
   512 00000368 89C2                <1> 	mov	dx, ax	; heads*spt					
   513 0000036A 58                  <1> 	pop	ax ; ** cylinders
   514 0000036B 48                  <1> 	dec	ax ; 1 cylinder reserved (!?)
   515 0000036C F7E2                <1> 	mul	dx ; cylinders * (heads*spt)		
   516 0000036E 8907                <1> 	mov	[bx], ax
   517 00000370 895702              <1> 	mov	[bx+2], dx
   518                              <1> 	;
   519                              <1> 	;pop	bx
   520 00000373 C3                  <1> 	retn
   521                              <1> 
   522                              <1> ;align 2
   523                              <1> 
   524                              <1> ;cylinders :  dw 0, 0, 0, 0, 0, 0
   525                              <1> ;heads	  :  dw 0, 0, 0, 0, 0, 0
   526                              <1> ;spt	  :  dw 0, 0, 0, 0, 0, 0
   527                              <1> ;disk_size :  dd 0, 0, 0, 0, 0, 0
   528                              <1> 
   529                              <1> ;last_drv:
   530                              <1> ;	db  0
   531                              <1> ;drv_status:
   532                              <1> ;	db  0,0,0,0,0,0
   533                              <1> ;	db 0
   534                              <1> 
   535                              <1> 
   536                              <1> ; End Of DISK I/O SYSTEM STRUCTURE INITIALIZATION /// 06/02/2015
   537                              <1> 
   538                              <1> L16:
   183                                  
   184                                  	; 10/11/2014
   185 00000374 FA                           	cli	; Disable interrupts (clear interrupt flag)
   186                                  		; Reset Interrupt MASK Registers (Master&Slave)
   187                                  	;mov	al, 0FFh	; mask off all interrupts
   188                                  	;out	21h, al		; on master PIC (8259)
   189                                  	;jmp 	$+2  ; (delay)
   190                                  	;out	0A1h, al	; on slave PIC (8259)
   191                                  	;
   192                                  	; Disable NMI 
   193 00000375 B080                    	mov   	al, 80h 
   194 00000377 E670                    	out   	70h, al		; set bit 7 to 1 for disabling NMI
   195                                  	;23/02/2015
   196 00000379 90                      	nop			;
   197                                  	;in	al, 71h		; read in 71h just after writing out to 70h
   198                                  				; for preventing unknown state (!?)
   199                                  	;
   200                                   	; 20/08/2014
   201                                  	; Moving the kernel 64 KB back (to physical address 0)
   202                                  	; DS = CS = 1000h
   203                                  	; 05/11/2014
   204 0000037A 31C0                    	xor	ax, ax
   205 0000037C 8EC0                    	mov	es, ax ; ES = 0
   206                                  	;
   207 0000037E B90040                  	mov	cx, (KEND - KLOAD)/4
   208 00000381 31F6                    	xor	si, si
   209 00000383 31FF                    	xor	di, di
   210 00000385 F366A5                  	rep	movsd
   211                                  	;
   212 00000388 06                      	push	es ; 0
   213 00000389 68[8D03]                	push	L17
   214 0000038C CB                      	retf
   215                                  	;
   216                                  L17:
   217                                  	; Turn off the floppy drive motor
   218 0000038D BAF203                          mov     dx, 3F2h
   219 00000390 EE                              out     dx, al ; 0 ; 31/12/2013
   220                                  
   221                                  	; Enable access to memory above one megabyte
   222                                  L18:
   223 00000391 E464                    	in	al, 64h
   224 00000393 A802                    	test	al, 2
   225 00000395 75FA                            jnz     short L18
   226 00000397 B0D1                    	mov	al, 0D1h	; Write output port
   227 00000399 E664                    	out	64h, al
   228                                  L19:
   229 0000039B E464                    	in	al, 64h
   230 0000039D A802                    	test	al, 2
   231 0000039F 75FA                            jnz     short L19
   232 000003A1 B0DF                    	mov	al, 0DFh	; Enable A20 line
   233 000003A3 E660                    	out	60h, al
   234                                  ;L20:
   235                                  	;
   236                                  	; Load global descriptor table register
   237                                  
   238                                          ;mov     ax, cs
   239                                          ;mov     ds, ax
   240                                  
   241 000003A5 2E0F0116[D09F]                  lgdt    [cs:gdtd]
   242                                  
   243 000003AB 0F20C0                          mov     eax, cr0
   244                                  	; or 	eax, 1
   245 000003AE 40                      	inc     ax
   246 000003AF 0F22C0                  	mov     cr0, eax
   247                                  
   248                                  	; Jump to 32 bit code
   249                                  	
   250 000003B2 66                      	db 66h 			; Prefix for 32-bit
   251 000003B3 EA                      	db 0EAh 		; Opcode for far jump
   252 000003B4 [BA030000]              	dd StartPM 		; Offset to start, 32-bit
   253                                  				; (1000h:StartPM = StartPM + 10000h)
   254 000003B8 0800                    	dw KCODE		; This is the selector for CODE32_DESCRIPTOR,
   255                                  				; assuming that StartPM resides in code32
   256                                  
   257                                  [BITS 32] 
   258                                  
   259                                  StartPM:
   260                                  	; Kernel Base Address = 0 ; 30/12/2013
   261 000003BA 66B81000                	mov ax, KDATA           ; Save data segment identifier
   262 000003BE 8ED8                            mov ds, ax              ; Move a valid data segment into DS register
   263 000003C0 8EC0                           	mov es, ax              ; Move data segment into ES register
   264 000003C2 8EE0                           	mov fs, ax              ; Move data segment into FS register
   265 000003C4 8EE8                          	mov gs, ax              ; Move data segment into GS register
   266 000003C6 8ED0                            mov ss, ax              ; Move data segment into SS register
   267 000003C8 BC00000900                      mov esp, 90000h         ; Move the stack pointer to 090000h
   268                                  
   269                                  clear_bss: ; Clear uninitialized data area
   270                                  	; 11/03/2015
   271 000003CD 31C0                    	xor  eax, eax ; 0
   272 000003CF B9C6070000              	mov  ecx, (bss_end - bss_start)/4
   273                                  	;shr  ecx, 2 ; bss section is already aligned for double words
   274 000003D4 BF[80A50000]            	mov  edi, bss_start	
   275 000003D9 F3AB                    	rep  stosd  		
   276                                  
   277                                  memory_init:
   278                                  	; Initialize memory allocation table and page tables
   279                                  	; 16/11/2014
   280                                  	; 15/11/2014
   281                                  	; 07/11/2014
   282                                  	; 06/11/2014
   283                                  	; 05/11/2014
   284                                  	; 04/11/2014
   285                                  	; 31/10/2014 (Retro UNIX 386 v1 - Beginning) 
   286                                  	;
   287                                  ;	xor	eax, eax
   288                                  ;	xor 	ecx, ecx
   289 000003DB B108                    	mov	cl, 8
   290 000003DD BF00001000              	mov	edi, MEM_ALLOC_TBL	
   291 000003E2 F3AB                    	rep	stosd		   ; clear Memory Allocation Table
   292                                  				   ; for the first 1 MB memory
   293                                  	;
   294 000003E4 668B0D[44A50000]        	mov	cx, [mem_1m_1k]	   ; Number of contiguous KB between
   295                                  				   ; 1 and 16 MB, max. 3C00h = 15 MB.
   296 000003EB 66C1E902                	shr	cx, 2		   ; convert 1 KB count to 4 KB count
   297 000003EF 890D[F0A70000]          	mov	[free_pages], ecx
   298 000003F5 668B15[46A50000]        	mov	dx, [mem_16m_64k]  ; Number of contiguous 64 KB blocks
   299                                  				   ; between 16 MB and 4 GB.	
   300 000003FC 6609D2                  	or	dx, dx
   301 000003FF 7413                    	jz	short mi_0
   302                                  	;
   303 00000401 6689D0                  	mov	ax, dx
   304 00000404 C1E004                  	shl	eax, 4		   ; 64 KB -> 4 KB (page count)
   305 00000407 0105[F0A70000]          	add	[free_pages], eax
   306 0000040D 0500100000              	add	eax, 4096	   ; 16 MB = 4096 pages
   307 00000412 EB07                    	jmp	short mi_1
   308                                  mi_0:
   309 00000414 6689C8                  	mov	ax, cx
   310 00000417 66050001                	add	ax, 256		   ; add 256 pages for the first 1 MB		 
   311                                  mi_1:
   312 0000041B A3[ECA70000]            	mov	[memory_size], eax ; Total available memory in pages
   313                                  				   ; 1 alloc. tbl. bit = 1 memory page
   314                                  				   ; 32 allocation bits = 32 mem. pages   
   315                                  	;
   316 00000420 05FF7F0000              	add	eax, 32767	   ; 32768 memory pages per 1 M.A.T. page 	
   317 00000425 C1E80F                  	shr	eax, 15		   ; ((32768 * x) + y) pages (y < 32768)
   318                                  				   ;  --> x + 1 M.A.T. pages, if y > 0
   319                                  				   ;  --> x M.A.T. pages, if y = 0
   320 00000428 66A3[00A80000]          	mov	[mat_size], ax	   ; Memory Alloc. Table Size in pages		
   321 0000042E C1E00C                  	shl	eax, 12		   ; 1 M.A.T. page = 4096 bytes
   322                                  	;			   ; Max. 32 M.A.T. pages (4 GB memory)
   323 00000431 89C3                    	mov	ebx, eax	   ; M.A.T. size in bytes
   324                                  	; Set/Calculate Kernel's Page Directory Address
   325 00000433 81C300001000            	add	ebx, MEM_ALLOC_TBL
   326 00000439 891D[E8A70000]          	mov	[k_page_dir], ebx  ; Kernel's Page Directory address
   327                                  				   ; just after the last M.A.T. page
   328                                  	;
   329 0000043F 83E804                  	sub	eax, 4		   ; convert M.A.T. size to offset value
   330 00000442 A3[F8A70000]            	mov	[last_page], eax   ; last page ofset in the M.A.T.
   331                                  	;			   ; (allocation status search must be 
   332                                  				   ; stopped after here)	
   333 00000447 31C0                    	xor	eax, eax
   334 00000449 48                      	dec	eax		   ; FFFFFFFFh (set all bits to 1)	
   335 0000044A 6651                    	push	cx
   336 0000044C C1E905                  	shr	ecx, 5		   ; convert 1 - 16 MB page count to 
   337                                  				   ; count of 32 allocation bits
   338 0000044F F3AB                    	rep	stosd
   339 00000451 6659                    	pop	cx
   340 00000453 40                      	inc	eax		   ; 0	
   341 00000454 80E11F                  	and	cl, 31		   ; remain bits
   342 00000457 7412                    	jz	short mi_4
   343 00000459 8907                    	mov	[edi], eax	   ; reset	
   344                                  mi_2:
   345 0000045B 0FAB07                  	bts	[edi], eax	   ; 06/11/2014		
   346 0000045E FEC9                    	dec	cl
   347 00000460 7404                    	jz	short mi_3
   348 00000462 FEC0                    	inc	al
   349 00000464 EBF5                    	jmp	short mi_2
   350                                  mi_3:
   351 00000466 28C0                    	sub	al, al	   	   ; 0
   352 00000468 83C704                  	add	edi, 4		   ; 15/11/2014
   353                                  mi_4:
   354 0000046B 6609D2                  	or	dx, dx		  ; check 16M to 4G memory space	
   355 0000046E 7421                    	jz	short mi_6	  ; max. 16 MB memory, no more...
   356                                  	;	
   357 00000470 B900021000              	mov	ecx, MEM_ALLOC_TBL + 512 ; End of first 16 MB memory
   358                                  	;	
   359 00000475 29F9                    	sub	ecx, edi	  ; displacement (to end of 16 MB)
   360 00000477 7406                    	jz	short mi_5	  ; jump if EDI points to 
   361                                  				  ;         end of first 16 MB	
   362 00000479 D1E9                    	shr	ecx, 1		  ; convert to dword count
   363 0000047B D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   364 0000047D F3AB                    	rep 	stosd		  ; reset all bits for reserved pages
   365                                  				  ; (memory hole under 16 MB)
   366                                  mi_5:
   367 0000047F 6689D1                  	mov	cx, dx		  ; count of 64 KB memory blocks
   368 00000482 D1E9                    	shr	ecx, 1		  ; 1 alloc. dword per 128 KB memory
   369 00000484 9C                      	pushf			  ; 16/11/2014		
   370 00000485 48                      	dec	eax		  ; FFFFFFFFh (set all bits to 1)
   371 00000486 F3AB                    	rep	stosd
   372 00000488 40                      	inc	eax		  ; 0
   373 00000489 9D                      	popf			  ; 16/11/2014
   374 0000048A 7305                    	jnc	short mi_6
   375 0000048C 6648                    	dec	ax		  ; eax = 0000FFFFh
   376 0000048E AB                      	stosd
   377 0000048F 6640                    	inc	ax		  ; 0		
   378                                  mi_6:
   379 00000491 39DF                    	cmp	edi, ebx	  ; check if EDI points to 	
   380 00000493 730A                    	jnb	short mi_7	  ; end of memory allocation table
   381                                  	;			  ; (>= MEM_ALLOC_TBL + 4906) 
   382 00000495 89D9                    	mov	ecx, ebx	  ; end of memory allocation table
   383 00000497 29F9                    	sub	ecx, edi	  ; convert displacement/offset
   384 00000499 D1E9                    	shr	ecx, 1		  ; to dword count 	 		
   385 0000049B D1E9                    	shr	ecx, 1		  ; (shift 2 bits right) 
   386 0000049D F3AB                    	rep 	stosd		  ; reset all remain M.A.T. bits
   387                                  mi_7:
   388                                  	; Reset M.A.T. bits in M.A.T. (allocate M.A.T. pages)
   389 0000049F BA00001000              	mov	edx, MEM_ALLOC_TBL
   390                                  	;sub	ebx, edx	  ; Mem. Alloc. Tbl. size in bytes
   391                                  	;shr	ebx, 12		  ; Mem. Alloc. Tbl. size in pages	
   392 000004A4 668B0D[00A80000]        	mov	cx, [mat_size]	  ; Mem. Alloc. Tbl. size in pages
   393 000004AB 89D7                    	mov	edi, edx
   394 000004AD C1EF0F                  	shr	edi, 15		  ; convert M.A.T. address to
   395                                  				  ; byte offset in M.A.T.
   396                                  				  ; (1 M.A.T. byte points to 
   397                                  				  ;	      32768 bytes)
   398                                  				  ; Note: MEM_ALLOC_TBL address 
   399                                  				  ; must be aligned on 128 KB 
   400                                  				  ; boundary!
   401 000004B0 01D7                    	add	edi, edx	  ; points to M.A.T.'s itself	
   402                                  	; eax = 0
   403 000004B2 290D[F0A70000]          	sub	[free_pages], ecx ; 07/11/2014
   404                                  mi_8:
   405 000004B8 0FB307                  	btr	[edi], eax	  ; clear bit 0 to bit x (1 to 31)
   406                                  	;dec	bl
   407 000004BB FEC9                    	dec	cl
   408 000004BD 7404                    	jz	short mi_9
   409 000004BF FEC0                    	inc	al
   410 000004C1 EBF5                    	jmp	short mi_8
   411                                  mi_9:
   412                                  	;
   413                                  	; Reset Kernel's Page Dir. and Page Table bits in M.A.T.
   414                                  	;		(allocate pages for system page tables)
   415                                  
   416                                  	; edx = MEM_ALLOC_TBL
   417 000004C3 8B0D[ECA70000]          	mov	ecx, [memory_size] ; memory size in pages (PTEs)
   418 000004C9 81C1FF030000            	add	ecx, 1023	 ; round up (1024 PTEs per table)	 	
   419 000004CF C1E90A                  	shr	ecx, 10		 ; convert memory page count to 
   420                                  				 ; page table count (PDE count)
   421                                  	;
   422 000004D2 51                      	push	ecx		 ; (**) PDE count (<= 1024)
   423                                  	;
   424 000004D3 41                      	inc	ecx		 ; +1 for kernel page directory	
   425                                  	;
   426 000004D4 290D[F0A70000]          	sub	[free_pages], ecx ; 07/11/2014
   427                                  	;
   428 000004DA 8B35[E8A70000]          	mov	esi, [k_page_dir] ; Kernel's Page Directory address
   429 000004E0 C1EE0C                  	shr	esi, 12		 ; convert to page number
   430                                  mi_10:
   431 000004E3 89F0                    	mov	eax, esi	 ; allocation bit offset		 
   432 000004E5 89C3                    	mov	ebx, eax
   433 000004E7 C1EB03                  	shr	ebx, 3		 ; convert to alloc. byte offset
   434 000004EA 80E3FC                  	and	bl,  0FCh	 ; clear bit 0 and bit 1
   435                                  				 ;   to align on dword boundary
   436 000004ED 83E01F                  	and	eax, 31		 ; set allocation bit position 
   437                                  				 ;  (bit 0 to bit 31)
   438                                  	;
   439 000004F0 01D3                    	add	ebx, edx	 ; offset in M.A.T. + M.A.T. address 
   440                                  	;
   441 000004F2 0FB303                  	btr 	[ebx], eax	 ; reset relevant bit (0 to 31)
   442                                  	;
   443 000004F5 46                      	inc	esi		 ; next page table
   444 000004F6 E2EB                    	loop	mi_10		 ; allocate next kernel page table 
   445                                  				 ; (ecx = page table count + 1)		
   446                                  	;
   447 000004F8 59                      	pop	ecx		 ; (**) PDE count (= pg. tbl. count)
   448                                  	;
   449                                  	; Initialize Kernel Page Directory and Kernel Page Tables
   450                                  	;
   451                                  	; Initialize Kernel's Page Directory
   452 000004F9 8B3D[E8A70000]          	mov	edi, [k_page_dir]
   453 000004FF 89F8                    	mov	eax, edi
   454 00000501 0C03                    	or	al, PDE_A_PRESENT + PDE_A_WRITE
   455                                  		     	      ; supervisor + read&write + present
   456 00000503 89CA                    	mov	edx, ecx 	; (**) PDE count (= pg. tbl. count)	
   457                                  mi_11:
   458 00000505 0500100000              	add	eax, 4096	; Add page size (PGSZ)
   459                                  			        ; EAX points to next page table
   460 0000050A AB                      	stosd
   461 0000050B E2F8                    	loop	mi_11
   462 0000050D 29C0                    	sub	eax, eax	; Empty PDE
   463 0000050F 66B90004                	mov	cx, 1024	; Entry count (PGSZ/4)
   464 00000513 29D1                    	sub	ecx, edx
   465 00000515 7402                    	jz	short mi_12
   466 00000517 F3AB                    	rep	stosd 		; clear remain (empty) PDEs
   467                                  	;
   468                                  	; Initialization of Kernel's Page Directory is OK, here.
   469                                  mi_12:
   470                                  	; Initialize Kernel's Page Tables
   471                                  	;
   472                                  	; (EDI points to address of page table 0)
   473                                  	; eax = 0
   474 00000519 8B0D[ECA70000]          	mov	ecx, [memory_size] ; memory size in pages
   475 0000051F 89CA                    	mov	edx, ecx	; (***)
   476 00000521 B003                    	mov	al, PTE_A_PRESENT + PTE_A_WRITE
   477                                  			     ; supervisor + read&write + present 	
   478                                  mi_13:
   479 00000523 AB                      	stosd
   480 00000524 0500100000              	add	eax, 4096	
   481 00000529 E2F8                    	loop	mi_13	
   482 0000052B 6681E2FF03              	and	dx, 1023	; (***)
   483 00000530 740B                    	jz	short mi_14
   484 00000532 66B90004                	mov	cx, 1024	
   485 00000536 6629D1                  	sub	cx, dx		; from dx (<= 1023) to 1024
   486 00000539 31C0                    	xor	eax, eax
   487 0000053B F3AB                    	rep	stosd		; clear remain (empty) PTEs 
   488                                  				; of the last page table
   489                                  mi_14:
   490                                  	;  Initialization of Kernel's Page Tables is OK, here.
   491                                  	;
   492 0000053D 89F8                    	mov	eax, edi	; end of the last page table page
   493                                  			        ; (beginging of user space pages)
   494 0000053F C1E80F                  	shr	eax, 15		; convert to M.A.T. byte offset
   495 00000542 24FC                    	and	al, 0FCh	; clear bit 0 and bit 1 for
   496                                  				; aligning on dword boundary	
   497                                  	 
   498 00000544 A3[FCA70000]            	mov	[first_page], eax
   499 00000549 A3[F4A70000]            	mov	[next_page], eax ; The first free page pointer
   500                                  				 ; for user programs
   501                                  				 ; (Offset in Mem. Alloc. Tbl.)	
   502                                  	;
   503                                  	; Linear/FLAT (1 to 1) memory paging for the kernel is OK, here.
   504                                  	;
   505                                  	
   506                                  	; Enable paging
   507                                  	;
   508 0000054E A1[E8A70000]                    mov     eax, [k_page_dir]
   509 00000553 0F22D8                  	mov	cr3, eax
   510 00000556 0F20C0                  	mov	eax, cr0
   511 00000559 0D00000080              	or	eax, 80000000h	; set paging bit (bit 31)
   512 0000055E 0F22C0                  	mov	cr0, eax
   513                                          ;jmp    KCODE:StartPMP
   514                                  
   515 00000561 EA                      	db 0EAh 		; Opcode for far jump
   516 00000562 [68050000]                      dd StartPMP		; 32 bit offset
   517 00000566 0800                    	dw KCODE		; kernel code segment descriptor
   518                                  
   519                                  
   520                                  StartPMP:
   521                                  	; 06/11//2014
   522                                  	; Clear video page 0
   523                                  	;
   524                                  	; Temporary Code
   525                                  	;
   526 00000568 B9E8030000              	mov	ecx, 80*25/2
   527 0000056D BF00800B00              	mov	edi, 0B8000h
   528                                  	; 30/01/2016
   529                                  	;xor	eax, eax	; black background, black fore color
   530 00000572 B800070007              	mov	eax, 07000700h  ; black background, light gray fore color
   531 00000577 F3AB                    	rep	stosd
   532                                  	
   533                                  	; 19/08/2014
   534                                  	; Kernel Base Address = 0
   535                                  	; It is mapped to (physically) 0 in the page table.
   536                                  	; So, here is exactly 'StartPMP' address.
   537                                  
   538                                   	; 29/01/2016 (TRDOS 386 = TRDOS v2.0)
   539 00000579 BE[48A50000]            	mov	esi, starting_msg
   540                                  	;; 14/08/2015 (kernel version message will appear
   541                                  	;;	       when protected mode and paging is enabled)
   542 0000057E BF00800B00              	mov	edi, 0B8000h ; 27/08/2014
   543 00000583 B40A                    	mov	ah, 0Ah ; Black background, light green forecolor
   544                                  	; 20/08/2014
   545 00000585 E87D010000              	call	printk
   546                                  
   547                                  	; 'UNIX v7/x86' source code by Robert Nordier (1999)
   548                                  	; // Set IRQ offsets
   549                                  	;
   550                                  	;  Linux (v0.12) source code by Linus Torvalds (1991)
   551                                  	;
   552                                  					;; ICW1
   553 0000058A B011                    	mov	al, 11h			; Initialization sequence
   554 0000058C E620                    	out	20h, al			; 	8259A-1
   555                                  	; jmp 	$+2
   556 0000058E E6A0                    	out	0A0h, al		; 	8259A-2
   557                                  					;; ICW2
   558 00000590 B020                    	mov	al, 20h			; Start of hardware ints (20h)
   559 00000592 E621                    	out	21h, al			;	for 8259A-1
   560                                  	; jmp 	$+2
   561 00000594 B028                    	mov	al, 28h			; Start of hardware ints (28h)
   562 00000596 E6A1                    	out	0A1h, al		; 	for 8259A-2
   563                                  					;
   564 00000598 B004                    	mov	al, 04h			;; ICW3
   565 0000059A E621                    	out	21h, al			; 	IRQ2 of 8259A-1 (master)
   566                                  	; jmp 	$+2
   567 0000059C B002                    	mov	al, 02h			; 	is 8259A-2 (slave)
   568 0000059E E6A1                    	out	0A1h, al		;
   569                                  					;; ICW4
   570 000005A0 B001                    	mov	al, 01h	 		;
   571 000005A2 E621                    	out	21h, al			; 	8086 mode, normal EOI	
   572                                  	; jmp 	$+2
   573 000005A4 E6A1                    	out	0A1h, al		;	for both chips.
   574                                  
   575                                  	;mov	al, 0FFh	; mask off all interrupts for now
   576                                  	;out	21h, al
   577                                  	;; jmp 	$+2
   578                                  	;out	0A1h, al
   579                                  
   580                                  	; 02/04/2015
   581                                  	; 26/03/2015 System call (INT 30h) modification
   582                                  	;  DPL = 3 (Interrupt service routine can be called from user mode)			
   583                                  	;
   584                                  	;; Linux (v0.12) source code by Linus Torvalds (1991)
   585                                  	;  setup_idt:
   586                                  	;
   587                                          ;; 16/02/2015
   588                                  	;;mov     dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
   589                                  	; 21/08/2014 (timer_int)
   590 000005A6 BE[DC9F0000]            	mov	esi, ilist
   591 000005AB 8D3D[80A50000]          	lea	edi, [idt]
   592                                  	; 26/03/2015
   593 000005B1 B930000000              	mov	ecx, 48		; 48 hardware interrupts (INT 0 to INT 2Fh)
   594                                  	; 02/04/2015
   595 000005B6 BB00000800              	mov	ebx,  80000h
   596                                  rp_sidt1:
   597 000005BB AD                      	lodsd
   598 000005BC 89C2                    	mov	edx, eax
   599 000005BE 66BA008E                	mov	dx, 8E00h
   600 000005C2 6689C3                  	mov	bx, ax
   601 000005C5 89D8                    	mov	eax, ebx	; /* selector = 0x0008 = cs */
   602                                         			        ; /* interrupt gate - dpl=0, present */
   603 000005C7 AB                      	stosd	; selector & offset bits 0-15 	
   604 000005C8 89D0                    	mov	eax, edx
   605 000005CA AB                      	stosd	; attributes & offset bits 16-23
   606 000005CB E2EE                    	loop	rp_sidt1
   607 000005CD B110                    	mov	cl, 16        ; 16 software interrupts (INT 30h to INT 3Fh)
   608                                  rp_sidt2:
   609 000005CF AD                      	lodsd
   610 000005D0 21C0                    	and	eax, eax
   611 000005D2 7413                    	jz	short rp_sidt3
   612 000005D4 89C2                    	mov	edx, eax
   613 000005D6 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
   614 000005DA 6689C3                  	mov	bx, ax
   615 000005DD 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
   616 000005DF AB                      	stosd
   617 000005E0 89D0                    	mov	eax, edx
   618 000005E2 AB                      	stosd
   619 000005E3 E2EA                    	loop	rp_sidt2
   620 000005E5 EB16                    	jmp	short sidt_OK
   621                                  rp_sidt3:
   622 000005E7 B8[310A0000]            	mov	eax, ignore_int
   623 000005EC 89C2                    	mov	edx, eax
   624 000005EE 66BA00EE                	mov	dx, 0EE00h	; P=1b/DPL=11b/01110b
   625 000005F2 6689C3                  	mov	bx, ax
   626 000005F5 89D8                    	mov	eax, ebx	; selector & offset bits 0-15 	
   627                                  rp_sidt4:
   628 000005F7 AB                      	stosd
   629 000005F8 92                      	xchg	eax, edx
   630 000005F9 AB                      	stosd
   631 000005FA 92                      	xchg	edx, eax
   632 000005FB E2FA                    	loop	rp_sidt4
   633                                  sidt_OK: 
   634 000005FD 0F011D[D69F0000]        	lidt 	[idtd]
   635                                  	;
   636                                  	; TSS descriptor setup ; 24/03/2015
   637 00000604 B8[80A70000]            	mov	eax, task_state_segment
   638 00000609 66A3[CA9F0000]          	mov	[gdt_tss0], ax
   639 0000060F C1C010                  	rol	eax, 16
   640 00000612 A2[CC9F0000]            	mov	[gdt_tss1], al
   641 00000617 8825[CF9F0000]          	mov	[gdt_tss2], ah
   642 0000061D 66C705[E6A70000]68-     	mov	word [tss.IOPB], tss_end - task_state_segment
   642 00000625 00                 
   643                                  		; 
   644                                  		; IO Map Base address (When this address points
   645                                  		; to end of the TSS, CPU does not use IO port 
   646                                  		; permission bit map for RING 3 IO permissions, 
   647                                  		; access to any IO ports in ring 3 will be forbidden.)
   648                                   		;
   649                                  	;mov	[tss.esp0], esp ; TSS offset 4
   650                                  	;mov	word [tss.ss0], KDATA ; TSS offset 8 (SS)
   651 00000626 66B82800                   	mov	ax, TSS  ; It is needed when an interrupt 
   652                                  			 ; occurs (or a system call -software INT- is requested)
   653                                  			 ; while cpu running in ring 3 (in user mode).				
   654                                  			 ; (Kernel stack pointer and segment will be loaded
   655                                  			 ; from offset 4 and 8 of the TSS, by the CPU.)	 
   656 0000062A 0F00D8                  	ltr	ax  ; Load task register
   657                                  	;
   658                                  esp0_set0:
   659                                  	; 30/07/2015
   660 0000062D 8B0D[ECA70000]          	mov 	ecx, [memory_size] ; memory size in pages
   661 00000633 C1E10C                  	shl 	ecx, 12 ; convert page count to byte count
   662 00000636 81F900004000            	cmp	ecx, CORE ; beginning of user's memory space (400000h)
   663                                  			  ; (kernel mode virtual address)
   664 0000063C 7605                    	jna	short esp0_set1
   665                                  	;
   666                                  	; If available memory > CORE (end of the 1st 4 MB)
   667                                  	; set stack pointer to CORE
   668                                  	;(Because, PDE 0 is reserved for kernel space in user's page directory)
   669                                  	;(PDE 0 points to page table of the 1st 4 MB virtual address space)
   670 0000063E B900004000              	mov	ecx, CORE
   671                                  esp0_set1:
   672 00000643 89CC                    	mov	esp, ecx ; top of kernel stack (**tss.esp0**)
   673                                  esp0_set_ok:
   674                                  	; 30/07/2015 (**tss.esp0**) 
   675 00000645 8925[84A70000]          	mov	[tss.esp0], esp
   676 0000064B 66C705[88A70000]10-             mov     word [tss.ss0], KDATA
   676 00000653 00                 
   677                                  	; 14/08/2015
   678                                  	; 10/11/2014 (Retro UNIX 386 v1 - Erdogan Tan)
   679                                  	;
   680                                  	;cli	; Disable interrupts (for CPU)
   681                                  	;    (CPU will not handle hardware interrupts, except NMI!)
   682                                  	;
   683 00000654 30C0                    	xor	al, al		; Enable all hardware interrupts!
   684 00000656 E621                    	out	21h, al		; (IBM PC-AT compatibility)
   685 00000658 EB00                    	jmp 	$+2		; (All conventional PC-AT hardware
   686 0000065A E6A1                    	out	0A1h, al	;  interrupts will be in use.)	
   687                                  				; (Even if related hardware component
   688                                  				;  does not exist!)
   689                                  	; Enable NMI 
   690 0000065C B07F                    	mov	al, 7Fh		; Clear bit 7 to enable NMI (again)
   691 0000065E E670                    	out  	70h, al
   692                                  	; 23/02/2015
   693 00000660 90                      	nop
   694 00000661 E471                    	in	al, 71h		; read in 71h just after writing out to 70h
   695                                  				; for preventing unknown state (!?)
   696                                  	;
   697                                  	; Only a NMI can occur here... (Before a 'STI' instruction)
   698                                  	;
   699                                  	; 02/09/2014
   700 00000663 6631DB                  	xor	bx, bx
   701 00000666 66BA0002                	mov	dx, 0200h	; Row 2, column 0  ; 07/03/2015
   702 0000066A E8DB110000              	call	_set_cpos	; 24/01/2016
   703                                  	;
   704                                  	; 06/11/2014
   705 0000066F E8BC120000              	call	memory_info
   706                                  	; 14/08/2015
   707                                  	;call getch ; 28/02/2015
   708                                  drv_init:
   709 00000674 FB                      	sti	; Enable Interrupts 
   710                                  	; 06/02/2015
   711 00000675 8B15[C0A20000]          	mov	edx, [hd0_type] ; hd0, hd1, hd2, hd3
   712 0000067B 668B1D[BEA20000]        	mov	bx, [fd0_type] ; fd0, fd1
   713                                  	; 22/02/2015
   714 00000682 6621DB                  	and	bx, bx
   715 00000685 751B                    	jnz	short di1
   716                                  	;
   717 00000687 09D2                    	or 	edx, edx
   718 00000689 7529                    	jnz	short di2
   719                                  	;
   720                                  setup_error:
   721 0000068B BE[0FA40000]            	mov 	esi, setup_error_msg
   722                                  psem:	
   723 00000690 AC                      	lodsb
   724 00000691 08C0                    	or	al, al
   725                                  	;jz	short haltx ; 22/02/2015
   726 00000693 7426                    	jz	short di3
   727 00000695 56                      	push	esi
   728 00000696 31DB                    	xor	ebx, ebx ; 0
   729                                  			; Video page 0 (bl=0)
   730 00000698 B407                    	mov	ah, 07h ; Black background, 
   731                                  			; light gray forecolor
   732 0000069A E817110000              	call	WRITE_TTY
   733 0000069F 5E                      	pop	esi
   734 000006A0 EBEE                    	jmp	short psem
   735                                  
   736                                  di1:
   737                                  	; supress 'jmp short T6'
   738                                  	;  (activate fdc motor control code)
   739 000006A2 66C705[88070000]90-     	mov	word [T5], 9090h ; nop
   739 000006AA 90                 
   740                                  	;
   741                                  	;mov	ax, int_0Eh	; IRQ 6 handler
   742                                  	;mov	di, 0Eh*4	; IRQ 6 vector
   743                                  	;stosw
   744                                  	;mov 	ax, cs
   745                                  	;stosw
   746                                  	;; 16/02/2015
   747                                          ;;mov     dword [DISKETTE_INT], fdc_int ; IRQ 6 handler
   748                                  	;
   749 000006AB E8DE210000              	CALL	DSKETTE_SETUP	; Initialize Floppy Disks
   750                                  	;
   751 000006B0 09D2                    	or	edx, edx
   752 000006B2 7407                            jz      short di3
   753                                  di2:
   754 000006B4 E81B220000              	call   	DISK_SETUP	; Initialize Fixed Disks
   755 000006B9 72D0                            jc      short setup_error
   756                                  di3:
   757 000006BB E844120000              	call	setup_rtc_int	; 22/05/2015 (dsectrpm.s)
   758                                  	;
   759 000006C0 E82C980000              	call	display_disks ; 07/03/2015  (Temporary)
   760                                  ;haltx:
   761                                  	; 14/08/2015
   762                                  	;call	getch ; 22/02/2015
   763                                  	;sti	; Enable interrupts (for CPU)
   764                                  ;	; 29/01/2016
   765                                  ;	sub	ah, ah ;  read time count
   766                                  ;	call	int1Ah
   767                                  ;	mov	edx, ecx ; 18.2 * seconds
   768                                  ;md_info_msg_wait1:
   769                                  ;	; 29/01/2016
   770                                  ;	mov	ah, 1
   771                                  ;	call	int16h
   772                                  ;	jz	short md_info_msg_wait2
   773                                  ;	xor	ah, ah ; 0
   774                                  ;       call    int16h
   775                                  ;	jmp 	short md_info_msg_ok
   776                                  ;md_info_msg_wait2:
   777                                  ;	sub	ah, ah  ; read time count
   778                                  ;	call	int1Ah
   779                                  ;	cmp	edx, ecx ; ; 18.2 * seconds
   780                                  ;	jna	short md_info_msg_wait3
   781                                  ;	xchg 	edx, ecx	
   782                                  ;md_info_msg_wait3:
   783                                  ;	sub	ecx, edx
   784                                  ;	cmp	ecx, 127 ; 7 seconds (18.2 * 7)
   785                                  ;	jb	short md_info_msg_wait1		
   786                                  ;md_info_msg_ok:
   787                                  	; 30/06/2015
   788 000006C5 E8D5340000              	call	sys_init
   789                                  	;
   790                                  	;jmp 	cpu_reset ; 22/02/2015
   791                                  hang:  
   792                                  	; 23/02/2015
   793                                  	;sti			; Enable interrupts
   794 000006CA F4                      	hlt
   795                                  	;
   796                                  	;nop
   797                                  	;; 03/12/2014
   798                                  	;; 28/08/2014
   799                                  	;mov	ah, 11h
   800                                  	;call	getc
   801                                  	;jz      _c8
   802                                  	;
   803                                  	; 23/02/2015
   804                                  	; 06/02/2015
   805                                  	; 07/09/2014
   806 000006CB 31DB                    	xor	ebx, ebx
   807 000006CD 8A1D[18A80000]          	mov	bl, [ptty]	; active_page
   808 000006D3 89DE                    	mov	esi, ebx
   809 000006D5 66D1E6                  	shl 	si, 1
   810 000006D8 81C6[1AA80000]          	add	esi, ttychr
   811 000006DE 668B06                  	mov	ax, [esi]
   812 000006E1 6621C0                  	and	ax, ax
   813                                  	;jz	short _c8
   814 000006E4 74E4                    	jz	short hang
   815 000006E6 66C7060000              	mov	word [esi], 0
   816 000006EB 80FB03                  	cmp	bl, 3		; Video page 3
   817                                  	;jb	short _c8
   818 000006EE 72DA                    	jb	short hang
   819                                  	;	
   820                                  	; 02/09/2014
   821 000006F0 B40E                    	mov	ah, 0Eh		; Yellow character 
   822                                  				; on black background
   823                                  	; 07/09/2014
   824                                  nxtl:
   825 000006F2 6653                    	push	bx
   826                                  	;
   827                                  	;xor	bx, bx		; bl = 0 (video page 0)
   828                                  				; bh = 0 (video mode)
   829                                  				; Retro UNIX 386 v1 - Video Mode 0
   830                                  				; (PC/AT Video Mode 3 - 80x25 Alpha.)
   831 000006F4 6650                    	push	ax
   832 000006F6 E8BB100000              	call 	WRITE_TTY
   833 000006FB 6658                    	pop	ax
   834 000006FD 665B                    	pop	bx ; 07/09/2014
   835 000006FF 3C0D                    	cmp	al, 0Dh		; carriage return (enter)
   836                                  	;jne	short _c8
   837 00000701 75C7                    	jne	short hang
   838 00000703 B00A                    	mov	al, 0Ah		; next line
   839 00000705 EBEB                    	jmp	short nxtl
   840                                  	
   841                                  ;_c8:
   842                                  ;	; 25/08/2014
   843                                  ;	cli				; Disable interrupts
   844                                  ;	mov	al, [scounter + 1]
   845                                  ;	and	al, al
   846                                  ;	jnz	hang
   847                                  ;	call	rtc_p
   848                                  ;	jmp     hang
   849                                  
   850                                  
   851                                  	; 27/08/2014
   852                                  	; 20/08/2014
   853                                  printk:
   854                                          ;mov    edi, [scr_row]
   855                                  pkl:
   856 00000707 AC                      	lodsb
   857 00000708 08C0                    	or 	al, al
   858 0000070A 7404                    	jz	short pkr
   859 0000070C 66AB                    	stosw
   860 0000070E EBF7                    	jmp	short pkl
   861                                  pkr:
   862 00000710 C3                      	retn
   863                                  
   864                                  ; 25/07/2015
   865                                  ; 14/05/2015 (multi tasking -time sharing- 'clock', x_timer)
   866                                  ; 17/02/2015
   867                                  ; 06/02/2015 (unix386.s)
   868                                  ; 11/12/2014 - 22/12/2014 (dsectrm2.s) 
   869                                  ;
   870                                  ; IBM PC-XT Model 286 Source Code - BIOS2.ASM (06/10/85)
   871                                  ;
   872                                  ;-- HARDWARE INT  08 H - ( IRQ LEVEL 0 ) ---------------------------------------
   873                                  ;	THIS ROUTINE HANDLES THE TIMER INTERRUPT FROM FROM CHANNEL 0 OF        :
   874                                  ;	THE 8254 TIMER.  INPUT FREQUENCY IS 1.19318 MHZ AND THE DIVISOR        :
   875                                  ;	IS 65536, RESULTING IN APPROXIMATELY 18.2 INTERRUPTS EVERY SECOND.     :
   876                                  ;									       :
   877                                  ;	THE INTERRUPT HANDLER MAINTAINS A COUNT (40:6C) OF INTERRUPTS SINCE    :
   878                                  ;	POWER ON TIME, WHICH MAY BE USED TO ESTABLISH TIME OF DAY.	       :
   879                                  ;	THE INTERRUPT HANDLER ALSO DECREMENTS THE MOTOR CONTROL COUNT (40:40)  :
   880                                  ;	OF THE DISKETTE, AND WHEN IT EXPIRES, WILL TURN OFF THE 	       :
   881                                  ;	DISKETTE MOTOR(s), AND RESET THE MOTOR RUNNING FLAGS.		       :
   882                                  ;	THE INTERRUPT HANDLER WILL ALSO INVOKE A USER ROUTINE THROUGH	       :
   883                                  ;	INTERRUPT 1CH AT EVERY TIME TICK.  THE USER MUST CODE A 	       :
   884                                  ;	ROUTINE AND PLACE THE CORRECT ADDRESS IN THE VECTOR TABLE.	       :
   885                                  ;-------------------------------------------------------------------------------
   886                                  ;
   887                                  
   888                                  timer_int:	; IRQ 0
   889                                  ;int_08h:	; Timer
   890                                  	; 14/10/2015
   891                                  	; Here, we are simulating system call entry (for task switch)
   892                                  	; (If multitasking is enabled, 
   893                                  	; 'clock' procedure may jump to 'sysrelease')
   894 00000711 1E                      	push	ds
   895 00000712 06                      	push	es
   896 00000713 0FA0                    	push	fs
   897 00000715 0FA8                    	push	gs
   898 00000717 60                      	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
   899 00000718 66B91000                	mov     cx, KDATA
   900 0000071C 8ED9                            mov     ds, cx
   901 0000071E 8EC1                            mov     es, cx
   902 00000720 8EE1                            mov     fs, cx
   903 00000722 8EE9                            mov     gs, cx
   904                                  	;
   905 00000724 0F20D9                  	mov	ecx, cr3
   906 00000727 890D[C6070000]          	mov	[cr3reg], ecx ; save current cr3 register value/content
   907                                  	;
   908 0000072D 3B0D[E8A70000]          	cmp 	ecx, [k_page_dir]
   909 00000733 741F                    	je	short T3
   910                                  	;
   911                                  	; timer interrupt has been occurred while OS is in user mode
   912 00000735 A3[C0B70000]            	mov 	[u.r0], eax
   913 0000073A 89E1                    	mov	ecx, esp
   914 0000073C 83C130                  	add	ecx, ESPACE ; 4 * 12 (stack frame)	
   915 0000073F 890D[B8B70000]          	mov	[u.sp], ecx ; kernel stack pointer at the start of interrupt
   916 00000745 8925[BCB70000]          	mov	[u.usp], esp ; kernel stack points to user's registers   
   917                                  	;
   918 0000074B 8B0D[E8A70000]          	mov	ecx, [k_page_dir]
   919 00000751 0F22D9                  	mov	cr3, ecx
   920                                  T3:
   921 00000754 FB                      	sti				; INTERRUPTS BACK ON
   922 00000755 66FF05[6CA80000]        	INC	word [TIMER_LOW]	; INCREMENT TIME
   923 0000075C 7507                    	JNZ	short T4		; GO TO TEST_DAY
   924 0000075E 66FF05[6EA80000]        	INC	word [TIMER_HIGH]	; INCREMENT HIGH WORD OF TIME
   925                                  T4:					; TEST_DAY
   926 00000765 66833D[6EA80000]18      	CMP	word [TIMER_HIGH],018H	; TEST FOR COUNT EQUALING 24 HOURS
   927 0000076D 7519                    	JNZ	short T5		; GO TO DISKETTE_CTL
   928 0000076F 66813D[6CA80000]B0-     	CMP	word [TIMER_LOW],0B0H
   928 00000777 00                 
   929 00000778 750E                    	JNZ	short T5		; GO TO DISKETTE_CTL
   930                                  
   931                                  ;-----	TIMER HAS GONE 24 HOURS
   932                                  	;;SUB	AX,AX
   933                                  	;MOV	[TIMER_HIGH],AX
   934                                  	;MOV	[TIMER_LOW],AX
   935 0000077A 29C0                    	sub	eax, eax
   936 0000077C A3[6CA80000]            	mov	[TIMER_LH], eax
   937                                  	;	
   938 00000781 C605[70A80000]01        	MOV	byte [TIMER_OFL],1
   939                                  
   940                                  ;-----	TEST FOR DISKETTE TIME OUT
   941                                  
   942                                  T5:
   943                                  	; 23/12/2014
   944 00000788 EB1D                    	jmp	short T6		; will be replaced with nop, nop
   945                                  					; (9090h) if a floppy disk
   946                                  					; is detected.
   947                                  	;mov	al,[CS:MOTOR_COUNT]
   948 0000078A A0[73A80000]            	mov	al, [MOTOR_COUNT]
   949 0000078F FEC8                    	dec	al
   950                                  	;mov	[CS:MOTOR_COUNT], al	; DECREMENT DISKETTE MOTOR CONTROL
   951 00000791 A2[73A80000]            	mov	[MOTOR_COUNT], al
   952                                  	;mov	[ORG_MOTOR_COUNT], al
   953 00000796 750F                    	JNZ	short T6		; RETURN IF COUNT NOT OUT
   954 00000798 B0F0                    	mov 	al,0F0h
   955                                  	;AND	[CS:MOTOR_STATUS],al 	; TURN OFF MOTOR RUNNING BITS
   956 0000079A 2005[72A80000]          	and	[MOTOR_STATUS], al
   957                                  	;and	[ORG_MOTOR_STATUS], al
   958 000007A0 B00C                    	MOV	AL,0CH			; bit 3 = enable IRQ & DMA, 
   959                                  					; bit 2 = enable controller
   960                                  					;	1 = normal operation
   961                                  					;	0 = reset	
   962                                  					; bit 0, 1 = drive select
   963                                  					; bit 4-7 = motor running bits 
   964 000007A2 66BAF203                	MOV	DX,03F2H		; FDC CTL PORT
   965 000007A6 EE                      	OUT	DX,AL			; TURN OFF THE MOTOR
   966                                  T6:	
   967                                  	;inc	word [CS:wait_count]	; 22/12/2014 (byte -> word)
   968                                  					; TIMER TICK INTERRUPT
   969                                  	;;inc	word [wait_count] ;;27/02/2015
   970                                  	;INT	1CH			; TRANSFER CONTROL TO A USER ROUTINE
   971                                  	;;;;cli
   972                                  	;call 	u_timer			; TRANSFER CONTROL TO A USER ROUTINE
   973 000007A7 FF15[C2070000]          	call	[x_timer] ; 14/05/2015
   974                                  T7:
   975                                  	; 14/10/2015
   976 000007AD B020                    	MOV	AL,EOI			; GET END OF INTERRUPT MASK
   977 000007AF FA                      	CLI				; DISABLE INTERRUPTS TILL STACK CLEARED
   978 000007B0 E620                    	OUT	INTA00,AL		; END OF INTERRUPT TO 8259 - 1	
   979                                  	;
   980 000007B2 A1[C6070000]            	mov 	eax, [cr3reg] 		; previous value/content of cr3 register
   981 000007B7 0F22D8                   	mov	cr3, eax  ; restore cr3 register content
   982                                  	;
   983 000007BA 61                      	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
   984                                  	;
   985 000007BB 0FA9                    	pop	gs
   986 000007BD 0FA1                    	pop	fs
   987 000007BF 07                      	pop	es
   988 000007C0 1F                      	pop	ds
   989 000007C1 CF                      	iretd	; return from interrupt
   990                                  
   991                                  
   992                                  ; ////////////////
   993                                  
   994                                  ; 14/05/2015 - Multi tasking 'clock' procedure (sys emt)
   995                                  x_timer:
   996 000007C2 [CA070000]              	dd 	u_timer			; 14/05/2015
   997                                  	;dd	clock
   998                                  
   999                                  ; 14/10/2015
  1000 000007C6 00000000                cr3reg: dd 0
  1001                                  
  1002                                  	; 06/02/2015
  1003                                  	; 07/09/2014
  1004                                  	; 21/08/2014
  1005                                  u_timer:
  1006                                  ;timer_int:	; IRQ 0
  1007                                  	; 06/02/2015
  1008                                  	;push	eax
  1009                                  	;push	edx
  1010                                  	;push	ecx
  1011                                  	;push	ebx
  1012                                  	;push	ds
  1013                                  	;push	es
  1014                                  	;mov	eax, KDATA
  1015                                  	;mov	ds, ax
  1016                                  	;mov	es, ax
  1017 000007CA FF05[2EA80000]          	inc	dword [tcount]
  1018 000007D0 BB[5DA30000]            	mov	ebx, tcountstr + 4
  1019 000007D5 66A1[2EA80000]          	mov	ax, [tcount]
  1020 000007DB B90A000000              	mov	ecx, 10
  1021                                  rp_divtcnt:
  1022 000007E0 31D2                    	xor	edx, edx
  1023 000007E2 F7F1                    	div	ecx
  1024 000007E4 80C230                  	add	dl, 30h
  1025 000007E7 8813                    	mov	[ebx], dl
  1026 000007E9 6609C0                  	or	ax, ax
  1027 000007EC 7403                    	jz	short print_lzero
  1028 000007EE 4B                      	dec	ebx
  1029 000007EF EBEF                    	jmp	short rp_divtcnt
  1030                                  print_lzero:
  1031 000007F1 81FB[59A30000]          	cmp	ebx, tcountstr
  1032 000007F7 7606                    	jna	short print_tcount
  1033 000007F9 4B                      	dec	ebx
  1034 000007FA C60330                   	mov	byte [ebx], 30h
  1035 000007FD EBF2                    	jmp	short print_lzero
  1036                                  print_tcount:
  1037 000007FF 56                      	push	esi
  1038 00000800 57                      	push	edi
  1039 00000801 BE[35A30000]            	mov	esi, timer_msg ; Timer interrupt message
  1040                                  	; 07/09/2014
  1041 00000806 66BB0100                	mov	bx, 1		; Video page 1
  1042                                  ptmsg:
  1043 0000080A AC                      	lodsb
  1044 0000080B 08C0                    	or	al, al
  1045 0000080D 740F                    	jz	short ptmsg_ok
  1046 0000080F 56                      	push	esi
  1047 00000810 6653                    	push	bx
  1048 00000812 B42F                            mov     ah,  2Fh ; Green background, white forecolor
  1049 00000814 E89D0F0000              	call 	WRITE_TTY
  1050 00000819 665B                    	pop	bx
  1051 0000081B 5E                      	pop	esi
  1052 0000081C EBEC                    	jmp	short ptmsg
  1053                                  	;; 27/08/2014
  1054                                  	;mov     edi, 0B8000h + 0A0h ; Row 1
  1055                                  	;call	printk
  1056                                  	;
  1057                                  ptmsg_ok:
  1058                                  	; 07/09/2014
  1059 0000081E 6631D2                  	xor	dx, dx		; column 0, row 0
  1060 00000821 E824100000              	call	_set_cpos	; set cursor position to 0,0 
  1061                                  	; 23/02/2015
  1062                                  	; 25/08/2014
  1063                                  	;mov	ebx, scounter		; (seconds counter)
  1064                                  	;dec	byte [ebx+1]		; (for reading real time clock)
  1065                                  ;	dec	byte [scounter+1]
  1066                                  ;;	jns	short timer_eoi		; 0 -> 0FFh ?
  1067                                  ;	jns	short u_timer_retn
  1068                                  	; 26/02/2015
  1069                                  ;	call	rtc_p
  1070                                  ;	mov	ebx, scounter		; (seconds counter)
  1071                                  ;	mov	byte [ebx+1], 18	; (18.2 timer ticks per second)
  1072                                  ;	dec 	byte [ebx]		; 19+18+18+18+18 (5)	
  1073                                  ;	jnz	short timer_eoi		; (109 timer ticks in 5 seconds)
  1074                                  ;	jnz	short u_timer_retn ; 06/02/2015
  1075                                  ;	mov	byte [ebx], 5
  1076                                  ;	inc	byte [ebx+1] ; 19
  1077                                  ;;timer_eoi:
  1078                                  ;;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1079                                  ;;	out	20h, al	; 8259 PORT
  1080                                  	;
  1081                                  ;u_timer_retn:  ; 06/02/2015
  1082 00000826 5F                      	pop	edi
  1083 00000827 5E                      	pop	esi
  1084                                  	;pop	es
  1085                                  	;pop	ds
  1086                                  	;pop	ebx
  1087                                  	;pop	ecx
  1088                                  	;pop	edx
  1089                                  	;pop	eax
  1090                                  	;iret
  1091 00000828 C3                      	retn	; 06/02/2015
  1092                                  
  1093                                  	; 28/08/2014
  1094                                  irq0:
  1095 00000829 6A00                            push 	dword 0
  1096 0000082B EB48                    	jmp	short which_irq
  1097                                  irq1:
  1098 0000082D 6A01                            push 	dword 1
  1099 0000082F EB44                    	jmp	short which_irq
  1100                                  irq2:
  1101 00000831 6A02                            push 	dword 2
  1102 00000833 EB40                    	jmp	short which_irq
  1103                                  irq3:
  1104                                  	; 20/11/2015
  1105                                  	; 24/10/2015
  1106 00000835 2EFF15[76990000]        	call	dword [cs:com2_irq3]
  1107 0000083C 6A03                    	push 	dword 3
  1108 0000083E EB35                    	jmp	short which_irq
  1109                                  irq4:
  1110                                  	; 20/11/2015
  1111                                  	; 24/10/2015
  1112 00000840 2EFF15[72990000]        	call	dword [cs:com1_irq4]
  1113 00000847 6A04                            push 	dword 4
  1114 00000849 EB2A                    	jmp	short which_irq
  1115                                  irq5:
  1116 0000084B 6A05                            push 	dword 5
  1117 0000084D EB26                    	jmp	short which_irq
  1118                                  irq6:
  1119 0000084F 6A06                            push 	dword 6
  1120 00000851 EB22                    	jmp	short which_irq
  1121                                  irq7:
  1122 00000853 6A07                            push 	dword 7
  1123 00000855 EB1E                    	jmp	short which_irq
  1124                                  irq8:
  1125 00000857 6A08                            push 	dword 8
  1126 00000859 EB1A                    	jmp	short which_irq
  1127                                  irq9:
  1128 0000085B 6A09                            push 	dword 9
  1129 0000085D EB16                    	jmp	short which_irq
  1130                                  irq10:
  1131 0000085F 6A0A                            push 	dword 10
  1132 00000861 EB12                    	jmp	short which_irq
  1133                                  irq11:
  1134 00000863 6A0B                            push 	dword 11
  1135 00000865 EB0E                    	jmp	short which_irq
  1136                                  irq12:
  1137 00000867 6A0C                            push 	dword 12
  1138 00000869 EB0A                    	jmp	short which_irq
  1139                                  irq13:
  1140 0000086B 6A0D                            push 	dword 13
  1141 0000086D EB06                    	jmp	short which_irq
  1142                                  irq14:
  1143 0000086F 6A0E                            push 	dword 14
  1144 00000871 EB02                    	jmp	short which_irq
  1145                                  irq15:
  1146 00000873 6A0F                            push 	dword 15
  1147                                  	;jmp	short which_irq
  1148                                  
  1149                                  	; 19/10/2015
  1150                                  	; 29/08/2014
  1151                                  	; 21/08/2014
  1152                                  which_irq:
  1153 00000875 870424                  	xchg	eax, [esp]  ; 28/08/2014
  1154 00000878 53                      	push	ebx
  1155 00000879 56                      	push	esi
  1156 0000087A 57                      	push	edi
  1157 0000087B 1E                      	push 	ds
  1158 0000087C 06                      	push 	es
  1159                                  	;
  1160 0000087D 88C3                    	mov	bl, al
  1161                                  	;
  1162 0000087F B810000000              	mov	eax, KDATA
  1163 00000884 8ED8                    	mov	ds, ax
  1164 00000886 8EC0                    	mov	es, ax
  1165                                  	; 19/10/2015
  1166 00000888 FC                      	cld
  1167                                          ; 27/08/2014
  1168 00000889 8105[18A30000]A000-             add     dword [scr_row], 0A0h
  1168 00000891 0000               
  1169                                  	;
  1170 00000893 B417                    	mov	ah, 17h	; blue (1) background, 
  1171                                  			; light gray (7) forecolor
  1172 00000895 8B3D[18A30000]                  mov     edi, [scr_row]
  1173 0000089B B049                    	mov	al, 'I'
  1174 0000089D 66AB                    	stosw
  1175 0000089F B052                    	mov	al, 'R'
  1176 000008A1 66AB                    	stosw
  1177 000008A3 B051                    	mov	al, 'Q'
  1178 000008A5 66AB                    	stosw
  1179 000008A7 B020                    	mov	al, ' '
  1180 000008A9 66AB                    	stosw
  1181 000008AB 88D8                    	mov	al, bl
  1182 000008AD 3C0A                    	cmp	al, 10
  1183 000008AF 7208                    	jb	short iix
  1184 000008B1 B031                    	mov	al, '1'
  1185 000008B3 66AB                    	stosw
  1186 000008B5 88D8                    	mov	al, bl
  1187 000008B7 2C0A                    	sub	al, 10
  1188                                  iix:
  1189 000008B9 0430                    	add	al, '0'
  1190 000008BB 66AB                    	stosw
  1191 000008BD B020                    	mov	al, ' '
  1192 000008BF 66AB                    	stosw
  1193 000008C1 B021                    	mov	al, '!'
  1194 000008C3 66AB                    	stosw
  1195 000008C5 B020                    	mov	al, ' '
  1196 000008C7 66AB                    	stosw
  1197                                  	; 23/02/2015
  1198 000008C9 80FB07                  	cmp	bl, 7 ; check for IRQ 8 to IRQ 15 
  1199 000008CC 0F868D010000            	jna	iiret
  1200 000008D2 B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  1201 000008D4 E6A0                    	out	0A0h, al ; the 2nd 8259
  1202 000008D6 E984010000              	jmp     iiret
  1203                                  	;
  1204                                  	; 22/08/2014
  1205                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1206                                  	;out	20h, al	; 8259 PORT
  1207                                  	;
  1208                                  	;pop	es
  1209                                  	;pop	ds
  1210                                  	;pop	edi
  1211                                  	;pop	esi
  1212                                  	;pop	ebx
  1213                                  	;pop 	eax
  1214                                  	;iret
  1215                                  
  1216                                  	; 02/04/2015
  1217                                  	; 25/08/2014
  1218                                  exc0:
  1219 000008DB 6A00                            push 	dword 0
  1220 000008DD E990000000                      jmp     cpu_except
  1221                                  exc1:
  1222 000008E2 6A01                            push 	dword 1
  1223 000008E4 E989000000                      jmp     cpu_except
  1224                                  exc2:
  1225 000008E9 6A02                            push 	dword 2
  1226 000008EB E982000000                      jmp     cpu_except
  1227                                  exc3:
  1228 000008F0 6A03                            push 	dword 3
  1229 000008F2 EB7E                            jmp     cpu_except
  1230                                  exc4:
  1231 000008F4 6A04                            push 	dword 4
  1232 000008F6 EB7A                            jmp     cpu_except
  1233                                  exc5:
  1234 000008F8 6A05                            push 	dword 5
  1235 000008FA EB76                            jmp     cpu_except
  1236                                  exc6:
  1237 000008FC 6A06                            push 	dword 6
  1238 000008FE EB72                            jmp     cpu_except
  1239                                  exc7:
  1240 00000900 6A07                            push 	dword 7
  1241 00000902 EB6E                            jmp     cpu_except
  1242                                  exc8:
  1243                                  	; [esp] = Error code
  1244 00000904 6A08                            push 	dword 8
  1245 00000906 EB5C                            jmp     cpu_except_en
  1246                                  exc9:
  1247 00000908 6A09                            push 	dword 9
  1248 0000090A EB66                            jmp     cpu_except
  1249                                  exc10:
  1250                                  	; [esp] = Error code
  1251 0000090C 6A0A                            push 	dword 10
  1252 0000090E EB54                            jmp     cpu_except_en
  1253                                  exc11:
  1254                                  	; [esp] = Error code
  1255 00000910 6A0B                            push 	dword 11
  1256 00000912 EB50                            jmp     cpu_except_en
  1257                                  exc12:
  1258                                  	; [esp] = Error code
  1259 00000914 6A0C                            push 	dword 12
  1260 00000916 EB4C                            jmp     cpu_except_en
  1261                                  exc13:
  1262                                  	; [esp] = Error code
  1263 00000918 6A0D                            push 	dword 13
  1264 0000091A EB48                            jmp     cpu_except_en
  1265                                  exc14:
  1266                                  	; [esp] = Error code
  1267 0000091C 6A0E                            push 	dword 14
  1268 0000091E EB44                    	jmp	short cpu_except_en
  1269                                  exc15:
  1270 00000920 6A0F                            push 	dword 15
  1271 00000922 EB4E                            jmp     cpu_except
  1272                                  exc16:
  1273 00000924 6A10                            push 	dword 16
  1274 00000926 EB4A                            jmp     cpu_except
  1275                                  exc17:
  1276                                  	; [esp] = Error code
  1277 00000928 6A11                            push 	dword 17
  1278 0000092A EB38                    	jmp	short cpu_except_en
  1279                                  exc18:
  1280 0000092C 6A12                            push 	dword 18
  1281 0000092E EB42                    	jmp	short cpu_except
  1282                                  exc19:
  1283 00000930 6A13                            push 	dword 19
  1284 00000932 EB3E                    	jmp	short cpu_except
  1285                                  exc20:
  1286 00000934 6A14                            push 	dword 20
  1287 00000936 EB3A                    	jmp	short cpu_except
  1288                                  exc21:
  1289 00000938 6A15                            push 	dword 21
  1290 0000093A EB36                    	jmp	short cpu_except
  1291                                  exc22:
  1292 0000093C 6A16                            push 	dword 22
  1293 0000093E EB32                    	jmp	short cpu_except
  1294                                  exc23:
  1295 00000940 6A17                            push 	dword 23
  1296 00000942 EB2E                    	jmp	short cpu_except
  1297                                  exc24:
  1298 00000944 6A18                            push 	dword 24
  1299 00000946 EB2A                    	jmp	short cpu_except
  1300                                  exc25:
  1301 00000948 6A19                            push 	dword 25
  1302 0000094A EB26                    	jmp	short cpu_except
  1303                                  exc26:
  1304 0000094C 6A1A                            push 	dword 26
  1305 0000094E EB22                    	jmp	short cpu_except
  1306                                  exc27:
  1307 00000950 6A1B                            push 	dword 27
  1308 00000952 EB1E                    	jmp	short cpu_except
  1309                                  exc28:
  1310 00000954 6A1C                            push 	dword 28
  1311 00000956 EB1A                    	jmp	short cpu_except
  1312                                  exc29:
  1313 00000958 6A1D                            push 	dword 29
  1314 0000095A EB16                    	jmp	short cpu_except
  1315                                  exc30:
  1316 0000095C 6A1E                            push 	dword 30
  1317 0000095E EB04                    	jmp	short cpu_except_en
  1318                                  exc31:
  1319 00000960 6A1F                            push 	dword 31
  1320 00000962 EB0E                            jmp     short cpu_except
  1321                                  
  1322                                  	; 19/10/2015
  1323                                  	; 19/09/2015
  1324                                  	; 01/09/2015
  1325                                  	; 28/08/2015
  1326                                  	; 28/08/2014
  1327                                  cpu_except_en:
  1328 00000964 87442404                	xchg	eax, [esp+4] ; Error code
  1329 00000968 36A3[8CC40000]          	mov	[ss:error_code], eax
  1330 0000096E 58                      	pop	eax  ; Exception number
  1331 0000096F 870424                  	xchg	eax, [esp]
  1332                                  		; eax = eax before exception
  1333                                  		; [esp] -> exception number
  1334                                  		; [esp+4] -> EIP to return
  1335                                  	; 19/10/2015
  1336                                  	; 19/09/2015
  1337                                  	; 01/09/2015
  1338                                  	; 28/08/2015
  1339                                  	; 29/08/2014
  1340                                  	; 28/08/2014
  1341                                  	; 25/08/2014
  1342                                  	; 21/08/2014
  1343                                  cpu_except:	; CPU Exceptions
  1344 00000972 FC                      	cld
  1345 00000973 870424                  	xchg	eax, [esp] 
  1346                                  		; eax = Exception number
  1347                                  		; [esp] = eax (before exception)	
  1348 00000976 53                      	push	ebx
  1349 00000977 56                      	push	esi
  1350 00000978 57                      	push	edi
  1351 00000979 1E                      	push 	ds
  1352 0000097A 06                      	push 	es
  1353                                  	; 28/08/2015
  1354 0000097B 66BB1000                	mov	bx, KDATA
  1355 0000097F 8EDB                    	mov	ds, bx
  1356 00000981 8EC3                    	mov	es, bx
  1357 00000983 0F20DB                  	mov	ebx, cr3
  1358 00000986 53                      	push	ebx ; (*) page directory
  1359                                  	; 19/10/2015
  1360 00000987 FC                      	cld
  1361                                  	; 25/03/2015
  1362 00000988 8B1D[E8A70000]          	mov	ebx, [k_page_dir]
  1363 0000098E 0F22DB                  	mov	cr3, ebx
  1364                                  	; 28/08/2015
  1365 00000991 83F80E                  	cmp	eax, 0Eh ; 14, PAGE FAULT	
  1366 00000994 7512                    	jne	short cpu_except_nfp
  1367 00000996 E83E2A0000              	call	page_fault_handler
  1368 0000099B 21C0                    	and 	eax, eax
  1369 0000099D 0F84B8000000                    jz	iiretp ; 01/09/2015
  1370 000009A3 B80E000000              	mov	eax, 0Eh ; 14
  1371                                  cpu_except_nfp:
  1372                                  	; 02/04/2015
  1373 000009A8 BB[CA060000]            	mov	ebx, hang
  1374 000009AD 875C241C                	xchg	ebx, [esp+28]
  1375                                  		; EIP (points to instruction which faults)
  1376                                  	  	; New EIP (hang)
  1377 000009B1 891D[90C40000]          	mov	[FaultOffset], ebx
  1378 000009B7 C744242008000000        	mov	dword [esp+32], KCODE ; kernel's code segment
  1379 000009BF 814C242400020000        	or	dword [esp+36], 200h ; enable interrupts (set IF)
  1380                                  	;
  1381 000009C7 88C4                    	mov	ah, al
  1382 000009C9 240F                    	and	al, 0Fh
  1383 000009CB 3C09                    	cmp	al, 9
  1384 000009CD 7602                    	jna	short h1ok
  1385 000009CF 0407                    	add	al, 'A'-':'
  1386                                  h1ok:
  1387 000009D1 D0EC                    	shr	ah, 1
  1388 000009D3 D0EC                    	shr	ah, 1
  1389 000009D5 D0EC                    	shr	ah, 1
  1390 000009D7 D0EC                    	shr	ah, 1
  1391 000009D9 80FC09                  	cmp	ah, 9
  1392 000009DC 7603                    	jna	short h2ok
  1393 000009DE 80C407                  	add	ah, 'A'-':'
  1394                                  h2ok:	
  1395 000009E1 86E0                    	xchg 	ah, al	
  1396 000009E3 66053030                	add	ax, '00'
  1397 000009E7 66A3[70A30000]          	mov	[excnstr], ax
  1398                                  	;
  1399                                  	; 29/08/2014
  1400 000009ED A1[90C40000]            	mov	eax, [FaultOffset]
  1401 000009F2 51                      	push	ecx
  1402 000009F3 52                      	push	edx
  1403 000009F4 89E3                    	mov	ebx, esp
  1404                                  	; 28/08/2015
  1405 000009F6 B910000000              	mov	ecx, 16	  ; divisor value to convert binary number
  1406                                  			  ; to hexadecimal string
  1407                                  	;mov	ecx, 10	    ; divisor to convert	
  1408                                  			    ; binary number to decimal string
  1409                                  b2d1:
  1410 000009FB 31D2                    	xor	edx, edx
  1411 000009FD F7F1                    	div	ecx
  1412 000009FF 6652                    	push	dx
  1413 00000A01 39C8                    	cmp	eax, ecx
  1414 00000A03 73F6                    	jnb	short b2d1
  1415 00000A05 BF[7BA30000]            	mov	edi, EIPstr ; EIP value
  1416                                  			    ; points to instruction which faults	
  1417                                  	; 28/08/2015
  1418 00000A0A 89C2                    	mov	edx, eax
  1419                                  b2d2:
  1420                                  	;add	al, '0'
  1421 00000A0C 8A82[F8190000]          	mov	al, [edx+hexchrs]
  1422 00000A12 AA                      	stosb		    ; write hexadecimal digit to its place	
  1423 00000A13 39E3                    	cmp	ebx, esp
  1424 00000A15 7606                    	jna	short b2d3
  1425 00000A17 6658                    	pop	ax
  1426 00000A19 88C2                    	mov	dl, al
  1427 00000A1B EBEF                    	jmp	short b2d2
  1428                                  b2d3:
  1429 00000A1D B068                    	mov 	al, 'h' ; 28/08/2015
  1430 00000A1F AA                      	stosb
  1431 00000A20 B020                    	mov	al, 20h	    ; space
  1432 00000A22 AA                      	stosb
  1433 00000A23 30C0                    	xor	al, al	    ; to do it an ASCIIZ string	
  1434 00000A25 AA                      	stosb
  1435                                  	;
  1436 00000A26 5A                      	pop	edx
  1437 00000A27 59                      	pop	ecx
  1438                                  	;
  1439 00000A28 B44F                    	mov	ah, 4Fh	; red (4) background, 
  1440                                  			; white (F) forecolor
  1441 00000A2A BE[60A30000]            	mov	esi, exc_msg ; message offset
  1442                                  	;
  1443 00000A2F EB11                    	jmp	short piemsg
  1444                                  	;
  1445                                          ;add    dword [scr_row], 0A0h
  1446                                          ;mov    edi, [scr_row]
  1447                                          ;
  1448                                  	;call 	printk
  1449                                  	;
  1450                                  	;mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1451                                  	;out	20h, al	; 8259 PORT
  1452                                  	;
  1453                                  	;pop	es
  1454                                  	;pop	ds
  1455                                  	;pop	edi
  1456                                  	;pop	esi
  1457                                  	;pop 	eax
  1458                                  	;iret
  1459                                  	
  1460                                  	; 28/08/2015
  1461                                  	; 23/02/2015
  1462                                  	; 20/08/2014
  1463                                  ignore_int:
  1464 00000A31 50                      	push	eax
  1465 00000A32 53                      	push	ebx ; 23/02/2015
  1466 00000A33 56                      	push	esi
  1467 00000A34 57                      	push	edi
  1468 00000A35 1E                      	push 	ds
  1469 00000A36 06                      	push 	es
  1470                                  	; 28/08/2015
  1471 00000A37 0F20D8                  	mov	eax, cr3
  1472 00000A3A 50                      	push	eax ; (*) page directory
  1473                                  	;
  1474 00000A3B B467                    	mov	ah, 67h	; brown (6) background, 
  1475                                  			; light gray (7) forecolor
  1476 00000A3D BE[20A30000]            	mov	esi, int_msg ; message offset
  1477                                  piemsg:
  1478                                          ; 27/08/2014
  1479 00000A42 8105[18A30000]A000-             add     dword [scr_row], 0A0h
  1479 00000A4A 0000               
  1480 00000A4C 8B3D[18A30000]                  mov     edi, [scr_row]
  1481                                          ;
  1482 00000A52 E8B0FCFFFF              	call 	printk
  1483                                  	;
  1484                                  	; 23/02/2015
  1485 00000A57 B020                    	mov	al, 20h  ; END OF INTERRUPT COMMAND TO
  1486 00000A59 E6A0                    	out	0A0h, al ; the 2nd 8259
  1487                                  iiretp: ; 01/09/2015
  1488                                  	; 28/08/2015
  1489 00000A5B 58                      	pop	eax ; (*) page directory
  1490 00000A5C 0F22D8                  	mov	cr3, eax
  1491                                  	;
  1492                                  iiret:
  1493                                  	; 22/08/2014
  1494 00000A5F B020                    	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
  1495 00000A61 E620                    	out	20h, al	; 8259 PORT
  1496                                  	;
  1497 00000A63 07                      	pop	es
  1498 00000A64 1F                      	pop	ds
  1499 00000A65 5F                      	pop	edi
  1500 00000A66 5E                      	pop	esi
  1501 00000A67 5B                      	pop	ebx ; 29/08/2014
  1502 00000A68 58                      	pop 	eax
  1503 00000A69 CF                      	iretd
  1504                                  
  1505                                  	; 26/02/2015
  1506                                  	; 07/09/2014
  1507                                  	; 25/08/2014
  1508                                  rtc_int:       ; Real Time Clock Interrupt (IRQ 8)
  1509                                  	; 22/08/2014
  1510 00000A6A 50                      	push	eax
  1511 00000A6B 53                      	push	ebx ; 29/08/2014
  1512 00000A6C 56                      	push	esi
  1513 00000A6D 57                      	push	edi
  1514 00000A6E 1E                      	push 	ds
  1515 00000A6F 06                      	push 	es
  1516                                  	;
  1517 00000A70 B810000000              	mov	eax, KDATA
  1518 00000A75 8ED8                    	mov	ds, ax
  1519 00000A77 8EC0                    	mov	es, ax
  1520                                  	;
  1521                                  	; 25/08/2014
  1522 00000A79 E884000000              	call	rtc_p
  1523                                  	;
  1524                                  	; 22/02/2015 - dsectpm.s
  1525                                  	; [ source: http://wiki.osdev.org/RTC ]
  1526                                  	; read status register C to complete procedure
  1527                                  	;(it is needed to get a next IRQ 8) 
  1528 00000A7E B00C                    	mov	al, 0Ch ; 
  1529 00000A80 E670                    	out	70h, al ; select register C
  1530 00000A82 90                      	nop
  1531 00000A83 E471                    	in	al, 71h ; just throw away contents
  1532                                  	; 22/02/2015
  1533 00000A85 B020                    	MOV	AL,EOI		; END OF INTERRUPT
  1534 00000A87 E6A0                    	OUT	INTB00,AL	; FOR CONTROLLER #2
  1535                                  	;
  1536 00000A89 EBD4                    	jmp	short iiret	
  1537                                  
  1538                                  	; 22/08/2014
  1539                                  	; IBM PC/AT BIOS source code ----- 10/06/85 (bios.asm)
  1540                                  	; (INT 1Ah)
  1541                                  	;; Linux (v0.12) source code (main.c) by Linus Torvalds (1991)
  1542                                  time_of_day:
  1543 00000A8B E8C0300000              	call	UPD_IPR			; WAIT TILL UPDATE NOT IN PROGRESS
  1544 00000A90 726F                            jc      short rtc_retn 
  1545 00000A92 B000                    	mov	al, CMOS_SECONDS
  1546 00000A94 E8D2300000              	call	CMOS_READ
  1547 00000A99 A2[5EA80000]            	mov	[time_seconds], al 
  1548 00000A9E B002                    	mov	al, CMOS_MINUTES
  1549 00000AA0 E8C6300000              	call	CMOS_READ
  1550 00000AA5 A2[5FA80000]            	mov	[time_minutes], al 
  1551 00000AAA B004                    	mov	al, CMOS_HOURS
  1552 00000AAC E8BA300000              	call	CMOS_READ
  1553 00000AB1 A2[60A80000]                    mov     [time_hours], al
  1554 00000AB6 B006                    	mov	al, CMOS_DAY_WEEK 
  1555 00000AB8 E8AE300000              	call	CMOS_READ
  1556 00000ABD A2[61A80000]            	mov	[date_wday], al
  1557 00000AC2 B007                     	mov	al, CMOS_DAY_MONTH
  1558 00000AC4 E8A2300000              	call	CMOS_READ
  1559 00000AC9 A2[62A80000]            	mov	[date_day], al
  1560 00000ACE B008                    	mov	al, CMOS_MONTH
  1561 00000AD0 E896300000              	call	CMOS_READ
  1562 00000AD5 A2[63A80000]            	mov	[date_month], al
  1563 00000ADA B009                    	mov	al, CMOS_YEAR
  1564 00000ADC E88A300000              	call	CMOS_READ
  1565 00000AE1 A2[64A80000]            	mov	[date_year], al
  1566 00000AE6 B032                    	mov	al, CMOS_CENTURY
  1567 00000AE8 E87E300000              	call	CMOS_READ
  1568 00000AED A2[65A80000]            	mov	[date_century], al
  1569                                  	;
  1570 00000AF2 B000                    	mov	al, CMOS_SECONDS
  1571 00000AF4 E872300000              	call 	CMOS_READ
  1572 00000AF9 3A05[5EA80000]          	cmp	al, [time_seconds]
  1573 00000AFF 758A                    	jne	short time_of_day
  1574                                  
  1575                                  rtc_retn:
  1576 00000B01 C3                      	retn
  1577                                  
  1578                                  rtc_p:	
  1579                                  	; 07/09/2014
  1580                                  	; 29/08/2014
  1581                                  	; 27/08/2014
  1582                                  	; 25/08/2014
  1583                                   	; Print Real Time Clock content
  1584                                  	;
  1585                                  	;
  1586 00000B02 E884FFFFFF              	call	time_of_day
  1587 00000B07 72F8                    	jc	short rtc_retn
  1588                                  	;
  1589 00000B09 3A05[D2A30000]          	cmp	al, [ptime_seconds]
  1590 00000B0F 74F0                            je      short rtc_retn ; 29/08/2014
  1591                                  	;
  1592 00000B11 A2[D2A30000]            	mov	[ptime_seconds], al
  1593                                  	;
  1594 00000B16 A0[65A80000]            	mov	al, [date_century]
  1595 00000B1B E8BE000000              	call	bcd_to_ascii
  1596 00000B20 66A3[9FA30000]          	mov	[datestr+6], ax
  1597 00000B26 A0[64A80000]            	mov	al, [date_year]
  1598 00000B2B E8AE000000              	call	bcd_to_ascii
  1599 00000B30 66A3[A1A30000]          	mov	[datestr+8], ax
  1600 00000B36 A0[63A80000]            	mov	al, [date_month]
  1601 00000B3B E89E000000              	call	bcd_to_ascii
  1602 00000B40 66A3[9CA30000]          	mov	[datestr+3], ax
  1603 00000B46 A0[62A80000]            	mov	al, [date_day]
  1604 00000B4B E88E000000              	call	bcd_to_ascii
  1605 00000B50 66A3[99A30000]          	mov	[datestr], ax
  1606                                  	;
  1607 00000B56 0FB61D[61A80000]        	movzx	ebx, byte [date_wday]
  1608 00000B5D C0E302                  	shl 	bl, 2
  1609 00000B60 81C3[B2A30000]          	add	ebx, daytmp
  1610 00000B66 8B03                    	mov	eax, [ebx]
  1611 00000B68 A3[A4A30000]            	mov	[daystr], eax
  1612                                  	;
  1613 00000B6D A0[60A80000]            	mov	al, [time_hours]
  1614 00000B72 E867000000              	call	bcd_to_ascii
  1615 00000B77 66A3[A8A30000]          	mov	[timestr], ax
  1616 00000B7D A0[5FA80000]            	mov	al, [time_minutes]
  1617 00000B82 E857000000              	call	bcd_to_ascii
  1618 00000B87 66A3[ABA30000]          	mov	[timestr+3], ax
  1619 00000B8D A0[5EA80000]            	mov	al, [time_seconds]
  1620 00000B92 E847000000              	call	bcd_to_ascii
  1621 00000B97 66A3[AEA30000]          	mov	[timestr+6], ax
  1622                                  	;		
  1623 00000B9D BE[87A30000]            	mov	esi, rtc_msg ; message offset
  1624                                  	; 23/02/2015
  1625 00000BA2 52                      	push	edx
  1626 00000BA3 51                      	push	ecx
  1627                                  	; 07/09/2014
  1628 00000BA4 66BB0200                	mov	bx, 2		; Video page 2
  1629                                  prtmsg:
  1630 00000BA8 AC                      	lodsb
  1631 00000BA9 08C0                    	or	al, al
  1632 00000BAB 740F                    	jz	short prtmsg_ok
  1633 00000BAD 56                      	push	esi
  1634 00000BAE 6653                    	push	bx
  1635 00000BB0 B43F                            mov	ah, 3Fh	; cyan (6) background, 
  1636                                  			; white (F) forecolor
  1637 00000BB2 E8FF0B0000              	call 	WRITE_TTY
  1638 00000BB7 665B                    	pop	bx
  1639 00000BB9 5E                      	pop	esi
  1640 00000BBA EBEC                    	jmp	short prtmsg
  1641                                  	;
  1642                                  	;mov	edi, 0B8000h+0A0h+0A0h ; Row 2
  1643                                  	;call	printk
  1644                                  prtmsg_ok:
  1645                                  	; 07/09/2014
  1646 00000BBC 6631D2                  	xor	dx, dx		; column 0, row 0
  1647 00000BBF E8860C0000              	call	_set_cpos	; set curspor position to 0,0 
  1648                                  	; 23/02/2015
  1649 00000BC4 59                      	pop	ecx
  1650 00000BC5 5A                      	pop	edx
  1651 00000BC6 C3                      	retn
  1652                                  
  1653                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  1654                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  1655                                  default_irq7:
  1656 00000BC7 6650                    	push	ax
  1657 00000BC9 B00B                    	mov	al, 0Bh  ; In-Service register
  1658 00000BCB E620                    	out	20h, al
  1659 00000BCD EB00                            jmp short $+2
  1660 00000BCF EB00                    	jmp short $+2
  1661 00000BD1 E420                    	in	al, 20h
  1662 00000BD3 2480                    	and 	al, 80h ; bit 7 (is it real IRQ 7 or fake?)
  1663 00000BD5 7404                            jz      short irq7_iret ; Fake (spurious) IRQ, do not send EOI 
  1664 00000BD7 B020                            mov     al, 20h ; EOI
  1665 00000BD9 E620                    	out	20h, al 
  1666                                  irq7_iret:
  1667 00000BDB 6658                    	pop	ax
  1668 00000BDD CF                      	iretd
  1669                                  	
  1670                                  bcd_to_ascii:
  1671                                  	; 25/08/2014
  1672                                  	; INPUT ->
  1673                                  	;	al = Packed BCD number
  1674                                  	; OUTPUT ->
  1675                                  	;	ax  = ASCII word/number
  1676                                  	;
  1677                                  	; Erdogan Tan - 1998 (proc_hex) - TRDOS.ASM (2004-2011)
  1678                                  	;
  1679 00000BDE D410                    	db 0D4h,10h                     ; Undocumented inst. AAM
  1680                                  					; AH = AL / 10h
  1681                                  					; AL = AL MOD 10h
  1682 00000BE0 660D3030                	or ax,'00'                      ; Make it ASCII based
  1683                                  
  1684 00000BE4 86E0                            xchg ah, al 
  1685                                  	
  1686 00000BE6 C3                      	retn	
  1687                                  	
  1688                                  
  1689                                  %include 'keyboard.s' ; 07/03/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - keyboard.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 29/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> ; 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 00000BE7 9C                  <1> 	pushfd	; 28/08/2014
    40 00000BE8 0E                  <1> 	push 	cs
    41 00000BE9 E801000000          <1> 	call 	KEYBOARD_IO_1 ; getc_int
    42 00000BEE 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> KEYBOARD_IO_1:	
   136 00000BEF FB                  <1> 	sti				; INTERRUPTS BACK ON
   137 00000BF0 1E                  <1> 	push	ds			; SAVE CURRENT DS
   138 00000BF1 53                  <1> 	push	ebx			; SAVE BX TEMPORARILY
   139                              <1> 	;push	ecx			; SAVE CX TEMPORARILY
   140 00000BF2 66BB1000            <1>         mov     bx, KDATA 
   141 00000BF6 8EDB                <1> 	mov	ds, bx			; PUT SEGMENT VALUE OF DATA AREA INTO DS
   142 00000BF8 08E4                <1> 	or	ah, ah			; CHECK FOR (AH)= 00H
   143 00000BFA 7439                <1> 	jz	short _K1		; ASCII_READ
   144 00000BFC FECC                <1> 	dec	ah                      ; CHECK FOR (AH)= 01H
   145 00000BFE 7452                <1>         jz      short _K2               ; ASCII_STATUS
   146 00000C00 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 02H
   147 00000C02 0F8485000000        <1>         jz      _K3                     ; SHIFT STATUS
   148 00000C08 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 03H	
   149 00000C0A 0F8484000000        <1>         jz      _K300                   ; SET TYPAMATIC RATE/DELAY
   150 00000C10 80EC02              <1> 	sub	ah, 2			; CHECK FOR (AH)= 05H	
   151 00000C13 0F84A1000000        <1>         jz      _K500                   ; KEYBOARD WRITE         
   152                              <1> _KIO1:	
   153 00000C19 80EC0B              <1> 	sub	ah, 11			; AH =  10H
   154 00000C1C 740B                <1> 	jz	short _K1E		; EXTENDED ASCII READ
   155 00000C1E FECC                <1> 	dec	ah			; CHECK FOR (AH)= 11H
   156 00000C20 7421                <1> 	jz	short _K2E		; EXTENDED_ASCII_STATUS
   157 00000C22 FECC                <1> 	dec	ah			; CHECK FOR (AH)= 12H
   158 00000C24 7449                <1> 	jz	short _K3E		; EXTENDED_SHIFT_STATUS
   159                              <1> _KIO_EXIT:
   160                              <1> 	;pop	ecx			; RECOVER REGISTER
   161 00000C26 5B                  <1> 	pop	ebx			; RECOVER REGISTER
   162 00000C27 1F                  <1> 	pop	ds			; RECOVER SEGMENT
   163 00000C28 CF                  <1> 	iretd				; INVALID COMMAND, EXIT
   164                              <1> 
   165                              <1> 	;-----	ASCII CHARACTER
   166                              <1> _K1E:	
   167 00000C29 E8B9000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER (EXTENDED)
   168 00000C2E E82E010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
   169 00000C33 EBF1                <1> 	jmp	short _KIO_EXIT         ; GIVE IT TO THE CALLER
   170                              <1> _K1:	
   171 00000C35 E8AD000000          <1> 	call	_K1S			; GET A CHARACTER FROM THE BUFFER
   172 00000C3A E82D010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
   173 00000C3F 72F4                <1> 	jc	short _K1		; CARRY SET MEANS TROW CODE AWAY
   174                              <1> _K1A:
   175 00000C41 EBE3                <1> 	jmp	short _KIO_EXIT         ; RETURN TO CALLER
   176                              <1> 
   177                              <1> 	;-----	ASCII STATUS
   178                              <1> _K2E:	
   179 00000C43 E8EA000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER (EXTENDED)
   180 00000C48 7420                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
   181 00000C4A 9C                  <1> 	pushf				; SAVE ZF FROM TEST
   182 00000C4B E811010000          <1> 	call	_KIO_E_XLAT		; ROUTINE TO XLATE FOR EXTENDED CALLS
   183 00000C50 EB17                <1> 	jmp	short _K2A	        ; GIVE IT TO THE CALLER
   184                              <1> _K2:	
   185 00000C52 E8DB000000          <1> 	call	_K2S			; TEST FOR CHARACTER IN BUFFER
   186 00000C57 7411                <1> 	jz	short _K2B		; RETURN IF BUFFER EMPTY
   187 00000C59 9C                  <1> 	pushf				; SAVE ZF FROM TEST
   188 00000C5A E80D010000          <1> 	call	_KIO_S_XLAT		; ROUTINE TO XLATE FOR STANDARD CALLS
   189 00000C5F 7308                <1> 	jnc	short _K2A	        ; CARRY CLEAR MEANS PASS VALID CODE
   190 00000C61 9D                  <1> 	popf				; INVALID CODE FOR THIS TYPE OF CALL
   191 00000C62 E880000000          <1> 	call	_K1S			; THROW THE CHARACTER AWAY
   192 00000C67 EBE9                <1> 	jmp	short _K2		; GO LOOK FOR NEXT CHAR, IF ANY
   193                              <1> _K2A:
   194 00000C69 9D                  <1> 	popf				; RESTORE ZF FROM TEST
   195                              <1> _K2B:
   196                              <1> 	;pop	ecx			; RECOVER REGISTER
   197 00000C6A 5B                  <1> 	pop	ebx			; RECOVER REGISTER
   198 00000C6B 1F                  <1> 	pop	ds			; RECOVER SEGMENT
   199 00000C6C CA0400              <1> 	retf	4			; THROW AWAY (e)FLAGS
   200                              <1> 
   201                              <1> 	;-----	SHIFT STATUS
   202                              <1> _K3E:                                   ; GET THE EXTENDED SHIFT STATUS FLAGS
   203 00000C6F 8A25[E2A10000]      <1> 	mov	ah, [KB_FLAG_1]		; GET SYSTEM SHIFT KEY STATUS
   204 00000C75 80E404              <1> 	and	ah, SYS_SHIFT		; MASK ALL BUT SYS KEY BIT
   205                              <1> 	;mov	cl, 5			; SHIFT THEW SYSTEMKEY BIT OVER TO
   206                              <1> 	;shl	ah, cl			; BIT 7 POSITION
   207 00000C78 C0E405              <1>         shl	ah, 5
   208 00000C7B A0[E2A10000]        <1> 	mov	al, [KB_FLAG_1]		; GET SYSTEM SHIFT STATES BACK
   209 00000C80 2473                <1> 	and	al, 01110011b		; ELIMINATE SYS SHIFT, HOLD_STATE AND INS_SHIFT
   210 00000C82 08C4                <1> 	or	ah, al                  ; MERGE REMAINING BITS INTO AH
   211 00000C84 A0[E4A10000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT CTL AND ALT
   212 00000C89 240C                <1> 	and	al, 00001100b		; ELIMINATE LC_E0 AND LC_E1
   213 00000C8B 08C4                <1> 	or	ah, al			; OR THE SHIFT FLAGS TOGETHER
   214                              <1> _K3:
   215 00000C8D A0[E1A10000]        <1> 	mov	al, [KB_FLAG]		; GET THE SHIFT STATUS FLAGS
   216 00000C92 EB92                <1> 	jmp	short _KIO_EXIT		; RETURN TO CALLER
   217                              <1> 
   218                              <1> 	;-----	SET TYPAMATIC RATE AND DELAY
   219                              <1> _K300:
   220 00000C94 3C05                <1> 	cmp	al, 5			; CORRECT FUNCTION CALL?
   221 00000C96 758E                <1> 	jne	short _KIO_EXIT		; NO, RETURN
   222 00000C98 F6C3E0              <1>      	test	bl, 0E0h		; TEST FOR OUT-OF-RANGE RATE
   223 00000C9B 7589                <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
   224 00000C9D F6C7FC              <1> 	test	BH, 0FCh		; TEST FOR OUT-OF-RANGE DELAY
   225 00000CA0 7584                <1> 	jnz	short _KIO_EXIT		; RETURN IF SO
   226 00000CA2 B0F3                <1> 	mov	al, KB_TYPA_RD		; COMMAND FOR TYPAMATIC RATE/DELAY		
   227 00000CA4 E8DA060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
   228                              <1> 	;mov	cx, 5			; SHIFT COUNT
   229                              <1> 	;shl	bh, cl			; SHIFT DELAY OVER
   230 00000CA9 C0E705              <1> 	shl	bh, 5
   231 00000CAC 88D8                <1> 	mov	al, bl			; PUT IN RATE
   232 00000CAE 08F8                <1> 	or	al, bh			; AND DELAY
   233 00000CB0 E8CE060000          <1> 	call	SND_DATA		; SEND TO KEYBOARD	
   234 00000CB5 E96CFFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER
   235                              <1> 
   236                              <1> 	;-----	WRITE TO KEYBOARD BUFFER
   237                              <1> _K500:
   238 00000CBA 56                  <1> 	push	esi			; SAVE SI (esi)
   239 00000CBB FA                  <1> 	cli				; 
   240 00000CBC 8B1D[F2A10000]      <1>      	mov	ebx, [BUFFER_TAIL]	; GET THE 'IN TO' POINTER TO THE BUFFER
   241 00000CC2 89DE                <1> 	mov	esi, ebx		; SAVE A COPY IN CASE BUFFER NOT FULL
   242 00000CC4 E8D3000000          <1> 	call	_K4			; BUMP THE POINTER TO SEE IF BUFFER IS FULL
   243 00000CC9 3B1D[EEA10000]      <1> 	cmp	ebx, [BUFFER_HEAD]	; WILL THE BUFFER OVERRUN IF WE STORE THIS?
   244 00000CCF 740D                <1> 	je	short _K502		; YES - INFORM CALLER OF ERROR		
   245 00000CD1 66890E              <1> 	mov	[esi], cx		; NO - PUT ASCII/SCAN CODE INTO BUFFER	
   246 00000CD4 891D[F2A10000]      <1> 	mov	[BUFFER_TAIL], ebx	; ADJUST 'IN TO' POINTER TO REFLECT CHANGE
   247 00000CDA 28C0                <1> 	sub	al, al			; TELL CALLER THAT OPERATION WAS SUCCESSFUL
   248 00000CDC EB02                <1> 	jmp	short _K504		; SUB INSTRUCTION ALSO RESETS CARRY FLAG
   249                              <1> _K502:
   250 00000CDE B001                <1> 	mov	al, 01h			; BUFFER FULL INDICATION
   251                              <1> _K504:
   252 00000CE0 FB                  <1> 	sti				
   253 00000CE1 5E                  <1> 	pop	esi			; RECOVER SI (esi)
   254 00000CE2 E93FFFFFFF          <1>         jmp     _KIO_EXIT               ; RETURN TO CALLER WITH STATUS IN AL
   255                              <1> 
   256                              <1> 	;-----	READ THE KEY TO FIGURE OUT WHAT TO DO -----
   257                              <1> _K1S:
   258 00000CE7 FA                  <1> 	cli	; 03/12/2014
   259 00000CE8 8B1D[EEA10000]      <1>         mov     ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
   260 00000CEE 3B1D[F2A10000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
   261                              <1> 	;jne	short _K1U		; IF ANYTHING IN BUFFER SKIP INTERRUPT
   262 00000CF4 750F                <1> 	jne	short _k1x ; 03/12/2014
   263                              <1> 	;
   264                              <1> 	; 03/12/2014
   265                              <1> 	; 28/08/2014
   266                              <1> 	; PERFORM OTHER FUNCTION ?? here !
   267                              <1> 	;; MOV	AX, 9002h		; MOVE IN WAIT CODE & TYPE
   268                              <1> 	;; INT 	15H			; PERFORM OTHER FUNCTION
   269                              <1> _K1T:                                   ; ASCII READ
   270 00000CF6 FB                  <1> 	sti				; INTERRUPTS BACK ON DURING LOOP
   271 00000CF7 90                  <1> 	nop				; ALLOW AN INTERRUPT TO OCCUR
   272                              <1> _K1U:	
   273 00000CF8 FA                  <1> 	cli				; INTERRUPTS BACK OFF
   274 00000CF9 8B1D[EEA10000]      <1>         mov    	ebx, [BUFFER_HEAD] 	; GET POINTER TO HEAD OF BUFFER
   275 00000CFF 3B1D[F2A10000]      <1>         cmp     ebx, [BUFFER_TAIL] 	; TEST END OF BUFFER
   276                              <1> _k1x:
   277 00000D05 53                  <1> 	push	ebx			; SAVE ADDRESS		
   278 00000D06 9C                  <1> 	pushf				; SAVE FLAGS
   279 00000D07 E82F070000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
   280 00000D0C 8A1D[E3A10000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
   281 00000D12 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
   282 00000D14 80E307              <1> 	and	bl, 07h	; KB_LEDS	; ISOLATE INDICATOR BITS
   283 00000D17 7406                <1> 	jz	short _K1V		; IF NO CHANGE BYPASS UPDATE
   284 00000D19 E8C9060000          <1> 	call	SND_LED1
   285 00000D1E FA                  <1> 	cli				; DISABLE INTERRUPTS
   286                              <1> _K1V:
   287 00000D1F 9D                  <1> 	popf				; RESTORE FLAGS
   288 00000D20 5B                  <1> 	pop	ebx			; RESTORE ADDRESS
   289 00000D21 74D3                <1>         je      short _K1T              ; LOOP UNTIL SOMETHING IN BUFFER
   290                              <1> 	;
   291 00000D23 668B03              <1> 	mov	ax, [ebx] 		; GET SCAN CODE AND ASCII CODE
   292 00000D26 E871000000          <1>         call    _K4                     ; MOVE POINTER TO NEXT POSITION
   293 00000D2B 891D[EEA10000]      <1>         mov     [BUFFER_HEAD], ebx      ; STORE VALUE IN VARIABLE
   294 00000D31 C3                  <1> 	retn				; RETURN
   295                              <1> 
   296                              <1> 	;-----	READ THE KEY TO SEE IF ONE IS PRESENT -----
   297                              <1> _K2S:
   298 00000D32 FA                  <1> 	cli				; INTERRUPTS OFF
   299 00000D33 8B1D[EEA10000]      <1>         mov     ebx, [BUFFER_HEAD]      ; GET HEAD POINTER
   300 00000D39 3B1D[F2A10000]      <1>         cmp     ebx, [BUFFER_TAIL]      ; IF EQUAL (Z=1) THEN NOTHING THERE
   301 00000D3F 668B03              <1> 	mov	ax, [ebx]
   302 00000D42 9C                  <1> 	pushf				; SAVE FLAGS
   303 00000D43 6650                <1> 	push	ax			; SAVE CODE
   304 00000D45 E8F1060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
   305 00000D4A 8A1D[E3A10000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
   306 00000D50 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
   307 00000D52 80E307              <1> 	and	bl, 07h ; KB_LEDS	; ISOLATE INDICATOR BITS
   308 00000D55 7405                <1> 	jz	short _K2T		; IF NO CHANGE BYPASS UPDATE
   309 00000D57 E874060000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
   310                              <1> _K2T:
   311 00000D5C 6658                <1> 	pop	ax			; RESTORE CODE
   312 00000D5E 9D                  <1> 	popf				; RESTORE FLAGS
   313 00000D5F FB                  <1> 	sti				; INTERRUPTS BACK ON
   314 00000D60 C3                  <1> 	retn				; RETURN
   315                              <1> 
   316                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR EXTENDED CALLS -----
   317                              <1> _KIO_E_XLAT:
   318 00000D61 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
   319 00000D63 7506                <1> 	jne	short _KIO_E_RET	; NO, PASS IT ON
   320 00000D65 08E4                <1>         or 	ah, ah			; AH = 0 IS SPECIAL CASE
   321 00000D67 7402                <1>         jz	short _KIO_E_RET        ; PASS THIS ON UNCHANGED
   322 00000D69 30C0                <1> 	xor	al, al			; OTHERWISE SET AL = 0
   323                              <1> _KIO_E_RET:				
   324 00000D6B C3                  <1> 	retn				; GO BACK
   325                              <1> 
   326                              <1> 	;-----	ROUTINE TO TRANSLATE SCAN CODE PAIRS FOR STANDARD CALLS -----
   327                              <1> _KIO_S_XLAT:
   328 00000D6C 80FCE0              <1> 	cmp	ah, 0E0h		; IS IT KEYPAD ENTER OR / ?
   329 00000D6F 750F                <1> 	jne	short _KIO_S2		; NO, CONTINUE
   330 00000D71 3C0D                <1> 	cmp	al, 0Dh			; KEYPAD ENTER CODE?
   331 00000D73 7408                <1>         je	short _KIO_S1		; YES, MASSAGE A BIT
   332 00000D75 3C0A                <1> 	cmp	al, 0Ah			; CTRL KEYPAD ENTER CODE?
   333 00000D77 7404                <1>         je	short _KIO_S1		; YES, MASSAGE THE SAME
   334 00000D79 B435                <1> 	mov	ah, 35h			; NO, MUST BE KEYPAD /
   335                              <1> _kio_ret: ; 03/12/2014
   336 00000D7B F8                  <1> 	clc
   337 00000D7C C3                  <1> 	retn
   338                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
   339                              <1> _KIO_S1:				
   340 00000D7D B41C                <1> 	mov	ah, 1Ch			; CONVERT TO COMPATIBLE OUTPUT
   341                              <1> 	;jmp	short _KIO_USE		; GIVE TO CALLER
   342 00000D7F C3                  <1> 	retn
   343                              <1> _KIO_S2:		
   344 00000D80 80FC84              <1> 	cmp	ah, 84h			; IS IT ONE OF EXTENDED ONES?
   345 00000D83 7715                <1> 	ja	short _KIO_DIS		; YES, THROW AWAY AND GET ANOTHER CHAR
   346 00000D85 3CF0                <1> 	cmp	al, 0F0h		; IS IT ONE OF THE FILL-INs?
   347 00000D87 7506                <1>         jne	short _KIO_S3		; NO, TRY LAST TEST
   348 00000D89 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
   349 00000D8B 740C                <1>         jz	short _KIO_USE		; PASS THIS ON UNCHANGED
   350 00000D8D EB0B                <1> 	jmp	short _KIO_DIS		; THROW AWAY THE REST
   351                              <1> _KIO_S3:
   352 00000D8F 3CE0                <1> 	cmp	al, 0E0h		; IS IT AN EXTENSION OF A PREVIOUS ONE?
   353                              <1> 	;jne	short _KIO_USE		; NO, MUST BE A STANDARD CODE
   354 00000D91 75E8                <1> 	jne	short _kio_ret
   355 00000D93 08E4                <1> 	or	ah, ah			; AH = 0 IS SPECIAL CASE
   356 00000D95 7402                <1>         jz	short _KIO_USE		; JUMP IF AH = 0
   357 00000D97 30C0                <1> 	xor	al, al			; CONVERT TO COMPATIBLE OUTPUT
   358                              <1> 	;jmp	short _KIO_USE		; PASS IT ON TO CALLER
   359                              <1> _KIO_USE:
   360                              <1> 	;clc				; CLEAR CARRY TO INDICATE GOOD CODE
   361 00000D99 C3                  <1> 	retn				; RETURN	
   362                              <1> _KIO_DIS:
   363 00000D9A F9                  <1> 	stc				; SET CARRY TO INDICATE DISCARD CODE
   364 00000D9B C3                  <1> 	retn				; RETURN
   365                              <1> 
   366                              <1> 	;-----	INCREMENT BUFFER POINTER ROUTINE -----
   367                              <1> _K4:    
   368 00000D9C 43                  <1> 	inc     ebx
   369 00000D9D 43                  <1> 	inc	ebx			; MOVE TO NEXT WORD IN LIST
   370 00000D9E 3B1D[EAA10000]      <1>         cmp     ebx, [BUFFER_END] 	; AT END OF BUFFER?
   371                              <1>         ;jne    short _K5               ; NO, CONTINUE
   372 00000DA4 7206                <1> 	jb	short _K5
   373 00000DA6 8B1D[E6A10000]      <1>         mov     ebx, [BUFFER_START]     ; YES, RESET TO BUFFER BEGINNING
   374                              <1> _K5:
   375 00000DAC C3                  <1> 	retn
   376                              <1> 
   377                              <1> ; 20/02/2015
   378                              <1> ; 05/12/2014
   379                              <1> ; 26/08/2014
   380                              <1> ; KEYBOARD (HARDWARE) INTERRUPT -  IRQ LEVEL 1
   381                              <1> ; (INT_09h - Retro UNIX 8086 v1 - U9.ASM, 07/03/2014)
   382                              <1> ;
   383                              <1> ; Derived from "KB_INT_1" procedure of IBM "pc-at" 
   384                              <1> ; rombios source code (06/10/1985)
   385                              <1> ; 'keybd.asm', HARDWARE INT 09h - (IRQ Level 1)
   386                              <1> 
   387                              <1> ; EQUATES (IBM PC-XT-286 BIOS, 1986, 'POSQEQU.INC')
   388                              <1> 
   389                              <1> ;--------- 8042 COMMANDS -------------------------------------------------------
   390                              <1> ENA_KBD		equ	0AEh		; ENABLE KEYBOARD COMMAND
   391                              <1> DIS_KBD		equ	0ADh		; DISABLE KEYBOARD COMMAND
   392                              <1> SHUT_CMD	equ	0FEh		; CAUSE A SHUTDOWN COMMAND
   393                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
   394                              <1> STATUS_PORT	equ	064h		; 8042 STATUS PORT
   395                              <1> INPT_BUF_FULL	equ	00000010b 	; 1 = +INPUT BUFFER FULL
   396                              <1> PORT_A		equ	060h		; 8042 KEYBOARD SCAN CODE/CONTROL PORT
   397                              <1> ;---------- 8042 KEYBOARD RESPONSE ---------------------------------------------
   398                              <1> KB_ACK		equ	0FAh		; ACKNOWLEDGE PROM TRANSMISSION
   399                              <1> KB_RESEND	equ	0FEh		; RESEND REQUEST
   400                              <1> KB_OVER_RUN	equ	0FFh		; OVER RUN SCAN CODE
   401                              <1> ;---------- KEYBOARD/LED COMMANDS ----------------------------------------------
   402                              <1> KB_ENABLE	equ	0F4h		; KEYBOARD ENABLE
   403                              <1> LED_CMD		equ	0EDh		; LED WRITE COMMAND
   404                              <1> KB_TYPA_RD	equ	0F3h		; TYPAMATIC RATE/DELAY COMMAND
   405                              <1> ;---------- KEYBOARD SCAN CODES ------------------------------------------------
   406                              <1> NUM_KEY		equ	69		; SCAN CODE FOR	 NUMBER LOCK KEY
   407                              <1> SCROLL_KEY	equ	70		; SCAN CODE FOR	 SCROLL LOCK KEY
   408                              <1> ALT_KEY		equ	56		; SCAN CODE FOR	 ALTERNATE SHIFT KEY
   409                              <1> CTL_KEY		equ	29		; SCAN CODE FOR	 CONTROL KEY
   410                              <1> CAPS_KEY	equ	58		; SCAN CODE FOR	 SHIFT LOCK KEY
   411                              <1> DEL_KEY		equ	83		; SCAN CODE FOR	 DELETE KEY
   412                              <1> INS_KEY		equ	82		; SCAN CODE FOR	 INSERT KEY
   413                              <1> LEFT_KEY	equ	42		; SCAN CODE FOR	 LEFT SHIFT
   414                              <1> RIGHT_KEY	equ	54		; SCAN CODE FOR	 RIGHT SHIFT
   415                              <1> SYS_KEY		equ	84		; SCAN CODE FOR	 SYSTEM KEY
   416                              <1> ;---------- ENHANCED KEYBOARD SCAN CODES ---------------------------------------
   417                              <1> ID_1		equ	0ABh		; 1ST ID CHARACTER FOR KBX
   418                              <1> ID_2		equ	041h		; 2ND ID CHARACTER FOR KBX
   419                              <1> ID_2A		equ	054h		; ALTERNATE 2ND ID CHARACTER FOR KBX
   420                              <1> F11_M		equ	87		; F11 KEY MAKE
   421                              <1> F12_M		equ	88		; F12 KEY MAKE
   422                              <1> MC_E0		equ	224		; GENERAL MARKER CODE
   423                              <1> MC_E1		equ	225		; PAUSE KEY MARKER CODE
   424                              <1> ;---------- FLAG EQUATES WITHIN @KB_FLAG----------------------------------------
   425                              <1> RIGHT_SHIFT	equ	00000001b	; RIGHT SHIFT KEY DEPRESSED
   426                              <1> LEFT_SHIFT	equ	00000010b	; LEFT SHIFT KEY DEPRESSED
   427                              <1> CTL_SHIFT	equ	00000100b	; CONTROL SHIFT KEY DEPRESSED
   428                              <1> ALT_SHIFT	equ	00001000b	; ALTERNATE SHIFT KEY DEPRESSED
   429                              <1> SCROLL_STATE	equ	00010000b	; SCROLL LOCK STATE IS ACTIVE
   430                              <1> NUM_STATE	equ	00100000b	; NUM LOCK STATE IS ACTIVE
   431                              <1> CAPS_STATE	equ	01000000b	; CAPS LOCK STATE IS ACTIVE
   432                              <1> INS_STATE	equ	10000000b	; INSERT STATE IS ACTIVE
   433                              <1> ;---------- FLAG EQUATES WITHIN	@KB_FLAG_1 -------------------------------------
   434                              <1> L_CTL_SHIFT	equ	00000001b	; LEFT CTL KEY DOWN
   435                              <1> L_ALT_SHIFT	equ	00000010b	; LEFT ALT KEY DOWN
   436                              <1> SYS_SHIFT	equ	00000100b	; SYSTEM KEY DEPRESSED AND HELD
   437                              <1> HOLD_STATE	equ	00001000b	; SUSPEND KEY HAS BEEN TOGGLED
   438                              <1> SCROLL_SHIFT	equ	00010000b	; SCROLL LOCK KEY IS DEPRESSED
   439                              <1> NUM_SHIFT	equ	00100000b	; NUM LOCK KEY IS DEPRESSED
   440                              <1> CAPS_SHIFT	equ	01000000b	; CAPS LOCK KEY IS DEPRE55ED
   441                              <1> INS_SHIFT	equ	10000000b	; INSERT KEY IS DEPRESSED
   442                              <1> ;---------- FLAGS EQUATES WITHIN @KB_FLAG_2 -----------------------------------
   443                              <1> KB_LEDS		equ	00000111b	; KEYBOARD LED STATE BITS
   444                              <1> ;		equ	00000001b	; SCROLL LOCK INDICATOR
   445                              <1> ;		equ	00000010b	; NUM LOCK INDICATOR
   446                              <1> ;		equ	00000100b	; CAPS LOCK INDICATOR
   447                              <1> ;		equ	00001000b	; RESERVED (MUST BE ZERO)
   448                              <1> KB_FA		equ	00010000b	; ACKNOWLEDGMENT RECEIVED
   449                              <1> KB_FE		equ	00100000b	; RESEND RECEIVED FLAG
   450                              <1> KB_PR_LED	equ	01000000b	; MODE INDICATOR UPDATE
   451                              <1> KB_ERR		equ	10000000b	; KEYBOARD TRANSMIT ERROR FLAG
   452                              <1> ;----------- FLAGS EQUATES WITHIN @KB_FLAG_3 -----------------------------------
   453                              <1> LC_E1		equ	00000001b	; LAST CODE WAS THE E1 HIDDEN CODE
   454                              <1> LC_E0		equ	00000010b	; LAST CODE WAS THE E0 HIDDEN CODE
   455                              <1> R_CTL_SHIFT	equ	00000100b	; RIGHT CTL KEY DOWN
   456                              <1> R_ALT_SHIFT	equ	00001000b	; RIGHT ALT KEY DOWN
   457                              <1> GRAPH_ON	equ	00001000b	; ALT GRAPHICS KEY DOWN (WT ONLY)	
   458                              <1> KBX		equ	00010000b	; ENHANCED KEYBOARD INSTALLED
   459                              <1> SET_NUM_LK	equ	00100000b	; FORCE NUM LOCK IF READ ID AND KBX
   460                              <1> LC_AB		equ	01000000b	; LAST CHARACTER WAS FIRST ID CHARACTER
   461                              <1> RD_ID		equ	10000000b	; DOING A READ ID (MUST BE BIT0)
   462                              <1> ;
   463                              <1> ;----------- INTERRUPT EQUATES -------------------------------------------------
   464                              <1> EOI		equ	020h		; END OF INTERRUPT COMMAND TO 8259
   465                              <1> INTA00		equ	020h		; 8259 PORT
   466                              <1> 
   467                              <1> 
   468                              <1> kb_int:
   469                              <1> 
   470                              <1> ; 17/10/2015 ('ctrlbrk') 
   471                              <1> ; 05/12/2014
   472                              <1> ; 04/12/2014 (derived from pc-xt-286 bios source code -1986-)
   473                              <1> ; 26/08/2014
   474                              <1> ;
   475                              <1> ; 03/06/86  KEYBOARD BIOS
   476                              <1> ;
   477                              <1> ;--- HARDWARE INT 09H -- (IRQ LEVEL 1) ------------------------------------------
   478                              <1> ;										;
   479                              <1> ;	KEYBOARD INTERRUPT ROUTINE						;
   480                              <1> ;										;
   481                              <1> ;--------------------------------------------------------------------------------
   482                              <1> 
   483                              <1> KB_INT_1:
   484 00000DAD FB                  <1> 	sti				; ENABLE INTERRUPTS
   485                              <1> 	;push	ebp
   486 00000DAE 50                  <1> 	push	eax
   487 00000DAF 53                  <1> 	push	ebx
   488 00000DB0 51                  <1> 	push	ecx
   489 00000DB1 52                  <1> 	push	edx
   490 00000DB2 56                  <1> 	push	esi
   491 00000DB3 57                  <1> 	push	edi
   492 00000DB4 1E                  <1> 	push	ds
   493 00000DB5 06                  <1> 	push	es
   494 00000DB6 FC                  <1> 	cld				; FORWARD DIRECTION
   495 00000DB7 66B81000            <1> 	mov	ax, KDATA
   496 00000DBB 8ED8                <1> 	mov	ds, ax
   497 00000DBD 8EC0                <1> 	mov	es, ax
   498                              <1> 	;
   499                              <1> 	;-----	WAIT FOR KEYBOARD DISABLE COMMAND TO BE ACCEPTED
   500 00000DBF B0AD                <1> 	mov	al, DIS_KBD		; DISABLE THE KEYBOARD COMMAND
   501 00000DC1 E8A9050000          <1> 	call	SHIP_IT			; EXECUTE DISABLE
   502 00000DC6 FA                  <1> 	cli				; DISABLE INTERRUPTS
   503 00000DC7 B900000100          <1> 	mov	ecx, 10000h		; SET MAXIMUM TIMEOUT
   504                              <1> KB_INT_01:
   505 00000DCC E464                <1> 	in	al, STATUS_PORT		; READ ADAPTER STATUS
   506 00000DCE A802                <1> 	test	al, INPT_BUF_FULL	; CHECK INPUT BUFFER FULL STATUS BIT
   507 00000DD0 E0FA                <1> 	loopnz	KB_INT_01		; WAIT FOR COMMAND TO BE ACCEPTED
   508                              <1> 	;
   509                              <1> 	;-----	READ CHARACTER FROM KEYBOARD INTERFACE
   510 00000DD2 E460                <1> 	in	al, PORT_A		; READ IN THE CHARACTER
   511                              <1> 	;
   512                              <1> 	;-----	SYSTEM HOOK INT 15H - FUNCTION 4FH (ON HARDWARE INT LEVEL 9H) 	
   513                              <1> 	;MOV	AH, 04FH		; SYSTEM INTERCEPT - KEY CODE FUNCTION
   514                              <1> 	;STC				; SET CY=1 (IN CASE OF IRET)
   515                              <1> 	;INT	15H			; CASETTE CALL (AL)=KEY SCAN CODE
   516                              <1> 	;				; RETURNS CY=1 FOR INVALID FUNCTION
   517                              <1> 	;JC	KB_INT_02		; CONTINUE IF CARRY FLAG SET ((AL)=CODE)
   518                              <1> 	;JMP	K26			; EXIT IF SYSTEM HANDLES SCAN CODE
   519                              <1> 	;				; EXT HANDLES HARDWARE EOI AND ENABLE		
   520                              <1> 	;
   521                              <1> 	;-----	CHECK FOR A RESEND COMMAND TO KEYBOARD
   522                              <1> KB_INT_02:				; 	  (AL)= SCAN CODE
   523 00000DD4 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
   524 00000DD5 3CFE                <1> 	cmp	al, KB_RESEND		; IS THE INPUT A RESEND
   525 00000DD7 7411                <1>         je      short KB_INT_4          ; GO IF RESEND
   526                              <1> 	;
   527                              <1> 	;-----	CHECK FOR RESPONSE TO A COMMAND TO KEYBOARD
   528 00000DD9 3CFA                <1> 	cmp	al, KB_ACK		; IS THE INPUT AN ACKNOWLEDGE
   529 00000DDB 751A                <1>         jne     short KB_INT_2          ; GO IF NOT
   530                              <1> 	;
   531                              <1> 	;-----	A COMMAND TO THE KEYBOARD WAS ISSUED
   532 00000DDD FA                  <1> 	cli				; DISABLE INTERRUPTS
   533 00000DDE 800D[E3A10000]10    <1> 	or	byte [KB_FLAG_2], KB_FA ; INDICATE ACK RECEIVED
   534 00000DE5 E97A020000          <1>         jmp     K26                     ; RETURN IF NOT (ACK RETURNED FOR DATA)
   535                              <1> 	;
   536                              <1> 	;-----	RESEND THE LAST BYTE
   537                              <1> KB_INT_4:
   538 00000DEA FA                  <1> 	cli				; DISABLE INTERRUPTS
   539 00000DEB 800D[E3A10000]20    <1> 	or	byte [KB_FLAG_2], KB_FE ; INDICATE RESEND RECEIVED
   540 00000DF2 E96D020000          <1>         jmp     K26                     ; RETURN IF NOT ACK RETURNED FOR DATA)
   541                              <1> 	;
   542                              <1> ;-----	UPDATE MODE INDICATORS IF CHANGE IN STATE
   543                              <1> KB_INT_2:
   544 00000DF7 6650                <1> 	push 	ax			; SAVE DATA IN
   545 00000DF9 E83D060000          <1> 	call	MAKE_LED		; GO GET MODE INDICATOR DATA BYTE
   546 00000DFE 8A1D[E3A10000]      <1> 	mov	bl, [KB_FLAG_2] 	; GET PREVIOUS BITS
   547 00000E04 30C3                <1> 	xor	bl, al			; SEE IF ANY DIFFERENT
   548 00000E06 80E307              <1> 	and	bl, KB_LEDS		; ISOLATE INDICATOR BITS
   549 00000E09 7405                <1> 	jz	short UP0		; IF NO CHANGE BYPASS UPDATE
   550 00000E0B E8C0050000          <1> 	call	SND_LED			; GO TURN ON MODE INDICATORS
   551                              <1> UP0:
   552 00000E10 6658                <1> 	pop	ax			; RESTORE DATA IN
   553                              <1> ;------------------------------------------------------------------------
   554                              <1> ;	START OF KEY PROCESSING						;
   555                              <1> ;------------------------------------------------------------------------
   556 00000E12 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE IN AH ALSO
   557                              <1> 	;
   558                              <1> 	;-----	TEST FOR OVERRUN SCAN CODE FROM KEYBOARD
   559 00000E14 3CFF                <1> 	cmp	al, KB_OVER_RUN		; IS THIS AN OVERRUN CHAR
   560 00000E16 0F843F050000        <1>         je      K62			; BUFFER_FULL_BEEP
   561                              <1> 	;
   562                              <1> K16:	
   563 00000E1C 8A3D[E4A10000]      <1> 	mov	bh, [KB_FLAG_3]		; LOAD FLAGS FOR TESTING
   564                              <1> 	;
   565                              <1> 	;-----	TEST TO SEE IF A READ_ID IS IN PROGRESS
   566 00000E22 F6C7C0              <1> 	test 	bh, RD_ID+LC_AB 	; ARE WE DOING A READ ID?
   567 00000E25 7449                <1> 	jz	short NOT_ID		; CONTINUE IF NOT
   568 00000E27 7917                <1> 	jns	short TST_ID_2		; IS THE RD_ID FLAG ON?
   569 00000E29 3CAB                <1> 	cmp	al, ID_1		; IS THIS THE 1ST ID CHARACTER?
   570 00000E2B 7507                <1> 	jne	short RST_RD_ID
   571 00000E2D 800D[E4A10000]40    <1> 	or	byte [KB_FLAG_3], LC_AB ; INDICATE 1ST ID WAS OK
   572                              <1> RST_RD_ID:
   573 00000E34 8025[E4A10000]7F    <1> 	and	byte [KB_FLAG_3], ~RD_ID ; RESET THE READ ID FLAG
   574                              <1>         ;jmp    short ID_EX		; AND EXIT
   575 00000E3B E924020000          <1> 	jmp	K26
   576                              <1> 	;
   577                              <1> TST_ID_2:
   578 00000E40 8025[E4A10000]BF    <1> 	and	byte [KB_FLAG_3], ~LC_AB ; RESET FLAG
   579 00000E47 3C54                <1> 	cmp	al, ID_2A		; IS THIS THE 2ND ID CHARACTER?
   580 00000E49 7419                <1>         je	short KX_BIT		; JUMP IF SO
   581 00000E4B 3C41                <1> 	cmp	al, ID_2		; IS THIS THE 2ND ID CHARACTER?
   582                              <1>         ;jne	short ID_EX		; LEAVE IF NOT
   583 00000E4D 0F8511020000        <1> 	jne	K26
   584                              <1> 	;
   585                              <1> 	;-----	A READ ID SAID THAT IT WAS ENHANCED KEYBOARD
   586 00000E53 F6C720              <1> 	test	bh, SET_NUM_LK 		; SHOULD WE SET NUM LOCK?
   587 00000E56 740C                <1>         jz      short KX_BIT		; EXIT IF NOT
   588 00000E58 800D[E1A10000]20    <1> 	or	byte [KB_FLAG], NUM_STATE ; FORCE NUM LOCK ON
   589 00000E5F E86C050000          <1> 	call	SND_LED			; GO SET THE NUM LOCK INDICATOR
   590                              <1> KX_BIT:
   591 00000E64 800D[E4A10000]10    <1> 	or	byte [KB_FLAG_3], KBX	; INDICATE ENHANCED KEYBOARD WAS FOUND
   592 00000E6B E9F4010000          <1> ID_EX:	jmp     K26			; EXIT
   593                              <1> 	;
   594                              <1> NOT_ID:
   595 00000E70 3CE0                <1> 	cmp	al, MC_E0		; IS THIS THE GENERAL MARKER CODE?
   596 00000E72 750C                <1> 	jne	short TEST_E1
   597 00000E74 800D[E4A10000]12    <1> 	or	byte [KB_FLAG_3], LC_E0+KBX ; SET FLAG BIT, SET KBX, AND
   598                              <1> 	;jmp	short EXIT		; THROW AWAY THIS CODE
   599 00000E7B E9EB010000          <1> 	jmp	K26A	
   600                              <1> TEST_E1:	
   601 00000E80 3CE1                <1> 	cmp	al, MC_E1		; IS THIS THE PAUSE KEY?
   602 00000E82 750C                <1> 	jne	short NOT_HC
   603 00000E84 800D[E4A10000]11    <1> 	or	byte [KB_FLAG_3], LC_E1+KBX ; SET FLAG BIT, SET KBX, AND
   604 00000E8B E9DB010000          <1> EXIT:	jmp	K26A			; THROW AWAY THIS CODE
   605                              <1> 	;
   606                              <1> NOT_HC:
   607 00000E90 247F                <1> 	and	al, 07Fh		; TURN OFF THE BREAK BIT
   608 00000E92 F6C702              <1> 	test	bh, LC_E0		; LAST CODE THE E0 MARKER CODE
   609 00000E95 7414                <1> 	jz	short NOT_LC_E0		; JUMP IF NOT
   610                              <1> 	;
   611 00000E97 BF[CEA00000]        <1> 	mov	edi, _K6+6		; IS THIS A SHIFT KEY?
   612 00000E9C AE                  <1> 	scasb
   613 00000E9D 0F84C1010000        <1>         je      K26 ; K16B              ; YES, THROW AWAY & RESET FLAG
   614 00000EA3 AE                  <1> 	scasb
   615 00000EA4 757C                <1> 	jne	short K16A		; NO, CONTINUE KEY PROCESSING
   616                              <1> 	;jmp	short K16B		; YES, THROW AWAY & RESET FLAG
   617 00000EA6 E9B9010000          <1> 	jmp	K26
   618                              <1> 	;
   619                              <1> NOT_LC_E0:
   620 00000EAB F6C701              <1> 	test	bh, LC_E1		; LAST CODE THE E1 MARKER CODE?
   621 00000EAE 7435                <1> 	jz	short T_SYS_KEY		; JUMP IF NOT
   622 00000EB0 B904000000          <1> 	mov	ecx, 4			; LENGHT OF SEARCH
   623 00000EB5 BF[CCA00000]        <1> 	mov	edi, _K6+4		; IS THIS AN ALT, CTL, OR SHIFT?
   624 00000EBA F2AE                <1> 	repne	scasb			; CHECK IT
   625                              <1> 	;je	short EXIT		; THROW AWAY IF SO
   626 00000EBC 0F84A9010000        <1> 	je	K26A			
   627                              <1> 	;
   628 00000EC2 3C45                <1> 	cmp	al, NUM_KEY		; IS IT THE PAUSE KEY?
   629                              <1> 	;jne	short K16B		; NO, THROW AWAY & RESET FLAG
   630 00000EC4 0F859A010000        <1> 	jne	K26
   631 00000ECA F6C480              <1> 	test	ah, 80h			; YES, IS IT THE BREAK OF THE KEY?
   632                              <1> 	;jnz	short K16B		; YES, THROW THIS AWAY, TOO	
   633 00000ECD 0F8591010000        <1> 	jnz	K26
   634                              <1>         ; 20/02/2015 
   635 00000ED3 F605[E2A10000]08    <1> 	test	byte [KB_FLAG_1],HOLD_STATE ;  NO, ARE WE PAUSED ALREADY?
   636                              <1> 	;jnz	short K16B		;  YES, THROW AWAY
   637 00000EDA 0F8584010000        <1> 	jnz	K26
   638 00000EE0 E9E1020000          <1> 	jmp     K39P                    ; NO, THIS IS THE REAL PAUSE STATE
   639                              <1> 	;
   640                              <1> 	;-----	TEST FOR SYSTEM KEY
   641                              <1> T_SYS_KEY:
   642 00000EE5 3C54                <1> 	cmp	al, SYS_KEY		; IS IT THE SYSTEM KEY?
   643 00000EE7 7539                <1> 	jnz	short K16A		; CONTINUE IF NOT
   644                              <1> 	;
   645 00000EE9 F6C480              <1> 	test	ah, 80h			; CHECK IF THIS A BREAK CODE
   646 00000EEC 7524                <1> 	jnz	short K16C		; DO NOT TOUCH SYSTEM INDICATOR IF TRUE
   647                              <1> 	;
   648 00000EEE F605[E2A10000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; SEE IF IN SYSTEM KEY HELD DOWN 
   649                              <1>         ;jnz	short K16B		; IF YES, DO NOT PROCESS SYSTEM INDICATOR	
   650 00000EF5 0F8569010000        <1> 	jnz     K26			
   651                              <1> 	;
   652 00000EFB 800D[E2A10000]04    <1> 	or	byte [KB_FLAG_1], SYS_SHIFT ; INDICATE SYSTEM KEY DEPRESSED
   653 00000F02 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
   654 00000F04 E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
   655                              <1> 					; INTERRUPT-RETURN-NO-EOI
   656 00000F06 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
   657 00000F08 E862040000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
   658                              <1> 	; !!! SYSREQ !!! function/system call (INTERRUPT) must be here !!!
   659                              <1> 	;MOV	AL, 8500H		; FUNCTION VALUE FOR MAKE OF SYSTEM KEY
   660                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
   661                              <1> 	;INT	15H			; USER INTERRUPT	
   662 00000F0D E965010000          <1>         jmp     K27A                    ; END PROCESSING
   663                              <1> 	;
   664                              <1> ;K16B:	jmp	K26			; IGNORE SYSTEM KEY
   665                              <1> 	;
   666                              <1> K16C:
   667 00000F12 8025[E2A10000]FB    <1> 	and	byte [KB_FLAG_1], ~SYS_SHIFT ; TURN OFF SHIFT KEY HELD DOWN
   668 00000F19 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
   669 00000F1B E620                <1> 	out	20h, al ;out INTA00, al ; SEND COMMAND TO INTERRUPT CONTROL PORT
   670                              <1> 					; INTERRUPT-RETURN-NO-EOI
   671                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
   672                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
   673                              <1> 	;
   674                              <1> 	;MOV	AX, 8501H		; FUNCTION VALUE FOR BREAK OF SYSTEM KEY
   675                              <1> 	;STI				; MAKE SURE INTERRUPTS ENABLED
   676                              <1> 	;INT	15H			; USER INTERRUPT
   677                              <1> 	;JMP	K27A			; INGONRE SYSTEM KEY				
   678                              <1> 	;
   679 00000F1D E94E010000          <1> 	jmp     K27			; IGNORE SYSTEM KEY
   680                              <1> 	;
   681                              <1> 	;-----	TEST FOR SHIFT KEYS
   682                              <1> K16A:
   683 00000F22 8A1D[E1A10000]      <1> 	mov	bl, [KB_FLAG]		; PUT STATE FLAGS IN BL
   684 00000F28 BF[C8A00000]        <1> 	mov	edi, _K6		; SHIFT KEY TABLE offset
   685 00000F2D B908000000          <1> 	mov	ecx, _K6L		; LENGTH
   686 00000F32 F2AE                <1> 	repne	scasb			; LOOK THROUGH THE TABLE FOR A MATCH
   687 00000F34 88E0                <1> 	mov	al, ah			; RECOVER SCAN CODE
   688 00000F36 0F8510010000        <1>         jne     K25                     ; IF NO MATCH, THEN SHIFT NOT FOUND
   689                              <1> 	;
   690                              <1> 	;------	SHIFT KEY FOUND
   691                              <1> K17:
   692 00000F3C 81EF[C9A00000]      <1>         sub     edi, _K6+1              ; ADJUST PTR TO SCAN CODE MATCH
   693 00000F42 8AA7[D0A00000]      <1>        	mov     ah, [edi+_K7]       	; GET MASK INTO AH
   694 00000F48 B102                <1> 	mov	cl, 2			; SETUP COUNT FOR FLAG SHIFTS
   695 00000F4A A880                <1> 	test	al, 80h			; TEST FOR BREAK KEY
   696 00000F4C 0F8596000000        <1>         jnz     K23                     ; JUMP OF BREAK
   697                              <1> 	;
   698                              <1> 	;-----	SHIFT MAKE FOUND, DETERMINE SET OR TOGGLE
   699                              <1> K17C:
   700 00000F52 80FC10              <1> 	cmp	ah, SCROLL_SHIFT
   701 00000F55 732B                <1> 	jae	short K18		; IF SCROLL SHIFT OR ABOVE, TOGGLE KEY
   702                              <1> 	;
   703                              <1> 	;-----	PLAIN SHIFT KEY, SET SHIFT ON
   704 00000F57 0825[E1A10000]      <1> 	or	[KB_FLAG], ah		; TURN ON SHIFT BIT
   705 00000F5D A80C                <1>         test	al, CTL_SHIFT+ALT_SHIFT ; IS IT ALT OR CTRL?
   706                              <1> 	;jnz	short K17D		; YES, MORE FLAGS TO SET
   707 00000F5F 0F84FF000000        <1> 	jz	K26			; NO, INTERRUPT RETURN
   708                              <1> K17D:
   709 00000F65 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF NEW KEYS?
   710 00000F68 740B                <1> 	jz 	short K17E		; NO, JUMP
   711 00000F6A 0825[E4A10000]      <1> 	or	[KB_FLAG_3], ah		; SET BITS FOR RIGHT CTRL, ALT
   712 00000F70 E9EF000000          <1> 	jmp	K26			; INTERRUPT RETURN
   713                              <1> K17E:
   714 00000F75 D2EC                <1> 	shr	ah, cl			; MOVE FLAG BITS TWO POSITIONS
   715 00000F77 0825[E2A10000]      <1> 	or	[KB_FLAG_1], ah		; SET BITS FOR LEFT CTRL, ALT
   716 00000F7D E9E2000000          <1> 	jmp	K26
   717                              <1> 	;
   718                              <1> 	;-----	TOGGLED SHIFT KEY, TEST FOR 1ST MAKE OR NOT
   719                              <1> K18:					; SHIFT-TOGGLE
   720 00000F82 F6C304              <1> 	test	bl, CTL_SHIFT 		; CHECK CTL SHIFT STATE
   721                              <1>         ;jz    	short K18A              ; JUMP IF NOT CTL STATE
   722 00000F85 0F85C1000000        <1>         jnz     K25                     ; JUMP IF CTL STATE
   723                              <1> K18A:
   724 00000F8B 3C52                <1> 	cmp	al, INS_KEY		; CHECK FOR INSERT KEY
   725 00000F8D 7524                <1> 	jne	short K22		; JUMP IF NOT INSERT KEY
   726 00000F8F F6C308              <1> 	test	bl, ALT_SHIFT 		; CHECK FOR ALTERNATE SHIFT
   727                              <1>       	;jz	short K18B		; JUMP IF NOT ALTERNATE SHIFT	
   728 00000F92 0F85B4000000        <1>         jnz     K25                     ; JUMP IF ALTERNATE SHIFT
   729                              <1> K18B:
   730 00000F98 F6C702              <1> 	test	bh, LC_E0 ;20/02/2015	; IS THIS NEW INSERT KEY?
   731 00000F9B 7516                <1> 	jnz	short K22		; YES, THIS ONE'S NEVER A '0'
   732                              <1> K19:	
   733 00000F9D F6C320              <1> 	test	bl, NUM_STATE 		; CHECK FOR BASE STATE
   734 00000FA0 750C                <1> 	jnz	short K21		; JUMP IF NUM LOCK IS ON
   735 00000FA2 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST FOR SHIFT STATE
   736 00000FA5 740C                <1> 	jz	short K22		; JUMP IF BASE STATE
   737                              <1> K20:					; NUMERIC ZERO, NOT INSERT KEY
   738 00000FA7 88C4                <1> 	mov	ah, al			; PUT SCAN CODE BACK IN AH
   739 00000FA9 E99E000000          <1>         jmp     K25                     ; NUMERAL '0', STNDRD. PROCESSING
   740                              <1> K21:					; MIGHT BE NUMERIC
   741 00000FAE F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT
   742 00000FB1 74F4                <1> 	jz	short K20		; IS NUMERIC, STD. PROC.
   743                              <1> 	;
   744                              <1> K22:					; SHIFT TOGGLE KEY HIT; PROCESS IT
   745 00000FB3 8425[E2A10000]      <1> 	test	ah, [KB_FLAG_1] 	; IS KEY ALREADY DEPRESSED
   746 00000FB9 0F85A5000000        <1>         jnz     K26                     ; JUMP IF KEY ALREADY DEPRESSED
   747                              <1> K22A:
   748 00000FBF 0825[E2A10000]      <1>         or      [KB_FLAG_1], ah 	; INDICATE THAT THE KEY IS DEPRESSED
   749 00000FC5 3025[E1A10000]      <1> 	xor	[KB_FLAG], ah		; TOGGLE THE SHIFT STATE
   750                              <1> 	;
   751                              <1> 	;-----	TOGGLE LED IF CAPS, NUM  OR SCROLL KEY DEPRESSED
   752 00000FCB F6C470              <1> 	test	ah, CAPS_SHIFT+NUM_SHIFT+SCROLL_SHIFT ; SHIFT TOGGLE?
   753 00000FCE 7409                <1> 	jz	short K22B		; GO IF NOT
   754                              <1> 	;
   755 00000FD0 6650                <1> 	push	ax			; SAVE SCAN CODE AND SHIFT MASK
   756 00000FD2 E8F9030000          <1> 	call	SND_LED			; GO TURN MODE INDICATORS ON
   757 00000FD7 6658                <1> 	pop	ax			; RESTORE SCAN CODE
   758                              <1> K22B:
   759 00000FD9 3C52                <1> 	cmp	al, INS_KEY		; TEST FOR 1ST MAKE OF INSERT KEY
   760 00000FDB 0F8583000000        <1>         jne     K26                     ; JUMP IF NOT INSERT KEY
   761 00000FE1 88C4                <1> 	mov	ah, al		        ; SCAN CODE IN BOTH HALVES OF AX
   762 00000FE3 E999000000          <1>         jmp     K28                     ; FLAGS UPDATED, PROC. FOR BUFFER
   763                              <1> 	;
   764                              <1> 	;-----	BREAK SHIFT FOUND
   765                              <1> K23:					; BREAK-SHIFT-FOUND
   766 00000FE8 80FC10              <1> 	cmp	ah, SCROLL_SHIFT	; IS THIS A TOGGLE KEY
   767 00000FEB F6D4                <1> 	not	ah			; INVERT MASK
   768 00000FED 7355                <1> 	jae	short K24		; YES, HANDLE BREAK TOGGLE
   769 00000FEF 2025[E1A10000]      <1> 	and	[KB_FLAG], ah		; TURN OFF SHIFT BIT
   770 00000FF5 80FCFB              <1> 	cmp	ah, ~CTL_SHIFT		; IS THIS ALT OR CTL?
   771 00000FF8 7730                <1> 	ja	short K23D		; NO, ALL DONE
   772                              <1> 	;
   773 00000FFA F6C702              <1> 	test	bh, LC_E0		; 2ND ALT OR CTL?
   774 00000FFD 7408                <1> 	jz	short K23A		; NO, HANSLE NORMALLY
   775 00000FFF 2025[E4A10000]      <1> 	and 	[KB_FLAG_3], ah		; RESET BIT FOR RIGHT ALT OR CTL
   776 00001005 EB08                <1> 	jmp	short K23B		; CONTINUE
   777                              <1> K23A:
   778 00001007 D2FC                <1> 	sar	ah, cl			; MOVE THE MASK BIT TWO POSITIONS
   779 00001009 2025[E2A10000]      <1> 	and	[KB_FLAG_1], ah		; RESET BIT FOR LEFT ALT AND CTL
   780                              <1> K23B:
   781 0000100F 88C4                <1> 	mov	ah, al			; SAVE SCAN CODE
   782 00001011 A0[E4A10000]        <1> 	mov	al, [KB_FLAG_3]		; GET RIGHT ALT & CTRL FLAGS
   783 00001016 D2E8                <1> 	shr	al, cl			; MOVE TO BITS 1 & 0
   784 00001018 0A05[E2A10000]      <1> 	or	al, [KB_FLAG_1]		; PUT IN LEFT ALT & CTL FLAGS
   785 0000101E D2E0                <1> 	shl	al, cl			; MOVE BACK TO BITS 3 & 2
   786 00001020 240C                <1> 	and	al, ALT_SHIFT+CTL_SHIFT ; FILTER OUT OTHER GARBAGE
   787 00001022 0805[E1A10000]      <1> 	or	[KB_FLAG], al		; PUT RESULT IN THE REAL FLAGS	
   788 00001028 88E0                <1> 	mov	al, ah
   789                              <1> K23D:
   790 0000102A 3CB8                <1> 	cmp	al, ALT_KEY+80h		; IS THIS ALTERNATE SHIFT RELEASE
   791 0000102C 7536                <1> 	jne	short K26		; INTERRUPT RETURN
   792                              <1> 	;	
   793                              <1> 	;-----	ALTERNATE SHIFT KEY RELEASED, GET THE VALUE INTO BUFFER
   794 0000102E A0[E5A10000]        <1> 	mov	al, [ALT_INPUT]
   795 00001033 B400                <1> 	mov	ah, 0			; SCAN CODE OF 0
   796 00001035 8825[E5A10000]      <1> 	mov	[ALT_INPUT], ah 	; ZERO OUT THE FIELD
   797 0000103B 3C00                <1> 	cmp	al, 0			; WAS THE INPUT = 0?
   798 0000103D 7425                <1> 	je	short K26		; INTERRUPT_RETURN
   799                              <1>         ; 29/01/2016
   800                              <1> 	;jmp     K61                    ; IT WASN'T, SO PUT IN BUFFER
   801 0000103F E9D0020000          <1> 	jmp	_K60
   802                              <1> 	;
   803                              <1> K24:					; BREAK-TOGGLE
   804 00001044 2025[E2A10000]      <1> 	and	[KB_FLAG_1], ah 	; INDICATE NO LONGER DEPRESSED
   805 0000104A EB18                <1> 	jmp	short K26		; INTERRUPT_RETURN
   806                              <1> 	;
   807                              <1> 	;-----	TEST FOR HOLD STATE
   808                              <1> 					; AL, AH = SCAN CODE
   809                              <1> K25:					; NO-SHIFT-FOUND
   810 0000104C 3C80                <1> 	cmp	al, 80h			; TEST FOR BREAK KEY
   811 0000104E 7314                <1> 	jae	short K26		; NOTHING FOR BREAK CHARS FROM HERE ON
   812 00001050 F605[E2A10000]08    <1> 	test	byte [KB_FLAG_1], HOLD_STATE ; ARE WE IN HOLD STATE
   813 00001057 7428                <1> 	jz	short K28		; BRANCH AROUND TEST IF NOT
   814 00001059 3C45                <1> 	cmp	al, NUM_KEY
   815 0000105B 7407                <1> 	je	short K26		; CAN'T END HOLD ON NUM_LOCK
   816 0000105D 8025[E2A10000]F7    <1> 	and	byte [KB_FLAG_1], ~HOLD_STATE ; TURN OFF THE HOLD STATE BIT
   817                              <1> 	;
   818                              <1> K26:
   819 00001064 8025[E4A10000]FC    <1> 	and	byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
   820                              <1> K26A:					; INTERRUPT-RETURN
   821 0000106B FA                  <1> 	cli				; TURN OFF INTERRUPTS
   822 0000106C B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
   823 0000106E E620                <1> 	out	20h, al	;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
   824                              <1> K27:					; INTERRUPT-RETURN-NO-EOI
   825 00001070 B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
   826 00001072 E8F8020000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
   827                              <1> K27A:
   828 00001077 FA                  <1> 	cli				; DISABLE INTERRUPTS
   829 00001078 07                  <1> 	pop	es			; RESTORE REGISTERS
   830 00001079 1F                  <1> 	pop	ds
   831 0000107A 5F                  <1> 	pop	edi
   832 0000107B 5E                  <1> 	pop	esi
   833 0000107C 5A                  <1> 	pop	edx
   834 0000107D 59                  <1> 	pop	ecx
   835 0000107E 5B                  <1> 	pop	ebx
   836 0000107F 58                  <1> 	pop	eax
   837                              <1> 	;pop	ebp
   838 00001080 CF                  <1> 	iret				; RETURN
   839                              <1> 
   840                              <1> 	;-----	NOT IN	HOLD STATE
   841                              <1> K28:					; NO-HOLD-STATE
   842 00001081 3C58                <1> 	cmp	al, 88			; TEST FOR OUT-OF-RANGE SCAN CODES
   843 00001083 77DF                <1> 	ja	short K26		; IGNORE IF OUT-OF-RANGE	
   844                              <1> 	;
   845 00001085 F6C308              <1> 	test	bl, ALT_SHIFT 		; ARE WE IN ALTERNATE SHIFT
   846                              <1>         ;jz	short K28A		; IF NOT ALTERNATE
   847 00001088 0F84F1000000        <1>         jz      K38
   848                              <1> 	;
   849 0000108E F6C710              <1> 	test	bh, KBX			; IS THIS THE ENCHANCED KEYBOARD?
   850 00001091 740D                <1> 	jz	short K29		; NO, ALT STATE IS REAL
   851                              <1> 	 ;28/02/2015
   852 00001093 F605[E2A10000]04    <1> 	test	byte [KB_FLAG_1], SYS_SHIFT ; YES, IS SYSREQ KEY DOWN?
   853                              <1> 	;jz	short K29		;  NO, ALT STATE IS REAL
   854 0000109A 0F85DF000000        <1> 	jnz	K38			; YES, THIS IS PHONY ALT STATE 
   855                              <1>         ;				; DUE TO PRESSING SYSREQ	
   856                              <1> ;K28A:	jmp	short K38
   857                              <1> 	;
   858                              <1> 	;-----	TEST FOR RESET KEY SEQUENCE (CTL ALT DEL)
   859                              <1> K29:					; TEST-RESET
   860 000010A0 F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT ALSO?
   861 000010A3 740B                <1> 	jz	short K31		; NO_RESET
   862 000010A5 3C53                <1> 	cmp	al, DEL_KEY		; CTL-ALT STATE, TEST FOR DELETE KEY
   863 000010A7 7507                <1> 	jne	short K31		; NO_RESET, IGNORE
   864                              <1> 	;
   865                              <1> 	;-----	CTL-ALT-DEL HAS BEEN FOUND
   866                              <1>  	; 26/08/2014
   867                              <1> cpu_reset:
   868                              <1> 	; IBM PC/AT ROM BIOS source code - 10/06/85 (TEST4.ASM - PROC_SHUTDOWN)
   869                              <1> 	; Send FEh (system reset command) to the keyboard controller.
   870 000010A9 B0FE                <1> 	mov	al, SHUT_CMD		; SHUTDOWN COMMAND
   871 000010AB E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROL PORT
   872                              <1> khere:
   873 000010AD F4                  <1> 	hlt				; WAIT FOR 80286 RESET
   874 000010AE EBFD                <1> 	jmp 	short khere		; INSURE HALT
   875                              <1> 
   876                              <1> 	;
   877                              <1> 	;-----	IN ALTERNATE SHIFT, RESET NOT FOUND
   878                              <1> K31:					; NO-RESET
   879 000010B0 3C39                <1> 	cmp	al, 57			; TEST FOR SPACE KEY
   880 000010B2 7507                <1> 	jne	short K311		; NOT THERE
   881 000010B4 B020                <1> 	mov	al, ' '			; SET SPACE CHAR
   882 000010B6 E948020000          <1>         jmp     K57                     ; BUFFER_FILL
   883                              <1> K311:
   884 000010BB 3C0F                <1> 	cmp	al, 15			; TEST FOR TAB KEY
   885 000010BD 7509                <1> 	jne	short K312		; NOT THERE
   886 000010BF 66B800A5            <1> 	mov	ax, 0A500h		; SET SPECIAL CODE FOR ALT-TAB
   887 000010C3 E93B020000          <1>         jmp     K57                     ; BUFFER_FILL
   888                              <1> K312:
   889 000010C8 3C4A                <1> 	cmp	al, 74			; TEST FOR KEY PAD -
   890 000010CA 0F84A2000000        <1>         je      K37B                    ; GO PROCESS
   891 000010D0 3C4E                <1> 	cmp	al, 78			; TEST FOR KEY PAD +
   892 000010D2 0F849A000000        <1>         je      K37B                    ; GO PROCESS
   893                              <1> 	;
   894                              <1> 	;-----	LOOK FOR KEY PAD ENTRY
   895                              <1> K32:					; ALT-KEY-PAD
   896 000010D8 BF[A4A00000]        <1> 	mov	edi, K30		; ALT-INPUT-TABLE offset
   897 000010DD B90A000000          <1> 	mov	ecx, 10			; LOOK FOR ENTRY USING KEYPAD
   898 000010E2 F2AE                <1> 	repne	scasb			; LOOK FOR MATCH
   899 000010E4 7525                <1> 	jne	short K33		; NO_ALT_KEYPAD
   900 000010E6 F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OF THE NEW KEYS?
   901 000010E9 0F858A000000        <1>         jnz     K37C                    ; YES, JUMP, NOT NUMPAD KEY
   902 000010EF 81EF[A5A00000]      <1> 	sub	edi, K30+1		; DI NOW HAS ENTRY VALUE
   903 000010F5 A0[E5A10000]        <1> 	mov	al, [ALT_INPUT] 	; GET THE CURRENT BYTE
   904 000010FA B40A                <1> 	mov	ah, 10			; MULTIPLY BY 10
   905 000010FC F6E4                <1> 	mul	ah
   906 000010FE 6601F8              <1> 	add	ax, di			; ADD IN THE LATEST ENTRY
   907 00001101 A2[E5A10000]        <1> 	mov	[ALT_INPUT], al 	; STORE IT AWAY
   908                              <1> ;K32A:
   909 00001106 E959FFFFFF          <1>         jmp     K26                     ; THROW AWAY THAT KEYSTROKE
   910                              <1> 	;
   911                              <1> 	;-----	LOOK FOR SUPERSHIFT ENTRY
   912                              <1> K33:					; NO-ALT-KEYPAD
   913 0000110B C605[E5A10000]00    <1>         mov     byte [ALT_INPUT], 0     ; ZERO ANY PREVIOUS ENTRY INTO INPUT
   914 00001112 B91A000000          <1> 	mov	ecx, 26			; (DI),(ES) ALREADY POINTING
   915 00001117 F2AE                <1> 	repne	scasb			; LOOK FOR MATCH IN ALPHABET
   916 00001119 7450                <1> 	je	short K37A		; MATCH FOUND, GO FILLL THE BUFFER
   917                              <1> 	;
   918                              <1> 	;-----	LOOK FOR TOP ROW OF ALTERNATE SHIFT
   919                              <1> K34:					; ALT-TOP-ROW
   920 0000111B 3C02                <1> 	cmp	al, 2			; KEY WITH '1' ON IT
   921 0000111D 7253                <1> 	jb	short K37B		; MUST BE ESCAPE
   922 0000111F 3C0D                <1> 	cmp	al, 13			; IS IT IN THE REGION
   923 00001121 7705                <1> 	ja	short K35		; NO, ALT SOMETHING ELSE
   924 00001123 80C476              <1> 	add	ah, 118			; CONVERT PSEUDO SCAN CODE TO RANGE
   925 00001126 EB43                <1> 	jmp	short K37A		; GO FILL THE BUFFER
   926                              <1> 	;
   927                              <1> 	;-----	TRANSLATE ALTERNATE SHIFT PSEUDO SCAN CODES
   928                              <1> K35:					; ALT-FUNCTION
   929 00001128 3C57                <1> 	cmp	al, F11_M		; IS IT F11?	
   930 0000112A 7209                <1> 	jb	short K35A ; 20/02/2015	; NO, BRANCH
   931 0000112C 3C58                <1> 	cmp	al, F12_M		; IS IT F12?
   932 0000112E 7705                <1> 	ja	short K35A ; 20/02/2015	; NO, BRANCH
   933 00001130 80C434              <1> 	add	ah, 52			; CONVERT TO PSEUDO SCAN CODE
   934 00001133 EB36                <1> 	jmp	short K37A		; GO FILL THE BUFFER
   935                              <1> K35A:
   936 00001135 F6C702              <1> 	test	bh, LC_E0		; DO WE HAVE ONE OF THE NEW KEYS?
   937 00001138 7422                <1> 	jz	short K37		; NO, JUMP
   938 0000113A 3C1C                <1> 	cmp	al, 28			; TEST FOR KEYPAD ENTER
   939 0000113C 7509                <1>         jne     short K35B              ; NOT THERE
   940 0000113E 66B800A6            <1> 	mov	ax, 0A600h		; SPECIAL CODE
   941 00001142 E9BC010000          <1> 	jmp	K57			; BUFFER FILL
   942                              <1> K35B:
   943 00001147 3C53                <1> 	cmp	al, 83			; TEST FOR DELETE KEY
   944 00001149 742E                <1> 	je	short K37C		; HANDLE WITH OTHER EDIT KEYS
   945 0000114B 3C35                <1> 	cmp	al, 53			; TEST FOR KEYPAD /
   946                              <1> 	;jne	short K32A		; NOT THERE, NO OTHER E0 SPECIALS	
   947 0000114D 0F8511FFFFFF        <1>         jne     K26
   948 00001153 66B800A4            <1> 	mov	ax, 0A400h		; SPECIAL CODE
   949 00001157 E9A7010000          <1> 	jmp	K57			; BUFFER FILL
   950                              <1> K37:
   951 0000115C 3C3B                <1> 	cmp	al, 59			; TEST FOR FUNCTION KEYS (F1)
   952 0000115E 7212                <1>         jb      short K37B		; NO FN, HANDLE W/OTHER EXTENDED
   953 00001160 3C44                <1> 	cmp	al, 68			; IN KEYPAD REGION?
   954                              <1>         ;ja	short K32A		; IF SO, IGNORE
   955 00001162 0F87FCFEFFFF        <1>         ja      K26
   956 00001168 80C42D              <1> 	add	ah, 45			; CONVERT TO PSEUDO SCAN CODE
   957                              <1> K37A:
   958 0000116B B000                <1> 	mov	al, 0			; ASCII CODE OF ZERO
   959 0000116D E991010000          <1>         jmp     K57                     ; PUT IT IN THE BUFFER
   960                              <1> K37B:
   961 00001172 B0F0                <1> 	mov	al, 0F0h		; USE SPECIAL ASCII CODE
   962 00001174 E98A010000          <1> 	jmp     K57                     ; PUT IT IN THE BUFFER
   963                              <1> K37C:
   964 00001179 0450                <1> 	add	al, 80			; CONVERT SCAN CODE (EDIT KEYS)
   965 0000117B 88C4                <1> 	mov	ah, al			; (SCAN CODE NOT IN AH FOR INSERT)
   966 0000117D EBEC                <1> 	jmp     short K37A              ; PUT IT IN THE BUFFER
   967                              <1> 	;
   968                              <1> 	;-----	NOT IN ALTERNATE SHIFT
   969                              <1> K38:					; NOT-ALT-SHIFT
   970                              <1> 					; BL STILL HAS SHIFT FLAGS
   971 0000117F F6C304              <1> 	test	bl, CTL_SHIFT 		; ARE WE IN CONTROL SHIFT?
   972                              <1> 	;jnz	short K38A		; YES, START PROCESSING	
   973 00001182 0F84B0000000        <1>         jz      K44                     ; NOT-CTL-SHIFT
   974                              <1> 	;
   975                              <1> 	;-----	CONTROL SHIFT, TEST SPECIAL CHARACTERS
   976                              <1> 	;-----	TEST FOR BREAK
   977                              <1> K38A:
   978 00001188 3C46                <1> 	cmp	al, SCROLL_KEY		; TEST FOR BREAK
   979 0000118A 7531                <1> 	jne	short K39		; JUMP, NO-BREAK
   980 0000118C F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
   981 0000118F 7405                <1> 	jz	short K38B		; NO, BREAK IS VALID	
   982 00001191 F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
   983 00001194 7427                <1> 	jz	short K39		; NO-BREAK, TEST FOR PAUSE	
   984                              <1> K38B:
   985 00001196 8B1D[EEA10000]      <1> 	mov	ebx, [BUFFER_HEAD] 	; RESET BUFFER TO EMPTY
   986 0000119C 891D[F2A10000]      <1> 	mov	[BUFFER_TAIL], ebx
   987 000011A2 C605[E0A10000]80    <1> 	mov	byte [BIOS_BREAK], 80h  ; TURN ON BIOS_BREAK BIT
   988                              <1> 	;
   989                              <1> 	;-----	ENABLE KEYBOARD
   990 000011A9 B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
   991 000011AB E8BF010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
   992                              <1> 	;
   993                              <1> 	; CTRL+BREAK code here !!!
   994                              <1> 	;INT	1BH			; BREAK INTERRUPT VECTOR
   995                              <1> 	; 17/10/2015	
   996 000011B0 E8FD2A0000          <1> 	call	ctrlbrk ; control+break subroutine
   997                              <1> 	;
   998 000011B5 6629C0              <1> 	sub	ax, ax			; PUT OUT DUMMY CHARACTER
   999 000011B8 E946010000          <1>         jmp     K57                     ; BUFFER_FILL
  1000                              <1> 	;
  1001                              <1> 	;-----	TEST FOR PAUSE
  1002                              <1> K39:					; NO_BREAK
  1003 000011BD F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  1004 000011C0 7537                <1> 	jnz	short K41		; YES, THEN THIS CAN'T BE PAUSE	
  1005 000011C2 3C45                <1> 	cmp	al, NUM_KEY		; LOOK FOR PAUSE KEY
  1006 000011C4 7533                <1> 	jne	short K41		; NO-PAUSE
  1007                              <1> K39P:
  1008 000011C6 800D[E2A10000]08    <1> 	or	byte [KB_FLAG_1], HOLD_STATE ; TURN ON THE HOLD FLAG
  1009                              <1> 	;
  1010                              <1> 	;-----	ENABLE KEYBOARD
  1011 000011CD B0AE                <1> 	mov	al, ENA_KBD		; ENABLE KEYBOARD
  1012 000011CF E89B010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  1013                              <1> K39A:
  1014 000011D4 B020                <1> 	mov	al, EOI			; END OF INTERRUPT TO CONTROL PORT
  1015 000011D6 E620                <1> 	out	20h, al ;out INTA00, al	; ALLOW FURTHER KEYSTROKE INTERRUPTS
  1016                              <1> 	;
  1017                              <1> 	;-----	DURING PAUSE INTERVAL, TURN COLOR CRT BACK ON
  1018 000011D8 803D[16A20000]07    <1>         cmp     byte [CRT_MODE], 7      ; IS THIS BLACK AND WHITE CARD
  1019 000011DF 740A                <1>         je      short K40              	; YES, NOTHING TO DO
  1020 000011E1 66BAD803            <1> 	mov	dx, 03D8h		; PORT FOR COLOR CARD
  1021 000011E5 A0[17A20000]        <1>         mov     al, [CRT_MODE_SET] 	; GET THE VALUE OF THE CURRENT MODE
  1022 000011EA EE                  <1> 	out	dx, al			; SET THE CRT MODE, SO THAT CRT IS ON
  1023                              <1> 	;
  1024                              <1> K40:					; PAUSE-LOOP
  1025 000011EB F605[E2A10000]08    <1>         test    byte [KB_FLAG_1], HOLD_STATE ; CHECK HOLD STATE FLAG
  1026 000011F2 75F7                <1> 	jnz	short K40		; LOOP UNTIL FLAG TURNED OFF
  1027                              <1> 	;
  1028 000011F4 E977FEFFFF          <1>         jmp     K27                     ; INTERRUPT_RETURN_NO_EOI
  1029                              <1>         ;
  1030                              <1> 	;-----	TEST SPECIAL CASE KEY 55
  1031                              <1> K41:					; NO-PAUSE
  1032 000011F9 3C37                <1> 	cmp	al, 55			; TEST FOR */PRTSC KEY
  1033 000011FB 7513                <1> 	jne	short K42		; NOT-KEY-55
  1034 000011FD F6C710              <1> 	test	bh, KBX			; IS THIS THE ENHANCED KEYBOARD?
  1035 00001200 7405                <1> 	jz	short K41A		; NO, CTL-PRTSC IS VALID	
  1036 00001202 F6C702              <1> 	test	bh, LC_E0		; YES, WAS LAST CODE AN E0?
  1037 00001205 7421                <1> 	jz	short K42B		; NO, TRANSLATE TO A FUNCTION
  1038                              <1> K41A:	
  1039 00001207 66B80072            <1> 	mov	ax, 114*256		; START/STOP PRINTING SWITCH
  1040 0000120B E9F3000000          <1>         jmp     K57                     ; BUFFER_FILL
  1041                              <1> 	;
  1042                              <1> 	;-----	SET UP TO TRANSLATE CONTROL SHIFT
  1043                              <1> K42:					; NOT-KEY-55
  1044 00001210 3C0F                <1> 	cmp	al, 15			; IS IT THE TAB KEY?
  1045 00001212 7414                <1> 	je	short K42B		; YES, XLATE TO FUNCTION CODE
  1046 00001214 3C35                <1> 	cmp	al, 53			; IS IT THE / KEY?
  1047 00001216 750E                <1> 	jne	short K42A		; NO, NO MORE SPECIAL CASES	
  1048 00001218 F6C702              <1> 	test	bh, LC_E0		; YES, IS IT FROM THE KEY PAD?
  1049 0000121B 7409                <1> 	jz	short K42A		; NO, JUST TRANSLATE
  1050 0000121D 66B80095            <1> 	mov	ax, 9500h		; YES, SPECIAL CODE FOR THIS ONE
  1051 00001221 E9DD000000          <1> 	jmp	K57			; BUFFER FILL	
  1052                              <1> K42A: 
  1053                              <1> 	;;mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  1054 00001226 3C3B                <1> 	cmp	al, 59			; IS IT IN CHARACTER TABLE?
  1055                              <1>         ;jb	short K45F              ; YES, GO TRANSLATE CHAR
  1056                              <1> 	;;jb	K56 ; 20/02/2015
  1057                              <1> 	;;jmp	K64 ; 20/02/2015
  1058                              <1> K42B:
  1059 00001228 BB[D8A00000]        <1> 	mov	ebx, _K8		; SET UP TO TRANSLATE CTL
  1060 0000122D 0F82AE000000        <1> 	jb	K56 ;; 20/02/2015	
  1061 00001233 E9B9000000          <1> 	jmp	K64	
  1062                              <1>         ;
  1063                              <1> 	;-----	NOT IN CONTROL SHIFT
  1064                              <1> K44:					; NOT-CTL-SHIFT
  1065 00001238 3C37                <1> 	cmp	al, 55			; PRINT SCREEN KEY?
  1066 0000123A 7528                <1> 	jne	short K45		; NOT PRINT SCREEN
  1067 0000123C F6C710              <1> 	test	bh, KBX			; IS THIS ENHANCED KEYBOARD?
  1068 0000123F 7407                <1> 	jz	short K44A		; NO, TEST FOR SHIFT STATE	
  1069 00001241 F6C702              <1> 	test	bh, LC_E0		; YES, LAST CODE A MARKER?
  1070 00001244 7507                <1> 	jnz	short K44B		; YES, IS PRINT SCREEN
  1071 00001246 EB41                <1> 	jmp	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  1072                              <1> K44A:
  1073 00001248 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; NOT 101 KBD, SHIFT KEY DOWN?
  1074 0000124B 743C                <1> 	jz	short K45C		; NO, TRANSLATE TO '*' CHARACTER
  1075                              <1> 	;
  1076                              <1> 	;-----	ISSUE INTERRUPT TO INDICATE PRINT SCREEN FUNCTION
  1077                              <1> K44B:
  1078 0000124D B0AE                <1> 	mov	al, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  1079 0000124F E81B010000          <1> 	call	SHIP_IT			; EXECUTE ENABLE
  1080 00001254 B020                <1> 	mov	al, EOI			; END OF CURRENT INTERRUPT
  1081 00001256 E620                <1> 	out	20h, al ;out INTA00, al	; SO FURTHER THINGS CAN HAPPEN
  1082                              <1> 	; Print Screen !!!		; ISSUE PRINT SCREEN INTERRUPT (INT 05h)
  1083                              <1> 	;PUSH 	BP			; SAVE POINTER
  1084                              <1> 	;INT 	5H			; ISSUE PRINT SCREEN INTERRUPT
  1085                              <1> 	;POP	BP			; RESTORE POINTER
  1086 00001258 8025[E4A10000]FC    <1>         and     byte [KB_FLAG_3], ~(LC_E0+LC_E1) ; ZERO OUT THESE FLAGS
  1087 0000125F E90CFEFFFF          <1>         jmp     K27                     ; GO BACK WITHOUT EOI OCCURRING
  1088                              <1> 	;
  1089                              <1> 	;-----	HANDLE IN-CORE KEYS
  1090                              <1> K45:					; NOT-PRINT-SCREEN
  1091 00001264 3C3A                <1> 	cmp	al, 58			; TEST FOR IN-CORE AREA
  1092 00001266 7734                <1> 	ja	short K46		; JUMP IF NOT
  1093 00001268 3C35                <1> 	cmp	al, 53			; IS THIS THE '/' KEY?
  1094 0000126A 7505                <1> 	jne	short K45A		; NO, JUMP
  1095 0000126C F6C702              <1> 	test	bh, LC_E0		; WAS THE LAST CODE THE MARKER?
  1096 0000126F 7518                <1> 	jnz	short K45C		; YES, TRANSLATE TO CHARACTER
  1097                              <1> K45A:
  1098 00001271 B91A000000          <1> 	mov	ecx, 26			; LENGHT OF SEARCH
  1099 00001276 BF[AEA00000]        <1> 	mov	edi, K30+10		; POINT TO TABLE OF A-Z CHARS
  1100 0000127B F2AE                <1> 	repne	scasb			; IS THIS A LETTER KEY?
  1101                              <1> 		; 20/02/2015
  1102 0000127D 7505                <1> 	jne	short K45B              ; NO, SYMBOL KEY
  1103                              <1> 	;
  1104 0000127F F6C340              <1> 	test	bl, CAPS_STATE		; ARE WE IN CAPS_LOCK?
  1105 00001282 750C                <1> 	jnz	short K45D		; TEST FOR SURE
  1106                              <1> K45B:
  1107 00001284 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  1108 00001287 750C                <1> 	jnz	short K45E		; YES, UPPERCASE
  1109                              <1> 					; NO, LOWERCASE
  1110                              <1> K45C:
  1111 00001289 BB[30A10000]        <1> 	mov	ebx, K10		; TRANSLATE TO LOWERCASE LETTERS
  1112 0000128E EB51                <1> 	jmp	short K56	
  1113                              <1> K45D:					; ALMOST-CAPS-STATE
  1114 00001290 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; CL ON. IS SHIFT ON, TOO?
  1115 00001293 75F4                <1> 	jnz	short K45C		; SHIFTED TEMP OUT OF CAPS STATE
  1116                              <1> K45E:
  1117 00001295 BB[88A10000]        <1> 	mov	ebx, K11		; TRANSLATE TO UPPER CASE LETTERS
  1118 0000129A EB45                <1> K45F:	jmp	short K56
  1119                              <1> 	;
  1120                              <1> 	;-----	TEST FOR KEYS F1 - F10
  1121                              <1> K46:					; NOT IN-CORE AREA
  1122 0000129C 3C44                <1> 	cmp	al, 68			; TEST FOR F1 - F10
  1123                              <1> 	;ja	short K47		; JUMP IF NOT
  1124                              <1> 	;jmp	short K53		; YES, GO DO FN KEY PROCESS			
  1125 0000129E 7635                <1> 	jna	short K53		
  1126                              <1> 	;
  1127                              <1> 	;-----	HANDLE THE NUMERIC PAD KEYS
  1128                              <1> K47:					; NOT F1 - F10
  1129 000012A0 3C53                <1> 	cmp	al, 83			; TEST NUMPAD KEYS
  1130 000012A2 772D                <1> 	ja	short K52		; JUMP IF NOT
  1131                              <1> 	;
  1132                              <1> 	;-----	KEYPAD KEYS, MUST TEST NUM LOCK FOR DETERMINATION
  1133                              <1> K48:
  1134 000012A4 3C4A                <1> 	cmp	al , 74			; SPECIAL CASE FOR MINUS
  1135 000012A6 74ED                <1> 	je	short K45E		; GO TRANSLATE
  1136 000012A8 3C4E                <1> 	cmp	al , 78			; SPECIAL CASE FOR PLUS
  1137 000012AA 74E9                <1> 	je	short K45E		; GO TRANSLATE
  1138 000012AC F6C702              <1> 	test	bh, LC_E0		; IS THIS ONE OFTHE NEW KEYS?
  1139 000012AF 750A                <1> 	jnz	short K49		; YES, TRANSLATE TO BASE STATE
  1140                              <1> 	;		
  1141 000012B1 F6C320              <1> 	test 	bl, NUM_STATE		; ARE WE IN NUM LOCK
  1142 000012B4 7514                <1> 	jnz	short K50		; TEST FOR SURE
  1143 000012B6 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; ARE WE IN SHIFT STATE?
  1144                              <1> 	;jnz	short K51		; IF SHIFTED, REALLY NUM STATE
  1145 000012B9 75DA                <1> 	jnz	short K45E
  1146                              <1> 	;
  1147                              <1> 	;-----	BASE CASE FOR KEYPAD
  1148                              <1> K49:					
  1149 000012BB 3C4C                <1> 	cmp	al, 76			; SPECIAL CASE FOR BASE STATE 5
  1150 000012BD 7504                <1> 	jne	short K49A		; CONTINUE IF NOT KEYPAD 5
  1151 000012BF B0F0                <1> 	mov	al, 0F0h		; SPECIAL ASCII CODE	
  1152 000012C1 EB40                <1> 	jmp	short K57		; BUFFER FILL
  1153                              <1> K49A:
  1154 000012C3 BB[30A10000]        <1> 	mov	ebx, K10		; BASE CASE TABLE	
  1155 000012C8 EB27                <1> 	jmp	short K64		; CONVERT TO PSEUDO SCAN
  1156                              <1> 	;
  1157                              <1> 	;-----	MIGHT BE NUM LOCK, TEST SHIFT STATUS
  1158                              <1> K50:					; ALMOST-NUM-STATE
  1159 000012CA F6C303              <1>         test    bl, LEFT_SHIFT+RIGHT_SHIFT
  1160 000012CD 75EC                <1> 	jnz 	short K49		; SHIFTED TEMP OUT OF NUM STATE
  1161 000012CF EBC4                <1> K51:	jmp	short K45E		; REALLY NUM STATE
  1162                              <1> 	;
  1163                              <1> 	;-----	TEST FOR THE NEW KEYS ON WT KEYBOARDS 
  1164                              <1> K52:					; NOT A NUMPAD KEY
  1165 000012D1 3C56                <1> 	cmp	al, 86			; IS IT THE NEW WT KEY?
  1166                              <1> 	;jne	short K53		; JUMP IF NOT
  1167                              <1> 	;jmp	short K45B		; HANDLE WITH REST OF LETTER KEYS
  1168 000012D3 74AF                <1> 	je	short K45B		
  1169                              <1> 	;
  1170                              <1> 	;-----	MUST BE F11 OR F12 
  1171                              <1> K53:					; F1 - F10 COME HERE, TOO
  1172 000012D5 F6C303              <1> 	test	bl, LEFT_SHIFT+RIGHT_SHIFT ; TEST SHIFT STATE
  1173 000012D8 74E1                <1> 	jz	short K49		; JUMP, LOWER CASE PSEUDO SC'S
  1174                              <1> 		; 20/02/2015 
  1175 000012DA BB[88A10000]        <1> 	mov	ebx, K11		; UPPER CASE PSEUDO SCAN CODES
  1176 000012DF EB10                <1> 	jmp	short K64		; TRANSLATE SCAN
  1177                              <1> 	;
  1178                              <1> 	;-----	TRANSLATE THE CHARACTER
  1179                              <1> K56:					; TRANSLATE-CHAR
  1180 000012E1 FEC8                <1> 	dec	al			; CONVERT ORIGIN
  1181 000012E3 D7                  <1> 	xlat    			; CONVERT THE SCAN CODE TO ASCII
  1182 000012E4 F605[E4A10000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  1183 000012EB 7416                <1> 	jz	short K57		; NO, GO FILL BUFFER
  1184 000012ED B4E0                <1> 	mov	ah, MC_E0		; YES, PUT SPECIAL MARKER IN AH
  1185 000012EF EB12                <1> 	jmp	short K57		; PUT IT INTO THE BUFFER	
  1186                              <1> 	;
  1187                              <1> 	;-----	TRANSLATE SCAN FOR PSEUDO SCAN CODES
  1188                              <1> K64:					; TRANSLATE-SCAN-ORGD
  1189 000012F1 FEC8                <1> 	dec	al			; CONVERT ORIGIN
  1190 000012F3 D7                  <1>        	xlat    	                ; CTL TABLE SCAN
  1191 000012F4 88C4                <1> 	mov	ah, al			; PUT VALUE INTO AH
  1192 000012F6 B000                <1> 	mov	al, 0			; ZERO ASCII CODE
  1193 000012F8 F605[E4A10000]02    <1> 	test	byte [KB_FLAG_3], LC_E0	; IS THIS A NEW KEY?
  1194 000012FF 7402                <1> 	jz	short K57		; NO, GO FILL BUFFER
  1195 00001301 B0E0                <1> 	mov	al, MC_E0		; YES, PUT SPECIAL MARKER IN AL
  1196                              <1> 	;
  1197                              <1> 	;-----	PUT CHARACTER INTO BUFFER
  1198                              <1> K57:					; BUFFER_FILL
  1199 00001303 3CFF                <1> 	cmp	al, -1			; IS THIS AN IGNORE CHAR
  1200                              <1>         ;je	short K59		; YES, DO NOTHING WITH IT
  1201 00001305 0F8459FDFFFF        <1> 	je      K26			; YES, DO NOTHING WITH IT
  1202 0000130B 80FCFF              <1> 	cmp	ah, -1			; LOOK FOR -1 PSEUDO SCAN
  1203                              <1>         ;jne	short K61		; NEAR_INTERRUPT_RETURN
  1204 0000130E 0F8450FDFFFF        <1> 	je      K26			; INTERRUPT_RETURN
  1205                              <1> ;K59:					; NEAR_INTERRUPT_RETURN
  1206                              <1> ;	jmp	K26			; INTERRUPT_RETURN
  1207                              <1> 
  1208                              <1> _K60: ; 29/01/2016
  1209 00001314 80FC68              <1> 	cmp	ah, 68h	; ALT + F1 key
  1210 00001317 721F                <1> 	jb	short K61
  1211 00001319 80FC6F              <1> 	cmp	ah, 6Fh ; ALT + F8 key	
  1212 0000131C 771A                <1> 	ja	short K61
  1213                              <1> 	;
  1214 0000131E 8A1D[18A80000]      <1> 	mov	bl, [ACTIVE_PAGE]
  1215 00001324 80C368              <1> 	add	bl, 68h
  1216 00001327 38E3                <1> 	cmp	bl, ah
  1217 00001329 740D                <1> 	je	short K61
  1218 0000132B 6650                <1> 	push	ax
  1219 0000132D 88E0                <1> 	mov	al, ah
  1220 0000132F 2C68                <1> 	sub	al, 68h
  1221 00001331 E85D020000          <1> 	call	set_active_page
  1222 00001336 6658                <1> 	pop	ax
  1223                              <1> K61:					; NOT-CAPS-STATE
  1224 00001338 8B1D[F2A10000]      <1> 	mov	ebx, [BUFFER_TAIL] 	; GET THE END POINTER TO THE BUFFER
  1225 0000133E 89DE                <1> 	mov	esi, ebx		; SAVE THE VALUE
  1226 00001340 E857FAFFFF          <1> 	call	_K4			; ADVANCE THE TAIL
  1227 00001345 3B1D[EEA10000]      <1> 	cmp	ebx, [BUFFER_HEAD] 	; HAS THE BUFFER WRAPPED AROUND
  1228 0000134B 740E                <1> 	je	short K62		; BUFFER_FULL_BEEP
  1229 0000134D 668906              <1> 	mov	[esi], ax		; STORE THE VALUE
  1230 00001350 891D[F2A10000]      <1> 	mov	[BUFFER_TAIL], ebx 	; MOVE THE POINTER UP
  1231 00001356 E909FDFFFF          <1> 	jmp	K26
  1232                              <1> 	;;cli				; TURN OFF INTERRUPTS
  1233                              <1> 	;;mov	al, EOI			; END OF INTERRUPT COMMAND
  1234                              <1> 	;;out	INTA00, al		; SEND COMMAND TO INTERRUPT CONTROL PORT
  1235                              <1> 	;MOV	AL, ENA_KBD		; INSURE KEYBOARD IS ENABLED
  1236                              <1> 	;CALL	SHIP_IT			; EXECUTE ENABLE
  1237                              <1> 	;MOV	AX, 9102H		; MOVE IN POST CODE & TYPE
  1238                              <1> 	;INT	15H			; PERFORM OTHER FUNCTION
  1239                              <1> 	;;and	byte [KB_FLAG_3],~(LC_E0+LC_E1) ; RESET LAST CHAR H.C. FLAG
  1240                              <1> 	;JMP	K27A			; INTERRUPT_RETURN
  1241                              <1> 	;;jmp   K27                    
  1242                              <1> 	;
  1243                              <1> 	;-----	BUFFER IS FULL SOUND THE BEEPER
  1244                              <1> K62:
  1245 0000135B B020                <1> 	mov	al, EOI			; ENABLE INTERRUPT CONTROLLER CHIP
  1246 0000135D E620                <1> 	out	INTA00, al
  1247 0000135F 66B9A602            <1> 	mov	cx, 678			; DIVISOR FOR 1760 HZ
  1248 00001363 B304                <1> 	mov	bl, 4			; SHORT BEEP COUNT (1/16 + 1/64 DELAY)
  1249 00001365 E839050000          <1> 	call	beep			; GO TO COMMON BEEP HANDLER
  1250 0000136A E901FDFFFF          <1> 	jmp     K27			; EXIT   
  1251                              <1> 
  1252                              <1> SHIP_IT:
  1253                              <1> 	;---------------------------------------------------------------------------------
  1254                              <1> 	; SHIP_IT
  1255                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  1256                              <1> 	;	TO THE KEYBOARD CONTROLLER.
  1257                              <1> 	;---------------------------------------------------------------------------------
  1258                              <1> 	;
  1259 0000136F 6650                <1> 	push	ax			; SAVE DATA TO SEND
  1260                              <1> 
  1261                              <1> 	;-----	WAIT FOR COMMAND TO ACCEPTED
  1262 00001371 FA                  <1> 	cli				; DISABLE INTERRUPTS TILL DATA SENT
  1263                              <1> 	; xor	ecx, ecx		; CLEAR TIMEOUT COUNTER
  1264 00001372 B900000100          <1> 	mov	ecx, 10000h			
  1265                              <1> S10:
  1266 00001377 E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD CONTROLLER STATUS
  1267 00001379 A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ITS INPUT BUFFER BUSY
  1268 0000137B E0FA                <1> 	loopnz	S10			; WAIT FOR COMMAND TO BE ACCEPTED
  1269                              <1> 
  1270 0000137D 6658                <1> 	pop	ax			; GET DATA TO SEND
  1271 0000137F E664                <1> 	out	STATUS_PORT, al		; SEND TO KEYBOARD CONTROLLER
  1272 00001381 FB                  <1> 	sti				; ENABLE INTERRUPTS AGAIN
  1273 00001382 C3                  <1> 	retn				; RETURN TO CALLER
  1274                              <1> 
  1275                              <1> SND_DATA:
  1276                              <1> 	; ---------------------------------------------------------------------------------
  1277                              <1> 	; SND_DATA
  1278                              <1> 	;	THIS ROUTINES HANDLES TRANSMISSION OF COMMAND AND DATA BYTES
  1279                              <1> 	;	TO THE KEYBOARD AND RECEIPT OF ACKNOWLEDGEMENTS. IT ALSO
  1280                              <1> 	;	HANDLES ANY RETRIES IF REQUIRED
  1281                              <1> 	; ---------------------------------------------------------------------------------
  1282                              <1> 	;
  1283 00001383 6650                <1> 	push	ax			; SAVE REGISTERS
  1284 00001385 6653                <1> 	push	bx
  1285 00001387 51                  <1> 	push	ecx
  1286 00001388 88C7                <1> 	mov	bh, al			; SAVE TRANSMITTED BYTE FOR RETRIES
  1287 0000138A B303                <1> 	mov	bl, 3			; LOAD RETRY COUNT
  1288                              <1> SD0:
  1289 0000138C FA                  <1> 	cli				; DISABLE INTERRUPTS
  1290 0000138D 8025[E3A10000]CF    <1> 	and	byte [KB_FLAG_2], ~(KB_FE+KB_FA) ; CLEAR ACK AND RESEND FLAGS
  1291                              <1> 	;
  1292                              <1> 	;-----	WAIT FOR COMMAND TO BE ACCEPTED
  1293 00001394 B900000100          <1> 	mov	ecx, 10000h		; MAXIMUM WAIT COUNT
  1294                              <1> SD5:
  1295 00001399 E464                <1> 	in	al, STATUS_PORT		; READ KEYBOARD PROCESSOR STATUS PORT
  1296 0000139B A802                <1> 	test	al, INPT_BUF_FULL	; CHECK FOR ANY PENDING COMMAND
  1297 0000139D E0FA                <1> 	loopnz	SD5			; WAIT FOR COMMAND TO BE ACCEPTED
  1298                              <1> 	;
  1299 0000139F 88F8                <1> 	mov	al, bh			; REESTABLISH BYTE TO TRANSMIT
  1300 000013A1 E660                <1> 	out	PORT_A, al		; SEND BYTE
  1301 000013A3 FB                  <1> 	sti				; ENABLE INTERRUPTS
  1302                              <1> 	;mov	cx, 01A00h		; LOAD COUNT FOR 10 ms+
  1303 000013A4 B9FFFF0000          <1> 	mov	ecx, 0FFFFh
  1304                              <1> SD1:
  1305 000013A9 F605[E3A10000]30    <1> 	test	byte [KB_FLAG_2], KB_FE+KB_FA ; SEE IF EITHER BIT SET
  1306 000013B0 750F                <1> 	jnz	short SD3		; IF SET, SOMETHING RECEIVED GO PROCESS
  1307 000013B2 E2F5                <1> 	loop	SD1			; OTHERWISE WAIT
  1308                              <1> SD2:
  1309 000013B4 FECB                <1> 	dec	bl			; DECREMENT RETRY COUNT
  1310 000013B6 75D4                <1> 	jnz	short SD0		; RETRY TRANSMISSION
  1311 000013B8 800D[E3A10000]80    <1> 	or	byte [KB_FLAG_2], KB_ERR ; TURN ON TRANSMIT ERROR FLAG
  1312 000013BF EB09                <1> 	jmp	short SD4		; RETRIES EXHAUSTED FORGET TRANSMISSION
  1313                              <1> SD3:
  1314 000013C1 F605[E3A10000]10    <1> 	test	byte [KB_FLAG_2], KB_FA ; SEE IF THIS IS AN ACKNOWLEDGE
  1315 000013C8 74EA                <1> 	jz	short SD2		; IF NOT, GO RESEND
  1316                              <1> SD4:	
  1317 000013CA 59                  <1> 	pop	ecx			; RESTORE REGISTERS
  1318 000013CB 665B                <1> 	pop	bx
  1319 000013CD 6658                <1> 	pop	ax
  1320 000013CF C3                  <1> 	retn				; RETURN, GOOD TRANSMISSION
  1321                              <1> 
  1322                              <1> SND_LED:
  1323                              <1> 	; ---------------------------------------------------------------------------------
  1324                              <1> 	; SND_LED
  1325                              <1> 	;	THIS ROUTINES TURNS ON THE MODE INDICATORS.
  1326                              <1> 	;
  1327                              <1> 	;----------------------------------------------------------------------------------
  1328                              <1> 	;
  1329 000013D0 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1330 000013D1 F605[E3A10000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  1331 000013D8 755F                <1> 	jnz 	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  1332                              <1> 	;
  1333 000013DA 800D[E3A10000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  1334 000013E1 B020                <1> 	mov	al, EOI			; END OF INTERRUPT COMMAND
  1335 000013E3 E620                <1> 	out	20h, al ;out INTA00, al	; SEND COMMAND TO INTERRUPT CONTROL PORT
  1336 000013E5 EB11                <1> 	jmp	short SL0		; GO SEND MODE INDICATOR COMMAND
  1337                              <1> SND_LED1:
  1338 000013E7 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1339 000013E8 F605[E3A10000]40    <1> 	test	byte [KB_FLAG_2], KB_PR_LED ; CHECK FOR MODE INDICATOR UPDATE
  1340 000013EF 7548                <1> 	jnz	short SL1		; DON'T UPDATE AGAIN IF UPDATE UNDERWAY
  1341                              <1> 	;
  1342 000013F1 800D[E3A10000]40    <1> 	or	byte [KB_FLAG_2], KB_PR_LED ; TURN ON UPDATE IN PROCESS
  1343                              <1> SL0:
  1344 000013F8 B0ED                <1> 	mov	al, LED_CMD		; LED CMD BYTE
  1345 000013FA E884FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  1346 000013FF FA                  <1> 	cli
  1347 00001400 E836000000          <1> 	call	MAKE_LED		; GO FORM INDICATOR DATA BYTE
  1348 00001405 8025[E3A10000]F8    <1> 	and	byte [KB_FLAG_2], 0F8h	; ~KB_LEDS ; CLEAR MODE INDICATOR BITS
  1349 0000140C 0805[E3A10000]      <1> 	or	[KB_FLAG_2], al 	; SAVE PRESENT INDICATORS FOR NEXT TIME
  1350 00001412 F605[E3A10000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  1351 00001419 750F                <1> 	jnz	short SL2		; IF SO, BYPASS SECOND BYTE TRANSMISSION
  1352                              <1> 	;
  1353 0000141B E863FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  1354 00001420 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1355 00001421 F605[E3A10000]80    <1> 	test	byte [KB_FLAG_2], KB_ERR ; TRANSMIT ERROR DETECTED
  1356 00001428 7408                <1> 	jz	short SL3		; IF NOT, DON'T SEND AN ENABLE COMMAND
  1357                              <1> SL2:
  1358 0000142A B0F4                <1> 	mov	al, KB_ENABLE		; GET KEYBOARD CSA ENABLE COMMAND
  1359 0000142C E852FFFFFF          <1> 	call	SND_DATA		; SEND DATA TO KEYBOARD
  1360 00001431 FA                  <1> 	cli				; TURN OFF INTERRUPTS
  1361                              <1> SL3:
  1362 00001432 8025[E3A10000]3F    <1> 	and	byte [KB_FLAG_2], ~(KB_PR_LED+KB_ERR) ; TURN OFF MODE INDICATOR
  1363                              <1> SL1:					; UPDATE AND TRANSMIT ERROR FLAG
  1364 00001439 FB                  <1> 	sti				; ENABLE INTERRUPTS
  1365 0000143A C3                  <1> 	retn				; RETURN TO CALLER
  1366                              <1> 
  1367                              <1> MAKE_LED:
  1368                              <1> 	;---------------------------------------------------------------------------------
  1369                              <1> 	; MAKE_LED
  1370                              <1> 	;	THIS ROUTINES FORMS THE DATA BYTE NECESSARY TO TURN ON/OFF
  1371                              <1> 	;	THE MODE INDICATORS.
  1372                              <1> 	;---------------------------------------------------------------------------------
  1373                              <1> 	;
  1374                              <1> 	;push 	cx			; SAVE CX
  1375 0000143B A0[E1A10000]        <1> 	mov	al, [KB_FLAG]		; GET CAPS & NUM LOCK INDICATORS
  1376 00001440 2470                <1> 	and	al, CAPS_STATE+NUM_STATE+SCROLL_STATE ; ISOLATE INDICATORS
  1377                              <1> 	;mov	cl, 4			; SHIFT COUNT
  1378                              <1> 	;rol	al, cl			; SHIFT BITS OVER TO TURN ON INDICATORS
  1379 00001442 C0C004              <1> 	rol	al, 4 ; 20/02/2015
  1380 00001445 2407                <1> 	and	al, 07h			; MAKE SURE ONLY MODE BITS ON
  1381                              <1> 	;pop	cx
  1382 00001447 C3                  <1> 	retn				; RETURN TO CALLER
  1383                              <1> 
  1384                              <1> ; % include 'kybdata.s'   ; KEYBOARD DATA
  1385                              <1> 
  1386                              <1> 
  1387                              <1> ; /// End Of KEYBOARD FUNCTIONS ///
  1690                                  
  1691                                  %include 'video.s' ; 07/03/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - video.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 30/01/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 16/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Turkish Rational DOS
    11                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ; video.inc (13/08/2015)
    15                              <1> ;
    16                              <1> ; Derived from 'IBM PC-AT' BIOS source code (1985) 
    17                              <1> ; ****************************************************************************
    18                              <1> 
    19                              <1> ; Retro UNIX 386 v1 Kernel - VIDEO.INC
    20                              <1> ; Last Modification: 13/08/2015
    21                              <1> ;		  (Video Data is in 'VIDATA.INC')
    22                              <1> ;
    23                              <1> ; ///////// VIDEO (CGA) FUNCTIONS ///////////////
    24                              <1> 
    25                              <1> ; 16/01/2016 (32 bit modifications, TRDOS386 - TRDOS v2.0, video.s)
    26                              <1> ; INT 32H (TRDOS 386) = INT 10H (IBM PC/AT REAL MODE)
    27                              <1> 
    28                              <1> ; IBM PC-AT BIOS Source Code
    29                              <1> ; TITLE VIDEO1 --- 06/10/85  VIDEO DISPLAY BIOS
    30                              <1> 
    31                              <1> int10h:
    32                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
    33 00001448 9C                  <1> 	pushfd
    34 00001449 0E                  <1> 	push 	cs
    35 0000144A E851000000          <1> 	call 	VIDEO_IO_1
    36 0000144F C3                  <1> 	retn
    37                              <1> 
    38                              <1> ;--- INT 10 H -------------------------------------------------------------------
    39                              <1> ; VIDEO_IO									:	
    40                              <1> ;	THESE ROUTINES PROVIDE THE CRT DISPLAY INTERFACE			:
    41                              <1> ;	THE FOLLOWING FUNCTIONS ARE PROVIDED:					:
    42                              <1> ;										:
    43                              <1> ;    (AH)= 00H	SET MODE (AL) CONTAINS MODE VALUE				:
    44                              <1> ;		(AL) = 00H  40X25 BW MODE (POWER ON DEFAULT)			:
    45                              <1> ;		(AL) = 01H  40X25 COLOR						:
    46                              <1> ;		(AL) = 02H  80X25 BW						:
    47                              <1> ;		(AL) = 03H  80X25 COLOR						:
    48                              <1> ;		              GRAPHICS MODES					:
    49                              <1> ;		(AL) = 04H  320X200 COLOR					:
    50                              <1> ;		(AL) = 05H  320X200 BW MODE					:
    51                              <1> ;		(AL) = 06H  640X200 BW MODE					:
    52                              <1> ;		(AL) = 07H   80X25 MONOCHROME (USED INTERNAL TO VIDEO ONLY)	:
    53                              <1> ;		*** NOTES -BW MODES OPERATE SAME AS COLOR MODES, BUT COLOR	:
    54                              <1> ;		           BURST IS NOT ENABLED					:
    55                              <1> ;		          -CURSOR IS NOT DISPLAYED IN GRAPHICS MODE		:
    56                              <1> ;    (AH)= 01H	SET CURSOR TYPE							:
    57                              <1> ;		(CH) = BITS 4-0 = START LINE FOR CURSOR				:
    58                              <1> ;		       ** HARDWARE WILL ALWAYS CAUSE BLINK			:
    59                              <1> ;		       ** SETTING BIT 5 OR 6 WILL CAUSE ERRATIC BLINKING	:
    60                              <1> ;		          OR NO CURSOR AT ALL					:
    61                              <1> ;		(CL) = BITS 4-0 = END LINE FOR CURSOR				:
    62                              <1> ;    (AH)= 02H	SET CURSOR POSITION						:
    63                              <1> ;		(DH,DL) = ROW,COLUMN  (00H,00H) IS UPPER LEFT			:
    64                              <1> ;		(BH) = A PAGE NUMBER (MUST BE 00H FOR GRAPHICS MODES)		:
    65                              <1> ;    (AH)= 03H	READ CURSOR POSITION						:
    66                              <1> ;		(BH) = PAGE NUMBER (MUST BE 00H FOR GRAPHICS MODES)		:
    67                              <1> ;		ON EXIT (DH,DL) = ROW,COLUMN OF CURRENT CURSOR			:
    68                              <1> ;		        (CH,CL) = CURSOR MODE CURRENTLY SET			:
    69                              <1> ;    (AH)= 04H	READ LIGHT PEN POSITION						:
    70                              <1> ;		ON EXIT:							:
    71                              <1> ;		(AH) = 00H -- LIGHT PEN SWITCH NOT DOWN/NOT TRIGGERED		:
    72                              <1> ;		(AH) = 01H -- VALID LIGHT PEN VALUE IN REGISTERS		:
    73                              <1> ;		        (DH,DL) = ROW,COLUMN OF CHARACTER LP POSITION		:
    74                              <1> ;		        (CH) = RASTER LINE (0-199)				:
    75                              <1> ;		        (BX) = PIXEL COLUMN (0-319,639)				:
    76                              <1> ;    (AH)= 05H	SELECT ACTIVE DISPLAY PAGE (VALID ONLY FOR ALPHA MODES)		:
    77                              <1> ;		(AL) = NEW PAGE VALUE (0-7 FOR MODES 0&1, 0-3 FOR MODES 2&3)	:
    78                              <1> ;    (AH)= 06H	SCROLL ACTIVE PAGE UP						:
    79                              <1> ;		(AL) = NUMBER OF LINES. ( LINES BLANKED AT BOTTOM OF WINDOW )	:
    80                              <1> ;		        (AL) = 00H MEANS BLANK ENTIRE WINDOW			:
    81                              <1> ;		(CH,CL) = ROW,COLUMN OF UPPER LEFT CORNER OF SCROLL		:
    82                              <1> ;		(DH,DL) = ROW,COLUMN OF LOWER RIGHT CORNER OF SCROLL		:
    83                              <1> ;		(BH) = ATTRIBUTE TO BE USED ON BLANK LINE			:
    84                              <1> ;    (AH)= 07H	SCROLL ACTIVE PAGE DOWN						:
    85                              <1> ;		(AL) = NUMBER OF LINES, INPUT LINES BLANKED AT TOP OF WINDOW	:
    86                              <1> ;		        (AL) = 00H MEANS BLANK ENTIRE WINDOW			:
    87                              <1> ;		(CH,CL) = ROW,COLUMN OF UPPER LEFT CORNER OF SCROLL		:
    88                              <1> ;		(DH,DL) = ROW,COLUMN OF LOWER RIGHT CORNER OF SCROLL		:
    89                              <1> ;		(BH) = ATTRIBUTE TO BE USED ON BLANK LINE			:
    90                              <1> ;										:
    91                              <1> ;   CHARACTER HANDLING ROUTINES							:
    92                              <1> ;										:
    93                              <1> ;    (AH)= 08H	READ ATTRIBUTE/CHARACTER AT CURRENT CURSOR POSITION		:
    94                              <1> ;		(BH) = DISPLAY PAGE (VALID FOR ALPHA MODES ONLY)		:
    95                              <1> ;		ON EXIT:							:
    96                              <1> ;		(AL) = CHAR READ						:
    97                              <1> ;		(AH) = ATTRIBUTE OF CHARACTER READ (ALPHA MODES ONLY)		:
    98                              <1> ;    (AH)= 09H	WRITE ATTRIBUTE/CHARACTER AT CURRENT CURSOR POSITION		:
    99                              <1> ;		(BH) = DISPLAY PAGE (VALID FOR ALPHA MODES ONLY)		:
   100                              <1> ;		(CX) = COUNT OF CHARACTERS TO WRITE				:
   101                              <1> ;		(AL) = CHAR TO WRITE						:
   102                              <1> ;		(BL) = ATTRIBUTE OF CHARACTER (ALPHA)/COLOR OF CHAR (GRAPHICS)	:
   103                              <1> ;		         SEE NOTE ON WRITE DOT FOR BIT 7 OF BL = 1.		:
   104                              <1> ;    (AH) = 0AH	WRITE CHARACTER ONLY AT CURRENT CURSOR POSITION			:
   105                              <1> ;		(BH) = DISPLAY PAGE (VALID FOR ALPHA MODES ONLY)		:
   106                              <1> ;		(CX) = COUNT OF CHARACTERS TO WRITE				:
   107                              <1> ;		(AL) = CHAR TO WRITE						:
   108                              <1> ;		       NOTE: USE FUNCTION (AH)= 09H IN GRAPHICS MODES		:
   109                              <1> ;	FOR READ/WRITE CHARACTER INTERFACE WHILE IN GRAPHICS MODE, THE		:
   110                              <1> ;		CHARACTERS ARE FORMED FROM A CHARACTER GENERATOR IMAGE		:
   111                              <1> ;		MAINTAINED IN THE SYSTEM ROM. ONLY THE 1ST 128 CHARS		:
   112                              <1> ;		ARE CONTAINED THERE. TO READ/WRITE THE SECOND 128 CHARS,	:
   113                              <1> ;		THE USER MUST INITIALIZE THE POINTER AT INTERRUPT 1FH		:
   114                              <1> ;		(LOCATION 0007CH) TO POINT TO THE 1K BYTE TABLE CONTAINING	:
   115                              <1> ;		THE CODE POINTS FOR THE SECOND 128 CHARS (128-255).		:
   116                              <1> ;	FOR WRITE CHARACTER INTERFACE IN GRAPHICS MODE, THE REPLICATION FACTOR	:
   117                              <1> ;		CONTAINED IN (CX) ON ENTRY WILL PRODUCE VALID RESULTS ONLY	:
   118                              <1> ;		FOR CHARACTERS CONTAINED ON THE SAME ROW. CONTINUATION TO	:
   119                              <1> ;		SUCCEEDING LINES WILL NOT PRODUCE CORRECTLY.			:
   120                              <1> ;										:
   121                              <1> ;    GRAPHICS INTERFACE								:
   122                              <1> ;    (AH)= 0BH	SET COLOR PALETTE						:
   123                              <1> ;		(BH) = PALETTE COLOR ID BEING SET (0-127)			:
   124                              <1> ;		(BL) = COLOR VALUE TO BE USED WITH THAT COLOR ID		:
   125                              <1> ;		       NOTE: FOR THE CURRENT COLOR CARD, THIS ENTRY POINT HAS	:
   126                              <1> ;		               MEANING ONLY FOR 320X200 GRAPHICS.		:
   127                              <1> ;		       COLOR ID = 0 SELECTS THE BACKGROUND COLOR (0-15)		:
   128                              <1> ;		       COLOR ID = 1 SELECTS THE PALETTE TO BE USED:		:
   129                              <1> ;		               0 = GREEN(1)/RED(2)/YELLOW(3)			:
   130                              <1> ;		               1 = CYAN(1)/MAGENTA(2)/WHITE(3)			:
   131                              <1> ;		       IN 40X25 OR 80X25 ALPHA MODES, THE VALUE SET FOR 	:
   132                              <1> ;		               PALETTE COLOR 0 INDICATES THE BORDER COLOR	:
   133                              <1> ;		               TO BE USED (VALUES 0-31, WHERE 16-31 SELECT	:
   134                              <1> ;		               THE HIGH INTENSITY BACKGROUND SET.		:
   135                              <1> ;    (AH)= 0CH	WRITE DOT							:
   136                              <1> ;		(DX) = ROW NUMBER						:
   137                              <1> ;		(CX) = COLUMN NUMBER						:
   138                              <1> ;		(AL) = COLOR VALUE						:
   139                              <1> ;		        IF BIT 7 OF AL = 1, THEN THE COLOR VALUE IS EXCLUSIVE	:
   140                              <1> ;		        ORed WITH THE CURRENT CONTENTS OF THE DOT		:
   141                              <1> ;    (AH)= ODH	READ DOT							:
   142                              <1> ;		(DX) = ROW NUMBER						:
   143                              <1> ;		(CX) = COLUMN NUMBER						:
   144                              <1> ;		(AL) = RETURNS THE DOT READ					:
   145                              <1> ;										:
   146                              <1> ;    ASCII TELETYPE ROUTINE FOR OUTPUT						:
   147                              <1> ;										:
   148                              <1> ;    (AH)= 0EH	WRITE TELETYPE TO ACTIVE PAGE					:
   149                              <1> ;		(AL) = CHAR TO WRITE						:
   150                              <1> ;		(BL) = FOREGROUND COLOR IN GRAPHICS MODE			:
   151                              <1> ;		NOTE -- SCREEN WIDTH IS CONTROLLED BY PREVIOUS MODE SET		:
   152                              <1> ;    (AH)= 0FH	CURRENT VIDEO STATE						:
   153                              <1> ;		RETURNS THE CURRENT VIDEO STATE					:
   154                              <1> ;		(AL) = MODE CURRENTLY SET ( SEE (AH)=00H FOR EXPLANATION)	:
   155                              <1> ;		(AH) = NUMBER OR CHARACTER COLUMNS ON SCREEN			:
   156                              <1> ;		(BH) = CURRENT ACTIVE DISPLAY PAGE				:
   157                              <1> ;    (AH)= 10H	RESERVED							:
   158                              <1> ;    (AH)= 11H	RESERVED							:
   159                              <1> ;    (AH)= 12H	RESERVED							:
   160                              <1> ;    (AH)= 13H	WRITE STRING							:
   161                              <1> ;			ES:BP  -  POINTER T0 STRING TO BE WRITTEN		:
   162                              <1> ;			CX     -  LENGTH OF CHARACTER STRING TO WRITTEN		:
   163                              <1> ;			DX     -  CURSOR POSITION FOR STRING TO BE WRITTEN	:
   164                              <1> ;			BH     -  PAGE NUMBER					:
   165                              <1> ;		(AL)= 00H	WRITE CHARACTER STRING				:
   166                              <1> ;			BL     -  ATTRIBUTE					:
   167                              <1> ;			STRING IS  <CHAR,CHAR, ... ,CHAR>			:
   168                              <1> ;			CURSOR NOT MOVED					:
   169                              <1> ;		(AL)= 01H	WRITE CHARACTER STRING AND MOVE CURSOR		:
   170                              <1> ;			BL     -  ATTRIBUTE					:
   171                              <1> ;			STRING IS  <CHAR,CHAR, ... ,CHAR>			:
   172                              <1> ;			CURSOR MOVED						:
   173                              <1> ;		(AL)= 02H	WRITE CHARACTER AND ATTRIBUTE STRING		:
   174                              <1> ;			       (VALID FOR ALPHA MODES ONLY)			:
   175                              <1> ;			STRING IS <CHAR,ATTR,CHAR,ATTR ..  ,CHAR,ATTR>		:
   176                              <1> ;			CURSOR IS NOT MOVED					:
   177                              <1> ;		(AL)= 03H WRITE CHARACTER AND ATTRIBUTE STRING AND MOVE CURSOR	:
   178                              <1> ;			       (VALID FOR ALPHA MODES ONLY)			:
   179                              <1> ;			STRING IS <CHAR,ATTR,CHAR,ATTR ..  ,CHAR,ATTR>		:
   180                              <1> ;			CURSOR IS MOVED						:
   181                              <1> ;		 NOTE:  CARRIAGE RETURN, LINE FEED, BACKSPACE, AND BELL ARE	:
   182                              <1> ;		        TREATED AS COMMANDS RATHER THAN PRINTABLE CHARACTERS.	:
   183                              <1> ;										:
   184                              <1> ;	BX,CX,DX,SI,DI,BP,SP,DS,ES,SS PRESERVED DURING CALLS EXCEPT FOR		:
   185                              <1> ;	BX,CX,DX RETURN VALUES ON FUNCTIONS 03H,04H,0DH AND 0FH. ON ALL CALLS	:
   186                              <1> ;	AX IS MODIFIED.								:
   187                              <1> ;--------------------------------------------------------------------------------
   188                              <1> 
   189 00001450 [EB140000]          <1> M1:	dd	SET_MODE	; TABLE OF ROUTINES WITHIN VIDEO I/O
   190 00001454 [4B150000]          <1> 	dd	SET_CTYPE
   191 00001458 [60150000]          <1> 	dd	SET_CPOS
   192 0000145C [67150000]          <1> 	dd	READ_CURSOR
   193 00001460 [F0140000]          <1> 	dd	VIDEO_RETURN	; READ_LPEN
   194 00001464 [89150000]          <1> 	dd	ACT_DISP_PAGE
   195 00001468 [02160000]          <1> 	dd	SCROLL_UP
   196 0000146C [E6160000]          <1> 	dd	SCROLL_DOWN
   197 00001470 [31170000]          <1> 	dd	READ_AC_CURRENT
   198 00001474 [5F170000]          <1> 	dd	WRITE_AC_CURRENT
   199 00001478 [72170000]          <1> 	dd	WRITE_C_CURRENT
   200 0000147C [F0140000]          <1> 	dd	VIDEO_RETURN	; SET_COLOR
   201 00001480 [F0140000]          <1> 	dd	VIDEO_RETURN	; WRITE_DOT
   202 00001484 [F0140000]          <1> 	dd	VIDEO_RETURN	; READ_DOT
   203 00001488 [B6170000]          <1> 	dd	WRITE_TTY
   204 0000148C [D8140000]          <1> 	dd	VIDEO_STATE
   205 00001490 [F0140000]          <1> 	dd	VIDEO_RETURN	; RESERVED
   206 00001494 [F0140000]          <1> 	dd	VIDEO_RETURN	; RESERVED
   207 00001498 [F0140000]          <1> 	dd	VIDEO_RETURN	; RESERVED
   208 0000149C [F0140000]          <1> 	dd	VIDEO_RETURN	; WRITE_STRING
   209                              <1> M1L	EQU	$ - M1
   210                              <1> 
   211                              <1> VIDEO_IO_1:
   212 000014A0 FB                  <1> 	sti				; INTERRUPTS BACK ON
   213 000014A1 FC                  <1> 	cld				; SET DIRECTION FORWARD
   214 000014A2 80FC14              <1> 	cmp	ah, M1L/4		; TEST FOR WITHIN TABLE RANGE
   215 000014A5 7320                <1> 	jnb	short M4		; BRANCH TO EXIT IF NOT A VALID COMMAND
   216                              <1> 
   217 000014A7 06                  <1> 	push	es
   218 000014A8 1E                  <1> 	push	ds			; SAVE WORK AND PARAMETER REGISTERS
   219 000014A9 52                  <1> 	push	edx
   220 000014AA 51                  <1> 	push	ecx
   221 000014AB 53                  <1> 	push	ebx
   222 000014AC 56                  <1> 	push	esi
   223 000014AD 57                  <1> 	push	edi
   224 000014AE 55                  <1> 	push	ebp
   225 000014AF 66BE1000            <1> 	mov	si, KDATA 		; POINT DS: TO DATA SEGMENT
   226 000014B3 8EDE                <1> 	mov	ds, si
   227 000014B5 8EC6                <1> 	mov	es, si
   228 000014B7 BF00800B00          <1> 	mov	edi, 0B8000h		; GET offset FOR COLOR CARD
   229 000014BC D0E4                <1> 	shl	ah, 1			; TIMES 2 FOR WORD TABLE LOOKUP
   230 000014BE 0FB6F4              <1> 	movzx	esi, ah			; MOVE OFFSET INTO LOOK UP REGISTER (SI)
   231                              <1> 	;mov	ah, [CRT_MODE]		; MOVE CURRENT MODE INTO (AH) REGISTER
   232                              <1> 
   233 000014C1 FFA6[50140000]      <1> 	JMP	dword [esi+M1]		; GO TO SELECTED FUNCTION
   234                              <1> 
   235                              <1> M4:					;	COMMAND NOT VALID
   236 000014C7 CF                  <1> 	iret				; DO NOTHING IF NOT IN VALID RANGE
   237                              <1> 
   238                              <1> 
   239                              <1> ; 02/09/2014 (Retro UNIX 386 v1)
   240                              <1> ;
   241                              <1> ; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   242                              <1> 
   243                              <1> set_mode_3:  	; will be called from 'write_tty' 
   244 000014C8 53                  <1> 	push	ebx
   245 000014C9 52                  <1> 	push	edx
   246 000014CA 50                  <1> 	push	eax
   247 000014CB 57                  <1> 	push	edi
   248 000014CC 51                  <1> 	push	ecx
   249 000014CD E827000000          <1> 	call	set_txt_mode
   250 000014D2 59                  <1> 	pop	ecx
   251 000014D3 5F                  <1> 	pop	edi
   252 000014D4 58                  <1> 	pop	eax
   253 000014D5 5A                  <1> 	pop	edx
   254 000014D6 5B                  <1> 	pop	ebx
   255 000014D7 C3                  <1> 	retn
   256                              <1> 
   257                              <1> VIDEO_STATE:
   258                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   259                              <1> 
   260                              <1> ;---------------------------------------------------
   261                              <1> ; VIDEO STATE
   262                              <1> ;  RETURNS THE CURRENT VIDEO STATE IN AX
   263                              <1> ;  AH = NUMBER OF COLUMNS ON THE SCREEN
   264                              <1> ;  AL = CURRENT VIDEO MODE
   265                              <1> ;  BH = CURRENT ACTIVE PAGE
   266                              <1> ;---------------------------------------------------
   267                              <1> 
   268                              <1> 	;mov	ah, [CRT_COLS]	; GET NUMBER OF COLUMNS
   269 000014D8 B480                <1> 	mov	ah, 80h
   270 000014DA A0[16A20000]        <1> 	mov	al, [CRT_MODE]	; CURRENT MODE
   271                              <1> 	;movzx	esi, al
   272                              <1> 	;mov	ah, [esi+M6] 
   273                              <1> 	; BL = active page (not BH!)
   274 000014DF 8A1D[18A80000]      <1> 	mov	bl, [ACTIVE_PAGE] ; GET CURRENT ACTIVE PAGE
   275 000014E5 5D                  <1> 	pop	ebp		; RECOVER REGISTERS
   276 000014E6 5F                  <1> 	pop	edi
   277 000014E7 5E                  <1> 	pop	esi
   278 000014E8 59                  <1> 	pop	ecx	; DISCARD SAVED BX
   279 000014E9 EB09                <1> 	jmp	short M15	; RETURN TO CALLER
   280                              <1> 
   281                              <1> SET_MODE:
   282                              <1> 	; For 32 bit TRDOS and Retro UNIX 386:
   283                              <1> 	;	valid video mode: 03h only!
   284                              <1> 	;	(VGA modes will be selected with another routine)
   285                              <1> 	;
   286                              <1> 	; set_txt_mode ; 80*25 (16 fore colors, 8 back colors)
   287                              <1> 
   288                              <1> ;------------------------------------------------------
   289                              <1> ; SET MODE					      :
   290                              <1> ;	THIS ROUTINE INITIALIZES THE ATTACHMENT TO    :
   291                              <1> ;	THE SELECTED MODE, THE SCREEN IS BLANKED.     :
   292                              <1> ; INPUT						      :
   293                              <1> ;	(AL) - MODE SELECTED (RANGE 0-7)	      :
   294                              <1> ; OUTPUT					      :
   295                              <1> ;	NONE					      :
   296                              <1> ;------------------------------------------------------
   297                              <1> 
   298 000014EB E809000000          <1> 	call	set_txt_mode
   299                              <1> 
   300                              <1> ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   301                              <1> 
   302                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
   303                              <1> 
   304                              <1> VIDEO_RETURN:
   305 000014F0 5D                  <1> 	pop	ebp
   306 000014F1 5F                  <1> 	pop	edi
   307 000014F2 5E                  <1> 	pop	esi
   308 000014F3 5B                  <1> 	pop	ebx
   309                              <1> M15:			;VIDEO_RETURN_C
   310 000014F4 59                  <1> 	pop	ecx
   311 000014F5 5A                  <1> 	pop	edx
   312 000014F6 1F                  <1> 	pop	ds
   313 000014F7 07                  <1> 	pop	es	; RECOVER SEGMENTS
   314 000014F8 CF                  <1> 	iret		; ALL DONE
   315                              <1> 
   316                              <1> ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   317                              <1> set_txt_mode:
   318                              <1> 	;mov	dx, 03D4h 	; address of color card
   319 000014F9 B003                <1> 	mov	al, 3
   320                              <1> ;M8:
   321 000014FB A2[16A20000]        <1> 	mov	[CRT_MODE], al  ; save mode in global variable
   322 00001500 B029                <1> 	mov	al, 29h
   323                              <1> 	;mov	[CRT_MODE_SET], al ; save the mode set value
   324 00001502 2437                <1> 	and	al, 037h	; video off, save high resolution bit	
   325                              <1> 	;push	dx  		; save port value
   326                              <1> 	;add	dx, 4		; point to control register
   327 00001504 66BAD803            <1> 	mov	dx, 3D8h
   328 00001508 EE                  <1> 	out	dx, al		; reset video to off to suppress rolling
   329                              <1> 	;pop	dx
   330                              <1> ;M9:
   331 00001509 BB[18A20000]        <1> 	mov	ebx, video_params ; initialization table
   332 0000150E 668B430A            <1> 	mov	ax, [ebx+10]      ; get the cursor mode from the table	
   333 00001512 86E0                <1> 	xchg 	ah, al
   334 00001514 66A3[06A80000]      <1> 	mov	[CURSOR_MODE], ax ; save cursor mode
   335 0000151A 30E4                <1> 	xor	ah, ah		  ; ah is register number during loop 
   336                              <1> 	
   337                              <1> ;-----	LOOP THROUGH TABLE, OUTPUTTING REGISTER ADDRESS, THEN VALUE FROM TABLE
   338 0000151C B910000000          <1> 	mov	ecx, 16 ; 16/01/2016
   339                              <1> M10:			;  initialization loop
   340 00001521 88E0                <1> 	mov	al, ah 	; get 6845 register number
   341 00001523 EE                  <1> 	out	dx, al
   342 00001524 6642                <1> 	inc	dx      ; point to data port
   343 00001526 FEC4                <1> 	inc	ah	; next register value
   344 00001528 8A03                <1> 	mov	al, [ebx] ; get table value
   345 0000152A EE                  <1> 	out	dx, al	; out to chip
   346 0000152B 43                  <1> 	inc	ebx	; next in table
   347 0000152C 664A                <1> 	dec	dx	; back to pointer register
   348 0000152E E2F1                <1> 	loop	M10	; do the whole table
   349                              <1> 
   350                              <1> ;-----	FILL REGEN AREA WITH BLANK
   351                              <1> 	;xor	ax, ax  
   352                              <1> 	;mov	[CRT_START], ax  ; start address saved in global
   353                              <1> 	;mov	[ACTIVE_PAGE], al ; 0 ; (re)set page value
   354                              <1> 	;mov	ecx, 8192 ; number of words in color card
   355                              <1> 	; black background, light gray characeter color, space character
   356                              <1> 	;mov	ax, 0720h ; fill char for alpha - attribute
   357                              <1> ;M13:			  ; clear buffer
   358                              <1> 	;add	edi, 0B8000h ; [crt_base]
   359                              <1> 	;rep	stosw	; FILL THE REGEN BUFFER WITH BLANKS
   360                              <1> 
   361                              <1> ;-----	ENABLE VIDEO AND CORRECT PORT SETTING
   362                              <1> 	;mov	dx, 3D4h ; mov dx, word [ADDR_6845]
   363                              <1> 			 ; prepare to output to video enable port
   364                              <1> 	;add	dx,4	 ; point to the mode control gerister
   365 00001530 66BAD803            <1> 	mov	dx, 3D8h
   366                              <1> 	;mov	al, [CRT_MODE_SET] ; get the mode set value
   367 00001534 B029                <1> 	mov	al, 29h
   368 00001536 EE                  <1> 	out	dx, al	 ; set video enable port
   369                              <1> 
   370                              <1> ;----- 	DETERMINE NUMBER OF COLUMNS, BOTH FOR ENTIRE DISPLAY
   371                              <1> ;----- 	AND THE NUMBER TO BE USED FOR TTY INTERFACE
   372                              <1> 	;
   373                              <1> 	;mov	byte [CRT_COLS], 80h ; initialize number of columns count
   374                              <1> 	;
   375                              <1> ;-----	SET CURSOR POSITIONS
   376                              <1> 	;mov	word [CRT_LEN], 80*25*2
   377 00001537 BF[08A80000]        <1> 	mov	edi, CURSOR_POSN
   378 0000153C B904000000          <1> 	mov	ecx, 4	; clear all cursor positions (16 bytes)
   379 00001541 31C0                <1> 	xor	eax, eax
   380 00001543 F3AB                <1> 	rep 	stosd	; fill with zeroes
   381                              <1> 
   382                              <1> ;-----	SET UP OVERSCAN REGISTER
   383 00001545 6642                <1> 	inc	dx	; set overscan port to a default
   384 00001547 B030                <1> 	mov	al, 30h	; 30H value for all modes except 640X200 bw
   385                              <1> ;M14:
   386 00001549 EE                  <1> 	out	dx, al	; output the correct value to 3D9 port
   387                              <1> 	;mov	[CRT_PALETTE], al ; save the value for future use
   388                              <1> 
   389                              <1> ;-----	NORMAL RETURN FROM ALL VIDEO RETURNS
   390 0000154A C3                  <1> 	retn
   391                              <1> 
   392                              <1> SET_CTYPE:
   393                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   394 0000154B E802000000          <1> 	call	_set_ctype
   395 00001550 EB9E                <1> 	jmp	short VIDEO_RETURN
   396                              <1> 
   397                              <1> _set_ctype:
   398                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
   399                              <1> 	;
   400                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   401                              <1> 
   402                              <1> 	; (CH) = BITS 4-0 = START LINE FOR CURSOR
   403                              <1> 	;  ** HARDWARE WILL ALWAYS CAUSE BLINK
   404                              <1> 	;  ** SETTING BIT 5 OR 6 WILL CAUSE ERRATIC BLINKING
   405                              <1> 	;     OR NO CURSOR AT ALL
   406                              <1> 	; (CL) = BITS 4-0 = END LINE FOR CURSOR
   407                              <1> 
   408                              <1> ;------------------------------------------------
   409                              <1> ; SET_CTYPE
   410                              <1> ;	THIS ROUTINE SETS THE CURSOR VALUE
   411                              <1> ; INPUT
   412                              <1> ;	(CX) HAS CURSOR VALUE CH-START LINE, CL-STOP LINE
   413                              <1> ; OUTPUT	
   414                              <1> ;	NONE
   415                              <1> ;------------------------------------------------
   416                              <1> 
   417 00001552 B40A                <1> 	mov	ah, 10	; 6845 register for cursor set
   418 00001554 66890D[06A80000]    <1> 	mov	[CURSOR_MODE], cx ; save in data area
   419                              <1> 	;call	m16	; output cx register
   420                              <1> 	;retn
   421 0000155B E915030000          <1>         jmp     m16
   422                              <1> 
   423                              <1> SET_CPOS:
   424                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   425 00001560 E8E5020000          <1> 	call	_set_cpos
   426 00001565 EB89                <1> 	jmp	short VIDEO_RETURN
   427                              <1> 
   428                              <1> READ_CURSOR:
   429                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   430                              <1> 	;
   431                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   432                              <1> 
   433                              <1> ;------------------------------------------------------
   434                              <1> ; READ_CURSOR
   435                              <1> ;	THIS ROUTINE READS THE CURRENT CURSOR VALUE FROM THE
   436                              <1> ;	845, FORMATS IT, AND SENDS IT BACK TO THE CALLER
   437                              <1> ; INPUT
   438                              <1> ;	BH - PAGE OF CURSOR
   439                              <1> ; OUTPUT
   440                              <1> ;	DX - ROW, COLUMN OF THE CURRENT CURSOR POSITION
   441                              <1> ;	CX - CURRENT CURSOR MODE
   442                              <1> ;------------------------------------------------------
   443                              <1> 
   444                              <1> 	; BL = Video page number (0 to 7)
   445                              <1> 	
   446                              <1> 
   447 00001567 E810000000          <1> 	call	get_cpos
   448 0000156C 0FB70D[06A80000]    <1> 	movzx	ecx, word [CURSOR_MODE]
   449                              <1> 
   450 00001573 5D                  <1> 	pop	ebp
   451 00001574 5F                  <1> 	pop	edi
   452 00001575 5E                  <1> 	pop	esi
   453 00001576 5B                  <1> 	pop	ebx
   454 00001577 58                  <1> 	pop	eax	; DISCARD SAVED CX AND DX
   455 00001578 58                  <1> 	pop	eax
   456 00001579 1F                  <1> 	pop	ds
   457 0000157A 07                  <1> 	pop	es
   458 0000157B CF                  <1> 	iret
   459                              <1> 
   460                              <1> get_cpos:
   461                              <1> 	; 16/01/2016
   462                              <1> 	; BL = Video page number (0 to 7)
   463                              <1> 	;
   464 0000157C D0E3                <1> 	shl	bl, 1 ; WORD OFFSET
   465 0000157E 0FB6F3              <1> 	movzx	esi, bl 
   466 00001581 0FB796[08A80000]    <1> 	movzx	edx, word [esi+CURSOR_POSN]
   467 00001588 C3                  <1> 	retn
   468                              <1> 
   469                              <1> ACT_DISP_PAGE:
   470                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   471                              <1> 	;
   472                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   473                              <1> 	;
   474                              <1> ;-----------------------------------------------------
   475                              <1> ; ACT_DISP_PAGE
   476                              <1> ;	THIS ROUTINE SETS THE ACTIVE DISPLAY PAGE, ALLOWING
   477                              <1> ;	THE FULL USE OF THE MEMORY SET ASIDE FOR THE VIDEO ATTACHMENT
   478                              <1> ; INPUT
   479                              <1> ;	AL HAS THE NEW ACTIVE DISPLAY PAGE
   480                              <1> ; OUTPUT
   481                              <1> ;	THE 6845 IS RESET TO DISPLAY THAT PAGE
   482                              <1> ;-----------------------------------------------------
   483                              <1> 
   484 00001589 E805000000          <1> 	call	set_active_page
   485 0000158E E95DFFFFFF          <1>         jmp     VIDEO_RETURN
   486                              <1> 
   487                              <1> set_active_page:   ; tty_sw
   488                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   489                              <1> 	; 30/06/2015
   490                              <1> 	; 04/03/2014  (act_disp_page --> tty_sw)
   491                              <1> 	; 10/12/2013
   492                              <1> 	; 04/12/2013
   493                              <1> 	;
   494 00001593 A2[18A80000]        <1> 	mov	[ACTIVE_PAGE], al ; save active page value ; [ptty]
   495                              <1> 	;mov	cx, [CRT_LEN] ; get saved length of regen buffer
   496 00001598 66B9A00F            <1> 	mov	cx, 25*80*2
   497                              <1> 	; 27/06/2015
   498 0000159C 0FB6D8              <1> 	movzx	ebx, al
   499                              <1> 	;
   500 0000159F 6698                <1> 	cbw	; 07/09/2014 (ah=0)
   501 000015A1 66F7E1              <1> 	mul 	cx	; display page times regen length
   502                              <1> 	; 10/12/2013
   503 000015A4 66A3[04A80000]      <1> 	mov	[CRT_START], ax ; save start address for later
   504 000015AA 6689C1              <1> 	mov	cx, ax ; start address to cx
   505                              <1> 	;sar	cx, 1
   506 000015AD 66D1E9              <1> 	shr	cx, 1	; divide by 2 for 6845 handling
   507 000015B0 B40C                <1> 	mov	ah, 12	; 6845 register for start address
   508 000015B2 E8BE020000          <1> 	call	m16
   509                              <1> 	;sal	bx, 1
   510                              <1> 	; 01/09/2014
   511 000015B7 D0E3                <1> 	shl	bl, 1	; *2 for word offset
   512 000015B9 81C3[08A80000]      <1> 	add	ebx, CURSOR_POSN
   513 000015BF 668B13              <1> 	mov	dx, [ebx] ; get cursor for this page
   514                              <1> 	; 16/01/2016
   515                              <1> 	;call	m18
   516                              <1> 	;retn
   517 000015C2 E99A020000          <1> 	jmp	m18
   518                              <1> 
   519                              <1> position:
   520                              <1> 	; 27/06/2015
   521                              <1> 	; 02/09/2014
   522                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
   523                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1)
   524                              <1> 	;
   525                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   526                              <1> 	;
   527                              <1> ;-----------------------------------------
   528                              <1> ; POSITION
   529                              <1> ;	THIS SERVICE ROUTINE CALCULATES THE REGEN BUFFER ADDRESS
   530                              <1> ;	OF A CHARACTER IN THE ALPHA MODE
   531                              <1> ; INPUT
   532                              <1> ;	AX = ROW, COLUMN POSITION
   533                              <1> ; OUTPUT
   534                              <1> ;	AX = OFFSET OF CHAR POSITION IN REGEN BUFFER
   535                              <1> ;-----------------------------------------
   536                              <1> 
   537                              <1> 		; DX = ROW, COLUMN POSITION
   538                              <1> 	;movzx	eax, byte [CRT_COLS] ; 27/06/2015
   539 000015C7 31C0                <1> 	xor	eax, eax ; 02/09/2014
   540 000015C9 B050                <1> 	mov	al, 80   ; determine bytes to row	
   541 000015CB F6E6                <1> 	mul	dh	 ; row value
   542 000015CD 30F6                <1> 	xor	dh, dh   ; 0	
   543 000015CF 6601D0              <1> 	add	ax, dx	 ; add column value to the result
   544 000015D2 66D1E0              <1> 	shl	ax, 1	; * 2 for attribute bytes
   545                              <1> 		; EAX = AX = OFFSET OF CHAR POSITION IN REGEN BUFFER 
   546 000015D5 C3                  <1> 	retn
   547                              <1> 
   548                              <1> find_position:
   549                              <1> 	; 27/06/2015
   550                              <1> 	; 07/09/2014
   551                              <1> 	; 02/09/2014
   552                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
   553                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   554 000015D6 0FB6CB              <1> 	movzx	ecx, bl ; video page number ; 27/06/2015 (movzx)
   555 000015D9 89CE                <1> 	mov	esi, ecx
   556 000015DB 66D1E6              <1> 	shl	si, 1
   557 000015DE 668B96[08A80000]    <1> 	mov	dx, [esi + CURSOR_POSN]
   558 000015E5 740A                <1> 	jz	short p21
   559 000015E7 6631F6              <1> 	xor	si, si
   560                              <1> p20:
   561                              <1> 	;add	si, [CRT_LEN]
   562 000015EA 6681C6A00F          <1> 	add	si, 80*25*2 ; add length of buffer for one page		
   563 000015EF E2F9                <1> 	loop	p20
   564                              <1> p21:
   565 000015F1 6621D2              <1> 	and	dx, dx
   566 000015F4 7407                <1> 	jz	short p22
   567 000015F6 E8CCFFFFFF          <1> 	call 	position ; determine location in regen in page
   568 000015FB 01C6                <1> 	add	esi, eax ; add location to start of regen page
   569                              <1> p22:	
   570                              <1> 	;mov	dx, [addr_6845] ; get base address of active display			
   571                              <1> 	;mov	dx, 03D4h ; I/O address of color card
   572                              <1> 	;add	dx, 6	; point at status port
   573 000015FD 66BADA03            <1> 	mov	dx, 03DAh ; status port
   574                              <1> 	; cx = 0
   575 00001601 C3                  <1> 	retn
   576                              <1> 
   577                              <1> SCROLL_UP:
   578                              <1> 	; 30/01/2016
   579                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   580                              <1> 	; 07/09/2014
   581                              <1> 	; 02/09/2014
   582                              <1> 	; 01/09/2014 (Retro UNIX 386 v1 - beginning)
   583                              <1> 	; 04/04/2014
   584                              <1> 	; 04/12/2013
   585                              <1> 	;
   586                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   587                              <1> 	;
   588                              <1> ;----------------------------------------------
   589                              <1> ; SCROLL UP
   590                              <1> ;	THIS ROUTINE MOVES A BLOCK OF CHARACTERS UP
   591                              <1> ;	ON THE SCREEN
   592                              <1> ; INPUT
   593                              <1> ;	(AH) = CURRENT CRT MODE
   594                              <1> ;	(AL) = NUMBER OF ROWS TO SCROLL
   595                              <1> ;	(CX) = ROW/COLUMN OF UPPER LEFT CORNER
   596                              <1> ;	(DX) = ROW/COLUMN OF LOWER RIGHT CORNER
   597                              <1> ;	(BH) = ATTRIBUTE TO BE USED ON BLANKED LINE
   598                              <1> ;	(DS) = DATA SEGMENT
   599                              <1> ;	(ES) = REGEN BUFFER SEGMENT
   600                              <1> ; OUTPUT
   601                              <1> ;	NONE -- THE REGEN BUFFER IS MODIFIED
   602                              <1> ;--------------------------------------------
   603                              <1> 
   604 00001602 E805000000          <1> 	call	_scroll_up
   605 00001607 E9E4FEFFFF          <1>         jmp     VIDEO_RETURN
   606                              <1> 
   607                              <1> _scroll_up:  ; from 'write_tty'
   608                              <1> 	;
   609                              <1> 	; ((ah = 3))
   610                              <1> 	; cl = left upper column
   611                              <1> 	; ch = left upper row
   612                              <1> 	; dl = right lower column
   613                              <1> 	; dh = right lower row
   614                              <1> 	;
   615                              <1> 	; al = line count 
   616                              <1> 	; ah = attribute to be used on blanked line	
   617                              <1> 	; bl = video page number (0 to 7)
   618                              <1> 	; 
   619                              <1> 
   620 0000160C E86C000000          <1> 	call	test_line_count ; 16/01/2016
   621                              <1> 
   622                              <1> 	;mov	bh, [CRT_MODE] ; current video mode	
   623                              <1> 	;cmp	bh, 4
   624                              <1>  	;jb	short n1
   625                              <1> 
   626                              <1> 	;cmp	bh, 7 ; TEST FOR BW CARD
   627                              <1> 	;jne	GRAPHICS_UP
   628                              <1> n1:
   629 00001611 30FF                <1> 	xor	bh, bh	; 0
   630 00001613 6650                <1> 	push	ax ; *
   631                              <1> 	;mov 	esi, [CRT_BASE]
   632 00001615 BE00800B00          <1>         mov     esi, 0B8000h  
   633 0000161A 3A1D[18A80000]      <1>         cmp     bl, [ACTIVE_PAGE]
   634 00001620 750B                <1> 	jne	short n2
   635                              <1> 	;
   636 00001622 66A1[04A80000]      <1>         mov     ax, [CRT_START]
   637 00001628 6601C6              <1>         add     si, ax
   638 0000162B EB0F                <1>         jmp     short n4
   639                              <1> n2:
   640 0000162D 20DB                <1>         and     bl, bl
   641 0000162F 740B                <1> 	jz	short n4
   642 00001631 88D8                <1> 	mov	al, bl
   643                              <1> n3:
   644                              <1>         ;add    si, [CRT_LEN]
   645                              <1>         ;add    esi, 80*25*2 
   646 00001633 6681C6A00F          <1>         add     si, 80*25*2
   647 00001638 FEC8                <1>         dec	al
   648 0000163A 75F7                <1> 	jnz	short n3
   649                              <1> n4:	
   650 0000163C E84D000000          <1> 	call	scroll_position ; 16/01/2016
   651 00001641 7419                <1>         jz      short n6 
   652                              <1> 
   653 00001643 01CE                <1>         add     esi, ecx ; from address for scroll
   654 00001645 88F7                <1> 	mov	bh, dh  ; #rows in block
   655 00001647 28C7                <1> 	sub	bh, al	; #rows to be moved
   656                              <1> n5:
   657 00001649 E880000000          <1> 	call	n10 ; 16/01/2016
   658                              <1> 	
   659                              <1>         ;mov    cl, [CRT_COLS] 
   660                              <1> 	;add	cl, cl
   661                              <1>         ;mov    ecx, 80*2
   662 0000164E 66B9A000            <1>         mov     cx, 80*2
   663 00001652 01CE                <1>         add     esi, ecx  ; next line
   664 00001654 01CF                <1>         add     edi, ecx
   665 00001656 FECF                <1> 	dec	bh	 ; count of lines to move
   666 00001658 75EF                <1> 	jnz	short n5 ; row loop
   667                              <1> 	; bh = 0
   668 0000165A 88C6                <1> 	mov	dh, al	 ; #rows	
   669                              <1> n6:
   670                              <1> 	; attribute in ah
   671 0000165C B020                <1> 	mov	al, ' '	 ; fill with blanks
   672                              <1> n7:
   673 0000165E E878000000          <1> 	call	n11 ; 16/01/2016
   674                              <1> 
   675                              <1> 	;mov	cl, [CRT_COLS]
   676                              <1> 	;add	cl, cl
   677                              <1>         ;mov    ecx, 80*2
   678 00001663 66B9A000            <1>         mov	cx, 80*2
   679 00001667 01CF                <1>         add     edi, ecx
   680 00001669 FECE                <1> 	dec	dh
   681 0000166B 75F1                <1> 	jnz	short n7
   682                              <1> 	;
   683 0000166D 3A1D[18A80000]      <1> 	cmp	bl, [ACTIVE_PAGE]
   684 00001673 7507                <1> 	jne	short n8
   685                              <1> 	;mov	al, [CRT_MODE_SET] ; get the value of mode set
   686 00001675 B029                <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3	
   687 00001677 66BAD803            <1> 	mov	dx, 03D8h ; always set color card port
   688 0000167B EE                  <1> 	out	dx, al
   689                              <1> n8:
   690 0000167C C3                  <1> 	retn
   691                              <1> 
   692                              <1> 
   693                              <1> test_line_count:
   694                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   695                              <1> 	; 07/09/2014 (scroll_up)
   696 0000167D 08C0                <1> 	or	al, al
   697 0000167F 740C                <1> 	jz	short al_set
   698 00001681 88F7                <1> 	mov	bh, dh	; subtract lower row from upper row
   699 00001683 28EF                <1> 	sub	bh, ch
   700 00001685 FEC7                <1> 	inc	bh	; adjust difference by 1
   701 00001687 38C7                <1> 	cmp	bh, al 	; line count = amount of rows in window?
   702 00001689 7502                <1> 	jne	short al_set ; if not the we're all set
   703 0000168B 30C0                <1> 	xor	al, al	; otherwise set al to zero
   704                              <1> al_set:
   705 0000168D C3                  <1> 	retn
   706                              <1> 
   707                              <1> scroll_position:
   708                              <1> 	; 30/01/2016
   709                              <1>         ; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   710                              <1> 	; 07/09/2014 (scroll_up)
   711                              <1> 
   712 0000168E 6652                <1> 	push	dx
   713 00001690 6689CA              <1> 	mov	dx, cx	; now, upper left position in DX
   714 00001693 E82FFFFFFF          <1> 	call	position
   715 00001698 01C6                <1> 	add	esi, eax
   716 0000169A 89F7                <1> 	mov	edi, esi
   717 0000169C 665A                <1> 	pop	dx	; lower right position in DX
   718 0000169E 6629CA              <1> 	sub	dx, cx
   719 000016A1 FEC6                <1> 	inc	dh	; dh = #rows 
   720 000016A3 FEC2                <1> 	inc	dl	; dl = #cols in block
   721 000016A5 59                  <1> 	pop	ecx 	; return address
   722 000016A6 6658                <1> 	pop	ax	; * ; al = line count, ah = attribute
   723 000016A8 51                  <1> 	push	ecx	; return address
   724 000016A9 0FB7C8              <1> 	movzx	ecx, ax
   725                              <1> 	;mov	ah, [CRT_COLS]
   726 000016AC B450                <1> 	mov	ah, 80
   727 000016AE F6E4                <1> 	mul	ah	; determine offset to from address
   728 000016B0 6601C0              <1> 	add	ax, ax  ; *2 for attribute byte
   729                              <1> 	;
   730 000016B3 6650                <1> 	push	ax	; offset 
   731 000016B5 6652                <1> 	push	dx
   732                              <1> 	;
   733                              <1> 	; 04/04/2014
   734 000016B7 66BADA03            <1> 	mov	dx, 3DAh ; guaranteed to be color card here	
   735                              <1> n9:                      ; wait_display_enable
   736 000016BB EC                  <1>         in      al, dx   ; get port
   737 000016BC A808                <1> 	test	al, RVRT ; wait for vertical retrace	
   738 000016BE 74FB                <1> 	jz	short n9 ; wait_display_enable
   739 000016C0 B025                <1> 	mov	al, 25h
   740 000016C2 B2D8                <1> 	mov	dl, 0D8h ; address control port
   741 000016C4 EE                  <1> 	out	dx, al	; turn off video during vertical retrace
   742 000016C5 665A                <1> 	pop	dx	; #rows, #cols
   743 000016C7 6658                <1>        	pop	ax	; offset
   744 000016C9 6691                <1> 	xchg	ax, cx	; 
   745                              <1> 	; ecx = offset, al = line count, ah = attribute
   746                              <1> 	;
   747 000016CB 08C0                <1> 	or	al, al
   748 000016CD C3                  <1> 	retn
   749                              <1> 
   750                              <1> n10:
   751                              <1> 	; Move rows
   752 000016CE 88D1                <1> 	mov	cl, dl	; get # of cols to move
   753 000016D0 56                  <1> 	push	esi
   754 000016D1 57                  <1> 	push	edi	; save start address
   755                              <1> n10r:
   756 000016D2 66A5                <1> 	movsw		; move that line on screen
   757 000016D4 FEC9                <1> 	dec	cl
   758 000016D6 75FA                <1>         jnz     short n10r
   759 000016D8 5F                  <1> 	pop	edi
   760 000016D9 5E                  <1> 	pop	esi	; recover addresses
   761 000016DA C3                  <1> 	retn
   762                              <1> n11:
   763                              <1> 	; Clear rows
   764                              <1>                 ; dh =  #rows
   765 000016DB 88D1                <1>         mov	cl, dl	; get # of cols to clear
   766 000016DD 57                  <1>         push    edi     ; save address
   767                              <1> n11r:
   768 000016DE 66AB                <1>         stosw           ; store fill character
   769 000016E0 FEC9                <1> 	dec	cl
   770 000016E2 75FA                <1>         jnz     short n11r
   771 000016E4 5F                  <1>         pop     edi     ; recover address
   772 000016E5 C3                  <1> 	retn
   773                              <1> 
   774                              <1> SCROLL_DOWN:
   775                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   776                              <1> 	;
   777                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   778                              <1> 
   779                              <1> ;------------------------------------------
   780                              <1> ; SCROLL DOWN
   781                              <1> ;	THIS ROUTINE MOVES THE CHARACTERS WITHIN A DEFINED
   782                              <1> ;	BLOCK DOWN ON THE SCREEN, FILLING THE TOP LINES
   783                              <1> ;	WITH A DEFINED CHARACTER
   784                              <1> ; INPUT
   785                              <1> ;	(AH) = CURRENT CRT MODE
   786                              <1> ;	(AL) = NUMBER OF LINES TO SCROLL
   787                              <1> ;	(CX) = UPPER LEFT CORNER OF RECION
   788                              <1> ;	(DX) = LOWER RIGHT CORNER OF REGION
   789                              <1> ;	(BH) = FILL CHARACTER
   790                              <1> ;	(DS) = DATA SEGMENT
   791                              <1> ;	(ES) = REGEN SEGMENT
   792                              <1> ; OUTPUT
   793                              <1> ;	NONE -- SCREEN IS SCROLLED
   794                              <1> ;------------------------------------------
   795                              <1> 
   796                              <1> 	; ((ah = 3))
   797                              <1> 	; cl = left upper column
   798                              <1> 	; ch = left upper row
   799                              <1> 	; dl = right lower column
   800                              <1> 	; dh = right lower row
   801                              <1> 	;
   802                              <1> 	; al = line count 
   803                              <1> 	; ah = attribute to be used on blanked line	
   804                              <1> 	; bl = video page number (0 to 7)
   805                              <1> 	; 
   806                              <1> 
   807                              <1> 	; !!!!
   808 000016E6 FD                  <1> 	std		; DIRECTION FOR SCROLL DOWN
   809                              <1> 	; !!!!
   810 000016E7 E891FFFFFF          <1> 	call	test_line_count ; 16/01/2016
   811                              <1> 	
   812                              <1> 	;mov	bh, [CRT_MODE] ; current video mode
   813                              <1> 	;cmp	bh, 4
   814                              <1>  	;jb	short n12
   815                              <1> 
   816                              <1> 	;cmp	bh, 7 ; TEST FOR BW CARD
   817                              <1> 	;jne	GRAPHICS_DOWN
   818                              <1> 
   819                              <1> n12:			; CONTINUE_DOWN
   820 000016EC 6650                <1> 	push	ax	; * ; save attribute in ah
   821 000016EE 6689D0              <1> 	mov	ax, dx	; LOWER RIGHT CORNER
   822 000016F1 E898FFFFFF          <1> 	call	scroll_position	; GET REGEN LOCATION
   823 000016F6 7419                <1> 	jz	short n14
   824 000016F8 29CE                <1> 	sub	esi, ecx  ; SI IS FROM ADDRESS
   825 000016FA 88F7                <1> 	mov	bh, dh  ; #rows in block
   826 000016FC 28C7                <1> 	sub	bh, al	; #rows to be moved
   827                              <1> n13:
   828 000016FE E8CBFFFFFF          <1> 	call	n10	; MOVE ONE ROW
   829                              <1> 
   830                              <1> 	;mov    cl, [CRT_COLS] 
   831                              <1> 	;add	cl, cl
   832                              <1>         ;mov    ecx, 80*2
   833 00001703 66B9A000            <1>         mov     cx, 80*2
   834 00001707 29CE                <1>         sub     esi, ecx  ; next line
   835 00001709 29CF                <1>         sub     edi, ecx
   836 0000170B FECF                <1> 	dec	bh	 ; count of lines to move
   837 0000170D 75EF                <1> 	jnz	short n13 ; row loop
   838                              <1> 	; bh = 0
   839 0000170F 88C6                <1> 	mov	dh, al	 ; #rows
   840                              <1> n14:
   841                              <1> 	; attribute in ah
   842 00001711 B020                <1> 	mov	al, ' '	 ; fill with blanks
   843                              <1> n15:
   844 00001713 E8C3FFFFFF          <1> 	call	n11 ; 16/01/2016
   845                              <1> 
   846                              <1> 	;mov	cl, [CRT_COLS]
   847                              <1> 	;add	cl, cl
   848                              <1>         ;mov    ecx, 80*2
   849 00001718 B1A0                <1>         mov	cl, 80*2
   850 0000171A 29CF                <1>         sub     edi, ecx
   851 0000171C FECE                <1> 	dec	dh
   852 0000171E 75F3                <1> 	jnz	short n15
   853                              <1> 	;
   854 00001720 3A1D[18A80000]      <1> 	cmp	bl, [ACTIVE_PAGE]
   855 00001726 7507                <1> 	jne	short n16
   856                              <1> 	;mov	al, [CRT_MODE_SET] ; get the value of mode set
   857 00001728 B029                <1> 	mov	al, 29h ; (ORGS.ASM), M7 mode set table value for mode 3	
   858 0000172A 66BAD803            <1> 	mov	dx, 03D8h ; always set color card port
   859 0000172E EE                  <1> 	out	dx, al
   860                              <1> n16:
   861                              <1> 	; !!!!
   862 0000172F FC                  <1> 	cld		; Clear direction flag !
   863                              <1> 	; !!!!
   864 00001730 C3                  <1> 	retn
   865                              <1> 
   866                              <1> READ_AC_CURRENT:
   867                              <1> 	; 18/01/2016
   868                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   869                              <1> 	;
   870                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   871                              <1> 	;
   872                              <1> 
   873 00001731 E805000000          <1> 	call	_read_ac_current
   874 00001736 E9B5FDFFFF          <1>         jmp     VIDEO_RETURN
   875                              <1> 
   876                              <1> ;------------------------------------------------------------------------
   877                              <1> ; READ_AC_CURRENT							:
   878                              <1> ;	THIS ROUTINE READS THE ATTRIBUTE AND CHARACTER AT THE CURRENT	:
   879                              <1> ;	CURSOR POSITION AND RETURNS THEM TO THE CALLER			:
   880                              <1> ; INPUT									:
   881                              <1> ;	(AH) = CURRENT CRT MODE						:
   882                              <1> ;	(BH) = DISPLAY PAGE ( ALPHA MODES ONLY )			:
   883                              <1> ;	(DS) = DATA SEGMENT						:
   884                              <1> ;	(ES) = REGEN SEGMENT						:
   885                              <1> ; OUTPUT								:
   886                              <1> ;	(AL) = CHARACTER READ						:
   887                              <1> ;	(AH) = ATTRIBUTE READ						:
   888                              <1> ;------------------------------------------------------------------------
   889                              <1> 
   890                              <1> _read_ac_current: ; 18/01/2016
   891                              <1> 
   892                              <1> p10:
   893 0000173B E896FEFFFF          <1> 	call	find_position	; GET REGEN LOCATION AND PORT ADDRESS
   894                              <1> 	;
   895                              <1> 	; esi = regen location
   896                              <1> 	; dx = status port
   897                              <1> 	;
   898                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE
   899                              <1> 	;
   900                              <1> p11:			; wait for horizontal retrace is low or vertical
   901 00001740 FB                  <1> 	sti		; enable interrupts first
   902 00001741 3A1D[18A80000]      <1>         cmp     bl, [ACTIVE_PAGE]
   903 00001747 750C                <1> 	jne	short p14 
   904 00001749 FA                  <1> 	cli 		; block interrupts for single loop
   905 0000174A EC                  <1> 	in	al, dx	; get status from the adapter
   906 0000174B A801                <1> 	test	al, RHRZ ; is horizontal retrace low
   907 0000174D 75F1                <1> 	jnz	short p11 ; wait until it is
   908                              <1> p12:			;  wait for either retrace high
   909 0000174F EC                  <1> 	in	al, dx ; get status again
   910 00001750 A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
   911 00001752 74FB                <1> 	jz	short p12 ; wait until either retrace active
   912 00001754 FB                  <1> 	sti
   913                              <1> p14:
   914 00001755 81C600800B00        <1> 	add	esi, 0B8000h 
   915 0000175B 668B06              <1> 	mov	ax, [esi]
   916                              <1> 
   917 0000175E C3                  <1> 	retn	; 18/01/2016
   918                              <1> 
   919                              <1> 
   920                              <1> WRITE_AC_CURRENT:
   921                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   922                              <1> 	;
   923                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   924                              <1> 	;
   925                              <1> ;----------------------------------------------------------------
   926                              <1> ; WRITE_AC_CURRENT						:
   927                              <1> ;	THTS ROUTINE WRITES THE ATTRIBUTE AND CHARACTER		:
   928                              <1> ;	AT THE CURRENT CURSOR POSITION				:
   929                              <1> ; INPUT								:
   930                              <1> ;	(AH) = CURRENT CRT MODE					:
   931                              <1> ;	(BH) = DISPLAY PAGE					:
   932                              <1> ;	(CX) = COUNT OF CHARACTERS TO WRITE			:
   933                              <1> ;	(AL) = CHAR TO WRITE					:
   934                              <1> ;	(BL) = ATTRIBUTE OF CHAR TO WRITE			:
   935                              <1> ;	(DS) = DATA SEGMENT					:
   936                              <1> ;	(ES) = REGEN SEGMENT					:
   937                              <1> ; OUTPUT							:
   938                              <1> ;	DISPLAY REGEN BUFFER UPDATED				:
   939                              <1> ;----------------------------------------------------------------
   940                              <1> 
   941 0000175F E821000000          <1> 	call	_write_c_current
   942                              <1> 
   943 00001764 0FB6F3              <1> 	movzx	esi, bl ; video page number (0 to 7)	
   944 00001767 88A6[28A20000]      <1> 	mov	[esi+chr_attrib], ah ; color/attribute
   945                              <1> 
   946 0000176D E97EFDFFFF          <1>         jmp     VIDEO_RETURN
   947                              <1> 
   948                              <1> WRITE_C_CURRENT:
   949                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   950                              <1> 	;
   951                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   952                              <1> 	;
   953                              <1> 
   954                              <1> 	;and	bl, 7 ; video page number (<= 7)
   955 00001772 0FB6F3              <1> 	movzx	esi, bl	
   956 00001775 8AA6[28A20000]      <1> 	mov	ah, [esi+chr_attrib]
   957                              <1> 
   958 0000177B E805000000          <1> 	call	_write_c_current
   959 00001780 E96BFDFFFF          <1>         jmp     VIDEO_RETURN
   960                              <1> 
   961                              <1> ;----------------------------------------------------------------
   962                              <1> ; WRITE_C_CURRENT						:
   963                              <1> ;	THIS ROUTINE WRITES THE CHARACTER AT			:
   964                              <1> ;	THE CURRENT CURSOR POSITION, ATTRIBUTE UNCHANGED	:
   965                              <1> ; INPUT								:
   966                              <1> ;	(AH) = CURRENT CRT MODE					:
   967                              <1> ;	(BH) = DISPLAY PAGE					:
   968                              <1> ;	(CX) = COUNT OF CHARACTERS TO WRITE			:
   969                              <1> ;	(AL) = CHAR TO WRITE					:
   970                              <1> ;	(DS) = DATA SEGMENT					:
   971                              <1> ;	(ES) = REGEN SEGMENT					:
   972                              <1> ; OUTPUT							:
   973                              <1> ;	DISPLAY REGEN BUFFER UPDATED				:
   974                              <1> ;----------------------------------------------------------------
   975                              <1> 
   976                              <1> _write_c_current:  ; from 'write_tty'
   977                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   978                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
   979                              <1> 	; 18/01/2014
   980                              <1> 	; 04/12/2013
   981                              <1> 	;
   982                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
   983                              <1> 	;
   984                              <1> 
   985 00001785 FA                  <1> 	cli		
   986                              <1> 	; bl = video page
   987                              <1> 	; al = character
   988                              <1> 	; ah = color/attribute
   989 00001786 6652                <1> 	push	dx
   990 00001788 6650                <1> 	push	ax	; save character & attribute/color
   991 0000178A E847FEFFFF          <1> 	call 	find_position  ; get regen location and port address
   992                              <1> 	; esi = regen location
   993                              <1> 	; dx = status port
   994                              <1> 	;
   995                              <1> 	; WAIT FOR HORIZONTAL RETRACE OR VERTICAL RETRACE
   996                              <1> 	;
   997                              <1> p41:			; wait for horizontal retrace is low or vertical
   998 0000178F FB                  <1> 	sti		; enable interrupts first
   999 00001790 3A1D[18A80000]      <1>         cmp     bl, [ACTIVE_PAGE]
  1000 00001796 7510                <1> 	jne	short p44 
  1001 00001798 FA                  <1> 	cli 		; block interrupts for single loop
  1002 00001799 EC                  <1> 	in	al, dx	; get status from the adapter
  1003 0000179A A808                <1> 	test	al, RVRT ; check for vertical retrace first
  1004 0000179C 7509                <1> 	jnz	short p43 ; Do fast write now if vertical retrace
  1005 0000179E A801                <1> 	test	al, RHRZ ; is horizontal retrace low
  1006 000017A0 75ED                <1> 	jnz	short p41 ; wait until it is
  1007                              <1> p42:			;  wait for either retrace high
  1008 000017A2 EC                  <1> 	in	al, dx ; get status again
  1009 000017A3 A809                <1> 	test	al, RVRT+RHRZ ; is horizontal or vertical retrace high
  1010 000017A5 74FB                <1> 	jz	short p42 ; wait until either retrace active
  1011                              <1> p43:	
  1012 000017A7 FB                  <1> 	sti
  1013                              <1> p44:
  1014 000017A8 6658                <1> 	pop	ax	; restore the character (al) & attribute (ah)
  1015 000017AA 81C600800B00        <1> 	add	esi, 0B8000h ; 30/08/2014 (crt_base) 
  1016                              <1> 				; Retro UNIX 386 v1 feature only!
  1017 000017B0 668906              <1> 	mov	[esi], ax
  1018 000017B3 665A                <1> 	pop	dx
  1019 000017B5 C3                  <1> 	retn
  1020                              <1> 
  1021                              <1> ; 18/01/2016
  1022                              <1> ; 16/01/2016
  1023                              <1> ; 30/06/2015
  1024                              <1> ; 27/06/2015
  1025                              <1> ; 11/03/2015
  1026                              <1> ; 02/09/2014
  1027                              <1> ; 30/08/2014
  1028                              <1> ; VIDEO FUNCTIONS
  1029                              <1> ; (write_tty - Retro UNIX 8086 v1 - U9.ASM, 01/02/2014)
  1030                              <1> 
  1031                              <1> WRITE_TTY:
  1032                              <1> 	; 30/01/2016
  1033                              <1> 	; 18/01/2016
  1034                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
  1035                              <1> 	; 13/08/2015
  1036                              <1> 	; 02/09/2014
  1037                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  1038                              <1> 	; 01/02/2014 (Retro UNIX 8086 v1 - last update)
  1039                              <1> 	; 03/12/2013 (Retro UNIX 8086 v1 - beginning)	
  1040                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
  1041                              <1> 	;
  1042                              <1> 	; INPUT -> AH = Color (Forecolor, Backcolor)
  1043                              <1> 	;	   AL = Character to be written
  1044                              <1> 	;	   EBX = Video Page (0 to 7)
  1045                              <1> 	;	   (BH = 0 --> Video Mode 3)
  1046                              <1> 
  1047                              <1> RVRT	equ	00001000b	; VIDEO VERTICAL RETRACE BIT
  1048                              <1> RHRZ	equ	00000001b	; VIDEO HORIZONTAL RETRACE BIT
  1049                              <1> 
  1050                              <1> ; Derived from "WRITE_TTY" procedure of IBM "pc-at" rombios source code
  1051                              <1> ; (06/10/1985), 'video.asm', INT 10H, VIDEO_IO
  1052                              <1> ;
  1053                              <1> ; 06/10/85  VIDEO DISPLAY BIOS
  1054                              <1> ;
  1055                              <1> ;--- WRITE_TTY ------------------------------------------------------------------
  1056                              <1> ;										:
  1057                              <1> ;   THIS INTERFACE PROVIDES A TELETYPE LIKE INTERFACE TO THE			:
  1058                              <1> ;   VIDEO CARDS. THE INPUT CHARACTER IS WRITTEN TO THE CURRENT			:
  1059                              <1> ;   CURSOR POSITION, AND THE CURSOR IS MOVED TO THE NEXT POSITION.		:
  1060                              <1> ;   IF THE CURSOR LEAVES THE LAST COLUMN OF THE FIELD, THE COLUMN		:
  1061                              <1> ;   IS SET TO ZERO, AND THE ROW VALUE IS INCREMENTED. IF THE ROW		:
  1062                              <1> ;   ROW VALUE LEAVES THE FIELD, THE CURSOR IS PLACED ON THE LAST ROW,		:
  1063                              <1> ;   FIRST COLUMN, AND THE ENTIRE SCREEN IS SCROLLED UP ONE LINE.		:
  1064                              <1> ;   WHEN THE SCREEN IS SCROLLED UP, THE ATTRIBUTE FOR FILLING THE		:
  1065                              <1> ;   NEWLY BLANKED LINE IS READ FROM THE CURSOR POSITION ON THE PREVIOUS		:
  1066                              <1> ;   LINE BEFORE THE SCROLL, IN CHARACTER MODE. IN GRAPHICS MODE,		:
  1067                              <1> ;   THE 0 COLOR IS USED.							:
  1068                              <1> ;   ENTRY --									:
  1069                              <1> ;     (AH) = CURRENT CRT MODE							:
  1070                              <1> ;     (AL) = CHARACTER TO BE WRITTEN						:
  1071                              <1> ;	    NOTE THAT BACK SPACE, CARRIAGE RETURN, BELL AND LINE FEED ARE	:
  1072                              <1> ;	    HANDLED AS COMMANDS RATHER THAN AS DISPLAY GRAPHICS CHARACTERS	:
  1073                              <1> ;     (BL) = FOREGROUND COLOR FOR CHAR WRITE IF CURRENTLY IN A GRAPHICS MODE	:
  1074                              <1> ;   EXIT -- 									:
  1075                              <1> ;     ALL REGISTERS SAVED							:
  1076                              <1> ;--------------------------------------------------------------------------------
  1077                              <1> 
  1078 000017B6 FA                  <1> 	cli
  1079                              <1> 	;
  1080                              <1> 	; READ CURSOR (04/12/2013)
  1081                              <1> 	; Retro UNIX 386 v1 Modifications: 30/08/2014
  1082 000017B7 08FF                <1> 	or	bh, bh
  1083 000017B9 0F85D5000000        <1> 	jnz	beeper
  1084                              <1> 	; 01/09/2014
  1085 000017BF 803D[16A20000]03    <1> 	cmp	byte [CRT_MODE], 3
  1086 000017C6 7405                <1> 	je	short m3
  1087                              <1> 	;
  1088 000017C8 E8FBFCFFFF          <1> 	call	set_mode_3 ; 16/01/2016
  1089                              <1> m3:
  1090 000017CD 89DE                <1> 	mov 	esi, ebx ; 13/08/2015 (0 to 7)
  1091 000017CF 66D1E6              <1> 	shl	si, 1
  1092 000017D2 81C6[08A80000]      <1> 	add	esi, CURSOR_POSN
  1093 000017D8 668B16              <1> 	mov	dx, [esi]
  1094                              <1> 	;
  1095                              <1> 	; dx now has the current cursor position
  1096                              <1> 	;
  1097 000017DB 3C0D                <1> 	cmp	al, 0Dh		; is it carriage return or control character
  1098 000017DD 762F                <1> 	jbe	short u8
  1099                              <1> 	;
  1100                              <1> 	; write the char to the screen
  1101                              <1> u0:	
  1102                              <1> 	; ah = attribute/color
  1103                              <1> 	; al = character
  1104                              <1> 	; bl = video page number (0 to 7)
  1105                              <1> 	; bh = 0
  1106                              <1> 	;
  1107 000017DF E8A1FFFFFF          <1> 	call	_write_c_current ; 16/01/2015
  1108                              <1> 	;
  1109                              <1> 	; position the cursor for next char
  1110 000017E4 FEC2                <1> 	inc	dl		; next column
  1111                              <1> 	;cmp	dl, [CRT_COLS]
  1112 000017E6 80FA50              <1> 	cmp	dl, 80		; test for column overflow 
  1113 000017E9 755F                <1>         jne     _set_cpos
  1114 000017EB B200                <1> 	mov	dl, 0		; column = 0
  1115                              <1> u10:				; (line feed found)
  1116 000017ED 80FE18              <1> 	cmp	dh, 25-1 	; check for last row
  1117 000017F0 7218                <1> 	jb 	short u6
  1118                              <1> 	;
  1119                              <1> 	; scroll required
  1120                              <1> u1:	
  1121                              <1> 	; SET CURSOR POSITION (04/12/2013)
  1122 000017F2 E853000000          <1> 	call	_set_cpos
  1123                              <1> 	;
  1124                              <1> 	; determine value to fill with during scroll
  1125                              <1> u2:
  1126                              <1> 	; bl = video page number
  1127                              <1> 	;
  1128 000017F7 E83FFFFFFF          <1> 	call _read_ac_current ; 18/01/2016
  1129                              <1> 	;
  1130                              <1> 	; al = character, ah = attribute
  1131                              <1> 	; bl = video page number 	
  1132                              <1> u3:
  1133                              <1> 	;;mov	ax, 0601h 	; scroll one line
  1134                              <1> 	;;sub	cx, cx		; upper left corner
  1135                              <1> 	;;mov	dh, 25-1 	; lower right row
  1136                              <1> 	;;;mov	dl, [CRT_COLS]
  1137                              <1> 	;mov	dl, 80		; lower right column	
  1138                              <1> 	;;dec	dl
  1139                              <1> 	;;mov	dl, 79
  1140                              <1> 
  1141                              <1> 	;;call	scroll_up	; 04/12/2013
  1142                              <1> 	;;; 11/03/2015
  1143                              <1> 	; 02/09/2014
  1144                              <1> 	;;;mov	cx, [crt_ulc] ; Upper left corner  (0000h)
  1145                              <1> 	;;;mov	dx, [crt_lrc] ; Lower right corner (184Fh)
  1146                              <1> 	; 11/03/2015
  1147 000017FC 6629C9              <1> 	sub	cx, cx
  1148 000017FF 66BA4F18            <1> 	mov	dx, 184Fh ; dl = 79 (column), dh = 24 (row)
  1149                              <1> 	;
  1150 00001803 B001                <1> 	mov	al, 1		; scroll 1 line up
  1151                              <1> 		; ah = attribute
  1152 00001805 E902FEFFFF          <1> 	jmp	_scroll_up	; 16/01/2016
  1153                              <1> ;u4:
  1154                              <1> 	;;int	10h		; video-call return
  1155                              <1> 				; scroll up the screen
  1156                              <1> 				; tty return
  1157                              <1> ;u5:
  1158                              <1> 	;retn			; return to the caller
  1159                              <1> 
  1160                              <1> u6:				; set-cursor-inc
  1161 0000180A FEC6                <1> 	inc	dh		; next row
  1162                              <1> 				; set cursor
  1163                              <1> ;u7:					
  1164                              <1> 	;;mov	ah, 02h
  1165                              <1> 	;;jmp	short u4 	; establish the new cursor
  1166                              <1> 	;call	_set_cpos
  1167                              <1> 	;jmp 	short u5
  1168 0000180C EB3C                <1> 	jmp     _set_cpos
  1169                              <1> 
  1170                              <1> 	; check for control characters
  1171                              <1> u8:
  1172 0000180E 7438                <1> 	je	short u9
  1173 00001810 3C0A                <1> 	cmp	al, 0Ah		; is it a line feed (0Ah)
  1174 00001812 74D9                <1> 	je	short u10
  1175 00001814 3C07                <1> 	cmp	al, 07h 	; is it a bell
  1176 00001816 747C                <1> 	je	short u11
  1177 00001818 3C08                <1> 	cmp	al, 08h		; is it a backspace
  1178                              <1> 	;jne	short u0
  1179 0000181A 7424                <1> 	je	short bs	; 12/12/2013
  1180                              <1> 	; 12/12/2013 (tab stop)
  1181 0000181C 3C09                <1> 	cmp	al, 09h		; is it a tab stop
  1182 0000181E 75BF                <1> 	jne	short u0
  1183 00001820 88D0                <1> 	mov	al, dl
  1184 00001822 6698                <1> 	cbw
  1185 00001824 B108                <1> 	mov	cl, 8
  1186 00001826 F6F1                <1> 	div	cl
  1187 00001828 28E1                <1> 	sub	cl, ah
  1188                              <1> ts:
  1189                              <1> 	; 02/09/2014
  1190                              <1> 	; 01/09/2014
  1191 0000182A B020                <1> 	mov	al, 20h
  1192                              <1> tsloop:
  1193 0000182C 6651                <1> 	push	cx
  1194 0000182E 6650                <1> 	push	ax
  1195 00001830 30FF                <1> 	xor 	bh, bh
  1196                              <1> 	;mov	bl, [ACTIVE_PAGE]
  1197 00001832 E896FFFFFF          <1> 	call	m3
  1198 00001837 6658                <1> 	pop	ax  ; ah = attribute/color
  1199 00001839 6659                <1> 	pop	cx
  1200 0000183B FEC9                <1> 	dec	cl
  1201 0000183D 75ED                <1> 	jnz	short tsloop
  1202 0000183F C3                  <1> 	retn
  1203                              <1> bs:	
  1204                              <1> 	; back space found
  1205                              <1> 
  1206 00001840 08D2                <1> 	or	dl, dl 		; is it already at start of line
  1207                              <1> 	;je	short u7 	; set_cursor
  1208 00001842 7406                <1> 	jz	short _set_cpos
  1209 00001844 664A                <1> 	dec	dx     		; no -- just move it back
  1210                              <1> 	;jmp	short u7
  1211 00001846 EB02                <1> 	jmp	short _set_cpos
  1212                              <1> 
  1213                              <1> 	; carriage return found
  1214                              <1> u9:
  1215 00001848 B200                <1> 	mov	dl, 0 		; move to first column
  1216                              <1> 	;jmp	short u7
  1217                              <1> 	;jmp	short _set_cpos ; 30/01/2016
  1218                              <1> 
  1219                              <1> 	; line feed found
  1220                              <1> ;u10:
  1221                              <1> ;	cmp	dh, 25-1 	; bottom of screen
  1222                              <1> ;	jne	short u6 	; no, just set the cursor
  1223                              <1> ;       jmp     u1              ; yes, scroll the screen
  1224                              <1> 
  1225                              <1> _set_cpos:
  1226                              <1> 	; 27/06/2015
  1227                              <1> 	; 01/09/2014
  1228                              <1> 	; 30/08/2014 (Retro UNIX 386 v1 - beginning)
  1229                              <1> 	;
  1230                              <1> 	; 12/12/2013 (Retro UNIX 8086 v1 - last update) 
  1231                              <1> 	; 04/12/2013 (Retro UNIX 8086 v1 - beginning)
  1232                              <1> 	;
  1233                              <1> 	; VIDEO.ASM - 06/10/85  VIDEO DISPLAY BIOS
  1234                              <1> 	;
  1235                              <1> ;----------------------------------------------
  1236                              <1> ; SET_CPOS
  1237                              <1> ;	THIS ROUTINE SETS THE CURRENT CURSOR POSITION TO THE
  1238                              <1> ;	NEW X-Y VALUES PASSED
  1239                              <1> ; INPUT
  1240                              <1> ;	DX - ROW,COLUMN OF NEW CURSOR
  1241                              <1> ;	BH - DISPLAY PAGE OF CURSOR
  1242                              <1> ; OUTPUT
  1243                              <1> ;	CURSOR ID SET AT 6845 IF DISPLAY PAGE IS CURRENT DISPLAY
  1244                              <1> ;----------------------------------------------
  1245                              <1> 	;
  1246 0000184A BE[08A80000]        <1> 	mov	esi, CURSOR_POSN
  1247 0000184F 0FB6C3              <1>         movzx   eax, bl	; BL = video page number ; 27/06/2015 (movzx)
  1248                              <1> ;	or	al, al
  1249                              <1> ;	jz	short _set_cpos_0
  1250 00001852 D0E0                <1>         shl     al, 1   ; word offset
  1251 00001854 01C6                <1>         add     esi, eax
  1252                              <1> ;_set_cpos_0:
  1253 00001856 668916              <1> 	mov	[esi], dx ; save the pointer
  1254 00001859 381D[18A80000]      <1> 	cmp	[ACTIVE_PAGE], bl
  1255 0000185F 7532                <1> 	jne	short m17
  1256                              <1> 	;call	m18	; CURSOR SET
  1257                              <1> ;m17:			; SET_CPOS_RETURN
  1258                              <1> 	; 01/09/2014
  1259                              <1> ;	retn
  1260                              <1> 		; DX  = row/column
  1261                              <1> m18:
  1262 00001861 E861FDFFFF          <1> 	call	position ; determine location in regen buffer	
  1263 00001866 668B0D[04A80000]    <1> 	mov	cx, [CRT_START]
  1264 0000186D 6601C1              <1> 	add	cx, ax  ; add char position in regen buffer
  1265                              <1> 			; to the start address (offset) for this page
  1266 00001870 66D1E9              <1> 	shr	cx, 1	; divide by 2 for char only count
  1267 00001873 B40E                <1> 	mov	ah, 14	; register number for cursor
  1268                              <1> 	;call	m16	; output value to the 6845	
  1269                              <1> 	;retn
  1270                              <1> 
  1271                              <1> 	;-----	THIS ROUTINE OUTPUTS THE CX REGISTER
  1272                              <1> 	;	TO THE 6845 REGISTERS NAMED IN (AH)
  1273                              <1> m16:
  1274 00001875 FA                  <1> 	cli
  1275                              <1> 	;mov	dx, [addr_6845] ; address register
  1276 00001876 66BAD403            <1> 	mov 	dx, 03D4h ; I/O address of color card
  1277 0000187A 88E0                <1> 	mov	al, ah	; get value
  1278 0000187C EE                  <1> 	out	dx, al	; register set
  1279 0000187D 6642                <1> 	inc	dx	; data register
  1280 0000187F EB00                <1> 	jmp	$+2	; i/o delay
  1281 00001881 88E8                <1> 	mov	al, ch	; data
  1282 00001883 EE                  <1> 	out	dx, al	
  1283 00001884 664A                <1> 	dec	dx	
  1284 00001886 88E0                <1> 	mov	al, ah
  1285 00001888 FEC0                <1> 	inc	al	; point to other data register
  1286 0000188A EE                  <1> 	out	dx, al	; set for second register
  1287 0000188B 6642                <1> 	inc	dx
  1288 0000188D EB00                <1> 	jmp	$+2	; i/o delay
  1289 0000188F 88C8                <1> 	mov	al, cl	; second data value
  1290 00001891 EE                  <1> 	out	dx, al
  1291 00001892 FB                  <1> 	sti
  1292                              <1> m17:
  1293 00001893 C3                  <1> 	retn
  1294                              <1> 
  1295                              <1> beeper: 
  1296                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1297                              <1> 	; 18/01/2014
  1298                              <1> 	; 03/12/2013
  1299                              <1> 	; bell found
  1300                              <1> u11:
  1301 00001894 FB                  <1> 	sti
  1302 00001895 3A1D[18A80000]      <1> 	cmp	bl, [ACTIVE_PAGE]
  1303 0000189B 7551                <1> 	jne	short u12	; Do not sound the beep 
  1304                              <1> 				; if it is not written on the active page
  1305 0000189D 66B93305            <1> 	mov	cx, 1331 	; divisor for 896 hz tone
  1306 000018A1 B31F                <1> 	mov	bl, 31		; set count for 31/64 second for beep
  1307                              <1> 	;call	beep		; sound the pod bell
  1308                              <1> 	;jmp	short u5 	; tty_return
  1309                              <1> 	;retn
  1310                              <1> 	
  1311                              <1> TIMER	equ 	040h   		; 8254 TIMER - BASE ADDRESS
  1312                              <1> PORT_B	equ	061h		; PORT B READ/WRITE DIAGNOSTIC REGISTER
  1313                              <1> GATE2	equ	00000001b	; TIMER 2 INPUT CATE CLOCK BIT
  1314                              <1> SPK2	equ	00000010b	; SPEAKER OUTPUT DATA ENABLE BIT
  1315                              <1> 
  1316                              <1> beep:
  1317                              <1> 	; 07/02/2015
  1318                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1319                              <1> 	; 18/01/2014
  1320                              <1> 	; 03/12/2013
  1321                              <1> 	;
  1322                              <1> 	; TEST4.ASM - 06/10/85  POST AND BIOS UTILITY ROUTINES
  1323                              <1> 	;
  1324                              <1> 	; ROUTINE TO SOUND THE BEEPER USING TIMER 2 FOR TONE
  1325                              <1> 	;
  1326                              <1> 	; ENTRY:
  1327                              <1> 	;    (BL) = DURATION COUNTER ( 1 FOR 1/64 SECOND )
  1328                              <1> 	;    (CX) = FREQUENCY DIVISOR (1193180/FREQUENCY) (1331 FOR 886 HZ)
  1329                              <1> 	; EXIT:				:
  1330                              <1> 	;    (AX),(BL),(CX) MODIFIED.
  1331                              <1> 
  1332 000018A3 9C                  <1> 	pushf  ; 18/01/2014	; save interrupt status
  1333 000018A4 FA                  <1> 	cli			; block interrupts during update
  1334 000018A5 B0B6                <1> 	mov	al, 10110110b	; select timer 2, lsb, msb binary
  1335 000018A7 E643                <1> 	out	TIMER+3, al 	; write timer mode register
  1336 000018A9 EB00                <1> 	jmp	$+2		; I/O delay
  1337 000018AB 88C8                <1> 	mov	al, cl		; divisor for hz (low)
  1338 000018AD E642                <1> 	out	TIMER+2,AL	; write timer 2 count - lsb
  1339 000018AF EB00                <1> 	jmp	$+2		; I/O delay
  1340 000018B1 88E8                <1> 	mov	al, ch		; divisor for hz (high)
  1341 000018B3 E642                <1> 	out	TIMER+2, al	; write timer 2 count - msb
  1342 000018B5 E461                <1> 	in	al, PORT_B	; get current setting of port
  1343 000018B7 88C4                <1> 	mov	ah, al		; save that setting
  1344 000018B9 0C03                <1> 	or	al, GATE2+SPK2	; gate timer 2 and turn speaker on
  1345 000018BB E661                <1> 	out	PORT_B, al	; and restore interrupt status
  1346                              <1> 	;popf	; 18/01/2014
  1347 000018BD FB                  <1> 	sti
  1348                              <1> g7:				; 1/64 second per count (bl)
  1349 000018BE B90B040000          <1> 	mov	ecx, 1035	; delay count for 1/64 of a second	
  1350 000018C3 E827000000          <1> 	call	waitf		; go to beep delay 1/64 count
  1351 000018C8 FECB                <1> 	dec	bl		; (bl) length count expired?
  1352 000018CA 75F2                <1> 	jnz	short g7	; no - continue beeping speaker
  1353                              <1> 	;
  1354                              <1> 	;pushf			; save interrupt status
  1355 000018CC FA                  <1> 	cli  	; 18/01/2014	; block interrupts during update
  1356 000018CD E461                <1> 	in	al, PORT_B	; get current port value
  1357                              <1>         ;or      al, not (GATE2+SPK2) ; isolate current speaker bits in case
  1358 000018CF 0CFC                <1>         or      al, ~(GATE2+SPK2)
  1359 000018D1 20C4                <1>         and	ah, al		; someone turned them off during beep
  1360 000018D3 88E0                <1> 	mov	al, ah		; recover value of port
  1361                              <1>         ;or      al, not (GATE2+SPK2) ; force speaker data off
  1362 000018D5 0CFC                <1> 	or 	al, ~(GATE2+SPK2) ; isolate current speaker bits in case
  1363 000018D7 E661                <1> 	out	PORT_B, al	; and stop speaker timer
  1364                              <1> 	;popf			; restore interrupt flag state
  1365 000018D9 FB                  <1> 	sti
  1366 000018DA B90B040000          <1> 	mov	ecx, 1035	; force 1/64 second delay (short)
  1367 000018DF E80B000000          <1> 	call	waitf		; minimum delay between all beeps
  1368                              <1> 	;pushf			; save interrupt status
  1369 000018E4 FA                  <1> 	cli			; block interrupts during update
  1370 000018E5 E461                <1> 	in	al, PORT_B	; get current port value in case	
  1371 000018E7 2403                <1> 	and	al, GATE2+SPK2	; someone turned them on
  1372 000018E9 08E0                <1> 	or	al, ah		; recover value of port_b
  1373 000018EB E661                <1> 	out	PORT_B, al	; restore speaker status
  1374 000018ED 9D                  <1> 	popf			; restore interrupt flag state
  1375                              <1> u12:	
  1376 000018EE C3                  <1> 	retn
  1377                              <1> 
  1378                              <1> REFRESH_BIT equ	00010000b 	; REFRESH TEST BIT
  1379                              <1> 
  1380                              <1> WAITF:
  1381                              <1> waitf:
  1382                              <1> 	; 30/08/2014 (Retro UNIX 386 v1)
  1383                              <1> 	; 03/12/2013
  1384                              <1> 	;
  1385                              <1> ;	push ax			; save work register (ah)	
  1386                              <1> ;waitf1:
  1387                              <1> 				; use timer 1 output bits
  1388                              <1> ;	in	al, PORT_B	; read current counter output status
  1389                              <1> ;	and	al, REFRESH_BIT	; mask for refresh determine bit
  1390                              <1> ;	cmp	al, ah		; did it just change
  1391                              <1> ;	je	short waitf1	; wait for a change in output line
  1392                              <1> ;	;
  1393                              <1> ;	mov	ah, al		; save new lflag state
  1394                              <1> ;	loop	waitf1		; decrement half cycles till count end		
  1395                              <1> ;	;
  1396                              <1> ;	pop	ax		; restore (ah)
  1397                              <1> ;	retn			; return (cx)=0
  1398                              <1> 
  1399                              <1> ; 06/02/2015 (unix386.s <-- dsectrm2.s)
  1400                              <1> ; 17/12/2014 (dsectrm2.s)
  1401                              <1> ; WAITF
  1402                              <1> ; /// IBM PC-XT Model 286 System BIOS Source Code - Test 4 - 06/10/85 ///
  1403                              <1> ;
  1404                              <1> ;---WAITF-----------------------------------------------------------------------
  1405                              <1> ;	FIXED TIME WAIT ROUTINE (HARDWARE CONTROLLED - NOT PROCESSOR)
  1406                              <1> ; ENTRY:
  1407                              <1> ;	(CX) =	COUNT OF 15.085737 MICROSECOND INTERVALS TO WAIT
  1408                              <1> ;	      	MEMORY REFRESH TIMER 1 OUTPUT USED AS REFERENCE
  1409                              <1> ; EXIT:
  1410                              <1> ;	       	AFTER (CX) TIME COUNT (PLUS OR MINUS 16 MICROSECONDS)
  1411                              <1> ;	(CX) = 0	
  1412                              <1> ;-------------------------------------------------------------------------------
  1413                              <1> 
  1414                              <1> ; Refresh period: 30 micro seconds (15-80 us)
  1415                              <1> ; (16/12/2014 - AWARDBIOS 1999 - ATORGS.ASM, WAIT_REFRESH)
  1416                              <1> 
  1417                              <1> ;WAITF:					; DELAY FOR (CX)*15.085737 US
  1418 000018EF 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER (AH)
  1419                              <1> 	; 16/12/2014
  1420                              <1> 	;shr	cx, 1			; convert to count of 30 micro seconds
  1421 000018F1 D1E9                <1> 	shr	ecx, 1	; 21/02/2015
  1422                              <1> ;17/12/2014	
  1423                              <1> ;WAITF1:
  1424                              <1> ;	IN	AL, PORT_B   ;061h	; READ CURRENT COUNTER OUTPUT STATUS
  1425                              <1> ;	AND	AL, REFRESH_BIT	;00010000b ; MASK FOR REFRESH DETERMINE BIT
  1426                              <1> ;	CMP	AL, AH			; DID IT JUST CHANGE
  1427                              <1> ;	JE	short WAITF1		; WAIT FOR A CHANGE IN OUTPUT LINE
  1428                              <1> ;	MOV	AH, AL			; SAVE NEW FLAG STATE
  1429                              <1> ;	LOOP	WAITF1			; DECREMENT HALF CYCLES TILL COUNT END		
  1430                              <1> 	;
  1431                              <1> 	; 17/12/2014
  1432                              <1> 	;
  1433                              <1> 	; Modification from 'WAIT_REFRESH' procedure of AWARD BIOS - 1999
  1434                              <1> 	;
  1435                              <1> ;WAIT_REFRESH:  Uses port 61, bit 4 to have CPU speed independent waiting.
  1436                              <1> ;   	INPUT:  CX = number of refresh periods to wait
  1437                              <1> ;     	       (refresh periods = 1 per 30 microseconds on most machines)
  1438                              <1> WR_STATE_0:
  1439 000018F3 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  1440 000018F5 A810                <1> 	TEST	AL,010H
  1441 000018F7 74FA                <1> 	JZ	SHORT WR_STATE_0
  1442                              <1> WR_STATE_1:
  1443 000018F9 E461                <1> 	IN	AL,PORT_B		; IN AL,SYS1
  1444 000018FB A810                <1> 	TEST	AL,010H
  1445 000018FD 75FA                <1> 	JNZ	SHORT WR_STATE_1
  1446 000018FF E2F2                <1>         LOOP    WR_STATE_0
  1447                              <1> 	;
  1448 00001901 6658                <1> 	POP	AX			; RESTORE (AH)
  1449 00001903 C3                  <1> 	RETn				; (CX) = 0
  1450                              <1> 
  1451                              <1> ; % include 'vidata.s' ; VIDEO DATA
  1452                              <1> 
  1453                              <1> ; /// End Of VIDEO FUNCTIONS ///
  1692                                  
  1693                                  setup_rtc_int:
  1694                                  ; source: http://wiki.osdev.org/RTC
  1695 00001904 FA                      	cli		; disable interrupts
  1696                                  	; default int frequency is 1024 Hz (Lower 4 bits of register A is 0110b or 6)
  1697                                  	; in order to change this ...
  1698                                  	; frequency  = 32768 >> (rate-1) --> 32768 >> 5 = 1024
  1699                                  	; (rate must be above 2 and not over 15)
  1700                                  	; new rate = 15 --> 32768 >> (15-1) = 2 Hz
  1701 00001905 B08A                    	mov	al, 8Ah 
  1702 00001907 E670                    	out	70h, al ; set index to register A, disable NMI
  1703 00001909 90                      	nop
  1704 0000190A E471                    	in	al, 71h ; get initial value of register A
  1705 0000190C 88C4                    	mov 	ah, al
  1706 0000190E 80E4F0                  	and	ah, 0F0h
  1707 00001911 B08A                    	mov	al, 8Ah 
  1708 00001913 E670                    	out	70h, al ; reset index to register A
  1709 00001915 88E0                    	mov	al, ah
  1710 00001917 0C0F                    	or	al, 0Fh	; new rate (0Fh -> 15)
  1711 00001919 E671                    	out	71h, al ; write only our rate to A. Note, rate is the bottom 4 bits. 
  1712                                  	; enable RTC interrupt
  1713 0000191B B08B                    	mov	al, 8Bh ;
  1714 0000191D E670                    	out	70h, al ; select register B and disable NMI
  1715 0000191F 90                      	nop
  1716 00001920 E471                    	in	al, 71h ; read the current value of register B
  1717 00001922 88C4                    	mov	ah, al  ;
  1718 00001924 B08B                    	mov 	al, 8Bh ;
  1719 00001926 E670                    	out	70h, al ; set the index again (a read will reset the index to register B)	
  1720 00001928 88E0                    	mov	al, ah  ;
  1721 0000192A 0C40                    	or	al, 40h ;
  1722 0000192C E671                    	out	71h, al ; write the previous value ORed with 0x40. This turns on bit 6 of register B
  1723 0000192E FB                      	sti
  1724 0000192F C3                      	retn
  1725                                  
  1726                                  ; Write memory information
  1727                                  ; 29/01/2016
  1728                                  ; 06/11/2014
  1729                                  ; 14/08/2015 
  1730                                  memory_info:	
  1731 00001930 A1[ECA70000]            	mov	eax, [memory_size] ; in pages
  1732 00001935 50                      	push	eax
  1733 00001936 C1E00C                  	shl	eax, 12		   ; in bytes
  1734 00001939 BB0A000000              	mov	ebx, 10
  1735 0000193E 89D9                    	mov	ecx, ebx	   ; 10
  1736 00001940 BE[37A40000]            	mov	esi, mem_total_b_str	
  1737 00001945 E8BE000000              	call	bintdstr
  1738 0000194A 58                      	pop	eax
  1739 0000194B B107                    	mov	cl, 7
  1740 0000194D BE[5BA40000]            	mov	esi, mem_total_p_str
  1741 00001952 E8B1000000              	call	bintdstr	
  1742                                  	; 14/08/2015
  1743 00001957 E8C9000000              	call	calc_free_mem
  1744                                  	; edx = calculated free pages
  1745                                  	; ecx = 0
  1746 0000195C A1[F0A70000]            	mov 	eax, [free_pages]
  1747 00001961 39D0                    	cmp	eax, edx ; calculated free mem value 
  1748                                  		; and initial free mem value are same or not?
  1749 00001963 751D                    	jne 	short pmim ; print mem info with '?' if not
  1750 00001965 52                      	push 	edx ; free memory in pages	
  1751                                  	;mov 	eax, edx
  1752 00001966 C1E00C                  	shl	eax, 12 ; convert page count
  1753                                  			; to byte count
  1754 00001969 B10A                    	mov	cl, 10
  1755 0000196B BE[7BA40000]            	mov	esi, free_mem_b_str
  1756 00001970 E893000000              	call	bintdstr
  1757 00001975 58                      	pop	eax
  1758 00001976 B107                    	mov	cl, 7
  1759 00001978 BE[9FA40000]            	mov	esi, free_mem_p_str
  1760 0000197D E886000000              	call	bintdstr
  1761                                  pmim:
  1762 00001982 BE[25A40000]            	mov	esi, msg_memory_info
  1763                                  	;
  1764 00001987 B407                    	mov	ah, 07h ; Black background, 
  1765                                  			; light gray forecolor
  1766                                  print_kmsg: ; 29/01/2016
  1767 00001989 8825[19A80000]          	mov	[ccolor], ah
  1768                                  pkmsg_loop:
  1769 0000198F AC                      	lodsb
  1770 00001990 08C0                    	or	al, al
  1771 00001992 7411                    	jz	short pkmsg_ok
  1772 00001994 56                      	push	esi
  1773 00001995 31DB                    	xor	ebx, ebx ; 0
  1774                                  			; Video page 0 (bl=0)
  1775 00001997 8A25[19A80000]          	mov	ah, [ccolor]
  1776 0000199D E814FEFFFF              	call	WRITE_TTY
  1777 000019A2 5E                      	pop	esi
  1778 000019A3 EBEA                    	jmp	short pkmsg_loop
  1779                                  pkmsg_ok:
  1780 000019A5 C3                      	retn
  1781                                  
  1782                                  ; Convert binary number to hexadecimal string
  1783                                  ; 10/05/2015  
  1784                                  ; dsectpm.s (28/02/2015)
  1785                                  ; Retro UNIX 386 v1 - Kernel v0.2.0.6  
  1786                                  ; 01/12/2014
  1787                                  ; 25/11/2014
  1788                                  ;
  1789                                  bytetohex:
  1790                                  	; INPUT ->
  1791                                  	; 	AL = byte (binary number)
  1792                                  	; OUTPUT ->
  1793                                  	;	AX = hexadecimal string
  1794                                  	;
  1795 000019A6 53                      	push	ebx
  1796 000019A7 31DB                    	xor	ebx, ebx
  1797 000019A9 88C3                    	mov	bl, al
  1798 000019AB C0EB04                  	shr	bl, 4
  1799 000019AE 8A9B[F8190000]          	mov	bl, [ebx+hexchrs] 	 	
  1800 000019B4 86D8                    	xchg	bl, al
  1801 000019B6 80E30F                  	and	bl, 0Fh
  1802 000019B9 8AA3[F8190000]          	mov	ah, [ebx+hexchrs] 
  1803 000019BF 5B                      	pop	ebx	
  1804 000019C0 C3                      	retn
  1805                                  
  1806                                  wordtohex:
  1807                                  	; INPUT ->
  1808                                  	; 	AX = word (binary number)
  1809                                  	; OUTPUT ->
  1810                                  	;	EAX = hexadecimal string
  1811                                  	;
  1812 000019C1 53                      	push	ebx
  1813 000019C2 31DB                    	xor	ebx, ebx
  1814 000019C4 86E0                    	xchg	ah, al
  1815 000019C6 6650                    	push	ax
  1816 000019C8 88E3                    	mov	bl, ah
  1817 000019CA C0EB04                  	shr	bl, 4
  1818 000019CD 8A83[F8190000]          	mov	al, [ebx+hexchrs] 	 	
  1819 000019D3 88E3                    	mov	bl, ah
  1820 000019D5 80E30F                  	and	bl, 0Fh
  1821 000019D8 8AA3[F8190000]          	mov	ah, [ebx+hexchrs]
  1822 000019DE C1E010                  	shl	eax, 16
  1823 000019E1 6658                    	pop	ax
  1824 000019E3 5B                      	pop	ebx
  1825 000019E4 EBC0                    	jmp	short bytetohex
  1826                                  	;mov	bl, al
  1827                                  	;shr	bl, 4
  1828                                  	;mov	bl, [ebx+hexchrs] 	 	
  1829                                  	;xchg	bl, al	 	
  1830                                  	;and	bl, 0Fh
  1831                                  	;mov	ah, [ebx+hexchrs] 
  1832                                  	;pop	ebx	
  1833                                  	;retn
  1834                                  
  1835                                  dwordtohex:
  1836                                  	; INPUT ->
  1837                                  	; 	EAX = dword (binary number)
  1838                                  	; OUTPUT ->
  1839                                  	;	EDX:EAX = hexadecimal string
  1840                                  	;
  1841 000019E6 50                      	push	eax
  1842 000019E7 C1E810                  	shr	eax, 16
  1843 000019EA E8D2FFFFFF              	call	wordtohex
  1844 000019EF 89C2                    	mov	edx, eax
  1845 000019F1 58                      	pop	eax
  1846 000019F2 E8CAFFFFFF              	call	wordtohex
  1847 000019F7 C3                      	retn
  1848                                  
  1849                                  ; 10/05/2015
  1850                                  hex_digits:
  1851                                  hexchrs:
  1852 000019F8 303132333435363738-     	db '0123456789ABCDEF'
  1852 00001A01 39414243444546     
  1853                                  
  1854                                  ; Convert binary number to decimal/numeric string
  1855                                  ; 06/11/2014
  1856                                  ; Temporary Code
  1857                                  ;
  1858                                  
  1859                                  bintdstr:
  1860                                  	; EAX = binary number
  1861                                  	; ESI = decimal/numeric string address
  1862                                  	; EBX = divisor (10)
  1863                                  	; ECX = string length (<=10)
  1864 00001A08 01CE                    	add	esi, ecx
  1865                                  btdstr0:
  1866 00001A0A 4E                      	dec	esi
  1867 00001A0B 31D2                    	xor	edx, edx
  1868 00001A0D F7F3                    	div	ebx
  1869 00001A0F 80C230                  	add	dl, 30h
  1870 00001A12 8816                    	mov	[esi], dl
  1871 00001A14 FEC9                    	dec	cl
  1872 00001A16 740C                    	jz	btdstr2
  1873 00001A18 09C0                    	or	eax, eax
  1874 00001A1A 75EE                    	jnz	short btdstr0
  1875                                  btdstr1:
  1876 00001A1C 4E                      	dec	esi
  1877 00001A1D C60620                          mov     byte [esi], 20h ; blank space
  1878 00001A20 FEC9                    	dec	cl
  1879 00001A22 75F8                    	jnz	short btdstr1
  1880                                  btdstr2:
  1881 00001A24 C3                      	retn
  1882                                  
  1883                                  ; Calculate free memory pages on M.A.T.
  1884                                  ; 06/11/2014
  1885                                  ; Temporary Code
  1886                                  ;
  1887                                  
  1888                                  calc_free_mem:
  1889 00001A25 31D2                    	xor	edx, edx
  1890                                  	;xor	ecx, ecx
  1891 00001A27 668B0D[00A80000]        	mov	cx, [mat_size] ; in pages
  1892 00001A2E C1E10A                  	shl	ecx, 10	; 1024 dwords per page
  1893 00001A31 BE00001000              	mov	esi, MEM_ALLOC_TBL
  1894                                  cfm0:
  1895 00001A36 AD                      	lodsd
  1896 00001A37 51                      	push	ecx
  1897 00001A38 B920000000              	mov	ecx, 32
  1898                                  cfm1:
  1899 00001A3D D1E8                    	shr	eax, 1
  1900 00001A3F 7301                    	jnc	short cfm2
  1901 00001A41 42                      	inc	edx
  1902                                  cfm2:
  1903 00001A42 E2F9                    	loop	cfm1
  1904 00001A44 59                      	pop	ecx
  1905 00001A45 E2EF                    	loop	cfm0
  1906 00001A47 C3                      	retn
  1907                                  
  1908                                  %include 'diskio.s'  ; 07/03/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - diskio.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 18/02/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Turkish Rational DOS
    11                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ; 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 00001A48 9C                  <1> 	pushfd
    31 00001A49 0E                  <1> 	push 	cs
    32 00001A4A E809000000          <1> 	call 	DISKETTE_IO_1
    33 00001A4F C3                  <1> 	retn
    34                              <1> 	
    35                              <1> ;;;;;; DISKETTE I/O ;;;;;;;;;;;;;;;;;;;; 06/02/2015 ;;;
    36                              <1> ;//////////////////////////////////////////////////////
    37                              <1> 
    38                              <1> ; DISKETTE I/O - Erdogan Tan (Retro UNIX 386 v1 project)
    39                              <1> ; 20/02/2015
    40                              <1> ; 06/02/2015 (unix386.s)
    41                              <1> ; 16/12/2014 - 02/01/2015 (dsectrm2.s)
    42                              <1> ;
    43                              <1> ; Code (DELAY) modifications - AWARD BIOS 1999 (ADISK.EQU, COMMON.MAC)
    44                              <1> ;
    45                              <1> ; ADISK.EQU
    46                              <1> 
    47                              <1> ;----- Wait control constants 
    48                              <1> 
    49                              <1> ;amount of time to wait while RESET is active.
    50                              <1> 
    51                              <1> WAITCPU_RESET_ON	EQU	21		;Reset on must last at least 14us
    52                              <1> 						;at 250 KBS xfer rate.
    53                              <1> 						;see INTEL MCS, 1985, pg. 5-456
    54                              <1> 
    55                              <1> WAITCPU_FOR_STATUS	EQU	100		;allow 30 microseconds for
    56                              <1> 						;status register to become valid
    57                              <1> 						;before re-reading.
    58                              <1> 
    59                              <1> ;After sending a byte to NEC, status register may remain
    60                              <1> ;incorrectly set for 24 us.
    61                              <1> 
    62                              <1> WAITCPU_RQM_LOW		EQU	24		;number of loops to check for
    63                              <1> 						;RQM low.
    64                              <1> 
    65                              <1> ; COMMON.MAC
    66                              <1> ;
    67                              <1> ;	Timing macros
    68                              <1> ;
    69                              <1> 
    70                              <1> %macro 		SIODELAY 0 			; SHORT IODELAY
    71                              <1> 		jmp short $+2
    72                              <1> %endmacro		
    73                              <1> 
    74                              <1> %macro		IODELAY  0			; NORMAL IODELAY
    75                              <1> 		jmp short $+2
    76                              <1> 		jmp short $+2
    77                              <1> %endmacro
    78                              <1> 
    79                              <1> %macro		NEWIODELAY 0
    80                              <1> 		out	0ebh,al
    81                              <1> %endmacro 
    82                              <1> 
    83                              <1> ; (According to) AWARD BIOS 1999 - ATORGS.ASM (dw -> equ, db -> equ)
    84                              <1> ;;; WAIT_FOR_MEM
    85                              <1> ;WAIT_FDU_INT_LO	equ	017798		; 2.5 secs in 30 micro units.
    86                              <1> ;WAIT_FDU_INT_HI	equ	1
    87                              <1> WAIT_FDU_INT_LH		equ	83334		; 27/02/2015 (2.5 seconds waiting)
    88                              <1> ;;; WAIT_FOR_PORT
    89                              <1> ;WAIT_FDU_SEND_LO	equ	16667		; .5 secons in 30 us units.
    90                              <1> ;WAIT_FDU_SEND_HI	equ	0
    91                              <1> WAIT_FDU_SEND_LH	equ 	16667		; 27/02/2015	
    92                              <1> ;Time to wait while waiting for each byte of NEC results = .5
    93                              <1> ;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
    94                              <1> ;WAIT_FDU_RESULTS_LO	equ	16667		; .5 seconds in 30 micro units.
    95                              <1> ;WAIT_FDU_RESULTS_HI	equ	0
    96                              <1> WAIT_FDU_RESULTS_LH	equ	16667  ; 27/02/2015
    97                              <1> ;;; WAIT_REFRESH
    98                              <1> ;amount of time to wait for head settle, per unit in parameter
    99                              <1> ;table = 1 ms.
   100                              <1> WAIT_FDU_HEAD_SETTLE	equ	33		; 1 ms in 30 micro units.
   101                              <1> 
   102                              <1> 
   103                              <1> ; //////////////// DISKETTE I/O ////////////////
   104                              <1> 
   105                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - POSTEQU.INC)
   106                              <1> 
   107                              <1> ;----------------------------------------
   108                              <1> ;	EQUATES USED BY POST AND BIOS	:
   109                              <1> ;----------------------------------------
   110                              <1> 
   111                              <1> ;--------- 8042 KEYBOARD INTERFACE AND DIAGNOSTIC CONTROL REGISTERS ------------
   112                              <1> ;PORT_A		EQU	060H		; 8042 KEYBOARD SCAN CODE/CONTROL PORT
   113                              <1> ;PORT_B		EQU	061H		; PORT B READ/WRITE DIAGNOSTIC REGISTER
   114                              <1> ;REFRESH_BIT	EQU	00010000B	; REFRESH TEST BIT
   115                              <1> 
   116                              <1> ;----------------------------------------
   117                              <1> ;	CMOS EQUATES FOR THIS SYSTEM	:
   118                              <1> ;-------------------------------------------------------------------------------
   119                              <1> ;CMOS_PORT	EQU	070H		; I/O ADDRESS OF CMOS ADDRESS PORT
   120                              <1> ;CMOS_DATA	EQU	071H		; I/O ADDRESS OF CMOS DATA PORT
   121                              <1> ;NMI		EQU	10000000B	; DISABLE NMI INTERRUPTS MASK -
   122                              <1> 					;  HIGH BIT OF CMOS LOCATION ADDRESS
   123                              <1> 
   124                              <1> ;---------- CMOS TABLE LOCATION ADDRESS'S ## -----------------------------------
   125                              <1> CMOS_DISKETTE	EQU	010H		; DISKETTE DRIVE TYPE BYTE	      ;
   126                              <1> ;		EQU	011H		; - RESERVED			      ;C
   127                              <1> CMOS_DISK	EQU	012H		; FIXED DISK TYPE BYTE		      ;H
   128                              <1> ;		EQU	013H		; - RESERVED			      ;E
   129                              <1> CMOS_EQUIP	EQU	014H		; EQUIPMENT WORD LOW BYTE	      ;C
   130                              <1> 
   131                              <1> ;---------- DISKETTE EQUATES ---------------------------------------------------
   132                              <1> INT_FLAG	EQU	10000000B	; INTERRUPT OCCURRENCE FLAG
   133                              <1> DSK_CHG 	EQU	10000000B	; DISKETTE CHANGE FLAG MASK BIT
   134                              <1> DETERMINED	EQU	00010000B	; SET STATE DETERMINED IN STATE BITS
   135                              <1> HOME		EQU	00010000B	; TRACK 0 MASK
   136                              <1> SENSE_DRV_ST	EQU	00000100B	; SENSE DRIVE STATUS COMMAND
   137                              <1> TRK_SLAP	EQU	030H		; CRASH STOP (48 TPI DRIVES)
   138                              <1> QUIET_SEEK	EQU	00AH		; SEEK TO TRACK 10
   139                              <1> ;MAX_DRV 	EQU	2		; MAX NUMBER OF DRIVES
   140                              <1> HD12_SETTLE	EQU	15		; 1.2 M HEAD SETTLE TIME
   141                              <1> HD320_SETTLE	EQU	20		; 320 K HEAD SETTLE TIME
   142                              <1> MOTOR_WAIT	EQU	37		; 2 SECONDS OF COUNTS FOR MOTOR TURN OFF
   143                              <1> 
   144                              <1> ;---------- DISKETTE ERRORS ----------------------------------------------------
   145                              <1> ;TIME_OUT	EQU	080H		; ATTACHMENT FAILED TO RESPOND
   146                              <1> ;BAD_SEEK	EQU	040H		; SEEK OPERATION FAILED
   147                              <1> BAD_NEC 	EQU	020H		; DISKETTE CONTROLLER HAS FAILED
   148                              <1> BAD_CRC 	EQU	010H		; BAD CRC ON DISKETTE READ
   149                              <1> MED_NOT_FND	EQU	00CH		; MEDIA TYPE NOT FOUND
   150                              <1> DMA_BOUNDARY	EQU	009H		; ATTEMPT TO DMA ACROSS 64K BOUNDARY
   151                              <1> BAD_DMA 	EQU	008H		; DMA OVERRUN ON OPERATION
   152                              <1> MEDIA_CHANGE	EQU	006H		; MEDIA REMOVED ON DUAL ATTACH CARD
   153                              <1> RECORD_NOT_FND	EQU	004H		; REQUESTED SECTOR NOT FOUND
   154                              <1> WRITE_PROTECT	EQU	003H		; WRITE ATTEMPTED ON WRITE PROTECT DISK
   155                              <1> BAD_ADDR_MARK	EQU	002H		; ADDRESS MARK NOT FOUND
   156                              <1> BAD_CMD 	EQU	001H		; BAD COMMAND PASSED TO DISKETTE I/O
   157                              <1> 
   158                              <1> ;---------- DISK CHANGE LINE EQUATES -------------------------------------------
   159                              <1> NOCHGLN 	EQU	001H		; NO DISK CHANGE LINE AVAILABLE
   160                              <1> CHGLN		EQU	002H		; DISK CHANGE LINE AVAILABLE
   161                              <1> 
   162                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS ---------------------------------------
   163                              <1> TRK_CAPA	EQU	00000001B	; 80 TRACK CAPABILITY
   164                              <1> FMT_CAPA	EQU	00000010B	; MULTIPLE FORMAT CAPABILITY (1.2M)
   165                              <1> DRV_DET 	EQU	00000100B	; DRIVE DETERMINED
   166                              <1> MED_DET 	EQU	00010000B	; MEDIA DETERMINED BIT
   167                              <1> DBL_STEP	EQU	00100000B	; DOUBLE STEP BIT
   168                              <1> RATE_MSK	EQU	11000000B	; MASK FOR CLEARING ALL BUT RATE
   169                              <1> RATE_500	EQU	00000000B	; 500 KBS DATA RATE
   170                              <1> RATE_300	EQU	01000000B	; 300 KBS DATA RATE
   171                              <1> RATE_250	EQU	10000000B	; 250 KBS DATA RATE
   172                              <1> STRT_MSK	EQU	00001100B	; OPERATION START RATE MASK
   173                              <1> SEND_MSK	EQU	11000000B	; MASK FOR SEND RATE BITS
   174                              <1> 
   175                              <1> ;---------- MEDIA/DRIVE STATE INDICATORS COMPATIBILITY -------------------------
   176                              <1> M3D3U		EQU	00000000B	; 360 MEDIA/DRIVE NOT ESTABLISHED
   177                              <1> M3D1U		EQU	00000001B	; 360 MEDIA,1.2DRIVE NOT ESTABLISHED
   178                              <1> M1D1U		EQU	00000010B	; 1.2 MEDIA/DRIVE NOT ESTABLISHED
   179                              <1> MED_UNK 	EQU	00000111B	; NONE OF THE ABOVE
   180                              <1> 
   181                              <1> ;---------- INTERRUPT EQUATES --------------------------------------------------
   182                              <1> ;EOI		EQU	020H		; END OF INTERRUPT COMMAND TO 8259
   183                              <1> ;INTA00		EQU	020H		; 8259 PORT
   184                              <1> INTA01		EQU	021H		; 8259 PORT
   185                              <1> INTB00		EQU	0A0H		; 2ND 8259
   186                              <1> INTB01		EQU	0A1H		;
   187                              <1> 
   188                              <1> ;-------------------------------------------------------------------------------
   189                              <1> DMA08		EQU	008H		; DMA STATUS REGISTER PORT ADDRESS
   190                              <1> DMA		EQU	000H		; DMA CH.0 ADDRESS REGISTER PORT ADDRESS
   191                              <1> DMA18		EQU	0D0H		; 2ND DMA STATUS PORT ADDRESS
   192                              <1> DMA1		EQU	0C0H		; 2ND DMA CH.0 ADDRESS REGISTER ADDRESS
   193                              <1> ;-------------------------------------------------------------------------------
   194                              <1> ;TIMER		EQU	040H		; 8254 TIMER - BASE ADDRESS
   195                              <1> 
   196                              <1> ;-------------------------------------------------------------------------------
   197                              <1> DMA_PAGE	EQU	081H		; START OF DMA PAGE REGISTERS
   198                              <1> 
   199                              <1> ; 06/02/2015 (unix386.s, protected mode modifications)
   200                              <1> ; (unix386.s <-- dsectrm2.s)
   201                              <1> ; 11/12/2014 (copy from IBM PC-XT Model 286 BIOS - DSEG.INC)
   202                              <1> 
   203                              <1> ; 10/12/2014
   204                              <1> ;
   205                              <1> ;int40h:
   206                              <1> ;	pushf
   207                              <1> ;	push 	cs
   208                              <1> ;	;cli
   209                              <1> ;	call 	DISKETTE_IO_1
   210                              <1> ;	retn
   211                              <1> 
   212                              <1> ; DSKETTE ----- 04/21/86 DISKETTE BIOS
   213                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
   214                              <1> ;
   215                              <1> 
   216                              <1> ;-- INT13H ---------------------------------------------------------------------
   217                              <1> ; DISKETTE I/O
   218                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO THE 5 1/4 INCH 360 KB,
   219                              <1> ;	1.2 MB, 720 KB AND 1.44 MB DISKETTE DRIVES.
   220                              <1> ; INPUT
   221                              <1> ;	(AH) =  00H RESET DISKETTE SYSTEM
   222                              <1> ;		HARD RESET TO NEC, PREPARE COMMAND, RECALIBRATE REQUIRED
   223                              <1> ;		ON ALL DRIVES
   224                              <1> ;------------------------------------------------------------------------------- 
   225                              <1> ;	(AH)= 01H  READ THE STATUS OF THE SYSTEM INTO (AH)
   226                              <1> ;		@DISKETTE_STATUS FROM LAST OPERATION IS USED
   227                              <1> ;-------------------------------------------------------------------------------
   228                              <1> ;	REGISTERS FOR READ/WRITE/VERIFY/FORMAT
   229                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
   230                              <1> ;	(DH) - HEAD NUMBER (0-1 ALLOWED, NOT VALUE CHECKED)
   231                              <1> ;	(CH) - TRACK NUMBER (NOT VALUE CHECKED)
   232                              <1> ;		MEDIA	DRIVE	TRACK NUMBER
   233                              <1> ;		320/360	320/360	    0-39
   234                              <1> ;		320/360	1.2M	    0-39
   235                              <1> ;		1.2M	1.2M	    0-79
   236                              <1> ;		720K	720K	    0-79
   237                              <1> ;		1.44M	1.44M	    0-79	
   238                              <1> ;	(CL) - 	SECTOR NUMBER (NOT VALUE CHECKED, NOT USED FOR FORMAT)
   239                              <1> ;		MEDIA	DRIVE	SECTOR NUMBER
   240                              <1> ;		320/360	320/360	     1-8/9
   241                              <1> ;		320/360	1.2M	     1-8/9
   242                              <1> ;		1.2M	1.2M	     1-15
   243                              <1> ;		720K	720K	     1-9
   244                              <1> ;		1.44M	1.44M	     1-18		
   245                              <1> ;	(AL)	NUMBER OF SECTORS (NOT VALUE CHECKED)
   246                              <1> ;		MEDIA	DRIVE	MAX NUMBER OF SECTORS
   247                              <1> ;		320/360	320/360	        8/9
   248                              <1> ;		320/360	1.2M	        8/9
   249                              <1> ;		1.2M	1.2M		15
   250                              <1> ;		720K	720K		9
   251                              <1> ;		1.44M	1.44M		18
   252                              <1> ;
   253                              <1> ;	(ES:BX) - ADDRESS OF BUFFER (NOT REQUIRED FOR VERIFY)
   254                              <1> ;
   255                              <1> ;-------------------------------------------------------------------------------
   256                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY
   257                              <1> ;-------------------------------------------------------------------------------
   258                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY
   259                              <1> ;-------------------------------------------------------------------------------
   260                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS
   261                              <1> ;-------------------------------------------------------------------------------
   262                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK
   263                              <1> ;		(ES,BX) MUST POINT TO THE COLLECTION OF DESIRED ADDRESS FIELDS
   264                              <1> ;		FOR THE	TRACK. EACH FIELD IS COMPOSED OF 4 BYTES, (C,H,R,N),
   265                              <1> ;		WHERE C = TRACK NUMBER, H=HEAD NUMBER, R = SECTOR NUMBER, 
   266                              <1> ;		N= NUMBER OF BYTES PER SECTOR (00=128,01=256,02=512,03=1024),
   267                              <1> ;		THERE MUST BE ONE ENTRY FOR EVERY SECTOR ON THE TRACK.
   268                              <1> ;		THIS INFORMATION IS USED TO FIND THE REQUESTED SECTOR DURING 
   269                              <1> ;		READ/WRITE ACCESS.
   270                              <1> ;		PRIOR TO FORMATTING A DISKETTE, IF THERE EXISTS MORE THAN
   271                              <1> ;		ONE SUPPORTED MEDIA FORMAT TYPE WITHIN THE DRIVE IN QUESTION,
   272                              <1> ;		THEN "SET DASD TYPE" (INT 13H, AH = 17H) OR 'SET MEDIA TYPE'
   273                              <1> ;		(INT 13H, AH =  18H) MUST BE CALLED TO SET THE DISKETTE TYPE
   274                              <1> ;		THAT IS TO BE FORMATTED. IF "SET DASD TYPE" OR "SET MEDIA TYPE"
   275                              <1> ;		IS NOT CALLED, THE FORMAT ROUTINE WILL ASSUME THE 
   276                              <1> ;		MEDIA FORMAT TO BE THE MAXIMUM CAPACITY OF THE DRIVE.
   277                              <1> ;
   278                              <1> ;		THESE PARAMETERS OF DISK BASE MUST BE CHANGED IN ORDER TO
   279                              <1> ;		FORMAT THE FOLLOWING MEDIAS:
   280                              <1> ;		---------------------------------------------
   281                              <1> ;		: MEDIA  :     DRIVE      : PARM 1 : PARM 2 :
   282                              <1> ;		---------------------------------------------
   283                              <1> ;		: 320K	 : 320K/360K/1.2M :  50H   :   8    :
   284                              <1> ;		: 360K	 : 320K/360K/1.2M :  50H   :   9    :
   285                              <1> ;		: 1.2M	 : 1.2M           :  54H   :  15    :
   286                              <1> ;		: 720K	 : 720K/1.44M     :  50H   :   9    :
   287                              <1> ;		: 1.44M	 : 1.44M          :  6CH   :  18    :		  	
   288                              <1> ;		---------------------------------------------
   289                              <1> ;		NOTES: - PARM 1 = GAP LENGTH FOR FORMAT
   290                              <1> ;		       - PARM 2 = EOT (LAST SECTOR ON TRACK)
   291                              <1> ;		       - DISK BASE IS POINTED BY DISK POINTER LOCATED
   292                              <1> ;			 AT ABSOLUTE ADDRESS 0:78.
   293                              <1> ;		       - WHEN FORMAT OPERATIONS ARE COMPLETE, THE PARAMETERS
   294                              <1> ;			 SHOULD BE RESTORED TO THEIR RESPECTIVE INITIAL VALUES.			
   295                              <1> ;-------------------------------------------------------------------------------
   296                              <1> ;	(AH) = 08H READ DRIVE PARAMETERS
   297                              <1> ;	REGISTERS
   298                              <1> ;	  INPUT
   299                              <1> ;	    (DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
   300                              <1> ;	  OUTPUT
   301                              <1> ;	    (ES:DI) POINTS TO DRIVE PARAMETER TABLE
   302                              <1> ;	    (CH) - LOW ORDER 8 OF 10 BITS MAXIMUM NUMBER OF TRACKS
   303                              <1> ;	    (CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
   304                              <1> ;	           BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
   305                              <1> ;	    (DH) - MAXIMUM HEAD NUMBER
   306                              <1> ;	    (DL) - NUMBER OF DISKETTE DRIVES INSTALLED
   307                              <1> ;	    (BH) - 0
   308                              <1> ;	    (BL) - BITS 7 THRU 4 - 0
   309                              <1> ;	           BITS 3 THRU 0 - VALID DRIVE TYPE VALUE IN CMOS
   310                              <1> ;	    (AX) - 0
   311                              <1> ;	 UNDER THE FOLLOWING CIRCUMSTANCES:
   312                              <1> ;	    (1) THE DRIVE NUMBER IS INVALID,
   313                              <1> ;	    (2) THE DRIVE TYPE IS UNKNOWN AND CMOS IS NOT PRESENT, 
   314                              <1> ;	    (3) THE DRIVE TYPE IS UNKNOWN AND CMOS IS BAD,
   315                              <1> ;	    (4) OR THE DRIVE TYPE IS UNKNOWN AND THE CMOS DRIVE TYPE IS INVALID
   316                              <1> ;	    THEN ES,AX,BX,CX,DH,DI=0 ; DL=NUMBER OF DRIVES. 
   317                              <1> ;	    IF NO DRIVES ARE PRESENT THEN: ES,AX,BX,CX,DX,DI=0.
   318                              <1> ;	    @DISKETTE_STATUS = 0 AND CY IS RESET.
   319                              <1> ;-------------------------------------------------------------------------------
   320                              <1> ;	(AH)= 15H  READ DASD TYPE
   321                              <1> ;	OUTPUT REGISTERS
   322                              <1> ;	(AH) - ON RETURN IF CARRY FLAG NOT SET, OTHERWISE ERROR	
   323                              <1> ;		00 - DRIVE NOT PRESENT	
   324                              <1> ;		01 - DISKETTE, NO CHANGE LINE AVAILABLE
   325                              <1> ;		02 - DISKETTE, CHANGE LINE AVAILABLE	
   326                              <1> ;		03 - RESERVED (FIXED DISK)
   327                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
   328                              <1> ;-------------------------------------------------------------------------------
   329                              <1> ;	(AH)= 16H  DISK CHANGE LINE STATUS
   330                              <1> ;	OUTPUT REGISTERS
   331                              <1> ;	(AH) - 00 - DISK CHANGE LINE NOT ACTIVE	
   332                              <1> ;	       06 - DISK CHANGE LINE ACTIVE & CARRY BIT ON
   333                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED)
   334                              <1> ;-------------------------------------------------------------------------------
   335                              <1> ;	(AH)= 17H  SET DASD TYPE FOR FORMAT
   336                              <1> ;	INPUT REGISTERS
   337                              <1> ;	(AL) -	00 - NOT USED	
   338                              <1> ;		01 - DISKETTE 320/360K IN 360K DRIVE	
   339                              <1> ;		02 - DISKETTE 360K IN 1.2M DRIVE
   340                              <1> ;		03 - DISKETTE 1.2M IN 1.2M DRIVE
   341                              <1> ;		04 - DISKETTE 720K IN 720K DRIVE
   342                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHECKED:
   343                              <1> ;	       (DO NOT USE WHEN DISKETTE ATTACH CARD USED)
   344                              <1> ;-------------------------------------------------------------------------------
   345                              <1> ;	(AH)= 18H  SET MEDIA TYPE FOR FORMAT
   346                              <1> ;	INPUT REGISTERS
   347                              <1> ;	(CH) - LOW ORDER 8 OF 10 BITS MAXIMUM TRACKS
   348                              <1> ;	(CL) - BITS 7 & 6 - HIGH ORDER TWO BITS OF MAXIMUM TRACKS
   349                              <1> ;	       BITS 5 THRU 0 - MAXIMUM SECTORS PER TRACK
   350                              <1> ;	(DL) - DRIVE NUMBER (0-1 ALLOWED, VALUE CHACKED)
   351                              <1> ;	OUTPUT REGISTERS:
   352                              <1> ;	(ES:DI) - POINTER TO DRIVE PARAMETERS TABLE FOR THIS MEDIA TYPE,
   353                              <1> ;		  UNCHANGED IF (AH) IS NON-ZERO
   354                              <1> ;	(AH) - 00H, CY = 0, TRACK AND SECTORS/TRACK COMBINATION IS SUPPORTED
   355                              <1> ;	     - 01H, CY = 1, FUNCTION IS NOT AVAILABLE
   356                              <1> ;	     - 0CH, CY = 1, TRACK AND SECTORS/TRACK COMBINATION IS NOT SUPPORTED
   357                              <1> ;	     - 80H, CY = 1, TIME OUT (DISKETTE NOT PRESENT)		
   358                              <1> ;-------------------------------------------------------------------------------
   359                              <1> ;	DISK CHANGE STATUS IS ONLY CHECKED WHEN A MEDIA SPECIFIED IS OTHER
   360                              <1> ;	THAN 360 KB DRIVE. IF THE DISK CHANGE LINE IS FOUND TO BE
   361                              <1> ;	ACTIVE THE FOLLOWING ACTIONS TAKE PLACE:
   362                              <1> ;		ATTEMPT TO RESET DISK CHANGE LINE TO INACTIVE STATE. 
   363                              <1> ;		IF ATTEMPT SUCCEEDS SET DASD TYPE FOR FORMAT AND RETURN DISK 
   364                              <1> ;		CHANGE ERROR CODE
   365                              <1> ;		IF ATTEMPT FAILS RETURN TIMEOUT ERROR CODE AND SET DASD TYPE 
   366                              <1> ;		TO A PREDETERMINED STATE INDICATING MEDIA TYPE UNKNOWN.
   367                              <1> ;	IF THE DISK CHANGE LINE IN INACTIVE PERFORM SET DASD TYPE FOR FORMAT.
   368                              <1> ;
   369                              <1> ; DATA VARIABLE -- @DISK_POINTER
   370                              <1> ;	DOUBLE WORD POINTER TO THE CURRENT SET OF DISKETTE PARAMETERS
   371                              <1> ;-------------------------------------------------------------------------------
   372                              <1> ; OUTPUT FOR ALL FUNCTIONS
   373                              <1> ;	AH = STATUS OF OPERATION
   374                              <1> ;		STATUS BITS ARE DEFINED IN THE EQUATES FOR @DISKETTE_STATUS
   375                              <1> ;		VARIABLE IN THE DATA SEGMENT OF THIS MODULE
   376                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN, EXCEPT FOR READ DASD
   377                              <1> ;		TYPE AH=(15)).
   378                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)
   379                              <1> ;	FOR READ/WRITE/VERIFY
   380                              <1> ;		DS,BX,DX,CX PRESERVED
   381                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISKETTE CODE, THE APPROPRIATE 
   382                              <1> ;		ACTION IS TO RESET THE DISKETTE, THEN RETRY THE OPERATION.
   383                              <1> ;		ON READ ACCESSES, NO MOTOR START DELAY IS TAKEN, SO THAT 
   384                              <1> ;		THREE RETRIES ARE REQUIRED ON READS TO ENSURE THAT THE 
   385                              <1> ;		PROBLEM IS NOT DUE TO MOTOR START-UP.
   386                              <1> ;-------------------------------------------------------------------------------
   387                              <1> ;
   388                              <1> ; DISKETTE STATE MACHINE - ABSOLUTE ADDRESS 40:90 (DRIVE A) & 91 (DRIVE B)
   389                              <1> ;
   390                              <1> ;   -----------------------------------------------------------------
   391                              <1> ;   |       |       |       |       |       |       |       |       |
   392                              <1> ;   |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   |
   393                              <1> ;   |       |       |       |       |       |       |       |       |
   394                              <1> ;   -----------------------------------------------------------------
   395                              <1> ;	|	|	|	|	|	|	|	|
   396                              <1> ;	|	|	|	|	|	-----------------
   397                              <1> ;	|	|	|	|	|		|
   398                              <1> ;	|	|	|	|    RESERVED		|
   399                              <1> ;	|	|	|	|		  PRESENT STATE
   400                              <1> ;	|	|	|	|	000: 360K IN 360K DRIVE UNESTABLISHED
   401                              <1> ;	|	|	|	|	001: 360K IN 1.2M DRIVE UNESTABLISHED
   402                              <1> ;	|	|	|	|	010: 1.2M IN 1.2M DRIVE UNESTABLISHED
   403                              <1> ;	|	|	|	|	011: 360K IN 360K DRIVE ESTABLISHED
   404                              <1> ;	|	|	|	|	100: 360K IN 1.2M DRIVE ESTABLISHED
   405                              <1> ;	|	|	|	|	101: 1.2M IN 1.2M DRIVE ESTABLISHED
   406                              <1> ;	|	|	|	|	110: RESERVED
   407                              <1> ;	|	|	|	|	111: NONE OF THE ABOVE
   408                              <1> ;	|	|	|	|
   409                              <1> ;	|	|	|	------>	MEDIA/DRIVE ESTABLISHED
   410                              <1> ;	|	|	|
   411                              <1> ;	|	|	-------------->	DOUBLE STEPPING REQUIRED (360K IN 1.2M
   412                              <1> ;	|	|			DRIVE)
   413                              <1> ;	|	|
   414                              <1> ;	------------------------------>	DATA TRANSFER RATE FOR THIS DRIVE:
   415                              <1> ;
   416                              <1> ;						00: 500 KBS
   417                              <1> ;						01: 300 KBS
   418                              <1> ;						10: 250 KBS
   419                              <1> ;						11: RESERVED
   420                              <1> ;
   421                              <1> ;
   422                              <1> ;-------------------------------------------------------------------------------
   423                              <1> ; STATE OPERATION STARTED - ABSOLUTE ADDRESS 40:92 (DRIVE A) & 93 (DRIVE B)
   424                              <1> ;-------------------------------------------------------------------------------
   425                              <1> ; PRESENT CYLINDER NUMBER - ABSOLUTE ADDRESS 40:94 (DRIVE A) & 95 (DRIVE B)
   426                              <1> ;-------------------------------------------------------------------------------
   427                              <1> 
   428                              <1> struc MD
   429 00000000 <res 00000001>      <1> 	.SPEC1		resb	1	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   430 00000001 <res 00000001>      <1> 	.SPEC2		resb	1	; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   431 00000002 <res 00000001>      <1> 	.OFF_TIM	resb	1	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   432 00000003 <res 00000001>      <1> 	.BYT_SEC	resb	1	; 512 BYTES/SECTOR
   433 00000004 <res 00000001>      <1> 	.SEC_TRK	resb	1	; EOT (LAST SECTOR ON TRACK)
   434 00000005 <res 00000001>      <1> 	.GAP		resb	1	; GAP LENGTH
   435 00000006 <res 00000001>      <1> 	.DTL		resb	1	; DTL
   436 00000007 <res 00000001>      <1> 	.GAP3		resb	1	; GAP LENGTH FOR FORMAT
   437 00000008 <res 00000001>      <1> 	.FIL_BYT	resb	1	; FILL BYTE FOR FORMAT
   438 00000009 <res 00000001>      <1> 	.HD_TIM		resb	1	; HEAD SETTLE TIME (MILLISECONDS)
   439 0000000A <res 00000001>      <1> 	.STR_TIM	resb	1	; MOTOR START TIME (1/8 SECONDS)
   440 0000000B <res 00000001>      <1> 	.MAX_TRK	resb	1	; MAX. TRACK NUMBER
   441 0000000C <res 00000001>      <1> 	.RATE		resb	1	; DATA TRANSFER RATE
   442                              <1> endstruc
   443                              <1> 
   444                              <1> BIT7OFF	EQU	7FH
   445                              <1> BIT7ON	EQU	80H
   446                              <1> 
   447                              <1> ;;int13h: ; 16/02/2015
   448                              <1> ;; 16/02/2015 - 21/02/2015
   449                              <1> int40h:
   450 00001A50 9C                  <1> 	pushfd
   451 00001A51 0E                  <1> 	push 	cs
   452 00001A52 E801000000          <1> 	call 	DISKETTE_IO_1
   453 00001A57 C3                  <1> 	retn	
   454                              <1> 
   455                              <1> DISKETTE_IO_1:
   456                              <1> 
   457 00001A58 FB                  <1> 	STI				; INTERRUPTS BACK ON
   458 00001A59 55                  <1> 	PUSH	eBP			; USER REGISTER
   459 00001A5A 57                  <1> 	PUSH	eDI			; USER REGISTER
   460 00001A5B 52                  <1> 	PUSH	eDX			; HEAD #, DRIVE # OR USER REGISTER
   461 00001A5C 53                  <1> 	PUSH	eBX			; BUFFER OFFSET PARAMETER OR REGISTER
   462 00001A5D 51                  <1> 	PUSH	eCX			; TRACK #-SECTOR # OR USER REGISTER
   463 00001A5E 89E5                <1> 	MOV	eBP,eSP			; BP     => PARAMETER LIST DEP. ON AH
   464                              <1> 					; [BP]   = SECTOR #
   465                              <1> 					; [BP+1] = TRACK #
   466                              <1> 					; [BP+2] = BUFFER OFFSET
   467                              <1> 					; FOR RETURN OF DRIVE PARAMETERS:
   468                              <1> 					; CL/[BP] = BITS 7&6 HI BITS OF MAX CYL
   469                              <1> 					; 	    BITS 0-5 MAX SECTORS/TRACK
   470                              <1> 					; CH/[BP+1] = LOW 8 BITS OF MAX CYL.
   471                              <1> 					; BL/[BP+2] = BITS 7-4 = 0
   472                              <1> 					;	      BITS 3-0 = VALID CMOS TYPE
   473                              <1> 					; BH/[BP+3] = 0
   474                              <1> 					; DL/[BP+4] = # DRIVES INSTALLED
   475                              <1> 					; DH/[BP+5] = MAX HEAD #
   476                              <1> 					; DI/[BP+6] = OFFSET TO DISK BASE
   477 00001A60 06                  <1> 	push	es ; 06/02/2015	
   478 00001A61 1E                  <1> 	PUSH	DS			; BUFFER SEGMENT PARM OR USER REGISTER
   479 00001A62 56                  <1> 	PUSH	eSI			; USER REGISTERS
   480                              <1> 	;CALL	DDS			; SEGMENT OF BIOS DATA AREA TO DS
   481                              <1> 	;mov	cx, cs
   482                              <1> 	;mov	ds, cx
   483 00001A63 66B91000            <1> 	mov	cx, KDATA
   484 00001A67 8ED9                <1>         mov     ds, cx
   485 00001A69 8EC1                <1>         mov     es, cx
   486                              <1> 
   487                              <1> 	;CMP	AH,(FNC_TAE-FNC_TAB)/2	; CHECK FOR > LARGEST FUNCTION
   488 00001A6B 80FC19              <1> 	cmp	ah,(FNC_TAE-FNC_TAB)/4 ; 18/02/2015
   489 00001A6E 7202                <1> 	JB	short OK_FUNC		; FUNCTION OK
   490 00001A70 B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
   491                              <1> OK_FUNC:
   492 00001A72 80FC01              <1> 	CMP	AH,1			; RESET OR STATUS ?
   493 00001A75 760C                <1> 	JBE	short OK_DRV		; IF RESET OR STATUS DRIVE ALWAYS OK
   494 00001A77 80FC08              <1> 	CMP	AH,8			; READ DRIVE PARMS ?
   495 00001A7A 7407                <1> 	JZ	short OK_DRV		; IF SO DRIVE CHECKED LATER
   496 00001A7C 80FA01              <1> 	CMP	DL,1			; DRIVES 0 AND 1 OK
   497 00001A7F 7602                <1> 	JBE	short OK_DRV		; IF 0 OR 1 THEN JUMP
   498 00001A81 B414                <1> 	MOV	AH,14H			; REPLACE WITH KNOWN INVALID FUNCTION
   499                              <1> OK_DRV:
   500 00001A83 31C9                <1> 	xor	ecx, ecx
   501                              <1> 	;mov	esi, ecx ; 08/02/2015
   502 00001A85 89CF                <1> 	mov	edi, ecx ; 08/02/2015
   503 00001A87 88E1                <1> 	MOV	CL,AH			; CL = FUNCTION
   504                              <1> 	;XOR	CH,CH			; CX = FUNCTION
   505                              <1> 	;SHL	CL, 1			; FUNCTION TIMES 2
   506 00001A89 C0E102              <1> 	SHL	CL, 2 ; 20/02/2015	; FUNCTION TIMES 4 (for 32 bit offset)
   507 00001A8C BB[C41A0000]        <1> 	MOV	eBX,FNC_TAB		; LOAD START OF FUNCTION TABLE
   508 00001A91 01CB                <1> 	ADD	eBX,eCX			; ADD OFFSET INTO TABLE => ROUTINE
   509 00001A93 88F4                <1> 	MOV	AH,DH			; AX = HEAD #,# OF SECTORS OR DASD TYPE
   510 00001A95 30F6                <1> 	XOR	DH,DH			; DX = DRIVE #
   511 00001A97 6689C6              <1> 	MOV	SI,AX			; SI = HEAD #,# OF SECTORS OR DASD TYPE
   512 00001A9A 6689D7              <1> 	MOV     DI,DX                   ; DI = DRIVE #
   513                              <1> 	;
   514                              <1> 	; 11/12/2014
   515 00001A9D 8815[B1A20000]      <1>         mov     [cfd], dl               ; current floppy drive (for 'GET_PARM')        
   516                              <1> 	;
   517 00001AA3 8A25[74A80000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; LOAD STATUS TO AH FOR STATUS FUNCTION
   518 00001AA9 C605[74A80000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; INITIALIZE FOR ALL OTHERS
   519                              <1> 
   520                              <1> ;	THROUGHOUT THE DISKETTE BIOS, THE FOLLOWING INFORMATION IS CONTAINED IN
   521                              <1> ;	THE FOLLOWING MEMORY LOCATIONS AND REGISTERS. NOT ALL DISKETTE BIOS
   522                              <1> ;	FUNCTIONS REQUIRE ALL OF THESE PARAMETERS.
   523                              <1> ;
   524                              <1> ;		DI	: DRIVE #
   525                              <1> ;		SI-HI	: HEAD #
   526                              <1> ;		SI-LOW	: # OF SECTORS OR DASD TYPE FOR FORMAT
   527                              <1> ;		ES	: BUFFER SEGMENT
   528                              <1> ;		[BP]	: SECTOR #
   529                              <1> ;		[BP+1]	: TRACK #
   530                              <1> ;		[BP+2]	: BUFFER OFFSET
   531                              <1> ;
   532                              <1> ;	ACROSS CALLS TO SUBROUTINES THE CARRY FLAG (CY=1), WHERE INDICATED IN 
   533                              <1> ;	SUBROUTINE PROLOGUES, REPRESENTS AN EXCEPTION RETURN (NORMALLY AN ERROR 
   534                              <1> ;	CONDITION). IN MOST CASES, WHEN CY = 1, @DSKETTE_STATUS CONTAINS THE 
   535                              <1> ;	SPECIFIC ERROR CODE.
   536                              <1> ;
   537                              <1> 					; (AH) = @DSKETTE_STATUS
   538 00001AB0 FF13                <1> 	CALL	dWORD [eBX]		; CALL THE REQUESTED FUNCTION
   539 00001AB2 5E                  <1> 	POP	eSI			; RESTORE ALL REGISTERS
   540 00001AB3 1F                  <1> 	POP	DS
   541 00001AB4 07                  <1> 	pop	es	; 06/02/2015
   542 00001AB5 59                  <1> 	POP	eCX
   543 00001AB6 5B                  <1> 	POP	eBX
   544 00001AB7 5A                  <1> 	POP	eDX
   545 00001AB8 5F                  <1> 	POP	eDI
   546 00001AB9 89E5                <1> 	MOV	eBP, eSP
   547 00001ABB 50                  <1> 	PUSH	eAX
   548 00001ABC 9C                  <1> 	PUSHFd
   549 00001ABD 58                  <1> 	POP	eAX
   550                              <1> 	;MOV	[BP+6], AX
   551 00001ABE 89450C              <1> 	mov	[ebp+12], eax  ; 18/02/2015, flags
   552 00001AC1 58                  <1> 	POP	eAX
   553 00001AC2 5D                  <1> 	POP	eBP
   554 00001AC3 CF                  <1> 	IRETd
   555                              <1> 
   556                              <1> ;-------------------------------------------------------------------------------
   557                              <1> ; DW --> dd (06/02/2015)
   558 00001AC4 [281B0000]          <1> FNC_TAB	dd	DSK_RESET		; AH = 00H; RESET
   559 00001AC8 [A11B0000]          <1> 	dd	DSK_STATUS		; AH = 01H; STATUS
   560 00001ACC [B21B0000]          <1> 	dd	DSK_READ		; AH = 02H; READ
   561 00001AD0 [C31B0000]          <1> 	dd	DSK_WRITE		; AH = 03H; WRITE
   562 00001AD4 [D41B0000]          <1> 	dd	DSK_VERF		; AH = 04H; VERIFY
   563 00001AD8 [E51B0000]          <1> 	dd	DSK_FORMAT		; AH = 05H; FORMAT
   564 00001ADC [6A1C0000]          <1> 	dd	FNC_ERR			; AH = 06H; INVALID
   565 00001AE0 [6A1C0000]          <1> 	dd	FNC_ERR			; AH = 07H; INVALID
   566 00001AE4 [771C0000]          <1> 	dd	DSK_PARMS		; AH = 08H; READ DRIVE PARAMETERS
   567 00001AE8 [6A1C0000]          <1> 	dd	FNC_ERR			; AH = 09H; INVALID
   568 00001AEC [6A1C0000]          <1> 	dd	FNC_ERR			; AH = 0AH; INVALID
   569 00001AF0 [6A1C0000]          <1> 	dd	FNC_ERR			; AH = 0BH; INVALID
   570 00001AF4 [6A1C0000]          <1> 	dd	FNC_ERR			; AH = 0CH; INVALID
   571 00001AF8 [6A1C0000]          <1> 	dd	FNC_ERR			; AH = 0DH; INVALID
   572 00001AFC [6A1C0000]          <1> 	dd	FNC_ERR			; AH = 0EH; INVALID
   573 00001B00 [6A1C0000]          <1> 	dd	FNC_ERR			; AH = 0FH; INVALID
   574 00001B04 [6A1C0000]          <1> 	dd	FNC_ERR			; AH = 10H; INVALID
   575 00001B08 [6A1C0000]          <1> 	dd	FNC_ERR			; AH = 11H; INVALID
   576 00001B0C [6A1C0000]          <1> 	dd	FNC_ERR			; AH = 12H; INVALID
   577 00001B10 [6A1C0000]          <1> 	dd	FNC_ERR			; AH = 13H; INVALID
   578 00001B14 [6A1C0000]          <1> 	dd	FNC_ERR			; AH = 14H; INVALID
   579 00001B18 [381D0000]          <1> 	dd	DSK_TYPE		; AH = 15H; READ DASD TYPE
   580 00001B1C [631D0000]          <1> 	dd	DSK_CHANGE		; AH = 16H; CHANGE STATUS
   581 00001B20 [9D1D0000]          <1> 	dd	FORMAT_SET		; AH = 17H; SET DASD TYPE
   582 00001B24 [201E0000]          <1> 	dd	SET_MEDIA		; AH = 18H; SET MEDIA TYPE	
   583                              <1> FNC_TAE EQU     $                       ; END
   584                              <1> 
   585                              <1> ;-------------------------------------------------------------------------------
   586                              <1> ; DISK_RESET	(AH = 00H)	
   587                              <1> ;		RESET THE DISKETTE SYSTEM.
   588                              <1> ;
   589                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   590                              <1> ;-------------------------------------------------------------------------------
   591                              <1> DSK_RESET:
   592 00001B28 66BAF203            <1> 	MOV	DX,03F2H		; ADAPTER CONTROL PORT
   593 00001B2C FA                  <1> 	CLI				; NO INTERRUPTS
   594 00001B2D A0[72A80000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
   595 00001B32 243F                <1> 	AND	AL,00111111B		; KEEP SELECTED AND MOTOR ON BITS
   596 00001B34 C0C004              <1> 	ROL	AL,4			; MOTOR VALUE TO HIGH NIBBLE
   597                              <1> 					; DRIVE SELECT TO LOW NIBBLE
   598 00001B37 0C08                <1> 	OR	AL,00001000B		; TURN ON INTERRUPT ENABLE
   599 00001B39 EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
   600 00001B3A C605[71A80000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
   601                              <1> 	;JMP	$+2			; WAIT FOR I/O
   602                              <1> 	;JMP	$+2			; WAIT FOR I/O (TO INSURE MINIMUM
   603                              <1> 					;      PULSE WIDTH)
   604                              <1> 	; 19/12/2014
   605                              <1> 	NEWIODELAY
   605 00001B41 E6EB                <2>  out 0ebh,al
   606                              <1> 
   607                              <1> 	; 17/12/2014 
   608                              <1> 	; AWARD BIOS 1999 - RESETDRIVES (ADISK.ASM)
   609 00001B43 B915000000          <1> 	mov	ecx, WAITCPU_RESET_ON	; cx = 21 -- Min. 14 micro seconds !?
   610                              <1> wdw1:
   611                              <1> 	NEWIODELAY   ; 27/02/2015
   611 00001B48 E6EB                <2>  out 0ebh,al
   612 00001B4A E2FC                <1> 	loop	wdw1
   613                              <1> 	;
   614 00001B4C 0C04                <1> 	OR	AL,00000100B		; TURN OFF RESET BIT
   615 00001B4E EE                  <1> 	OUT	DX,AL			; RESET THE ADAPTER
   616                              <1> 	; 16/12/2014
   617                              <1> 	IODELAY
   617 00001B4F EB00                <2>  jmp short $+2
   617 00001B51 EB00                <2>  jmp short $+2
   618                              <1> 	;
   619                              <1> 	;STI				; ENABLE THE INTERRUPTS
   620 00001B53 E8250C0000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
   621 00001B58 723E                <1> 	JC	short DR_ERR		; IF ERROR, RETURN IT
   622 00001B5A 66B9C000            <1> 	MOV	CX,11000000B		; CL = EXPECTED @NEC_STATUS
   623                              <1> NXT_DRV:
   624 00001B5E 6651                <1> 	PUSH	CX			; SAVE FOR CALL
   625 00001B60 B8[961B0000]        <1> 	MOV	eAX, DR_POP_ERR 	; LOAD NEC_OUTPUT ERROR ADDRESS
   626 00001B65 50                  <1> 	PUSH	eAX			; "
   627 00001B66 B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
   628 00001B68 E8030B0000          <1> 	CALL	NEC_OUTPUT
   629 00001B6D 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
   630 00001B6E E83A0C0000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
   631 00001B73 6659                <1> 	POP	CX			; RESTORE AFTER CALL
   632 00001B75 7221                <1> 	JC	short DR_ERR		; ERROR RETURN
   633 00001B77 3A0D[75A80000]      <1> 	CMP	CL, [NEC_STATUS]	; TEST FOR DRIVE READY TRANSITION
   634 00001B7D 7519                <1> 	JNZ	short DR_ERR		; EVERYTHING OK
   635 00001B7F FEC1                <1> 	INC	CL			; NEXT EXPECTED @NEC_STATUS
   636 00001B81 80F9C3              <1> 	CMP	CL,11000011B		; ALL POSSIBLE DRIVES CLEARED
   637 00001B84 76D8                <1> 	JBE	short NXT_DRV		; FALL THRU IF 11000100B OR >
   638                              <1> 	;
   639 00001B86 E852030000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
   640                              <1> RESBAC:
   641 00001B8B E806090000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   642 00001B90 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   643 00001B93 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   644 00001B95 C3                  <1> 	RETn		
   645                              <1> DR_POP_ERR:
   646 00001B96 6659                <1> 	POP	CX			; CLEAR STACK
   647                              <1> DR_ERR:
   648 00001B98 800D[74A80000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; SET ERROR CODE
   649 00001B9F EBEA                <1> 	JMP	SHORT RESBAC		; RETURN FROM RESET
   650                              <1> 
   651                              <1> ;-------------------------------------------------------------------------------
   652                              <1> ; DISK_STATUS	(AH = 01H)
   653                              <1> ;	DISKETTE STATUS.
   654                              <1> ;
   655                              <1> ; ON ENTRY:	AH : STATUS OF PREVIOUS OPERATION
   656                              <1> ;
   657                              <1> ; ON EXIT:	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF PREVIOUS OPERATION.
   658                              <1> ;-------------------------------------------------------------------------------
   659                              <1> DSK_STATUS:
   660 00001BA1 8825[74A80000]      <1> 	MOV	[DSKETTE_STATUS],AH	; PUT BACK FOR SETUP END
   661 00001BA7 E8EA080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   662 00001BAC 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   663 00001BAF 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   664 00001BB1 C3                  <1> 	RETn		
   665                              <1> 
   666                              <1> ;-------------------------------------------------------------------------------
   667                              <1> ; DISK_READ	(AH = 02H)	
   668                              <1> ;	DISKETTE READ.
   669                              <1> ;
   670                              <1> ; ON ENTRY:	DI	: DRIVE #
   671                              <1> ;		SI-HI	: HEAD #
   672                              <1> ;		SI-LOW	: # OF SECTORS
   673                              <1> ;		ES	: BUFFER SEGMENT
   674                              <1> ;		[BP]	: SECTOR #
   675                              <1> ;		[BP+1]	: TRACK #
   676                              <1> ;		[BP+2]	: BUFFER OFFSET
   677                              <1> ;
   678                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   679                              <1> ;-------------------------------------------------------------------------------
   680                              <1> 
   681                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
   682                              <1> 
   683                              <1> DSK_READ:
   684 00001BB2 8025[72A80000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
   685 00001BB9 66B846E6            <1> 	MOV	AX,0E646H		; AX = NEC COMMAND, DMA COMMAND
   686 00001BBD E825040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   687 00001BC2 C3                  <1> 	RETn
   688                              <1> 
   689                              <1> ;-------------------------------------------------------------------------------
   690                              <1> ; DISK_WRITE	(AH = 03H)
   691                              <1> ;	DISKETTE WRITE.
   692                              <1> ;
   693                              <1> ; ON ENTRY:	DI	: DRIVE #
   694                              <1> ;		SI-HI	: HEAD #
   695                              <1> ;		SI-LOW	: # OF SECTORS
   696                              <1> ;		ES	: BUFFER SEGMENT
   697                              <1> ;		[BP]	: SECTOR #
   698                              <1> ;		[BP+1]	: TRACK #
   699                              <1> ;		[BP+2]	: BUFFER OFFSET
   700                              <1> ;
   701                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   702                              <1> ;-------------------------------------------------------------------------------
   703                              <1> 
   704                              <1> ; 06/02/2015, ES:BX -> EBX (unix386.s)
   705                              <1> 
   706                              <1> DSK_WRITE:
   707 00001BC3 66B84AC5            <1> 	MOV	AX,0C54AH		; AX = NEC COMMAND, DMA COMMAND
   708 00001BC7 800D[72A80000]80    <1>         OR      byte [MOTOR_STATUS],10000000B ; INDICATE WRITE OPERATION
   709 00001BCE E814040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   710 00001BD3 C3                  <1> 	RETn
   711                              <1> 
   712                              <1> ;-------------------------------------------------------------------------------
   713                              <1> ; DISK_VERF	(AH = 04H)
   714                              <1> ;	DISKETTE VERIFY.
   715                              <1> ;
   716                              <1> ; ON ENTRY:	DI	: DRIVE #
   717                              <1> ;		SI-HI	: HEAD #
   718                              <1> ;		SI-LOW	: # OF SECTORS
   719                              <1> ;		ES	: BUFFER SEGMENT
   720                              <1> ;		[BP]	: SECTOR #
   721                              <1> ;		[BP+1]	: TRACK #
   722                              <1> ;		[BP+2]	: BUFFER OFFSET
   723                              <1> ;
   724                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   725                              <1> ;-------------------------------------------------------------------------------
   726                              <1> DSK_VERF:
   727 00001BD4 8025[72A80000]7F    <1> 	AND	byte [MOTOR_STATUS],01111111B ; INDICATE A READ OPERATION
   728 00001BDB 66B842E6            <1> 	MOV	AX,0E642H		; AX = NEC COMMAND, DMA COMMAND
   729 00001BDF E803040000          <1> 	CALL	RD_WR_VF		; COMMON READ/WRITE/VERIFY
   730 00001BE4 C3                  <1> 	RETn
   731                              <1> 
   732                              <1> ;-------------------------------------------------------------------------------
   733                              <1> ; DISK_FORMAT	(AH = 05H)
   734                              <1> ;	DISKETTE FORMAT.
   735                              <1> ;
   736                              <1> ; ON ENTRY:	DI	: DRIVE #
   737                              <1> ;		SI-HI	: HEAD #
   738                              <1> ;		SI-LOW	: # OF SECTORS
   739                              <1> ;		ES	: BUFFER SEGMENT
   740                              <1> ;		[BP]	: SECTOR #
   741                              <1> ;		[BP+1]	: TRACK #
   742                              <1> ;		[BP+2]	: BUFFER OFFSET
   743                              <1> ;		@DISK_POINTER POINTS TO THE PARAMETER TABLE OF THIS DRIVE
   744                              <1> ;
   745                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   746                              <1> ;-------------------------------------------------------------------------------
   747                              <1> DSK_FORMAT:
   748 00001BE5 E83C030000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
   749 00001BEA E838050000          <1> 	CALL	FMT_INIT		; ESTABLISH STATE IF UNESTABLISHED
   750 00001BEF 800D[72A80000]80    <1>         OR      byte [MOTOR_STATUS], 10000000B ; INDICATE WRITE OPERATION
   751 00001BF6 E880050000          <1> 	CALL	MED_CHANGE		; CHECK MEDIA CHANGE AND RESET IF SO
   752 00001BFB 725D                <1>         JC      short FM_DON            ; MEDIA CHANGED, SKIP
   753 00001BFD E8DB020000          <1> 	CALL	SEND_SPEC		; SEND SPECIFY COMMAND TO NEC
   754 00001C02 E8E6050000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMPT RATE IS SAME AS LAST RATE
   755 00001C07 7405                <1>         JZ      short FM_WR             ; YES, SKIP SPECIFY COMMAND
   756 00001C09 E8BD050000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO CONTROLLER
   757                              <1> FM_WR:
   758 00001C0E E873060000          <1> 	CALL	FMTDMA_SET		; SET UP THE DMA FOR FORMAT
   759 00001C13 7245                <1>         JC      short FM_DON            ; RETURN WITH ERROR
   760 00001C15 B44D                <1> 	MOV	AH,04DH			; ESTABLISH THE FORMAT COMMAND
   761 00001C17 E8D0060000          <1> 	CALL	NEC_INIT		; INITIALIZE THE NEC
   762 00001C1C 723C                <1>         JC      short FM_DON            ; ERROR - EXIT
   763 00001C1E B8[5A1C0000]        <1>         MOV     eAX, FM_DON             ; LOAD ERROR ADDRESS
   764 00001C23 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
   765 00001C24 B203                <1> 	MOV	DL,3			; BYTES/SECTOR VALUE TO NEC
   766 00001C26 E83F090000          <1> 	CALL	GET_PARM
   767 00001C2B E8400A0000          <1> 	CALL	NEC_OUTPUT
   768 00001C30 B204                <1> 	MOV	DL,4			; SECTORS/TRACK VALUE TO NEC
   769 00001C32 E833090000          <1> 	CALL	GET_PARM
   770 00001C37 E8340A0000          <1> 	CALL	NEC_OUTPUT
   771 00001C3C B207                <1> 	MOV	DL,7			; GAP LENGTH VALUE TO NEC
   772 00001C3E E827090000          <1> 	CALL	GET_PARM
   773 00001C43 E8280A0000          <1> 	CALL	NEC_OUTPUT
   774 00001C48 B208                <1> 	MOV	DL,8			; FILLER BYTE TO NEC
   775 00001C4A E81B090000          <1> 	CALL	GET_PARM
   776 00001C4F E81C0A0000          <1> 	CALL	NEC_OUTPUT
   777 00001C54 58                  <1> 	POP	eAX			; THROW AWAY ERROR
   778 00001C55 E810070000          <1> 	CALL	NEC_TERM		; TERMINATE, RECEIVE STATUS, ETC,
   779                              <1> FM_DON:
   780 00001C5A E8F8020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   781 00001C5F E832080000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   782 00001C64 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   783 00001C67 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   784 00001C69 C3                  <1> 	RETn
   785                              <1> 
   786                              <1> ;-------------------------------------------------------------------------------
   787                              <1> ; FNC_ERR
   788                              <1> ;	INVALID FUNCTION REQUESTED OR INVALID DRIVE: 
   789                              <1> ;	SET BAD COMMAND IN STATUS.
   790                              <1> ;
   791                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
   792                              <1> ;-------------------------------------------------------------------------------
   793                              <1> FNC_ERR:				; INVALID FUNCTION REQUEST
   794 00001C6A 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
   795 00001C6D B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
   796 00001C6F 8825[74A80000]      <1> 	MOV	[DSKETTE_STATUS],AH	; STORE IN DATA AREA
   797 00001C75 F9                  <1> 	STC				; SET CARRY INDICATING ERROR
   798 00001C76 C3                  <1> 	RETn
   799                              <1> 
   800                              <1> ;-------------------------------------------------------------------------------
   801                              <1> ; DISK_PARMS	(AH = 08H)	
   802                              <1> ;	READ DRIVE PARAMETERS.
   803                              <1> ;
   804                              <1> ; ON ENTRY:	DI : DRIVE #
   805                              <1> ;
   806                              <1> ; ON EXIT:	CL/[BP]   = BITS 7 & 6 HI 2 BITS OF MAX CYLINDER
   807                              <1> ;		            BITS 0-5 MAX SECTORS/TRACK
   808                              <1> ;		CH/[BP+1] = LOW 8 BITS OF MAX CYLINDER
   809                              <1> ;		BL/[BP+2] = BITS 7-4 = 0
   810                              <1> ;		            BITS 3-0 = VALID CMOS DRIVE TYPE
   811                              <1> ;		BH/[BP+3] = 0
   812                              <1> ;		DL/[BP+4] = # DRIVES INSTALLED (VALUE CHECKED)
   813                              <1> ;		DH/[BP+5] = MAX HEAD #
   814                              <1> ;		DI/[BP+6] = OFFSET TO DISK_BASE
   815                              <1> ;		ES        = SEGMENT OF DISK_BASE
   816                              <1> ;		AX        = 0
   817                              <1> ;
   818                              <1> ;		NOTE : THE ABOVE INFORMATION IS STORED IN THE USERS STACK AT
   819                              <1> ;		       THE LOCATIONS WHERE THE MAIN ROUTINE WILL POP THEM
   820                              <1> ;		       INTO THE APPROPRIATE REGISTERS BEFORE RETURNING TO THE
   821                              <1> ;		       CALLER.
   822                              <1> ;-------------------------------------------------------------------------------
   823                              <1> DSK_PARMS:
   824 00001C77 E8AA020000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
   825                              <1>      ;	MOV	WORD [BP+2],0		; DRIVE TYPE = 0
   826 00001C7C 29D2                <1> 	sub     edx, edx ; 20/02/2015
   827 00001C7E 895504              <1>         mov	[ebp+4], edx ; 20/02/2015
   828                              <1>      ;  MOV     AX, [EQUIP_FLAG]        ; LOAD EQUIPMENT FLAG FOR # DISKETTES
   829                              <1>      ;  AND     AL,11000001B            ; KEEP DISKETTE DRIVE BITS
   830                              <1>      ;  MOV     DL,2                    ; DISKETTE DRIVES = 2
   831                              <1>      ;  CMP     AL,01000001B            ; 2 DRIVES INSTALLED ?
   832                              <1>      ;  JZ      short STO_DL            ; IF YES JUMP
   833                              <1>      ;  DEC     DL                      ; DISKETTE DRIVES = 1
   834                              <1>      ;  CMP     AL,00000001B            ; 1 DRIVE INSTALLED ?
   835                              <1>      ;  JNZ     short NON_DRV           ; IF NO JUMP
   836                              <1> 	;sub	edx, edx
   837 00001C81 66A1[BEA20000]      <1> 	mov     ax, [fd0_type]
   838 00001C87 6621C0              <1> 	and     ax, ax
   839 00001C8A 7474                <1> 	jz      short NON_DRV
   840 00001C8C FEC2                <1> 	inc     dl
   841 00001C8E 20E4                <1> 	and     ah, ah
   842 00001C90 7402                <1> 	jz      short STO_DL
   843 00001C92 FEC2                <1> 	inc     dl
   844                              <1> STO_DL:
   845                              <1> 	;MOV	[BP+4],DL		; STORE NUMBER OF DRIVES
   846 00001C94 895508              <1> 	mov	[ebp+8], edx ; 20/02/2015	 	
   847 00001C97 6683FF01            <1> 	CMP	DI,1			; CHECK FOR VALID DRIVE
   848 00001C9B 7766                <1> 	JA	short NON_DRV1		; DRIVE INVALID
   849                              <1> 	;MOV	BYTE [BP+5],1		; MAXIMUM HEAD NUMBER =	1
   850 00001C9D C6450901            <1> 	mov	byte [ebp+9], 1  ; 20/02/2015	
   851 00001CA1 E8BB080000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
   852                              <1> 	;;20/02/2015
   853                              <1> 	;;JC	short CHK_EST		; IF CMOS BAD CHECKSUM ESTABLISHED
   854                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE TYPE
   855 00001CA6 7412                <1> 	JZ	short CHK_EST		; JUMP IF SO
   856 00001CA8 E805020000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   857 00001CAD 720B                <1> 	JC	short CHK_EST		; TYPE NOT IN TABLE (POSSIBLE BAD CMOS)
   858                              <1> 	;MOV	[BP+2],AL		; STORE VALID CMOS DRIVE TYPE
   859 00001CAF 884504              <1>         mov	[ebp+4], al ; 06/02/2015
   860 00001CB2 8A4B04              <1> 	MOV     CL, [eBX+MD.SEC_TRK]     ; GET SECTOR/TRACK
   861 00001CB5 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]     ; GET MAX. TRACK NUMBER
   862 00001CB8 EB36                <1> 	JMP	SHORT STO_CX		; CMOS GOOD, USE CMOS
   863                              <1> CHK_EST:
   864 00001CBA 8AA7[81A80000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; LOAD STATE FOR THIS DRIVE
   865 00001CC0 F6C410              <1> 	TEST	AH,MED_DET		; CHECK FOR ESTABLISHED STATE
   866 00001CC3 743E                <1> 	JZ	short NON_DRV1		; CMOS BAD/INVALID OR UNESTABLISHED
   867                              <1> USE_EST:
   868 00001CC5 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE STATE
   869 00001CC8 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
   870 00001CCB 7557                <1> 	JNE	short USE_EST2		; NO, GO CHECK OTHER RATE
   871                              <1> 
   872                              <1> ;-----	DATA RATE IS 250 KBS, TRY 360 KB TABLE FIRST
   873                              <1> 
   874 00001CCD B001                <1> 	MOV	AL,01			; DRIVE TYPE 1 (360KB)
   875 00001CCF E8DE010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   876 00001CD4 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   877 00001CD7 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   878 00001CDA F687[81A80000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; 80 TRACK ?
   879 00001CE1 740D                <1> 	JZ	short STO_CX		; MUST BE 360KB DRIVE 
   880                              <1> 
   881                              <1> ;-----	IT IS 1.44 MB DRIVE
   882                              <1> 
   883                              <1> PARM144:
   884 00001CE3 B004                <1> 	MOV	AL,04			; DRIVE TYPE 4 (1.44MB)
   885 00001CE5 E8C8010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   886 00001CEA 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   887 00001CED 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   888                              <1> STO_CX:
   889 00001CF0 894D00              <1> 	MOV	[eBP],eCX		; SAVE POINTER IN STACK FOR RETURN
   890                              <1> ES_DI:
   891                              <1> 	;MOV	[BP+6],BX		; ADDRESS OF MEDIA/DRIVE PARM TABLE 
   892 00001CF3 895D0C              <1> 	mov	[ebp+12], ebx ; 06/02/2015
   893                              <1> 	;MOV	AX,CS			; SEGMENT MEDIA/DRIVE PARAMETER TABLE
   894                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
   895                              <1> DP_OUT:
   896 00001CF6 E85C020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   897 00001CFB 6631C0              <1> 	XOR	AX,AX			; CLEAR
   898 00001CFE F8                  <1> 	CLC
   899 00001CFF C3                  <1> 	RETn
   900                              <1> 
   901                              <1> ;-----	NO DRIYE PRESENT HANDLER
   902                              <1> 
   903                              <1> NON_DRV:
   904                              <1> 	;MOV	BYTE [BP+4],0		; CLEAR NUMBER OF DRIVES
   905 00001D00 895508              <1> 	mov	[ebp+8], edx ; 0 ; 20/02/2015
   906                              <1> NON_DRV1:
   907 00001D03 6681FF8000          <1> 	CMP	DI,80H			; CHECK FOR FIXED MEDIA TYPE REQUEST
   908 00001D08 720C                <1> 	JB	short NON_DRV2		; CONTINUE IF NOT REQUEST FALL THROUGH
   909                              <1> 
   910                              <1> ;-----	FIXED DISK REQUEST FALL THROUGH ERROR
   911                              <1> 	
   912 00001D0A E848020000          <1> 	CALL	XLAT_OLD		; ELSE TRANSLATE TO COMPATIBLE MODE
   913 00001D0F 6689F0              <1> 	MOV	AX,SI			; RESTORE AL
   914 00001D12 B401                <1> 	MOV	AH,BAD_CMD		; SET BAD COMMAND ERROR
   915 00001D14 F9                  <1> 	STC
   916 00001D15 C3                  <1> 	RETn
   917                              <1> 
   918                              <1> NON_DRV2:
   919                              <1> 	;XOR	AX,AX			; CLEAR PARMS IF NO DRIVES OR CMOS BAD
   920 00001D16 31C0                <1> 	xor	eax, eax	
   921 00001D18 66894500            <1> 	MOV	[eBP],AX		; TRACKS, SECTORS/TRACK = 0
   922                              <1> 	;MOV	[BP+5],AH		; HEAD = 0
   923 00001D1C 886509              <1> 	mov	[ebp+9], ah ; 06/02/2015
   924                              <1> 	;MOV	[BP+6],AX		; OFFSET TO DISK_BASE = 0
   925 00001D1F 89450C              <1> 	mov	[ebp+12], eax
   926                              <1> 	;MOV	ES,AX			; ES IS SEGMENT OF TABLE
   927 00001D22 EBD2                <1> 	JMP	SHORT DP_OUT
   928                              <1> 
   929                              <1> ;-----	DATA RATE IS EITHER 300 KBS OR 500 KBS, TRY 1.2 MB TABLE FIRST
   930                              <1> 
   931                              <1> USE_EST2:
   932 00001D24 B002                <1> 	MOV	AL,02			; DRIVE TYPE 2 (1.2MB)
   933 00001D26 E887010000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
   934 00001D2B 8A4B04              <1>         MOV     CL, [eBX+MD.SEC_TRK]    ; GET SECTOR/TRACK
   935 00001D2E 8A6B0B              <1>         MOV     CH, [eBX+MD.MAX_TRK]    ; GET MAX. TRACK NUMBER
   936 00001D31 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
   937 00001D34 74BA                <1> 	JZ	short STO_CX		; MUST BE 1.2MB DRIVE
   938 00001D36 EBAB                <1> 	JMP	SHORT PARM144		; ELSE, IT IS 1.44MB DRIVE 
   939                              <1> 
   940                              <1> ;-------------------------------------------------------------------------------
   941                              <1> ; DISK_TYPE (AH = 15H)	
   942                              <1> ;	THIS ROUTINE RETURNS THE TYPE OF MEDIA INSTALLED.
   943                              <1> ;
   944                              <1> ;  ON ENTRY:	DI = DRIVE #
   945                              <1> ;
   946                              <1> ;  ON EXIT:	AH = DRIVE TYPE, CY=0
   947                              <1> ;-------------------------------------------------------------------------------
   948                              <1> DSK_TYPE:
   949 00001D38 E8E9010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
   950 00001D3D 8A87[81A80000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET PRESENT STATE INFORMATION
   951 00001D43 08C0                <1> 	OR	AL,AL			; CHECK FOR NO DRIVE
   952 00001D45 7418                <1> 	JZ	short NO_DRV
   953 00001D47 B401                <1> 	MOV	AH,NOCHGLN		; NO CHANGE LINE FOR 40 TRACK DRIVE
   954 00001D49 A801                <1> 	TEST	AL,TRK_CAPA		; IS THIS DRIVE AN 80 TRACK DRIVE?
   955 00001D4B 7402                <1> 	JZ	short DT_BACK			; IF NO JUMP
   956 00001D4D B402                <1> 	MOV	AH,CHGLN		; CHANGE LINE FOR 80 TRACK DRIVE
   957                              <1> DT_BACK:
   958 00001D4F 6650                <1> 	PUSH	AX			; SAVE RETURN VALUE
   959 00001D51 E801020000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   960 00001D56 6658                <1> 	POP	AX			; RESTORE RETURN VALUE
   961 00001D58 F8                  <1> 	CLC				; NO ERROR
   962 00001D59 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   963 00001D5C 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   964 00001D5E C3                  <1> 	RETn
   965                              <1> NO_DRV:	
   966 00001D5F 30E4                <1> 	XOR	AH,AH			; NO DRIVE PRESENT OR UNKNOWN
   967 00001D61 EBEC                <1> 	JMP	SHORT DT_BACK
   968                              <1> 
   969                              <1> ;-------------------------------------------------------------------------------
   970                              <1> ; DISK_CHANGE	(AH = 16H)
   971                              <1> ;	THIS ROUTINE RETURNS THE STATE OF THE DISK CHANGE LINE.
   972                              <1> ;
   973                              <1> ; ON ENTRY:	DI = DRIVE #
   974                              <1> ;
   975                              <1> ; ON EXIT:	AH = @DSKETTE_STATUS
   976                              <1> ;		     00 - DISK CHANGE LINE INACTIVE, CY = 0
   977                              <1> ;		     06 - DISK CHANGE LINE ACTIVE, CY = 1
   978                              <1> ;-------------------------------------------------------------------------------
   979                              <1> DSK_CHANGE:
   980 00001D63 E8BE010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
   981 00001D68 8A87[81A80000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET MEDIA STATE INFORMATION
   982 00001D6E 08C0                <1> 	OR	AL,AL			; DRIVE PRESENT ?
   983 00001D70 7422                <1> 	JZ	short DC_NON		; JUMP IF NO DRIVE
   984 00001D72 A801                <1> 	TEST	AL,TRK_CAPA		; 80 TRACK DRIVE ?
   985 00001D74 7407                <1> 	JZ	short SETIT		; IF SO , CHECK CHANGE LINE
   986                              <1> DC0:
   987 00001D76 E88D0A0000          <1>         CALL    READ_DSKCHNG            ; GO CHECK STATE OF DISK CHANGE LINE
   988 00001D7B 7407                <1> 	JZ	short FINIS		; CHANGE LINE NOT ACTIVE
   989                              <1> 
   990 00001D7D C605[74A80000]06    <1> SETIT:	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; INDICATE MEDIA REMOVED
   991                              <1> 
   992 00001D84 E8CE010000          <1> FINIS:	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
   993 00001D89 E808070000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
   994 00001D8E 6689F3              <1> 	MOV	BX,SI			; GET SAVED AL TO BL
   995 00001D91 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
   996 00001D93 C3                  <1> 	RETn
   997                              <1> DC_NON:
   998 00001D94 800D[74A80000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; SET TIMEOUT, NO DRIVE
   999 00001D9B EBE7                <1> 	JMP	SHORT FINIS
  1000                              <1> 
  1001                              <1> ;-------------------------------------------------------------------------------
  1002                              <1> ; FORMAT_SET	(AH = 17H)
  1003                              <1> ;	THIS ROUTINE IS USED TO ESTABLISH THE TYPE OF MEDIA TO BE USED
  1004                              <1> ;	FOR THE FOLLOWING FORMAT OPERATION.
  1005                              <1> ;
  1006                              <1> ; ON ENTRY:	SI LOW = DASD TYPE FOR FORMAT
  1007                              <1> ;		DI     = DRIVE #
  1008                              <1> ;
  1009                              <1> ; ON EXIT:	@DSKETTE_STATUS REFLECTS STATUS
  1010                              <1> ;		AH = @DSKETTE_STATUS
  1011                              <1> ;		CY = 1 IF ERROR
  1012                              <1> ;-------------------------------------------------------------------------------
  1013                              <1> FORMAT_SET:
  1014 00001D9D E884010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1015 00001DA2 6656                <1> 	PUSH	SI			; SAVE DASD TYPE
  1016 00001DA4 6689F0              <1> 	MOV	AX,SI			; AH = ? , AL , DASD TYPE
  1017 00001DA7 30E4                <1> 	XOR	AH,AH			; AH , 0 , AL , DASD TYPE
  1018 00001DA9 6689C6              <1> 	MOV	SI,AX			; SI = DASD TYPE
  1019 00001DAC 80A7[81A80000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  1020 00001DB3 664E                <1> 	DEC	SI			; CHECK FOR 320/360K MEDIA & DRIVE
  1021 00001DB5 7509                <1> 	JNZ	short NOT_320		; BYPASS IF NOT
  1022 00001DB7 808F[81A80000]90    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_250 ; SET TO 320/360
  1023 00001DBE EB48                <1> 	JMP	SHORT S0
  1024                              <1> 
  1025                              <1> NOT_320:
  1026 00001DC0 E8B6030000          <1> 	CALL	MED_CHANGE		; CHECK FOR TIME_OUT
  1027 00001DC5 803D[74A80000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT
  1028 00001DCC 743A                <1> 	JZ	short S0		; IF TIME OUT TELL CALLER
  1029                              <1> S3:
  1030 00001DCE 664E                <1> 	DEC	SI			; CHECK FOR 320/360K IN 1.2M DRIVE
  1031 00001DD0 7509                <1> 	JNZ	short NOT_320_12	; BYPASS IF NOT
  1032 00001DD2 808F[81A80000]70    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+DBL_STEP+RATE_300 ; SET STATE
  1033 00001DD9 EB2D                <1> 	JMP	SHORT S0
  1034                              <1> 
  1035                              <1> NOT_320_12:
  1036 00001DDB 664E                <1> 	DEC	SI			; CHECK FOR 1.2M MEDIA IN 1.2M DRIVE
  1037 00001DDD 7509                <1> 	JNZ	short NOT_12		; BYPASS IF NOT
  1038 00001DDF 808F[81A80000]10    <1> 	OR	byte [DSK_STATE+eDI], MED_DET+RATE_500 ; SET STATE VARIABLE
  1039 00001DE6 EB20                <1> 	JMP	SHORT S0		; RETURN TO CALLER
  1040                              <1> 
  1041                              <1> NOT_12:	
  1042 00001DE8 664E                <1> 	DEC	SI			; CHECK FOR SET DASD TYPE 04
  1043 00001DEA 752B                <1> 	JNZ	short FS_ERR		; BAD COMMAND EXIT IF NOT VALID TYPE
  1044                              <1> 
  1045 00001DEC F687[81A80000]04    <1> 	TEST	byte [DSK_STATE+eDI], DRV_DET ; DRIVE DETERMINED ?
  1046 00001DF3 740B                <1> 	JZ	short ASSUME		; IF STILL NOT DETERMINED ASSUME
  1047 00001DF5 B050                <1> 	MOV	AL,MED_DET+RATE_300
  1048 00001DF7 F687[81A80000]02    <1>         TEST    byte [DSK_STATE+eDI], FMT_CAPA ; MULTIPLE FORMAT CAPABILITY ?
  1049 00001DFE 7502                <1> 	JNZ	short OR_IT_IN		; IF 1.2 M THEN DATA RATE 300
  1050                              <1> 
  1051                              <1> ASSUME:
  1052 00001E00 B090                <1> 	MOV	AL,MED_DET+RATE_250	; SET UP
  1053                              <1> 
  1054                              <1> OR_IT_IN:
  1055 00001E02 0887[81A80000]      <1> 	OR	[DSK_STATE+eDI], AL	; OR IN THE CORRECT STATE
  1056                              <1> S0:
  1057 00001E08 E84A010000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1058 00001E0D E884060000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1059 00001E12 665B                <1> 	POP	BX			; GET SAVED AL TO BL
  1060 00001E14 88D8                <1> 	MOV	AL,BL			; PUT BACK FOR RETURN
  1061 00001E16 C3                  <1> 	RETn
  1062                              <1> 
  1063                              <1> FS_ERR:
  1064 00001E17 C605[74A80000]01    <1> 	MOV	byte [DSKETTE_STATUS], BAD_CMD ; UNKNOWN STATE,BAD COMMAND
  1065 00001E1E EBE8                <1> 	JMP	SHORT S0
  1066                              <1> 
  1067                              <1> ;-------------------------------------------------------------------------------
  1068                              <1> ; SET_MEDIA	(AH = 18H)
  1069                              <1> ;	THIS ROUTINE SETS THE TYPE OF MEDIA AND DATA RATE 
  1070                              <1> ;	TO BE USED FOR THE FOLLOWING FORMAT OPERATION.
  1071                              <1> ;
  1072                              <1> ; ON ENTRY:
  1073                              <1> ;	[BP]	= SECTOR PER TRACK
  1074                              <1> ;	[BP+1]	= TRACK #
  1075                              <1> ;	DI	= DRIVE #
  1076                              <1> ;
  1077                              <1> ; ON EXIT:
  1078                              <1> ;	@DSKETTE_STATUS REFLECTS STATUS
  1079                              <1> ;	IF NO ERROR:
  1080                              <1> ;		AH = 0
  1081                              <1> ;		CY = 0
  1082                              <1> ;		ES = SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  1083                              <1> ;		DI/[BP+6] = OFFSET OF MEDIA/DRIVE PARAMETER TABLE
  1084                              <1> ;	IF ERROR:	
  1085                              <1> ;		AH = @DSKETTE_STATUS
  1086                              <1> ;		CY = 1
  1087                              <1> ;-------------------------------------------------------------------------------
  1088                              <1> SET_MEDIA:
  1089 00001E20 E801010000          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1090 00001E25 F687[81A80000]01    <1>         TEST    byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR CHANGE LINE AVAILABLE
  1091 00001E2C 7415                <1> 	JZ	short SM_CMOS		; JUMP IF 40 TRACK DRIVE
  1092 00001E2E E848030000          <1> 	CALL	MED_CHANGE		; RESET CHANGE LINE
  1093 00001E33 803D[74A80000]80    <1> 	CMP	byte [DSKETTE_STATUS], TIME_OUT ; IF TIME OUT TELL CALLER
  1094 00001E3A 746B                <1> 	JE	short SM_RTN
  1095 00001E3C C605[74A80000]00    <1> 	MOV	byte [DSKETTE_STATUS], 0 ; CLEAR STATUS
  1096                              <1> SM_CMOS:
  1097 00001E43 E819070000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  1098                              <1> 	;;20/02/2015
  1099                              <1> 	;;JC	short MD_NOT_FND	; ERROR IN CMOS
  1100                              <1> 	;;OR	AL,AL			; TEST FOR NO DRIVE
  1101 00001E48 745D                <1> 	JZ	short SM_RTN		; RETURN IF SO
  1102 00001E4A E863000000          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL
  1103 00001E4F 7231                <1> 	JC	short MD_NOT_FND	; TYPE NOT IN TABLE (BAD CMOS)
  1104 00001E51 57                  <1> 	PUSH	eDI			; SAVE REG.
  1105 00001E52 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR. TYPE TABLE
  1106 00001E54 B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1107                              <1> DR_SEARCH:
  1108 00001E59 8AA3[3CA20000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  1109 00001E5F 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  1110 00001E62 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH ?
  1111 00001E64 7516                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT DRIVE TYPE
  1112                              <1> DR_FND:
  1113 00001E66 8BBB[3DA20000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAM TABLE
  1114                              <1> MD_SEARCH:
  1115 00001E6C 8A6704              <1>         MOV     AH, [eDI+MD.SEC_TRK]    ; GET SECTOR/TRACK
  1116 00001E6F 386500              <1> 	CMP	[eBP],AH		; MATCH?
  1117 00001E72 7508                <1> 	JNE	short NXT_MD		; NO, CHECK NEXT MEDIA
  1118 00001E74 8A670B              <1>         MOV     AH, [eDI+MD.MAX_TRK]    ; GET MAX. TRACK #
  1119 00001E77 386501              <1> 	CMP 	[eBP+1],AH		; MATCH?
  1120 00001E7A 740F                <1> 	JE	short MD_FND		; YES, GO GET RATE
  1121                              <1> NXT_MD:
  1122                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  1123 00001E7C 83C305              <1>         add	ebx, 5 ; 18/02/2015
  1124 00001E7F E2D8                <1> 	LOOP    DR_SEARCH
  1125 00001E81 5F                  <1> 	POP	eDI			; RESTORE REG.
  1126                              <1> MD_NOT_FND:
  1127 00001E82 C605[74A80000]0C    <1> 	MOV	byte [DSKETTE_STATUS], MED_NOT_FND ; ERROR, MEDIA TYPE NOT FOUND
  1128 00001E89 EB1C                <1> 	JMP	SHORT SM_RTN		; RETURN
  1129                              <1> MD_FND:
  1130 00001E8B 8A470C              <1>         MOV     AL, [eDI+MD.RATE]       ; GET RATE
  1131 00001E8E 3C40                <1> 	CMP	AL,RATE_300		; DOUBLE STEP REQUIRED FOR RATE 300
  1132 00001E90 7502                <1> 	JNE	short MD_SET
  1133 00001E92 0C20                <1> 	OR	AL,DBL_STEP
  1134                              <1> MD_SET:
  1135                              <1> 	;MOV	[BP+6],DI		; SAVE TABLE POINTER IN STACK
  1136 00001E94 897D0C              <1> 	mov	[ebp+12], edi ; 18/02/2015
  1137 00001E97 0C10                <1> 	OR	AL,MED_DET		; SET MEDIA ESTABLISHED
  1138 00001E99 5F                  <1> 	POP	eDI
  1139 00001E9A 80A7[81A80000]0F    <1> 	AND	byte [DSK_STATE+eDI], ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR STATE
  1140 00001EA1 0887[81A80000]      <1> 	OR	[DSK_STATE+eDI], AL
  1141                              <1> 	;MOV	AX, CS			; SEGMENT OF MEDIA/DRIVE PARAMETER TABLE
  1142                              <1> 	;MOV	ES, AX			; ES IS SEGMENT OF TABLE
  1143                              <1> SM_RTN:
  1144 00001EA7 E8AB000000          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1145 00001EAC E8E5050000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1146 00001EB1 C3                  <1> 	RETn
  1147                              <1> 
  1148                              <1> ;----------------------------------------------------------------
  1149                              <1> ; DR_TYPE_CHECK							:
  1150                              <1> ;	CHECK IF THE GIVEN DRIVE TYPE IN REGISTER (AL)		:
  1151                              <1> ;	IS SUPPORTED IN BIOS DRIVE TYPE TABLE			:
  1152                              <1> ; ON ENTRY:							:
  1153                              <1> ;	AL = DRIVE TYPE						:
  1154                              <1> ; ON EXIT:							:
  1155                              <1> ;	CS = SEGMENT MEDIA/DRIVE PARAMETER TABLE (CODE)		:
  1156                              <1> ;	CY = 0 	DRIVE TYPE SUPPORTED				:
  1157                              <1> ;	     BX = OFFSET TO MEDIA/DRIVE PARAMETER TABLE		:
  1158                              <1> ;	CY = 1	DRIVE TYPE NOT SUPPORTED 			:
  1159                              <1> ; REGISTERS ALTERED: eBX						:
  1160                              <1> ;----------------------------------------------------------------		
  1161                              <1> DR_TYPE_CHECK:
  1162 00001EB2 6650                <1> 	PUSH	AX			
  1163 00001EB4 51                  <1> 	PUSH	eCX
  1164 00001EB5 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  1165 00001EB7 B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1166                              <1> TYPE_CHK:	
  1167 00001EBC 8AA3[3CA20000]      <1> 	MOV	AH,[DR_TYPE+eBX]	; GET DRIVE TYPE
  1168 00001EC2 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  1169 00001EC4 740D                <1> 	JE	short DR_TYPE_VALID	; YES, RETURN WITH CARRY RESET
  1170                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  1171 00001EC6 83C305              <1>         add	ebx, 5	; 16/02/2015 (32 bit address modification)
  1172 00001EC9 E2F1                <1> 	LOOP    TYPE_CHK
  1173                              <1> 	;
  1174 00001ECB BB[9BA20000]        <1> 	mov	ebx, MD_TBL6		; 1.44MB fd parameter table
  1175                              <1> 					; Default for GET_PARM (11/12/2014)
  1176                              <1> 	;
  1177 00001ED0 F9                  <1> 	STC				; DRIVE TYPE NOT FOUND IN TABLE
  1178 00001ED1 EB06                <1> 	JMP	SHORT TYPE_RTN
  1179                              <1> DR_TYPE_VALID:
  1180 00001ED3 8B9B[3DA20000]      <1> 	MOV	eBX,[DR_TYPE+eBX+1] 	; BX = MEDIA TABLE
  1181                              <1> TYPE_RTN:
  1182 00001ED9 59                  <1> 	POP	eCX
  1183 00001EDA 6658                <1> 	POP	AX
  1184 00001EDC C3                  <1> 	RETn	
  1185                              <1> 		
  1186                              <1> ;----------------------------------------------------------------
  1187                              <1> ; SEND_SPEC							:
  1188                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  1189                              <1> ;	THE DRIVE PARAMETER TABLE POINTED BY @DISK_POINTER	:
  1190                              <1> ; ON ENTRY:	@DISK_POINTER = DRIVE PARAMETER TABLE		:
  1191                              <1> ; ON EXIT:	NONE						:	
  1192                              <1> ; REGISTERS ALTERED: CX, DX					:
  1193                              <1> ;----------------------------------------------------------------		
  1194                              <1> SEND_SPEC:
  1195 00001EDD 50                  <1> 	PUSH	eAX			; SAVE AX
  1196 00001EDE B8[041F0000]        <1> 	MOV	eAX, SPECBAC		; LOAD ERROR ADDRESS
  1197 00001EE3 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1198 00001EE4 B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  1199 00001EE6 E885070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1200 00001EEB 28D2                <1> 	SUB	DL,DL			; FIRST SPECIFY BYTE
  1201 00001EED E878060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  1202 00001EF2 E879070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1203 00001EF7 B201                <1> 	MOV	DL,1			; SECOND SPECIFY BYTE
  1204 00001EF9 E86C060000          <1> 	CALL	GET_PARM		; GET PARAMETER TO AH
  1205 00001EFE E86D070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1206 00001F03 58                  <1> 	POP	eAX			; POP ERROR RETURN
  1207                              <1> SPECBAC:
  1208 00001F04 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  1209 00001F05 C3                  <1> 	RETn
  1210                              <1> 
  1211                              <1> ;----------------------------------------------------------------
  1212                              <1> ; SEND_SPEC_MD							:
  1213                              <1> ;	SEND THE SPECIFY COMMAND TO CONTROLLER USING DATA FROM	:
  1214                              <1> ;	THE MEDIA/DRIVE PARAMETER TABLE POINTED BY (CS:BX)	:
  1215                              <1> ; ON ENTRY:	CS:BX = MEDIA/DRIVE PARAMETER TABLE		:
  1216                              <1> ; ON EXIT:	NONE						:	
  1217                              <1> ; REGISTERS ALTERED: AX						:
  1218                              <1> ;----------------------------------------------------------------		
  1219                              <1> SEND_SPEC_MD:
  1220 00001F06 50                  <1> 	PUSH	eAX			; SAVE RATE DATA
  1221 00001F07 B8[241F0000]        <1> 	MOV	eAX, SPEC_ESBAC		; LOAD ERROR ADDRESS
  1222 00001F0C 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1223 00001F0D B403                <1> 	MOV	AH,03H			; SPECIFY COMMAND
  1224 00001F0F E85C070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1225 00001F14 8A23                <1>         MOV     AH, [eBX+MD.SPEC1]      ; GET 1ST SPECIFY BYTE
  1226 00001F16 E855070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1227 00001F1B 8A6301              <1>         MOV     AH, [eBX+MD.SPEC2]      ; GET SECOND SPECIFY BYTE
  1228 00001F1E E84D070000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE COMMAND
  1229 00001F23 58                  <1> 	POP	eAX			; POP ERROR RETURN
  1230                              <1> SPEC_ESBAC:
  1231 00001F24 58                  <1> 	POP	eAX			; RESTORE ORIGINAL AX VALUE
  1232 00001F25 C3                  <1> 	RETn
  1233                              <1> 
  1234                              <1> ;-------------------------------------------------------------------------------
  1235                              <1> ; XLAT_NEW  
  1236                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM COMPATIBLE
  1237                              <1> ;	MODE TO NEW ARCHITECTURE.
  1238                              <1> ;
  1239                              <1> ; ON ENTRY:	DI = DRIVE #
  1240                              <1> ;-------------------------------------------------------------------------------
  1241                              <1> XLAT_NEW:
  1242 00001F26 83FF01              <1> 	CMP	eDI,1				; VALID DRIVE
  1243 00001F29 7725                <1> 	JA	short XN_OUT			; IF INVALID BACK
  1244 00001F2B 80BF[81A80000]00    <1> 	CMP	byte [DSK_STATE+eDI], 0		; NO DRIVE ?
  1245 00001F32 741D                <1> 	JZ	short DO_DET			; IF NO DRIVE ATTEMPT DETERMINE
  1246 00001F34 6689F9              <1> 	MOV	CX,DI				; CX = DRIVE NUMBER
  1247 00001F37 C0E102              <1> 	SHL	CL,2				; CL = SHIFT COUNT, A=0, B=4
  1248 00001F3A A0[80A80000]        <1> 	MOV	AL, [HF_CNTRL]			; DRIVE INFORMATION
  1249 00001F3F D2C8                <1> 	ROR	AL,CL				; TO LOW NIBBLE
  1250 00001F41 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA	; KEEP DRIVE BITS
  1251 00001F43 80A7[81A80000]F8    <1>         AND     byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA)
  1252 00001F4A 0887[81A80000]      <1> 	OR	[DSK_STATE+eDI], AL		; UPDATE DRIVE STATE
  1253                              <1> XN_OUT:
  1254 00001F50 C3                  <1> 	RETn
  1255                              <1> DO_DET:
  1256 00001F51 E8BF080000          <1> 	CALL	DRIVE_DET			; TRY TO DETERMINE
  1257 00001F56 C3                  <1> 	RETn
  1258                              <1> 
  1259                              <1> ;-------------------------------------------------------------------------------
  1260                              <1> ; XLAT_OLD 
  1261                              <1> ;	TRANSLATES DISKETTE STATE LOCATIONS FROM NEW
  1262                              <1> ;	ARCHITECTURE TO COMPATIBLE MODE.
  1263                              <1> ;
  1264                              <1> ; ON ENTRY:	DI = DRIVE
  1265                              <1> ;-------------------------------------------------------------------------------
  1266                              <1> XLAT_OLD:
  1267 00001F57 83FF01              <1> 	CMP	eDI,1			; VALID DRIVE ?
  1268                              <1>         ;JA     short XO_OUT            ; IF INVALID BACK
  1269 00001F5A 0F8786000000        <1>         ja      XO_OUT
  1270 00001F60 80BF[81A80000]00    <1>         CMP	byte [DSK_STATE+eDI],0	; NO DRIVE ?
  1271 00001F67 747D                <1> 	JZ	short XO_OUT		; IF NO DRIVE TRANSLATE DONE
  1272                              <1> 
  1273                              <1> ;-----	TEST FOR SAVED DRIVE INFORMATION ALREADY SET
  1274                              <1> 
  1275 00001F69 6689F9              <1> 	MOV	CX,DI			; CX = DRIVE NUMBER
  1276 00001F6C C0E102              <1> 	SHL	CL,2			; CL = SHIFT COUNT, A=0, B=4
  1277 00001F6F B402                <1> 	MOV	AH,FMT_CAPA		; LOAD MULTIPLE DATA RATE BIT MASK
  1278 00001F71 D2CC                <1> 	ROR	AH,CL			; ROTATE BY MASK
  1279 00001F73 8425[80A80000]      <1> 	TEST	[HF_CNTRL], AH		; MULTIPLE-DATA RATE DETERMINED ?
  1280 00001F79 751C                <1> 	JNZ	short SAVE_SET		; IF SO, NO NEED TO RE-SAVE
  1281                              <1> 
  1282                              <1> ;-----	ERASE DRIVE BITS IN @HF_CNTRL FOR THIS DRIVE
  1283                              <1> 
  1284 00001F7B B407                <1> 	MOV	AH,DRV_DET+FMT_CAPA+TRK_CAPA ; MASK TO KEEP
  1285 00001F7D D2CC                <1> 	ROR	AH,CL			; FIX MASK TO KEEP
  1286 00001F7F F6D4                <1> 	NOT	AH			; TRANSLATE MASK
  1287 00001F81 2025[80A80000]      <1> 	AND	[HF_CNTRL], AH		; KEEP BITS FROM OTHER DRIVE INTACT
  1288                              <1> 
  1289                              <1> ;-----	ACCESS CURRENT DRIVE BITS AND STORE IN @HF_CNTRL
  1290                              <1> 
  1291 00001F87 8A87[81A80000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; ACCESS STATE
  1292 00001F8D 2407                <1> 	AND	AL,DRV_DET+FMT_CAPA+TRK_CAPA ; KEEP DRIVE BITS
  1293 00001F8F D2C8                <1> 	ROR	AL,CL			; FIX FOR THIS DRIVE
  1294 00001F91 0805[80A80000]      <1> 	OR	[HF_CNTRL], AL		; UPDATE SAVED DRIVE STATE
  1295                              <1> 
  1296                              <1> ;-----	TRANSLATE TO COMPATIBILITY MODE
  1297                              <1> 
  1298                              <1> SAVE_SET:
  1299 00001F97 8AA7[81A80000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  1300 00001F9D 88E7                <1> 	MOV	BH,AH			; TO BH FOR LATER
  1301 00001F9F 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE
  1302 00001FA2 80FC00              <1> 	CMP	AH,RATE_500		; RATE 500 ?
  1303 00001FA5 7410                <1> 	JZ	short CHK_144		; YES 1.2/1.2 OR 1.44/1.44
  1304 00001FA7 B001                <1> 	MOV	AL,M3D1U		; AL = 360 IN 1.2 UNESTABLISHED
  1305 00001FA9 80FC40              <1> 	CMP	AH,RATE_300		; RATE 300 ?
  1306 00001FAC 7518                <1> 	JNZ	short CHK_250		; NO, 360/360, 720/720 OR 720/1.44
  1307 00001FAE F6C720              <1> 	TEST	BH,DBL_STEP		; CHECK FOR DOUBLE STEP
  1308 00001FB1 751F                <1> 	JNZ	short TST_DET		; MUST BE 360 IN 1.2
  1309                              <1> UNKNO:
  1310 00001FB3 B007                <1> 	MOV	AL,MED_UNK		; NONE OF THE ABOVE
  1311 00001FB5 EB22                <1> 	JMP	SHORT AL_SET		; PROCESS COMPLETE
  1312                              <1> CHK_144:
  1313 00001FB7 E8A5050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  1314                              <1> 	;;20/02/2015
  1315                              <1> 	;;JC	short UNKNO		; ERROR, SET 'NONE OF ABOVE'
  1316 00001FBC 74F5                <1> 	jz	short UNKNO ;; 20/02/2015
  1317 00001FBE 3C02                <1> 	CMP	AL,2			; 1.2MB DRIVE ?
  1318 00001FC0 75F1                <1> 	JNE	short UNKNO		; NO, GO SET 'NONE OF ABOVE'
  1319 00001FC2 B002                <1> 	MOV	AL,M1D1U		; AL = 1.2 IN 1.2 UNESTABLISHED
  1320 00001FC4 EB0C                <1> 	JMP	SHORT TST_DET
  1321                              <1> CHK_250:
  1322 00001FC6 B000                <1> 	MOV	AL,M3D3U		; AL = 360 IN 360 UNESTABLISHED
  1323 00001FC8 80FC80              <1> 	CMP	AH,RATE_250		; RATE 250 ?
  1324 00001FCB 75E6                <1> 	JNZ	short UNKNO		; IF SO FALL IHRU
  1325 00001FCD F6C701              <1> 	TEST	BH,TRK_CAPA		; 80 TRACK CAPABILITY ?
  1326 00001FD0 75E1                <1> 	JNZ	short UNKNO		; IF SO JUMP, FALL THRU TEST DET
  1327                              <1> TST_DET:
  1328 00001FD2 F6C710              <1> 	TEST	BH,MED_DET		; DETERMINED ?
  1329 00001FD5 7402                <1> 	JZ	short AL_SET		; IF NOT THEN SET
  1330 00001FD7 0403                <1> 	ADD	AL,3			; MAKE DETERMINED/ESTABLISHED
  1331                              <1> AL_SET:
  1332 00001FD9 80A7[81A80000]F8    <1> 	AND	byte [DSK_STATE+eDI], ~(DRV_DET+FMT_CAPA+TRK_CAPA) ; CLEAR DRIVE
  1333 00001FE0 0887[81A80000]      <1> 	OR	[DSK_STATE+eDI], AL	; REPLACE WITH COMPATIBLE MODE
  1334                              <1> XO_OUT:
  1335 00001FE6 C3                  <1> 	RETn
  1336                              <1> 
  1337                              <1> ;-------------------------------------------------------------------------------
  1338                              <1> ; RD_WR_VF
  1339                              <1> ;	COMMON READ, WRITE AND VERIFY: 
  1340                              <1> ;	MAIN LOOP FOR STATE RETRIES.
  1341                              <1> ;
  1342                              <1> ; ON ENTRY:	AH = READ/WRITE/VERIFY NEC PARAMETER
  1343                              <1> ;		AL = READ/WRITE/VERIFY DMA PARAMETER
  1344                              <1> ;
  1345                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1346                              <1> ;-------------------------------------------------------------------------------
  1347                              <1> RD_WR_VF:
  1348 00001FE7 6650                <1> 	PUSH	AX			; SAVE DMA, NEC PARAMETERS
  1349 00001FE9 E838FFFFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH.
  1350 00001FEE E8F3000000          <1> 	CALL	SETUP_STATE		; INITIALIZE START AND END RATE
  1351 00001FF3 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  1352                              <1> DO_AGAIN:
  1353 00001FF5 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  1354 00001FF7 E87F010000          <1> 	CALL	MED_CHANGE		; MEDIA CHANGE AND RESET IF CHANGED
  1355 00001FFC 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY
  1356 00001FFE 0F82C9000000        <1>         JC      RWV_END                 ; MEDIA CHANGE ERROR OR TIME-OUT
  1357                              <1> RWV:
  1358 00002004 6650                <1> 	PUSH	AX			; SAVE READ/WRITE/VERIFY PARAMETER
  1359 00002006 8AB7[81A80000]      <1> 	MOV	DH, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1360 0000200C 80E6C0              <1> 	AND	DH,RATE_MSK		; KEEP ONLY RATE
  1361 0000200F E84D050000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL (AL)
  1362                              <1> 	;;20/02/2015
  1363                              <1> 	;;JC	short RWV_ASSUME	; ERROR IN CMOS
  1364 00002014 7451                <1> 	jz	short RWV_ASSUME ; 20/02/2015
  1365 00002016 3C01                <1> 	CMP	AL,1			; 40 TRACK DRIVE?
  1366 00002018 750D                <1> 	JNE	short RWV_1		; NO, BYPASS CMOS VALIDITY CHECK
  1367 0000201A F687[81A80000]01    <1> 	TEST	byte [DSK_STATE+eDI], TRK_CAPA ; CHECK FOR 40 TRACK DRIVE
  1368 00002021 7413                <1> 	JZ	short RWV_2		; YES, CMOS IS CORRECT
  1369 00002023 B002                <1> 	MOV	AL,2			; CHANGE TO 1.2M
  1370 00002025 EB0F                <1> 	JMP	SHORT RWV_2
  1371                              <1> RWV_1:
  1372 00002027 720D                <1> 	JB	short RWV_2		; NO DRIVE SPECIFIED, CONTINUE
  1373 00002029 F687[81A80000]01    <1> 	TEST    byte [DSK_STATE+eDI], TRK_CAPA ; IS IT REALLY 40 TRACK?
  1374 00002030 7504                <1> 	JNZ	short RWV_2		; NO, 80 TRACK
  1375 00002032 B001                <1> 	MOV	AL,1			; IT IS 40 TRACK, FIX CMOS VALUE
  1376 00002034 EB04                <1> 	jmp	short rwv_3
  1377                              <1> RWV_2:
  1378 00002036 08C0                <1> 	OR	AL,AL			; TEST FOR NO DRIVE
  1379 00002038 742D                <1> 	JZ	short RWV_ASSUME	; ASSUME TYPE, USE MAX TRACK
  1380                              <1> rwv_3:
  1381 0000203A E873FEFFFF          <1> 	CALL	DR_TYPE_CHECK		; RTN CS:BX = MEDIA/DRIVE PARAM TBL.
  1382 0000203F 7226                <1> 	JC	short RWV_ASSUME	; TYPE NOT IN TABLE (BAD CMOS)
  1383                              <1> 
  1384                              <1> ;-----	SEARCH FOR MEDIA/DRIVE PARAMETER TABLE
  1385                              <1> 
  1386 00002041 57                  <1> 	PUSH	eDI			; SAVE DRIVE #
  1387 00002042 31DB                <1> 	XOR	eBX,eBX			; BX = INDEX TO DR_TYPE TABLE
  1388 00002044 B906000000          <1> 	MOV	eCX,DR_CNT		; CX = LOOP COUNT
  1389                              <1> RWV_DR_SEARCH:
  1390 00002049 8AA3[3CA20000]      <1> 	MOV	AH, [DR_TYPE+eBX]	; GET DRIVE TYPE
  1391 0000204F 80E47F              <1> 	AND	AH,BIT7OFF		; MASK OUT MSB
  1392 00002052 38E0                <1> 	CMP	AL,AH			; DRIVE TYPE MATCH?
  1393 00002054 750B                <1> 	JNE	short RWV_NXT_MD	; NO, CHECK NEXT DRIVE TYPE
  1394                              <1> RWV_DR_FND:
  1395 00002056 8BBB[3DA20000]      <1> 	MOV	eDI, [DR_TYPE+eBX+1] 	; DI = MEDIA/DRIVE PARAMETER TABLE
  1396                              <1> RWV_MD_SEARH:
  1397 0000205C 3A770C              <1>         CMP     DH, [eDI+MD.RATE]       ; MATCH?
  1398 0000205F 741B                <1> 	JE	short RWV_MD_FND	; YES, GO GET 1ST SPECIFY BYTE
  1399                              <1> RWV_NXT_MD:
  1400                              <1> 	;ADD	BX,3			; CHECK NEXT DRIVE TYPE
  1401 00002061 83C305              <1> 	add	eBX, 5
  1402 00002064 E2E3                <1> 	LOOP	RWV_DR_SEARCH
  1403 00002066 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  1404                              <1> 
  1405                              <1> ;-----	ASSUME PRIMARY DRIVE IS INSTALLED AS SHIPPED
  1406                              <1> 
  1407                              <1> RWV_ASSUME:
  1408 00002067 BB[5AA20000]        <1> 	MOV	eBX, MD_TBL1		; POINT TO 40 TRACK 250 KBS
  1409 0000206C F687[81A80000]01    <1> 	TEST 	byte [DSK_STATE+eDI], TRK_CAPA ; TEST FOR 80 TRACK
  1410 00002073 740A                <1> 	JZ	short RWV_MD_FND1	; MUST BE 40 TRACK
  1411 00002075 BB[74A20000]        <1> 	MOV	eBX, MD_TBL3		; POINT TO 80 TRACK 500 KBS
  1412 0000207A EB03                <1> 	JMP	short RWV_MD_FND1	; GO SPECIFY PARAMTERS
  1413                              <1> 
  1414                              <1> ;-----	CS:BX POINTS TO MEDIA/DRIVE PARAMETER TABLE
  1415                              <1> 	 			
  1416                              <1> RWV_MD_FND:
  1417 0000207C 89FB                <1> 	MOV	eBX,eDI			; BX = MEDIA/DRIVE PARAMETER TABLE
  1418 0000207E 5F                  <1> 	POP	eDI			; RESTORE DRIVE #
  1419                              <1> 	
  1420                              <1> ;-----	SEND THE SPECIFY COMMAND TO THE CONTROLLER
  1421                              <1> 
  1422                              <1> RWV_MD_FND1:
  1423 0000207F E882FEFFFF          <1> 	CALL	SEND_SPEC_MD
  1424 00002084 E864010000          <1> 	CALL	CHK_LASTRATE		; ZF=1 ATTEMP RATE IS SAME AS LAST RATE
  1425 00002089 7405                <1> 	JZ	short RWV_DBL		; YES,SKIP SEND RATE COMMAND
  1426 0000208B E83B010000          <1> 	CALL	SEND_RATE		; SEND DATA RATE TO NEC
  1427                              <1> RWV_DBL:
  1428 00002090 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1429 00002091 E822040000          <1> 	CALL	SETUP_DBL		; CHECK FOR DOUBLE STEP
  1430 00002096 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  1431 00002097 7226                <1> 	JC	short CHK_RET		; ERROR FROM READ ID, POSSIBLE RETRY
  1432 00002099 6658                <1> 	POP	AX			; RESTORE NEC, DMA COMMAND
  1433 0000209B 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1434 0000209D 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1435 0000209E E861010000          <1> 	CALL	DMA_SETUP		; SET UP THE DMA
  1436 000020A3 5B                  <1> 	POP	eBX 
  1437 000020A4 6658                <1> 	POP	AX			; RESTORE NEC COMMAND
  1438 000020A6 722F                <1> 	JC	short RWV_BAC		; CHECK FOR DMA BOUNDARY ERROR
  1439 000020A8 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1440 000020AA 53                  <1> 	PUSH	eBX			; SAVE MEDIA/DRIVE PARAM TBL ADDRESS
  1441 000020AB E83C020000          <1> 	CALL	NEC_INIT		; INITIALIZE NEC
  1442 000020B0 5B                  <1> 	POP	eBX			; RESTORE ADDRESS
  1443 000020B1 720C                <1> 	JC	short CHK_RET		; ERROR - EXIT
  1444 000020B3 E866020000          <1> 	CALL	RWV_COM			; OP CODE COMMON TO READ/WRITE/VERIFY
  1445 000020B8 7205                <1> 	JC	short CHK_RET		; ERROR - EXIT
  1446 000020BA E8AB020000          <1> 	CALL	NEC_TERM		; TERMINATE, GET STATUS, ETC.
  1447                              <1> CHK_RET:
  1448 000020BF E84A030000          <1> 	CALL	RETRY			; CHECK FOR, SETUP RETRY
  1449 000020C4 6658                <1> 	POP	AX			; RESTORE READ/WRITE/VERIFY PARAMETER
  1450 000020C6 7305                <1> 	JNC	short RWV_END		; CY = 0 NO RETRY
  1451 000020C8 E928FFFFFF          <1>         JMP     DO_AGAIN                ; CY = 1 MEANS RETRY
  1452                              <1> RWV_END:
  1453 000020CD E8F4020000          <1> 	CALL	DSTATE			; ESTABLISH STATE IF SUCCESSFUL
  1454 000020D2 E887030000          <1> 	CALL	NUM_TRANS		; AL = NUMBER TRANSFERRED
  1455                              <1> RWV_BAC:				; BAD DMA ERROR ENTRY
  1456 000020D7 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  1457 000020D9 E879FEFFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  1458 000020DE 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  1459 000020E0 E8B1030000          <1> 	CALL	SETUP_END		; VARIOUS CLEANUPS
  1460 000020E5 C3                  <1> 	RETn
  1461                              <1> 
  1462                              <1> ;-------------------------------------------------------------------------------
  1463                              <1> ; SETUP_STATE:	INITIALIZES START AND END RATES.
  1464                              <1> ;-------------------------------------------------------------------------------
  1465                              <1> SETUP_STATE:
  1466 000020E6 F687[81A80000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; MEDIA DETERMINED ?
  1467 000020ED 7537                <1> 	JNZ	short J1C		; NO STATES IF DETERMINED
  1468 000020EF 66B84000            <1>         MOV     AX,(RATE_500*256)+RATE_300  ; AH = START RATE, AL = END RATE
  1469 000020F3 F687[81A80000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE ?
  1470 000020FA 740D                <1> 	JZ	short AX_SET		; DO NOT KNOW DRIVE
  1471 000020FC F687[81A80000]02    <1> 	TEST	byte [DSK_STATE+eDI], FMT_CAPA ; MULTI-RATE?
  1472 00002103 7504                <1> 	JNZ	short AX_SET		; JUMP IF YES
  1473 00002105 66B88080            <1>         MOV     AX,RATE_250*257         ; START A END RATE 250 FOR 360 DRIVE
  1474                              <1> AX_SET:	
  1475 00002109 80A7[81A80000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP) ; TURN OFF THE RATE
  1476 00002110 08A7[81A80000]      <1> 	OR	[DSK_STATE+eDI], AH	; RATE FIRST TO TRY
  1477 00002116 8025[7CA80000]F3    <1> 	AND	byte [LASTRATE], ~STRT_MSK ; ERASE LAST TO TRY RATE BITS
  1478 0000211D C0C804              <1> 	ROR	AL,4			; TO OPERATION LAST RATE LOCATION
  1479 00002120 0805[7CA80000]      <1> 	OR	[LASTRATE], AL		; LAST RATE
  1480                              <1> J1C:	
  1481 00002126 C3                  <1> 	RETn
  1482                              <1> 
  1483                              <1> ;-------------------------------------------------------------------------------
  1484                              <1> ;  FMT_INIT: ESTABLISH STATE IF UNESTABLISHED AT FORMAT TIME.
  1485                              <1> ;-------------------------------------------------------------------------------
  1486                              <1> FMT_INIT:
  1487 00002127 F687[81A80000]10    <1> 	TEST	byte [DSK_STATE+eDI], MED_DET ; IS MEDIA ESTABLISHED
  1488 0000212E 7546                <1> 	JNZ	short F1_OUT		; IF SO RETURN
  1489 00002130 E82C040000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN AL
  1490                              <1> 	;; 20/02/2015
  1491                              <1> 	;;JC	short CL_DRV		; ERROR IN CMOS ASSUME NO DRIVE
  1492 00002135 7440                <1> 	jz	short CL_DRV ;; 20/02/2015
  1493 00002137 FEC8                <1> 	DEC	AL			; MAKE ZERO ORIGIN
  1494                              <1> 	;;JS	short CL_DRV		; NO DRIVE IF AL 0
  1495 00002139 8AA7[81A80000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; AH = CURRENT STATE
  1496 0000213F 80E40F              <1> 	AND	AH, ~(MED_DET+DBL_STEP+RATE_MSK) ; CLEAR
  1497 00002142 08C0                <1> 	OR	AL,AL			; CHECK FOR 360
  1498 00002144 7505                <1> 	JNZ	short N_360		; IF 360 WILL BE 0
  1499 00002146 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; ESTABLISH MEDIA
  1500 00002149 EB25                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  1501                              <1> N_360:	
  1502 0000214B FEC8                <1> 	DEC	AL			; 1.2 M DRIVE
  1503 0000214D 7505                <1> 	JNZ	short N_12		; JUMP IF NOT
  1504                              <1> F1_RATE:
  1505 0000214F 80CC10              <1> 	OR	AH,MED_DET+RATE_500	; SET FORMAT RATE
  1506 00002152 EB1C                <1> 	JMP	SHORT SKP_STATE		; SKIP OTHER STATE PROCESSING
  1507                              <1> N_12:	
  1508 00002154 FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 3
  1509 00002156 750F                <1> 	JNZ	short N_720		; JUMP IF NOT
  1510 00002158 F6C404              <1> 	TEST	AH,DRV_DET		; IS DRIVE DETERMINED
  1511 0000215B 7410                <1> 	JZ	short ISNT_12		; TREAT AS NON 1.2 DRIVE
  1512 0000215D F6C402              <1> 	TEST	AH,FMT_CAPA		; IS 1.2M
  1513 00002160 740B                <1> 	JZ	short ISNT_12		; JUMP IF NOT
  1514 00002162 80CC50              <1> 	OR	AH,MED_DET+RATE_300	; RATE 300
  1515 00002165 EB09                <1> 	JMP	SHORT SKP_STATE		; CONTINUE
  1516                              <1> N_720:
  1517 00002167 FEC8                <1> 	DEC	AL			; CHECK FOR TYPE 4
  1518 00002169 750C                <1> 	JNZ	short CL_DRV		; NO DRIVE, CMOS BAD
  1519 0000216B EBE2                <1> 	JMP	SHORT F1_RATE
  1520                              <1> ISNT_12: 
  1521 0000216D 80CC90              <1> 	OR	AH,MED_DET+RATE_250	; MUST BE RATE 250
  1522                              <1> 
  1523                              <1> SKP_STATE:
  1524 00002170 88A7[81A80000]      <1> 	MOV	[DSK_STATE+eDI], AH	; STORE AWAY
  1525                              <1> F1_OUT:
  1526 00002176 C3                  <1> 	RETn
  1527                              <1> CL_DRV:	
  1528 00002177 30E4                <1> 	XOR	AH,AH			; CLEAR STATE
  1529 00002179 EBF5                <1> 	JMP	SHORT SKP_STATE		; SAVE IT
  1530                              <1> 
  1531                              <1> ;-------------------------------------------------------------------------------
  1532                              <1> ; MED_CHANGE	
  1533                              <1> ;	CHECKS FOR MEDIA CHANGE, RESETS MEDIA CHANGE, 
  1534                              <1> ;	CHECKS MEDIA CHANGE AGAIN.
  1535                              <1> ;
  1536                              <1> ; ON EXIT:	CY = 1 MEANS MEDIA CHANGE OR TIMEOUT
  1537                              <1> ;		@DSKETTE_STATUS = ERROR CODE
  1538                              <1> ;-------------------------------------------------------------------------------
  1539                              <1> MED_CHANGE:
  1540 0000217B E888060000          <1> 	CALL	READ_DSKCHNG		; READ DISK CHANCE LINE STATE
  1541 00002180 7447                <1> 	JZ	short MC_OUT		; BYPASS HANDLING DISK CHANGE LINE
  1542 00002182 80A7[81A80000]EF    <1> 	AND	byte [DSK_STATE+eDI], ~MED_DET ; CLEAR STATE FOR THIS DRIVE
  1543                              <1> 
  1544                              <1> ;	THIS SEQUENCE ENSURES WHENEVER A DISKETTE IS CHANGED THAT
  1545                              <1> ;	ON THE NEXT OPERATION THE REQUIRED MOTOR START UP TIME WILL
  1546                              <1> ;	BE WAITED. (DRIVE MOTOR MAY GO OFF UPON DOOR OPENING).
  1547                              <1> 
  1548 00002189 6689F9              <1> 	MOV	CX,DI			; CL = DRIVE 0
  1549 0000218C B001                <1> 	MOV	AL,1			; MOTOR ON BIT MASK
  1550 0000218E D2E0                <1> 	SHL	AL,CL			; TO APPROPRIATE POSITION
  1551 00002190 F6D0                <1> 	NOT	AL			; KEEP ALL BUT MOTOR ON
  1552 00002192 FA                  <1> 	CLI				; NO INTERRUPTS
  1553 00002193 2005[72A80000]      <1> 	AND	[MOTOR_STATUS], AL	; TURN MOTOR OFF INDICATOR
  1554 00002199 FB                  <1> 	STI				; INTERRUPTS ENABLED
  1555 0000219A E810040000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON
  1556                              <1> 
  1557                              <1> ;-----	THIS SEQUENCE OF SEEKS IS USED TO RESET DISKETTE CHANGE SIGNAL
  1558                              <1> 
  1559 0000219F E884F9FFFF          <1> 	CALL	DSK_RESET		; RESET NEC
  1560 000021A4 B501                <1> 	MOV	CH,01H			; MOVE TO CYLINDER 1
  1561 000021A6 E8FF040000          <1> 	CALL	SEEK			; ISSUE SEEK
  1562 000021AB 30ED                <1> 	XOR	CH,CH			; MOVE TO CYLINDER 0
  1563 000021AD E8F8040000          <1> 	CALL	SEEK			; ISSUE SEEK
  1564 000021B2 C605[74A80000]06    <1> 	MOV	byte [DSKETTE_STATUS], MEDIA_CHANGE ; STORE IN STATUS
  1565                              <1> OK1:
  1566 000021B9 E84A060000          <1> 	CALL	READ_DSKCHNG		; CHECK MEDIA CHANGED AGAIN
  1567 000021BE 7407                <1> 	JZ	short OK2		; IF ACTIVE, NO DISKETTE, TIMEOUT
  1568                              <1> OK4:
  1569 000021C0 C605[74A80000]80    <1> 	MOV	byte [DSKETTE_STATUS], TIME_OUT ; TIMEOUT IF DRIVE EMPTY
  1570                              <1> OK2:		
  1571 000021C7 F9                  <1> 	STC				; MEDIA CHANGED, SET CY
  1572 000021C8 C3                  <1> 	RETn
  1573                              <1> MC_OUT:
  1574 000021C9 F8                  <1> 	CLC				; NO MEDIA CHANGED, CLEAR CY
  1575 000021CA C3                  <1> 	RETn
  1576                              <1> 
  1577                              <1> ;-------------------------------------------------------------------------------
  1578                              <1> ; SEND_RATE
  1579                              <1> ;	SENDS DATA RATE COMMAND TO NEC
  1580                              <1> ; ON ENTRY:	DI = DRIVE #
  1581                              <1> ; ON EXIT:	NONE
  1582                              <1> ; REGISTERS ALTERED: DX
  1583                              <1> ;-------------------------------------------------------------------------------
  1584                              <1> SEND_RATE:
  1585 000021CB 6650                <1> 	PUSH	AX			; SAVE REG.
  1586 000021CD 8025[7CA80000]3F    <1> 	AND	byte [LASTRATE], ~SEND_MSK ; ELSE CLEAR LAST RATE ATTEMPTED
  1587 000021D4 8A87[81A80000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1588 000021DA 24C0                <1> 	AND	AL,SEND_MSK		; KEEP ONLY RATE BITS
  1589 000021DC 0805[7CA80000]      <1> 	OR	[LASTRATE], AL		; SAVE NEW RATE FOR NEXT CHECK
  1590 000021E2 C0C002              <1> 	ROL	AL,2			; MOVE TO BIT OUTPUT POSITIONS
  1591 000021E5 66BAF703            <1> 	MOV	DX,03F7H		; OUTPUT NEW DATA RATE
  1592 000021E9 EE                  <1> 	OUT	DX,AL
  1593 000021EA 6658                <1> 	POP	AX			; RESTORE REG.
  1594 000021EC C3                  <1> 	RETn
  1595                              <1> 
  1596                              <1> ;-------------------------------------------------------------------------------
  1597                              <1> ; CHK_LASTRATE
  1598                              <1> ;	CHECK PREVIOUS DATE RATE SNT TO THE CONTROLLER.
  1599                              <1> ; ON ENTRY:
  1600                              <1> ;	DI = DRIVE #
  1601                              <1> ; ON EXIT:
  1602                              <1> ;	ZF =  1 DATA RATE IS THE SAME AS THE LAST RATE SENT TO NEC
  1603                              <1> ;	ZF =  0 DATA RATE IS DIFFERENT FROM LAST RATE
  1604                              <1> ; REGISTERS ALTERED: DX
  1605                              <1> ;-------------------------------------------------------------------------------
  1606                              <1> CHK_LASTRATE:
  1607 000021ED 6650                <1> 	PUSH	AX			; SAVE REG
  1608 000021EF 2225[7CA80000]      <1> 	AND	AH, [LASTRATE]		; GET LAST DATA RATE SELECTED
  1609 000021F5 8A87[81A80000]      <1> 	MOV	AL, [DSK_STATE+eDI]	; GET RATE STATE OF THIS DRIVE
  1610 000021FB 6625C0C0            <1>         AND     AX, SEND_MSK*257        ; KEEP ONLY RATE BITS OF BOTH
  1611 000021FF 38E0                <1> 	CMP	AL, AH			; COMPARE TO PREVIOUSLY TRIED
  1612                              <1> 					; ZF = 1 RATE IS THE SAME
  1613 00002201 6658                <1> 	POP	AX			; RESTORE REG.
  1614 00002203 C3                  <1> 	RETn
  1615                              <1> 
  1616                              <1> ;-------------------------------------------------------------------------------
  1617                              <1> ; DMA_SETUP
  1618                              <1> ;	THIS ROUTINE SETS UP THE DMA FOR READ/WRITE/VERIFY OPERATIONS.
  1619                              <1> ;
  1620                              <1> ; ON ENTRY:	AL = DMA COMMAND
  1621                              <1> ;
  1622                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1623                              <1> ;-------------------------------------------------------------------------------
  1624                              <1> 
  1625                              <1> ; SI = Head #, # of Sectors or DASD Type
  1626                              <1> 
  1627                              <1> ; 22/08/2015
  1628                              <1> ; 08/02/2015 - Protected Mode Modification
  1629                              <1> ; 06/02/2015 - 07/02/2015
  1630                              <1> ; NOTE: Buffer address must be in 1st 16MB of Physical Memory (24 bit limit).
  1631                              <1> ; (DMA Addres = Physical Address)
  1632                              <1> ; (Retro UNIX 386 v1 Kernel/System Mode Virtual Address = Physical Address)
  1633                              <1> ;
  1634                              <1> 
  1635                              <1> 
  1636                              <1> ; 04/02/2016 (clc)
  1637                              <1> ; 20/02/2015 modification (source: AWARD BIOS 1999, DMA_SETUP)
  1638                              <1> ; 16/12/2014 (IODELAY)
  1639                              <1> 
  1640                              <1> DMA_SETUP:
  1641                              <1> 
  1642                              <1> ;; 20/02/2015
  1643 00002204 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  1644 00002207 F7C2000000FF        <1> 	test	edx, 0FF000000h		; 16 MB limit (22/08/2015, bugfix)
  1645 0000220D 756E                <1> 	jnz	short dma_bnd_err_stc
  1646                              <1> 	;
  1647 0000220F 6650                <1> 	push	ax			; DMA command
  1648 00002211 52                  <1> 	push	edx			; *
  1649 00002212 B203                <1> 	mov	dl, 3			; GET BYTES/SECTOR PARAMETER
  1650 00002214 E851030000          <1> 	call	GET_PARM		; 
  1651 00002219 88E1                <1> 	mov	cl, ah 			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  1652 0000221B 6689F0              <1> 	mov	ax, si			; Sector count
  1653 0000221E 88C4                <1> 	mov	ah, al			; AH =  # OF SECTORS
  1654 00002220 28C0                <1> 	sub	al, al			; AL = 0, AX = # SECTORS * 256
  1655 00002222 66D1E8              <1> 	shr	ax, 1			; AX = # SECTORS * 128
  1656 00002225 66D3E0              <1> 	shl	ax, cl			; SHIFT BY PARAMETER VALUE
  1657 00002228 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  1658 0000222A 6689C1              <1> 	mov	cx, ax
  1659 0000222D 5A                  <1> 	pop	edx			; *
  1660 0000222E 6658                <1> 	pop	ax
  1661 00002230 3C42                <1> 	cmp	al, 42h
  1662 00002232 7507                <1>         jne     short NOT_VERF
  1663 00002234 BA0000FF00          <1> 	mov	edx, 0FF0000h
  1664 00002239 EB08                <1> 	jmp	short J33
  1665                              <1> NOT_VERF:
  1666 0000223B 6601CA              <1> 	add	dx, cx			; check for overflow
  1667 0000223E 723E                <1> 	jc	short dma_bnd_err
  1668                              <1> 	;
  1669 00002240 6629CA              <1> 	sub	dx, cx			; Restore start address
  1670                              <1> J33:
  1671 00002243 FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1672 00002244 E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1673                              <1> 	IODELAY				; WAIT FOR I/O
  1673 00002246 EB00                <2>  jmp short $+2
  1673 00002248 EB00                <2>  jmp short $+2
  1674 0000224A E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1675 0000224C 89D0                <1> 	mov	eax, edx		; Buffer address
  1676 0000224E E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1677                              <1> 	IODELAY				; WAIT FOR I/O
  1677 00002250 EB00                <2>  jmp short $+2
  1677 00002252 EB00                <2>  jmp short $+2
  1678 00002254 88E0                <1> 	MOV	AL,AH
  1679 00002256 E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1680 00002258 C1E810              <1> 	shr	eax, 16
  1681                              <1> 	IODELAY				; I/O WAIT STATE
  1681 0000225B EB00                <2>  jmp short $+2
  1681 0000225D EB00                <2>  jmp short $+2
  1682 0000225F E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  1683                              <1> 	IODELAY
  1683 00002261 EB00                <2>  jmp short $+2
  1683 00002263 EB00                <2>  jmp short $+2
  1684 00002265 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  1685 00002268 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1686                              <1> 	IODELAY				; WAIT FOR I/O
  1686 0000226A EB00                <2>  jmp short $+2
  1686 0000226C EB00                <2>  jmp short $+2
  1687 0000226E 88E0                <1> 	MOV	AL, AH
  1688 00002270 E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1689                              <1> 	IODELAY
  1689 00002272 EB00                <2>  jmp short $+2
  1689 00002274 EB00                <2>  jmp short $+2
  1690 00002276 FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  1691 00002277 B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  1692 00002279 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1693                              <1> 
  1694 0000227B F8                  <1> 	clc	; 04/02/2016
  1695 0000227C C3                  <1> 	retn
  1696                              <1> 
  1697                              <1> dma_bnd_err_stc:
  1698 0000227D F9                  <1> 	stc
  1699                              <1> dma_bnd_err:
  1700 0000227E C605[74A80000]09    <1> 	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  1701 00002285 C3                  <1> 	RETn				; CY SET BY ABOVE IF ERROR
  1702                              <1> 
  1703                              <1> ;; 16/12/2014
  1704                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1705                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1706                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1707                              <1> ;;	IODELAY
  1708                              <1> ;; 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1709                              <1> ;;	;SIODELAY
  1710                              <1> ;;      ;CMP	AL, 42H			; DMA VERIFY COMMAND
  1711                              <1> ;;      ;JNE	short NOT_VERF		; NO
  1712                              <1> ;;      ;XOR	AX, AX			; START ADDRESS
  1713                              <1> ;;      ;JMP	SHORT J33
  1714                              <1> ;;;NOT_VERF:	
  1715                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  1716                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  1717                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  1718                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  1719                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  1720                              <1> ;;	mov	eax, [ebp+4] ; 06/02/2015	
  1721                              <1> ;;	;JNC	short J33
  1722                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  1723                              <1> ;;;J33:
  1724                              <1> ;;	PUSH	eAX			; SAVE START ADDRESS
  1725                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1726                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1727                              <1> ;;	IODELAY
  1728                              <1> ;;	MOV	AL,AH
  1729                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1730                              <1> ;;	shr	eax, 16	     ; 07/02/2015
  1731                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  1732                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  1733                              <1> ;;	IODELAY
  1734                              <1> ;;	;AND	AL,00001111B
  1735                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  1736                              <1> ;;	;SIODELAY
  1737                              <1> ;;
  1738                              <1> ;;;----- DETERMINE COUNT
  1739                              <1> ;;	sub	eax, eax ; 08/02/2015
  1740                              <1> ;;	MOV	AX, SI			; AL =  # OF SECTORS
  1741                              <1> ;;	XCHG	AL, AH			; AH =  # OF SECTORS
  1742                              <1> ;;	SUB	AL, AL			; AL = 0, AX = # SECTORS * 256
  1743                              <1> ;;	SHR	AX, 1			; AX = # SECTORS * 128
  1744                              <1> ;;	PUSH	AX			; SAVE # OF SECTORS * 128
  1745                              <1> ;;	MOV	DL, 3			; GET BYTES/SECTOR PARAMETER
  1746                              <1> ;;	CALL	GET_PARM		; "
  1747                              <1> ;;	MOV	CL,AH			; SHIFT COUNT (0=128, 1=256, 2=512 ETC)
  1748                              <1> ;;	POP	AX			; AX = # SECTORS * 128
  1749                              <1> ;;	SHL	AX,CL			; SHIFT BY PARAMETER VALUE
  1750                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  1751                              <1> ;;	PUSH	eAX  ; 08/02/2015	; SAVE COUNT VALUE
  1752                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1753                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1754                              <1> ;;	IODELAY
  1755                              <1> ;;	MOV	AL, AH
  1756                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1757                              <1> ;;	;IODELAY
  1758                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  1759                              <1> ;;	POP	eCX  ; 08/02/2015 	; RECOVER COUNT VALUE
  1760                              <1> ;;	POP	eAX  ; 08/02/2015	; RECOVER ADDRESS VALUE
  1761                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  1762                              <1> ;;	add	ecx, eax ; 08/02/2015
  1763                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  1764                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1765                              <1> ;;	SIODELAY
  1766                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1767                              <1> ;;	;JNC	short NO_BAD		; CHECK FOR ERROR
  1768                              <1> ;;	jc	short dma_bnd_err ; 08/02/2015
  1769                              <1> ;;	and	ecx, 0FFF00000h ; 16 MB limit
  1770                              <1> ;;	jz	short NO_BAD
  1771                              <1> ;;dma_bnd_err:
  1772                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  1773                              <1> ;;NO_BAD:
  1774                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  1775                              <1> 
  1776                              <1> ;-------------------------------------------------------------------------------
  1777                              <1> ; FMTDMA_SET
  1778                              <1> ;	THIS ROUTINE SETS UP THE DMA CONTROLLER FOR A FORMAT OPERATION.
  1779                              <1> ;
  1780                              <1> ; ON ENTRY:	NOTHING REQUIRED
  1781                              <1> ;
  1782                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1783                              <1> ;-------------------------------------------------------------------------------
  1784                              <1> 
  1785                              <1> FMTDMA_SET:
  1786                              <1> ;; 20/02/2015 modification	
  1787 00002286 8B5504              <1> 	mov	edx, [ebp+4] 		; Buffer address
  1788 00002289 F7C20000F0FF        <1> 	test	edx, 0FFF00000h		; 16 MB limit
  1789 0000228F 75EC                <1> 	jnz	short dma_bnd_err_stc
  1790                              <1> 	;
  1791 00002291 6652                <1> 	push	dx			; *
  1792 00002293 B204                <1> 	mov	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  1793 00002295 E8D0020000          <1> 	call	GET_PARM		; "
  1794 0000229A 88E0                <1> 	mov	al, ah			; AL = SECTORS/TRACK VALUE
  1795 0000229C 28E4                <1> 	sub	ah, ah			; AX = SECTORS/TRACK VALUE
  1796 0000229E 66C1E002            <1> 	shl	ax, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  1797 000022A2 6648                <1> 	dec	ax			; -1 FOR DMA VALUE
  1798 000022A4 6689C1              <1> 	mov	cx, ax
  1799 000022A7 665A                <1> 	pop	dx			; *
  1800 000022A9 6601CA              <1> 	add	dx, cx			; check for overflow
  1801 000022AC 72D0                <1> 	jc	short dma_bnd_err
  1802                              <1> 	;
  1803 000022AE 6629CA              <1> 	sub	dx, cx			; Restore start address
  1804                              <1> 	;
  1805 000022B1 B04A                <1> 	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  1806 000022B3 FA                  <1> 	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1807 000022B4 E60C                <1> 	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1808                              <1> 	IODELAY				; WAIT FOR I/O
  1808 000022B6 EB00                <2>  jmp short $+2
  1808 000022B8 EB00                <2>  jmp short $+2
  1809 000022BA E60B                <1> 	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1810 000022BC 89D0                <1> 	mov	eax, edx		; Buffer address
  1811 000022BE E604                <1> 	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1812                              <1> 	IODELAY				; WAIT FOR I/O
  1812 000022C0 EB00                <2>  jmp short $+2
  1812 000022C2 EB00                <2>  jmp short $+2
  1813 000022C4 88E0                <1> 	MOV	AL,AH
  1814 000022C6 E604                <1> 	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1815 000022C8 C1E810              <1> 	shr	eax, 16
  1816                              <1> 	IODELAY				; I/O WAIT STATE
  1816 000022CB EB00                <2>  jmp short $+2
  1816 000022CD EB00                <2>  jmp short $+2
  1817 000022CF E681                <1> 	OUT	081H,AL			; OUTPUT highest BITS TO PAGE REGISTER
  1818                              <1> 	IODELAY
  1818 000022D1 EB00                <2>  jmp short $+2
  1818 000022D3 EB00                <2>  jmp short $+2
  1819 000022D5 6689C8              <1> 	mov	ax, cx			; Byte count - 1
  1820 000022D8 E605                <1> 	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1821                              <1> 	IODELAY				; WAIT FOR I/O
  1821 000022DA EB00                <2>  jmp short $+2
  1821 000022DC EB00                <2>  jmp short $+2
  1822 000022DE 88E0                <1> 	MOV	AL, AH
  1823 000022E0 E605                <1> 	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1824                              <1> 	IODELAY
  1824 000022E2 EB00                <2>  jmp short $+2
  1824 000022E4 EB00                <2>  jmp short $+2
  1825 000022E6 FB                  <1> 	STI				; RE-ENABLE INTERRUPTS
  1826 000022E7 B002                <1> 	MOV	AL, 2			; MODE FOR 8237
  1827 000022E9 E60A                <1> 	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1828 000022EB C3                  <1> 	retn
  1829                              <1> 
  1830                              <1> ;; 08/02/2015 - Protected Mode Modification
  1831                              <1> ;;	MOV	AL, 04AH		; WILL WRITE TO THE DISKETTE
  1832                              <1> ;;	CLI				; DISABLE INTERRUPTS DURING DMA SET-UP
  1833                              <1> ;;	OUT	DMA+12,AL		; SET THE FIRST/LA5T F/F
  1834                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1835                              <1> ;;	IODELAY
  1836                              <1> ;;	OUT	DMA+11,AL		; OUTPUT THE MODE BYTE
  1837                              <1> ;;	;MOV	AX,ES			; GET THE ES VALUE
  1838                              <1> ;;	;ROL	AX,4			; ROTATE LEFT
  1839                              <1> ;;	;MOV	CH,AL			; GET HIGHEST NIBBLE OF ES TO CH
  1840                              <1> ;;	;AND	AL,11110000B		; ZERO THE LOW NIBBLE FROM SEGMENT
  1841                              <1> ;;	;ADD	AX,[BP+2]		; TEST FOR CARRY FROM ADDITION
  1842                              <1> ;;	;JNC	short J33A
  1843                              <1> ;;	;INC	CH			; CARRY MEANS HIGH 4 BITS MUST BE INC
  1844                              <1> ;;	mov	eax, [ebp+4] ; 08/02/2015
  1845                              <1> ;;;J33A:
  1846                              <1> ;;	PUSH	eAX ; 08/02/2015	; SAVE START ADDRESS
  1847                              <1> ;;	OUT	DMA+4,AL		; OUTPUT LOW ADDRESS
  1848                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1849                              <1> ;;	IODELAY
  1850                              <1> ;;	MOV	AL,AH
  1851                              <1> ;;	OUT	DMA+4,AL		; OUTPUT HIGH ADDRESS
  1852                              <1> ;;	shr 	eax, 16 ; 08/02/2015
  1853                              <1> ;;	;MOV	AL,CH			; GET HIGH 4 BITS
  1854                              <1> ;;	;JMP	$+2			; I/O WAIT STATE
  1855                              <1> ;;	IODELAY
  1856                              <1> ;;	;AND	AL,00001111B
  1857                              <1> ;;	OUT	081H,AL			; OUTPUT HIGH 4 BITS TO PAGE REGISTER
  1858                              <1> ;;
  1859                              <1> ;;;----- DETERMINE COUNT
  1860                              <1> ;;	sub	eax, eax ; 08/02/2015
  1861                              <1> ;;	MOV	DL, 4			; SECTORS/TRACK VALUE IN PARM TABLE
  1862                              <1> ;;	CALL	GET_PARM		; "
  1863                              <1> ;;	XCHG	AL, AH			; AL = SECTORS/TRACK VALUE
  1864                              <1> ;;	SUB	AH, AH			; AX = SECTORS/TRACK VALUE
  1865                              <1> ;;	SHL	AX, 2			; AX = SEC/TRK * 4 (OFFSET C,H,R,N)
  1866                              <1> ;;	DEC	AX			; -1 FOR DMA VALUE
  1867                              <1> ;;	PUSH	eAX 	; 08/02/2015	; SAVE # OF BYTES TO BE TRANSFERED
  1868                              <1> ;;	OUT	DMA+5,AL		; LOW BYTE OF COUNT
  1869                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1870                              <1> ;;	IODELAY
  1871                              <1> ;;	MOV	AL, AH
  1872                              <1> ;;	OUT	DMA+5,AL		; HIGH BYTE OF COUNT
  1873                              <1> ;;	STI				; RE-ENABLE INTERRUPTS
  1874                              <1> ;;	POP	eCX	; 08/02/2015	; RECOVER COUNT VALUE
  1875                              <1> ;;	POP	eAX	; 08/02/2015	; RECOVER ADDRESS VALUE
  1876                              <1> ;;	;ADD	AX, CX			; ADD, TEST FOR 64K OVERFLOW
  1877                              <1> ;;	add	ecx, eax ; 08/02/2015
  1878                              <1> ;;	MOV	AL, 2			; MODE FOR 8237
  1879                              <1> ;;	;JMP	$+2			; WAIT FOR I/O
  1880                              <1> ;;	SIODELAY
  1881                              <1> ;;	OUT	DMA+10, AL		; INITIALIZE THE DISKETTE CHANNEL
  1882                              <1> ;;	;JNC	short FMTDMA_OK		; CHECK FOR ERROR
  1883                              <1> ;;	jc	short fmtdma_bnd_err ; 08/02/2015
  1884                              <1> ;;	and	ecx, 0FFF00000h  ; 16 MB limit
  1885                              <1> ;;	jz	short FMTDMA_OK
  1886                              <1> ;;	stc	; 20/02/2015
  1887                              <1> ;;fmtdma_bnd_err:
  1888                              <1> ;;	MOV	byte [DSKETTE_STATUS], DMA_BOUNDARY ; SET ERROR
  1889                              <1> ;;FMTDMA_OK:
  1890                              <1> ;;	RETn				; CY SET BY ABOVE IF ERROR
  1891                              <1> 
  1892                              <1> ;-------------------------------------------------------------------------------
  1893                              <1> ; NEC_INIT	
  1894                              <1> ;	THIS ROUTINE SEEKS TO THE REQUESTED TRACK AND INITIALIZES
  1895                              <1> ;	THE NEC FOR THE READ/WRITE/VERIFY/FORMAT OPERATION.
  1896                              <1> ;
  1897                              <1> ; ON ENTRY:	AH = NEC COMMAND TO BE PERFORMED
  1898                              <1> ;
  1899                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1900                              <1> ;-------------------------------------------------------------------------------
  1901                              <1> NEC_INIT:
  1902 000022EC 6650                <1> 	PUSH	AX			; SAVE NEC COMMAND
  1903 000022EE E8BC020000          <1> 	CALL	MOTOR_ON		; TURN MOTOR ON FOR SPECIFIC DRIVE
  1904                              <1> 
  1905                              <1> ;-----	DO THE SEEK OPERATION
  1906                              <1> 
  1907 000022F3 8A6D01              <1> 	MOV	CH,[eBP+1]		; CH = TRACK #
  1908 000022F6 E8AF030000          <1> 	CALL	SEEK			; MOVE TO CORRECT TRACK
  1909 000022FB 6658                <1> 	POP	AX			; RECOVER COMMAND
  1910 000022FD 721E                <1> 	JC	short ER_1		; ERROR ON SEEK
  1911 000022FF BB[1D230000]        <1> 	MOV	eBX, ER_1		; LOAD ERROR ADDRESS
  1912 00002304 53                  <1> 	PUSH	eBX			; PUSH NEC_OUT ERROR RETURN
  1913                              <1> 
  1914                              <1> ;-----	SEND OUT THE PARAMETERS TO THE CONTROLLER
  1915                              <1> 
  1916 00002305 E866030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE OPERATION COMMAND
  1917 0000230A 6689F0              <1> 	MOV	AX,SI			; AH = HEAD #
  1918 0000230D 89FB                <1> 	MOV	eBX,eDI			; BL = DRIVE #
  1919 0000230F C0E402              <1> 	SAL	AH,2			; MOVE IT TO BIT 2
  1920 00002312 80E404              <1> 	AND	AH,00000100B		; ISOLATE THAT BIT
  1921 00002315 08DC                <1> 	OR	AH,BL			; OR IN THE DRIVE NUMBER
  1922 00002317 E854030000          <1> 	CALL	NEC_OUTPUT		; FALL THRU CY SET IF ERROR
  1923 0000231C 5B                  <1> 	POP	eBX			; THROW AWAY ERROR RETURN
  1924                              <1> ER_1:
  1925 0000231D C3                  <1> 	RETn
  1926                              <1> 
  1927                              <1> ;-------------------------------------------------------------------------------
  1928                              <1> ; RWV_COM
  1929                              <1> ;	THIS ROUTINE SENDS PARAMETERS TO THE NEC SPECIFIC TO THE 
  1930                              <1> ;	READ/WRITE/VERIFY OPERATIONS.
  1931                              <1> ;
  1932                              <1> ; ON ENTRY:	CS:BX = ADDRESS OF MEDIA/DRIVE PARAMETER TABLE
  1933                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1934                              <1> ;-------------------------------------------------------------------------------
  1935                              <1> RWV_COM:
  1936 0000231E B8[69230000]        <1> 	MOV	eAX, ER_2		; LOAD ERROR ADDRESS
  1937 00002323 50                  <1> 	PUSH	eAX			; PUSH NEC_OUT ERROR RETURN
  1938 00002324 8A6501              <1> 	MOV	AH,[eBP+1]		; OUTPUT TRACK #
  1939 00002327 E844030000          <1> 	CALL	NEC_OUTPUT
  1940 0000232C 6689F0              <1> 	MOV	AX,SI			; OUTPUT HEAD #
  1941 0000232F E83C030000          <1> 	CALL	NEC_OUTPUT
  1942 00002334 8A6500              <1>         MOV     AH,[eBP]                ; OUTPUT SECTOR #
  1943 00002337 E834030000          <1> 	CALL	NEC_OUTPUT
  1944 0000233C B203                <1> 	MOV	DL,3			; BYTES/SECTOR PARAMETER FROM BLOCK
  1945 0000233E E827020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  1946 00002343 E828030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  1947 00002348 B204                <1> 	MOV	DL,4			; EOT PARAMETER FROM BLOCK
  1948 0000234A E81B020000          <1> 	CALL	GET_PARM 		; ... TO THE NEC
  1949 0000234F E81C030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  1950 00002354 8A6305              <1>         MOV     AH, [eBX+MD.GAP]        ; GET GAP LENGTH
  1951                              <1> _R15:
  1952 00002357 E814030000          <1> 	CALL	NEC_OUTPUT
  1953 0000235C B206                <1> 	MOV	DL,6			; DTL PARAMETER PROM BLOCK
  1954 0000235E E807020000          <1> 	CALL	GET_PARM		;  TO THE NEC
  1955 00002363 E808030000          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO CONTROLLER
  1956 00002368 58                  <1> 	POP	eAX			; THROW AWAY ERROR EXIT
  1957                              <1> ER_2:
  1958 00002369 C3                  <1> 	RETn
  1959                              <1> 
  1960                              <1> ;-------------------------------------------------------------------------------
  1961                              <1> ; NEC_TERM
  1962                              <1> ;	THIS ROUTINE WAITS FOR THE OPERATION THEN ACCEPTS THE STATUS 
  1963                              <1> ;	FROM THE NEC FOR THE READ/WRITE/VERIFY/FORWAT OPERATION.
  1964                              <1> ;
  1965                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  1966                              <1> ;-------------------------------------------------------------------------------
  1967                              <1> NEC_TERM:
  1968                              <1> 
  1969                              <1> ;-----	LET THE OPERATION HAPPEN
  1970                              <1> 
  1971 0000236A 56                  <1> 	PUSH	eSI			; SAVE HEAD #, # OF SECTORS
  1972 0000236B E80D040000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  1973 00002370 9C                  <1> 	PUSHF
  1974 00002371 E837040000          <1> 	CALL	RESULTS			; GET THE NEC STATUS
  1975 00002376 724B                <1> 	JC	short SET_END_POP
  1976 00002378 9D                  <1> 	POPF
  1977 00002379 723E                <1> 	JC	short SET_END		; LOOK FOR ERROR
  1978                              <1> 
  1979                              <1> ;-----	CHECK THE RESULTS RETURNED BY THE CONTROLLER
  1980                              <1> 
  1981 0000237B FC                  <1> 	CLD				; SET THE CORRECT DIRECTION
  1982 0000237C BE[75A80000]        <1> 	MOV	eSI, NEC_STATUS		; POINT TO STATUS FIELD
  1983 00002381 AC                  <1> 	lodsb				; GET ST0
  1984 00002382 24C0                <1> 	AND	AL,11000000B		; TEST FOR NORMAL TERMINATION
  1985 00002384 7433                <1> 	JZ	short SET_END
  1986 00002386 3C40                <1> 	CMP	AL,01000000B		; TEST FOR ABNORMAL TERMINATION
  1987 00002388 7527                <1> 	JNZ	short J18		; NOT ABNORMAL, BAD NEC
  1988                              <1> 
  1989                              <1> ;-----	ABNORMAL TERMINATION, FIND OUT WHY
  1990                              <1> 
  1991 0000238A AC                  <1> 	lodsb				; GET ST1
  1992 0000238B D0E0                <1> 	SAL	AL,1			; TEST FOR EDT FOUND
  1993 0000238D B404                <1> 	MOV	AH,RECORD_NOT_FND
  1994 0000238F 7222                <1> 	JC	short J19
  1995 00002391 C0E002              <1> 	SAL	AL,2
  1996 00002394 B410                <1> 	MOV	AH,BAD_CRC
  1997 00002396 721B                <1> 	JC	short J19
  1998 00002398 D0E0                <1> 	SAL	AL,1			; TEST FOR DMA OVERRUN
  1999 0000239A B408                <1> 	MOV	AH,BAD_DMA
  2000 0000239C 7215                <1> 	JC	short J19
  2001 0000239E C0E002              <1> 	SAL	AL,2			; TEST FOR RECORD NOT FOUND
  2002 000023A1 B404                <1> 	MOV	AH,RECORD_NOT_FND
  2003 000023A3 720E                <1> 	JC	short J19
  2004 000023A5 D0E0                <1> 	SAL	AL,1
  2005 000023A7 B403                <1> 	MOV	AH,WRITE_PROTECT	; TEST FOR WRITE_PROTECT
  2006 000023A9 7208                <1> 	JC	short J19
  2007 000023AB D0E0                <1> 	SAL	AL,1			; TEST MISSING ADDRESS MARK
  2008 000023AD B402                <1> 	MOV	AH,BAD_ADDR_MARK
  2009 000023AF 7202                <1> 	JC	short J19
  2010                              <1> 
  2011                              <1> ;----- 	NEC MUST HAVE FAILED
  2012                              <1> J18:
  2013 000023B1 B420                <1> 	MOV	AH,BAD_NEC
  2014                              <1> J19:
  2015 000023B3 0825[74A80000]      <1> 	OR	[DSKETTE_STATUS], AH
  2016                              <1> SET_END:
  2017 000023B9 803D[74A80000]01    <1> 	CMP	byte [DSKETTE_STATUS], 1 ; SET ERROR CONDITION
  2018 000023C0 F5                  <1> 	CMC
  2019 000023C1 5E                  <1> 	POP	eSI
  2020 000023C2 C3                  <1> 	RETn				; RESTORE HEAD #, # OF SECTORS
  2021                              <1> 
  2022                              <1> SET_END_POP:
  2023 000023C3 9D                  <1> 	POPF
  2024 000023C4 EBF3                <1> 	JMP	SHORT SET_END
  2025                              <1> 
  2026                              <1> ;-------------------------------------------------------------------------------
  2027                              <1> ; DSTATE:	ESTABLISH STATE UPON SUCCESSFUL OPERATION.
  2028                              <1> ;-------------------------------------------------------------------------------
  2029                              <1> DSTATE:
  2030 000023C6 803D[74A80000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  2031 000023CD 753E                <1> 	JNZ	short SETBAC		    ; IF ERROR JUMP
  2032 000023CF 808F[81A80000]10    <1> 	OR	byte [DSK_STATE+eDI],MED_DET ; NO ERROR, MARK MEDIA AS DETERMINED
  2033 000023D6 F687[81A80000]04    <1> 	TEST	byte [DSK_STATE+eDI],DRV_DET ; DRIVE DETERMINED ?
  2034 000023DD 752E                <1> 	JNZ	short SETBAC		; IF DETERMINED NO TRY TO DETERMINE
  2035 000023DF 8A87[81A80000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  2036 000023E5 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  2037 000023E7 3C80                <1> 	CMP	AL,RATE_250		; RATE 250 ?
  2038 000023E9 751B                <1> 	JNE	short M_12		; NO, MUST BE 1.2M OR 1.44M DRIVE
  2039                              <1> 
  2040                              <1> ;----- 	CHECK IF IT IS 1.44M
  2041                              <1> 
  2042 000023EB E871010000          <1> 	CALL	CMOS_TYPE		; RETURN DRIVE TYPE IN (AL)
  2043                              <1> 	;;20/02/2015
  2044                              <1> 	;;JC	short M_12		; CMOS BAD
  2045 000023F0 7414                <1> 	jz	short M_12 ;; 20/02/2015
  2046 000023F2 3C04                <1> 	CMP	AL, 4			; 1.44MB DRIVE ?
  2047 000023F4 7410                <1> 	JE	short M_12		; YES
  2048                              <1> M_720:
  2049 000023F6 80A7[81A80000]FD    <1> 	AND	byte [DSK_STATE+eDI], ~FMT_CAPA ; TURN OFF FORMAT CAPABILITY
  2050 000023FD 808F[81A80000]04    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET  ; MARK DRIVE DETERMINED
  2051 00002404 EB07                <1> 	JMP	SHORT SETBAC		; BACK
  2052                              <1> M_12:	
  2053 00002406 808F[81A80000]06    <1> 	OR	byte [DSK_STATE+eDI],DRV_DET+FMT_CAPA 
  2054                              <1> 					; TURN ON DETERMINED & FMT CAPA
  2055                              <1> SETBAC:
  2056 0000240D C3                  <1> 	RETn
  2057                              <1> 
  2058                              <1> ;-------------------------------------------------------------------------------
  2059                              <1> ; RETRY	
  2060                              <1> ;	DETERMINES WHETHER A RETRY IS NECESSARY. 
  2061                              <1> ;	IF RETRY IS REQUIRED THEN STATE INFORMATION IS UPDATED FOR RETRY.
  2062                              <1> ;
  2063                              <1> ; ON EXIT:	CY = 1 FOR RETRY, CY = 0 FOR NO RETRY
  2064                              <1> ;-------------------------------------------------------------------------------
  2065                              <1> RETRY:
  2066 0000240E 803D[74A80000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; GET STATUS OF OPERATION
  2067 00002415 7445                <1> 	JZ	short NO_RETRY		; SUCCESSFUL OPERATION
  2068 00002417 803D[74A80000]80    <1> 	CMP	byte [DSKETTE_STATUS],TIME_OUT ; IF TIME OUT NO RETRY
  2069 0000241E 743C                <1> 	JZ	short NO_RETRY
  2070 00002420 8AA7[81A80000]      <1> 	MOV	AH,[DSK_STATE+eDI]	; GET MEDIA STATE OF DRIVE
  2071 00002426 F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED/DETERMINED ?
  2072 00002429 7531                <1> 	JNZ	short NO_RETRY		; IF ESTABLISHED STATE THEN TRUE ERROR
  2073 0000242B 80E4C0              <1> 	AND	AH,RATE_MSK		; ISOLATE RATE
  2074 0000242E 8A2D[7CA80000]      <1> 	MOV	CH,[LASTRATE]		; GET START OPERATION STATE
  2075 00002434 C0C504              <1> 	ROL	CH,4			; TO CORRESPONDING BITS
  2076 00002437 80E5C0              <1> 	AND	CH,RATE_MSK		; ISOLATE RATE BITS
  2077 0000243A 38E5                <1> 	CMP	CH,AH			; ALL RATES TRIED
  2078 0000243C 741E                <1> 	JE	short NO_RETRY		; IF YES, THEN TRUE ERROR
  2079                              <1> 
  2080                              <1> ;	SETUP STATE INDICATOR FOR RETRY ATTEMPT TO NEXT RATE
  2081                              <1> ;	 00000000B (500) -> 10000000B	(250)
  2082                              <1> ;	 10000000B (250) -> 01000000B	(300)
  2083                              <1> ;	 01000000B (300) -> 00000000B	(500)
  2084                              <1> 
  2085 0000243E 80FC01              <1> 	CMP	AH,RATE_500+1		; SET CY FOR RATE 500
  2086 00002441 D0DC                <1> 	RCR	AH,1			; TO NEXT STATE
  2087 00002443 80E4C0              <1> 	AND	AH,RATE_MSK		; KEEP ONLY RATE BITS
  2088 00002446 80A7[81A80000]1F    <1> 	AND	byte [DSK_STATE+eDI], ~(RATE_MSK+DBL_STEP)
  2089                              <1> 					; RATE, DBL STEP OFF
  2090 0000244D 08A7[81A80000]      <1> 	OR	[DSK_STATE+eDI],AH	; TURN ON NEW RATE
  2091 00002453 C605[74A80000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; RESET STATUS FOR RETRY
  2092 0000245A F9                  <1> 	STC				; SET CARRY FOR RETRY
  2093 0000245B C3                  <1> 	RETn				; RETRY RETURN
  2094                              <1> 
  2095                              <1> NO_RETRY:
  2096 0000245C F8                  <1> 	CLC				; CLEAR CARRY NO RETRY
  2097 0000245D C3                  <1> 	RETn				; NO RETRY RETURN
  2098                              <1> 
  2099                              <1> ;-------------------------------------------------------------------------------
  2100                              <1> ; NUM_TRANS
  2101                              <1> ;	THIS ROUTINE CALCULATES THE NUMBER OF SECTORS THAT WERE
  2102                              <1> ;	ACTUALLY TRANSFERRED TO/FROM THE DISKETTE.
  2103                              <1> ;
  2104                              <1> ; ON ENTRY:	[BP+1] = TRACK
  2105                              <1> ;		SI-HI  = HEAD
  2106                              <1> ;		[BP]   = START SECTOR
  2107                              <1> ;
  2108                              <1> ; ON EXIT:	AL = NUMBER ACTUALLY TRANSFERRED
  2109                              <1> ;-------------------------------------------------------------------------------
  2110                              <1> NUM_TRANS:
  2111 0000245E 30C0                <1> 	XOR	AL,AL			; CLEAR FOR ERROR
  2112 00002460 803D[74A80000]00    <1> 	CMP	byte [DSKETTE_STATUS],0	; CHECK FOR ERROR
  2113 00002467 752C                <1> 	JNZ	NT_OUT			; IF ERROR 0 TRANSFERRED
  2114 00002469 B204                <1> 	MOV	DL,4			; SECTORS/TRACK OFFSET TO DL
  2115 0000246B E8FA000000          <1> 	CALL	GET_PARM		; AH = SECTORS/TRACK
  2116 00002470 8A1D[7AA80000]      <1> 	MOV	BL, [NEC_STATUS+5]	; GET ENDING SECTOR
  2117 00002476 6689F1              <1> 	MOV	CX,SI			; CH = HEAD # STARTED
  2118 00002479 3A2D[79A80000]      <1> 	CMP	CH, [NEC_STATUS+4]	; GET HEAD ENDED UP ON
  2119 0000247F 750D                <1> 	JNZ	DIF_HD			; IF ON SAME HEAD, THEN NO ADJUST
  2120 00002481 8A2D[78A80000]      <1> 	MOV	CH, [NEC_STATUS+3]	; GET TRACK ENDED UP ON
  2121 00002487 3A6D01              <1> 	CMP	CH,[eBP+1]		; IS IT ASKED FOR TRACK
  2122 0000248A 7404                <1> 	JZ	short SAME_TRK		; IF SAME TRACK NO INCREASE
  2123 0000248C 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  2124                              <1> DIF_HD:
  2125 0000248E 00E3                <1> 	ADD	BL,AH			; ADD SECTORS/TRACK
  2126                              <1> SAME_TRK:
  2127 00002490 2A5D00              <1> 	SUB	BL,[eBP]		; SUBTRACT START FROM END
  2128 00002493 88D8                <1> 	MOV	AL,BL			; TO AL
  2129                              <1> NT_OUT:
  2130 00002495 C3                  <1> 	RETn
  2131                              <1> 
  2132                              <1> ;-------------------------------------------------------------------------------
  2133                              <1> ; SETUP_END
  2134                              <1> ;	RESTORES @MOTOR_COUNT TO PARAMETER PROVIDED IN TABLE 
  2135                              <1> ;	AND LOADS @DSKETTE_STATUS TO AH, AND SETS CY.
  2136                              <1> ;
  2137                              <1> ; ON EXIT:
  2138                              <1> ;	AH, @DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  2139                              <1> ;-------------------------------------------------------------------------------
  2140                              <1> SETUP_END:
  2141 00002496 B202                <1> 	MOV	DL,2			; GET THE MOTOR WAIT PARAMETER
  2142 00002498 6650                <1> 	PUSH	AX			; SAVE NUMBER TRANSFERRED
  2143 0000249A E8CB000000          <1> 	CALL	GET_PARM
  2144 0000249F 8825[73A80000]      <1> 	MOV	[MOTOR_COUNT],AH	; STORE UPON RETURN
  2145 000024A5 6658                <1> 	POP	AX			; RESTORE NUMBER TRANSFERRED
  2146 000024A7 8A25[74A80000]      <1> 	MOV	AH, [DSKETTE_STATUS]	; GET STATUS OF OPERATION
  2147 000024AD 08E4                <1> 	OR	AH,AH			; CHECK FOR ERROR
  2148 000024AF 7402                <1> 	JZ	short NUN_ERR			; NO ERROR
  2149 000024B1 30C0                <1> 	XOR	AL,AL			; CLEAR NUMBER RETURNED
  2150                              <1> NUN_ERR: 
  2151 000024B3 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  2152 000024B6 F5                  <1> 	CMC				; SUCCESS OR FAILURE
  2153 000024B7 C3                  <1> 	RETn
  2154                              <1> 
  2155                              <1> ;-------------------------------------------------------------------------------
  2156                              <1> ; SETUP_DBL
  2157                              <1> ;	CHECK DOUBLE STEP.
  2158                              <1> ;
  2159                              <1> ; ON ENTRY :	DI = DRIVE
  2160                              <1> ;
  2161                              <1> ; ON EXIT :	CY = 1 MEANS ERROR
  2162                              <1> ;-------------------------------------------------------------------------------
  2163                              <1> SETUP_DBL:
  2164 000024B8 8AA7[81A80000]      <1> 	MOV	AH, [DSK_STATE+eDI]	; ACCESS STATE
  2165 000024BE F6C410              <1> 	TEST	AH,MED_DET		; ESTABLISHED STATE ?
  2166 000024C1 757E                <1> 	JNZ	short NO_DBL			; IF ESTABLISHED THEN DOUBLE DONE
  2167                              <1> 
  2168                              <1> ;-----	CHECK FOR TRACK 0 TO SPEED UP ACKNOWLEDGE OF UNFORMATTED DISKETTE
  2169                              <1> 
  2170 000024C3 C605[71A80000]00    <1> 	MOV	byte [SEEK_STATUS],0	; SET RECALIBRATE REQUIRED ON ALL DRIVES
  2171 000024CA E8E0000000          <1> 	CALL	MOTOR_ON		; ENSURE MOTOR STAY ON
  2172 000024CF B500                <1> 	MOV	CH,0			; LOAD TRACK 0
  2173 000024D1 E8D4010000          <1> 	CALL	SEEK			; SEEK TO TRACK 0
  2174 000024D6 E868000000          <1> 	CALL	READ_ID			; READ ID FUNCTION
  2175 000024DB 7249                <1> 	JC	short SD_ERR		; IF ERROR NO TRACK 0
  2176                              <1> 
  2177                              <1> ;-----	INITIALIZE START AND MAX TRACKS (TIMES 2 FOR BOTH HEADS)
  2178                              <1> 
  2179 000024DD 66B95004            <1> 	MOV	CX,0450H 		; START, MAX TRACKS
  2180 000024E1 F687[81A80000]01    <1> 	TEST	byte [DSK_STATE+eDI],TRK_CAPA ; TEST FOR 80 TRACK CAPABILITY
  2181 000024E8 7402                <1> 	JZ	short CNT_OK		; IF NOT COUNT IS SETUP
  2182 000024EA B1A0                <1> 	MOV	CL,0A0H			; MAXIMUM TRACK 1.2 MB
  2183                              <1> 
  2184                              <1> ;	ATTEMPT READ ID OF ALL TRACKS, ALL HEADS UNTIL SUCCESS; UPON SUCCESS,
  2185                              <1> ;	MUST SEE IF ASKED FOR TRACK IN SINGLE STEP MODE = TRACK ID READ; IF NOT
  2186                              <1> ;	THEN SET DOUBLE STEP ON.
  2187                              <1> 
  2188                              <1> CNT_OK:
  2189 000024EC C605[73A80000]FF    <1>         MOV     byte [MOTOR_COUNT], 0FFH ; ENSURE MOTOR STAYS ON FOR OPERATION 
  2190 000024F3 6651                <1> 	PUSH	CX			; SAVE TRACK, COUNT
  2191 000024F5 C605[74A80000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR STATUS, EXPECT ERRORS
  2192 000024FC 6631C0              <1> 	XOR	AX,AX			; CLEAR AX
  2193 000024FF D0ED                <1> 	SHR	CH,1			; HALVE TRACK, CY = HEAD
  2194 00002501 C0D003              <1> 	RCL	AL,3			; AX = HEAD IN CORRECT BIT
  2195 00002504 6650                <1> 	PUSH	AX			; SAVE HEAD
  2196 00002506 E89F010000          <1> 	CALL	SEEK			; SEEK TO TRACK
  2197 0000250B 6658                <1> 	POP	AX			; RESTORE HEAD
  2198 0000250D 6609C7              <1> 	OR	DI,AX			; DI = HEAD OR'ED DRIVE
  2199 00002510 E82E000000          <1> 	CALL	READ_ID			; READ ID HEAD 0
  2200 00002515 9C                  <1> 	PUSHF				; SAVE RETURN FROM READ_ID
  2201 00002516 6681E7FB00          <1> 	AND	DI,11111011B		; TURN OFF HEAD 1 BIT
  2202 0000251B 9D                  <1> 	POPF				; RESTORE ERROR RETURN
  2203 0000251C 6659                <1> 	POP	CX			; RESTORE COUNT
  2204 0000251E 7308                <1> 	JNC	short DO_CHK		; IF OK, ASKED = RETURNED TRACK ?
  2205 00002520 FEC5                <1> 	INC	CH			; INC FOR NEXT TRACK
  2206 00002522 38CD                <1> 	CMP	CH,CL			; REACHED MAXIMUM YET
  2207 00002524 75C6                <1> 	JNZ	short CNT_OK		; CONTINUE TILL ALL TRIED
  2208                              <1> 
  2209                              <1> ;-----	FALL THRU, READ ID FAILED FOR ALL TRACKS
  2210                              <1> 
  2211                              <1> SD_ERR:	
  2212 00002526 F9                  <1> 	STC				; SET CARRY FOR ERROR
  2213 00002527 C3                  <1> 	RETn				; SETUP_DBL ERROR EXIT
  2214                              <1> 
  2215                              <1> DO_CHK:
  2216 00002528 8A0D[78A80000]      <1> 	MOV	CL, [NEC_STATUS+3]	; LOAD RETURNED TRACK
  2217 0000252E 888F[85A80000]      <1> 	MOV	[DSK_TRK+eDI], CL	; STORE TRACK NUMBER
  2218 00002534 D0ED                <1> 	SHR	CH,1			; HALVE TRACK
  2219 00002536 38CD                <1> 	CMP	CH,CL			; IS IT THE SAME AS ASKED FOR TRACK
  2220 00002538 7407                <1> 	JZ	short NO_DBL		; IF SAME THEN NO DOUBLE STEP
  2221 0000253A 808F[81A80000]20    <1> 	OR	byte [DSK_STATE+eDI],DBL_STEP ; TURN ON DOUBLE STEP REQUIRED
  2222                              <1> NO_DBL:
  2223 00002541 F8                  <1> 	CLC				; CLEAR ERROR FLAG
  2224 00002542 C3                  <1> 	RETn
  2225                              <1> 
  2226                              <1> ;-------------------------------------------------------------------------------
  2227                              <1> ; READ_ID
  2228                              <1> ;	READ ID FUNCTION.
  2229                              <1> ;
  2230                              <1> ; ON ENTRY:	DI : BIT 2 = HEAD; BITS 1,0 = DRIVE
  2231                              <1> ;
  2232                              <1> ; ON EXIT: 	DI : BIT 2 IS RESET, BITS 1,0 = DRIVE
  2233                              <1> ;		@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION
  2234                              <1> ;-------------------------------------------------------------------------------
  2235                              <1> READ_ID:
  2236 00002543 B8[60250000]        <1> 	MOV	eAX, ER_3		; MOVE NEC OUTPUT ERROR ADDRESS
  2237 00002548 50                  <1> 	PUSH	eAX
  2238 00002549 B44A                <1> 	MOV	AH,4AH			; READ ID COMMAND
  2239 0000254B E820010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  2240 00002550 6689F8              <1> 	MOV	AX,DI			; DRIVE # TO AH, HEAD 0
  2241 00002553 88C4                <1> 	MOV	AH,AL
  2242 00002555 E816010000          <1> 	CALL	NEC_OUTPUT		; TO CONTROLLER
  2243 0000255A E80BFEFFFF          <1> 	CALL	NEC_TERM		; WAIT FOR OPERATION, GET STATUS
  2244 0000255F 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  2245                              <1> ER_3:
  2246 00002560 C3                  <1> 	RETn
  2247                              <1> 
  2248                              <1> ;-------------------------------------------------------------------------------
  2249                              <1> ; CMOS_TYPE
  2250                              <1> ;	RETURNS DISKETTE TYPE FROM CMOS
  2251                              <1> ;
  2252                              <1> ; ON ENTRY:	DI = DRIVE #
  2253                              <1> ;
  2254                              <1> ; ON EXIT:	AL = TYPE; CY REFLECTS STATUS
  2255                              <1> ;-------------------------------------------------------------------------------
  2256                              <1> 
  2257                              <1> CMOS_TYPE: ; 11/12/2014
  2258 00002561 8A87[BEA20000]      <1> mov	al, [eDI+fd0_type]
  2259 00002567 20C0                <1> and 	al, al ; 18/12/2014
  2260 00002569 C3                  <1> retn
  2261                              <1> 
  2262                              <1> ;CMOS_TYPE:
  2263                              <1> ;	MOV	AL, CMOS_DIAG		; CMOS DIAGNOSTIC STATUS BYTE ADDRESS
  2264                              <1> ;	CALL	CMOS_READ		; GET CMOS STATUS
  2265                              <1> ;	TEST	AL,BAD_BAT+BAD_CKSUM	; BATTERY GOOD AND CHECKSUM VALID
  2266                              <1> ;	STC				; SET CY = 1 INDICATING ERROR FOR RETURN
  2267                              <1> ;	JNZ	short BAD_CM		; ERROR IF EITHER BIT ON
  2268                              <1> ;	MOV	AL,CMOS_DISKETTE	; ADDRESS OF DISKETTE BYTE IN CMOS
  2269                              <1> ;	CALL	CMOS_READ		; GET DISKETTE BYTE
  2270                              <1> ;	OR	DI,DI			; SEE WHICH DRIVE IN QUESTION
  2271                              <1> ;	JNZ	short TB		; IF DRIVE 1, DATA IN LOW NIBBLE
  2272                              <1> ;	ROR	AL,4			; EXCHANGE NIBBLES IF SECOND DRIVE
  2273                              <1> ;TB:
  2274                              <1> ;	AND	AL,0FH			; KEEP ONLY DRIVE DATA, RESET CY, 0
  2275                              <1> ;BAD_CM:
  2276                              <1> ;	RETn				; CY, STATUS OF READ
  2277                              <1> 
  2278                              <1> ;-------------------------------------------------------------------------------
  2279                              <1> ; GET_PARM
  2280                              <1> ;	THIS ROUTINE FETCHES THE INDEXED POINTER FROM THE DISK_BASE
  2281                              <1> ;	BLOCK POINTED TO BY THE DATA VARIABLE @DISK_POINTER. A BYTE FROM
  2282                              <1> ;	THAT TABLE IS THEN MOVED INTO AH, THE INDEX OF THAT BYTE BEING
  2283                              <1> ;	THE PARAMETER IN DL.
  2284                              <1> ;
  2285                              <1> ; ON ENTRY:	DL = INDEX OF BYTE TO BE FETCHED
  2286                              <1> ;
  2287                              <1> ; ON EXIT:	AH = THAT BYTE FROM BLOCK
  2288                              <1> ;		AL,DH DESTROYED
  2289                              <1> ;-------------------------------------------------------------------------------
  2290                              <1> GET_PARM:
  2291                              <1> 	;PUSH	DS
  2292 0000256A 56                  <1> 	PUSH	eSI
  2293                              <1>     	;SUB	AX,AX			; DS = 0, BIOS DATA AREA
  2294                              <1>     	;MOV	DS,AX
  2295                              <1> 	;;mov	ax, cs
  2296                              <1> 	;;mov	ds, ax
  2297                              <1> 	; 08/02/2015 (protected mode modifications, bx -> ebx)
  2298 0000256B 87D3                <1> 	XCHG	eDX,eBX			; BL = INDEX
  2299                              <1> 	;SUB	BH,BH			; BX = INDEX
  2300 0000256D 81E3FF000000        <1> 	and	ebx, 0FFh
  2301                              <1>     	;LDS	SI, [DISK_POINTER]	; POINT TO BLOCK
  2302                              <1> 	;
  2303                              <1> 	; 17/12/2014
  2304 00002573 66A1[B1A20000]      <1> 	mov	ax, [cfd] ; current (AL) and previous fd (AH)
  2305 00002579 38E0                <1> 	cmp	al, ah
  2306 0000257B 7425                <1> 	je	short gpndc
  2307 0000257D A2[B2A20000]        <1> 	mov	[pfd], al ; current drive -> previous drive
  2308 00002582 53                  <1> 	push	ebx ; 08/02/2015
  2309 00002583 88C3                <1> 	mov	bl, al 
  2310                              <1> 	; 11/12/2014
  2311 00002585 8A83[BEA20000]      <1> 	mov	al, [eBX+fd0_type]	; Drive type (0,1,2,3,4)
  2312                              <1> 	; 18/12/2014
  2313 0000258B 20C0                <1> 	and	al, al
  2314 0000258D 7507                <1> 	jnz	short gpdtc
  2315 0000258F BB[9BA20000]        <1> 	mov	ebx, MD_TBL6		; 1.44 MB param. tbl. (default)
  2316 00002594 EB05                <1>         jmp     short gpdpu
  2317                              <1> gpdtc:	
  2318 00002596 E817F9FFFF          <1> 	call	DR_TYPE_CHECK
  2319                              <1> 	; cf = 1 -> eBX points to 1.44MB fd parameter table (default)
  2320                              <1> gpdpu:
  2321 0000259B 891D[38A20000]      <1> 	mov	[DISK_POINTER], ebx
  2322 000025A1 5B                  <1> 	pop	ebx
  2323                              <1> gpndc:
  2324 000025A2 8B35[38A20000]      <1> 	mov	esi, [DISK_POINTER] ; 08/02/2015, si -> esi
  2325 000025A8 8A241E              <1> 	MOV	AH, [eSI+eBX]		; GET THE WORD
  2326 000025AB 87D3                <1> 	XCHG	eDX,eBX			; RESTORE BX
  2327 000025AD 5E                  <1> 	POP	eSI
  2328                              <1> 	;POP	DS
  2329 000025AE C3                  <1> 	RETn
  2330                              <1> 
  2331                              <1> ;-------------------------------------------------------------------------------
  2332                              <1> ; MOTOR_ON
  2333                              <1> ;	TURN MOTOR ON AND WAIT FOR MOTOR START UP TIME. THE @MOTOR_COUNT
  2334                              <1> ;	IS REPLACED WITH A SUFFICIENTLY HIGH NUMBER (0FFH) TO ENSURE
  2335                              <1> ;	THAT THE MOTOR DOES NOT GO OFF DURING THE OPERATION. IF THE
  2336                              <1> ;	MOTOR NEEDED TO BE TURNED ON, THE MULTI-TASKING HOOK FUNCTION
  2337                              <1> ;	(AX=90FDH, INT 15) IS CALLED TELLING THE OPERATING SYSTEM
  2338                              <1> ;	THAT THE BIOS IS ABOUT TO WAIT FOR MOTOR START UP. IF THIS
  2339                              <1> ;	FUNCTION RETURNS WITH CY = 1, IT MEANS THAT THE MINIMUM WAIT
  2340                              <1> ;	HAS BEEN COMPLETED. AT THIS POINT A CHECK IS MADE TO ENSURE
  2341                              <1> ;	THAT THE MOTOR WASN'T TURNED OFF BY THE TIMER. IF THE HOOK DID
  2342                              <1> ;	NOT WAIT, THE WAIT FUNCTION (AH=086H) IS CALLED TO WAIT THE
  2343                              <1> ;	PRESCRIBED AMOUNT OF TIME. IF THE CARRY FLAG IS SET ON RETURN,
  2344                              <1> ;	IT MEANS THAT THE FUNCTION IS IN USE AND DID NOT PERFORM THE
  2345                              <1> ;	WAIT. A TIMER 1 WAIT LOOP WILL THEN DO THE WAIT.
  2346                              <1> ;
  2347                              <1> ; ON ENTRY:	DI = DRIVE #
  2348                              <1> ; ON EXIT:	AX,CX,DX DESTROYED
  2349                              <1> ;-------------------------------------------------------------------------------
  2350                              <1> MOTOR_ON:
  2351 000025AF 53                  <1> 	PUSH	eBX			; SAVE REG.
  2352 000025B0 E82A000000          <1> 	CALL	TURN_ON			; TURN ON MOTOR
  2353 000025B5 7226                <1> 	JC	short MOT_IS_ON		; IF CY=1 NO WAIT
  2354 000025B7 E89BF9FFFF          <1> 	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  2355 000025BC E865F9FFFF          <1> 	CALL	XLAT_NEW		; TRANSLATE STATE TO PRESENT ARCH,
  2356                              <1> 	;CALL	TURN_ON 		; CHECK AGAIN IF MOTOR ON
  2357                              <1> 	;JC	MOT_IS_ON		; IF NO WAIT MEANS IT IS ON
  2358                              <1> M_WAIT:
  2359 000025C1 B20A                <1> 	MOV	DL,10			; GET THE MOTOR WAIT PARAMETER
  2360 000025C3 E8A2FFFFFF          <1> 	CALL	GET_PARM
  2361                              <1> 	;MOV	AL,AH			; AL = MOTOR WAIT PARAMETER
  2362                              <1> 	;XOR	AH,AH			; AX = MOTOR WAIT PARAMETER
  2363                              <1> 	;CMP	AL,8			; SEE IF AT LEAST A SECOND IS SPECIFIED
  2364 000025C8 80FC08              <1> 	cmp	ah, 8
  2365                              <1> 	;JAE	short GP2		; IF YES, CONTINUE
  2366 000025CB 7702                <1> 	ja	short J13
  2367                              <1> 	;MOV	AL,8			; ONE SECOND WAIT FOR MOTOR START UP
  2368 000025CD B408                <1> 	mov	ah, 8
  2369                              <1> 
  2370                              <1> ;-----	AS CONTAINS NUMBER OF 1/8 SECONDS (125000 MICROSECONDS) TO WAIT
  2371                              <1> GP2:	
  2372                              <1> ;----- 	FOLLOWING LOOPS REQUIRED WHEN RTC WAIT FUNCTION IS ALREADY IN USE
  2373                              <1> J13:					; WAIT FOR 1/8 SECOND PER (AL)
  2374 000025CF B95E200000          <1> 	MOV	eCX,8286		; COUNT FOR 1/8 SECOND AT 15.085737 US
  2375 000025D4 E816F3FFFF          <1> 	CALL	WAITF			; GO TO FIXED WAIT ROUTINE
  2376                              <1> 	;DEC	AL			; DECREMENT TIME VALUE
  2377 000025D9 FECC                <1> 	dec	ah
  2378 000025DB 75F2                <1> 	JNZ	short J13		; ARE WE DONE YET
  2379                              <1> MOT_IS_ON:
  2380 000025DD 5B                  <1> 	POP	eBX			; RESTORE REG.
  2381 000025DE C3                  <1> 	RETn
  2382                              <1> 
  2383                              <1> ;-------------------------------------------------------------------------------
  2384                              <1> ; TURN_ON
  2385                              <1> ;	TURN MOTOR ON AND RETURN WAIT STATE.
  2386                              <1> ;
  2387                              <1> ; ON ENTRY:	DI = DRIVE #
  2388                              <1> ;
  2389                              <1> ; ON EXIT:	CY = 0 MEANS WAIT REQUIRED
  2390                              <1> ;		CY = 1 MEANS NO WAIT REQUIRED
  2391                              <1> ;		AX,BX,CX,DX DESTROYED
  2392                              <1> ;-------------------------------------------------------------------------------
  2393                              <1> TURN_ON:
  2394 000025DF 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2395 000025E1 88D9                <1> 	MOV	CL,BL			; CL = DRIVE #
  2396 000025E3 C0C304              <1> 	ROL	BL,4			; BL = DRIVE SELECT
  2397 000025E6 FA                  <1> 	CLI				; NO INTERRUPTS WHILE DETERMINING STATUS
  2398 000025E7 C605[73A80000]FF    <1> 	MOV	byte [MOTOR_COUNT],0FFH	; ENSURE MOTOR STAYS ON FOR OPERATION
  2399 000025EE A0[72A80000]        <1> 	MOV	AL, [MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  2400 000025F3 2430                <1> 	AND	AL,00110000B		; KEEP ONLY DRIVE SELECT BITS
  2401 000025F5 B401                <1> 	MOV	AH,1			; MASK FOR DETERMINING MOTOR BIT
  2402 000025F7 D2E4                <1> 	SHL	AH,CL			; AH = MOTOR ON, A=00000001, B=00000010
  2403                              <1> 
  2404                              <1> ;  AL = DRIVE SELECT FROM @MOTOR_STATUS
  2405                              <1> ;  BL = DRIVE SELECT DESIRED
  2406                              <1> ;  AH = MOTOR ON MASK DESIRED
  2407                              <1> 
  2408 000025F9 38D8                <1> 	CMP	AL,BL			; REQUESTED DRIVE ALREADY SELECTED ?
  2409 000025FB 7508                <1> 	JNZ	short TURN_IT_ON	; IF NOT SELECTED JUMP
  2410 000025FD 8425[72A80000]      <1> 	TEST	AH, [MOTOR_STATUS]	; TEST MOTOR ON BIT
  2411 00002603 7535                <1> 	JNZ	short NO_MOT_WAIT	; JUMP IF MOTOR ON AND SELECTED
  2412                              <1> 
  2413                              <1> TURN_IT_ON:
  2414 00002605 08DC                <1> 	OR	AH,BL			; AH = DRIVE SELECT AND MOTOR ON
  2415 00002607 8A3D[72A80000]      <1> 	MOV	BH,[MOTOR_STATUS]	; SAVE COPY OF @MOTOR_STATUS BEFORE
  2416 0000260D 80E70F              <1> 	AND	BH,00001111B		; KEEP ONLY MOTOR BITS
  2417 00002610 8025[72A80000]CF    <1> 	AND	byte [MOTOR_STATUS],11001111B ; CLEAR OUT DRIVE SELECT
  2418 00002617 0825[72A80000]      <1> 	OR	[MOTOR_STATUS],AH	; OR IN DRIVE SELECTED AND MOTOR ON
  2419 0000261D A0[72A80000]        <1> 	MOV	AL,[MOTOR_STATUS]	; GET DIGITAL OUTPUT REGISTER REFLECTION
  2420 00002622 88C3                <1> 	MOV	BL,AL			; BL=@MOTOR_STATUS AFTER, BH=BEFORE
  2421 00002624 80E30F              <1> 	AND	BL,00001111B		; KEEP ONLY MOTOR BITS
  2422 00002627 FB                  <1> 	STI				; ENABLE INTERRUPTS AGAIN
  2423 00002628 243F                <1> 	AND	AL,00111111B		; STRIP AWAY UNWANTED BITS
  2424 0000262A C0C004              <1> 	ROL	AL,4			; PUT BITS IN DESIRED POSITIONS
  2425 0000262D 0C0C                <1> 	OR	AL,00001100B		; NO RESET, ENABLE DMA/INTERRUPT
  2426 0000262F 66BAF203            <1> 	MOV	DX,03F2H		; SELECT DRIVE AND TURN ON MOTOR
  2427 00002633 EE                  <1> 	OUT	DX,AL
  2428 00002634 38FB                <1> 	CMP	BL,BH			; NEW MOTOR TURNED ON ?
  2429                              <1> 	;JZ	short NO_MOT_WAIT	; NO WAIT REQUIRED IF JUST SELECT
  2430 00002636 7403                <1> 	je	short no_mot_w1 ; 27/02/2015 
  2431 00002638 F8                  <1> 	CLC				; (re)SET CARRY MEANING WAIT
  2432 00002639 C3                  <1> 	RETn
  2433                              <1> 
  2434                              <1> NO_MOT_WAIT:
  2435 0000263A FB                  <1> 	sti
  2436                              <1> no_mot_w1: ; 27/02/2015
  2437 0000263B F9                  <1> 	STC				; SET NO WAIT REQUIRED
  2438                              <1> 	;STI				; INTERRUPTS BACK ON
  2439 0000263C C3                  <1> 	RETn
  2440                              <1> 
  2441                              <1> ;-------------------------------------------------------------------------------
  2442                              <1> ; HD_WAIT
  2443                              <1> ;	WAIT FOR HEAD SETTLE TIME.
  2444                              <1> ;
  2445                              <1> ; ON ENTRY:	DI = DRIVE #
  2446                              <1> ;
  2447                              <1> ; ON EXIT:	AX,BX,CX,DX DESTROYED
  2448                              <1> ;-------------------------------------------------------------------------------
  2449                              <1> HD_WAIT:
  2450 0000263D B209                <1> 	MOV	DL,9			; GET HEAD SETTLE PARAMETER
  2451 0000263F E826FFFFFF          <1> 	CALL	GET_PARM
  2452 00002644 08E4                <1> 	or	ah, ah	; 17/12/2014
  2453 00002646 7519                <1> 	jnz	short DO_WAT
  2454 00002648 F605[72A80000]80    <1>         TEST    byte [MOTOR_STATUS],10000000B ; SEE IF A WRITE OPERATION
  2455                              <1> 	;JZ	short ISNT_WRITE	; IF NOT, DO NOT ENFORCE ANY VALUES
  2456                              <1> 	;OR	AH,AH			; CHECK FOR ANY WAIT?
  2457                              <1> 	;JNZ	short DO_WAT		; IF THERE DO NOT ENFORCE
  2458 0000264F 741E                <1> 	jz	short HW_DONE
  2459 00002651 B40F                <1> 	MOV	AH,HD12_SETTLE		; LOAD 1.2M HEAD SETTLE MINIMUM
  2460 00002653 8A87[81A80000]      <1> 	MOV	AL,[DSK_STATE+eDI]	; LOAD STATE
  2461 00002659 24C0                <1> 	AND	AL,RATE_MSK		; KEEP ONLY RATE
  2462 0000265B 3C80                <1> 	CMP	AL,RATE_250		; 1.2 M DRIVE ?
  2463 0000265D 7502                <1> 	JNZ	short DO_WAT		; DEFAULT HEAD SETTLE LOADED
  2464                              <1> ;GP3:
  2465 0000265F B414                <1> 	MOV	AH,HD320_SETTLE		; USE 320/360 HEAD SETTLE
  2466                              <1> ;	JMP	SHORT DO_WAT
  2467                              <1> 
  2468                              <1> ;ISNT_WRITE:
  2469                              <1> ;	OR	AH,AH			; CHECK FOR NO WAIT
  2470                              <1> ;	JZ	short HW_DONE		; IF NOT WRITE AND 0 ITS OK
  2471                              <1> 
  2472                              <1> ;-----	AH CONTAINS NUMBER OF MILLISECONDS TO WAIT
  2473                              <1> DO_WAT:
  2474                              <1> ;	MOV	AL,AH			; AL = # MILLISECONDS
  2475                              <1> ;	;XOR	AH,AH			; AX = # MILLISECONDS
  2476                              <1> J29:					; 	1 MILLISECOND LOOP
  2477                              <1> 	;mov	cx, WAIT_FDU_HEAD_SETTLE ; 33 ; 1 ms in 30 micro units.
  2478 00002661 B942000000          <1> 	MOV	eCX,66			; COUNT AT 15.085737 US PER COUNT
  2479 00002666 E884F2FFFF          <1> 	CALL	WAITF			; DELAY FOR 1 MILLISECOND
  2480                              <1> 	;DEC	AL			; DECREMENT THE COUNT
  2481 0000266B FECC                <1> 	dec	ah
  2482 0000266D 75F2                <1> 	JNZ	short J29		; DO AL MILLISECOND # OF TIMES
  2483                              <1> HW_DONE:
  2484 0000266F C3                  <1> 	RETn
  2485                              <1> 
  2486                              <1> ;-------------------------------------------------------------------------------
  2487                              <1> ; NEC_OUTPUT
  2488                              <1> ;	THIS ROUTINE SENDS A BYTE TO THE NEC CONTROLLER AFTER TESTING
  2489                              <1> ;	FOR CORRECT DIRECTION AND CONTROLLER READY THIS ROUTINE WILL
  2490                              <1> ;	TIME OUT IF THE BYTE IS NOT ACCEPTED WITHIN A REASONABLE AMOUNT
  2491                              <1> ;	OF TIME, SETTING THE DISKETTE STATUS ON COMPLETION.
  2492                              <1> ; 
  2493                              <1> ; ON ENTRY: 	AH = BYTE TO BE OUTPUT
  2494                              <1> ;
  2495                              <1> ; ON EXIT:	CY = 0  SUCCESS
  2496                              <1> ;		CY = 1  FAILURE -- DISKETTE STATUS UPDATED
  2497                              <1> ;		        IF A FAILURE HAS OCCURRED, THE RETURN IS MADE ONE LEVEL
  2498                              <1> ;		        HIGHER THAN THE CALLER OF NEC OUTPUT. THIS REMOVES THE
  2499                              <1> ;		        REQUIREMENT OF TESTING AFTER EVERY CALL OF NEC_OUTPUT.
  2500                              <1> ;		AX,CX,DX DESTROYED
  2501                              <1> ;-------------------------------------------------------------------------------
  2502                              <1> 
  2503                              <1> ; 09/12/2014 [Erdogan Tan] 
  2504                              <1> ;	(from 'PS2 Hardware Interface Tech. Ref. May 88', Page 09-05.)
  2505                              <1> ; Diskette Drive Controller Status Register (3F4h)
  2506                              <1> ;	This read only register facilitates the transfer of data between
  2507                              <1> ;	the system microprocessor and the controller.
  2508                              <1> ; Bit 7 - When set to 1, the Data register is ready to transfer data 
  2509                              <1> ;	  with the system micrprocessor.
  2510                              <1> ; Bit 6 - The direction of data transfer. If this bit is set to 0,
  2511                              <1> ;	  the transfer is to the controller.
  2512                              <1> ; Bit 5 - When this bit is set to 1, the controller is in the non-DMA mode.
  2513                              <1> ; Bit 4 - When this bit is set to 1, a Read or Write command is being executed.
  2514                              <1> ; Bit 3 - Reserved.
  2515                              <1> ; Bit 2 - Reserved.
  2516                              <1> ; Bit 1 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  2517                              <1> ; Bit 0 - When this bit is set to 1, dskette drive 1 is in the seek mode.
  2518                              <1> 
  2519                              <1> ; Data Register (3F5h)
  2520                              <1> ; This read/write register passes data, commands and parameters, and provides
  2521                              <1> ; diskette status information.
  2522                              <1>   		
  2523                              <1> NEC_OUTPUT:
  2524                              <1> 	;PUSH	BX			; SAVE REG.
  2525 00002670 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  2526                              <1> 	;MOV	BL,2			; HIGH ORDER COUNTER
  2527                              <1> 	;XOR	CX,CX			; COUNT FOR TIME OUT
  2528                              <1> 	; 16/12/2014
  2529                              <1> 	; waiting for (max.) 0.5 seconds
  2530                              <1>         ;;mov     byte [wait_count], 0 ;; 27/02/2015
  2531                              <1> 	;
  2532                              <1> 	; 17/12/2014
  2533                              <1> 	; Modified from AWARD BIOS 1999 - ADISK.ASM - SEND_COMMAND
  2534                              <1> 	;
  2535                              <1> 	;WAIT_FOR_PORT:	Waits for a bit at a port pointed to by DX to
  2536                              <1> 	;		go on.
  2537                              <1> 	;INPUT:
  2538                              <1> 	;	AH=Mask for isolation bits.
  2539                              <1> 	;	AL=pattern to look for.
  2540                              <1> 	;	DX=Port to test for
  2541                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  2542                              <1> 	;	     (normally 30 microseconds per period.)
  2543                              <1> 	;
  2544                              <1> 	;WFP_SHORT:  
  2545                              <1> 	;	Wait for port if refresh cycle is short (15-80 Us range).
  2546                              <1> 	;
  2547                              <1> 
  2548                              <1> ;	mov	bl, WAIT_FDU_SEND_HI+1	; 0+1
  2549                              <1> ;	mov	cx, WAIT_FDU_SEND_LO	; 16667
  2550 00002674 B91B410000          <1> 	mov	ecx, WAIT_FDU_SEND_LH   ; 16667 (27/02/2015)
  2551                              <1> ;
  2552                              <1> ;WFPS_OUTER_LP:
  2553                              <1> ;	;
  2554                              <1> ;WFPS_CHECK_PORT:
  2555                              <1> J23:
  2556 00002679 EC                  <1> 	IN	AL,DX			; GET STATUS
  2557 0000267A 24C0                <1> 	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  2558 0000267C 3C80                <1> 	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  2559 0000267E 7418                <1> 	JZ	short J27		; STATUS AND DIRECTION OK
  2560                              <1> WFPS_HI:
  2561 00002680 E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  2562 00002682 A810                <1> 	TEST	AL,010H			; transition on memory
  2563 00002684 75FA                <1> 	JNZ	SHORT WFPS_HI		; refresh.
  2564                              <1> WFPS_LO:
  2565 00002686 E461                <1> 	IN	AL, PORT_B		; SYS1
  2566 00002688 A810                <1> 	TEST	AL,010H
  2567 0000268A 74FA                <1> 	JZ	SHORT WFPS_LO
  2568                              <1> 	;LOOP	SHORT WFPS_CHECK_PORT
  2569 0000268C E2EB                <1> 	loop	J23	; 27/02/2015
  2570                              <1> ;	;
  2571                              <1> ;	dec	bl
  2572                              <1> ;	jnz	short WFPS_OUTER_LP
  2573                              <1> ;	jmp	short WFPS_TIMEOUT	; fail
  2574                              <1> ;J23:
  2575                              <1> ;	IN	AL,DX			; GET STATUS
  2576                              <1> ;	AND	AL,11000000B		; KEEP STATUS AND DIRECTION
  2577                              <1> ;	CMP	AL,10000000B		; STATUS 1 AND DIRECTION 0 ?
  2578                              <1> ;	JZ	short J27		; STATUS AND DIRECTION OK
  2579                              <1> 	;LOOP	J23			; CONTINUE TILL CX EXHAUSTED
  2580                              <1> 	;DEC	BL			; DECREMENT COUNTER
  2581                              <1> 	;JNZ	short J23		; REPEAT TILL DELAY FINISHED, CX = 0
  2582                              <1>    
  2583                              <1> 	;;27/02/2015
  2584                              <1> 	;16/12/2014
  2585                              <1>         ;;cmp     byte [wait_count], 10   ; (10/18.2 seconds)
  2586                              <1> 	;;jb	short J23
  2587                              <1> 
  2588                              <1> ;WFPS_TIMEOUT:
  2589                              <1> 
  2590                              <1> ;-----	FALL THRU TO ERROR RETURN
  2591                              <1> 
  2592 0000268E 800D[74A80000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  2593                              <1> 	;POP	BX			; RESTORE REG.
  2594 00002695 58                  <1> 	POP	eAX ; 08/02/2015	; DISCARD THE RETURN ADDRESS
  2595 00002696 F9                  <1> 	STC				; INDICATE ERROR TO CALLER
  2596 00002697 C3                  <1> 	RETn
  2597                              <1> 
  2598                              <1> ;-----	DIRECTION AND STATUS OK; OUTPUT BYTE
  2599                              <1> 
  2600                              <1> J27:	
  2601 00002698 88E0                <1> 	MOV	AL,AH			; GET BYTE TO OUTPUT
  2602 0000269A 6642                <1> 	INC	DX			; DATA PORT = STATUS PORT + 1
  2603 0000269C EE                  <1> 	OUT	DX,AL			; OUTPUT THE BYTE
  2604                              <1> 	;;NEWIODELAY  ;; 27/02/2015
  2605                              <1> 	; 27/02/2015
  2606 0000269D 9C                  <1> 	PUSHF				; SAVE FLAGS
  2607 0000269E B903000000          <1> 	MOV	eCX, 3			; 30 TO 45 MICROSECONDS WAIT FOR
  2608 000026A3 E847F2FFFF          <1> 	CALL 	WAITF			; NEC FLAGS UPDATE CYCLE
  2609 000026A8 9D                  <1> 	POPF				; RESTORE FLAGS FOR EXIT
  2610                              <1> 	;POP	BX			; RESTORE REG
  2611 000026A9 C3                  <1> 	RETn				; CY = 0 FROM TEST INSTRUCTION
  2612                              <1> 
  2613                              <1> ;-------------------------------------------------------------------------------
  2614                              <1> ; SEEK
  2615                              <1> ;	THIS ROUTINE WILL MOVE THE HEAD ON THE NAMED DRIVE TO THE NAMED
  2616                              <1> ;	TRACK. IF THE DRIVE HAS NOT BEEN ACCESSED SINCE THE DRIVE
  2617                              <1> ;	RESET COMMAND WAS ISSUED, THE DRIVE WILL BE RECALIBRATED.
  2618                              <1> ;
  2619                              <1> ; ON ENTRY:	DI = DRIVE #
  2620                              <1> ;		CH = TRACK #
  2621                              <1> ;
  2622                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2623                              <1> ;		AX,BX,CX DX DESTROYED
  2624                              <1> ;-------------------------------------------------------------------------------
  2625                              <1> SEEK:
  2626 000026AA 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2627 000026AC B001                <1> 	MOV	AL,1			; ESTABLISH MASK FOR RECALIBRATE TEST
  2628 000026AE 86CB                <1> 	XCHG	CL,BL			; SET DRIVE VALULE INTO CL
  2629 000026B0 D2C0                <1> 	ROL	AL,CL			; SHIFT MASK BY THE DRIVE VALUE
  2630 000026B2 86CB                <1> 	XCHG	CL,BL			; RECOVER TRACK VALUE
  2631 000026B4 8405[71A80000]      <1> 	TEST	AL,[SEEK_STATUS]	; TEST FOR RECALIBRATE REQUIRED
  2632 000026BA 7526                <1> 	JNZ	short J28A		; JUMP IF RECALIBRATE NOT REQUIRED
  2633                              <1> 
  2634 000026BC 0805[71A80000]      <1> 	OR	[SEEK_STATUS],AL	; TURN ON THE NO RECALIBRATE BIT IN FLAG
  2635 000026C2 E862000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  2636 000026C7 730E                <1> 	JNC	short AFT_RECAL		; RECALIBRATE DONE
  2637                              <1> 
  2638                              <1> ;-----	ISSUE RECALIBRATE FOR 80 TRACK DISKETTES
  2639                              <1> 
  2640 000026C9 C605[74A80000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; CLEAR OUT INVALID STATUS
  2641 000026D0 E854000000          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  2642 000026D5 7251                <1> 	JC	short RB		; IF RECALIBRATE FAILS TWICE THEN ERROR
  2643                              <1> 
  2644                              <1> AFT_RECAL:
  2645 000026D7 C687[85A80000]00    <1>         MOV     byte [DSK_TRK+eDI],0    ; SAVE NEW CYLINDER AS PRESENT POSITION
  2646 000026DE 08ED                <1> 	OR	CH,CH			; CHECK FOR SEEK TO TRACK 0
  2647 000026E0 743F                <1> 	JZ	short DO_WAIT		; HEAD SETTLE, CY = 0 IF JUMP
  2648                              <1> 
  2649                              <1> ;-----	DRIVE IS IN SYNCHRONIZATION WITH CONTROLLER, SEEK TO TRACK
  2650                              <1> 
  2651 000026E2 F687[81A80000]20    <1> J28A:	TEST	byte [DSK_STATE+eDI],DBL_STEP ; CHECK FOR DOUBLE STEP REQUIRED
  2652 000026E9 7402                <1> 	JZ	short _R7		; SINGLE STEP REQUIRED BYPASS DOUBLE
  2653 000026EB D0E5                <1> 	SHL	CH,1			; DOUBLE NUMBER OF STEP TO TAKE
  2654                              <1> 
  2655 000026ED 3AAF[85A80000]      <1> _R7:	CMP	CH, [DSK_TRK+eDI]	; SEE IF ALREADY AT THE DESIRED TRACK
  2656 000026F3 7433                <1> 	JE	short RB		; IF YES, DO NOT NEED TO SEEK
  2657                              <1> 
  2658 000026F5 BA[28270000]        <1> 	MOV	eDX, NEC_ERR		; LOAD RETURN ADDRESS
  2659 000026FA 52                  <1> 	PUSH	eDX ; (*)		; ON STACK FOR NEC OUTPUT ERROR
  2660 000026FB 88AF[85A80000]      <1> 	MOV	[DSK_TRK+eDI],CH	; SAVE NEW CYLINDER AS PRESENT POSITION
  2661 00002701 B40F                <1> 	MOV	AH,0FH			; SEEK COMMAND TO NEC
  2662 00002703 E868FFFFFF          <1> 	CALL	NEC_OUTPUT
  2663 00002708 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2664 0000270A 88DC                <1> 	MOV	AH,BL			; OUTPUT DRIVE NUMBER
  2665 0000270C E85FFFFFFF          <1> 	CALL	NEC_OUTPUT
  2666 00002711 8AA7[85A80000]      <1> 	MOV	AH, [DSK_TRK+eDI]	; GET CYLINDER NUMBER
  2667 00002717 E854FFFFFF          <1> 	CALL	NEC_OUTPUT
  2668 0000271C E829000000          <1> 	CALL	CHK_STAT_2		; ENDING INTERRUPT AND SENSE STATUS
  2669                              <1> 
  2670                              <1> ;-----	WAIT FOR HEAD SETTLE
  2671                              <1> 
  2672                              <1> DO_WAIT:
  2673 00002721 9C                  <1> 	PUSHF				; SAVE STATUS
  2674 00002722 E816FFFFFF          <1> 	CALL	HD_WAIT			; WAIT FOR HEAD SETTLE TIME
  2675 00002727 9D                  <1> 	POPF				; RESTORE STATUS
  2676                              <1> RB:
  2677                              <1> NEC_ERR:
  2678                              <1> 	; 08/02/2015 (code trick here from original IBM PC/AT DISKETTE.ASM)
  2679                              <1> 	; (*) nec_err -> retn (push edx -> pop edx) -> nec_err -> retn
  2680 00002728 C3                  <1> 	RETn				; RETURN TO CALLER
  2681                              <1> 
  2682                              <1> ;-------------------------------------------------------------------------------
  2683                              <1> ; RECAL
  2684                              <1> ;	RECALIBRATE DRIVE
  2685                              <1> ;
  2686                              <1> ; ON ENTRY:	DI = DRIVE #
  2687                              <1> ;
  2688                              <1> ; ON EXIT:	CY REFLECTS STATUS OF OPERATION.
  2689                              <1> ;-------------------------------------------------------------------------------
  2690                              <1> RECAL:
  2691 00002729 6651                <1> 	PUSH	CX
  2692 0000272B B8[47270000]        <1> 	MOV	eAX, RC_BACK		; LOAD NEC_OUTPUT ERROR
  2693 00002730 50                  <1> 	PUSH	eAX
  2694 00002731 B407                <1> 	MOV	AH,07H			; RECALIBRATE COMMAND
  2695 00002733 E838FFFFFF          <1> 	CALL	NEC_OUTPUT
  2696 00002738 89FB                <1> 	MOV	eBX,eDI			; BX = DRIVE #
  2697 0000273A 88DC                <1> 	MOV	AH,BL
  2698 0000273C E82FFFFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT THE DRIVE NUMBER
  2699 00002741 E804000000          <1> 	CALL	CHK_STAT_2		; GET THE INTERRUPT AND SENSE INT STATUS
  2700 00002746 58                  <1> 	POP	eAX			; THROW AWAY ERROR
  2701                              <1> RC_BACK:
  2702 00002747 6659                <1> 	POP	CX
  2703 00002749 C3                  <1> 	RETn
  2704                              <1> 
  2705                              <1> ;-------------------------------------------------------------------------------
  2706                              <1> ; CHK_STAT_2
  2707                              <1> ;	THIS ROUTINE HANDLES THE INTERRUPT RECEIVED AFTER RECALIBRATE,
  2708                              <1> ;	OR SEEK TO THE ADAPTER. THE INTERRUPT IS WAITED FOR, THE
  2709                              <1> ;	INTERRUPT STATUS SENSED, AND THE RESULT RETURNED TO THE CALLER.
  2710                              <1> ;
  2711                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2712                              <1> ;-------------------------------------------------------------------------------
  2713                              <1> CHK_STAT_2:
  2714 0000274A B8[72270000]        <1>         MOV     eAX, CS_BACK            ; LOAD NEC_OUTPUT ERROR ADDRESS
  2715 0000274F 50                  <1> 	PUSH	eAX
  2716 00002750 E828000000          <1> 	CALL	WAIT_INT		; WAIT FOR THE INTERRUPT
  2717 00002755 721A                <1> 	JC	short J34		; IF ERROR, RETURN IT
  2718 00002757 B408                <1> 	MOV	AH,08H			; SENSE INTERRUPT STATUS COMMAND
  2719 00002759 E812FFFFFF          <1> 	CALL	NEC_OUTPUT
  2720 0000275E E84A000000          <1> 	CALL	RESULTS			; READ IN THE RESULTS
  2721 00002763 720C                <1> 	JC	short J34
  2722 00002765 A0[75A80000]        <1> 	MOV	AL,[NEC_STATUS]		; GET THE FIRST STATUS BYTE
  2723 0000276A 2460                <1> 	AND	AL,01100000B		; ISOLATE THE BITS
  2724 0000276C 3C60                <1> 	CMP	AL,01100000B		; TEST FOR CORRECT VALUE
  2725 0000276E 7403                <1> 	JZ	short J35		; IF ERROR, GO MARK IT
  2726 00002770 F8                  <1> 	CLC				; GOOD RETURN
  2727                              <1> J34:
  2728 00002771 58                  <1> 	POP	eAX			; THROW AWAY ERROR RETURN
  2729                              <1> CS_BACK:
  2730 00002772 C3                  <1> 	RETn
  2731                              <1> J35:
  2732 00002773 800D[74A80000]40    <1> 	OR	byte [DSKETTE_STATUS], BAD_SEEK
  2733 0000277A F9                  <1> 	STC				; ERROR RETURN CODE
  2734 0000277B EBF4                <1> 	JMP	SHORT J34
  2735                              <1> 
  2736                              <1> ;-------------------------------------------------------------------------------
  2737                              <1> ; WAIT_INT
  2738                              <1> ;	THIS ROUTINE WAITS FOR AN INTERRUPT TO OCCUR A TIME OUT ROUTINE
  2739                              <1> ;	TAKES PLACE DURING THE WAIT, SO THAT AN ERROR MAY BE RETURNED
  2740                              <1> ;	IF THE DRIVE IS NOT READY.
  2741                              <1> ;
  2742                              <1> ; ON EXIT: 	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2743                              <1> ;-------------------------------------------------------------------------------
  2744                              <1> 
  2745                              <1> ; 17/12/2014
  2746                              <1> ; 2.5 seconds waiting !
  2747                              <1> ;(AWARD BIOS - 1999, WAIT_FDU_INT_LOW, WAIT_FDU_INT_HI)
  2748                              <1> ; amount of time to wait for completion interrupt from NEC.
  2749                              <1> 
  2750                              <1> 
  2751                              <1> WAIT_INT:
  2752 0000277D FB                  <1> 	STI				; TURN ON INTERRUPTS, JUST IN CASE
  2753 0000277E F8                  <1> 	CLC				; CLEAR TIMEOUT INDICATOR
  2754                              <1>        ;MOV	BL,10			; CLEAR THE COUNTERS
  2755                              <1>        ;XOR	CX,CX			; FOR 2 SECOND WAIT
  2756                              <1> 
  2757                              <1> 	; Modification from AWARD BIOS - 1999 (ATORGS.ASM, WAIT
  2758                              <1> 	;
  2759                              <1> 	;WAIT_FOR_MEM:	
  2760                              <1> 	;	Waits for a bit at a specified memory location pointed
  2761                              <1> 	;	to by ES:[DI] to become set.
  2762                              <1> 	;INPUT:
  2763                              <1> 	;	AH=Mask to test with.
  2764                              <1> 	;	ES:[DI] = memory location to watch.
  2765                              <1> 	;	BH:CX=Number of memory refresh periods to delay.
  2766                              <1> 	;	     (normally 30 microseconds per period.)
  2767                              <1> 
  2768                              <1> 	; waiting for (max.) 2.5 secs in 30 micro units.
  2769                              <1> ;	mov 	cx, WAIT_FDU_INT_LO		; 017798
  2770                              <1> ;;	mov 	bl, WAIT_FDU_INT_HI
  2771                              <1> ;	mov 	bl, WAIT_FDU_INT_HI + 1
  2772                              <1> 	; 27/02/2015
  2773 0000277F B986450100          <1> 	mov 	ecx, WAIT_FDU_INT_LH	; 83334 (2.5 seconds)		
  2774                              <1> WFMS_CHECK_MEM:
  2775 00002784 F605[71A80000]80    <1> 	test	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  2776 0000278B 7516                <1>         jnz     short J37
  2777                              <1> WFMS_HI:
  2778 0000278D E461                <1> 	IN	AL,PORT_B  ; 061h	; SYS1, wait for lo to hi
  2779 0000278F A810                <1> 	TEST	AL,010H			; transition on memory
  2780 00002791 75FA                <1> 	JNZ	SHORT WFMS_HI		; refresh.
  2781                              <1> WFMS_LO:
  2782 00002793 E461                <1> 	IN	AL,PORT_B		;SYS1
  2783 00002795 A810                <1> 	TEST	AL,010H
  2784 00002797 74FA                <1> 	JZ	SHORT WFMS_LO
  2785 00002799 E2E9                <1>         LOOP    WFMS_CHECK_MEM
  2786                              <1> ;WFMS_OUTER_LP:
  2787                              <1> ;;	or	bl, bl			; check outer counter
  2788                              <1> ;;	jz	short J36A		; WFMS_TIMEOUT
  2789                              <1> ;	dec	bl
  2790                              <1> ;	jz	short J36A	
  2791                              <1> ;	jmp	short WFMS_CHECK_MEM
  2792                              <1> 
  2793                              <1> 	;17/12/2014
  2794                              <1> 	;16/12/2014
  2795                              <1> ;        mov     byte [wait_count], 0    ; Reset (INT 08H) counter
  2796                              <1> ;J36:
  2797                              <1> ;	TEST	byte [SEEK_STATUS],INT_FLAG ; TEST FOR INTERRUPT OCCURRING
  2798                              <1> ;	JNZ	short J37
  2799                              <1> 	;16/12/2014
  2800                              <1> 	;LOOP	J36			; COUNT DOWN WHILE WAITING
  2801                              <1> 	;DEC	BL			; SECOND LEVEL COUNTER
  2802                              <1> 	;JNZ	short J36
  2803                              <1> ;       cmp     byte [wait_count], 46   ; (46/18.2 seconds)
  2804                              <1> ;	jb	short J36
  2805                              <1> 
  2806                              <1> ;WFMS_TIMEOUT:
  2807                              <1> ;J36A:
  2808 0000279B 800D[74A80000]80    <1> 	OR	byte [DSKETTE_STATUS], TIME_OUT ; NOTHING HAPPENED
  2809 000027A2 F9                  <1> 	STC				; ERROR RETURN
  2810                              <1> J37:
  2811 000027A3 9C                  <1> 	PUSHF				; SAVE CURRENT CARRY
  2812 000027A4 8025[71A80000]7F    <1> 	AND	byte [SEEK_STATUS], ~INT_FLAG ; TURN OFF INTERRUPT FLAG
  2813 000027AB 9D                  <1> 	POPF				; RECOVER CARRY
  2814 000027AC C3                  <1> 	RETn				; GOOD RETURN CODE
  2815                              <1> 
  2816                              <1> ;-------------------------------------------------------------------------------
  2817                              <1> ; RESULTS
  2818                              <1> ;	THIS ROUTINE WILL READ ANYTHING THAT THE NEC CONTROLLER RETURNS 
  2819                              <1> ;	FOLLOWING AN INTERRUPT.
  2820                              <1> ;
  2821                              <1> ; ON EXIT:	@DSKETTE_STATUS, CY REFLECT STATUS OF OPERATION.
  2822                              <1> ;		AX,BX,CX,DX DESTROYED
  2823                              <1> ;-------------------------------------------------------------------------------
  2824                              <1> RESULTS:
  2825 000027AD 57                  <1> 	PUSH	eDI
  2826 000027AE BF[75A80000]        <1> 	MOV	eDI, NEC_STATUS		; POINTER TO DATA AREA
  2827 000027B3 B307                <1> 	MOV	BL,7			; MAX STATUS BYTES
  2828 000027B5 66BAF403            <1> 	MOV	DX,03F4H		; STATUS PORT
  2829                              <1> 
  2830                              <1> ;-----	WAIT FOR REQUEST FOR MASTER
  2831                              <1> 
  2832                              <1> _R10: 
  2833                              <1> 	; 16/12/2014
  2834                              <1> 	; wait for (max) 0.5 seconds
  2835                              <1> 	;MOV	BH,2			; HIGH ORDER COUNTER
  2836                              <1> 	;XOR	CX,CX			; COUNTER
  2837                              <1> 
  2838                              <1> 	;Time to wait while waiting for each byte of NEC results = .5
  2839                              <1> 	;seconds.  .5 seconds = 500,000 micros.  500,000/30 = 16,667.
  2840                              <1> 	; 27/02/2015
  2841 000027B9 B91B410000          <1> 	mov 	ecx, WAIT_FDU_RESULTS_LH ; 16667  
  2842                              <1> 	;mov	cx, WAIT_FDU_RESULTS_LO  ; 16667
  2843                              <1> 	;mov	bh, WAIT_FDU_RESULTS_HI+1 ; 0+1
  2844                              <1> 
  2845                              <1> WFPSR_OUTER_LP:
  2846                              <1> 	;
  2847                              <1> WFPSR_CHECK_PORT:
  2848                              <1> J39:					; WAIT FOR MASTER
  2849 000027BE EC                  <1> 	IN	AL,DX			; GET STATUS
  2850 000027BF 24C0                <1> 	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  2851 000027C1 3CC0                <1> 	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  2852 000027C3 7418                <1> 	JZ	short J42		; STATUS AND DIRECTION OK
  2853                              <1> WFPSR_HI:
  2854 000027C5 E461                <1> 	IN	AL, PORT_B	;061h	; SYS1	; wait for hi to lo
  2855 000027C7 A810                <1> 	TEST	AL,010H			; transition on memory
  2856 000027C9 75FA                <1> 	JNZ	SHORT WFPSR_HI		; refresh.
  2857                              <1> WFPSR_LO:
  2858 000027CB E461                <1> 	IN	AL, PORT_B		; SYS1
  2859 000027CD A810                <1> 	TEST	AL,010H
  2860 000027CF 74FA                <1> 	JZ	SHORT WFPSR_LO
  2861 000027D1 E2EB                <1>         LOOP    WFPSR_CHECK_PORT
  2862                              <1> 	;; 27/02/2015
  2863                              <1> 	;;dec	bh
  2864                              <1> 	;;jnz	short WFPSR_OUTER_LP
  2865                              <1> 	;jmp	short WFPSR_TIMEOUT	; fail
  2866                              <1> 
  2867                              <1> 	;;mov	byte [wait_count], 0
  2868                              <1> ;J39:					; WAIT FOR MASTER
  2869                              <1> ;	IN	AL,DX			; GET STATUS
  2870                              <1> ;	AND	AL,11000000B		; KEEP ONLY STATUS AND DIRECTION
  2871                              <1> ;	CMP	AL,11000000B		; STATUS 1 AND DIRECTION 1 ?
  2872                              <1> ;	JZ	short J42		; STATUS AND DIRECTION OK
  2873                              <1> 	;LOOP	J39			; LOOP TILL TIMEOUT
  2874                              <1> 	;DEC	BH			; DECREMENT HIGH ORDER COUNTER
  2875                              <1> 	;JNZ	short J39		; REPEAT TILL DELAY DONE
  2876                              <1> 	;
  2877                              <1> 	;;cmp	byte [wait_count], 10  ; (10/18.2 seconds)
  2878                              <1> 	;;jb	short J39	
  2879                              <1> 
  2880                              <1> ;WFPSR_TIMEOUT:
  2881 000027D3 800D[74A80000]80    <1> 	OR	byte [DSKETTE_STATUS],TIME_OUT
  2882 000027DA F9                  <1> 	STC				; SET ERROR RETURN
  2883 000027DB EB29                <1> 	JMP	SHORT POPRES		; POP REGISTERS AND RETURN
  2884                              <1> 
  2885                              <1> ;-----	READ IN THE STATUS
  2886                              <1> 
  2887                              <1> J42:
  2888 000027DD EB00                <1> 	JMP	$+2			; I/O DELAY
  2889 000027DF 6642                <1> 	INC	DX			; POINT AT DATA PORT
  2890 000027E1 EC                  <1> 	IN	AL,DX			; GET THE DATA
  2891                              <1> 	; 16/12/2014
  2892                              <1> 	NEWIODELAY
  2892 000027E2 E6EB                <2>  out 0ebh,al
  2893 000027E4 8807                <1>         MOV     [eDI],AL                ; STORE THE BYTE
  2894 000027E6 47                  <1> 	INC	eDI			; INCREMENT THE POINTER
  2895                              <1> 	; 16/12/2014
  2896                              <1> ;	push	cx
  2897                              <1> ;	mov	cx, 30
  2898                              <1> ;wdw2:
  2899                              <1> ;	NEWIODELAY
  2900                              <1> ;	loop	wdw2
  2901                              <1> ;	pop	cx
  2902                              <1> 
  2903 000027E7 B903000000          <1> 	MOV	eCX,3			; MINIMUM 24 MICROSECONDS FOR NEC
  2904 000027EC E8FEF0FFFF          <1> 	CALL	WAITF			; WAIT 30 TO 45 MICROSECONDS
  2905 000027F1 664A                <1> 	DEC	DX			; POINT AT STATUS PORT
  2906 000027F3 EC                  <1> 	IN	AL,DX			; GET STATUS
  2907                              <1> 	; 16/12/2014
  2908                              <1> 	NEWIODELAY
  2908 000027F4 E6EB                <2>  out 0ebh,al
  2909                              <1> 	;
  2910 000027F6 A810                <1> 	TEST	AL,00010000B		; TEST FOR NEC STILL BUSY
  2911 000027F8 740C                <1> 	JZ	short POPRES		; RESULTS DONE ?
  2912                              <1> 
  2913 000027FA FECB                <1> 	DEC	BL			; DECREMENT THE STATUS COUNTER
  2914 000027FC 75BB                <1>         JNZ     short _R10              ; GO BACK FOR MORE
  2915 000027FE 800D[74A80000]20    <1> 	OR	byte [DSKETTE_STATUS],BAD_NEC ; TOO MANY STATUS BYTES
  2916 00002805 F9                  <1> 	STC				; SET ERROR FLAG
  2917                              <1> 
  2918                              <1> ;-----	RESULT OPERATION IS DONE
  2919                              <1> POPRES:
  2920 00002806 5F                  <1> 	POP	eDI
  2921 00002807 C3                  <1> 	RETn				; RETURN WITH CARRY SET
  2922                              <1> 
  2923                              <1> ;-------------------------------------------------------------------------------
  2924                              <1> ; READ_DSKCHNG
  2925                              <1> ;	READS THE STATE OF THE DISK CHANGE LINE.
  2926                              <1> ;
  2927                              <1> ; ON ENTRY:	DI = DRIVE #
  2928                              <1> ;
  2929                              <1> ; ON EXIT:	DI = DRIVE #
  2930                              <1> ;		ZF = 0 : DISK CHANGE LINE INACTIVE
  2931                              <1> ;		ZF = 1 : DISK CHANGE LINE ACTIVE
  2932                              <1> ;		AX,CX,DX DESTROYED
  2933                              <1> ;-------------------------------------------------------------------------------
  2934                              <1> READ_DSKCHNG:
  2935 00002808 E8A2FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON THE MOTOR IF OFF
  2936 0000280D 66BAF703            <1> 	MOV	DX,03F7H		; ADDRESS DIGITAL INPUT REGISTER
  2937 00002811 EC                  <1> 	IN	AL,DX			; INPUT DIGITAL INPUT REGISTER
  2938 00002812 A880                <1> 	TEST	AL,DSK_CHG		; CHECK FOR DISK CHANGE LINE ACTIVE
  2939 00002814 C3                  <1> 	RETn				; RETURN TO CALLER WITH ZERO FLAG SET
  2940                              <1> 
  2941                              <1> ;-------------------------------------------------------------------------------
  2942                              <1> ; DRIVE_DET
  2943                              <1> ;	DETERMINES WHETHER DRIVE IS 80 OR 40 TRACKS AND
  2944                              <1> ;	UPDATES STATE INFORMATION ACCORDINGLY.
  2945                              <1> ; ON ENTRY:	DI = DRIVE #
  2946                              <1> ;-------------------------------------------------------------------------------
  2947                              <1> DRIVE_DET:
  2948 00002815 E895FDFFFF          <1> 	CALL	MOTOR_ON		; TURN ON MOTOR IF NOT ALREADY ON
  2949 0000281A E80AFFFFFF          <1> 	CALL	RECAL			; RECALIBRATE DRIVE
  2950 0000281F 7251                <1> 	JC	short DD_BAC		; ASSUME NO DRIVE PRESENT
  2951 00002821 B530                <1> 	MOV	CH,TRK_SLAP		; SEEK TO TRACK 48
  2952 00002823 E882FEFFFF          <1> 	CALL	SEEK
  2953 00002828 7248                <1> 	JC	short DD_BAC		; ERROR NO DRIVE
  2954 0000282A B50B                <1> 	MOV	CH,QUIET_SEEK+1		; SEEK TO TRACK 10
  2955                              <1> SK_GIN:
  2956 0000282C FECD                <1> 	DEC	CH			; DECREMENT TO NEXT TRACK
  2957 0000282E 6651                <1> 	PUSH	CX			; SAVE TRACK
  2958 00002830 E875FEFFFF          <1> 	CALL	SEEK
  2959 00002835 723C                <1> 	JC	short POP_BAC		; POP AND RETURN
  2960 00002837 B8[73280000]        <1> 	MOV	eAX, POP_BAC		; LOAD NEC OUTPUT ERROR ADDRESS
  2961 0000283C 50                  <1> 	PUSH	eAX
  2962 0000283D B404                <1> 	MOV	AH,SENSE_DRV_ST		; SENSE DRIVE STATUS COMMAND BYTE
  2963 0000283F E82CFEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  2964 00002844 6689F8              <1> 	MOV	AX,DI			; AL = DRIVE
  2965 00002847 88C4                <1> 	MOV	AH,AL			; AH = DRIVE
  2966 00002849 E822FEFFFF          <1> 	CALL	NEC_OUTPUT		; OUTPUT TO NEC
  2967 0000284E E85AFFFFFF          <1> 	CALL	RESULTS			; GO GET STATUS
  2968 00002853 58                  <1> 	POP	eAX			; THROW AWAY ERROR ADDRESS
  2969 00002854 6659                <1> 	POP	CX			; RESTORE TRACK
  2970 00002856 F605[75A80000]10    <1> 	TEST	byte [NEC_STATUS], HOME	; TRACK 0 ?
  2971 0000285D 74CD                <1> 	JZ	short SK_GIN		; GO TILL TRACK 0
  2972 0000285F 08ED                <1> 	OR	CH,CH			; IS HOME AT TRACK 0
  2973 00002861 7408                <1> 	JZ	short IS_80		; MUST BE 80 TRACK DRIVE
  2974                              <1> 
  2975                              <1> ;	DRIVE IS A 360; SET DRIVE TO DETERMINED;
  2976                              <1> ;	SET MEDIA TO DETERMINED AT RATE 250.
  2977                              <1> 
  2978 00002863 808F[81A80000]94    <1> 	OR	byte [DSK_STATE+eDI], DRV_DET+MED_DET+RATE_250
  2979 0000286A C3                  <1> 	RETn				; ALL INFORMATION SET
  2980                              <1> IS_80:
  2981 0000286B 808F[81A80000]01    <1> 	OR	byte [DSK_STATE+eDI], TRK_CAPA ; SETUP 80 TRACK CAPABILITY
  2982                              <1> DD_BAC:
  2983 00002872 C3                  <1> 	RETn
  2984                              <1> POP_BAC:
  2985 00002873 6659                <1> 	POP	CX			; THROW AWAY
  2986 00002875 C3                  <1> 	RETn
  2987                              <1> 
  2988                              <1> fdc_int:  
  2989                              <1> 	  ; 30/07/2015	
  2990                              <1> 	  ; 16/02/2015
  2991                              <1> ;int_0Eh: ; 11/12/2014
  2992                              <1> 
  2993                              <1> ;--- HARDWARE INT 0EH -- ( IRQ LEVEL  6 ) --------------------------------------
  2994                              <1> ; DISK_INT
  2995                              <1> ;	THIS ROUTINE HANDLES THE DISKETTE INTERRUPT.
  2996                              <1> ;
  2997                              <1> ; ON EXIT:	THE INTERRUPT FLAG IS SET IN @SEEK_STATUS.
  2998                              <1> ;-------------------------------------------------------------------------------
  2999                              <1> DISK_INT_1:
  3000                              <1> 
  3001 00002876 6650                <1> 	PUSH	AX			; SAVE WORK REGISTER
  3002 00002878 1E                  <1> 	push	ds
  3003 00002879 66B81000            <1> 	mov	ax, KDATA
  3004 0000287D 8ED8                <1> 	mov 	ds, ax
  3005 0000287F 800D[71A80000]80    <1>         OR      byte [SEEK_STATUS], INT_FLAG ; TURN ON INTERRUPT OCCURRED
  3006 00002886 B020                <1> 	MOV     AL,EOI                  ; END OF INTERRUPT MARKER
  3007 00002888 E620                <1> 	OUT	INTA00,AL		; INTERRUPT CONTROL PORT
  3008 0000288A 1F                  <1> 	pop	ds
  3009 0000288B 6658                <1> 	POP	AX			; RECOVER REGISTER
  3010 0000288D CF                  <1> 	IRET				; RETURN FROM INTERRUPT
  3011                              <1> 
  3012                              <1> ;-------------------------------------------------------------------------------
  3013                              <1> ; DSKETTE_SETUP
  3014                              <1> ;	THIS ROUTINE DOES A PRELIMINARY CHECK TO SEE WHAT TYPE OF
  3015                              <1> ;	DISKETTE DRIVES ARE ATTACH TO THE SYSTEM.
  3016                              <1> ;-------------------------------------------------------------------------------
  3017                              <1> DSKETTE_SETUP:
  3018                              <1> 	;PUSH	AX			; SAVE REGISTERS
  3019                              <1> 	;PUSH	BX
  3020                              <1> 	;PUSH	CX
  3021 0000288E 52                  <1> 	PUSH	eDX
  3022                              <1> 	;PUSH	DI
  3023                              <1> 	;;PUSH	DS
  3024                              <1> 	; 14/12/2014
  3025                              <1> 	;mov	word [DISK_POINTER], MD_TBL6
  3026                              <1> 	;mov	[DISK_POINTER+2], cs
  3027                              <1> 	;
  3028                              <1> 	;OR	byte [RTC_WAIT_FLAG], 1	; NO RTC WAIT, FORCE USE OF LOOP
  3029 0000288F 31FF                <1> 	XOR	eDI,eDI			; INITIALIZE DRIVE POINTER
  3030 00002891 66C705[81A80000]00- <1> 	MOV	WORD [DSK_STATE],0	; INITIALIZE STATES
  3030 00002899 00                  <1>
  3031 0000289A 8025[7CA80000]33    <1> 	AND	byte [LASTRATE],~(STRT_MSK+SEND_MSK) ; CLEAR START & SEND
  3032 000028A1 800D[7CA80000]C0    <1> 	OR	byte [LASTRATE],SEND_MSK ; INITIALIZE SENT TO IMPOSSIBLE
  3033 000028A8 C605[71A80000]00    <1> 	MOV	byte [SEEK_STATUS],0	; INDICATE RECALIBRATE NEEDED
  3034 000028AF C605[73A80000]00    <1> 	MOV	byte [MOTOR_COUNT],0	; INITIALIZE MOTOR COUNT
  3035 000028B6 C605[72A80000]00    <1> 	MOV	byte [MOTOR_STATUS],0	; INITIALIZE DRIVES TO OFF STATE
  3036 000028BD C605[74A80000]00    <1> 	MOV	byte [DSKETTE_STATUS],0	; NO ERRORS
  3037                              <1> 	;
  3038                              <1> 	; 28/02/2015
  3039                              <1> 	;mov	word [cfd], 100h 
  3040 000028C4 E85FF2FFFF          <1> 	call	DSK_RESET
  3041 000028C9 5A                  <1> 	pop	edx
  3042 000028CA C3                  <1> 	retn
  3043                              <1> 
  3044                              <1> ;SUP0:
  3045                              <1> ;	CALL	DRIVE_DET		; DETERMINE DRIVE
  3046                              <1> ;	CALL	XLAT_OLD		; TRANSLATE STATE TO COMPATIBLE MODE
  3047                              <1> ;	; 02/01/2015
  3048                              <1> ;	;INC	DI			; POINT TO NEXT DRIVE
  3049                              <1> ;	;CMP	DI,MAX_DRV		; SEE IF DONE
  3050                              <1> ;	;JNZ	short SUP0		; REPEAT FOR EACH ORIVE
  3051                              <1> ;       cmp     byte [fd1_type], 0	
  3052                              <1> ;	jna	short sup1
  3053                              <1> ;	or	di, di
  3054                              <1> ;	jnz	short sup1
  3055                              <1> ;	inc	di
  3056                              <1> ;       jmp     short SUP0
  3057                              <1> ;sup1:
  3058                              <1> ;	MOV	byte [SEEK_STATUS],0	; FORCE RECALIBRATE
  3059                              <1> ;	;AND	byte [RTC_WAIT_FLAG],0FEH ; ALLOW FOR RTC WAIT
  3060                              <1> ;	CALL	SETUP_END		; VARIOUS CLEANUPS
  3061                              <1> ;	;;POP	DS			; RESTORE CALLERS REGISTERS
  3062                              <1> ;	;POP	DI
  3063                              <1> ;	POP	eDX
  3064                              <1> ;	;POP	CX
  3065                              <1> ;	;POP	BX
  3066                              <1> ;	;POP	AX
  3067                              <1> ;	RETn
  3068                              <1> 
  3069                              <1> ;//////////////////////////////////////////////////////
  3070                              <1> ;; END OF DISKETTE I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3071                              <1> ;
  3072                              <1> 
  3073                              <1> int13h: ; 21/02/2015
  3074 000028CB 9C                  <1> 	pushfd
  3075 000028CC 0E                  <1> 	push 	cs
  3076 000028CD E859000000          <1> 	call 	DISK_IO
  3077 000028D2 C3                  <1> 	retn
  3078                              <1> 
  3079                              <1> ;;;;;; DISK I/O ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 21/02/2015 ;;;
  3080                              <1> ;/////////////////////////////////////////////////////////////////////
  3081                              <1> 
  3082                              <1> ; DISK I/O - Erdogan Tan (Retro UNIX 386 v1 project)
  3083                              <1> ; 18/02/2016
  3084                              <1> ; 17/02/2016
  3085                              <1> ; 23/02/2015
  3086                              <1> ; 21/02/2015 (unix386.s)
  3087                              <1> ; 22/12/2014 - 14/02/2015 (dsectrm2.s)
  3088                              <1> ;
  3089                              <1> ; Original Source Code:
  3090                              <1> ; DISK ----- 09/25/85 FIXED DISK BIOS
  3091                              <1> ; (IBM PC XT Model 286 System BIOS Source Code, 04-21-86)
  3092                              <1> ;
  3093                              <1> ; Modifications: by reference of AWARD BIOS 1999 (D1A0622) 
  3094                              <1> ;		 Source Code - ATORGS.ASM, AHDSK.ASM
  3095                              <1> ;
  3096                              <1> 
  3097                              <1> 
  3098                              <1> ;The wait for controller to be not busy is 10 seconds.
  3099                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  3100                              <1> ;;WAIT_HDU_CTLR_BUSY_LO	equ	1615h		
  3101                              <1> ;;WAIT_HDU_CTLR_BUSY_HI	equ	  05h
  3102                              <1> WAIT_HDU_CTRL_BUSY_LH	equ	51615h	 ;21/02/2015		
  3103                              <1> 
  3104                              <1> ;The wait for controller to issue completion interrupt is 10 seconds.
  3105                              <1> ;10,000,000 / 30 = 333,333.  333,333 decimal = 051615h
  3106                              <1> ;;WAIT_HDU_INT_LO	equ	1615h
  3107                              <1> ;;WAIT_HDU_INT_HI	equ	  05h
  3108                              <1> WAIT_HDU_INT_LH		equ	51615h	; 21/02/2015
  3109                              <1> 
  3110                              <1> ;The wait for Data request on read and write longs is
  3111                              <1> ;2000 us. (?)
  3112                              <1> ;;WAIT_HDU_DRQ_LO	equ	1000	; 03E8h
  3113                              <1> ;;WAIT_HDU_DRQ_HI	equ	0
  3114                              <1> WAIT_HDU_DRQ_LH		equ	1000	; 21/02/2015
  3115                              <1> 
  3116                              <1> ; Port 61h (PORT_B)
  3117                              <1> SYS1		equ	61h	; PORT_B  (diskette.inc)
  3118                              <1> 
  3119                              <1> ; 23/12/2014
  3120                              <1> %define CMD_BLOCK       eBP-8  ; 21/02/2015
  3121                              <1> 
  3122                              <1> 
  3123                              <1> ;--- INT 13H -------------------------------------------------------------------
  3124                              <1> ;									       :
  3125                              <1> ; FIXED DISK I/O INTERFACE						       :
  3126                              <1> ;									       :
  3127                              <1> ;	THIS INTERFACE PROVIDES ACCESS TO 5 1/4" FIXED DISKS THROUGH           :
  3128                              <1> ;	THE IBM FIXED DISK CONTROLLER.					       :
  3129                              <1> ;									       :
  3130                              <1> ;	THE  BIOS  ROUTINES  ARE  MEANT  TO  BE  ACCESSED  THROUGH	       :
  3131                              <1> ;	SOFTWARE  INTERRUPTS  ONLY.    ANY  ADDRESSES  PRESENT	IN	       :
  3132                              <1> ;	THESE  LISTINGS  ARE  INCLUDED	 ONLY	FOR  COMPLETENESS,	       :
  3133                              <1> ;	NOT  FOR  REFERENCE.  APPLICATIONS   WHICH  REFERENCE  ANY	       :
  3134                              <1> ;	ABSOLUTE  ADDRESSES  WITHIN  THE  CODE	SEGMENTS  OF  BIOS	       :
  3135                              <1> ;	VIOLATE  THE  STRUCTURE  AND  DESIGN  OF  BIOS. 		       :
  3136                              <1> ;									       :
  3137                              <1> ;------------------------------------------------------------------------------:
  3138                              <1> ;									       :
  3139                              <1> ; INPUT  (AH)= HEX COMMAND VALUE					       :
  3140                              <1> ;									       :
  3141                              <1> ;	(AH)= 00H  RESET DISK (DL = 80H,81H) / DISKETTE 		       :
  3142                              <1> ;	(AH)= 01H  READ THE STATUS OF THE LAST DISK OPERATION INTO (AL)        :
  3143                              <1> ;		    NOTE: DL < 80H - DISKETTE				       :
  3144                              <1> ;			  DL > 80H - DISK				       :
  3145                              <1> ;	(AH)= 02H  READ THE DESIRED SECTORS INTO MEMORY 		       :
  3146                              <1> ;	(AH)= 03H  WRITE THE DESIRED SECTORS FROM MEMORY		       :
  3147                              <1> ;	(AH)= 04H  VERIFY THE DESIRED SECTORS				       :
  3148                              <1> ;	(AH)= 05H  FORMAT THE DESIRED TRACK				       :
  3149                              <1> ;	(AH)= 06H  UNUSED						       :
  3150                              <1> ;	(AH)= 07H  UNUSED						       :
  3151                              <1> ;	(AH)= 08H  RETURN THE CURRENT DRIVE PARAMETERS			       :
  3152                              <1> ;	(AH)= 09H  INITIALIZE DRIVE PAIR CHARACTERISTICS		       :
  3153                              <1> ;		    INTERRUPT 41 POINTS TO DATA BLOCK FOR DRIVE 0	       :
  3154                              <1> ;		    INTERRUPT 46 POINTS TO DATA BLOCK FOR DRIVE 1	       :
  3155                              <1> ;	(AH)= 0AH  READ LONG						       :
  3156                              <1> ;	(AH)= 0BH  WRITE LONG  (READ & WRITE LONG ENCOMPASS 512 + 4 BYTES ECC) :
  3157                              <1> ;	(AH)= 0CH  SEEK 						       :
  3158                              <1> ;	(AH)= 0DH  ALTERNATE DISK RESET (SEE DL)			       :
  3159                              <1> ;	(AH)= 0EH  UNUSED						       :
  3160                              <1> ;	(AH)= 0FH  UNUSED						       :
  3161                              <1> ;	(AH)= 10H  TEST DRIVE READY					       :
  3162                              <1> ;	(AH)= 11H  RECALIBRATE						       :
  3163                              <1> ;	(AH)= 12H  UNUSED						       :
  3164                              <1> ;	(AH)= 13H  UNUSED						       :
  3165                              <1> ;	(AH)= 14H  CONTROLLER INTERNAL DIAGNOSTIC			       :
  3166                              <1> ;	(AH)= 15H  READ DASD TYPE					       :
  3167                              <1> ;									       :
  3168                              <1> ;-------------------------------------------------------------------------------
  3169                              <1> ;									       :
  3170                              <1> ;	REGISTERS USED FOR FIXED DISK OPERATIONS			       :
  3171                              <1> ;									       :
  3172                              <1> ;		(DL)	-  DRIVE NUMBER     (80H-81H FOR DISK. VALUE CHECKED)  :
  3173                              <1> ;		(DH)	-  HEAD NUMBER	    (0-15 ALLOWED, NOT VALUE CHECKED)  :
  3174                              <1> ;		(CH)	-  CYLINDER NUMBER  (0-1023, NOT VALUE CHECKED)(SEE CL):
  3175                              <1> ;		(CL)	-  SECTOR NUMBER    (1-17, NOT VALUE CHECKED)	       :
  3176                              <1> ;									       :
  3177                              <1> ;			   NOTE: HIGH 2 BITS OF CYLINDER NUMBER ARE PLACED     :
  3178                              <1> ;				 IN THE HIGH 2 BITS OF THE CL REGISTER	       :
  3179                              <1> ;				 (10 BITS TOTAL)			       :
  3180                              <1> ;									       :
  3181                              <1> ;		(AL)	-  NUMBER OF SECTORS (MAXIMUM POSSIBLE RANGE 1-80H,    :
  3182                              <1> ;					      FOR READ/WRITE LONG 1-79H)       :
  3183                              <1> ;									       :
  3184                              <1> ;		(ES:BX) -  ADDRESS OF BUFFER FOR READS AND WRITES,	       :
  3185                              <1> ;			   (NOT REQUIRED FOR VERIFY)			       :
  3186                              <1> ;									       :
  3187                              <1> ;		FORMAT (AH=5) ES:BX POINTS TO A 512 BYTE BUFFER. THE FIRST     :
  3188                              <1> ;			   2*(SECTORS/TRACK) BYTES CONTAIN F,N FOR EACH SECTOR.:
  3189                              <1> ;			   F = 00H FOR A GOOD SECTOR			       :
  3190                              <1> ;			       80H FOR A BAD SECTOR			       :
  3191                              <1> ;			   N = SECTOR NUMBER				       :
  3192                              <1> ;			   FOR AN INTERLEAVE OF 2 AND 17 SECTORS/TRACK	       :
  3193                              <1> ;			   THE TABLE SHOULD BE: 			       :
  3194                              <1> ;									       :
  3195                              <1> ;		   DB	   00H,01H,00H,0AH,00H,02H,00H,0BH,00H,03H,00H,0CH     :
  3196                              <1> ;		   DB	   00H,04H,00H,0DH,00H,05H,00H,0EH,00H,06H,00H,0FH     :
  3197                              <1> ;		   DB	   00H,07H,00H,10H,00H,08H,00H,11H,00H,09H	       :
  3198                              <1> ;									       :
  3199                              <1> ;-------------------------------------------------------------------------------
  3200                              <1> 
  3201                              <1> ;-------------------------------------------------------------------------------
  3202                              <1> ; OUTPUT								       :
  3203                              <1> ;	AH = STATUS OF CURRENT OPERATION				       :
  3204                              <1> ;	     STATUS BITS ARE DEFINED IN THE EQUATES BELOW		       :
  3205                              <1> ;	CY = 0	SUCCESSFUL OPERATION (AH=0 ON RETURN)			       :
  3206                              <1> ;	CY = 1	FAILED OPERATION (AH HAS ERROR REASON)			       :
  3207                              <1> ;									       :
  3208                              <1> ;	NOTE:	ERROR 11H  INDICATES THAT THE DATA READ HAD A RECOVERABLE      :
  3209                              <1> ;		ERROR WHICH WAS CORRECTED BY THE ECC ALGORITHM.  THE DATA      :
  3210                              <1> ;		IS PROBABLY GOOD,   HOWEVER THE BIOS ROUTINE INDICATES AN      :
  3211                              <1> ;		ERROR TO ALLOW THE CONTROLLING PROGRAM A CHANCE TO DECIDE      :
  3212                              <1> ;		FOR ITSELF.  THE  ERROR  MAY  NOT  RECUR  IF  THE DATA IS      :
  3213                              <1> ;		REWRITTEN.						       :
  3214                              <1> ;									       :
  3215                              <1> ;	IF DRIVE PARAMETERS WERE REQUESTED (DL >= 80H), 		       :
  3216                              <1> ;	   INPUT:							       :
  3217                              <1> ;	     (DL) = DRIVE NUMBER					       :
  3218                              <1> ;	   OUTPUT:							       :
  3219                              <1> ;	     (DL) = NUMBER OF CONSECUTIVE ACKNOWLEDGING DRIVES ATTACHED (1-2)  :
  3220                              <1> ;		    (CONTROLLER CARD ZERO TALLY ONLY)			       :
  3221                              <1> ;	     (DH) = MAXIMUM USEABLE VALUE FOR HEAD NUMBER		       :
  3222                              <1> ;	     (CH) = MAXIMUM USEABLE VALUE FOR CYLINDER NUMBER		       :
  3223                              <1> ;	     (CL) = MAXIMUM USEABLE VALUE FOR SECTOR NUMBER		       :
  3224                              <1> ;		    AND CYLINDER NUMBER HIGH BITS			       :
  3225                              <1> ;									       :
  3226                              <1> ;	IF READ DASD TYPE WAS REQUESTED,				       :
  3227                              <1> ;									       :
  3228                              <1> ;	AH = 0 - NOT PRESENT						       :
  3229                              <1> ;	     1 - DISKETTE - NO CHANGE LINE AVAILABLE			       :
  3230                              <1> ;	     2 - DISKETTE - CHANGE LINE AVAILABLE			       :
  3231                              <1> ;	     3 - FIXED DISK						       :
  3232                              <1> ;									       :
  3233                              <1> ;	CX,DX = NUMBER OF 512 BYTE BLOCKS WHEN AH = 3			       :
  3234                              <1> ;									       :
  3235                              <1> ;	REGISTERS WILL BE PRESERVED EXCEPT WHEN THEY ARE USED TO RETURN        :
  3236                              <1> ;	INFORMATION.							       :
  3237                              <1> ;									       :
  3238                              <1> ;	NOTE: IF AN ERROR IS REPORTED BY THE DISK CODE, THE APPROPRIATE        :
  3239                              <1> ;		ACTION IS TO RESET THE DISK, THEN RETRY THE OPERATION.	       :
  3240                              <1> ;									       :
  3241                              <1> ;-------------------------------------------------------------------------------
  3242                              <1> 
  3243                              <1> SENSE_FAIL	EQU	0FFH		; NOT IMPLEMENTED
  3244                              <1> NO_ERR		EQU	0E0H		; STATUS ERROR/ERROR REGISTER=0
  3245                              <1> WRITE_FAULT	EQU	0CCH		; WRITE FAULT ON SELECTED DRIVE
  3246                              <1> UNDEF_ERR	EQU	0BBH		; UNDEFINED ERROR OCCURRED
  3247                              <1> NOT_RDY 	EQU	0AAH		; DRIVE NOT READY
  3248                              <1> TIME_OUT	EQU	80H		; ATTACHMENT FAILED TO RESPOND
  3249                              <1> BAD_SEEK	EQU	40H		; SEEK OPERATION FAILED
  3250                              <1> BAD_CNTLR	EQU	20H		; CONTROLLER HAS FAILED
  3251                              <1> DATA_CORRECTED	EQU	11H		; ECC CORRECTED DATA ERROR
  3252                              <1> BAD_ECC 	EQU	10H		; BAD ECC ON DISK READ
  3253                              <1> BAD_TRACK	EQU	0BH		; NOT IMPLEMENTED
  3254                              <1> BAD_SECTOR	EQU	0AH		; BAD SECTOR FLAG DETECTED
  3255                              <1> ;DMA_BOUNDARY	EQU	09H		; DATA EXTENDS TOO FAR
  3256                              <1> INIT_FAIL	EQU	07H		; DRIVE PARAMETER ACTIVITY FAILED
  3257                              <1> BAD_RESET	EQU	05H		; RESET FAILED
  3258                              <1> ;RECORD_NOT_FND	EQU	04H		; REQUESTED SECTOR NOT FOUND
  3259                              <1> ;BAD_ADDR_MARK	EQU	02H		; ADDRESS MARK NOT FOUND
  3260                              <1> ;BAD_CMD 	EQU	01H		; BAD COMMAND PASSED TO DISK I/O
  3261                              <1> 
  3262                              <1> ;--------------------------------------------------------
  3263                              <1> ;							:
  3264                              <1> ; FIXED DISK PARAMETER TABLE				:
  3265                              <1> ;  -  THE TABLE IS COMPOSED OF A BLOCK DEFINED AS:	:
  3266                              <1> ;							:
  3267                              <1> ;  +0	(1 WORD) - MAXIMUM NUMBER OF CYLINDERS		:
  3268                              <1> ;  +2	(1 BYTE) - MAXIMUM NUMBER OF HEADS		:
  3269                              <1> ;  +3	(1 WORD) - NOT USED/SEE PC-XT			:
  3270                              <1> ;  +5	(1 WORD) - STARTING WRITE PRECOMPENSATION CYL	:
  3271                              <1> ;  +7	(1 BYTE) - MAXIMUM ECC DATA BURST LENGTH	:
  3272                              <1> ;  +8	(1 BYTE) - CONTROL BYTE 			:
  3273                              <1> ;		   BIT	  7 DISABLE RETRIES -OR-	:
  3274                              <1> ;		   BIT	  6 DISABLE RETRIES		:
  3275                              <1> ;		   BIT	  3 MORE THAN 8 HEADS		:
  3276                              <1> ;  +9	(3 BYTES)- NOT USED/SEE PC-XT			:
  3277                              <1> ; +12	(1 WORD) - LANDING ZONE 			:
  3278                              <1> ; +14	(1 BYTE) - NUMBER OF SECTORS/TRACK		:
  3279                              <1> ; +15	(1 BYTE) - RESERVED FOR FUTURE USE		:
  3280                              <1> ;							:
  3281                              <1> ;	 - TO DYNAMICALLY DEFINE A SET OF PARAMETERS	:
  3282                              <1> ;	   BUILD A TABLE FOR UP TO 15 TYPES AND PLACE	:
  3283                              <1> ;	   THE CORRESPONDING VECTOR INTO INTERRUPT 41	:
  3284                              <1> ;	   FOR DRIVE 0 AND INTERRUPT 46 FOR DRIVE 1.	:
  3285                              <1> ;							:
  3286                              <1> ;--------------------------------------------------------
  3287                              <1> 
  3288                              <1> ;--------------------------------------------------------
  3289                              <1> ;							:
  3290                              <1> ; HARDWARE SPECIFIC VALUES				:
  3291                              <1> ;							:
  3292                              <1> ;  -  CONTROLLER I/O PORT				:
  3293                              <1> ;							:
  3294                              <1> ;     > WHEN READ FROM: 				:
  3295                              <1> ;	HF_PORT+0 - READ DATA (FROM CONTROLLER TO CPU)	:
  3296                              <1> ;	HF_PORT+1 - GET ERROR REGISTER			:
  3297                              <1> ;	HF_PORT+2 - GET SECTOR COUNT			:
  3298                              <1> ;	HF_PORT+3 - GET SECTOR NUMBER			:
  3299                              <1> ;	HF_PORT+4 - GET CYLINDER LOW			:
  3300                              <1> ;	HF_PORT+5 - GET CYLINDER HIGH (2 BITS)		:
  3301                              <1> ;	HF_PORT+6 - GET SIZE/DRIVE/HEAD 		:
  3302                              <1> ;	HF_PORT+7 - GET STATUS REGISTER 		:
  3303                              <1> ;							:
  3304                              <1> ;     > WHEN WRITTEN TO:				:
  3305                              <1> ;	HF_PORT+0 - WRITE DATA (FROM CPU TO CONTROLLER) :
  3306                              <1> ;	HF_PORT+1 - SET PRECOMPENSATION CYLINDER	:
  3307                              <1> ;	HF_PORT+2 - SET SECTOR COUNT			:
  3308                              <1> ;	HF_PORT+3 - SET SECTOR NUMBER			:
  3309                              <1> ;	HF_PORT+4 - SET CYLINDER LOW			:
  3310                              <1> ;	HF_PORT+5 - SET CYLINDER HIGH (2 BITS)		:
  3311                              <1> ;	HF_PORT+6 - SET SIZE/DRIVE/HEAD 		:
  3312                              <1> ;	HF_PORT+7 - SET COMMAND REGISTER		:
  3313                              <1> ;							:
  3314                              <1> ;--------------------------------------------------------
  3315                              <1> 
  3316                              <1> ;HF_PORT 	EQU	01F0H	; DISK PORT
  3317                              <1> ;HF1_PORT	equ	0170h	
  3318                              <1> ;HF_REG_PORT	EQU	03F6H
  3319                              <1> ;HF1_REG_PORT	equ	0376h
  3320                              <1> 
  3321                              <1> HDC1_BASEPORT	equ	1F0h
  3322                              <1> HDC2_BASEPORT	equ	170h		
  3323                              <1> 
  3324 000028D3 90                  <1> align 2
  3325                              <1> 
  3326                              <1> ;-----		STATUS REGISTER
  3327                              <1> 
  3328                              <1> ST_ERROR	EQU	00000001B	;
  3329                              <1> ST_INDEX	EQU	00000010B	;
  3330                              <1> ST_CORRCTD	EQU	00000100B	; ECC CORRECTION SUCCESSFUL
  3331                              <1> ST_DRQ		EQU	00001000B	;
  3332                              <1> ST_SEEK_COMPL	EQU	00010000B	; SEEK COMPLETE
  3333                              <1> ST_WRT_FLT	EQU	00100000B	; WRITE FAULT
  3334                              <1> ST_READY	EQU	01000000B	;
  3335                              <1> ST_BUSY 	EQU	10000000B	;
  3336                              <1> 
  3337                              <1> ;-----		ERROR REGISTER
  3338                              <1> 
  3339                              <1> ERR_DAM 	EQU	00000001B	; DATA ADDRESS MARK NOT FOUND
  3340                              <1> ERR_TRK_0	EQU	00000010B	; TRACK 0 NOT FOUND ON RECAL
  3341                              <1> ERR_ABORT	EQU	00000100B	; ABORTED COMMAND
  3342                              <1> ;		EQU	00001000B	; NOT USED
  3343                              <1> ERR_ID		EQU	00010000B	; ID NOT FOUND
  3344                              <1> ;		EQU	00100000B	; NOT USED
  3345                              <1> ERR_DATA_ECC	EQU	01000000B
  3346                              <1> ERR_BAD_BLOCK	EQU	10000000B
  3347                              <1> 
  3348                              <1> 
  3349                              <1> RECAL_CMD	EQU	00010000B	; DRIVE RECAL	(10H)
  3350                              <1> READ_CMD	EQU	00100000B	;	READ	(20H)
  3351                              <1> WRITE_CMD	EQU	00110000B	;	WRITE	(30H)
  3352                              <1> VERIFY_CMD	EQU	01000000B	;	VERIFY	(40H)
  3353                              <1> FMTTRK_CMD	EQU	01010000B	; FORMAT TRACK	(50H)
  3354                              <1> INIT_CMD	EQU	01100000B	;   INITIALIZE	(60H)
  3355                              <1> SEEK_CMD	EQU	01110000B	;	SEEK	(70H)
  3356                              <1> DIAG_CMD	EQU	10010000B	; DIAGNOSTIC	(90H)
  3357                              <1> SET_PARM_CMD	EQU	10010001B	; DRIVE PARMS	(91H)
  3358                              <1> NO_RETRIES	EQU	00000001B	; CHD MODIFIER	(01H)
  3359                              <1> ECC_MODE	EQU	00000010B	; CMD MODIFIER	(02H)
  3360                              <1> BUFFER_MODE	EQU	00001000B	; CMD MODIFIER	(08H)
  3361                              <1> 
  3362                              <1> ;MAX_FILE	EQU	2
  3363                              <1> ;S_MAX_FILE	EQU	2
  3364                              <1> MAX_FILE	equ	4		; 22/12/2014
  3365                              <1> S_MAX_FILE	equ	4		; 22/12/2014
  3366                              <1> 
  3367                              <1> DELAY_1 	EQU	25H		; DELAY FOR OPERATION COMPLETE
  3368                              <1> DELAY_2 	EQU	0600H		; DELAY FOR READY
  3369                              <1> DELAY_3 	EQU	0100H		; DELAY FOR DATA REQUEST
  3370                              <1> 
  3371                              <1> HF_FAIL 	EQU	08H		; CMOS FLAG IN BYTE 0EH
  3372                              <1> 
  3373                              <1> ;-----		COMMAND BLOCK REFERENCE
  3374                              <1> 
  3375                              <1> ;CMD_BLOCK      EQU     BP-8            ; @CMD_BLOCK REFERENCES BLOCK HEAD IN SS
  3376                              <1> 					;  (BP) POINTS TO COMMAND BLOCK TAIL
  3377                              <1> 					;	AS DEFINED BY THE "ENTER" PARMS
  3378                              <1> ; 19/12/2014
  3379                              <1> ORG_VECTOR	equ	4*13h		; INT 13h vector
  3380                              <1> DISK_VECTOR	equ	4*40h		; INT 40h vector (for floppy disks)
  3381                              <1> ;HDISK_INT	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  3382                              <1> ;HDISK_INT1	equ	4*76h		; Primary HDC - Hardware interrupt (IRQ14)
  3383                              <1> ;HDISK_INT2	equ	4*77h		; Secondary HDC - Hardware interrupt (IRQ15)
  3384                              <1> ;HF_TBL_VEC	equ	4*41h		; Pointer to 1st fixed disk parameter table
  3385                              <1> ;HF1_TBL_VEC	equ	4*46h		; Pointer to 2nd fixed disk parameter table
  3386                              <1> 
  3387                              <1> align 2
  3388                              <1> 
  3389                              <1> ;----------------------------------------------------------------
  3390                              <1> ; FIXED DISK I/O SETUP						:
  3391                              <1> ;								:
  3392                              <1> ;  -  ESTABLISH TRANSFER VECTORS FOR THE FIXED DISK		:
  3393                              <1> ;  -  PERFORM POWER ON DIAGNOSTICS				:
  3394                              <1> ;     SHOULD AN ERROR OCCUR A "1701" MESSAGE IS DISPLAYED       :
  3395                              <1> ;								:
  3396                              <1> ;----------------------------------------------------------------
  3397                              <1> 
  3398                              <1> DISK_SETUP:
  3399                              <1> 	;CLI
  3400                              <1> 	;;MOV	AX,ABS0 			; GET ABSOLUTE SEGMENT
  3401                              <1> 	;xor	ax,ax
  3402                              <1> 	;MOV	DS,AX				; SET SEGMENT REGISTER
  3403                              <1> 	;MOV	AX, [ORG_VECTOR] 		; GET DISKETTE VECTOR
  3404                              <1> 	;MOV	[DISK_VECTOR],AX		;  INTO INT 40H
  3405                              <1> 	;MOV	AX, [ORG_VECTOR+2]
  3406                              <1> 	;MOV	[DISK_VECTOR+2],AX
  3407                              <1> 	;MOV	word [ORG_VECTOR],DISK_IO	; FIXED DISK HANDLER
  3408                              <1> 	;MOV	[ORG_VECTOR+2],CS
  3409                              <1> 	; 1st controller (primary master, slave)   - IRQ 14
  3410                              <1> 	;;MOV	word [HDISK_INT],HD_INT		; FIXED DISK INTERRUPT
  3411                              <1> 	;mov	word [HDISK_INT1],HD_INT	;
  3412                              <1> 	;;MOV	[HDISK_INT+2],CS
  3413                              <1> 	;mov	[HDISK_INT1+2],CS
  3414                              <1> 	; 2nd controller (secondary master, slave) - IRQ 15
  3415                              <1> 	;mov	word [HDISK_INT2],HD1_INT	;
  3416                              <1> 	;mov	[HDISK_INT2+2],CS
  3417                              <1> 	;
  3418                              <1> 	;;MOV	word [HF_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80
  3419                              <1> 	;;MOV	word [HF_TBL_VEC+2],DPT_SEGM
  3420                              <1> 	;;MOV	word [HF1_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81
  3421                              <1> 	;;MOV	word [HF1_TBL_VEC+2],DPT_SEGM
  3422                              <1> 	;push	cs
  3423                              <1> 	;pop	ds
  3424                              <1> 	;mov	word [HDPM_TBL_VEC],HD0_DPT	; PARM TABLE DRIVE 80h
  3425                              <1> 	;mov	word [HDPM_TBL_VEC+2],DPT_SEGM
  3426 000028D4 C705[8CA80000]0000- <1> 	mov 	dword [HDPM_TBL_VEC], (DPT_SEGM*16)+HD0_DPT
  3426 000028DC 0900                <1>
  3427                              <1> 	;mov	word [HDPS_TBL_VEC],HD1_DPT	; PARM TABLE DRIVE 81h
  3428                              <1> 	;mov	word [HDPS_TBL_VEC+2],DPT_SEGM
  3429 000028DE C705[90A80000]2000- <1> 	mov 	dword [HDPS_TBL_VEC], (DPT_SEGM*16)+HD1_DPT
  3429 000028E6 0900                <1>
  3430                              <1> 	;mov	word [HDSM_TBL_VEC],HD2_DPT	; PARM TABLE DRIVE 82h
  3431                              <1> 	;mov	word [HDSM_TBL_VEC+2],DPT_SEGM
  3432 000028E8 C705[94A80000]4000- <1> 	mov 	dword [HDSM_TBL_VEC], (DPT_SEGM*16)+HD2_DPT
  3432 000028F0 0900                <1>
  3433                              <1> 	;mov	word [HDSS_TBL_VEC],HD3_DPT	; PARM TABLE DRIVE 83h
  3434                              <1> 	;mov	word [HDSS_TBL_VEC+2],DPT_SEGM
  3435 000028F2 C705[98A80000]6000- <1> 	mov 	dword [HDSS_TBL_VEC], (DPT_SEGM*16)+HD3_DPT
  3435 000028FA 0900                <1>
  3436                              <1> 	;
  3437                              <1> 	;;IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  3438                              <1> 	;;;AND	AL,0BFH
  3439                              <1> 	;;and	al, 3Fh			; enable IRQ 14 and IRQ 15
  3440                              <1> 	;;;JMP	$+2
  3441                              <1> 	;;IODELAY
  3442                              <1> 	;;OUT	INTB01,AL
  3443                              <1> 	;;IODELAY
  3444                              <1> 	;;IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  3445                              <1> 	;;AND	AL,0FBH 		;  SECOND CHIP
  3446                              <1> 	;;;JMP	$+2
  3447                              <1> 	;;IODELAY
  3448                              <1> 	;;OUT	INTA01,AL
  3449                              <1> 	;
  3450                              <1> 	;STI
  3451                              <1> 	;;PUSH	DS			; MOVE ABS0 POINTER TO
  3452                              <1> 	;;POP	ES			; EXTRA SEGMENT POINTER
  3453                              <1> 	;;;CALL	DDS			; ESTABLISH DATA SEGMENT
  3454                              <1> 	;;MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  3455                              <1> 	;;MOV	byte [HF_NUM],0		; ZERO NUMBER OF FIXED DISKS
  3456                              <1> 	;;MOV	byte [CONTROL_BYTE],0
  3457                              <1> 	;;MOV	byte [PORT_OFF],0	; ZERO CARD OFFSET
  3458                              <1> 	; 20/12/2014 - private code by Erdogan Tan
  3459                              <1> 		      ; (out of original PC-AT, PC-XT BIOS code)
  3460                              <1> 	;mov	si, hd0_type
  3461 000028FC BE[C0A20000]        <1> 	mov	esi, hd0_type
  3462                              <1> 	;mov	cx, 4
  3463 00002901 B904000000          <1> 	mov	ecx, 4
  3464                              <1> hde_l:
  3465 00002906 AC                  <1> 	lodsb
  3466 00002907 3C80                <1> 	cmp	al, 80h			; 8?h = existing
  3467 00002909 7206                <1> 	jb	short _L4
  3468 0000290B FE05[88A80000]      <1> 	inc	byte [HF_NUM]		; + 1 hard (fixed) disk drives
  3469                              <1> _L4: ; 26/02/2015
  3470 00002911 E2F3                <1> 	loop	hde_l	
  3471                              <1> ;_L4:					; 0 <= [HF_NUM] =< 4
  3472                              <1> ;L4:
  3473                              <1> 	; 
  3474                              <1> 	;; 31/12/2014 - cancel controller diagnostics here
  3475                              <1> 	;;;mov 	cx, 3  ; 26/12/2014 (Award BIOS 1999)
  3476                              <1> 	;;mov 	cl, 3
  3477                              <1> 	;;
  3478                              <1> 	;;MOV	DL,80H			; CHECK THE CONTROLLER
  3479                              <1> ;;hdc_dl:
  3480                              <1> 	;;MOV	AH,14H			; USE CONTROLLER DIAGNOSTIC COMMAND
  3481                              <1> 	;;INT	13H			; CALL BIOS WITH DIAGNOSTIC COMMAND
  3482                              <1> 	;;;JC	short CTL_ERRX		; DISPLAY ERROR MESSAGE IF BAD RETURN
  3483                              <1> 	;;;jc	short POD_DONE ;22/12/2014
  3484                              <1> 	;;jnc	short hdc_reset0
  3485                              <1> 	;;loop	hdc_dl
  3486                              <1> 	;;; 27/12/2014
  3487                              <1> 	;;stc
  3488                              <1> 	;;retn
  3489                              <1> 	;
  3490                              <1> ;;hdc_reset0:
  3491                              <1> 	; 18/01/2015
  3492 00002913 8A0D[88A80000]      <1> 	mov	cl, [HF_NUM]
  3493 00002919 20C9                <1> 	and	cl, cl
  3494 0000291B 740D                <1> 	jz	short POD_DONE
  3495                              <1> 	;
  3496 0000291D B27F                <1> 	mov	dl, 7Fh
  3497                              <1> hdc_reset1:
  3498 0000291F FEC2                <1> 	inc	dl
  3499                              <1> 	;; 31/12/2015
  3500                              <1> 	;;push	dx
  3501                              <1> 	;;push	cx
  3502                              <1> 	;;push	ds
  3503                              <1> 	;;sub	ax, ax
  3504                              <1> 	;;mov	ds, ax
  3505                              <1> 	;;MOV	AX, [TIMER_LOW]		; GET START TIMER COUNTS
  3506                              <1> 	;;pop	ds
  3507                              <1> 	;;MOV	BX,AX
  3508                              <1> 	;;ADD	AX,6*182		; 60 SECONDS* 18.2
  3509                              <1> 	;;MOV	CX,AX
  3510                              <1> 	;;mov	word [wait_count], 0	; 22/12/2014 (reset wait counter)
  3511                              <1> 	;;
  3512                              <1> 	;; 31/12/2014 - cancel HD_RESET_1
  3513                              <1> 	;;CALL	HD_RESET_1		; SET UP DRIVE 0, (1,2,3)
  3514                              <1> 	;;pop	cx
  3515                              <1> 	;;pop	dx
  3516                              <1> 	;;
  3517                              <1> 	; 18/01/2015
  3518 00002921 B40D                <1> 	mov	ah, 0Dh ; ALTERNATE RESET
  3519                              <1> 	;int	13h
  3520 00002923 E8A3FFFFFF          <1> 	call	int13h
  3521 00002928 E2F5                <1> 	loop	hdc_reset1
  3522                              <1> POD_DONE:
  3523 0000292A C3                  <1> 	RETn
  3524                              <1> 
  3525                              <1> ;;-----	POD_ERROR
  3526                              <1> 
  3527                              <1> ;;CTL_ERRX:
  3528                              <1> ;	;MOV	SI,OFFSET F1782 	; CONTROLLER ERROR
  3529                              <1> ;	;CALL	SET_FAIL		; DO NOT IPL FROM DISK
  3530                              <1> ;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  3531                              <1> ;	;JMP	short POD_DONE
  3532                              <1> 
  3533                              <1> ;;HD_RESET_1:
  3534                              <1> ;;	;PUSH	BX			; SAVE TIMER LIMITS
  3535                              <1> ;;	;PUSH	CX
  3536                              <1> ;;RES_1: MOV	AH,09H			; SET DRIVE PARAMETERS
  3537                              <1> ;;	INT	13H
  3538                              <1> ;;	JC	short RES_2
  3539                              <1> ;;	MOV	AH,11H			; RECALIBRATE DRIVE
  3540                              <1> ;;	INT	13H
  3541                              <1> ;;	JNC	short RES_CK		; DRIVE OK
  3542                              <1> ;;RES_2: ;CALL	POD_TCHK		; CHECK TIME OUT
  3543                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  3544                              <1> ;;					; (30 seconds)		
  3545                              <1> ;;	;cmc
  3546                              <1> ;;	;JNC	short RES_1
  3547                              <1> ;;	jb	short RES_1
  3548                              <1> ;;;RES_FL: ;MOV	SI,OFFSET F1781 	; INDICATE DISK 1 FAILURE;
  3549                              <1> ;;	;TEST	DL,1
  3550                              <1> ;;	;JNZ	RES_E1
  3551                              <1> ;;	;MOV	SI,OFFSET F1780 	; INDICATE DISK 0 FAILURE
  3552                              <1> ;;	;CALL	SET_FAIL		; DO NOT TRY TO IPL DISK 0
  3553                              <1> ;;	;JMP	SHORT RES_E1
  3554                              <1> ;;RES_ER: ; 22/12/2014
  3555                              <1> ;;RES_OK:
  3556                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  3557                              <1> ;;	;POP	BX
  3558                              <1> ;;	RETn
  3559                              <1> ;;
  3560                              <1> ;;RES_RS: MOV	AH,00H			; RESET THE DRIVE
  3561                              <1> ;;	INT	13H
  3562                              <1> ;;RES_CK: MOV	AH,08H			; GET MAX CYLINDER,HEAD,SECTOR
  3563                              <1> ;;	MOV	BL,DL			; SAVE DRIVE CODE
  3564                              <1> ;;	INT	13H
  3565                              <1> ;;	JC	short RES_ER
  3566                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE MAX CYLINDER, SECTOR
  3567                              <1> ;;	MOV	DL,BL			; RESTORE DRIVE CODE
  3568                              <1> ;;RES_3: MOV	AX,0401H		; VERIFY THE LAST SECTOR
  3569                              <1> ;;	INT	13H
  3570                              <1> ;;	JNC	short RES_OK		; VERIFY OK
  3571                              <1> ;;	CMP	AH,BAD_SECTOR		; OK ALSO IF JUST ID READ
  3572                              <1> ;;	JE	short RES_OK
  3573                              <1> ;;	CMP	AH,DATA_CORRECTED
  3574                              <1> ;;	JE	short RES_OK
  3575                              <1> ;;	CMP	AH,BAD_ECC
  3576                              <1> ;;	JE	short RES_OK
  3577                              <1> ;;	;CALL	POD_TCHK		; CHECK FOR TIME OUT
  3578                              <1> ;;	cmp	word [wait_count], 6*182 ; waiting time (in timer ticks)
  3579                              <1> ;;					; (60 seconds)		
  3580                              <1> ;;	cmc
  3581                              <1> ;;	JC	short RES_ER		; FAILED
  3582                              <1> ;;	MOV	CX,[NEC_STATUS] 	; GET SECTOR ADDRESS, AND CYLINDER
  3583                              <1> ;;	MOV	AL,CL			; SEPARATE OUT SECTOR NUMBER
  3584                              <1> ;;	AND	AL,3FH
  3585                              <1> ;;	DEC	AL			; TRY PREVIOUS ONE
  3586                              <1> ;;	JZ	short RES_RS		; WE'VE TRIED ALL SECTORS ON TRACK
  3587                              <1> ;;	AND	CL,0C0H 		; KEEP CYLINDER BITS
  3588                              <1> ;;	OR	CL,AL			; MERGE SECTOR WITH CYLINDER BITS
  3589                              <1> ;;	MOV	[NEC_STATUS],CX 	; SAVE CYLINDER, NEW SECTOR NUMBER
  3590                              <1> ;;	JMP	short RES_3		; TRY AGAIN
  3591                              <1> ;;;RES_ER: MOV	SI,OFFSET F1791 	; INDICATE DISK 1 ERROR
  3592                              <1> ;;	;TEST	DL,1
  3593                              <1> ;;	;JNZ	short RES_E1
  3594                              <1> ;;	;MOV	SI,OFFSET F1790 	; INDICATE DISK 0 ERROR
  3595                              <1> ;;;RES_E1:
  3596                              <1> ;;	;CALL	E_MSG			; DISPLAY ERROR AND SET (BP) ERROR FLAG
  3597                              <1> ;;;RES_OK:
  3598                              <1> ;;	;POP	CX			; RESTORE TIMER LIMITS
  3599                              <1> ;;	;POP	BX
  3600                              <1> ;;	;RETn
  3601                              <1> ;
  3602                              <1> ;;SET_FAIL:
  3603                              <1> ;	;MOV	AX,X*(CMOS_DIAG+NMI)	; GET CMOS ERROR BYTE
  3604                              <1> ;	;CALL	CMOS_READ
  3605                              <1> ;	;OR	AL,HF_FAIL		; SET DO NOT IPL FROM DISK FLAG
  3606                              <1> ;	;XCHG	AH,AL			; SAVE IT
  3607                              <1> ;	;CALL	CMOS_WRITE		; PUT IT OUT
  3608                              <1> ;	;RETn
  3609                              <1> ;
  3610                              <1> ;;POD_TCHK:				; CHECK FOR 30 SECOND TIME OUT
  3611                              <1> ;	;POP	AX			; SAVE RETURN
  3612                              <1> ;	;POP	CX			; GET TIME OUT LIMITS
  3613                              <1> ;	;POP	BX
  3614                              <1> ;	;PUSH	BX			; AND SAVE THEM AGAIN
  3615                              <1> ;	;PUSH	CX
  3616                              <1> ;	;PUSH	AX
  3617                              <1> ;	;push	ds
  3618                              <1> ;	;xor	ax, ax
  3619                              <1> ;	;mov	ds, ax			; RESTORE RETURN
  3620                              <1> ;	;MOV	AX, [TIMER_LOW]		; AX = CURRENT TIME
  3621                              <1> ;	;				; BX = START TIME
  3622                              <1> ;	;				; CX = END TIME
  3623                              <1> ;	;pop	ds
  3624                              <1> ;	;CMP	BX,CX
  3625                              <1> ;	;JB	short TCHK1		; START < END
  3626                              <1> ;	;CMP	BX,AX
  3627                              <1> ;	;JB	short TCHKG		; END < START < CURRENT
  3628                              <1> ;	;JMP	SHORT TCHK2		; END, CURRENT < START
  3629                              <1> ;;TCHK1: CMP	AX,BX
  3630                              <1> ;;	JB	short TCHKNG		; CURRENT < START < END
  3631                              <1> ;;TCHK2: CMP	AX,CX
  3632                              <1> ;;	JB	short TCHKG		; START < CURRENT < END
  3633                              <1> ;;					; OR CURRENT < END < START
  3634                              <1> ;;TCHKNG: STC				; CARRY SET INDICATES TIME OUT
  3635                              <1> ;;	RETn
  3636                              <1> ;;TCHKG: CLC				; INDICATE STILL TIME
  3637                              <1> ;;	RETn
  3638                              <1> ;;
  3639                              <1> ;;int_13h:
  3640                              <1> 
  3641                              <1> ;----------------------------------------
  3642                              <1> ;	FIXED DISK BIOS ENTRY POINT	:
  3643                              <1> ;----------------------------------------
  3644                              <1> 
  3645                              <1> DISK_IO:
  3646 0000292B 80FA80              <1> 	CMP	DL,80H			; TEST FOR FIXED DISK DRIVE
  3647                              <1> 	;JAE	short A1		; YES, HANDLE HERE
  3648                              <1> 	;;;INT	40H			; DISKETTE HANDLER
  3649                              <1> 	;;call	int40h
  3650 0000292E 0F8224F1FFFF        <1> 	jb	DISKETTE_IO_1
  3651                              <1> ;RET_2:
  3652                              <1> 	;RETf	2			; BACK TO CALLER
  3653                              <1> ;	retf	4
  3654                              <1> A1:
  3655 00002934 FB                  <1> 	STI				; ENABLE INTERRUPTS
  3656                              <1> 	;; 04/01/2015
  3657                              <1> 	;;OR	AH,AH
  3658                              <1> 	;;JNZ	short A2
  3659                              <1> 	;;INT	40H			; RESET NEC WHEN AH=0
  3660                              <1> 	;;SUB	AH,AH
  3661 00002935 80FA83              <1> 	CMP	DL,(80H + S_MAX_FILE - 1)
  3662 00002938 772C                <1> 	JA	short RET_2
  3663                              <1> 	; 18/01/2015
  3664 0000293A 08E4                <1> 	or	ah,ah
  3665 0000293C 742B                <1> 	jz	short A4
  3666 0000293E 80FC0D              <1> 	cmp	ah, 0Dh	; Alternate reset
  3667 00002941 7504                <1> 	jne	short A2
  3668 00002943 28E4                <1> 	sub	ah,ah	; Reset
  3669 00002945 EB22                <1> 	jmp	short A4
  3670                              <1> A2:
  3671 00002947 80FC08              <1> 	CMP	AH,08H			; GET PARAMETERS IS A SPECIAL CASE
  3672                              <1> 	;JNZ	short A3
  3673                              <1>         ;JMP    GET_PARM_N
  3674 0000294A 0F841C030000        <1> 	je	GET_PARM_N
  3675 00002950 80FC15              <1> A3:	CMP	AH,15H			; READ DASD TYPE IS ALSO
  3676                              <1> 	;JNZ	short A4
  3677                              <1>         ;JMP    READ_DASD_TYPE
  3678 00002953 0F84C7020000        <1>         je      READ_DASD_TYPE
  3679                              <1> 	; 02/02/2015
  3680 00002959 80FC1D              <1> 	cmp	ah, 1Dh			;(Temporary for Retro UNIX 386 v1)
  3681                              <1> 	; 12/01/2015
  3682 0000295C F5                  <1> 	cmc
  3683 0000295D 730A                <1> 	jnc	short A4
  3684                              <1> 	; 30/01/2015
  3685                              <1> 	;mov     byte [CS:DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  3686 0000295F C605[87A80000]01    <1>         mov     byte [DISK_STATUS1], BAD_CMD
  3687                              <1> 	;jmp	short RET_2
  3688                              <1> RET_2:
  3689 00002966 CA0400              <1> 	retf	4
  3690                              <1> A4:					; SAVE REGISTERS DURING OPERATION
  3691 00002969 C8080000            <1> 	ENTER	8,0			; SAVE (BP) AND MAKE ROOM FOR @CMD_BLOCK
  3692 0000296D 53                  <1> 	PUSH	eBX			;  IN THE STACK, THE COMMAND BLOCK IS:
  3693 0000296E 51                  <1> 	PUSH	eCX			;   @CMD_BLOCK == BYTE PTR [BP]-8
  3694 0000296F 52                  <1> 	PUSH	eDX
  3695 00002970 1E                  <1> 	PUSH	DS
  3696 00002971 06                  <1> 	PUSH	ES
  3697 00002972 56                  <1> 	PUSH	eSI
  3698 00002973 57                  <1> 	PUSH	eDI
  3699                              <1> 	;;04/01/2015
  3700                              <1> 	;;OR	AH,AH			; CHECK FOR RESET
  3701                              <1> 	;;JNZ	short A5
  3702                              <1> 	;;MOV	DL,80H			; FORCE DRIVE 80 FOR RESET
  3703                              <1> ;;A5:	
  3704                              <1> 	;push	cs
  3705                              <1> 	;pop	ds
  3706                              <1> 	; 21/02/2015
  3707 00002974 6650                <1> 	push	ax
  3708 00002976 66B81000            <1> 	mov	ax, KDATA
  3709 0000297A 8ED8                <1> 	mov	ds, ax
  3710 0000297C 8EC0                <1> 	mov	es, ax	
  3711 0000297E 6658                <1> 	pop	ax
  3712 00002980 E889000000          <1> 	CALL	DISK_IO_CONT		; PERFORM THE OPERATION
  3713                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  3714 00002985 8A25[87A80000]      <1> 	MOV	AH,[DISK_STATUS1]	; GET STATUS FROM OPERATION
  3715 0000298B 80FC01              <1> 	CMP	AH,1			; SET THE CARRY FLAG TO INDICATE
  3716 0000298E F5                  <1> 	CMC				; SUCCESS OR FAILURE
  3717 0000298F 5F                  <1> 	POP	eDI			; RESTORE REGISTERS
  3718 00002990 5E                  <1> 	POP	eSI
  3719 00002991 07                  <1>         POP     ES
  3720 00002992 1F                  <1>         POP     DS
  3721 00002993 5A                  <1> 	POP	eDX
  3722 00002994 59                  <1> 	POP	eCX
  3723 00002995 5B                  <1> 	POP	eBX
  3724 00002996 C9                  <1> 	LEAVE				; ADJUST (SP) AND RESTORE (BP)
  3725                              <1> 	;RETf	2			; THROW AWAY SAVED FLAGS
  3726 00002997 CA0400              <1> 	retf	4
  3727                              <1> 
  3728                              <1> ; 21/02/2015
  3729                              <1> ;       dw --> dd
  3730                              <1> D1:					; FUNCTION TRANSFER TABLE
  3731 0000299A [5C2B0000]          <1> 	dd	DISK_RESET		; 000H
  3732 0000299E [D32B0000]          <1> 	dd	RETURN_STATUS		; 001H
  3733 000029A2 [E02B0000]          <1> 	dd	DISK_READ		; 002H
  3734 000029A6 [E92B0000]          <1> 	dd	DISK_WRITE		; 003H
  3735 000029AA [F22B0000]          <1> 	dd	DISK_VERF		; 004H
  3736 000029AE [0A2C0000]          <1> 	dd	FMT_TRK 		; 005H
  3737 000029B2 [522B0000]          <1> 	dd	BAD_COMMAND		; 006H	FORMAT BAD SECTORS
  3738 000029B6 [522B0000]          <1> 	dd	BAD_COMMAND		; 007H	FORMAT DRIVE
  3739 000029BA [522B0000]          <1> 	dd	BAD_COMMAND		; 008H	RETURN PARAMETERS
  3740 000029BE [D12C0000]          <1> 	dd	INIT_DRV		; 009H
  3741 000029C2 [302D0000]          <1> 	dd	RD_LONG 		; 00AH
  3742 000029C6 [392D0000]          <1> 	dd	WR_LONG 		; 00BH
  3743 000029CA [422D0000]          <1> 	dd	DISK_SEEK		; 00CH
  3744 000029CE [5C2B0000]          <1> 	dd	DISK_RESET		; 00DH
  3745 000029D2 [522B0000]          <1> 	dd	BAD_COMMAND		; 00EH	READ BUFFER
  3746 000029D6 [522B0000]          <1> 	dd	BAD_COMMAND		; 00FH	WRITE BUFFER
  3747 000029DA [6A2D0000]          <1> 	dd	TST_RDY 		; 010H
  3748 000029DE [8E2D0000]          <1> 	dd	HDISK_RECAL		; 011H
  3749 000029E2 [522B0000]          <1> 	dd	BAD_COMMAND		; 012H	MEMORY DIAGNOSTIC
  3750 000029E6 [522B0000]          <1> 	dd	BAD_COMMAND		; 013H	DRIVE DIAGNOSTIC
  3751 000029EA [C42D0000]          <1> 	dd	CTLR_DIAGNOSTIC 	; 014H	CONTROLLER DIAGNOSTIC
  3752                              <1> 	; 02/02/2015 (Temporary - Retro UNIX 386 v1 - DISK I/O test)
  3753 000029EE [522B0000]          <1> 	dd	BAD_COMMAND		; 015h
  3754 000029F2 [522B0000]          <1> 	dd	BAD_COMMAND		; 016h
  3755 000029F6 [522B0000]          <1> 	dd	BAD_COMMAND		; 017h
  3756 000029FA [522B0000]          <1> 	dd	BAD_COMMAND		; 018h
  3757 000029FE [522B0000]          <1> 	dd	BAD_COMMAND		; 019h
  3758 00002A02 [522B0000]          <1> 	dd	BAD_COMMAND		; 01Ah
  3759 00002A06 [E02B0000]          <1> 	dd	DISK_READ		; 01Bh ; LBA read
  3760 00002A0A [E92B0000]          <1> 	dd	DISK_WRITE		; 01Ch ; LBA write
  3761                              <1> D1L     EQU    $ - D1
  3762                              <1> 
  3763                              <1> DISK_IO_CONT:
  3764                              <1> 	;;CALL	DDS			; ESTABLISH SEGMENT
  3765 00002A0E 80FC01              <1> 	CMP	AH,01H			; RETURN STATUS
  3766                              <1> 	;;JNZ	short SU0
  3767                              <1>         ;;JMP    RETURN_STATUS
  3768 00002A11 0F84BC010000        <1> 	je	RETURN_STATUS
  3769                              <1> SU0:
  3770 00002A17 C605[87A80000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; RESET THE STATUS INDICATOR
  3771                              <1> 	;;PUSH	BX			; SAVE DATA ADDRESS
  3772                              <1> 	;mov	si, bx ;; 14/02/2015
  3773 00002A1E 89DE                <1> 	mov	esi, ebx ; 21/02/2015
  3774 00002A20 8A1D[88A80000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  3775                              <1> 	;; 04/01/2015
  3776                              <1> 	;;PUSH	AX
  3777 00002A26 80E27F              <1> 	AND	DL,7FH			; GET DRIVE AS 0 OR 1
  3778                              <1> 					; (get drive number as 0 to 3)
  3779 00002A29 38D3                <1> 	CMP	BL,DL
  3780                              <1>         ;;JBE   BAD_COMMAND_POP         ; INVALID DRIVE
  3781 00002A2B 0F8621010000        <1>         jbe     BAD_COMMAND ;; 14/02/2015
  3782                              <1>         ;
  3783                              <1> 	;;03/01/2015
  3784 00002A31 29DB                <1> 	sub	ebx, ebx
  3785 00002A33 88D3                <1> 	mov	bl, dl
  3786                              <1> 	;sub	bh, bh
  3787 00002A35 883D[9CA80000]      <1> 	mov	[LBAMode], bh 	; 0
  3788                              <1> 	;;test	byte [bx+hd0_type], 1	; LBA ready ?
  3789                              <1> 	;test	byte [ebx+hd0_type], 1
  3790                              <1> 	;jz	short su1		; no
  3791                              <1> 	;inc	byte [LBAMode]
  3792                              <1> ;su1:
  3793                              <1> 	; 21/02/2015 (32 bit modification)
  3794                              <1> 	;04/01/2015
  3795 00002A3B 6650                <1> 	push	ax ; ***
  3796                              <1> 	;PUSH	ES ; **
  3797 00002A3D 6652                <1> 	PUSH	DX ; *
  3798 00002A3F 6650                <1> 	push	ax
  3799 00002A41 E864060000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS
  3800                              <1> 	; 02/02/2015
  3801                              <1> 	;mov	ax, [ES:BX+16] ; I/O port base address (1F0h, 170h)
  3802 00002A46 668B4310            <1> 	mov	ax, [ebx+16]
  3803 00002A4A 66A3[B4A20000]      <1> 	mov	[HF_PORT], ax
  3804                              <1> 	;mov	dx, [ES:BX+18] ; control port address (3F6h, 376h)
  3805 00002A50 668B5312            <1> 	mov	dx, [ebx+18]
  3806 00002A54 668915[B6A20000]    <1> 	mov	[HF_REG_PORT], dx
  3807                              <1> 	;mov	al, [ES:BX+20] ; head register upper nibble (A0h,B0h,E0h,F0h)
  3808 00002A5B 8A4314              <1> 	mov	al, [ebx+20]
  3809                              <1> 	; 23/02/2015
  3810 00002A5E A840                <1> 	test	al, 40h	 ; LBA bit (bit 6)
  3811 00002A60 7406                <1> 	jz 	short su1
  3812 00002A62 FE05[9CA80000]      <1> 	inc	byte [LBAMode] ; 1 
  3813                              <1> su1: 	 
  3814 00002A68 C0E804              <1> 	shr 	al, 4
  3815 00002A6B 2401                <1> 	and	al, 1			
  3816 00002A6D A2[B8A20000]        <1> 	mov	[hf_m_s], al 
  3817                              <1> 	;
  3818                              <1> 	; 03/01/2015
  3819                              <1> 	;MOV	AL,byte [ES:BX+8]	; GET CONTROL BYTE MODIFIER
  3820 00002A72 8A4308              <1> 	mov	al, [ebx+8]
  3821                              <1> 	;MOV	DX,[HF_REG_PORT]	; Device Control register	
  3822 00002A75 EE                  <1> 	OUT	DX,AL			; SET EXTRA HEAD OPTION
  3823                              <1> 					; Control Byte:  (= 08h, here)
  3824                              <1> 					; bit 0 - 0
  3825                              <1> 					; bit 1 - nIEN (1 = disable irq)
  3826                              <1> 					; bit 2 - SRST (software RESET)
  3827                              <1> 					; bit 3 - use extra heads (8 to 15)
  3828                              <1> 					;         -always set to 1-	
  3829                              <1> 					; (bits 3 to 7 are reserved
  3830                              <1> 					;          for ATA devices)
  3831 00002A76 8A25[89A80000]      <1> 	MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  3832 00002A7C 80E4C0              <1> 	AND	AH,0C0H 		; CONTROL BYTE
  3833 00002A7F 08C4                <1> 	OR	AH,AL
  3834 00002A81 8825[89A80000]      <1> 	MOV	[CONTROL_BYTE],AH	
  3835                              <1> 	; 04/01/2015
  3836 00002A87 6658                <1> 	pop	ax
  3837 00002A89 665A                <1> 	pop	dx ; * ;; 14/02/2015
  3838 00002A8B 20E4                <1> 	and	ah, ah	; Reset function ?
  3839 00002A8D 7507                <1> 	jnz	short su2
  3840                              <1> 	;;pop	dx ; * ;; 14/02/2015
  3841                              <1> 	;pop	es ; **
  3842 00002A8F 6658                <1> 	pop	ax ; ***
  3843                              <1> 	;;pop	bx
  3844 00002A91 E9C6000000          <1>         jmp     DISK_RESET
  3845                              <1> su2:
  3846 00002A96 803D[9CA80000]00    <1> 	cmp	byte [LBAMode], 0
  3847 00002A9D 7661                <1> 	jna	short su3
  3848                              <1> 	;
  3849                              <1> 	; 02/02/2015 (LBA read/write function calls)
  3850 00002A9F 80FC1B              <1> 	cmp	ah, 1Bh
  3851 00002AA2 720B                <1> 	jb	short lbarw1
  3852 00002AA4 80FC1C              <1> 	cmp	ah, 1Ch
  3853 00002AA7 775C                <1> 	ja 	short invldfnc
  3854                              <1> 	;;pop	dx ; * ; 14/02/2015
  3855                              <1> 	;mov	ax, cx ; Lower word of LBA address (bits 0-15)
  3856 00002AA9 89C8                <1> 	mov	eax, ecx ; LBA address (21/02/2015)
  3857                              <1> 	;; 14/02/2015
  3858 00002AAB 88D1                <1> 	mov	cl, dl ; 14/02/2015
  3859                              <1> 	;;mov	dx, bx
  3860                              <1> 	;mov	dx, si ; higher word of LBA address (bits 16-23)
  3861                              <1> 	;;mov	bx, di
  3862                              <1> 	;mov	si, di ; Buffer offset
  3863 00002AAD EB31                <1> 	jmp	short lbarw2
  3864                              <1> lbarw1:
  3865                              <1> 	; convert CHS to LBA
  3866                              <1> 	;
  3867                              <1> 	; LBA calculation - AWARD BIOS - 1999 - AHDSK.ASM
  3868                              <1> 	; LBA = "# of Heads" * Sectors/Track * Cylinder + Head * Sectors/Track
  3869                              <1> 	;	+ Sector - 1
  3870 00002AAF 6652                <1> 	push	dx ; * ;; 14/02/2015
  3871                              <1> 	;xor	dh, dh
  3872 00002AB1 31D2                <1> 	xor	edx, edx
  3873                              <1> 	;mov	dl, [ES:BX+14]	; sectors per track (logical)
  3874 00002AB3 8A530E              <1> 	mov	dl, [ebx+14]
  3875                              <1> 	;xor	ah, ah
  3876 00002AB6 31C0                <1> 	xor	eax, eax
  3877                              <1> 	;mov	al, [ES:BX+2]	; heads (logical) 	
  3878 00002AB8 8A4302              <1> 	mov	al, [ebx+2]
  3879 00002ABB FEC8                <1> 	dec	al
  3880 00002ABD 6640                <1> 	inc	ax		; 0 =  256
  3881 00002ABF 66F7E2              <1> 	mul 	dx
  3882                              <1> 		; AX = # of Heads" * Sectors/Track
  3883 00002AC2 6689CA              <1> 	mov	dx, cx
  3884                              <1> 	;and	cx, 3Fh	 ; sector  (1 to 63)
  3885 00002AC5 83E13F              <1> 	and	ecx, 3fh
  3886 00002AC8 86D6                <1> 	xchg	dl, dh
  3887 00002ACA C0EE06              <1> 	shr	dh, 6
  3888                              <1> 		; DX = cylinder (0 to 1023)
  3889                              <1> 	;mul 	dx
  3890                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder
  3891 00002ACD F7E2                <1> 	mul	edx
  3892 00002ACF FEC9                <1> 	dec	cl  ; sector - 1
  3893                              <1> 	;add	ax, cx
  3894                              <1> 	;adc	dx, 0
  3895                              <1> 		; DX:AX = # of Heads" * Sectors/Track * Cylinder + Sector -1
  3896 00002AD1 01C8                <1> 	add	eax, ecx
  3897 00002AD3 6659                <1> 	pop	cx ; * ; ch = head, cl = drive number (zero based)
  3898                              <1> 	;push	dx
  3899                              <1> 	;push	ax
  3900 00002AD5 50                  <1> 	push	eax
  3901                              <1> 	;mov	al, [ES:BX+14]	; sectors per track (logical)	
  3902 00002AD6 8A430E              <1> 	mov	al, [ebx+14]
  3903 00002AD9 F6E5                <1> 	mul	ch
  3904                              <1> 		;  AX = Head * Sectors/Track
  3905 00002ADB 6699                <1>         cwd
  3906                              <1> 	;pop	dx
  3907 00002ADD 5A                  <1> 	pop	edx
  3908                              <1> 	;add	ax, dx
  3909                              <1> 	;pop	dx
  3910                              <1> 	;adc	dx, 0 ; add carry bit
  3911 00002ADE 01D0                <1> 	add	eax, edx
  3912                              <1> lbarw2:
  3913 00002AE0 29D2                <1> 	sub	edx, edx ; 21/02/2015
  3914 00002AE2 88CA                <1> 	mov	dl, cl ; 21/02/2015
  3915 00002AE4 C645F800            <1>         mov     byte [CMD_BLOCK], 0 ; Features Register
  3916                              <1> 				; NOTE: Features register (1F1h, 171h)
  3917                              <1> 				; is not used for ATA device R/W functions. 
  3918                              <1> 				; It is old/obsolete 'write precompensation'
  3919                              <1> 				; register and error register
  3920                              <1> 				; for old ATA/IDE devices.
  3921                              <1> 	; 18/01/2014
  3922                              <1> 	;mov	ch, [hf_m_s]	; Drive 0 (master) or 1 (slave)
  3923 00002AE8 8A0D[B8A20000]      <1> 	mov	cl, [hf_m_s]
  3924                              <1> 	;shl	ch, 4		; bit 4 (drive bit)
  3925                              <1> 	;or	ch, 0E0h	; bit 5 = 1
  3926                              <1> 				; bit 6 = 1 = LBA mode
  3927                              <1> 				; bit 7 = 1
  3928 00002AEE 80C90E              <1> 	or	cl, 0Eh ; 1110b
  3929                              <1> 	;and	dh, 0Fh		; LBA byte 4 (bits 24 to 27)
  3930 00002AF1 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh
  3931 00002AF6 C1E11C              <1> 	shl	ecx, 28 ; 21/02/2015
  3932                              <1> 	;or	dh, ch
  3933 00002AF9 09C8                <1> 	or	eax, ecx	
  3934                              <1> 	;;mov	[CMD_BLOCK+2], al ; LBA byte 1 (bits 0 to 7)
  3935                              <1> 				  ; (Sector Number Register)
  3936                              <1> 	;;mov	[CMD_BLOCK+3], ah ; LBA byte 2 (bits 8 to 15)
  3937                              <1> 				  ; (Cylinder Low Register)
  3938                              <1> 	;mov	[CMD_BLOCK+2], ax ; LBA byte 1, 2
  3939                              <1> 	;mov	[CMD_BLOCK+4], dl ; LBA byte 3 (bits 16 to 23)
  3940                              <1> 				  ; (Cylinder High Register)
  3941                              <1> 	;;mov	[CMD_BLOCK+5], dh ; LBA byte 4 (bits 24 to 27)
  3942                              <1> 				  ; (Drive/Head Register)
  3943                              <1> 	
  3944                              <1> 	;mov	[CMD_BLOCK+4], dx ; LBA byte 4, LBA & DEV select bits
  3945 00002AFB 8945FA              <1> 	mov	[CMD_BLOCK+2], eax ; 21/02/2015
  3946                              <1> 	;14/02/2015
  3947                              <1> 	;mov	dl, cl ; Drive number (INIT_DRV)		
  3948 00002AFE EB38                <1> 	jmp	short su4
  3949                              <1> su3:
  3950                              <1> 	; 02/02/2015 
  3951                              <1> 	; (Temporary functions 1Bh & 1Ch are not valid for CHS mode) 
  3952 00002B00 80FC14              <1> 	cmp 	ah, 14h
  3953 00002B03 7604                <1> 	jna 	short chsfnc
  3954                              <1> invldfnc:
  3955                              <1>         ; 14/02/2015  
  3956                              <1> 	;pop	es ; **
  3957 00002B05 6658                <1>         pop     ax ; ***
  3958                              <1>         ;jmp     short BAD_COMMAND_POP
  3959 00002B07 EB49                <1>         jmp     short BAD_COMMAND
  3960                              <1> chsfnc:	
  3961                              <1> 	;MOV	AX,[ES:BX+5]		; GET WRITE PRE-COMPENSATION CYLINDER
  3962 00002B09 668B4305            <1> 	mov	ax, [ebx+5]
  3963 00002B0D 66C1E802            <1> 	SHR	AX,2
  3964 00002B11 8845F8              <1> 	MOV	[CMD_BLOCK],AL
  3965                              <1> 	;;MOV	AL,[ES:BX+8]		; GET CONTROL BYTE MODIFIER
  3966                              <1> 	;;PUSH	DX
  3967                              <1> 	;;MOV	DX,[HF_REG_PORT]
  3968                              <1> 	;;OUT	DX,AL			; SET EXTRA HEAD OPTION
  3969                              <1> 	;;POP	DX ; * 
  3970                              <1> 	;;POP	ES ; **
  3971                              <1> 	;;MOV	AH,[CONTROL_BYTE]	; SET EXTRA HEAD OPTION IN
  3972                              <1> 	;;AND	AH,0C0H 		; CONTROL BYTE	
  3973                              <1> 	;;OR	AH,AL
  3974                              <1> 	;;MOV	[CONTROL_BYTE],AH
  3975                              <1> 	;
  3976 00002B14 88C8                <1> 	MOV	AL,CL			; GET SECTOR NUMBER
  3977 00002B16 243F                <1> 	AND	AL,3FH
  3978 00002B18 8845FA              <1> 	MOV	[CMD_BLOCK+2],AL
  3979 00002B1B 886DFB              <1> 	MOV	[CMD_BLOCK+3],CH 	; GET CYLINDER NUMBER
  3980 00002B1E 88C8                <1> 	MOV	AL,CL
  3981 00002B20 C0E806              <1> 	SHR	AL,6
  3982 00002B23 8845FC              <1> 	MOV	[CMD_BLOCK+4],AL 	; CYLINDER HIGH ORDER 2 BITS
  3983                              <1> 	;;05/01/2015
  3984                              <1> 	;;MOV	AL,DL			; DRIVE NUMBER
  3985 00002B26 A0[B8A20000]        <1> 	mov	al, [hf_m_s]
  3986 00002B2B C0E004              <1> 	SHL	AL,4
  3987 00002B2E 80E60F              <1> 	AND	DH,0FH			; HEAD NUMBER
  3988 00002B31 08F0                <1> 	OR	AL,DH
  3989                              <1> 	;OR	AL,80H or 20H
  3990 00002B33 0CA0                <1> 	OR	AL,80h+20h		; ECC AND 512 BYTE SECTORS
  3991 00002B35 8845FD              <1> 	MOV	[CMD_BLOCK+5],AL 	; ECC/SIZE/DRIVE/HEAD
  3992                              <1> su4:
  3993                              <1> 	;POP	ES ; **
  3994                              <1>         ;; 14/02/2015
  3995                              <1>         ;;POP   AX
  3996                              <1>         ;;MOV   [CMD_BLOCK+1],AL        ; SECTOR COUNT
  3997                              <1>         ;;PUSH  AX
  3998                              <1>         ;;MOV   AL,AH                   ; GET INTO LOW BYTE
  3999                              <1>         ;;XOR   AH,AH                   ; ZERO HIGH BYTE
  4000                              <1>         ;;SAL   AX,1                    ; *2 FOR TABLE LOOKUP
  4001 00002B38 6658                <1>         pop     ax ; ***
  4002 00002B3A 8845F9              <1>         mov     [CMD_BLOCK+1], al
  4003 00002B3D 29DB                <1>         sub	ebx, ebx
  4004 00002B3F 88E3                <1> 	mov     bl, ah
  4005                              <1>         ;xor     bh, bh
  4006                              <1>         ;sal     bx, 1
  4007 00002B41 66C1E302            <1>         sal	bx, 2	; 32 bit offset (21/02/2015)
  4008                              <1> 	;;MOV   SI,AX                   ; PUT INTO SI FOR BRANCH
  4009                              <1>         ;;CMP   AX,D1L                  ; TEST WITHIN RANGE
  4010                              <1>         ;;JNB   short BAD_COMMAND_POP
  4011                              <1>         ;cmp     bx, D1L
  4012 00002B45 83FB74              <1> 	cmp	ebx, D1L
  4013 00002B48 7308                <1> 	jnb	short BAD_COMMAND
  4014                              <1>         ;xchg    bx, si
  4015 00002B4A 87DE                <1>         xchg	ebx, esi
  4016                              <1> 	;;;POP	AX			; RESTORE AX
  4017                              <1> 	;;;POP	BX			; AND DATA ADDRESS
  4018                              <1> 	
  4019                              <1> 	;;PUSH	CX
  4020                              <1> 	;;PUSH	AX			; ADJUST ES:BX
  4021                              <1> 	;MOV	CX,BX			; GET 3 HIGH ORDER NIBBLES OF BX
  4022                              <1> 	;SHR	CX,4
  4023                              <1> 	;MOV	AX,ES
  4024                              <1> 	;ADD	AX,CX
  4025                              <1> 	;MOV	ES,AX
  4026                              <1> 	;AND	BX,000FH		; ES:BX CHANGED TO ES:000X
  4027                              <1> 	;;POP	AX
  4028                              <1> 	;;POP	CX
  4029                              <1> 	;;JMP	word [CS:SI+D1]
  4030                              <1> 	;jmp	word [SI+D1]
  4031 00002B4C FFA6[9A290000]      <1> 	jmp	dword [esi+D1]
  4032                              <1> ;;BAD_COMMAND_POP:
  4033                              <1> ;;	POP	AX
  4034                              <1> ;;	POP	BX
  4035                              <1> BAD_COMMAND:
  4036 00002B52 C605[87A80000]01    <1>         MOV     byte [DISK_STATUS1],BAD_CMD  ; COMMAND ERROR
  4037 00002B59 B000                <1> 	MOV	AL,0
  4038 00002B5B C3                  <1> 	RETn
  4039                              <1> 
  4040                              <1> ;----------------------------------------
  4041                              <1> ;	RESET THE DISK SYSTEM  (AH=00H) :
  4042                              <1> ;----------------------------------------
  4043                              <1> 
  4044                              <1> ; 18-1-2015 : one controller reset (not other one)
  4045                              <1> 
  4046                              <1> DISK_RESET:
  4047 00002B5C FA                  <1> 	CLI
  4048 00002B5D E4A1                <1> 	IN	AL,INTB01		; GET THE MASK REGISTER
  4049                              <1> 	;JMP	$+2
  4050                              <1> 	IODELAY
  4050 00002B5F EB00                <2>  jmp short $+2
  4050 00002B61 EB00                <2>  jmp short $+2
  4051                              <1> 	;AND	AL,0BFH 		; ENABLE FIXED DISK INTERRUPT
  4052 00002B63 243F                <1> 	and	al,3Fh			; 22/12/2014 (IRQ 14 & IRQ 15)
  4053 00002B65 E6A1                <1> 	OUT	INTB01,AL
  4054 00002B67 FB                  <1> 	STI				; START INTERRUPTS
  4055                              <1> 	; 14/02/2015
  4056 00002B68 6689D7              <1> 	mov	di, dx	
  4057                              <1> 	; 04/01/2015
  4058                              <1> 	;xor	di,di
  4059                              <1> drst0:
  4060 00002B6B B004                <1> 	MOV	AL,04H  ; bit 2 - SRST 
  4061                              <1> 	;MOV	DX,HF_REG_PORT
  4062 00002B6D 668B15[B6A20000]    <1> 	MOV	DX,[HF_REG_PORT]
  4063 00002B74 EE                  <1> 	OUT	DX,AL			; RESET
  4064                              <1> ;	MOV	CX,10			; DELAY COUNT
  4065                              <1> ;DRD:	DEC	CX
  4066                              <1> ;	JNZ	short DRD		; WAIT 4.8 MICRO-SEC
  4067                              <1> 	;mov	cx,2			; wait for 30 micro seconds	
  4068 00002B75 B902000000          <1>         mov	ecx, 2 ; 21/02/2015
  4069 00002B7A E870EDFFFF          <1> 	call    WAITF                   ; (Award Bios 1999 - WAIT_REFRESH,
  4070                              <1>                                         ; 40 micro seconds)
  4071 00002B7F A0[89A80000]        <1> 	mov	al,[CONTROL_BYTE]
  4072 00002B84 240F                <1> 	AND	AL,0FH			; SET HEAD OPTION
  4073 00002B86 EE                  <1> 	OUT	DX,AL			; TURN RESET OFF
  4074 00002B87 E814040000          <1> 	CALL	NOT_BUSY
  4075 00002B8C 7515                <1> 	JNZ	short DRERR		; TIME OUT ON RESET
  4076 00002B8E 668B15[B4A20000]    <1> 	MOV	DX,[HF_PORT]
  4077 00002B95 FEC2                <1> 	inc	dl  ; HF_PORT+1
  4078                              <1> 	; 02/01/2015 - Award BIOS 1999 - AHDSK.ASM
  4079                              <1>         ;mov     cl, 10
  4080 00002B97 B90A000000          <1>         mov     ecx, 10 ; 21/02/2015 
  4081                              <1> drst1:
  4082 00002B9C EC                  <1> 	IN	AL,DX			; GET RESET STATUS
  4083 00002B9D 3C01                <1> 	CMP	AL,1
  4084                              <1> 	; 04/01/2015
  4085 00002B9F 740A                <1> 	jz	short drst2
  4086                              <1> 	;JNZ	short DRERR		; BAD RESET STATUS
  4087                              <1>         	; Drive/Head Register - bit 4
  4088 00002BA1 E2F9                <1> 	loop	drst1
  4089                              <1> DRERR:	
  4090 00002BA3 C605[87A80000]05    <1> 	MOV	byte [DISK_STATUS1],BAD_RESET ; CARD FAILED
  4091 00002BAA C3                  <1> 	RETn
  4092                              <1> drst2:
  4093                              <1> 	; 14/02/2015
  4094 00002BAB 6689FA              <1> 	mov	dx,di
  4095                              <1> ;drst3:
  4096                              <1> ;	; 05/01/2015
  4097                              <1> ;	shl 	di,1
  4098                              <1> ;	; 04/01/2015
  4099                              <1> ;	mov	ax,[di+hd_cports]
  4100                              <1> ;	cmp	ax,[HF_REG_PORT]
  4101                              <1> ;	je	short drst4
  4102                              <1> ;	mov	[HF_REG_PORT], ax
  4103                              <1> ;	; 03/01/2015
  4104                              <1> ;	mov	ax,[di+hd_ports]
  4105                              <1> ;       mov     [HF_PORT], ax
  4106                              <1> ;	; 05/01/2014
  4107                              <1> ;	shr	di,1
  4108                              <1> ;	; 04/01/2015
  4109                              <1> ;	jmp	short drst0	; reset other controller
  4110                              <1> ;drst4:
  4111                              <1> ;	; 05/01/2015
  4112                              <1> ;	shr	di,1
  4113                              <1> ;	mov	al,[di+hd_dregs]
  4114                              <1> ;	and	al,10h ; bit 4 only
  4115                              <1> ;	shr	al,4 ; bit 4  -> bit 0
  4116                              <1> ;	mov	[hf_m_s], al ; (0 = master, 1 = slave)
  4117                              <1> 	;
  4118 00002BAE A0[B8A20000]        <1> 	mov	al, [hf_m_s] ; 18/01/2015
  4119 00002BB3 A801                <1> 	test	al,1
  4120                              <1> ;	jnz	short drst6
  4121 00002BB5 7516                <1>         jnz     short drst4
  4122 00002BB7 8065FDEF            <1> 	AND     byte [CMD_BLOCK+5],0EFH ; SET TO DRIVE 0
  4123                              <1> ;drst5:
  4124                              <1> drst3:
  4125 00002BBB E811010000          <1> 	CALL	INIT_DRV		; SET MAX HEADS
  4126                              <1> 	;mov	dx,di
  4127 00002BC0 E8C9010000          <1> 	CALL	HDISK_RECAL		; RECAL TO RESET SEEK SPEED
  4128                              <1> 	; 04/01/2014
  4129                              <1> ;	inc	di
  4130                              <1> ;	mov	dx,di
  4131                              <1> ;	cmp	dl,[HF_NUM]
  4132                              <1> ;	jb	short drst3
  4133                              <1> ;DRE:
  4134 00002BC5 C605[87A80000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; IGNORE ANY SET UP ERRORS
  4135 00002BCC C3                  <1> 	RETn
  4136                              <1> ;drst6:
  4137                              <1> drst4:		; Drive/Head Register - bit 4
  4138 00002BCD 804DFD10            <1> 	OR      byte [CMD_BLOCK+5],010H ; SET TO DRIVE 1     
  4139                              <1>         ;jmp    short drst5
  4140 00002BD1 EBE8                <1>         jmp     short drst3
  4141                              <1> 
  4142                              <1> ;----------------------------------------
  4143                              <1> ;	DISK STATUS ROUTINE  (AH = 01H) :
  4144                              <1> ;----------------------------------------
  4145                              <1> 
  4146                              <1> RETURN_STATUS:
  4147 00002BD3 A0[87A80000]        <1> 	MOV	AL,[DISK_STATUS1]	; OBTAIN PREVIOUS STATUS
  4148 00002BD8 C605[87A80000]00    <1>         MOV     byte [DISK_STATUS1],0   ; RESET STATUS
  4149 00002BDF C3                  <1> 	RETn
  4150                              <1> 
  4151                              <1> ;----------------------------------------
  4152                              <1> ;	DISK READ ROUTINE    (AH = 02H) :
  4153                              <1> ;----------------------------------------
  4154                              <1> 
  4155                              <1> DISK_READ:
  4156 00002BE0 C645FE20            <1> 	MOV	byte [CMD_BLOCK+6],READ_CMD
  4157 00002BE4 E930020000          <1>         JMP     COMMANDI
  4158                              <1> 
  4159                              <1> ;----------------------------------------
  4160                              <1> ;	DISK WRITE ROUTINE   (AH = 03H) :
  4161                              <1> ;----------------------------------------
  4162                              <1> 
  4163                              <1> DISK_WRITE:
  4164 00002BE9 C645FE30            <1> 	MOV	byte [CMD_BLOCK+6],WRITE_CMD
  4165 00002BED E982020000          <1>         JMP     COMMANDO
  4166                              <1> 
  4167                              <1> ;----------------------------------------
  4168                              <1> ;	DISK VERIFY	     (AH = 04H) :
  4169                              <1> ;----------------------------------------
  4170                              <1> 
  4171                              <1> DISK_VERF:
  4172 00002BF2 C645FE40            <1> 	MOV	byte [CMD_BLOCK+6],VERIFY_CMD
  4173 00002BF6 E8F0020000          <1> 	CALL	COMMAND
  4174 00002BFB 750C                <1> 	JNZ	short VERF_EXIT		; CONTROLLER STILL BUSY
  4175 00002BFD E862030000          <1> 	CALL	_WAIT			; (Original: CALL WAIT)	
  4176 00002C02 7505                <1> 	JNZ	short VERF_EXIT		; TIME OUT
  4177 00002C04 E8EF030000          <1> 	CALL	CHECK_STATUS
  4178                              <1> VERF_EXIT:
  4179 00002C09 C3                  <1> 	RETn
  4180                              <1> 
  4181                              <1> ;----------------------------------------
  4182                              <1> ;	FORMATTING	     (AH = 05H) :
  4183                              <1> ;----------------------------------------
  4184                              <1> 
  4185                              <1> FMT_TRK:				; FORMAT TRACK	(AH = 005H)
  4186 00002C0A C645FE50            <1> 	MOV	byte [CMD_BLOCK+6],FMTTRK_CMD
  4187                              <1> 	;PUSH	ES
  4188                              <1> 	;PUSH	BX
  4189 00002C0E 53                  <1> 	push	ebx
  4190 00002C0F E896040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETERS ADDRESS
  4191                              <1> 	;MOV	AL,[ES:BX+14]		; GET SECTORS/TRACK
  4192 00002C14 8A430E              <1> 	mov	al, [ebx+14]
  4193 00002C17 8845F9              <1> 	MOV	[CMD_BLOCK+1],AL 	; SET SECTOR COUNT IN COMMAND
  4194 00002C1A 5B                  <1> 	pop	ebx
  4195                              <1> 	;POP	BX
  4196                              <1> 	;POP	ES
  4197 00002C1B E95B020000          <1>         JMP     CMD_OF                  ; GO EXECUTE THE COMMAND
  4198                              <1> 
  4199                              <1> ;----------------------------------------
  4200                              <1> ;	READ DASD TYPE	     (AH = 15H) :
  4201                              <1> ;----------------------------------------
  4202                              <1> 
  4203                              <1> READ_DASD_TYPE:
  4204                              <1> READ_D_T:				; GET DRIVE PARAMETERS
  4205 00002C20 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  4206                              <1> 	;PUSH	ES
  4207 00002C21 53                  <1> 	PUSH	eBX
  4208                              <1> 	;CALL	DDS			; ESTABLISH ADDRESSING
  4209                              <1> 	;push	cs
  4210                              <1> 	;pop	ds
  4211 00002C22 66BB1000            <1>         mov	bx, KDATA
  4212 00002C26 8EDB                <1> 	mov	ds, bx
  4213                              <1> 	;mov	es, bx
  4214 00002C28 C605[87A80000]00    <1> 	MOV     byte [DISK_STATUS1],0
  4215 00002C2F 8A1D[88A80000]      <1> 	MOV	BL,[HF_NUM]		; GET NUMBER OF DRIVES
  4216 00002C35 80E27F              <1> 	AND	DL,7FH			; GET DRIVE NUMBER
  4217 00002C38 38D3                <1> 	CMP	BL,DL
  4218 00002C3A 7625                <1> 	JBE	short RDT_NOT_PRESENT 	; RETURN DRIVE NOT PRESENT
  4219 00002C3C E869040000          <1> 	CALL	GET_VEC 		; GET DISK PARAMETER ADDRESS
  4220                              <1> 	;MOV	AL,[ES:BX+2]		; HEADS
  4221 00002C41 8A4302              <1> 	mov	al, [ebx+2]
  4222                              <1> 	;MOV	CL,[ES:BX+14]
  4223 00002C44 8A4B0E              <1> 	mov	cl, [ebx+14]
  4224 00002C47 F6E9                <1> 	IMUL	CL			; * NUMBER OF SECTORS
  4225                              <1> 	;MOV	CX,[ES:BX]		; MAX NUMBER OF CYLINDERS
  4226 00002C49 668B0B              <1> 	mov	cx ,[ebx]
  4227                              <1> 	;
  4228                              <1> 	; 02/01/2015 
  4229                              <1> 	; ** leave the last cylinder as reserved for diagnostics **
  4230                              <1> 	; (Also in Award BIOS - 1999, AHDSK.ASM, FUN15 -> sub ax, 1)
  4231 00002C4C 6649                <1> 	DEC	CX			; LEAVE ONE FOR DIAGNOSTICS
  4232                              <1> 	;
  4233 00002C4E 66F7E9              <1> 	IMUL	CX			; NUMBER OF SECTORS
  4234 00002C51 6689D1              <1> 	MOV	CX,DX			; HIGH ORDER HALF
  4235 00002C54 6689C2              <1> 	MOV	DX,AX			; LOW ORDER HALF
  4236                              <1> 	;SUB	AX,AX
  4237 00002C57 28C0                <1> 	sub	al, al
  4238 00002C59 B403                <1> 	MOV	AH,03H			; INDICATE FIXED DISK
  4239 00002C5B 5B                  <1> RDT2:	POP	eBX			; RESTORE REGISTERS
  4240                              <1> 	;POP	ES
  4241 00002C5C 1F                  <1> 	POP	DS
  4242 00002C5D F8                  <1> 	CLC				; CLEAR CARRY
  4243                              <1> 	;RETf	2
  4244 00002C5E CA0400              <1> 	retf	4
  4245                              <1> RDT_NOT_PRESENT:
  4246 00002C61 6629C0              <1> 	SUB	AX,AX			; DRIVE NOT PRESENT RETURN
  4247 00002C64 6689C1              <1> 	MOV	CX,AX			; ZERO BLOCK COUNT
  4248 00002C67 6689C2              <1> 	MOV	DX,AX
  4249 00002C6A EBEF                <1> 	JMP	short RDT2
  4250                              <1> 
  4251                              <1> ;----------------------------------------
  4252                              <1> ;	GET PARAMETERS	     (AH = 08H) :
  4253                              <1> ;----------------------------------------
  4254                              <1> 
  4255                              <1> GET_PARM_N:
  4256                              <1> ;GET_PARM:				; GET DRIVE PARAMETERS
  4257 00002C6C 1E                  <1> 	PUSH	DS			; SAVE REGISTERS
  4258                              <1> 	;PUSH	ES
  4259 00002C6D 53                  <1> 	PUSH	eBX
  4260                              <1> 	;MOV	AX,ABS0 		; ESTABLISH ADDRESSING
  4261                              <1> 	;MOV	DS,AX
  4262                              <1> 	;TEST	DL,1			; CHECK FOR DRIVE 1
  4263                              <1> 	;JZ	short G0
  4264                              <1> 	;LES	BX,@HF1_TBL_VEC
  4265                              <1> 	;JMP	SHORT G1
  4266                              <1> ;G0:	LES	BX,@HF_TBL_VEC
  4267                              <1> ;G1:
  4268                              <1> 	;CALL	DDS			; ESTABLISH SEGMENT
  4269                              <1> 	; 22/12/2014
  4270                              <1> 	;push	cs
  4271                              <1> 	;pop	ds
  4272 00002C6E 66BB1000            <1> 	mov	bx, KDATA
  4273 00002C72 8EDB                <1> 	mov	ds, bx
  4274                              <1> 	;mov	es, bx
  4275                              <1> 	;
  4276 00002C74 80EA80              <1> 	SUB	DL,80H
  4277 00002C77 80FA04              <1> 	CMP	DL,MAX_FILE		; TEST WITHIN RANGE
  4278 00002C7A 7341                <1> 	JAE	short G4
  4279                              <1> 	;
  4280 00002C7C 31DB                <1> 	xor	ebx, ebx ; 21/02/2015
  4281                              <1> 	; 22/12/2014
  4282 00002C7E 88D3                <1> 	mov	bl, dl
  4283                              <1> 	;xor	bh, bh  
  4284 00002C80 C0E302              <1> 	shl	bl, 2			; convert index to offset
  4285                              <1> 	;add	bx, HF_TBL_VEC
  4286 00002C83 81C3[8CA80000]      <1> 	add	ebx, HF_TBL_VEC
  4287                              <1> 	;mov	ax, [bx+2]
  4288                              <1> 	;mov	es, ax			; dpt segment
  4289                              <1> 	;mov	bx, [bx]		; dpt offset
  4290 00002C89 8B1B                <1> 	mov	ebx, [ebx] ; 32 bit offset	
  4291                              <1> 
  4292 00002C8B C605[87A80000]00    <1> 	MOV	byte [DISK_STATUS1],0
  4293                              <1>         ;MOV     AX,[ES:BX]              ; MAX NUMBER OF CYLINDERS
  4294 00002C92 668B03              <1> 	mov	ax, [ebx]
  4295                              <1> 	;;SUB	AX,2			; ADJUST FOR 0-N
  4296 00002C95 6648                <1> 	dec	ax			; max. cylinder number
  4297 00002C97 88C5                <1> 	MOV	CH,AL
  4298 00002C99 66250003            <1> 	AND	AX,0300H		; HIGH TWO BITS OF CYLINDER
  4299 00002C9D 66D1E8              <1> 	SHR	AX,1
  4300 00002CA0 66D1E8              <1> 	SHR	AX,1
  4301                              <1> 	;OR	AL,[ES:BX+14]		; SECTORS
  4302 00002CA3 0A430E              <1> 	or	al, [ebx+14]
  4303 00002CA6 88C1                <1> 	MOV	CL,AL
  4304                              <1> 	;MOV	DH,[ES:BX+2]		; HEADS
  4305 00002CA8 8A7302              <1> 	mov	dh, [ebx+2]
  4306 00002CAB FECE                <1> 	DEC	DH			; 0-N RANGE
  4307 00002CAD 8A15[88A80000]      <1> 	MOV	DL,[HF_NUM]		; DRIVE COUNT
  4308 00002CB3 6629C0              <1> 	SUB	AX,AX
  4309                              <1>         ;27/12/2014 
  4310                              <1> 	; ES:DI = Address of disk parameter table from BIOS
  4311                              <1> 	;(Programmer's Guide to the AMIBIOS - 1993)
  4312                              <1> 	;mov	di, bx			; HDPT offset
  4313 00002CB6 89DF                <1> 	mov	edi, ebx
  4314                              <1> G5:
  4315 00002CB8 5B                  <1> 	POP	eBX			; RESTORE REGISTERS
  4316                              <1> 	;POP	ES
  4317 00002CB9 1F                  <1> 	POP	DS
  4318                              <1> 	;RETf	2
  4319 00002CBA CA0400              <1> 	retf	4
  4320                              <1> G4:
  4321 00002CBD C605[87A80000]07    <1> 	MOV     byte [DISK_STATUS1],INIT_FAIL ; OPERATION FAILED
  4322 00002CC4 B407                <1> 	MOV	AH,INIT_FAIL
  4323 00002CC6 28C0                <1> 	SUB	AL,AL
  4324 00002CC8 6629D2              <1> 	SUB	DX,DX
  4325 00002CCB 6629C9              <1> 	SUB	CX,CX
  4326 00002CCE F9                  <1> 	STC				; SET ERROR FLAG
  4327 00002CCF EBE7                <1> 	JMP	short G5
  4328                              <1> 
  4329                              <1> ;----------------------------------------
  4330                              <1> ;	INITIALIZE DRIVE     (AH = 09H) :
  4331                              <1> ;----------------------------------------
  4332                              <1> 	; 03/01/2015
  4333                              <1> 	; According to ATA-ATAPI specification v2.0 to v5.0
  4334                              <1> 	; logical sector per logical track
  4335                              <1> 	; and logical heads - 1 would be set but
  4336                              <1> 	; it is seen as it will be good
  4337                              <1> 	; if physical parameters will be set here
  4338                              <1> 	; because, number of heads <= 16.
  4339                              <1> 	; (logical heads usually more than 16)
  4340                              <1> 	; NOTE: ATA logical parameters (software C, H, S)
  4341                              <1> 	;	== INT 13h physical parameters
  4342                              <1> 
  4343                              <1> ;INIT_DRV:
  4344                              <1> ;	MOV	byte [CMD_BLOCK+6],SET_PARM_CMD
  4345                              <1> ;	CALL	GET_VEC 		; ES:BX -> PARAMETER BLOCK
  4346                              <1> ;	MOV	AL,[ES:BX+2]		; GET NUMBER OF HEADS
  4347                              <1> ;	DEC	AL			; CONVERT TO 0-INDEX
  4348                              <1> ;	MOV	AH,[CMD_BLOCK+5] 	; GET SDH REGISTER
  4349                              <1> ;	AND	AH,0F0H 		; CHANGE HEAD NUMBER
  4350                              <1> ;	OR	AH,AL			; TO MAX HEAD
  4351                              <1> ;	MOV	[CMD_BLOCK+5],AH
  4352                              <1> ;	MOV	AL,[ES:BX+14]		; MAX SECTOR NUMBER
  4353                              <1> ;	MOV	[CMD_BLOCK+1],AL
  4354                              <1> ;	SUB	AX,AX
  4355                              <1> ;	MOV	[CMD_BLOCK+3],AL 	; ZERO FLAGS
  4356                              <1> ;	CALL	COMMAND 		; TELL CONTROLLER
  4357                              <1> ;	JNZ	short INIT_EXIT		; CONTROLLER BUSY ERROR
  4358                              <1> ;	CALL	NOT_BUSY		; WAIT FOR IT TO BE DONE
  4359                              <1> ;	JNZ	short INIT_EXIT		; TIME OUT
  4360                              <1> ;	CALL	CHECK_STATUS
  4361                              <1> ;INIT_EXIT:
  4362                              <1> ;	RETn
  4363                              <1> 
  4364                              <1> ; 04/01/2015
  4365                              <1> ; 02/01/2015 - Derived from from AWARD BIOS 1999
  4366                              <1> ;				 AHDSK.ASM - INIT_DRIVE
  4367                              <1> INIT_DRV:
  4368                              <1> 	;xor	ah,ah
  4369 00002CD1 31C0                <1> 	xor	eax, eax ; 21/02/2015
  4370 00002CD3 B00B                <1> 	mov	al,11 ; Physical heads from translated HDPT
  4371 00002CD5 3825[9CA80000]      <1>         cmp     [LBAMode], ah   ; 0
  4372 00002CDB 7702                <1> 	ja	short idrv0
  4373 00002CDD B002                <1> 	mov	al,2  ; Physical heads from standard HDPT
  4374                              <1> idrv0:
  4375                              <1> 	; DL = drive number (0 based)
  4376 00002CDF E8C6030000          <1> 	call	GET_VEC
  4377                              <1> 	;push	bx
  4378 00002CE4 53                  <1> 	push	ebx ; 21/02/2015
  4379                              <1> 	;add	bx,ax
  4380 00002CE5 01C3                <1> 	add	ebx, eax
  4381                              <1> 	;; 05/01/2015
  4382 00002CE7 8A25[B8A20000]      <1> 	mov	ah, [hf_m_s] ; drive number (0= master, 1= slave)
  4383                              <1> 	;;and 	ah,1 
  4384 00002CED C0E404              <1> 	shl	ah,4
  4385 00002CF0 80CCA0              <1> 	or	ah,0A0h  ; Drive/Head register - 10100000b (A0h)	
  4386                              <1> 	;mov	al,[es:bx]
  4387 00002CF3 8A03                <1> 	mov	al, [ebx] ; 21/02/2015
  4388 00002CF5 FEC8                <1> 	dec	al	 ; last head number 
  4389                              <1> 	;and	al,0Fh
  4390 00002CF7 08E0                <1> 	or	al,ah	 ; lower 4 bits for head number
  4391                              <1> 	;
  4392 00002CF9 C645FE91            <1> 	mov	byte [CMD_BLOCK+6],SET_PARM_CMD
  4393 00002CFD 8845FD              <1> 	mov	[CMD_BLOCK+5],al
  4394                              <1> 	;pop	bx
  4395 00002D00 5B                  <1> 	pop	ebx
  4396 00002D01 29C0                <1> 	sub	eax, eax ; 21/02/2015
  4397 00002D03 B004                <1> 	mov	al,4 ; Physical sec per track from translated HDPT
  4398 00002D05 803D[9CA80000]00    <1> 	cmp	byte [LBAMode], 0
  4399 00002D0C 7702                <1> 	ja	short idrv1
  4400 00002D0E B00E                <1> 	mov	al,14 ; Physical sec per track from standard HDPT
  4401                              <1> idrv1:
  4402                              <1> 	;xor	ah,ah
  4403                              <1> 	;add	bx,ax
  4404 00002D10 01C3                <1> 	add	ebx, eax ; 21/02/2015
  4405                              <1> 	;mov	al,[es:bx]
  4406                              <1> 			; sector number
  4407 00002D12 8A03                <1> 	mov	al, [ebx]
  4408 00002D14 8845F9              <1> 	mov	[CMD_BLOCK+1],al
  4409 00002D17 28C0                <1> 	sub	al,al
  4410 00002D19 8845FB              <1> 	mov	[CMD_BLOCK+3],al  ; ZERO FLAGS
  4411 00002D1C E8CA010000          <1> 	call	COMMAND 	  ; TELL CONTROLLER
  4412 00002D21 750C                <1> 	jnz	short INIT_EXIT	  ; CONTROLLER BUSY ERROR
  4413 00002D23 E878020000          <1> 	call	NOT_BUSY	  ; WAIT FOR IT TO BE DONE
  4414 00002D28 7505                <1> 	jnz	short INIT_EXIT	  ; TIME OUT
  4415 00002D2A E8C9020000          <1> 	call	CHECK_STATUS
  4416                              <1> INIT_EXIT:
  4417 00002D2F C3                  <1> 	RETn
  4418                              <1> 
  4419                              <1> ;----------------------------------------
  4420                              <1> ;	READ LONG	     (AH = 0AH) :
  4421                              <1> ;----------------------------------------
  4422                              <1> 
  4423                              <1> RD_LONG:
  4424                              <1> 	;MOV	@CMD_BLOCK+6,READ_CMD OR ECC_MODE
  4425 00002D30 C645FE22            <1>         mov     byte [CMD_BLOCK+6],READ_CMD + ECC_MODE 
  4426 00002D34 E9E0000000          <1>         JMP     COMMANDI
  4427                              <1> 
  4428                              <1> ;----------------------------------------
  4429                              <1> ;	WRITE LONG	     (AH = 0BH) :
  4430                              <1> ;----------------------------------------
  4431                              <1> 
  4432                              <1> WR_LONG:
  4433                              <1> 	;MOV	@CMD_BLOCK+6,WRITE_CMD OR ECC_MODE
  4434 00002D39 C645FE32            <1>         MOV     byte [CMD_BLOCK+6],WRITE_CMD + ECC_MODE
  4435 00002D3D E932010000          <1>         JMP     COMMANDO
  4436                              <1> 
  4437                              <1> ;----------------------------------------
  4438                              <1> ;	SEEK		     (AH = 0CH) :
  4439                              <1> ;----------------------------------------
  4440                              <1> 
  4441                              <1> DISK_SEEK:
  4442 00002D42 C645FE70            <1>         MOV     byte [CMD_BLOCK+6],SEEK_CMD
  4443 00002D46 E8A0010000          <1> 	CALL	COMMAND
  4444 00002D4B 751C                <1> 	JNZ	short DS_EXIT 		; CONTROLLER BUSY ERROR
  4445 00002D4D E812020000          <1> 	CALL	_WAIT
  4446 00002D52 7515                <1>         JNZ     DS_EXIT                 ; TIME OUT ON SEEK
  4447 00002D54 E89F020000          <1> 	CALL	CHECK_STATUS
  4448 00002D59 803D[87A80000]40    <1>         CMP     byte [DISK_STATUS1],BAD_SEEK
  4449 00002D60 7507                <1> 	JNE	short DS_EXIT
  4450 00002D62 C605[87A80000]00    <1>         MOV     byte [DISK_STATUS1],0
  4451                              <1> DS_EXIT:
  4452 00002D69 C3                  <1> 	RETn
  4453                              <1> 
  4454                              <1> ;----------------------------------------
  4455                              <1> ;	TEST DISK READY      (AH = 10H) :
  4456                              <1> ;----------------------------------------
  4457                              <1> 
  4458                              <1> TST_RDY:				; WAIT FOR CONTROLLER
  4459 00002D6A E831020000          <1> 	CALL	NOT_BUSY
  4460 00002D6F 751C                <1> 	JNZ	short TR_EX
  4461 00002D71 8A45FD              <1> 	MOV	AL,[CMD_BLOCK+5] 	; SELECT DRIVE
  4462 00002D74 668B15[B4A20000]    <1> 	MOV	DX,[HF_PORT]
  4463 00002D7B 80C206              <1> 	add	dl,6
  4464 00002D7E EE                  <1> 	OUT	DX,AL
  4465 00002D7F E88C020000          <1> 	CALL	CHECK_ST		; CHECK STATUS ONLY
  4466 00002D84 7507                <1> 	JNZ	short TR_EX
  4467 00002D86 C605[87A80000]00    <1> 	MOV	byte [DISK_STATUS1],0 	; WIPE OUT DATA CORRECTED ERROR
  4468                              <1> TR_EX:	
  4469 00002D8D C3                  <1> 	RETn
  4470                              <1> 
  4471                              <1> ;----------------------------------------
  4472                              <1> ;	RECALIBRATE	     (AH = 11H) :
  4473                              <1> ;----------------------------------------
  4474                              <1> 
  4475                              <1> HDISK_RECAL:
  4476 00002D8E C645FE10            <1>         MOV     byte [CMD_BLOCK+6],RECAL_CMD ; 10h, 16
  4477 00002D92 E854010000          <1> 	CALL	COMMAND 		; START THE OPERATION
  4478 00002D97 7523                <1> 	JNZ	short RECAL_EXIT	; ERROR
  4479 00002D99 E8C6010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION
  4480 00002D9E 7407                <1> 	JZ	short RECAL_X 		; TIME OUT ONE OK ?
  4481 00002DA0 E8BF010000          <1> 	CALL	_WAIT			; WAIT FOR COMPLETION LONGER
  4482 00002DA5 7515                <1> 	JNZ	short RECAL_EXIT	; TIME OUT TWO TIMES IS ERROR
  4483                              <1> RECAL_X:
  4484 00002DA7 E84C020000          <1> 	CALL	CHECK_STATUS
  4485 00002DAC 803D[87A80000]40    <1> 	CMP	byte [DISK_STATUS1],BAD_SEEK ; SEEK NOT COMPLETE
  4486 00002DB3 7507                <1> 	JNE	short RECAL_EXIT	; IS OK
  4487 00002DB5 C605[87A80000]00    <1> 	MOV	byte [DISK_STATUS1],0
  4488                              <1> RECAL_EXIT:
  4489 00002DBC 803D[87A80000]00    <1>         CMP     byte [DISK_STATUS1],0
  4490 00002DC3 C3                  <1> 	RETn
  4491                              <1> 
  4492                              <1> ;----------------------------------------
  4493                              <1> ;      CONTROLLER DIAGNOSTIC (AH = 14H) :
  4494                              <1> ;----------------------------------------
  4495                              <1> 
  4496                              <1> CTLR_DIAGNOSTIC:
  4497 00002DC4 FA                  <1>         CLI                             ; DISABLE INTERRUPTS WHILE CHANGING MASK
  4498 00002DC5 E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  4499                              <1> 	;AND	AL,0BFH
  4500 00002DC7 243F                <1> 	and	al, 3Fh			; enable IRQ 14 & IRQ 15
  4501                              <1> 	;JMP	$+2
  4502                              <1> 	IODELAY
  4502 00002DC9 EB00                <2>  jmp short $+2
  4502 00002DCB EB00                <2>  jmp short $+2
  4503 00002DCD E6A1                <1> 	OUT	INTB01,AL
  4504                              <1> 	IODELAY
  4504 00002DCF EB00                <2>  jmp short $+2
  4504 00002DD1 EB00                <2>  jmp short $+2
  4505 00002DD3 E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  4506 00002DD5 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  4507                              <1> 	;JMP	$+2
  4508                              <1> 	IODELAY
  4508 00002DD7 EB00                <2>  jmp short $+2
  4508 00002DD9 EB00                <2>  jmp short $+2
  4509 00002DDB E621                <1> 	OUT	INTA01,AL
  4510 00002DDD FB                  <1> 	STI
  4511 00002DDE E8BD010000          <1> 	CALL	NOT_BUSY		; WAIT FOR CARD
  4512 00002DE3 752B                <1> 	JNZ	short CD_ERR		; BAD CARD
  4513                              <1> 	;MOV	DX, HF_PORT+7
  4514 00002DE5 668B15[B4A20000]    <1> 	mov	dx, [HF_PORT]
  4515 00002DEC 80C207              <1> 	add	dl, 7
  4516 00002DEF B090                <1> 	MOV	AL,DIAG_CMD		; START DIAGNOSE
  4517 00002DF1 EE                  <1> 	OUT	DX,AL
  4518 00002DF2 E8A9010000          <1> 	CALL	NOT_BUSY		; WAIT FOR IT TO COMPLETE
  4519 00002DF7 B480                <1> 	MOV	AH,TIME_OUT
  4520 00002DF9 7517                <1> 	JNZ	short CD_EXIT 		; TIME OUT ON DIAGNOSTIC
  4521                              <1> 	;MOV	DX,HF_PORT+1		; GET ERROR REGISTER
  4522 00002DFB 668B15[B4A20000]    <1> 	mov	dx, [HF_PORT]
  4523 00002E02 FEC2                <1> 	inc	dl
  4524 00002E04 EC                  <1> 	IN	AL,DX
  4525 00002E05 A2[7EA80000]        <1> 	MOV	[HF_ERROR],AL		; SAVE IT
  4526 00002E0A B400                <1> 	MOV	AH,0
  4527 00002E0C 3C01                <1> 	CMP	AL,1			; CHECK FOR ALL OK
  4528 00002E0E 7402                <1> 	JE	SHORT CD_EXIT
  4529 00002E10 B420                <1> CD_ERR: MOV	AH,BAD_CNTLR
  4530                              <1> CD_EXIT:
  4531 00002E12 8825[87A80000]      <1> 	MOV	[DISK_STATUS1],AH
  4532 00002E18 C3                  <1> 	RETn
  4533                              <1> 
  4534                              <1> ;----------------------------------------
  4535                              <1> ; COMMANDI				:
  4536                              <1> ;	REPEATEDLY INPUTS DATA TILL	:
  4537                              <1> ;	NSECTOR RETURNS ZERO		:
  4538                              <1> ;----------------------------------------
  4539                              <1> COMMANDI:
  4540 00002E19 E862020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  4541 00002E1E 7253                <1> 	JC	short CMD_ABORT
  4542                              <1> 	;MOV	DI,BX
  4543 00002E20 89DF                <1> 	mov	edi, ebx ; 21/02/2015
  4544 00002E22 E8C4000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  4545 00002E27 754A                <1> 	JNZ	short CMD_ABORT
  4546                              <1> CMD_I1:
  4547 00002E29 E836010000          <1> 	CALL	_WAIT			; WAIT FOR DATA REQUEST INTERRUPT
  4548 00002E2E 7543                <1> 	JNZ	short TM_OUT		; TIME OUT
  4549                              <1> cmd_i1x: ; 18/02/2016
  4550                              <1> 	;MOV	CX,256			; SECTOR SIZE IN WORDS
  4551 00002E30 B900010000          <1> 	mov	ecx, 256 ; 21/02/2015	
  4552                              <1> 	;MOV	DX,HF_PORT
  4553 00002E35 668B15[B4A20000]    <1> 	mov	dx,[HF_PORT]
  4554 00002E3C FA                  <1> 	CLI
  4555 00002E3D FC                  <1> 	CLD
  4556 00002E3E F3666D              <1> 	REP	INSW			; GET THE SECTOR
  4557 00002E41 FB                  <1> 	STI
  4558 00002E42 F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL INPUT
  4559 00002E46 7419                <1> 	JZ	short CMD_I3
  4560 00002E48 E880010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4561 00002E4D 7224                <1> 	JC	short TM_OUT
  4562                              <1> 	;MOV	DX,HF_PORT
  4563 00002E4F 668B15[B4A20000]    <1> 	mov	dx,[HF_PORT]
  4564                              <1> 	;MOV	CX,4			; GET ECC BYTES
  4565 00002E56 B904000000          <1> 	mov 	ecx, 4 ; mov cx, 4 
  4566 00002E5B EC                  <1> CMD_I2: IN	AL,DX
  4567                              <1> 	;MOV	[ES:DI],AL		; GO SLOW FOR BOARD
  4568 00002E5C 8807                <1> 	mov 	[edi], al ; 21/02/2015
  4569 00002E5E 47                  <1> 	INC	eDI
  4570 00002E5F E2FA                <1> 	LOOP	CMD_I2
  4571                              <1> CMD_I3: 
  4572                              <1> 	; wait for 400 ns
  4573 00002E61 80C207              <1> 	add 	dl, 7
  4574 00002E64 EC                  <1> 	in	al, dx
  4575 00002E65 EC                  <1> 	in	al, dx
  4576 00002E66 EC                  <1> 	in	al, dx
  4577                              <1> 	;
  4578 00002E67 E88C010000          <1> 	CALL	CHECK_STATUS
  4579 00002E6C 7505                <1> 	JNZ	short CMD_ABORT		; ERROR RETURNED
  4580 00002E6E FE4DF9              <1> 	DEC	byte [CMD_BLOCK+1]	; CHECK FOR MORE
  4581                              <1> 	;JNZ	SHORT CMD_I1
  4582 00002E71 75BD                <1> 	jnz	short cmd_i1x ; 18/02/2016
  4583                              <1> CMD_ABORT:
  4584 00002E73 C3                  <1> TM_OUT: RETn
  4585                              <1> 
  4586                              <1> ;----------------------------------------
  4587                              <1> ; COMMANDO				:
  4588                              <1> ;	REPEATEDLY OUTPUTS DATA TILL	:
  4589                              <1> ;	NSECTOR RETURNS ZERO		:
  4590                              <1> ;----------------------------------------
  4591                              <1> COMMANDO:
  4592 00002E74 E807020000          <1> 	CALL	CHECK_DMA		; CHECK 64K BOUNDARY ERROR
  4593 00002E79 72F8                <1> 	JC	short CMD_ABORT
  4594 00002E7B 89DE                <1> CMD_OF: MOV	eSI,eBX ; 21/02/2015
  4595 00002E7D E869000000          <1> 	CALL	COMMAND 		; OUTPUT COMMAND
  4596 00002E82 75EF                <1> 	JNZ	short CMD_ABORT
  4597 00002E84 E844010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4598 00002E89 72E8                <1> 	JC	short TM_OUT			; TOO LONG
  4599                              <1> CMD_O1: ;PUSH	DS
  4600                              <1> 	;PUSH	ES			; MOVE ES TO DS
  4601                              <1> 	;POP	DS
  4602                              <1> 	;MOV	CX,256			; PUT THE DATA OUT TO THE CARD
  4603                              <1> 	;MOV	DX,HF_PORT
  4604                              <1> 	; 01/02/2015
  4605 00002E8B 668B15[B4A20000]    <1> 	mov	dx, [HF_PORT]
  4606                              <1> 	;push	es
  4607                              <1> 	;pop	ds
  4608                              <1> 	;mov	cx, 256
  4609 00002E92 B900010000          <1> 	mov	ecx, 256 ; 21/02/2015
  4610 00002E97 FA                  <1> 	CLI
  4611 00002E98 FC                  <1> 	CLD
  4612 00002E99 F3666F              <1> 	REP	OUTSW
  4613 00002E9C FB                  <1> 	STI
  4614                              <1> 	;POP	DS			; RESTORE DS
  4615 00002E9D F645FE02            <1> 	TEST	byte [CMD_BLOCK+6],ECC_MODE ; CHECK FOR NORMAL OUTPUT
  4616 00002EA1 7419                <1> 	JZ	short CMD_O3
  4617 00002EA3 E825010000          <1> 	CALL	WAIT_DRQ		; WAIT FOR DATA REQUEST
  4618 00002EA8 72C9                <1> 	JC	short TM_OUT
  4619                              <1> 	;MOV	DX,HF_PORT
  4620 00002EAA 668B15[B4A20000]    <1> 	mov	dx, [HF_PORT]
  4621                              <1> 	;MOV	CX,4			; OUTPUT THE ECC BYTES
  4622 00002EB1 B904000000          <1> 	mov	ecx, 4  ; mov cx, 4
  4623                              <1> CMD_O2: ;MOV	AL,[ES:SI]
  4624 00002EB6 8A06                <1> 	mov	al, [esi]
  4625 00002EB8 EE                  <1> 	OUT	DX,AL
  4626 00002EB9 46                  <1> 	INC	eSI
  4627 00002EBA E2FA                <1> 	LOOP	CMD_O2
  4628                              <1> CMD_O3:
  4629 00002EBC E8A3000000          <1> 	CALL	_WAIT			; WAIT FOR SECTOR COMPLETE INTERRUPT
  4630 00002EC1 75B0                <1> 	JNZ	short TM_OUT		; ERROR RETURNED
  4631 00002EC3 E830010000          <1> 	CALL	CHECK_STATUS
  4632 00002EC8 75A9                <1> 	JNZ	short CMD_ABORT
  4633 00002ECA F605[7DA80000]08    <1> 	TEST	byte [HF_STATUS],ST_DRQ	; CHECK FOR MORE
  4634 00002ED1 75B8                <1> 	JNZ	SHORT CMD_O1
  4635                              <1> 	;MOV	DX,HF_PORT+2		; CHECK RESIDUAL SECTOR COUNT
  4636 00002ED3 668B15[B4A20000]    <1> 	mov	dx, [HF_PORT]
  4637                              <1> 	;add	dl, 2
  4638 00002EDA FEC2                <1> 	inc	dl
  4639 00002EDC FEC2                <1> 	inc	dl
  4640 00002EDE EC                  <1> 	IN	AL,DX			;
  4641 00002EDF A8FF                <1> 	TEST	AL,0FFH 		;
  4642 00002EE1 7407                <1> 	JZ	short CMD_O4			; COUNT = 0  OK
  4643 00002EE3 C605[87A80000]BB    <1> 	MOV	byte [DISK_STATUS1],UNDEF_ERR 
  4644                              <1> 					; OPERATION ABORTED - PARTIAL TRANSFER
  4645                              <1> CMD_O4:
  4646 00002EEA C3                  <1> 	RETn
  4647                              <1> 
  4648                              <1> ;--------------------------------------------------------
  4649                              <1> ; COMMAND						:
  4650                              <1> ;	THIS ROUTINE OUTPUTS THE COMMAND BLOCK		:
  4651                              <1> ; OUTPUT						:
  4652                              <1> ;	BL = STATUS					:
  4653                              <1> ;	BH = ERROR REGISTER				:
  4654                              <1> ;--------------------------------------------------------
  4655                              <1> 
  4656                              <1> COMMAND:
  4657 00002EEB 53                  <1> 	PUSH	eBX			; WAIT FOR SEEK COMPLETE AND READY
  4658                              <1> 	;;MOV	CX,DELAY_2		; SET INITIAL DELAY BEFORE TEST
  4659                              <1> COMMAND1:
  4660                              <1> 	;;PUSH	CX			; SAVE LOOP COUNT
  4661 00002EEC E879FEFFFF          <1> 	CALL	TST_RDY 		; CHECK DRIVE READY
  4662                              <1> 	;;POP	CX
  4663 00002EF1 7419                <1> 	JZ	short COMMAND2		; DRIVE IS READY
  4664 00002EF3 803D[87A80000]80    <1>         CMP     byte [DISK_STATUS1],TIME_OUT ; TST_RDY TIMED OUT--GIVE UP
  4665                              <1> 	;JZ	short CMD_TIMEOUT
  4666                              <1> 	;;LOOP	COMMAND1		; KEEP TRYING FOR A WHILE
  4667                              <1> 	;JMP	SHORT COMMAND4		; ITS NOT GOING TO GET READY
  4668 00002EFA 7507                <1> 	jne	short COMMAND4
  4669                              <1> CMD_TIMEOUT:
  4670 00002EFC C605[87A80000]20    <1> 	MOV	byte [DISK_STATUS1],BAD_CNTLR
  4671                              <1> COMMAND4:
  4672 00002F03 5B                  <1> 	POP	eBX
  4673 00002F04 803D[87A80000]00    <1>         CMP     byte [DISK_STATUS1],0   ; SET CONDITION CODE FOR CALLER
  4674 00002F0B C3                  <1> 	RETn
  4675                              <1> COMMAND2:
  4676 00002F0C 5B                  <1> 	POP	eBX
  4677 00002F0D 57                  <1> 	PUSH	eDI
  4678 00002F0E C605[7FA80000]00    <1> 	MOV	byte [HF_INT_FLAG],0	; RESET INTERRUPT FLAG
  4679 00002F15 FA                  <1> 	CLI				; INHIBIT INTERRUPTS WHILE CHANGING MASK
  4680 00002F16 E4A1                <1> 	IN	AL,INTB01		; TURN ON SECOND INTERRUPT CHIP
  4681                              <1> 	;AND	AL,0BFH
  4682 00002F18 243F                <1> 	and	al, 3Fh			; Enable IRQ 14 & 15
  4683                              <1> 	;JMP	$+2
  4684                              <1> 	IODELAY
  4684 00002F1A EB00                <2>  jmp short $+2
  4684 00002F1C EB00                <2>  jmp short $+2
  4685 00002F1E E6A1                <1> 	OUT	INTB01,AL
  4686 00002F20 E421                <1> 	IN	AL,INTA01		; LET INTERRUPTS PASS THRU TO
  4687 00002F22 24FB                <1> 	AND	AL,0FBH 		;  SECOND CHIP
  4688                              <1> 	;JMP	$+2
  4689                              <1> 	IODELAY
  4689 00002F24 EB00                <2>  jmp short $+2
  4689 00002F26 EB00                <2>  jmp short $+2
  4690 00002F28 E621                <1> 	OUT	INTA01,AL
  4691 00002F2A FB                  <1> 	STI
  4692 00002F2B 31FF                <1> 	XOR	eDI,eDI			; INDEX THE COMMAND TABLE
  4693                              <1> 	;MOV	DX,HF_PORT+1		; DISK ADDRESS
  4694 00002F2D 668B15[B4A20000]    <1> 	mov	dx, [HF_PORT]
  4695 00002F34 FEC2                <1> 	inc	dl
  4696 00002F36 F605[89A80000]C0    <1> 	TEST	byte [CONTROL_BYTE],0C0H ; CHECK FOR RETRY SUPPRESSION
  4697 00002F3D 7411                <1> 	JZ	short COMMAND3
  4698 00002F3F 8A45FE              <1> 	MOV	AL, [CMD_BLOCK+6] 	; YES-GET OPERATION CODE
  4699 00002F42 24F0                <1> 	AND	AL,0F0H 		; GET RID OF MODIFIERS
  4700 00002F44 3C20                <1> 	CMP	AL,20H			; 20H-40H IS READ, WRITE, VERIFY
  4701 00002F46 7208                <1> 	JB	short COMMAND3
  4702 00002F48 3C40                <1> 	CMP	AL,40H
  4703 00002F4A 7704                <1> 	JA	short COMMAND3
  4704 00002F4C 804DFE01            <1> 	OR	byte [CMD_BLOCK+6],NO_RETRIES 
  4705                              <1> 					; VALID OPERATION FOR RETRY SUPPRESS
  4706                              <1> COMMAND3:
  4707 00002F50 8A443DF8            <1> 	MOV	AL,[CMD_BLOCK+eDI]	; GET THE COMMAND STRING BYTE
  4708 00002F54 EE                  <1> 	OUT	DX,AL			; GIVE IT TO CONTROLLER
  4709                              <1> 	IODELAY
  4709 00002F55 EB00                <2>  jmp short $+2
  4709 00002F57 EB00                <2>  jmp short $+2
  4710 00002F59 47                  <1> 	INC	eDI			; NEXT BYTE IN COMMAND BLOCK
  4711 00002F5A 6642                <1> 	INC	DX			; NEXT DISK ADAPTER REGISTER
  4712 00002F5C 6683FF07            <1> 	cmp	di, 7	; 1/1/2015	; ALL DONE?
  4713 00002F60 75EE                <1> 	JNZ	short COMMAND3		; NO--GO DO NEXT ONE
  4714 00002F62 5F                  <1> 	POP	eDI
  4715 00002F63 C3                  <1> 	RETn				; ZERO FLAG IS SET
  4716                              <1> 
  4717                              <1> ;CMD_TIMEOUT:
  4718                              <1> ;	MOV	byte [DISK_STATUS1],BAD_CNTLR
  4719                              <1> ;COMMAND4:
  4720                              <1> ;	POP	BX
  4721                              <1> ;	CMP	[DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  4722                              <1> ;	RETn
  4723                              <1> 
  4724                              <1> ;----------------------------------------
  4725                              <1> ;	WAIT FOR INTERRUPT		:
  4726                              <1> ;----------------------------------------
  4727                              <1> ;WAIT:
  4728                              <1> _WAIT:
  4729 00002F64 FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  4730                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  4731                              <1> 	;CLC
  4732                              <1> 	;MOV	AX,9000H		; DEVICE WAIT INTERRUPT
  4733                              <1> 	;INT	15H
  4734                              <1> 	;JC	WT2			; DEVICE TIMED OUT
  4735                              <1> 	;MOV	BL,DELAY_1		; SET DELAY COUNT
  4736                              <1> 
  4737                              <1> 	;mov	bl, WAIT_HDU_INT_HI
  4738                              <1> 	;; 21/02/2015
  4739                              <1> 	;;mov	bl, WAIT_HDU_INT_HI + 1
  4740                              <1> 	;;mov	cx, WAIT_HDU_INT_LO
  4741 00002F65 B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH
  4742                              <1> 					; (AWARD BIOS -> WAIT_FOR_MEM)
  4743                              <1> ;-----	WAIT LOOP
  4744                              <1> 
  4745                              <1> WT1:	
  4746                              <1> 	;TEST	byte [HF_INT_FLAG],80H	; TEST FOR INTERRUPT
  4747 00002F6A F605[7FA80000]C0    <1> 	test 	byte [HF_INT_FLAG],0C0h
  4748                              <1> 	;LOOPZ	WT1
  4749 00002F71 7517                <1> 	JNZ	short WT3		; INTERRUPT--LETS GO
  4750                              <1> 	;DEC	BL
  4751                              <1> 	;JNZ	short WT1		; KEEP TRYING FOR A WHILE
  4752                              <1> 
  4753                              <1> WT1_hi:
  4754 00002F73 E461                <1> 	in	al, SYS1 ; 61h (PORT_B)	; wait for lo to hi
  4755 00002F75 A810                <1> 	test	al, 10h			; transition on memory
  4756 00002F77 75FA                <1> 	jnz	short WT1_hi		; refresh.
  4757                              <1> WT1_lo:
  4758 00002F79 E461                <1> 	in	al, SYS1 		; 061h (PORT_B)	
  4759 00002F7B A810                <1> 	test	al, 10h			
  4760 00002F7D 74FA                <1> 	jz	short WT1_lo
  4761 00002F7F E2E9                <1> 	loop	WT1
  4762                              <1> 	;;or	bl, bl
  4763                              <1> 	;;jz	short WT2	
  4764                              <1> 	;;dec	bl
  4765                              <1> 	;;jmp	short WT1
  4766                              <1> 	;dec	bl
  4767                              <1> 	;jnz	short WT1	
  4768                              <1> 
  4769 00002F81 C605[87A80000]80    <1> WT2:	MOV	byte [DISK_STATUS1],TIME_OUT ; REPORT TIME OUT ERROR
  4770 00002F88 EB0E                <1> 	JMP	SHORT WT4
  4771 00002F8A C605[87A80000]00    <1> WT3:	MOV	byte [DISK_STATUS1],0
  4772 00002F91 C605[7FA80000]00    <1> 	MOV	byte [HF_INT_FLAG],0
  4773 00002F98 803D[87A80000]00    <1> WT4:	CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  4774 00002F9F C3                  <1> 	RETn
  4775                              <1> 
  4776                              <1> ;----------------------------------------
  4777                              <1> ;	WAIT FOR CONTROLLER NOT BUSY	:
  4778                              <1> ;----------------------------------------
  4779                              <1> NOT_BUSY:
  4780 00002FA0 FB                  <1> 	STI				; MAKE SURE INTERRUPTS ARE ON
  4781                              <1> 	;PUSH	eBX
  4782                              <1> 	;SUB	CX,CX			; SET INITIAL DELAY BEFORE TEST
  4783 00002FA1 668B15[B4A20000]    <1> 	mov	DX, [HF_PORT]
  4784 00002FA8 80C207              <1> 	add	dl, 7			; Status port (HF_PORT+7)
  4785                              <1> 	;MOV	BL,DELAY_1
  4786                              <1> 					; wait for 10 seconds
  4787                              <1> 	;mov 	cx, WAIT_HDU_INT_LO	; 1615h
  4788                              <1> 	;;mov 	bl, WAIT_HDU_INT_HI	;   05h
  4789                              <1> 	;mov	bl, WAIT_HDU_INT_HI + 1
  4790 00002FAB B915160500          <1> 	mov	ecx, WAIT_HDU_INT_LH  ; 21/02/2015
  4791                              <1> 	;
  4792                              <1> ;;      mov     byte [wait_count], 0    ; Reset wait counter
  4793                              <1> NB1:	
  4794 00002FB0 EC                  <1> 	IN	AL,DX			; CHECK STATUS
  4795                              <1> 	;TEST	AL,ST_BUSY
  4796 00002FB1 2480                <1> 	and	al, ST_BUSY
  4797                              <1> 	;LOOPNZ	NB1
  4798 00002FB3 7410                <1> 	JZ	short NB2		; NOT BUSY--LETS GO
  4799                              <1> 	;DEC	BL			
  4800                              <1> 	;JNZ	short NB1		; KEEP TRYING FOR A WHILE
  4801                              <1> 
  4802 00002FB5 E461                <1> NB1_hi: IN	AL,SYS1			; wait for hi to lo
  4803 00002FB7 A810                <1> 	TEST	AL,010H			; transition on memory
  4804 00002FB9 75FA                <1> 	JNZ	SHORT NB1_hi		; refresh.
  4805 00002FBB E461                <1> NB1_lo: IN	AL,SYS1
  4806 00002FBD A810                <1> 	TEST	AL,010H
  4807 00002FBF 74FA                <1> 	JZ	short NB1_lo
  4808 00002FC1 E2ED                <1> 	LOOP	NB1
  4809                              <1> 	;dec	bl
  4810                              <1> 	;jnz	short NB1
  4811                              <1> 	;
  4812                              <1> ;;      cmp     byte [wait_count], 182  ; 10 seconds (182 timer ticks)
  4813                              <1> ;;	jb	short NB1
  4814                              <1> 	;
  4815                              <1> 	;MOV	[DISK_STATUS1],TIME_OUT	; REPORT TIME OUT ERROR
  4816                              <1> 	;JMP	SHORT NB3
  4817 00002FC3 B080                <1> 	mov	al, TIME_OUT
  4818                              <1> NB2:	
  4819                              <1> 	;MOV	byte [DISK_STATUS1],0
  4820                              <1> ;NB3:	
  4821                              <1> 	;POP	eBX
  4822 00002FC5 A2[87A80000]        <1> 	mov	[DISK_STATUS1], al	;;; will be set after return
  4823                              <1> 	;CMP	byte [DISK_STATUS1],0 	; SET CONDITION CODE FOR CALLER
  4824 00002FCA 08C0                <1> 	or	al, al			; (zf = 0 --> timeout)
  4825 00002FCC C3                  <1> 	RETn
  4826                              <1> 
  4827                              <1> ;----------------------------------------
  4828                              <1> ;	WAIT FOR DATA REQUEST		:
  4829                              <1> ;----------------------------------------
  4830                              <1> WAIT_DRQ:
  4831                              <1> 	;MOV	CX,DELAY_3
  4832                              <1> 	;MOV	DX,HF_PORT+7
  4833 00002FCD 668B15[B4A20000]    <1> 	mov	dx, [HF_PORT]
  4834 00002FD4 80C207              <1> 	add	dl, 7
  4835                              <1> 	;;MOV	bl, WAIT_HDU_DRQ_HI	; 0
  4836                              <1> 	;MOV	cx, WAIT_HDU_DRQ_LO	; 1000 (30 milli seconds)
  4837                              <1> 					; (but it is written as 2000
  4838                              <1> 					; micro seconds in ATORGS.ASM file
  4839                              <1> 					; of Award Bios - 1999, D1A0622)
  4840 00002FD7 B9E8030000          <1> 	mov 	ecx, WAIT_HDU_DRQ_LH ; 21/02/2015 
  4841 00002FDC EC                  <1> WQ_1:	IN	AL,DX			; GET STATUS
  4842 00002FDD A808                <1> 	TEST	AL,ST_DRQ		; WAIT FOR DRQ
  4843 00002FDF 7516                <1> 	JNZ	short WQ_OK
  4844                              <1> 	;LOOP	WQ_1			; KEEP TRYING FOR A SHORT WHILE
  4845                              <1> WQ_hi:	
  4846 00002FE1 E461                <1> 	IN	AL,SYS1			; wait for hi to lo
  4847 00002FE3 A810                <1> 	TEST	AL,010H			; transition on memory
  4848 00002FE5 75FA                <1> 	JNZ	SHORT WQ_hi		; refresh.
  4849 00002FE7 E461                <1> WQ_lo:  IN      AL,SYS1
  4850 00002FE9 A810                <1> 	TEST	AL,010H
  4851 00002FEB 74FA                <1> 	JZ	SHORT WQ_lo
  4852 00002FED E2ED                <1> 	LOOP	WQ_1
  4853                              <1> 
  4854 00002FEF C605[87A80000]80    <1>         MOV     byte [DISK_STATUS1],TIME_OUT ; ERROR
  4855 00002FF6 F9                  <1> 	STC
  4856                              <1> WQ_OK:
  4857 00002FF7 C3                  <1> 	RETn
  4858                              <1> ;WQ_OK:	;CLC
  4859                              <1> ;	RETn
  4860                              <1> 
  4861                              <1> ;----------------------------------------
  4862                              <1> ;	CHECK FIXED DISK STATUS 	:
  4863                              <1> ;----------------------------------------
  4864                              <1> CHECK_STATUS:
  4865 00002FF8 E813000000          <1> 	CALL	CHECK_ST		; CHECK THE STATUS BYTE
  4866 00002FFD 7509                <1> 	JNZ	short CHECK_S1		; AN ERROR WAS FOUND
  4867 00002FFF A801                <1> 	TEST	AL,ST_ERROR		; WERE THERE ANY OTHER ERRORS
  4868 00003001 7405                <1> 	JZ	short CHECK_S1		; NO ERROR REPORTED
  4869 00003003 E849000000          <1> 	CALL	CHECK_ER		; ERROR REPORTED
  4870                              <1> CHECK_S1:
  4871 00003008 803D[87A80000]00    <1> 	CMP	byte [DISK_STATUS1],0 	; SET STATUS FOR CALLER
  4872 0000300F C3                  <1> 	RETn
  4873                              <1> 
  4874                              <1> ;----------------------------------------
  4875                              <1> ;	CHECK FIXED DISK STATUS BYTE	:
  4876                              <1> ;----------------------------------------
  4877                              <1> CHECK_ST:
  4878                              <1> 	;MOV	DX,HF_PORT+7		; GET THE STATUS
  4879 00003010 668B15[B4A20000]    <1> 	mov	dx, [HF_PORT]
  4880 00003017 80C207              <1> 	add	dl, 7
  4881                              <1> 	
  4882                              <1> 	; 17/02/2016
  4883                              <1> 	;(http://wiki.osdev.org/ATA_PIO_Mode)
  4884                              <1> 	;"delay 400ns to allow drive to set new values of BSY and DRQ"
  4885 0000301A EC                  <1> 	IN	AL,DX
  4886                              <1> 	;in	al, dx ; 100ns
  4887                              <1> 	;in	al, dx ; 100ns
  4888                              <1>  	;in	al, dx ; 100ns
  4889                              <1> 	NEWIODELAY ; 18/02/2016 (AWARD BIOS - 1999, 'CKST' in AHSDK.ASM)
  4889 0000301B E6EB                <2>  out 0ebh,al
  4890                              <1> 	;
  4891 0000301D A2[7DA80000]        <1> 	MOV	[HF_STATUS],AL
  4892 00003022 B400                <1> 	MOV	AH,0
  4893 00003024 A880                <1> 	TEST	AL,ST_BUSY		; IF STILL BUSY
  4894 00003026 751A                <1> 	JNZ	short CKST_EXIT		;  REPORT OK
  4895 00003028 B4CC                <1> 	MOV	AH,WRITE_FAULT
  4896 0000302A A820                <1> 	TEST	AL,ST_WRT_FLT		; CHECK FOR WRITE FAULT
  4897 0000302C 7514                <1> 	JNZ	short CKST_EXIT
  4898 0000302E B4AA                <1> 	MOV	AH,NOT_RDY
  4899 00003030 A840                <1> 	TEST	AL,ST_READY		; CHECK FOR NOT READY
  4900 00003032 740E                <1> 	JZ	short CKST_EXIT
  4901 00003034 B440                <1> 	MOV	AH,BAD_SEEK
  4902 00003036 A810                <1> 	TEST	AL,ST_SEEK_COMPL	; CHECK FOR SEEK NOT COMPLETE
  4903 00003038 7408                <1> 	JZ	short CKST_EXIT
  4904 0000303A B411                <1> 	MOV	AH,DATA_CORRECTED
  4905 0000303C A804                <1> 	TEST	AL,ST_CORRCTD		; CHECK FOR CORRECTED ECC
  4906 0000303E 7502                <1> 	JNZ	short CKST_EXIT
  4907 00003040 B400                <1> 	MOV	AH,0
  4908                              <1> CKST_EXIT:
  4909 00003042 8825[87A80000]      <1> 	MOV	[DISK_STATUS1],AH	; SET ERROR FLAG
  4910 00003048 80FC11              <1> 	CMP	AH,DATA_CORRECTED	; KEEP GOING WITH DATA CORRECTED
  4911 0000304B 7403                <1> 	JZ	short CKST_EX1
  4912 0000304D 80FC00              <1> 	CMP	AH,0
  4913                              <1> CKST_EX1:
  4914 00003050 C3                  <1> 	RETn
  4915                              <1> 
  4916                              <1> ;----------------------------------------
  4917                              <1> ;	CHECK FIXED DISK ERROR REGISTER :
  4918                              <1> ;----------------------------------------
  4919                              <1> CHECK_ER:
  4920                              <1> 	;MOV	DX, HF_PORT+1		; GET THE ERROR REGISTER
  4921 00003051 668B15[B4A20000]    <1> 	mov	dx, [HF_PORT]		;
  4922 00003058 FEC2                <1> 	inc	dl
  4923 0000305A EC                  <1> 	IN	AL,DX
  4924 0000305B A2[7EA80000]        <1> 	MOV	[HF_ERROR],AL
  4925 00003060 53                  <1> 	PUSH	eBX ; 21/02/2015
  4926 00003061 B908000000          <1> 	MOV	eCX,8			; TEST ALL 8 BITS
  4927 00003066 D0E0                <1> CK1:	SHL	AL,1			; MOVE NEXT ERROR BIT TO CARRY
  4928 00003068 7202                <1> 	JC	short CK2		; FOUND THE ERROR
  4929 0000306A E2FA                <1> 	LOOP	CK1			; KEEP TRYING
  4930 0000306C BB[A8A20000]        <1> CK2:	MOV	eBX, ERR_TBL		; COMPUTE ADDRESS OF
  4931 00003071 01CB                <1> 	ADD	eBX,eCX			; ERROR CODE
  4932                              <1> 	;;MOV	AH,BYTE [CS:BX]		; GET ERROR CODE
  4933                              <1> 	;mov	ah, [bx]
  4934 00003073 8A23                <1> 	mov	ah, [ebx] ; 21/02/2015	
  4935 00003075 8825[87A80000]      <1> CKEX:	MOV	[DISK_STATUS1],AH	; SAVE ERROR CODE
  4936 0000307B 5B                  <1> 	POP	eBX
  4937 0000307C 80FC00              <1> 	CMP	AH,0
  4938 0000307F C3                  <1> 	RETn
  4939                              <1> 
  4940                              <1> ;--------------------------------------------------------
  4941                              <1> ; CHECK_DMA						:
  4942                              <1> ;  -CHECK ES:BX AND # SECTORS TO MAKE SURE THAT IT WILL :
  4943                              <1> ;   FIT WITHOUT SEGMENT OVERFLOW.			:
  4944                              <1> ;  -ES:BX HAS BEEN REVISED TO THE FORMAT SSSS:000X	:
  4945                              <1> ;  -OK IF # SECTORS < 80H (7FH IF LONG READ OR WRITE)	:
  4946                              <1> ;  -OK IF # SECTORS = 80H (7FH) AND BX <= 00H (04H)	:
  4947                              <1> ;  -ERROR OTHERWISE					:
  4948                              <1> ;--------------------------------------------------------
  4949                              <1> CHECK_DMA:
  4950 00003080 6650                <1> 	PUSH	AX			; SAVE REGISTERS
  4951 00003082 66B80080            <1> 	MOV	AX,8000H		; AH = MAX # SECTORS AL = MAX OFFSET
  4952 00003086 F645FE02            <1>         TEST    byte [CMD_BLOCK+6],ECC_MODE
  4953 0000308A 7404                <1> 	JZ	short CKD1
  4954 0000308C 66B8047F            <1> 	MOV	AX,7F04H		; ECC IS 4 MORE BYTES
  4955 00003090 3A65F9              <1> CKD1:	CMP	AH, [CMD_BLOCK+1] 	; NUMBER OF SECTORS
  4956 00003093 7706                <1> 	JA	short CKDOK		; IT WILL FIT
  4957 00003095 7208                <1> 	JB	short CKDERR		; TOO MANY
  4958 00003097 38D8                <1> 	CMP	AL,BL			; CHECK OFFSET ON MAX SECTORS
  4959 00003099 7204                <1> 	JB	short CKDERR		; ERROR
  4960 0000309B F8                  <1> CKDOK:	CLC				; CLEAR CARRY
  4961 0000309C 6658                <1> 	POP	AX
  4962 0000309E C3                  <1> 	RETn				; NORMAL RETURN
  4963 0000309F F9                  <1> CKDERR: STC				; INDICATE ERROR
  4964 000030A0 C605[87A80000]09    <1>         MOV     byte [DISK_STATUS1],DMA_BOUNDARY
  4965 000030A7 6658                <1> 	POP	AX
  4966 000030A9 C3                  <1> 	RETn
  4967                              <1> 
  4968                              <1> ;----------------------------------------
  4969                              <1> ;	SET UP ES:BX-> DISK PARMS	:
  4970                              <1> ;----------------------------------------
  4971                              <1> 					
  4972                              <1> ; INPUT -> DL = 0 based drive number
  4973                              <1> ; OUTPUT -> ES:BX = disk parameter table address
  4974                              <1> 
  4975                              <1> GET_VEC:
  4976                              <1> 	;SUB	AX,AX			; GET DISK PARAMETER ADDRESS
  4977                              <1> 	;MOV	ES,AX
  4978                              <1> 	;TEST	DL,1
  4979                              <1> 	;JZ	short GV_0
  4980                              <1> ;	LES	BX,[HF1_TBL_VEC] 	; ES:BX -> DRIVE PARAMETERS
  4981                              <1> ;	JMP	SHORT GV_EXIT
  4982                              <1> ;GV_0:
  4983                              <1> ;	LES	BX,[HF_TBL_VEC]		; ES:BX -> DRIVE PARAMETERS
  4984                              <1> ;
  4985                              <1> 	;xor	bh, bh
  4986 000030AA 31DB                <1> 	xor	ebx, ebx
  4987 000030AC 88D3                <1> 	mov	bl, dl
  4988                              <1> 	;;02/01/2015
  4989                              <1> 	;;shl	bl, 1			; port address offset
  4990                              <1> 	;;mov	ax, [bx+hd_ports]	; Base port address (1F0h, 170h)
  4991                              <1> 	;;shl	bl, 1			; dpt pointer offset
  4992 000030AE C0E302              <1> 	shl	bl, 2	;;
  4993                              <1> 	;add	bx, HF_TBL_VEC		; Disk parameter table pointer
  4994 000030B1 81C3[8CA80000]      <1> 	add	ebx, HF_TBL_VEC ; 21/02/2015
  4995                              <1> 	;push	word [bx+2]		; dpt segment
  4996                              <1> 	;pop	es
  4997                              <1> 	;mov	bx, [bx]		; dpt offset
  4998 000030B7 8B1B                <1> 	mov	ebx, [ebx]		
  4999                              <1> ;GV_EXIT:
  5000 000030B9 C3                  <1> 	RETn
  5001                              <1> 
  5002                              <1> hdc1_int: ; 21/02/2015
  5003                              <1> ;--- HARDWARE INT 76H -- ( IRQ LEVEL  14 ) ----------------------
  5004                              <1> ;								:
  5005                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  5006                              <1> ;								:
  5007                              <1> ;----------------------------------------------------------------
  5008                              <1> 
  5009                              <1> ; 22/12/2014
  5010                              <1> ; IBM PC-XT Model 286 System BIOS Source Code - DISK.ASM (HD_INT)
  5011                              <1> ;	 '11/15/85'
  5012                              <1> ; AWARD BIOS 1999 (D1A0622) 
  5013                              <1> ;	Source Code - ATORGS.ASM (INT_HDISK, INT_HDISK1)
  5014                              <1> 
  5015                              <1> ;int_76h:
  5016                              <1> HD_INT:
  5017 000030BA 6650                <1> 	PUSH	AX
  5018 000030BC 1E                  <1> 	PUSH	DS
  5019                              <1> 	;CALL	DDS
  5020                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  5021 000030BD 66B81000            <1> 	mov	ax, KDATA
  5022 000030C1 8ED8                <1> 	mov 	ds, ax
  5023                              <1> 	;
  5024                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
  5025                              <1>         ;mov     byte [CS:HF_INT_FLAG], 0FFh
  5026 000030C3 C605[7FA80000]FF    <1> 	mov	byte [HF_INT_FLAG], 0FFh
  5027                              <1> 	;
  5028 000030CA 6652                <1> 	push	dx
  5029 000030CC 66BAF701            <1> 	mov	dx, HDC1_BASEPORT+7	; Status Register (1F7h)
  5030                              <1> 					; Clear Controller
  5031                              <1> Clear_IRQ1415:				; (Award BIOS - 1999)
  5032 000030D0 EC                  <1> 	in	al, dx			;
  5033 000030D1 665A                <1> 	pop	dx
  5034                              <1> 	NEWIODELAY
  5034 000030D3 E6EB                <2>  out 0ebh,al
  5035                              <1> 	;
  5036 000030D5 B020                <1> 	MOV	AL,EOI			; NON-SPECIFIC END OF INTERRUPT
  5037 000030D7 E6A0                <1> 	OUT	INTB00,AL		; FOR CONTROLLER #2
  5038                              <1> 	;JMP	$+2			; WAIT
  5039                              <1> 	NEWIODELAY
  5039 000030D9 E6EB                <2>  out 0ebh,al
  5040 000030DB E620                <1> 	OUT	INTA00,AL		; FOR CONTROLLER #1
  5041 000030DD 1F                  <1> 	POP	DS
  5042                              <1> 	;STI				; RE-ENABLE INTERRUPTS
  5043                              <1> 	;MOV	AX,9100H		; DEVICE POST
  5044                              <1> 	;INT	15H			;  INTERRUPT
  5045                              <1> irq15_iret: ; 25/02/2015
  5046 000030DE 6658                <1> 	POP	AX
  5047 000030E0 CF                  <1> 	IRETd				; RETURN FROM INTERRUPT
  5048                              <1> 
  5049                              <1> hdc2_int: ; 21/02/2015
  5050                              <1> ;++++ HARDWARE INT 77H ++ ( IRQ LEVEL  15 ) +++++++++++++++++++++
  5051                              <1> ;								:
  5052                              <1> ;	FIXED DISK INTERRUPT ROUTINE				:
  5053                              <1> ;								:
  5054                              <1> ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5055                              <1> 
  5056                              <1> ;int_77h:
  5057                              <1> HD1_INT:
  5058 000030E1 6650                <1> 	PUSH	AX
  5059                              <1> 	; Check if that is a spurious IRQ (from slave PIC)
  5060                              <1> 	; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  5061 000030E3 B00B                <1> 	mov	al, 0Bh  ; In-Service Register
  5062 000030E5 E6A0                <1> 	out	0A0h, al
  5063 000030E7 EB00                <1>         jmp short $+2
  5064 000030E9 EB00                <1> 	jmp short $+2
  5065 000030EB E4A0                <1> 	in	al, 0A0h
  5066 000030ED 2480                <1> 	and 	al, 80h ; bit 7 (is it real IRQ 15 or fake?)
  5067 000030EF 74ED                <1> 	jz	short irq15_iret ; Fake (spurious)IRQ, do not send EOI)
  5068                              <1> 	;
  5069 000030F1 1E                  <1> 	PUSH	DS
  5070                              <1> 	;CALL	DDS
  5071                              <1> 	; 21/02/2015 (32 bit, 386 pm modification)
  5072 000030F2 66B81000            <1> 	mov	ax, KDATA
  5073 000030F6 8ED8                <1> 	mov 	ds, ax
  5074                              <1> 	;
  5075                              <1> 	;;MOV	@HF_INT_FLAG,0FFH	; ALL DONE
  5076                              <1>         ;or      byte [CS:HF_INT_FLAG],0C0h 
  5077 000030F8 800D[7FA80000]C0    <1> 	or	byte [HF_INT_FLAG], 0C0h
  5078                              <1> 	;
  5079 000030FF 6652                <1> 	push	dx
  5080 00003101 66BA7701            <1> 	mov	dx, HDC2_BASEPORT+7	; Status Register (177h)
  5081                              <1> 					; Clear Controller (Award BIOS 1999)
  5082 00003105 EBC9                <1> 	jmp	short Clear_IRQ1415
  5083                              <1> 
  5084                              <1> 
  5085                              <1> ;%include 'diskdata.inc' ; 11/03/2015
  5086                              <1> ;%include 'diskbss.inc' ; 11/03/2015
  5087                              <1> 
  5088                              <1> 
  5089                              <1> ;////////////////////////////////////////////////////////////////////
  5090                              <1> ;; END OF DISK I/O SYTEM ///
  1909                                  %include 'memory.s'  ; 09/03/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - memory.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 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> ; memory.inc (18/10/2015)
    15                              <1> ; ****************************************************************************
    16                              <1> 
    17                              <1> ; MEMORY.ASM - Retro UNIX 386 v1 MEMORY MANAGEMENT FUNCTIONS (PROCEDURES)
    18                              <1> ; Retro UNIX 386 v1 Kernel (unix386.s, v0.2.0.14) - MEMORY.INC
    19                              <1> ; Last Modification: 18/10/2015
    20                              <1> 
    21                              <1> ; ///////// MEMORY MANAGEMENT FUNCTIONS (PROCEDURES) ///////////////
    22                              <1> 
    23                              <1> ;;04/11/2014 (unix386.s)	
    24                              <1> ;PDE_A_PRESENT	equ	1		; Present flag for PDE
    25                              <1> ;PDE_A_WRITE	equ 	2		; Writable (write permission) flag
    26                              <1> ;PDE_A_USER	equ	4		; User (non-system/kernel) page flag
    27                              <1> ;;
    28                              <1> ;PTE_A_PRESENT	equ	1		; Present flag for PTE (bit 0)
    29                              <1> ;PTE_A_WRITE	equ 	2		; Writable (write permission) flag (bit 1)
    30                              <1> ;PTE_A_USER	equ	4		; User (non-system/kernel) page flag (bit 2)
    31                              <1> ;PTE_A_ACCESS   equ	32		; Accessed flag (bit 5) ; 09/03/2015
    32                              <1> 
    33                              <1> ; 27/04/2015
    34                              <1> ; 09/03/2015
    35                              <1> PAGE_SIZE 	equ 4096		; page size in bytes
    36                              <1> PAGE_SHIFT 	equ 12			; page table shift count
    37                              <1> PAGE_D_SHIFT 	equ 22	; 12 + 10	; page directory shift count
    38                              <1> PAGE_OFF	equ 0FFFh		; 12 bit byte offset in page frame
    39                              <1> PTE_MASK 	equ 03FFh		; page table entry mask
    40                              <1> PTE_DUPLICATED  equ 200h		; duplicated page sign (AVL bit 0)
    41                              <1> PDE_A_CLEAR	equ 0F000h		; to clear PDE attribute bits
    42                              <1> PTE_A_CLEAR	equ 0F000h		; to clear PTE attribute bits
    43                              <1> LOGIC_SECT_SIZE equ 512			; logical sector size
    44                              <1> ERR_MAJOR_PF	equ 0E0h		; major error: page fault
    45                              <1> ERR_MINOR_IM	equ 1			; insufficient (out of) memory
    46                              <1> ERR_MINOR_DSK	equ 2			; disk read/write error
    47                              <1> ERR_MINOR_PV	equ 3			; protection violation
    48                              <1> SWP_DISK_READ_ERR equ 4
    49                              <1> SWP_DISK_NOT_PRESENT_ERR equ 5
    50                              <1> SWP_SECTOR_NOT_PRESENT_ERR equ 6
    51                              <1> SWP_NO_FREE_SPACE_ERR equ 7
    52                              <1> SWP_DISK_WRITE_ERR equ 8
    53                              <1> SWP_NO_PAGE_TO_SWAP_ERR equ 9
    54                              <1> PTE_A_ACCESS_BIT equ 5  ; Bit 5 (accessed flag)        
    55                              <1> SECTOR_SHIFT    equ 3   ; sector shift (to convert page block number)
    56                              <1> 
    57                              <1> ;
    58                              <1> ;; Retro Unix 386 v1 - paging method/principles
    59                              <1> ;;
    60                              <1> ;; 10/10/2014
    61                              <1> ;; RETRO UNIX 386 v1 - PAGING METHOD/PRINCIPLES
    62                              <1> ;;
    63                              <1> ;; KERNEL PAGE MAP: 1 to 1 physical memory page map
    64                              <1> ;;	(virtual address = physical address)
    65                              <1> ;; KERNEL PAGE TABLES:
    66                              <1> ;;	Kernel page directory and all page tables are
    67                              <1> ;;	on memory as initialized, as equal to physical memory
    68                              <1> ;;	layout. Kernel pages can/must not be swapped out/in.
    69                              <1> ;;
    70                              <1> ;;	what for: User pages may be swapped out, when accessing
    71                              <1> ;;	a page in kernel/system mode, if it would be swapped out,
    72                              <1> ;;	kernel would have to swap it in! But it is also may be
    73                              <1> ;;	in use by a user process. (In system/kernel mode
    74                              <1> ;;	kernel can access all memory pages even if they are
    75                              <1> ;;	reserved/allocated for user processes. Swap out/in would
    76                              <1> ;;	cause conflicts.) 
    77                              <1> ;;	
    78                              <1> ;;	As result of these conditions,
    79                              <1> ;;	all kernel pages must be initialized as equal to 
    80                              <1> ;;	physical layout for preventing page faults. 
    81                              <1> ;;	Also, calling "allocate page" procedure after
    82                              <1> ;;	a page fault can cause another page fault (double fault)
    83                              <1> ;;	if all kernel page tables would not be initialized.
    84                              <1> ;;
    85                              <1> ;;	[first_page] = Beginning of users space, as offset to 
    86                              <1> ;;	memory allocation table. (double word aligned)
    87                              <1> ;;
    88                              <1> ;;	[next_page] = first/next free space to be searched
    89                              <1> ;;	as offset to memory allocation table. (dw aligned)
    90                              <1> ;;
    91                              <1> ;;	[last_page] = End of memory (users space), as offset
    92                              <1> ;;	to memory allocation table. (double word aligned)
    93                              <1> ;;
    94                              <1> ;; USER PAGE TABLES:
    95                              <1> ;;	Demand paging (& 'copy on write' allocation method) ...
    96                              <1> ;;		'ready only' marked copies of the 
    97                              <1> ;;		parent process's page table entries (for
    98                              <1> ;;		same physical memory).
    99                              <1> ;;		(A page will be copied to a new page after
   100                              <1> ;;		 if it causes R/W page fault.)
   101                              <1> ;;
   102                              <1> ;;	Every user process has own (different)
   103                              <1> ;;	page directory and page tables.	
   104                              <1> ;;
   105                              <1> ;;	Code starts at virtual address 0, always.
   106                              <1> ;;	(Initial value of EIP is 0 in user mode.)
   107                              <1> ;;	(Programs can be written/developed as simple
   108                              <1> ;;	 flat memory programs.)
   109                              <1> ;;
   110                              <1> ;; MEMORY ALLOCATION STRATEGY:
   111                              <1> ;;	Memory page will be allocated by kernel only 
   112                              <1> ;;		(in kernel/system mode only).
   113                              <1> ;;	* After a
   114                              <1> ;;	  - 'not present' page fault
   115                              <1> ;;	  - 'writing attempt on read only page' page fault 	 	
   116                              <1> ;;	* For loading (opening, reading) a file or disk/drive
   117                              <1> ;;	* As responce to 'allocate additional memory blocks' 
   118                              <1> ;;	  request by running process.
   119                              <1> ;;	* While creating a process, allocating a new buffer,
   120                              <1> ;;	  new page tables etc.
   121                              <1> ;;
   122                              <1> ;;	At first,
   123                              <1> ;;	- 'allocate page' procedure will be called;
   124                              <1> ;,	   if it will return with a valid (>0) physical address
   125                              <1> ;;	   (that means the relevant M.A.T. bit has been RESET)	
   126                              <1> ;;	   relevant memory page/block will be cleared (zeroed).
   127                              <1> ;;	- 'allocate page' will be called for allocating page
   128                              <1> ;;	   directory, page table and running space (data/code).
   129                              <1> ;;	- every successful 'allocate page' call will decrease
   130                              <1> ;;	  'free_pages' count (pointer).
   131                              <1> ;;	- 'out of (insufficient) memory error' will be returned
   132                              <1> ;;	  if 'free_pages' points to a ZERO.
   133                              <1> ;;	- swapping out and swapping in (if it is not a new page)
   134                              <1> ;;	  procedures will be called as responce to 'out of memory'
   135                              <1> ;;	  error except errors caused by attribute conflicts.
   136                              <1> ;;	 (swapper functions)	 
   137                              <1> ;;					
   138                              <1> ;;	At second,
   139                              <1> ;;	- page directory entry will be updated then page table
   140                              <1> ;;	  entry will be updated.		
   141                              <1> ;;
   142                              <1> ;; MEMORY ALLOCATION TABLE FORMAT:
   143                              <1> ;;	- M.A.T. has a size according to available memory as
   144                              <1> ;;	  follows:
   145                              <1> ;;		  - 1 (allocation) bit per 1 page (4096 bytes)
   146                              <1> ;;		  - a bit with value of 0 means allocated page
   147                              <1> ;;		  - a bit with value of 1 means a free page
   148                              <1> ;,	- 'free_pages' pointer holds count of free pages
   149                              <1> ;;	  depending on M.A.T.
   150                              <1> ;;		(NOTE: Free page count will not be checked
   151                              <1> ;;		again -on M.A.T.- after initialization. 
   152                              <1> ;;		Kernel will trust on initial count.)
   153                              <1> ;,	- 'free_pages' count will be decreased by allocation
   154                              <1> ;;	  and it will be increased by deallocation procedures.
   155                              <1> ;;	
   156                              <1> ;;	- Available memory will be calculated during
   157                              <1> ;;	  the kernel's initialization stage (in real mode).
   158                              <1> ;;	  Memory allocation table and kernel page tables 
   159                              <1> ;;	  will be formatted/sized as result of available
   160                              <1> ;;	  memory calculation before paging is enabled.
   161                              <1> ;;
   162                              <1> ;; For 4GB Available/Present Memory: (max. possible memory size)
   163                              <1> ;;	- Memory Allocation Table size will be 128 KB.
   164                              <1> ;;	- Memory allocation for kernel page directory size 
   165                              <1> ;;	  is always 4 KB. (in addition to total allocation size
   166                              <1> ;;	  for page tables)
   167                              <1> ;;	- Memory allocation for kernel page tables (1024 tables)
   168                              <1> ;;	  is 4 MB (1024*4*1024 bytes).
   169                              <1> ;;	- User (available) space will be started 
   170                              <1> ;;	  at 6th MB of the memory (after 1MB+4MB).
   171                              <1> ;;	- The first 640 KB is for kernel's itself plus
   172                              <1> ;;	  memory allocation table and kernel's page directory
   173                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
   174                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
   175                              <1> ;; 	  for buffers.
   176                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
   177                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
   178                              <1> ;;	- Kernel page tables start at 100000h (2nd MB)
   179                              <1> ;;
   180                              <1> ;; For 1GB Available Memory:
   181                              <1> ;;	- Memory Allocation Table size will be 32 KB.
   182                              <1> ;;	- Memory allocation for kernel page directory size 
   183                              <1> ;;	  is always 4 KB. (in addition to total allocation size
   184                              <1> ;;	  for page tables)
   185                              <1> ;;	- Memory allocation for kernel page tables (256 tables)
   186                              <1> ;;	  is 1 MB (256*4*1024 bytes).
   187                              <1> ;;	- User (available) space will be started 
   188                              <1> ;;	  at 3th MB of the memory (after 1MB+1MB).
   189                              <1> ;;	- The first 640 KB is for kernel's itself plus
   190                              <1> ;;	  memory allocation table and kernel's page directory
   191                              <1> ;;	  (D0000h-EFFFFh may be used as kernel space...)	
   192                              <1> ;;	- B0000h to B7FFFh address space (32 KB) will be used
   193                              <1> ;; 	  for buffers.
   194                              <1> ;;	- ROMBIOS, VIDEO BUFFER and VIDEO ROM space are reserved.
   195                              <1> ;,	  (A0000h-AFFFFh, C0000h-CFFFFh, F0000h-FFFFFh)
   196                              <1> ;;	- Kernel page tables start at 100000h (2nd MB).	
   197                              <1> ;;
   198                              <1> ;;
   199                              <1> 
   200                              <1> 
   201                              <1> ;;************************************************************************************
   202                              <1> ;; 
   203                              <1> ;; RETRO UNIX 386 v1 - Paging (Method for Copy On Write paging principle)
   204                              <1> ;; DEMAND PAGING - PARENT&CHILD PAGE TABLE DUPLICATION PRINCIPLES (23/04/2015)
   205                              <1> 
   206                              <1> ;; Main factor: "sys fork" system call 
   207                              <1> ;;	
   208                              <1> ;; 		FORK
   209                              <1> ;;                      |----> parent - duplicated PTEs, read only pages
   210                              <1> ;;  writable pages ---->|
   211                              <1> ;;                      |----> child - duplicated PTEs, read only pages
   212                              <1> ;; 
   213                              <1> ;; AVL bit (0) of Page Table Entry is used as duplication sign 
   214                              <1> ;; 
   215                              <1> ;; AVL Bit 0 [PTE Bit 9] = 'Duplicated PTE belongs to child' sign/flag (if it is set)
   216                              <1> ;; Note: Dirty bit (PTE bit 6) may be used instead of AVL bit 0 (PTE bit 9)
   217                              <1> ;;       -while R/W bit is 0-. 
   218                              <1> ;; 
   219                              <1> ;; Duplicate page tables with writable pages (the 1st sys fork in the process):
   220                              <1> ;; # Parent's Page Table Entries are updated to point same pages as read only, 
   221                              <1> ;;   as duplicated PTE bit  -AVL bit 0, PTE bit 9- are reset/clear.
   222                              <1> ;; # Then Parent's Page Table is copied to Child's Page Table.
   223                              <1> ;; # Child's Page Table Entries are updated as duplicated child bit
   224                              <1> ;;   -AVL bit 0, PTE bit 9- is set.	  
   225                              <1> ;; 
   226                              <1> ;; Duplicate page tables with read only pages (several sys fork system calls):
   227                              <1> ;; # Parent's read only pages are copied to new child pages. 
   228                              <1> ;;   Parent's PTE attributes are not changed.
   229                              <1> ;;   (Because, there is another parent-child fork before this fork! We must not
   230                              <1> ;;    destroy/mix previous fork result).
   231                              <1> ;; # Child's Page Table Entries (which are corresponding to Parent's 
   232                              <1> ;;   read only pages) are set as writable (while duplicated PTE bit is clear). 
   233                              <1> ;; # Parent's PTEs with writable page attribute are updated to point same pages 
   234                              <1> ;;   as read only, (while) duplicated PTE bit is reset (clear).
   235                              <1> ;; # Parent's Page Table Entries (with writable page attribute) are duplicated 
   236                              <1> ;;   as Child's Page Table Entries without copying actual page.
   237                              <1> ;; # Child 's Page Table Entries (which are corresponding to Parent's writable 
   238                              <1> ;;   pages) are updated as duplicated PTE bit (AVL bit 0, PTE bit 9- is set.
   239                              <1> ;; 
   240                              <1> ;; !? WHAT FOR (duplication after duplication):
   241                              <1> ;; In UNIX method for sys fork (a typical 'fork' application in /etc/init)
   242                              <1> ;; program/executable code continues from specified location as child process, 
   243                              <1> ;; returns back previous code location as parent process, every child after 
   244                              <1> ;; every sys fork uses last image of code and data just prior the fork.
   245                              <1> ;; Even if the parent code changes data, the child will not see the changed data 
   246                              <1> ;; after the fork. In Retro UNIX 8086 v1, parent's process segment (32KB)
   247                              <1> ;; was copied to child's process segment (all of code and data) according to
   248                              <1> ;; original UNIX v1 which copies all of parent process code and data -core- 
   249                              <1> ;; to child space -core- but swaps that core image -of child- on to disk.
   250                              <1> ;; If I (Erdogan Tan) would use a method of to copy parent's core
   251                              <1> ;; (complete running image of parent process) to the child process; 
   252                              <1> ;; for big sizes, i would force Retro UNIX 386 v1 to spend many memory pages 
   253                              <1> ;; and times only for a sys fork. (It would excessive reservation for sys fork,
   254                              <1> ;; because sys fork usually is prior to sys exec; sys exec always establishes
   255                              <1> ;; a new/fresh core -running space-, by clearing all code/data content). 
   256                              <1> ;; 'Read Only' page flag ensures page fault handler is needed only for a few write
   257                              <1> ;; attempts between sys fork and sys exec, not more... (I say so by thinking 
   258                              <1> ;; of "/etc/init" content, specially.) sys exec will clear page tables and
   259                              <1> ;; new/fresh pages will be used to load and run new executable/program.
   260                              <1> ;; That is what for i have preferred "copy on write", "duplication" method
   261                              <1> ;; for sharing same read only pages between parent and child processes.
   262                              <1> ;; That is a pitty i have to use new private flag (AVL bit 0, "duplicated PTE 
   263                              <1> ;; belongs to child" sign) for cooperation on duplicated pages between a parent 
   264                              <1> ;; and it's child processes; otherwise parent process would destroy data belongs
   265                              <1> ;; to its child or vice versa; or some pages would remain unclaimed 
   266                              <1> ;; -deallocation problem-.
   267                              <1> ;; Note: to prevent conflicts, read only pages must not be swapped out... 
   268                              <1> ;; 
   269                              <1> ;; WHEN PARENT TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
   270                              <1> ;; # Page fault handler will do those:
   271                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
   272                              <1> ;;   - If it is reset/clear, there is a child uses same page.
   273                              <1> ;;   - Parent's read only page -previous page- is copied to a new writable page. 
   274                              <1> ;;   - Parent's PTE is updated as writable page, as unique page (AVL=0)
   275                              <1> ;;   - (Page fault handler whill check this PTE later, if child process causes to
   276                              <1> ;;     page fault due to write attempt on read only page. Of course, the previous 
   277                              <1> ;;     read only page will be converted to writable and unique page which belongs
   278                              <1> ;;     to child process.)	
   279                              <1> ;; WHEN CHILD TRIES TO WRITE IT'S READ ONLY (DUPLICATED) PAGE:
   280                              <1> ;; # Page fault handler will do those:
   281                              <1> ;;   - 'Duplicated PTE' flag (PTE bit 9) is checked (on the failed PTE).
   282                              <1> ;;   - If it is set, there is a parent uses -or was using- same page.
   283                              <1> ;;   - Same PTE address within parent's page table is checked if it has same page
   284                              <1> ;;     address or not. 
   285                              <1> ;;   - If parent's PTE has same address, child will continue with a new writable page.
   286                              <1> ;;     Parent's PTE will point to same (previous) page as writable, unique (AVL=0).	
   287                              <1> ;;   - If parent's PTE has different address, child will continue with it's 
   288                              <1> ;;     own/same page but read only flag (0) will be changed to writable flag (1) and
   289                              <1> ;;     'duplicated PTE (belongs to child)' flag/sign will be cleared/reset. 	  	
   290                              <1> ;; 
   291                              <1> ;; NOTE: When a child process is terminated, read only flags of parent's page tables
   292                              <1> ;;       will be set as writable (and unique) in case of child process was using 
   293                              <1> ;;       same pages with duplicated child PTE sign... Depending on sys fork and 
   294                              <1> ;;       duplication method details, it is not possible multiple child processes
   295                              <1> ;;       were using same page with duplicated PTEs.
   296                              <1> ;; 
   297                              <1> ;;************************************************************************************   
   298                              <1> 
   299                              <1> ;; 08/10/2014
   300                              <1> ;; 11/09/2014 - Retro UNIX 386 v1 PAGING (further) draft
   301                              <1> ;;		by Erdogan Tan (Based on KolibriOS 'memory.inc')
   302                              <1> 
   303                              <1> ;; 'allocate_page' code is derived and modified from KolibriOS
   304                              <1> ;; 'alloc_page' procedure in 'memory.inc' 
   305                              <1> ;; (25/08/2014, Revision: 5057) file 
   306                              <1> ;; by KolibriOS Team (2004-2012)
   307                              <1> 
   308                              <1> allocate_page:
   309                              <1> 	; 01/07/2015
   310                              <1> 	; 05/05/2015
   311                              <1> 	; 30/04/2015
   312                              <1> 	; 16/10/2014
   313                              <1> 	; 08/10/2014
   314                              <1> 	; 09/09/2014 (Retro UNIX 386 v1 - beginning)
   315                              <1> 	;
   316                              <1> 	; INPUT -> none
   317                              <1> 	;
   318                              <1> 	; OUTPUT ->
   319                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
   320                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is RESET)
   321                              <1> 	;
   322                              <1> 	;	CF = 1 and EAX = 0 
   323                              <1> 	; 		   if there is not a free page to be allocated	
   324                              <1> 	;
   325                              <1> 	; Modified Registers -> none (except EAX)
   326                              <1> 	;
   327 00003107 A1[F0A70000]        <1> 	mov	eax, [free_pages]
   328 0000310C 21C0                <1> 	and	eax, eax
   329 0000310E 7438                <1> 	jz	short out_of_memory
   330                              <1> 	;
   331 00003110 53                  <1> 	push	ebx
   332 00003111 51                  <1> 	push	ecx
   333                              <1> 	;
   334 00003112 BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table offset
   335 00003117 89D9                <1> 	mov	ecx, ebx
   336                              <1>  				     ; NOTE: 32 (first_page) is initial
   337                              <1> 				     ; value of [next_page].
   338                              <1> 				     ; It points to the first available
   339                              <1> 				     ; page block for users (ring 3) ...	
   340                              <1> 				     ; (MAT offset 32 = 1024/32)	
   341                              <1> 				     ; (at the of the first 4 MB)		
   342 00003119 031D[F4A70000]      <1> 	add	ebx, [next_page] ; Free page searching starts from here
   343                              <1> 				 ; next_free_page >> 5
   344 0000311F 030D[F8A70000]      <1> 	add	ecx, [last_page] ; Free page searching ends here
   345                              <1> 				 ; (total_pages - 1) >> 5
   346                              <1> al_p_scan:
   347 00003125 39CB                <1> 	cmp	ebx, ecx
   348 00003127 770A                <1> 	ja	short al_p_notfound
   349                              <1> 	;
   350                              <1> 	; 01/07/2015
   351                              <1> 	; AMD64 Architecture Programmers Manual
   352                              <1> 	; Volume 3:
   353                              <1> 	; General-Purpose and System Instructions
   354                              <1> 	;
   355                              <1> 	; BSF - Bit Scan Forward
   356                              <1> 	;
   357                              <1> 	;   Searches the value in a register or a memory location
   358                              <1> 	;   (second operand) for the least-significant set bit. 
   359                              <1> 	;   If a set bit is found, the instruction clears the zero flag (ZF)
   360                              <1> 	;   and stores the index of the least-significant set bit in a destination
   361                              <1> 	;   register (first operand). If the second operand contains 0, 
   362                              <1> 	;   the instruction sets ZF to 1 and does not change the contents of the 
   363                              <1> 	;   destination register. The bit index is an unsigned offset from bit 0 
   364                              <1> 	;   of the searched value
   365                              <1> 	;
   366 00003129 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
   367                              <1> 			   ; Clear ZF if a bit is found set (1) and 
   368                              <1> 			   ; loads the destination with an index to
   369                              <1> 			   ; first set bit. (0 -> 31) 
   370                              <1> 			   ; Sets ZF to 1 if no bits are found set.
   371 0000312C 7525                <1> 	jnz	short al_p_found ; ZF = 0 -> a free page has been found
   372                              <1> 			 ;
   373                              <1> 			 ; NOTE:  a Memory Allocation Table bit 
   374                              <1> 			 ;	  with value of 1 means 
   375                              <1> 			 ;	  the corresponding page is free 
   376                              <1> 			 ;	  (Retro UNIX 386 v1 feaure only!)
   377 0000312E 83C304              <1> 	add	ebx, 4
   378                              <1> 			 ; We return back for searching next page block
   379                              <1> 			 ; NOTE: [free_pages] is not ZERO; so, 
   380                              <1> 			 ;	 we always will find at least 1 free page here.
   381 00003131 EBF2                <1>         jmp     short al_p_scan
   382                              <1> 	;
   383                              <1> al_p_notfound:
   384 00003133 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
   385 00003139 890D[F4A70000]      <1> 	mov	[next_page], ecx ; next/first free page = last page 
   386                              <1> 				 ; (deallocate_page procedure will change it)
   387 0000313F 31C0                <1> 	xor	eax, eax
   388 00003141 A3[F0A70000]        <1> 	mov	[free_pages], eax ; 0
   389 00003146 59                  <1> 	pop	ecx
   390 00003147 5B                  <1> 	pop	ebx
   391                              <1> 	;
   392                              <1> out_of_memory:
   393 00003148 E857040000          <1> 	call	swap_out
   394 0000314D 7325                <1> 	jnc	short al_p_ok  ; [free_pages] = 0, re-allocation by swap_out
   395                              <1> 	;
   396 0000314F 29C0                <1> 	sub 	eax, eax ; 0
   397 00003151 F9                  <1> 	stc
   398 00003152 C3                  <1> 	retn
   399                              <1> 
   400                              <1> al_p_found:
   401 00003153 89D9                <1> 	mov	ecx, ebx
   402 00003155 81E900001000        <1> 	sub	ecx, MEM_ALLOC_TBL
   403 0000315B 890D[F4A70000]      <1> 	mov	[next_page], ecx ; Set first free page searching start
   404                              <1> 				 ; address/offset (to the next)
   405 00003161 FF0D[F0A70000]      <1>         dec     dword [free_pages] ; 1 page has been allocated (X = X-1) 
   406                              <1> 	;
   407 00003167 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
   408                              <1> 				 ; is copied into the Carry Flag and then cleared
   409                              <1> 				 ; in the destination.
   410                              <1> 				 ;
   411                              <1> 				 ; Reset the bit which is corresponding to the 
   412                              <1> 				 ; (just) allocated page.
   413                              <1> 	; 01/07/2015 (4*8 = 32, 1 allocation byte = 8 pages)	
   414 0000316A C1E103              <1> 	shl	ecx, 3		 ; (page block offset * 32) + page index
   415 0000316D 01C8                <1> 	add	eax, ecx	 ; = page number
   416 0000316F C1E00C              <1> 	shl	eax, 12		 ; physical address of the page (flat/real value)
   417                              <1> 	; EAX = physical address of memory page
   418                              <1> 	;
   419                              <1> 	; NOTE: The relevant page directory and page table entry will be updated
   420                              <1> 	;       according to this EAX value...
   421 00003172 59                  <1> 	pop	ecx
   422 00003173 5B                  <1> 	pop	ebx
   423                              <1> al_p_ok:
   424 00003174 C3                  <1> 	retn
   425                              <1> 
   426                              <1> 
   427                              <1> make_page_dir:
   428                              <1> 	; 18/04/2015
   429                              <1> 	; 12/04/2015
   430                              <1> 	; 23/10/2014
   431                              <1> 	; 16/10/2014
   432                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
   433                              <1> 	;
   434                              <1> 	; INPUT ->
   435                              <1> 	;	none
   436                              <1> 	; OUTPUT ->
   437                              <1> 	;	(EAX = 0)
   438                              <1> 	;	cf = 1 -> insufficient (out of) memory error
   439                              <1> 	;	cf = 0 ->
   440                              <1> 	;	u.pgdir = page directory (physical) address of the current
   441                              <1> 	;		  process/user.
   442                              <1> 	;
   443                              <1> 	; Modified Registers -> EAX
   444                              <1> 	;
   445 00003175 E88DFFFFFF          <1> 	call	allocate_page
   446 0000317A 7216                <1> 	jc	short mkpd_error
   447                              <1> 	;
   448 0000317C A3[19B80000]        <1> 	mov	[u.pgdir], eax    ; Page dir address for current user/process
   449                              <1> 				  ; (Physical address)
   450                              <1> clear_page:
   451                              <1> 	; 18/04/2015
   452                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
   453                              <1> 	;
   454                              <1> 	; INPUT ->
   455                              <1> 	;	EAX = physical address of the page
   456                              <1> 	; OUTPUT ->
   457                              <1> 	;	all bytes of the page will be cleared
   458                              <1> 	;
   459                              <1> 	; Modified Registers -> none
   460                              <1> 	;
   461 00003181 57                  <1> 	push	edi
   462 00003182 51                  <1> 	push	ecx
   463 00003183 50                  <1> 	push	eax
   464 00003184 B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
   465 00003189 89C7                <1> 	mov	edi, eax
   466 0000318B 31C0                <1> 	xor	eax, eax
   467 0000318D F3AB                <1> 	rep	stosd
   468 0000318F 58                  <1> 	pop	eax
   469 00003190 59                  <1> 	pop	ecx
   470 00003191 5F                  <1> 	pop	edi
   471                              <1> mkpd_error:
   472                              <1> mkpt_error:
   473 00003192 C3                  <1> 	retn
   474                              <1> 
   475                              <1> make_page_table:
   476                              <1> 	; 23/06/2015
   477                              <1> 	; 18/04/2015
   478                              <1> 	; 12/04/2015
   479                              <1> 	; 16/10/2014
   480                              <1> 	; 09/10/2014 ; (Retro UNIX 386 v1 - beginning)
   481                              <1> 	;
   482                              <1> 	; INPUT ->
   483                              <1> 	;	EBX = virtual (linear) address
   484                              <1> 	;	ECX = page table attributes (lower 12 bits)
   485                              <1> 	;	      (higher 20 bits must be ZERO)
   486                              <1> 	;	      (bit 0 must be 1)	 
   487                              <1> 	;	u.pgdir = page directory (physical) address
   488                              <1> 	; OUTPUT ->
   489                              <1> 	;	EDX = Page directory entry address
   490                              <1> 	;	EAX = Page table address
   491                              <1> 	;	cf = 1 -> insufficient (out of) memory error
   492                              <1> 	;	cf = 0 -> page table address in the PDE (EDX)
   493                              <1> 	;
   494                              <1> 	; Modified Registers -> EAX, EDX
   495                              <1> 	;
   496 00003193 E86FFFFFFF          <1> 	call	allocate_page
   497 00003198 72F8                <1> 	jc	short mkpt_error
   498 0000319A E811000000          <1> 	call	set_pde	
   499 0000319F EBE0                <1> 	jmp	short clear_page
   500                              <1> 
   501                              <1> make_page:
   502                              <1> 	; 24/07/2015
   503                              <1> 	; 23/06/2015 ; (Retro UNIX 386 v1 - beginning)
   504                              <1> 	;
   505                              <1> 	; INPUT ->
   506                              <1> 	;	EBX = virtual (linear) address
   507                              <1> 	;	ECX = page attributes (lower 12 bits)
   508                              <1> 	;	      (higher 20 bits must be ZERO)
   509                              <1> 	;	      (bit 0 must be 1)	 
   510                              <1> 	;	u.pgdir = page directory (physical) address
   511                              <1> 	; OUTPUT ->
   512                              <1> 	;	EBX = Virtual address
   513                              <1> 	;	(EDX = PTE value)
   514                              <1> 	;	EAX = Physical address
   515                              <1> 	;	cf = 1 -> insufficient (out of) memory error
   516                              <1> 	;
   517                              <1> 	; Modified Registers -> EAX, EDX
   518                              <1> 	;
   519 000031A1 E861FFFFFF          <1> 	call	allocate_page
   520 000031A6 7207                <1> 	jc	short mkp_err
   521 000031A8 E821000000          <1> 	call	set_pte	
   522 000031AD 73D2                <1> 	jnc	short clear_page ; 18/04/2015
   523                              <1> mkp_err:
   524 000031AF C3                  <1> 	retn
   525                              <1> 
   526                              <1> 
   527                              <1> set_pde:	; Set page directory entry (PDE)
   528                              <1> 	; 20/07/2015
   529                              <1> 	; 18/04/2015
   530                              <1> 	; 12/04/2015
   531                              <1> 	; 23/10/2014
   532                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
   533                              <1> 	;
   534                              <1> 	; INPUT ->
   535                              <1> 	;	EAX = physical address
   536                              <1> 	;	      (use present value if EAX = 0)
   537                              <1> 	;	EBX = virtual (linear) address
   538                              <1> 	;	ECX = page table attributes (lower 12 bits)
   539                              <1> 	;	      (higher 20 bits must be ZERO)
   540                              <1> 	;	      (bit 0 must be 1)	 
   541                              <1> 	;	u.pgdir = page directory (physical) address
   542                              <1> 	; OUTPUT ->
   543                              <1> 	;	EDX = PDE address
   544                              <1> 	;	EAX = page table address (physical)
   545                              <1> 	;	;(CF=1 -> Invalid page address)
   546                              <1> 	;
   547                              <1> 	; Modified Registers -> EDX
   548                              <1> 	;
   549 000031B0 89DA                <1> 	mov	edx, ebx
   550 000031B2 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22
   551 000031B5 C1E202              <1> 	shl	edx, 2 ; offset to page directory (1024*4)
   552 000031B8 0315[19B80000]      <1> 	add	edx, [u.pgdir]
   553                              <1> 	;
   554 000031BE 21C0                <1> 	and	eax, eax
   555 000031C0 7506                <1> 	jnz	short spde_1
   556                              <1> 	;
   557 000031C2 8B02                <1> 	mov	eax, [edx]  ; old PDE value
   558                              <1> 	;test	al, 1
   559                              <1> 	;jz	short spde_2
   560 000031C4 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h  ; clear lower 12 bits
   561                              <1> spde_1:
   562                              <1> 	;and	cx, 0FFFh
   563 000031C8 8902                <1> 	mov	[edx], eax
   564 000031CA 66090A              <1> 	or	[edx], cx
   565 000031CD C3                  <1> 	retn
   566                              <1> ;spde_2: ; error
   567                              <1> ;	stc
   568                              <1> ;	retn
   569                              <1> 
   570                              <1> set_pte:	; Set page table entry (PTE)
   571                              <1> 	; 24/07/2015
   572                              <1> 	; 20/07/2015
   573                              <1> 	; 23/06/2015
   574                              <1> 	; 18/04/2015
   575                              <1> 	; 12/04/2015
   576                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
   577                              <1> 	;
   578                              <1> 	; INPUT ->
   579                              <1> 	;	EAX = physical page address
   580                              <1> 	;	      (use present value if EAX = 0)
   581                              <1> 	;	EBX = virtual (linear) address
   582                              <1> 	;	ECX = page attributes (lower 12 bits)
   583                              <1> 	;	      (higher 20 bits must be ZERO)
   584                              <1> 	;	      (bit 0 must be 1)	 
   585                              <1> 	;	u.pgdir = page directory (physical) address
   586                              <1> 	; OUTPUT ->
   587                              <1> 	;	EAX = physical page address
   588                              <1> 	;	(EDX = PTE value)
   589                              <1> 	;	EBX = virtual address
   590                              <1> 	;
   591                              <1> 	;	CF = 1 -> error
   592                              <1> 	;
   593                              <1> 	; Modified Registers -> EAX, EDX
   594                              <1> 	;
   595 000031CE 50                  <1> 	push	eax
   596 000031CF A1[19B80000]        <1> 	mov	eax, [u.pgdir] ; 20/07/2015
   597 000031D4 E837000000          <1> 	call 	get_pde
   598                              <1> 		; EDX = PDE address
   599                              <1> 		; EAX = PDE value
   600 000031D9 5A                  <1> 	pop	edx ; physical page address
   601 000031DA 722A                <1> 	jc	short spte_err ; PDE not present
   602                              <1> 	;
   603 000031DC 53                  <1> 	push	ebx ; 24/07/2015
   604 000031DD 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
   605                              <1> 			    ; EDX = PT address (physical)	
   606 000031E1 C1EB0C              <1> 	shr	ebx, PAGE_SHIFT ; 12
   607 000031E4 81E3FF030000        <1> 	and	ebx, PTE_MASK	; 03FFh
   608                              <1> 			 ; clear higher 10 bits (PD bits)
   609 000031EA C1E302              <1> 	shl	ebx, 2   ; offset to page table (1024*4)
   610 000031ED 01C3                <1> 	add	ebx, eax
   611                              <1> 	;
   612 000031EF 8B03                <1> 	mov	eax, [ebx] ; Old PTE value
   613 000031F1 A801                <1> 	test	al, 1
   614 000031F3 740C                <1> 	jz	short spte_0
   615 000031F5 09D2                <1> 	or	edx, edx
   616 000031F7 750F                <1> 	jnz	short spte_1
   617 000031F9 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 bits
   618 000031FD 89C2                <1> 	mov	edx, eax
   619 000031FF EB09                <1> 	jmp	short spte_2	
   620                              <1> spte_0:
   621                              <1> 	; If this PTE contains a swap (disk) address,
   622                              <1> 	; it can be updated by using 'swap_in' procedure
   623                              <1> 	; only!
   624 00003201 21C0                <1> 	and	eax, eax
   625 00003203 7403                <1> 	jz	short spte_1
   626                              <1> 	; 24/07/2015
   627                              <1> 	; swapped page ! (on disk)
   628 00003205 5B                  <1> 	pop	ebx
   629                              <1> spte_err:
   630 00003206 F9                  <1> 	stc
   631 00003207 C3                  <1> 	retn
   632                              <1> spte_1: 
   633 00003208 89D0                <1> 	mov	eax, edx
   634                              <1> spte_2:
   635 0000320A 09CA                <1> 	or	edx, ecx
   636                              <1> 	; 23/06/2015
   637 0000320C 8913                <1> 	mov	[ebx], edx ; PTE value in EDX
   638                              <1> 	; 24/07/2015
   639 0000320E 5B                  <1> 	pop	ebx
   640 0000320F C3                  <1> 	retn
   641                              <1> 
   642                              <1> get_pde:	; Get present value of the relevant PDE
   643                              <1> 	; 20/07/2015
   644                              <1> 	; 18/04/2015
   645                              <1> 	; 12/04/2015
   646                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
   647                              <1> 	;
   648                              <1> 	; INPUT ->
   649                              <1> 	;	EBX = virtual (linear) address
   650                              <1> 	;	EAX = page directory (physical) address
   651                              <1> 	; OUTPUT ->
   652                              <1> 	;	EDX = Page directory entry address
   653                              <1> 	;	EAX = Page directory entry value
   654                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
   655                              <1> 	; Modified Registers -> EDX, EAX
   656                              <1> 	;
   657 00003210 89DA                <1> 	mov	edx, ebx
   658 00003212 C1EA16              <1> 	shr	edx, PAGE_D_SHIFT ; 22  (12+10)
   659 00003215 C1E202              <1> 	shl 	edx, 2 ; offset to page directory (1024*4)
   660 00003218 01C2                <1> 	add	edx, eax ; page directory address (physical)
   661 0000321A 8B02                <1> 	mov	eax, [edx]
   662 0000321C A801                <1> 	test	al, PDE_A_PRESENT ; page table is present or not !
   663 0000321E 751F                <1> 	jnz	short gpte_retn
   664 00003220 F9                  <1> 	stc
   665                              <1> gpde_retn:	
   666 00003221 C3                  <1> 	retn
   667                              <1> 
   668                              <1> get_pte:
   669                              <1> 		; Get present value of the relevant PTE
   670                              <1> 	; 29/07/2015
   671                              <1> 	; 20/07/2015
   672                              <1> 	; 18/04/2015
   673                              <1> 	; 12/04/2015
   674                              <1> 	; 10/10/2014 ; (Retro UNIX 386 v1 - beginning)
   675                              <1> 	;
   676                              <1> 	; INPUT ->
   677                              <1> 	;	EBX = virtual (linear) address
   678                              <1> 	;	EAX = page directory (physical) address
   679                              <1> 	; OUTPUT ->
   680                              <1> 	;	EDX = Page table entry address (if CF=0)
   681                              <1> 	;	      Page directory entry address (if CF=1)
   682                              <1> 	;            (Bit 0 value is 0 if PT is not present)
   683                              <1> 	;	EAX = Page table entry value (page address)
   684                              <1> 	;	CF = 1 -> PDE not present or invalid ? 
   685                              <1> 	; Modified Registers -> EAX, EDX
   686                              <1> 	;
   687 00003222 E8E9FFFFFF          <1> 	call 	get_pde
   688 00003227 72F8                <1> 	jc	short gpde_retn	; page table is not present
   689                              <1> 	;jnc	short gpte_1
   690                              <1> 	;retn
   691                              <1> ;gpte_1:
   692 00003229 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 bits
   693 0000322D 89DA                <1> 	mov	edx, ebx
   694 0000322F C1EA0C              <1> 	shr	edx, PAGE_SHIFT ; 12
   695 00003232 81E2FF030000        <1> 	and	edx, PTE_MASK	; 03FFh
   696                              <1> 			 ; clear higher 10 bits (PD bits)
   697 00003238 C1E202              <1> 	shl	edx, 2 ; offset from start of page table (1024*4)
   698 0000323B 01C2                <1> 	add	edx, eax
   699 0000323D 8B02                <1> 	mov	eax, [edx]
   700                              <1> gpte_retn:
   701 0000323F C3                  <1> 	retn
   702                              <1> 
   703                              <1> deallocate_page_dir:
   704                              <1> 	; 15/09/2015
   705                              <1> 	; 05/08/2015
   706                              <1> 	; 30/04/2015
   707                              <1> 	; 28/04/2015
   708                              <1> 	; 17/10/2014
   709                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
   710                              <1> 	;
   711                              <1> 	; INPUT ->
   712                              <1> 	;	EAX = PHYSICAL ADDRESS OF THE PAGE DIRECTORY (CHILD)
   713                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
   714                              <1> 	; OUTPUT ->
   715                              <1> 	;	All of page tables in the page directory
   716                              <1> 	;	and page dir's itself will be deallocated
   717                              <1> 	;	except 'read only' duplicated pages (will be converted
   718                              <1> 	;	to writable pages).
   719                              <1> 	;
   720                              <1> 	; Modified Registers -> EAX
   721                              <1> 	;
   722                              <1> 	;
   723 00003240 56                  <1> 	push	esi
   724 00003241 51                  <1> 	push	ecx
   725 00003242 50                  <1> 	push	eax
   726 00003243 89C6                <1> 	mov	esi, eax 
   727 00003245 31C9                <1> 	xor	ecx, ecx
   728                              <1> 	; The 1st PDE points to Kernel Page Table 0 (the 1st 4MB),
   729                              <1> 	; it must not be deallocated
   730 00003247 890E                <1> 	mov	[esi], ecx ; 0 ; clear PDE 0
   731                              <1> dapd_0:
   732 00003249 AD                  <1> 	lodsd
   733 0000324A A801                <1> 	test	al, PDE_A_PRESENT ; bit 0, present flag (must be 1)
   734 0000324C 7409                <1> 	jz	short dapd_1	
   735 0000324E 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
   736 00003252 E812000000          <1> 	call	deallocate_page_table			
   737                              <1> dapd_1:
   738 00003257 41                  <1> 	inc	ecx ; page directory entry index
   739 00003258 81F900040000        <1> 	cmp	ecx, PAGE_SIZE / 4 ; 1024
   740 0000325E 72E9                <1> 	jb	short dapd_0
   741                              <1> dapd_2:
   742 00003260 58                  <1> 	pop	eax
   743 00003261 E879000000          <1> 	call	deallocate_page	; deallocate the page dir's itself
   744 00003266 59                  <1> 	pop	ecx
   745 00003267 5E                  <1> 	pop	esi
   746 00003268 C3                  <1> 	retn
   747                              <1> 
   748                              <1> deallocate_page_table:
   749                              <1> 	; 19/09/2015
   750                              <1> 	; 15/09/2015
   751                              <1> 	; 05/08/2015
   752                              <1> 	; 30/04/2015
   753                              <1> 	; 28/04/2015
   754                              <1> 	; 24/10/2014
   755                              <1> 	; 23/10/2014
   756                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
   757                              <1> 	;
   758                              <1> 	; INPUT ->
   759                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE PAGE TABLE
   760                              <1> 	;	EBX = PHYSICAL ADDRESS OF THE PARENT'S PAGE DIRECTORY
   761                              <1> 	;	(ECX = page directory entry index)
   762                              <1> 	; OUTPUT ->
   763                              <1> 	;	All of pages in the page table and page table's itself
   764                              <1> 	;	will be deallocated except 'read only' duplicated pages
   765                              <1> 	;	(will be converted to writable pages).
   766                              <1> 	;
   767                              <1> 	; Modified Registers -> EAX
   768                              <1> 	;
   769 00003269 56                  <1> 	push	esi
   770 0000326A 57                  <1> 	push	edi
   771 0000326B 52                  <1> 	push	edx
   772 0000326C 50                  <1> 	push	eax ; *
   773 0000326D 89C6                <1> 	mov	esi, eax 
   774 0000326F 31FF                <1> 	xor	edi, edi ; 0
   775                              <1> dapt_0:
   776 00003271 AD                  <1> 	lodsd
   777 00003272 A801                <1> 	test	al, PTE_A_PRESENT ; bit 0, present flag (must be 1)
   778 00003274 7441                <1> 	jz	short dapt_1
   779                              <1> 	;
   780 00003276 A802                <1> 	test	al, PTE_A_WRITE   ; bit 1, writable (r/w) flag
   781                              <1> 				  ; (must be 1)
   782 00003278 754C                <1> 	jnz	short dapt_3
   783                              <1> 	; Read only -duplicated- page (belongs to a parent or a child)
   784 0000327A 66A90002            <1>         test    ax, PTE_DUPLICATED ; Was this page duplicated 
   785                              <1> 				   ; as child's page ?
   786 0000327E 744B                <1> 	jz	short dapt_4 ; Clear PTE but don't deallocate the page!
   787                              <1> 	; check the parent's PTE value is read only & same page or not.. 
   788                              <1> 	; ECX = page directory entry index (0-1023)
   789 00003280 53                  <1> 	push	ebx
   790 00003281 51                  <1> 	push	ecx
   791 00003282 66C1E102            <1> 	shl	cx, 2 ; *4 
   792 00003286 01CB                <1> 	add	ebx, ecx ; PDE offset (for the parent)
   793 00003288 8B0B                <1> 	mov	ecx, [ebx]
   794 0000328A F6C101              <1> 	test	cl, PDE_A_PRESENT ; present (valid) or not ?
   795 0000328D 7435                <1> 	jz	short dapt_2	; parent process does not use this page
   796 0000328F 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
   797                              <1> 	; EDI = page table entry index (0-1023)
   798 00003294 89FA                <1> 	mov	edx, edi 
   799 00003296 66C1E202            <1> 	shl	dx, 2 ; *4 
   800 0000329A 01CA                <1> 	add	edx, ecx ; PTE offset (for the parent)
   801 0000329C 8B1A                <1> 	mov	ebx, [edx]
   802 0000329E F6C301              <1> 	test	bl, PTE_A_PRESENT ; present or not ?
   803 000032A1 7421                <1> 	jz	short dapt_2	; parent process does not use this page
   804 000032A3 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; Clear attribute bits 
   805 000032A7 6681E300F0          <1> 	and	bx, PTE_A_CLEAR ; 0F000h ; Clear attribute bits
   806 000032AC 39D8                <1> 	cmp	eax, ebx	; parent's and child's pages are same ?
   807 000032AE 7514                <1> 	jne	short dapt_2	; not same page
   808                              <1> 				; deallocate the child's page
   809 000032B0 800A02              <1>         or      byte [edx], PTE_A_WRITE ; convert to writable page (parent)
   810 000032B3 59                  <1> 	pop	ecx
   811 000032B4 5B                  <1> 	pop	ebx
   812 000032B5 EB14                <1> 	jmp	short dapt_4
   813                              <1> dapt_1:
   814 000032B7 09C0                <1> 	or	eax, eax	; swapped page ?
   815 000032B9 7417                <1> 	jz	short dapt_5	; no
   816                              <1> 				; yes
   817 000032BB D1E8                <1> 	shr	eax, 1
   818 000032BD E848040000          <1> 	call	unlink_swap_block ; Deallocate swapped page block
   819                              <1> 				  ; on the swap disk (or in file)
   820 000032C2 EB0E                <1> 	jmp	short dapt_5
   821                              <1> dapt_2:
   822 000032C4 59                  <1> 	pop	ecx
   823 000032C5 5B                  <1> 	pop	ebx
   824                              <1> dapt_3:	
   825                              <1> 	;and	ax, PTE_A_CLEAR ; 0F000h ; clear lower 12 (attribute) bits
   826 000032C6 E814000000          <1> 	call	deallocate_page
   827                              <1> dapt_4:
   828 000032CB C746FC00000000      <1> 	mov	dword [esi-4], 0 ; clear/reset PTE (child, dupl. as parent)
   829                              <1> dapt_5:
   830 000032D2 47                  <1> 	inc	edi ; page table entry index
   831 000032D3 81FF00040000        <1> 	cmp	edi, PAGE_SIZE / 4 ; 1024
   832 000032D9 7296                <1> 	jb	short dapt_0
   833                              <1> 	;
   834 000032DB 58                  <1> 	pop	eax ; *
   835 000032DC 5A                  <1> 	pop	edx
   836 000032DD 5F                  <1> 	pop	edi	
   837 000032DE 5E                  <1> 	pop	esi
   838                              <1> 	;
   839                              <1> 	;call	deallocate_page	; deallocate the page table's itself
   840                              <1> 	;retn
   841                              <1> 
   842                              <1> deallocate_page:
   843                              <1> 	; 15/09/2015
   844                              <1> 	; 28/04/2015
   845                              <1> 	; 10/03/2015
   846                              <1> 	; 17/10/2014
   847                              <1> 	; 12/10/2014 (Retro UNIX 386 v1 - beginning)
   848                              <1> 	;
   849                              <1> 	; INPUT -> 
   850                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
   851                              <1> 	; OUTPUT ->
   852                              <1> 	;	[free_pages] is increased
   853                              <1> 	;	(corresponding MEMORY ALLOCATION TABLE bit is SET)
   854                              <1> 	;	CF = 1 if the page is already deallocated
   855                              <1> 	; 	       (or not allocated) before.  
   856                              <1> 	;
   857                              <1> 	; Modified Registers -> EAX
   858                              <1> 	;
   859 000032DF 53                  <1> 	push	ebx
   860 000032E0 52                  <1> 	push	edx
   861                              <1> 	;
   862 000032E1 C1E80C              <1> 	shr	eax, PAGE_SHIFT      ; shift physical address to 
   863                              <1> 				     ; 12 bits right
   864                              <1> 				     ; to get page number
   865 000032E4 89C2                <1> 	mov	edx, eax
   866                              <1> 	; 15/09/2015
   867 000032E6 C1EA03              <1> 	shr	edx, 3		     ; to get offset to M.A.T.
   868                              <1> 				     ; (1 allocation bit = 1 page)
   869                              <1> 				     ; (1 allocation bytes = 8 pages)
   870 000032E9 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
   871                              <1> 				     ; (to get 32 bit position)			
   872                              <1> 	;
   873 000032EC BB00001000          <1> 	mov	ebx, MEM_ALLOC_TBL   ; Memory Allocation Table address
   874 000032F1 01D3                <1> 	add	ebx, edx
   875 000032F3 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
   876                              <1> 				     ; (allocation bit position)	 
   877 000032F6 3B15[F4A70000]      <1> 	cmp 	edx, [next_page]     ; is the new free page address lower
   878                              <1> 				     ; than the address in 'next_page' ?
   879                              <1> 				     ; (next/first free page value)		
   880 000032FC 7306                <1> 	jnb	short dap_1	     ; no	
   881 000032FE 8915[F4A70000]      <1> 	mov	[next_page], edx     ; yes
   882                              <1> dap_1:
   883 00003304 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate page
   884                              <1> 				     ; set relevant bit to 1.
   885                              <1> 				     ; set CF to the previous bit value	
   886                              <1> 	;cmc			     ; complement carry flag	
   887                              <1> 	;jc	short dap_2	     ; do not increase free_pages count
   888                              <1> 				     ; if the page is already deallocated
   889                              <1> 				     ; before.	
   890 00003307 FF05[F0A70000]      <1>         inc     dword [free_pages]
   891                              <1> dap_2:
   892 0000330D 5A                  <1> 	pop	edx
   893 0000330E 5B                  <1> 	pop	ebx
   894 0000330F C3                  <1> 	retn
   895                              <1> 
   896                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   897                              <1> ;;                                                              ;;
   898                              <1> ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;;
   899                              <1> ;; Distributed under terms of the GNU General Public License    ;;
   900                              <1> ;;                                                              ;;
   901                              <1> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   902                              <1> 
   903                              <1> ;;$Revision: 5057 $
   904                              <1> 
   905                              <1> 
   906                              <1> ;;align 4
   907                              <1> ;;proc alloc_page
   908                              <1> 
   909                              <1> ;;        pushfd
   910                              <1> ;;        cli
   911                              <1> ;;        push    ebx
   912                              <1> ;;;//-
   913                              <1> ;;        cmp     [pg_data.pages_free], 1
   914                              <1> ;;        jle     .out_of_memory
   915                              <1> ;;;//-
   916                              <1> ;;
   917                              <1> ;;        mov     ebx, [page_start]
   918                              <1> ;;        mov     ecx, [page_end]
   919                              <1> ;;.l1:
   920                              <1> ;;        bsf     eax, [ebx];
   921                              <1> ;;        jnz     .found
   922                              <1> ;;        add     ebx, 4
   923                              <1> ;;        cmp     ebx, ecx
   924                              <1> ;;        jb      .l1
   925                              <1> ;;        pop     ebx
   926                              <1> ;;        popfd
   927                              <1> ;;        xor     eax, eax
   928                              <1> ;;        ret
   929                              <1> ;;.found:
   930                              <1> ;;;//-
   931                              <1> ;;        dec     [pg_data.pages_free]
   932                              <1> ;;        jz      .out_of_memory
   933                              <1> ;;;//-
   934                              <1> ;;        btr     [ebx], eax
   935                              <1> ;;        mov     [page_start], ebx
   936                              <1> ;;        sub     ebx, sys_pgmap
   937                              <1> ;;        lea     eax, [eax+ebx*8]
   938                              <1> ;;        shl     eax, 12
   939                              <1> ;;;//-       dec [pg_data.pages_free]
   940                              <1> ;;        pop     ebx
   941                              <1> ;;        popfd
   942                              <1> ;;        ret
   943                              <1> ;;;//-
   944                              <1> ;;.out_of_memory:
   945                              <1> ;;        mov     [pg_data.pages_free], 1
   946                              <1> ;;        xor     eax, eax
   947                              <1> ;;        pop     ebx
   948                              <1> ;;        popfd
   949                              <1> ;;        ret
   950                              <1> ;;;//-
   951                              <1> ;;endp
   952                              <1> 
   953                              <1> duplicate_page_dir:
   954                              <1> 	; 21/09/2015
   955                              <1> 	; 31/08/2015
   956                              <1> 	; 20/07/2015
   957                              <1> 	; 28/04/2015
   958                              <1> 	; 27/04/2015
   959                              <1> 	; 18/04/2015
   960                              <1> 	; 12/04/2015
   961                              <1> 	; 18/10/2014
   962                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
   963                              <1> 	;
   964                              <1> 	; INPUT -> 
   965                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
   966                              <1> 	;		    page directory.
   967                              <1> 	; OUTPUT ->
   968                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
   969                              <1> 	;	       page directory.
   970                              <1> 	;	(New page directory with new page table entries.)
   971                              <1> 	;	(New page tables with read only copies of the parent's
   972                              <1> 	;	pages.)
   973                              <1> 	;	EAX = 0 -> Error (CF = 1)
   974                              <1> 	;
   975                              <1> 	; Modified Registers -> none (except EAX)
   976                              <1> 	;
   977 00003310 E8F2FDFFFF          <1> 	call	allocate_page
   978 00003315 723E                <1> 	jc	short dpd_err
   979                              <1> 	;
   980 00003317 55                  <1> 	push	ebp ; 20/07/2015
   981 00003318 56                  <1> 	push	esi
   982 00003319 57                  <1> 	push	edi
   983 0000331A 53                  <1> 	push	ebx
   984 0000331B 51                  <1> 	push	ecx
   985 0000331C 8B35[19B80000]      <1> 	mov	esi, [u.pgdir]
   986 00003322 89C7                <1> 	mov	edi, eax
   987 00003324 50                  <1> 	push	eax ; save child's page directory address
   988                              <1> 	; 31/08/2015
   989                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
   990                              <1> 	; (use same system space for all user page tables) 
   991 00003325 A5                  <1> 	movsd
   992 00003326 BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
   993 0000332B B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
   994                              <1> dpd_0:	
   995 00003330 AD                  <1> 	lodsd
   996                              <1> 	;or	eax, eax
   997                              <1>         ;jnz     short dpd_1
   998 00003331 A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
   999 00003333 7508                <1> 	jnz	short dpd_1
  1000                              <1>  	; 20/07/2015 (virtual address at the end of the page table)	
  1001 00003335 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
  1002 0000333B EB0F                <1> 	jmp	short dpd_2
  1003                              <1> dpd_1:	
  1004 0000333D 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
  1005 00003341 89C3                <1> 	mov	ebx, eax
  1006                              <1> 	; EBX = Parent's page table address
  1007 00003343 E81F000000          <1> 	call	duplicate_page_table
  1008 00003348 720C                <1> 	jc	short dpd_p_err
  1009                              <1> 	; EAX = Child's page table address
  1010 0000334A 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
  1011                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
  1012                              <1> 			 ; (present, writable, user)
  1013                              <1> dpd_2:
  1014 0000334C AB                  <1> 	stosd
  1015 0000334D E2E1                <1> 	loop	dpd_0
  1016                              <1> 	;
  1017 0000334F 58                  <1> 	pop	eax  ; restore child's page directory address
  1018                              <1> dpd_3:
  1019 00003350 59                  <1> 	pop	ecx
  1020 00003351 5B                  <1> 	pop	ebx
  1021 00003352 5F                  <1> 	pop	edi
  1022 00003353 5E                  <1> 	pop	esi
  1023 00003354 5D                  <1> 	pop	ebp ; 20/07/2015
  1024                              <1> dpd_err:
  1025 00003355 C3                  <1> 	retn
  1026                              <1> dpd_p_err:
  1027                              <1> 	; release the allocated pages missing (recover free space)
  1028 00003356 58                  <1> 	pop	eax  ; the new page directory address (physical)
  1029 00003357 8B1D[19B80000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
  1030 0000335D E8DEFEFFFF          <1> 	call 	deallocate_page_dir
  1031 00003362 29C0                <1> 	sub	eax, eax ; 0
  1032 00003364 F9                  <1> 	stc
  1033 00003365 EBE9                <1> 	jmp	short dpd_3	
  1034                              <1> 
  1035                              <1> duplicate_page_table:
  1036                              <1> 	; 21/09/2015
  1037                              <1> 	; 20/07/2015
  1038                              <1> 	; 05/05/2015
  1039                              <1> 	; 28/04/2015
  1040                              <1> 	; 27/04/2015
  1041                              <1> 	; 18/04/2015
  1042                              <1> 	; 18/10/2014
  1043                              <1> 	; 16/10/2014 (Retro UNIX 386 v1 - beginning)
  1044                              <1> 	;
  1045                              <1> 	; INPUT -> 
  1046                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
  1047                              <1> 	;	EBP = page table entry index (from 'duplicate_page_dir')
  1048                              <1> 	; OUTPUT ->
  1049                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
  1050                              <1> 	;	      (with 'read only' attribute of page table entries)
  1051                              <1> 	;	EBP = (recent) page table index (for 'add_to_swap_queue')	
  1052                              <1> 	;	CF = 1 -> error 
  1053                              <1> 	;
  1054                              <1> 	; Modified Registers -> EBP (except EAX)
  1055                              <1> 	;
  1056 00003367 E89BFDFFFF          <1> 	call	allocate_page
  1057 0000336C 726A                <1> 	jc	short dpt_err
  1058                              <1> 	;
  1059 0000336E 50                  <1> 	push	eax ; *
  1060 0000336F 56                  <1> 	push	esi
  1061 00003370 57                  <1> 	push	edi
  1062 00003371 52                  <1> 	push	edx
  1063 00003372 51                  <1> 	push	ecx
  1064                              <1> 	;
  1065 00003373 89DE                <1> 	mov	esi, ebx
  1066 00003375 89C7                <1> 	mov	edi, eax
  1067 00003377 89C2                <1> 	mov	edx, eax
  1068 00003379 81C200100000        <1> 	add	edx, PAGE_SIZE 	
  1069                              <1> dpt_0:
  1070 0000337F AD                  <1> 	lodsd
  1071 00003380 21C0                <1> 	and	eax, eax
  1072 00003382 7444                <1> 	jz	short dpt_3
  1073 00003384 A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
  1074 00003386 7507                <1> 	jnz	short dpt_1
  1075                              <1> 	; 20/07/2015
  1076                              <1> 	; ebp = virtual (linear) address of the memory page
  1077 00003388 E887040000          <1> 	call	reload_page ; 28/04/2015
  1078 0000338D 7244                <1> 	jc	short dpt_p_err
  1079                              <1> dpt_1:
  1080                              <1> 	; 21/09/2015
  1081 0000338F 89C1                <1> 	mov	ecx, eax
  1082 00003391 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  1083 00003395 F6C102              <1> 	test	cl, PTE_A_WRITE ; writable page ?
  1084 00003398 7525                <1> 	jnz	short dpt_2
  1085                              <1> 	; Read only (parent) page
  1086                              <1> 	; 	- there is a third process which uses this page -
  1087                              <1> 	; Allocate a new page for the child process
  1088 0000339A E868FDFFFF          <1> 	call	allocate_page
  1089 0000339F 7232                <1> 	jc	short dpt_p_err
  1090 000033A1 57                  <1> 	push	edi
  1091 000033A2 56                  <1> 	push	esi
  1092 000033A3 89CE                <1> 	mov	esi, ecx
  1093 000033A5 89C7                <1> 	mov	edi, eax
  1094 000033A7 B900040000          <1> 	mov	ecx, PAGE_SIZE/4
  1095 000033AC F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
  1096 000033AE 5E                  <1> 	pop	esi
  1097 000033AF 5F                  <1> 	pop	edi
  1098                              <1> 	; 
  1099 000033B0 53                  <1> 	push	ebx
  1100 000033B1 50                  <1> 	push	eax
  1101                              <1> 	; 20/07/2015
  1102 000033B2 89EB                <1> 	mov	ebx, ebp
  1103                              <1> 	; ebx = virtual address of the memory page
  1104 000033B4 E80B030000          <1> 	call	add_to_swap_queue
  1105 000033B9 58                  <1> 	pop	eax
  1106 000033BA 5B                  <1> 	pop	ebx
  1107                              <1> 	; 21/09/2015
  1108 000033BB 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
  1109                              <1> 		; user + writable + present page
  1110 000033BD EB09                <1> 	jmp	short dpt_3
  1111                              <1> dpt_2:
  1112                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
  1113 000033BF 0C05                <1> 	or	al, PTE_A_USER+PTE_A_PRESENT 
  1114                              <1> 		    ; (read only page!)
  1115 000033C1 8946FC              <1> 	mov	[esi-4], eax ; update parent's PTE
  1116 000033C4 660D0002            <1> 	or      ax, PTE_DUPLICATED  ; (read only page & duplicated PTE!)
  1117                              <1> dpt_3:
  1118 000033C8 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
  1119                              <1> 	;
  1120 000033C9 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
  1121                              <1> 	;
  1122 000033CF 39D7                <1> 	cmp	edi, edx
  1123 000033D1 72AC                <1> 	jb	short dpt_0
  1124                              <1> dpt_p_err:
  1125 000033D3 59                  <1> 	pop	ecx
  1126 000033D4 5A                  <1> 	pop	edx
  1127 000033D5 5F                  <1> 	pop	edi
  1128 000033D6 5E                  <1> 	pop	esi
  1129 000033D7 58                  <1> 	pop	eax ; *
  1130                              <1> dpt_err:
  1131 000033D8 C3                  <1> 	retn
  1132                              <1> 
  1133                              <1> page_fault_handler:	; CPU EXCEPTION 0Eh (14) : Page Fault !
  1134                              <1> 	; 21/09/2015
  1135                              <1> 	; 19/09/2015
  1136                              <1> 	; 17/09/2015
  1137                              <1> 	; 28/08/2015
  1138                              <1> 	; 20/07/2015
  1139                              <1> 	; 28/06/2015
  1140                              <1> 	; 03/05/2015
  1141                              <1> 	; 30/04/2015
  1142                              <1> 	; 18/04/2015
  1143                              <1> 	; 12/04/2015
  1144                              <1> 	; 30/10/2014
  1145                              <1> 	; 11/09/2014
  1146                              <1> 	; 10/09/2014 (Retro UNIX 386 v1 - beginning)
  1147                              <1> 	;
  1148                              <1> 	; Note: This is not an interrupt/exception handler.
  1149                              <1> 	;	This is a 'page fault remedy' subroutine 
  1150                              <1> 	;	which will be called by standard/uniform
  1151                              <1> 	;	exception handler.
  1152                              <1> 	;
  1153                              <1> 	; INPUT -> 
  1154                              <1> 	;	[error_code] = 32 bit ERROR CODE (lower 5 bits are valid)
  1155                              <1> 	;
  1156                              <1> 	;	cr2 = the virtual (linear) address 
  1157                              <1> 	;	      which has caused to page fault (19/09/2015)
  1158                              <1> 	;
  1159                              <1> 	; OUTPUT ->
  1160                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
  1161                              <1> 	;	EAX = 0 -> no error
  1162                              <1> 	;	EAX > 0 -> error code in EAX (also CF = 1)
  1163                              <1> 	;
  1164                              <1> 	; Modified Registers -> none (except EAX)
  1165                              <1> 	;	
  1166                              <1>         ;
  1167                              <1>         ; ERROR CODE:
  1168                              <1> 	;	 31  .....	4   3	2   1	0
  1169                              <1> 	;	+---+-- --+---+---+---+---+---+---+
  1170                              <1> 	;	|   Reserved  | I | R | U | W | P |
  1171                              <1> 	;	+---+-- --+---+---+---+---+---+---+
  1172                              <1> 	;
  1173                              <1> 	; P : PRESENT -	When set, the page fault was caused by 
  1174                              <1>     	;		a page-protection violation. When not set,
  1175                              <1> 	;		it was caused by a non-present page.
  1176                              <1> 	; W : WRITE   -	When set, the page fault was caused by
  1177                              <1> 	;		a page write. When not set, it was caused
  1178                              <1> 	;		by a page read.
  1179                              <1> 	; U : USER    -	When set, the page fault was caused 
  1180                              <1> 	;		while CPL = 3. 
  1181                              <1> 	;		This does not necessarily mean that
  1182                              <1> 	;		the page fault was a privilege violation.
  1183                              <1> 	; R : RESERVD -	When set, the page fault was caused by
  1184                              <1> 	;     WRITE	reading a 1 in a reserved field.
  1185                              <1> 	; I : INSTRUC -	When set, the page fault was caused by
  1186                              <1> 	;     FETCH	an instruction fetch
  1187                              <1> 	;
  1188                              <1> 	;; x86 (32 bit) VIRTUAL ADDRESS TRANSLATION
  1189                              <1> 	;  31               22                  12 11                    0
  1190                              <1> 	; +-------------------+-------------------+-----------------------+
  1191                              <1>        	; | PAGE DIR. ENTRY # | PAGE TAB. ENTRY # |        OFFSET         |
  1192                              <1>        	; +-------------------+-------------------+-----------------------+
  1193                              <1> 	;
  1194                              <1> 
  1195                              <1> 	;; CR3 REGISTER (Control Register 3)
  1196                              <1> 	;  31                                   12             5 4 3 2   0
  1197                              <1> 	; +---------------------------------------+-------------+---+-----+
  1198                              <1>       	; |                                       |  		|P|P|     |
  1199                              <1>       	; |   PAGE DIRECTORY TABLE BASE ADDRESS   |  reserved	|C|W|rsvrd|
  1200                              <1>       	; |                                       | 		|D|T|     |
  1201                              <1>    	; +---------------------------------------+-------------+---+-----+
  1202                              <1> 	;
  1203                              <1> 	;	PWT    - WRITE THROUGH
  1204                              <1> 	;	PCD    - CACHE DISABLE		
  1205                              <1> 	;
  1206                              <1> 	;
  1207                              <1> 	;; x86 PAGE DIRECTORY ENTRY (4 KByte Page)
  1208                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
  1209                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
  1210                              <1>       	; |                                       |     | | | | |P|P|U|R| |
  1211                              <1>       	; |     PAGE TABLE BASE ADDRESS 31..12    | AVL |G|0|D|A|C|W|/|/|P|
  1212                              <1>       	; |                                       |     | | | | |D|T|S|W| |
  1213                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
  1214                              <1> 	;
  1215                              <1>         ;       P      - PRESENT
  1216                              <1>         ;       R/W    - READ/WRITE
  1217                              <1>         ;       U/S    - USER/SUPERVISOR
  1218                              <1> 	;	PWT    - WRITE THROUGH
  1219                              <1> 	;	PCD    - CACHE DISABLE	
  1220                              <1> 	;	A      - ACCESSED	
  1221                              <1>         ;       D      - DIRTY (IGNORED)
  1222                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
  1223                              <1> 	;	G      - GLOBAL	(IGNORED) 
  1224                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
  1225                              <1> 	;
  1226                              <1> 	;
  1227                              <1> 	;; x86 PAGE TABLE ENTRY (4 KByte Page)
  1228                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
  1229                              <1> 	; +---------------------------------------+-----+---+-+-+---+-+-+-+
  1230                              <1>       	; |                                       |     | |P| | |P|P|U|R| |
  1231                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |G|A|D|A|C|W|/|/|P|
  1232                              <1>       	; |                                       |     | |T| | |D|T|S|W| |
  1233                              <1>    	; +---------------------------------------+-----+---+-+-+---+-+-+-+
  1234                              <1> 	;
  1235                              <1>         ;       P      - PRESENT
  1236                              <1>         ;       R/W    - READ/WRITE
  1237                              <1>         ;       U/S    - USER/SUPERVISOR
  1238                              <1> 	;	PWT    - WRITE THROUGH
  1239                              <1> 	;	PCD    - CACHE DISABLE	
  1240                              <1> 	;	A      - ACCESSED	
  1241                              <1>         ;       D      - DIRTY
  1242                              <1> 	;	PAT    - PAGE ATTRIBUTE TABLE INDEX (CACHE BEHAVIOR)
  1243                              <1> 	;	G      - GLOBAL	 
  1244                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
  1245                              <1> 	;
  1246                              <1> 	;
  1247                              <1> 	;; 80386 PAGE TABLE ENTRY (4 KByte Page)
  1248                              <1> 	;  31                                   12 11  9 8 7 6 5 4 3 2 1 0
  1249                              <1> 	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
  1250                              <1>       	; |                                       |     | | | | | | |U|R| |
  1251                              <1>       	; |     PAGE FRAME BASE ADDRESS 31..12    | AVL |0|0|D|A|0|0|/|/|P|
  1252                              <1>       	; |                                       |     | | | | | | |S|W| |
  1253                              <1>       	; +---------------------------------------+-----+-+-+-+-+---+-+-+-+
  1254                              <1> 	;
  1255                              <1>         ;       P      - PRESENT
  1256                              <1>         ;       R/W    - READ/WRITE
  1257                              <1>         ;       U/S    - USER/SUPERVISOR
  1258                              <1>         ;       D      - DIRTY
  1259                              <1>         ;       AVL    - AVAILABLE FOR SYSTEMS PROGRAMMER USE
  1260                              <1> 	;
  1261                              <1>         ;       NOTE: 0 INDICATES INTEL RESERVED. DO NOT DEFINE.
  1262                              <1> 	;
  1263                              <1> 	;
  1264                              <1> 	;; Invalid Page Table Entry
  1265                              <1> 	; 31                                                           1 0
  1266                              <1>       	; +-------------------------------------------------------------+-+
  1267                              <1>       	; |                                                             | |
  1268                              <1>       	; |                          AVAILABLE                          |0|
  1269                              <1>       	; |                                                             | |
  1270                              <1>       	; +-------------------------------------------------------------+-+
  1271                              <1> 	;
  1272                              <1> 
  1273 000033D9 53                  <1> 	push	ebx
  1274 000033DA 52                  <1> 	push	edx
  1275 000033DB 51                  <1> 	push	ecx
  1276                              <1> 	;
  1277                              <1> 	; 21/09/2015 (debugging)
  1278 000033DC FF05[29B80000]      <1> 	inc	dword [u.pfcount] ; page fault count for running process
  1279 000033E2 FF05[94C40000]      <1> 	inc	dword [PF_Count] ; total page fault count	
  1280                              <1> 	; 28/06/2015
  1281                              <1> 	;mov	edx, [error_code] ; Lower 5 bits are valid
  1282 000033E8 8A15[8CC40000]      <1> 	mov	dl, [error_code]
  1283                              <1> 	;
  1284 000033EE F6C201              <1> 	test	dl, 1	; page fault was caused by a non-present page
  1285                              <1> 			; sign
  1286 000033F1 7422                <1> 	jz	short pfh_alloc_np
  1287                              <1> 	; 
  1288                              <1> 	; If it is not a 'write on read only page' type page fault
  1289                              <1> 	; major page fault error with minor reason must be returned without 
  1290                              <1> 	; fixing the problem. 'sys_exit with error' will be needed
  1291                              <1> 	; after return here!
  1292                              <1> 	; Page fault will be remedied, by copying page contents
  1293                              <1> 	; to newly allocated page with write permission;
  1294                              <1> 	; sys_fork -> sys_exec -> copy on write, demand paging method is 
  1295                              <1> 	; used for working with minimum possible memory usage. 
  1296                              <1> 	; sys_fork will duplicate page directory and tables of parent  
  1297                              <1> 	; process with 'read only' flag. If the child process attempts to
  1298                              <1> 	; write on these read only pages, page fault will be directed here
  1299                              <1> 	; for allocating a new page with same data/content. 
  1300                              <1> 	;
  1301                              <1> 	; IMPORTANT : Retro UNIX 386 v1 (and SINGLIX and TR-DOS)
  1302                              <1> 	; will not force to separate CODE and DATA space 
  1303                              <1> 	; in a process/program... 
  1304                              <1> 	; CODE segment/section may contain DATA!
  1305                              <1> 	; It is flat, smoth and simplest programming method already as in 
  1306                              <1> 	; Retro UNIX 8086 v1 and MS-DOS programs.
  1307                              <1> 	;	
  1308 000033F3 F6C202              <1> 	test	dl, 2	; page fault was caused by a page write
  1309                              <1> 			; sign
  1310 000033F6 0F84AB000000        <1>         jz      pfh_p_err
  1311                              <1> 	; 31/08/2015
  1312 000033FC F6C204              <1> 	test	dl, 4	; page fault was caused while CPL = 3 (user mode)
  1313                              <1> 			; sign.  (U+W+P = 4+2+1 = 7)
  1314 000033FF 0F84A2000000        <1>         jz	pfh_pv_err
  1315                              <1> 	;
  1316                              <1> 	; make a new page and copy the parent's page content
  1317                              <1> 	; as the child's new page content
  1318                              <1> 	;
  1319 00003405 0F20D3              <1> 	mov	ebx, cr2 ; CR2 contains the linear address 
  1320                              <1> 			 ; which has caused to page fault
  1321 00003408 E8A2000000          <1> 	call 	copy_page
  1322 0000340D 0F828D000000        <1>         jc      pfh_im_err ; insufficient memory
  1323                              <1> 	;
  1324 00003413 EB7D                <1>         jmp     pfh_cpp_ok
  1325                              <1> 	;
  1326                              <1> pfh_alloc_np:
  1327 00003415 E8EDFCFFFF          <1> 	call	allocate_page	; (allocate a new page)
  1328 0000341A 0F8280000000        <1>         jc      pfh_im_err	; 'insufficient memory' error
  1329                              <1> pfh_chk_cpl:
  1330                              <1> 	; EAX = Physical (base) address of the allocated (new) page
  1331                              <1> 		; (Lower 12 bits are ZERO, because 
  1332                              <1> 		;	the address is on a page boundary)
  1333 00003420 80E204              <1> 	and	dl, 4	; CPL = 3 ?
  1334 00003423 7505                <1> 	jnz	short pfh_um
  1335                              <1> 			; Page fault handler for kernel/system mode (CPL=0)		
  1336 00003425 0F20DB              <1> 	mov	ebx, cr3 ; CR3 (Control Register 3) contains physical address
  1337                              <1> 			 ; of the current/active page directory
  1338                              <1> 			 ; (Always kernel/system mode page directory, here!)
  1339                              <1> 			 ; Note: Lower 12 bits are 0. (page boundary)
  1340 00003428 EB06                <1> 	jmp	short pfh_get_pde
  1341                              <1> 	;
  1342                              <1> pfh_um:			; Page fault handler for user/appl. mode (CPL=3)
  1343 0000342A 8B1D[19B80000]      <1>  	mov	ebx, [u.pgdir] ; Page directory of current/active process
  1344                              <1> 			; Physical address of the USER's page directory
  1345                              <1> 			; Note: Lower 12 bits are 0. (page boundary)
  1346                              <1> pfh_get_pde:
  1347 00003430 80CA03              <1> 	or	dl, 3	; USER + WRITE + PRESENT or SYSTEM + WRITE + PRESENT
  1348 00003433 0F20D1              <1> 	mov	ecx, cr2 ; CR2 contains the virtual address 
  1349                              <1> 			 ; which has been caused to page fault
  1350                              <1> 			 ;
  1351 00003436 C1E914              <1> 	shr	ecx, 20	 ; shift 20 bits right
  1352 00003439 80E1FC              <1> 	and	cl, 0FCh ; mask lower 2 bits to get PDE offset		
  1353                              <1> 	;
  1354 0000343C 01CB                <1> 	add	ebx, ecx ; now, EBX points to the relevant page dir entry 
  1355 0000343E 8B0B                <1> 	mov	ecx, [ebx] ; physical (base) address of the page table 	
  1356 00003440 F6C101              <1> 	test	cl, 1	 ; check bit 0 is set (1) or not (0).
  1357 00003443 740B                <1> 	jz	short pfh_set_pde ; Page directory entry is not valid,
  1358                              <1> 			  	  ; set/validate page directory entry
  1359 00003445 6681E100F0          <1> 	and	cx, PDE_A_CLEAR ; 0F000h ; Clear attribute bits
  1360 0000344A 89CB                <1> 	mov	ebx, ecx ; Physical address of the page table
  1361 0000344C 89C1                <1> 	mov	ecx, eax ; new page address (physical) 	
  1362 0000344E EB16                <1> 	jmp	short pfh_get_pte
  1363                              <1> pfh_set_pde:
  1364                              <1> 	;; NOTE: Page directories and page tables never be swapped out!
  1365                              <1> 	;;	 (So, we know this PDE is empty or invalid)
  1366                              <1> 	;
  1367 00003450 08D0                <1> 	or	al, dl	 ; lower 3 bits are used as U/S, R/W, P flags
  1368 00003452 8903                <1> 	mov	[ebx], eax ; Let's put the new page directory entry here !
  1369 00003454 30C0                <1> 	xor	al, al	 ; clear lower (3..8) bits
  1370 00003456 89C3                <1> 	mov	ebx, eax
  1371 00003458 E8AAFCFFFF          <1> 	call	allocate_page	 ; (allocate a new page)
  1372 0000345D 7241                <1> 	jc	short pfh_im_err   ; 'insufficient memory' error
  1373                              <1> pfh_spde_1:
  1374                              <1> 	; EAX = Physical (base) address of the allocated (new) page
  1375 0000345F 89C1                <1> 	mov	ecx, eax
  1376 00003461 E81BFDFFFF          <1> 	call	clear_page ; Clear page content
  1377                              <1> pfh_get_pte:
  1378 00003466 0F20D0              <1> 	mov	eax, cr2 ; virtual address
  1379                              <1> 			 ; which has been caused to page fault
  1380 00003469 89C7                <1> 	mov	edi, eax ; 20/07/2015
  1381 0000346B C1E80C              <1> 	shr	eax, 12	 ; shift 12 bit right to get 
  1382                              <1> 			 ; higher 20 bits of the page fault address 
  1383 0000346E 25FF030000          <1> 	and	eax, 3FFh ; mask PDE# bits, the result is PTE# (0 to 1023)
  1384 00003473 C1E002              <1> 	shl	eax, 2	; shift 2 bits left to get PTE offset
  1385 00003476 01C3                <1> 	add	ebx, eax ; now, EBX points to the relevant page table entry 
  1386 00003478 8B03                <1> 	mov	eax, [ebx] ; get previous value of pte
  1387                              <1> 		; bit 0 of EAX is always 0 (otherwise we would not be here)
  1388 0000347A 21C0                <1> 	and	eax, eax
  1389 0000347C 7410                <1> 	jz	short pfh_gpte_1
  1390                              <1> 	; 20/07/2015
  1391 0000347E 87D9                <1> 	xchg	ebx, ecx ; new page address (physical)
  1392 00003480 55                  <1> 	push	ebp ; 20/07/2015
  1393 00003481 0F20D5              <1> 	mov	ebp, cr2
  1394                              <1> 		; ECX = physical address of the page table entry
  1395                              <1> 		; EBX = Memory page address (physical!)
  1396                              <1> 		; EAX = Swap disk (offset) address
  1397                              <1> 		; EBP = virtual address (page fault address)
  1398 00003484 E8B7000000          <1> 	call	swap_in
  1399 00003489 5D                  <1> 	pop	ebp
  1400 0000348A 7210                <1> 	jc      short pfh_err_retn
  1401 0000348C 87CB                <1> 	xchg	ecx, ebx
  1402                              <1> 		; EBX = physical address of the page table entry
  1403                              <1> 		; ECX = new page
  1404                              <1> pfh_gpte_1:
  1405 0000348E 08D1                <1> 	or	cl, dl	; lower 3 bits are used as U/S, R/W, P flags
  1406 00003490 890B                <1> 	mov	[ebx], ecx ; Let's put the new page table entry here !
  1407                              <1> pfh_cpp_ok:
  1408                              <1> 	; 20/07/2015
  1409 00003492 0F20D3              <1> 	mov	ebx, cr2
  1410 00003495 E82A020000          <1> 	call 	add_to_swap_queue
  1411                              <1> 	;
  1412                              <1> 	; The new PTE (which contains the new page) will be added to 
  1413                              <1> 	; the swap queue, here. 
  1414                              <1> 	; (Later, if memory will become insufficient, 
  1415                              <1> 	; one page will be swapped out which is at the head of 
  1416                              <1> 	; the swap queue by using FIFO and access check methods.)
  1417                              <1> 	;
  1418 0000349A 31C0                <1> 	xor	eax, eax  ; 0
  1419                              <1> 	;
  1420                              <1> pfh_err_retn:
  1421 0000349C 59                  <1> 	pop	ecx
  1422 0000349D 5A                  <1> 	pop	edx
  1423 0000349E 5B                  <1> 	pop	ebx
  1424 0000349F C3                  <1> 	retn 
  1425                              <1> 	
  1426                              <1> pfh_im_err:
  1427 000034A0 B8E1000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_IM ; Error code in AX
  1428                              <1> 			; Major (Primary) Error: Page Fault
  1429                              <1> 			; Minor (Secondary) Error: Insufficient Memory !
  1430 000034A5 EBF5                <1> 	jmp	short pfh_err_retn
  1431                              <1> 
  1432                              <1> 
  1433                              <1> pfh_p_err: ; 09/03/2015
  1434                              <1> pfh_pv_err:
  1435                              <1> 	; Page fault was caused by a protection-violation
  1436 000034A7 B8E3000000          <1> 	mov	eax, ERR_MAJOR_PF + ERR_MINOR_PV ; Error code in AX
  1437                              <1> 			; Major (Primary) Error: Page Fault
  1438                              <1> 			; Minor (Secondary) Error: Protection violation !
  1439 000034AC F9                  <1> 	stc
  1440 000034AD EBED                <1> 	jmp	short pfh_err_retn
  1441                              <1> 
  1442                              <1> copy_page:
  1443                              <1> 	; 22/09/2015
  1444                              <1> 	; 21/09/2015
  1445                              <1> 	; 19/09/2015
  1446                              <1> 	; 07/09/2015
  1447                              <1> 	; 31/08/2015
  1448                              <1> 	; 20/07/2015
  1449                              <1> 	; 05/05/2015
  1450                              <1> 	; 03/05/2015
  1451                              <1> 	; 18/04/2015
  1452                              <1> 	; 12/04/2015
  1453                              <1> 	; 30/10/2014
  1454                              <1> 	; 18/10/2014 (Retro UNIX 386 v1 - beginning)
  1455                              <1> 	;
  1456                              <1> 	; INPUT -> 
  1457                              <1> 	;	EBX = Virtual (linear) address of source page
  1458                              <1> 	;	     (Page fault address)
  1459                              <1> 	; OUTPUT ->
  1460                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF THE ALLOCATED PAGE
  1461                              <1> 	;	(corresponding PAGE TABLE ENTRY is mapped/set)
  1462                              <1> 	;	EAX = 0 (CF = 1) 
  1463                              <1> 	;		if there is not a free page to be allocated
  1464                              <1> 	;	(page content of the source page will be copied
  1465                              <1> 	;	onto the target/new page) 	
  1466                              <1> 	;
  1467                              <1> 	; Modified Registers -> ecx, ebx (except EAX)
  1468                              <1> 	;	
  1469 000034AF 56                  <1> 	push	esi
  1470 000034B0 57                  <1> 	push	edi
  1471                              <1> 	;push	ebx
  1472                              <1> 	;push	ecx
  1473 000034B1 31F6                <1> 	xor 	esi, esi
  1474 000034B3 C1EB0C              <1> 	shr	ebx, 12 ; shift 12 bits right to get PDE & PTE numbers
  1475 000034B6 89D9                <1> 	mov	ecx, ebx ; save page fault address (as 12 bit shifted)
  1476 000034B8 C1EB08              <1> 	shr	ebx, 8	 ; shift 8 bits right and then
  1477 000034BB 80E3FC              <1> 	and	bl, 0FCh ; mask lower 2 bits to get PDE offset	
  1478 000034BE 89DF                <1> 	mov 	edi, ebx ; save it for the parent of current process
  1479 000034C0 031D[19B80000]      <1> 	add	ebx, [u.pgdir] ; EBX points to the relevant page dir entry 
  1480 000034C6 8B03                <1> 	mov	eax, [ebx] ; physical (base) address of the page table
  1481 000034C8 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits 	
  1482 000034CC 89CB                <1> 	mov	ebx, ecx   ; (restore higher 20 bits of page fault address)
  1483 000034CE 81E3FF030000        <1> 	and	ebx, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
  1484 000034D4 66C1E302            <1> 	shl	bx, 2	   ; shift 2 bits left to get PTE offset
  1485 000034D8 01C3                <1> 	add	ebx, eax   ; EBX points to the relevant page table entry 
  1486                              <1> 	; 07/09/2015
  1487 000034DA 66F7030002          <1>         test    word [ebx], PTE_DUPLICATED ; (Does current process share this
  1488                              <1> 				     ; read only page as a child process?)	
  1489 000034DF 7509                <1> 	jnz	short cpp_0 ; yes
  1490 000034E1 8B0B                <1> 	mov	ecx, [ebx] ; PTE value
  1491 000034E3 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h  ; clear page attributes
  1492 000034E8 EB32                <1> 	jmp	short cpp_1
  1493                              <1> cpp_0:
  1494 000034EA 89FE                <1> 	mov	esi, edi
  1495 000034EC 0335[1DB80000]      <1> 	add	esi, [u.ppgdir] ; the parent's page directory entry
  1496 000034F2 8B06                <1> 	mov	eax, [esi] ; physical (base) address of the page table
  1497 000034F4 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  1498 000034F8 89CE                <1> 	mov	esi, ecx   ; (restore higher 20 bits of page fault address)	
  1499 000034FA 81E6FF030000        <1> 	and	esi, 3FFh  ; mask PDE# bits, the result is PTE# (0 to 1023)
  1500 00003500 66C1E602            <1> 	shl	si, 2	   ; shift 2 bits left to get PTE offset
  1501 00003504 01C6                <1> 	add	esi, eax   ; EDX points to the relevant page table entry  	
  1502 00003506 8B0E                <1> 	mov	ecx, [esi] ; PTE value of the parent process
  1503                              <1> 	; 21/09/2015
  1504 00003508 8B03                <1> 	mov	eax, [ebx] ; PTE value of the child process
  1505 0000350A 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear page attributes	
  1506                              <1> 	;
  1507 0000350E F6C101              <1> 	test	cl, PTE_A_PRESENT ; is it a present/valid page ?
  1508 00003511 7424                <1> 	jz	short cpp_3 ; the parent's page is not same page  	
  1509                              <1> 	;
  1510 00003513 6681E100F0          <1> 	and	cx, PTE_A_CLEAR ; 0F000h ; clear page attributes
  1511 00003518 39C8                <1> 	cmp	eax, ecx   ; Same page?	
  1512 0000351A 751B                <1> 	jne	short cpp_3 ; Parent page and child page are not same 
  1513                              <1> 			    ; Convert child's page to writable page
  1514                              <1> cpp_1:
  1515 0000351C E8E6FBFFFF          <1> 	call	allocate_page
  1516 00003521 721A                <1> 	jc	short cpp_4 ; 'insufficient memory' error
  1517 00003523 21F6                <1> 	and	esi, esi    ; check ESI is valid or not
  1518 00003525 7405                <1> 	jz	short cpp_2
  1519                              <1> 		; Convert read only page to writable page 
  1520                              <1> 		;(for the parent of the current process)
  1521                              <1> 	;and	word [esi], PTE_A_CLEAR ; 0F000h
  1522                              <1> 	; 22/09/2015
  1523 00003527 890E                <1> 	mov	[esi], ecx
  1524 00003529 800E07              <1> 	or	byte [esi], PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER
  1525                              <1> 				 ; 1+2+4 = 7
  1526                              <1> cpp_2:
  1527 0000352C 89C7                <1> 	mov	edi, eax ; new page address of the child process
  1528                              <1> 	; 07/09/2015
  1529 0000352E 89CE                <1> 	mov	esi, ecx ; the page address of the parent process
  1530 00003530 B900040000          <1> 	mov	ecx, PAGE_SIZE / 4
  1531 00003535 F3A5                <1> 	rep	movsd ; 31/08/2015
  1532                              <1> cpp_3:		
  1533 00003537 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_WRITE + PTE_A_USER ; 1+2+4 = 7
  1534 00003539 8903                <1> 	mov	[ebx], eax ; Update PTE
  1535 0000353B 28C0                <1> 	sub	al, al ; clear attributes
  1536                              <1> cpp_4:
  1537                              <1> 	;pop	ecx
  1538                              <1> 	;pop	ebx
  1539 0000353D 5F                  <1> 	pop	edi
  1540 0000353E 5E                  <1> 	pop	esi
  1541 0000353F C3                  <1> 	retn
  1542                              <1> 
  1543                              <1> ;; 28/04/2015
  1544                              <1> ;; 24/10/2014
  1545                              <1> ;; 21/10/2014 (Retro UNIX 386 v1 - beginning)
  1546                              <1> ;; SWAP_PAGE_QUEUE (4096 bytes)
  1547                              <1> ;;
  1548                              <1> ;;   0000   0001   0002   0003   ....   1020   1021   1022   1023	
  1549                              <1> ;; +------+------+------+------+-    -+------+------+------+------+
  1550                              <1> ;; |  pg1 |  pg2 |  pg3 |  pg4 | .... |pg1021|pg1022|pg1023|pg1024|
  1551                              <1> ;; +------+------+------+------+-    -+------+------+------+------+    
  1552                              <1> ;;
  1553                              <1> ;; [swpq_last] = 0 to 4096 (step 4) -> the last position on the queue
  1554                              <1> ;;
  1555                              <1> ;; Method:
  1556                              <1> ;;	Swap page queue is a list of allocated pages with physical
  1557                              <1> ;;	addresses (system mode virtual adresses = physical addresses).
  1558                              <1> ;;	It is used for 'swap_in' and 'swap_out' procedures.
  1559                              <1> ;;	When a new page is being allocated, swap queue is updated
  1560                              <1> ;;	by 'swap_queue_shift' procedure, header of the queue (offset 0)
  1561                              <1> ;;	is checked for 'accessed' flag. If the 1st page on the queue
  1562                              <1> ;;	is 'accessed' or 'read only', it is dropped from the list;
  1563                              <1> ;;	other pages from the 2nd to the last (in [swpq_last]) shifted
  1564                              <1> ;; 	to head then the 2nd page becomes the 1st and '[swpq_last]' 
  1565                              <1> ;;	offset value becomes it's previous offset value - 4.
  1566                              <1> ;;	If the 1st page of the swap page queue is not 'accessed'	
  1567                              <1> ;;	the queue/list is not shifted.
  1568                              <1> ;;	After the queue/list shift, newly allocated page is added
  1569                              <1> ;;	to the tail of the queue at the [swpq_count*4] position.
  1570                              <1> ;;	But, if [swpq_count] > 1023, the newly allocated page
  1571                              <1> ;;	will not be added to the tail of swap page queue.  		 
  1572                              <1> ;;	
  1573                              <1> ;;	During 'swap_out' procedure, swap page queue is checked for
  1574                              <1> ;;	the first non-accessed, writable page in the list, 
  1575                              <1> ;;	from the head to the tail. The list is shifted to left 
  1576                              <1> ;;	(to the head) till a non-accessed page will be found in the list.
  1577                              <1> ;;	Then, this page	is swapped out (to disk) and then it is dropped
  1578                              <1> ;;	from the list by a final swap queue shift. [swpq_count] value
  1579                              <1> ;;	is changed. If all pages on the queue' are 'accessed', 
  1580                              <1> ;;	'insufficient memory' error will be returned ('swap_out' 
  1581                              <1> ;;	procedure will be failed)...
  1582                              <1> ;;
  1583                              <1> ;;	Note: If the 1st page of the queue is an 'accessed' page,
  1584                              <1> ;;	'accessed' flag of the page will be reset (0) and that page
  1585                              <1> ;;	(PTE) will be added to the tail of the queue after
  1586                              <1> ;;	the check, if [swpq_count] < 1023. If [swpq_count] = 1024
  1587                              <1> ;;	the queue will be rotated and the PTE in the head will be
  1588                              <1> ;;	added to the tail after resetting 'accessed' bit. 
  1589                              <1> ;;
  1590                              <1> ;;
  1591                              <1> ;;	
  1592                              <1> ;; SWAP DISK/FILE (with 4096 bytes swapped page blocks)
  1593                              <1> ;;
  1594                              <1> ;;  00000000  00000004  00000008  0000000C   ...   size-8    size-4
  1595                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+
  1596                              <1> ;; |descriptr| page(1) | page(2) | page(3) | ... |page(n-1)| page(n) |
  1597                              <1> ;; +---------+---------+---------+---------+-- --+---------+---------+    
  1598                              <1> ;;
  1599                              <1> ;; [swpd_next] = the first free block address in swapped page records
  1600                              <1> ;;    		 for next free block search by 'swap_out' procedure.
  1601                              <1> ;; [swpd_size] = swap disk/file size in sectors (512 bytes)
  1602                              <1> ;;		 NOTE: max. possible swap disk size is 1024 GB
  1603                              <1> ;; 		 (entire swap space must be accessed by using
  1604                              <1> ;;		 31 bit offset address) 
  1605                              <1> ;; [swpd_free] = free block (4096 bytes) count in swap disk/file space
  1606                              <1> ;; [swpd_start] = absolute/start address of the swap disk/file
  1607                              <1> ;;		  0 for file, or beginning sector of the swap partition
  1608                              <1> ;; [swp_drv] = logical drive description table addr. of swap disk/file
  1609                              <1> ;;
  1610                              <1> ;; 					
  1611                              <1> ;; Method:
  1612                              <1> ;;	When the memory (ram) becomes insufficient, page allocation
  1613                              <1> ;;	procedure swaps out a page from memory to the swap disk 
  1614                              <1> ;;	(partition) or swap file to get a new free page at the memory.
  1615                              <1> ;;	Swapping out is performed by using swap page queue.
  1616                              <1> ;;
  1617                              <1> ;; 	Allocation block size of swap disk/file is equal to page size
  1618                              <1> ;;	(4096 bytes). Swapping address (in sectors) is recorded
  1619                              <1> ;;	into relevant page file entry as 31 bit physical (logical)
  1620                              <1> ;;	offset address as 1 bit shifted to left for present flag (0).
  1621                              <1> ;;	Swapped page address is between 1 and swap disk/file size - 4.	  
  1622                              <1> ;;	Absolute physical (logical) address of the swapped page is 
  1623                              <1> ;;	calculated by adding offset value to the swap partition's 
  1624                              <1> ;;	start address. If the swap device (disk) is a virtual disk 
  1625                              <1> ;;	or it is a file, start address of the swap disk/volume is 0, 
  1626                              <1> ;;	and offset value is equal to absolute (physical or logical)
  1627                              <1> ;;	address/position. (It has not to be ZERO if the swap partition 
  1628                              <1> ;;	is in a partitioned virtual hard disk.) 
  1629                              <1> ;;
  1630                              <1> ;;	Note: Swap addresses are always specified/declared in sectors, 
  1631                              <1> ;;	not in bytes or	in blocks/zones/clusters (4096 bytes) as unit.
  1632                              <1> ;;
  1633                              <1> ;;	Swap disk/file allocation is mapped via 'Swap Allocation Table'
  1634                              <1> ;;	at memory as similar to 'Memory Allocation Table'.
  1635                              <1> ;;
  1636                              <1> ;;	Every bit of Swap Allocation Table repsesents one swap block
  1637                              <1> ;;	(equal to page size) respectively. Bit 0 of the S.A.T. byte 0
  1638                              <1> ;;	is reserved for swap disk/file block 0 as descriptor block
  1639                              <1> ;;	(also for compatibility with PTE). If bit value is ZERO,
  1640                              <1> ;;	it means relevant (respective) block is in use, and, 
  1641                              <1> ;;	of course, if bit value is 1, it means relevant (respective)
  1642                              <1> ;;      swap disk/file block is free.
  1643                              <1> ;;	For example: bit 1 of the byte 128 repsesents block 1025 
  1644                              <1> ;;	(128*8+1) or sector (offset) 8200 on the swap disk or
  1645                              <1> ;;	byte (offset/position) 4198400 in the swap file. 
  1646                              <1> ;;	4GB swap space is represented via 128KB Swap Allocation Table.
  1647                              <1> ;;	Initial layout of Swap Allocation Table is as follows:
  1648                              <1> ;;	------------------------------------------------------------
  1649                              <1> ;;	0111111111111111111111111 .... 11111111111111111111111111111
  1650                              <1> ;;	------------------------------------------------------------
  1651                              <1> ;;	(0 is reserved block, 1s represent free blocks respectively.)
  1652                              <1> ;;	(Note: Allocation cell/unit of the table is bit, not byte)
  1653                              <1> ;;
  1654                              <1> ;;	..............................................................
  1655                              <1> ;;
  1656                              <1> ;;	'swap_out' procedure checks 'free_swap_blocks' count at first,
  1657                              <1> ;;	then it searches Swap Allocation Table if free count is not
  1658                              <1> ;;	zero. From begining the [swpd_next] dword value, the first bit 
  1659                              <1> ;;	position with value of 1 on the table is converted to swap
  1660                              <1> ;;	disk/file offset address, in sectors (not 4096 bytes block).
  1661                              <1> ;;	'ldrv_write' procedure is called with ldrv (logical drive
  1662                              <1> ;;	number of physical swap disk or virtual swap disk)
  1663                              <1> ;;	number, sector offset (not absolute sector -LBA- number),
  1664                              <1> ;;	and sector count (8, 512*8 = 4096) and buffer adress
  1665                              <1> ;;	(memory page). That will be a direct disk write procedure.
  1666                              <1> ;;	(for preventing late memory allocation, significant waiting). 
  1667                              <1> ;;	If disk write procedure returns with error or free count of 
  1668                              <1> ;;	swap blocks is ZERO, 'swap_out' procedure will return with
  1669                              <1> ;;	'insufficient memory error' (cf=1). 
  1670                              <1> ;;
  1671                              <1> ;;	(Note: Even if free swap disk/file blocks was not zero,
  1672                              <1> ;;	any disk write error will not be fixed by 'swap_out' procedure,
  1673                              <1> ;;	in other words, 'swap_out' will not check the table for other
  1674                              <1> ;;	free blocks after a disk write error. It will return to 
  1675                              <1> ;;	the caller with error (CF=1) which means swapping is failed. 
  1676                              <1> ;;
  1677                              <1> ;;	After writing the page on to swap disk/file address/sector,
  1678                              <1> ;;	'swap_out' procesure returns with that swap (offset) sector
  1679                              <1> ;;	address (cf=0). 
  1680                              <1> ;;
  1681                              <1> ;;	..............................................................
  1682                              <1> ;;
  1683                              <1> ;;	'swap_in' procedure loads addressed (relevant) swap disk or
  1684                              <1> ;;	file sectors at specified memory page. Then page allocation
  1685                              <1> ;;	procedure updates relevant page table entry with 'present' 
  1686                              <1> ;;	attribute. If swap disk or file reading fails there is nothing
  1687                              <1> ;;	to do, except to terminate the process which is the owner of
  1688                              <1> ;;	the swapped page.
  1689                              <1> ;;
  1690                              <1> ;;	'swap_in' procedure sets the relevant/respective bit value
  1691                              <1> ;;	in the Swap Allocation Table (as free block). 'swap_in' also
  1692                              <1> ;;	updates [swpd_first] pointer if it is required.
  1693                              <1> ;;
  1694                              <1> ;;	..............................................................	 
  1695                              <1> ;;
  1696                              <1> ;;	Note: If [swap_enabled] value is ZERO, that means there is not
  1697                              <1> ;;	a swap disk or swap file in use... 'swap_in' and 'swap_out'
  1698                              <1> ;;	procedures ans 'swap page que' procedures will not be active...
  1699                              <1> ;;	'Insufficient memory' error will be returned by 'swap_out'
  1700                              <1> ;;	and 'general protection fault' will be returned by 'swap_in'
  1701                              <1> ;;	procedure, if it is called mistakenly (a wrong value in a PTE).		
  1702                              <1> ;;
  1703                              <1> 
  1704                              <1> swap_in:
  1705                              <1> 	; 31/08/2015
  1706                              <1> 	; 20/07/2015
  1707                              <1> 	; 28/04/2015
  1708                              <1> 	; 18/04/2015
  1709                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  1710                              <1> 	;
  1711                              <1> 	; INPUT -> 
  1712                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS OF THE MEMORY PAGE
  1713                              <1> 	;	EBP = VIRTUAL (LINEAR) ADDRESS (page fault address)
  1714                              <1> 	;	EAX = Offset Address for the swapped page on the
  1715                              <1> 	;	      swap disk or in the swap file.
  1716                              <1> 	;
  1717                              <1> 	; OUTPUT ->
  1718                              <1> 	;	EAX = 0 if loading at memory has been successful
  1719                              <1> 	;
  1720                              <1> 	;	CF = 1 -> swap disk reading error (disk/file not present
  1721                              <1> 	;		  or sector not present or drive not ready
  1722                              <1> 	;	     EAX = Error code
  1723                              <1> 	;	     [u.error] = EAX 
  1724                              <1> 	;		       = The last error code for the process
  1725                              <1> 	;		         (will be reset after returning to user)	  
  1726                              <1> 	;
  1727                              <1> 	; Modified Registers -> EAX
  1728                              <1> 	;
  1729                              <1> 
  1730 00003540 833D[77C40000]00    <1>         cmp     dword [swp_drv], 0
  1731 00003547 7648                <1> 	jna	short swpin_dnp_err
  1732                              <1> 
  1733 00003549 3B05[7BC40000]      <1> 	cmp	eax, [swpd_size]
  1734 0000354F 734C                <1> 	jnb	short swpin_snp_err
  1735                              <1> 
  1736 00003551 56                  <1> 	push	esi
  1737 00003552 53                  <1> 	push	ebx
  1738 00003553 51                  <1> 	push	ecx
  1739 00003554 8B35[77C40000]      <1> 	mov	esi, [swp_drv]	
  1740 0000355A B908000000          <1> 	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
  1741                              <1> 		; Note: Even if corresponding physical disk's sector 
  1742                              <1> 		; size different than 512 bytes, logical disk sector
  1743                              <1> 		; size is 512 bytes and disk reading procedure
  1744                              <1> 		; will be performed for reading 4096 bytes
  1745                              <1> 		; (2*2048, 8*512). 
  1746                              <1> 	; ESI = Logical disk description table address
  1747                              <1> 	; EBX = Memory page (buffer) address (physical!)
  1748                              <1> 	; EAX = Sector adress (offset address, logical sector number)
  1749                              <1> 	; ECX = Sector count ; 8 sectors
  1750 0000355F 50                  <1> 	push	eax
  1751 00003560 E833020000          <1> 	call	logical_disk_read
  1752 00003565 58                  <1> 	pop	eax
  1753 00003566 730C                <1> 	jnc	short swpin_read_ok
  1754                              <1> 	;
  1755 00003568 B804000000          <1> 	mov	eax, SWP_DISK_READ_ERR ; drive not ready or read error
  1756 0000356D A3[15B80000]        <1> 	mov	[u.error], eax
  1757 00003572 EB19                <1> 	jmp	short swpin_retn
  1758                              <1> 	;
  1759                              <1> swpin_read_ok:
  1760                              <1> 	; EAX = Offset address (logical sector number)
  1761 00003574 E891010000          <1> 	call	unlink_swap_block  ; Deallocate swap block	
  1762                              <1> 	;
  1763                              <1> 	; EBX = Memory page (buffer) address (physical!)
  1764                              <1> 	; 20/07/2015
  1765 00003579 89EB                <1> 	mov	ebx, ebp ; virtual address (page fault address)
  1766 0000357B 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
  1767 00003580 8A1D[0FB80000]      <1> 	mov	bl, [u.uno] ; current process number
  1768                              <1> 	; EBX = Virtual address & process number combination
  1769 00003586 E89E000000          <1> 	call	swap_queue_shift
  1770 0000358B 29C0                <1> 	sub	eax, eax  ; 0 ; Error Code = 0  (no error)
  1771                              <1> 	;
  1772                              <1> swpin_retn:
  1773 0000358D 59                  <1> 	pop	ecx
  1774 0000358E 5B                  <1> 	pop	ebx
  1775 0000358F 5E                  <1> 	pop	esi
  1776 00003590 C3                  <1> 	retn
  1777                              <1> 
  1778                              <1> swpin_dnp_err:
  1779 00003591 B805000000          <1> 	mov	eax, SWP_DISK_NOT_PRESENT_ERR
  1780                              <1> swpin_err_retn:
  1781 00003596 A3[15B80000]        <1> 	mov	[u.error], eax
  1782 0000359B F9                  <1> 	stc
  1783 0000359C C3                  <1> 	retn
  1784                              <1> 
  1785                              <1> swpin_snp_err:
  1786 0000359D B806000000          <1> 	mov	eax, SWP_SECTOR_NOT_PRESENT_ERR
  1787 000035A2 EBF2                <1> 	jmp	short swpin_err_retn
  1788                              <1> 
  1789                              <1> swap_out:
  1790                              <1> 	; 31/08/2015
  1791                              <1> 	; 05/05/2015
  1792                              <1> 	; 30/04/2015
  1793                              <1> 	; 28/04/2015
  1794                              <1> 	; 18/04/2015
  1795                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  1796                              <1> 	;
  1797                              <1> 	; INPUT -> 
  1798                              <1> 	;	none
  1799                              <1> 	;
  1800                              <1> 	; OUTPUT ->
  1801                              <1> 	;	EAX = Physical page address (which is swapped out
  1802                              <1> 	;	      for allocating a new page)
  1803                              <1> 	;	CF = 1 -> swap disk writing error (disk/file not present
  1804                              <1> 	;		  or sector not present or drive not ready
  1805                              <1> 	;	     EAX = Error code
  1806                              <1> 	;	     [u.error] = EAX 
  1807                              <1> 	;		       = The last error code for the process
  1808                              <1> 	;		         (will be reset after returning to user)	  
  1809                              <1> 	;
  1810                              <1> 	; Modified Registers -> non (except EAX)
  1811                              <1> 	;
  1812 000035A4 66833D[75C40000]01  <1> 	cmp 	word [swpq_count], 1
  1813 000035AC 7274                <1>         jc      short swpout_im_err ; 'insufficient memory'
  1814                              <1> 
  1815                              <1>         ;cmp     dword [swp_drv], 1
  1816                              <1> 	;jc	short swpout_dnp_err ; 'swap disk/file not present'
  1817                              <1> 
  1818 000035AE 833D[7FC40000]01    <1>         cmp     dword [swpd_free], 1
  1819 000035B5 7258                <1> 	jc	short swpout_nfspc_err ; 'no free space on swap disk'
  1820                              <1> 
  1821 000035B7 53                  <1> 	push	ebx
  1822                              <1> swpout_1:
  1823 000035B8 31DB                <1> 	xor	ebx, ebx
  1824 000035BA E86A000000          <1> 	call	swap_queue_shift
  1825 000035BF 21C0                <1> 	and	eax, eax	; entry count (before shifting)
  1826 000035C1 7457                <1> 	jz	short swpout_npts_err  ; There is no any PTE in
  1827                              <1> 				       ; the swap queue
  1828 000035C3 BB00E00800          <1> 	mov	ebx, swap_queue	       ; Addres of the head of 
  1829                              <1> 				       ; the swap queue		
  1830 000035C8 8B03                <1> 	mov	eax, [ebx]	       ; The PTE in the queue head	
  1831                              <1> 
  1832                              <1> 	;test	al, PTE_A_PRESENT      ; bit 0 = 1
  1833                              <1> 	;jz	short swpout_1	       ; non-present page already
  1834                              <1> 				       ; must not be in the queue
  1835                              <1> 
  1836                              <1> 	;test	al, PTE_A_WRITE	       ; bit 1 = 0
  1837                              <1> 	;jz	short swpout_1 	       ; read only page (must not be
  1838                              <1> 				       ; swapped out)
  1839                              <1> 	
  1840 000035CA A820                <1> 	test	al, PTE_A_ACCESS       ; bit 5 = 1 (Accessed)
  1841 000035CC 75EA                <1> 	jnz	short swpout_1 	       ; accessed page (must not be
  1842                              <1> 				       ; swapped out, at this stage)
  1843                              <1> 	;
  1844 000035CE 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  1845                              <1> 	;
  1846 000035D2 52                  <1> 	push	edx
  1847 000035D3 89DA                <1> 	mov	edx, ebx	       ; Page table entry address	
  1848 000035D5 89C3                <1> 	mov	ebx, eax	       ; Buffer (Page) Address				
  1849                              <1> 	;
  1850 000035D7 E861010000          <1> 	call	link_swap_block
  1851 000035DC 7304                <1> 	jnc	short swpout_2	       ; It may not be needed here	
  1852 000035DE 5A                  <1> 	pop	edx		       ; because [swpd_free] value	
  1853 000035DF 5B                  <1> 	pop	ebx
  1854 000035E0 EB2D                <1> 	jmp	short swpout_nfspc_err ; was checked at the beginging. 	
  1855                              <1> swpout_2:	
  1856 000035E2 56                  <1> 	push	esi
  1857 000035E3 51                  <1> 	push	ecx
  1858 000035E4 50                  <1> 	push	eax ; sector address
  1859 000035E5 8B35[77C40000]      <1> 	mov	esi, [swp_drv]	
  1860 000035EB B908000000          <1> 	mov	ecx, PAGE_SIZE / LOGIC_SECT_SIZE  ; 8 !
  1861                              <1> 		; Note: Even if corresponding physical disk's sector 
  1862                              <1> 		; size different than 512 bytes, logical disk sector
  1863                              <1> 		; size is 512 bytes and disk writing procedure
  1864                              <1> 		; will be performed for writing 4096 bytes
  1865                              <1> 		; (2*2048, 8*512). 
  1866                              <1> 	; ESI = Logical disk description table address
  1867                              <1> 	; EBX = Buffer address
  1868                              <1> 	; EAX = Sector adress (offset address, logical sector number)
  1869                              <1> 	; ECX = Sector count ; 8 sectors
  1870 000035F0 E8A4010000          <1> 	call	logical_disk_write
  1871 000035F5 59                  <1> 	pop	ecx ; sector address	
  1872 000035F6 730C                <1> 	jnc	short swpout_write_ok
  1873                              <1> 	;
  1874                              <1> 	;; call	unlink_swap_block ; this block must be left as 'in use'
  1875                              <1> swpout_dw_err:
  1876 000035F8 B808000000          <1> 	mov	eax, SWP_DISK_WRITE_ERR ; drive not ready or write error
  1877 000035FD A3[15B80000]        <1> 	mov	[u.error], eax
  1878 00003602 EB06                <1> 	jmp	short swpout_retn
  1879                              <1> 	;
  1880                              <1> swpout_write_ok:
  1881                              <1> 	; EBX = Buffer (page) address
  1882                              <1> 	; EDX = Page Table entry address
  1883                              <1> 	; ECX = Swap disk sector (file block) address (31 bit)
  1884 00003604 D1E1                <1> 	shl 	ecx, 1  ; 31 bit sector address from bit 1 to bit 31 
  1885 00003606 890A                <1> 	mov 	[edx], ecx 
  1886                              <1> 		; bit 0 = 0 (swapped page)
  1887 00003608 89D8                <1> 	mov	eax, ebx
  1888                              <1> swpout_retn:
  1889 0000360A 59                  <1> 	pop	ecx
  1890 0000360B 5E                  <1> 	pop	esi
  1891 0000360C 5A                  <1> 	pop	edx
  1892 0000360D 5B                  <1> 	pop	ebx
  1893 0000360E C3                  <1> 	retn
  1894                              <1> 
  1895                              <1> ; Note: Swap_queue will not be updated in 'swap_out' procedure
  1896                              <1> ;	after the page is swapped out. (the PTE at the queue head
  1897                              <1> ;	-with 'non-present' attribute- will be dropped from the
  1898                              <1> ;	the queue in next 'swap_out' or in next 'swap_queue_shift'.
  1899                              <1> 	
  1900                              <1> ;swpout_dnp_err:
  1901                              <1> ;	mov	eax, SWP_DISK_NOT_PRESENT_ERR ; disk not present
  1902                              <1> ;	jmp	short swpout_err_retn
  1903                              <1> swpout_nfspc_err:
  1904 0000360F B807000000          <1> 	mov	eax, SWP_NO_FREE_SPACE_ERR ; no free space
  1905                              <1> swpout_err_retn:
  1906 00003614 A3[15B80000]        <1> 	mov	[u.error], eax
  1907                              <1> 	;stc
  1908 00003619 C3                  <1> 	retn
  1909                              <1> swpout_npts_err:
  1910 0000361A B809000000          <1> 	mov	eax, SWP_NO_PAGE_TO_SWAP_ERR
  1911 0000361F 5B                  <1> 	pop	ebx
  1912 00003620 EBF2                <1> 	jmp	short swpout_err_retn
  1913                              <1> swpout_im_err:
  1914 00003622 B801000000          <1> 	mov	eax, ERR_MINOR_IM ; insufficient (out of) memory
  1915 00003627 EBEB                <1> 	jmp	short swpout_err_retn
  1916                              <1> 
  1917                              <1> swap_queue_shift:
  1918                              <1> 	; 20/07/2015
  1919                              <1> 	; 28/04/2015
  1920                              <1> 	; 18/04/2015
  1921                              <1> 	; 23/10/2014 (Retro UNIX 386 v1 - beginning)
  1922                              <1> 	;
  1923                              <1> 	; INPUT ->
  1924                              <1> 	;	EBX = Virtual (linear) address (bit 12 to 31) 
  1925                              <1> 	;	      and process number combination (bit 0 to 11)
  1926                              <1> 	;	EBX = 0 -> shift/drop from the head (offset 0)
  1927                              <1> 	; OUTPUT ->
  1928                              <1> 	;	If EBX input > 0 
  1929                              <1> 	;	    the queue will be shifted 4 bytes (dword),
  1930                              <1> 	; 	    from the tail to the head, up to entry offset
  1931                              <1> 	; 	    which points to EBX input value or nothing
  1932                              <1> 	;	    to do if EBX value is not found in the queue.
  1933                              <1> 	;	    (The entry -with EBX value- will be removed
  1934                              <1> 	;	     from the queue if it is found.)	
  1935                              <1> 	;	If EBX input = 0
  1936                              <1> 	;	    the queue will be shifted 4 bytes (dword),
  1937                              <1> 	; 	    from the tail to the head, if the PTE address
  1938                              <1> 	;	    in head of the queue is marked as "accessed"
  1939                              <1> 	;	    or it is marked as "non present".
  1940                              <1> 	;	    (If "accessed" flag of the PTE -in the head-
  1941                              <1> 	; 	    is set -to 1-, it will be reset -to 0- and then, 
  1942                              <1> 	;	    the queue will be rotated -without dropping
  1943                              <1> 	; 	    the PTE from the queue-, for 4 bytes on head
  1944                              <1> 	; 	    to tail direction. The PTE in the head will be
  1945                              <1> 	;	    moved in the tail, other PTEs will be shifted on
  1946                              <1> 	;	    head direction.)	
  1947                              <1> 	;
  1948                              <1> 	;	EAX = [swpq_count] (before the shifting)
  1949                              <1> 	;	    (EAX = 0 -> next 'swap_out' stage 
  1950                              <1> 	; 	     is not applicable)	
  1951                              <1> 	;
  1952                              <1> 	; Modified Registers -> EAX
  1953                              <1> 	;
  1954 00003629 0FB705[75C40000]    <1> 	movzx   eax, word [swpq_count]  ; Max. 1024
  1955 00003630 6621C0              <1> 	and	ax, ax
  1956 00003633 7433                <1> 	jz	short swpqs_retn
  1957 00003635 57                  <1> 	push	edi
  1958 00003636 56                  <1> 	push	esi
  1959 00003637 53                  <1> 	push	ebx
  1960 00003638 51                  <1> 	push	ecx
  1961 00003639 50                  <1> 	push	eax
  1962 0000363A BE00E00800          <1> 	mov	esi, swap_queue
  1963 0000363F 89C1                <1> 	mov	ecx, eax
  1964 00003641 09DB                <1> 	or	ebx, ebx
  1965 00003643 7424                <1> 	jz	short swpqs_7
  1966                              <1> swpqs_1:
  1967 00003645 AD                  <1> 	lodsd
  1968 00003646 39D8                <1> 	cmp	eax, ebx
  1969 00003648 7404                <1> 	je	short swpqs_2
  1970 0000364A E2F9                <1> 	loop	swpqs_1
  1971 0000364C EB15                <1> 	jmp	short swpqs_6
  1972                              <1> swpqs_2:
  1973 0000364E 89F7                <1> 	mov	edi, esi
  1974 00003650 83EF04              <1> 	sub 	edi, 4
  1975                              <1> swpqs_3:
  1976 00003653 66FF0D[75C40000]    <1> 	dec	word [swpq_count]
  1977 0000365A 7403                <1> 	jz	short swpqs_5
  1978                              <1> swpqs_4:
  1979 0000365C 49                  <1> 	dec 	ecx
  1980 0000365D F3A5                <1> 	rep	movsd	; shift up (to the head)
  1981                              <1> swpqs_5:
  1982 0000365F 31C0                <1> 	xor	eax, eax
  1983 00003661 8907                <1> 	mov	[edi], eax
  1984                              <1> swpqs_6:
  1985 00003663 58                  <1> 	pop	eax
  1986 00003664 59                  <1> 	pop	ecx
  1987 00003665 5B                  <1> 	pop	ebx
  1988 00003666 5E                  <1> 	pop	esi
  1989 00003667 5F                  <1> 	pop	edi
  1990                              <1> swpqs_retn:
  1991 00003668 C3                  <1> 	retn		
  1992                              <1> swpqs_7:
  1993 00003669 89F7                <1> 	mov	edi, esi ; head
  1994 0000366B AD                  <1> 	lodsd
  1995                              <1> 	; 20/07/2015
  1996 0000366C 89C3                <1> 	mov	ebx, eax
  1997 0000366E 81E300F0FFFF        <1> 	and	ebx, ~PAGE_OFF ; ~0FFFh 
  1998                              <1> 		      ; ebx = virtual address (at page boundary)	
  1999 00003674 25FF0F0000          <1> 	and	eax, PAGE_OFF ; 0FFFh
  2000                              <1> 		      ; ax = process number (1 to 4095)
  2001 00003679 3A05[0FB80000]      <1> 	cmp	al, [u.uno]
  2002                              <1> 		; Max. 16 (nproc) processes for Retro UNIX 386 v1
  2003 0000367F 7507                <1> 	jne	short swpqs_8
  2004 00003681 A1[19B80000]        <1> 	mov	eax, [u.pgdir]
  2005 00003686 EB16                <1> 	jmp	short swpqs_9
  2006                              <1> swpqs_8:
  2007                              <1> 	;shl	ax, 2
  2008 00003688 C0E002              <1> 	shl	al, 2
  2009 0000368B 8B80[50B50000]      <1> 	mov 	eax, [eax+p.upage-4]
  2010 00003691 09C0                <1> 	or	eax, eax
  2011 00003693 74BE                <1> 	jz	short swpqs_3 ; invalid upage
  2012 00003695 83C061              <1> 	add	eax, u.pgdir - user
  2013                              <1> 			 ; u.pgdir value for the process
  2014                              <1> 			 ; is in [eax]
  2015 00003698 8B00                <1> 	mov	eax, [eax]
  2016 0000369A 21C0                <1> 	and	eax, eax
  2017 0000369C 74B5                <1> 	jz	short swpqs_3 ; invalid page directory
  2018                              <1> swpqs_9:
  2019 0000369E 52                  <1> 	push	edx
  2020                              <1> 	; eax = page directory
  2021                              <1> 	; ebx = virtual address
  2022 0000369F E87EFBFFFF          <1> 	call	get_pte
  2023 000036A4 89D3                <1> 	mov	ebx, edx ; PTE address
  2024 000036A6 5A                  <1> 	pop	edx
  2025 000036A7 72AA                <1> 	jc	short swpqs_3 ; empty PDE
  2026                              <1> 	; EAX = PTE value
  2027 000036A9 A801                <1> 	test	al, PTE_A_PRESENT ; bit 0 = 1
  2028 000036AB 74A6                <1> 	jz	short swpqs_3 ; Drop non-present page
  2029                              <1> 			      ; from the queue (head)
  2030 000036AD A802                <1> 	test	al, PTE_A_WRITE	  ; bit 1 = 0
  2031 000036AF 74A2                <1> 	jz	short swpqs_3 ; Drop read only page
  2032                              <1> 			      ; from the queue (head) 	
  2033                              <1> 	;test	al, PTE_A_ACCESS  ; bit 5 = 1 (Accessed)
  2034                              <1> 	;jz	short swpqs_6 ; present
  2035                              <1> 			      ; non-accessed page
  2036 000036B1 0FBAF005            <1>         btr     eax, PTE_A_ACCESS_BIT ; reset 'accessed' bit
  2037 000036B5 73AC                <1> 	jnc	short swpqs_6  ; non-accessed page
  2038 000036B7 8903                <1> 	mov	[ebx], eax     ; save changed attribute
  2039                              <1> 	;
  2040                              <1> 	; Rotation (head -> tail)
  2041 000036B9 49                  <1> 	dec	ecx     ; entry count -> last entry number		
  2042 000036BA 74A7                <1> 	jz	short swpqs_6
  2043                              <1> 		; esi = head + 4
  2044                              <1> 		; edi = head
  2045 000036BC 8B07                <1> 	mov	eax, [edi] ; 20/07/2015
  2046 000036BE F3A5                <1> 	rep	movsd	 ; n = 1 to k-1, [n - 1] = [n]
  2047 000036C0 8907                <1> 	mov	[edi], eax ; head -> tail ; [k] = [1] 		
  2048 000036C2 EB9F                <1> 	jmp	short swpqs_6
  2049                              <1> 
  2050                              <1> add_to_swap_queue:
  2051                              <1> ; temporary - 16/09/2015
  2052 000036C4 C3                  <1> retn
  2053                              <1> 	; 20/07/2015
  2054                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  2055                              <1> 	;
  2056                              <1> 	; Adds new page to swap queue
  2057                              <1> 	; (page directories and page tables must not be added
  2058                              <1> 	; to swap queue)	
  2059                              <1> 	;
  2060                              <1> 	; INPUT ->
  2061                              <1> 	;	EBX = Virtual address (for current process, [u.uno])
  2062                              <1> 	;
  2063                              <1> 	; OUTPUT ->
  2064                              <1> 	;	EAX = [swpq_count]
  2065                              <1> 	;	      (after the PTE has been added)
  2066                              <1> 	;	EAX = 0 -> Swap queue is full, (1024 entries)
  2067                              <1> 	;	      the pte could not be added.
  2068                              <1> 	;
  2069                              <1> 	; Modified Registers -> EAX
  2070                              <1> 	;
  2071 000036C5 53                  <1> 	push	ebx
  2072 000036C6 6681E300F0          <1>         and     bx, ~PAGE_OFF ; ~0FFFh ; reset bits, 0 to 11
  2073 000036CB 8A1D[0FB80000]      <1> 	mov	bl, [u.uno] ; current process number
  2074 000036D1 E853FFFFFF          <1> 	call	swap_queue_shift ; drop from the queue if
  2075                              <1> 				 ; it is already in the queue
  2076                              <1> 		; Then add it to the tail of the queue
  2077 000036D6 0FB705[75C40000]    <1> 	movzx	eax, word [swpq_count]
  2078 000036DD 663D0004            <1> 	cmp	ax, 1024
  2079 000036E1 7205                <1> 	jb	short atsq_1
  2080 000036E3 6629C0              <1> 	sub	ax, ax
  2081 000036E6 5B                  <1> 	pop	ebx
  2082 000036E7 C3                  <1> 	retn
  2083                              <1> atsq_1:
  2084 000036E8 56                  <1> 	push	esi
  2085 000036E9 BE00E00800          <1> 	mov	esi, swap_queue
  2086 000036EE 6621C0              <1> 	and	ax, ax
  2087 000036F1 740A                <1> 	jz	short atsq_2
  2088 000036F3 66C1E002            <1> 	shl	ax, 2	; convert to offset
  2089 000036F7 01C6                <1> 	add	esi, eax
  2090 000036F9 66C1E802            <1> 	shr	ax, 2
  2091                              <1> atsq_2:
  2092 000036FD 6640                <1> 	inc	ax
  2093 000036FF 891E                <1> 	mov	[esi], ebx ; Virtual address + [u.uno] combination
  2094 00003701 66A3[75C40000]      <1> 	mov	[swpq_count], ax
  2095 00003707 5E                  <1> 	pop	esi
  2096 00003708 5B                  <1> 	pop	ebx
  2097 00003709 C3                  <1> 	retn
  2098                              <1> 
  2099                              <1> unlink_swap_block:
  2100                              <1> 	; 15/09/2015
  2101                              <1> 	; 30/04/2015
  2102                              <1> 	; 18/04/2015
  2103                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  2104                              <1> 	;
  2105                              <1> 	; INPUT -> 
  2106                              <1> 	;	EAX = swap disk/file offset address
  2107                              <1> 	;	      (bit 1 to bit 31)
  2108                              <1> 	; OUTPUT ->
  2109                              <1> 	;	[swpd_free] is increased
  2110                              <1> 	;	(corresponding SWAP DISK ALLOC. TABLE bit is SET)
  2111                              <1> 	;
  2112                              <1> 	; Modified Registers -> EAX
  2113                              <1> 	;
  2114 0000370A 53                  <1> 	push	ebx
  2115 0000370B 52                  <1> 	push	edx
  2116                              <1> 	;
  2117 0000370C C1E804              <1> 	shr	eax, SECTOR_SHIFT+1  ;3+1 ; shift sector address to 
  2118                              <1> 				     ; 3 bits right
  2119                              <1> 				     ; to get swap block/page number
  2120 0000370F 89C2                <1> 	mov	edx, eax
  2121                              <1> 	; 15/09/2015
  2122 00003711 C1EA03              <1> 	shr	edx, 3		     ; to get offset to S.A.T.
  2123                              <1> 				     ; (1 allocation bit = 1 page)
  2124                              <1> 				     ; (1 allocation bytes = 8 pages)
  2125 00003714 80E2FC              <1> 	and	dl, 0FCh 	     ; clear lower 2 bits
  2126                              <1> 				     ; (to get 32 bit position)			
  2127                              <1> 	;
  2128 00003717 BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table address
  2129 0000371C 01D3                <1> 	add	ebx, edx
  2130 0000371E 83E01F              <1> 	and	eax, 1Fh	     ; lower 5 bits only
  2131                              <1> 				     ; (allocation bit position)	 
  2132 00003721 3B05[83C40000]      <1> 	cmp 	eax, [swpd_next]     ; is the new free block addr. lower
  2133                              <1> 				     ; than the address in 'swpd_next' ?
  2134                              <1> 				     ; (next/first free block value)		
  2135 00003727 7305                <1> 	jnb	short uswpbl_1	     ; no	
  2136 00003729 A3[83C40000]        <1> 	mov	[swpd_next], eax     ; yes	
  2137                              <1> uswpbl_1:
  2138 0000372E 0FAB03              <1> 	bts	[ebx], eax	     ; unlink/release/deallocate block
  2139                              <1> 				     ; set relevant bit to 1.
  2140                              <1> 				     ; set CF to the previous bit value	
  2141 00003731 F5                  <1> 	cmc			     ; complement carry flag	
  2142 00003732 7206                <1> 	jc	short uswpbl_2	     ; do not increase swfd_free count
  2143                              <1> 				     ; if the block is already deallocated
  2144                              <1> 				     ; before.	
  2145 00003734 FF05[7FC40000]      <1>         inc     dword [swpd_free]
  2146                              <1> uswpbl_2:
  2147 0000373A 5A                  <1> 	pop	edx
  2148 0000373B 5B                  <1> 	pop	ebx
  2149 0000373C C3                  <1> 	retn
  2150                              <1> 
  2151                              <1> link_swap_block:
  2152                              <1> 	; 01/07/2015
  2153                              <1> 	; 18/04/2015
  2154                              <1> 	; 24/10/2014 (Retro UNIX 386 v1 - beginning)
  2155                              <1> 	;
  2156                              <1> 	; INPUT -> none
  2157                              <1> 	;
  2158                              <1> 	; OUTPUT ->
  2159                              <1> 	;	EAX = OFFSET ADDRESS OF THE ALLOCATED BLOCK (4096 bytes)
  2160                              <1> 	;	      in sectors (corresponding 
  2161                              <1> 	;	      SWAP DISK ALLOCATION TABLE bit is RESET)
  2162                              <1> 	;
  2163                              <1> 	;	CF = 1 and EAX = 0 
  2164                              <1> 	; 		   if there is not a free block to be allocated	
  2165                              <1> 	;
  2166                              <1> 	; Modified Registers -> none (except EAX)
  2167                              <1> 	;
  2168                              <1> 
  2169                              <1> 	;mov	eax, [swpd_free]
  2170                              <1> 	;and	eax, eax
  2171                              <1> 	;jz	short out_of_swpspc
  2172                              <1> 	;
  2173 0000373D 53                  <1> 	push	ebx
  2174 0000373E 51                  <1> 	push	ecx
  2175                              <1> 	;
  2176 0000373F BB00000D00          <1> 	mov	ebx, swap_alloc_table ; Swap Allocation Table offset
  2177 00003744 89D9                <1> 	mov	ecx, ebx
  2178 00003746 031D[83C40000]      <1> 	add	ebx, [swpd_next] ; Free block searching starts from here
  2179                              <1> 				 ; next_free_swap_block >> 5
  2180 0000374C 030D[87C40000]      <1> 	add	ecx, [swpd_last] ; Free block searching ends here
  2181                              <1> 				 ; (total_swap_blocks - 1) >> 5
  2182                              <1> lswbl_scan:
  2183 00003752 39CB                <1> 	cmp	ebx, ecx
  2184 00003754 770A                <1> 	ja	short lswbl_notfound
  2185                              <1> 	;
  2186 00003756 0FBC03              <1> 	bsf	eax, [ebx] ; Scans source operand for first bit set (1).
  2187                              <1> 			   ; Clears ZF if a bit is found set (1) and 
  2188                              <1> 			   ; loads the destination with an index to
  2189                              <1> 			   ; first set bit. (0 -> 31) 
  2190                              <1> 			   ; Sets ZF to 1 if no bits are found set.
  2191                              <1> 	; 01/07/2015
  2192 00003759 751C                <1> 	jnz	short lswbl_found ; ZF = 0 -> a free block has been found
  2193                              <1> 			 ;
  2194                              <1> 			 ; NOTE:  a Swap Disk Allocation Table bit 
  2195                              <1> 			 ;	  with value of 1 means 
  2196                              <1> 			 ;	  the corresponding page is free 
  2197                              <1> 			 ;	  (Retro UNIX 386 v1 feaure only!)
  2198 0000375B 83C304              <1> 	add	ebx, 4
  2199                              <1> 			 ; We return back for searching next page block
  2200                              <1> 			 ; NOTE: [swpd_free] is not ZERO; so, 
  2201                              <1> 			 ;	 we always will find at least 1 free block here.
  2202 0000375E EBF2                <1> 	jmp    	short lswbl_scan
  2203                              <1> 	;
  2204                              <1> lswbl_notfound:	
  2205 00003760 81E900000D00        <1> 	sub	ecx, swap_alloc_table
  2206 00003766 890D[83C40000]      <1> 	mov	[swpd_next], ecx ; next/first free page = last page 
  2207                              <1> 				 ; (unlink_swap_block procedure will change it)
  2208 0000376C 31C0                <1> 	xor	eax, eax
  2209 0000376E A3[7FC40000]        <1> 	mov	[swpd_free], eax
  2210 00003773 F9                  <1> 	stc
  2211                              <1> lswbl_ok:
  2212 00003774 59                  <1> 	pop	ecx
  2213 00003775 5B                  <1> 	pop	ebx
  2214 00003776 C3                  <1> 	retn
  2215                              <1> 	;
  2216                              <1> ;out_of_swpspc:
  2217                              <1> ;	stc
  2218                              <1> ;	retn
  2219                              <1> 
  2220                              <1> lswbl_found:
  2221 00003777 89D9                <1> 	mov	ecx, ebx
  2222 00003779 81E900000D00        <1> 	sub	ecx, swap_alloc_table
  2223 0000377F 890D[83C40000]      <1> 	mov	[swpd_next], ecx ; Set first free block searching start
  2224                              <1> 				 ; address/offset (to the next)
  2225 00003785 FF0D[7FC40000]      <1>         dec     dword [swpd_free] ; 1 block has been allocated (X = X-1) 
  2226                              <1> 	;
  2227 0000378B 0FB303              <1> 	btr	[ebx], eax	 ; The destination bit indexed by the source value
  2228                              <1> 				 ; is copied into the Carry Flag and then cleared
  2229                              <1> 				 ; in the destination.
  2230                              <1> 				 ;
  2231                              <1> 				 ; Reset the bit which is corresponding to the 
  2232                              <1> 				 ; (just) allocated block.
  2233 0000378E C1E105              <1> 	shl	ecx, 5		 ; (block offset * 32) + block index
  2234 00003791 01C8                <1> 	add	eax, ecx	 ; = block number
  2235 00003793 C1E003              <1> 	shl	eax, SECTOR_SHIFT ; 3, sector (offset) address of the block
  2236                              <1> 				 ; 1 block =  8 sectors
  2237                              <1> 	;
  2238                              <1> 	; EAX = offset address of swap disk/file sector (beginning of the block)
  2239                              <1> 	;
  2240                              <1> 	; NOTE: The relevant page table entry will be updated
  2241                              <1> 	;       according to this EAX value...
  2242                              <1> 	;
  2243 00003796 EBDC                <1> 	jmp	short lswbl_ok
  2244                              <1> 
  2245                              <1> logical_disk_read:
  2246                              <1> 	; 20/07/2015
  2247                              <1> 	; 09/03/2015 (temporary code here)
  2248                              <1> 	;
  2249                              <1> 	; INPUT ->
  2250                              <1> 	; 	ESI = Logical disk description table address
  2251                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
  2252                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
  2253                              <1> 	; 	ECX = Sector count
  2254                              <1> 	;
  2255                              <1> 	;
  2256 00003798 C3                  <1> 	retn
  2257                              <1> 
  2258                              <1> logical_disk_write:
  2259                              <1> 	; 20/07/2015
  2260                              <1> 	; 09/03/2015 (temporary code here)
  2261                              <1> 	;
  2262                              <1> 	; INPUT ->
  2263                              <1> 	; 	ESI = Logical disk description table address
  2264                              <1> 	; 	EBX = Memory page (buffer) address (physical!)
  2265                              <1> 	; 	EAX = Sector adress (offset address, logical sector number)
  2266                              <1> 	; 	ECX = Sector count
  2267                              <1> 	;
  2268 00003799 C3                  <1> 	retn
  2269                              <1> 
  2270                              <1> get_physical_addr:
  2271                              <1> 	; 18/10/2015
  2272                              <1> 	; 29/07/2015
  2273                              <1> 	; 20/07/2015
  2274                              <1> 	; 04/06/2015
  2275                              <1> 	; 20/05/2015
  2276                              <1> 	; 28/04/2015
  2277                              <1> 	; 18/04/2015
  2278                              <1> 	; Get physical address
  2279                              <1> 	;     (allocates a new page for user if it is not present)
  2280                              <1> 	;	
  2281                              <1> 	; (This subroutine is needed for mapping user's virtual 
  2282                              <1> 	; (buffer) address to physical address (of the buffer).)
  2283                              <1> 	; ('sys write', 'sys read' system calls...)
  2284                              <1> 	;
  2285                              <1> 	; INPUT ->
  2286                              <1> 	;	EBX = virtual address
  2287                              <1> 	;	u.pgdir = page directory (physical) address
  2288                              <1> 	;
  2289                              <1> 	; OUTPUT ->
  2290                              <1> 	;	EAX = physical address 
  2291                              <1> 	;	EBX = linear address	
  2292                              <1> 	;	EDX = physical address of the page frame
  2293                              <1> 	;	      (with attribute bits)
  2294                              <1> 	;	ECX = byte count within the page frame
  2295                              <1> 	;
  2296                              <1> 	; Modified Registers -> EAX, EBX, ECX, EDX
  2297                              <1> 	;
  2298 0000379A 81C300004000        <1> 	add	ebx, CORE ; 18/10/2015
  2299                              <1> 	;
  2300 000037A0 A1[19B80000]        <1> 	mov	eax, [u.pgdir]
  2301 000037A5 E878FAFFFF          <1> 	call	get_pte
  2302                              <1> 		; EDX = Page table entry address (if CF=0)
  2303                              <1> 	        ;       Page directory entry address (if CF=1)
  2304                              <1> 		;       (Bit 0 value is 0 if PT is not present)
  2305                              <1> 		; EAX = Page table entry value (page address)
  2306                              <1> 		;	CF = 1 -> PDE not present or invalid ? 
  2307 000037AA 731C                <1> 	jnc	short gpa_1
  2308                              <1> 	;
  2309 000037AC E856F9FFFF          <1> 	call	allocate_page
  2310 000037B1 725B                <1> 	jc	short gpa_im_err  ; 'insufficient memory' error
  2311                              <1> gpa_0:
  2312 000037B3 E8C9F9FFFF          <1> 	call 	clear_page
  2313                              <1> 	; EAX = Physical (base) address of the allocated (new) page
  2314 000037B8 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER ; 4+2+1 = 7
  2315                              <1> 			   ; lower 3 bits are used as U/S, R/W, P flags
  2316                              <1> 			   ; (user, writable, present page)	
  2317 000037BA 8902                <1> 	mov	[edx], eax ; Let's put the new page directory entry here !
  2318 000037BC A1[19B80000]        <1> 	mov	eax, [u.pgdir]	
  2319 000037C1 E85CFAFFFF          <1> 	call	get_pte
  2320 000037C6 7246                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
  2321                              <1> gpa_1:
  2322                              <1> 	; EAX = PTE value, EDX = PTE address
  2323 000037C8 A801                <1> 	test 	al, PTE_A_PRESENT
  2324 000037CA 751A                <1> 	jnz	short gpa_3
  2325 000037CC 09C0                <1> 	or	eax, eax
  2326 000037CE 7430                <1> 	jz	short gpa_4  ; Allocate a new page
  2327                              <1> 	; 20/07/2015
  2328 000037D0 55                  <1> 	push	ebp
  2329 000037D1 89DD                <1> 	mov	ebp, ebx ; virtual (linear) address
  2330                              <1> 	; reload swapped page
  2331 000037D3 E83C000000          <1> 	call	reload_page ; 28/04/2015
  2332 000037D8 5D                  <1> 	pop	ebp
  2333 000037D9 7224                <1> 	jc	short gpa_retn
  2334                              <1> gpa_2:
  2335                              <1> 	; 20/07/2015
  2336                              <1> 	; 20/05/2015
  2337                              <1> 	; add this page to swap queue
  2338 000037DB 50                  <1> 	push	eax 
  2339                              <1> 	; EBX = virtual address
  2340 000037DC E8E3FEFFFF          <1> 	call 	add_to_swap_queue
  2341 000037E1 58                  <1> 	pop	eax
  2342                              <1> 		; PTE address in EDX
  2343                              <1> 		; virtual address in EBX
  2344                              <1> 	; EAX = memory page address
  2345 000037E2 0C07                <1> 	or	al, PTE_A_PRESENT + PTE_A_USER + PTE_A_WRITE
  2346                              <1> 				  ; present flag, bit 0 = 1
  2347                              <1> 				  ; user flag, bit 2 = 1	
  2348                              <1> 				  ; writable flag, bit 1 = 1
  2349 000037E4 8902                <1> 	mov	[edx], eax  ; Update PTE value
  2350                              <1> gpa_3:
  2351                              <1> 	; 18/10/2015
  2352 000037E6 89D9                <1> 	mov	ecx, ebx
  2353 000037E8 81E1FF0F0000        <1> 	and	ecx, PAGE_OFF
  2354 000037EE 89C2                <1> 	mov 	edx, eax
  2355 000037F0 662500F0            <1> 	and	ax, PTE_A_CLEAR
  2356 000037F4 01C8                <1> 	add	eax, ecx
  2357 000037F6 F7D9                <1> 	neg	ecx ; 1 -> -1 (0FFFFFFFFh), 4095 (0FFFh) -> -4095
  2358 000037F8 81C100100000        <1> 	add	ecx, PAGE_SIZE
  2359 000037FE F8                  <1> 	clc
  2360                              <1> gpa_retn:
  2361 000037FF C3                  <1> 	retn	
  2362                              <1> gpa_4:	
  2363 00003800 E802F9FFFF          <1> 	call	allocate_page
  2364 00003805 7207                <1> 	jc	short gpa_im_err ; 'insufficient memory' error
  2365 00003807 E875F9FFFF          <1> 	call	clear_page
  2366 0000380C EBCD                <1> 	jmp	short gpa_2
  2367                              <1> 
  2368                              <1> gpa_im_err:	
  2369 0000380E B801000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
  2370                              <1> 				  ; Major error = 0 (No protection fault)	
  2371 00003813 C3                  <1> 	retn
  2372                              <1> 
  2373                              <1> reload_page:
  2374                              <1> 	; 20/07/2015
  2375                              <1> 	; 28/04/2015 (Retro UNIX 386 v1 - beginning)
  2376                              <1> 	;
  2377                              <1> 	; Reload (Restore) swapped page at memory
  2378                              <1> 	;
  2379                              <1> 	; INPUT -> 
  2380                              <1> 	;	EBP = Virtual (linear) memory address
  2381                              <1> 	;	EAX = PTE value (swap disk sector address)
  2382                              <1> 	;	(Swap disk sector address = bit 1 to bit 31 of EAX)	
  2383                              <1> 	; OUTPUT ->
  2384                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS OF RELOADED PAGE
  2385                              <1> 	;
  2386                              <1> 	;	CF = 1 and EAX = error code
  2387                              <1> 	;
  2388                              <1> 	; Modified Registers -> none (except EAX)
  2389                              <1> 	;
  2390 00003814 D1E8                <1> 	shr	eax, 1   ; Convert PTE value to swap disk address 
  2391 00003816 53                  <1> 	push	ebx      ;
  2392 00003817 89C3                <1> 	mov	ebx, eax ; Swap disk (offset) address	
  2393 00003819 E8E9F8FFFF          <1> 	call	allocate_page
  2394 0000381E 720C                <1> 	jc	short rlp_im_err
  2395 00003820 93                  <1> 	xchg 	eax, ebx	
  2396                              <1> 	; EBX = Physical memory (page) address
  2397                              <1> 	; EAX = Swap disk (offset) address
  2398                              <1> 	; EBP = Virtual (linear) memory address
  2399 00003821 E81AFDFFFF          <1> 	call	swap_in
  2400 00003826 720B                <1> 	jc	short rlp_swp_err  ; (swap disk/file read error)
  2401 00003828 89D8                <1> 	mov	eax, ebx	
  2402                              <1> rlp_retn:
  2403 0000382A 5B                  <1> 	pop	ebx
  2404 0000382B C3                  <1> 	retn
  2405                              <1> 	
  2406                              <1> rlp_im_err:	
  2407 0000382C B801000000          <1> 	mov	eax, ERR_MINOR_IM ; Insufficient memory (minor) error!
  2408                              <1> 				  ; Major error = 0 (No protection fault)	
  2409 00003831 EBF7                <1> 	jmp	short rlp_retn
  2410                              <1> 
  2411                              <1> rlp_swp_err:
  2412 00003833 B804000000          <1> 	mov 	eax, SWP_DISK_READ_ERR ; Swap disk read error !
  2413 00003838 EBF0                <1> 	jmp	short rlp_retn
  2414                              <1> 
  2415                              <1> 
  2416                              <1> copy_page_dir:
  2417                              <1> 	; 19/09/2015
  2418                              <1> 	; temporary - 07/09/2015
  2419                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
  2420                              <1> 	;
  2421                              <1> 	; INPUT -> 
  2422                              <1> 	;	[u.pgdir] = PHYSICAL (real/flat) ADDRESS of the parent's
  2423                              <1> 	;		    page directory.
  2424                              <1> 	; OUTPUT ->
  2425                              <1> 	;	EAX =  PHYSICAL (real/flat) ADDRESS of the child's
  2426                              <1> 	;	       page directory.
  2427                              <1> 	;	(New page directory with new page table entries.)
  2428                              <1> 	;	(New page tables with read only copies of the parent's
  2429                              <1> 	;	pages.)
  2430                              <1> 	;	EAX = 0 -> Error (CF = 1)
  2431                              <1> 	;
  2432                              <1> 	; Modified Registers -> none (except EAX)
  2433                              <1> 	;
  2434 0000383A E8C8F8FFFF          <1> 	call	allocate_page
  2435 0000383F 723E                <1> 	jc	short cpd_err
  2436                              <1> 	;
  2437 00003841 55                  <1> 	push	ebp ; 20/07/2015
  2438 00003842 56                  <1> 	push	esi
  2439 00003843 57                  <1> 	push	edi
  2440 00003844 53                  <1> 	push	ebx
  2441 00003845 51                  <1> 	push	ecx
  2442 00003846 8B35[19B80000]      <1> 	mov	esi, [u.pgdir]
  2443 0000384C 89C7                <1> 	mov	edi, eax
  2444 0000384E 50                  <1> 	push	eax ; save child's page directory address
  2445                              <1> 	; copy PDE 0 from the parent's page dir to the child's page dir
  2446                              <1> 	; (use same system space for all user page tables) 
  2447 0000384F A5                  <1> 	movsd
  2448 00003850 BD00004000          <1> 	mov	ebp, 1024*4096 ; pass the 1st 4MB (system space)
  2449 00003855 B9FF030000          <1> 	mov	ecx, (PAGE_SIZE / 4) - 1 ; 1023
  2450                              <1> cpd_0:	
  2451 0000385A AD                  <1> 	lodsd
  2452                              <1> 	;or	eax, eax
  2453                              <1>         ;jnz     short cpd_1
  2454 0000385B A801                <1> 	test	al, PDE_A_PRESENT ;  bit 0 =  1
  2455 0000385D 7508                <1> 	jnz	short cpd_1
  2456                              <1>  	; (virtual address at the end of the page table)	
  2457 0000385F 81C500004000        <1> 	add	ebp, 1024*4096 ; page size * PTE count
  2458 00003865 EB0F                <1> 	jmp	short cpd_2
  2459                              <1> cpd_1:	
  2460 00003867 662500F0            <1> 	and	ax, PDE_A_CLEAR ; 0F000h ; clear attribute bits
  2461 0000386B 89C3                <1> 	mov	ebx, eax
  2462                              <1> 	; EBX = Parent's page table address
  2463 0000386D E81F000000          <1> 	call	copy_page_table
  2464 00003872 720C                <1> 	jc	short cpd_p_err
  2465                              <1> 	; EAX = Child's page table address
  2466 00003874 0C07                <1> 	or	al, PDE_A_PRESENT + PDE_A_WRITE + PDE_A_USER
  2467                              <1> 			 ; set bit 0, bit 1 and bit 2 to 1
  2468                              <1> 			 ; (present, writable, user)
  2469                              <1> cpd_2:
  2470 00003876 AB                  <1> 	stosd
  2471 00003877 E2E1                <1> 	loop	cpd_0
  2472                              <1> 	;
  2473 00003879 58                  <1> 	pop	eax  ; restore child's page directory address
  2474                              <1> cpd_3:
  2475 0000387A 59                  <1> 	pop	ecx
  2476 0000387B 5B                  <1> 	pop	ebx
  2477 0000387C 5F                  <1> 	pop	edi
  2478 0000387D 5E                  <1> 	pop	esi
  2479 0000387E 5D                  <1> 	pop	ebp
  2480                              <1> cpd_err:
  2481 0000387F C3                  <1> 	retn
  2482                              <1> cpd_p_err:
  2483                              <1> 	; release the allocated pages missing (recover free space)
  2484 00003880 58                  <1> 	pop	eax  ; the new page directory address (physical)
  2485 00003881 8B1D[19B80000]      <1> 	mov	ebx, [u.pgdir] ; parent's page directory address 
  2486 00003887 E8B4F9FFFF          <1> 	call 	deallocate_page_dir
  2487 0000388C 29C0                <1> 	sub	eax, eax ; 0
  2488 0000388E F9                  <1> 	stc
  2489 0000388F EBE9                <1> 	jmp	short cpd_3	
  2490                              <1> 
  2491                              <1> copy_page_table:
  2492                              <1> 	; 19/09/2015
  2493                              <1> 	; temporary - 07/09/2015
  2494                              <1> 	; 07/09/2015 (Retro UNIX 386 v1 - beginning)
  2495                              <1> 	;
  2496                              <1> 	; INPUT -> 
  2497                              <1> 	;	EBX = PHYSICAL (real/flat) ADDRESS of the parent's page table.
  2498                              <1> 	;	EBP = page table entry index (from 'copy_page_dir')
  2499                              <1> 	; OUTPUT ->
  2500                              <1> 	;	EAX = PHYSICAL (real/flat) ADDRESS of the child's page table.
  2501                              <1> 	;	EBP = (recent) page table index (for 'add_to_swap_queue')	
  2502                              <1> 	;	CF = 1 -> error 
  2503                              <1> 	;
  2504                              <1> 	; Modified Registers -> EBP (except EAX)
  2505                              <1> 	;
  2506 00003891 E871F8FFFF          <1> 	call	allocate_page
  2507 00003896 725A                <1> 	jc	short cpt_err
  2508                              <1> 	;
  2509 00003898 50                  <1> 	push	eax ; *
  2510                              <1> 	;push 	ebx
  2511 00003899 56                  <1> 	push	esi
  2512 0000389A 57                  <1> 	push	edi
  2513 0000389B 52                  <1> 	push	edx
  2514 0000389C 51                  <1> 	push	ecx
  2515                              <1> 	;
  2516 0000389D 89DE                <1> 	mov	esi, ebx
  2517 0000389F 89C7                <1> 	mov	edi, eax
  2518 000038A1 89C2                <1> 	mov	edx, eax
  2519 000038A3 81C200100000        <1> 	add	edx, PAGE_SIZE 	
  2520                              <1> cpt_0:
  2521 000038A9 AD                  <1> 	lodsd
  2522 000038AA A801                <1> 	test	al, PTE_A_PRESENT ;  bit 0 =  1
  2523 000038AC 750B                <1> 	jnz	short cpt_1
  2524 000038AE 21C0                <1> 	and	eax, eax
  2525 000038B0 7430                <1> 	jz	short cpt_2
  2526                              <1> 	; ebp = virtual (linear) address of the memory page
  2527 000038B2 E85DFFFFFF          <1> 	call	reload_page ; 28/04/2015
  2528 000038B7 7234                <1> 	jc	short cpt_p_err
  2529                              <1> cpt_1:
  2530 000038B9 662500F0            <1> 	and	ax, PTE_A_CLEAR ; 0F000h ; clear attribute bits
  2531 000038BD 89C1                <1> 	mov	ecx, eax
  2532                              <1> 	; Allocate a new page for the child process
  2533 000038BF E843F8FFFF          <1> 	call	allocate_page
  2534 000038C4 7227                <1> 	jc	short cpt_p_err
  2535 000038C6 57                  <1> 	push	edi
  2536 000038C7 56                  <1> 	push	esi
  2537 000038C8 89CE                <1> 	mov	esi, ecx
  2538 000038CA 89C7                <1> 	mov	edi, eax
  2539 000038CC B900040000          <1> 	mov	ecx, PAGE_SIZE/4
  2540 000038D1 F3A5                <1> 	rep	movsd	; copy page (4096 bytes)
  2541 000038D3 5E                  <1> 	pop	esi
  2542 000038D4 5F                  <1> 	pop	edi
  2543                              <1> 	; 
  2544 000038D5 53                  <1> 	push	ebx
  2545 000038D6 50                  <1> 	push	eax
  2546 000038D7 89EB                <1> 	mov	ebx, ebp
  2547                              <1> 	; ebx = virtual address of the memory page
  2548 000038D9 E8E6FDFFFF          <1> 	call	add_to_swap_queue
  2549 000038DE 58                  <1> 	pop	eax
  2550 000038DF 5B                  <1> 	pop	ebx
  2551                              <1> 	;
  2552                              <1> 	;or	ax, PTE_A_USER+PTE_A_PRESENT 
  2553 000038E0 0C07                <1> 	or	al, PTE_A_USER+PTE_A_WRITE+PTE_A_PRESENT 
  2554                              <1> cpt_2:
  2555 000038E2 AB                  <1> 	stosd  ; EDI points to child's PTE  	 
  2556                              <1> 	;
  2557 000038E3 81C500100000        <1> 	add	ebp, 4096 ; 20/07/2015 (next page)
  2558                              <1> 	;
  2559 000038E9 39D7                <1> 	cmp	edi, edx
  2560 000038EB 72BC                <1> 	jb	short cpt_0
  2561                              <1> cpt_p_err:
  2562 000038ED 59                  <1> 	pop	ecx
  2563 000038EE 5A                  <1> 	pop	edx
  2564 000038EF 5F                  <1> 	pop	edi
  2565 000038F0 5E                  <1> 	pop	esi
  2566                              <1> 	;pop	ebx
  2567 000038F1 58                  <1> 	pop	eax ; *
  2568                              <1> cpt_err:
  2569 000038F2 C3                  <1> 	retn
  2570                              <1> 
  2571                              <1> 
  2572                              <1> ; /// End Of MEMORY MANAGEMENT FUNCTIONS ///
  2573                              <1> 
  2574                              <1> ;; Data:
  2575                              <1> 
  2576                              <1> ; 09/03/2015
  2577                              <1> ;swpq_count: dw 0 ; count of pages on the swap que
  2578                              <1> ;swp_drv:    dd 0 ; logical drive description table address of the swap drive/disk
  2579                              <1> ;swpd_size:  dd 0 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
  2580                              <1> ;swpd_free:  dd 0 ; free page blocks (4096 bytes) on swap disk/drive (logical)
  2581                              <1> ;swpd_next:  dd 0 ; next free page block
  2582                              <1> ;swpd_last:  dd 0 ; last swap page block		 		
  1910                                  %include 'timer.s'   ; 17/01/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - timer.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 29/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> ;
    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 000038F3 9C                  <1> 	pushfd
    30 000038F4 0E                  <1> 	push 	cs
    31 000038F5 E801000000          <1> 	call 	TIME_OF_DAY_1
    32 000038FA C3                  <1> 	retn
    33                              <1> 
    34                              <1> ;--- INT  1A H -- (TIME OF DAY) -------------------------------------------------
    35                              <1> ;       THIS BIOS ROUTINE ALLOWS THE CLOCKS TO BE SET OR READ			:
    36                              <1> ;										:
    37                              <1> ; PARAMETERS:									:
    38                              <1> ;     (AH) = 00H  READ THE CURRENT SETTING AND RETURN WITH,			:
    39                              <1> ;                      (CX) = HIGH PORTION OF COUNT				:
    40                              <1> ;                      (DX) = LOW PORTION OF COUNT				:
    41                              <1> ;                      (AL) = 0 TIMER HAS NOT PASSED 24 HOURS SINCE LAST READ	:
    42                              <1> ;                             1 IF ON ANOTHER DAY. (RESET TO ZERO AFTER READ)	:
    43                              <1> ;										:
    44                              <1> ;     (AH) = 01H  SET THE CURRENT CLOCK USING,					:
    45                              <1> ;		     (CX) = HIGH PORTION OF COUNT				:
    46                              <1> ;		     (DX) = LOW PORTION OF COUNT.				:
    47                              <1> ;										:
    48                              <1> ;               NOTE: COUNTS OCCUR AT THE RATE OF 1193180/65536 COUNTS/SECOND	:
    49                              <1> ;                            (OR ABOUT 18.2 PER SECOND -- SEE EQUATES)		:
    50                              <1> ;										:
    51                              <1> ;     (AH) = 02H  READ THE REAL TIME CLOCK AND RETURN WITH,			:
    52                              <1> ;                      (CH) = HOURS IN BCD (00-23)				:
    53                              <1> ;                      (CL) = MINUTES IN BCD (00-59)				:
    54                              <1> ;                      (DH) = SECONDS IN BCD (00-59)				:
    55                              <1> ;                      (DL) = DAYLIGHT SAVINGS ENABLE (00-01)			:
    56                              <1> ;										:
    57                              <1> ;     (AH) = 03H  SET THE REAL TIME CLOCK USING,				:
    58                              <1> ;                     (CH) = HOURS IN BCD (00-23)				:
    59                              <1> ;                     (CL) = MINUTES IN BCD (00-59)				:
    60                              <1> ;                     (DH) = SECONDS IN BCD (00-59)				:
    61                              <1> ;                     (DL) = 01 IF DAYLIGHT SAVINGS ENABLE OPTION, ELSE 00.	:
    62                              <1> ;										:
    63                              <1> ;             NOTE: (DL) = 00 IF DAYLIGHT SAVINGS TIME ENABLE IS NOT ENABLED.	:
    64                              <1> ;                   (DL) = 01 ENABLES TWO SPECIAL UPDATES THE LAST SUNDAY IN	:
    65                              <1> ;	           APRIL   (1:59:59 --> 3:00:00 AM) AND THE LAST SUNDAY IN	:
    66                              <1> ;                   OCTOBER (1:59:59 --> 1:00:00 AM) THE FIRST TIME.		:
    67                              <1> ;										:
    68                              <1> ;     (AH) = 04H  READ THE DATE FROM THE REAL TIME CLOCK AND RETURN WITH,	:
    69                              <1> ;                      (CH) = CENTURY IN BCD (19 OR 20)				:
    70                              <1> ;                      (CL) = YEAR IN BCD (00-99)				:
    71                              <1> ;                      (DH) = MONTH IN BCD (01-12)				:
    72                              <1> ;                      (DL) = DAY IN BCD (01-31).				:
    73                              <1> ;										:
    74                              <1> ;     (AH) = 05H  SET THE DATE INTO THE REAL TIME CLOCK USING,			:
    75                              <1> ;                     (CH) = CENTURY IN BCD (19 OR 20)				:
    76                              <1> ;                     (CL) = YEAR IN BCD (00-99)				:
    77                              <1> ;                     (DH) = MONTH IN BCD (01-12)				:
    78                              <1> ;                     (DL) = DAY IN BCD (01-31).				:
    79                              <1> ;										:
    80                              <1> ;     (AH) = 06H  SET THE ALARM TO INTERRUPT AT SPECIFIED TIME,			:
    81                              <1> ;                     (CH) = HOURS IN BCD (00-23 (OR FFH))			:
    82                              <1> ;                     (CL) = MINUTES IN BCD (00-59 (OR FFH))			:
    83                              <1> ;                     (DH) = SECONDS IN BCD (00-59 (OR FFH))			:
    84                              <1> ;										:
    85                              <1> ;     (AH) = 07H  RESET THE ALARM INTERRUPT FUNCTION.				:
    86                              <1> ;										:
    87                              <1> ; NOTES: FOR ALL RETURNS CY= 0 FOR SUCCESSFUL OPERATION.			:
    88                              <1> ;        FOR (AH)= 2, 4, 6 - CARRY FLAG SET IF REAL TIME CLOCK NOT OPERATING.	:
    89                              <1> ;        FOR (AH)= 6 - CARRY FLAG SET IF ALARM ALREADY ENABLED. 		:
    90                              <1> ;        FOR THE ALARM FUNCTION (AH = 6) THE USER MUST SUPPLY A ROUTINE AND	:
    91                              <1> ;         INTERCEPT THE CORRECT ADDRESS IN THE VECTOR TABLE FOR INTERRUPT 4AH.	:
    92                              <1> ;         USE 0FFH FOR ANY "DO NOT CARE" POSITION FOR INTERVAL INTERRUPTS.	:
    93                              <1> ;        INTERRUPTS ARE DISABLED DURING DATA MODIFICATION. 			:
    94                              <1> ;        AH & AL ARE RETURNED MODIFIED AND NOT DEFINED EXCEPT WHERE INDICATED.	:
    95                              <1> ;--------------------------------------------------------------------------------
    96                              <1> 
    97                              <1> ; 29/01/2016
    98                              <1> ; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
    99                              <1> 
   100                              <1> TIME_OF_DAY_1:
   101 000038FB FB                  <1> 	sti				; INTERRUPTS BACK ON
   102 000038FC 80FC08              <1> 	cmp	ah, (RTC_TBE-RTC_TB)/4	; CHECK IF COMMAND IN VALID RANGE (0-7)
   103 000038FF F5                  <1> 	cmc				; COMPLEMENT CARRY FOR ERROR EXIT
   104 00003900 721A                <1> 	jc	short TIME_9		; EXIT WITH CARRY = 1 IF NOT VALID
   105                              <1> 
   106 00003902 1E                  <1> 	push	ds
   107 00003903 56                  <1> 	push	esi
   108 00003904 66BE1000            <1> 	mov	si, KDATA		; kernel data segment
   109 00003908 8EDE                <1> 	mov	ds, si
   110 0000390A C0E402              <1> 	shl	ah, 2			; convert function to dword offset
   111 0000390D 0FB6F4              <1> 	movzx	esi, ah			; PLACE INTO ADDRESSING REGISTER
   112 00003910 FA                  <1> 	cli				; NO INTERRUPTS DURING TIME FUNCTIONS
   113 00003911 FF96[1F390000]      <1> 	call	[esi+RTC_TB]		; VECTOR TO FUNCTION REQUESTED WITH CY=0
   114                              <1> 					; RETURN WITH CARRY FLAG SET FOR RESULT
   115 00003917 FB                  <1> 	sti				; INTERRUPTS BACK ON
   116 00003918 B400                <1> 	mov	ah, 0			; CLEAR (AH) TO ZERO
   117 0000391A 5E                  <1> 	pop	esi			; RECOVER USERS REGISTER
   118 0000391B 1F                  <1> 	pop	ds			; RECOVER USERS SEGMENT SELECTOR
   119                              <1> TIME_9:					; RETURN WITH CY= 0 IF NO ERROR
   120 0000391C CA0400              <1> 	retf	4
   121                              <1> 					; ROUTINE VECTOR TABLE (AH)=
   122                              <1> RTC_TB:
   123 0000391F [3F390000]          <1> 	dd	RTC_00			; 0 = READ CURRENT CLOCK COUNT
   124 00003923 [52390000]          <1> 	dd	RTC_10			; 1 = SET CLOCK COUNT
   125 00003927 [60390000]          <1> 	dd	RTC_20			; 2 = READ THE REAL TIME CLOCK TIME
   126 0000392B [8F390000]          <1> 	dd	RTC_30			; 3 = SET REAL TIME CLOCK TIME
   127 0000392F [D1390000]          <1> 	dd	RTC_40			; 4 = READ THE REAL TIME CLOCK DATE
   128 00003933 [FE390000]          <1> 	dd	RTC_50			; 5 = SET REAL TIME CLOCK DATE
   129 00003937 [4B3A0000]          <1> 	dd	RTC_60			; 6 = SET THE REAL TIME CLOCK ALARM
   130 0000393B [9E3A0000]          <1> 	dd	RTC_70			; 7 = RESET ALARM
   131                              <1> 
   132                              <1> RTC_TBE	equ	$
   133                              <1> 
   134                              <1> RTC_00:				; READ TIME COUNT
   135 0000393F A0[70A80000]        <1> 	mov	al, [TIMER_OFL]		; GET THE OVERFLOW FLAG
   136 00003944 C605[70A80000]00    <1> 	mov	byte [TIMER_OFL], 0	; AND THEN RESET THE OVERFLOW FLAG
   137 0000394B 8B0D[6CA80000]      <1>         mov     ecx, [TIMER_LH]         ; GET COUNT OF TIME
   138 00003951 C3                  <1> 	retn
   139                              <1> 
   140                              <1> RTC_10:				; SET TIME COUNT
   141 00003952 890D[6CA80000]      <1>         mov     [TIMER_LH], ecx         ; SET TIME COUNT
   142 00003958 C605[70A80000]00    <1> 	mov	byte [TIMER_OFL], 0	; RESET OVERFLOW FLAG
   143 0000395F C3                  <1> 	retn				; RETURN WITH NO CARRY
   144                              <1> 
   145                              <1> RTC_20:				; GET RTC TIME
   146 00003960 E8EB010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   147 00003965 7227                <1> 	jc	short RTC_29		; EXIT IF ERROR (CY= 1)
   148                              <1> 
   149 00003967 B000                <1> 	mov	al, CMOS_SECONDS	; SET ADDRESS OF SECONDS
   150 00003969 E8FD010000          <1> 	call	CMOS_READ		; GET SECONDS
   151 0000396E 88C6                <1> 	mov	dh, al			; SAVE
   152 00003970 B00B                <1> 	mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   153 00003972 E8F4010000          <1> 	call	CMOS_READ		; READ CURRENT VALUE OF DSE BIT
   154 00003977 2401                <1> 	and	al, 00000001b		; MASK FOR VALID DSE BIT
   155 00003979 88C2                <1> 	mov	dl, al			; SET [DL] TO ZERO FOR NO DSE BIT
   156 0000397B B002                <1> 	mov	al, CMOS_MINUTES	; SET ADDRESS OF MINUTES
   157 0000397D E8E9010000          <1> 	call	CMOS_READ		; GET MINUTES
   158 00003982 88C1                <1> 	mov	cl, al			; SAVE
   159 00003984 B004                <1>         mov     al, CMOS_HOURS          ; SET ADDRESS OF HOURS
   160 00003986 E8E0010000          <1> 	call	CMOS_READ		; GET HOURS
   161 0000398B 88C5                <1> 	mov	ch, al			; SAVE
   162 0000398D F8                  <1> 	clc				; SET CY= 0
   163                              <1> RTC_29:
   164 0000398E C3                  <1> 	retn				; RETURN WITH RESULT IN CARRY FLAG
   165                              <1> 
   166                              <1> RTC_30:				; SET RTC TIME
   167 0000398F E8BC010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   168 00003994 7305                <1> 	jnc	short RTC_35		; GO AROUND IF CLOCK OPERATING
   169 00003996 E817010000          <1> 	call	RTC_STA			; ELSE TRY INITIALIZING CLOCK
   170                              <1> RTC_35:
   171 0000399B 88F4                <1> 	mov	ah, dh			; GET TIME BYTE - SECONDS
   172 0000399D B000                <1> 	mov	al, CMOS_SECONDS	; ADDRESS SECONDS
   173 0000399F E8DF010000          <1> 	call	CMOS_WRITE		; UPDATE SECONDS
   174 000039A4 88CC                <1> 	mov	ah, cl			; GET TIME BYTE - MINUTES
   175 000039A6 B002                <1> 	mov	al, CMOS_MINUTES	; ADDRESS MINUTES
   176 000039A8 E8D6010000          <1> 	call	CMOS_WRITE		; UPDATE MINUTES
   177 000039AD 88EC                <1> 	mov	ah, ch			; GET TIME BYTE - HOURS
   178 000039AF B004                <1> 	mov	al, CMOS_HOURS		; ADDRESS HOURS
   179 000039B1 E8CD010000          <1> 	call	CMOS_WRITE		; UPDATE ADDRESS
   180                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   181                              <1> 	;mov	ah, al
   182 000039B6 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   183 000039BA E8AC010000          <1> 	call	CMOS_READ		; READ CURRENT TIME
   184 000039BF 2462                <1> 	and	al, 01100010b		; MASK FOR VALID BIT POSITIONS
   185 000039C1 0C02                <1> 	or	al, 00000010b		; TURN ON 24 HOUR MODE
   186 000039C3 80E201              <1> 	and	dl, 00000001b		; USE ONLY THE DSE BIT
   187 000039C6 08D0                <1> 	or	al, dl			; GET DAY LIGHT SAVINGS TIME BIT (OSE)
   188 000039C8 86E0                <1> 	xchg	ah, al			; PLACE IN WORK REGISTER AND GET ADDRESS
   189 000039CA E8B4010000          <1> 	call	CMOS_WRITE		; SET NEW ALARM SITS
   190 000039CF F8                  <1> 	clc				; SET CY= 0
   191 000039D0 C3                  <1> 	retn				; RETURN WITH CY= 0
   192                              <1> 
   193                              <1> RTC_40:				; GET RTC DATE
   194 000039D1 E87A010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   195 000039D6 7225                <1> 	jc	short RTC_49		; EXIT IF ERROR (CY= 1)
   196                              <1> 
   197 000039D8 B007                <1> 	mov	al, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH
   198 000039DA E88C010000          <1> 	call	CMOS_READ		; READ DAY OF MONTH
   199 000039DF 88C2                <1> 	mov	dl, al			; SAVE
   200 000039E1 B008                <1> 	mov	al, CMOS_MONTH		; ADDRESS MONTH
   201 000039E3 E883010000          <1> 	call	CMOS_READ		; READ MONTH
   202 000039E8 88C6                <1> 	mov	dh, al			; SAVE
   203 000039EA B009                <1> 	mov	al, CMOS_YEAR		; ADDRESS YEAR
   204 000039EC E87A010000          <1> 	call	CMOS_READ		; READ YEAR
   205 000039F1 88C1                <1> 	mov	cl, al			; SAVE
   206 000039F3 B032                <1> 	mov	al, CMOS_CENTURY	; ADDRESS CENTURY LOCATION
   207 000039F5 E871010000          <1> 	call	CMOS_READ		; GET CENTURY BYTE
   208 000039FA 88C5                <1> 	mov	ch, al			; SAVE
   209 000039FC F8                  <1> 	clc				; SET CY=0
   210                              <1> RTC_49:
   211 000039FD C3                  <1> 	retn				; RETURN WITH RESULTS IN CARRY FLAG
   212                              <1> 
   213                              <1> RTC_50:				; SET RTC DATE
   214 000039FE E84D010000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   215 00003A03 7305                <1> 	jnc	short RTC_55		; GO AROUND IF NO ERROR
   216 00003A05 E8A8000000          <1> 	call	RTC_STA			; ELSE INITIALIZE CLOCK
   217                              <1> RTC_55:
   218 00003A0A 66B80600            <1> 	mov	ax, CMOS_DAY_WEEK	; ADDRESS OF DAY OF WEEK BYTE
   219 00003A0E E870010000          <1> 	call	CMOS_WRITE		; LOAD ZEROS TO DAY OF WEEK
   220 00003A13 88D4                <1> 	mov	ah, dl			; GET DAY OF MONTH BYTE
   221 00003A15 B007                <1> 	mov	al, CMOS_DAY_MONTH	; ADDRESS DAY OF MONTH BYTE
   222 00003A17 E867010000          <1> 	call	CMOS_WRITE		; WRITE OF DAY OF MONTH REGISTER
   223 00003A1C 88F4                <1> 	mov	ah, dh			; GET MONTH
   224 00003A1E B008                <1> 	mov	al, CMOS_MONTH		; ADDRESS MONTH BYTE
   225 00003A20 E85E010000          <1> 	call	CMOS_WRITE		; WRITE MONTH REGISTER
   226 00003A25 88CC                <1> 	mov	ah, cl			; GET YEAR BYTE
   227 00003A27 B009                <1> 	mov	al, CMOS_YEAR		; ADDRESS YEAR REGISTER
   228 00003A29 E855010000          <1> 	call	CMOS_WRITE		; WRITE YEAR REGISTER
   229 00003A2E 88EC                <1> 	mov	ah, ch			; GET CENTURY BYTE
   230 00003A30 B032                <1> 	mov	al, CMOS_CENTURY	; ADDRESS CENTURY BYTE
   231 00003A32 E84C010000          <1> 	call	CMOS_WRITE		; WRITE CENTURY LOCATION
   232                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   233                              <1> 	;mov	ah, al
   234 00003A37 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   235 00003A3B E82B010000          <1> 	call	CMOS_READ		; READ WIRRENT SETTINGS
   236 00003A40 247F                <1> 	and	al, 07Fh		; CLEAR 'SET BIT'
   237 00003A42 86E0                <1> 	xchg	ah, al			; MOVE TO WORK REGISTER
   238 00003A44 E83A010000          <1> 	call	CMOS_WRITE		; AND START CLOCK UPDATING
   239 00003A49 F8                  <1> 	clc				; SET CY= 0
   240 00003A4A C3                  <1> 	retn				; RETURN CY=0
   241                              <1> 
   242                              <1> RTC_60:				; SET RTC ALARM
   243 00003A4B B00B                <1> 	mov	al, CMOS_REG_B		; ADDRESS ALARM
   244 00003A4D E819010000          <1> 	call	CMOS_READ		; READ ALARM REGISTER
   245 00003A52 A820                <1> 	test	al, 20h			; CHECK FOR ALARM ALREADY ENABLED
   246 00003A54 F9                  <1> 	stc				; SET CARRY IN CASE OF ERROR
   247 00003A55 7542                <1> 	jnz	short RTC_69		; ERROR EXIT IF ALARM SET
   248 00003A57 E8F4000000          <1> 	call	UPD_IPR			; CHECK FOR UPDATE IN PROCESS
   249 00003A5C 7305                <1> 	jnc	short RTC_65		; SKIP INITIALIZATION IF NO ERROR
   250 00003A5E E84F000000          <1> 	call	RTC_STA			; ELSE INITIALIZE CLOCK
   251                              <1> RTC_65:	
   252 00003A63 88F4                <1> 	mov	ah, dh			; GET SECONDS BYTE
   253 00003A65 B001                <1> 	mov	al, CMOS_SEC_ALARM	; ADDRESS THE SECONDS ALARM REGISTER
   254 00003A67 E817010000          <1> 	call	CMOS_WRITE		; INSERT SECONDS
   255 00003A6C 88CC                <1> 	mov	ah, cl			; GET MINUTES PARAMETER
   256 00003A6E B003                <1> 	mov	al, CMOS_MIN_ALARM	; ADDRESS MINUTES ALARM REGISTER
   257 00003A70 E80E010000          <1> 	call	CMOS_WRITE		; INSERT MINUTES
   258 00003A75 88EC                <1> 	mov	ah, ch			; GET HOURS PARAMETER
   259 00003A77 B005                <1> 	mov	al, CMOS_HR_ALARM	; ADDRESS HOUR ALARM REGISTER
   260 00003A79 E805010000          <1> 	call	CMOS_WRITE		; INSERT HOURS
   261 00003A7E E4A1                <1> 	in	al, INTB01		; READ SECOND INTERRUPT MASK REGISTER
   262 00003A80 24FE                <1> 	and	al, 0FEh		; ENABLE ALARM TIMER BIT (CY= 0)
   263 00003A82 E6A1                <1> 	out	INTB01, al		; WRITE UPDATED MASK
   264                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   265                              <1> 	;mov	ah, al
   266 00003A84 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257
   267 00003A88 E8DE000000          <1> 	call	CMOS_READ		; READ CURRENT ALARM REGISTER
   268 00003A8D 247F                <1> 	and	al, 07Fh		; ENSURE SET BIT TURNED OFF
   269 00003A8F 0C20                <1> 	or	al, 20h			; TURN ON ALARM ENABLE
   270 00003A91 86E0                <1> 	xchg	ah, al			; MOVE MASK TO OUTPUT REGISTER
   271 00003A93 E8EB000000          <1> 	call	CMOS_WRITE		; WRITE NEW ALARM MASK
   272 00003A98 F8                  <1> 	clc				; SET CY= 0
   273                              <1> RTC_69:
   274 00003A99 66B80000            <1> 	mov	ax, 0			; CLEAR AX REGISTER
   275 00003A9D C3                  <1> 	retn				; RETURN WITH RESULTS IN CARRY FLAC
   276                              <1> 
   277                              <1> RTC_70:				; RESET ALARM
   278                              <1> 	;mov	al, CMOS_REG_B		; ADDRESS ALARM REGISTER
   279                              <1> 	;mov	ah, al
   280 00003A9E 66B80B0B            <1> 	mov	ax, CMOS_REG_B * 257	; ADDRESS ALARM REGISTER (TO BOTH AH,AL)
   281 00003AA2 E8C4000000          <1> 	call	CMOS_READ		; READ ALARM REGISTER
   282 00003AA7 2457                <1> 	and	al, 57h			; TURN OFF ALARM ENABLE
   283 00003AA9 86E0                <1> 	xchg	ah, al			; SAVE DATA AND RECOVER ADDRESS
   284 00003AAB E8D3000000          <1> 	call	CMOS_WRITE		; RESTORE NEW VALUE
   285 00003AB0 F8                  <1> 	clc				; SET CY= 0
   286 00003AB1 C3                  <1> 	retn				; RETURN WITH NO CARRY
   287                              <1> 
   288                              <1> RTC_STA:			; INITIALIZE REAL TIME CLOCK
   289                              <1> 	;mov	al, CMOS_REG_A		; ADDRESS REGISTER A AND LOAD DATA MASK		
   290                              <1> 	;mov	ah, 26h
   291 00003AB2 66B80A26            <1> 	mov	ax, (26h*100h)+CMOS_REG_A
   292 00003AB6 E8C8000000          <1> 	call	CMOS_WRITE		; INITIALIZE STATUS REGISTER A
   293                              <1> 	;mov	al, CMOS_REG_B		; SET "SET BIT" FOR CLOCK INITIALIZATION	
   294                              <1> 	;mov	ah, 82h
   295 00003ABB 66B80B82            <1> 	mov	ax, (82h*100h)+CMOS_REG_B
   296 00003ABF E8BF000000          <1> 	call	CMOS_WRITE		; AND 24 HOUR MODE TO REGISTER B
   297 00003AC4 B00C                <1> 	mov	al, CMOS_REG_C		; ADDRESS REGISTER C
   298 00003AC6 E8A0000000          <1> 	call	CMOS_READ		; READ REGISTER C TO INITIALIZE
   299 00003ACB B00D                <1> 	mov	al, CMOS_REG_D		; ADDRESS REGISTER D
   300 00003ACD E899000000          <1> 	call	CMOS_READ		; READ REGISTER D TO INITIALIZE
   301 00003AD2 C3                  <1> 	retn
   302                              <1> 
   303                              <1> ; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
   304                              <1> 
   305                              <1> ;--- HARDWARE INT  70 H -- ( IRQ LEVEL  8) --------------------------------------
   306                              <1> ; ALARM INTERRUPT HANDLER (RTC)							:
   307                              <1> ;       THIS ROUTINE HANDLES THE PERIODIC AND ALARM INTERRUPTS FROM THE CMOS	:
   308                              <1> ;       TIMER. INPUT FREQUENCY IS 1.024 KHZ OR APPROXIMATELY 1024 INTERRUPTS	:
   309                              <1> ;       EVERY SECOND FOR THE PERIODIC INTERRUPT. FOR THE ALARM FUNCTION,	:
   310                              <1> ;       THE INTERRUPT WILL OCCUR AT THE DESIGNATED TIME.			:
   311                              <1> ;										:
   312                              <1> ;       INTERRUPTS ARE ENABLED WHEN THE EVENT OR ALARM FUNCTION IS ACTIVATED.	:
   313                              <1> ;       FOR THE EVENT INTERRUPT, THE HANDLER WILL DECREMENT THE WAIT COUNTER	:
   314                              <1> ;       AND WHEN IT EXPIRES WILL SET THE DESIGNATED LOCATION TO 80H. FOR	:
   315                              <1> ;       THE ALARM INTERRUPT. THE USER MUST PROVIDE A ROUTINE TO INTERCEPT	:
   316                              <1> ;       THE CORRECT ADDRESS FROM THE VECTOR TABLE INVOKED BY INTERRUPT 4AH	:
   317                              <1> ;       PRIOR TO SETTING THE REAL TIME CLOCK ALARM (INT 1AH, AH= 06H).		:
   318                              <1> ;--------------------------------------------------------------------------------
   319                              <1> 
   320                              <1> RTC_INT:			; ALARM INTERRUPT
   321 00003AD3 1E                  <1> 	push	ds			; LEAVE INTERRUPTS DISABLED
   322 00003AD4 50                  <1> 	push	eax			; SAVE REGISTERS
   323 00003AD5 57                  <1> 	push	edi
   324                              <1> RTC_I_1:				; CHECK FOR SECOND INTERRUPT
   325 00003AD6 66B88C8B            <1> 	mov	ax, 256*(CMOS_REG_B+NMI)+CMOS_REG_C+NMI ; ALARM AND STATUS
   326 00003ADA E670                <1> 	out	CMOS_PORT, al		; WRITE ALARM FLAG MASK ADDRESS
   327 00003ADC 90                  <1> 	nop				; I/O DELAY
   328 00003ADD EB00                <1> 	jmp	short $+2
   329 00003ADF E471                <1> 	in	al, CMOS_DATA		; READ AND RESET INTERRUPT REQUEST FLAGS
   330 00003AE1 A860                <1> 	test	al, 01100000b		; CHECK FOR EITHER INTERRUPT PENDING
   331 00003AE3 745D                <1> 	jz	short	RTC_I_9		; EXIT IF NOT A VALID RTC INTERRUPT
   332                              <1> 
   333 00003AE5 86E0                <1> 	xchg	ah, al			; SAVE FLAGS AND GET ENABLE ADDRESS
   334 00003AE7 E670                <1> 	out	CMOS_PORT, al		; WRITE ALARM ENABLE MASK ADDRESS
   335 00003AE9 90                  <1> 	nop				; I/O DELAY
   336 00003AEA EB00                <1> 	jmp	short $+2	
   337 00003AEC E471                <1> 	in	al, CMOS_DATA		; READ CURRENT ALARM ENABLE MASK
   338 00003AEE 20E0                <1> 	and	al, ah			; ALLOW ONLY SOURCES THAT ARE ENABLED
   339 00003AF0 A840                <1> 	test	al, 01000000b		; CHECK FOR PERIODIC INTERRUPT
   340 00003AF2 743B                <1> 	jz	short RTC_I_5		; SKIP IF NOT A PERIODIC INTERRUPT
   341                              <1> 
   342                              <1> ;-----	DECREMENT WAIT COUNT BY INTERRUPT INTERVAL
   343                              <1> 
   344 00003AF4 66BF1000            <1> 	mov	di, KDATA		; kernel data segment
   345 00003AF8 8EDF                <1> 	mov	ds, di
   346                              <1> 	
   347 00003AFA 812D[66A80000]D003- <1> 	sub	dword [RTC_LH], 976	; DECREMENT COUNT BY 1/1024
   347 00003B02 0000                <1>
   348 00003B04 7329                <1> 	jnc	short RTC_I_5		; SKIP TILL 32 BIT WORD LESS THAN ZERO
   349                              <1> 
   350                              <1> ;-----	TURN OFF PERIODIC INTERRUPT ENABLE
   351                              <1> 
   352 00003B06 6650                <1> 	push	ax			; SAVE INTERRUPT FLAG MASK
   353 00003B08 66B88B8B            <1> 	mov	ax, 257*(CMOS_REG_B+NMI) ; INTERRUPT ENABLE REGISTER
   354 00003B0C E670                <1> 	out	CMOS_PORT, al		; WRITE ADDRESS TO CMOS CLOCK
   355 00003B0E 90                  <1> 	nop				; I/O DELAY
   356 00003B0F EB00                <1> 	jmp	short $+2
   357 00003B11 E471                <1> 	in	al, CMOS_DATA		; READ CURRENT ENABLES
   358 00003B13 24BF                <1> 	and	al, 0BFh		; TURN OFF PIE
   359 00003B15 86C4                <1> 	xchg	al, ah			; GET CMOS ADDRESS AND SAVE VALUE
   360 00003B17 E670                <1> 	out	CMOS_PORT, al		; ADDRESS REGISTER B
   361 00003B19 86C4                <1> 	xchg	al, ah			; GET NEW INTERRUPT ENABLE MASK
   362 00003B1B E671                <1> 	out	CMOS_DATA, al		; SET MASK IN INTERRUPT ENABLE REGISTER
   363 00003B1D C605[6AA80000]00    <1> 	mov	byte [RTC_WAIT_FLAG], 0	; SET FUNCTION ACTIVE FLAG OFF
   364 00003B24 8B3D[6BA80000]      <1> 	mov	edi, [USER_FLAG]	; SET UP (DS:DI) TO POINT TO USER FLAG
   365 00003B2A C60780              <1> 	mov	byte [edi], 80h		; TURN ON USERS FLAG
   366 00003B2D 6658                <1> 	pop	ax			; GET INTERRUPT SOURCE BACK
   367                              <1> RTC_I_5:
   368 00003B2F A820                <1> 	test	al, 00100000b		; TEST FOR ALARM INTERRUPT
   369 00003B31 740D                <1> 	jz	short RTC_I_7		; SKIP USER INTERRUPT CALL IF NOT ALARM
   370                              <1> 
   371 00003B33 B00D                <1> 	mov	al, CMOS_REG_D		; POINT TO DEFAULT READ ONLY REGISTER
   372 00003B35 E670                <1> 	out	CMOS_PORT, al		; ENABLE NMI AND CMOS ADDRESS TO DEFAULT
   373 00003B37 FB                  <1> 	sti				; INTERRUPTS BACK ON NOW
   374 00003B38 52                  <1> 	push	edx
   375 00003B39 E8185C0000          <1> 	call	INT4Ah			; TRANSFER TO USER ROUTINE
   376 00003B3E 5A                  <1> 	pop	edx
   377 00003B3F FA                  <1> 	cli				; BLOCK INTERRUPT FOR RETRY
   378                              <1> RTC_I_7:				; RESTART ROUTINE TO HANDLE DELAYED
   379 00003B40 EB94                <1> 	jmp	short RTC_I_1		;  ENTRY AND SECOND EVENT BEFORE DONE
   380                              <1> 
   381                              <1> RTC_I_9:				; EXIT - NO PENDING INTERRUPTS
   382 00003B42 B00D                <1> 	mov	al, CMOS_REG_D		; POINT TO DEFAULT READ ONLY REGISTER
   383 00003B44 E670                <1> 	out	CMOS_PORT, al		; ENABLE NMI AND CMOS ADDRESS TO DEFAULT
   384 00003B46 B020                <1> 	mov	al, EOI			; END OF INTERRUPT MASK TO 8259 - 2
   385 00003B48 E6A0                <1> 	out	INTB00, al		; TO 8259 - 2
   386 00003B4A E620                <1> 	out	INTA00,	al		; TO 8259 - 1
   387 00003B4C 5F                  <1> 	pop	edi			; RESTORE REGISTERS
   388 00003B4D 58                  <1> 	pop	eax
   389 00003B4E 1F                  <1> 	pop	ds
   390 00003B4F CF                  <1> 	iret				; END OF INTERRUPT
   391                              <1> 
   392                              <1> 
   393                              <1> 	; 22/08/2014 (Retro UNIX 386 v1)
   394                              <1> 	; IBM PC/AT BIOS source code ----- 10/06/85 (bios2.asm)
   395                              <1> UPD_IPR:				; WAIT TILL UPDATE NOT IN PROGRESS
   396 00003B50 51                  <1> 	push	ecx
   397 00003B51 B9FFFF0000          <1> 	mov	ecx, 65535		; SET TIMEOUT LOOP COUNT (= 800)
   398                              <1> 		; mov cx, 800	
   399                              <1> UPD_10:
   400 00003B56 B00A                <1> 	mov	al, CMOS_REG_A		; ADDRESS STATUS REGISTER A
   401 00003B58 FA                  <1> 	cli				; NO TIMER INTERRUPTS DURING UPDATES
   402 00003B59 E80D000000          <1> 	call	CMOS_READ		; READ UPDATE IN PROCESS FLAG
   403 00003B5E A880                <1> 	test	al, 80h			; IF UIP BIT IS ON ( CANNOT READ TIME )
   404 00003B60 7406                <1> 	jz	short UPD_90		; EXIT WITH CY= 0 IF CAN READ CLOCK NOW
   405 00003B62 FB                  <1> 	sti				; ALLOW INTERRUPTS WHILE WAITING
   406 00003B63 E2F1                <1> 	loop	UPD_10			; LOOP TILL READY OR TIMEOUT
   407 00003B65 31C0                <1> 	xor	eax, eax		; CLEAR RESULTS IF ERROR
   408                              <1> 		; xor ax, ax
   409 00003B67 F9                  <1> 	stc				; SET CARRY FOR ERROR
   410                              <1> UPD_90:
   411 00003B68 59                  <1> 	pop	ecx			; RESTORE CALLERS REGISTER
   412 00003B69 FA                  <1> 	cli				; INTERRUPTS OFF DURING SET
   413 00003B6A C3                  <1> 	retn				; RETURN WITH CY FLAG SET
   414                              <1> 
   415                              <1> 	; 22/08/2014 (Retro UNIX 386 v1)
   416                              <1> 	; IBM PC/AT BIOS source code ----- 10/06/85 (test4.asm)
   417                              <1> 
   418                              <1> ;--- CMOS_READ -----------------------------------------------------------------
   419                              <1> ;		READ BYTE FROM CMOS_SYSTEM CLOCK CONFIGURATION TABLE	       :
   420                              <1> ;									       :
   421                              <1> ; INPUT: (AL)=	CMOS_TABLE ADDRESS TO BE READ				       :
   422                              <1> ;		BIT    7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT    :
   423                              <1> ;		BITS 6-0 = ADDRESS OF TABLE LOCATION TO READ		       :
   424                              <1> ;									       :
   425                              <1> ; OUTPUT: (AL)	VALUE AT LOCATION (AL) MOVED INTO (AL). IF BIT 7 OF (AL) WAS   :
   426                              <1> ;		ON THEN NMI LEFT DISABLED, DURING THE CMOS READ BOTH NMI AND   :
   427                              <1> ;		NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. :
   428                              <1> ;		THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND    :
   429                              <1> ;		THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN.      :
   430                              <1> ;		ONLY THE (AL) REGISTER AND THE NMI STATE IS CHANGED.	       :
   431                              <1> ;-------------------------------------------------------------------------------
   432                              <1> 
   433                              <1> CMOS_READ:
   434 00003B6B 9C                  <1> 	pushf				; SAVE INTERRUPT ENABLE STATUS AND FLAGS
   435 00003B6C D0C0                <1> 	rol	al, 1			; MOVE NMI BIT TO LOW POSITION
   436 00003B6E F9                  <1> 	stc				; FORCE NMI BIT ON IN CARRY FLAG
   437 00003B6F D0D8                <1> 	rcr	al, 1			; HIGH BIT ON TO DISABLE NMI - OLD IN CY
   438 00003B71 FA                  <1> 	cli				; DISABLE INTERRUPTS
   439 00003B72 E670                <1> 	out	CMOS_PORT, al		; ADDRESS LOCATION AND DISABLE NMI
   440 00003B74 90                  <1> 	nop				; I/O DELAY
   441 00003B75 E471                <1> 	in	al, CMOS_DATA		; READ THE REQUESTED CMOS LOCATION
   442 00003B77 6650                <1> 	push	ax			; SAVE (AH) REGISTER VALUE AND CMOS BYTE
   443                              <1> 	; 15/03/2015 ; IBM PC/XT Model 286 BIOS source code 
   444                              <1> 		     ; ----- 10/06/85 (test4.asm)
   445 00003B79 B01E                <1> 	mov	al, CMOS_SHUT_DOWN*2 ; GET ADDRESS OF DEFAULT LOCATION
   446                              <1> 	;mov	al, CMOS_REG_D*2 	; GET ADDRESS OF DEFAULT LOCATION
   447 00003B7B D0D8                <1> 	rcr	al, 1			; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
   448 00003B7D E670                <1> 	out	CMOS_PORT, al		; SET DEFAULT TO READ ONLY REGISTER
   449 00003B7F 6658                <1> 	pop	ax			; RESTORE (AH) AND (AL), CMOS BYTE
   450 00003B81 9D                  <1> 	popf	
   451 00003B82 C3                  <1> 	retn				; RETURN WITH FLAGS RESTORED
   452                              <1> 
   453                              <1> ; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
   454                              <1> 
   455                              <1> ;--- CMOS_WRITE ----------------------------------------------------------------
   456                              <1> ;	WRITE BYTE TO CMOS SYSTEM CLOCK CONFIGURATION TABLE		       :
   457                              <1> ;									       :
   458                              <1> ; INPUT: (AL)=	CMOS TABLE ADDRESS TO BE WRITTEN TO			       :
   459                              <1> ;		BIT    7 = 0 FOR NMI ENABLED AND 1 FOR NMI DISABLED ON EXIT    :
   460                              <1> ;		BITS 6-0 = ADDRESS OF TABLE LOCATION TO WRITE		       :
   461                              <1> ;	 (AH)=	NEW VALUE TO BE PLACED IN THE ADDRESSED TABLE LOCATION	       :
   462                              <1> ;									       :
   463                              <1> ; OUTPUT:	VALUE IN (AH) PLACED IN LOCATION (AL) WITH NMI LEFT DISABLED   :
   464                              <1> ;		IF BIT 7 OF (AL) IS ON, DURING THE CMOS UPDATE BOTH NMI AND    :
   465                              <1> ;		NORMAL INTERRUPTS ARE DISABLED TO PROTECT CMOS DATA INTEGRITY. :
   466                              <1> ;		THE CMOS ADDRESS REGISTER IS POINTED TO A DEFAULT VALUE AND    :
   467                              <1> ;		THE INTERRUPT FLAG RESTORED TO THE ENTRY STATE ON RETURN.      :
   468                              <1> ;		ONLY THE CMOS LOCATION AND THE NMI STATE IS CHANGED.	       :
   469                              <1> ;-------------------------------------------------------------------------------
   470                              <1> 
   471                              <1> CMOS_WRITE:				; WRITE (AH) TO LOCATION (AL)
   472 00003B83 9C                  <1> 	pushf				; SAVE INTERRUPT ENABLE STATUS AND FLAGS
   473 00003B84 6650                <1> 	push	ax			; SAVE WORK REGISTER VALUES
   474 00003B86 D0C0                <1> 	rol	al, 1			; MOVE NMI BIT TO LOW POSITION
   475 00003B88 F9                  <1> 	stc				; FORCE NMI BIT ON IN CARRY FLAG
   476 00003B89 D0D8                <1> 	rcr	al, 1			; HIGH BIT ON TO DISABLE NMI - OLD IN CY
   477 00003B8B FA                  <1> 	cli				; DISABLE INTERRUPTS
   478 00003B8C E670                <1> 	out	CMOS_PORT, al		; ADDRESS LOCATION AND DISABLE NMI
   479 00003B8E 88E0                <1> 	mov	al, ah			; GET THE DATA BYTE TO WRITE
   480 00003B90 E671                <1> 	out	CMOS_DATA, al		; PLACE IN REQUESTED CMOS LOCATION
   481 00003B92 B01E                <1> 	mov	al, CMOS_SHUT_DOWN*2	; GET ADDRESS OF DEFAULT LOCATION
   482                              <1> 	;mov	al, CMOS_REG_D*2 	; GET ADDRESS OF DEFAULT LOCATION
   483 00003B94 D0D8                <1> 	rcr	al, 1			; PUT ORIGINAL NMI MASK BIT INTO ADDRESS
   484 00003B96 E670                <1> 	out	CMOS_PORT, al		; SET DEFAULT TO READ ONLY REGISTER
   485 00003B98 90                  <1> 	nop				; I/O DELAY
   486 00003B99 E471                <1> 	in	al, CMOS_DATA		; OPEN STANDBY LATCH
   487 00003B9B 6658                <1> 	pop	ax			; RESTORE WORK REGISTERS
   488 00003B9D 9D                  <1> 	popf
   489 00003B9E C3                  <1> 	retn
   490                              <1> 
   491                              <1> ; /// End Of TIMER FUNCTIONS ///
  1911                                  %include 'sysdefs.s' ; 24/01/2015
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - SYSTEM DEFINITIONS : sysdefs.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 24/01/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    11                              <1> ; sysdefs.inc (14/11/2015)
    12                              <1> ; ****************************************************************************
    13                              <1> 
    14                              <1> ; Retro UNIX 386 v1 Kernel - SYSDEFS.INC
    15                              <1> ; Last Modification: 14/11/2015
    16                              <1> ;
    17                              <1> ; ///////// RETRO UNIX 386 V1 SYSTEM DEFINITIONS ///////////////
    18                              <1> ; (Modified from 
    19                              <1> ;	Retro UNIX 8086 v1 system definitions in 'UNIX.ASM', 01/09/2014)
    20                              <1> ; ((UNIX.ASM (RETRO UNIX 8086 V1 Kernel), 11/03/2013 - 01/09/2014))
    21                              <1> ; 	UNIX.ASM (MASM 6.11) --> SYSDEFS.INC (NASM 2.11)
    22                              <1> ; ----------------------------------------------------------------------------
    23                              <1> ;
    24                              <1> ; Derived from UNIX Operating System (v1.0 for PDP-11) 
    25                              <1> ; (Original) Source Code by Ken Thompson (1971-1972)
    26                              <1> ; <Bell Laboratories (17/3/1972)>
    27                              <1> ; <Preliminary Release of UNIX Implementation Document>
    28                              <1> ;
    29                              <1> ; ****************************************************************************
    30                              <1> 
    31                              <1> nproc 	equ	16  ; number of processes
    32                              <1> nfiles 	equ	50
    33                              <1> ntty	equ     8   ; 8+1 -> 8 (10/05/2013)
    34                              <1> nbuf	equ	4   ; 6 ;; 21/08/2015 - 'namei' buffer problem when nbuf > 4 	
    35                              <1> 		; NOTE: If fd0 super block buffer addres is beyond of the 1st
    36                              <1> 		; 32K, DMA r/w routine or someting else causes a jump to 
    37                              <1> 		; kernel panic routine (in 'alloc' routine, in u5.s)
    38                              <1> 		; because of invalid buffer content (r/w error). 
    39                              <1> 		; When all buffers are set before the end of the 1st 32k,
    40                              <1> 		; there is no problem!? (14/11/2015) 
    41                              <1> 
    42                              <1> ;csgmnt	equ	2000h	; 26/05/2013 (segment of process 1)
    43                              <1> ;core	equ 	0  	    ; 19/04/2013	
    44                              <1> ;ecore	equ	32768 - 64  ; 04/06/2013 (24/05/2013)
    45                              <1> 	; (if total size of argument list and arguments is 128 bytes)
    46                              <1> 	; maximum executable file size = 32768-(64+40+128-6) = 32530 bytes
    47                              <1> 	; maximum stack size = 40 bytes (+6 bytes for 'IRET' at 32570)	
    48                              <1> 	; initial value of user's stack pointer = 32768-64-128-2 = 32574
    49                              <1> 	; 	(sp=32768-args_space-2 at the beginning of execution)
    50                              <1> 	; argument list offset = 32768-64-128 = 32576 (if it is 128 bytes)
    51                              <1> 	; 'u' structure offset (for the '/core' dump file) = 32704
    52                              <1> 	; '/core' dump file size = 32768 bytes
    53                              <1>  
    54                              <1> ; 08/03/2014 
    55                              <1> ;sdsegmnt equ	6C0h  ; 256*16 bytes (swap data segment size for 16 processes)		 	 
    56                              <1> ; 19/04/2013 Retro UNIX 8086 v1 feaure only !
    57                              <1> ;;sdsegmnt equ 	740h  ; swap data segment (for user structures and registers)
    58                              <1> 
    59                              <1> ; 30/08/2013
    60                              <1> time_count equ 4 ; 10 --> 4 01/02/2014
    61                              <1> 
    62                              <1> ; 05/02/2014
    63                              <1> ; process status
    64                              <1> ;SFREE 	equ 0
    65                              <1> ;SRUN	equ 1
    66                              <1> ;SWAIT	equ 2
    67                              <1> ;SZOMB	equ 3
    68                              <1> ;SSLEEP	equ 4 ; Retro UNIX 8086 V1 extension (for sleep and wakeup)
    69                              <1> 
    70                              <1> ; 09/03/2015
    71                              <1> userdata equ 80000h ; user structure data address for current user ; temporary
    72                              <1> swap_queue equ 90000h - 2000h ; swap queue address ; temporary
    73                              <1> swap_alloc_table equ 0D0000h  ;  swap allocation table address ; temporary
    74                              <1> 
    75                              <1> ; 17/09/2015
    76                              <1> ESPACE equ 48 ; [u.usp] (at 'sysent') - [u.sp] value for error return
    77                              <1> 
    78                              <1> ; 21/09/2015 (36) 
    79                              <1> ; 01/07/2015 (35)
    80                              <1> ; 14/07/2013 (0-34)
    81                              <1> ; UNIX v1 system calls
    82                              <1> _rele 	equ 0
    83                              <1> _exit 	equ 1
    84                              <1> _fork 	equ 2
    85                              <1> _read 	equ 3
    86                              <1> _write	equ 4
    87                              <1> _open	equ 5
    88                              <1> _close 	equ 6
    89                              <1> _wait 	equ 7
    90                              <1> _creat 	equ 8
    91                              <1> _link 	equ 9
    92                              <1> _unlink	equ 10
    93                              <1> _exec	equ 11
    94                              <1> _chdir	equ 12
    95                              <1> _time 	equ 13
    96                              <1> _mkdir 	equ 14
    97                              <1> _chmod	equ 15
    98                              <1> _chown	equ 16
    99                              <1> _break	equ 17
   100                              <1> _stat	equ 18
   101                              <1> _seek	equ 19
   102                              <1> _tell 	equ 20
   103                              <1> _mount	equ 21
   104                              <1> _umount	equ 22
   105                              <1> _setuid	equ 23
   106                              <1> _getuid	equ 24
   107                              <1> _stime	equ 25
   108                              <1> _quit	equ 26	
   109                              <1> _intr	equ 27
   110                              <1> _fstat	equ 28
   111                              <1> _emt 	equ 29
   112                              <1> _mdate 	equ 30
   113                              <1> _stty 	equ 31
   114                              <1> _gtty	equ 32
   115                              <1> _ilgins	equ 33
   116                              <1> _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
   117                              <1> _msg	equ 35 ; Retro UNIX 386 v1 feature only !
   118                              <1> _geterr	equ 36 ; Retro UNIX 386 v1 feature only !
   119                              <1> 
   120                              <1> %macro sys 1-4
   121                              <1>     ; 13/04/2015
   122                              <1>     ; Retro UNIX 386 v1 system call.		
   123                              <1>     mov eax, %1
   124                              <1>     %if %0 >= 2   
   125                              <1>         mov ebx, %2
   126                              <1>         %if %0 >= 3    
   127                              <1>             mov ecx, %3
   128                              <1>             %if %0 = 4
   129                              <1>                mov edx, %4   
   130                              <1>             %endif
   131                              <1>         %endif
   132                              <1>     %endif
   133                              <1>     int 30h	   
   134                              <1> %endmacro
   135                              <1> 
   136                              <1> ; 13/05/2015 - ERROR CODES
   137                              <1> ERR_FILE_NOT_OPEN  equ 10 ; 'file not open !' error
   138                              <1> ERR_FILE_ACCESS    equ 11 ; 'permission denied !' error
   139                              <1> ; 14/05/2015
   140                              <1> ERR_DIR_ACCESS     equ 11 ; 'permission denied !' error
   141                              <1> ERR_FILE_NOT_FOUND equ 12 ; 'file not found !' error
   142                              <1> ERR_TOO_MANY_FILES equ 13 ; 'too many open files !' error
   143                              <1> ERR_DIR_EXISTS     equ 14 ; 'directory already exists !' error 	
   144                              <1> ; 16/05/2015		
   145                              <1> ERR_DRV_NOT_RDY    equ 15 ; 'drive not ready !' error
   146                              <1> ; 18/05/2015
   147                              <1> ERR_DEV_NOT_RDY    equ 15 ; 'device not ready !' error
   148                              <1> ERR_DEV_ACCESS     equ 11 ; 'permission denied !' error 
   149                              <1> ERR_DEV_NOT_OPEN   equ 10 ; 'device not open !' error	
   150                              <1> ; 07/06/2015
   151                              <1> ERR_FILE_EOF	   equ 16 ; 'end of file !' error
   152                              <1> ERR_DEV_VOL_SIZE   equ 16 ; 'out of volume' error
   153                              <1> ; 09/06/2015
   154                              <1> ERR_DRV_READ	   equ 17 ; 'disk read error !'
   155                              <1> ERR_DRV_WRITE	   equ 18 ; 'disk write error !'
   156                              <1> ; 16/06/2015
   157                              <1> ERR_NOT_DIR	   equ 19 ; 'not a (valid) directory !' error
   158                              <1> ERR_FILE_SIZE	   equ 20 ; 'file size error !'	
   159                              <1> ; 22/06/2015
   160                              <1> ERR_NOT_SUPERUSER  equ 11 ; 'permission denied !' error
   161                              <1> ERR_NOT_OWNER      equ 11 ; 'permission denied !' error
   162                              <1> ERR_NOT_FILE       equ 11 ; 'permission denied !' error	
   163                              <1> ; 23/06/2015
   164                              <1> ERR_FILE_EXISTS    equ 14 ; 'file already exists !' error
   165                              <1> ERR_DRV_NOT_SAME   equ 21 ; 'not same drive !' error
   166                              <1> ERR_DIR_NOT_FOUND  equ 12 ; 'directory not found !' error
   167                              <1> ERR_NOT_EXECUTABLE equ 22 ; 'not executable file !' error
   168                              <1> ; 27/06/2015
   169                              <1> ERR_INV_PARAMETER  equ 23 ; 'invalid parameter !' error
   170                              <1> ERR_INV_DEV_NAME   equ 24 ; 'invalid device name !' error
   171                              <1> ; 29/06/2015
   172                              <1> ERR_TIME_OUT	   equ 25 ; 'time out !' error			
   173                              <1> ERR_DEV_NOT_RESP   equ 25 ; 'device not responding !' error	
   174                              <1> 
   175                              <1> ; 26/08/2015
   176                              <1> ; 24/07/2015
   177                              <1> ; 24/06/2015
   178                              <1> MAX_ARG_LEN	   equ 256 ; max. length of sys exec arguments
   179                              <1> ; 01/07/2015
   180                              <1> MAX_MSG_LEN	   equ 255 ; max. msg length for 'sysmsg'
   181                              <1> ;	 					 		
  1912                                  %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
  1913                                  %include 'trdosk1.s' ; 04/01/2016 
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - SYS INIT : trdosk1.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 30/01/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 04/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    11                              <1> ; TRDOS2.ASM (09/11/2011)
    12                              <1> ; ****************************************************************************
    13                              <1> ; TRDOS2.ASM (c) 2004-2011 Erdogan TAN [ 17/01/2004 ] Last Update: 09/11/2011
    14                              <1> ;
    15                              <1> 
    16                              <1> sys_init:
    17                              <1> 	; 24/01/2016
    18                              <1> 	; 06/01/2016
    19                              <1> 	; 04/01/2016
    20                              <1> 
    21 00003B9F B83F3A2F00          <1> 	mov	eax, '?:/'
    22 00003BA4 A3[AFA80000]        <1> 	mov	[Current_Dir_Drv], eax
    23                              <1> 
    24                              <1> 	; Logical DRV INIT (only for hard disks)
    25 00003BA9 E854010000          <1> 	call 	ldrv_init  ; trdosk2.s
    26                              <1> 	
    27                              <1> 	; When floppy_drv_init call is disabled
    28                              <1> 	; media changed sign is needed
    29                              <1> 	; for proper drive initialization
    30                              <1>         
    31 00003BAE BE00010900          <1> 	mov 	esi, Logical_DOSDisks
    32 00003BB3 B001                <1> 	mov 	al, 1 ; Initialization sign (invalid_fd_parameter)
    33 00003BB5 83C67E              <1> 	add 	esi, LD_MediaChanged ; Media Change Status = 1 (init needed)
    34 00003BB8 8806                <1> 	mov 	[esi], al ; A:
    35 00003BBA 81C600010000        <1> 	add 	esi, 100h 
    36 00003BC0 8806                <1> 	mov 	[esi], al ; B: 
    37                              <1>            
    38                              <1> _current_drive_bootdisk:
    39 00003BC2 8A15[BAA20000]      <1> 	mov 	dl, [boot_drv] ; physical drive number
    40 00003BC8 80FAFF              <1> 	cmp 	dl, 0FFh
    41 00003BCB 740A                <1> 	je 	short _last_dos_diskno_check
    42                              <1> _boot_drive_check:
    43 00003BCD 80FA80              <1> 	cmp 	dl, 80h
    44 00003BD0 7218                <1> 	jb 	short _current_drive_a
    45 00003BD2 80EA7E              <1> 	sub 	dl, 7Eh ; C = 2 , D = 3
    46 00003BD5 EB13                <1> 	jmp 	short _current_drive_a 
    47                              <1> 
    48                              <1> _last_dos_diskno_check:
    49 00003BD7 8A15[7C990000]      <1> 	mov 	dl, [Last_DOS_DiskNo]
    50 00003BDD 80FA02              <1> 	cmp 	dl, 2
    51 00003BE0 7706                <1> 	ja 	short _current_drive_c
    52 00003BE2 7406                <1> 	je 	short _current_drive_a
    53 00003BE4 30D2                <1> 	xor 	dl, dl ; A:
    54 00003BE6 EB02                <1> 	jmp 	short _current_drive_a
    55                              <1> 
    56                              <1> _current_drive_c:
    57 00003BE8 B202                <1> 	mov 	dl, 2 ; C:
    58                              <1> 
    59                              <1> _current_drive_a:
    60 00003BEA 8815[BBA20000]      <1> 	mov	[drv], dl
    61 00003BF0 BE[7E990000]        <1>         mov     esi, msg_CRLF_temp
    62 00003BF5 E840000000          <1> 	call 	print_msg
    63                              <1> 
    64 00003BFA 8A15[BBA20000]      <1> 	mov	dl, [drv]
    65 00003C00 E839090000          <1> 	call 	change_current_drive
    66 00003C05 730C                <1> 	jnc 	short _start_mainprog
    67                              <1> 
    68                              <1> _drv_not_ready_error: 
    69 00003C07 BE[429C0000]        <1> 	mov 	esi, msgl_drv_not_ready
    70 00003C0C E829000000          <1> 	call 	print_msg
    71 00003C11 EB05                <1> 	jmp 	short _end_of_mainprog
    72                              <1> 
    73                              <1> _start_mainprog:
    74 00003C13 E8620A0000          <1>         call    dos_prompt
    75                              <1>               
    76                              <1> _end_of_mainprog:
    77 00003C18 BE[7E990000]        <1>         mov     esi, msg_CRLF_temp
    78 00003C1D E818000000          <1> 	call 	print_msg
    79 00003C22 BE[84990000]        <1> 	mov 	esi, mainprog_Version
    80 00003C27 E80E000000          <1> 	call 	print_msg
    81                              <1> 	; 24/01/2016
    82 00003C2C 28E4                <1> 	sub	ah, ah
    83 00003C2E E8B4CFFFFF          <1> 	call	int16h ; call getch
    84 00003C33 E971D4FFFF          <1> 	jmp	cpu_reset
    85                              <1> 
    86 00003C38 EBFE                <1> infinitiveloop: jmp short infinitiveloop
    87                              <1> 
    88                              <1> 
    89                              <1> print_msg:
    90                              <1> 	; 04/01/2016
    91                              <1> 	; 01/07/2015
    92                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
    93                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
    94                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI, EDI)
    95                              <1> 	;
    96 00003C3A AC                  <1> 	lodsb
    97                              <1> pmsg1:
    98 00003C3B 56                  <1> 	push 	esi
    99 00003C3C 0FB61D[18A80000]    <1> 	movzx	ebx, byte [ACTIVE_PAGE] ; 04/01/2016 (ptty)
   100 00003C43 B407                <1> 	mov	ah, 07h ; Black background, light gray forecolor
   101 00003C45 E86CDBFFFF          <1> 	call 	WRITE_TTY
   102 00003C4A 5E                  <1> 	pop	esi
   103 00003C4B AC                  <1> 	lodsb
   104 00003C4C 20C0                <1> 	and 	al, al
   105 00003C4E 75EB                <1> 	jnz 	short pmsg1
   106 00003C50 C3                  <1> 	retn
   107                              <1> 
   108                              <1> clear_screen:
   109                              <1> 	; 30/01/2016
   110                              <1> 	; 24/01/2016
   111                              <1> 	; 04/01/2016
   112 00003C51 0FB61D[18A80000]    <1> 	movzx	ebx, byte [ACTIVE_PAGE] ; video page number (0 to 7)
   113 00003C58 8AA3[30A20000]      <1> 	mov 	ah, [ebx+vmode] ; default = 03h (80x25 text)
   114 00003C5E 80FC04              <1> 	cmp	ah, 4
   115 00003C61 7205                <1> 	jb	short cls1
   116 00003C63 80FC07              <1> 	cmp	ah, 7
   117 00003C66 7524                <1> 	jne	short vga_clear
   118                              <1> cls1:
   119 00003C68 3A25[16A20000]      <1> 	cmp	ah, [CRT_MODE] ; current video mode ? 
   120                              <1> 	;je	short cls2 ; yes (current video mode = 3)
   121                              <1> 	;;call	set_mode_3 ; set video mode to 3 (& clear screen)
   122                              <1> 	;;retn
   123                              <1> 	;jmp	set_mode_3
   124 00003C6E 0F8554D8FFFF        <1> 	jne	set_mode_3
   125                              <1> cls2:
   126 00003C74 B407                <1> 	mov	ah, 07h ; attribute to be used on blanked line
   127 00003C76 28C0                <1> 	sub 	al, al ; 0 =  entire window
   128 00003C78 6631C9              <1> 	xor 	cx, cx
   129 00003C7B 66BA4F18            <1> 	mov 	dx, 184Fh
   130 00003C7F E888D9FFFF          <1> 	call	_scroll_up ; 24/01/2016
   131                              <1> 	;
   132                              <1> 	;mov	bl, [ACTIVE_PAGE] ; video page number (0 to 7)
   133 00003C84 6631D2              <1> 	xor 	dx, dx
   134 00003C87 E8BEDBFFFF          <1> 	call	_set_cpos ; 24/01/2016 
   135                              <1> 	;retn
   136                              <1> vga_clear:
   137 00003C8C C3                  <1> 	retn	
   138                              <1> 
   139                              <1> panic:
   140                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
   141                              <1> 	; 07/03/2014 (Retro UNIX 8086 v1)
   142 00003C8D BE[C9A40000]        <1> 	mov 	esi, panic_msg
   143 00003C92 E8A3FFFFFF          <1> 	call 	print_msg
   144                              <1> key_to_reboot:
   145                              <1>         ; 24/01/2016
   146 00003C97 28E4                <1>         sub     ah, ah
   147 00003C99 E849CFFFFF          <1>         call    int16h ; call   getch
   148                              <1>         ; wait for a character from the current tty
   149                              <1> 	;
   150 00003C9E B00A                <1> 	mov	al, 0Ah
   151 00003CA0 8A1D[18A80000]      <1> 	mov	bl, [ptty] ; [ACTIVE_PAGE]
   152 00003CA6 B407                <1> 	mov	ah, 07h ; Black background, 
   153                              <1> 			; light gray forecolor
   154 00003CA8 E809DBFFFF          <1> 	call 	WRITE_TTY
   155 00003CAD E9F7D3FFFF          <1> 	jmp	cpu_reset 
   156                              <1> 
   157                              <1> ctrlbrk:
   158                              <1> 	; 12/11/2015
   159                              <1> 	; 13/03/2015 (Retro UNIX 386 v1)
   160                              <1> 	; 06/12/2013 (Retro UNIX 8086 v1)
   161                              <1> 	;
   162                              <1> 	; INT 1Bh (control+break) handler		
   163                              <1> 	;
   164                              <1>       	; Retro Unix 8086 v1 feature only!
   165                              <1>       	;
   166 00003CB2 66833D[04B80000]00  <1> 	cmp 	word [u.intr], 0
   167 00003CBA 7645                <1> 	jna 	short cbrk4
   168                              <1> cbrk0:
   169                              <1> 	; 12/11/2015
   170                              <1> 	; 06/12/2013
   171 00003CBC 66833D[06B80000]00  <1> 	cmp 	word [u.quit], 0
   172 00003CC4 743B                <1> 	jz	short cbrk4
   173                              <1> 	;
   174                              <1> 	; 20/09/2013	
   175 00003CC6 6650                <1> 	push 	ax
   176 00003CC8 A0[18A80000]        <1> 	mov	al, [ptty]
   177                              <1> 	;
   178                              <1> 	; 12/11/2015
   179                              <1> 	;
   180                              <1> 	; ctrl+break (EOT, CTRL+D) from serial port
   181                              <1> 	; or ctrl+break from console (pseudo) tty
   182                              <1> 	; (!redirection!)
   183                              <1> 	;
   184 00003CCD 3C08                <1> 	cmp	al, 8 ; serial port tty nums > 7
   185 00003CCF 7211                <1>         jb      short cbrk1 ; console (pseudo) tty
   186                              <1> 	;	
   187                              <1> 	; Serial port interrupt handler sets [ptty]
   188                              <1> 	; to the port's tty number (as temporary).
   189                              <1> 	;
   190                              <1> 	; If active process is using a stdin or 
   191                              <1> 	; stdout redirection (by the shell),
   192                              <1>         ; console tty keyboard must be available
   193                              <1> 	; to terminate running process,
   194                              <1> 	; in order to prevent a deadlock. 
   195                              <1> 	;
   196 00003CD1 52                  <1> 	push	edx
   197 00003CD2 0FB615[0FB80000]    <1> 	movzx	edx, byte [u.uno]
   198 00003CD9 3A82[13B50000]      <1> 	cmp     al, [edx+p.ttyc-1] ; console tty (rw)
   199 00003CDF 5A                  <1> 	pop	edx
   200 00003CE0 7412                <1> 	je	short cbrk2
   201                              <1> cbrk1:
   202 00003CE2 FEC0                <1> 	inc 	al  ; [u.ttyp] : 1 based tty number
   203                              <1> 	; 06/12/2013
   204 00003CE4 3A05[F0B70000]      <1> 	cmp	al, [u.ttyp] ; recent open tty (r)
   205 00003CEA 7408                <1> 	je	short cbrk2	
   206 00003CEC 3A05[F1B70000]      <1>         cmp     al, [u.ttyp+1] ; recent open tty (w)
   207 00003CF2 750B                <1> 	jne	short cbrk3	
   208                              <1> cbrk2:
   209                              <1> 	;; 06/12/2013
   210                              <1> 	;mov	ax, [u.quit]
   211                              <1> 	;and	ax, ax
   212                              <1> 	;jz	short cbrk3
   213                              <1> 	;
   214 00003CF4 6631C0              <1> 	xor	ax, ax ; 0
   215 00003CF7 6648                <1> 	dec	ax
   216                              <1> 	; 0FFFFh = 'ctrl+brk' keystroke
   217 00003CF9 66A3[06B80000]      <1> 	mov	[u.quit], ax
   218                              <1> cbrk3:
   219 00003CFF 6658                <1> 	pop	ax
   220                              <1> cbrk4:
   221 00003D01 C3                  <1> 	retn
  1914                                  %include 'trdosk2.s' ; 04/01/2016
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - DRV INIT : trdosk2.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 29/02/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 04/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    11                              <1> ; TRDOS2.ASM (09/11/2011)
    12                              <1> ; ****************************************************************************
    13                              <1> ; DRV_INIT.ASM (c) 2009-2011 Erdogan TAN  [26/09/2009] Last Update: 07/08/2011
    14                              <1> ;
    15                              <1> 
    16                              <1> ldrv_init: ; Logical Drive Initialization
    17                              <1> 	; 12/02/2016
    18                              <1> 	; 06/01/2016
    19                              <1> 	;  	('diskinit.inc', 'diskio.inc' integration)
    20                              <1> 	; 04/01/2016 (TRDOS 386 = TRDOS v2.0)
    21                              <1> 	; 07/08/2011
    22                              <1> 	; 20/09/2009
    23                              <1> 	; 2005
    24 00003D02 0FB60D[88A80000]    <1> 	movzx	ecx, byte [HF_NUM] ; number of fixed disks
    25 00003D09 80F901              <1> 	cmp	cl, 1
    26 00003D0C 7301                <1> 	jnb	short load_hd_partition_tables
    27                              <1> 	; No hard disks
    28 00003D0E C3                  <1> 	retn
    29                              <1> load_hd_partition_tables:
    30 00003D0F 8B35[8CA80000]      <1> 	mov	esi, [HDPM_TBL_VEC] ; primary master disk FDPT
    31 00003D15 BF[AEAC0000]        <1> 	mov 	edi, PTable_hd0
    32 00003D1A B280                <1> 	mov 	dl, 80h
    33                              <1> load_next_hd_partition_table:
    34 00003D1C 51                  <1> 	push	ecx
    35 00003D1D 57                  <1> 	push	edi
    36 00003D1E 56                  <1> 	push	esi ; FDPT (+ DPTE) address
    37 00003D1F 8A4614              <1> 	mov	al, [esi+20] ; DPTE offset 4
    38 00003D22 2440                <1> 	and	al, 40h ;  LBA bit (bit 6)
    39                              <1> 	;shr	al, 6
    40 00003D24 A2[AEAE0000]        <1> 	mov 	[HD_LBA_yes], al
    41 00003D29 E81C040000          <1> 	call	load_masterboot
    42 00003D2E 7275                <1> 	jc	short pass_pt_this_hard_disk
    43                              <1> 
    44 00003D30 BE[6CAC0000]        <1> 	mov	esi, PartitionTable
    45 00003D35 89F3                <1> 	mov	ebx, esi
    46                              <1> 	;mov	ecx, 16
    47 00003D37 B110                <1> 	mov	cl, 16
    48 00003D39 F3A5                <1> 	rep 	movsd
    49 00003D3B 89DE                <1> 	mov 	esi, ebx 
    50 00003D3D C605[BDA20000]04    <1> 	mov 	byte [hdc], 4 ; 4 - partition index
    51                              <1> loc_validate_hdp_partition:
    52 00003D44 807E0400            <1> 	cmp 	byte [esi+ptFileSystemID], 0
    53 00003D48 7641                <1> 	jna	short loc_validate_next_hdp_partition2
    54 00003D4A 56                  <1> 	push	esi ; Masterboot partition table offset
    55 00003D4B 52                  <1> 	push	edx ; dl = Physical drive number 
    56 00003D4C FE05[AFAE0000]      <1> 	inc	byte [PP_Counter]
    57 00003D52 31FF                <1>         xor	edi, edi ; 0  
    58                              <1> 	; Input -> ESI = PartitionTable offset
    59                              <1> 	; DL = Hard disk drive number 
    60                              <1> 	; EDI = 0 -> Primary Partition
    61                              <1> 	; EDI > 0 -> Extended Partition's Start Sector   
    62 00003D54 E879010000          <1> 	call 	validate_hd_fat_partition
    63 00003D59 730A                <1> 	jnc 	short loc_set_valid_hdp_partition_entry
    64                              <1> 	;pop	edx
    65                              <1> 	;push	edx
    66 00003D5B 8B1424              <1> 	mov	edx, [esp] 
    67 00003D5E E8C5020000          <1> 	call	validate_hd_fs_partition
    68 00003D63 7224                <1> 	jc	short loc_validate_next_hdp_partition1
    69                              <1> loc_set_valid_hdp_partition_entry:
    70 00003D65 8A0D[7C990000]      <1> 	mov 	cl, [Last_DOS_DiskNo] 
    71 00003D6B 80C141              <1> 	add 	cl, 'A'
    72                              <1> 	; ESI = Logical dos drive description table address
    73 00003D6E 880E                <1> 	mov	[esi+LD_Name], cl
    74 00003D70 8A6602              <1> 	mov	ah, [esi+LD_PhyDrvNo]
    75 00003D73 88E0                <1> 	mov	al, ah ; Physical drive number
    76 00003D75 2C80                <1> 	sub	al, 80h
    77 00003D77 C0E002              <1> 	shl	al, 2
    78 00003D7A 0404                <1> 	add	al, 4 ; 0 Based
    79 00003D7C 2A05[BDA20000]      <1> 	sub	al, [hdc] ; 4 - partition index
    80                              <1> 	; AL = Partition entry/index, 0 based
    81                              <1> 	;  0 -> hd 0, Partition Table offset = 0
    82                              <1> 	; 15 -> hd 3, Partition Table offset = 3
    83                              <1> 	;mov	[esi+LD_PartitionEntry], al 
    84 00003D82 80EC7E              <1> 	sub 	ah, 7Eh
    85                              <1> 	; AH = Physical drive index, zero based
    86                              <1> 	;  0 for drive A:, 2 for drive C:
    87                              <1> 	;mov 	[esi+LD_DParamEntry], ah 
    88 00003D85 6689467C            <1> 	mov 	[esi+LD_PartitionEntry], ax
    89                              <1> loc_validate_next_hdp_partition1:
    90 00003D89 5A                  <1> 	pop 	edx ; dl = Physical drive number 
    91 00003D8A 5E                  <1> 	pop	esi ; Masterboot partition table offset
    92                              <1> loc_validate_next_hdp_partition2:
    93                              <1> 	; ESI = PartitionTable offset
    94                              <1> 	; DL = Hard/Fixed disk drive number
    95 00003D8B FE0D[BDA20000]      <1> 	dec	byte [hdc] ; 4 - partition index
    96 00003D91 7412                <1> 	jz	short pass_pt_this_hard_disk
    97 00003D93 83C610              <1> 	add	esi, 16 ; 10h
    98 00003D96 EBAC                <1> 	jmp	short loc_validate_hdp_partition
    99                              <1> loc_next_hd_partition_table:
   100 00003D98 FEC2                <1> 	inc	dl
   101 00003D9A 83C620              <1> 	add	esi, 32 ; next FDPT address
   102 00003D9D 83C740              <1> 	add	edi, 64 ; next partition table destination
   103 00003DA0 E977FFFFFF          <1>         jmp     load_next_hd_partition_table
   104                              <1> pass_pt_this_hard_disk:
   105 00003DA5 5E                  <1> 	pop	esi ; FDPT (+ DPTE) address
   106 00003DA6 5F                  <1> 	pop	edi ; Ptable_hd?
   107 00003DA7 59                  <1> 	pop	ecx
   108 00003DA8 E2EE                <1> 	loop	loc_next_hd_partition_table
   109 00003DAA 803D[AFAE0000]01    <1> 	cmp	byte [PP_Counter], 1
   110 00003DB1 7301                <1> 	jnb	short load_extended_dos_partitions
   111                              <1> 	; Empty partition table
   112 00003DB3 C3                  <1> 	retn 
   113                              <1> load_extended_dos_partitions:
   114 00003DB4 BE[AEAC0000]        <1> 	mov	esi, PTable_hd0
   115 00003DB9 BF[AEAD0000]        <1> 	mov	edi, PTable_ep0
   116 00003DBE C605[BDA20000]80    <1> 	mov	byte [hdc], 80h
   117                              <1> next_hd_extd_partition:
   118 00003DC5 56                  <1> 	push	esi ; PTable_hd? offset
   119 00003DC6 57                  <1> 	push	edi ; PTable_ep?
   120                              <1> 	;mov	ecx, 4
   121 00003DC7 B104                <1> 	mov	cl, 4
   122 00003DC9 8A15[BDA20000]      <1> 	mov	dl, byte [hdc]
   123                              <1> hd_check_fs_id_05h:
   124 00003DCF 8A4604              <1> 	mov	al, [esi+ptFileSystemID]
   125 00003DD2 3C05                <1> 	cmp	al, 05h ; Is it an extended dos partition ?
   126 00003DD4 7404                <1> 	je	short loc_set_ep_start_sector
   127 00003DD6 3C0F                <1> 	cmp	al, 0Fh ; Is it an extended win4 (LBA mode) partition ?
   128 00003DD8 7546                <1> 	jne	short continue_to_check_ep
   129                              <1> loc_set_ep_start_sector:
   130 00003DDA FE05[B0AE0000]      <1> 	inc	byte [EP_Counter]
   131 00003DE0 88D4                <1> 	mov	ah, dl ; byte [hdc]
   132 00003DE2 86E0                <1> 	xchg	ah, al ; al = Drv Number, ah = Partition Identifier
   133 00003DE4 50                  <1> 	push	eax 
   134 00003DE5 30E4                <1> 	xor	ah, ah  
   135 00003DE7 2C80                <1> 	sub	al, 80h
   136 00003DE9 50                  <1> 	push	eax
   137 00003DEA C0E002              <1> 	shl	al, 2 ; al = al * 4
   138 00003DED 0FB6D8              <1> 	movzx	ebx, al
   139 00003DF0 81C3[B1AE0000]      <1> 	add	ebx, EP_StartSector
   140 00003DF6 8B4608              <1> 	mov	eax, [esi+ptStartSector]
   141                              <1>         ; EAX = Extended partition's start sector
   142 00003DF9 8903                <1>         mov	[ebx], eax
   143 00003DFB 58                  <1> 	pop	eax ; AL = Drv number - 80h, AH = 0 
   144 00003DFC 5A                  <1> 	pop	edx ; DL = Drv number, DH = Partition ID
   145 00003DFD BB[AEAA0000]        <1> 	mov	ebx, MasterBootBuff
   146 00003E02 803D[AEAE0000]01    <1> 	cmp	byte [HD_LBA_yes], 1 ; LBA ready = Yes
   147 00003E09 7240                <1> 	jb	short loc_hd_load_ep_05h
   148 00003E0B 80FE05              <1> 	cmp	dh, 05h
   149 00003E0E 743B                <1> 	je	short loc_hd_load_ep_05h
   150                              <1> loc_hd_load_ep_0Fh:
   151                              <1> 	; 04/01/2016
   152 00003E10 51                  <1> 	push	ecx
   153 00003E11 8B4E08              <1> 	mov	ecx, [esi+ptStartSector] ; sector number
   154                              <1> 	;mov	ebx, MasterBootBuff ; buffer address
   155                              <1> 	; LBA read/write (with private LBA function) 
   156                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
   157                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
   158 00003E14 B41B                <1> 	mov	ah, 1Bh ; LBA read
   159 00003E16 B001                <1> 	mov	al, 1 ; sector count
   160 00003E18 E8AEEAFFFF          <1> 	call	int13h
   161 00003E1D 59                  <1> 	pop	ecx
   162 00003E1E 733F                <1> 	jnc	short loc_hd_move_ep_table
   163                              <1> continue_to_check_ep:
   164 00003E20 83C610              <1> 	add	esi, 16
   165 00003E23 E2AA                <1> 	loop	hd_check_fs_id_05h
   166                              <1> continue_check_ep_next_disk:
   167 00003E25 5F                  <1> 	pop	edi ; PTable_ep?
   168 00003E26 5E                  <1> 	pop	esi ; PTable_hd?
   169 00003E27 A0[88A80000]        <1> 	mov	al, [HF_NUM] ; number of hard disks
   170 00003E2C 047F                <1> 	add	al, 7Fh
   171 00003E2E 3805[BDA20000]      <1> 	cmp	[hdc], al
   172 00003E34 0F8392000000        <1> 	jnb	loc_validating_hd_partitions_ok
   173 00003E3A 83C640              <1> 	add	esi, 64
   174 00003E3D 83C740              <1> 	add	edi, 64
   175 00003E40 FE05[BDA20000]      <1> 	inc	byte [hdc]
   176 00003E46 E97AFFFFFF          <1> 	jmp	next_hd_extd_partition
   177                              <1> loc_hd_load_ep_05h:
   178 00003E4B 51                  <1> 	push	ecx 
   179 00003E4C 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   180 00003E4F 668B4E02            <1>         mov     cx, word [esi+ptBeginSector]
   181 00003E53 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   182                              <1> 	;mov	ebx, MasterBootBuff
   183 00003E57 E86FEAFFFF          <1> 	call	int13h
   184 00003E5C 59                  <1> 	pop	ecx  
   185 00003E5D 72C1                <1> 	jc	short continue_to_check_ep
   186                              <1> loc_hd_move_ep_table:
   187                              <1>         ;pop	edi
   188                              <1> 	;push	edi  ; PTable_ep?
   189 00003E5F 8B3C24              <1> 	mov	edi, [esp]        
   190 00003E62 BE[6CAC0000]        <1>         mov	esi, PartitionTable ; Extended
   191 00003E67 89F3                <1> 	mov	ebx, esi
   192                              <1> 	;mov	ecx, 16
   193 00003E69 B110                <1> 	mov	cl, 16
   194 00003E6B F3A5                <1>        	rep	movsd
   195 00003E6D 89DE                <1> 	mov	esi, ebx 
   196                              <1> loc_set_hde_sub_partition_count:
   197 00003E6F C605[AFAE0000]04    <1> 	mov	byte [PP_Counter], 4
   198                              <1> loc_validate_hde_partition:
   199 00003E76 807E0400            <1> 	cmp	byte [esi+ptFileSystemID], 0
   200 00003E7A 763F                <1> 	jna	short loc_validate_next_hde_partition2
   201 00003E7C 56                  <1> 	push	esi ; Extended partition table offset
   202 00003E7D 8A15[BDA20000]      <1> 	mov	dl, byte [hdc]
   203 00003E83 0FB6C2              <1> 	movzx	eax, dl
   204 00003E86 2C80                <1> 	sub	al, 80h
   205 00003E88 C0E002              <1> 	shl	al, 2
   206                              <1> 	; 06/01/2016 
   207                              <1> 	; (TRDOS v1.0 had a bug here, in 'DRV_INIT.ASM')
   208                              <1> 	; BUGFIX *
   209                              <1> 	;mov	ecx, eax
   210 00003E8B 88C1                <1> 	mov	cl, al
   211 00003E8D 80C104              <1> 	add	cl, 4
   212 00003E90 2A0D[AFAE0000]      <1> 	sub	cl, [PP_Counter] ; 4 to 1
   213                              <1> 	; CL = Partition entry/index, 0 based
   214                              <1>         ;  0 -> hd 0, Partition Table offset = 0
   215                              <1>         ; 15 -> hd 3, Partition Table offset = 3
   216 00003E96 88D5                <1>       	mov	ch, dl   
   217 00003E98 80ED7E              <1> 	sub	ch, 7Eh ;
   218                              <1> 	; CH = Physical drive index, zero based
   219                              <1> 	;  0 for drive A:, 2 for drive C:	
   220                              <1> 	; BUGFIX *
   221 00003E9B 51                  <1> 	push	ecx ; *
   222 00003E9C BF[B1AE0000]        <1> 	mov	edi, EP_StartSector
   223 00003EA1 01C7                <1> 	add	edi, eax
   224                              <1> 	; Input -> ESI = PartitionTable offset
   225                              <1> 	; DL = Hard disk drive number   
   226                              <1> 	; EDI = Extended partition start sector pointer
   227 00003EA3 E82A000000          <1> 	call	validate_hd_fat_partition
   228 00003EA8 59                  <1> 	pop	ecx ; *
   229 00003EA9 720F                <1> 	jc	short loc_validate_next_hde_partition1
   230                              <1> loc_set_valid_hde_partition_entry:
   231                              <1> 	; 06/01/2016 (TRDOS v2.0)
   232                              <1> 	; BUGFIX *
   233                              <1> 	;mov	[esi+LD_PartitionEntry], cl 
   234                              <1> 	;mov	[esi+LD_DParamEntry], ch 
   235 00003EAB 66894E7C            <1> 	mov	[esi+LD_PartitionEntry], cx 
   236                              <1> 	;
   237 00003EAF 8A0D[7C990000]      <1> 	mov	cl, [Last_DOS_DiskNo] 
   238 00003EB5 80C141              <1> 	add	cl, 'A'
   239 00003EB8 880E                <1> 	mov	[esi+LD_Name], cl
   240                              <1> loc_validate_next_hde_partition1:
   241 00003EBA 5E                  <1> 	pop	esi ; Extended partition table offset
   242                              <1> loc_validate_next_hde_partition2:
   243                              <1> 	; ESI = Extended partition table offset
   244                              <1> 	; DL = Hard disk drive number
   245 00003EBB FE0D[AFAE0000]      <1> 	dec	byte [PP_Counter]
   246 00003EC1 0F845EFFFFFF        <1> 	jz	continue_check_ep_next_disk
   247 00003EC7 83C610              <1> 	add 	esi, 16 ; 10h
   248 00003ECA EBAA                <1> 	jmp	short loc_validate_hde_partition
   249                              <1> loc_validating_hd_partitions_ok:
   250 00003ECC A0[7C990000]        <1> 	mov	al, [Last_DOS_DiskNo]
   251                              <1> loc_drv_init_retn:
   252 00003ED1 C3                  <1> 	retn
   253                              <1> 
   254                              <1> validate_hd_fat_partition:
   255                              <1> 	; 12/02/2016
   256                              <1> 	; 07/01/2016 (TRDOS 386 = TRDOS v2.0)
   257                              <1> 	; 07/08/2011
   258                              <1> 	; 23/07/2011
   259                              <1> 	; Input
   260                              <1> 	;   DL = Hard/Fixed Disk Drive Number
   261                              <1> 	;   ESI = PartitionTable offset
   262                              <1> 	;   EDI = Extend. Part. Start Sector Pointer
   263                              <1> 	;   EDI = 0 -> Primary Partition 
   264                              <1> 	;   byte [Last_DOS_DiskNo]
   265                              <1>  	; Output
   266                              <1> 	;  cf=0 -> Validated
   267                              <1> 	;   ESI = Logical dos drv desc. table
   268                              <1> 	;   EBX = FAT boot sector buffer
   269                              <1> 	;   byte [Last_DOS_DiskNo]
   270                              <1> 	;  cf=1 -> Not a valid FAT partition
   271                              <1> 	; EAX, EDX, ECX, EDI -> changed 
   272                              <1> 	
   273                              <1> 	;mov 	esi, PartitionTable
   274 00003ED2 8A6604              <1> 	mov 	ah, [esi+ptFileSystemID]
   275 00003ED5 80FC06              <1> 	cmp 	ah, 06h ; FAT16 CHS partition
   276                              <1> 	; 12/02/2016
   277                              <1> 	;jb	short loc_not_a_valid_fat_partition2
   278 00003ED8 7305                <1>  	jnb	short vhdp_FAT16_32
   279                              <1> 	;
   280 00003EDA 80FC04              <1> 	cmp	ah, 04h ; FAT16 CHS partition (< 32MB)		
   281 00003EDD 7519                <1> 	jne	short loc_not_a_valid_fat_partition1
   282                              <1> vhdp_FAT16_32:
   283 00003EDF B002                <1> 	mov	al, 2
   284 00003EE1 7417                <1> 	je	short loc_set_valid_hd_partition_params
   285 00003EE3 80FC0E              <1> 	cmp	ah, 0Eh ; FAT16 LBA partition
   286 00003EE6 7710                <1> 	ja	short loc_not_a_valid_fat_partition1
   287 00003EE8 7410                <1> 	je	short loc_set_valid_hd_partition_params
   288                              <1> 
   289 00003EEA FEC0                <1> 	inc	al ; 3
   290 00003EEC 80FC0B              <1> 	cmp	ah, 0Bh ; FAT32 CHS partition 
   291 00003EEF 7409                <1> 	je	short loc_set_valid_hd_partition_params
   292 00003EF1 7206                <1> 	jb	short loc_not_a_valid_fat_partition2
   293 00003EF3 80FC0C              <1> 	cmp	ah, 0Ch ; FAT32 LBA partition
   294 00003EF6 7402                <1> 	je	short loc_set_valid_hd_partition_params
   295                              <1> loc_not_a_valid_fat_partition1:
   296 00003EF8 F9                  <1> 	stc
   297                              <1> loc_not_a_valid_fat_partition2:
   298 00003EF9 C3                  <1> 	retn
   299                              <1> 
   300                              <1> loc_set_valid_hd_partition_params:
   301 00003EFA FE05[7C990000]      <1> 	inc 	byte [Last_DOS_DiskNo] ; > 1
   302                              <1> 	;
   303 00003F00 31DB                <1> 	xor	ebx, ebx
   304 00003F02 8A3D[7C990000]      <1> 	mov	bh, [Last_DOS_DiskNo] ; * 256	
   305 00003F08 81C300010900        <1> 	add	ebx, Logical_DOSDisks
   306                              <1> 	;
   307 00003F0E C6430102            <1> 	mov	byte [ebx+LD_DiskType], 2
   308 00003F12 885302              <1> 	mov	byte [ebx+LD_PhyDrvNo], dl
   309                              <1> 	;mov	byte [ebx+LD_FATType], al ; 2 or 3
   310                              <1> 	;mov	byte [ebx+LD_FSType], ah ; 06h, 0Eh, 0Bh, 0Ch
   311 00003F15 66894303            <1> 	mov	word [ebx+LD_FATType], ax
   312                              <1> 	;
   313 00003F19 8B4E08              <1> 	mov	ecx, [esi+ptStartSector]
   314 00003F1C 09FF                <1> 	or	edi, edi 
   315 00003F1E 7402                <1> 	jz	short pass_hd_FAT_ep_start_sector_adding
   316                              <1> loc_add_hd_FAT_ep_start_sector:
   317 00003F20 030F                <1> 	add	ecx, [edi]
   318                              <1> pass_hd_FAT_ep_start_sector_adding:
   319 00003F22 894B6C              <1> 	mov	[ebx+LD_StartSector], ecx
   320                              <1> loc_hd_FAT_logical_drv_init:
   321 00003F25 89DD                <1> 	mov	ebp, ebx
   322                              <1> 	;mov	dl, [ebx+LD_PhyDrvNo]
   323 00003F27 A0[AEAE0000]        <1> 	mov	al, [HD_LBA_yes] ; 07/01/2016
   324 00003F2C 884305              <1> 	mov	[ebx+LD_LBAYes], al
   325 00003F2F BB[C1AE0000]        <1> 	mov	ebx, DOSBootSectorBuff ; buffer address
   326 00003F34 08C0                <1> 	or	al, al
   327 00003F36 740C                <1> 	jz	short loc_hd_FAT_drv_init_load_bs_chs
   328                              <1> loc_hd_FAT_drv_init_load_bs_lba:
   329                              <1> 	; DL = Physical drive number
   330                              <1>    	;mov	ecx, [esi+ptStartSector] ; sector number
   331                              <1> 	;mov	ebx, DOSBootSectorBuff ; buffer address
   332                              <1> 	; LBA read/write (with private LBA function) 
   333                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
   334                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
   335 00003F38 B41B                <1> 	mov	ah, 1Bh ; LBA read
   336 00003F3A B001                <1> 	mov	al, 1 ; sector count
   337 00003F3C E88AE9FFFF          <1> 	call	int13h
   338 00003F41 7313                <1> 	jnc	short loc_hd_drv_FAT_boot_validation
   339                              <1> loc_not_a_valid_fat_partition3:
   340 00003F43 C3                  <1> 	retn
   341                              <1> loc_hd_FAT_drv_init_load_bs_chs:
   342 00003F44 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   343 00003F47 668B4E02            <1> 	mov	cx, [esi+ptBeginSector]
   344 00003F4B 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   345                              <1> 	;mov	ebx, DOSBootSectorBuff
   346 00003F4F E877E9FFFF          <1> 	call	int13h
   347 00003F54 72ED                <1> 	jc	short loc_not_a_valid_fat_partition3
   348                              <1> loc_hd_drv_FAT_boot_validation:
   349                              <1> 	;mov	esi, DOSBootSectorBuff
   350 00003F56 89DE                <1> 	mov	esi, ebx
   351 00003F58 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
   352 00003F61 751A                <1> 	jne	short loc_not_a_valid_fat_partition4
   353 00003F63 807E15F8            <1> 	cmp	byte [esi+BPB_Media], 0F8h
   354 00003F67 7514                <1> 	jne	short loc_not_a_valid_fat_partition4
   355 00003F69 66837E1600          <1> 	cmp	word [esi+BPB_FATSz16], 0
   356 00003F6E 770F                <1> 	ja	short loc_hd_FAT16_BPB
   357 00003F70 807E4229            <1> 	cmp	byte [esi+BS_FAT32_BootSig], 29h
   358 00003F74 7507                <1> 	jne	short loc_not_a_valid_fat_partition4
   359                              <1> loc_hd_FAT32_BPB:
   360 00003F76 B92D000000          <1> 	mov	ecx, 45
   361 00003F7B EB0D                <1> 	jmp	short loc_hd_move_FAT_BPB
   362                              <1> 	;
   363                              <1> loc_not_a_valid_fat_partition4:
   364 00003F7D F9                  <1> 	stc
   365 00003F7E C3                  <1> 	retn
   366                              <1> 	;
   367                              <1> loc_hd_FAT16_BPB:
   368 00003F7F 807E2629            <1> 	cmp	byte [esi+BS_BootSig], 29h
   369 00003F83 75F8                <1> 	jne	short loc_not_a_valid_fat_partition4
   370 00003F85 B920000000          <1> 	mov	ecx, 32
   371                              <1> loc_hd_move_FAT_BPB:
   372 00003F8A 89EF                <1> 	mov 	edi, ebp
   373                              <1> 	;mov	esi, ebx ; Boot sector
   374 00003F8C 57                  <1> 	push	edi
   375 00003F8D 83C706              <1> 	add	edi, LD_BPB
   376 00003F90 F366A5              <1> 	rep	movsw 
   377 00003F93 5E                  <1> 	pop	esi
   378 00003F94 0FB74614            <1> 	movzx	eax, word [esi+LD_BPB+BPB_RsvdSecCnt]
   379 00003F98 03466C              <1> 	add	eax, [esi+LD_StartSector]
   380 00003F9B 894660              <1> 	mov	[esi+LD_FATBegin], eax
   381 00003F9E 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3
   382 00003FA2 7224                <1> 	jb	short loc_set_FAT16_RootDirLoc
   383                              <1> loc_set_FAT32_RootDirLoc:
   384 00003FA4 8B462A              <1> 	mov	eax, [esi+LD_BPB+BPB_FATSz32]
   385 00003FA7 0FB65E16            <1>         movzx	ebx, byte [esi+LD_BPB+BPB_NumFATs]
   386 00003FAB F7E3                <1> 	mul	ebx
   387 00003FAD 034660              <1> 	add	eax, [esi+LD_FATBegin]
   388                              <1> loc_set_FAT32_data_begin:
   389 00003FB0 894668              <1> 	mov	[esi+LD_DATABegin], eax
   390 00003FB3 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
   391                              <1> 	; If Root Directory Cluster <> 2 then
   392                              <1> 	; change the beginning sector value 
   393                              <1> 	; of the root dir by adding sector offset.
   394 00003FB6 8B4632              <1> 	mov	eax, [esi+LD_BPB+BPB_RootClus]
   395 00003FB9 83E802              <1> 	sub	eax, 2
   396 00003FBC 7442                <1> 	jz	short short loc_set_32bit_FAT_total_sectors  
   397                              <1> 	;movzx	ebx, byte [esi+LD_BPB+BPB_SecPerClust]
   398 00003FBE 8A5E13              <1> 	mov	bl, byte [esi+LD_BPB+BPB_SecPerClust] 
   399 00003FC1 F7E3                <1> 	mul	ebx
   400 00003FC3 014664              <1> 	add	[esi+LD_ROOTBegin], eax
   401 00003FC6 EB38                <1> 	jmp	short loc_set_32bit_FAT_total_sectors
   402                              <1> 	;
   403                              <1> loc_set_FAT16_RootDirLoc:
   404 00003FC8 0FB64616            <1> 	movzx	eax, byte [esi+LD_BPB+BPB_NumFATs]
   405 00003FCC 0FB7561C            <1> 	movzx	edx, word [esi+LD_BPB+BPB_FATSz16]
   406 00003FD0 F7E2                <1> 	mul	edx
   407 00003FD2 034660              <1> 	add	eax, [esi+LD_FATBegin]  
   408 00003FD5 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
   409                              <1> loc_set_FAT16_data_begin:
   410 00003FD8 894668              <1> 	mov	[esi+LD_DATABegin], eax 
   411 00003FDB B820000000          <1> 	mov	eax, 20h  ; Size of a directory entry
   412                              <1> 	;movzx	edx, word [esi+LD_BPB+BPB_RootEntCnt]
   413 00003FE0 668B5617            <1>         mov     dx, [esi+LD_BPB+BPB_RootEntCnt]
   414 00003FE4 F7E2                <1>         mul	edx
   415                              <1> 	;mov	ecx, 511
   416 00003FE6 66B9FF01            <1> 	mov	cx, 511
   417 00003FEA 01C8                <1> 	add	eax, ecx
   418 00003FEC 41                  <1> 	inc	ecx ; 512
   419 00003FED F7F1                <1> 	div	ecx
   420 00003FEF 014668              <1> 	add	[esi+LD_DATABegin], eax
   421 00003FF2 0FB74619            <1> 	movzx	eax, word [esi+LD_BPB+BPB_TotalSec16]
   422 00003FF6 6685C0              <1> 	test	ax, ax
   423 00003FF9 7405                <1> 	jz	short loc_set_32bit_FAT_total_sectors
   424                              <1> loc_set_16bit_FAT_total_sectors:
   425 00003FFB 894670              <1> 	mov	[esi+LD_TotalSectors], eax
   426 00003FFE EB06                <1> 	jmp	short loc_set_hd_FAT_cluster_count
   427                              <1> loc_set_32bit_FAT_total_sectors:
   428 00004000 8B4626              <1> 	mov	eax, [esi+LD_BPB+BPB_TotalSec32]
   429 00004003 894670              <1> 	mov	[esi+LD_TotalSectors], eax
   430                              <1> loc_set_hd_FAT_cluster_count:
   431 00004006 8B5668              <1> 	mov	edx, [esi+LD_DATABegin]
   432 00004009 2B566C              <1> 	sub	edx, [esi+LD_StartSector]
   433 0000400C 29D0                <1> 	sub	eax, edx
   434 0000400E 31D2                <1> 	xor	edx, edx ; 0
   435 00004010 0FB64E13            <1>         movzx   ecx, byte [esi+LD_BPB+BPB_SecPerClust]
   436 00004014 F7F1                <1>         div	ecx 
   437 00004016 894678              <1> 	mov	[esi+LD_Clusters], eax
   438                              <1> 	; Maximum Valid Cluster Number= EAX +1
   439                              <1> 	; with 2 reserved clusters= EAX +2
   440                              <1> loc_set_hd_FAT_fs_free_sectors:
   441                              <1> 	;mov	dword [esi+LD_FreeSectors], 0
   442 00004019 E859010000          <1> 	call	get_free_FAT_sectors
   443 0000401E 7207                <1> 	jc	short loc_validate_hd_FAT_partition_retn
   444 00004020 894674              <1> 	mov	[esi+LD_FreeSectors], eax
   445 00004023 C6467E06            <1> 	mov	byte [esi+LD_MediaChanged], 6  ; Volume Name Reset
   446                              <1> 	;mov	cl, [Last_DOS_DiskNo] 
   447                              <1> 	;add	cl, 'A'
   448                              <1> 	;mov	[esi+LD_FS_Name], cl
   449                              <1> 
   450                              <1> loc_validate_hd_FAT_partition_retn:         
   451 00004027 C3                  <1> 	retn
   452                              <1> 
   453                              <1> validate_hd_fs_partition:
   454                              <1> 	; 13/02/2016
   455                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
   456                              <1> 	; 29/01/2011
   457                              <1> 	; 23/07/2011
   458                              <1> 	; Input
   459                              <1> 	;   DL = Hard/Fixed Disk Drive Number
   460                              <1> 	;   ESI = PartitionTable offset
   461                              <1> 	;   byte [Last_DOS_DiskNo]
   462                              <1> 	; Output
   463                              <1> 	;  cf=0 -> Validated
   464                              <1> 	;   ESI = Logical dos drv desc. table
   465                              <1> 	;   EBX = Singlix FS boot sector buffer
   466                              <1> 	;   byte [Last_DOS_DiskNo]
   467                              <1> 	;  cf=1 -> Not a valid 'Singlix FS' partition
   468                              <1> 	; EAX, EDX, ECX, EDI -> changed 
   469                              <1> 
   470                              <1> 	;mov	esi, PartitionTable
   471 00004028 8A6604              <1> 	mov	ah, [esi+ptFileSystemID]
   472 0000402B 80FCA1              <1> 	cmp	ah, 0A1h ; SINGLIX FS1 (trfs1) partition
   473 0000402E 7549                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   474                              <1> loc_set_valid_hd_fs_partition_params:
   475 00004030 FE05[7C990000]      <1> 	inc	byte [Last_DOS_DiskNo] ; > 1
   476 00004036 30C0                <1> 	xor	al, al ; mov al, 0
   477                              <1> 	;mov	[drv], dl
   478 00004038 29DB                <1> 	sub	ebx, ebx ; 0
   479 0000403A 8A3D[7C990000]      <1> 	mov	bh, [Last_DOS_DiskNo] 
   480 00004040 81C300010900        <1> 	add	ebx, Logical_DOSDisks
   481 00004046 C6430102            <1> 	mov	byte [ebx+LD_DiskType], 2
   482 0000404A 885302              <1> 	mov	[ebx+LD_PhyDrvNo], dl
   483                              <1> 	;mov	[ebx+LD_FATType], al ; 0
   484                              <1> 	;mov	[ebx+LD_FSType], ah
   485 0000404D 66894303            <1> 	mov	[ebx+LD_FATType], ax
   486                              <1> 	;mov	eax, [esi+ptStartSector]
   487                              <1> 	;mov	[ebx+LD_StartSector], eax
   488                              <1> loc_hd_fs_logical_drv_init:
   489 00004051 89DD                <1> 	mov	ebp, ebx ; 10/01/2016
   490                              <1> 	;mov	dl, [ebx+LD_PhyDrvNo]
   491 00004053 A0[AEAE0000]        <1> 	mov	al, [HD_LBA_yes] ; 10/01/2016
   492 00004058 884305              <1> 	mov	[ebx+LD_LBAYes], al
   493 0000405B 89DE                <1> 	mov	esi, ebx
   494 0000405D BB[C1AE0000]        <1> 	mov	ebx, DOSBootSectorBuff ; buffer addressh
   495 00004062 08C0                <1> 	or	al, al
   496 00004064 7515                <1> 	jnz	short loc_hd_fs_drv_init_load_bs_lba
   497                              <1> loc_hd_fs_drv_init_load_bs_chs:
   498 00004066 8A7601              <1> 	mov	dh, [esi+ptBeginHead]
   499 00004069 668B4E02            <1> 	mov	cx, [esi+ptBeginSector]
   500 0000406D 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   501                              <1> 	;mov	ebx, DOSBootSectorBuff
   502 00004071 E855E8FFFF          <1> 	call	int13h
   503 00004076 7311                <1> 	jnc	short loc_hd_drv_fs_boot_validation
   504                              <1> loc_validate_hd_fs_partition_err_retn:
   505 00004078 C3                  <1> 	retn
   506                              <1> loc_validate_hd_fs_partition_stc_retn:
   507 00004079 F9                  <1> 	stc
   508 0000407A C3                  <1> 	retn
   509                              <1> loc_hd_fs_drv_init_load_bs_lba:
   510                              <1> 	; DL = Physical drive number
   511                              <1> 	;mov	esi, ebx
   512 0000407B 8B4E08              <1>    	mov	ecx, [esi+ptStartSector] ; sector number
   513                              <1> 	;mov	ebx, DOSBootSectorBuff ; buffer address
   514                              <1> 	; LBA read/write (with private LBA function) 
   515                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
   516                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
   517 0000407E B41B                <1> 	mov	ah, 1Bh ; LBA read
   518 00004080 B001                <1> 	mov	al, 1 ; sector count
   519 00004082 E844E8FFFF          <1> 	call	int13h
   520 00004087 72EF                <1> 	jc	short loc_validate_hd_fs_partition_err_retn
   521                              <1> loc_hd_drv_fs_boot_validation:
   522                              <1> 	;mov	esi, DOSBootSectorBuff
   523 00004089 89DE                <1> 	mov	esi, ebx ; Boot sector buffer
   524 0000408B 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
   525 00004094 75E3                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   526                              <1>         ;
   527                              <1> 	;Singlix FS Extensions to TR-DOS (7/6/2009) 
   528 00004096 66817E035346        <1> 	cmp	word [esi+bs_FS_Identifier], 'SF'
   529 0000409C 75DB                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   530                              <1>         ;'A1h' check is not necessary
   531                              <1> 	;  if 'FS' check is passed as OK/Yes.
   532 0000409E 807E09A1            <1> 	cmp	byte [esi+bs_FS_PartitionID], 0A1h
   533 000040A2 75D5                <1> 	jne	short loc_validate_hd_fs_partition_stc_retn
   534                              <1> 	;
   535 000040A4 89EF                <1> 	mov	edi, ebp ; 10/01/2016
   536                              <1> 	;
   537 000040A6 8A462D              <1> 	mov	al, byte [esi+bs_FS_LBA_Ready]
   538 000040A9 884705              <1> 	mov	[edi+LD_FS_LBAYes], al
   539                              <1> 	;
   540                              <1> 	; 03/01/2010 CHS -> DOS FAT/BPB compatibility fix
   541 000040AC 8A4608              <1> 	mov	al, [esi+bs_FS_MediaAttrib]
   542 000040AF 884706              <1> 	mov	byte [edi+LD_FS_MediaAttrib], al
   543                              <1> 	;
   544 000040B2 8A460A              <1> 	mov	al, [esi+bs_FS_VersionMaj]
   545 000040B5 884707              <1> 	mov	[edi+LD_FS_VersionMajor], al
   546                              <1> 	;
   547 000040B8 668B4606            <1> 	mov	ax, [esi+bs_FS_BytesPerSec]
   548 000040BC 66894711            <1> 	mov	[edi+LD_FS_BytesPerSec], ax
   549 000040C0 8A462E              <1> 	mov	al, [esi+bs_FS_SecPerTrack]
   550 000040C3 6698                <1> 	cbw
   551 000040C5 6689471E            <1> 	mov	[edi+LD_FS_SecPerTrack], ax
   552 000040C9 8A462F              <1> 	mov	al, [esi+bs_FS_Heads]
   553                              <1> 	;cbw
   554 000040CC 66894720            <1> 	mov	[edi+LD_FS_NumHeads], ax
   555                              <1> 	;
   556 000040D0 8B4628              <1> 	mov	eax, [esi+bs_FS_UnDelDirD]
   557 000040D3 894722              <1> 	mov	[edi+LD_FS_UnDelDirD], eax
   558 000040D6 8B5618              <1> 	mov	edx, [esi+bs_FS_MATLocation]
   559 000040D9 89570C              <1> 	mov	[edi+LD_FS_MATLocation], edx
   560 000040DC 8B461C              <1> 	mov	eax, [esi+bs_FS_RootDirD]
   561 000040DF 894708              <1> 	mov	[edi+LD_FS_RootDirD], eax
   562 000040E2 8B460C              <1> 	mov	eax, [esi+bs_FS_BeginSector]
   563 000040E5 89476C              <1> 	mov	[edi+LD_FS_BeginSector], eax
   564 000040E8 8B4710              <1> 	mov	eax, [edi+bs_FS_VolumeSize]
   565 000040EB 894770              <1> 	mov	[edi+LD_FS_VolumeSize], eax
   566                              <1> 	;
   567 000040EE 89D0                <1> 	mov	eax, edx ; [edi+LD_FS_MATLocation]
   568 000040F0 03476C              <1> 	add	eax, [edi+LD_FS_BeginSector]
   569 000040F3 89FE                <1> 	mov	esi, edi
   570                              <1> mread_hd_fs_MAT_sector:
   571                              <1>        ;mov	ebx, DOSBootSectorBuff
   572 000040F5 B901000000          <1> 	mov	ecx, 1
   573 000040FA E844550000          <1> 	call	disk_read
   574 000040FF 7248                <1> 	jc	short loc_validate_hd_fs_partition_retn
   575                              <1> 	; EDI will not be changed
   576 00004101 89DE                <1> 	mov	esi, ebx
   577                              <1> use_hdfs_mat_sector_params:
   578 00004103 8B460C              <1> 	mov	eax, [esi+FS_MAT_DATLocation]
   579 00004106 894714              <1> 	mov	[edi+LD_FS_DATLocation], eax
   580 00004109 8B4610              <1> 	mov	eax, [esi+FS_MAT_DATScount]
   581 0000410C 894718              <1> 	mov	[edi+LD_FS_DATSectors], eax
   582 0000410F 8B4614              <1> 	mov	eax, [esi+FS_MAT_FreeSectors]
   583 00004112 894774              <1>         mov     [edi+LD_FS_FreeSectors], eax
   584 00004115 8B4618              <1> 	mov	eax, [esi+FS_MAT_FirstFreeSector]
   585 00004118 894778              <1> 	mov	[edi+LD_FS_FirstFreeSector], eax
   586 0000411B 8B4708              <1> 	mov	eax, [edi+LD_FS_RootDirD]
   587 0000411E 03476C              <1> 	add	eax, [edi+LD_FS_BeginSector]
   588 00004121 89FE                <1> 	mov	esi, edi   
   589                              <1> read_hd_fs_RDT_sector:
   590 00004123 BB[C1AE0000]        <1> 	mov	ebx, DOSBootSectorBuff
   591                              <1> 	;mov	ecx, 1
   592 00004128 B101                <1> 	mov	cl, 1
   593 0000412A E814550000          <1> 	call	disk_read
   594 0000412F 7218                <1> 	jc	short loc_validate_hd_fs_partition_retn
   595                              <1> 	; EDI will not be changed
   596 00004131 89DE                <1> 	mov	esi, ebx
   597                              <1> use_hdfs_RDT_sector_params:
   598 00004133 8B461C              <1> 	mov	eax, [esi+FS_RDT_VolumeSerialNo]
   599 00004136 894728              <1> 	mov	[edi+LD_FS_VolumeSerial], eax
   600 00004139 57                  <1> 	push	edi
   601                              <1> 	;mov	ecx, 16
   602 0000413A B110                <1> 	mov	cl, 16
   603 0000413C 83C640              <1> 	add	esi, FS_RDT_VolumeName
   604 0000413F 83C72C              <1> 	add	edi, LD_FS_VolumeName
   605 00004142 F3A5                <1> 	rep	movsd ; 64 bytes
   606 00004144 5E                  <1> 	pop	esi
   607                              <1> 		; Volume Name Reset
   608 00004145 C6467E06            <1>         mov     byte [esi+LD_FS_MediaChanged], 6
   609                              <1> 	;
   610                              <1>         ;mov	cl, [Last_DOS_DiskNo] 
   611                              <1> 	;add	cl, 'A'
   612                              <1> 	;mov	[esi+LD_FS_Name], cl
   613                              <1> 
   614                              <1> loc_validate_hd_fs_partition_retn:
   615 00004149 C3                  <1> 	retn
   616                              <1> 
   617                              <1> load_masterboot:
   618                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
   619                              <1> 	; 2005 - 2011
   620                              <1> 	; input -> DL = drive number
   621 0000414A B40D                <1> 	mov	ah, 0Dh ; Alternate disk reset
   622 0000414C E87AE7FFFF          <1> 	call	int13h
   623 00004151 7301                <1> 	jnc	short pass_reset_error
   624                              <1> harddisk_error:
   625 00004153 C3                  <1>   	retn
   626                              <1> pass_reset_error:
   627 00004154 BB[AEAA0000]        <1> 	mov	ebx, MasterBootBuff
   628 00004159 66B80102            <1> 	mov	ax, 0201h
   629 0000415D 66B90100            <1> 	mov	cx, 1
   630 00004161 30F6                <1> 	xor	dh, dh
   631 00004163 E863E7FFFF          <1>  	call	int13h
   632 00004168 72E9                <1> 	jc	short harddisk_error
   633                              <1> 	;
   634 0000416A 66813D[ACAC0000]55- <1> 	cmp	word [MBIDCode], 0AA55h
   634 00004172 AA                  <1>
   635 00004173 7401                <1> 	je	short load_masterboot_ok
   636 00004175 F9                  <1> 	stc
   637                              <1> load_masterboot_ok:
   638 00004176 C3                  <1> 	retn
   639                              <1> 
   640                              <1> get_free_FAT_sectors:
   641                              <1> 	; 29/02/2016
   642                              <1> 	; 13/02/2016
   643                              <1> 	; 04/02/2016
   644                              <1> 	; 07/01/2016 (TRDOS 386 = TRDOS v2.0)
   645                              <1> 	; 11/07/2010
   646                              <1> 	; 21/06/2009
   647                              <1> 	; INPUT: ESI = Logical DOS Drive Description Table address
   648                              <1> 	; OUTPUT: STC => Error
   649                              <1>         ;	cf = 0 and EAX = Free FAT sectors
   650                              <1> 	; Also, related parameters and FAT buffer will be reset and updated
   651                              <1> 
   652 00004177 31C0                <1> 	xor	eax, eax
   653                              <1> 	;mov	[esi+LD_FreeSectors], eax ; Reset
   654                              <1> 	
   655 00004179 807E0302            <1>         cmp     byte [esi+LD_FATType], 2
   656 0000417D 7650                <1> 	jna	short loc_gfc_get_fat_free_clusters
   657                              <1> 
   658                              <1> 	; 29/02/2016
   659 0000417F 48                  <1> 	dec	eax ; 0FFFFFFFFh
   660 00004180 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count (reset)
   661 00004183 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; First Free Cluster (reset)
   662 00004186 40                  <1> 	inc	eax ; 0
   663                              <1> 	;
   664 00004187 668B4636            <1> 	mov	ax, [esi+LD_BPB+BPB_FSInfo]
   665 0000418B 03466C              <1> 	add	eax, [esi+LD_StartSector]
   666                              <1> 
   667 0000418E BB[C1AE0000]        <1> 	mov	ebx, DOSBootSectorBuff
   668 00004193 B901000000          <1> 	mov	ecx, 1
   669 00004198 E8A6540000          <1>  	call	disk_read
   670 0000419D 7301                <1> 	jnc	short loc_gfc_check_fsinfo_signs
   671                              <1> retn_gfc_get_fsinfo_sec:
   672 0000419F C3                  <1> 	retn
   673                              <1> 
   674                              <1> loc_gfc_check_fsinfo_signs:
   675 000041A0 BB[C1AE0000]        <1> 	mov 	ebx, DOSBootSectorBuff ; 13/02/2016
   676 000041A5 813B52526141        <1>         cmp     dword [ebx], 41615252h
   677 000041AB 7520                <1> 	jne	short retn_gfc_get_fsinfo_stc
   678                              <1> 	;add	ebx, 484
   679                              <1> 	;cmp	dword [ebx], 61417272h
   680 000041AD 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
   680 000041B6 61                  <1>
   681 000041B7 7514                <1> 	jne	short retn_gfc_get_fsinfo_stc
   682                              <1> 	;add	ebx, 4
   683                              <1> 	;mov	eax, [ebx]
   684 000041B9 8B83E8010000        <1> 	mov	eax, [ebx+488]
   685                              <1> 	; 29/02/2016
   686 000041BF 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count
   687 000041C2 8B93EC010000        <1> 	mov	edx,  [ebx+492] 
   688 000041C8 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; First Free Cluster
   689                              <1> 	;
   690 000041CB EB12                <1> 	jmp	short retn_from_get_free_fat32_clusters
   691                              <1> 
   692                              <1> retn_gfc_get_fsinfo_stc:
   693 000041CD F9                  <1> 	stc
   694 000041CE C3                  <1> 	retn
   695                              <1> 
   696                              <1> loc_gfc_get_fat_free_clusters:
   697                              <1> 	;mov	eax, 2
   698 000041CF B002                <1> 	mov	al, 2
   699                              <1> 	;mov	[FAT_CurrentCluster], eax
   700                              <1> loc_gfc_loop_get_next_cluster:
   701 000041D1 E81C350000          <1> 	call	get_next_cluster
   702 000041D6 730E                <1> 	jnc	short loc_gfc_free_fat_clusters_cont
   703 000041D8 21C0                <1> 	and	eax, eax
   704 000041DA 7411                <1> 	jz	short loc_gfc_pass_inc_free_cluster_count
   705                              <1>  
   706                              <1> retn_from_get_free_fat_clusters:
   707 000041DC 8B4674              <1> 	mov	eax, [esi+LD_FreeSectors] ; Free clusters !
   708                              <1> retn_from_get_free_fat32_clusters:
   709 000041DF 0FB65E13            <1>         movzx	ebx, byte [esi+LD_BPB+BPB_SecPerClust]
   710 000041E3 F7E3                <1>       	mul	ebx
   711                              <1> 	;mov	[esi+LD_FreeSectors], eax ; Free sectors
   712                              <1> retn_get_free_sectors_calc:
   713 000041E5 C3                  <1> 	retn
   714                              <1> 
   715                              <1> loc_gfc_free_fat_clusters_cont:
   716 000041E6 09C0                <1> 	or	eax, eax
   717 000041E8 7503                <1> 	jnz	short loc_gfc_pass_inc_free_cluster_count
   718 000041EA FF4674              <1> 	inc	dword [esi+LD_FreeSectors] ; Free clusters !
   719                              <1>    
   720                              <1> loc_gfc_pass_inc_free_cluster_count:
   721                              <1> 	;mov	eax, [FAT_CurrentCluster]
   722 000041ED 89C8                <1> 	mov	eax, ecx ; [FAT_CurrentCluster]
   723 000041EF 3B4678              <1> 	cmp	eax, [esi+LD_Clusters]
   724 000041F2 77E8                <1> 	ja	short retn_from_get_free_fat_clusters
   725 000041F4 40                  <1> 	inc	eax
   726                              <1> 	;mov	[FAT_CurrentCluster], eax
   727 000041F5 EBDA                <1> 	jmp	short loc_gfc_loop_get_next_cluster
   728                              <1> 
   729                              <1> floppy_drv_init:
   730                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
   731                              <1> 	; 24/07/2011
   732                              <1> 	; 04/07/2009
   733                              <1> 	; INPUT ->
   734                              <1> 	;	DL = Drive number (0,1)
   735                              <1> 	; OUTPUT ->
   736                              <1> 	;	BL = drive name
   737                              <1> 	;	BH = drive number
   738                              <1> 	;	ESI = Logical DOS drv description table
   739                              <1> 	;	EAX = Volume serial number
   740                              <1>  
   741 000041F7 BE[BEA20000]        <1> 	mov	esi, fd0_type ; 10/01/2016
   742 000041FC BF00010900          <1> 	mov	edi, Logical_DOSDisks
   743 00004201 08D2                <1> 	or	dl, dl
   744 00004203 7407                <1> 	jz	short loc_drv_init_fd0_fd1
   745 00004205 81C700010000        <1> 	add	edi, 100h
   746 0000420B 46                  <1> 	inc	esi ; fd1_type ; 10/01/2016
   747                              <1> loc_drv_init_fd0_fd1:
   748 0000420C C6477E00            <1> 	mov	byte [edi+LD_MediaChanged], 0
   749 00004210 803E01              <1> 	cmp	byte [esi], 1 ; type (>0 if it is existing) 
   750                              <1> 		; 4 = 1.44 MB, 80 track, 3 1/2"
   751 00004213 7221                <1> 	jb	short read_fd_boot_sector_retn
   752 00004215 885702              <1> 	mov	[edi+LD_PhyDrvNo], dl
   753                              <1> read_fd_boot_sector:
   754 00004218 30F6                <1> 	xor	dh, dh
   755 0000421A B904000000          <1> 	mov	ecx, 4 ; Retry Count
   756                              <1> read_fd_boot_sector_again:
   757 0000421F 51                  <1> 	push 	ecx
   758                              <1> 	;mov	cx, 1
   759 00004220 B101                <1> 	mov	cl, 1
   760 00004222 66B80102            <1> 	mov	ax, 0201h ; Read 1 sector
   761 00004226 BB[C1AE0000]        <1> 	mov	ebx, DOSBootSectorBuff
   762 0000422B E89BE6FFFF          <1> 	call	int13h
   763 00004230 59                  <1> 	pop	ecx
   764 00004231 7304                <1> 	jnc	short use_fd_boot_sector_params
   765 00004233 E2EA                <1> 	loop	read_fd_boot_sector_again
   766                              <1> 
   767                              <1> read_fd_boot_sector_stc_retn:
   768 00004235 F9                  <1> 	stc
   769                              <1> read_fd_boot_sector_retn:
   770 00004236 C3                  <1> 	retn
   771                              <1> 
   772                              <1> use_fd_boot_sector_params:
   773                              <1> 	;mov	esi, DOSBootSectorBuff
   774 00004237 89DE                <1> 	mov	esi, ebx
   775 00004239 6681BEFE01000055AA  <1> 	cmp	word [esi+BS_Validation], 0AA55h
   776 00004242 75F1                <1> 	jne	short read_fd_boot_sector_stc_retn
   777 00004244 66817E035346        <1>         cmp     word [esi+bs_FS_Identifier], 'SF'
   778 0000424A 0F85A2000000        <1>         jne     use_fd_fatfs_boot_sector_params
   779                              <1> 	;
   780 00004250 8A462D              <1> 	mov	al, [esi+bs_FS_LBA_Ready]
   781 00004253 884705              <1> 	mov	[edi+LD_FS_LBAYes], al
   782                              <1> 	;
   783                              <1> 	; 03/01/2010 CHS -> DOS FAT/BPB compatibility fix
   784 00004256 8A4608              <1> 	mov	al, [esi+bs_FS_MediaAttrib]
   785 00004259 884706              <1> 	mov	[edi+LD_FS_MediaAttrib], al
   786                              <1> 	;
   787 0000425C 8A460A              <1>         mov	al, [esi+bs_FS_VersionMaj]
   788 0000425F 884707              <1> 	mov	byte [edi+LD_FS_VersionMajor], al
   789 00004262 668B4606            <1> 	mov	ax, [esi+bs_FS_BytesPerSec]
   790 00004266 66894711            <1> 	mov	[edi+LD_FS_BytesPerSec], ax
   791 0000426A 8A462E              <1> 	mov	al, [esi+bs_FS_SecPerTrack]
   792 0000426D 6698                <1> 	cbw
   793 0000426F 6689471E            <1> 	mov	[edi+LD_FS_SecPerTrack], ax
   794 00004273 8A462F              <1> 	mov	al, [esi+bs_FS_Heads]
   795                              <1> 	;cbw
   796 00004276 66894720            <1> 	mov	[edi+LD_FS_NumHeads], ax
   797                              <1> 	;
   798 0000427A 8B4628              <1> 	mov	eax, [esi+bs_FS_UnDelDirD]
   799 0000427D 894722              <1> 	mov	[edi+LD_FS_UnDelDirD], eax
   800 00004280 8B4618              <1> 	mov	eax, [esi+bs_FS_MATLocation]
   801 00004283 89470C              <1> 	mov	[edi+LD_FS_MATLocation], eax
   802 00004286 8B461C              <1> 	mov	eax, [esi+bs_FS_RootDirD]
   803 00004289 894708              <1> 	mov	[edi+LD_FS_RootDirD], eax
   804 0000428C 8B460C              <1> 	mov	eax, [esi+bs_FS_BeginSector]
   805 0000428F 89476C              <1> 	mov	[edi+LD_FS_BeginSector], eax
   806 00004292 8B4610              <1> 	mov	eax, [esi+bs_FS_VolumeSize]
   807 00004295 894770              <1> 	mov	[edi+LD_FS_VolumeSize], eax
   808                              <1> 	;		
   809 00004298 89FE                <1> 	mov	esi, edi
   810 0000429A 8B460C              <1>  	mov	eax, [esi+LD_FS_MATLocation]
   811                              <1> 	;add	eax, [edi+LD_FS_BeginSector]
   812                              <1> read_fd_MAT_sector_again:
   813                              <1> 	;mov	ebx, DOSBootSectorBuff
   814                              <1> 	;mov	ecx, 1
   815 0000429D B101                <1> 	mov	cl, 1
   816 0000429F E8A5530000          <1> 	call	chs_read
   817 000042A4 89DE                <1> 	mov	esi, ebx
   818 000042A6 7301                <1> 	jnc	short use_fdfs_mat_sector_params
   819                              <1> 	;jmp	short read_fd_boot_sector_retn
   820 000042A8 C3                  <1> 	retn
   821                              <1> use_fdfs_mat_sector_params:
   822 000042A9 8B460C              <1> 	mov	eax, [esi+FS_MAT_DATLocation]
   823 000042AC 894714              <1> 	mov	[edi+LD_FS_DATLocation], eax
   824 000042AF 8B4610              <1> 	mov	eax, [esi+FS_MAT_DATScount]
   825 000042B2 894718              <1> 	mov	[edi+LD_FS_DATSectors], eax
   826 000042B5 8B4714              <1> 	mov	eax, [edi+FS_MAT_FreeSectors]
   827 000042B8 894774              <1> 	mov	[edi+LD_FS_FreeSectors], eax
   828 000042BB 8B4618              <1> 	mov	eax, [esi+FS_MAT_FirstFreeSector]
   829 000042BE 894778              <1> 	mov	[edi+LD_FS_FirstFreeSector], eax
   830                              <1> 	;
   831 000042C1 89FE                <1> 	mov	esi, edi
   832 000042C3 8B4608              <1>  	mov	eax, [esi+LD_FS_RootDirD]
   833                              <1> read_fd_RDT_sector_again:
   834                              <1> 	;mov	ebx, DOSBootSectorBuff
   835                              <1> 	;mov	cx, 1
   836 000042C6 B101                <1> 	mov	cl, 1
   837 000042C8 E87C530000          <1> 	call	chs_read
   838 000042CD 89DE                <1> 	mov	esi, ebx
   839 000042CF 7220                <1> 	jc	short read_fd_RDT_sector_retn
   840                              <1> use_fdfs_RDT_sector_params:
   841 000042D1 8B461C              <1> 	mov	eax, [esi+FS_RDT_VolumeSerialNo]
   842 000042D4 894728              <1> 	mov	[edi+LD_FS_VolumeSerial], eax
   843 000042D7 57                  <1> 	push	edi
   844                              <1> 	;mov	ecx, 16
   845 000042D8 B110                <1> 	mov	cl, 16	
   846 000042DA 83C640              <1> 	add	esi, FS_RDT_VolumeName
   847 000042DD 83C72C              <1> 	add	edi, LD_FS_VolumeName
   848 000042E0 F3A5                <1> 	rep	movsd ; 64 bytes
   849 000042E2 5E                  <1> 	pop	esi
   850 000042E3 C6460300            <1> 	mov	byte [esi+LD_FATType], 0
   851 000042E7 C64604A1            <1> 	mov	byte [esi+LD_FSType], 0A1h  
   852 000042EB E9AA000000          <1>         jmp     loc_cont_use_fd_boot_sector_params
   853                              <1> 
   854                              <1> read_fd_RDT_sector_stc_retn:
   855 000042F0 F9                  <1> 	stc
   856                              <1> read_fd_RDT_sector_retn:
   857 000042F1 C3                  <1> 	retn
   858                              <1> 
   859                              <1> use_fd_fatfs_boot_sector_params:
   860 000042F2 807E2629            <1> 	cmp	byte [esi+BS_BootSig], 29h
   861 000042F6 75F8                <1> 	jne	short read_fd_RDT_sector_stc_retn
   862 000042F8 807E15F0            <1> 	cmp	byte [esi+BPB_Media], 0F0h
   863 000042FC 72F3                <1> 	jb	short read_fd_RDT_sector_retn
   864 000042FE 57                  <1> 	push	edi
   865 000042FF 83C706              <1> 	add	edi, LD_BPB
   866                              <1> 	;mov	ecx, 16
   867 00004302 B110                <1> 	mov	cl, 16
   868 00004304 F3A5                <1> 	rep	movsd ; 64 bytes 
   869 00004306 5E                  <1> 	pop	esi
   870 00004307 31C0                <1> 	xor	eax, eax
   871 00004309 89466C              <1> 	mov	[esi+LD_StartSector], eax ; 0
   872 0000430C 668B461C            <1> 	mov	ax, [esi+LD_BPB+BPB_FATSz16]
   873 00004310 8A4E16              <1> 	mov	cl, [esi+LD_BPB+BPB_NumFATs] 
   874 00004313 F7E1                <1>   	mul	ecx
   875                              <1> 	; edx = 0 !
   876 00004315 668B5614            <1> 	mov	dx, [esi+LD_BPB+BPB_RsvdSecCnt]
   877 00004319 66895660            <1> 	mov	[esi+LD_FATBegin], dx
   878                              <1> 	;add	eax, edx
   879 0000431D 6601D0              <1> 	add	ax, dx
   880 00004320 894664              <1> 	mov	[esi+LD_ROOTBegin], eax
   881 00004323 894668              <1> 	mov	[esi+LD_DATABegin], eax 
   882 00004326 668B5617            <1> 	mov	dx, [esi+LD_BPB+BPB_RootEntCnt]
   883                              <1> 	;shl	edx, 5 ; * 32 (Size of a directory entry)
   884 0000432A 66C1E205            <1> 	shl	dx, 5
   885                              <1> 	;add	edx, 511
   886 0000432E 6681C2FF01          <1> 	add	dx, 511
   887                              <1> 	;shr	edx, 9 ; edx = ((edx*32)+511) / 512
   888 00004333 66C1EA09            <1> 	shr	dx, 9
   889 00004337 015668              <1> 	add 	[esi+LD_DATABegin], edx
   890                              <1> 	;movzx	eax, word [esi+LD_BPB+BPB_TotalSec16]
   891 0000433A 668B4619            <1> 	mov	ax, [esi+LD_BPB+BPB_TotalSec16]
   892 0000433E 894670              <1> 	mov	[esi+LD_TotalSectors], eax
   893 00004341 2B4668              <1> 	sub	eax, [esi+LD_DATABegin]
   894                              <1>   	;movzx	ecx, byte [esi+LD_BPB+BPB_SecPerClust]
   895 00004344 8A4E13              <1> 	mov	cl, [esi+LD_BPB+BPB_SecPerClust]  
   896 00004347 80F901              <1> 	cmp	cl, 1
   897 0000434A 7605                <1> 	jna	short save_fd_fatfs_cluster_count
   898                              <1> 	;sub	edx, edx
   899 0000434C 6629D2              <1> 	sub	dx, dx ; 0
   900 0000434F F7F1                <1> 	div	ecx
   901                              <1> save_fd_fatfs_cluster_count:
   902 00004351 894678              <1> 	mov	[esi+LD_Clusters], eax
   903                              <1> 
   904                              <1>       ; Maximum Valid Cluster Number = EAX +1
   905                              <1>       ; with 2 reserved clusters= EAX +2
   906                              <1>  
   907                              <1> reset_FAT_buffer_decriptors:
   908 00004354 29C0                <1> 	sub	eax, eax ; 0  
   909 00004356 A2[C5B00000]        <1> 	mov	[FAT_BuffValidData], al ; 0
   910 0000435B A2[C6B00000]        <1> 	mov	[FAT_BuffDrvName], al ; 0
   911 00004360 A3[C9B00000]        <1> 	mov	[FAT_BuffSector], eax ; 0
   912                              <1> 
   913                              <1> read_fd_FAT_sectors:
   914 00004365 BB001C0900          <1>   	mov	ebx, FAT_Buffer
   915 0000436A 668B4614            <1> 	mov	ax, [esi+LD_BPB+BPB_RsvdSecCnt]
   916                              <1> 	;mov	ecx, 3
   917 0000436E B103                <1> 	mov	cl, 3 ; 3 sectors
   918 00004370 E8D4520000          <1> 	call	chs_read
   919 00004375 7240                <1> 	jc	short read_fd_FAT_sectors_retn
   920                              <1> use_fd_FAT_sectors:
   921 00004377 8A4602              <1> 	mov	al, [esi+LD_PhyDrvNo]
   922 0000437A 0441                <1> 	add	al, 'A' 
   923 0000437C A2[C6B00000]        <1> 	mov	[FAT_BuffDrvName], al 
   924 00004381 C605[C5B00000]01    <1>  	mov	byte [FAT_BuffValidData], 1
   925 00004388 E82B000000          <1> 	call	fd_init_calculate_free_clusters
   926 0000438D 7228                <1> 	jc	short read_fd_FAT_sectors_retn
   927                              <1>   
   928                              <1> loc_use_fd_boot_sector_params_FAT:
   929 0000438F C6460301            <1> 	mov	byte [esi+LD_FATType], 1 ; FAT 12
   930 00004393 C6460401            <1> 	mov	byte [esi+LD_FSType], 1
   931 00004397 8B462D              <1>         mov     eax, [esi+LD_BPB+VolumeID]
   932                              <1> loc_cont_use_fd_boot_sector_params:
   933 0000439A 8A7E02              <1> 	mov	bh, [esi+LD_PhyDrvNo]
   934 0000439D 887E7D              <1> 	mov	[esi+LD_DParamEntry], bh
   935 000043A0 88FB                <1> 	mov	bl, bh
   936 000043A2 80C341              <1> 	add	bl, 'A'
   937 000043A5 881E                <1> 	mov	byte [esi+LD_Name], bl
   938 000043A7 C6460101            <1> 	mov	byte [esi+LD_DiskType], 1
   939 000043AB C6460500            <1> 	mov	byte [esi+LD_LBAYes], 0
   940 000043AF C6467C00            <1> 	mov	byte [esi+LD_PartitionEntry], 0
   941 000043B3 C6467E06            <1> 	mov	byte [esi+LD_MediaChanged], 6 ; Volume Name Reset
   942                              <1> 
   943                              <1> read_fd_FAT_sectors_retn:
   944 000043B7 C3                  <1> 	retn   
   945                              <1> 
   946                              <1> fd_init_calculate_free_clusters:
   947                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
   948                              <1> 	; 04/07/2009
   949                              <1> 	; INPUT ->
   950                              <1> 	;     ESI = Logical DOS drive description table address
   951                              <1> 	; OUTPUT ->
   952                              <1> 	;    [ESI+LD_FreeSectors] will be set
   953                              <1> 	
   954 000043B8 29C0                <1> 	sub	eax, eax
   955 000043BA 894674              <1> 	mov	[esi+LD_FreeSectors], eax ; 0
   956 000043BD B002                <1> 	mov	al, 2 ; eax = 2
   957                              <1> 
   958                              <1> fd_init_loop_get_next_cluster:
   959 000043BF E830000000          <1> 	call	fd_init_get_next_cluster
   960 000043C4 722D                <1> 	jc	short fd_init_calculate_free_clusters_retn
   961                              <1> 
   962                              <1> fd_init_free_fat_clusters:
   963                              <1> 	;cmp 	eax, 0
   964                              <1> 	;ja	short fd_init_pass_inc_free_cluster_count
   965                              <1> 	;and	eax, eax
   966                              <1> 	;jnz	short fd_init_pass_inc_free_cluster_count
   967 000043C6 6621C0              <1> 	and	ax, ax
   968 000043C9 7504                <1> 	jnz	short fd_init_pass_inc_free_cluster_count
   969                              <1> 	;inc	dword [esi+LD_FreeSectors]
   970 000043CB 66FF4674            <1>         inc	word [esi+LD_FreeSectors]
   971                              <1>     
   972                              <1> fd_init_pass_inc_free_cluster_count:
   973                              <1>   	;mov	eax, [FAT_CurrentCluster]
   974 000043CF 66A1[C1B00000]      <1> 	mov	ax, [FAT_CurrentCluster]
   975                              <1> 	;cmp	eax, [esi+LD_Clusters]
   976 000043D5 663B4678            <1> 	cmp	ax, [esi+LD_Clusters]
   977 000043D9 7704                <1> 	ja	short short retn_from_fd_init_calculate_free_clusters
   978                              <1> 	;inc	eax
   979 000043DB 6640                <1> 	inc	ax
   980 000043DD EBE0                <1> 	jmp	short fd_init_loop_get_next_cluster
   981                              <1> 
   982                              <1> retn_from_fd_init_calculate_free_clusters:
   983 000043DF 8A4613              <1>   	mov	al, [esi+LD_BPB+BPB_SecPerClust]
   984 000043E2 3C01                <1>   	cmp	al, 1
   985 000043E4 760D                <1> 	jna	short fd_init_calculate_free_clusters_retn
   986                              <1> 	;movzx	eax, al
   987 000043E6 6698                <1> 	cbw
   988                              <1> 	;mov	ecx, [esi+LD_FreeSectors]
   989 000043E8 668B4E74            <1> 	mov	cx, [esi+LD_FreeSectors] ; Count of free clusters
   990                              <1>   	;mul	ecx
   991 000043EC 66F7E1              <1> 	mul	cx
   992                              <1> 	;mov	[esi+LD_FreeSectors], eax
   993 000043EF 66894674            <1> 	mov	[esi+LD_FreeSectors], ax
   994                              <1> fd_init_calculate_free_clusters_retn:
   995 000043F3 C3                  <1> 	retn
   996                              <1> 
   997                              <1> fd_init_get_next_cluster:
   998                              <1> 	; 04/02/2016
   999                              <1> 	; 02/02/2016
  1000                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
  1001                              <1> 	; 04/07/2009
  1002                              <1> 	; INPUT ->
  1003                              <1> 	;    EAX = Current cluster
  1004                              <1> 	;    ESI = Logical DOS drive description table address
  1005                              <1> 	;    EDX = 0
  1006                              <1> 	; OUTPUT ->
  1007                              <1> 	;    EAX = Next cluster
  1008                              <1> 
  1009 000043F4 A3[C1B00000]        <1> 	mov	[FAT_CurrentCluster], eax
  1010                              <1> fd_init_get_next_cluster_readnext:
  1011 000043F9 29D2                <1> 	sub	edx, edx ; 0
  1012 000043FB BB00040000          <1>   	mov	ebx, 1024 ; 400h
  1013 00004400 F7F3                <1>   	div	ebx
  1014                              <1>   	; EAX = Count of 3 FAT sectors
  1015                              <1>   	; EDX = Buffer entry index
  1016 00004402 89C1                <1> 	mov	ecx, eax
  1017                              <1> 	;mov	eax, 3
  1018 00004404 B003                <1> 	mov	al, 3
  1019 00004406 F7E2                <1> 	mul	edx ; Multiply by 3
  1020 00004408 66D1E8              <1> 	shr	ax, 1 ; Divide by 2
  1021 0000440B 89C3                <1> 	mov	ebx, eax ; Buffer byte offset
  1022 0000440D 81C3001C0900        <1> 	add	ebx, FAT_Buffer
  1023 00004413 89C8                <1> 	mov	eax, ecx
  1024                              <1> 	;mov	edx, 3
  1025 00004415 66BA0300            <1> 	mov	dx, 3
  1026 00004419 F7E2                <1> 	mul	edx 
  1027                              <1>   	; EAX = FAT Beginning Sector
  1028                              <1> 	; EDX = 0
  1029 0000441B 8A0E                <1> 	mov	cl, [esi+LD_Name]
  1030                              <1> 	;cmp	byte [FAT_BuffValidData], 0
  1031                              <1> 	;jna	short fd_init_load_FAT_sectors0
  1032 0000441D 3A0D[C6B00000]      <1> 	cmp	cl, [FAT_BuffDrvName]
  1033 00004423 751E                <1> 	jne	short fd_init_load_FAT_sectors0
  1034 00004425 3B05[C9B00000]      <1> 	cmp	eax, [FAT_BuffSector]
  1035 0000442B 751C                <1> 	jne	short fd_init_load_FAT_sectors1
  1036                              <1> 	;mov	eax, [FAT_CurrentCluster]
  1037 0000442D A0[C1B00000]        <1> 	mov	al, [FAT_CurrentCluster]
  1038                              <1> 	;shr	eax, 1
  1039 00004432 D0E8                <1> 	shr	al, 1
  1040 00004434 668B03              <1> 	mov	ax, [ebx]
  1041 00004437 7306                <1>   	jnc	short fd_init_gnc_even
  1042 00004439 66C1E804            <1> 	shr	ax, 4
  1043                              <1> fd_init_gnc_clc_retn:
  1044 0000443D F8                  <1> 	clc
  1045 0000443E C3                  <1> 	retn
  1046                              <1> 
  1047                              <1> fd_init_gnc_even:
  1048 0000443F 80E40F              <1> 	and	ah, 0Fh
  1049 00004442 C3                  <1> 	retn
  1050                              <1> 
  1051                              <1> fd_init_load_FAT_sectors0:
  1052 00004443 880D[C6B00000]      <1> 	mov 	[FAT_BuffDrvName], cl
  1053                              <1> fd_init_load_FAT_sectors1:
  1054 00004449 C605[C5B00000]00    <1> 	mov	byte [FAT_BuffValidData], 0
  1055 00004450 A3[C9B00000]        <1> 	mov	[FAT_BuffSector], eax
  1056 00004455 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1057 00004458 BB001C0900          <1>  	mov	ebx, FAT_Buffer
  1058                              <1> 	;movzx	ecx, word [esi+LD_BPB+BPB_FATSz16]
  1059 0000445D 668B4E1C            <1> 	mov	cx, [esi+LD_BPB+BPB_FATSz16]
  1060 00004461 662B0D[C9B00000]    <1> 	sub	cx, [FAT_BuffSector]
  1061                              <1>         ;cmp	ecx, 3
  1062 00004468 6683F903            <1> 	cmp	cx, 3
  1063 0000446C 7605                <1> 	jna	short fdinit_pass_fix_sector_count_3
  1064                              <1> 	;mov	ecx, 3
  1065 0000446E B903000000          <1> 	mov	ecx, 3
  1066                              <1> fdinit_pass_fix_sector_count_3:  
  1067 00004473 E8D1510000          <1> 	call	chs_read
  1068 00004478 730D                <1> 	jnc	short fd_init_FAT_sectors_no_load_error
  1069 0000447A C605[C5B00000]00    <1> 	mov	byte [FAT_BuffValidData], 0
  1070                              <1> 		; Drv not ready or read Error !
  1071 00004481 B80F000000          <1> 	mov	eax, ERR_DRV_NOT_RDY ; 15
  1072                              <1> 	;xor	edx, edx
  1073 00004486 C3                  <1> 	retn
  1074                              <1> 
  1075                              <1> fd_init_FAT_sectors_no_load_error:
  1076 00004487 C605[C5B00000]01    <1> 	mov	byte [FAT_BuffValidData], 1
  1077 0000448E A1[C1B00000]        <1> 	mov	eax, [FAT_CurrentCluster]
  1078 00004493 E961FFFFFF          <1>         jmp     fd_init_get_next_cluster_readnext
  1079                              <1> 
  1080                              <1> get_FAT_volume_name:
  1081                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
  1082                              <1> 	; 12/09/2009
  1083                              <1> 	; INPUT ->
  1084                              <1> 	;	BH = Logical DOS drive number (0,1,2,3,4 ...)
  1085                              <1> 	;       BL = 0
  1086                              <1> 	; OUTPUT ->
  1087                              <1> 	;	CF = 0 -> ESI = Volume name address
  1088                              <1> 	; 	CF = 1 -> Root volume name not found
  1089                              <1> 
  1090                              <1> 	;mov 	ah, 0FFh
  1091                              <1> 	;mov 	al, [Last_Dos_DiskNo]
  1092                              <1> 	;cmp 	al, bh
  1093                              <1> 	;jb     short loc_gfvn_dir_load_err
  1094                              <1> 
  1095 00004498 89DE                <1> 	mov	esi, ebx
  1096 0000449A 81E600FF0000        <1> 	and	esi, 0FF00h ; esi = bh
  1097 000044A0 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1098 000044A6 8A06                <1> 	mov     al, [esi+LD_Name]
  1099 000044A8 8A6603              <1> 	mov     ah, [esi+LD_FATType]
  1100 000044AB 80FC01              <1> 	cmp     ah, 1
  1101 000044AE 7210                <1> 	jb    	short loc_gfvn_dir_load_err
  1102 000044B0 3C41                <1> 	cmp 	al, 'A'
  1103 000044B2 720C                <1> 	jb      short loc_gfvn_dir_load_err
  1104 000044B4 80FC02              <1> 	cmp 	ah, 2 
  1105 000044B7 7708                <1> 	ja      short get_FAT32_root_cluster
  1106                              <1> 	
  1107 000044B9 E88A330000          <1> 	call    load_FAT_root_directory
  1108 000044BE 730B                <1> 	jnc     short loc_get_volume_name
  1109                              <1> 
  1110                              <1> loc_gfvn_dir_load_err:
  1111 000044C0 C3                  <1> 	retn
  1112                              <1> 
  1113                              <1> get_FAT32_root_cluster:
  1114 000044C1 8B4632              <1> 	mov	eax, [esi+LD_BPB+BPB_RootClus]
  1115 000044C4 E80A340000          <1> 	call    load_FAT_sub_directory
  1116 000044C9 7224                <1> 	jc	short loc_get_volume_name_retn
  1117                              <1> 
  1118                              <1> loc_get_volume_name:
  1119 000044CB BE00000800          <1>         mov     esi, Directory_Buffer
  1120 000044D0 6631C9              <1> 	xor	cx, cx ; 0
  1121                              <1> check_root_volume_name:
  1122 000044D3 8A06                <1> 	mov	al, [esi]
  1123 000044D5 08C0                <1> 	or      al, al
  1124 000044D7 7416                <1> 	jz      short loc_get_volume_name_retn
  1125 000044D9 807E0B08            <1> 	cmp     byte [esi+0Bh], 08h
  1126 000044DD 7410                <1> 	je      short loc_get_volume_name_retn
  1127 000044DF 663B0D[DBB00000]    <1> 	cmp     cx, [DirBuff_LastEntry]
  1128 000044E6 7308                <1> 	jnb     short pass_check_root_volume_name
  1129 000044E8 6641                <1> 	inc     cx
  1130 000044EA 83C620              <1> 	add     esi, 32
  1131 000044ED EBE4                <1> 	jmp     short check_root_volume_name
  1132                              <1> 
  1133                              <1> loc_get_volume_name_retn:
  1134 000044EF C3                  <1> 	retn
  1135                              <1>     
  1136                              <1> pass_check_root_volume_name:
  1137 000044F0 803D[D7B00000]03    <1> 	cmp	byte [DirBuff_FATType], 3
  1138 000044F7 7230                <1> 	jb	short loc_get_volume_name_retn_xor
  1139                              <1> 
  1140 000044F9 BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1141 000044FE BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1142 00004503 31C0                <1> 	xor	eax, eax
  1143 00004505 8A25[D6B00000]      <1> 	mov	ah, [DirBuff_DRV]
  1144 0000450B 80EC41              <1> 	sub	ah, 'A' 
  1145 0000450E 01C6                <1> 	add	esi, eax
  1146 00004510 A1[DDB00000]        <1> 	mov	eax, [DirBuff_Cluster]
  1147 00004515 E8D8310000          <1> 	call	get_next_cluster
  1148 0000451A 7305                <1> 	jnc 	short loc_gfvn_load_FAT32_dir_cluster
  1149                              <1>   	
  1150 0000451C 83F801              <1> 	cmp     eax, 1
  1151 0000451F F5                  <1> 	cmc
  1152 00004520 C3                  <1> 	retn
  1153                              <1>   
  1154                              <1> loc_gfvn_load_FAT32_dir_cluster:
  1155 00004521 E8AD330000          <1> 	call	load_FAT_sub_directory
  1156 00004526 73A3                <1> 	jnc	short loc_get_volume_name
  1157 00004528 C3                  <1> 	retn
  1158                              <1> 
  1159                              <1> loc_get_volume_name_retn_xor:
  1160 00004529 31C0                <1> 	xor 	eax, eax
  1161 0000452B C3                  <1> 	retn
  1162                              <1> 
  1163                              <1> get_media_change_status:
  1164                              <1> 	; 10/01/2016 (TRDOS 386 = TRDOS v2.0)
  1165                              <1> 	; 09/09/2009
  1166                              <1> 	; INPUT:
  1167                              <1> 	;     DL = Drive number (physical)
  1168                              <1> 	; OUTPUT: clc & AH = 6 media changed
  1169                              <1> 	;     clc & AH = 0 media not changed         
  1170                              <1> 	;     stc -> Drive not ready or an error 
  1171                              <1>   
  1172 0000452C B416                <1> 	mov	ah, 16h
  1173 0000452E E898E3FFFF          <1>   	call	int13h
  1174 00004533 80FC06              <1> 	cmp	ah, 06h
  1175 00004536 7405                <1> 	je	short loc_gmc_status_retn
  1176 00004538 08E4                <1> 	or	ah, ah
  1177 0000453A 7401                <1> 	jz	short loc_gmc_status_retn
  1178                              <1> loc_gmc_status_stc_retn:    
  1179 0000453C F9                  <1> 	stc
  1180                              <1> loc_gmc_status_retn:
  1181 0000453D C3                  <1> 	retn
  1915                                  %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: 06/03/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 06/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    11                              <1> ; MAINPROG.ASM (09/11/2011)
    12                              <1> ; ****************************************************************************
    13                              <1> ; MAINPROG.ASM [ TRDOS KERNEL - COMMAND EXECUTER SECTION - MAIN PROGRAM ]
    14                              <1> ; (c) 2004-2011  Erdogan TAN  [ 17/01/2004 ]  Last Update: 09/11/2011
    15                              <1> ; CMD_INTR.ASM [ TRDOS Command Interpreter Procedure ] Last Update: 09/11/2011
    16                              <1> ; DIR.ASM [ DIRECTORY FUNCTIONS ] Last Update: 09/10/2011
    17                              <1> ; FILE.ASM [ FILE FUNCTIONS ] Last Update: 09/10/2011
    18                              <1> 
    19                              <1> change_current_drive:
    20                              <1> 	; 02/02/2016
    21                              <1> 	; 15/01/2016 (TRDOS 386 = TRDOS v2.0)
    22                              <1> 	; 18/08/2011
    23                              <1> 	; 09/09/2009
    24                              <1> 	; INPUT:
    25                              <1> 	;   DL = Logical DOS Drive Number
    26                              <1> 	; OUTPUT:
    27                              <1> 	;  cf=1 -> Not successful
    28                              <1> 	;   EAX = Error code
    29                              <1> 	;  cf=0 ->
    30                              <1> 	;   EAX = 0 (successful)
    31                              <1> 
    32 0000453E 31DB                <1> 	xor	ebx, ebx
    33 00004540 88D7                <1> 	mov	bh, dl
    34                              <1> 
    35                              <1> 	;cmp	dl, 1
    36                              <1> 	;jna	short loc_ccdrv_initial_media_change_check
    37                              <1> 	;cmp	bh, [Last_Dos_DiskNo]
    38                              <1> 	;ja	short loc_ccdrv_drive_not_ready_err
    39                              <1> 
    40                              <1> loc_ccdrv_initial_media_change_check:
    41 00004542 BE00010900          <1> 	mov	esi, Logical_DOSDisks
    42 00004547 01DE                <1> 	add	esi, ebx
    43                              <1> loc_ccdrv_dos_drive_name_check:
    44 00004549 80FA02              <1> 	cmp	dl, 2
    45 0000454C 720F                <1> 	jb	short loc_ccdrv_dos_drive_name_check_ok
    46                              <1> 
    47 0000454E 8A06                <1> 	mov	al, [esi+LD_Name]
    48 00004550 2C41                <1> 	sub	al, 'A'
    49 00004552 38D0                <1> 	cmp	al, dl
    50 00004554 7407                <1> 	je	short loc_ccdrv_dos_drive_name_check_ok
    51                              <1> 
    52                              <1> loc_ccdrv_drive_not_ready_err:
    53 00004556 B815000000          <1> 	mov	eax, 15h ; Drive not ready
    54                              <1> loc_change_current_drive_stc_retn:
    55 0000455B F9                  <1> 	stc
    56 0000455C C3                  <1> 	retn  
    57                              <1> 
    58                              <1> loc_ccdrv_dos_drive_name_check_ok:
    59 0000455D 8A667E              <1> 	mov	ah, [esi+LD_MediaChanged]
    60 00004560 80FC06              <1> 	cmp	ah, 6  ; VOLUME NAME CHECK/MOVE SIGN
    61 00004563 7450                <1> 	je	short loc_ccdrv_get_FAT_volume_name_0
    62                              <1> 
    63 00004565 80FA01              <1> 	cmp	dl, 1
    64 00004568 7778                <1> 	ja	short loc_gmcs_init_drv_hd
    65                              <1> 
    66                              <1> loc_gmcs_init_drv_fd:
    67 0000456A 08E4                <1> 	or	ah, ah 
    68                              <1> 	; AH = 1 is initialization sign (invalid_fd_parameter)
    69 0000456C 7517                <1> 	jnz	short loc_ccdrv_call_fd_init
    70                              <1> 
    71 0000456E E8B9FFFFFF          <1> 	call	get_media_change_status
    72 00004573 72E1                <1> 	jc	short loc_ccdrv_drive_not_ready_err
    73                              <1> 
    74 00004575 20E4                <1> 	and	ah, ah
    75 00004577 7471                <1> 	jz	short loc_change_current_drv3
    76                              <1> 
    77 00004579 80F406              <1> 	xor	ah, 6
    78 0000457C 75D8                <1> 	jnz	short loc_ccdrv_drive_not_ready_err
    79                              <1> 
    80                              <1> loc_ccdrv_call_fd_init_check_vol_id:
    81 0000457E E8410A0000          <1> 	call	get_volume_serial_number
    82 00004583 7308                <1> 	jnc	short loc_ccdrv_check_vol_serial
    83                              <1> 
    84                              <1> loc_ccdrv_call_fd_init:
    85 00004585 E86DFCFFFF          <1> 	call	floppy_drv_init
    86 0000458A 7315                <1> 	jnc	short loc_reset_drv_fd_current_dir
    87                              <1> 
    88                              <1> loc_ccdrv_fdinit_fail_retn:
    89 0000458C C3                  <1> 	retn
    90                              <1> 
    91                              <1> loc_ccdrv_check_vol_serial:
    92 0000458D A3[A4A80000]        <1> 	mov	[Current_VolSerial], eax
    93                              <1> 	;mov	dl, bh
    94 00004592 E860FCFFFF          <1> 	call	floppy_drv_init
    95 00004597 72F3                <1> 	jc	short loc_ccdrv_fdinit_fail_retn
    96                              <1> 
    97 00004599 3B05[A4A80000]      <1> 	cmp	eax, [Current_VolSerial]
    98 0000459F 7445                <1> 	je	short loc_change_current_drv2
    99                              <1> 
   100                              <1> loc_reset_drv_fd_current_dir:
   101 000045A1 31C0                <1> 	xor	eax, eax              
   102 000045A3 88467F              <1>         mov	[esi+LD_CDirLevel], al
   103 000045A6 89F7                <1> 	mov	edi, esi
   104 000045A8 81C780000000        <1> 	add	edi, LD_CurrentDirectory
   105 000045AE B920000000          <1> 	mov	ecx, 32
   106 000045B3 F3AB                <1> 	rep	stosd   
   107                              <1>  
   108                              <1> loc_ccdrv_get_FAT_volume_name_0:
   109 000045B5 8A4603              <1> 	mov	al, [esi+LD_FATType]
   110 000045B8 08C0                <1> 	or	al, al
   111 000045BA 742A                <1> 	jz	short loc_change_current_drv2
   112                              <1> 
   113 000045BC 56                  <1> 	push	esi 
   114 000045BD 3C02                <1> 	cmp	al, 2
   115 000045BF 7705                <1> 	ja	short loc_ccdrv_get_FAT32_vol_name
   116                              <1>              
   117                              <1> loc_ccdrv_get_FAT2_16_vol_name:
   118 000045C1 83C631              <1> 	add	esi, LD_BPB + VolumeLabel
   119 000045C4 EB03                <1> 	jmp	short loc_ccdrv_get_FAT_volume_name_1
   120                              <1> 
   121                              <1> loc_ccdrv_get_FAT32_vol_name:
   122 000045C6 83C64D              <1> 	add	esi, LD_BPB + FAT32_VolLab
   123                              <1> loc_ccdrv_get_FAT_volume_name_1:
   124 000045C9 53                  <1> 	push	ebx
   125 000045CA 56                  <1> 	push	esi
   126 000045CB E8C8FEFFFF          <1> 	call	get_FAT_volume_name
   127 000045D0 5F                  <1> 	pop	edi
   128 000045D1 5B                  <1> 	pop	ebx
   129                              <1> 	; BL = 0
   130 000045D2 720B                <1> 	jc	short loc_change_current_drv1
   131 000045D4 20C0                <1> 	and	al, al
   132 000045D6 7407                <1> 	jz	short loc_change_current_drv1
   133                              <1> 
   134                              <1> loc_ccdrv_move_FAT_volume_name:
   135 000045D8 B90B000000          <1> 	mov	ecx, 11
   136 000045DD F3A4                <1> 	rep	movsb
   137                              <1> 
   138                              <1> loc_change_current_drv1:
   139 000045DF 5E                  <1> 	pop	esi
   140 000045E0 EB04                <1> 	jmp	short loc_change_current_drv2
   141                              <1> 
   142                              <1> loc_gmcs_init_drv_hd:
   143 000045E2 08E4                <1> 	or	ah, ah
   144 000045E4 7404                <1> 	jz	short loc_change_current_drv3
   145                              <1> 	; BL = 0, BH = Logical DOS drive number
   146                              <1> loc_change_current_drv2:
   147 000045E6 C6467E00            <1> 	mov	byte [esi+LD_MediaChanged], 0
   148                              <1> loc_change_current_drv3:
   149 000045EA 883D[AEA80000]      <1> 	mov	[Current_Drv], bh
   150                              <1> 
   151                              <1> 	;call	restore_current_directory
   152                              <1> 	;retn
   153                              <1> 
   154                              <1> restore_current_directory:
   155                              <1> 	; 11/02/2016
   156                              <1> 	; 15/01/2016 (TRDOS 386 = TRDOS v2.0)
   157                              <1> 	; 25/01/2010
   158                              <1> 	; 12/10/2009
   159                              <1> 	;
   160                              <1> 	; INPUT:
   161                              <1> 	;   ESI = Logical DOS Drive Description Table
   162                              <1> 	;
   163                              <1> 	; OUTPUT:
   164                              <1> 	;   ESI = Logical DOS Drive Description Table
   165                              <1> 	;   EDI = offset Current_Dir_Drv 
   166                              <1> 
   167 000045F0 8A4603              <1> 	mov	al, [esi+LD_FATType]
   168 000045F3 A2[ADA80000]        <1> 	mov	[Current_FATType], al
   169                              <1> 
   170 000045F8 8A26                <1> 	mov	ah, [esi+LD_Name] 
   171 000045FA 8825[AFA80000]      <1> 	mov	[Current_Dir_Drv], ah
   172                              <1> 
   173 00004600 20C0                <1> 	and	al, al
   174 00004602 741D                <1> 	jz	short loc_restore_FS_current_directory
   175                              <1> 
   176                              <1> loc_restore_FAT_current_directory:
   177 00004604 8A667F              <1> 	mov	ah, [esi+LD_CDirLevel]
   178 00004607 8825[ACA80000]      <1> 	mov	[Current_Dir_Level], ah
   179 0000460D 08E4                <1> 	or	ah, ah
   180 0000460F 7416                <1>         jz	short loc_ccdrv_reset_cdir_FAT_12_16_32_fcluster
   181                              <1> 
   182 00004611 0FB6D4              <1> 	movzx	edx, ah
   183 00004614 C0E204              <1> 	shl	dl, 4 ; * 16
   184 00004617 01F2                <1>         add	edx, esi
   185 00004619 8B828C000000        <1> 	mov	eax, [edx+LD_CurrentDirectory+12]
   186 0000461F EB2C                <1> 	jmp	short loc_ccdrv_reset_cdir_FAT_fcluster
   187                              <1> 
   188                              <1> loc_restore_FS_current_directory:
   189 00004621 E8E8320000          <1> 	call	load_current_FS_directory 
   190 00004626 C3                  <1> 	retn 
   191                              <1> 
   192                              <1> loc_ccdrv_reset_cdir_FAT_12_16_32_fcluster:
   193 00004627 3C03                <1> 	cmp	al, 3
   194 00004629 7205                <1> 	jb	short loc_ccdrv_reset_cdir_FAT_12_16_fcluster
   195                              <1> loc_ccdrv_reset_cdir_FAT32_fcluster:
   196 0000462B 8B4632              <1> 	mov	eax, [esi+LD_BPB+FAT32_RootFClust]
   197 0000462E EB04                <1> 	jmp	short loc_ccdrv_check_rootdir_sign
   198                              <1> loc_ccdrv_reset_cdir_FAT_12_16_fcluster:   
   199 00004630 30C0                <1> 	xor	al, al  ; xor eax, eax
   200 00004632 31D2                <1> 	xor	edx, edx
   201                              <1> loc_ccdrv_check_rootdir_sign:
   202 00004634 80BE8000000000      <1> 	cmp	byte [esi+LD_CurrentDirectory], 0
   203 0000463B 7510                <1> 	jne	short loc_ccdrv_reset_cdir_FAT_fcluster
   204                              <1> loc_ccdrv_set_rootdir_FAT_fcluster:
   205 0000463D 89868C000000        <1>         mov     [esi+LD_CurrentDirectory+12], eax
   206 00004643 C78680000000524F4F- <1> 	mov	dword [esi+LD_CurrentDirectory], 'ROOT'
   206 0000464C 54                  <1>
   207                              <1> 
   208                              <1> loc_ccdrv_reset_cdir_FAT_fcluster:
   209 0000464D A3[A8A80000]        <1> 	mov	[Current_Dir_FCluster], eax
   210                              <1> 
   211 00004652 BF[0FB10000]        <1> 	mov	edi, PATH_Array
   212 00004657 89F2                <1> 	mov	edx, esi
   213 00004659 81C680000000        <1> 	add	esi, LD_CurrentDirectory
   214 0000465F B920000000          <1> 	mov	ecx, 32
   215 00004664 F3A5                <1> 	rep	movsd
   216                              <1> 
   217 00004666 E8D5200000          <1> 	call	change_prompt_dir_string
   218                              <1>                
   219 0000466B 89D6                <1> 	mov	esi, edx
   220                              <1>                
   221 0000466D 29C0                <1>         sub	eax, eax
   222                              <1>        ;sub	edx, edx
   223 0000466F BF[AFA80000]        <1> 	mov	edi, Current_Dir_Drv
   224                              <1> 
   225 00004674 A2[7D990000]        <1> 	mov	[Restore_CDIR], al ; 0
   226 00004679 C3                  <1> 	retn
   227                              <1> 
   228                              <1> dos_prompt:
   229                              <1> 	; 30/01/2016
   230                              <1> 	; 29/01/2016
   231                              <1> 	; 16/01/2016 (TRDOS 386 = TRDOS v2.0)
   232                              <1> 	; 15/09/2011
   233                              <1> 	; 13/09/2009
   234                              <1> 	; 2004-2005
   235                              <1> 
   236                              <1> loc_TRDOS_prompt:
   237 0000467A BF[AEA90000]        <1> 	mov	edi, TextBuffer
   238 0000467F C6075B              <1> 	mov	byte [edi], "["
   239 00004682 47                  <1> 	inc	edi
   240 00004683 BE[D0990000]        <1> 	mov	esi, TRDOSPromptLabel
   241                              <1> get_next_prompt_label_char:
   242 00004688 803E20              <1> 	cmp	byte [esi], 20h
   243 0000468B 7203                <1> 	jb	short pass_prompt_label
   244 0000468D A4                  <1> 	movsb
   245 0000468E EBF8                <1> 	jmp	short get_next_prompt_label_char
   246                              <1> pass_prompt_label:
   247 00004690 C6075D              <1> 	mov	byte [edi], "]"
   248 00004693 47                  <1> 	inc	edi
   249 00004694 C60720              <1> 	mov	byte [edi], 20h
   250 00004697 47                  <1> 	inc	edi
   251 00004698 BE[AFA80000]        <1> 	mov	esi, Current_Dir_Drv
   252 0000469D 66A5                <1> 	movsw
   253 0000469F A4                  <1> 	movsb 
   254                              <1> loc_prompt_current_directory:
   255 000046A0 803E20              <1> 	cmp	byte [esi], 20h
   256 000046A3 7203                <1> 	jb	short pass_prompt_current_directory
   257 000046A5 A4                  <1> 	movsb
   258 000046A6 EBF8                <1> 	jmp	short loc_prompt_current_directory  
   259                              <1> pass_prompt_current_directory:
   260 000046A8 C6073E              <1> 	mov	byte [edi], '>'
   261 000046AB 47                  <1> 	inc	edi
   262 000046AC C60700              <1> 	mov	byte [edi], 0  
   263 000046AF BE[AEA90000]        <1> 	mov	esi, TextBuffer
   264 000046B4 E881F5FFFF          <1> 	call	print_msg
   265                              <1>         
   266                              <1> 	;sub	bl, bl ; video page = 0
   267                              <1> 	;call	get_cpos ; get cursor position
   268 000046B9 668B15[08A80000]    <1> 	mov	dx, [CURSOR_POSN] ; video page 0
   269 000046C0 8815[0EA90000]      <1> 	mov	[CursorColumn], dl
   270                              <1> 
   271                              <1> 	; 30/01/2016 (to show cursor on the row, again)
   272                              <1> 	; (Initial color attributes of video page 0 is 0)
   273                              <1> 	; (see: 'StartPMP' in trdos386.s)
   274                              <1> 	; 
   275                              <1> 	;mov	edi, 0B8000h ; start of video page 0
   276                              <1> 	;movzx	ecx, dl ; column	 
   277                              <1> 	;mov	al, 80
   278                              <1> 	;mul	dh
   279                              <1> 	;add	ax, cx
   280                              <1> 	;shl	ax, 1 ; character + attribute
   281                              <1> 	;add	di, ax ; (2*80*row) + (2*column)
   282                              <1> 	;neg	cl
   283                              <1> 	;add	cl, 80
   284                              <1> 	;mov	ax, 700h ;  ah = 7 (color attribute)
   285                              <1> 	;rep	stosw	
   286                              <1> 
   287                              <1> loc_rw_char:
   288 000046C6 E899000000          <1> 	call	rw_char
   289                              <1> loc_move_command:
   290 000046CB BE[5EA90000]        <1> 	mov	esi, CommandBuffer
   291 000046D0 89F7                <1> 	mov	edi, esi
   292 000046D2 31C9                <1> 	xor	ecx, ecx
   293                              <1> first_command_char:
   294 000046D4 AC                  <1> 	lodsb
   295 000046D5 3C20                <1> 	cmp	al, 20h
   296 000046D7 772E                <1> 	ja	short pass_space_control
   297 000046D9 7241                <1> 	jb	short loc_move_cmd_arguments_ok
   298 000046DB 81FE[ADA90000]      <1> 	cmp	esi, CommandBuffer + 79
   299 000046E1 72F1                <1> 	jb	short first_command_char
   300 000046E3 EB37                <1> 	jmp	short loc_move_cmd_arguments_ok
   301                              <1> 
   302                              <1> next_command_char:
   303 000046E5 AC                  <1> 	lodsb
   304 000046E6 3C20                <1> 	cmp	al, 20h
   305 000046E8 771D                <1> 	ja	short pass_space_control
   306 000046EA 7230                <1> 	jb	short loc_move_cmd_arguments_ok
   307                              <1> 
   308                              <1> loc_1st_cmd_arg: ; 30/01/2016
   309 000046EC AC                  <1> 	lodsb
   310 000046ED 3C20                <1> 	cmp	al, 20h
   311 000046EF 74FB                <1> 	je	short loc_1st_cmd_arg
   312 000046F1 7229                <1> 	jb	short loc_move_cmd_arguments_ok
   313                              <1> 	
   314 000046F3 C60700              <1>         mov     byte [edi], 0
   315 000046F6 47                  <1> 	inc	edi
   316                              <1> 
   317                              <1> loc_move_cmd_arguments:
   318 000046F7 AA                  <1> 	stosb
   319 000046F8 81FE[ADA90000]      <1> 	cmp	esi, CommandBuffer + 79
   320 000046FE 731C                <1> 	jnb	short loc_move_cmd_arguments_ok
   321 00004700 AC                  <1>         lodsb
   322 00004701 3C20                <1> 	cmp	al, 20h
   323 00004703 73F2                <1> 	jnb	short loc_move_cmd_arguments
   324 00004705 EB15                <1> 	jmp	short loc_move_cmd_arguments_ok
   325                              <1> 
   326                              <1> pass_space_control:
   327 00004707 3C61                <1> 	cmp	al, 61h
   328 00004709 7206                <1> 	jb	short pass_capitalize
   329 0000470B 3C7A                <1> 	cmp	al, 7Ah
   330 0000470D 7702                <1> 	ja	short pass_capitalize
   331 0000470F 24DF                <1> 	and	al, 0DFh
   332                              <1> pass_capitalize:
   333 00004711 AA                  <1> 	stosb   
   334 00004712 FEC1                <1> 	inc     cl
   335 00004714 81FE[ADA90000]      <1>         cmp     esi, CommandBuffer + 79
   336 0000471A 72C9                <1> 	jb      short next_command_char 
   337                              <1> 
   338                              <1> loc_move_cmd_arguments_ok:
   339 0000471C C60700              <1>         mov     byte [edi], 0
   340                              <1>        
   341                              <1> call_command_intepreter:
   342 0000471F E8DB080000          <1> 	call    command_interpreter
   343                              <1> 
   344 00004724 B950000000          <1>         mov	ecx, 80
   345                              <1> 	;mov	cx, 80
   346 00004729 BF[5EA90000]        <1> 	mov	edi, CommandBuffer
   347 0000472E 30C0                <1> 	xor	al, al
   348 00004730 F3AA                <1> 	rep	stosb
   349                              <1> 	;cmp	byte [Program_Exit], 0
   350                              <1> 	;ja	short loc_terminate_trdos
   351                              <1>         
   352                              <1> 	; 16/01/2016
   353 00004732 803D[16A20000]03    <1> 	cmp	byte [CRT_MODE], 3 ; 80*25 color
   354 00004739 741D                <1> 	je	short pass_set_txt_mode
   355                              <1> 
   356 0000473B E8B9CDFFFF          <1> 	call	set_txt_mode ; set vide mode to 03h
   357                              <1> 
   358                              <1> loc_check_active_page:
   359 00004740 30C0                <1> 	xor	al, al
   360 00004742 3805[18A80000]      <1> 	cmp	[ACTIVE_PAGE], al ; 0
   361 00004748 0F842CFFFFFF        <1>         je      loc_TRDOS_prompt 
   362                              <1> 	; AL = 0 = video page 0
   363 0000474E E840CEFFFF          <1> 	call	set_active_page
   364 00004753 E922FFFFFF          <1>         jmp     loc_TRDOS_prompt ; infinitive loop
   365                              <1> 
   366                              <1> pass_set_txt_mode: 
   367 00004758 BE[C6A40000]        <1> 	mov	esi, nextline
   368 0000475D E8D8F4FFFF          <1> 	call	print_msg
   369 00004762 EBDC                <1> 	jmp     short loc_check_active_page
   370                              <1> 
   371                              <1> rw_char:
   372                              <1> 	; 30/01/2016
   373                              <1> 	; 29/01/2016
   374                              <1> 	; 17/01/2016 (TRDOS 386 = TRDOS v2.0)
   375                              <1> 	; 2004-2005
   376                              <1> 	
   377                              <1> 	; DH = cursor row, DL = cursor column
   378                              <1> 	; BL = 0 = video page number (active page)
   379                              <1> 
   380                              <1> readnextchar:
   381 00004764 30E4                <1> 	xor     ah, ah
   382 00004766 E87CC4FFFF          <1> 	call	int16h
   383 0000476B 20C0                <1> 	and	al, al
   384 0000476D 7439                <1> 	jz	short loc_arrow    
   385 0000476F 3CE0                <1> 	cmp	al, 0E0h          
   386 00004771 7435                <1> 	je	short loc_arrow
   387 00004773 3C08                <1> 	cmp	al, 08h             
   388 00004775 7549                <1> 	jne	short char_return
   389                              <1> loc_back:
   390 00004777 3A15[0EA90000]      <1> 	cmp	dl, [CursorColumn]
   391 0000477D 76E5                <1> 	jna     short readnextchar
   392                              <1> prev_column:
   393 0000477F FECA                <1> 	dec	dl
   394                              <1> set_cursor_pos:
   395 00004781 6652                <1> 	push	dx
   396 00004783 30DB                <1> 	xor	bl, bl ; 0 = video page 0
   397                              <1> 	; DH = Row, DL = Column
   398 00004785 E8C0D0FFFF          <1> 	call	_set_cpos ; 17/01/2016
   399 0000478A 665A                <1>         pop	dx
   400 0000478C 0FB6DA              <1> 	movzx	ebx, dl
   401 0000478F 2A1D[0EA90000]      <1> 	sub	bl, [CursorColumn] 
   402 00004795 B407                <1> 	mov	ah, 7 ; color attribute
   403 00004797 B020                <1> 	mov	al, 20h
   404 00004799 8883[5EA90000]      <1> 	mov	[CommandBuffer+ebx], al
   405 0000479F 28DB                <1> 	sub	bl, bl ; video page 0
   406                              <1> 	;mov	cx, 1
   407 000047A1 E8DFCFFFFF          <1> 	call	_write_c_current ; 17/01/2016
   408                              <1> 	;mov	dx, [CURSOR_POSN]
   409 000047A6 EBBC                <1> 	jmp	short readnextchar
   410                              <1> loc_arrow:    
   411 000047A8 80FC4B              <1> 	cmp	ah, 4Bh
   412 000047AB 74CA                <1> 	je	short loc_back
   413 000047AD 80FC53              <1> 	cmp	ah, 53h
   414 000047B0 74C5                <1> 	je      short loc_back
   415 000047B2 80FC4D              <1> 	cmp	ah, 4Dh
   416 000047B5 75AD                <1> 	jne	short readnextchar
   417 000047B7 80FA4F              <1> 	cmp	dl, 79
   418 000047BA 73A8                <1> 	jnb	short readnextchar
   419 000047BC FEC2                <1> 	inc	dl
   420 000047BE EBC1                <1> 	jmp	short set_cursor_pos
   421                              <1> char_return:
   422 000047C0 0FB6DA              <1> 	movzx	ebx, dl
   423 000047C3 2A1D[0EA90000]      <1> 	sub	bl, [CursorColumn] 
   424 000047C9 3C20                <1> 	cmp	al, 20h
   425 000047CB 7220                <1> 	jb	short loc_escape
   426 000047CD 8883[5EA90000]      <1> 	mov	[CommandBuffer+ebx], al
   427 000047D3 28DB                <1> 	sub	bl, bl ; 0
   428 000047D5 80FA4F              <1> 	cmp	dl, 79
   429 000047D8 738A                <1> 	jnb	short readnextchar
   430 000047DA B407                <1> 	mov	ah, 7 ; color attribute
   431 000047DC E8D5CFFFFF          <1> 	call	WRITE_TTY
   432 000047E1 668B15[08A80000]    <1> 	mov	dx, [CURSOR_POSN] ; video page 0
   433 000047E8 E977FFFFFF          <1>         jmp     readnextchar
   434                              <1> loc_escape:
   435 000047ED 3C1B                <1> 	cmp	al, 1Bh
   436 000047EF 741A                <1> 	je	short rw_char_retn
   437                              <1> 	;
   438 000047F1 3C0D                <1> 	cmp	al, 0Dh ; CR
   439 000047F3 0F856BFFFFFF        <1>         jne     readnextchar
   440 000047F9 30DB                <1> 	xor	bl, bl ; 0
   441 000047FB B407                <1> 	mov	ah, 7 ; attribute/color
   442 000047FD E8B4CFFFFF          <1> 	call	WRITE_TTY
   443 00004802 B407                <1> 	mov	ah, 7 ; attribute/color
   444 00004804 B00A                <1> 	mov	al, 0Ah ; LF
   445 00004806 E8ABCFFFFF          <1> 	call	WRITE_TTY
   446                              <1> rw_char_retn:
   447 0000480B C3                  <1> 	retn
   448                              <1> 
   449                              <1> show_date:
   450                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   451                              <1>         ; 2004-2005
   452                              <1> 
   453                              <1> 	;mov	ah, 04h
   454                              <1> 	;call	int1Ah
   455 0000480C E8C0F1FFFF          <1> 	call	RTC_40	; GET RTC DATE
   456                              <1> 
   457 00004811 88D0                <1> 	mov	al, dl
   458 00004813 E8C6C3FFFF          <1>   	call	bcd_to_ascii
   459 00004818 66A3[C59A0000]      <1> 	mov	[Day], ax
   460                              <1> 
   461 0000481E 88F0                <1> 	mov	al, dh
   462 00004820 E8B9C3FFFF          <1>   	call	bcd_to_ascii
   463 00004825 66A3[C89A0000]      <1> 	mov	[Month], ax
   464                              <1> 
   465 0000482B 88E8                <1> 	mov	al, ch
   466 0000482D E8ACC3FFFF          <1>   	call	bcd_to_ascii
   467 00004832 66A3[CB9A0000]      <1> 	mov	[Century], ax
   468                              <1> 
   469 00004838 88C8                <1> 	mov	al, cl
   470 0000483A E89FC3FFFF          <1>   	call	bcd_to_ascii
   471 0000483F 66A3[CD9A0000]      <1> 	mov	word [Year], ax
   472                              <1> 
   473 00004845 BE[B59A0000]        <1> 	mov	esi, Msg_Show_Date
   474 0000484A E8EBF3FFFF          <1> 	call	print_msg
   475                              <1> 
   476 0000484F C3                  <1> 	retn
   477                              <1> 
   478                              <1> set_date:
   479                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   480                              <1>         ; 2004-2005
   481                              <1> 
   482 00004850 BE[999A0000]        <1> 	mov	esi, Msg_Enter_Date
   483 00004855 E8E0F3FFFF          <1> 	call	print_msg
   484                              <1> 
   485                              <1> loc_enter_day_1:
   486 0000485A 30E4                <1> 	xor     ah, ah
   487 0000485C E886C3FFFF          <1> 	call	int16h
   488                              <1> 	; AL = ASCII Code of the Character
   489 00004861 3C0D                <1> 	cmp	al, 13
   490 00004863 0F84B7010000        <1> 	je	loc_set_date_retn
   491 00004869 3C1B                <1> 	cmp	al, 27
   492 0000486B 0F84AF010000        <1> 	je	loc_set_date_retn
   493 00004871 A2[C59A0000]        <1> 	mov	[Day], al
   494 00004876 3C30                <1> 	cmp	al, '0'
   495 00004878 0F82AD010000        <1> 	jb	loc_set_date_stc_0
   496 0000487E 3C33                <1> 	cmp	al, '3'
   497 00004880 0F87A5010000        <1> 	ja	loc_set_date_stc_0
   498                              <1> 	;sub	bl, bl ; 0
   499 00004886 B407                <1> 	mov	ah, 7 ; attribute/color
   500 00004888 E829CFFFFF          <1> 	call	WRITE_TTY
   501                              <1> loc_enter_day_2:
   502 0000488D 30E4                <1> 	xor     ah, ah
   503 0000488F E853C3FFFF          <1> 	call	int16h
   504                              <1> 	; AL = ASCII Code of the Character
   505 00004894 3C1B                <1> 	cmp	al, 27
   506 00004896 0F8484010000        <1>         je      loc_set_date_retn
   507 0000489C A2[C69A0000]        <1> 	mov	[Day+1], al
   508 000048A1 3C30                <1> 	cmp	al, '0'
   509 000048A3 0F828C010000        <1>         jb      loc_set_date_stc_1
   510 000048A9 3C39                <1> 	cmp	al, '9'
   511 000048AB 0F8784010000        <1>         ja      loc_set_date_stc_1
   512 000048B1 803D[C59A0000]33    <1> 	cmp	byte [Day], '3'
   513 000048B8 7208                <1> 	jb	short pass_set_day_31
   514 000048BA 3C31                <1> 	cmp	al, '1'
   515 000048BC 0F8773010000        <1>         ja      loc_set_date_stc_1
   516                              <1> pass_set_day_31:
   517                              <1> 	;sub	bl, bl ; 0
   518 000048C2 B407                <1> 	mov	ah, 7 ; attribute/color
   519 000048C4 E8EDCEFFFF          <1> 	call	WRITE_TTY
   520                              <1> loc_enter_separator_1:
   521 000048C9 28E4                <1> 	sub     ah, ah ; 0
   522 000048CB E817C3FFFF          <1> 	call	int16h
   523                              <1> 	; AL = ASCII Code of the Character
   524 000048D0 3C1B                <1> 	cmp	al, 27
   525 000048D2 0F8448010000        <1>         je      loc_set_date_retn
   526 000048D8 3C2D                <1> 	cmp	al, '-'
   527 000048DA 7408                <1> 	je	short pass_set_date_separator_1
   528 000048DC 3C2F                <1> 	cmp	al, '/'
   529 000048DE 0F856C010000        <1>         jne     loc_set_date_stc_2
   530                              <1> pass_set_date_separator_1:
   531                              <1> 	;xor	bl, bl ; 0
   532 000048E4 B407                <1> 	mov	ah, 7 ; attribute/color
   533 000048E6 E8CBCEFFFF          <1> 	call	WRITE_TTY
   534                              <1> loc_enter_month_1:
   535 000048EB 30E4                <1> 	xor     ah, ah ; 0
   536 000048ED E8F5C2FFFF          <1> 	call	int16h
   537                              <1> 	; AL = ASCII Code of the Character
   538 000048F2 3C1B                <1> 	cmp	al, 27
   539 000048F4 0F8426010000        <1>         je      loc_set_date_retn
   540 000048FA A2[C89A0000]        <1> 	mov	[Month], al
   541 000048FF 3C30                <1> 	cmp	al, '0'
   542 00004901 0F8264010000        <1>         jb      loc_set_date_stc_3
   543 00004907 3C31                <1> 	cmp	al, '1'
   544 00004909 0F875C010000        <1>         ja      loc_set_date_stc_3
   545                              <1> 	;sub	bl, bl
   546 0000490F B407                <1> 	mov	ah, 7 ; attribute/color
   547 00004911 E8A0CEFFFF          <1> 	call	WRITE_TTY
   548                              <1> loc_enter_month_2:
   549 00004916 30E4                <1> 	xor     ah, ah
   550 00004918 E8CAC2FFFF          <1> 	call	int16h
   551                              <1> 	; AL = ASCII Code of the Character
   552 0000491D 3C1B                <1> 	cmp	al, 27
   553 0000491F 0F84FB000000        <1>         je      loc_set_date_retn
   554 00004925 A2[C99A0000]        <1> 	mov	[Month+1], al
   555 0000492A 3C30                <1> 	cmp	al, '0'
   556 0000492C 0F8254010000        <1>         jb      loc_set_date_stc_4
   557 00004932 3C39                <1> 	cmp	al, '9'
   558 00004934 0F874C010000        <1>         ja      loc_set_date_stc_4
   559 0000493A 803D[C89A0000]31    <1> 	cmp	byte [Month], '1'
   560 00004941 7208                <1> 	jb	short pass_set_month_12
   561 00004943 3C32                <1> 	cmp	al, '2'
   562 00004945 0F873B010000        <1>         ja      loc_set_date_stc_4
   563                              <1> pass_set_month_12:
   564                              <1> 	;sub	bl, bl
   565 0000494B B407                <1> 	mov	ah, 7 ; attribute/color
   566 0000494D E864CEFFFF          <1> 	call	WRITE_TTY
   567                              <1> loc_enter_separator_2:
   568 00004952 28E4                <1> 	sub     ah, ah
   569 00004954 E88EC2FFFF          <1> 	call	int16h
   570                              <1> 	; AL = ASCII Code of the Character
   571 00004959 3C1B                <1> 	cmp	al, 27
   572 0000495B 0F84BF000000        <1>         je      loc_set_date_retn
   573 00004961 3C2D                <1> 	cmp	al, '-'
   574 00004963 7408                <1> 	je	short pass_set_date_separator_2
   575 00004965 3C2F                <1> 	cmp	al, '/'
   576 00004967 0F8534010000        <1>         jne     loc_set_date_stc_5
   577                              <1> pass_set_date_separator_2:
   578                              <1> 	;xor	bl, bl
   579 0000496D B407                <1> 	mov	ah, 7 ; attribute/color
   580 0000496F E842CEFFFF          <1> 	call	WRITE_TTY
   581                              <1> loc_enter_year_1:
   582 00004974 30E4                <1> 	xor    ah, ah
   583 00004976 E86CC2FFFF          <1> 	call	int16h
   584                              <1> 	; AL = ASCII Code of the Character
   585 0000497B 3C1B                <1> 	cmp	al, 27
   586 0000497D 0F849D000000        <1>         je      loc_set_date_retn
   587 00004983 A2[CD9A0000]        <1> 	mov	[Year], al
   588 00004988 3C30                <1> 	cmp	al, '0'
   589 0000498A 0F822C010000        <1>         jb      loc_set_date_stc_6
   590 00004990 3C39                <1> 	cmp	al, '9'
   591 00004992 0F8724010000        <1>         ja      loc_set_date_stc_6
   592                              <1> 	;sub	bl, bl
   593 00004998 B407                <1> 	mov	ah, 7 ; attribute/color
   594 0000499A E817CEFFFF          <1> 	call	WRITE_TTY
   595                              <1> loc_enter_year_2:
   596 0000499F 30E4                <1> 	xor	ah, ah
   597 000049A1 E841C2FFFF          <1> 	call	int16h
   598                              <1> 	; AL = ASCII Code of the Character
   599 000049A6 3C1B                <1> 	cmp	al, 27
   600 000049A8 7476                <1> 	je	short loc_set_date_retn
   601 000049AA A2[CE9A0000]        <1> 	mov	byte [Year+1], al
   602 000049AF 3C30                <1> 	cmp	al, '0'
   603 000049B1 0F8220010000        <1>         jb      loc_set_date_stc_7
   604 000049B7 3C39                <1> 	cmp	al, '9'
   605 000049B9 0F8718010000        <1>         ja      loc_set_date_stc_7
   606                              <1> 	;sub	bl, bl
   607 000049BF B407                <1> 	mov	ah, 7 ; attribute/color
   608 000049C1 E8F0CDFFFF          <1> 	call	WRITE_TTY
   609                              <1> loc_set_date_get_lchar_again:
   610 000049C6 28E4                <1> 	sub	ah, ah ; 0
   611 000049C8 E81AC2FFFF          <1> 	call	int16h
   612                              <1> 	; AL = ASCII Code of the Character
   613 000049CD 3C0D                <1> 	cmp	al, 13 ; ENTER key
   614 000049CF 7412                <1> 	je	short loc_set_date_progress
   615 000049D1 3C1B                <1> 	cmp	al, 27 ; ESC key
   616 000049D3 744B                <1> 	je	short loc_set_date_retn
   617                              <1> 	;
   618 000049D5 E82A010000          <1> 	call	check_for_backspace
   619 000049DA 75EA                <1> 	jne	short loc_set_date_get_lchar_again
   620                              <1> 
   621                              <1> loc_set_date_bs_8:
   622 000049DC E811010000          <1> 	call	write_backspace
   623 000049E1 EBBC                <1> 	jmp	short loc_enter_year_2
   624                              <1> 
   625                              <1> loc_set_date_progress:
   626                              <1> 	; Get Current Date
   627                              <1> 	;mov	ah, 04h
   628                              <1> 	;call	int1Ah
   629 000049E3 E8E9EFFFFF          <1> 	call	RTC_40	; GET RTC DATE
   630                              <1> 	; CH = century (in BCD)
   631                              <1> 
   632 000049E8 66A1[CD9A0000]      <1> 	mov	ax, [Year]
   633 000049EE 662D3030            <1> 	sub	ax, '00'
   634 000049F2 C0E004              <1> 	shl	al, 4 ; * 16
   635 000049F5 88C1                <1> 	mov	cl, al
   636 000049F7 00E1                <1> 	add	cl, ah
   637 000049F9 66A1[C89A0000]      <1> 	mov	ax, [Month]
   638 000049FF 662D3030            <1> 	sub	ax, '00'
   639 00004A03 C0E004              <1> 	shl	al, 4 ; * 16
   640 00004A06 88C6                <1> 	mov	dh, al
   641 00004A08 00E6                <1> 	add	dh, ah
   642 00004A0A 66A1[C59A0000]      <1> 	mov	ax, [Day]
   643 00004A10 662D3030            <1> 	sub	ax, '00'
   644 00004A14 C0E004              <1> 	shl	al, 4 ; * 16
   645 00004A17 88C2                <1> 	mov	dl, al
   646 00004A19 00E2                <1> 	add	dl, ah
   647                              <1> 
   648                              <1> 	;mov	ah, 05h
   649                              <1> 	;call	int1Ah
   650 00004A1B E8DEEFFFFF          <1> 	call	RTC_50	; SET RTC DATE
   651                              <1> 
   652                              <1> loc_set_date_retn:
   653 00004A20 BE[C6A40000]        <1> 	mov	esi, nextline
   654 00004A25 E810F2FFFF          <1> 	call	print_msg
   655 00004A2A C3                  <1> 	retn
   656                              <1> 
   657                              <1> loc_set_date_stc_0:
   658                              <1> 	;xor	bl, bl ; video page 0
   659 00004A2B E864CEFFFF          <1> 	call	beeper ; BEEP !
   660 00004A30 E925FEFFFF          <1>         jmp     loc_enter_day_1
   661                              <1> loc_set_date_stc_1:
   662 00004A35 E8CA000000          <1> 	call	check_for_backspace
   663 00004A3A 740A                <1> 	je	short loc_set_date_bs_1
   664                              <1> 	;xor	bl, bl ; video page 0
   665 00004A3C E853CEFFFF          <1> 	call	beeper ; BEEP !
   666 00004A41 E947FEFFFF          <1>         jmp     loc_enter_day_2
   667                              <1> loc_set_date_bs_1:
   668 00004A46 E8A7000000          <1> 	call	write_backspace
   669 00004A4B E90AFEFFFF          <1>         jmp     loc_enter_day_1
   670                              <1> loc_set_date_stc_2:
   671 00004A50 E8AF000000          <1> 	call	check_for_backspace
   672 00004A55 740A                <1> 	je	short loc_set_date_bs_2
   673                              <1> 	;xor	bl, bl ; video page 0
   674 00004A57 E838CEFFFF          <1> 	call	beeper ; BEEP !
   675 00004A5C E968FEFFFF          <1>         jmp     loc_enter_separator_1
   676                              <1> loc_set_date_bs_2:
   677 00004A61 E88C000000          <1> 	call	write_backspace
   678 00004A66 E922FEFFFF          <1>         jmp     loc_enter_day_2
   679                              <1> loc_set_date_stc_3:
   680 00004A6B E894000000          <1> 	call	check_for_backspace	
   681 00004A70 740A                <1> 	je short loc_set_date_bs_3
   682                              <1> 	;xor	bl, bl ; video page 0
   683 00004A72 E81DCEFFFF          <1> 	call	beeper ; BEEP !
   684 00004A77 E96FFEFFFF          <1>         jmp     loc_enter_month_1
   685                              <1> loc_set_date_bs_3:
   686 00004A7C E871000000          <1> 	call	write_backspace
   687 00004A81 E943FEFFFF          <1>         jmp     loc_enter_separator_1
   688                              <1> loc_set_date_stc_4:
   689 00004A86 E879000000          <1> 	call	check_for_backspace	
   690 00004A8B 740A                <1> 	je	short loc_set_date_bs_4
   691                              <1> 	;xor	bl, bl ; video page 0
   692 00004A8D E802CEFFFF          <1> 	call	beeper ; BEEP !
   693 00004A92 E97FFEFFFF          <1>         jmp     loc_enter_month_2
   694                              <1> loc_set_date_bs_4:
   695 00004A97 E856000000          <1> 	call	write_backspace
   696 00004A9C E94AFEFFFF          <1>         jmp     loc_enter_month_1
   697                              <1> loc_set_date_stc_5:
   698 00004AA1 E85E000000          <1> 	call	check_for_backspace
   699 00004AA6 740A                <1> 	je	short loc_set_date_bs_5
   700                              <1> 	;xor	bl, bl ; video page 0
   701 00004AA8 E8E7CDFFFF          <1> 	call	beeper ; BEEP !
   702 00004AAD E9A0FEFFFF          <1>         jmp     loc_enter_separator_2
   703                              <1> loc_set_date_bs_5:
   704 00004AB2 E83B000000          <1> 	call	write_backspace
   705 00004AB7 E95AFEFFFF          <1>         jmp     loc_enter_month_2
   706                              <1> loc_set_date_stc_6:
   707 00004ABC E843000000          <1> 	call	check_for_backspace
   708 00004AC1 740A                <1>         je      short  loc_set_date_bs_6
   709                              <1> 	;xor	bl, bl ; video page 0
   710 00004AC3 E8CCCDFFFF          <1> 	call	beeper ; BEEP !
   711 00004AC8 E9A7FEFFFF          <1>         jmp     loc_enter_year_1
   712                              <1> loc_set_date_bs_6:
   713 00004ACD E820000000          <1> 	call	write_backspace
   714 00004AD2 E97BFEFFFF          <1>         jmp     loc_enter_separator_2
   715                              <1> loc_set_date_stc_7:
   716 00004AD7 E828000000          <1> 	call	check_for_backspace
   717 00004ADC 740A                <1> 	je	short loc_set_date_bs_7
   718                              <1> 	;xor	bl, bl ; video page 0
   719 00004ADE E8B1CDFFFF          <1> 	call	beeper ; BEEP !
   720 00004AE3 E9B7FEFFFF          <1>         jmp     loc_enter_year_2
   721                              <1> loc_set_date_bs_7:
   722 00004AE8 E805000000          <1> 	call	write_backspace
   723 00004AED E982FEFFFF          <1>         jmp     loc_enter_year_1
   724                              <1> 
   725                              <1> write_backspace:
   726                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   727 00004AF2 B008                <1> 	mov	al, 08h ; BACKSPACE
   728                              <1> 	;xor	bl, bl
   729 00004AF4 B407                <1> 	mov	ah, 7 ; attribute/color
   730 00004AF6 E8BBCCFFFF          <1> 	call	WRITE_TTY
   731 00004AFB B020                <1> 	mov	al, 20h ; BLANK/SPACE char 
   732                              <1> 	;xor	bl, bl
   733 00004AFD B407                <1> 	mov	ah, 7 ; attribute/color
   734                              <1> 	;call	_write_c_current
   735                              <1> 	;retn
   736 00004AFF E981CCFFFF          <1> 	jmp	_write_c_current
   737                              <1> 
   738                              <1> check_for_backspace:
   739                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   740 00004B04 663D080E            <1> 	cmp	ax, 0E08h
   741 00004B08 7410                <1> 	je	short cfbs_retn
   742 00004B0A 663DE04B            <1> 	cmp	ax, 4BE0h
   743 00004B0E 740A                <1> 	je	short cfbs_retn
   744 00004B10 663D004B            <1> 	cmp	ax, 4B00h
   745 00004B14 7404                <1> 	je	short cfbs_retn
   746 00004B16 663DE053            <1> 	cmp	ax, 53E0h
   747                              <1> cfbs_retn:
   748 00004B1A C3                  <1> 	retn
   749                              <1> 
   750                              <1> show_time:
   751                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   752                              <1>         ; 2004-2005
   753                              <1> 
   754                              <1> 	;mov	ah, 02h
   755                              <1> 	;call	int1Ah
   756 00004B1B E840EEFFFF          <1> 	call	RTC_20	; GET RTC TIME
   757                              <1> 	
   758 00004B20 88E8                <1> 	mov	al, ch
   759 00004B22 E8B7C0FFFF          <1> 	call	bcd_to_ascii
   760 00004B27 66A3[F39A0000]      <1> 	mov	[Hour], ax
   761                              <1> 
   762 00004B2D 88C8                <1> 	mov	al, cl
   763 00004B2F E8AAC0FFFF          <1> 	call	bcd_to_ascii
   764 00004B34 66A3[F69A0000]      <1> 	mov	[Minute], ax
   765                              <1> 
   766 00004B3A 88F0                <1> 	mov	al, dh
   767 00004B3C E89DC0FFFF          <1> 	call	bcd_to_ascii
   768 00004B41 66A3[F99A0000]      <1> 	mov	[Second], ax
   769                              <1> 
   770 00004B47 BE[E39A0000]        <1> 	mov	esi, Msg_Show_Time
   771 00004B4C E8E9F0FFFF          <1> 	call	print_msg
   772 00004B51 C3                  <1> 	retn
   773                              <1> 
   774                              <1> set_time:
   775                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
   776                              <1>         ; 2004-2005
   777                              <1> 
   778 00004B52 BE[D29A0000]        <1> 	mov 	esi, Msg_Enter_Time
   779 00004B57 E8DEF0FFFF          <1> 	call	print_msg
   780                              <1> 
   781                              <1> loc_enter_hour_1:
   782 00004B5C 30E4                <1> 	xor     ah, ah
   783 00004B5E E884C0FFFF          <1> 	call	int16h
   784                              <1> 	; AL = ASCII Code of the Character
   785 00004B63 3C0D                <1> 	cmp	al, 13 ; ENTER key
   786 00004B65 0F84AE010000        <1>         je      loc_set_time_retn
   787 00004B6B 3C1B                <1> 	cmp	al, 27 ; ESC key
   788 00004B6D 0F84A6010000        <1>         je      loc_set_time_retn
   789 00004B73 A2[F39A0000]        <1> 	mov	[Hour], al
   790 00004B78 3C30                <1> 	cmp	al, '0'
   791 00004B7A 0F82A4010000        <1>         jb      loc_set_time_stc_0
   792 00004B80 3C32                <1> 	cmp	al, '2'
   793 00004B82 0F879C010000        <1>         ja      loc_set_time_stc_0
   794                              <1> 	;sub	bl, bl ; 0
   795 00004B88 B407                <1> 	mov	ah, 7 ; attribute/color
   796 00004B8A E827CCFFFF          <1> 	call	WRITE_TTY
   797                              <1> loc_enter_hour_2:
   798 00004B8F 30E4                <1> 	xor     ah, ah
   799 00004B91 E851C0FFFF          <1> 	call	int16h
   800                              <1> 	; AL = ASCII Code of the Character
   801 00004B96 3C1B                <1> 	cmp	al, 27
   802 00004B98 0F847B010000        <1>         je      loc_set_time_retn
   803 00004B9E A2[F49A0000]        <1> 	mov	[Hour+1], al
   804 00004BA3 3C30                <1> 	cmp	al, '0'
   805 00004BA5 0F8283010000        <1>         jb      loc_set_time_stc_1
   806 00004BAB 3C39                <1> 	cmp	al, '9'
   807 00004BAD 0F877B010000        <1> 	ja	loc_set_time_stc_1
   808 00004BB3 803D[F39A0000]32    <1>         cmp     byte [Hour], '2'
   809 00004BBA 7208                <1> 	jb	short pass_set_time_24
   810 00004BBC 3C34                <1> 	cmp	al, '4'
   811 00004BBE 0F876A010000        <1>         ja      loc_set_time_stc_1
   812                              <1> pass_set_time_24:
   813                              <1> 	;sub	bl, bl ; 0
   814 00004BC4 B407                <1> 	mov	ah, 7 ; attribute/color
   815 00004BC6 E8EBCBFFFF          <1> 	call	WRITE_TTY
   816                              <1> loc_enter_time_separator_1:
   817 00004BCB 28E4                <1> 	sub    ah, ah ; 0
   818 00004BCD E815C0FFFF          <1> 	call	int16h
   819                              <1> 	; AL = ASCII Code of the Character
   820 00004BD2 3C1B                <1> 	cmp	al, 27
   821 00004BD4 0F843F010000        <1>         je      loc_set_time_retn
   822 00004BDA 3C3A                <1> 	cmp	al, ':'
   823 00004BDC 0F8567010000        <1>         jne     loc_set_time_stc_2
   824                              <1> 	;xor	bl, bl
   825 00004BE2 B407                <1> 	mov	ah, 7 ; attribute/color
   826 00004BE4 E8CDCBFFFF          <1> 	call	WRITE_TTY
   827                              <1> loc_enter_minute_1:
   828 00004BE9 30E4                <1> 	xor     ah, ah
   829 00004BEB E8F7BFFFFF          <1> 	call	int16h
   830                              <1> 	; AL = ASCII Code of the Character
   831 00004BF0 3C1B                <1> 	cmp	al, 27
   832 00004BF2 0F8421010000        <1>         je      loc_set_time_retn
   833 00004BF8 A2[F69A0000]        <1> 	mov	[Minute], al
   834 00004BFD 3C30                <1> 	cmp	al, '0'
   835 00004BFF 0F825F010000        <1>         jb      loc_set_time_stc_3
   836 00004C05 3C35                <1> 	cmp	al, '5'
   837 00004C07 0F8757010000        <1>         ja      loc_set_time_stc_3
   838                              <1> 	;sub	bl, bl
   839 00004C0D B407                <1> 	mov	ah, 7 ; attribute/color
   840 00004C0F E8A2CBFFFF          <1> 	call	WRITE_TTY
   841                              <1> loc_enter_minute_2:
   842 00004C14 30E4                <1> 	xor     ah, ah
   843 00004C16 E8CCBFFFFF          <1> 	call	int16h
   844                              <1> 	; AL = ASCII Code of the Character
   845 00004C1B 3C1B                <1> 	cmp	al, 27
   846 00004C1D 0F84F6000000        <1>         je      loc_set_time_retn
   847 00004C23 A2[F79A0000]        <1> 	mov	[Minute+1], al
   848 00004C28 3C30                <1> 	cmp	al, '0'
   849 00004C2A 0F824F010000        <1>         jb      loc_set_time_stc_4
   850 00004C30 3C39                <1> 	cmp	al, '9'
   851 00004C32 0F8747010000        <1>         ja      loc_set_time_stc_4
   852                              <1> 	;sub	bl, bl
   853 00004C38 B407                <1> 	mov	ah, 7 ; attribute/color
   854 00004C3A E877CBFFFF          <1> 	call	WRITE_TTY
   855                              <1> loc_enter_time_separator_2:
   856 00004C3F 66C705[F99A0000]30- <1> 	mov	word [Second], 3030h
   856 00004C47 30                  <1>
   857 00004C48 28E4                <1> 	sub     ah, ah
   858 00004C4A E898BFFFFF          <1> 	call	int16h
   859                              <1> 	; AL = ASCII Code of the Character
   860 00004C4F 3C0D                <1> 	cmp	al, 13
   861 00004C51 0F8485000000        <1>         je      loc_set_time_progress
   862 00004C57 3C1B                <1> 	cmp	al, 27
   863 00004C59 0F84BA000000        <1>         je      loc_set_time_retn
   864 00004C5F 3C3A                <1> 	cmp	al, ':'
   865 00004C61 0F8533010000        <1>         jne     loc_set_time_stc_5
   866                              <1> 	;xor	bl, bl
   867 00004C67 B407                <1> 	mov	ah, 7 ; attribute/color
   868 00004C69 E848CBFFFF          <1> 	call	WRITE_TTY
   869                              <1> loc_enter_second_1:
   870 00004C6E 30E4                <1> 	xor     ah, ah
   871 00004C70 E872BFFFFF          <1> 	call	int16h
   872                              <1> 	; AL = ASCII Code of the Character
   873 00004C75 3C0D                <1> 	cmp	al, 13
   874 00004C77 7463                <1> 	je	short loc_set_time_progress
   875 00004C79 3C1B                <1> 	cmp	al, 27
   876 00004C7B 0F8498000000        <1>         je      loc_set_time_retn
   877 00004C81 A2[F99A0000]        <1> 	mov	[Second], al
   878 00004C86 3C30                <1> 	cmp	al, '0'
   879 00004C88 0F8227010000        <1>         jb      loc_set_time_stc_6
   880 00004C8E 3C35                <1> 	cmp	al, '5'
   881 00004C90 0F871F010000        <1>         ja      loc_set_time_stc_6
   882                              <1> 	;sub	bl, bl
   883 00004C96 B407                <1> 	mov	ah, 7 ; attribute/color
   884 00004C98 E819CBFFFF          <1> 	call	WRITE_TTY
   885                              <1> loc_enter_second_2:
   886 00004C9D 30E4                <1> 	xor     ah, ah
   887 00004C9F E843BFFFFF          <1> 	call	int16h
   888                              <1> 	; AL = ASCII Code of the Character
   889 00004CA4 3C1B                <1> 	cmp	al, 27
   890 00004CA6 7471                <1> 	je	short loc_set_time_retn
   891 00004CA8 3C30                <1> 	cmp	al, '0'
   892 00004CAA 0F8229010000        <1>         jb      loc_set_time_stc_7
   893 00004CB0 3C39                <1> 	cmp	al, '9'
   894 00004CB2 0F8721010000        <1>         ja      loc_set_time_stc_7
   895                              <1> 	;sub	bl, bl
   896 00004CB8 B407                <1> 	mov	ah, 7 ; attribute/color
   897 00004CBA E8F7CAFFFF          <1> 	call	WRITE_TTY
   898                              <1> loc_set_time_get_lchar_again:
   899 00004CBF 28E4                <1> 	sub	ah, ah ; 0
   900 00004CC1 E821BFFFFF          <1> 	call	int16h
   901                              <1> 	; AL = ASCII Code of the Character
   902 00004CC6 3C0D                <1> 	cmp	al, 13
   903 00004CC8 7412                <1> 	je	short loc_set_time_progress
   904 00004CCA 3C1B                <1> 	cmp	al, 27
   905 00004CCC 744B                <1> 	je	short loc_set_time_retn
   906                              <1> 	;
   907 00004CCE E831FEFFFF          <1> 	call	check_for_backspace
   908 00004CD3 75EA                <1> 	jne	short loc_set_time_get_lchar_again
   909                              <1> 
   910                              <1> loc_set_time_bs_8:
   911 00004CD5 E818FEFFFF          <1> 	call	write_backspace
   912 00004CDA EBC1                <1> 	jmp	short loc_enter_second_2
   913                              <1> 
   914                              <1> loc_set_time_progress:
   915                              <1> 	; Get Current Time
   916                              <1> 	;mov 	ah, 02h
   917                              <1> 	;call	int1Ah
   918 00004CDC E87FECFFFF          <1> 	call	RTC_20	; GET RTC TIME
   919                              <1> 	;DL = Daylight Savings Enable option (0-1)	
   920                              <1> 
   921 00004CE1 66A1[F39A0000]      <1> 	mov	ax, [Hour]
   922 00004CE7 662D3030            <1> 	sub	ax, '00'
   923 00004CEB C0E004              <1> 	shl	al, 4 ; * 16
   924 00004CEE 88C5                <1> 	mov	ch, al
   925 00004CF0 00E5                <1> 	add	ch, ah
   926 00004CF2 66A1[F69A0000]      <1> 	mov	ax, [Minute]
   927 00004CF8 662D3030            <1> 	sub	ax, '00'
   928 00004CFC C0E004              <1> 	shl	al, 4 ; * 16
   929 00004CFF 88C1                <1> 	mov	cl, al
   930 00004D01 00E1                <1> 	add	cl, ah
   931 00004D03 66A1[F99A0000]      <1> 	mov	ax, [Second]
   932 00004D09 662D3030            <1> 	sub	ax, '00'
   933 00004D0D C0E004              <1> 	shl	al, 4 ; * 16
   934 00004D10 88C6                <1> 	mov	dh, al
   935 00004D12 00E6                <1> 	add	dh, ah
   936                              <1> 	
   937                              <1> 	;mov	ah, 03h
   938                              <1> 	;call	int1Ah
   939 00004D14 E876ECFFFF          <1> 	call	RTC_30	; SET RTC TIME
   940                              <1> 
   941                              <1> loc_set_time_retn:
   942 00004D19 BE[C6A40000]        <1> 	mov 	esi, nextline
   943 00004D1E E817EFFFFF          <1> 	call	print_msg
   944 00004D23 C3                  <1> 	retn
   945                              <1> 
   946                              <1> loc_set_time_stc_0:
   947                              <1> 	;xor	bl, bl ; video page 0
   948 00004D24 E86BCBFFFF          <1> 	call	beeper ; BEEP !
   949 00004D29 E92EFEFFFF          <1>         jmp     loc_enter_hour_1
   950                              <1> loc_set_time_stc_1:
   951 00004D2E E8D1FDFFFF          <1> 	call	check_for_backspace
   952 00004D33 740A                <1> 	je	short loc_set_time_bs_1
   953                              <1> 	;xor	bl, bl ; video page 0
   954 00004D35 E85ACBFFFF          <1> 	call	beeper ; BEEP !
   955 00004D3A E950FEFFFF          <1>         jmp     loc_enter_hour_2
   956                              <1> loc_set_time_bs_1:
   957 00004D3F E8AEFDFFFF          <1> 	call	write_backspace
   958 00004D44 E913FEFFFF          <1>         jmp     loc_enter_hour_1
   959                              <1> loc_set_time_stc_2:
   960 00004D49 E8B6FDFFFF          <1> 	call	check_for_backspace
   961 00004D4E 740A                <1> 	je	short loc_set_time_bs_2
   962                              <1> 	;xor	bl, bl ; video page 0
   963 00004D50 E83FCBFFFF          <1> 	call	beeper ; BEEP !
   964 00004D55 E971FEFFFF          <1>         jmp     loc_enter_time_separator_1
   965                              <1> loc_set_time_bs_2:
   966 00004D5A E893FDFFFF          <1> 	call	write_backspace
   967 00004D5F E92BFEFFFF          <1>         jmp     loc_enter_hour_2
   968                              <1> loc_set_time_stc_3:
   969 00004D64 E89BFDFFFF          <1> 	call	check_for_backspace
   970 00004D69 740A                <1> 	je	short loc_set_time_bs_3
   971                              <1> 	;xor	bl, bl ; video page 0
   972 00004D6B E824CBFFFF          <1> 	call	beeper ; BEEP !6
   973 00004D70 E974FEFFFF          <1>         jmp     loc_enter_minute_1
   974                              <1> loc_set_time_bs_3:
   975 00004D75 E878FDFFFF          <1> 	call	write_backspace
   976 00004D7A E94CFEFFFF          <1>         jmp     loc_enter_time_separator_1
   977                              <1> loc_set_time_stc_4:
   978 00004D7F E880FDFFFF          <1> 	call	check_for_backspace
   979 00004D84 740A                <1> 	je	short loc_set_time_bs_4
   980                              <1> 	;xor	bl, bl ; video page 0
   981 00004D86 E809CBFFFF          <1> 	call	beeper ; BEEP !
   982 00004D8B E984FEFFFF          <1>         jmp     loc_enter_minute_2
   983                              <1> loc_set_time_bs_4:
   984 00004D90 E85DFDFFFF          <1> 	call	write_backspace
   985 00004D95 E94FFEFFFF          <1>         jmp     loc_enter_minute_1
   986                              <1> loc_set_time_stc_5:
   987 00004D9A E865FDFFFF          <1> 	call	check_for_backspace
   988 00004D9F 740A                <1> 	je	short loc_set_time_bs_5
   989                              <1> 	;xor	bl, bl ; video page 0
   990 00004DA1 E8EECAFFFF          <1> 	call	beeper ; BEEP !
   991 00004DA6 E994FEFFFF          <1>         jmp     loc_enter_time_separator_2
   992                              <1> loc_set_time_bs_5:
   993 00004DAB E842FDFFFF          <1> 	call	write_backspace
   994 00004DB0 E95FFEFFFF          <1>         jmp     loc_enter_minute_2
   995                              <1> loc_set_time_stc_6:
   996 00004DB5 E84AFDFFFF          <1> 	call	check_for_backspace
   997 00004DBA 7413                <1> 	je	short loc_set_time_bs_6
   998                              <1> 	;xor	bl, bl ; video page 0
   999 00004DBC E8D3CAFFFF          <1> 	call	beeper ; BEEP !
  1000 00004DC1 66C705[F99A0000]30- <1> 	mov	word [Second], 3030h
  1000 00004DC9 30                  <1>
  1001 00004DCA E99FFEFFFF          <1>         jmp     loc_enter_second_1
  1002                              <1> loc_set_time_bs_6:
  1003 00004DCF E81EFDFFFF          <1> 	call	write_backspace
  1004 00004DD4 E966FEFFFF          <1>         jmp     loc_enter_time_separator_2
  1005                              <1> loc_set_time_stc_7:
  1006 00004DD9 E826FDFFFF          <1> 	call	check_for_backspace
  1007 00004DDE 740A                <1> 	je	short loc_set_time_bs_7
  1008                              <1> 	;xor	bl, bl ; video page 0
  1009 00004DE0 E8AFCAFFFF          <1> 	call	beeper ; BEEP !
  1010 00004DE5 E9B3FEFFFF          <1>         jmp     loc_enter_second_2
  1011                              <1> loc_set_time_bs_7:
  1012 00004DEA E803FDFFFF          <1> 	call	write_backspace
  1013 00004DEF E97AFEFFFF          <1>         jmp     loc_enter_second_1
  1014                              <1> 
  1015                              <1> print_volume_info:
  1016                              <1> 	; 01/03/2016
  1017                              <1> 	; 08/02/2016
  1018                              <1> 	; 06/02/2016
  1019                              <1> 	; 04/02/2016
  1020                              <1> 	; 18/01/2016 (TRDOS 386 = TRDOS v2.0)
  1021                              <1> 	; 25/10/2009
  1022                              <1> 	;
  1023                              <1> 	; "Volume Serial No: "
  1024                              <1>  	;
  1025                              <1> 	; INPUT  : AL = DOS Drive Number
  1026                              <1> 	; OUTPUT : AH = FS Type
  1027                              <1> 	;          AL = DOS Drive Name
  1028                              <1> 	; CF = 0 -> OK
  1029                              <1> 	; CF = 1 -> Drive not ready 
  1030                              <1> 
  1031 00004DF4 88C4                <1> 	mov	ah, al
  1032 00004DF6 28C0                <1> 	sub	al, al
  1033 00004DF8 0FB7F0              <1> 	movzx	esi, ax	
  1034 00004DFB 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1035 00004E01 8A06                <1> 	mov	al, [esi]
  1036 00004E03 3C41                <1> 	cmp	al, 'A'  
  1037 00004E05 7304                <1> 	jnb	short loc_pvi_set_vol_name
  1038 00004E07 8A6604              <1> 	mov	ah, [esi+LD_FSType]
  1039 00004E0A C3                  <1> 	retn
  1040                              <1> 
  1041                              <1> loc_pvi_set_vol_name:
  1042 00004E0B A2[2D9B0000]        <1> 	mov	[Vol_Drv_Name], al
  1043 00004E10 56                  <1> 	push	esi
  1044 00004E11 E858010000          <1> 	call	move_volume_name_and_serial_no ;;;
  1045 00004E16 7302                <1> 	jnc	short loc_pvi_mvn_ok
  1046 00004E18 5E                  <1> 	pop	esi
  1047 00004E19 C3                  <1> 	retn
  1048                              <1> 
  1049                              <1> loc_pvi_mvn_ok:
  1050 00004E1A 8B3424              <1> 	mov	esi, [esp]
  1051 00004E1D 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  1052 00004E21 7509                <1> 	jne	short loc_pvi_fat_vol_size
  1053 00004E23 8B4670              <1> 	mov	eax, [esi+LD_FS_VolumeSize]
  1054 00004E26 0FB75E11            <1> 	movzx	ebx, word [esi+LD_FS_BytesPerSec]
  1055 00004E2A EB07                <1> 	jmp	short loc_vol_size_mul32
  1056                              <1> loc_pvi_fat_vol_size:
  1057 00004E2C 8B4670              <1> 	mov	eax, [esi+LD_TotalSectors]
  1058 00004E2F 0FB75E11            <1> 	movzx	ebx, word [esi+LD_BPB+BPB_BytsPerSec]
  1059                              <1> loc_vol_size_mul32:
  1060 00004E33 F7E3                <1> 	mul	ebx
  1061 00004E35 09D2                <1> 	or	edx, edx
  1062 00004E37 7507                <1> 	jnz	short loc_vol_size_in_kbytes
  1063                              <1> loc_vol_size_in_bytes:
  1064 00004E39 B9[0B9B0000]        <1> 	mov	ecx, VolSize_Bytes
  1065 00004E3E EB0D                <1> 	jmp	short loc_write_vol_size_str
  1066                              <1> loc_vol_size_in_kbytes:
  1067 00004E40 66BB0004            <1> 	mov	bx, 1024
  1068 00004E44 F7F3                <1> 	div	ebx
  1069 00004E46 B9[FE9A0000]        <1> 	mov 	ecx, VolSize_KiloBytes
  1070 00004E4B 31D2                <1> 	xor	edx, edx ; 0
  1071                              <1> loc_write_vol_size_str:
  1072 00004E4D 890D[E7B00000]      <1> 	mov	[VolSize_Unit1], ecx
  1073                              <1> 	; 
  1074 00004E53 BF[FDB00000]        <1> 	mov	edi, Vol_Tot_Sec_Str_End
  1075                              <1>         ;mov	byte [edi], 0
  1076 00004E58 B90A000000          <1> 	mov	ecx, 10
  1077                              <1> loc_write_vol_size_chr:
  1078 00004E5D F7F1                <1> 	div	ecx
  1079 00004E5F 80C230              <1> 	add	dl, '0'
  1080 00004E62 4F                  <1> 	dec	edi	
  1081 00004E63 8817                <1> 	mov	[edi], dl
  1082 00004E65 85C0                <1> 	test	eax, eax
  1083 00004E67 7404                <1> 	jz	short loc_write_vol_size_str_ok
  1084 00004E69 28D2                <1> 	sub	dl, dl ; 0
  1085 00004E6B EBF0                <1> 	jmp	short loc_write_vol_size_chr
  1086                              <1> 
  1087                              <1> loc_write_vol_size_str_ok:
  1088 00004E6D 893D[EFB00000]      <1> 	mov	[Vol_Tot_Sec_Str_Start], edi
  1089                              <1> 	;
  1090 00004E73 BF[169B0000]        <1> 	mov	edi, Vol_FS_Name
  1091 00004E78 8A4E03              <1> 	mov	cl, [esi+LD_FATType]
  1092 00004E7B 20C9                <1> 	and	cl, cl ; 0 ?
  1093 00004E7D 7515                <1> 	jnz	short loc_write_vol_FAT_str_1
  1094 00004E7F 66C7075452          <1> 	mov	word [edi], 'TR'
  1095 00004E84 C7470420465331      <1> 	mov	dword [edi+4], ' FS1'
  1096                              <1> 	;movzx	ebx, word [esi+LD_FS_BytesPerSec]
  1097 00004E8B 668B5E11            <1> 	mov	bx, [esi+LD_FS_BytesPerSec]
  1098 00004E8F 8B4674              <1> 	mov	eax, [esi+LD_FS_FreeSectors]
  1099 00004E92 EB36                <1> 	jmp	short loc_vol_freespace_mul32
  1100                              <1> 
  1101                              <1> loc_write_vol_FAT_str_1:
  1102 00004E94 66B83332            <1> 	mov	ax, '32' ; FAT32
  1103 00004E98 80F902              <1> 	cmp	cl, 2 ; [esi+LD_FATType]
  1104 00004E9B 7708                <1> 	ja	short loc_write_vol_FAT_str_2
  1105 00004E9D 66B83132            <1> 	mov	ax, '12' ; FAT12
  1106 00004EA1 7202                <1> 	jb	short loc_write_vol_FAT_str_2
  1107 00004EA3 B436                <1> 	mov	ah, '6'  ; FAT16
  1108                              <1> loc_write_vol_FAT_str_2:
  1109 00004EA5 C70746415420        <1> 	mov	dword [edi], 'FAT '
  1110 00004EAB 66894704            <1> 	mov	word [edi+4], ax
  1111                              <1> 	;
  1112                              <1> 	;movzx	ebx, word [esi+LD_BPB+BPB_BytsPerSec]
  1113 00004EAF 668B5E11            <1> 	mov	bx, [esi+LD_BPB+BPB_BytsPerSec]
  1114 00004EB3 8B4674              <1> 	mov	eax, [esi+LD_FreeSectors]
  1115                              <1> 
  1116                              <1> loc_vol_freespace_recalc0:
  1117                              <1> 	; 01/03/2016
  1118 00004EB6 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh
  1119 00004EB9 720F                <1> 	jb	short loc_vol_freespace_mul32
  1120                              <1> 	;inc	eax ; 0
  1121 00004EBB 20C9                <1> 	and	cl, cl ; byte [esi+LD_FATType]
  1122 00004EBD 740B                <1> 	jz	short loc_vol_freespace_mul32 	
  1123 00004EBF 53                  <1> 	push	ebx
  1124 00004EC0 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free sectors
  1125 00004EC4 E88E2E0000          <1> 	call	calculate_fat_freespace
  1126 00004EC9 5B                  <1> 	pop	ebx
  1127                              <1> 
  1128                              <1> loc_vol_freespace_mul32:
  1129 00004ECA F7E3                <1> 	mul	ebx
  1130 00004ECC 09D2                <1> 	or	edx, edx
  1131 00004ECE 7507                <1> 	jnz	short loc_vol_fspace_in_kbytes
  1132                              <1> loc_vol_fspace_in_bytes:
  1133 00004ED0 B9[0B9B0000]        <1> 	mov	ecx, VolSize_Bytes
  1134 00004ED5 EB0D                <1> 	jmp	short loc_write_vol_fspace_str
  1135                              <1> loc_vol_fspace_in_kbytes:
  1136 00004ED7 66BB0004            <1> 	mov	bx, 1024
  1137 00004EDB F7F3                <1> 	div	ebx
  1138 00004EDD B9[FE9A0000]        <1> 	mov 	ecx, VolSize_KiloBytes
  1139 00004EE2 31D2                <1> 	xor	edx, edx ; 0
  1140                              <1> loc_write_vol_fspace_str:
  1141 00004EE4 890D[EBB00000]      <1> 	mov	[VolSize_Unit2], ecx
  1142                              <1> 	;	
  1143 00004EEA BF[0DB10000]        <1> 	mov	edi, Vol_Free_Sectors_Str_End
  1144                              <1>         ;mov	byte [edi], 0
  1145 00004EEF B90A000000          <1> 	mov	ecx, 10
  1146                              <1> loc_write_vol_fspace_chr:
  1147 00004EF4 F7F1                <1> 	div	ecx
  1148 00004EF6 80C230              <1> 	add	dl, '0'
  1149 00004EF9 4F                  <1> 	dec	edi	
  1150 00004EFA 8817                <1> 	mov	[edi], dl
  1151 00004EFC 85C0                <1> 	test	eax, eax
  1152 00004EFE 7404                <1> 	jz	short loc_write_vol_fspace_str_ok
  1153 00004F00 28D2                <1> 	sub	dl, dl ; 0
  1154 00004F02 EBF0                <1> 	jmp	short loc_write_vol_fspace_chr
  1155                              <1> 
  1156                              <1> loc_write_vol_fspace_str_ok:
  1157 00004F04 893D[FFB00000]      <1> 	mov	[Vol_Free_Sectors_Str_Start], edi
  1158                              <1> 	;
  1159 00004F0A BE[149B0000]        <1> 	mov	esi, Volume_in_drive
  1160 00004F0F E826EDFFFF          <1> 	call	print_msg
  1161 00004F14 BE[549B0000]        <1> 	mov	esi, Vol_Name
  1162 00004F19 E81CEDFFFF          <1> 	call	print_msg
  1163 00004F1E BE[C6A40000]        <1> 	mov	esi, nextline
  1164 00004F23 E812EDFFFF          <1> 	call	print_msg
  1165                              <1> 	;
  1166 00004F28 BE[B59B0000]        <1> 	mov	esi, Vol_Total_Sector_Header
  1167 00004F2D E808EDFFFF          <1> 	call	print_msg
  1168 00004F32 8B35[EFB00000]      <1> 	mov	esi, [Vol_Tot_Sec_Str_Start]
  1169 00004F38 E8FDECFFFF          <1> 	call	print_msg
  1170 00004F3D 8B35[E7B00000]      <1> 	mov	esi, [VolSize_Unit1]
  1171 00004F43 E8F2ECFFFF          <1> 	call	print_msg
  1172                              <1> 	;
  1173 00004F48 BE[C69B0000]        <1> 	mov	esi, Vol_Free_Sectors_Header
  1174 00004F4D E8E8ECFFFF          <1> 	call	print_msg
  1175 00004F52 8B35[FFB00000]      <1> 	mov	esi, [Vol_Free_Sectors_Str_Start]
  1176 00004F58 E8DDECFFFF          <1> 	call	print_msg
  1177 00004F5D 8B35[EBB00000]      <1> 	mov	esi, [VolSize_Unit2]
  1178 00004F63 E8D2ECFFFF          <1> 	call	print_msg
  1179                              <1> 	;
  1180 00004F68 5E                  <1> 	pop	esi
  1181                              <1> 	
  1182                              <1> 	;mov	ah, [esi+LD_FSType]
  1183                              <1> 	;mov	al, [esi+LD_FATType]
  1184 00004F69 668B4603            <1> 	mov	ax, [esi+LD_FATType]
  1185                              <1> 
  1186 00004F6D C3                  <1> 	retn
  1187                              <1> 
  1188                              <1> move_volume_name_and_serial_no:
  1189                              <1> 	; 08/02/2016  (TRDOS 386 = TRDOS v2.0)
  1190                              <1> 	; this routine will be called by
  1191                              <1> 	; "print_volume_info" and "print_directory"
  1192                              <1> 	; INPUT ->
  1193                              <1> 	;	ESI = Logical DOS drv descripton table address
  1194                              <1> 	; OUTPUT ->
  1195                              <1> 	;	*Volume name will be moved to text area
  1196                              <1> 	;	*Volume serial number will be converted to
  1197                              <1> 	;	 text and will be moved to text area
  1198                              <1> 	;   cf = 1 -> invalid/unknown dos drive
  1199                              <1> 	;   cf = 0 -> ecx = 0
  1200                              <1> 	;
  1201                              <1> 	; (eax, edx, ecx, esi, edi will be changed)
  1202                              <1> 
  1203 00004F6E BF[549B0000]        <1> 	mov 	edi, Vol_Name
  1204                              <1> 
  1205                              <1> 	;mov	ah, [esi+LD_FSType]
  1206                              <1> 	;mov	al, [esi+LD_FATType]
  1207 00004F73 668B4603            <1> 	mov	ax, [esi+LD_FATType]
  1208 00004F77 80FCA1              <1> 	cmp	ah, 0A1h
  1209 00004F7A 7418                <1> 	je	short mvn_2
  1210 00004F7C 08E4                <1> 	or	ah, ah
  1211 00004F7E 7404                <1> 	jz	short mvn_0
  1212 00004F80 08C0                <1> 	or	al, al
  1213 00004F82 7504                <1> 	jnz	short mvn_1
  1214                              <1> mvn_0:
  1215 00004F84 8A06                <1> 	mov	al, [esi]
  1216 00004F86 F9                  <1> 	stc
  1217 00004F87 C3                  <1> 	retn
  1218                              <1> mvn_1:
  1219 00004F88 3C02                <1> 	cmp	al, 2
  1220 00004F8A 7717                <1> 	ja	short mvn_3 
  1221                              <1> 	;or	al, al
  1222                              <1> 	;jz	short mvn_2
  1223 00004F8C 8B462D              <1> 	mov	eax, [esi+LD_BPB+VolumeID]
  1224 00004F8F 83C631              <1> 	add	esi, LD_BPB+VolumeLabel
  1225 00004F92 EB15                <1> 	jmp	short mvn_4
  1226                              <1> mvn_2:
  1227 00004F94 8B4628              <1> 	mov	eax, [esi+LD_FS_VolumeSerial]
  1228 00004F97 83C62C              <1> 	add	esi, LD_FS_VolumeName
  1229 00004F9A B910000000          <1> 	mov	ecx, 16
  1230 00004F9F F3A5                <1> 	rep	movsd
  1231 00004FA1 EB10                <1> 	jmp	short mvn_5
  1232                              <1> mvn_3:
  1233 00004FA3 8B4649              <1> 	mov	eax, [esi+LD_BPB+FAT32_VolID]
  1234 00004FA6 83C64D              <1> 	add	esi, LD_BPB+FAT32_VolLab
  1235                              <1> mvn_4:
  1236 00004FA9 B90B000000          <1> 	mov	ecx, 11
  1237 00004FAE F3A4                <1> 	rep	movsb
  1238 00004FB0 C60700              <1> 	mov	byte [edi], 0
  1239                              <1> mvn_5:
  1240                              <1> 	;mov	[Current_VolSerial], eax  
  1241 00004FB3 E82ECAFFFF          <1> 	call	dwordtohex
  1242 00004FB8 8915[A99B0000]      <1> 	mov	[Vol_Serial1], edx
  1243 00004FBE A3[AE9B0000]        <1> 	mov	[Vol_Serial2], eax
  1244                              <1> 	; ecx = 0
  1245 00004FC3 C3                  <1> 	retn
  1246                              <1> 
  1247                              <1> get_volume_serial_number:
  1248                              <1> 	; 19/01/2016 (TRDOS 386 = TRDOS v2.0)
  1249                              <1> 	; 08/08/2010
  1250                              <1> 	;
  1251                              <1> 	; INPUT -> DL = Logical DOS Drive number
  1252                              <1> 	; OUTPUT -> EAX = Volume serial number
  1253                              <1> 	;          BL= FAT Type	    
  1254                              <1> 	;          BH = Logical DOS drv Number (DL input)
  1255                              <1> 	; cf = 1 -> Drive not ready
  1256                              <1> 
  1257 00004FC4 31DB                <1> 	xor	ebx, ebx
  1258 00004FC6 88D7                <1> 	mov	bh, dl
  1259 00004FC8 3815[7C990000]      <1> 	cmp	[Last_DOS_DiskNo], dl
  1260 00004FCE 7304                <1> 	jnb	short loc_gvsn_start
  1261                              <1> loc_gvsn_stc_retn:
  1262 00004FD0 31C0                <1> 	xor	eax, eax
  1263 00004FD2 F9                  <1> 	stc 
  1264 00004FD3 C3                  <1>         retn 
  1265                              <1> loc_gvsn_start:
  1266 00004FD4 56                  <1> 	push	esi
  1267 00004FD5 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1268 00004FDA 01DE                <1> 	add	esi, ebx
  1269 00004FDC 8A5E03              <1> 	mov	bl, [esi+LD_FATType]
  1270 00004FDF 20DB                <1> 	and	bl, bl
  1271 00004FE1 740F                <1> 	jz	short loc_gvsn_fs
  1272 00004FE3 80FB02              <1> 	cmp	bl, 2
  1273 00004FE6 7705                <1> 	ja	short loc_gvsn_fat32
  1274                              <1> loc_gvsn_fat:
  1275 00004FE8 83C62D              <1> 	add	esi, LD_BPB + VolumeID
  1276 00004FEB EB0E                <1> 	jmp	short loc_gvsn_return
  1277                              <1> loc_gvsn_fat32: 
  1278 00004FED 83C649              <1> 	add	esi, LD_BPB + FAT32_VolID
  1279 00004FF0 EB09                <1> 	jmp	short loc_gvsn_return 
  1280                              <1> loc_gvsn_fs:
  1281 00004FF2 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  1282 00004FF6 75D8                <1> 	jne	short loc_gvsn_stc_retn 
  1283 00004FF8 83C628              <1> 	add	esi, LD_FS_VolumeSerial
  1284                              <1> loc_gvsn_return:
  1285 00004FFB 8B06                <1> 	mov	eax, [esi]
  1286 00004FFD 5E                  <1> 	pop	esi
  1287 00004FFE C3                  <1> 	retn
  1288                              <1> 
  1289                              <1> ; CMD_INTR.ASM [ TRDOS Command Interpreter Procedure ]
  1290                              <1> ; 09/11/2011
  1291                              <1> ; 29/01/2005
  1292                              <1> 
  1293                              <1> command_interpreter:
  1294                              <1> 	; 04/03/2016
  1295                              <1> 	; 04/02/2016
  1296                              <1> 	; 03/02/2016
  1297                              <1> 	; 30/01/2016
  1298                              <1> 	; 29/01/2016 (TRDOS 386 = TRDOS 2.0)
  1299                              <1> 	; 15/09/2011         
  1300                              <1> 	; 29/01/2005
  1301                              <1>         
  1302                              <1> 	; Input: ecx = command word length (CL)
  1303                              <1> 	;	 CommandBuffer = Command string offset
  1304                              <1>  
  1305 00004FFF C605[A0B10000]00    <1> 	mov	byte [Program_Exit],0
  1306 00005006 80F904              <1> 	cmp	cl, 4
  1307 00005009 0F87A8020000        <1>         ja      c_6
  1308 0000500F 0F8216010000        <1>         jb      c_2
  1309                              <1> c_4:
  1310                              <1> 
  1311                              <1> cmp_cmd_exit:
  1312 00005015 BF[EA990000]        <1> 	mov	edi, Cmd_Exit
  1313 0000501A E8B9030000          <1> 	call	cmp_cmd	
  1314 0000501F 7208                <1> 	jc	short cmp_cmd_date
  1315                              <1> 
  1316 00005021 C605[A0B10000]01    <1>         mov     byte [Program_Exit], 1
  1317 00005028 C3                  <1>         retn
  1318                              <1> 
  1319                              <1> cmp_cmd_date:
  1320 00005029 B104                <1> 	mov	cl, 4
  1321 0000502B BF[069A0000]        <1> 	mov	edi, Cmd_Date
  1322 00005030 E8A3030000          <1> 	call	cmp_cmd	
  1323 00005035 720B                <1>         jc	short cmp_cmd_time
  1324                              <1> 	
  1325 00005037 E8D0F7FFFF          <1> 	call	show_date
  1326 0000503C E80FF8FFFF          <1> 	call	set_date
  1327 00005041 C3                  <1> 	retn
  1328                              <1> 
  1329                              <1> cmp_cmd_time:
  1330 00005042 B104                <1> 	mov	cl, 4
  1331 00005044 BF[0B9A0000]        <1> 	mov	edi, Cmd_Time
  1332 00005049 E88A030000          <1>    	call	cmp_cmd	
  1333 0000504E 720B                <1> 	jc	short cmp_cmd_show
  1334                              <1> 
  1335 00005050 E8C6FAFFFF          <1> 	call	show_time
  1336 00005055 E8F8FAFFFF          <1> 	call	set_time
  1337 0000505A C3                  <1> 	retn
  1338                              <1> 
  1339                              <1> cmp_cmd_show:
  1340 0000505B B104                <1> 	mov	cl, 4
  1341 0000505D BF[1C9A0000]        <1> 	mov	edi, Cmd_Show
  1342 00005062 E871030000          <1>    	call	cmp_cmd	
  1343 00005067 0F83E0090000        <1>         jnc     show_file
  1344                              <1> 
  1345                              <1> cmp_cmd_echo:
  1346 0000506D B104                <1> 	mov	cl, 4
  1347 0000506F BF[619A0000]        <1> 	mov	edi, Cmd_Echo
  1348 00005074 E85F030000          <1>    	call	cmp_cmd	
  1349 00005079 720A                <1> 	jc	short cmp_cmd_copy
  1350                              <1> 
  1351 0000507B 803E20              <1> 	cmp	byte [esi], 20h
  1352 0000507E 0F83B6EBFFFF        <1> 	jnb	print_msg
  1353 00005084 C3                  <1> 	retn
  1354                              <1> 
  1355                              <1> cmp_cmd_copy:
  1356 00005085 B104                <1> 	mov	cl, 4
  1357 00005087 BF[3F9A0000]        <1> 	mov	edi, Cmd_Copy
  1358 0000508C E847030000          <1>    	call	cmp_cmd	
  1359 00005091 0F839E160000        <1> 	jnc	copy_file
  1360                              <1> 
  1361                              <1> cmp_cmd_move:
  1362 00005097 B104                <1> 	mov	cl, 4
  1363 00005099 BF[449A0000]        <1> 	mov	edi, Cmd_Move
  1364 0000509E E835030000          <1>    	call	cmp_cmd	
  1365 000050A3 0F838D160000        <1> 	jnc	move_file
  1366                              <1> 
  1367                              <1> cmp_cmd_path:
  1368 000050A9 B104                <1> 	mov	cl, 4
  1369 000050AB BF[499A0000]        <1> 	mov	edi, Cmd_Path
  1370 000050B0 E823030000          <1>    	call	cmp_cmd	
  1371 000050B5 0F837C160000        <1> 	jnc	set_get_path
  1372                              <1> 
  1373                              <1> cmp_cmd_beep:
  1374 000050BB B104                <1> 	mov	cl, 4
  1375 000050BD BF[7F9A0000]        <1> 	mov	edi, Cmd_Beep
  1376 000050C2 E811030000          <1>    	call	cmp_cmd	
  1377 000050C7 0F83C7C7FFFF        <1> 	jnc	beeper
  1378                              <1> 
  1379                              <1> cmp_cmd_find:
  1380 000050CD B104                <1> 	mov	cl, 4
  1381 000050CF BF[539A0000]        <1> 	mov	edi, Cmd_Find
  1382 000050D4 E8FF020000          <1>    	call	cmp_cmd	
  1383 000050D9 0F82E6020000        <1>         jc      loc_cmd_failed
  1384                              <1> 
  1385                              <1> 	;call	find_and_list_files
  1386 000050DF E954160000          <1> 	jmp	find_and_list_files
  1387                              <1> 	;retn
  1388                              <1> 
  1389                              <1> c_1:
  1390 000050E4 AD                  <1> 	lodsd
  1391                              <1> cmp_cmd_help:
  1392 000050E5 3C3F                <1> 	cmp	al, '?'
  1393 000050E7 751D                <1>         jne     short cmp_cmd_remark
  1394                              <1> 
  1395 000050E9 BE[DC990000]        <1> 	mov	esi, Command_List
  1396                              <1> cmd_help_next_w:
  1397 000050EE E847EBFFFF          <1> 	call	print_msg
  1398                              <1> 
  1399 000050F3 803E20              <1> 	cmp	byte [esi], 20h ; 0
  1400 000050F6 7232                <1> 	jb	short cmd_help_retn
  1401                              <1> 	
  1402 000050F8 56                  <1> 	push	esi
  1403 000050F9 BE[C6A40000]        <1> 	mov	esi, nextline
  1404 000050FE E837EBFFFF          <1> 	call	print_msg
  1405 00005103 5E                  <1> 	pop	esi
  1406 00005104 EBE8                <1> 	jmp	short cmd_help_next_w	
  1407                              <1> 
  1408                              <1> cmp_cmd_remark:
  1409 00005106 3C2A                <1> 	cmp	al, '*'
  1410 00005108 0F85B7020000        <1>         jne     loc_cmd_failed
  1411 0000510E 46                  <1> 	inc	esi
  1412 0000510F BF[10A90000]        <1> 	mov	edi, Remark
  1413 00005114 8A06                <1> 	mov	al, [esi]
  1414 00005116 3C20                <1> 	cmp	al, 20h
  1415 00005118 7707                <1> 	ja	short cmd_remark_write
  1416 0000511A 89FE                <1> 	mov	esi, edi ; Remark
  1417 0000511C E919EBFFFF          <1> 	jmp	print_msg
  1418                              <1> 
  1419                              <1> cmd_remark_write:
  1420 00005121 AA                  <1> 	stosb
  1421 00005122 AC                  <1> 	lodsb
  1422 00005123 3C20                <1> 	cmp	al, 20h
  1423 00005125 73FA                <1> 	jnb	short cmd_remark_write
  1424 00005127 C60700              <1> 	mov	byte [edi], 0
  1425                              <1> 
  1426                              <1> cmd_help_retn:
  1427                              <1> cmd_remark_retn:
  1428                              <1> cd_retn:
  1429 0000512A C3                  <1> 	retn
  1430                              <1> 
  1431                              <1> c_2:
  1432 0000512B 80F902              <1> 	cmp	cl, 2
  1433 0000512E 0F87B1000000        <1>         ja      c_3
  1434 00005134 BE[5EA90000]        <1> 	mov	esi, CommandBuffer
  1435 00005139 72A9                <1> 	jb	short c_1
  1436                              <1> 
  1437                              <1> cmp_cmd_cd:
  1438 0000513B 66AD                <1> 	lodsw
  1439 0000513D 663D4344            <1> 	cmp	ax, 'CD'
  1440 00005141 7553                <1> 	jne	short cmp_cmd_drive
  1441 00005143 46                  <1>         inc	esi
  1442                              <1> cd_0:
  1443 00005144 668B06              <1> 	mov	ax, [esi]	
  1444 00005147 3C20                <1> 	cmp	al, 20h
  1445 00005149 76DF                <1> 	jna	short cd_retn
  1446                              <1> 	; 10/02/2016
  1447 0000514B 80FC3A              <1> 	cmp	ah, ':'
  1448 0000514E 7504                <1> 	jne	short cd_1
  1449 00005150 46                  <1> 	inc	esi
  1450 00005151 46                  <1> 	inc	esi
  1451 00005152 EB4B                <1> 	jmp	short cd_2
  1452                              <1> 
  1453                              <1> cd_1:	; change current directory
  1454                              <1> 	; 29/11/2009
  1455                              <1> 	; AH = CDh	; to separate 'CD' command from others
  1456                              <1> 			; for restoring current directory
  1457                              <1> 			; 0CDh sign is for saving cdir into 
  1458                              <1> 			; DOS drv description table cdir area
  1459                              <1> 	
  1460 00005154 B4CD                <1> 	mov	ah, 0CDh ; mov byte [CD_COMMAND], 0CDh 
  1461                              <1> 
  1462 00005156 E8C5160000          <1> 	call	change_current_directory
  1463 0000515B 0F83DF150000        <1>         jnc     change_prompt_dir_string
  1464                              <1> 
  1465                              <1> cd_error_messages:
  1466 00005161 3C03                <1> 	cmp	al, 3
  1467 00005163 740C                <1> 	je	short cd_path_not_found
  1468 00005165 3C15                <1> 	cmp	al, 15h 
  1469 00005167 745B                <1> 	je	short cd_drive_not_ready
  1470 00005169 3C18                <1> 	cmp	al, 18h ; Bad request structure length 
  1471 0000516B 746C                <1> 	je	short cd_command_failed
  1472 0000516D 3C1A                <1> 	cmp	al, 1Ah ; Unknown media type, non-DOS disk
  1473 0000516F 7468                <1>         je      short cd_command_failed
  1474                              <1> 
  1475                              <1> cd_path_not_found:
  1476 00005171 6650                <1> 	push	ax	
  1477 00005173 BE[889C0000]        <1> 	mov	esi, Msg_Dir_Not_Found
  1478 00005178 E8BDEAFFFF          <1> 	call	print_msg
  1479 0000517D 6658                <1> 	pop	ax
  1480 0000517F 3A25[ACA80000]      <1> 	cmp	ah, [Current_Dir_Level]
  1481 00005185 0F83B5150000        <1>         jnb     change_prompt_dir_string
  1482 0000518B 8825[ACA80000]      <1> 	mov	[Current_Dir_Level], ah
  1483 00005191 E9AA150000          <1>         jmp     change_prompt_dir_string   
  1484                              <1> 
  1485                              <1> cmp_cmd_drive: ; change current drive
  1486                              <1> 	; C:, D:, E: etc.
  1487 00005196 80FC3A              <1> 	cmp	ah, ':'
  1488 00005199 0F8526020000        <1>         jne     loc_cmd_failed
  1489                              <1> 
  1490                              <1> cd_2:	; 'CD C:', 'CD D:' ...
  1491 0000519F 803E20              <1> 	cmp	byte [esi], 20h
  1492 000051A2 0F871D020000        <1>         ja      loc_cmd_failed
  1493                              <1> 
  1494 000051A8 24DF                <1> 	and	al, 0DFh
  1495 000051AA 2C41                <1> 	sub	al, 'A'
  1496 000051AC 0F8213020000        <1>         jc      loc_cmd_failed
  1497                              <1> 
  1498 000051B2 3A05[7C990000]      <1>         cmp     al, [Last_DOS_DiskNo]
  1499 000051B8 770A                <1>         ja	short cd_drive_not_ready
  1500                              <1> 	
  1501 000051BA 88C2                <1> 	mov	dl, al
  1502 000051BC E87DF3FFFF          <1> 	call 	change_current_drive
  1503 000051C1 7201                <1> 	jc	short cd_drive_not_ready	
  1504 000051C3 C3                  <1> 	retn
  1505                              <1> 
  1506                              <1> cd_drive_not_ready:
  1507 000051C4 BE[459C0000]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1508 000051C9 E86CEAFFFF          <1> 	call	print_msg
  1509                              <1> 
  1510                              <1> cd_fail_drive_restart:
  1511 000051CE 8A15[AEA80000]      <1> 	mov	dl, [Current_Drv]
  1512                              <1> 	;call 	change_current_drive
  1513 000051D4 E965F3FFFF          <1>         jmp     change_current_drive
  1514                              <1> 	;retn
  1515                              <1> 
  1516                              <1> cd_command_failed:
  1517 000051D9 BE[269C0000]        <1> 	mov	esi, Msg_Bad_Command
  1518 000051DE E857EAFFFF          <1> 	call	print_msg
  1519 000051E3 EBE9                <1> 	jmp	short cd_fail_drive_restart
  1520                              <1> 
  1521                              <1> c_3:
  1522                              <1> cmp_cmd_dir:
  1523 000051E5 BF[DC990000]        <1> 	mov	edi, Cmd_Dir
  1524 000051EA E8E9010000          <1> 	call	cmp_cmd	
  1525 000051EF 0F8388020000        <1> 	jnc	print_directory_list
  1526                              <1> 
  1527                              <1> cmp_cmd_cls:
  1528 000051F5 B103                <1> 	mov	cl, 3
  1529 000051F7 BF[189A0000]        <1> 	mov	edi, Cmd_Cls
  1530 000051FC E8D7010000          <1> 	call	cmp_cmd	
  1531 00005201 0F834AEAFFFF        <1>         jnc	clear_screen
  1532                              <1> 
  1533                              <1> cmp_cmd_ver:
  1534 00005207 B103                <1> 	mov	cl, 3
  1535 00005209 BF[E6990000]        <1> 	mov	edi, Cmd_Ver
  1536 0000520E E8C5010000          <1> 	call	cmp_cmd	
  1537 00005213 720A                <1> 	jc	short cmp_cmd_mem
  1538                              <1> 
  1539 00005215 BE[84990000]        <1> 	mov	esi, mainprog_Version
  1540                              <1> 	;call	print_msg
  1541 0000521A E91BEAFFFF          <1> 	jmp	print_msg
  1542                              <1> 	;retn
  1543                              <1> 
  1544                              <1> cmp_cmd_mem:
  1545 0000521F B103                <1> 	mov	cl, 3
  1546 00005221 BF[4E9A0000]        <1> 	mov	edi, Cmd_Mem
  1547 00005226 E8AD010000          <1> 	call	cmp_cmd	
  1548 0000522B 0F83FFC6FFFF        <1> 	jnc	memory_info
  1549                              <1> 
  1550                              <1> cmp_cmd_del:
  1551 00005231 B103                <1> 	mov	cl, 3
  1552 00005233 BF[219A0000]        <1> 	mov	edi, Cmd_Del
  1553 00005238 E89B010000          <1> 	call	cmp_cmd	
  1554 0000523D 0F83320F0000        <1>         jnc     delete_file
  1555                              <1> 
  1556                              <1> cmp_cmd_set:
  1557 00005243 B103                <1> 	mov	cl, 3
  1558 00005245 BF[149A0000]        <1> 	mov	edi, Cmd_Set
  1559 0000524A E889010000          <1> 	call	cmp_cmd	
  1560 0000524F 0F83E4140000        <1>         jnc     set_get_env
  1561                              <1> 
  1562                              <1> cmp_cmd_run:
  1563 00005255 B103                <1> 	mov	cl, 3
  1564 00005257 BF[109A0000]        <1> 	mov	edi, Cmd_Run
  1565 0000525C E877010000          <1> 	call	cmp_cmd	
  1566 00005261 0F825E010000        <1>         jc      loc_cmd_failed
  1567                              <1> 
  1568 00005267 E8CE140000          <1> 	call	set_exec_arguments
  1569 0000526C 0F8253010000        <1>         jc      loc_cmd_failed
  1570                              <1> 
  1571 00005272 E8C4140000          <1> 	call	load_and_execute_file
  1572 00005277 0F8273010000        <1>         jc      loc_run_cmd_failed
  1573 0000527D C3                  <1> 	retn
  1574                              <1> 
  1575                              <1> c_5:
  1576                              <1> cmp_cmd_mkdir:
  1577 0000527E BF[399A0000]        <1> 	mov	edi, Cmd_Mkdir
  1578 00005283 E850010000          <1> 	call	cmp_cmd	
  1579 00005288 0F837F0A0000        <1>         jnc     make_directory
  1580                              <1> 
  1581                              <1> cmp_cmd_rmdir:
  1582 0000528E B105                <1> 	mov	cl, 5
  1583 00005290 BF[339A0000]        <1> 	mov	edi, Cmd_Rmdir
  1584 00005295 E83E010000          <1> 	call	cmp_cmd	
  1585 0000529A 0F838C0B0000        <1>         jnc     delete_directory
  1586                              <1> 
  1587                              <1> cmp_cmd_chdir:
  1588 000052A0 B105                <1> 	mov	cl, 5
  1589 000052A2 BF[799A0000]        <1> 	mov	edi, Cmd_Chdir
  1590 000052A7 E82C010000          <1> 	call	cmp_cmd	
  1591 000052AC 0F8213010000        <1> 	jc	loc_cmd_failed
  1592                              <1> 
  1593 000052B2 E98DFEFFFF          <1> 	jmp	cd_0
  1594                              <1> 
  1595                              <1> c_6:
  1596 000052B7 80F906              <1> 	cmp	cl, 6
  1597 000052BA 0F87DF000000        <1>         ja      c_8
  1598 000052C0 72BC                <1> 	jb	short c_5
  1599                              <1> cmp_cmd_prompt:
  1600 000052C2 BF[EF990000]        <1> 	mov	edi, Cmd_Prompt
  1601 000052C7 E80C010000          <1> 	call	cmp_cmd	
  1602 000052CC 722E                <1>         jc	short cmp_cmd_volume
  1603                              <1> get_prompt_name_fchar:
  1604 000052CE AC                  <1> 	lodsb
  1605 000052CF 3C20                <1> 	cmp	al, 20h
  1606 000052D1 74FB                <1> 	je	short get_prompt_name_fchar
  1607 000052D3 7712                <1> 	ja	short loc_change_prompt_label
  1608 000052D5 BE[D0990000]        <1> 	mov	esi, TRDOSPromptLabel
  1609 000052DA C7065452444F        <1> 	mov	dword [esi], "TRDO"
  1610 000052E0 66C746045300        <1>        	mov	word [esi+4], "S" 
  1611                              <1> loc_cmd_prompt_return:
  1612 000052E6 C3                  <1> 	retn
  1613                              <1> loc_change_prompt_label:
  1614 000052E7 66B90B00            <1> 	mov	cx, 11
  1615 000052EB BF[D0990000]        <1> 	mov	edi, TRDOSPromptLabel
  1616                              <1> put_char_new_prompt_label:
  1617 000052F0 AA                  <1> 	stosb
  1618 000052F1 AC                  <1> 	lodsb
  1619 000052F2 3C20                <1> 	cmp	al, 20h
  1620 000052F4 7202                <1> 	jb	short pass_put_new_prompt_label
  1621 000052F6 E2F8                <1> 	loop	put_char_new_prompt_label
  1622                              <1> pass_put_new_prompt_label:
  1623 000052F8 C60700              <1> 	mov	byte [edi], 0
  1624 000052FB C3                  <1> 	retn
  1625                              <1> 
  1626                              <1> cmp_cmd_volume:
  1627 000052FC B106                <1> 	mov	cl, 6
  1628 000052FE BF[F6990000]        <1> 	mov	edi, Cmd_Volume
  1629 00005303 E8D0000000          <1> 	call	cmp_cmd	
  1630 00005308 7255                <1>         jc	short cmp_cmd_attrib
  1631                              <1> 
  1632                              <1> cmd_vol1:
  1633 0000530A AC                  <1> 	lodsb
  1634 0000530B 3C20                <1> 	cmp	al, 20h
  1635 0000530D 7707                <1> 	ja	short cmd_vol2
  1636 0000530F A0[AEA80000]        <1> 	mov	al, [Current_Drv]
  1637 00005314 EB3D                <1> 	jmp	short cmd_vol4
  1638                              <1> cmd_vol2:
  1639 00005316 3C41                <1> 	cmp	al, 'A'
  1640 00005318 0F82A7000000        <1>         jb      loc_cmd_failed
  1641 0000531E 3C7A                <1> 	cmp	al, 'z'
  1642 00005320 0F879F000000        <1>         ja      loc_cmd_failed
  1643 00005326 3C5A                <1> 	cmp	al, 'Z'
  1644 00005328 760A                <1> 	jna	short cmd_vol3
  1645 0000532A 3C61                <1> 	cmp	al, 'a'
  1646 0000532C 0F8293000000        <1>         jb      loc_cmd_failed
  1647 00005332 24DF                <1> 	and	al, 0DFh
  1648                              <1> cmd_vol3:
  1649 00005334 8A26                <1> 	mov	ah, [esi]
  1650 00005336 80FC3A              <1> 	cmp	ah, ':'
  1651 00005339 0F8586000000        <1>         jne     loc_cmd_failed
  1652 0000533F 2C41                <1> 	sub	al, 'A'
  1653 00005341 3A05[7C990000]      <1>         cmp     al, [Last_DOS_DiskNo]
  1654 00005347 760A                <1> 	jna	short cmd_vol4
  1655                              <1> 
  1656 00005349 BE[459C0000]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1657 0000534E E9E7E8FFFF          <1> 	jmp	print_msg
  1658                              <1> 	
  1659                              <1> cmd_vol4:
  1660 00005353 E89CFAFFFF          <1> 	call	print_volume_info
  1661 00005358 0F8266FEFFFF        <1>         jc      cd_drive_not_ready
  1662 0000535E C3                  <1> 	retn
  1663                              <1> 
  1664                              <1> cmp_cmd_attrib:
  1665 0000535F B106                <1> 	mov	cl, 6
  1666 00005361 BF[259A0000]        <1> 	mov	edi, Cmd_Attrib
  1667 00005366 E86D000000          <1> 	call	cmp_cmd	
  1668 0000536B 0F83240F0000        <1>         jnc     set_file_attributes
  1669                              <1> 
  1670                              <1> cmp_cmd_rename:
  1671 00005371 B106                <1> 	mov	cl, 6
  1672 00005373 BF[2C9A0000]        <1> 	mov	edi, Cmd_Rename
  1673 00005378 E85B000000          <1> 	call	cmp_cmd	
  1674 0000537D 0F835A110000        <1>         jnc     rename_file
  1675                              <1> 
  1676                              <1> cmp_cmd_device:
  1677 00005383 B106                <1> 	mov	cl, 6
  1678 00005385 BF[6A9A0000]        <1> 	mov	edi, Cmd_Device
  1679 0000538A E849000000          <1> 	call	cmp_cmd	
  1680 0000538F 7234                <1>         jc	short loc_cmd_failed
  1681                              <1> 
  1682 00005391 C3                  <1> 	retn
  1683                              <1> 
  1684                              <1> c_7:
  1685                              <1> cmp_cmd_devlist:
  1686 00005392 BF[719A0000]        <1> 	mov	edi, Cmd_DevList
  1687 00005397 E83C000000          <1> 	call	cmp_cmd	
  1688 0000539C 7227                <1>         jc	short loc_cmd_failed
  1689                              <1> 
  1690 0000539E C3                  <1> 	retn
  1691                              <1> 
  1692                              <1> c_8:
  1693 0000539F 80F908              <1>         cmp	cl, 8
  1694 000053A2 7721                <1> 	ja	short cmp_cmd_external
  1695 000053A4 72EC                <1> 	jb	short c_7
  1696                              <1> 
  1697                              <1> cmp_cmd_longname:
  1698 000053A6 BF[FD990000]        <1> 	mov	edi, Cmd_LongName
  1699 000053AB E828000000          <1> 	call	cmp_cmd	
  1700 000053B0 0F8341060000        <1>         jnc     get_and_print_longname
  1701                              <1> 
  1702                              <1> cmp_cmd_readfile:
  1703 000053B6 B108                <1> 	mov	cl, 8
  1704 000053B8 BF[589A0000]        <1> 	mov	edi, Cmd_ReadFile
  1705 000053BD E816000000          <1> 	call	cmp_cmd	
  1706 000053C2 7201                <1>         jc	short loc_cmd_failed
  1707                              <1> 
  1708                              <1> loc_cmd_return:
  1709 000053C4 C3                  <1> 	retn
  1710                              <1> 
  1711                              <1> cmp_cmd_external:
  1712                              <1> loc_cmd_failed:
  1713 000053C5 803D[5EA90000]20    <1> 	cmp	byte [CommandBuffer], 20h
  1714 000053CC 76F6                <1> 	jna	short loc_cmd_return
  1715 000053CE BE[269C0000]        <1> 	mov	esi, Msg_Bad_Command
  1716                              <1> ;	call	print_msg
  1717                              <1> ;loc_cmd_return:
  1718                              <1> ;	retn
  1719 000053D3 E962E8FFFF          <1> 	jmp	print_msg
  1720                              <1> 
  1721                              <1> cmp_cmd:
  1722                              <1> 	 ; 29/01/2016 (TRDOS 386 = TRDOS v2.0)
  1723 000053D8 BE[5EA90000]        <1>          mov  esi, CommandBuffer
  1724                              <1>          ; edi = internal command word (ASCIIZ)
  1725                              <1> 	 ; ecx = command length (<=8)
  1726                              <1> cmp_cmd_1:
  1727 000053DD AC                  <1> 	lodsb
  1728 000053DE AE                  <1> 	scasb
  1729 000053DF 750D                <1> 	jne	short cmp_cmd_3
  1730 000053E1 E2FA                <1> 	loop	cmp_cmd_1
  1731 000053E3 AC                  <1>  	lodsb
  1732 000053E4 3C20                <1> 	cmp	al, 20h
  1733 000053E6 7703                <1> 	ja	short cmp_cmd_2
  1734 000053E8 30C0                <1> 	xor	al, al
  1735                              <1> 	; ZF = 1 -> internal command word matches
  1736 000053EA C3                  <1> 	retn
  1737                              <1> cmp_cmd_2:
  1738                              <1> 	; ZF = 0 (CF = 0) -> external command word 	
  1739 000053EB 58                  <1> 	pop	eax ; no return to the caller from here 
  1740 000053EC EBD7                <1> 	jmp	cmp_cmd_external	
  1741                              <1> cmp_cmd_3:
  1742 000053EE F9                  <1> 	stc
  1743                              <1> 	; CF = 1 -> internal command word does not match
  1744 000053EF C3                  <1> 	retn
  1745                              <1> 
  1746                              <1> loc_run_cmd_failed:
  1747                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1748                              <1> 	; 07/12/2009 (CMD_INTR.ASM)	
  1749                              <1> 	; 29/11/2009
  1750                              <1> 
  1751 000053F0 E855000000          <1> 	call	restore_cdir_after_cmd_fail
  1752                              <1> 
  1753                              <1> loc_run_cmd_failed_cmp_al:
  1754                              <1> 	; End of Restore_CDIR code (29/11/2009)
  1755                              <1> 
  1756 000053F5 3C01                <1> 	cmp	al, 1
  1757 000053F7 74CC                <1> 	je	loc_cmd_failed
  1758                              <1> loc_run_dir_not_found:
  1759 000053F9 3C03                <1> 	cmp	al, 3
  1760 000053FB 750A                <1> 	jne	short loc_run_file_notfound_msg
  1761                              <1> 	; Path not found (MS-DOS Error Code = 3)
  1762 000053FD BE[889C0000]        <1> 	mov	esi, Msg_Dir_Not_Found
  1763 00005402 E933E8FFFF          <1> 	jmp	print_msg
  1764                              <1> 
  1765                              <1> loc_run_file_notfound_msg:
  1766 00005407 3C02                <1> 	cmp	al, 2 ; File not found
  1767 00005409 750A                <1> 	jne	short loc_run_file_drv_read_err
  1768                              <1> 
  1769                              <1> loc_print_file_notfound_msg: 
  1770 0000540B BE[9F9C0000]        <1>         mov     esi, Msg_File_Not_Found
  1771                              <1> 	;call	proc_printmsg
  1772                              <1> 	;retn
  1773 00005410 E925E8FFFF          <1> 	jmp	print_msg
  1774                              <1> 
  1775                              <1> loc_run_file_drv_read_err:
  1776                              <1> 	; 16/05/2010 -> Err: 1Eh (Read fault)
  1777 00005415 3C1E                <1> 	cmp	al, 1Eh ; Drive not ready or read error
  1778 00005417 7404                <1> 	je	short loc_run_file_print_drv_read_err
  1779                              <1> 	;
  1780 00005419 3C15                <1> 	cmp	al, 15h ; Drive not ready (or read error)
  1781 0000541B 750A                <1> 	jne	short loc_run_file_toobig
  1782                              <1> 
  1783                              <1> loc_run_file_print_drv_read_err:
  1784 0000541D BE[459C0000]        <1> 	mov	esi, Msg_Not_Ready_Read_Err
  1785 00005422 E913E8FFFF          <1> 	jmp	print_msg
  1786                              <1> 
  1787                              <1> loc_run_file_toobig:
  1788 00005427 3C08                <1> 	cmp	al, 8 ; Not enough free memory to load&run file
  1789 00005429 750A                <1> 	jne	short loc_run_misc_error
  1790 0000542B BE[E79C0000]        <1> 	mov	esi, Msg_Insufficient_Memory
  1791 00005430 E905E8FFFF          <1> 	jmp	print_msg
  1792                              <1> 
  1793                              <1> loc_run_misc_error:
  1794 00005435 E86CC5FFFF          <1> 	call	bytetohex ; 15/02/2016
  1795 0000543A 66A3[1B9D0000]      <1> 	mov	[Error_Code], ax
  1796                              <1> 	
  1797 00005440 BE[FE9C0000]        <1> 	mov	esi, Msg_Error_Code 
  1798 00005445 E9F0E7FFFF          <1> 	jmp	print_msg
  1799                              <1> 
  1800                              <1> restore_cdir_after_cmd_fail:
  1801                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1802 0000544A 50                  <1> 	push	eax
  1803 0000544B 8A3D[0EB10000]      <1> 	mov	bh, [RUN_CDRV] ; it is set at the beginning
  1804                              <1> 				; of the 'run' command.
  1805 00005451 3A3D[AEA80000]      <1> 	cmp	bh, [Current_Drv]
  1806 00005457 7409                <1> 	je	short loc_run_restore_cdir
  1807 00005459 88FA                <1> 	mov	dl, bh
  1808 0000545B E8DEF0FFFF          <1> 	call	change_current_drive 
  1809 00005460 EB19                <1> 	jmp	short loc_run_err_pass_restore_cdir
  1810                              <1> 
  1811                              <1> loc_run_restore_cdir:
  1812 00005462 803D[7D990000]00    <1> 	cmp	byte [Restore_CDIR], 0
  1813 00005469 7610                <1> 	jna	short loc_run_err_pass_restore_cdir
  1814 0000546B 30DB                <1> 	xor	bl, bl
  1815 0000546D 0FB7F3              <1> 	movzx	esi, bx
  1816 00005470 81C600010900        <1> 	add	esi, Logical_DOSDisks
  1817 00005476 E875F1FFFF          <1> 	call	restore_current_directory
  1818                              <1> 
  1819                              <1> loc_run_err_pass_restore_cdir:
  1820 0000547B 58                  <1> 	pop	eax
  1821 0000547C C3                  <1> 	retn
  1822                              <1> 
  1823                              <1> print_directory_list:
  1824                              <1> 	; 10/02/2016
  1825                              <1> 	; 08/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1826                              <1> 	; 06/12/2009 ('cmp_cmd_dir')	
  1827                              <1> 	;
  1828 0000547D 66C705[50B20000]00- <1> 	mov	word [AttributesMask], 0800h ; ..except volume names..
  1828 00005485 08                  <1>
  1829 00005486 A0[AEA80000]        <1> 	mov	al, [Current_Drv]
  1830 0000548B A2[0EB10000]        <1> 	mov	[RUN_CDRV], al
  1831                              <1> get_dfname_fchar:
  1832 00005490 AC                  <1> 	lodsb
  1833 00005491 3C20                <1> 	cmp	al, 20h
  1834 00005493 74FB                <1> 	je	short get_dfname_fchar
  1835 00005495 0F82A4000000        <1>         jb      loc_print_dir_call_all
  1836 0000549B 3C2D                <1> 	cmp	al, '-'
  1837 0000549D 7542                <1> 	jne	short loc_print_dir_call_flt
  1838                              <1> get_next_attr_char:
  1839 0000549F AC                  <1> 	lodsb
  1840 000054A0 3C20                <1> 	cmp	al, 20h
  1841 000054A2 74FB                <1> 	je	short get_next_attr_char
  1842 000054A4 0F821BFFFFFF        <1>         jb      loc_cmd_failed
  1843 000054AA 24DF                <1> 	and	al, 0DFh
  1844 000054AC 3C44                <1> 	cmp	al, 'D' ; directories only ?
  1845 000054AE 7512                <1> 	jne	short pass_only_directories
  1846 000054B0 AC                  <1> 	lodsb
  1847 000054B1 3C20                <1> 	cmp	al, 20h
  1848 000054B3 0F870CFFFFFF        <1>         ja      loc_cmd_failed
  1849 000054B9 800D[50B20000]10    <1> 	or	byte [AttributesMask], 10h ; ..directory..
  1850 000054C0 EB18                <1> 	jmp	short get_dfname_fchar_attr
  1851                              <1> pass_only_directories:
  1852 000054C2 3C46                <1> 	cmp	al, 'F'	; files only ?
  1853 000054C4 0F85B0000000        <1>         jne     check_attr_s
  1854 000054CA AC                  <1> 	lodsb
  1855 000054CB 3C20                <1> 	cmp	al, 20h
  1856 000054CD 0F87F2FEFFFF        <1>         ja      loc_cmd_failed
  1857 000054D3 800D[51B20000]10    <1> 	or	byte [AttributesMask+1], 10h ; ..except directories..
  1858                              <1> get_dfname_fchar_attr:
  1859 000054DA AC                  <1> 	lodsb
  1860 000054DB 3C20                <1> 	cmp	al, 20h
  1861 000054DD 74FB                <1> 	je	short get_dfname_fchar_attr
  1862 000054DF 725E                <1> 	jb	short loc_print_dir_call_all
  1863                              <1> 
  1864                              <1> loc_print_dir_call_flt:
  1865 000054E1 4E                  <1> 	dec	esi
  1866 000054E2 BF[52B20000]        <1> 	mov	edi, FindFile_Drv
  1867 000054E7 E848190000          <1> 	call	parse_path_name
  1868 000054EC 7308                <1>  	jnc	short loc_print_dir_change_drv_1
  1869 000054EE 3C01                <1> 	cmp	al, 1
  1870 000054F0 0F87FAFEFFFF        <1>         ja      loc_run_cmd_failed
  1871                              <1> 
  1872                              <1> loc_print_dir_change_drv_1:
  1873 000054F6 8A15[52B20000]      <1> 	mov	dl, [FindFile_Drv]
  1874                              <1> loc_print_dir_change_drv_2:
  1875 000054FC 3A15[0EB10000]      <1> 	cmp	dl, [RUN_CDRV]
  1876 00005502 740B                <1> 	je	short loc_print_dir_change_directory 
  1877 00005504 E835F0FFFF          <1> 	call	change_current_drive
  1878 00005509 0F82E1FEFFFF        <1>         jc      loc_run_cmd_failed
  1879                              <1> loc_print_dir_change_directory:
  1880 0000550F 803D[53B20000]20    <1> 	cmp	byte [FindFile_Directory], 20h ; 0 or 20h ?
  1881 00005516 761D                <1> 	jna	short pass_print_dir_change_directory
  1882                              <1> 
  1883 00005518 FE05[7D990000]      <1> 	inc	byte [Restore_CDIR]
  1884 0000551E BE[53B20000]        <1> 	mov	esi, FindFile_Directory
  1885 00005523 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  1886 00005525 E8F6120000          <1> 	call	change_current_directory
  1887 0000552A 0F82C0FEFFFF        <1>         jc      loc_run_cmd_failed
  1888                              <1> 
  1889                              <1> loc_print_dir_change_prompt_dir_string:
  1890 00005530 E80B120000          <1> 	call	change_prompt_dir_string
  1891                              <1> 
  1892                              <1> pass_print_dir_change_directory:
  1893 00005535 BE[94B20000]        <1> 	mov	esi, FindFile_Name
  1894 0000553A 803E20              <1> 	cmp	byte [esi], 20h ; ; 0 or 20h ?
  1895 0000553D 7706                <1> 	ja	short loc_print_dir_call
  1896                              <1> 
  1897                              <1> loc_print_dir_call_all:
  1898 0000553F C7062A2E2A00        <1> 	mov	dword [esi], '*.*'
  1899                              <1> loc_print_dir_call:
  1900 00005545 E87E000000          <1> 	call	print_directory
  1901                              <1> 
  1902 0000554A 8A15[0EB10000]      <1> 	mov	dl, [RUN_CDRV]  ; it is set at the beginning
  1903 00005550 3A15[AEA80000]      <1> 	cmp	dl, [Current_Drv]
  1904 00005556 7406                <1> 	je	short loc_print_dir_call_restore_cdir_retn
  1905 00005558 E8E1EFFFFF          <1> 	call	change_current_drive 
  1906 0000555D C3                  <1> 	retn
  1907                              <1> 
  1908                              <1> loc_print_dir_call_restore_cdir_retn:
  1909 0000555E 803D[7D990000]00    <1> 	cmp	byte [Restore_CDIR], 0
  1910 00005565 7610                <1> 	jna	short pass_print_dir_call_restore_cdir_retn
  1911                              <1> 
  1912 00005567 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1913 0000556C 31C0                <1> 	xor	eax, eax
  1914 0000556E 88D4                <1> 	mov	ah, dl
  1915 00005570 01C6                <1> 	add	esi, eax
  1916                              <1> 
  1917 00005572 E879F0FFFF          <1> 	call	restore_current_directory
  1918                              <1> 
  1919                              <1> pass_print_dir_call_restore_cdir_retn:
  1920 00005577 C3                  <1> 	retn
  1921                              <1> 
  1922                              <1> check_attr_s_cap:
  1923 00005578 24DF                <1> 	and	al, 0DFh
  1924                              <1> check_attr_s:
  1925 0000557A 3C53                <1> 	cmp	al, 'S'
  1926 0000557C 7514                <1> 	jne	short pass_attr_s
  1927 0000557E 800D[50B20000]04    <1> 	or	byte [AttributesMask], 4 ; system
  1928 00005585 AC                  <1> 	lodsb
  1929 00005586 3C20                <1> 	cmp	al, 20h
  1930 00005588 0F844CFFFFFF        <1>         je      get_dfname_fchar_attr
  1931 0000558E 72AF                <1> 	jb	short loc_print_dir_call_all
  1932 00005590 24DF                <1> 	and	al, 0DFh
  1933                              <1> pass_attr_s:
  1934 00005592 3C48                <1> 	cmp	al, 'H'
  1935 00005594 7514                <1> 	jne	short pass_attr_h
  1936 00005596 800D[50B20000]02    <1> 	or	byte [AttributesMask], 2 ; hidden
  1937                              <1> pass_attr_shr:
  1938 0000559D AC                  <1> 	lodsb
  1939 0000559E 3C20                <1> 	cmp	al, 20h
  1940 000055A0 0F8434FFFFFF        <1>         je      get_dfname_fchar_attr
  1941 000055A6 7297                <1> 	jb	short loc_print_dir_call_all
  1942 000055A8 EBCE                <1> 	jmp	short check_attr_s_cap
  1943                              <1> 
  1944                              <1> pass_attr_h:
  1945 000055AA 3C52                <1> 	cmp	al, 'R'
  1946 000055AC 7509                <1> 	jne	short pass_attr_r
  1947 000055AE 800D[50B20000]01    <1> 	or	byte [AttributesMask], 1 ; read only
  1948 000055B5 EBE6                <1> 	jmp	short pass_attr_shr
  1949                              <1> 
  1950                              <1> pass_attr_r:
  1951 000055B7 3C41                <1> 	cmp	al, 'A'
  1952 000055B9 0F8506FEFFFF        <1>         jne     loc_cmd_failed
  1953 000055BF 800D[50B20000]20    <1> 	or	byte [AttributesMask], 20h ; archive
  1954 000055C6 EBD5                <1> 	jmp	short pass_attr_shr
  1955                              <1> 
  1956                              <1> print_directory:
  1957                              <1> 	; 11/02/2016
  1958                              <1> 	; 10/02/2016
  1959                              <1> 	; 08/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1960                              <1> 	; 30/10/2010 ('proc_print_directory')	
  1961                              <1> 	; 19/09/2009
  1962                              <1> 	; 2005 
  1963                              <1> 	; INPUT ->
  1964                              <1> 	;	ESI = Asciiz File/Dir Name Address
  1965                              <1> 
  1966 000055C8 56                  <1> 	push	esi
  1967                              <1> 
  1968 000055C9 29C0                <1> 	sub	eax, eax
  1969                              <1> 
  1970 000055CB 66A3[DCB20000]      <1> 	mov	word [Dir_Count], ax ; 0
  1971 000055D1 66A3[DAB20000]      <1> 	mov 	word [File_Count], ax ; 0
  1972 000055D7 A3[DEB20000]        <1> 	mov 	dword [Total_FSize], eax ; 0
  1973                              <1> 
  1974 000055DC E870E6FFFF          <1> 	call    clear_screen
  1975                              <1> 	
  1976 000055E1 31C9                <1> 	xor	ecx, ecx	
  1977 000055E3 8A2D[AEA80000]      <1> 	mov     ch, [Current_Drv] ; DirBuff_Drv - 'A'
  1978 000055E9 A0[AFA80000]        <1> 	mov     al, [Current_Dir_Drv] 
  1979 000055EE A2[439B0000]        <1> 	mov     [Dir_Drive_Name], al
  1980 000055F3 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1981 000055F8 01CE                <1> 	add	esi, ecx
  1982                              <1> 
  1983 000055FA E86FF9FFFF          <1> 	call	move_volume_name_and_serial_no
  1984 000055FF 7306                <1> 	jnc	short print_dir_strlen_check
  1985                              <1> 
  1986 00005601 5E                  <1> 	pop	esi
  1987                              <1> 	;call	beeper
  1988                              <1> 	;retn
  1989 00005602 E98DC2FFFF          <1> 	jmp	beeper  ; beep ! and return
  1990                              <1> 
  1991                              <1> print_dir_strlen_check:
  1992 00005607 BE[B1A80000]        <1> 	mov	esi, Current_Dir_Root
  1993 0000560C BF[E09B0000]        <1> 	mov	edi, Dir_Str_Root
  1994                              <1> 	
  1995                              <1> 	;xor	ecx, ecx
  1996 00005611 8A0D[0DA90000]      <1>         mov     cl, [Current_Dir_StrLen]
  1997 00005617 FEC1                <1> 	inc	cl
  1998 00005619 80F940              <1> 	cmp	cl, 64
  1999 0000561C 760D                <1> 	jna	short pass_print_dir_strlen_shorting
  2000 0000561E 46                  <1> 	inc	esi
  2001 0000561F 01CE                <1> 	add	esi, ecx
  2002 00005621 83EE40              <1> 	sub	esi, 64 
  2003 00005624 47                  <1> 	inc	edi
  2004 00005625 B82E2E2E20          <1> 	mov	eax, '... ' 
  2005 0000562A AB                  <1> 	stosd
  2006                              <1>  
  2007                              <1> pass_print_dir_strlen_shorting:
  2008 0000562B F3A4                <1> 	rep	movsb
  2009                              <1> 
  2010 0000562D BE[369B0000]        <1> 	mov	esi, Dir_Drive_Str
  2011 00005632 E803E6FFFF          <1> 	call	print_msg
  2012                              <1> 
  2013 00005637 BE[959B0000]        <1> 	mov	esi, Vol_Serial_Header
  2014 0000563C E8F9E5FFFF          <1> 	call	print_msg
  2015                              <1> 
  2016 00005641 BE[D59B0000]        <1> 	mov	esi, Dir_Str_Header
  2017 00005646 E8EFE5FFFF          <1> 	call	print_msg
  2018                              <1> 	
  2019 0000564B BE[C4A40000]        <1> 	mov	esi, next2line
  2020 00005650 E8E5E5FFFF          <1> 	call	print_msg
  2021                              <1> 
  2022                              <1> loc_print_dir_first_file:
  2023 00005655 C605[F1B20000]10    <1> 	mov	byte [PrintDir_RowCounter], 16
  2024 0000565C 66A1[50B20000]      <1> 	mov	ax, [AttributesMask]
  2025 00005662 5E                  <1> 	pop	esi
  2026                              <1> 
  2027 00005663 E859020000          <1> 	call	find_first_file
  2028 00005668 0F826F010000        <1>         jc      loc_dir_ok
  2029                              <1> 	 
  2030                              <1> loc_dfname_use_this:
  2031                              <1> 	; bl =	File Attributes (bh = Long Name Entry Length)
  2032 0000566E F6C310              <1> 	test	bl, 10h  ; Is it a directory?
  2033 00005671 741B                <1> 	jz	short loc_not_dir
  2034                              <1> 
  2035 00005673 66FF05[DCB20000]    <1> 	inc	word [Dir_Count]
  2036 0000567A 89F2                <1> 	mov	edx, esi 	; FindFile_DirEntry address
  2037 0000567C BE[229D0000]        <1>  	mov	esi, Type_Dir	; '<DIR>     '
  2038 00005681 BF[399D0000]        <1> 	mov	edi, Dir_Or_FileSize
  2039                              <1> 	; move 10 bytes
  2040 00005686 A5                  <1> 	movsd
  2041 00005687 A5                  <1> 	movsd
  2042 00005688 66A5                <1> 	movsw	    	
  2043 0000568A 89D6                <1> 	mov	esi, edx
  2044 0000568C EB36                <1> 	jmp     short loc_dir_attribute
  2045                              <1> 
  2046                              <1> loc_not_dir:
  2047 0000568E 66FF05[DAB20000]    <1> 	inc	word [File_Count]
  2048 00005695 0105[DEB20000]      <1> 	add	[Total_FSize], eax
  2049                              <1> 
  2050 0000569B B90A000000          <1> 	mov	ecx, 10  ; 32 bit divisor
  2051 000056A0 89CF                <1> 	mov	edi, ecx
  2052 000056A2 81C7[399D0000]      <1> 	add	edi, Dir_Or_FileSize
  2053                              <1> loc_dir_rdivide:
  2054 000056A8 29D2                <1> 	sub	edx, edx
  2055 000056AA F7F1                <1> 	div	ecx 	 ; remainder in dl (< 10)
  2056 000056AC 80C230              <1> 	add     dl, '0'	 ; to make visible (ascii)
  2057 000056AF 4F                  <1> 	dec	edi
  2058 000056B0 8817                <1> 	mov     [edi], dl
  2059 000056B2 21C0                <1> 	and	eax, eax
  2060 000056B4 75F2                <1> 	jnz	short loc_dir_rdivide
  2061                              <1> 
  2062                              <1> loc_dir_fill_space:
  2063 000056B6 81FF[399D0000]      <1> 	cmp     edi, Dir_Or_FileSize
  2064 000056BC 7606                <1> 	jna     short loc_dir_attribute
  2065 000056BE 4F                  <1> 	dec     edi
  2066 000056BF C60720              <1> 	mov     byte [edi], 20h
  2067 000056C2 EBF2                <1> 	jmp     short loc_dir_fill_space
  2068                              <1> 
  2069                              <1> loc_dir_attribute:
  2070 000056C4 C705[449D0000]2020- <1> 	mov	dword [File_Attribute], 20202020h
  2070 000056CC 2020                <1>
  2071                              <1> 
  2072 000056CE 80FB20              <1> 	cmp	bl, 20h  ; Is it an archive file?
  2073 000056D1 7207                <1> 	jb	short loc_dir_pass_arch
  2074 000056D3 C605[479D0000]41    <1> 	mov	byte [File_Attribute+3], 'A'
  2075                              <1> 
  2076                              <1> loc_dir_pass_arch:
  2077 000056DA 80E307              <1> 	and	bl, 7
  2078 000056DD 7428                <1> 	jz	short loc_dir_file_name
  2079 000056DF 88DF                <1> 	mov	bh, bl
  2080 000056E1 80E303              <1> 	and	bl, 3
  2081 000056E4 38DF                <1> 	cmp	bh, bl
  2082 000056E6 7607                <1> 	jna	short loc_dir_pass_s
  2083 000056E8 C605[449D0000]53    <1> 	mov	byte [File_Attribute], 'S'
  2084                              <1> 
  2085                              <1> loc_dir_pass_s:
  2086 000056EF 80E302              <1> 	and     bl,2
  2087 000056F2 7407                <1> 	jz      short loc_dir_pass_h
  2088 000056F4 C605[459D0000]48    <1> 	mov     byte [File_Attribute+1], 'H'
  2089                              <1> loc_dir_pass_h:
  2090 000056FB 80E701              <1> 	and     bh,1
  2091 000056FE 7407                <1> 	jz      short loc_dir_file_name
  2092 00005700 C605[469D0000]52    <1> 	mov     byte [File_Attribute+2], 'R'
  2093                              <1> loc_dir_file_name:
  2094                              <1> 	;mov     bx, [esi+18h] ; Date
  2095                              <1> 	;mov     dx, [esi+16h] ; Time
  2096 00005707 8B5E16              <1> 	mov	ebx, [esi+16h]
  2097 0000570A 89F1                <1> 	mov	ecx, esi ; FindFile_DirEntry address
  2098 0000570C BF[2C9D0000]        <1> 	mov     edi, File_Name
  2099                              <1> 	; move 8 bytes
  2100 00005711 A5                  <1> 	movsd
  2101 00005712 A5                  <1> 	movsd
  2102 00005713 C60720              <1> 	mov	byte [edi], 20h
  2103 00005716 47                  <1> 	inc	edi
  2104                              <1> 	; move 3 bytes
  2105 00005717 66A5                <1> 	movsw
  2106 00005719 A4                  <1> 	movsb
  2107 0000571A 89CE                <1> 	mov	esi, ecx
  2108                              <1> 
  2109                              <1> Dir_Time_start:
  2110                              <1> 	;mov	ax, dx		; Time
  2111 0000571C 6689D8              <1> 	mov	ax, bx
  2112 0000571F 66C1E805            <1> 	shr	ax, 5		; shift right 5 times
  2113 00005723 6683E03F            <1> 	and	ax, 0000111111b	; Minute Mask
  2114 00005727 D40A                <1> 	aam			; Q([AL]/10)->AH
  2115                              <1> 				; R([AL]/10)->AL
  2116                              <1> 				; [AL]+[AH]= Minute as BCD
  2117 00005729 660D3030            <1> 	or	ax, '00'	; Convert to ASCII
  2118 0000572D 86E0                <1> 	xchg	ah, al
  2119 0000572F 66A3[579D0000]      <1> 	mov	[File_Minute], ax
  2120                              <1> 
  2121                              <1> 	;mov	al, dh
  2122 00005735 88F8                <1> 	mov	al, bh
  2123 00005737 C0E803              <1> 	shr	al, 3		; shift right 3 times
  2124 0000573A D40A                <1> 	aam			; [AL]+[AH]= Hours as BCD
  2125 0000573C 660D3030            <1> 	or	ax, '00'
  2126 00005740 86E0                <1> 	xchg	ah, al
  2127 00005742 66A3[549D0000]      <1> 	mov     [File_Hour], ax
  2128                              <1> 
  2129 00005748 C1EB10              <1> 	shr	ebx, 16		; BX = Date
  2130                              <1> 	
  2131                              <1> Dir_Date_start:
  2132 0000574B 6689D8              <1> 	mov	ax, bx		; Date
  2133 0000574E 6683E01F            <1> 	and	ax, 00011111b	; Day Mask
  2134 00005752 D40A                <1> 	aam			; Q([AL]/10)->AH
  2135                              <1> 				; R([AL]/10)->AL
  2136                              <1> 				; [AL]+[AH]= Day as BCD
  2137 00005754 660D3030            <1> 	or	ax, '00'	; Convert to ASCII
  2138 00005758 86C4                <1> 	xchg	al, ah
  2139                              <1> 
  2140 0000575A 66A3[499D0000]      <1> 	mov	[File_Day], ax
  2141                              <1> 
  2142 00005760 6689D8              <1> 	mov	ax, bx
  2143 00005763 66C1E805            <1> 	shr	ax, 5		; shift right 5 times
  2144 00005767 6683E00F            <1> 	and	ax, 00001111b	; Month Mask
  2145 0000576B D40A                <1> 	aam
  2146 0000576D 660D3030            <1> 	or	ax, '00'
  2147 00005771 86E0                <1> 	xchg	ah, al
  2148 00005773 66A3[4C9D0000]      <1> 	mov	[File_Month], ax
  2149                              <1> 
  2150 00005779 6689D8              <1> 	mov	ax, bx
  2151 0000577C 66C1E809            <1> 	shr     ax, 9
  2152 00005780 6683E07F            <1> 	and	ax, 01111111b	; Result = Year - 1980
  2153 00005784 6605BC07            <1> 	add	ax, 1980
  2154                              <1> 
  2155 00005788 B10A                <1> 	mov	cl, 10
  2156 0000578A F6F1                <1> 	div	cl		; Q -> AL, R -> AH 
  2157 0000578C 80CC30              <1> 	or	ah, '0'
  2158 0000578F 8825[529D0000]      <1> 	mov	[File_Year+3], ah
  2159 00005795 D40A                <1> 	aam
  2160 00005797 86E0                <1> 	xchg	ah, al
  2161 00005799 80CC30              <1> 	or	ah, '0'	  ; Convert to ASCII
  2162 0000579C 8825[519D0000]      <1> 	mov	[File_Year+2], ah
  2163 000057A2 D40A                <1> 	aam
  2164 000057A4 86C4                <1> 	xchg	al, ah
  2165 000057A6 660D3030            <1> 	or	ax, '00'
  2166 000057AA 66A3[4F9D0000]      <1> 	mov	[File_Year], ax
  2167                              <1> 
  2168                              <1> loc_show_line:
  2169 000057B0 56                  <1> 	push	esi
  2170 000057B1 BE[2C9D0000]        <1> 	mov     esi, File_Name
  2171 000057B6 E87FE4FFFF          <1> 	call	print_msg
  2172 000057BB BE[C6A40000]        <1> 	mov	esi, nextline
  2173 000057C0 E875E4FFFF          <1> 	call	print_msg
  2174 000057C5 5E                  <1> 	pop	esi
  2175                              <1> 
  2176 000057C6 FE0D[F1B20000]      <1> 	dec	byte [PrintDir_RowCounter]
  2177 000057CC 0F84D4000000        <1>         jz      pause_dir_scroll
  2178                              <1> 
  2179                              <1> loc_next_entry:
  2180 000057D2 E899010000          <1> 	call	find_next_file
  2181 000057D7 0F8391FEFFFF        <1>         jnc     loc_dfname_use_this
  2182                              <1> 
  2183                              <1> loc_dir_ok:
  2184 000057DD B90A000000          <1> 	mov     ecx, 10
  2185 000057E2 66A1[DCB20000]      <1> 	mov	ax, [Dir_Count]
  2186 000057E8 BF[6D9D0000]        <1> 	mov	edi, Decimal_Dir_Count
  2187 000057ED 6639C8              <1> 	cmp	ax, cx ; 10
  2188 000057F0 7216                <1> 	jb	short pass_ddc
  2189 000057F2 47                  <1> 	inc	edi
  2190 000057F3 6683F864            <1> 	cmp	ax, 100
  2191 000057F7 720F                <1> 	jb	short pass_ddc
  2192 000057F9 47                  <1> 	inc	edi
  2193 000057FA 663DE803            <1> 	cmp	ax, 1000
  2194 000057FE 7208                <1> 	jb	short pass_ddc
  2195 00005800 47                  <1> 	inc	edi
  2196 00005801 663D1027            <1> 	cmp	ax, 10000
  2197 00005805 7201                <1> 	jb	short pass_ddc
  2198 00005807 47                  <1> 	inc	edi
  2199                              <1> pass_ddc:
  2200 00005808 886F01              <1> 	mov     [edi+1], ch ; 0
  2201                              <1> loc_ddc_rediv:
  2202 0000580B 31D2                <1> 	xor     edx, edx
  2203 0000580D 66F7F1              <1> 	div     cx	; 10
  2204 00005810 80C230              <1> 	add     dl, '0'
  2205 00005813 8817                <1> 	mov     [edi], dl
  2206 00005815 4F                  <1> 	dec     edi
  2207 00005816 6609C0              <1> 	or	ax, ax
  2208 00005819 75F0                <1> 	jnz	short loc_ddc_rediv
  2209                              <1> 
  2210 0000581B 66A1[DAB20000]      <1> 	mov     ax, [File_Count]
  2211 00005821 BF[5C9D0000]        <1> 	mov     edi, Decimal_File_Count
  2212 00005826 6639C8              <1> 	cmp     ax, cx ; 10
  2213 00005829 7216                <1> 	jb      short pass_dfc
  2214 0000582B 47                  <1> 	inc     edi
  2215 0000582C 6683F864            <1> 	cmp     ax, 100
  2216 00005830 720F                <1> 	jb      short pass_dfc
  2217 00005832 47                  <1> 	inc     edi
  2218 00005833 663DE803            <1> 	cmp     ax, 1000
  2219 00005837 7208                <1> 	jb      short pass_dfc
  2220 00005839 47                  <1> 	inc     edi
  2221 0000583A 663D1027            <1> 	cmp     ax, 10000
  2222 0000583E 7201                <1> 	jb      short pass_dfc
  2223 00005840 47                  <1> 	inc     edi
  2224                              <1> pass_dfc:
  2225                              <1> 	;mov    cx, 10
  2226 00005841 886F01              <1> 	mov     [edi+1], ch ; 00
  2227                              <1> loc_dfc_rediv:
  2228                              <1> 	;xor	dx, dx
  2229 00005844 30D2                <1> 	xor	dl, dl
  2230 00005846 66F7F1              <1> 	div	cx
  2231 00005849 80C230              <1> 	add	dl, '0'
  2232 0000584C 8817                <1> 	mov	[edi], dl
  2233 0000584E 4F                  <1> 	dec	edi
  2234 0000584F 6609C0              <1> 	or	ax, ax
  2235 00005852 75F0                <1> 	jnz	short loc_dfc_rediv
  2236                              <1> 
  2237 00005854 BF[F0B20000]        <1> 	mov     edi, TFS_Dec_End
  2238                              <1>         ;mov    byte [edi], 0
  2239 00005859 A1[DEB20000]        <1> 	mov     eax, [Total_FSize]
  2240                              <1> 	;mov    ecx, 10
  2241                              <1> rediv_tfs_hex:
  2242                              <1> 	;sub	edx, edx
  2243 0000585E 28D2                <1> 	sub	dl, dl
  2244 00005860 F7F1                <1> 	div	ecx
  2245 00005862 80C230              <1> 	add	dl, '0'
  2246 00005865 4F                  <1> 	dec     edi
  2247 00005866 8817                <1> 	mov     [edi], dl
  2248 00005868 21C0                <1> 	and	eax, eax
  2249 0000586A 75F2                <1> 	jnz	short rediv_tfs_hex
  2250                              <1> 	
  2251 0000586C 893D[E2B20000]      <1> 	mov	[TFS_Dec_Begin], edi
  2252 00005872 BE[5A9D0000]        <1> 	mov	esi, Decimal_File_Count_Header
  2253 00005877 E8BEE3FFFF          <1> 	call	print_msg
  2254 0000587C BE[629D0000]        <1> 	mov	esi, str_files
  2255 00005881 E8B4E3FFFF          <1> 	call	print_msg
  2256 00005886 BE[739D0000]        <1> 	mov	esi, str_dirs
  2257 0000588B E8AAE3FFFF          <1> 	call	print_msg
  2258 00005890 8B35[E2B20000]      <1> 	mov	esi, [TFS_Dec_Begin]
  2259 00005896 E89FE3FFFF          <1> 	call	print_msg
  2260 0000589B BE[849D0000]        <1> 	mov	esi, str_bytes
  2261 000058A0 E895E3FFFF          <1> 	call	print_msg
  2262                              <1> 
  2263 000058A5 C3                  <1> 	retn
  2264                              <1> 
  2265                              <1> pause_dir_scroll:
  2266 000058A6 28E4                <1> 	sub	ah, ah           
  2267 000058A8 E83AB3FFFF          <1> 	call	int16h
  2268 000058AD 3C1B                <1> 	cmp	al, 1Bh
  2269 000058AF 0F8428FFFFFF        <1>         je      loc_dir_ok
  2270 000058B5 C605[F1B20000]10    <1> 	mov	byte [PrintDir_RowCounter], 16 ; Reset counter
  2271 000058BC E911FFFFFF          <1>         jmp     loc_next_entry
  2272                              <1> 
  2273                              <1> find_first_file:
  2274                              <1> 	; 11/02/2015
  2275                              <1> 	; 10/02/2016
  2276                              <1> 	; 08/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2277                              <1> 	; 09/10/2011
  2278                              <1> 	; 17/09/2009
  2279                              <1> 	; 2005
  2280                              <1> 	; INPUT ->
  2281                              <1> 	;	ESI = ASCIIZ File/Dir/Path Name Address
  2282                              <1> 	;	AL = Attributes AND mask (The AND result must be equal to AL)
  2283                              <1> 	;	      bit 0 = Read Only
  2284                              <1> 	;	      bir 1 = Hidden
  2285                              <1> 	;	      bit 2 = System
  2286                              <1> 	;	      bit 3 = Volume Label
  2287                              <1> 	;	      bit 4 = Directory
  2288                              <1> 	;	      bit 5 = Archive
  2289                              <1> 	;	      bit 6 = Reserved, must be 0
  2290                              <1> 	;	      bit 7 = Reserved, must be 0
  2291                              <1> 	;       AH = Attributes Negative AND mask (The AND result must be ZERO)
  2292                              <1> 	;
  2293                              <1> 	; OUTPUT ->
  2294                              <1> 	;	CF = 1 -> Error, Error Code in EAX (AL)
  2295                              <1> 	;	CF = 0 ->
  2296                              <1> 	;	     ESI = Directory Entry (FindFile_DirEntry) Location
  2297                              <1> 	;	     EDI = Directory Buffer Directory Entry Location
  2298                              <1> 	;	     EAX = File Size
  2299                              <1> 	;	      BL = Attributes of The File/Directory
  2300                              <1> 	;	      BH = Long Name Yes/No Status (>0 is YES)
  2301                              <1> 	;             DX > 0 : Ambiguous filename chars are used
  2302                              <1> 	;
  2303                              <1> 	; (EAX, EBX, ECX, EDX, ESI, EDI will be changed)
  2304                              <1> 
  2305 000058C1 66A3[A2B20000]      <1> 	mov	[FindFile_AttributesMask], ax
  2306 000058C7 BF[A4B20000]        <1> 	mov	edi, FindFile_DirEntry ; TR-DOS Fullfilename formatted buffer
  2307 000058CC 31C0                <1> 	xor	eax, eax
  2308 000058CE B90B000000          <1> 	mov	ecx, 11
  2309 000058D3 F3AB                <1> 	rep	stosd	; 44 bytes
  2310                              <1> 	;stosw		; +2 bytes 
  2311                              <1> 	    
  2312 000058D5 BF[94B20000]        <1> 	mov	edi, FindFile_Name ; FFF structure, offset 66
  2313 000058DA 39FE                <1> 	cmp	esi, edi
  2314 000058DC 7408                <1> 	je	short loc_fff_mfn_ok
  2315 000058DE 89FA                <1> 	mov	edx, edi 
  2316                              <1> 	 ; move 13 bytes
  2317 000058E0 A5                  <1> 	movsd
  2318 000058E1 A5                  <1> 	movsd
  2319 000058E2 A5                  <1> 	movsd
  2320 000058E3 AA                  <1> 	stosb
  2321 000058E4 89D6                <1> 	mov	esi, edx
  2322                              <1> loc_fff_mfn_ok:
  2323 000058E6 BF[43B20000]        <1> 	mov	edi, Dir_Entry_Name ; Dir Entry Format File Name
  2324 000058EB E879140000          <1> 	call	convert_file_name
  2325 000058F0 89FE                <1> 	mov	esi, edi ; offset Dir_Entry_Name
  2326                              <1> 
  2327 000058F2 66A1[A2B20000]      <1> 	mov	ax, [FindFile_AttributesMask]
  2328                              <1> 	;xor	ecx, ecx
  2329 000058F8 30C9                <1> 	xor	cl, cl  
  2330 000058FA E875110000          <1> 	call	locate_current_dir_file
  2331 000058FF 726E                <1> 	jc	short loc_fff_retn
  2332                              <1> 	; EDI = Directory Entry
  2333                              <1> 	; EBX = Directory Buffer Entry Index/Number
  2334                              <1> 
  2335                              <1> loc_fff_fnf_ln_check:
  2336 00005901 30ED                <1> 	xor	ch, ch 
  2337 00005903 80F60F              <1> 	xor	dh, 0Fh
  2338 00005906 7408                <1> 	jz	short loc_fff_longname_yes
  2339 00005908 882D[A1B20000]      <1> 	mov	[FindFile_LongNameYes], ch ; 0
  2340 0000590E EB0C                <1> 	jmp	short loc_fff_longname_no
  2341                              <1> 
  2342                              <1> loc_fff_longname_yes:
  2343                              <1> 	;inc	byte [FindFile_LongNameYes]
  2344 00005910 8A0D[AEB10000]      <1> 	mov	cl, [LFN_EntryLength]  
  2345 00005916 880D[A1B20000]      <1> 	mov	[FindFile_LongNameEntryLength], cl ; FindFile_LongNameYes
  2346                              <1> 
  2347                              <1> loc_fff_longname_no:
  2348                              <1> 	;mov	bx, [DirBuff_CurrentEntry]
  2349 0000591C 66891D[CCB20000]    <1> 	mov	[FindFile_DirEntryNumber], bx
  2350 00005923 6689C2              <1> 	mov	dx, ax ; Ambigouos Filename chars used sign > 0
  2351                              <1> 
  2352 00005926 A0[AEA80000]        <1> 	mov	al, [Current_Drv]
  2353 0000592B A2[52B20000]        <1> 	mov	[FindFile_Drv], al 
  2354                              <1> 
  2355 00005930 A1[A8A80000]        <1> 	mov	eax, [Current_Dir_FCluster]
  2356 00005935 A3[C4B20000]        <1> 	mov	[FindFile_DirFirstCluster], eax
  2357                              <1> 
  2358 0000593A A1[DDB00000]        <1> 	mov	eax, [DirBuff_Cluster]
  2359 0000593F A3[C8B20000]        <1> 	mov	[FindFile_DirCluster], eax
  2360                              <1> 
  2361 00005944 66FF05[CEB20000]    <1> 	inc	word [FindFile_MatchCounter]
  2362                              <1> 
  2363 0000594B 89FB                <1> 	mov	ebx, edi
  2364 0000594D 89FE                <1> 	mov	esi, edi
  2365 0000594F BF[A4B20000]        <1> 	mov	edi, FindFile_DirEntry
  2366 00005954 89F8                <1> 	mov	eax, edi
  2367 00005956 B108                <1> 	mov	cl, 8
  2368 00005958 F3A5                <1> 	rep	movsd
  2369 0000595A 89C6                <1> 	mov	esi, eax
  2370 0000595C 89DF                <1> 	mov	edi, ebx
  2371                              <1> 
  2372 0000595E A1[C0B20000]        <1> 	mov	eax, [FindFile_DirEntry+28] ; File Size
  2373                              <1> 
  2374 00005963 8A1D[AFB20000]      <1> 	mov	bl, [FindFile_DirEntry+11] ; File Attributes 
  2375 00005969 8A3D[A1B20000]      <1> 	mov	bh, [FindFile_LongNameYes]
  2376                              <1> 
  2377                              <1> 	;mov	cx, [DirBuff_EntryCounter]
  2378                              <1> 	;mov	[FindFile_DirEntryNumber], cx
  2379                              <1> 	;mov	cx, [FindFile_DirEntryNumber]
  2380                              <1> 	; ecx = 0
  2381                              <1> 
  2382                              <1> loc_fff_retn:
  2383 0000596F C3                  <1> 	retn
  2384                              <1> 
  2385                              <1> find_next_file:
  2386                              <1> 	; 10/02/2016
  2387                              <1> 	; 08/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2388                              <1> 	; 06/02/2011
  2389                              <1> 	; 17/09/2009
  2390                              <1> 	; 2005
  2391                              <1> 	; INPUT ->
  2392                              <1> 	;	NONE, Find First File Parameters
  2393                              <1> 	; OUTPUT ->
  2394                              <1> 	;	CF = 1 -> Error, Error Code in EAX (AL)
  2395                              <1> 	;	CF = 0 -> 
  2396                              <1> 	;	    ESI = Directory Entry (FindFile_DirEntry) Location
  2397                              <1> 	;	    EDI = Directory Buffer Directory Entry Location
  2398                              <1> 	;	    EAX = File Size
  2399                              <1> 	;	      BL = Attributes of The File/Directory
  2400                              <1> 	;	      BH = Long Name Yes/No Status (>0 is YES)
  2401                              <1> 	;             DX > 0 : Ambiguous filename chars are used 
  2402                              <1> 	;
  2403                              <1> 	; (EAX, EBX, ECX, EDX, ESI, EDI will be changed)
  2404                              <1> 
  2405 00005970 66833D[CEB20000]00  <1> 	cmp	word [FindFile_MatchCounter], 0
  2406 00005978 7707                <1> 	ja	short loc_start_search_next_file
  2407                              <1> 
  2408                              <1> loc_fnf_stc_retn:
  2409 0000597A F9                  <1> 	stc
  2410                              <1> loc_fnf_ax12h_retn:
  2411 0000597B B812000000          <1> 	mov	eax, 12h ; 18, No More files
  2412                              <1> ;loc_fnf_retn:
  2413 00005980 C3                  <1> 	retn
  2414                              <1> 
  2415                              <1> loc_start_search_next_file:
  2416 00005981 668B1D[CCB20000]    <1> 	mov	bx, [FindFile_DirEntryNumber]
  2417 00005988 6643                <1> 	inc	bx
  2418 0000598A 663B1D[DBB00000]    <1> 	cmp	bx, [DirBuff_LastEntry]
  2419 00005991 7719                <1> 	ja	short loc_cont_search_next_file
  2420                              <1> 
  2421                              <1> loc_fnf_search:
  2422 00005993 BE[43B20000]        <1> 	mov	esi, Dir_Entry_Name
  2423 00005998 66A1[A2B20000]      <1> 	mov	ax, [FindFile_AttributesMask]
  2424 0000599E 6631C9              <1> 	xor	cx, cx
  2425 000059A1 E8D0110000          <1> 	call	find_directory_entry
  2426 000059A6 0F8355FFFFFF        <1>         jnc     loc_fff_fnf_ln_check
  2427                              <1> 
  2428                              <1> loc_cont_search_next_file:
  2429 000059AC 31DB                <1> 	xor	ebx, ebx
  2430 000059AE 8A3D[AEA80000]      <1> 	mov	bh, [Current_Drv]
  2431 000059B4 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2432 000059B9 01DE                <1> 	add	esi, ebx
  2433                              <1> 
  2434 000059BB 803D[ACA80000]00    <1> 	cmp	byte [Current_Dir_Level], 0
  2435 000059C2 7608                <1> 	jna	short loc_fnf_check_FAT_type
  2436 000059C4 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  2437 000059C8 72B1                <1> 	jb	short loc_fnf_ax12h_retn
  2438 000059CA EB06                <1> 	jmp	short loc_fnf_check_next_cluster
  2439                              <1>  
  2440                              <1> loc_fnf_check_FAT_type:
  2441 000059CC 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3
  2442 000059D0 72A9                <1> 	jb	short loc_fnf_ax12h_retn
  2443                              <1> 
  2444                              <1> loc_fnf_check_next_cluster:
  2445 000059D2 A1[DDB00000]        <1> 	mov	eax, [DirBuff_Cluster]
  2446 000059D7 E8161D0000          <1> 	call	get_next_cluster
  2447 000059DC 7306                <1> 	jnc	short loc_fnf_load_next_dir_cluster
  2448 000059DE 09C0                <1> 	or	eax, eax
  2449 000059E0 7498                <1> 	jz	short loc_fnf_stc_retn
  2450                              <1> 	;mov	eax, 15h ;Drive not ready or read error
  2451 000059E2 F5                  <1>  	cmc	;stc
  2452                              <1> loc_fnf_retn:
  2453 000059E3 C3                  <1> 	retn
  2454                              <1> 
  2455                              <1> loc_fnf_load_next_dir_cluster:
  2456 000059E4 E8EA1E0000          <1> 	call	load_FAT_sub_directory
  2457 000059E9 72F8                <1> 	jc	short loc_fnf_retn
  2458 000059EB 6631DB              <1> 	xor	bx, bx
  2459 000059EE 66891D[CCB20000]    <1> 	mov	[FindFile_DirEntryNumber], bx
  2460 000059F5 EB9C                <1> 	jmp	short loc_fnf_search
  2461                              <1> 
  2462                              <1> get_and_print_longname:
  2463                              <1> 	; 13/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2464                              <1> 	; 24/01/2010
  2465                              <1> 	; 17/10/2009 (CMD_INTR.ASM, 'cmp_cmd_longname')
  2466                              <1> get_longname_fchar:
  2467 000059F7 803E20              <1> 	cmp	byte [esi], 20h
  2468 000059FA 7701                <1> 	ja	short loc_find_longname
  2469                              <1> 	;jb	short loc_longname_retn
  2470                              <1> 	;inc	esi
  2471                              <1> 	;je	short get_longname_fchar
  2472                              <1> ;loc_longname_retn:
  2473 000059FC C3                  <1> 	retn
  2474                              <1> loc_find_longname:
  2475 000059FD E8DB140000          <1> 	call	find_longname
  2476 00005A02 7320                <1> 	jnc	short loc_print_longname
  2477                              <1>                
  2478 00005A04 08C0                <1> 	or	al, al
  2479 00005A06 7412                <1> 	jz	short loc_longname_not_found
  2480                              <1> 	  
  2481 00005A08 3C15                <1> 	cmp	al, 15h
  2482 00005A0A 0F84B4F7FFFF        <1> 	je	cd_drive_not_ready
  2483                              <1> 
  2484                              <1> loc_ln_file_dir_not_found:
  2485 00005A10 BE[B19C0000]        <1> 	mov	esi, Msg_File_Directory_Not_Found
  2486                              <1> 	;call	print_msg	
  2487                              <1>         ;retn
  2488 00005A15 E920E2FFFF          <1> 	jmp	print_msg
  2489                              <1> 
  2490                              <1> loc_longname_not_found:
  2491 00005A1A BE[D09C0000]        <1>         mov     esi, Msg_LongName_Not_Found
  2492                              <1> 	;call	print_msg	
  2493                              <1>         ;retn
  2494 00005A1F E916E2FFFF          <1> 	jmp	print_msg
  2495                              <1> 
  2496                              <1> loc_print_longname:
  2497                              <1> 	;mov	esi, LongFileName
  2498 00005A24 BF[AEA90000]        <1> 	mov	edi, TextBuffer
  2499 00005A29 57                  <1> 	push	edi 
  2500 00005A2A 3C00                <1> 	cmp	al, 0
  2501 00005A2C 7708                <1> 	ja	short loc_print_longname_1
  2502                              <1> loc_print_FS_longname: ; Singlix FS (64 byte ASCIIZ file name)
  2503 00005A2E AC                  <1> 	lodsb
  2504 00005A2F AA                  <1> 	stosb  
  2505 00005A30 08C0                <1> 	or	al, al
  2506 00005A32 75FA                <1> 	jnz	short loc_print_FS_longname
  2507 00005A34 EB07                <1> 	jmp	short loc_print_longname_2
  2508                              <1> 	;
  2509                              <1> loc_print_longname_1: ; MS Windows long name (UNICODE chars)
  2510 00005A36 66AD                <1> 	lodsw
  2511 00005A38 AA                  <1> 	stosb  
  2512 00005A39 08C0                <1> 	or	al, al
  2513 00005A3B 75F9                <1> 	jnz	short loc_print_longname_1
  2514                              <1> 	;
  2515                              <1> loc_print_longname_2:               
  2516 00005A3D 5E                  <1> 	pop	esi
  2517 00005A3E E8F7E1FFFF          <1> 	call	print_msg
  2518 00005A43 BE[C6A40000]        <1>   	mov	esi, nextline
  2519                              <1> 	;call	print_msg
  2520                              <1> 	;retn
  2521 00005A48 E9EDE1FFFF          <1> 	jmp	print_msg	
  2522                              <1> 
  2523                              <1> show_file:
  2524                              <1> 	; 18/02/2016
  2525                              <1> 	; 17/02/2016
  2526                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2527                              <1> 	; 13/09/2011 (CMD_INTR.ASM, 'cmp_cmd_show')
  2528                              <1> 	; 08/11/2009
  2529                              <1> 
  2530                              <1> loc_show_parse_path_name:
  2531 00005A4D BF[52B20000]        <1> 	mov	edi, FindFile_Drv
  2532 00005A52 E8DD130000          <1> 	call	parse_path_name
  2533 00005A57 0F8268F9FFFF        <1> 	jc	loc_cmd_failed
  2534                              <1> 
  2535                              <1> loc_show_check_filename_exists:
  2536 00005A5D BE[94B20000]        <1> 	mov	esi, FindFile_Name
  2537 00005A62 803E20              <1> 	cmp	byte [esi], 20h
  2538 00005A65 0F865AF9FFFF        <1> 	jna	loc_cmd_failed
  2539                              <1> 
  2540                              <1> 	; 15/02/2016 (invalid file name check)
  2541 00005A6B E805020000          <1> 	call	check_filename 	
  2542 00005A70 730A                <1> 	jnc	short loc_show_change_drv
  2543                              <1> 
  2544 00005A72 BE[9A9D0000]        <1> 	mov	esi, Msg_invalid_name_chars
  2545 00005A77 E9BEE1FFFF          <1> 	jmp	print_msg
  2546                              <1>    
  2547                              <1> loc_show_change_drv:
  2548 00005A7C 8A35[AEA80000]      <1> 	mov	dh, [Current_Drv]
  2549 00005A82 8835[0EB10000]      <1> 	mov	[RUN_CDRV], dh
  2550 00005A88 8A15[52B20000]      <1> 	mov	dl, [FindFile_Drv]
  2551 00005A8E 38F2                <1> 	cmp	dl, dh
  2552 00005A90 740B                <1> 	je	short loc_show_change_directory
  2553 00005A92 E8A7EAFFFF          <1> 	call	change_current_drive
  2554                              <1> 	;jc	loc_file_rw_cmd_failed
  2555 00005A97 0F8253F9FFFF        <1> 	jc	loc_run_cmd_failed
  2556                              <1> 
  2557                              <1> loc_show_change_directory:
  2558 00005A9D 803D[53B20000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  2559 00005AA4 7618                <1> 	jna	short loc_findload_showfile
  2560                              <1> 
  2561 00005AA6 FE05[7D990000]      <1> 	inc	byte [Restore_CDIR]
  2562 00005AAC BE[53B20000]        <1> 	mov	esi, FindFile_Directory
  2563 00005AB1 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2564 00005AB3 E8680D0000          <1> 	call	change_current_directory
  2565                              <1> 	;jc	loc_file_rw_cmd_failed
  2566 00005AB8 0F8232F9FFFF        <1> 	jc	loc_run_cmd_failed
  2567                              <1> 
  2568                              <1> ;loc_show_change_prompt_dir_string:
  2569                              <1> 	;call	change_prompt_dir_string
  2570                              <1> 
  2571                              <1> loc_findload_showfile:
  2572                              <1> 	; 15/02/2016
  2573 00005ABE BE[94B20000]        <1> 	mov	esi, FindFile_Name
  2574 00005AC3 BF[43B20000]        <1> 	mov	edi, Dir_Entry_Name ; Dir Entry Format File Name
  2575 00005AC8 E89C120000          <1> 	call	convert_file_name
  2576 00005ACD 89FE                <1> 	mov	esi, edi ; offset Dir_Entry_Name
  2577                              <1> 
  2578 00005ACF 28C0                <1> 	sub	al, al	; Attrib AND mask = 0
  2579                              <1> 	; Directory attribute : 10h
  2580                              <1> 	; Volume name attribute: 8h
  2581 00005AD1 B418                <1> 	mov	ah, 00011000b ; 18h (Attrib NAND, AND --> zero mask)
  2582                              <1> 	;
  2583 00005AD3 6631C9              <1> 	xor	cx, cx  
  2584 00005AD6 E8990F0000          <1> 	call	locate_current_dir_file
  2585                              <1> 	;jc	loc_file_rw_cmd_failed
  2586 00005ADB 0F820FF9FFFF        <1> 	jc	loc_run_cmd_failed
  2587                              <1> 
  2588                              <1> loc_show_load_file:
  2589                              <1> 	; EDI = Directory Entry
  2590 00005AE1 668B4714            <1> 	mov	ax, [edi+DirEntry_FstClusHI] ; First Cluster High Word
  2591 00005AE5 C1E010              <1> 	shl	eax, 16
  2592 00005AE8 668B471A            <1> 	mov	ax, [edi+DirEntry_FstClusLO] ; First Cluster Low Word
  2593 00005AEC A3[FCB20000]        <1> 	mov	[Show_Cluster], eax
  2594 00005AF1 8B471C              <1> 	mov	eax, [edi+DirEntry_FileSize] ; File Size
  2595 00005AF4 21C0                <1> 	and	eax, eax ; Empty file !
  2596 00005AF6 0F8491000000        <1>         jz      end_of_show_file 
  2597 00005AFC A3[00B30000]        <1> 	mov	[Show_FileSize], eax
  2598 00005B01 31C0                <1> 	xor	eax, eax
  2599 00005B03 A3[04B30000]        <1> 	mov	[Show_FilePointer], eax ; 0
  2600 00005B08 66A3[08B30000]      <1> 	mov	[Show_ClusterPointer], ax ; 0
  2601 00005B0E 29DB                <1> 	sub	ebx, ebx
  2602 00005B10 8A3D[AEA80000]      <1> 	mov	bh, [Current_Drv]
  2603 00005B16 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2604 00005B1B 01DE                <1> 	add	esi, ebx
  2605 00005B1D 8935[F8B20000]      <1> 	mov	[Show_LDDDT], esi ; Logical DOS Drv Description Table addr
  2606                              <1> 
  2607 00005B23 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0	
  2608 00005B27 7713                <1> 	ja	short loc_show_calculate_cluster_size
  2609                              <1> 	; Singlix FS
  2610                              <1> 	; First Cluster Number is FDT number (in compatibility buffer)
  2611 00005B29 8B15[FCB20000]      <1> 	mov	edx, [Show_Cluster] ; Compatibility dir. buffer value (FDT)	
  2612 00005B2F 8915[F4B20000]      <1> 	mov	[Show_FDT], edx
  2613 00005B35 31C0                <1> 	xor	eax, eax
  2614 00005B37 A3[FCB20000]        <1> 	mov	[Show_Cluster], eax ; Sector index  = 0
  2615                              <1> 				    ; (next time it will be 1)			
  2616                              <1> loc_show_calculate_cluster_size:
  2617 00005B3C 668B5E11            <1> 	mov	bx, [esi+LD_BPB+BPB_BytsPerSec] ; FAT 12-16-32 (512)
  2618                              <1> 	; BX = 512 = [esi+LD_FS_BytesPerSec] ; Singlix FS	
  2619 00005B40 8A4613              <1> 	mov	al, [esi+LD_BPB+BPB_SecPerClust] ; FAT 12-16-32 (<= 128)
  2620                              <1> 	; AL = 1 = [esi+LD_FS_Reserved2] ; SectPerClust for Singlix FS
  2621 00005B43 F7E3                <1> 	mul	ebx	
  2622                              <1> 
  2623                              <1> 	;cmp	eax, 65536 ; non-compatible (very big) cluster size
  2624                              <1> 	;ja	short end_of_show_file	
  2625 00005B45 66A3[0AB30000]      <1> 	mov	[Show_ClusterSize], ax
  2626                              <1> 
  2627                              <1> loc_start_show_file:
  2628 00005B4B BE[C6A40000]        <1> 	mov	esi, nextline
  2629 00005B50 E8E5E0FFFF          <1> 	call	print_msg
  2630                              <1> 
  2631 00005B55 A1[FCB20000]        <1> 	mov	eax, [Show_Cluster]
  2632 00005B5A C605[0CB30000]17    <1> 	mov	byte [Show_RowCount], 23
  2633                              <1> 
  2634                              <1> 	; 17/02/2016
  2635 00005B61 8B35[F8B20000]      <1> 	mov	esi, [Show_LDDDT]
  2636                              <1> 
  2637                              <1> loc_show_next_cluster:
  2638                              <1> 	; 15/02/2016
  2639 00005B67 BB00000700          <1> 	mov	ebx, Cluster_Buffer ; 70000h (for current TRDOS 386 version)
  2640                              <1> 	; ESI = Logical DOS drv description table address
  2641 00005B6C E8A01D0000          <1> 	call	read_cluster
  2642                              <1> 	;jc	loc_file_rw_cmd_failed
  2643 00005B71 0F8279F8FFFF        <1> 	jc	loc_run_cmd_failed
  2644                              <1> 
  2645 00005B77 31DB                <1> 	xor 	ebx, ebx
  2646                              <1> loc_show_next_byte:
  2647 00005B79 803D[0CB30000]00    <1> 	cmp	byte [Show_RowCount], 0
  2648 00005B80 7521                <1> 	jne	short pass_show_wait_for_key
  2649 00005B82 30E4                <1> 	xor	ah, ah
  2650 00005B84 E85EB0FFFF          <1> 	call	int16h
  2651 00005B89 3C1B                <1> 	cmp	al, 1Bh
  2652 00005B8B 750F                <1> 	jne	short pass_exit_show
  2653                              <1> end_of_show_file:
  2654                              <1> pass_show_file:
  2655 00005B8D BE[C6A40000]        <1> 	mov	esi, nextline
  2656 00005B92 E8A3E0FFFF          <1> 	call	print_msg
  2657 00005B97 E949010000          <1> 	jmp	loc_file_rw_restore_retn
  2658                              <1> 
  2659                              <1> pass_exit_show:
  2660 00005B9C C605[0CB30000]14    <1> 	mov	byte [Show_RowCount], 20
  2661                              <1> pass_show_wait_for_key:
  2662 00005BA3 81C300000700        <1> 	add	ebx, Cluster_Buffer
  2663 00005BA9 8A03                <1> 	mov	al, [ebx]
  2664 00005BAB 0FB61D[18A80000]    <1> 	movzx	ebx, byte [ACTIVE_PAGE] ; [ptty]
  2665 00005BB2 3C0D                <1> 	cmp	al, 0Dh
  2666 00005BB4 0F858A000000        <1>         jne     loc_show_check_tab_space
  2667 00005BBA FE0D[0CB30000]      <1> 	dec	byte [Show_RowCount]
  2668                              <1> pass_show_dec_rowcount:
  2669 00005BC0 B407                <1> 	mov	ah, 7 ; (light gray character color, black background)
  2670 00005BC2 E8EFBBFFFF          <1> 	call	WRITE_TTY
  2671                              <1> loc_show_check_eof:
  2672 00005BC7 FF05[04B30000]      <1> 	inc	dword [Show_FilePointer]
  2673 00005BCD A1[04B30000]        <1> 	mov	eax, [Show_FilePointer]
  2674 00005BD2 3B05[00B30000]      <1> 	cmp	eax, [Show_FileSize]
  2675 00005BD8 73B3                <1> 	jnb	short end_of_show_file
  2676 00005BDA 66FF05[08B30000]    <1> 	inc	word [Show_ClusterPointer]
  2677 00005BE1 0FB71D[08B30000]    <1> 	movzx	ebx, word [Show_ClusterPointer]
  2678                              <1> 
  2679                              <1> 	; 17/02/2016
  2680                              <1> 	; (sector boundary -9 bits- check, 512 = 0)
  2681 00005BE8 66F7C3FF01          <1>         test    bx, 1FFh ;  1 to 511
  2682 00005BED 758A                <1> 	jnz	short loc_show_next_byte
  2683                              <1> 
  2684                              <1> 	; 16/02/2016
  2685 00005BEF 8B35[F8B20000]      <1> 	mov	esi, [Show_LDDDT]
  2686                              <1> 	;
  2687 00005BF5 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
  2688 00005BF9 7719                <1> 	ja	short loc_show_check_fat_cluster_size
  2689                              <1> 
  2690                              <1> 	; Singlix FS
  2691                              <1> 	; 1 sector, more... (cluster size = 1 sector)
  2692 00005BFB A1[FCB20000]        <1> 	mov	eax, [Show_Cluster]
  2693 00005C00 40                  <1> 	inc	eax
  2694 00005C01 A3[FCB20000]        <1> 	mov	[Show_Cluster], eax
  2695                              <1> 
  2696 00005C06 6621DB              <1> 	and	bx, bx ; 65536 -> 0
  2697 00005C09 0F856AFFFFFF        <1>         jnz	loc_show_next_byte
  2698 00005C0F E953FFFFFF          <1> 	jmp     loc_show_next_cluster
  2699                              <1> 	 
  2700                              <1> loc_show_check_fat_cluster_size:
  2701                              <1> 	; 17/02/2016
  2702 00005C14 663B1D[0AB30000]    <1> 	cmp	bx, [Show_ClusterSize] ; cluster size in bytes
  2703 00005C1B 0F8258FFFFFF        <1>         jb	loc_show_next_byte
  2704 00005C21 66C705[08B30000]00- <1> 	mov	word [Show_ClusterPointer], 0
  2704 00005C29 00                  <1>
  2705                              <1> 
  2706 00005C2A A1[FCB20000]        <1> 	mov	eax, [Show_Cluster]
  2707                              <1> 	;mov	esi, [Show_LDDDT]
  2708                              <1> loc_show_get_next_cluster:
  2709 00005C2F E8BE1A0000          <1> 	call	get_next_cluster
  2710                              <1> 	;jc	loc_file_rw_cmd_failed
  2711 00005C34 0F82B6F7FFFF        <1> 	jc	loc_run_cmd_failed
  2712                              <1> loc_show_update_ccluster:
  2713 00005C3A A3[FCB20000]        <1> 	mov	[Show_Cluster], eax			
  2714 00005C3F E923FFFFFF          <1>         jmp     loc_show_next_cluster
  2715                              <1> 
  2716                              <1> loc_show_check_tab_space:
  2717 00005C44 3C09                <1> 	cmp	al, 09h
  2718 00005C46 0F8574FFFFFF        <1>         jne     pass_show_dec_rowcount
  2719                              <1> loc_show_put_tab_space:
  2720                              <1> 	;movzx	ebx, byte [ACTIVE_PAGE] ; [ptty]
  2721 00005C4C E82BB9FFFF          <1> 	call	get_cpos
  2722                              <1> 	; dl = cursor column
  2723 00005C51 80E207              <1> 	and	dl, 7 ; 18/02/2016
  2724                              <1> loc_show_put_space_chars:
  2725                              <1> 	;mov	al, 20h ; space
  2726                              <1> 	;mov 	ah, 7	; color attribute
  2727 00005C54 66B82007            <1> 	mov	ax, 0720h ; 
  2728 00005C58 0FB61D[18A80000]    <1> 	movzx	ebx, byte [ACTIVE_PAGE] ; [ptty]
  2729 00005C5F 6652                <1> 	push	dx
  2730 00005C61 E850BBFFFF          <1> 	call	WRITE_TTY
  2731 00005C66 665A                <1> 	pop	dx
  2732                              <1> 	; 18/02/2016
  2733 00005C68 80FA07              <1> 	cmp	dl, 7
  2734 00005C6B 0F8356FFFFFF        <1> 	jnb	loc_show_check_eof
  2735 00005C71 FEC2                <1> 	inc	dl
  2736 00005C73 EBDF                <1> 	jmp	short loc_show_put_space_chars
  2737                              <1> 
  2738                              <1> check_filename:
  2739                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2740                              <1> 	; 07/08/2010 (FILE.ASM, 'proc_check_filename')
  2741                              <1> 	; 10/07/2010
  2742                              <1> 	; Derived from 'proc_check_filename'
  2743                              <1> 	; in the old TRDOS.ASM (09/02/2005).
  2744                              <1> 	;
  2745                              <1> 	; INPUT -> 
  2746                              <1> 	;	ESI = Dot File Name Location
  2747                              <1> 	; OUTPUT ->
  2748                              <1> 	;	cf = 1 -> error code in AL
  2749                              <1> 	;	     AL = 0Bh -> Invalid file name   
  2750                              <1> 	;	cf = 0 -> valid file name
  2751                              <1> 	; 
  2752                              <1> 	;(EAX, ECX, EDI will be changed)
  2753                              <1> 
  2754                              <1> check_invalid_filename_chars:
  2755                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2756                              <1> 	; 10/07/2010 (FILE.ASM, 'proc_check_invalid_filename_chars')
  2757                              <1> 	; 10/02/2010
  2758                              <1> 	; Derived from 'proc_check_invalid_filename_chars'
  2759                              <1> 	; in the old TRDOS.ASM (09/02/2005).
  2760                              <1> 	;
  2761                              <1> 	; INPUT -> 
  2762                              <1> 	;	ESI = ASCIIZ FileName
  2763                              <1> 	; OUTPUT ->
  2764                              <1> 	;	cf = 1 -> invalid
  2765                              <1> 	;	cf = 0 -> valid
  2766                              <1> 	; 
  2767                              <1> 	;(EAX, ECX, ESI, EDI will be changed)
  2768                              <1>   
  2769 00005C75 56                  <1> 	push	esi
  2770                              <1> 
  2771 00005C76 BF[859A0000]        <1>         mov     edi, invalid_fname_chars
  2772 00005C7B AC                  <1> 	lodsb
  2773                              <1> check_filename_next_char:
  2774 00005C7C B914000000          <1> 	mov	ecx, sizeInvFnChars
  2775 00005C81 BF[859A0000]        <1> 	mov	edi, invalid_fname_chars
  2776                              <1> loc_scan_invalid_filename_char:
  2777 00005C86 AE                  <1> 	scasb 
  2778 00005C87 741F                <1> 	je	short loc_invalid_filename_stc 
  2779 00005C89 E2FB                <1> 	loop	loc_scan_invalid_filename_char
  2780 00005C8B AC                  <1> 	lodsb
  2781 00005C8C 3C1F                <1> 	cmp	al, 1Fh  ; 20h and above 
  2782 00005C8E 77EC                <1> 	ja	short check_filename_next_char
  2783                              <1> 
  2784                              <1> check_filename_dot:
  2785 00005C90 8B3424              <1> 	mov	esi, [esp]
  2786                              <1> 
  2787 00005C93 B421                <1> 	mov	ah, 21h
  2788 00005C95 B908000000          <1> 	mov	ecx, 8
  2789                              <1> loc_check_filename_next_char:
  2790 00005C9A AC                  <1> 	lodsb
  2791 00005C9B 3C2E                <1> 	cmp	al, 2Eh
  2792 00005C9D 7511                <1> 	jne	short pass_check_fn_dot_check
  2793                              <1> loc_check_filename_ext_0:
  2794 00005C9F AC                  <1> 	lodsb
  2795 00005CA0 38E0                <1> 	cmp	al, ah ; 21h
  2796 00005CA2 7205                <1> 	jb	short loc_invalid_filename
  2797 00005CA4 3C2E                <1> 	cmp	al, 2Eh
  2798 00005CA6 7519                <1> 	jne	short loc_check_filename_ext_1
  2799                              <1> 
  2800                              <1> loc_invalid_filename_stc:
  2801                              <1> loc_check_fn_stc_rtn:
  2802 00005CA8 F9                  <1> 	stc
  2803                              <1> loc_invalid_filename:
  2804 00005CA9 B80B000000          <1> 	mov	eax, 0Bh ; Invalid format
  2805                              <1> 	; Invalid file name chars
  2806                              <1> loc_check_fn_rtn:
  2807 00005CAE 5E                  <1> 	pop	esi
  2808 00005CAF C3                  <1> 	retn
  2809                              <1> 
  2810                              <1> pass_check_fn_dot_check:
  2811 00005CB0 38E0                <1> 	cmp	al, ah ; 21h
  2812 00005CB2 7224                <1> 	jb	short loc_check_fn_clc_rtn
  2813 00005CB4 E2E4                <1> 	loop	loc_check_filename_next_char
  2814 00005CB6 AC                  <1> 	lodsb
  2815 00005CB7 38E0                <1> 	cmp	al, ah ; 21h
  2816 00005CB9 721D                <1> 	jb	short loc_check_fn_clc_rtn
  2817 00005CBB 3C2E                <1> 	cmp	al, 2Eh
  2818 00005CBD 75E9                <1> 	jne	short loc_check_fn_stc_rtn
  2819 00005CBF EBDE                <1> 	jmp	short loc_check_filename_ext_0
  2820                              <1> 
  2821                              <1> loc_check_filename_ext_1:
  2822 00005CC1 AC                  <1> 	lodsb
  2823 00005CC2 38E0                <1> 	cmp	al, ah ; 21h
  2824 00005CC4 7212                <1> 	jb	short loc_check_fn_clc_rtn
  2825 00005CC6 3C2E                <1> 	cmp	al, 2Eh
  2826 00005CC8 74DE                <1> 	je	short loc_check_fn_stc_rtn
  2827 00005CCA AC                  <1> 	lodsb
  2828 00005CCB 38E0                <1> 	cmp	al, ah ; 21h
  2829 00005CCD 7209                <1> 	jb	short loc_check_fn_clc_rtn
  2830 00005CCF 3C2E                <1> 	cmp	al, 2Eh
  2831 00005CD1 74D5                <1> 	je	short loc_check_fn_stc_rtn
  2832 00005CD3 AC                  <1> 	lodsb
  2833 00005CD4 38E0                <1> 	cmp	al, ah ; 21h
  2834 00005CD6 73D0                <1> 	jnb	short loc_check_fn_stc_rtn
  2835                              <1> 
  2836                              <1> loc_check_fn_clc_rtn:
  2837 00005CD8 5E                  <1> 	pop	esi
  2838 00005CD9 F8                  <1> 	clc
  2839 00005CDA C3                  <1> 	retn
  2840                              <1> 
  2841                              <1> loc_print_deleted_message:
  2842 00005CDB BE[6F9E0000]        <1> 	mov	esi, Msg_Deleted
  2843 00005CE0 E855DFFFFF          <1> 	call	print_msg
  2844                              <1> 
  2845                              <1> 	;clc
  2846                              <1> 
  2847                              <1> loc_file_rw_restore_retn:
  2848                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2849                              <1> 	; 28/02/2010 (CMD_INTR.ASM)
  2850                              <1> loc_file_rw_cmd_failed:
  2851 00005CE5 9C                  <1> 	pushf 
  2852 00005CE6 E85FF7FFFF          <1> 	call	restore_cdir_after_cmd_fail	
  2853 00005CEB 9D                  <1> 	popf
  2854 00005CEC 720D                <1> 	jc	short loc_file_rw_check_write_fault
  2855 00005CEE C3                  <1> 	retn
  2856                              <1> 
  2857                              <1> loc_permission_denied:
  2858                              <1> 	; 27/02/2016
  2859 00005CEF BE[7C9E0000]        <1> 	mov	esi, Msg_Permission_Denied
  2860 00005CF4 E841DFFFFF          <1> 	call	print_msg
  2861 00005CF9 EBEA                <1> 	jmp	short loc_file_rw_restore_retn
  2862                              <1> 
  2863                              <1> loc_file_rw_check_write_fault:
  2864 00005CFB 3C1D                <1> 	cmp	al, 1Dh ; Write Fault
  2865 00005CFD 0F85F2F6FFFF        <1>         jne     loc_run_cmd_failed_cmp_al
  2866 00005D03 BE[669C0000]        <1> 	mov	esi, Msg_Not_Ready_Write_Err
  2867                              <1> 	;call	print_msg
  2868                              <1> 	;retn
  2869 00005D08 E92DDFFFFF          <1> 	jmp	print_msg
  2870                              <1> 
  2871                              <1> make_directory:
  2872                              <1> 	; 21/02/2016 (TRDOS 386 =  TRDOS v2.0)
  2873                              <1> 	; 12/03/2011 (CMD_INTR.ASM, 'cmp_cmd_mkdir')
  2874                              <1> 	; 14/08/2010
  2875                              <1> 	; 10/07/2010
  2876                              <1> 	; 29/11/2009
  2877                              <1> 	;
  2878                              <1> get_mkdir_fchar:
  2879                              <1> 	; esi = directory name
  2880 00005D0D 803E20              <1> 	cmp	byte [esi], 20h
  2881 00005D10 7701                <1>         ja	short loc_mkdir_parse_path_name
  2882                              <1> 
  2883                              <1> loc_mkdir_nodirname_retn:
  2884 00005D12 C3                  <1> 	retn
  2885                              <1> 
  2886                              <1> loc_mkdir_parse_path_name:
  2887 00005D13 BF[52B20000]        <1> 	mov	edi, FindFile_Drv
  2888 00005D18 E817110000          <1>         call    parse_path_name
  2889 00005D1D 0F82A2F6FFFF        <1> 	jc	loc_cmd_failed
  2890                              <1> 
  2891                              <1> loc_mkdir_check_dirname_exists:
  2892 00005D23 BE[94B20000]        <1> 	mov	esi, FindFile_Name
  2893 00005D28 803E20              <1> 	cmp	byte [esi], 20h
  2894 00005D2B 0F8694F6FFFF        <1> 	jna	loc_cmd_failed
  2895 00005D31 8935[10B30000]      <1> 	mov	[DelFile_FNPointer], esi
  2896 00005D37 E839FFFFFF          <1> 	call	check_filename
  2897 00005D3C 7259                <1> 	jc	short loc_mkdir_invalid_dir_name_chars
  2898                              <1> 
  2899                              <1> loc_mkdir_drv:
  2900 00005D3E 8A35[AEA80000]      <1> 	mov	dh, [Current_Drv]
  2901 00005D44 8835[0EB10000]      <1> 	mov	[RUN_CDRV], dh
  2902                              <1> 	
  2903 00005D4A 8A15[52B20000]      <1> 	mov	dl, [FindFile_Drv]
  2904 00005D50 38F2                <1> 	cmp	dl, dh
  2905 00005D52 7407                <1> 	je	short loc_mkdir_change_directory
  2906                              <1> 
  2907 00005D54 E8E5E7FFFF          <1> 	call	change_current_drive
  2908 00005D59 728A                <1> 	jc	loc_file_rw_cmd_failed
  2909                              <1> 
  2910                              <1> loc_mkdir_change_directory:
  2911 00005D5B 803D[53B20000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  2912 00005D62 7614                <1> 	jna	short loc_mkdir_find_directory
  2913                              <1> 
  2914 00005D64 FE05[7D990000]      <1> 	inc	byte [Restore_CDIR]
  2915 00005D6A BE[53B20000]        <1> 	mov	esi, FindFile_Directory
  2916 00005D6F 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  2917 00005D71 E8AA0A0000          <1> 	call	change_current_directory
  2918 00005D76 722E                <1> 	jc	short loc_mkdir_check_error_code
  2919                              <1> 
  2920                              <1> ;loc_mkdir_change_prompt_dir_string:
  2921                              <1> 	;call	change_prompt_dir_string
  2922                              <1> 
  2923                              <1> loc_mkdir_find_directory:
  2924                              <1> 	;mov	esi, FindFile_Name
  2925 00005D78 8B35[10B30000]      <1> 	mov	esi, [DelFile_FNPointer]
  2926                              <1> 	;xor	eax, eax
  2927 00005D7E 6631C0              <1> 	xor	ax, ax ; any name (dir, file, volume)
  2928 00005D81 E83BFBFFFF          <1> 	call	find_first_file
  2929 00005D86 721E                <1> 	jc	short loc_mkdir_check_error_code
  2930                              <1> 
  2931                              <1> loc_mkdir_directory_found:
  2932 00005D88 BE[C79D0000]        <1> 	mov	esi, Msg_Name_Exists
  2933 00005D8D E8A8DEFFFF          <1> 	call	print_msg
  2934                              <1> 
  2935 00005D92 E94EFFFFFF          <1>         jmp     loc_file_rw_restore_retn
  2936                              <1> 
  2937                              <1> loc_mkdir_invalid_dir_name_chars:
  2938 00005D97 BE[9A9D0000]        <1> 	mov	esi, Msg_invalid_name_chars
  2939 00005D9C E899DEFFFF          <1> 	call	print_msg
  2940                              <1> 
  2941 00005DA1 E93FFFFFFF          <1>         jmp     loc_file_rw_restore_retn
  2942                              <1> 
  2943                              <1> loc_mkdir_check_error_code:
  2944 00005DA6 3C02                <1> 	cmp	al, 2
  2945                              <1> 	;je	short loc_mkdir_directory_not_found
  2946 00005DA8 7406                <1> 	je	short loc_mkdir_ask_for_yes_no
  2947 00005DAA F9                  <1> 	stc
  2948 00005DAB E935FFFFFF          <1>         jmp     loc_file_rw_cmd_failed
  2949                              <1> 
  2950                              <1> loc_mkdir_directory_not_found:
  2951                              <1> loc_mkdir_ask_for_yes_no:
  2952 00005DB0 BE[E89D0000]        <1> 	mov	esi, Msg_DoYouWantMkdir
  2953 00005DB5 E880DEFFFF          <1> 	call	print_msg
  2954 00005DBA 8B35[10B30000]      <1> 	mov	esi, [DelFile_FNPointer]
  2955 00005DC0 E875DEFFFF          <1> 	call	print_msg
  2956 00005DC5 BE[079E0000]        <1> 	mov	esi, Msg_YesNo
  2957 00005DCA E86BDEFFFF          <1> 	call	print_msg
  2958                              <1> 
  2959 00005DCF C605[119E0000]20    <1> 	mov	byte [Y_N_nextline], 20h
  2960                              <1> 
  2961                              <1> loc_mkdir_ask_again:
  2962 00005DD6 30E4                <1> 	xor	ah, ah
  2963 00005DD8 E80AAEFFFF          <1> 	call	int16h
  2964 00005DDD 3C1B                <1> 	cmp	al, 1Bh
  2965                              <1> 	;je	short loc_do_not_make_directory
  2966 00005DDF 7447                <1> 	je	short loc_mkdir_y_n_escape
  2967 00005DE1 24DF                <1> 	and	al, 0DFh ; y -> Y, n -> N
  2968 00005DE3 3C59                <1> 	cmp	al, 'Y' ; 'yes'
  2969 00005DE5 7404                <1> 	je	short loc_mkdir_yes_make_directory
  2970 00005DE7 3C4E                <1> 	cmp	al, 'N' ; 'no'
  2971 00005DE9 75EB                <1> 	jne	short loc_mkdir_ask_again
  2972                              <1> 
  2973                              <1> loc_do_not_make_directory:
  2974                              <1> loc_mkdir_yes_make_directory:
  2975 00005DEB A2[119E0000]        <1> 	mov	[Y_N_nextline], al
  2976 00005DF0 6650                <1> 	push	ax
  2977 00005DF2 BE[119E0000]        <1> 	mov	esi, Y_N_nextline
  2978 00005DF7 E83EDEFFFF          <1> 	call	print_msg
  2979 00005DFC 6658                <1> 	pop	ax
  2980                              <1> 	;cmp	al, 'Y' ; 'yes'
  2981                              <1> 	;cmc
  2982                              <1>         ;jnc	loc_file_rw_restore_retn
  2983 00005DFE 3C4E                <1> 	cmp	al, 'N' ; 'no'
  2984 00005E00 0F84DFFEFFFF        <1>         je	loc_file_rw_restore_retn  
  2985                              <1> 
  2986                              <1> loc_mkdir_call_make_sub_directory:
  2987 00005E06 8B35[10B30000]      <1> 	mov	esi, [DelFile_FNPointer]
  2988 00005E0C B110                <1> 	mov	cl, 10h ; Directory attributes 
  2989 00005E0E E820110000          <1> 	call	make_sub_directory
  2990                              <1> loc_rename_file_ok: ; 06/03/2016
  2991 00005E13 0F82CCFEFFFF        <1>         jc	loc_file_rw_cmd_failed
  2992                              <1> 
  2993 00005E19 BE[159E0000]        <1> 	mov	esi, Msg_OK
  2994 00005E1E E817DEFFFF          <1> 	call	print_msg
  2995 00005E23 E9BDFEFFFF          <1> 	jmp	loc_file_rw_restore_retn
  2996                              <1> 
  2997                              <1> loc_mkdir_y_n_escape:
  2998 00005E28 B04E                <1> 	mov	al, 'N' ; 'no'
  2999 00005E2A EBBF                <1> 	jmp	short loc_do_not_make_directory
  3000                              <1> 
  3001                              <1> delete_directory:
  3002                              <1> 	; 06/03/2016
  3003                              <1> 	; 01/03/2016
  3004                              <1> 	; 29/02/2016
  3005                              <1> 	; 28/02/2016
  3006                              <1> 	; 27/02/2016
  3007                              <1> 	; 26/02/2016 (TRDOS 386 =  TRDOS v2.0)
  3008                              <1> 	; 16/10/2010 (CMD_INTR.ASM, 'cmp_cmd_rmdir')
  3009                              <1> 	; 05/06/2010
  3010                              <1> 	;
  3011                              <1> get_rmdir_fchar:
  3012                              <1> 	; esi = directory name
  3013 00005E2C 803E20              <1> 	cmp	byte [esi], 20h
  3014 00005E2F 7701                <1>         ja	short loc_rmdir_parse_path_name
  3015                              <1> 
  3016                              <1> loc_rmdir_nodirname_retn:
  3017 00005E31 C3                  <1> 	retn
  3018                              <1> 
  3019                              <1> loc_rmdir_parse_path_name:
  3020 00005E32 BF[52B20000]        <1> 	mov	edi, FindFile_Drv
  3021 00005E37 E8F80F0000          <1> 	call	parse_path_name
  3022 00005E3C 0F8283F5FFFF        <1> 	jc	loc_cmd_failed
  3023                              <1> 
  3024                              <1> loc_rmdir_check_dirname_exists:
  3025 00005E42 BE[94B20000]        <1> 	mov	esi, FindFile_Name
  3026 00005E47 803E20              <1> 	cmp	byte [esi], 20h
  3027 00005E4A 0F8675F5FFFF        <1> 	jna	loc_cmd_failed
  3028 00005E50 8935[10B30000]      <1> 	mov	[DelFile_FNPointer], esi 
  3029                              <1> 
  3030                              <1> loc_rmdir_drv:
  3031 00005E56 8A35[AEA80000]      <1> 	mov	dh, [Current_Drv]
  3032 00005E5C 8835[0EB10000]      <1> 	mov	[RUN_CDRV], dh
  3033                              <1> 
  3034 00005E62 8A15[52B20000]      <1> 	mov	dl, [FindFile_Drv]
  3035 00005E68 38F2                <1> 	cmp	dl, dh
  3036 00005E6A 740B                <1> 	je	short loc_rmdir_change_directory
  3037                              <1> 
  3038 00005E6C E8CDE6FFFF          <1> 	call	change_current_drive
  3039 00005E71 0F826EFEFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3040                              <1> 
  3041                              <1> loc_rmdir_change_directory:
  3042 00005E77 803D[53B20000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3043 00005E7E 7614                <1> 	jna	short loc_rmdir_find_directory
  3044                              <1> 
  3045 00005E80 FE05[7D990000]      <1> 	inc	byte [Restore_CDIR]
  3046 00005E86 BE[53B20000]        <1> 	mov	esi, FindFile_Directory
  3047 00005E8B 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3048 00005E8D E88E090000          <1> 	call	change_current_directory
  3049 00005E92 7211                <1> 	jc	short loc_rmdir_check_error_code
  3050                              <1> 
  3051                              <1> ;loc_rmdir_change_prompt_dir_string:
  3052                              <1> 	;call	change_prompt_dir_string
  3053                              <1> 
  3054                              <1> loc_rmdir_find_directory:
  3055                              <1> 	;mov	esi, FindFile_Name
  3056 00005E94 8B35[10B30000]      <1> 	mov	esi, [DelFile_FNPointer]
  3057 00005E9A 66B81008            <1> 	mov	ax, 0810h ; Only directories
  3058 00005E9E E81EFAFFFF          <1> 	call	find_first_file
  3059 00005EA3 730A                <1> 	jnc	short loc_rmdir_ambgfn_check
  3060                              <1> 
  3061                              <1> loc_rmdir_check_error_code:
  3062 00005EA5 3C02                <1> 	cmp	al, 2
  3063 00005EA7 740B                <1> 	je	short loc_rmdir_directory_not_found
  3064 00005EA9 F9                  <1> 	stc
  3065 00005EAA E936FEFFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3066                              <1> 
  3067                              <1> loc_rmdir_ambgfn_check:
  3068 00005EAF 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3069 00005EB2 740F                <1> 	jz	short loc_rmdir_directory_found
  3070                              <1> 
  3071                              <1> loc_rmdir_directory_not_found:
  3072 00005EB4 BE[889C0000]        <1> 	mov	esi, Msg_Dir_Not_Found
  3073 00005EB9 E87CDDFFFF          <1> 	call	print_msg
  3074                              <1> 
  3075 00005EBE E922FEFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3076                              <1> 
  3077                              <1> loc_rmdir_directory_found:
  3078 00005EC3 80E307              <1> 	and	bl, 07h ; Attributes
  3079 00005EC6 0F8523FEFFFF        <1> 	jnz	loc_permission_denied
  3080                              <1> 
  3081                              <1> loc_rmdir_save_lnel: ; 28/02/2016
  3082                              <1>        ;mov	bh, [LongName_EntryLength]
  3083 00005ECC 883D[1AB30000]      <1> 	mov	[DelFile_LNEL], bh ; Long name entry length (if > 0)
  3084                              <1> 	; edi = Directory Entry Offset (DirBuff)
  3085                              <1> 	; esi = Directory Entry (FFF Structure)
  3086                              <1> 	;mov	[DelFile_DirEntryAddr], edi ; not required
  3087                              <1> 	;mov	ax, [edi+20] ; First Cluster High Word
  3088                              <1>         ;shl	eax, 16
  3089                              <1> 	;mov	ax, [edi+26] ; First Cluster Low Word
  3090                              <1> 	; ROOT Dir First Cluster = 0
  3091                              <1>         ;cmp	eax, 2
  3092                              <1> 	;jb	loc_update_direntry_1
  3093                              <1> 
  3094                              <1> pass_rmdir_fc_check:
  3095 00005ED2 57                  <1> 	push	edi ; * (29/02/2016)
  3096                              <1> 
  3097 00005ED3 BE[1B9E0000]        <1> 	mov	esi, Msg_DoYouWantRmDir
  3098 00005ED8 E85DDDFFFF          <1> 	call	print_msg
  3099 00005EDD 8B35[10B30000]      <1> 	mov	esi, [DelFile_FNPointer]
  3100 00005EE3 E852DDFFFF          <1> 	call	print_msg
  3101 00005EE8 BE[079E0000]        <1> 	mov	esi, Msg_YesNo
  3102 00005EED E848DDFFFF          <1> 	call	print_msg
  3103                              <1> 
  3104                              <1> loc_rmdir_ask_again:
  3105 00005EF2 30E4                <1> 	xor	ah, ah
  3106 00005EF4 E8EEACFFFF          <1> 	call	int16h
  3107 00005EF9 3C1B                <1> 	cmp	al, 1Bh
  3108                              <1> 	;je	short loc_do_not_delete_directory
  3109 00005EFB 0F8498000000        <1>         je      loc_rmdir_y_n_escape ; 06/03/2016
  3110 00005F01 24DF                <1> 	and	al, 0DFh
  3111 00005F03 A2[119E0000]        <1> 	mov	[Y_N_nextline], al
  3112 00005F08 3C59                <1> 	cmp	al, 'Y'
  3113 00005F0A 7404                <1> 	je	short loc_rmdir_yes_delete_directory
  3114 00005F0C 3C4E                <1> 	cmp	al, 'N'
  3115 00005F0E 75E2                <1> 	jne	short loc_rmdir_ask_again
  3116                              <1> 
  3117                              <1> loc_do_not_delete_directory:
  3118                              <1> loc_rmdir_yes_delete_directory:
  3119 00005F10 A2[119E0000]        <1> 	mov	[Y_N_nextline], al
  3120 00005F15 6650                <1> 	push	ax
  3121 00005F17 BE[119E0000]        <1> 	mov	esi, Y_N_nextline
  3122 00005F1C E819DDFFFF          <1> 	call	print_msg
  3123 00005F21 6658                <1> 	pop	ax
  3124 00005F23 5F                  <1> 	pop	edi ; * (29/02/2016)
  3125                              <1> 	;cmp	al, 'Y' ; 'yes'
  3126                              <1> 	;cmc
  3127                              <1>         ;jnc	loc_file_rw_restore_retn
  3128 00005F24 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3129 00005F26 0F84B9FDFFFF        <1>         je	loc_file_rw_restore_retn  
  3130                              <1> 
  3131                              <1> loc_rmdir_delete_short_name_check_dir_empty:
  3132                              <1> 	; EDI = Directory buffer entry offset/address 
  3133 00005F2C 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  3134 00005F30 C1E010              <1>         shl	eax, 16
  3135 00005F33 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  3136                              <1> 
  3137 00005F37 A3[14B30000]        <1> 	mov 	[DelFile_FCluster], eax
  3138                              <1> 
  3139                              <1> 	;mov	bx, [DirBuff_EntryCounter]
  3140 00005F3C 668B1D[CCB20000]    <1> 	mov	bx, [FindFile_DirEntryNumber] ; 27/02/2016
  3141 00005F43 66891D[18B30000]    <1> 	mov	[DelFile_EntryCounter], bx
  3142                              <1> 
  3143 00005F4A 29DB                <1>     	sub	ebx, ebx
  3144 00005F4C 8A3D[52B20000]      <1> 	mov	bh, [FindFile_Drv]
  3145 00005F52 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3146 00005F57 01DE                <1> 	add	esi, ebx
  3147                              <1> 
  3148 00005F59 66817F0CA101        <1> 	cmp	word [edi+DirEntry_NTRes], 01A1h
  3149 00005F5F 743F                <1> 	je	short loc_rmdir_delete_fs_directory
  3150                              <1> 
  3151                              <1> 	;cmp	byte [esi+LD_FATType], 1
  3152                              <1> 	;jnb	short loc_rmdir_get__last_cluster_0
  3153                              <1> 	;mov	eax, 0Bh ; Invalid Format
  3154                              <1> 	;jmp	loc_file_rw_cmd_failed
  3155                              <1>   
  3156                              <1> ;loc_rmdir_get_last_cluster_0:
  3157 00005F61 8B15[DDB00000]      <1> 	mov	edx, [DirBuff_Cluster]
  3158 00005F67 8915[44B30000]      <1> 	mov	[RmDir_ParentDirCluster], edx
  3159                              <1> 
  3160 00005F6D 893D[40B30000]      <1> 	mov	[RmDir_DirEntryOffset], edi
  3161                              <1> 
  3162                              <1> 	; 01/03/2016
  3163 00005F73 C705[CDB00000]0000- <1> 	mov	dword [FAT_ClusterCounter], 0 ; Reset
  3163 00005F7B 0000                <1>
  3164                              <1> 
  3165                              <1> loc_rmdir_get_last_cluster:
  3166 00005F7D E84C1F0000          <1> 	call	get_last_cluster
  3167 00005F82 0F82B8000000        <1>         jc      loc_rmdir_cmd_failed
  3168                              <1> 	
  3169 00005F88 3B05[14B30000]      <1> 	cmp	eax, [DelFile_FCluster]
  3170 00005F8E 752F                <1> 	jne	short loc_rmdir_multi_dir_clusters
  3171                              <1> 
  3172 00005F90 C605[3FB30000]00    <1> 	mov	byte [RmDir_MultiClusters], 0
  3173 00005F97 EB2D                <1> 	jmp	short pass_rmdir_multi_dir_clusters
  3174                              <1> 
  3175                              <1> loc_rmdir_y_n_escape:
  3176 00005F99 B04E                <1> 	mov	al, 'N' ; 'no'
  3177 00005F9B E970FFFFFF          <1>         jmp     loc_do_not_delete_directory
  3178                              <1> 
  3179                              <1> loc_rmdir_delete_fs_directory:
  3180 00005FA0 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  3181 00005FA4 0F8545FDFFFF        <1> 	jne	loc_permission_denied
  3182                              <1> 
  3183 00005FAA E88D070000          <1> 	call	delete_fs_directory
  3184 00005FAF 0F8326FDFFFF        <1> 	jnc	loc_print_deleted_message
  3185                              <1> 
  3186 00005FB5 09C0                <1> 	or	eax, eax
  3187 00005FB7 745D                <1> 	jz	loc_rmdir_directory_not_empty_2         
  3188 00005FB9 F9                  <1> 	stc
  3189 00005FBA E926FDFFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3190                              <1>  
  3191                              <1> loc_rmdir_multi_dir_clusters:
  3192 00005FBF C605[3FB30000]01    <1> 	mov	byte [RmDir_MultiClusters], 1
  3193                              <1> 
  3194                              <1> pass_rmdir_multi_dir_clusters:
  3195 00005FC6 A3[48B30000]        <1> 	mov 	[RmDir_DirLastCluster], eax
  3196 00005FCB 890D[4CB30000]      <1> 	mov	[RmDir_PreviousCluster], ecx
  3197                              <1> 
  3198                              <1> loc_rmdir_load_fat_sub_directory:
  3199 00005FD1 E8FD180000          <1> 	call	load_FAT_sub_directory
  3200 00005FD6 7268                <1> 	jc	loc_rmdir_cmd_failed
  3201                              <1> 
  3202                              <1> loc_rmdir_find_last_dir_entry:
  3203 00005FD8 56                  <1> 	push	esi
  3204 00005FD9 BE[36B20000]        <1> 	mov	esi, Dir_File_Name
  3205 00005FDE C6062A              <1> 	mov	byte [esi], '*'
  3206 00005FE1 C646082A            <1> 	mov	byte [esi+8], '*'
  3207 00005FE5 31DB                <1> 	xor	ebx, ebx ; Entry offset  = 0
  3208                              <1> loc_rmdir_find_last_dir_entry_next:
  3209 00005FE7 66B80008            <1> 	mov	ax, 0800h ; Except volume/long names
  3210 00005FEB 6631C9              <1> 	xor	cx, cx ; 0 = Find a valid file or dir name
  3211 00005FEE E8830B0000          <1> 	call	find_directory_entry
  3212 00005FF3 7271                <1> 	jc	short loc_rmdir_empty_dir_cluster
  3213 00005FF5 83FB01              <1> 	cmp	ebx, 1
  3214 00005FF8 771B                <1> 	ja	short loc_rmdir_directory_not_empty_1
  3215                              <1> loc_rmdir_dot_entry_check:
  3216 00005FFA 80FD2E              <1> 	cmp	ch, '.' ; The first char of the dir entry
  3217 00005FFD 7516                <1> 	jne	short loc_rmdir_directory_not_empty_1
  3218 00005FFF 08DB                <1> 	or	bl, bl
  3219 00006001 7506                <1> 	jnz	short loc_rmdir_dotdot_entry_check
  3220 00006003 807F0120            <1> 	cmp	byte [edi+1], 20h
  3221 00006007 EB06                <1> 	jmp	short pass_rmdir_dot_entry_check
  3222                              <1> 
  3223                              <1> loc_rmdir_dotdot_entry_check:
  3224 00006009 66817F012E20        <1> 	cmp	word [edi+1], '. '
  3225                              <1> pass_rmdir_dot_entry_check:	
  3226 0000600F 7504                <1> 	jne	short loc_rmdir_directory_not_empty_1 
  3227 00006011 FEC3                <1> 	inc	bl
  3228 00006013 EBD2                <1> 	jmp	short loc_rmdir_find_last_dir_entry_next 
  3229                              <1> 
  3230                              <1> 
  3231                              <1> loc_rmdir_directory_not_empty_1:
  3232 00006015 58                  <1> 	pop	eax ; pushed esi 
  3233                              <1> 
  3234                              <1> loc_rmdir_directory_not_empty_2:
  3235 00006016 BE[3C9E0000]        <1> 	mov	esi, Msg_Dir_Not_Empty
  3236 0000601B E81ADCFFFF          <1> 	call	print_msg
  3237                              <1> 	; 01/03/2016
  3238 00006020 A1[CDB00000]        <1> 	mov	eax, [FAT_ClusterCounter]
  3239 00006025 09C0                <1> 	or	eax, eax ; 0 ?
  3240 00006027 0F84B8FCFFFF        <1> 	jz	loc_file_rw_restore_retn
  3241                              <1> 	; ESI = Logical DOS Drive Description Table address	
  3242                              <1> 
  3243 0000602D 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> use ESI for Drive parameters
  3244                              <1> 	           ; BL = 1 -> add free clusters
  3245 00006031 E8211D0000          <1> 	call	calculate_fat_freespace
  3246 00006036 09C9                <1> 	or	ecx, ecx
  3247 00006038 0F84A7FCFFFF        <1>         jz      loc_file_rw_restore_retn ; ecx = 0 -> OK
  3248                              <1> 	; ecx > 0 -> Error (Recalculation is neeeded)
  3249 0000603E EB0E                <1> 	jmp	short loc_rmdir_cmd_return
  3250                              <1> 
  3251                              <1> 
  3252                              <1> loc_rmdir_cmd_failed:
  3253 00006040 833D[CDB00000]01    <1> 	cmp	dword [FAT_ClusterCounter], 1
  3254 00006047 0F8298FCFFFF        <1> 	jb	loc_file_rw_cmd_failed	
  3255 0000604D F9                  <1> 	stc
  3256                              <1> loc_rmdir_cmd_return:
  3257                              <1> 	; 01/03/2016
  3258 0000604E 9C                  <1> 	pushf
  3259                              <1> 	; ESI = Logical DOS Drive Description Table address	
  3260 0000604F 66BB00FF            <1> 	mov	bx, 0FF00h ; BH = FFh -> use ESI for Drive parameters
  3261                              <1> 	           ; BL = 0 -> Recalculate free cluster count
  3262 00006053 50                  <1> 	push	eax
  3263 00006054 E8FE1C0000          <1> 	call	calculate_fat_freespace	
  3264 00006059 58                  <1> 	pop	eax
  3265 0000605A 9D                  <1> 	popf
  3266 0000605B 0F8284FCFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3267 00006061 E97FFCFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3268                              <1> 
  3269                              <1> 
  3270                              <1> loc_rmdir_empty_dir_cluster:
  3271 00006066 5E                  <1> 	pop	esi
  3272                              <1> 
  3273                              <1> loc_rmdir_set_prev_cluster_dir_last_cluster:
  3274 00006067 803D[3FB30000]00    <1> 	cmp	byte [RmDir_MultiClusters], 0
  3275 0000606E 761D                <1> 	jna	short loc_rmdir_unlink_dir_last_cluster
  3276                              <1> 
  3277 00006070 A1[4CB30000]        <1> 	mov	eax, [RmDir_PreviousCluster]
  3278                              <1> 	;xor	ecx, ecx
  3279 00006075 49                  <1> 	dec	ecx ; FFFFFFFFh
  3280 00006076 E893190000          <1> 	call	update_cluster
  3281 0000607B 7310                <1> 	jnc	short loc_rmdir_unlink_dir_last_cluster
  3282                              <1> 
  3283                              <1> loc_rmdir_unlink_stc_retn:
  3284                              <1> 	; 01/03/2016
  3285 0000607D 83F801              <1> 	cmp	eax, 1  ; eax = 0 -> end of cluster chain
  3286 00006080 F5                  <1> 	cmc 
  3287 00006081 72BD                <1> 	jc	short loc_rmdir_cmd_failed
  3288 00006083 EB1D                <1> 	jmp	short loc_rmdir_save_fat_buffer 
  3289                              <1> 	
  3290                              <1> loc_rmdir_unlink_stc_retn_0Bh:
  3291 00006085 B80B000000          <1> 	mov	eax, 0Bh ; Invalid format
  3292 0000608A F9                  <1> 	stc
  3293 0000608B EBB3                <1> 	jmp	short loc_rmdir_cmd_failed
  3294                              <1>  
  3295                              <1> loc_rmdir_unlink_dir_last_cluster:
  3296 0000608D A1[48B30000]        <1> 	mov	eax, [RmDir_DirLastCluster]
  3297 00006092 31C9                <1> 	xor	ecx, ecx ; 0
  3298 00006094 E875190000          <1> 	call	update_cluster
  3299 00006099 73EA                <1> 	jnc	short loc_rmdir_unlink_stc_retn_0Bh
  3300                              <1> 	; Because of it is the last cluster
  3301                              <1> 	; 'update_cluster' must return with eocc error 
  3302 0000609B 09C0                <1> 	or	eax, eax
  3303 0000609D 7403                <1> 	jz	short loc_rmdir_save_fat_buffer ; eocc	
  3304 0000609F F9                  <1> 	stc
  3305 000060A0 EB9E                <1>         jmp     short loc_rmdir_cmd_failed
  3306                              <1> 	 
  3307                              <1> loc_rmdir_save_fat_buffer:
  3308 000060A2 803D[C5B00000]02    <1> 	cmp	byte [FAT_BuffValidData], 2
  3309 000060A9 7525                <1> 	jne	short loc_rmdir_calculate_FAT_freespace
  3310 000060AB E8171C0000          <1> 	call	save_fat_buffer
  3311 000060B0 728E                <1> 	jc	short loc_rmdir_cmd_failed
  3312                              <1> 
  3313                              <1> 	; 01/03/2016
  3314 000060B2 803D[3FB30000]00    <1> 	cmp	byte [RmDir_MultiClusters], 0
  3315 000060B9 7615                <1> 	jna	short loc_rmdir_calculate_FAT_freespace
  3316                              <1> 
  3317 000060BB A1[14B30000]        <1> 	mov	eax, [DelFile_FCluster]
  3318 000060C0 E9B8FEFFFF          <1>         jmp     loc_rmdir_get_last_cluster
  3319                              <1> 
  3320                              <1> loc_rmdir_delete_short_name_invalid_data:
  3321 000060C5 B80D000000          <1> 	mov	eax, 0Dh ; Invalid data
  3322 000060CA F9                  <1> 	stc
  3323 000060CB E970FFFFFF          <1>         jmp     loc_rmdir_cmd_failed
  3324                              <1> 
  3325                              <1> loc_rmdir_calculate_FAT_freespace:
  3326 000060D0 A1[CDB00000]        <1> 	mov	eax, [FAT_ClusterCounter]
  3327 000060D5 66BB01FF            <1> 	mov	bx, 0FF01h
  3328                              <1> 	; BL = 1 -> Add EAX to free space count
  3329                              <1> 	; BH = FFh ->
  3330                              <1> 	; ESI = Logical DOS Drive Description Table address
  3331 000060D9 E8791C0000          <1> 	call	calculate_fat_freespace
  3332                              <1> 
  3333 000060DE 21C9                <1> 	and	ecx, ecx ; ecx = 0 -> valid free sector count
  3334 000060E0 7409                <1> 	jz 	short loc_rmdir_delete_short_name_continue
  3335                              <1> 
  3336                              <1> loc_rmdir_recalculate_FAT_freespace:
  3337 000060E2 66BB00FF            <1>         mov     bx, 0FF00h ; BL = 0 -> Recalculate free space
  3338 000060E6 E86C1C0000          <1> 	call	calculate_fat_freespace
  3339                              <1> 	          
  3340                              <1> loc_rmdir_delete_short_name_continue:
  3341 000060EB A1[44B30000]        <1> 	mov	eax, [RmDir_ParentDirCluster]
  3342 000060F0 83F802              <1> 	cmp	eax, 2
  3343 000060F3 730D                <1> 	jnb	short loc_rmdir_del_short_name_load_sub_dir
  3344 000060F5 E84E170000          <1> 	call	load_FAT_root_directory
  3345 000060FA 0F82E5FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3346 00006100 EB0B                <1> 	jmp	short loc_rmdir_del_short_name_ld_chk_fclust
  3347                              <1> 
  3348                              <1> loc_rmdir_del_short_name_load_sub_dir:	
  3349 00006102 E8CC170000          <1> 	call	load_FAT_sub_directory
  3350 00006107 0F82D8FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3351                              <1> 
  3352                              <1> loc_rmdir_del_short_name_ld_chk_fclust:
  3353 0000610D 0FB73D[40B30000]    <1> 	movzx	edi, word [RmDir_DirEntryOffset]
  3354 00006114 81C700000800        <1> 	add	edi, Directory_Buffer
  3355                              <1> 
  3356 0000611A 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  3357 0000611E C1E010              <1> 	shl	eax, 16
  3358 00006121 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  3359                              <1>         ; Not necessary... 
  3360 00006125 3B05[14B30000]      <1> 	cmp	eax, [DelFile_FCluster]
  3361 0000612B 7598                <1> 	jne	short loc_rmdir_delete_short_name_invalid_data
  3362                              <1> 	;
  3363 0000612D C607E5              <1> 	mov	byte [edi], 0E5h ; 'Deleted' sign
  3364                              <1> 	; 27/02/2016
  3365                              <1> 	; TRDOS v1 has a bug here! it does not set
  3366                              <1> 	; 'DirBuff_ValidData' to 2; as result of this bug,
  3367                              <1> 	; 'save_directory_buffer' would not save the change ! 
  3368 00006130 C605[D8B00000]02    <1>   	mov	byte [DirBuff_ValidData], 2 ; change sign
  3369                              <1> 	;
  3370 00006137 E85C110000          <1> 	call	save_directory_buffer
  3371 0000613C 0F82A3FBFFFF        <1> 	jc	loc_file_rw_cmd_failed 
  3372                              <1> 
  3373                              <1> loc_rmdir_del_long_name:
  3374 00006142 0FB615[1AB30000]    <1> 	movzx	edx, byte [DelFile_LNEL]
  3375 00006149 08D2                <1> 	or	dl, dl
  3376 0000614B 7414                <1> 	jz	short loc_rmdir_update_parent_dir_lmdt
  3377                              <1>              
  3378 0000614D 0FB705[18B30000]    <1> 	movzx	eax, word [DelFile_EntryCounter]
  3379 00006154 29D0                <1> 	sub	eax, edx
  3380 00006156 0F8289FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3381                              <1>  
  3382                              <1>  	; EAX = Directory Entry Number of the long name last entry
  3383 0000615C E890120000          <1> 	call	delete_longname
  3384                              <1> 	;jc	short loc_file_rw_cmd_failed
  3385                              <1> 
  3386                              <1> loc_rmdir_update_parent_dir_lmdt:
  3387 00006161 E8C6110000          <1> 	call	update_parent_dir_lmdt
  3388                              <1> 	;jc	short loc_file_rw_cmd_failed
  3389                              <1> 
  3390                              <1> loc_rmdir_ok:
  3391 00006166 BE[159E0000]        <1> 	mov	esi, Msg_OK
  3392 0000616B E8CADAFFFF          <1> 	call	print_msg
  3393 00006170 E970FBFFFF          <1> 	jmp	loc_file_rw_restore_retn
  3394                              <1> 
  3395                              <1> 
  3396                              <1> delete_file:
  3397                              <1> 	; 29/02/2016
  3398                              <1> 	; 28/02/2016 (TRDOS 386 =  TRDOS v2.0)
  3399                              <1> 	; 09/08/2010 (CMD_INTR.ASM, 'cmp_cmd_del')
  3400                              <1> 	; 28/02/2010
  3401                              <1> 
  3402                              <1> get_delfile_fchar:
  3403                              <1> 	; esi = file name
  3404 00006175 803E20              <1> 	cmp	byte [esi], 20h
  3405 00006178 7701                <1>         ja	short loc_delfile_parse_path_name
  3406                              <1> 
  3407                              <1> loc_delfile_nofilename_retn:
  3408 0000617A C3                  <1> 	retn
  3409                              <1> 
  3410                              <1> loc_delfile_parse_path_name:
  3411 0000617B BF[52B20000]        <1> 	mov	edi, FindFile_Drv
  3412 00006180 E8AF0C0000          <1> 	call	parse_path_name
  3413 00006185 0F823AF2FFFF        <1> 	jc	loc_cmd_failed
  3414                              <1> 
  3415                              <1> loc_delfile_check_filename_exists:
  3416 0000618B BE[94B20000]        <1> 	mov	esi, FindFile_Name
  3417 00006190 803E20              <1> 	cmp	byte [esi], 20h
  3418 00006193 0F862CF2FFFF        <1> 	jna	loc_cmd_failed
  3419 00006199 8935[10B30000]      <1> 	mov	[DelFile_FNPointer], esi 
  3420                              <1> 
  3421                              <1> loc_delfile_drv:
  3422 0000619F 8A15[52B20000]      <1> 	mov	dl, [FindFile_Drv]
  3423 000061A5 8A35[AEA80000]      <1> 	mov	dh, [Current_Drv]
  3424 000061AB 8835[0EB10000]      <1> 	mov	[RUN_CDRV], dh
  3425 000061B1 38F2                <1> 	cmp	dl, dh
  3426 000061B3 740B                <1> 	je	short loc_delfile_change_directory
  3427                              <1> 
  3428 000061B5 E884E3FFFF          <1> 	call	change_current_drive
  3429 000061BA 0F8225FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3430                              <1> 
  3431                              <1> loc_delfile_change_directory:
  3432 000061C0 803D[53B20000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3433 000061C7 7618                <1> 	jna	short loc_delfile_find
  3434                              <1> 
  3435 000061C9 FE05[7D990000]      <1> 	inc	byte [Restore_CDIR]
  3436 000061CF BE[53B20000]        <1> 	mov	esi, FindFile_Directory
  3437 000061D4 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3438 000061D6 E845060000          <1> 	call	change_current_directory
  3439 000061DB 0F8204FBFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3440                              <1> 
  3441                              <1> ;loc_delfile_change_prompt_dir_string:
  3442                              <1> 	;call	change_prompt_dir_string
  3443                              <1> 
  3444                              <1> loc_delfile_find:
  3445                              <1> 	;mov	esi, FindFile_Name
  3446 000061E1 8B35[10B30000]      <1> 	mov	esi, [DelFile_FNPointer]
  3447 000061E7 66B80018            <1> 	mov	ax, 1800h ; Except volume label and dirs
  3448 000061EB E8D1F6FFFF          <1> 	call	find_first_file
  3449 000061F0 0F82EFFAFFFF        <1> 	jc	loc_file_rw_cmd_failed
  3450                              <1> 
  3451                              <1> loc_delfile_ambgfn_check:
  3452 000061F6 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3453 000061F9 740B                <1> 	jz	short loc_delfile_found
  3454                              <1> 
  3455                              <1> loc_file_not_found:
  3456 000061FB B802000000          <1> 	mov	eax, 2 ; File not found sign
  3457 00006200 F9                  <1> 	stc
  3458 00006201 E9DFFAFFFF          <1> 	jmp	loc_file_rw_cmd_failed   
  3459                              <1> 
  3460                              <1> loc_delfile_found:
  3461 00006206 80E307              <1> 	and	bl, 07h ; Attributes
  3462 00006209 0F85E0FAFFFF        <1>         jnz     loc_permission_denied
  3463                              <1> 
  3464                              <1> ;loc_delfile_found_save_lnel:
  3465                              <1> ;	mov	[DelFile_LNEL], bh ; Long name entry length (if > 0)
  3466                              <1> 
  3467                              <1> loc_delfile_ask_for_delete:
  3468 0000620F 57                  <1> 	push	edi ; * (29/02/2016)
  3469                              <1> 
  3470 00006210 BE[539E0000]        <1> 	mov	esi, Msg_DoYouWantDelete
  3471 00006215 E820DAFFFF          <1> 	call	print_msg
  3472 0000621A 8B35[10B30000]      <1> 	mov	esi, [DelFile_FNPointer]
  3473 00006220 E815DAFFFF          <1> 	call	print_msg
  3474 00006225 BE[079E0000]        <1> 	mov	esi, Msg_YesNo
  3475 0000622A E80BDAFFFF          <1> 	call	print_msg
  3476                              <1> 
  3477                              <1> loc_delfile_ask_again:
  3478 0000622F 30E4                <1> 	xor	ah, ah
  3479 00006231 E8B1A9FFFF          <1> 	call	int16h
  3480 00006236 3C1B                <1> 	cmp	al, 1Bh
  3481                              <1> 	;je	short loc_do_not_delete_file
  3482 00006238 7457                <1> 	je	short loc_delfile_y_n_escape ; 06/03/2016
  3483 0000623A 24DF                <1> 	and	al, 0DFh
  3484 0000623C A2[119E0000]        <1> 	mov	[Y_N_nextline], al
  3485 00006241 3C59                <1> 	cmp	al, 'Y'
  3486 00006243 7404                <1> 	je	short loc_yes_delete_file
  3487 00006245 3C4E                <1> 	cmp	al, 'N'
  3488 00006247 75E6                <1> 	jne	short loc_delfile_ask_again
  3489                              <1> 
  3490                              <1> loc_do_not_delete_file:
  3491                              <1> loc_yes_delete_file:
  3492 00006249 A2[119E0000]        <1> 	mov	[Y_N_nextline], al
  3493 0000624E 6650                <1> 	push	ax
  3494 00006250 BE[119E0000]        <1> 	mov	esi, Y_N_nextline
  3495 00006255 E8E0D9FFFF          <1> 	call	print_msg
  3496 0000625A 6658                <1> 	pop	ax
  3497 0000625C 5F                  <1> 	pop	edi ; * (29/02/2016)
  3498                              <1> 	;cmp	al, 'Y' ; 'yes'
  3499                              <1> 	;cmc
  3500                              <1>         ;jnc	loc_file_rw_restore_retn
  3501 0000625D 3C4E                <1> 	cmp	al, 'N' ; 'no'
  3502 0000625F 0F8480FAFFFF        <1>         je	loc_file_rw_restore_retn  
  3503                              <1> 
  3504                              <1> loc_delete_file:
  3505 00006265 8A3D[52B20000]      <1> 	mov	bh, [FindFile_Drv]
  3506                              <1> 	;mov	bl, [DelFile_LNEL]
  3507 0000626B 8A1D[A1B20000]      <1> 	mov	bl, [FindFile_LongNameEntryLength]
  3508                              <1> 	;mov	cx, [DirBuff_EntryCounter]
  3509 00006271 668B0D[CCB20000]    <1> 	mov	cx, [FindFile_DirEntryNumber]
  3510                              <1> 	; (*) EDI = Directory buffer entry offset/address 
  3511 00006278 E859130000          <1> 	call	remove_file ; (FILE.ASM, 'proc_delete_file')
  3512 0000627D 0F8358FAFFFF        <1> 	jnc	loc_print_deleted_message
  3513                              <1> 
  3514 00006283 3C05                <1> 	cmp	al, 05h
  3515 00006285 0F8464FAFFFF        <1> 	je	loc_permission_denied
  3516 0000628B F9                  <1> 	stc
  3517 0000628C E954FAFFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3518                              <1> 
  3519                              <1> loc_delfile_y_n_escape:
  3520 00006291 B04E                <1> 	mov	al, 'N' ; 'no'
  3521 00006293 EBB4                <1> 	jmp	short loc_do_not_delete_file
  3522                              <1> 
  3523                              <1> set_file_attributes:
  3524                              <1> 	; 06/03/2016
  3525                              <1> 	; 04/03/2016 (TRDOS 386 =  TRDOS v2.0)
  3526                              <1> 	; 10/07/2010 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_attrib')
  3527                              <1> 	; 23/05/2010 
  3528                              <1> 	; 17/12/2000 (P2000.ASM)
  3529                              <1> 
  3530                              <1> 	; esi = file or directory name
  3531 00006295 6631C0              <1> 	xor	ax, ax
  3532 00006298 66A3[A49E0000]      <1> 	mov	[Attr_Chars], ax
  3533 0000629E A2[68B30000]        <1> 	mov	[Attributes], al
  3534                              <1> 
  3535                              <1> get_attrib_fchar:
  3536                              <1> 	; esi = file name
  3537 000062A3 8A06                <1> 	mov	al, [esi]
  3538 000062A5 3C20                <1> 	cmp	al, 20h
  3539 000062A7 7623                <1> 	jna	short loc_attr_file_nofilename_retn
  3540                              <1> 
  3541                              <1> loc_scan_attrib_params:
  3542 000062A9 3C2D                <1> 	cmp	al, '-'
  3543 000062AB 0F871C010000        <1> 	ja	loc_attr_file_parse_path_name
  3544 000062B1 7408                <1> 	je	short loc_attr_space
  3545                              <1> 
  3546 000062B3 3C2B                <1> 	cmp	al, '+'
  3547 000062B5 0F850AF1FFFF        <1> 	jne	loc_cmd_failed
  3548                              <1> 
  3549                              <1> loc_attr_space:
  3550 000062BB 8A6601              <1> 	mov	ah, [esi+1]
  3551 000062BE 80FC20              <1>  	cmp	ah, 20h
  3552 000062C1 770A                <1> 	ja	short pass_attr_space
  3553 000062C3 0F82FCF0FFFF        <1> 	jb	loc_cmd_failed
  3554 000062C9 46                  <1> 	inc	esi
  3555 000062CA EBEF                <1> 	jmp	short loc_attr_space
  3556                              <1> 
  3557                              <1> loc_attr_file_nofilename_retn:
  3558 000062CC C3                  <1> 	retn
  3559                              <1> 
  3560                              <1> pass_attr_space:
  3561 000062CD 80E4DF              <1> 	and	ah, 0DFh
  3562 000062D0 80FC53              <1> 	cmp	ah, 'S'
  3563 000062D3 0F87ECF0FFFF        <1> 	ja	loc_cmd_failed
  3564 000062D9 7204                <1> 	jb	short pass_attr_system
  3565 000062DB B404                <1> 	mov	ah, 04h   ; System
  3566 000062DD EB21                <1> 	jmp	short pass_attr_archive
  3567                              <1> 
  3568                              <1> pass_attr_system:
  3569 000062DF 80FC48              <1> 	cmp	ah, 'H'
  3570 000062E2 7706                <1> 	ja	short pass_attr_hidden
  3571 000062E4 7213                <1> 	jb	short pass_attr_read_only
  3572 000062E6 B402                <1> 	mov	ah, 02h    ; Hidden
  3573 000062E8 EB16                <1> 	jmp	short pass_attr_archive
  3574                              <1> 
  3575                              <1> pass_attr_hidden:
  3576 000062EA 80FC52              <1> 	cmp	ah, 'R'
  3577 000062ED 0F87D2F0FFFF        <1> 	ja	loc_cmd_failed
  3578 000062F3 7204                <1> 	jb	short pass_attr_read_only ; Read only
  3579 000062F5 B401                <1> 	mov	ah, 01h
  3580 000062F7 EB07                <1> 	jmp	short pass_attr_archive
  3581                              <1> 
  3582                              <1> pass_attr_read_only:
  3583 000062F9 80FC41              <1> 	cmp	ah, 'A'
  3584 000062FC 753B                <1> 	jne	short loc_chk_attr_enter
  3585 000062FE B420                <1> 	mov	ah, 20h    ; Archive
  3586                              <1> 
  3587                              <1> pass_attr_archive:
  3588 00006300 3C2D                <1> 	cmp	al, '-'
  3589 00006302 7508                <1> 	jne	short pass_reducing_attributes
  3590 00006304 0825[A49E0000]      <1> 	or	[Attr_Chars], ah
  3591 0000630A EB06                <1> 	jmp	short loc_change_attributes_inc
  3592                              <1> 
  3593                              <1> pass_reducing_attributes:
  3594 0000630C 0825[A59E0000]      <1> 	or	[Attr_Chars+1], ah
  3595                              <1> 
  3596                              <1> loc_change_attributes_inc:
  3597 00006312 46                  <1> 	inc	esi
  3598 00006313 8A6601              <1> 	mov	ah, [esi+1]
  3599 00006316 80FC20              <1> 	cmp	ah, 20h
  3600 00006319 7227                <1> 	jb	short pass_change_attr
  3601 0000631B 74F5                <1> 	je	short loc_change_attributes_inc
  3602 0000631D 80FC2D              <1> 	cmp	ah, '-'
  3603 00006320 770D                <1> 	ja	short loc_chk_next_attr_char1
  3604 00006322 7405                <1> 	je	short loc_chk_next_attr_char0
  3605 00006324 80FC2B              <1> 	cmp	ah, '+'
  3606 00006327 7506                <1> 	jne	short loc_chk_next_attr_char1
  3607                              <1> 
  3608                              <1> loc_chk_next_attr_char0:
  3609 00006329 46                  <1> 	inc	esi
  3610 0000632A 668B06              <1> 	mov	ax, [esi]
  3611 0000632D EB9E                <1> 	jmp	short pass_attr_space
  3612                              <1> 
  3613                              <1> loc_chk_next_attr_char1:
  3614 0000632F 803E2D              <1> 	cmp	byte [esi], '-'
  3615 00006332 7799                <1> 	ja	short pass_attr_space
  3616 00006334 E988000000          <1>         jmp     loc_attr_file_check_fname_fchar
  3617                              <1> 
  3618                              <1> loc_chk_attr_enter:
  3619 00006339 80FC0D              <1> 	cmp	ah, 0Dh
  3620 0000633C 0F8583F0FFFF        <1> 	jne	loc_cmd_failed
  3621                              <1> 
  3622                              <1> pass_change_attr:
  3623 00006342 A0[A49E0000]        <1> 	mov	al, [Attr_Chars]
  3624 00006347 F6D0                <1> 	not	al
  3625 00006349 2005[68B30000]      <1> 	and	[Attributes], al
  3626 0000634F A0[A59E0000]        <1> 	mov	al, [Attr_Chars+1]
  3627 00006354 0805[68B30000]      <1> 	or	[Attributes], al
  3628                              <1> 
  3629                              <1> loc_show_attributes:
  3630 0000635A BE[C6A40000]        <1> 	mov	esi, nextline
  3631 0000635F E8D6D8FFFF          <1> 	call	print_msg
  3632                              <1> 
  3633                              <1> loc_show_attributes_no_nextline:
  3634 00006364 C705[A49E0000]4E4F- <1> 	mov	dword [Attr_Chars], 'NORM'
  3634 0000636C 524D                <1>
  3635 0000636E 66C705[A89E0000]41- <1> 	mov	word [Attr_Chars+4], 'AL'
  3635 00006376 4C                  <1>
  3636 00006377 BE[A49E0000]        <1> 	mov	esi, Attr_Chars
  3637 0000637C A0[68B30000]        <1> 	mov	al, [Attributes]
  3638 00006381 A804                <1> 	test	al, 04h
  3639 00006383 7406                <1> 	jz	short pass_put_attr_s
  3640 00006385 66C7065300          <1> 	mov	word [esi], 0053h     ; S
  3641 0000638A 46                  <1> 	inc	esi
  3642                              <1> 
  3643                              <1> pass_put_attr_s:
  3644 0000638B A802                <1> 	test	al, 02h
  3645 0000638D 7406                <1> 	jz	short pass_put_attr_h
  3646 0000638F 66C7064800          <1> 	mov	word [esi], 0048h     ; H
  3647 00006394 46                  <1> 	inc	esi
  3648                              <1> 
  3649                              <1> pass_put_attr_h:
  3650 00006395 A801                <1> 	test	al, 01h
  3651 00006397 7406                <1> 	jz	short pass_put_attr_r
  3652 00006399 66C7065200          <1> 	mov	word [esi], 0052h     ; R
  3653 0000639E 46                  <1> 	inc	esi
  3654                              <1> 
  3655                              <1> pass_put_attr_r:
  3656 0000639F 3C20                <1> 	cmp	al, 20h
  3657 000063A1 7205                <1> 	jb	short pass_put_attr_a
  3658 000063A3 66C7064100          <1> 	mov	word [esi], 0041h     ; A
  3659                              <1> 
  3660                              <1> pass_put_attr_a:
  3661 000063A8 BE[979E0000]        <1> 	mov	esi, Str_Attributes
  3662 000063AD E888D8FFFF          <1> 	call	print_msg
  3663 000063B2 BE[C6A40000]        <1> 	mov	esi, nextline
  3664 000063B7 E87ED8FFFF          <1> 	call	print_msg
  3665 000063BC E924F9FFFF          <1> 	jmp	loc_file_rw_restore_retn 
  3666                              <1> 
  3667                              <1> loc_attr_file_check_fname_fchar:
  3668 000063C1 46                  <1> 	inc	esi
  3669 000063C2 803E20              <1> 	cmp	byte [esi], 20h
  3670 000063C5 74FA                <1> 	je	short loc_attr_file_check_fname_fchar
  3671 000063C7 0F8275FFFFFF        <1>         jb      pass_change_attr
  3672                              <1> 		   
  3673                              <1> loc_attr_file_parse_path_name:
  3674 000063CD BF[52B20000]        <1> 	mov	edi, FindFile_Drv
  3675 000063D2 E85D0A0000          <1> 	call	parse_path_name
  3676 000063D7 0F82E8EFFFFF        <1> 	jc	loc_cmd_failed
  3677                              <1> 
  3678                              <1> loc_attr_file_check_filename_exists:
  3679 000063DD BE[94B20000]        <1> 	mov	esi, FindFile_Name
  3680 000063E2 803E20              <1> 	cmp	byte [esi], 20h
  3681 000063E5 0F86DAEFFFFF        <1> 	jna	loc_cmd_failed
  3682 000063EB 8935[10B30000]      <1> 	mov	[DelFile_FNPointer], esi 
  3683                              <1> 
  3684                              <1> loc_attr_file_drv:
  3685 000063F1 8A35[AEA80000]      <1> 	mov	dh, [Current_Drv]
  3686 000063F7 8835[0EB10000]      <1> 	mov	[RUN_CDRV], dh
  3687                              <1> 
  3688 000063FD 8A15[52B20000]      <1> 	mov	dl, [FindFile_Drv]
  3689 00006403 38F2                <1> 	cmp	dl, dh
  3690 00006405 740B                <1> 	je	short loc_attr_file_change_directory
  3691                              <1> 
  3692 00006407 E832E1FFFF          <1> 	call	change_current_drive
  3693 0000640C 0F82D3F8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3694                              <1> 
  3695                              <1> loc_attr_file_change_directory:
  3696 00006412 803D[53B20000]20    <1>         cmp     byte [FindFile_Directory], 20h
  3697 00006419 7618                <1> 	jna	short loc_attr_file_find
  3698                              <1> 
  3699 0000641B FE05[7D990000]      <1> 	inc	byte [Restore_CDIR]
  3700                              <1> 	
  3701 00006421 BE[53B20000]        <1> 	mov	esi, FindFile_Directory
  3702 00006426 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3703 00006428 E8F3030000          <1> 	call	change_current_directory
  3704 0000642D 0F82B2F8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3705                              <1> 
  3706                              <1> ;loc_attr_file_change_prompt_dir_string:
  3707                              <1> 	;call	change_prompt_dir_string
  3708                              <1> 
  3709                              <1> loc_attr_file_find:
  3710                              <1> 	;mov	esi, FindFile_Name
  3711 00006433 8B35[10B30000]      <1> 	mov	esi, [DelFile_FNPointer]
  3712 00006439 66B80008            <1> 	mov	ax, 0800h ; Except volume labels
  3713 0000643D E87FF4FFFF          <1> 	call	find_first_file
  3714 00006442 0F829DF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3715                              <1> 
  3716                              <1> loc_attr_file_ambgfn_check:
  3717 00006448 6609D2              <1> 	or	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3718                              <1> 	;	(Note: It was BX in TRDOS v1)
  3719                              <1> 	;jz	short loc_attr_file_found
  3720 0000644B 0F85AAFDFFFF        <1>         jnz     loc_file_not_found ; 06/03/2016 
  3721                              <1> 
  3722                              <1> 	;mov	eax, 2 ; File not found sign
  3723                              <1> 	;stc
  3724                              <1> 	;jmp	loc_file_rw_cmd_failed   
  3725                              <1> 
  3726                              <1> loc_attr_file_found:
  3727                              <1> 	; EDI = Directory buffer entry offset/address
  3728                              <1> 	; BL = File (or Directory) Attributes 
  3729                              <1> 	;	(Note: It was 'CL' in TRDOS v1)
  3730                              <1> 	; mov	bl, [EDI+0Bh]
  3731                              <1> 	
  3732 00006451 66833D[A49E0000]00  <1> 	cmp	word [Attr_Chars], 0
  3733 00006459 770B                <1> 	ja	short loc_attr_file_change_attributes
  3734 0000645B 881D[68B30000]      <1> 	mov	[Attributes], bl
  3735 00006461 E9F4FEFFFF          <1> 	jmp	loc_show_attributes
  3736                              <1> 
  3737                              <1> loc_attr_file_change_attributes:
  3738 00006466 A0[A49E0000]        <1> 	mov	al, [Attr_Chars]
  3739 0000646B F6D0                <1> 	not	al
  3740 0000646D 20C3                <1> 	and	bl, al
  3741 0000646F A0[A59E0000]        <1> 	mov	al, [Attr_Chars+1]
  3742 00006474 08C3                <1> 	or	bl, al
  3743                              <1> 
  3744 00006476 66817F0CA101        <1> 	cmp	word [edi+DirEntry_NTRes], 01A1h ; Singlix FS
  3745 0000647C 741D                <1> 	je	short loc_attr_file_fs_check
  3746                              <1> 
  3747 0000647E 881D[68B30000]      <1> 	mov	[Attributes], bl
  3748 00006484 885F0B              <1> 	mov	[edi+0Bh], bl    ; Attributes (New!)
  3749                              <1> 
  3750                              <1> 	; 04/03/2016
  3751                              <1> 	; TRDOS v1 has a bug here! it does not set
  3752                              <1> 	; 'DirBuff_ValidData' to 2; as result of this bug,
  3753                              <1> 	; 'save_directory_buffer' would not save the new attributes ! 
  3754                              <1> 	
  3755 00006487 C605[D8B00000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  3756                              <1> 
  3757 0000648E E8050E0000          <1> 	call 	save_directory_buffer
  3758 00006493 0F824CF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3759                              <1> 
  3760 00006499 EB33                <1> 	jmp	short loc_print_attr_changed_message
  3761                              <1> 
  3762                              <1> loc_attr_file_fs_check:
  3763 0000649B 29C0                <1> 	sub	eax, eax
  3764 0000649D 8A25[D6B00000]      <1>         mov     ah, [DirBuff_DRV]
  3765 000064A3 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  3766 000064A8 01C6                <1>         add     esi, eax
  3767 000064AA 807E04A1            <1>         cmp     byte [esi+LD_FSType], 0A1h
  3768 000064AE 7309                <1> 	jnc	short loc_attr_file_change_fs_file_attributes
  3769 000064B0 66B80D00            <1> 	mov	ax, 0Dh ; Invalid Data
  3770 000064B4 E92CF8FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3771                              <1> 
  3772                              <1> loc_attr_file_change_fs_file_attributes:
  3773                              <1> 	; BL = New MS-DOS File Attributes
  3774 000064B9 88D8                <1> 	mov	al, bl ; File/Directory Attributes
  3775 000064BB 30E4                <1> 	xor	ah, ah ; Attributes in MS-DOS format sign	  
  3776 000064BD E87D020000          <1> 	call	change_fs_file_attributes
  3777 000064C2 0F821DF8FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3778                              <1> 
  3779 000064C8 881D[68B30000]      <1> 	mov	[Attributes], bl 
  3780                              <1> 
  3781                              <1> loc_print_attr_changed_message:
  3782 000064CE BE[929E0000]        <1> 	mov	esi, Msg_New
  3783 000064D3 E862D7FFFF          <1> 	call	print_msg
  3784 000064D8 E987FEFFFF          <1> 	jmp	loc_show_attributes_no_nextline
  3785                              <1> 
  3786                              <1> rename_file:
  3787                              <1> 	; 06/03/2016 (TRDOS 386 =  TRDOS v2.0)
  3788                              <1> 	; 20/11/2010 (TRDOS v1, CMD_INTR.ASM, 'cmp_cmd_rename')
  3789                              <1> 	; 16/11/2010 
  3790                              <1> 
  3791                              <1> get_rename_source_fchar:
  3792                              <1> 	; esi = file name
  3793 000064DD 803E20              <1> 	cmp	byte [esi], 20h
  3794 000064E0 7701                <1>         ja	short rename_scan_source_file_1
  3795                              <1> 
  3796                              <1> loc_rename_nofilename_retn:
  3797 000064E2 C3                  <1> 	retn
  3798                              <1> 
  3799                              <1> rename_scan_source_file_1:
  3800 000064E3 8935[8CB30000]      <1> 	mov	[SourceFilePath], esi
  3801                              <1> 
  3802                              <1> rename_scan_source_file_2:
  3803 000064E9 46                  <1> 	inc	esi
  3804 000064EA 803E20              <1> 	cmp	byte [esi], 20h
  3805 000064ED 7408                <1> 	je	short rename_scan_destination_file_1
  3806                              <1> 	;jb	short loc_rename_nofilename_retn
  3807 000064EF 0F82D0EEFFFF        <1> 	jb	loc_cmd_failed
  3808 000064F5 EBF2                <1> 	jmp	short rename_scan_source_file_2
  3809                              <1> 
  3810                              <1> rename_scan_destination_file_1:
  3811 000064F7 C60600              <1> 	mov	byte [esi], 0
  3812                              <1> 
  3813                              <1> rename_scan_destination_file_2:
  3814 000064FA 46                  <1> 	inc	esi  
  3815 000064FB 803E20              <1> 	cmp	byte [esi], 20h
  3816 000064FE 74FA                <1> 	je	short rename_scan_destination_file_2
  3817                              <1> 	;jb	short loc_rename_nofilename_retn
  3818 00006500 0F82BFEEFFFF        <1> 	jb	loc_cmd_failed
  3819                              <1> 
  3820 00006506 8935[90B30000]      <1> 	mov	[DestinationFilePath], esi
  3821                              <1> 
  3822                              <1> rename_scan_destination_file_3:
  3823 0000650C 46                  <1> 	inc	esi  
  3824 0000650D 803E20              <1> 	cmp	byte [esi], 20h
  3825 00006510 77FA                <1> 	ja	short rename_scan_destination_file_3
  3826                              <1> 
  3827 00006512 C60600              <1> 	mov	byte [esi], 0
  3828                              <1> 
  3829                              <1> loc_rename_save_current_drive:
  3830 00006515 8A35[AEA80000]      <1> 	mov	dh, [Current_Drv]
  3831 0000651B 8835[0EB10000]      <1> 	mov	byte [RUN_CDRV], dh
  3832                              <1> 
  3833                              <1> loc_rename_sf_parse_path_name:
  3834 00006521 8B35[8CB30000]      <1> 	mov	esi, [SourceFilePath] 
  3835 00006527 BF[52B20000]        <1> 	mov	edi, FindFile_Drv
  3836 0000652C E803090000          <1> 	call	parse_path_name
  3837 00006531 0F828EEEFFFF        <1> 	jc	loc_cmd_failed
  3838                              <1> 
  3839                              <1> loc_rename_sf_check_filename_exists:
  3840 00006537 BE[94B20000]        <1> 	mov	esi, FindFile_Name
  3841 0000653C 803E20              <1> 	cmp	byte [esi], 20h
  3842 0000653F 0F8680EEFFFF        <1> 	jna	loc_cmd_failed
  3843                              <1> 
  3844                              <1> 	;mov	[DelFile_FNPointer], esi 
  3845                              <1> 
  3846                              <1> loc_rename_sf_drv:
  3847                              <1> 	;mov	dh, [Current_Drv]
  3848                              <1> 	;mov	[RUN_CDRV], dh
  3849                              <1> 
  3850 00006545 8A15[52B20000]      <1> 	mov	dl, [FindFile_Drv]
  3851 0000654B 38F2                <1> 	cmp	dl, dh ; dh = [Current_Drv]
  3852 0000654D 740B                <1> 	je	short rename_sf_change_directory
  3853                              <1> 
  3854 0000654F E8EADFFFFF          <1> 	call	change_current_drive
  3855 00006554 0F828BF7FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3856                              <1> 
  3857                              <1> rename_sf_change_directory:
  3858 0000655A 803D[53B20000]20    <1> 	cmp	byte [FindFile_Directory], 20h
  3859 00006561 7618                <1> 	jna	short rename_sf_find
  3860                              <1> 
  3861 00006563 FE05[7D990000]      <1> 	inc	byte [Restore_CDIR]
  3862 00006569 BE[53B20000]        <1> 	mov	esi, FindFile_Directory
  3863 0000656E 30E4                <1> 	xor	ah, ah ; CD_COMMAND sign -> 0 
  3864 00006570 E8AB020000          <1> 	call	change_current_directory
  3865 00006575 0F826AF7FFFF        <1>  	jc	loc_file_rw_cmd_failed
  3866                              <1> 
  3867                              <1> ;rename_sf_change_prompt_dir_string:
  3868                              <1> 	;call	change_prompt_dir_string
  3869                              <1> 
  3870                              <1> rename_sf_find:
  3871                              <1> 	;mov	esi, [DelFile_FNPointer]
  3872 0000657B BE[94B20000]        <1> 	mov	esi, FindFile_Name
  3873                              <1> 
  3874 00006580 66B80008            <1> 	mov	ax, 0800h ; Except volume labels
  3875 00006584 E838F3FFFF          <1> 	call	find_first_file
  3876 00006589 0F8256F7FFFF        <1> 	jc	loc_file_rw_cmd_failed
  3877                              <1> 
  3878                              <1> loc_rename_sf_ambgfn_check:
  3879 0000658F 6621D2              <1> 	and	dx, dx ; Ambiguous filename chars used sign (DX>0)
  3880                              <1> 	;	(Note: It was BX in TRDOS v1)
  3881                              <1> 	;jz	short loc_rename_sf_found
  3882 00006592 0F8563FCFFFF        <1> 	jnz	loc_file_not_found
  3883                              <1> 
  3884                              <1> 	;mov	eax, 2 ; File not found sign
  3885                              <1> 	;stc
  3886                              <1> 	;jmp	loc_file_rw_cmd_failed   
  3887                              <1> 
  3888                              <1> loc_rename_sf_found:
  3889                              <1> 	; EDI = Directory buffer entry offset/address
  3890                              <1> 	; BL = File (or Directory) Attributes 
  3891                              <1> 	;	(Note: It was 'CL' in TRDOS v1)
  3892                              <1> 	; mov	bl, [EDI+0Bh]
  3893                              <1> 
  3894 00006598 F6C307              <1> 	test	bl, 07h ; Attributes, S-H-R
  3895 0000659B 0F854EF7FFFF        <1> 	jnz	loc_permission_denied
  3896                              <1> 	
  3897 000065A1 BE[52B20000]        <1>         mov     esi, FindFile_Drv
  3898 000065A6 BF[94B30000]        <1>         mov     edi, SourceFile_Drv
  3899 000065AB B920000000          <1> 	mov	ecx, 32
  3900 000065B0 F3A5                <1> 	rep	movsd
  3901                              <1> 
  3902                              <1> loc_rename_df_parse_path_name:
  3903 000065B2 8B35[90B30000]      <1> 	mov	esi, [DestinationFilePath]
  3904 000065B8 BF[52B20000]        <1> 	mov	edi, FindFile_Drv
  3905 000065BD E872080000          <1> 	call	parse_path_name
  3906 000065C2 7219                <1> 	jc	short loc_rename_df_cmd_failed
  3907                              <1> 
  3908                              <1> 	;mov	dh, [RUN_CDRV]
  3909 000065C4 8A35[AEA80000]      <1> 	mov	dh, [Current_Drv]
  3910                              <1> 
  3911                              <1> 	; 'rename' command is valid only for same dos drive and same dir!
  3912                              <1> 	; ('move' command must be used if source file and destination file
  3913                              <1> 	; directories are not same!) 
  3914 000065CA 8A15[52B20000]      <1> 	mov	dl, [FindFile_Drv]
  3915 000065D0 38F2                <1> 	cmp	dl, dh ; are source and destination drives different ?!
  3916 000065D2 7509                <1> 	jne	short loc_rename_df_cmd_failed ; yes! 
  3917                              <1> 
  3918                              <1> rename_df_check_dirname_exists:
  3919 000065D4 803D[53B20000]00    <1> 	cmp	byte [FindFile_Directory], 0
  3920 000065DB 760B                <1> 	jna	short rename_df_check_filename_exists
  3921                              <1> 
  3922                              <1> 	; different source file and destination file directories !
  3923                              <1> loc_rename_df_cmd_failed:
  3924                              <1> loc_rename_df_found:
  3925 000065DD B801000000          <1> 	mov	eax, 1 ; TRDOS 'Bad command or file name' error
  3926 000065E2 F9                  <1> 	stc
  3927 000065E3 E9FDF6FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3928                              <1>                  
  3929                              <1> rename_df_check_filename_exists:
  3930 000065E8 BE[94B20000]        <1> 	mov	esi, FindFile_Name
  3931 000065ED E883F6FFFF          <1> 	call	check_filename
  3932 000065F2 0F829FF7FFFF        <1> 	jc	loc_mkdir_invalid_dir_name_chars
  3933                              <1> 
  3934                              <1> 	;mov	[DelFile_FNPointer], esi 
  3935                              <1> 	;cmp	byte [esi], 20h
  3936                              <1> 	;ja	short loc_rename_df_find
  3937                              <1> 
  3938                              <1> 	;mov	dh, [Current_Drv] ; dh has not been changed
  3939                              <1> 
  3940                              <1> rename_df_drv_check_writable:
  3941 000065F8 0FB6F6              <1> 	movzx	esi, dh
  3942                              <1> 	;movzx	esi, byte [Current_Drv]
  3943 000065FB 81C600010900        <1> 	add	esi, Logical_DOSDisks
  3944                              <1> 
  3945 00006601 88F2                <1> 	mov	dl, dh ; dl = [Current_Drv]
  3946 00006603 8A7601              <1> 	mov	dh, [esi+LD_DiskType]
  3947                              <1> 
  3948 00006606 80FE01              <1> 	cmp	dh, 1 ; 0 = Invalid
  3949 00006609 7310                <1> 	jnb	short rename_df_compare_sf_df_name
  3950                              <1> 
  3951 0000660B B813000000          <1> 	mov	eax, 13h ; MSDOS err => Disk write-protected
  3952 00006610 8B1D[90B30000]      <1> 	mov	ebx, [DestinationFilePath] 
  3953 00006616 E9CAF6FFFF          <1> 	jmp	loc_file_rw_cmd_failed
  3954                              <1> 
  3955                              <1> rename_df_compare_sf_df_name:
  3956 0000661B BE[94B20000]        <1> 	mov	esi, FindFile_Name
  3957 00006620 BF[D6B30000]        <1> 	mov	edi, SourceFile_Name
  3958 00006625 B90C000000          <1> 	mov	ecx, 12
  3959                              <1> rename_df_compare_sf_df_name_next: 
  3960 0000662A AC                  <1> 	lodsb
  3961 0000662B AE                  <1> 	scasb
  3962 0000662C 7506                <1> 	jne	short loc_rename_df_find
  3963 0000662E 08C0                <1> 	or	al, al
  3964 00006630 74AB                <1> 	jz	short loc_rename_df_cmd_failed
  3965 00006632 E2F6                <1> 	loop	rename_df_compare_sf_df_name_next 
  3966                              <1> 
  3967                              <1> loc_rename_df_find:
  3968                              <1> 	;mov	esi, [DelFile_FNPointer]
  3969 00006634 BE[94B20000]        <1> 	mov	esi, FindFile_Name
  3970                              <1> 
  3971 00006639 6631C0              <1> 	xor	ax, ax ; Any
  3972 0000663C E880F2FFFF          <1> 	call	find_first_file
  3973 00006641 739A                <1> 	jnc	short loc_rename_df_found
  3974                              <1> 
  3975                              <1> loc_rename_df_check_error_code:
  3976                              <1> 	;cmp	eax, 2
  3977 00006643 3C02                <1> 	cmp	al, 2 ; Not found error
  3978 00006645 7406                <1> 	je	short rename_df_move_find_struct_to_dest
  3979 00006647 F9                  <1> 	stc
  3980 00006648 E998F6FFFF          <1> 	jmp loc_file_rw_cmd_failed
  3981                              <1> 
  3982                              <1> ;loc_rename_df_found:
  3983                              <1> ;	mov	eax, 1 ;Bad command or file name error
  3984                              <1> ;	stc
  3985                              <1> ;	jmp	loc_file_rw_cmd_failed
  3986                              <1> 
  3987                              <1> rename_df_move_find_struct_to_dest:
  3988 0000664D BE[52B20000]        <1>         mov     esi, FindFile_Drv
  3989 00006652 BF[14B40000]        <1>         mov     edi, DestinationFile_Drv
  3990 00006657 B920000000          <1> 	mov	ecx, 32
  3991 0000665C F3A5                <1> 	rep	movsd
  3992                              <1> 
  3993                              <1> loc_rename_df_process_q_sf:
  3994                              <1> 	;mov	ecx, 12
  3995 0000665E B10C                <1> 	mov	cl, 12
  3996 00006660 BE[D6B30000]        <1>  	mov	esi, SourceFile_Name
  3997 00006665 BF[D39E0000]        <1> 	mov	edi, Rename_OldName
  3998                              <1> rename_df_process_q_nml_1_sf:
  3999 0000666A AC                  <1> 	lodsb
  4000 0000666B 3C20                <1>         cmp	al, 20h
  4001 0000666D 7603                <1>         jna	short rename_df_process_q_nml_2_sf
  4002 0000666F AA                  <1> 	stosb
  4003 00006670 E2F8                <1> 	loop	rename_df_process_q_nml_1_sf
  4004                              <1> 
  4005                              <1> rename_df_process_q_nml_2_sf:
  4006 00006672 C60700              <1> 	mov	byte [edi], 0
  4007                              <1> 
  4008                              <1> loc_rename_df_process_q_df:
  4009                              <1> 	;mov	ecx, 12
  4010 00006675 B10C                <1> 	mov	cl, 12
  4011 00006677 BE[56B40000]        <1> 	mov	esi, DestinationFile_Name
  4012 0000667C BF[E49E0000]        <1> 	mov	edi, Rename_NewName
  4013                              <1> rename_df_process_q_nml_1_df:
  4014 00006681 AC                  <1> 	lodsb
  4015 00006682 3C20                <1> 	cmp	al, 20h
  4016 00006684 7603                <1> 	jna	short loc_rename_df_process_q_nml_2_df
  4017 00006686 AA                  <1> 	stosb
  4018 00006687 E2F8                <1> 	loop	rename_df_process_q_nml_1_df
  4019                              <1> 
  4020                              <1> loc_rename_df_process_q_nml_2_df:
  4021 00006689 C60700              <1> 	mov	byte [edi], 0
  4022                              <1> 
  4023                              <1> loc_rename_confirmation_question:
  4024 0000668C BE[AB9E0000]        <1> 	mov	esi, Msg_DoYouWantRename
  4025 00006691 E8A4D5FFFF          <1> 	call	print_msg
  4026                              <1> 
  4027 00006696 A0[F1B30000]        <1> 	mov	al, [SourceFile_DirEntry+11] ; Attributes
  4028 0000669B 2410                <1> 	and	al, 10h
  4029 0000669D 750C                <1> 	jnz	short rename_confirmation_question_dir
  4030                              <1> 
  4031                              <1> rename_confirmation_question_file:
  4032 0000669F BE[C29E0000]        <1> 	mov	esi, Rename_File
  4033 000066A4 E891D5FFFF          <1> 	call	print_msg 
  4034 000066A9 EB0A                <1> 	jmp	short rename_confirmation_question_as 
  4035                              <1> 
  4036                              <1> rename_confirmation_question_dir:
  4037 000066AB BE[C89E0000]        <1> 	mov	esi, Rename_Directory
  4038 000066B0 E885D5FFFF          <1> 	call	print_msg
  4039                              <1> 
  4040                              <1> rename_confirmation_question_as:
  4041 000066B5 BE[D39E0000]        <1> 	mov	esi, Rename_OldName
  4042 000066BA E87BD5FFFF          <1> 	call	print_msg
  4043 000066BF BE[E09E0000]        <1> 	mov	esi, Msg_File_rename_as
  4044 000066C4 E871D5FFFF          <1> 	call	print_msg
  4045 000066C9 BE[079E0000]        <1> 	mov	esi, Msg_YesNo
  4046 000066CE E867D5FFFF          <1> 	call	print_msg
  4047                              <1> 
  4048                              <1> loc_rename_ask_again:
  4049 000066D3 30E4                <1> 	xor	ah, ah
  4050 000066D5 E80DA5FFFF          <1> 	call	int16h
  4051 000066DA 3C0B                <1> 	cmp	al, 0Bh
  4052 000066DC 740F                <1> 	je	short loc_do_not_rename_file
  4053 000066DE 24DF                <1> 	and	al, 0DFh
  4054 000066E0 A2[119E0000]        <1> 	mov	[Y_N_nextline], al
  4055 000066E5 3C59                <1> 	cmp	al, 'Y'
  4056 000066E7 7404                <1> 	je	short loc_yes_rename_file
  4057 000066E9 3C4E                <1> 	cmp	al, 'N'
  4058 000066EB 75E6                <1> 	jne	short loc_rename_ask_again
  4059                              <1> 
  4060                              <1> loc_do_not_rename_file:
  4061                              <1> loc_yes_rename_file:
  4062 000066ED A2[119E0000]        <1> 	mov	[Y_N_nextline], al
  4063 000066F2 6650                <1> 	push	ax
  4064 000066F4 BE[119E0000]        <1> 	mov	esi, Y_N_nextline
  4065 000066F9 E83CD5FFFF          <1> 	call	print_msg
  4066 000066FE 6658                <1> 	pop	ax
  4067                              <1> 	;cmp	al, 'Y' ; 'yes'
  4068                              <1> 	;cmc
  4069                              <1>         ;jnc	loc_file_rw_restore_retn
  4070 00006700 3C4E                <1> 	cmp	al, 'N' ; 'no'
  4071 00006702 0F84DDF5FFFF        <1>         je	loc_file_rw_restore_retn  
  4072                              <1> 
  4073 00006708 BE[E49E0000]        <1> 	mov	esi, Rename_NewName
  4074 0000670D 668B0D[0EB40000]    <1> 	mov	cx, [SourceFile_DirEntryNumber] 
  4075 00006714 66A1[FAB30000]      <1> 	mov	ax, [SourceFile_DirEntry+20] ; First Cluster, HW 
  4076 0000671A 66C1E010            <1> 	shl	ax, 16
  4077 0000671E 66A1[00B40000]      <1> 	mov	ax, [SourceFile_DirEntry+26] ; First Cluster, LW 
  4078                              <1> 
  4079 00006724 0FB61D[E3B30000]    <1>   	movzx	ebx, byte [SourceFile_LongNameEntryLength]  
  4080 0000672B E8420F0000          <1>    	call	rename_directory_entry
  4081 00006730 E9DEF6FFFF          <1> 	jmp	loc_rename_file_ok	
  4082                              <1> ;loc_rename_file_ok:
  4083                              <1> ;	jc	loc_run_cmd_failed
  4084                              <1> ;	mov	esi, Msg_OK
  4085                              <1> ;	call	proc_printmsg
  4086                              <1> ;	jmp	loc_file_rw_restore_retn
  4087                              <1> 
  4088                              <1> copy_file:
  4089 00006735 C3                  <1> 	retn
  4090                              <1> move_file:
  4091 00006736 C3                  <1> 	retn
  4092                              <1> set_get_path:
  4093 00006737 C3                  <1> 	retn
  4094                              <1> find_and_list_files:
  4095 00006738 C3                  <1> 	retn
  4096                              <1> set_get_env:
  4097 00006739 C3                  <1> 	retn
  4098                              <1> set_exec_arguments:
  4099 0000673A C3                  <1> 	retn
  4100                              <1> load_and_execute_file:
  4101 0000673B C3                  <1> 	retn
  4102                              <1> delete_fs_directory:
  4103 0000673C 31C0                <1> 	xor eax, eax
  4104 0000673E C3                  <1> 	retn
  4105                              <1> 
  4106                              <1> change_fs_file_attributes:
  4107                              <1> 	; 04/03/2016 ; Temporary
  4108                              <1> 	; AL = File or directory attributes
  4109                              <1> 	; AH = 0 -> Attributes are in MS-DOS format
  4110                              <1> 	; AH > 0 -> Attributes are in SINGLIX format
  4111                              <1> 	;push	ebx
  4112                              <1> 	; ... do somethings here ...
  4113                              <1> 	;pop	ebx
  4114                              <1> 	; BL = File or directory attributes
  4115 0000673F C3                  <1> 	retn
  1916                                  %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: 06/03/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    11                              <1> ; DIR.ASM (09/10/2011)
    12                              <1> ; ****************************************************************************
    13                              <1> 
    14                              <1> ; DIR.ASM  [ TRDOS KERNEL - COMMAND EXECUTER SECTION - DIRECTORY FUNCTIONS ]
    15                              <1> ; (c) 2004-2010  Erdogan TAN  [ 17/01/2004 ]  Last Update: 09/10/2011
    16                              <1> ; FILE.ASM [ FILE FUNCTIONS ] Last Update: 09/10/2011
    17                              <1> 
    18                              <1> change_prompt_dir_string:
    19                              <1> 	; 24/01/2016 (TRDOS 386 = TRDOS v2.0)
    20                              <1> 	; 27/03/2011
    21                              <1> 	; 09/10/2009
    22                              <1> 	; INPUT/OUTPUT => none
    23                              <1> 	; this procedure changes current directory string/text  
    24                              <1> 	; 2005
    25                              <1> 
    26 00006740 BF[B2A80000]        <1> 	mov	edi, Current_Directory
    27 00006745 8A25[ACA80000]      <1> 	mov	ah, [Current_Dir_Level]
    28 0000674B BE[0FB10000]        <1> 	mov	esi, PATH_Array
    29 00006750 E807000000          <1> 	call	set_current_directory_string
    30 00006755 880D[0DA90000]      <1> 	mov	[Current_Dir_StrLen], cl
    31                              <1> 
    32 0000675B C3                  <1> 	retn
    33                              <1> 
    34                              <1> set_current_directory_string:
    35                              <1> 	; 24/01/2016 (TRDOS 386 = TRDOS v2.0)
    36                              <1> 	; 27/03/2011
    37                              <1> 	; 09/10/2009
    38                              <1> 	; INPUT:
    39                              <1> 	;    ESI = Path Array Address 
    40                              <1> 	;    EDI = Current Directory String Buffer
    41                              <1> 	;    AH = Current Directory Level
    42                              <1> 	; OUTPUT => EAX, EBX, ESI will be changed
    43                              <1> 	;    EDI will be same with input
    44                              <1> 	;    ECX = Current Directory String Length 
    45                              <1> 
    46 0000675C 57                  <1> 	push    edi
    47 0000675D 80FC00              <1> 	cmp     ah, 0
    48 00006760 7652                <1> 	jna	short pass_write_path
    49 00006762 83C610              <1> 	add	esi, 16
    50 00006765 89F3                <1> 	mov	ebx, esi
    51                              <1> loc_write_path:
    52 00006767 B908000000          <1> 	mov	ecx, 8
    53                              <1> path_write_dirname1:
    54 0000676C AC                  <1> 	lodsb
    55 0000676D 3C20                <1> 	cmp	al, 20h
    56 0000676F 7612                <1> 	jna	short pass_write_dirname1
    57 00006771 AA                  <1> 	stosb
    58 00006772 81FF[0CA90000]      <1> 	cmp	edi, End_Of_Current_Dir_Str
    59 00006778 733A                <1> 	jnb	short pass_write_path
    60 0000677A E2F0                <1> 	loop	path_write_dirname1
    61 0000677C 803E20              <1> 	cmp	byte [esi], 20h
    62 0000677F 7624                <1> 	jna	short pass_write_dirname2
    63 00006781 EB0A                <1> 	jmp     short loc_put_dot_cont_ext
    64                              <1> pass_write_dirname1:
    65 00006783 89DE                <1> 	mov	esi, ebx
    66 00006785 83C608              <1> 	add	esi, 8
    67 00006788 803E20              <1> 	cmp	byte [esi], 20h
    68 0000678B 7618                <1> 	jna	short pass_write_dirname2
    69                              <1> loc_put_dot_cont_ext:
    70 0000678D C6072E              <1> 	mov	byte [edi], "."
    71                              <1> 	;mov	ecx, 3
    72 00006790 B103                <1> 	mov	cl, 3
    73                              <1> loc_check_dir_name_ext:
    74 00006792 AC                  <1> 	lodsb
    75 00006793 47                  <1> 	inc	edi
    76 00006794 3C20                <1> 	cmp	al, 20h
    77 00006796 760D                <1> 	jna	short pass_write_dirname2
    78 00006798 8807                <1> 	mov	[edi], al
    79 0000679A 81FF[0CA90000]      <1> 	cmp	edi, End_Of_Current_Dir_Str
    80 000067A0 7312                <1> 	jnb	short pass_write_path
    81 000067A2 E2EE                <1> 	loop    loc_check_dir_name_ext
    82 000067A4 47                  <1> 	inc	edi
    83                              <1> pass_write_dirname2:
    84 000067A5 FECC                <1> 	dec	ah
    85 000067A7 740B                <1> 	jz      short pass_write_path
    86 000067A9 83C310              <1> 	add	ebx, 16
    87 000067AC 89DE                <1> 	mov	esi, ebx
    88 000067AE C6072F              <1> 	mov	byte [edi],"/"
    89 000067B1 47                  <1> 	inc	edi
    90 000067B2 EBB3                <1> 	jmp	short loc_write_path
    91                              <1> pass_write_path:
    92 000067B4 C60700              <1> 	mov	byte [edi], 0
    93 000067B7 47                  <1> 	inc	edi
    94 000067B8 89F9                <1> 	mov	ecx, edi
    95 000067BA 5F                  <1> 	pop	edi
    96 000067BB 29F9                <1> 	sub	ecx, edi
    97                              <1> 	; ECX = Current Directory String Length
    98 000067BD C3                  <1> 	retn
    99                              <1> 
   100                              <1> get_current_directory:
   101                              <1> 	; 14/02/2016
   102                              <1> 	; 24/01/2016 (TRDOS 386 = TRDOS v2.0)
   103                              <1> 	; 27/03/2011
   104                              <1> 	;
   105                              <1> 	; INPUT-> ESI = Current Directory Buffer
   106                              <1> 	;         DL = TRDOS Logical Dos Drive Number + 1
   107                              <1> 	;              (0= Default/Current Drive)
   108                              <1> 	;           
   109                              <1> 	;   Note: Required dir buffer length may be <= 92 bytes
   110                              <1> 	;         for TRDOS (7*12 name chars + 7 slash + 0)
   111                              <1> 	; OUTPUT ->  ESI = Current Directory Buffer
   112                              <1> 	;            EAX, EBX, ECX, EDX, EDI will be changed
   113                              <1> 	;            CX/CL = Current Directory String Length
   114                              <1> 	;	     DL = Drive Number (0 based)
   115                              <1> 	;            (If input is 0, output is current drv number) 
   116                              <1> 	;            DH = same with input 
   117                              <1> 	;   cf = 0 -> AL = 0
   118                              <1> 	;   cf = 1 -> error code in AL 
   119                              <1>               
   120                              <1> loc_get_current_drive_0:
   121 000067BE 80FA00              <1> 	cmp	dl, 0
   122 000067C1 7708                <1> 	ja	short loc_get_current_drive_1
   123 000067C3 8A15[AEA80000]      <1> 	mov	dl, [Current_Drv]
   124 000067C9 EB17                <1> 	jmp	short loc_get_current_drive_2
   125                              <1> loc_get_current_drive_1:
   126 000067CB FECA                <1> 	dec 	dl
   127 000067CD 3A15[7C990000]      <1> 	cmp	dl, [Last_DOS_DiskNo]
   128 000067D3 760D                <1> 	jna	short loc_get_current_drive_2
   129 000067D5 B80F000000          <1> 	mov	eax, 0Fh ; Invalid drive
   130 000067DA F5                  <1> 	cmc 	; stc
   131 000067DB C3                  <1> 	retn
   132                              <1> 
   133                              <1> loc_get_current_drive_not_ready_retn:
   134 000067DC 5E                  <1> 	pop	esi
   135                              <1> 	;mov	eax, 15h
   136 000067DD 66B81500            <1> 	mov	ax, 15h ; Drive not ready
   137 000067E1 C3                  <1> 	retn  
   138                              <1>  
   139                              <1> loc_get_current_drive_2:
   140 000067E2 31C0                <1> 	xor	eax, eax
   141 000067E4 88D4                <1> 	mov	ah, dl
   142 000067E6 56                  <1> 	push	esi
   143 000067E7 BE00010900          <1> 	mov	esi, Logical_DOSDisks
   144 000067EC 01C6                <1> 	add	esi, eax
   145 000067EE 8A06                <1> 	mov	al, [esi+LD_Name] 
   146 000067F0 3C41                <1> 	cmp	al, 'A'
   147 000067F2 72E8                <1> 	jb	short loc_get_current_drive_not_ready_retn
   148                              <1> 
   149 000067F4 8A667F              <1> 	mov	ah, [esi+LD_CDirLevel]
   150 000067F7 08E4                <1> 	or	ah, ah
   151 000067F9 7506                <1> 	jnz	short loc_get_current_drive_3
   152                              <1> 
   153                              <1> 	;xor	ah, ah ; mov ah, 0
   154 000067FB 8826                <1> 	mov	[esi], ah
   155 000067FD 31C9                <1> 	xor	ecx, ecx
   156 000067FF EB1C                <1> 	jmp	short loc_get_current_drive_4
   157                              <1> 
   158                              <1> loc_get_current_drive_3:
   159 00006801 BF[0FB10000]        <1>         mov     edi, PATH_Array
   160 00006806 57                  <1> 	push	edi
   161 00006807 81C680000000        <1> 	add	esi, LD_CurrentDirectory
   162 0000680D B920000000          <1> 	mov	ecx, 32
   163 00006812 F3A5                <1> 	rep	movsd
   164 00006814 5E                  <1> 	pop	esi ; Path Array Address
   165 00006815 5F                  <1> 	pop	edi ; pushed esi (current dir buffer offset) 
   166                              <1> 	;
   167 00006816 E841FFFFFF          <1> 	call	set_current_directory_string
   168 0000681B 89FE                <1> 	mov	esi, edi
   169                              <1> 
   170                              <1> loc_get_current_drive_4:
   171 0000681D 30C0                <1> 	xor	al, al
   172 0000681F C3                  <1> 	retn
   173                              <1> 
   174                              <1> change_current_directory:
   175                              <1> 	; 19/02/2016
   176                              <1> 	; 11/02/2016
   177                              <1> 	; 10/02/2016
   178                              <1> 	; 08/02/2016
   179                              <1> 	; 06/02/2016 (TRDOS 386 = TRDOS v2.0)
   180                              <1> 	; 18/09/2011 (DIR.ASM, 09/10/2011)	
   181                              <1> 	; 04/10/2009
   182                              <1> 	; 2005
   183                              <1> 	; INPUT -> 
   184                              <1> 	;	ESI = Directory string
   185                              <1> 	;	ah = CD command (CDh = save current dir string)
   186                              <1> 	; OUTPUT -> 
   187                              <1> 	; 	EDI = DOS Drive Description Table
   188                              <1> 	; 	cf = 1 -> error
   189                              <1> 	;	   EAX = Error code
   190                              <1> 	;	cf = 0 -> succesful
   191                              <1> 	;	   ESI = PATH_Array
   192                              <1> 	;	   EAX = Current Directory First Cluster
   193                              <1> 	;
   194                              <1> 	; (EAX, EBX, ECX, EDX, ESI, EDI will be changed)
   195                              <1> 	
   196 00006820 8825[9DB10000]      <1> 	mov	[CD_COMMAND], ah
   197 00006826 803E2F              <1> 	cmp	byte [esi], '/'
   198 00006829 7505                <1> 	jne	short loc_ccd_cdir_level
   199 0000682B 46                  <1> 	inc	esi
   200 0000682C 30C0                <1> 	xor	al, al
   201 0000682E EB05                <1> 	jmp	short loc_ccd_parse_path_name
   202                              <1> loc_ccd_cdir_level:
   203 00006830 A0[ACA80000]        <1> 	mov	al, [Current_Dir_Level]
   204                              <1> loc_ccd_parse_path_name:
   205 00006835 88C4                <1> 	mov	ah, al
   206 00006837 BF[0FB10000]        <1> 	mov	edi, PATH_Array
   207                              <1> 
   208                              <1> ; Reset directory levels > cdir level
   209                              <1> 	; is this required !?
   210                              <1> 	;
   211                              <1> 	; Relations:
   212                              <1> 	; MAINPROG.ASM (pass_ccdrv_reset_cdir_FAT_fcluster)
   213                              <1> 	; proc_parse_dir_name,
   214                              <1> 	; proc_change_current_directory (this procedure)
   215                              <1> 	; proc_change_prompt_dir_string 
   216                              <1>  
   217 0000683C 0FB6C8              <1> 	movzx	ecx, al
   218 0000683F FEC1                <1> 	inc	cl
   219 00006841 C0E104              <1> 	shl	cl, 4
   220 00006844 01CF                <1> 	add	edi, ecx
   221 00006846 B107                <1> 	mov	cl, 7
   222 00006848 28C1                <1> 	sub	cl, al
   223 0000684A C0E102              <1> 	shl	cl, 2
   224 0000684D 89C3                <1> 	mov	ebx, eax
   225 0000684F 31C0                <1> 	xor	eax, eax ; 0
   226 00006851 F3AB                <1> 	rep	stosd
   227 00006853 89D8                <1> 	mov	eax, ebx
   228                              <1> 
   229 00006855 BF[0FB10000]        <1> 	mov	edi, PATH_Array
   230                              <1> 
   231 0000685A 803E20              <1> 	cmp	byte [esi], 20h
   232 0000685D F5                  <1> 	cmc
   233 0000685E 7305                <1> 	jnc	short pass_ccd_parse_dir_name
   234                              <1> 
   235                              <1> 		; ESI = Path name
   236                              <1> 		; AL = CCD_Level
   237 00006860 E872010000          <1>         call    parse_dir_name
   238                              <1> 		; AL = CCD_Level 
   239                              <1> 		; AH = Last_Dir_Level
   240                              <1> 		; (EDI = PATH_Array)
   241                              <1> 
   242                              <1> pass_ccd_parse_dir_name:
   243 00006865 9C                  <1> 	pushf
   244                              <1> 
   245                              <1> 	;mov	[CCD_Level], al
   246                              <1>         ;mov	[Last_Dir_Level], ah
   247 00006866 66A3[93B10000]      <1> 	mov	[CCD_Level], ax
   248                              <1> 
   249 0000686C 31DB                <1> 	xor	ebx, ebx
   250 0000686E 8A3D[AEA80000]      <1> 	mov	bh, [Current_Drv]
   251 00006874 BE00010900          <1> 	mov	esi, Logical_DOSDisks
   252 00006879 01DE                <1> 	add	esi, ebx
   253                              <1> 
   254 0000687B 9D                  <1> 	popf 
   255 0000687C 720A                <1> 	jc	short loc_ccd_bad_path_name_retn
   256                              <1> 
   257 0000687E 8935[8FB10000]      <1> 	mov	[CCD_DriveDT], esi
   258                              <1> 
   259 00006884 3C07                <1> 	cmp	al, 7
   260 00006886 7209                <1> 	jb	short loc_ccd_load_child_dir
   261                              <1> 
   262                              <1> loc_ccd_bad_path_name_retn:
   263 00006888 87F7                <1> 	xchg	esi, edi
   264                              <1> 	; DOS Error Code 
   265 0000688A B818000000          <1> 	mov	eax, 18h ; Bad request structure length 
   266 0000688F F9                  <1> 	stc
   267                              <1> loc_ccd_retn_p:
   268 00006890 C3                  <1> 	retn
   269                              <1> 
   270                              <1> loc_ccd_load_child_dir:
   271                              <1> 	; AL = CCD_Level
   272 00006891 08C0                <1> 	or	al, al
   273 00006893 7468                <1> 	jz	short loc_ccd_load_root_dir
   274                              <1> 
   275 00006895 6689C1              <1> 	mov	cx, ax
   276 00006898 C0E004              <1> 	shl	al, 4
   277 0000689B 0FB6F0              <1> 	movzx	esi, al
   278 0000689E 01FE                <1>      	add	esi, edi  ; offset PATH_Array
   279                              <1> 
   280 000068A0 8B460C              <1> 	mov	eax, [esi+12]
   281 000068A3 38E9                <1> 	cmp	cl, ch
   282 000068A5 0F84FA000000        <1>         je      loc_ccd_load_sub_directory
   283 000068AB A3[A8A80000]        <1> 	mov	[Current_Dir_FCluster], eax
   284                              <1> 
   285                              <1> loc_ccd_load_child_dir_next:
   286 000068B0 83C610              <1> 	add	esi, 16 ; DOS DirEntry Format FileName Address
   287                              <1> 
   288                              <1>  	; Directory attribute : 10h
   289 000068B3 B010                <1> 	mov	al, 00010000b ; 10h (Attrib AND mask)
   290                              <1> 	;mov	ah, 11001000b ; C8h
   291                              <1> 	; Volume name attribute: 8h
   292 000068B5 B408                <1> 	mov	ah, 00001000b ; 08h (Attrib NAND, AND --> zero mask)
   293                              <1> 
   294 000068B7 6631C9              <1> 	xor	cx, cx  
   295 000068BA E8B5010000          <1> 	call	locate_current_dir_file
   296 000068BF 7353                <1> 	jnc	short loc_ccd_set_dir_cluster_ptr
   297                              <1> 
   298                              <1> 	 ; 19/02/2016
   299                              <1> 	;mov	edi, [CCD_DriveDT]
   300 000068C1 8A25[93B10000]      <1> 	mov	ah, [CCD_Level]
   301 000068C7 803D[9DB10000]CD    <1> 	cmp	byte [CD_COMMAND], 0CDh ;'CD' command or another
   302 000068CE 7509                <1> 	jne	short loc_ccd_load_child_dir_err
   303                              <1> 	; It is better to save recent successful part 
   304                              <1> 	; of the (requested) path as current directory.
   305                              <1> 	; (Otherwise the path would be reset to back
   306                              <1> 	; on the next 'CD' command.)
   307 000068D0 88E1                <1> 	mov	cl, ah
   308 000068D2 50                  <1> 	push	eax
   309 000068D3 E8E3000000          <1> 	call	loc_ccd_save_current_dir
   310 000068D8 58                  <1> 	pop	eax
   311                              <1> loc_ccd_load_child_dir_err:            
   312 000068D9 3C03                <1> 	cmp	al, 3	; AL = 2 => File not found error
   313 000068DB 7202                <1> 	jb	short loc_ccd_path_not_found_retn
   314 000068DD F9                  <1> 	stc
   315 000068DE C3                  <1> 	retn
   316                              <1> 
   317                              <1> loc_ccd_path_not_found_retn:
   318 000068DF B003                <1> 	mov	al, 3	; Path not found
   319 000068E1 C3                  <1> 	retn
   320                              <1> 
   321                              <1> loc_ccd_load_FAT_root_dir:
   322 000068E2 803D[ADA80000]02    <1> 	cmp	byte [Current_FATType], 2
   323 000068E9 776B                <1> 	ja	short loc_ccd_load_FAT32_root_dir
   324                              <1> 
   325                              <1> 	;mov	esi, [CCD_DriveDT]
   326                              <1> 	;push	esi
   327 000068EB E8580F0000          <1> 	call	load_FAT_root_directory
   328                              <1> 	;pop	edi ; Dos Drv Description Table
   329                              <1> 
   330 000068F0 89F7                <1> 	mov	edi, esi
   331 000068F2 BE[0FB10000]        <1> 	mov	esi, PATH_Array
   332 000068F7 7297                <1> 	jc	short loc_ccd_retn_p
   333                              <1> 
   334 000068F9 31C0                <1> 	xor	eax, eax
   335 000068FB EB78                <1>         jmp	short loc_ccd_set_cdfc
   336                              <1> 
   337                              <1> loc_ccd_load_root_dir:
   338 000068FD 803D[ADA80000]01    <1> 	cmp	byte [Current_FATType], 1
   339 00006904 73DC                <1> 	jnb	short loc_ccd_load_FAT_root_dir
   340                              <1> 
   341                              <1> loc_ccd_load_FS_root_dir:
   342 00006906 E804100000          <1> 	call	load_FS_root_directory
   343 0000690B EB5C                <1> 	jmp	short pass_ccd_load_FAT_sub_directory
   344                              <1> 
   345                              <1> loc_ccd_load_FS_sub_directory_next:
   346 0000690D E8FE0F0000          <1> 	call	load_FS_sub_directory
   347 00006912 EB1F                <1> 	jmp	short pass_ccd_set_dir_cluster_ptr  
   348                              <1> 
   349                              <1> loc_ccd_set_dir_cluster_ptr:
   350                              <1> 	; EDI = Directory Entry
   351 00006914 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
   352 00006918 C1E010              <1> 	shl	eax, 16
   353 0000691B 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
   354                              <1> 
   355 0000691F 8B35[8FB10000]      <1> 	mov	esi, [CCD_DriveDT]
   356 00006925 803D[ADA80000]01    <1> 	cmp	byte [Current_FATType], 1
   357 0000692C 72DF                <1> 	jb	short loc_ccd_load_FS_sub_directory_next
   358                              <1> 	;push	esi
   359 0000692E E8A00F0000          <1> 	call	load_FAT_sub_directory
   360                              <1> 	;pop	edi ; Dos Drv Description Table
   361                              <1> 
   362                              <1> pass_ccd_set_dir_cluster_ptr:
   363                              <1> 	;mov	edi, esi
   364 00006933 BE[0FB10000]        <1> 	mov	esi, PATH_Array
   365 00006938 7264                <1> 	jc	short loc_ccd_retn_c
   366                              <1> 
   367 0000693A A1[DDB00000]        <1> 	mov	eax, [DirBuff_Cluster]
   368                              <1> 
   369 0000693F FE05[93B10000]      <1> 	inc	byte [CCD_Level]
   370 00006945 0FB61D[93B10000]    <1> 	movzx	ebx, byte [CCD_Level]
   371 0000694C C0E304              <1> 	shl	bl, 4 ; * 16 (<= 128)   
   372 0000694F 01DE                <1> 	add	esi, ebx ; 19/02/2016
   373 00006951 89460C              <1> 	mov	[esi+12], eax
   374 00006954 EB1F                <1> 	jmp	short loc_ccd_set_cdfc
   375                              <1> 
   376                              <1> loc_ccd_load_FAT32_root_dir:
   377 00006956 BE[0FB10000]        <1> 	mov	esi, PATH_Array
   378 0000695B 8B460C              <1> 	mov	eax, [esi+12]
   379 0000695E 8B35[8FB10000]      <1> 	mov	esi, [CCD_DriveDT]
   380                              <1>  
   381                              <1> loc_ccd_load_FAT_sub_directory:
   382                              <1> 	;push	esi
   383 00006964 E86A0F0000          <1> 	call	load_FAT_sub_directory
   384                              <1> 	;pop	edi ; Dos Drv Description Table
   385                              <1> 
   386                              <1> pass_ccd_load_FAT_sub_directory:
   387                              <1> 	;mov	edi, esi
   388 00006969 BE[0FB10000]        <1> 	mov	esi, PATH_Array
   389 0000696E 722E                <1> 	jc	short loc_ccd_retn_c
   390                              <1> 
   391 00006970 A1[DDB00000]        <1> 	mov	eax, [DirBuff_Cluster]
   392                              <1> 
   393                              <1> loc_ccd_set_cdfc:
   394 00006975 8A0D[93B10000]      <1> 	mov	cl, [CCD_Level]
   395 0000697B 880D[ACA80000]      <1> 	mov	[Current_Dir_Level], cl
   396 00006981 A3[A8A80000]        <1> 	mov	[Current_Dir_FCluster], eax
   397                              <1> 
   398 00006986 8A2D[94B10000]      <1> 	mov	ch, [Last_Dir_Level]
   399 0000698C 38E9                <1> 	cmp	cl, ch 
   400 0000698E 0F821CFFFFFF        <1> 	jb	loc_ccd_load_child_dir_next
   401                              <1> 	
   402 00006994 803D[9DB10000]CD    <1> 	cmp	byte [CD_COMMAND], 0CDh ;'CD' command or another
   403 0000699B 741E                <1> 	je	short loc_ccd_save_current_dir
   404                              <1> 
   405                              <1>         ; jne -> don't save, restore (the previous cdir) later !
   406                              <1>         ; (saving the cdir would prevent previous cdir restoration!)
   407                              <1> 
   408 0000699D F8                  <1> 	clc
   409                              <1> 
   410                              <1> loc_ccd_retn_c:
   411 0000699E 8B3D[8FB10000]      <1> 	mov	edi, [CCD_DriveDT]
   412 000069A4 C3                  <1> 	retn
   413                              <1> 
   414                              <1> loc_ccd_load_sub_directory:
   415 000069A5 8B35[8FB10000]      <1> 	mov	esi, [CCD_DriveDT]
   416 000069AB 803D[ADA80000]01    <1> 	cmp	byte [Current_FATType], 1
   417 000069B2 73B0                <1> 	jnb	short loc_ccd_load_FAT_sub_directory 
   418 000069B4 E8570F0000          <1> 	call	load_FS_sub_directory
   419 000069B9 EBAE                <1> 	jmp	short pass_ccd_load_FAT_sub_directory 
   420                              <1> 
   421                              <1> loc_ccd_save_current_dir:
   422 000069BB BE[0FB10000]        <1> 	mov	esi, PATH_Array ; 19/02/2016
   423 000069C0 8B3D[8FB10000]      <1> 	mov	edi, [CCD_DriveDT]
   424 000069C6 57                  <1> 	push	edi
   425 000069C7 83C77F              <1>         add     edi, LD_CDirLevel
   426 000069CA 880F                <1> 	mov	[edi], cl
   427 000069CC 47                  <1> 	inc	edi ; LD_CurrentDirectory 
   428 000069CD 56                  <1> 	push	esi
   429                              <1> 	;mov	ecx, 32  ; always < 65536 (in this procedure)
   430 000069CE 66B92000            <1> 	mov	cx, 32
   431 000069D2 F3A5                <1> 	rep	movsd
   432                              <1> 	; Current directory has been saved to 
   433                              <1> 	; the DOS drive description table, cdir area !
   434 000069D4 5E                  <1> 	pop	esi  ; PATH_Array
   435 000069D5 5F                  <1> 	pop	edi  ; Dos Drv Description Table
   436                              <1> 
   437 000069D6 C3                  <1> 	retn
   438                              <1> 
   439                              <1> parse_dir_name:
   440                              <1> 	; 11/02/2016
   441                              <1> 	; 10/02/2016
   442                              <1> 	; 07/02/2016 (TRDOS 386 = TRDOS v2.0)
   443                              <1> 	; 18/09/2011
   444                              <1> 	; 17/10/2009
   445                              <1> 	; INPUT ->
   446                              <1> 	;	ESI = ASCIIZ Directory String Address
   447                              <1> 	;	AL = Current Directory Level
   448                              <1> 	;	EDI = Destination Adress
   449                              <1> 	;	     (8 levels, each one 12+4 byte)
   450                              <1> 	; OUTPUT ->
   451                              <1> 	;	EDI = Dir Entry Formatted Array
   452                              <1> 	;	     with zero cluster pointer at the last level
   453                              <1> 	;	AH = Last Dir Level
   454                              <1> 	;	AL = Current Dir Level
   455                              <1> 	;
   456                              <1> 	; (esi, ebx, ecx will be changed) 
   457                              <1> 
   458                              <1> 	;mov	[PATH_Array_Ptr], edi
   459 000069D7 88C4                <1> 	mov	ah, al
   460 000069D9 66A3[34B20000]      <1> 	mov	[PATH_CDLevel], ax
   461                              <1> repeat_ppdn_check_slash:
   462 000069DF AC                  <1> 	lodsb
   463 000069E0 3C2F                <1> 	cmp	al, '/'
   464 000069E2 74FB                <1> 	je	short repeat_ppdn_check_slash
   465 000069E4 3C21                <1> 	cmp	al, 21h
   466 000069E6 7219                <1> 	jb	short loc_ppdn_retn
   467 000069E8 57                  <1> 	push	edi
   468                              <1> loc_ppdn_get_dir_name:
   469 000069E9 B90C000000          <1> 	mov	ecx, 12
   470 000069EE BF[36B20000]        <1> 	mov	edi, Dir_File_Name
   471                              <1> repeat_ppdn_get_dir_name:
   472 000069F3 AA                  <1> 	stosb
   473 000069F4 AC                  <1> 	lodsb
   474 000069F5 3C2F                <1> 	cmp	al, '/'
   475 000069F7 740A                <1> 	je	short loc_check_level_dot_conv_dir_name
   476 000069F9 3C20                <1> 	cmp	al, 20h
   477 000069FB 7605                <1> 	jna	short loc_ppdn_end_of_path_scan
   478 000069FD E2F4                <1> 	loop	repeat_ppdn_get_dir_name
   479 000069FF 5F                  <1> 	pop	edi
   480 00006A00 F9                  <1> 	stc
   481                              <1> loc_ppdn_retn:
   482 00006A01 C3                  <1> 	retn
   483                              <1> 
   484                              <1> loc_ppdn_end_of_path_scan:
   485 00006A02 4E                  <1> 	dec	esi
   486                              <1> loc_check_level_dot_conv_dir_name:
   487 00006A03 31C0                <1> 	xor	eax, eax
   488 00006A05 AA                  <1> 	stosb
   489 00006A06 89F3                <1> 	mov	ebx, esi
   490 00006A08 BE[36B20000]        <1> 	mov	esi, Dir_File_Name
   491 00006A0D AC                  <1> 	lodsb
   492                              <1> repeat_ppdn_name_check_dot:
   493 00006A0E 3C2E                <1> 	cmp	al, '.'
   494 00006A10 7509                <1> 	jne	short loc_ppdn_convert_sub_dir_name
   495                              <1> repeat_ppdn_name_dot_dot:
   496 00006A12 AC                  <1> 	lodsb
   497 00006A13 3C2E                <1> 	cmp	al, '.'
   498 00006A15 743E                <1> 	je	short loc_ppdn_dot_dot
   499 00006A17 3C21                <1> 	cmp	al, 21h
   500 00006A19 7226                <1> 	jb	short pass_ppdn_convert_sub_dir_name
   501                              <1> loc_ppdn_convert_sub_dir_name:
   502 00006A1B 8A25[35B20000]      <1> 	mov	ah, [PATH_Level]
   503 00006A21 80FC07              <1> 	cmp	ah, 7
   504 00006A24 731B                <1> 	jnb	short pass_ppdn_convert_sub_dir_name
   505 00006A26 FEC4                <1> 	inc	ah  
   506 00006A28 8825[35B20000]      <1> 	mov	[PATH_Level], ah
   507 00006A2E BE[36B20000]        <1> 	mov	esi, Dir_File_Name
   508                              <1> 	;mov	edi, [PATH_Array_Ptr]
   509 00006A33 B010                <1> 	mov	al, 16
   510 00006A35 F6E4                <1> 	mul	ah
   511 00006A37 8B3C24              <1> 	mov	edi, [esp]
   512                              <1> 	;push	edi 
   513 00006A3A 01C7                <1> 	add	edi, eax
   514 00006A3C E828030000          <1> 	call	convert_file_name
   515                              <1> 	;pop	edi
   516                              <1> pass_ppdn_convert_sub_dir_name:
   517 00006A41 89DE                <1> 	mov	esi, ebx
   518                              <1> repeat_ppdn_check_last_slash:
   519 00006A43 AC                  <1> 	lodsb
   520 00006A44 3C2F                <1> 	cmp	al, '/'
   521 00006A46 74FB                <1> 	je	short repeat_ppdn_check_last_slash
   522 00006A48 3C21                <1> 	cmp	al, 21h
   523 00006A4A 739D                <1> 	jnb	short loc_ppdn_get_dir_name
   524                              <1> end_of_parse_dir_name:
   525 00006A4C 5F                  <1> 	pop	edi
   526 00006A4D F5                  <1> 	cmc  
   527                              <1> 	;mov	al, [PATH_CDLevel]
   528                              <1> 	;mov	ah, [PATH_Level]
   529 00006A4E 66A1[34B20000]      <1> 	mov	ax, [PATH_CDLevel]
   530 00006A54 C3                  <1> 	retn
   531                              <1> 
   532                              <1> loc_ppdn_dot_dot:
   533 00006A55 AC                  <1> 	lodsb
   534 00006A56 3C21                <1> 	cmp	al, 21h
   535 00006A58 73F2                <1> 	jnb	short end_of_parse_dir_name 
   536                              <1> loc_ppdn_dot_dot_prev_level:
   537 00006A5A 66A1[34B20000]      <1> 	mov	ax, [PATH_CDLevel]
   538 00006A60 80EC01              <1> 	sub	ah, 1
   539 00006A63 80D400              <1> 	adc	ah, 0
   540 00006A66 38E0                <1> 	cmp	al, ah
   541 00006A68 7602                <1> 	jna	short pass_ppdn_set_al_to_ah
   542 00006A6A 88E0                <1> 	mov	al, ah
   543                              <1> pass_ppdn_set_al_to_ah:
   544 00006A6C 66A3[34B20000]      <1> 	mov	[PATH_CDLevel], ax
   545 00006A72 EBCD                <1> 	jmp	short pass_ppdn_convert_sub_dir_name
   546                              <1> 
   547                              <1> locate_current_dir_file:
   548                              <1> 	; 14/02/2016
   549                              <1> 	; 13/02/2016
   550                              <1> 	; 10/02/2016
   551                              <1> 	; 06/02/2016 (TRDOS 386 = TRDOS v2.0)
   552                              <1> 	; 14/08/2010
   553                              <1> 	; 19/09/2009
   554                              <1>         ; 2005
   555                              <1> 	; INPUT ->
   556                              <1> 	;	ESI = DOS DirEntry Format FileName Address
   557                              <1> 	;	AL = Attributes Mask 
   558                              <1> 	;	(<AL AND EntryAttrib> must be equal to AL)
   559                              <1> 	;	AH = Negative Attributes Mask (If AH>0)
   560                              <1> 	;	(<AH AND EntryAttrib> must be ZERO)
   561                              <1> 	;	CH > 0 Find First Free Dir Entry or Deleted Entry
   562                              <1> 	;	CL = 0 -> Return the First Free Dir Entry
   563                              <1> 	;	CL = E5h -> Return the 1st deleted entry
   564                              <1> 	;	CL = FFh -> Return the 1st deleted or free entry
   565                              <1> 	;	CL > 0 and CL <> E5h and CL <> FFh -> Return the first 
   566                              <1> 	;	     proper entry (which fits with Atributes Masks)
   567                              <1> 	;	CX = 0 Find Valid File/Directory/VolumeName
   568                              <1> 	;	? = Any One Char
   569                              <1> 	;	* = Every Chars
   570                              <1> 	; OUTPUT ->
   571                              <1> 	;	EDI = Directory Entry Address (in Directory Buffer)
   572                              <1> 	;	ESI = DOS DirEntry Format FileName Address
   573                              <1> 	;	CF = 0 -> No Error, Proper Entry,
   574                              <1> 	;	DL = Attributes
   575                              <1> 	;	DH = Previous Entry Attr (LongName Check)
   576                              <1> 	;	AL > 0 -> Ambiguous filename wildcard "?" used
   577                              <1> 	;	AH > 0 -> Ambiguous filename wildcard "*" used
   578                              <1> 	;	AX = 0 -> Filename full fits with directory entry
   579                              <1> 	;	CH = The 1st Name Char of Current Dir Entry
   580                              <1> 	;	CF = 1 -> Proper entry not found, Error Code in EAX/AL
   581                              <1> 	;	CL = 0 and CH = 0 -> Free Entry (End Of Dir)
   582                              <1> 	;	CL = 0 and CH = E5h -> Deleted Entry fits with filters
   583                              <1> 	;	CL > 0 -> Entry not found, CH invalid
   584                              <1> 	;	CF = 0 -> 
   585                              <1> 	;	EBX = Current Directory Entry Index/Number (BX)
   586                              <1> 
   587                              <1> 	;mov	word [DirBuff_EntryCounter], 0 ; Zero Based
   588                              <1> 
   589 00006A74 8935[97B10000]      <1> 	mov	[CDLF_FNAddress], esi
   590 00006A7A 66A3[95B10000]      <1> 	mov	[CDLF_AttributesMask], ax
   591 00006A80 66890D[9BB10000]    <1> 	mov	[CDLF_DEType], cx
   592                              <1> 
   593 00006A87 31DB                <1> 	xor	ebx, ebx
   594 00006A89 881D[ACB10000]      <1> 	mov	[PreviousAttr], bl ; 0  ; 13/02/2016
   595                              <1> 
   596 00006A8F 8A3D[AEA80000]      <1> 	mov	bh, [Current_Drv]
   597 00006A95 381D[D8B00000]      <1> 	cmp	byte [DirBuff_ValidData], bl ; 0
   598 00006A9B 761D                <1> 	jna	short loc_lcdf_reload_current_dir2
   599 00006A9D 8A1D[D6B00000]      <1>         mov     bl, [DirBuff_DRV]
   600 00006AA3 80EB41              <1> 	sub	bl, 'A'
   601 00006AA6 38DF                <1> 	cmp	bh, bl
   602 00006AA8 750E                <1> 	jne	short loc_lcdf_reload_current_dir1
   603 00006AAA 8B15[DDB00000]      <1> 	mov	edx, [DirBuff_Cluster]
   604 00006AB0 3B15[A8A80000]      <1> 	cmp	edx, [Current_Dir_FCluster]
   605 00006AB6 7412                <1> 	je	short loc_cdir_locatefile_search
   606                              <1> 
   607                              <1> loc_lcdf_reload_current_dir1:
   608 00006AB8 30DB                <1> 	xor	bl, bl
   609                              <1> loc_lcdf_reload_current_dir2:
   610 00006ABA 89DE                <1> 	mov	esi, ebx
   611 00006ABC 81C600010900        <1>         add     esi, Logical_DOSDisks
   612 00006AC2 E872000000          <1> 	call	reload_current_directory 
   613 00006AC7 735B                <1> 	jnc	short loc_locatefile_search_again 
   614 00006AC9 C3                  <1> 	retn  
   615                              <1> 
   616                              <1> loc_cdir_locatefile_search:
   617 00006ACA 31DB                <1> 	xor	ebx, ebx
   618 00006ACC E8A5000000          <1> 	call	find_directory_entry
   619 00006AD1 7349                <1> 	jnc	short loc_cdir_locate_file_retn
   620                              <1> 
   621                              <1> loc_locatefile_check_stc_reason:
   622 00006AD3 08ED                <1> 	or	ch, ch
   623 00006AD5 7444                <1> 	jz	short loc_cdir_locate_file_stc_retn
   624                              <1> 
   625                              <1> loc_locatefile_check_next_entryblock:
   626 00006AD7 8A3D[AEA80000]      <1> 	mov	bh, [Current_Drv]
   627 00006ADD 28DB                <1> 	sub	bl, bl
   628 00006ADF 0FB7F3              <1> 	movzx	esi, bx
   629 00006AE2 81C600010900        <1>         add     esi, Logical_DOSDisks
   630                              <1> 
   631 00006AE8 803D[ACA80000]00    <1> 	cmp	byte [Current_Dir_Level], 0
   632 00006AEF 760A                <1> 	jna	short loc_locatefile_check_FAT_type
   633                              <1>             
   634 00006AF1 803D[ADA80000]01    <1> 	cmp	byte [Current_FATType], 1
   635 00006AF8 730A                <1> 	jnb	short loc_locatefile_load_subdir_cluster
   636 00006AFA C3                  <1> 	retn  
   637                              <1> 
   638                              <1> loc_locatefile_check_FAT_type:
   639 00006AFB 803D[ADA80000]03    <1> 	cmp	byte [Current_FATType], 3
   640 00006B02 7218                <1> 	jb	short loc_cdir_locate_file_retn
   641                              <1> 
   642                              <1> loc_locatefile_load_subdir_cluster:
   643 00006B04 A1[DDB00000]        <1> 	mov	eax, [DirBuff_Cluster]
   644 00006B09 E8E40B0000          <1> 	call	get_next_cluster
   645 00006B0E 730D                <1> 	jnc	short loc_locatefile_next_cluster
   646 00006B10 09C0                <1> 	or	eax, eax
   647 00006B12 7507                <1> 	jnz	short loc_locatefile_drive_not_ready_read_err
   648 00006B14 F9                  <1> 	stc
   649                              <1> loc_locatefile_file_notfound:
   650 00006B15 B802000000          <1> 	mov	eax, 2 ; File/Directory/VolName not found
   651 00006B1A C3                  <1> 	retn
   652                              <1> 
   653                              <1> loc_locatefile_drive_not_ready_read_err:
   654                              <1> 	;mov	eax, 15h ;Drive not ready or read error
   655                              <1> loc_cdir_locate_file_stc_retn:
   656 00006B1B F5                  <1> 	cmc ;stc
   657                              <1> loc_cdir_locate_file_retn:
   658 00006B1C C3                  <1> 	retn
   659                              <1> 
   660                              <1> loc_locatefile_next_cluster:
   661 00006B1D E8B10D0000          <1> 	call	load_FAT_sub_directory
   662                              <1> 	;jc	short loc_locatefile_drive_not_ready_read_err
   663 00006B22 72F8                <1> 	jc	short loc_cdir_locate_file_retn 
   664                              <1> 
   665                              <1> loc_locatefile_search_again:
   666 00006B24 8B35[97B10000]      <1> 	mov	esi, [CDLF_FNAddress] 
   667 00006B2A 66A1[95B10000]      <1> 	mov	ax, [CDLF_AttributesMask]
   668 00006B30 668B0D[9BB10000]    <1> 	mov	cx, [CDLF_DEType] 
   669 00006B37 EB91                <1> 	jmp	short loc_cdir_locatefile_search
   670                              <1> 
   671                              <1> reload_current_directory:
   672                              <1> 	; 06/02/2016 (TRDOS 386 = TRDOS v2.0)
   673                              <1> 	; 13/06/2010
   674                              <1> 	; 22/09/2009
   675                              <1>         ;
   676                              <1> 	; INPUT ->
   677                              <1> 	;	ESI = Dos drive description table address
   678                              <1> 	
   679                              <1> 	;mov	al, [esi+LD_FATType]
   680 00006B39 A0[ADA80000]        <1> 	mov	al, [Current_FATType]
   681 00006B3E 3C02                <1> 	cmp	al, 2
   682 00006B40 7729                <1> 	ja	short loc_reload_FAT_sub_directory
   683 00006B42 8A25[ACA80000]      <1> 	mov	ah, [Current_Dir_Level]
   684 00006B48 08C0                <1> 	or	al, al
   685 00006B4A 740A                <1> 	jz	short loc_reload_FS_directory
   686 00006B4C 08E4                <1> 	or	ah, ah
   687 00006B4E 751B                <1> 	jnz	short loc_reload_FAT_sub_directory
   688                              <1> loc_reload_FAT_12_16_root_directory:
   689 00006B50 E8F30C0000          <1> 	call	load_FAT_root_directory
   690 00006B55 C3                  <1> 	retn
   691                              <1> loc_reload_FS_directory:
   692 00006B56 20E4                <1> 	and	ah, ah
   693 00006B58 7506                <1> 	jnz	short loc_reload_FS_sub_directory 
   694                              <1> loc_reload_FS_root_directory: 
   695 00006B5A E8B00D0000          <1> 	call	load_FS_root_directory
   696 00006B5F C3                  <1> 	retn
   697                              <1> loc_reload_FS_sub_directory:
   698 00006B60 A1[A8A80000]        <1> 	mov	eax, [Current_Dir_FCluster]
   699 00006B65 E8A60D0000          <1> 	call	load_FS_sub_directory
   700 00006B6A C3                  <1> 	retn 
   701                              <1> loc_reload_FAT_sub_directory:
   702 00006B6B A1[A8A80000]        <1> 	mov	eax, [Current_Dir_FCluster]
   703 00006B70 E85E0D0000          <1> 	call	load_FAT_sub_directory
   704 00006B75 C3                  <1> 	retn
   705                              <1> 
   706                              <1> find_directory_entry:
   707                              <1> 	; 14/02/2016
   708                              <1> 	; 13/02/2016
   709                              <1> 	; 10/02/2016
   710                              <1> 	; 06/02/2016 (TRDOS 386 = TRDOS v2.0)
   711                              <1> 	; 14/08/2010 (DIR.ASM, "proc_find_direntry")
   712                              <1> 	; 19/09/2009
   713                              <1> 	; 2005
   714                              <1> 	; INPUT ->
   715                              <1> 	;	ESI = Sub Dir or File Name Address
   716                              <1> 	;	AL = Attributes Mask 
   717                              <1> 	;	(<AL AND EntryAttrib> must be equal to AL)
   718                              <1> 	;	AH = Negative Attributes Mask (If AH>0)
   719                              <1> 	;	(<AH AND EntryAttrib> must be ZERO)
   720                              <1> 	;	CH > 0 Find First Free Dir Entry or Deleted Entry
   721                              <1> 	;	CL = 0 -> Return the First Free Dir Entry
   722                              <1> 	;	CL = E5h -> Return the 1st deleted entry
   723                              <1> 	;	CL = FFh -> Return the 1st deleted or free entry
   724                              <1> 	;	CL > 0 and CL <> E5h and CL <> FFh -> Return the first 
   725                              <1> 	;            proper entry (which fits with Atributes Masks)
   726                              <1> 	;	CX = 0 -> Find Valid File/Directory/VolumeName
   727                              <1> 	;	? = Any One Char
   728                              <1> 	;	* = Every Chars
   729                              <1> 	;	EBX = Current Dir Entry (BX)
   730                              <1> 	;
   731                              <1> 	; OUTPUT -> 
   732                              <1> 	;	EDI = Directory Entry Address (in DirectoryBuffer)
   733                              <1> 	;	ESI = Sub Dir or File Name Address
   734                              <1> 	;	CF = 0 -> No Error, Proper Entry,
   735                              <1> 	;	DL = Attributes
   736                              <1> 	;	DH = Previous Entry Attr (LongName Check)
   737                              <1> 	;	AL > 0 -> Ambiguous filename wildcard "?" used
   738                              <1> 	;	AH > 0 -> Ambiguous filename wildcard "*" used
   739                              <1> 	;	AX = 0 -> Filename full fits with directory entry
   740                              <1> 	;	EBX = CurrentDirEntry (BX)
   741                              <1> 	;	CH = The 1st Name Char of Current Dir Entry
   742                              <1> 	;	CF = 1 -> Proper entry not found, Error Code in AX/AL
   743                              <1> 	;	CL = 0 and CH = 0 -> Free Entry (End Of Dir)
   744                              <1> 	;	CL = 0 and CH = E5h -> Deleted Entry fits with filters
   745                              <1> 	;	CL > 0 -> Entry not found, CH invalid
   746                              <1> 	;
   747                              <1> 	; (EAX, EBX, ECX, EDX, EDI, EBP will be changed)	 
   748                              <1> 
   749 00006B76 663B1D[DBB00000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   750 00006B7D 0F8739010000        <1>         ja      loc_ffde_stc_retn_255
   751                              <1> 
   752                              <1> 	;mov    [DirBuff_CurrentEntry], bx  
   753                              <1> 
   754 00006B83 BF00000800          <1>   	mov	edi, Directory_Buffer
   755 00006B88 66A3[A8B10000]      <1> 	mov	[FDE_AttrMask], ax
   756                              <1> 
   757 00006B8E 29C0                <1> 	sub	eax, eax
   758                              <1>             
   759                              <1> 	;;mov	[PreviousAttr], al ; 0 ;; 13/02/2016
   760 00006B90 66A3[AAB10000]      <1> 	mov	[AmbiguousFileName], ax ; 0
   761                              <1> 
   762 00006B96 6689D8              <1> 	mov	ax, bx
   763 00006B99 66C1E005            <1> 	shl	ax, 5 ; ; * 32 ; Directory entry size
   764 00006B9D 01C7                <1> 	add     edi, eax
   765                              <1> 
   766 00006B9F 08ED                <1> 	or	ch, ch
   767 00006BA1 0F852C010000        <1>         jnz     loc_find_free_deleted_entry_0
   768                              <1> 
   769 00006BA7 08C9                <1> 	or      cl, cl
   770 00006BA9 0F850D010000        <1>         jnz     loc_ffde_stc_retn_255
   771                              <1>  
   772                              <1> check_find_dir_entry:
   773 00006BAF 66A1[A8B10000]      <1> 	mov	ax, [FDE_AttrMask]
   774 00006BB5 8A2F                <1> 	mov	ch, [edi]
   775 00006BB7 80FD00              <1> 	cmp     ch, 0 ; Is it never used entry?
   776 00006BBA 0F86FF000000        <1> 	jna	loc_find_direntry_stc_retn 
   777 00006BC0 56                  <1> 	push	esi
   778 00006BC1 8A570B              <1> 	mov	dl, [edi+0Bh] ; File attributes
   779 00006BC4 80FDE5              <1> 	cmp	ch, 0E5h ; Is it a deleted file?
   780 00006BC7 746D                <1> 	je	short loc_find_dir_next_entry_prevdeleted
   781                              <1> 
   782 00006BC9 80FA0F              <1> 	cmp     dl, 0Fh ; longname sub component check
   783 00006BCC 7505                <1> 	jne     short loc_check_attributes_mask
   784 00006BCE E8ED010000          <1> 	call	save_longname_sub_component
   785                              <1> 
   786                              <1> loc_check_attributes_mask:
   787 00006BD3 88C6                <1> 	mov	dh, al
   788 00006BD5 20D6                <1> 	and	dh, dl    
   789 00006BD7 38F0                <1> 	cmp	al, dh
   790 00006BD9 0F85BA000000        <1>         jne     loc_find_dir_next_entry
   791 00006BDF 20D4                <1> 	and	ah, dl
   792 00006BE1 0F85B2000000        <1>         jnz     loc_find_dir_next_entry
   793 00006BE7 80FA0F              <1> 	cmp	dl, 0Fh
   794 00006BEA 751A                <1> 	jne	short pass_direntry_attr_check
   795                              <1> 
   796 00006BEC 3C0F                <1> 	cmp	al, 0Fh ; AL = 0Fh -> find long name
   797 00006BEE 0F85A5000000        <1>         jne     loc_find_dir_next_entry
   798                              <1> 
   799 00006BF4 5E                  <1> 	pop	esi
   800 00006BF5 6631C0              <1> 	xor	ax, ax
   801 00006BF8 8A35[ACB10000]      <1> 	mov	dh, [PreviousAttr]
   802 00006BFE 66891D[D9B00000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   803 00006C05 C3                  <1> 	retn
   804                              <1> 
   805                              <1> pass_direntry_attr_check:
   806 00006C06 89FD                <1> 	mov	ebp, edi ; 14/02/2016
   807 00006C08 B908000000          <1> 	mov	ecx, 8
   808                              <1> loc_lodsb_find_dir:
   809 00006C0D AC                  <1> 	lodsb
   810 00006C0E 3C2A                <1> 	cmp	al, '*'
   811 00006C10 7508                <1> 	jne	short pass_fde_ambiguous1_check
   812 00006C12 FE05[ABB10000]      <1>         inc     byte [AmbiguousFileName+1]
   813 00006C18 EB28                <1> 	jmp	short loc_check_direntry_extension
   814                              <1> 
   815                              <1> pass_fde_ambiguous1_check:
   816 00006C1A 3C3F                <1> 	cmp	al, '?'
   817 00006C1C 750D                <1> 	jne	short pass_fde_ambiguous2_check
   818 00006C1E FE05[AAB10000]      <1> 	inc	byte [AmbiguousFileName]
   819 00006C24 803F20              <1> 	cmp	byte [edi], 20h
   820 00006C27 764E                <1> 	jna	short loc_find_dir_next_entry_ebp
   821 00006C29 EB14                <1> 	jmp	short loc_scasb_find_dir_inc_di
   822                              <1> 
   823                              <1> pass_fde_ambiguous2_check:
   824 00006C2B 3C20                <1> 	cmp	al, 20h
   825 00006C2D 750C                <1> 	jne	short loc_scasb_find_dir
   826 00006C2F 803F20              <1> 	cmp	byte [edi], 20h
   827 00006C32 7543                <1> 	jne	short loc_find_dir_next_entry_ebp
   828 00006C34 EB0C                <1> 	jmp	short loc_check_direntry_extension
   829                              <1> 
   830                              <1> loc_find_dir_next_entry_prevdeleted:
   831 00006C36 80CA80              <1> 	or	dl, 80h  ; Bit 7 -> deleted entry sign
   832 00006C39 EB5E                <1> 	jmp	short loc_find_dir_next_entry
   833                              <1> 
   834                              <1> loc_scasb_find_dir:
   835 00006C3B 3A07                <1> 	cmp	al, [edi]
   836 00006C3D 7538                <1> 	jne	short loc_find_dir_next_entry_ebp
   837                              <1> loc_scasb_find_dir_inc_di:
   838 00006C3F 47                  <1> 	inc	edi
   839 00006C40 E2CB                <1> 	loop	loc_lodsb_find_dir
   840                              <1> 
   841                              <1> loc_check_direntry_extension:
   842 00006C42 BE08000000          <1> 	mov	esi, 8
   843 00006C47 89F7                <1> 	mov	edi, esi ; 8
   844 00006C49 033424              <1> 	add	esi, [esp] ; Sub Dir or File Name Address
   845 00006C4C 01EF                <1> 	add	edi, ebp
   846 00006C4E B103                <1> 	mov	cl, 3
   847                              <1> loc_lodsb_find_dir_ext:
   848 00006C50 AC                  <1> 	lodsb
   849 00006C51 3C2A                <1> 	cmp	al, '*'
   850 00006C53 7508                <1> 	jne	short pass_fde_ambiguous3_check
   851 00006C55 FE05[ABB10000]      <1> 	inc	byte [AmbiguousFileName+1]
   852 00006C5B EB1E                <1> 	jmp	short loc_find_dir_proper_direntry
   853                              <1> 
   854                              <1> pass_fde_ambiguous3_check:
   855 00006C5D 3C3F                <1> 	cmp	al, '?'
   856 00006C5F 750D                <1> 	jne	short pass_fde_ambiguous4_check
   857 00006C61 FE05[AAB10000]      <1> 	inc	byte [AmbiguousFileName]
   858 00006C67 803F20              <1> 	cmp	byte [edi], 20h
   859 00006C6A 760B                <1> 	jna	short loc_find_dir_next_entry_ebp
   860 00006C6C EB49                <1> 	jmp	short loc_scasb_find_dir_ext_inc_di
   861                              <1> 
   862                              <1> pass_fde_ambiguous4_check:
   863 00006C6E 3C20                <1> 	cmp	al, 20h
   864 00006C70 7541                <1> 	jne	short loc_scasb_find_dir_ext
   865 00006C72 803F20              <1> 	cmp	byte [edi], 20h
   866 00006C75 7404                <1> 	je	short loc_find_dir_proper_direntry
   867                              <1> 
   868                              <1> loc_find_dir_next_entry_ebp:
   869 00006C77 89EF                <1> 	mov	edi, ebp ; 14/02/2016
   870 00006C79 EB1E                <1> 	jmp	short loc_find_dir_next_entry
   871                              <1> 
   872                              <1> loc_find_dir_proper_direntry:
   873 00006C7B 30C9                <1> 	xor	cl, cl
   874                              <1> loc_find_dir_proper_direntry_1:
   875 00006C7D 5E                  <1> 	pop	esi
   876 00006C7E 89EF                <1>         mov     edi, ebp
   877 00006C80 8A2F                <1> 	mov	ch, [edi]
   878 00006C82 8A570B              <1> 	mov     dl, [edi+0Bh] ; Dir entry attributes
   879 00006C85 66A1[AAB10000]      <1> 	mov	ax, [AmbiguousFileName]
   880                              <1> loc_find_dir_proper_direntry_2:
   881 00006C8B 8A35[ACB10000]      <1> 	mov     dh, [PreviousAttr]
   882 00006C91 66891D[D9B00000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   883 00006C98 C3                  <1> 	retn
   884                              <1> 
   885                              <1> loc_find_dir_next_entry:
   886 00006C99 8815[ACB10000]      <1> 	mov	byte [PreviousAttr], dl ; LongName check
   887                              <1> loc_find_dir_next_entry_1:
   888 00006C9F 5E                  <1> 	pop	esi
   889 00006CA0 83C720              <1> 	add	edi, 32
   890                              <1> 	;inc	word [DirBuff_EntryCounter]
   891 00006CA3 6643                <1> 	inc	bx
   892 00006CA5 663B1D[DBB00000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   893 00006CAC 770E                <1> 	ja	short loc_ffde_stc_retn_255
   894 00006CAE E9FCFEFFFF          <1>         jmp     check_find_dir_entry 
   895                              <1> 
   896                              <1> loc_scasb_find_dir_ext:
   897 00006CB3 3A07                <1> 	cmp	al, [edi]
   898 00006CB5 75C0                <1> 	jne	short loc_find_dir_next_entry_ebp
   899                              <1> loc_scasb_find_dir_ext_inc_di:
   900 00006CB7 47                  <1> 	inc	edi
   901 00006CB8 E296                <1> 	loop    loc_lodsb_find_dir_ext
   902 00006CBA EBC1                <1> 	jmp	short loc_find_dir_proper_direntry_1
   903                              <1> 
   904                              <1> loc_ffde_stc_retn_255:
   905                              <1> 	;mov	cx, 0FFFFh
   906 00006CBC 31C9                <1> 	xor	ecx, ecx
   907 00006CBE 49                  <1> 	dec	ecx ; 0FFFFFFFFh
   908                              <1> 	;xor	eax, eax
   909                              <1> loc_find_direntry_stc_retn:
   910                              <1> loc_check_ffde_retn_1:
   911                              <1> 	;mov	ax, 2
   912 00006CBF B802000000          <1> 	mov	eax, 2 ; File Not Found
   913 00006CC4 8A35[ACB10000]      <1> 	mov	dh, [PreviousAttr]
   914 00006CCA 66891D[D9B00000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   915 00006CD1 F9                  <1> 	stc
   916 00006CD2 C3                  <1> 	retn
   917                              <1> 
   918                              <1> loc_find_free_deleted_entry_0:
   919 00006CD3 66A1[A8B10000]      <1> 	mov	ax, [FDE_AttrMask]
   920 00006CD9 8A2F                <1> 	mov	ch, [edi]
   921 00006CDB 8A570B              <1> 	mov	dl, [edi+0Bh] ; File attributes
   922 00006CDE 08C9                <1> 	or	cl, cl 
   923 00006CE0 7407                <1> 	jz	short loc_check_ffde_0_repeat
   924                              <1> 	;cmp	cl, 0E5h
   925                              <1> 	;je	short pass_loc_check_ffde_0_err
   926 00006CE2 80F9FF              <1> 	cmp	cl, 0FFh
   927 00006CE5 7432                <1> 	je	short loc_find_free_deleted_entry_1
   928 00006CE7 EB4D                <1> 	jmp	short pass_loc_check_ffde_0_err
   929                              <1> 
   930                              <1> loc_check_ffde_0_repeat:
   931 00006CE9 08ED                <1> 	or	ch, ch
   932 00006CEB 7511                <1> 	jnz	short loc_check_ffde_0_next
   933                              <1> 
   934                              <1> loc_check_ffde_retn_2:
   935 00006CED 6629C0              <1> 	sub	ax, ax
   936 00006CF0 8A35[ACB10000]      <1> 	mov	dh, [PreviousAttr]
   937 00006CF6 66891D[D9B00000]    <1> 	mov	[DirBuff_CurrentEntry], bx
   938 00006CFD C3                  <1> 	retn
   939                              <1>  
   940                              <1> loc_check_ffde_0_next:
   941 00006CFE 6643                <1> 	inc	bx
   942 00006D00 83C720              <1> 	add	edi, 32
   943                              <1> 	;inc	word [DirBuff_EntryCounter]
   944                              <1> 	 
   945 00006D03 663B1D[DBB00000]    <1>         cmp	bx, [DirBuff_LastEntry]
   946 00006D0A 77B0                <1> 	ja	short loc_ffde_stc_retn_255
   947 00006D0C 8815[ACB10000]      <1> 	mov	[PreviousAttr], dl
   948 00006D12 8A2F                <1> 	mov	ch, [edi]
   949 00006D14 8A570B              <1> 	mov	dl, [edi+0Bh] ; file attributes
   950 00006D17 EBD0                <1> 	jmp	short loc_check_ffde_0_repeat
   951                              <1> 
   952                              <1> loc_find_free_deleted_entry_1:
   953 00006D19 28D2                <1> 	sub	dl, dl      
   954                              <1> loc_find_free_deleted_entry_2:
   955 00006D1B 20ED                <1> 	and	ch, ch  
   956 00006D1D 74CE                <1> 	jz	short loc_check_ffde_retn_2
   957 00006D1F 80FDE5              <1> 	cmp	ch, 0E5h
   958 00006D22 74C9                <1> 	je	short loc_check_ffde_retn_2
   959 00006D24 6643                <1> 	inc	bx
   960 00006D26 83C720              <1> 	add	edi, 32
   961 00006D29 663B1D[DBB00000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   962 00006D30 778A                <1> 	ja	short loc_ffde_stc_retn_255
   963 00006D32 8A2F                <1> 	mov	ch, [edi]
   964 00006D34 EBE5                <1> 	jmp	short loc_find_free_deleted_entry_2
   965                              <1> 
   966                              <1> pass_loc_check_ffde_0_err:
   967 00006D36 38CD                <1> 	cmp	ch, cl
   968 00006D38 741F                <1> 	je	short loc_check_ffde_attrib 
   969                              <1> 
   970 00006D3A 6643                <1> 	inc	bx
   971 00006D3C 83C720              <1> 	add	edi, 32
   972 00006D3F 663B1D[DBB00000]    <1> 	cmp	bx, [DirBuff_LastEntry]
   973 00006D46 0F8770FFFFFF        <1>         ja      loc_ffde_stc_retn_255
   974 00006D4C 8815[ACB10000]      <1> 	mov	[PreviousAttr], dl
   975 00006D52 8A2F                <1> 	mov	ch, [edi]
   976 00006D54 8A570B              <1> 	mov	dl, [edi+0Bh]
   977 00006D57 EBDD                <1> 	jmp	short pass_loc_check_ffde_0_err
   978                              <1> 
   979                              <1> loc_check_ffde_attrib:
   980 00006D59 88C6                <1> 	mov	dh, al
   981 00006D5B 20D6                <1> 	and	dh, dl    
   982 00006D5D 38F0                <1> 	cmp	al, dh
   983 00006D5F 759D                <1> 	jne	short loc_check_ffde_0_next
   984 00006D61 20D4                <1> 	and	ah, dl
   985 00006D63 7599                <1> 	jnz	short loc_check_ffde_0_next
   986 00006D65 30C9                <1> 	xor	cl, cl 
   987 00006D67 EB84                <1>         jmp     loc_check_ffde_retn_2
   988                              <1> 
   989                              <1> convert_file_name:
   990                              <1> 	; 06/03/2016
   991                              <1> 	; 11/02/2016
   992                              <1> 	; 07/02/2016 (TRDOS 386 = TRDOS v2.0)
   993                              <1> 	; 06/10/2009
   994                              <1> 	; 2005
   995                              <1> 	;
   996                              <1> 	; INPUT  ->
   997                              <1> 	;	ESI = Dot File Name Location
   998                              <1> 	;	EDI = Dir Entry Format File Name Location
   999                              <1> 	; OUTPUT ->
  1000                              <1> 	;	EDI = Dir Entry Format File Name Location
  1001                              <1> 	;	ESI = Dot File Name Location (capitalized)
  1002                              <1> 	;
  1003                              <1> 	; (ECX, AL will be changed) 
  1004                              <1>      
  1005 00006D69 56                  <1> 	push	esi  
  1006 00006D6A 57                  <1> 	push	edi
  1007                              <1> 
  1008 00006D6B B90B000000          <1> 	mov	ecx, 11
  1009 00006D70 B020                <1> 	mov	al, 20h
  1010 00006D72 F3AA                <1> 	rep	stosb
  1011                              <1> 
  1012 00006D74 8B3C24              <1> 	mov	edi, [esp]
  1013                              <1> 
  1014 00006D77 B10C                <1> 	mov	cl, 12 ; file name length (max.)
  1015                              <1> 	; 06/03/2016
  1016                              <1> 	; Directory entry name limit (11 bytes) check for
  1017                              <1> 	; 'rename_directory_entry' procedure.
  1018                              <1> 	; (EDI points to Directory Entry)
  1019                              <1> 	; (If the file name would not contain a dot
  1020                              <1> 	; and file name length would be 12, this would cause to
  1021                              <1> 	; overwrite the attributes byte of the directory entry.)
  1022                              <1> 	;
  1023 00006D79 B50B                <1> 	mov	ch, 11 ; directory entry's name length
  1024                              <1> loc_check_first_dot:
  1025 00006D7B 8A06                <1> 	mov	al, [esi]
  1026 00006D7D 3C2E                <1> 	cmp	al, 2Eh
  1027 00006D7F 750C                <1> 	jne	short pass_check_first_dot
  1028 00006D81 8807                <1> 	mov	[edi], al
  1029 00006D83 47                  <1> 	inc	edi
  1030 00006D84 46                  <1> 	inc	esi
  1031 00006D85 FEC9                <1> 	dec	cl
  1032 00006D87 75F2                <1> 	jnz	short loc_check_first_dot
  1033                              <1> 	;;(ecx <= 12)
  1034                              <1> 	;;loop	loc_check_first_dot 
  1035 00006D89 EB30                <1> 	jmp	short stop_convert_file
  1036                              <1> 
  1037                              <1> loc_get_fchar:
  1038 00006D8B 8A06                <1> 	mov	al, [esi]
  1039                              <1> pass_check_first_dot:
  1040 00006D8D 3C61                <1> 	cmp	al, 61h ; 'a'
  1041 00006D8F 7208                <1> 	jb	short pass_name_capitalize
  1042 00006D91 3C7A                <1> 	cmp	al, 7Ah ; 'z'
  1043 00006D93 7704                <1> 	ja	short pass_name_capitalize
  1044 00006D95 24DF                <1> 	and	al, 0DFh
  1045 00006D97 8806                <1> 	mov	[esi], al
  1046                              <1> pass_name_capitalize:
  1047 00006D99 3C21                <1> 	cmp	al, 21h
  1048 00006D9B 721E                <1> 	jb	short stop_convert_file
  1049 00006D9D 3C2E                <1> 	cmp	al, 2Eh ; '.'
  1050 00006D9F 750C                <1> 	jne	short pass_dot_space
  1051                              <1> add_dot_space: 
  1052 00006DA1 80F904              <1> 	cmp	cl, 4
  1053 00006DA4 760E                <1> 	jna	short inc_and_loop
  1054 00006DA6 47                  <1> 	inc	edi
  1055 00006DA7 FECD                <1> 	dec	ch ; 06/03/2016
  1056 00006DA9 FEC9                <1> 	dec	cl
  1057 00006DAB EBF4                <1> 	jmp	short add_dot_space
  1058                              <1> 	
  1059                              <1> 	;mov	al, 4
  1060                              <1> 	;cmp	cl, al
  1061                              <1> 	;jna	short inc_and_loop
  1062                              <1> 	;sub	cl, al
  1063                              <1> 	;add	edi, ecx
  1064                              <1> 	;mov	cl, al
  1065                              <1> 	;jmp	short inc_and_loop	
  1066                              <1> 
  1067                              <1> pass_dot_space:
  1068 00006DAD 8807                <1> 	mov	[edi], al
  1069                              <1> loc_after_double_dot:
  1070                              <1> 	; 06/03/2016
  1071 00006DAF FECD                <1> 	dec	ch ; count down for 11 bytes dir entry limit
  1072 00006DB1 740A                <1> 	jz	short stop_convert_file_x
  1073 00006DB3 47                  <1> 	inc	edi
  1074                              <1> inc_and_loop:
  1075 00006DB4 FEC9                <1> 	dec	cl ; count down for 12 bytes filename limit 
  1076 00006DB6 7403                <1> 	jz	short stop_convert_file	
  1077 00006DB8 46                  <1> 	inc	esi
  1078                              <1> 	;;(ecx <= 12)
  1079                              <1> 	;;loop	loc_get_fchar
  1080 00006DB9 EBD0                <1> 	jmp	short loc_get_fchar
  1081                              <1> 
  1082                              <1> stop_convert_file:
  1083                              <1> 	; 06/03/2016
  1084 00006DBB 30ED                <1> 	xor	ch, ch
  1085                              <1> 	; ECX < 256 ; 'find_first_file' -> xor cl, cl
  1086                              <1> stop_convert_file_x:
  1087 00006DBD 5F                  <1> 	pop	edi
  1088 00006DBE 5E                  <1> 	pop	esi
  1089 00006DBF C3                  <1> 	retn
  1090                              <1>  
  1091                              <1> save_longname_sub_component:
  1092                              <1> 	; 13/02/2016
  1093                              <1> 	; 06/02/2016 (TRDOS 386 = TRDOS v2.0)
  1094                              <1> 	; 28/02/2010
  1095                              <1> 	; 17/10/2009
  1096                              <1> 	; INPUT ->
  1097                              <1> 	;	EDI = Directory Entry    
  1098                              <1> 	;     	// This procedure is called
  1099                              <1> 	;	// from 'find_directory_entry' procedure.
  1100                              <1> 	;	// If the last entry returns with
  1101                              <1> 	;	// a non-zero LongnameFound value and
  1102                              <1> 	;	// if LFN_CheckSum value is equal to
  1103                              <1> 	;	// the next shortname checksum,
  1104                              <1> 	;	// long name is valid.
  1105                              <1> 	;	// If a longname is longer than 65 bytes,
  1106                              <1> 	;	// it is invalid for trdos. (>45h)
  1107                              <1>  
  1108 00006DC0 57                  <1> 	push	edi
  1109 00006DC1 56                  <1> 	push	esi
  1110                              <1> 	;push	ebx
  1111                              <1> 	;push	ecx
  1112                              <1> 	;push	edx
  1113 00006DC2 50                  <1> 	push	eax
  1114                              <1>            
  1115 00006DC3 29C9                <1> 	sub	ecx, ecx
  1116                              <1> 	;sub	eax, eax
  1117 00006DC5 B11A                <1> 	mov	cl, 26
  1118                              <1> 
  1119 00006DC7 0FB607              <1> 	movzx	eax, byte [edi] ; LDIR_Order
  1120 00006DCA 3C41                <1> 	cmp	al, 41h  ; 40h (last long entry sign) + 1
  1121 00006DCC 722B                <1> 	jb	short pass_pslnsc_last_long_entry
  1122                              <1> 
  1123 00006DCE 88C4                <1> 	mov	ah, al
  1124 00006DD0 80EC40              <1> 	sub	ah, 40h
  1125 00006DD3 8825[AEB10000]      <1> 	mov	[LFN_EntryLength], ah
  1126                              <1> 	
  1127 00006DD9 3C45                <1> 	cmp	al, 45h  ; 40h (last long entry sign) + 5
  1128                              <1>  		; Max 130 byte length is usable in TRDOS
  1129                              <1> ; 26*5 = 130
  1130 00006DDB 7753                <1> 	ja	short loc_pslnsc_retn
  1131                              <1> 
  1132 00006DDD 2407                <1> 	and	al, 07h ; 0Fh
  1133 00006DDF A2[ADB10000]        <1> 	mov	[LongNameFound], al
  1134                              <1> 
  1135 00006DE4 FEC8                <1> 	dec	al
  1136                              <1> 	;mov	cl, 26
  1137 00006DE6 F6E1                <1> 	mul	cl
  1138                              <1> 
  1139 00006DE8 89C6                <1> 	mov	esi, eax
  1140 00006DEA 01CE                <1> 	add	esi, ecx
  1141                              <1> 		; to make is an ASCIZZ string
  1142                              <1> 		; with ax+26 bytes length
  1143 00006DEC 81C6[B0B10000]      <1> 	add	esi, LongFileName
  1144 00006DF2 66C7060000          <1> 	mov	word [esi], 0   
  1145 00006DF7 EB16                <1> 	jmp	short loc_pslsc_move_ldir_name2 
  1146                              <1> 
  1147                              <1> pass_pslnsc_last_long_entry:
  1148 00006DF9 3C04                <1> 	cmp	al, 04h
  1149 00006DFB 7733                <1> 	ja	short loc_pslnsc_retn
  1150 00006DFD FE0D[ADB10000]      <1> 	dec	byte [LongNameFound]
  1151 00006E03 3A05[ADB10000]      <1> 	cmp	al, [LongNameFound]
  1152 00006E09 7525                <1> 	jne	short loc_pslnsc_retn
  1153                              <1> 
  1154                              <1> loc_pslsc_move_ldir_name1:
  1155 00006E0B FEC8                <1> 	dec	al
  1156                              <1> 	;mov	cl, 26
  1157 00006E0D F6E1                <1> 	mul	cl
  1158                              <1> 
  1159                              <1> loc_pslsc_move_ldir_name2:
  1160 00006E0F 8A4F0D              <1> 	mov	cl, [edi+0Dh] ; long name checksum
  1161 00006E12 880D[AFB10000]      <1> 	mov	[LFN_CheckSum], cl 
  1162 00006E18 89FE                <1> 	mov	esi, edi ; LDIR_Order
  1163 00006E1A BF[B0B10000]        <1> 	mov	edi, LongFileName
  1164 00006E1F 01C7                <1> 	add	edi, eax
  1165 00006E21 46                  <1> 	inc	esi
  1166 00006E22 B105                <1> 	mov	cl, 5 ; chars 1 to 5
  1167 00006E24 F366A5              <1> 	rep	movsw
  1168 00006E27 83C603              <1> 	add	esi, 3
  1169 00006E2A A5                  <1> 	movsd	; char 6 & 7 
  1170 00006E2B A5                  <1> 	movsd	; char 8 & 9
  1171 00006E2C A5                  <1> 	movsd	; char 10 & 11
  1172 00006E2D 46                  <1> 	inc	esi
  1173 00006E2E 46                  <1> 	inc	esi 
  1174 00006E2F A5                  <1> 	movsd   ; char 12 & 13 
  1175                              <1> 
  1176                              <1> loc_pslnsc_retn:
  1177 00006E30 58                  <1>  	pop	eax
  1178                              <1> 	;pop	edx
  1179                              <1> 	;pop	ecx
  1180                              <1> 	;pop	ebx
  1181 00006E31 5E                  <1> 	pop	esi  
  1182 00006E32 5F                  <1> 	pop	edi
  1183                              <1>  
  1184 00006E33 C3                  <1>     	retn
  1185                              <1> 
  1186                              <1> parse_path_name:
  1187                              <1> 	; 10/02/2016
  1188                              <1> 	; 08/02/2016 (TRDOS 386 = TRDOS v2.0)
  1189                              <1> 	; 10/009/2011 ('proc_parse_pathname')
  1190                              <1> 	; 27/11/2009
  1191                              <1> 	; 05/12/2004
  1192                              <1> 	;
  1193                              <1> 	; INPUT ->
  1194                              <1> 	;	ESI = Beginning of ASCIIZ pathname string
  1195                              <1> 	;       EDI = Destination Address
  1196                              <1> 	;	      (which is TR-DOS FindFile data buffer)
  1197                              <1> 	; OUTPUT ->
  1198                              <1> 	;	CF = 1 -> Error
  1199                              <1> 	;	     EAX = Error Code (AL)
  1200                              <1> 	;
  1201                              <1> 	; (Modified registers: eax, ecx, esi, edi) 
  1202                              <1> 	
  1203                              <1> 	; Clear the pathname bytes in TR-DOS Findfile data buffer 
  1204 00006E34 57                  <1> 	push	edi
  1205 00006E35 B914000000          <1> 	mov	ecx, 20  ; 80 bytes
  1206 00006E3A 31C0                <1> 	xor	eax, eax
  1207 00006E3C F3AB                <1> 	rep	stosd 
  1208 00006E3E 5F                  <1> 	pop	edi
  1209                              <1> 
  1210 00006E3F 668B06              <1> 	mov	ax, [esi]
  1211 00006E42 80FC3A              <1> 	cmp	ah, ':'
  1212 00006E45 741C                <1> 	je	short loc_ppn_change_drive
  1213 00006E47 A0[AEA80000]        <1> 	mov	al, [Current_Drv]
  1214 00006E4C EB33                <1> 	jmp	short pass_ppn_change_drive
  1215                              <1> 
  1216                              <1> pass_ppn_cdir:
  1217 00006E4E 8B35[D2B20000]      <1> 	mov	esi, [First_Path_Pos]
  1218 00006E54 AC                  <1> 	lodsb
  1219                              <1> loc_ppn_get_filename:
  1220 00006E55 83C741              <1> 	add	edi, 65 ; FindFile_Name location
  1221                              <1> 	; TRDOS Filename length must not be more than 12 bytes
  1222                              <1> 	;mov	ecx, 12
  1223 00006E58 B10C                <1> 	mov	cl, 12
  1224                              <1> loc_ppn_get_fnchar_next:
  1225 00006E5A AA                  <1> 	stosb
  1226 00006E5B AC                  <1> 	lodsb
  1227 00006E5C 3C21                <1> 	cmp	al, 21h
  1228 00006E5E 7274                <1> 	jb	short loc_ppn_clc_return 
  1229 00006E60 E2F8                <1>         loop    loc_ppn_get_fnchar_next
  1230                              <1> loc_ppn_return:
  1231 00006E62 C3                  <1> 	retn
  1232                              <1> 
  1233                              <1> loc_ppn_change_drive:
  1234 00006E63 24DF                <1> 	and	al, 0DFh
  1235 00006E65 2C41                <1> 	sub	al, 'A'; A:
  1236 00006E67 726F                <1> 	jc	short loc_ppn_invalid_drive
  1237 00006E69 3805[7C990000]      <1> 	cmp	[Last_DOS_DiskNo], al
  1238 00006E6F 7267                <1> 	jb	short loc_ppn_invalid_drive
  1239                              <1> 
  1240 00006E71 46                  <1> 	inc	esi
  1241 00006E72 46                  <1> 	inc	esi
  1242 00006E73 8A26                <1> 	mov	ah, [esi]
  1243 00006E75 80FC21              <1> 	cmp	ah, 21h
  1244 00006E78 7307                <1> 	jnb	short pass_ppn_change_drive
  1245                              <1> 
  1246                              <1> loc_ppn_cmd_failed:
  1247                              <1> 	; File or directory name is not existing
  1248 00006E7A 8807                <1> 	mov	[edi], al ; Drv 
  1249 00006E7C 66B80100            <1> 	mov	ax, 1 ; eax = 1
  1250                              <1> 	; TR-DOS Error Code 1h = Bad Command Argument
  1251                              <1> 	; MS-DOS Error Code 1h : Invalid Function Number
  1252                              <1> 	;stc
  1253                              <1> 	; (MainProg ErrMsg: "Bad command or file name!")
  1254 00006E80 C3                  <1> 	retn
  1255                              <1> 
  1256                              <1> pass_ppn_change_drive:
  1257 00006E81 8935[D2B20000]      <1> 	mov	[First_Path_Pos], esi
  1258 00006E87 C705[D6B20000]0000- <1> 	mov	dword [Last_Slash_Pos], 0
  1258 00006E8F 0000                <1>
  1259 00006E91 AA                  <1> 	stosb
  1260 00006E92 8A06                <1> 	mov	al, [esi]
  1261                              <1> loc_scan_ppn_dslash:
  1262 00006E94 3C2F                <1> 	cmp	al, '/'
  1263 00006E96 7506                <1>   	jne	short loc_scan_next_slash_pos
  1264 00006E98 8935[D6B20000]      <1> 	mov	[Last_Slash_Pos], esi
  1265                              <1> loc_scan_next_slash_pos:
  1266 00006E9E 46                  <1> 	inc	esi
  1267 00006E9F 8A06                <1> 	mov	al, [esi]
  1268 00006EA1 3C20                <1> 	cmp	al, 20h
  1269 00006EA3 77EF                <1> 	ja	short loc_scan_ppn_dslash
  1270 00006EA5 833D[D6B20000]00    <1> 	cmp	dword [Last_Slash_Pos], 0
  1271 00006EAC 76A0                <1> 	jna	short pass_ppn_cdir
  1272                              <1> 	
  1273 00006EAE 8B0D[D6B20000]      <1> 	mov	ecx, [Last_Slash_Pos]
  1274 00006EB4 8B35[D2B20000]      <1> 	mov	esi, [First_Path_Pos]
  1275 00006EBA 29F1                <1> 	sub	ecx, esi
  1276 00006EBC 41                  <1> 	inc	ecx
  1277                              <1> 	;cmp	ecx, 64
  1278 00006EBD 80F940              <1> 	cmp	cl, 64
  1279 00006EC0 7715                <1> 	ja	short loc_ppn_invalid_drive_stc
  1280                              <1> 
  1281 00006EC2 89F8                <1> 	mov	eax, edi ; Dest Dir String Location (65 byte)
  1282 00006EC4 F3A4                <1> 	rep	movsb
  1283                              <1> 	;mov	[edi], cl ; 0, End of Dir String
  1284 00006EC6 8B35[D6B20000]      <1> 	mov	esi, [Last_Slash_Pos]
  1285 00006ECC 46                  <1> 	inc	esi
  1286 00006ECD 89C7                <1> 	mov	edi, eax
  1287 00006ECF AC                  <1> 	lodsb
  1288 00006ED0 3C21                <1> 	cmp	al, 21h
  1289 00006ED2 7381                <1> 	jnb	short loc_ppn_get_filename
  1290                              <1> loc_ppn_clc_return:
  1291                              <1> 	;clc
  1292 00006ED4 31C0                <1> 	xor	eax, eax
  1293 00006ED6 C3                  <1> 	retn
  1294                              <1> 
  1295                              <1> loc_ppn_invalid_drive_stc:
  1296 00006ED7 F5                  <1> 	cmc	 ; stc
  1297                              <1> loc_ppn_invalid_drive:
  1298                              <1> 	; cf = 1
  1299                              <1> 	; The Drive Letter/Char < "A" or > "Z"
  1300 00006ED8 66B80F00            <1> 	mov	ax, 0Fh
  1301                              <1> 	; MS-DOS Error Code 0Fh = Disk Drive Invalid 
  1302                              <1> 	; (MainProg ErrMsg: "Drive not ready or read error!")
  1303 00006EDC C3                  <1> 	retn
  1304                              <1> 
  1305                              <1> find_longname:
  1306                              <1> 	; 13/02/2016 (TRDOS 386 = TRDOS v2.0)
  1307                              <1> 	; 24/01/2010 (DIR.ASM, 'proc_find_longname')
  1308                              <1> 	; 17/10/2009
  1309                              <1> 	
  1310                              <1> 	; INPUT -> 
  1311                              <1> 	;	ESI = DOS short file name address
  1312                              <1> 	; 	for example: "filename.ext"
  1313                              <1> 	;
  1314                              <1> 	; OUTPUT ->
  1315                              <1> 	; 	ESI = ASCIIZ longname address (cf = 0)
  1316                              <1> 	;	cf = 1 -> error number returns in EAX (AL)
  1317                              <1> 	;	AL = 0 & CF=1 -> longname not found
  1318                              <1> 	;	     the file/directory has no longname
  1319                              <1> 	; 	cf = 0 -> AL = FAT Type 
  1320                              <1>  
  1321                              <1> 	; 17/10/2009
  1322                              <1> 	; ASCIIZ string will be returned
  1323                              <1> 	; as LongFileName
  1324                              <1> 	; clearing/reset is not needed
  1325                              <1> 	;mov	ecx, 33
  1326                              <1> 	;mov	edi, LongFileName
  1327                              <1> 	;sub	ax, ax ; 0
  1328                              <1> 	;rep	stosw
  1329                              <1> 
  1330                              <1> 	;mov	byte [LongNameFound], 0
  1331                              <1> 
  1332                              <1> 	; ESI = ASCIIZ file/directory name address
  1333                              <1> 	;   AL = Attributes AND mask 
  1334                              <1> 	;	(Result of AND must be equal to AL)
  1335                              <1> 	;   AH = Negative attributes mask 
  1336                              <1> 	;	(Result of AND must be ZERO)
  1337 00006EDD 66B80008            <1> 	mov	ax, 0800h 
  1338                              <1> 		; it must not be volume name or longname
  1339 00006EE1 E8DBE9FFFF          <1> 	call	find_first_file
  1340 00006EE6 7216                <1> 	jc	short loc_fln_retn
  1341                              <1>  
  1342                              <1> loc_fln_check_FAT_Type:
  1343 00006EE8 803D[ADA80000]01    <1> 	cmp	byte [Current_FATType], 1
  1344 00006EEF 7306                <1> 	jnb	short loc_fln_check_longname_yes_sign
  1345                              <1> 
  1346 00006EF1 E839000000          <1> 	call	get_fs_longname
  1347 00006EF6 C3                  <1> 	retn
  1348                              <1> 
  1349                              <1> loc_fln_check_longname_yes_sign:
  1350 00006EF7 08FF                <1> 	or	bh, bh
  1351 00006EF9 7504                <1> 	jnz	short loc_fln_check_longnamefound_number
  1352                              <1> loc_fln_longname_not_found_retn:
  1353 00006EFB 31C0                <1> 	xor	eax, eax 
  1354                              <1> 	; cf = 1 & al = 0 -> longname not found
  1355 00006EFD F9                  <1> 	stc
  1356                              <1> loc_fln_retn:
  1357 00006EFE C3                  <1> 	retn
  1358                              <1> 
  1359                              <1> loc_fln_check_longnamefound_number:
  1360                              <1> 	; 'LongNameFound' is set by
  1361                              <1>         ; by 'save_longname_sub_component'
  1362                              <1> 	; which is called from
  1363                              <1> 	; 'find_directory_entry' 
  1364                              <1> 	; which is called from 
  1365                              <1> 	; 'find_first_file'
  1366                              <1> 	; It must 1 if the longname is valid
  1367 00006EFF 803D[ADB10000]01    <1>         cmp     byte [LongNameFound], 1
  1368 00006F06 75F3                <1> 	jne	short loc_fln_longname_not_found_retn
  1369                              <1>              
  1370                              <1> loc_fln_calculate_checksum: 
  1371 00006F08 E813000000          <1> 	call	calculate_checksum
  1372                              <1> 	; AL = shortname checksum
  1373                              <1> 
  1374                              <1> loc_fln_longname_validation:
  1375                              <1> 	; 'LFN_CheckSum' has been set already
  1376                              <1> 	; by 'save_longname_sub_component'
  1377                              <1> 	; which is called from
  1378                              <1> 	; 'find_directory_entry' 
  1379                              <1> 	; which is called from 
  1380                              <1> 	; 'find_first_file'
  1381 00006F0D 3805[AFB10000]      <1> 	cmp	[LFN_CheckSum], al
  1382 00006F13 75E6                <1> 	jne	short loc_fln_longname_not_found_retn
  1383                              <1> 
  1384 00006F15 BE[B0B10000]        <1> 	mov	esi, LongFileName
  1385 00006F1A A0[ADA80000]        <1> 	mov	al, [Current_FATType]
  1386 00006F1F C3                  <1> 	retn
  1387                              <1> 
  1388                              <1> calculate_checksum:
  1389                              <1> 	; 13/02/2016 (TRDOS 386 = TRDOS v2.0)
  1390                              <1> 	; 17/10/2009 (DIR.ASM, 'proc_calculate_checksum')
  1391                              <1>         ;    
  1392                              <1> 	; INPUT ->
  1393                              <1> 	;	ESI = 11 byte DOS File Name location
  1394                              <1> 	;	(in DOS Directory Entry Format)
  1395                              <1> 	; OUTPUT ->
  1396                              <1> 	;	 AL = 8 bit checksum (CRC) value
  1397                              <1> 	;
  1398                              <1> 	; (Modified registers: EAX, ECX, ESI)
  1399                              <1> 
  1400                              <1> 	; Erdogan Tan [ 17-10-2009 ]
  1401                              <1> 	;  'ror al, 1' instruction
  1402                              <1> 
  1403                              <1> 	; Erdogan Tan [ 20-06-2004 ]
  1404                              <1> 	; This 8086 assembly code is an original code
  1405                              <1> 	; which is adapted from C code in
  1406                              <1> 	; Microsoft FAT32 File System Specification
  1407                              <1> 	; Version 1.03, December 6, 2000
  1408                              <1> 	; Page 28
  1409                              <1> 
  1410 00006F20 30C0                <1> 	xor	al, al
  1411 00006F22 B90B000000          <1> 	mov	ecx, 11
  1412                              <1> loc_next_sum:
  1413                              <1> 	;xor	ah, ah
  1414                              <1> 	;test	al, 1
  1415                              <1> 	;jz	short pass_ah_80h
  1416                              <1> 	;mov	ah, 80h
  1417                              <1> ;pass_ah_80h:
  1418                              <1> 	;shr	al, 1
  1419 00006F27 D0C8                <1> 	ror	al, 1 ; 17/10/2009  
  1420 00006F29 0206                <1> 	add	al, [esi]
  1421 00006F2B 46                  <1> 	inc	esi
  1422                              <1> 	;add	al, ah
  1423 00006F2C E2F9                <1> 	loop	loc_next_sum
  1424 00006F2E C3                  <1> 	retn
  1425                              <1> 
  1426                              <1> get_fs_longname:
  1427                              <1> 	; temporary (13/02/2016)
  1428 00006F2F 31C0                <1> 	xor eax, eax
  1429 00006F31 F9                  <1> 	stc
  1430 00006F32 C3                  <1> 	retn
  1431                              <1> 
  1432                              <1> make_sub_directory:
  1433                              <1> 	; 03/03/2016
  1434                              <1> 	; 02/03/2016
  1435                              <1> 	; 27/02/2026
  1436                              <1> 	; 26/02/2016
  1437                              <1> 	; 21/02/2016 (TRDOS 386 = TRDOS v2.0)
  1438                              <1> 	; 01/08/2011 (DIR.ASM, 'proc_make_directory')
  1439                              <1> 	; 10/07/2010
  1440                              <1> 	; INPUT ->
  1441                              <1> 	; 	ESI = ASCIIZ Directory Name
  1442                              <1> 	;	CL = Directory Attributes
  1443                              <1> 	; OUTPUT ->
  1444                              <1> 	;	EAX = New sub dir's first cluster
  1445                              <1> 	;	ESI = Logical Dos Drv Descr. Table Addr.
  1446                              <1> 	;	CF = 1 -> error code in AL (EAX)
  1447                              <1> 
  1448                              <1> 	;test	cl, 10h  ; directory
  1449                              <1> 	;jz	short loc_make_directory_access_denied
  1450                              <1> 	;test	cl, 08h ; volume name
  1451                              <1> 	;jnz	short loc_make_directory_access_denied
  1452                              <1> 
  1453 00006F33 80E107              <1> 	and	cl, 07h
  1454 00006F36 880D[2CB30000]      <1> 	mov	byte [mkdir_attrib], cl
  1455                              <1> 
  1456 00006F3C 56                  <1> 	push	esi
  1457 00006F3D 31DB                <1> 	xor	ebx, ebx
  1458 00006F3F 8A3D[AEA80000]      <1> 	mov	bh, [Current_Drv]
  1459 00006F45 BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1460 00006F4A 01DE                <1> 	add	esi, ebx
  1461 00006F4C 5B                  <1> 	pop	ebx
  1462                              <1> 
  1463                              <1> 	; 10/07/2010 -> 1st writable disk check for trdos
  1464                              <1> 	; LD_DiskType = 0 for write protection (read only) 
  1465 00006F4D 807E0101            <1> 	cmp	byte [esi+LD_DiskType], 1 ; 0 = Invalid
  1466 00006F51 730B                <1> 	jnb	short loc_mkdir_check_file_sytem
  1467 00006F53 B813000000          <1> 	mov	eax, 13h ; MSDOS err => Disk write-protected 
  1468 00006F58 BA00000000          <1> 	mov	edx, 0
  1469                              <1> 	; err retn: EDX = 0, EBX = Dir name offset
  1470                              <1> 	;ESI = Logical DOS drive description table address
  1471 00006F5D C3                  <1> 	retn
  1472                              <1> 
  1473                              <1> ;loc_make_directory_access_denied:
  1474                              <1> 	;mov	ax, 05h ; access denied (invalid attributes input)
  1475                              <1> 	;stc
  1476                              <1> 	;retn
  1477                              <1> 
  1478                              <1> loc_mkdir_check_file_sytem:
  1479 00006F5E 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  1480 00006F62 730B                <1> 	jnb	short loc_mkdir_check_free_sectors
  1481                              <1> 
  1482                              <1> loc_make_fs_directory:
  1483 00006F64 A1[A8A80000]        <1> 	mov	eax, [Current_Dir_FCluster]
  1484                              <1> 	; EAX = Parent directory DDT Address
  1485                              <1> 	; ESI = Logical DOS Drive DT Address
  1486                              <1> 	; EBX = Directory name offset (as ASCIIZ name)
  1487 00006F69 E881070000          <1> 	call	make_fs_directory
  1488 00006F6E C3                  <1> 	retn
  1489                              <1> 
  1490                              <1> loc_mkdir_check_free_sectors:
  1491 00006F6F 0FB64613            <1>         movzx   eax, byte [esi+LD_BPB+SecPerClust]
  1492 00006F73 8B4E74              <1> 	mov	ecx, [esi+LD_FreeSectors]
  1493 00006F76 39C1                <1> 	cmp	ecx, eax
  1494 00006F78 7255                <1> 	jb	short loc_mkdir_insufficient_disk_space
  1495                              <1> 
  1496                              <1> loc_make_fat_directory:
  1497 00006F7A 891D[1CB30000]      <1> 	mov	[mkdir_DirName_Offset], ebx
  1498 00006F80 890D[28B30000]      <1> 	mov	[mkdir_FreeSectors], ecx
  1499                              <1> 
  1500                              <1> 	;mov	al, [esi+LD_BPB+SecPerClust]
  1501 00006F86 A2[2EB30000]        <1> 	mov	byte [mkdir_SecPerClust], al
  1502                              <1> 
  1503                              <1> loc_mkdir_gffc_1:
  1504 00006F8B E8B0090000          <1> 	call	get_first_free_cluster
  1505 00006F90 722A                <1> 	jc	short loc_mkdir_gffc_retn
  1506                              <1> 
  1507                              <1> ;loc_mkdir_gffc_1_cont: 
  1508                              <1> 	;cmp	eax, 2
  1509                              <1> 	;jb	short loc_mkdir_gffc_insufficient_disk_space
  1510                              <1> 
  1511                              <1> ;loc_mkdir_gffc_1_save_fcluster:  
  1512 00006F92 A3[20B30000]        <1> 	mov	[mkdir_FFCluster], eax
  1513                              <1> 
  1514                              <1> loc_mkdir_locate_ffe:
  1515                              <1> 	; Current directory fcluster <> Directory buffer cluster
  1516                              <1> 	; Current directory will be reloaded by
  1517                              <1> 	; 'locate_current_dir_file' procedure
  1518                              <1> 	;
  1519                              <1> 	; ESI = Logical DOS Drive Description Table Address 
  1520                              <1> 	;push	esi ; 27/02/2016
  1521 00006F97 31C0                <1> 	xor	eax, eax
  1522 00006F99 89C1                <1>         mov	ecx, eax
  1523 00006F9B 6649                <1> 	dec	cx ; FFFFh  
  1524                              <1> 	; CX = FFFFh -> find first deleted or free entry
  1525                              <1> 	; ESI would be ASCIIZ filename address if the call
  1526                              <1> 	; would not be for first free or deleted dir entry
  1527 00006F9D E8D2FAFFFF          <1> 	call	locate_current_dir_file
  1528 00006FA2 734C                <1> 	jnc	short loc_mkdir_set_ff_dir_entry_1
  1529                              <1> 	;pop	esi 
  1530                              <1> 	; ESI = Logical DOS Drive Description Table Address 
  1531 00006FA4 83F802              <1> 	cmp	eax, 2  ; cmp al, 2 ; File/Dir not found !
  1532 00006FA7 752B                <1> 	jne	short loc_mkdir_stc_return
  1533                              <1> 
  1534                              <1> loc_mkdir_add_new_cluster:
  1535 00006FA9 3805[ADA80000]      <1> 	cmp	byte [Current_FATType], al ; 2
  1536                              <1> 	;cmp	byte ptr [esi+LD_FATType], 2
  1537 00006FAF 770C                <1> 	ja	short loc_mkdir_add_new_cluster_check_fsc
  1538 00006FB1 803D[ACA80000]01    <1> 	cmp	byte [Current_Dir_Level], 1
  1539                              <1> 	;cmp	byte [esi+LD_CDirLevel], 1
  1540 00006FB8 7303                <1> 	jnb	short loc_mkdir_add_new_cluster_check_fsc
  1541                              <1> 
  1542 00006FBA B00C                <1> 	mov	al, 12 ; No more files 
  1543                              <1> loc_mkdir_gffc_retn:
  1544 00006FBC C3                  <1> 	retn
  1545                              <1> 
  1546                              <1> loc_mkdir_add_new_cluster_check_fsc:
  1547 00006FBD 8B0D[28B30000]      <1> 	mov	ecx, [mkdir_FreeSectors]
  1548                              <1> 	;movzx	eax, byte [mkdir_SecPerClust]
  1549 00006FC3 A0[2EB30000]        <1> 	mov	al, [mkdir_SecPerClust]
  1550 00006FC8 66D1E0              <1> 	shl	ax, 1 ; AX = 2 * AX
  1551 00006FCB 39C1                <1> 	cmp	ecx, eax
  1552 00006FCD 7350                <1> 	jnb	short loc_mkdir_add_new_subdir_cluster
  1553                              <1> 
  1554                              <1> loc_mkdir_insufficient_disk_space:
  1555                              <1> 	;mov	edx, ecx
  1556                              <1> ;loc_mkdir_gffc_insufficient_disk_space:
  1557 00006FCF 66B82700            <1> 	mov	ax, 27h ; MSDOS err => insufficient disk space
  1558                              <1> 	; err retn: EDX = Free sectors, EBX = Dir name offset
  1559                              <1>         ; ESI -> Dos drive description table address
  1560                              <1> 	;; ecx = edx
  1561                              <1> 	;
  1562 00006FD3 C3                  <1> 	retn
  1563                              <1> 
  1564                              <1> loc_mkdir_stc_return:
  1565 00006FD4 F9                  <1> 	stc
  1566 00006FD5 C3                  <1> 	retn 
  1567                              <1> 
  1568                              <1> loc_mkdir_gffc_2:
  1569 00006FD6 E865090000          <1> 	call	get_first_free_cluster
  1570 00006FDB 72DF                <1> 	jc	short loc_mkdir_gffc_retn
  1571                              <1> 
  1572                              <1> ;loc_mkdir_gffc_1_cont: 
  1573                              <1> 	;cmp	eax, 2
  1574                              <1> 	;jb	short loc_mkdir_gffc_insufficient_disk_space
  1575                              <1> 
  1576                              <1> ;loc_mkdir_gffc_2_save_fcluster:  
  1577 00006FDD A3[20B30000]        <1> 	mov	[mkdir_FFCluster], eax
  1578                              <1> 
  1579 00006FE2 A1[24B30000]        <1> 	mov	eax, [mkdir_LastDirCluster]
  1580                              <1> 
  1581 00006FE7 E8E7080000          <1> 	call	load_FAT_sub_directory 
  1582 00006FEC 72CE                <1> 	jc	short loc_mkdir_gffc_retn
  1583                              <1> 
  1584 00006FEE 31FF                <1> 	xor	edi, edi
  1585                              <1> loc_mkdir_set_ff_dir_entry_1:
  1586                              <1> 	; 27/02/2016
  1587 00006FF0 56                  <1> 	push	esi ; Logical DOS Drv Desc. Tbl. address
  1588                              <1> 	; EDI = Directory Entry Address
  1589 00006FF1 8B35[1CB30000]      <1> 	mov	esi, [mkdir_DirName_Offset]
  1590 00006FF7 A1[20B30000]        <1> 	mov	eax, [mkdir_FFCluster]
  1591                              <1> 
  1592 00006FFC 66B91000            <1> 	mov	cx, 10h	; CL = Directory attribute
  1593                              <1> 			; CH = 0 -> File size is 0
  1594 00007000 0A0D[2CB30000]      <1> 	or	cl, [mkdir_attrib] ; S, H, R  
  1595 00007006 E8B0010000          <1> 	call	make_directory_entry
  1596                              <1> 
  1597 0000700B 5E                  <1> 	pop	esi
  1598                              <1> 
  1599 0000700C C605[D8B00000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1600 00007013 E880020000          <1> 	call	save_directory_buffer
  1601 00007018 0F83DA000000        <1>         jnc     loc_mkdir_set_ff_dir_entry_2
  1602                              <1> 
  1603                              <1> loc_mkdir_return:
  1604 0000701E C3                  <1> 	retn
  1605                              <1> 
  1606                              <1> loc_mkdir_add_new_subdir_cluster:
  1607 0000701F 8B15[DDB00000]      <1> 	mov	edx, [DirBuff_Cluster]
  1608 00007025 8915[24B30000]      <1> 	mov	[mkdir_LastDirCluster], edx       
  1609                              <1> 
  1610 0000702B A1[20B30000]        <1> 	mov	eax, [mkdir_FFCluster]
  1611 00007030 E89E080000          <1> 	call	load_FAT_sub_directory 
  1612 00007035 72E7                <1> 	jc	short loc_mkdir_return
  1613                              <1> 	; eax = 0
  1614                              <1> 	; ecx =  directory buffer sector count (<= 128)
  1615                              <1> 
  1616                              <1> pass_mkdir_add_new_subdir_cluster:
  1617 00007037 29FF                <1> 	sub	edi, edi ; 0
  1618                              <1> 	;mov	al, 128 ; double word
  1619                              <1> 	;mul	ecx ; ecx =  directory buffer sector count
  1620                              <1> 	;mov	ecx, eax
  1621                              <1> 	;shl	cx, 7 ; 128 * sector count	
  1622 00007039 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec] ; 512
  1623 0000703D 66C1E802            <1> 	shr	ax, 2 ; 'byte count / 4' for 'stosd'
  1624 00007041 66F7E1              <1> 	mul	cx ; max = 128*(512/4) -> 16384 (stosd)
  1625 00007044 6689C1              <1> 	mov	cx, ax
  1626 00007047 6629C0              <1> 	sub	ax, ax ; 0
  1627 0000704A F3AB                <1> 	rep	stosd ; clear directory buffer
  1628                              <1> 
  1629 0000704C C605[D8B00000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1630 00007053 E840020000          <1> 	call	save_directory_buffer 
  1631 00007058 72C4                <1> 	jc	short loc_mkdir_return
  1632                              <1> 
  1633                              <1> loc_mkdir_save_added_cluster:
  1634 0000705A A1[24B30000]        <1> 	mov	eax, [mkdir_LastDirCluster]
  1635 0000705F 8B0D[20B30000]      <1> 	mov	ecx, [mkdir_FFCluster]
  1636                              <1> 	; 01/03/2016
  1637 00007065 31D2                <1> 	xor	edx, edx
  1638 00007067 8915[CDB00000]      <1> 	mov	[FAT_ClusterCounter], edx ; 0 ; reset
  1639 0000706D E89C090000          <1> 	call	update_cluster
  1640 00007072 7304                <1> 	jnc	short loc_mkdir_save_fat_buffer_0
  1641 00007074 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eoc
  1642 00007076 7518                <1> 	jnz	short loc_mkdir_save_fat_buffer_stc_retn
  1643                              <1> 
  1644                              <1> loc_mkdir_save_fat_buffer_0:
  1645 00007078 A1[20B30000]        <1> 	mov	eax, [mkdir_FFCluster]
  1646 0000707D A3[24B30000]        <1> 	mov	[mkdir_LastDirCluster], eax
  1647                              <1> 
  1648 00007082 31C9                <1> 	xor	ecx, ecx
  1649 00007084 49                  <1> 	dec	ecx ; FFFFFFFFh
  1650                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1651 00007085 E884090000          <1> 	call	update_cluster
  1652 0000708A 731A                <1> 	jnc	short loc_mkdir_save_fat_buffer_1
  1653 0000708C 09C0                <1> 	or	eax, eax
  1654 0000708E 7416                <1> 	jz	short loc_mkdir_save_fat_buffer_1
  1655                              <1> 
  1656                              <1> loc_mkdir_save_fat_buffer_stc_retn:
  1657                              <1> 	; 01/03/2016
  1658 00007090 803D[CDB00000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1659 00007097 720C                <1> 	jb	short loc_mkdir_save_fat_buffer_retn
  1660                              <1> 
  1661 00007099 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate free space (BL = 0)
  1662                              <1> 			   ; (BH = FFh -> Use ESI as Drv Param. Tbl.)
  1663 0000709D 50                  <1> 	push	eax
  1664 0000709E E8B40C0000          <1> 	call	calculate_fat_freespace
  1665 000070A3 58                  <1> 	pop	eax
  1666 000070A4 F9                  <1> 	stc
  1667                              <1> loc_mkdir_save_fat_buffer_retn:
  1668 000070A5 C3                  <1> 	retn
  1669                              <1> 
  1670                              <1> loc_mkdir_save_fat_buffer_1:
  1671                              <1> 	; byte [FAT_BuffValidData] = 2 
  1672 000070A6 E81C0C0000          <1> 	call	save_fat_buffer
  1673 000070AB 72E3                <1> 	jc	short loc_mkdir_save_fat_buffer_stc_retn
  1674                              <1> 
  1675                              <1> 	; 01/03/2016
  1676 000070AD 803D[CDB00000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1677 000070B4 721B                <1> 	jb	short loc_mkdir_save_fat_buffer_2
  1678                              <1> 
  1679                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1680 000070B6 A1[CDB00000]        <1> 	mov	eax, [FAT_ClusterCounter]
  1681 000070BB 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  1682 000070BF E8930C0000          <1> 	call	calculate_fat_freespace
  1683                              <1> 
  1684                              <1> 	;inc	eax ; 0FFFFFFFFh -> 0 ; recalculation is needed!
  1685                              <1> 	;jnz	short loc_mkdir_save_fat_buffer_2
  1686                              <1> 
  1687                              <1> 	; ecx > 0 -> Recalculation is needed
  1688 000070C4 09C9                <1> 	or	ecx, ecx 
  1689 000070C6 7409                <1> 	jz	short loc_mkdir_save_fat_buffer_2
  1690                              <1> 
  1691 000070C8 66BB00FF            <1> 	mov	bx, 0FF00h ; ; recalculate free space
  1692 000070CC E8860C0000          <1> 	call	calculate_fat_freespace
  1693                              <1> 
  1694                              <1> loc_mkdir_save_fat_buffer_2:
  1695 000070D1 C605[2FB30000]01    <1> 	mov	byte [mkdir_add_new_cluster], 1
  1696 000070D8 E9C4000000          <1> 	jmp	loc_mkdir_upd_parent_dir_lmdt
  1697                              <1> 
  1698                              <1> loc_mkdir_update_sub_dir_cluster:
  1699 000070DD A1[20B30000]        <1> 	mov	eax, [mkdir_FFCluster]
  1700 000070E2 29C9                <1> 	sub	ecx, ecx ; 0
  1701                              <1> 	; 01/03/2016
  1702 000070E4 890D[CDB00000]      <1> 	mov	[FAT_ClusterCounter], ecx ; 0 ; Reset
  1703 000070EA 49                  <1> 	dec	ecx ; 0FFFFFFFFh
  1704                              <1> 
  1705                              <1> 	; ESI = Logical DOS Drive Descisption Table address  
  1706 000070EB E81E090000          <1> 	call	update_cluster
  1707 000070F0 7379                <1> 	jnc	short loc_mkdir_save_fat_buffer_3
  1708 000070F2 09C0                <1> 	or	eax, eax ; EAX = 0 -> cluster value is 0 or eocc
  1709 000070F4 7475                <1> 	jz	short loc_mkdir_save_fat_buffer_3
  1710                              <1> 	; 01/03/2016
  1711 000070F6 EB98                <1> 	jmp	short loc_mkdir_save_fat_buffer_stc_retn
  1712                              <1> 
  1713                              <1> loc_mkdir_set_ff_dir_entry_2:
  1714                              <1> 	; ESI = Logical DOS Drive Description Table address  
  1715 000070F8 A1[20B30000]        <1> 	mov	eax, [mkdir_FFCluster]
  1716                              <1> 	; Load disk sectors as a directory cluster
  1717 000070FD E8D1070000          <1> 	call	load_FAT_sub_directory 
  1718 00007102 7266                <1> 	jc	short retn_make_fat_directory
  1719                              <1> 	
  1720                              <1> 	; eax = 0
  1721                              <1> 	; ecx =  directory buffer sector count (<= 128)
  1722                              <1> 
  1723 00007104 BF40000800          <1> 	mov	edi, Directory_Buffer + 64 ; 26/02/2016
  1724                              <1> 
  1725                              <1> 	; 02/03/2016
  1726 00007109 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec] ; 512
  1727 0000710D 66C1E802            <1> 	shr	ax, 2 ; 'byte count / 4' for 'stosd'
  1728 00007111 F7E1                <1> 	mul 	ecx
  1729 00007113 89C1                <1> 	mov	ecx, eax
  1730 00007115 6629C0              <1> 	sub	ax, ax
  1731 00007118 F3AB                <1> 	rep	stosd
  1732                              <1> 
  1733                              <1> 	;;mov	al, 128 ; double word
  1734                              <1> 	;;mul	ecx ; ecx =  directory buffer sector count
  1735                              <1> 	;;mov	ecx, eax
  1736                              <1> 	;shl	cx, 7 ; 128 * sector count	
  1737                              <1> 	;;sub	eax, eax
  1738                              <1> 	;;sub	al, al ; 0
  1739                              <1> 	;rep	stosd ; clear directory buffer
  1740                              <1> 
  1741 0000711A BF00000800          <1> 	mov	edi, Directory_Buffer ; 26/02/2016
  1742                              <1> 	
  1743 0000711F 56                  <1> 	push	esi
  1744                              <1> 
  1745 00007120 BE[30B30000]        <1> 	mov	esi, mkdir_Name
  1746 00007125 66C7062E00          <1> 	mov	word [esi], 2Eh ; db '.', '0'
  1747                              <1> 
  1748 0000712A A1[20B30000]        <1> 	mov	eax, [mkdir_FFCluster]
  1749 0000712F 66B91000            <1> 	mov	cx, 10h ; CL = Directory attribute
  1750                              <1> 			; CH = 0 -> File size is 0
  1751 00007133 E883000000          <1> 	call	make_directory_entry
  1752                              <1> 
  1753 00007138 BF20000800          <1> 	mov	edi, Directory_Buffer + 32 ; 26/02/2016
  1754                              <1> 
  1755                              <1> 	; 03/03/2016
  1756                              <1> 	; Following modification has been done according to 
  1757                              <1> 	; 'Microsoft Extensible Firmware Initiative
  1758                              <1> 	; FAT32 File System Specification' document,
  1759                              <1> 	; 'FAT: General Overview of On-Disk FormatPage 25'.
  1760                              <1> 	; "Finally, you set DIR_FstClusLO and DIR_FstClusHI
  1761                              <1> 	; for the dotdot entry (the second entry) to the
  1762                              <1> 	; first cluster number of the directory in which you 
  1763                              <1> 	; just created the directory (value is 0 if this directory
  1764                              <1> 	; is the root directory even for FAT32 volumes)."
  1765                              <1> 	; (Correctness of this modification has been verified
  1766                              <1> 	;  by using Windows 98 'scandisk.exe'.)
  1767                              <1> 
  1768 0000713D 29C0                <1> 	sub	eax, eax
  1769 0000713F 3805[ACA80000]      <1> 	cmp	byte [Current_Dir_Level], al ; 0
  1770 00007145 7605                <1> 	jna	short loc_mkdir_set_ff_dir_entry_3
  1771 00007147 A1[A8A80000]        <1> 	mov	eax, [Current_Dir_FCluster] ; parent dir
  1772                              <1> loc_mkdir_set_ff_dir_entry_3:
  1773 0000714C 66C746012E00        <1> 	mov	word [esi+1], 2Eh ; db '.', '0'
  1774                              <1> 
  1775                              <1> 	;mov	cx, 10h
  1776 00007152 E864000000          <1> 	call	make_directory_entry
  1777                              <1> 
  1778 00007157 5E                  <1> 	pop	esi
  1779                              <1> 
  1780 00007158 C605[D8B00000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  1781 0000715F E834010000          <1> 	call	save_directory_buffer
  1782 00007164 0F8373FFFFFF        <1>         jnc     loc_mkdir_update_sub_dir_cluster
  1783                              <1>  
  1784                              <1> retn_make_fat_directory:
  1785 0000716A C3                  <1> 	retn
  1786                              <1> 
  1787                              <1> loc_mkdir_save_fat_buffer_3:
  1788                              <1> 	; 01/03/2016
  1789                              <1> 	; byte [FAT_BuffValidData] = 2 
  1790 0000716B E8570B0000          <1> 	call	save_fat_buffer
  1791 00007170 0F821AFFFFFF        <1>         jc      loc_mkdir_save_fat_buffer_stc_retn
  1792                              <1> 
  1793 00007176 803D[CDB00000]01    <1> 	cmp	byte [FAT_ClusterCounter], 1
  1794 0000717D 721B                <1> 	jb	short loc_mkdir_save_fat_buffer_4
  1795                              <1> 
  1796                              <1> 	; ESI = Logical DOS Drive Description Table address 
  1797 0000717F A1[CDB00000]        <1> 	mov	eax, [FAT_ClusterCounter]
  1798 00007184 66BB01FF            <1> 	mov	bx, 0FF01h ; add free clusters 
  1799 00007188 E8CA0B0000          <1> 	call	calculate_fat_freespace
  1800                              <1> 
  1801                              <1> 	;inc	eax ; 0FFFFFFFFh -> 0 ; recalculation is needed!
  1802                              <1>         ;jnz    short loc_mkdir_save_fat_buffer_4
  1803                              <1> 
  1804                              <1> 	; ecx > 0 -> Recalculation is needed
  1805 0000718D 09C9                <1> 	or	ecx, ecx 
  1806 0000718F 7409                <1>         jz      short loc_mkdir_save_fat_buffer_4
  1807                              <1> 
  1808 00007191 66BB00FF            <1> 	mov	bx, 0FF00h ; ; recalculate free space
  1809 00007195 E8BD0B0000          <1> 	call	calculate_fat_freespace
  1810                              <1> 
  1811                              <1> loc_mkdir_save_fat_buffer_4:	
  1812 0000719A C605[2FB30000]00    <1> 	mov	byte [mkdir_add_new_cluster], 0
  1813                              <1> 
  1814                              <1> loc_mkdir_upd_parent_dir_lmdt:
  1815 000071A1 E886010000          <1> 	call	update_parent_dir_lmdt
  1816                              <1> 
  1817                              <1> 	; 01/03/2016
  1818 000071A6 803D[2FB30000]00    <1> 	cmp	byte [mkdir_add_new_cluster], 0
  1819 000071AD 0F8723FEFFFF        <1>         ja      loc_mkdir_gffc_2
  1820                              <1> 
  1821                              <1> loc_mkdir_retn_new_dir_cluster:
  1822 000071B3 A1[20B30000]        <1> 	mov	eax, [mkdir_FFCluster]
  1823 000071B8 31D2                <1> 	xor	edx, edx
  1824                              <1> loc_mkdir_retn:
  1825 000071BA C3                  <1> 	retn
  1826                              <1> 
  1827                              <1> make_directory_entry:
  1828                              <1> 	; 02/03/2016
  1829                              <1> 	; 21/02/2016 (TRDOS 386 = TRDOS v2.0)
  1830                              <1> 	; 09/08/2010 (DIR.ASM, 'proc_make_directory_entry')
  1831                              <1> 	; 17/07/2010
  1832                              <1> 	; INPUT ->
  1833                              <1> 	; 	EDI = Directory Entry Address
  1834                              <1> 	;	ESI = Dot File Name Location
  1835                              <1> 	;	EAX = First Cluster
  1836                              <1> 	;	File Size = 0 (Must be set later)
  1837                              <1> 	;	CL = Attributes
  1838                              <1> 	;	CH = 0 (File size = 0) 
  1839                              <1> 	;	(If CH>0, File size is in dword [EBX]) (*)
  1840                              <1> 	; OUTPUT -> 
  1841                              <1> 	;	EDI = Directory Entry Address
  1842                              <1> 	;	ESI = Dot File Name Location (Capitalized)
  1843                              <1> 	;	If CH input = 0, File Size = 0
  1844                              <1> 	;	Otherwise file size is as dword [EBX] (*)
  1845                              <1> 	;	DX = Date, AX = Time in DOS Dir Entry format
  1846                              <1> 	;	EBX = same
  1847                              <1> 	;	ECX = same
  1848                              <1> 
  1849 000071BB 51                  <1> 	push	ecx
  1850                              <1> 
  1851 000071BC 884F0B              <1> 	mov	[edi+11], cl ; Attributes
  1852 000071BF 6689471A            <1> 	mov	[edi+26], ax ; FClusterLw, 26
  1853 000071C3 C1E810              <1> 	shr	eax, 16
  1854 000071C6 66894714            <1> 	mov	[edi+20], ax ; FClusterHw, 20
  1855 000071CA 6631C0              <1> 	xor	ax, ax 
  1856 000071CD 6689470C            <1> 	mov	[edi+12], ax ; NTReserved, 12
  1857                              <1> 			     ; CrtTimeTenth, 13
  1858 000071D1 08ED                <1> 	or	ch, ch
  1859 000071D3 7402                <1> 	jz	short loc_make_direntry_set_filesize
  1860                              <1> 
  1861 000071D5 8B03                <1> 	mov	eax, [ebx]
  1862                              <1>         
  1863                              <1> loc_make_direntry_set_filesize:
  1864 000071D7 89471C              <1> 	mov	[edi+28], eax ; FileSize, 28
  1865                              <1> 	
  1866 000071DA E88AFBFFFF          <1> 	call	convert_file_name
  1867                              <1> 	;EDI = Dir Entry Format File Name Location
  1868                              <1> 	;ESI = Dot File Name Location (capitalized)
  1869                              <1> 
  1870 000071DF E816000000          <1> 	call	convert_current_date_time
  1871                              <1> 	; OUTPUT -> DX = Date in dos dir entry format
  1872                              <1>         ; 	    AX = Time in dos dir entry format
  1873 000071E4 6689470E            <1> 	mov	[edi+14], ax ; CrtTime, 14
  1874 000071E8 66895710            <1> 	mov	[edi+16], dx ; CrtDate, 16
  1875 000071EC 66895712            <1> 	mov	[edi+18], dx ; LastAccDate, 18
  1876 000071F0 66894716            <1> 	mov	[edi+22], ax ; WrtTime, 14
  1877 000071F4 66895718            <1> 	mov	[edi+24], dx ; WrtDate, 16
  1878 000071F8 59                  <1> 	pop	ecx
  1879                              <1> 
  1880 000071F9 C3                  <1> 	retn
  1881                              <1> 
  1882                              <1> convert_current_date_time:
  1883                              <1> 	; 21/02/2016 (TRDOS 386 = TRDOS v2.0)
  1884                              <1> 	; 13/06/2010 (DIR.ASM, 'proc_convert_current_date_time')
  1885                              <1> 	; converts date&time to dos dir entry format
  1886                              <1> 	; INPUT -> none
  1887                              <1> 	; OUTPUT -> DX = Date in dos dir entry format
  1888                              <1> 	;           AX = Time in dos dir entry format
  1889                              <1>  
  1890 000071FA B404                <1> 	mov	ah, 04h ; Return Current Date
  1891 000071FC E8F2C6FFFF          <1> 	call	int1Ah 
  1892                              <1> 
  1893 00007201 88E8                <1> 	mov	al, ch ; <- century BCD
  1894 00007203 240F                <1> 	and	al, 0Fh
  1895 00007205 88EC                <1> 	mov	ah, ch
  1896 00007207 C0EC04              <1> 	shr	ah, 4
  1897 0000720A D50A                <1> 	aad
  1898 0000720C 88C5                <1> 	mov	ch, al ; -> century 
  1899                              <1> 
  1900 0000720E 88C8                <1> 	mov	al, cl ; <- year BCD
  1901 00007210 240F                <1> 	and	al, 0Fh
  1902 00007212 88CC                <1> 	mov	ah, cl
  1903 00007214 C0EC04              <1> 	shr	ah, 4
  1904 00007217 D50A                <1> 	aad
  1905 00007219 88C1                <1> 	mov	cl, al ; -> year
  1906                              <1> 
  1907 0000721B 88E8                <1> 	mov	al, ch
  1908 0000721D B464                <1> 	mov	ah, 100
  1909 0000721F F6E4                <1> 	mul	ah
  1910 00007221 30ED                <1> 	xor	ch, ch
  1911 00007223 6601C8              <1> 	add	ax, cx
  1912 00007226 662DBC07            <1> 	sub	ax, 1980 ; ms-dos epoch
  1913 0000722A 6689C1              <1> 	mov	cx, ax
  1914                              <1> 
  1915 0000722D 88F0                <1> 	mov	al, dh ; <- month in bcd
  1916 0000722F 240F                <1> 	and	al, 0Fh
  1917 00007231 88F4                <1> 	mov	ah, dh
  1918 00007233 C0EC04              <1> 	shr	ah, 4
  1919 00007236 D50A                <1> 	aad
  1920 00007238 88C6                <1> 	mov	dh, al ; -> month
  1921                              <1> 
  1922 0000723A 88D0                <1> 	mov	al, dl ; <- day BCD
  1923 0000723C 240F                <1> 	and	al, 0Fh
  1924 0000723E 88D4                <1> 	mov	ah, dl
  1925 00007240 C0EC04              <1> 	shr	ah, 4
  1926 00007243 D50A                <1> 	aad
  1927 00007245 88C2                <1> 	mov	dl, al ; -> day
  1928                              <1> 
  1929 00007247 88C8                <1> 	mov	al, cl ; count of years from 1980
  1930 00007249 66C1E004            <1> 	shl	ax, 4
  1931 0000724D 08F0                <1> 	or	al, dh ; month of year, 1 to 12
  1932 0000724F 66C1E005            <1> 	shl	ax, 5
  1933 00007253 08D0                <1> 	or	al, dl ; day of year, 1 to 31
  1934                              <1> 	
  1935 00007255 6650                <1> 	push	ax ; push date
  1936                              <1> 
  1937 00007257 B402                <1> 	mov	ah, 02h ; Return Current Time
  1938 00007259 E895C6FFFF          <1> 	call	int1Ah
  1939                              <1> 
  1940 0000725E 88E8                <1> 	mov	al, ch ; <- hours BCD
  1941 00007260 240F                <1> 	and	al, 0Fh
  1942 00007262 88EC                <1> 	mov	ah, ch
  1943 00007264 C0EC04              <1> 	shr	ah, 4
  1944 00007267 D50A                <1> 	aad
  1945 00007269 88C5                <1> 	mov	ch, al ; -> hours
  1946                              <1> 
  1947 0000726B 88C8                <1> 	mov	al, cl ; <- minutes BCD
  1948 0000726D 240F                <1> 	and	al, 0Fh
  1949 0000726F 88CC                <1> 	mov	ah, cl
  1950 00007271 C0EC04              <1> 	shr	ah, 4
  1951 00007274 D50A                <1> 	aad
  1952 00007276 88C1                <1> 	mov	cl, al ; -> minutes
  1953                              <1> 
  1954 00007278 88F0                <1> 	mov	al, dh ; <- seconds BCD
  1955 0000727A 240F                <1> 	and	al, 0Fh
  1956 0000727C 88F4                <1> 	mov	ah, dh
  1957 0000727E C0EC04              <1> 	shr	ah, 4
  1958 00007281 D50A                <1> 	aad
  1959 00007283 88C6                <1> 	mov	dh, al ; -> seconds
  1960                              <1> 
  1961 00007285 88E8                <1> 	mov	al, ch ; hours
  1962 00007287 66C1E006            <1> 	shl	ax, 6
  1963 0000728B 08C8                <1> 	or	al, cl ; minutes
  1964 0000728D 66C1E005            <1> 	shl	ax, 5
  1965 00007291 D0EE                <1> 	shr	dh, 1 ; 2 seconds
  1966                              <1> 	; There is a bug in TRDOS v1 here !
  1967                              <1> 	; it was 'or al, dl' ! 
  1968 00007293 08F0                <1> 	or	al, dh ; seconds
  1969                              <1> 
  1970 00007295 665A                <1> 	pop	dx ; pop date
  1971                              <1> 	
  1972 00007297 C3                  <1> 	retn
  1973                              <1> 
  1974                              <1> save_directory_buffer:
  1975                              <1> 	; 26/02/2016
  1976                              <1> 	; 22/02/2016 (TRDOS 386 = TRDOS v2.0)
  1977                              <1> 	; 01/08/2011
  1978                              <1> 	; 14/03/2010
  1979                              <1> 	; INPUT ->
  1980                              <1> 	; 	 none
  1981                              <1> 	; OUTPUT ->
  1982                              <1> 	;  cf = 0 -> write OK...
  1983                              <1> 	;  cf = 1 -> error code in AL (EAX)
  1984                              <1> 	;  cf = 1 & AL = 0Dh => CH & CL = FS & FAT type
  1985                              <1> 	;  EBX = Directory Buffer Address
  1986                              <1> 	;
  1987                              <1> 	;  (EAX, ECX, EDX will be modified)
  1988                              <1>  
  1989 00007298 BB00000800          <1> 	mov	ebx, Directory_Buffer
  1990 0000729D 803D[D8B00000]02    <1> 	cmp	byte [DirBuff_ValidData], 2
  1991 000072A4 7403                <1> 	je	short loc_save_dir_buffer
  1992 000072A6 31C0                <1> 	xor	eax, eax
  1993 000072A8 C3                  <1> 	retn            
  1994                              <1> 
  1995                              <1> loc_save_dir_buffer:
  1996 000072A9 56                  <1> 	push	esi
  1997 000072AA 31DB                <1> 	xor	ebx, ebx 
  1998 000072AC 8A3D[D6B00000]      <1>         mov     bh, [DirBuff_DRV]
  1999 000072B2 80EF41              <1> 	sub	bh, 'A'
  2000 000072B5 BE00010900          <1>         mov     esi, Logical_DOSDisks
  2001 000072BA 01DE                <1> 	add	esi, ebx
  2002 000072BC 668B4E03            <1>         mov     cx, [esi+LD_FATType]
  2003                              <1> 	; CH = FS Type (A1h for FS)
  2004                              <1> 	; CL = FAT Type (0 for FS)
  2005 000072C0 08C9                <1> 	or	cl, cl
  2006 000072C2 7433                <1> 	jz	short loc_save_dir_buff_stc_retn
  2007                              <1> 
  2008                              <1> loc_save_dir_buffer_check_cluster_no:    
  2009 000072C4 A1[DDB00000]        <1> 	mov	eax, [DirBuff_Cluster]
  2010 000072C9 28FF                <1> 	sub	bh, bh ; ebx = 0
  2011 000072CB 09C0                <1> 	or	eax, eax
  2012 000072CD 7539                <1> 	jnz	short loc_save_sub_dir_buffer
  2013 000072CF 8A25[D7B00000]      <1> 	mov	ah, [DirBuff_FATType]
  2014 000072D5 FEC3                <1> 	inc	bl ;  bl = 1
  2015 000072D7 38DC                <1> 	cmp	ah, bl
  2016 000072D9 721D                <1> 	jb	short loc_save_dir_buff_inv_data_retn
  2017 000072DB FEC3                <1> 	inc	bl ; bl = 2
  2018 000072DD 38E3                <1> 	cmp	bl, ah
  2019 000072DF 7217                <1> 	jb	short loc_save_dir_buff_inv_data_retn
  2020                              <1> 
  2021                              <1> loc_save_root_dir_buffer:
  2022 000072E1 668B5E17            <1> 	mov	bx, [esi+LD_BPB+RootDirEnts]
  2023 000072E5 6683C30F            <1> 	add	bx, 15
  2024 000072E9 66C1EB04            <1> 	shr	bx, 4 ; 16 dir entries per sector
  2025 000072ED 6609DB              <1> 	or	bx, bx
  2026 000072F0 7405                <1> 	jz	short loc_save_dir_buff_stc_retn
  2027                              <1> 	;mov	ecx, ebx 
  2028 000072F2 8B4664              <1> 	mov	eax, [esi+LD_ROOTBegin] ; 26/02/2016
  2029 000072F5 EB1C                <1> 	jmp	short loc_write_directory_to_disk
  2030                              <1> 
  2031                              <1> loc_save_dir_buff_stc_retn:
  2032 000072F7 F9                  <1> 	stc
  2033                              <1> loc_save_dir_buff_inv_data_retn:
  2034 000072F8 B00D                <1> 	mov	al, 0Dh ; Invalid data !
  2035 000072FA C605[D8B00000]00    <1> 	mov	byte [DirBuff_ValidData], 0 
  2036                              <1> loc_write_directory_to_disk_err:
  2037                              <1> loc_save_dir_buff_retn:
  2038 00007301 BB00000800          <1> 	mov	ebx, Directory_Buffer
  2039 00007306 5E                  <1> 	pop	esi
  2040 00007307 C3                  <1> 	retn 
  2041                              <1> 
  2042                              <1> loc_save_sub_dir_buffer:
  2043                              <1> 	; ebx  = 0
  2044 00007308 83E802              <1> 	sub	eax, 2
  2045 0000730B 8A5E13              <1> 	mov	bl, [esi+LD_BPB+SecPerClust]
  2046 0000730E F7E3                <1> 	mul	ebx
  2047 00007310 034668              <1>         add     eax, [esi+LD_DATABegin]
  2048                              <1>  	;mov	ecx, ebx
  2049                              <1> 
  2050                              <1> loc_write_directory_to_disk:
  2051 00007313 89D9                <1>  	mov	ecx, ebx
  2052 00007315 BB00000800          <1> 	mov	ebx, Directory_Buffer
  2053 0000731A E815230000          <1> 	call	disk_write
  2054 0000731F 72E0                <1> 	jc	short loc_write_directory_to_disk_err
  2055                              <1> 
  2056                              <1> loc_save_dir_buff_validate_retn:
  2057 00007321 C605[D8B00000]01    <1> 	mov	byte [DirBuff_ValidData], 1
  2058 00007328 31C0                <1> 	xor	eax, eax
  2059                              <1> 	; 26/02/2016
  2060 0000732A EBD5                <1> 	jmp	short loc_save_dir_buff_retn
  2061                              <1> 
  2062                              <1> update_parent_dir_lmdt:
  2063                              <1> 	; 22/02/2016 (TRDOS 386 = TRDOS v2.0)
  2064                              <1> 	; 01/08/2011
  2065                              <1> 	; 16/10/2010 
  2066                              <1> 	; 
  2067                              <1> 	; INPUT -> 
  2068                              <1> 	;	none
  2069                              <1>  	; OUTPUT ->
  2070                              <1> 	;	(last modification date & time of the parent dir
  2071                              <1> 	;	will be changed/updated)
  2072                              <1> 	;
  2073                              <1> 	; (EAX, EBX, ECX, EDX, EDI will be changed)
  2074                              <1> 
  2075 0000732C 29C0                <1> 	sub	eax, eax
  2076 0000732E 8A25[ACA80000]      <1> 	mov	ah, [Current_Dir_Level]
  2077 00007334 A0[ADA80000]        <1> 	mov	al, [Current_FATType]
  2078 00007339 3C01                <1> 	cmp	al, 1
  2079 0000733B 723A                <1> 	jb	short loc_UPDLMDT_proc_retn
  2080                              <1>     
  2081                              <1> loc_update_parent_dir_lm_date_time:
  2082 0000733D 08E4                <1> 	or	ah, ah
  2083 0000733F 7436                <1> 	jz	short loc_UPDLMDT_proc_retn
  2084                              <1> 
  2085 00007341 56                  <1> 	push	esi ; *
  2086 00007342 8825[50B30000]      <1> 	mov	[UPDLMDT_CDirLevel], ah
  2087 00007348 8B15[A8A80000]      <1> 	mov	edx, [Current_Dir_FCluster]
  2088 0000734E 8915[51B30000]      <1> 	mov	[UPDLMDT_CDirFCluster], edx
  2089                              <1> 
  2090 00007354 FECC                <1> 	dec	ah
  2091 00007356 B90C000000          <1> 	mov	ecx, 12
  2092 0000735B BE[0FB10000]        <1>         mov     esi, PATH_Array
  2093                              <1> 
  2094 00007360 8825[ACA80000]      <1> 	mov	[Current_Dir_Level], ah
  2095 00007366 08E4                <1> 	or	ah, ah
  2096 00007368 750E                <1> 	jnz	short loc_update_parent_dir_lmdt_load_sub_dir_1
  2097 0000736A 803D[ADA80000]02    <1> 	cmp	byte [Current_FATType], 2
  2098 00007371 770B                <1> 	ja	short loc_update_parent_dir_lmdt_load_sub_dir_2
  2099 00007373 28C0                <1> 	sub	al, al ; eax = 0
  2100 00007375 EB0A                <1> 	jmp	short loc_update_parent_dir_lmdt_load_sub_dir_3
  2101                              <1> 
  2102                              <1> loc_UPDLMDT_proc_retn:
  2103 00007377 C3                  <1> 	retn
  2104                              <1>          
  2105                              <1> loc_update_parent_dir_lmdt_load_sub_dir_1:
  2106 00007378 B010                <1> 	mov	al, 16
  2107 0000737A F6E4                <1> 	mul	ah 
  2108 0000737C 01C6                <1> 	add	esi, eax
  2109                              <1> 
  2110                              <1> loc_update_parent_dir_lmdt_load_sub_dir_2:  
  2111 0000737E 8B460C              <1> 	mov	eax, [esi+12] ; Parent Dir First Cluster
  2112                              <1> 
  2113                              <1> loc_update_parent_dir_lmdt_load_sub_dir_3:
  2114 00007381 A3[A8A80000]        <1> 	mov	[Current_Dir_FCluster], eax
  2115                              <1> 
  2116 00007386 83C610              <1> 	add	esi, 16
  2117 00007389 66BF[36B2]          <1> 	mov	di, Dir_File_Name  
  2118 0000738D F3A4                <1> 	rep	movsb
  2119                              <1> 	
  2120 0000738F BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2121 00007394 29DB                <1> 	sub	ebx, ebx
  2122 00007396 8A3D[AEA80000]      <1> 	mov	bh, [Current_Drv]
  2123 0000739C 01DE                <1> 	add	esi, ebx
  2124 0000739E E896F7FFFF          <1> 	call	reload_current_directory
  2125 000073A3 7232                <1> 	jc	short loc_update_parent_dir_lmdt_restore_cdirlevel
  2126                              <1> 
  2127                              <1> loc_update_parent_dir_lmdt_locate_dir: 
  2128 000073A5 BE[36B20000]        <1> 	mov	esi, Dir_File_Name        
  2129 000073AA 6631C9              <1> 	xor	cx, cx
  2130 000073AD 66B81008            <1> 	mov	ax, 0810h ; Only directories
  2131 000073B1 E8BEF6FFFF          <1>         call    locate_current_dir_file
  2132                              <1> 	; EDI = DirBuff Directory Entry Address
  2133 000073B6 721F                <1> 	jc short loc_update_parent_dir_lmdt_restore_cdirlevel
  2134                              <1> 
  2135 000073B8 E83DFEFFFF          <1> 	call	convert_current_date_time
  2136 000073BD 66895712            <1> 	mov	[edi+18], dx ; Last Access Date
  2137 000073C1 66895718            <1> 	mov	[edi+24], dx ; Last Write Date
  2138 000073C5 66894716            <1> 	mov	[edi+22], ax ; Last Write Time
  2139                              <1> 
  2140 000073C9 C605[D8B00000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  2141 000073D0 E8C3FEFFFF          <1> 	call	save_directory_buffer
  2142 000073D5 7200                <1> 	jc	short loc_update_parent_dir_lmdt_restore_cdirlevel
  2143                              <1> 	;xor	al, al 
  2144                              <1> loc_update_parent_dir_lmdt_restore_cdirlevel:
  2145                              <1>  	;current directory level restoration
  2146 000073D7 8A25[50B30000]      <1> 	mov	ah, [UPDLMDT_CDirLevel]
  2147 000073DD 8825[ACA80000]      <1> 	mov	[Current_Dir_Level], ah
  2148 000073E3 8B15[51B30000]      <1>         mov     edx, [UPDLMDT_CDirFCluster]
  2149 000073E9 8915[A8A80000]      <1> 	mov	[Current_Dir_FCluster], edx
  2150                              <1> 
  2151 000073EF 5E                  <1> 	pop	esi ; *
  2152 000073F0 C3                  <1> 	retn
  2153                              <1> 
  2154                              <1> delete_longname:
  2155                              <1> 	; 27/02/2016 (TRDOS 386 = TRDOS v2.0)
  2156                              <1> 	; 01/08/2011 (DIR.ASM, 'proc_delete_longname')
  2157                              <1> 	; 14/03/2010
  2158                              <1> 	; INPUT ->
  2159                              <1> 	; 	EAX = Directory Entry (Index) Number (< 65536)
  2160                              <1> 	; OUTPUT ->
  2161                              <1> 	;	cf = 0 -> OK  (EAX = 0)
  2162                              <1> 	; 	cf = 1 -> error code in EAX (AL)
  2163                              <1> 	;
  2164                              <1> 	; (Modified registers: EAX, EDX, ECX, EBX, EDI) 
  2165                              <1> 
  2166 000073F1 66A3[7CB30000]      <1> 	mov	[DLN_EntryNumber], ax
  2167 000073F7 C605[7EB30000]40    <1>         mov     byte [DLN_40h], 40h
  2168                              <1> 
  2169 000073FE E858000000          <1> 	call	locate_current_dir_entry
  2170 00007403 7308                <1> 	jnc	short loc_dln_check_attributes
  2171 00007405 C3                  <1> 	retn
  2172                              <1> 
  2173                              <1> loc_dln_longname_not_found:
  2174 00007406 B802000000          <1> 	mov	eax, 2
  2175 0000740B F9                  <1> 	stc
  2176 0000740C C3                  <1> 	retn
  2177                              <1> 
  2178                              <1> loc_dln_check_attributes:
  2179 0000740D B00F                <1> 	mov	al, 0Fh  ; long name
  2180 0000740F 8A670B              <1> 	mov	ah, [edi+0Bh] ; dir entry attributes
  2181 00007412 38C4                <1> 	cmp	ah, al
  2182 00007414 75F0                <1> 	jne	short loc_dln_longname_not_found
  2183 00007416 8A27                <1> 	mov	ah, [edi]
  2184 00007418 2A25[7EB30000]      <1> 	sub	ah, [DLN_40h]
  2185 0000741E 76E6                <1> 	jna	short loc_dln_longname_not_found         
  2186 00007420 80FC14              <1> 	cmp	ah, 14h ; 84-64=20 -> 20*13=260 bytes
  2187 00007423 77E1                <1> 	ja	short loc_dln_longname_not_found
  2188                              <1>              
  2189 00007425 C607E5              <1> 	mov	byte [edi], 0E5h  ; deleted sign
  2190 00007428 C605[D8B00000]02    <1> 	mov	byte [DirBuff_ValidData], 2 ; changed/write sign
  2191 0000742F C605[7EB30000]00    <1> 	mov	byte [DLN_40h], 0 ; 40h -> 0
  2192                              <1> 	  
  2193                              <1> loc_dln_delete_next_ln_entry:
  2194 00007436 80FC01              <1> 	cmp	ah, 1
  2195 00007439 7616                <1> 	jna	short loc_dln_longname_retn
  2196                              <1> loc_dln_delete_next_ln_entry_0:
  2197 0000743B 66FF05[7CB30000]    <1> 	inc	word [DLN_EntryNumber]
  2198 00007442 0FB705[7CB30000]    <1> 	movzx	eax, word [DLN_EntryNumber] 
  2199 00007449 E80D000000          <1> 	call	locate_current_dir_entry
  2200 0000744E 73BD                <1> 	jnc	short loc_dln_check_attributes
  2201                              <1> 
  2202                              <1> loc_dln_longname_stc_retn:
  2203 00007450 C3                  <1> 	retn 
  2204                              <1> 	   
  2205                              <1> loc_dln_longname_retn:
  2206                              <1> 	;cmp	byte [DirBuff_ValidData], 2
  2207                              <1> 	;jne	short loc_dln_longname_retn_xor_eax
  2208 00007451 E842FEFFFF          <1> 	call	save_directory_buffer
  2209 00007456 72F8                <1> 	jc	short loc_dln_longname_stc_retn
  2210                              <1> 
  2211                              <1> loc_dln_longname_retn_xor_eax:
  2212 00007458 31C0                <1> 	xor	eax, eax
  2213 0000745A C3                  <1> 	retn
  2214                              <1> 
  2215                              <1> locate_current_dir_entry:
  2216                              <1> 	; 27/02/2016 (TRDOS 386 = TRDOS v2.0)
  2217                              <1> 	; 01/08/2011 (DIR.ASM, 'proc_locate_current_dir_entry')
  2218                              <1> 	; 07/03/2010
  2219                              <1> 	; INPUT ->
  2220                              <1> 	;	EAX = Directory Entry (Index) Number (< 65536) 
  2221                              <1> 	; OUTPUT ->
  2222                              <1> 	;	EDI = Directory Entry Address
  2223                              <1> 	; 	EAX = Cluster Number of Directory Buffer
  2224                              <1> 	;	EBX = Directory Buffer Entry Offset
  2225                              <1> 	;	ECX = DirBuff Valid Data identifier (CL)
  2226                              <1> 	;   	If CF = 0 and CL = 2 then
  2227                              <1> 	;	   directory buffer modified and
  2228                              <1> 	;	   must be written to disk.
  2229                              <1> 	; 	If CF = 0  and CL = 1 then
  2230                              <1> 	;	   dir buffer has been written to disk, already.
  2231                              <1> 	;	CF = 1 -> Error code in EAX (AL)
  2232                              <1> 	;
  2233                              <1> 	; (Modified registers: EAX, EDX, ECX, EBX, EDI) 
  2234                              <1> 
  2235                              <1> loc_locate_current_dir_entry:
  2236 0000745B 56                  <1> 	push	esi
  2237 0000745C 89C1                <1> 	mov	ecx, eax
  2238 0000745E BA20000000          <1> 	mov	edx, 32
  2239 00007463 F7E2                <1> 	mul	edx 
  2240 00007465 A3[88B30000]        <1> 	mov	[LCDE_ByteOffset], eax
  2241 0000746A 31DB                <1> 	xor	ebx, ebx
  2242 0000746C 8A3D[AEA80000]      <1> 	mov	bh, [Current_Drv]
  2243 00007472 A0[D6B00000]        <1>         mov     al, [DirBuff_DRV]
  2244 00007477 2C41                <1> 	sub	al, 'A'
  2245 00007479 BE00010900          <1>         mov     esi, Logical_DOSDisks
  2246 0000747E 01DE                <1> 	add	esi, ebx
  2247 00007480 38C7                <1> 	cmp	bh, al
  2248 00007482 0F8592000000        <1>         jne     loc_lcde_reload_current_directory
  2249                              <1> loc_lcde_cdl_check:
  2250 00007488 803D[ACA80000]00    <1> 	cmp	byte [Current_Dir_Level], 0
  2251 0000748F 772A                <1> 	ja	short loc_lcde_calc_dirbuff_cluster_offset
  2252                              <1> 	; 27/02/2016
  2253                              <1> 	; TRDOS v1 has bug here for FAT32 fs !
  2254                              <1> 	; (Root Directory Entries for FAT32 = 0)
  2255 00007491 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3  ; FAT32
  2256 00007495 7324                <1> 	jnb	short loc_lcde_calc_dirbuff_cluster_offset
  2257                              <1> 
  2258                              <1> loc_lcde_cdl_check_FAT12_16:
  2259 00007497 668B4617            <1> 	mov	ax, [esi+LD_BPB+RootDirEnts]
  2260 0000749B 6648                <1> 	dec	ax
  2261                              <1> 	;xor	dx, dx  
  2262 0000749D 6639C8              <1> 	cmp	ax, cx ; cx = Directory Entry (Index) Number
  2263 000074A0 720E                <1> 	jb	short loc_lcde_stc_12h_retn
  2264 000074A2 66890D[80B30000]    <1> 	mov	[LCDE_EntryIndex], cx
  2265 000074A9 31C0                <1> 	xor	eax, eax
  2266 000074AB E993000000          <1>         jmp     loc_lcde_check_dir_buffer_cluster
  2267                              <1> 
  2268                              <1> loc_lcde_stc_12h_retn:
  2269 000074B0 5E                  <1> 	pop	esi
  2270 000074B1 89CB                <1> 	mov	ebx, ecx
  2271 000074B3 89D1                <1> 	mov	ecx, edx
  2272 000074B5 B812000000          <1> 	mov	eax, 12h ; No more files
  2273 000074BA C3                  <1> 	retn 
  2274                              <1> 
  2275                              <1> loc_lcde_calc_dirbuff_cluster_offset:
  2276 000074BB 8A5E13              <1> 	mov	bl, [esi+LD_BPB+SecPerClust]
  2277 000074BE 30FF                <1> 	xor	bh, bh
  2278 000074C0 668B4611            <1> 	mov	ax, [esi+LD_BPB+BytesPerSec]
  2279 000074C4 66F7E3              <1> 	mul	bx
  2280 000074C7 6609D2              <1>  	or	dx, dx ; If bytes per cluster > 32KB it is invalid
  2281 000074CA 755D                <1> 	jnz	short loc_lcde_invalid_format
  2282                              <1> 	;mov	ecx, eax
  2283 000074CC 6689C1              <1> 	mov	cx, ax ; BYTES PER CLUSTER
  2284 000074CF A1[88B30000]        <1> 	mov	eax, [LCDE_ByteOffset]
  2285                              <1> 	;sub	edx, edx
  2286 000074D4 F7F1                <1> 	div	ecx
  2287 000074D6 3DFFFF0000          <1> 	cmp	eax, 65535
  2288 000074DB 774C                <1> 	ja	short loc_lcde_invalid_format
  2289                              <1> 
  2290                              <1> 	; cluster sequence number of directory (< 65536)
  2291 000074DD 66A3[82B30000]      <1> 	mov	[LCDE_ClusterSN], ax 
  2292                              <1> 
  2293 000074E3 6689D0              <1> 	mov	ax, dx ; byte offset in cluster (directory buffer)
  2294 000074E6 66BB2000            <1> 	mov	bx, 32 ; ; 1 dir entry = 32 bytes
  2295 000074EA 6629D2              <1>         sub     dx, dx  ; 0
  2296 000074ED 66F7F3              <1> 	div	bx 
  2297 000074F0 66A3[80B30000]      <1> 	mov	[LCDE_EntryIndex], ax ; dir entry index/sequence number
  2298                              <1> 				      ; (in directory buffer/cluster)	  
  2299                              <1> loc_lcde_get_current_sub_dir_fcluster:
  2300 000074F6 A1[A8A80000]        <1> 	mov	eax, [Current_Dir_FCluster]
  2301                              <1> 
  2302                              <1> loc_lcde_get_next_cluster:
  2303 000074FB 66833D[82B30000]00  <1> 	cmp	word [LCDE_ClusterSN], 0
  2304 00007503 763E                <1> 	jna	short loc_lcde_check_dir_buffer_cluster
  2305 00007505 A3[84B30000]        <1> 	mov	[LCDE_Cluster], eax
  2306 0000750A E8E3010000          <1> 	call	get_next_cluster
  2307 0000750F 7220                <1> 	jc	short loc_lcde_check_gnc_error
  2308 00007511 66FF0D[82B30000]    <1>   	dec	word [LCDE_ClusterSN]
  2309 00007518 EBE1                <1> 	jmp	short loc_lcde_get_next_cluster
  2310                              <1> 
  2311                              <1> loc_lcde_reload_current_directory:
  2312 0000751A 51                  <1> 	push	ecx
  2313 0000751B E819F6FFFF          <1> 	call	reload_current_directory
  2314 00007520 59                  <1> 	pop	ecx
  2315 00007521 0F8361FFFFFF        <1>         jnc     loc_lcde_cdl_check
  2316 00007527 5E                  <1> 	pop	esi
  2317 00007528 C3                  <1> 	retn
  2318                              <1> 
  2319                              <1> loc_lcde_invalid_format:
  2320 00007529 B80B000000          <1> 	mov	eax, 0Bh ; MSDOS Error code: Invalid Format
  2321                              <1> 	;mov	eax, 0Dh ; MSDOS Error code: Invalid Data
  2322                              <1> loc_lcde_drive_not_ready_read_err:
  2323 0000752E F9                  <1> 	stc
  2324 0000752F 5E                  <1> 	pop	esi 
  2325 00007530 C3                  <1> 	retn  
  2326                              <1> 
  2327                              <1> loc_lcde_check_gnc_error:
  2328 00007531 09C0                <1> 	or	eax, eax
  2329 00007533 75F9                <1> 	jnz	short loc_lcde_drive_not_ready_read_err
  2330 00007535 66FF0D[82B30000]    <1> 	dec	word [LCDE_ClusterSN]
  2331 0000753C 75EB                <1> 	jnz	short loc_lcde_invalid_format 
  2332 0000753E A1[84B30000]        <1> 	mov	eax, [LCDE_Cluster]
  2333                              <1> 
  2334                              <1> loc_lcde_check_dir_buffer_cluster:
  2335 00007543 3B05[DDB00000]      <1> 	cmp	eax, [DirBuff_Cluster]
  2336 00007549 7555                <1> 	jne	short loc_lcde_load_dir_cluster
  2337 0000754B 803D[D8B00000]00    <1> 	cmp	byte [DirBuff_ValidData], 0
  2338 00007552 7720                <1> 	ja	short lcde_check_dir_buffer_cluster_next
  2339 00007554 803D[ACA80000]00    <1> 	cmp	byte [Current_Dir_Level], 0    
  2340 0000755B 7758                <1> 	ja	short loc_lcde_load_dir_cluster_0
  2341                              <1> 	; 27/02/2016
  2342                              <1> 	; TRDOS v1 has bug here for FAT32 fs !
  2343 0000755D 807E0303            <1> 	cmp	byte [esi+LD_FATType], 3  ; FAT32
  2344 00007561 7352                <1> 	jnb	short loc_lcde_load_dir_cluster_0
  2345                              <1> 	;
  2346 00007563 0FB74E17            <1> 	movzx	ecx, word [esi+LD_BPB+RootDirEnts]
  2347 00007567 6683C10F            <1> 	add	cx, 15 ; round up (16 entries per sector)
  2348 0000756B 66C1E904            <1> 	shr	cx, 4 ; 1 sector contains 16 dir entries	
  2349                              <1> 
  2350 0000756F 8B4664              <1>         mov     eax, [esi+LD_ROOTBegin]
  2351 00007572 EB4D                <1> 	jmp	short loc_lcde_load_dir_cluster_1 
  2352                              <1> 
  2353                              <1> lcde_check_dir_buffer_cluster_next:
  2354 00007574 0FB71D[80B30000]    <1> 	movzx	ebx, word [LCDE_EntryIndex]
  2355 0000757B 663B1D[DBB00000]    <1> 	cmp	bx, [DirBuff_LastEntry]
  2356 00007582 77A5                <1> 	ja	short loc_lcde_invalid_format 
  2357 00007584 B820000000          <1> 	mov	eax, 32
  2358 00007589 F7E3                <1> 	mul	ebx
  2359                              <1> 	;or	edx, edx
  2360                              <1> 	;jnz	short loc_lcde_invalid_format
  2361                              <1> 
  2362 0000758B BF00000800          <1> 	mov	edi, Directory_Buffer  
  2363 00007590 01C7                <1> 	add	edi, eax ; add entry offset to buffer address
  2364                              <1> 
  2365                              <1> loc_lcde_dir_buffer_last_check:
  2366 00007592 A1[DDB00000]        <1> 	mov	eax, [DirBuff_Cluster]
  2367 00007597 0FB60D[D8B00000]    <1> 	movzx	ecx, byte [DirBuff_ValidData]
  2368                              <1> 
  2369                              <1> loc_lcde_retn:
  2370 0000759E 5E                  <1> 	pop	esi
  2371 0000759F C3                  <1> 	retn
  2372                              <1> 
  2373                              <1> loc_lcde_load_dir_cluster:
  2374                              <1> 	;cmp	byte [DirBuff_ValidData], 2
  2375                              <1> 	;jne	short loc_lcde_load_dir_cluster_n2
  2376 000075A0 50                  <1> 	push	eax
  2377 000075A1 E8F2FCFFFF          <1> 	call	save_directory_buffer
  2378 000075A6 58                  <1> 	pop	eax
  2379 000075A7 72F5                <1> 	jc	short loc_lcde_retn
  2380                              <1> 
  2381                              <1> loc_lcde_load_dir_cluster_n2:
  2382 000075A9 C605[D8B00000]00    <1> 	mov	byte [DirBuff_ValidData], 0
  2383 000075B0 A3[DDB00000]        <1> 	mov	[DirBuff_Cluster], eax
  2384                              <1> 
  2385                              <1> loc_lcde_load_dir_cluster_0:
  2386 000075B5 83E802              <1> 	sub	eax, 2
  2387 000075B8 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  2388 000075BC F7E1                <1> 	mul	ecx
  2389 000075BE 034668              <1>         add     eax, [esi+LD_DATABegin]
  2390                              <1> 
  2391                              <1> loc_lcde_load_dir_cluster_1:
  2392 000075C1 BB00000800          <1> 	mov	ebx, Directory_Buffer
  2393                              <1> 	; ecx = sector count
  2394 000075C6 E878200000          <1> 	call	disk_read
  2395 000075CB 72D1                <1> 	jc	short loc_lcde_retn
  2396                              <1> 
  2397                              <1> loc_lcde_validate_dirBuff:
  2398 000075CD C605[D8B00000]01    <1> 	mov	byte [DirBuff_ValidData], 1
  2399 000075D4 EB9E                <1> 	jmp	short lcde_check_dir_buffer_cluster_next
  2400                              <1> 
  2401                              <1> remove_file:
  2402                              <1> 	; 28/02/2016 (TRDOS 386 = TRDOS v2.0)
  2403                              <1> 	; 10/04/2011 (FILE.ASM, 'proc_delete_file')
  2404                              <1> 	; 09/08/2010
  2405                              <1> 	; INPUT ->
  2406                              <1> 	;	EDI = Directory Buffer Entry Address
  2407                              <1> 	;	 CX = Directory Buffer Entry Counter/Index
  2408                              <1> 	;	 BL = Longname Entry Length
  2409                              <1> 	;	 BH = Logical DOS Drive Number 
  2410                              <1> 
  2411 000075D6 29C0                <1> 	sub	eax, eax
  2412 000075D8 88FC                <1> 	mov	ah, bh
  2413 000075DA BE00010900          <1> 	mov	esi, Logical_DOSDisks
  2414 000075DF 01C6                <1> 	add	esi, eax
  2415                              <1> 
  2416 000075E1 807E0301            <1> 	cmp	byte [esi+LD_FATType], 1
  2417 000075E5 7312                <1> 	jnb	short loc_del_fat_file 
  2418                              <1>               
  2419 000075E7 807E04A1            <1> 	cmp	byte [esi+LD_FSType], 0A1h
  2420 000075EB 7406                <1> 	je	short loc_del_fs_file
  2421                              <1> 
  2422                              <1> loc_del_file_invalid_format:
  2423 000075ED 30E4                <1> 	xor	ah, ah
  2424 000075EF B00B                <1> 	mov	al, 0Bh ; Invalid Format
  2425 000075F1 F9                  <1> 	stc 
  2426 000075F2 C3                  <1> 	retn
  2427                              <1> 
  2428                              <1> loc_del_fs_file:
  2429 000075F3 E8F8000000          <1> 	call	delete_fs_file
  2430 000075F8 C3                  <1> 	retn
  2431                              <1> 
  2432                              <1> loc_del_fat_file:
  2433 000075F9 E808000000          <1> 	call	delete_directory_entry
  2434 000075FE 7205                <1> 	jc	short loc_del_file_err_retn 
  2435                              <1> 
  2436                              <1> loc_delfile_unlink_cluster_chain:
  2437 00007600 E8E8080000          <1> 	call	truncate_cluster_chain
  2438                              <1> 	;jc	short loc_del_file_err_retn
  2439                              <1> 
  2440                              <1> loc_delfile_return:
  2441                              <1> loc_del_file_err_retn:
  2442 00007605 C3                  <1> 	retn
  2443                              <1> 
  2444                              <1> delete_directory_entry:
  2445                              <1> 	; 28/02/2016 (TRDOS 386 = TRDOS v2.0)
  2446                              <1> 	; 01/08/2011 (DIR.ASM, 'proc_delete_directory_entry')
  2447                              <1> 	; 10/04/2011 
  2448                              <1> 	; INPUT ->
  2449                              <1> 	; 	ESI = Logical Dos Drive Descripton Table Address 
  2450                              <1> 	;	EDI = Directory Buffer Entry Address
  2451                              <1> 	;	 CX = Directory Buffer Entry Counter/Index
  2452                              <1> 	;	 BL = Longname Entry Length
  2453                              <1> 	;	 BH = Logical DOS Drive Number 
  2454                              <1> 	; OUTPUT ->
  2455                              <1> 	; 	ESI = Logical dos drive descripton table address 
  2456                              <1> 	;	EAX = First cluster to be truncated/unlinked
  2457                              <1> 	;       CF = 1 -> Error code in EAX (AL)
  2458                              <1> 	;       CF = 0 & BH <> 0 -> LMDT write error  (BH = 1)
  2459                              <1> 	;       CF = 0 & BL <> 0 -> Long name delete error (BL = FFh) 
  2460                              <1> 	;
  2461                              <1> 	;  (EDI, EBX, ECX register contents will be changed)
  2462                              <1> 
  2463 00007606 881D[1AB30000]      <1> 	mov	[DelFile_LNEL], bl
  2464 0000760C 66890D[18B30000]    <1> 	mov	[DelFile_EntryCounter], cx
  2465                              <1> 
  2466 00007613 668B4714            <1> 	mov	ax, [edi+20] ; First Cluster High Word
  2467 00007617 C1E010              <1> 	shl	eax, 16
  2468 0000761A 668B471A            <1> 	mov	ax, [edi+26] ; First Cluster Low Word
  2469                              <1> 
  2470 0000761E A3[14B30000]        <1> 	mov	[DelFile_FCluster], eax
  2471                              <1> 
  2472                              <1> loc_del_short_name:
  2473 00007623 C607E5              <1> 	mov	byte [edi], 0E5h  ; Deleted sign
  2474                              <1> 
  2475 00007626 C605[D8B00000]02    <1> 	mov	byte [DirBuff_ValidData], 2
  2476 0000762D E866FCFFFF          <1> 	call	save_directory_buffer
  2477 00007632 723D                <1> 	jc	short loc_delete_direntry_err_return
  2478                              <1>  
  2479                              <1> loc_del_long_name:
  2480 00007634 0FB615[1AB30000]    <1> 	movzx	edx, byte [DelFile_LNEL]
  2481 0000763B 08D2                <1> 	or	dl, dl
  2482 0000763D 7416                <1> 	jz	short loc_del_dir_entry_update_parent_dir_lm_date
  2483                              <1> 
  2484 0000763F 8835[1AB30000]      <1> 	mov	byte [DelFile_LNEL], dh ; 0              
  2485                              <1>   
  2486 00007645 0FB705[18B30000]    <1> 	movzx	eax,  word [DelFile_EntryCounter]
  2487 0000764C 29D0                <1> 	sub	eax, edx
  2488                              <1> 	;jnc	short loc_del_long_name_continue
  2489 0000764E 7205                <1> 	jc	short loc_del_dir_entry_update_parent_dir_lm_date   
  2490                              <1> 
  2491                              <1> ;loc_del_direntry_inv_data_return:
  2492                              <1> ;	mov	eax, 0Dh ; Invalid data
  2493                              <1> ;	retn
  2494                              <1> 
  2495                              <1> loc_del_long_name_continue: 
  2496                              <1> 	; AX = Directory Entry Number of the long name last entry
  2497 00007650 E89CFDFFFF          <1> 	call	delete_longname
  2498                              <1> 	;jc	short loc_delete_direntry_err_return
  2499                              <1> 
  2500                              <1> loc_del_dir_entry_update_parent_dir_lm_date:
  2501 00007655 801D[1AB30000]00    <1> 	sbb	byte [DelFile_LNEL], 0 ; 0FFh if cf = 1
  2502                              <1> 
  2503 0000765C E8CBFCFFFF          <1> 	call	update_parent_dir_lmdt
  2504 00007661 B700                <1> 	mov	bh, 0
  2505 00007663 80D700              <1> 	adc	bh, 0
  2506                              <1> 
  2507 00007666 8A1D[1AB30000]      <1> 	mov	bl, byte [DelFile_LNEL]
  2508                              <1>  
  2509                              <1> loc_delete_direntry_return:
  2510 0000766C A1[14B30000]        <1> 	mov	eax, [DelFile_FCluster]
  2511                              <1> loc_delete_direntry_err_return:
  2512 00007671 C3                  <1> 	retn
  2513                              <1> 
  2514                              <1> rename_directory_entry:
  2515                              <1> 	; 06/03/2016 (TRDOS 386 = TRDOS v2.0)
  2516                              <1> 	; 01/08/2011 (DIR.ASM, 'proc_rename_directory_entry')
  2517                              <1> 	; 19/11/2010
  2518                              <1> 	; INPUT -> (Current Directory)
  2519                              <1> 	;	CX = Directory Entry Number
  2520                              <1> 	;      EAX = First Cluster number of file or directory
  2521                              <1> 	;      EBX = Longname Length (dir entry count) (< 256)
  2522                              <1> 	;      ESI = New file (or directory) name (no path).
  2523                              <1> 	;           (ASCIIZ string)  
  2524                              <1> 	; OUTPUT -> 
  2525                              <1> 	;      CF = 0 -> successfull
  2526                              <1> 	;      CF = 1 -> error code in EAX (AL)
  2527                              <1> 	;
  2528                              <1> 	; (EAX, EBX, ECX, EDX, ESI, EDI will be changed)
  2529                              <1> 
  2530 00007672 803D[ADA80000]00    <1> 	cmp	byte [Current_FATType], 0
  2531 00007679 7706                <1> 	ja	short loc_rename_directory_entry
  2532                              <1> 
  2533 0000767B E871000000          <1> 	call	rename_fs_file_or_directory
  2534 00007680 C3                  <1> 	retn 
  2535                              <1> 	
  2536                              <1> loc_rename_directory_entry:
  2537 00007681 881D[1AB30000]      <1> 	mov	[DelFile_LNEL], bl
  2538 00007687 66890D[18B30000]    <1> 	mov	[DelFile_EntryCounter], cx
  2539 0000768E A3[14B30000]        <1> 	mov	[DelFile_FCluster], eax
  2540                              <1> 
  2541 00007693 0FB7C1              <1> 	movzx	eax, cx
  2542 00007696 E8C0FDFFFF          <1> 	call	locate_current_dir_entry
  2543 0000769B 7308                <1> 	jnc	short loc_rename_direntry_check_fcluster
  2544                              <1> 
  2545                              <1> loc_rename_direntry_pop_retn:
  2546 0000769D C3                  <1> 	retn
  2547                              <1> 
  2548                              <1> loc_rename_direntry_pop_invd_retn:
  2549 0000769E F9                  <1> 	stc
  2550                              <1> loc_rename_direntry_invd_retn:
  2551 0000769F B80D000000          <1> 	mov	eax, 0Dh ; Invalid data
  2552                              <1> loc_rename_retn:
  2553 000076A4 C3                  <1> 	retn 
  2554                              <1> 
  2555                              <1> loc_rename_direntry_check_fcluster:
  2556 000076A5 668B5714            <1> 	mov	dx, [edi+20] ; First Cluster HW
  2557 000076A9 66C1E210            <1> 	shl	dx, 16
  2558 000076AD 668B571A            <1> 	mov	dx, [edi+26] ; First Cluster LW
  2559 000076B1 3B15[14B30000]      <1> 	cmp	edx, [DelFile_FCluster]
  2560 000076B7 75E5                <1> 	jne	short loc_rename_direntry_pop_invd_retn
  2561                              <1> 	; ESI = New file (or directory) name. (ASCIIZ string)
  2562                              <1> 	; 06/03/2016
  2563                              <1> 	; TRDOS v2 - NOTE: 'convert_file_name' procedure
  2564                              <1> 	; has been modified for eliminating following situation.
  2565                              <1> 	; 
  2566                              <1> 	; TRDOS v1 - NOTE: If file/dir name is more than 11 bytes
  2567                              <1> 	; without a dot, attributes (edi+11) byte will be overwritten !
  2568                              <1> 	; (Dot file name input must be proper for 11 byte dir entry
  2569                              <1> 	;  type file name output.) 
  2570 000076B9 E8ABF6FFFF          <1> 	call	convert_file_name
  2571                              <1> 
  2572 000076BE C605[D8B00000]02    <1>         mov     byte [DirBuff_ValidData], 2
  2573 000076C5 E8CEFBFFFF          <1> 	call	save_directory_buffer
  2574 000076CA 72D8                <1> 	jc	short loc_rename_retn
  2575                              <1> 
  2576                              <1> loc_rename_direntry_del_ln:
  2577 000076CC 0FB615[1AB30000]    <1> 	movzx	edx, byte [DelFile_LNEL]
  2578 000076D3 08D2                <1> 	or	dl, dl
  2579 000076D5 7410                <1> 	jz	short loc_rename_direntry_update_parent_dir_lm_date
  2580                              <1> 
  2581 000076D7 0FB705[18B30000]    <1> 	movzx	eax, word [DelFile_EntryCounter]
  2582 000076DE 29D0                <1> 	sub	eax, edx
  2583 000076E0 72BD                <1> 	jc	short loc_rename_direntry_invd_retn
  2584                              <1> 
  2585                              <1> loc_rename_direntry_del_ln_continue: 
  2586                              <1> 	; EAX = Directory Entry Number of the long name last entry
  2587 000076E2 E80AFDFFFF          <1> 	call	delete_longname
  2588                              <1> 
  2589                              <1> loc_rename_direntry_update_parent_dir_lm_date:
  2590 000076E7 E840FCFFFF          <1> 	call	update_parent_dir_lmdt
  2591 000076EC 31C0                <1> 	xor	eax, eax 
  2592 000076EE C3                  <1> 	retn
  2593                              <1> 
  2594                              <1> make_fs_directory:
  2595                              <1> 	; temporary (21/02/2016)
  2596 000076EF C3                  <1> 	retn
  2597                              <1> 
  2598                              <1> delete_fs_file:
  2599                              <1> 	; temporary (28/02/2016)
  2600 000076F0 C3                  <1> 	retn
  2601                              <1> 
  2602                              <1> rename_fs_file_or_directory:
  2603 000076F1 C3                  <1> 	retn
  1917                                  %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: 02/03/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> 	; 01/02/2016 (TRDOS 386 =  TRDOS v2.0)
    17                              <1> 	; 05/07/2011
    18                              <1> 	; 07/07/2009
    19                              <1> 	; 2005
    20                              <1> 	; INPUT ->
    21                              <1> 	;	EAX = Cluster Number (32 bit)
    22                              <1> 	;	ESI = Logical DOS Drive Parameters Table
    23                              <1> 	; OUTPUT ->
    24                              <1> 	;	cf = 0 -> No Error, EAX valid
    25                              <1> 	;	cf = 1 & EAX = 0 -> End Of Cluster Chain
    26                              <1> 	;	cf = 1 & EAX > 0 -> Error
    27                              <1> 	;	ECX = Current/Previous cluster (if CF = 0)
    28                              <1> 	;	EAX = Next Cluster Number (32 bit)
    29                              <1> 	;
    30                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
    31                              <1> 
    32 000076F2 A3[C1B00000]        <1> 	mov	[FAT_CurrentCluster], eax
    33                              <1> check_next_cluster_fat_type:
    34 000076F7 29D2                <1> 	sub	edx, edx ; 0
    35 000076F9 807E0302            <1>         cmp     byte [esi+LD_FATType], 2
    36 000076FD 7250                <1> 	jb	short get_FAT12_next_cluster
    37 000076FF 0F87AF000000        <1>         ja      get_FAT32_next_cluster
    38                              <1> get_FAT16_next_cluster:
    39 00007705 BB00030000          <1> 	mov	ebx, 300h ;768
    40 0000770A F7F3                <1> 	div	ebx
    41                              <1> 	; EAX = Count of 3 FAT sectors
    42                              <1> 	; EDX = Cluster Offset (< 768)
    43 0000770C 66D1E2              <1> 	shl	dx, 1 ; Multiply by 2
    44 0000770F 89D3                <1> 	mov	ebx, edx ; Byte Offset
    45 00007711 81C3001C0900        <1> 	add	ebx, FAT_Buffer
    46 00007717 66BA0300            <1> 	mov	dx, 3
    47 0000771B F7E2                <1> 	mul	edx  
    48                              <1> 	; EAX = FAT Sector (<= 256)
    49                              <1> 	; EDX = 0
    50 0000771D 8A0E                <1> 	mov	cl, [esi+LD_Name]
    51 0000771F 803D[C5B00000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
    52 00007726 0F86CC000000        <1>         jna     load_FAT_sectors0
    53 0000772C 3A0D[C6B00000]      <1> 	cmp	cl, [FAT_BuffDrvName]
    54 00007732 0F85C0000000        <1>         jne     load_FAT_sectors0
    55 00007738 3B05[C9B00000]      <1> 	cmp	eax, [FAT_BuffSector]
    56 0000773E 0F85BA000000        <1>         jne     load_FAT_sectors1
    57                              <1> 	;movzx	eax, word [ebx]
    58 00007744 668B03              <1> 	mov	ax, [ebx]
    59                              <1> 	; 01/02/2016
    60                              <1> 	; DRV_FAT.ASM (21/08/2011) had a FATal bug here !
    61                              <1> 	; (cmp ah, 0Fh) ! (ax >= FF7h)
    62                              <1> 	; (how can i do a such mistake!?)
    63                              <1> 	;cmp	al, 0F7h
    64                              <1> 	;jb	short loc_pass_gnc_FAT16_eoc_check
    65                              <1> 	;cmp	ah, 0FFh
    66                              <1> 	;jb	short loc_pass_gnc_FAT16_eoc_check
    67 00007747 6683F8F7            <1> 	cmp	ax, 0FFF7h
    68 0000774B 725A                <1> 	jb	short loc_pass_gnc_FAT16_eoc_check
    69                              <1> 	; ax >= FFF7h (cluster 0002h to FFF6h is valid, in use)
    70 0000774D EB56                <1> 	jmp	short loc_pass_gnc_FAT16_eoc_check_xor_eax
    71                              <1> 
    72                              <1> get_FAT12_next_cluster:
    73 0000774F BB00040000          <1> 	mov	ebx, 400h ;1024
    74 00007754 F7F3                <1> 	div	ebx
    75                              <1> 	; EAX = Count of 3 FAT sectors
    76                              <1> 	; EDX = Cluster Offset (< 1024)
    77 00007756 6650                <1> 	push	ax
    78 00007758 66B80300            <1> 	mov	ax, 3	
    79 0000775C 66F7E2              <1> 	mul	dx    	; Multiply by 3
    80 0000775F 66D1E8              <1> 	shr	ax, 1	; Divide by 2
    81 00007762 6689C3              <1>         mov	bx, ax 	; Byte Offset
    82 00007765 81C3001C0900        <1> 	add	ebx, FAT_Buffer
    83 0000776B 6658                <1> 	pop	ax
    84 0000776D 66BA0300            <1> 	mov	dx, 3
    85 00007771 F7E2                <1> 	mul	edx 
    86                              <1> 	; EAX = FAT Sector (<= 12)
    87                              <1> 	; EDX = 0
    88 00007773 8A0E                <1> 	mov	cl, [esi+LD_Name]
    89 00007775 803D[C5B00000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
    90 0000777C 767A                <1> 	jna	short load_FAT_sectors0
    91 0000777E 3A0D[C6B00000]      <1> 	cmp	cl, [FAT_BuffDrvName]
    92 00007784 7572                <1> 	jne	short load_FAT_sectors0
    93 00007786 3B05[C9B00000]      <1> 	cmp	eax, [FAT_BuffSector]
    94 0000778C 7570                <1> 	jne	short load_FAT_sectors1
    95 0000778E A1[C1B00000]        <1> 	mov	eax, [FAT_CurrentCluster]
    96 00007793 66D1E8              <1> 	shr	ax, 1
    97                              <1> 	;movzx	eax, word [ebx]
    98 00007796 668B03              <1> 	mov	ax, [ebx]
    99 00007799 7314                <1> 	jnc	short get_FAT12_nc_even
   100 0000779B 66C1E804            <1> 	shr	ax, 4
   101                              <1> loc_gnc_fat12_eoc_check:
   102                              <1> 	;cmp	al, 0F7h
   103                              <1> 	;jb	short loc_pass_gnc_FAT16_eoc_check
   104                              <1> 	;cmp	ah, 0Fh
   105                              <1> 	;jb	short loc_pass_gnc_FAT16_eoc_check
   106 0000779F 663DF70F            <1> 	cmp	ax, 0FF7h
   107 000077A3 7202                <1> 	jb	short loc_pass_gnc_FAT16_eoc_check
   108                              <1> 	; ax >= FF7h (cluster 0002h to FF6h is valid, in use)
   109                              <1> 
   110                              <1> loc_pass_gnc_FAT16_eoc_check_xor_eax:
   111 000077A5 31C0                <1> 	xor	eax, eax ; 0
   112                              <1> loc_pass_gnc_FAT16_eoc_check:
   113                              <1> loc_pass_gnc_FAT32_eoc_check:
   114 000077A7 8B0D[C1B00000]      <1> 	mov	ecx, [FAT_CurrentCluster]
   115 000077AD F5                  <1> 	cmc
   116 000077AE C3                  <1> 	retn
   117                              <1> 
   118                              <1> get_FAT12_nc_even:
   119 000077AF 80E40F              <1> 	and	ah, 0Fh
   120 000077B2 EBEB                <1> 	jmp	short loc_gnc_fat12_eoc_check
   121                              <1> 
   122                              <1> get_FAT32_next_cluster:
   123 000077B4 BB80010000          <1> 	mov	ebx, 180h ;384
   124 000077B9 F7F3                <1> 	div	ebx
   125                              <1> 	; EAX = Count of 3 FAT sectors
   126                              <1> 	; EDX = Cluster Offset (< 384)
   127 000077BB 66C1E202            <1> 	shl	dx, 2	; Multiply by 4
   128 000077BF 89D3                <1> 	mov	ebx, edx ; Byte Offset
   129 000077C1 81C3001C0900        <1> 	add	ebx, FAT_Buffer
   130 000077C7 66BA0300            <1> 	mov	dx, 3
   131 000077CB F7E2                <1> 	mul	edx	
   132                              <1>         ; EAX = FAT Sector (<= 2097152) ; (FFFFFF7h * 4) / 512
   133                              <1> 	; 	for 32KB cluster size:
   134                              <1> 	;	EAX <= 1024 = (4GB / 32KB) * 4) / 512 	
   135                              <1> 	; EDX = 0
   136 000077CD 8A0E                <1> 	mov	cl, [esi+LD_Name]
   137 000077CF 803D[C5B00000]00    <1> 	cmp	byte [FAT_BuffValidData], 0
   138 000077D6 7620                <1> 	jna	short load_FAT_sectors0
   139 000077D8 3A0D[C6B00000]      <1> 	cmp	cl, [FAT_BuffDrvName]
   140 000077DE 7518                <1> 	jne	short load_FAT_sectors0
   141 000077E0 3B05[C9B00000]      <1> 	cmp	eax, [FAT_BuffSector] ; 0, 3, 6, 9 ...
   142 000077E6 7516                <1> 	jne	short load_FAT_sectors1
   143 000077E8 8B03                <1> 	mov	eax, [ebx]
   144 000077EA 25FFFFFF0F          <1>  	and	eax, 0FFFFFFFh ; 28 bit Cluster
   145 000077EF 3DF7FFFF0F          <1> 	cmp	eax, 0FFFFFF7h
   146 000077F4 72B1                <1> 	jb	short loc_pass_gnc_FAT32_eoc_check
   147                              <1> 	; eax >= FFFFFF7h (cluster 0002h to FFFFFF6h is valid)
   148 000077F6 EBAD                <1> 	jmp	short loc_pass_gnc_FAT16_eoc_check_xor_eax
   149                              <1> 
   150                              <1> load_FAT_sectors0:
   151 000077F8 880D[C6B00000]      <1> 	mov	[FAT_BuffDrvName], cl
   152                              <1> load_FAT_sectors1:
   153 000077FE A3[C9B00000]        <1> 	mov	[FAT_BuffSector], eax
   154 00007803 89C3                <1> 	mov	ebx, eax
   155 00007805 034660              <1>         add     eax, [esi+LD_FATBegin]
   156 00007808 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
   157 0000780C 7706                <1>         ja      short load_FAT_sectors3
   158 0000780E 0FB74E1C            <1> 	movzx	ecx, word [esi+LD_BPB+BPB_FATSz16]
   159 00007812 EB03                <1> 	jmp	short load_FAT_sectors4
   160                              <1> load_FAT_sectors3:
   161 00007814 8B4E2A              <1> 	mov	ecx, [esi+LD_BPB+BPB_FATSz32]
   162                              <1> load_FAT_sectors4:
   163 00007817 29D9                <1> 	sub	ecx, ebx ; [FAT_BuffSector]
   164 00007819 83F903              <1>         cmp     ecx, 3
   165 0000781C 7605                <1>         jna     short load_FAT_sectors5
   166 0000781E B903000000          <1> 	mov	ecx, 3
   167                              <1> load_FAT_sectors5:
   168 00007823 BB001C0900          <1> 	mov	ebx, FAT_Buffer
   169 00007828 E8161E0000          <1> 	call	disk_read
   170 0000782D 7308                <1> 	jnc	short load_FAT_sectors_ok
   171 0000782F C605[C5B00000]00    <1> 	mov	byte [FAT_BuffValidData], 0
   172 00007836 C3                  <1> 	retn
   173                              <1> load_FAT_sectors_ok:
   174 00007837 C605[C5B00000]01    <1> 	mov	byte [FAT_BuffValidData], 1
   175 0000783E A1[C1B00000]        <1> 	mov	eax, [FAT_CurrentCluster]
   176 00007843 E9AFFEFFFF          <1>         jmp     check_next_cluster_fat_type
   177                              <1> 
   178                              <1> load_FAT_root_directory:
   179                              <1> 	; 07/02/2016
   180                              <1> 	; 02/02/2016
   181                              <1> 	; 01/02/2016 (TRDOS 386 =  TRDOS v2.0)
   182                              <1> 	; 21/05/2011
   183                              <1> 	; 22/08/2009
   184                              <1> 	;
   185                              <1> 	; INPUT ->
   186                              <1> 	;	ESI = Logical DOS Drive Description Table
   187                              <1> 	; OUTPUT ->
   188                              <1> 	;	cf = 1 -> Root directory could not be loaded
   189                              <1> 	;	    EAX > 0 -> Error number
   190                              <1> 	;	cf = 0 -> EAX = 0
   191                              <1> 	;	ECX = Directory buffer size in sectors (CL)
   192                              <1> 	;	EBX = Directory buffer address
   193                              <1> 	; 	NOTE: DirBuffer_Size is in bytes ! (word)
   194                              <1> 	;
   195                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
   196                              <1> 
   197                              <1> 	; NOTE: Only for FAT12 and FAT16 file systems !
   198                              <1> 	; (FAT32 fs root dir must be loaded as sub directory)
   199                              <1> 
   200 00007848 8A1E                <1> 	mov	bl, [esi+LD_Name]
   201 0000784A 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   202                              <1> 
   203                              <1> 	;mov	[DirBuff_DRV], bl
   204                              <1> 	;mov	[DirBuff_FATType], bh
   205 0000784D 66891D[D6B00000]    <1> 	mov	[DirBuff_DRV], bx
   206                              <1> 	
   207                              <1> 	;cmp	bh, 2
   208                              <1> 	;ja	short load_FAT32_root_dir0 ; FAT32 root dir
   209                              <1> 
   210 00007854 0FB75617            <1> 	movzx	edx, word [esi+LD_BPB+RootDirEnts]
   211                              <1> 
   212                              <1> 	;or	dx, dx ; 0 for FAT32 file systems
   213                              <1> 	;jz	short load_FAT32_root_dir0 ; FAT32 root dir
   214                              <1> 
   215 00007858 6681FA0002          <1> 	cmp	dx, 512 ; Number of Root Dir Entries
   216 0000785D 7414                <1> 	je	short lrd_mov_ecx_32
   217 0000785F 89D0                <1> 	mov	eax, edx
   218 00007861 6683C00F            <1> 	add	ax, 15 ; round up 
   219 00007865 66C1E804            <1> 	shr	ax, 4  ; 16 entries per sector (512/32)
   220 00007869 89C1                <1> 	mov	ecx, eax ; Root directory size in sectors
   221 0000786B 66C1E009            <1> 	shl	ax, 9 ; Root directory size in bytes
   222 0000786F 664A                <1> 	dec	dx    ; Last entry number of root dir
   223                              <1> 	; cx = Dir Buffer sector count             
   224 00007871 EB0B                <1> 	jmp	short lrd_check_dir_buffer
   225                              <1> 
   226                              <1> lrd_mov_ecx_32:
   227 00007873 B920000000          <1> 	mov	ecx, 32
   228 00007878 664A                <1> 	dec	dx ; 511
   229 0000787A 66B80040            <1> 	mov	ax, 32*512 
   230                              <1>  
   231                              <1> lrd_check_dir_buffer:
   232 0000787E 29DB                <1> 	sub	ebx, ebx ; 0
   233 00007880 881D[D8B00000]      <1> 	mov	[DirBuff_ValidData], bl ; 0
   234 00007886 668915[DBB00000]    <1> 	mov	[DirBuff_LastEntry], dx
   235 0000788D 891D[DDB00000]      <1> 	mov	[DirBuff_Cluster], ebx ; 0
   236 00007893 66A3[E1B00000]      <1> 	mov	[DirBuffer_Size], ax
   237                              <1> 
   238 00007899 8B4664              <1> 	mov	eax, [esi+LD_ROOTBegin]
   239                              <1> read_directory:
   240 0000789C BB00000800          <1> 	mov	ebx, Directory_Buffer
   241 000078A1 51                  <1> 	push	ecx ; Directory buffer sector count
   242 000078A2 53                  <1> 	push	ebx
   243 000078A3 E89B1D0000          <1> 	call	disk_read
   244 000078A8 5B                  <1> 	pop	ebx
   245 000078A9 720B                <1> 	jc	short load_DirBuff_error
   246                              <1> 
   247                              <1> validate_DirBuff_and_return:
   248 000078AB 59                  <1> 	pop	ecx ; Number of loaded sectors
   249 000078AC C605[D8B00000]01    <1> 	mov	byte [DirBuff_ValidData], 1
   250 000078B3 31C0                <1> 	xor	eax, eax ; 0 = no error
   251 000078B5 C3                  <1> 	retn
   252                              <1> 
   253                              <1> load_DirBuff_error:
   254 000078B6 89C8                <1> 	mov	eax, ecx ; remaining sectors
   255 000078B8 59                  <1> 	pop	ecx ; sector count
   256 000078B9 29C1                <1> 	sub	ecx, eax ; Number of loaded sectors
   257 000078BB B815000000          <1> 	mov	eax, 15h ; DRV NOT READY OR READ ERROR !
   258 000078C0 F9                  <1> 	stc
   259 000078C1 C3                  <1>         retn
   260                              <1> 
   261                              <1> load_FAT32_root_directory:
   262                              <1> 	; 02/02/2016 (TRDOS 386 =  TRDOS v2.0)
   263                              <1> 	;
   264                              <1> 	; INPUT ->
   265                              <1> 	;	ESI = Logical DOS Drive Description Table
   266                              <1> 	; OUTPUT ->
   267                              <1> 	;	cf = 1 -> Root directory could not be loaded
   268                              <1> 	;	    EAX > 0 -> Error number
   269                              <1> 	;	cf = 0 -> EAX = 0
   270                              <1> 	;	ECX = Directory buffer size in sectors (CL)
   271                              <1> 	;	EBX = Directory buffer address
   272                              <1> 	; 	NOTE: DirBuffer_Size is in bytes ! (word)
   273                              <1> 	;
   274                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
   275                              <1> 
   276                              <1> 
   277 000078C2 8A1E                <1> 	mov	bl, [esi+LD_Name]
   278 000078C4 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   279                              <1> 
   280                              <1> 	;mov	[DirBuff_DRV], bl
   281                              <1> 	;mov	[DirBuff_FATType], bh
   282 000078C7 66891D[D6B00000]    <1> 	mov	[DirBuff_DRV], bx
   283                              <1> 
   284                              <1> load_FAT32_root_dir0:
   285 000078CE 8B4632              <1> 	mov	eax, [esi+LD_BPB+FAT32_RootFClust]
   286 000078D1 EB0C                <1> 	jmp	short load_FAT_sub_dir0
   287                              <1> 	
   288                              <1> load_FAT_sub_directory:
   289                              <1> 	; 01/02/2016 (TRDOS 386 =  TRDOS v2.0)
   290                              <1> 	; 05/07/2011
   291                              <1> 	; 23/08/2009
   292                              <1> 	;
   293                              <1> 	; INPUT ->
   294                              <1> 	;	ESI = Logical DOS Drive Description Table
   295                              <1> 	;	EAX = Cluster Number
   296                              <1> 	; OUTPUT ->
   297                              <1> 	;	cf = 1 -> Sub directory could not be loaded
   298                              <1> 	;	    EAX > 0 -> Error number
   299                              <1> 	;	cf = 0 -> EAX = 0
   300                              <1> 	;	ECX = Directory buffer size in sectors (CL)
   301                              <1> 	;	EBX = Directory buffer address
   302                              <1> 	;
   303                              <1> 	; 	NOTE: DirBuffer_Size is in bytes ! (word)
   304                              <1> 	;
   305                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
   306                              <1> 
   307 000078D3 8A1E                <1> 	mov	bl, [esi+LD_Name]
   308 000078D5 8A7E03              <1> 	mov	bh, [esi+LD_FATType]
   309                              <1> 
   310                              <1> 	;mov	[DirBuff_DRV], bl
   311                              <1> 	;mov	[DirBuff_FATType], bh
   312 000078D8 66891D[D6B00000]    <1> 	mov	[DirBuff_DRV], bx
   313                              <1> 
   314                              <1> load_FAT_sub_dir0:
   315 000078DF 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
   316                              <1> 
   317 000078E3 882D[D8B00000]      <1> 	mov	[DirBuff_ValidData], ch ; 0
   318 000078E9 A3[DDB00000]        <1> 	mov	[DirBuff_Cluster], eax
   319                              <1> 
   320 000078EE 0FB74611            <1> 	movzx	eax, word [esi+LD_BPB+BytesPerSec]
   321 000078F2 F7E1                <1> 	mul	ecx
   322 000078F4 C1E805              <1> 	shr	eax, 5 ; directory entry count (dir size / 32)
   323 000078F7 6648                <1> 	dec	ax ; last entry
   324 000078F9 66A3[DBB00000]      <1> 	mov	[DirBuff_LastEntry], ax
   325                              <1> 
   326 000078FF A1[DDB00000]        <1> 	mov	eax, [DirBuff_Cluster]
   327 00007904 83E802              <1> 	sub	eax, 2
   328 00007907 F7E1                <1> 	mul	ecx
   329 00007909 034668              <1> 	add	eax, [esi+LD_DATABegin]
   330                              <1> 	; ecx = sector per cluster (dir buffer size = 32 sectors)
   331 0000790C EB8E                <1> 	jmp	short read_directory
   332                              <1> 
   333                              <1> ; DRV_FS.ASM
   334                              <1> 
   335                              <1> load_current_FS_directory:
   336 0000790E C3                  <1> 	retn
   337                              <1> load_FS_root_directory:
   338 0000790F C3                  <1> 	retn
   339                              <1> load_FS_sub_directory:
   340 00007910 C3                  <1> 	retn
   341                              <1> 
   342                              <1> read_cluster:
   343                              <1> 	; 17/02/2016
   344                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
   345                              <1> 	;
   346                              <1> 	; INPUT ->
   347                              <1> 	;	EAX = Cluster Number (Sector index for SINGLIX FS)
   348                              <1> 	;	ESI = Logical DOS Drive Description Table address
   349                              <1> 	;	EBX = Cluster (File R/W) Buffer address (max. 64KB)
   350                              <1> 	;	Only for SINGLIX FS:
   351                              <1> 	;	EDX = File Number (The 1st FDT address) 
   352                              <1> 	; OUTPUT ->
   353                              <1> 	;	cf = 1 -> Cluster can not be loaded at the buffer
   354                              <1> 	;	    EAX > 0 -> Error number
   355                              <1> 	;	cf = 0 -> Cluster has been loaded at the buffer
   356                              <1> 	;
   357                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
   358                              <1> 	
   359 00007911 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+BPB_SecPerClust] 
   360                              <1> 	; CL = 1 = [esi+LD_FS_Reserved2] ; SectPerClust for Singlix FS
   361                              <1> 
   362 00007915 807E0300            <1> 	cmp	byte [esi+LD_FATType], 0
   363 00007919 7618                <1> 	jna	short read_fs_cluster
   364                              <1> 
   365 0000791B 83E802              <1> 	sub	eax, 2 ; Beginning cluster number is always 2
   366 0000791E F7E1                <1> 	mul	ecx
   367 00007920 034668              <1> 	add	eax, [esi+LD_DATABegin] ; absolute address of the cluster
   368                              <1> 	
   369 00007923 E81B1D0000          <1> 	call	disk_read
   370 00007928 7306                <1> 	jnc	short rclust_retn
   371                              <1> 	
   372 0000792A B815000000          <1> 	mov	eax, 15h ; Drive not ready or read error !
   373 0000792F C3                  <1> 	retn
   374                              <1> 
   375                              <1> rclust_retn:
   376 00007930 29C0                <1> 	sub	eax, eax ; 0
   377 00007932 C3                  <1> 	retn
   378                              <1> 
   379                              <1> read_fs_cluster:
   380                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
   381                              <1> 	; Singlix FS
   382                              <1> 	
   383                              <1> 	; EAX = Cluster number is sector index number of the file (eax)
   384                              <1> 	
   385                              <1> 	; EDX = File number is the first File Descriptor Table address 
   386                              <1> 	;	of the file. (Absolute address of the FDT).
   387                              <1> 	
   388                              <1> 	; eax = sector index (0 for the first sector)
   389                              <1> 	; edx = FDT0 address
   390                              <1> 		; 64 KB buffer = 128 sectors (limit) 
   391 00007933 B980000000          <1> 	mov	ecx, 128 ; maximum count of sectors (before eof) 
   392 00007938 E801000000          <1> 	call	read_fs_sectors
   393 0000793D C3                  <1> 	retn
   394                              <1> 
   395                              <1> read_fs_sectors:
   396                              <1> 	; 15/02/2016 (TRDOS 386 =  TRDOS v2.0)
   397 0000793E F9                  <1> 	stc
   398 0000793F C3                  <1> 	retn
   399                              <1> 
   400                              <1> get_first_free_cluster:
   401                              <1> 	; 02/03/2016
   402                              <1> 	; 21/02/2016 (TRDOS 386 =  TRDOS v2.0)
   403                              <1> 	; 26/10/2010 (DRV_FAT.ASM, 'proc_get_first_free_cluster')
   404                              <1> 	; 10/07/2010
   405                              <1> 	; INPUT ->
   406                              <1> 	;	ESI = Logical DOS Drive Description Table address
   407                              <1> 	; OUTPUT ->
   408                              <1> 	;	cf = 1 -> Error code in AL (EAX)
   409                              <1> 	;	cf = 0 -> 
   410                              <1> 	;	  If EAX = FFFFFFFFh -> no free space
   411                              <1> 	;	If the drive has FAT32 fs:
   412                              <1> 	;	  EBX = FAT32 FSI sector buffer address (if > 0)
   413                              <1> 
   414 00007940 8B4678              <1> 	mov	eax, [esi+LD_Clusters]
   415 00007943 40                  <1> 	inc	eax ; add eax, 1
   416 00007944 A3[60B30000]        <1> 	mov	[gffc_last_free_cluster], eax
   417                              <1> 
   418 00007949 31DB                <1> 	xor	ebx, ebx ; 0 ; 02/03/2016
   419                              <1> 
   420 0000794B 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
   421 0000794F 760E                <1> 	jna	short loc_gffc_get_first_fat_free_cluster0
   422                              <1> 
   423                              <1> loc_gffc_get_first_fat32_free_cluster:
   424                              <1> 	; 02/03/2016
   425 00007951 E81E060000          <1> 	call	get_fat32_fsinfo_sector_parms
   426 00007956 7207                <1> 	jc	short loc_gffc_get_first_fat_free_cluster0 
   427                              <1> 
   428                              <1> loc_gffc_check_fsinfo_parms:
   429                              <1> 	;;mov	ebx, DOSBootSectorBuff
   430                              <1> 	;cmp	dword [ebx], 41615252h
   431                              <1> 	;jne	short loc_gffc_fat32_fsinfo_err
   432                              <1> 	;cmp	dword [ebx+484], 61417272h
   433                              <1> 	;jne	short loc_gffc_fat32_fsinfo_err
   434                              <1> 	;mov	eax, [ebx+492] ; FSI_Next_Free
   435                              <1> 	;EAX = First free cluster 
   436                              <1> 	;(from FAT32 FSInfo sector)
   437 00007958 89D0                <1> 	mov	eax, edx ; FSI_Next_Free (First Free Cluster)
   438 0000795A 83F8FF              <1> 	cmp	eax, 0FFFFFFFFh ; invalid (unknown) !
   439 0000795D 7205                <1> 	jb	short loc_gffc_get_first_fat_free_cluster1
   440                              <1> 
   441                              <1> 	; Start from the 1st cluster of the FAT(32) file system
   442                              <1> loc_gffc_get_first_fat_free_cluster0:
   443 0000795F B802000000          <1> 	mov	eax, 2
   444                              <1> 	;xor	edx, edx
   445                              <1> 
   446                              <1> loc_gffc_get_first_fat_free_cluster1:
   447 00007964 53                  <1> 	push	ebx ; 02/03/2016 
   448                              <1> 
   449                              <1> loc_gffc_get_first_fat_free_cluster2:   
   450 00007965 A3[5CB30000]        <1> 	mov	[gffc_first_free_cluster], eax
   451 0000796A A3[58B30000]        <1> 	mov	[gffc_next_free_cluster], eax
   452                              <1> 
   453                              <1> 	; EBX = FAT32 FSINFO sector buffer address
   454                              <1> 	; (EBX = 0, if the drive has not got FAT32 fs or
   455                              <1> 	; FAT32 FSINFO sector buffer is invalid.)
   456                              <1> 
   457                              <1> loc_gffc_get_first_fat_free_cluster3:
   458 0000796F E87EFDFFFF          <1> 	call	get_next_cluster
   459 00007974 7307                <1> 	jnc	short loc_gffc_get_first_fat_free_cluster4
   460 00007976 09C0                <1> 	or	eax, eax
   461 00007978 740B                <1> 	jz	short loc_gffc_first_free_fat_cluster_next
   462 0000797A 5B                  <1> 	pop	ebx ; 02/03/2016
   463 0000797B F5                  <1> 	cmc 	; stc
   464 0000797C C3                  <1> 	retn
   465                              <1> 
   466                              <1> loc_gffc_get_first_fat_free_cluster4:
   467 0000797D 21C0                <1> 	and	eax, eax ; next cluster value
   468 0000797F 7504                <1> 	jnz	short loc_gffc_first_free_fat_cluster_next
   469 00007981 89C8                <1> 	mov	eax, ecx ; current (previous cluster) value
   470 00007983 EB22                <1> 	jmp	short loc_gffc_check_for_set
   471                              <1>  
   472                              <1> loc_gffc_first_free_fat_cluster_next:
   473 00007985 A1[58B30000]        <1> 	mov	eax, [gffc_next_free_cluster]
   474 0000798A 3B05[60B30000]      <1> 	cmp	eax, [gffc_last_free_cluster]
   475 00007990 7308                <1> 	jnb	short retn_stc_from_get_first_free_cluster
   476                              <1> pass_gffc_last_cluster_eax_check:
   477 00007992 40                  <1> 	inc	eax ; add eax, 1
   478 00007993 A3[58B30000]        <1> 	mov	[gffc_next_free_cluster], eax
   479 00007998 EBD5                <1> 	jmp	short loc_gffc_get_first_fat_free_cluster3
   480                              <1> 
   481                              <1> retn_stc_from_get_first_free_cluster:
   482 0000799A A1[5CB30000]        <1> 	mov	eax, [gffc_first_free_cluster]
   483 0000799F 83F802              <1> 	cmp	eax, 2
   484 000079A2 7709                <1> 	ja	short loc_gffc_check_previous_clusters
   485 000079A4 29C0                <1> 	sub	eax, eax
   486 000079A6 48                  <1> 	dec	eax ; FFFFFFFFh
   487                              <1> 
   488                              <1> loc_gffc_check_for_set:
   489                              <1> 	; 02/03/2016
   490 000079A7 5B                  <1> 	pop	ebx
   491                              <1> 
   492                              <1> 	; EBX = FAT32 FSINFO sector buffer address
   493                              <1> 	; (EBX = 0, if the drive has not got FAT32 fs or
   494                              <1> 	; FAT32 FSINFO sector buffer is invalid.)
   495                              <1> 
   496 000079A8 09DB                <1> 	or	ebx, ebx
   497 000079AA 750E                <1> 	jnz	short loc_gffc_set_ffree_fat32_cluster
   498                              <1> 
   499                              <1> 	;cmp	byte [esi+LD_FATType], 3
   500                              <1> 	;jnb	short loc_gffc_set_ffree_fat32_cluster
   501                              <1> 
   502                              <1> 	;xor	ebx, ebx ; 0
   503                              <1> 
   504                              <1> loc_gffc_retn:
   505 000079AC C3                  <1> 	retn
   506                              <1> 
   507                              <1> loc_gffc_check_previous_clusters:
   508 000079AD 48                  <1> 	dec	eax ; sub eax, 1
   509 000079AE A3[60B30000]        <1> 	mov	[gffc_last_free_cluster], eax 
   510 000079B3 B802000000          <1> 	mov	eax, 2
   511                              <1> 	;xor	edx, edx
   512 000079B8 EBAB                <1> 	jmp	short loc_gffc_get_first_fat_free_cluster2
   513                              <1> 
   514                              <1> loc_gffc_set_ffree_fat32_cluster:
   515                              <1> 	;call	set_first_free_cluster
   516                              <1> 	;retn
   517                              <1> 	;jmp	short set_first_free_cluster	
   518                              <1> 
   519                              <1> set_first_free_cluster:
   520                              <1> 	; 02/03/2016
   521                              <1> 	; 29/02/2016
   522                              <1> 	; 26/02/2016
   523                              <1> 	; 21/02/2016 (TRDOS 386 =  TRDOS v2.0)
   524                              <1> 	; 21/08/2011 (DRV_FAT.ASM, 'proc_set_first_free_cluster')
   525                              <1> 	; 11/07/2010
   526                              <1> 	; INPUT -> 
   527                              <1> 	;	ESI = Logical DOS Drive Description Table address
   528                              <1> 	;	EAX = First free cluster
   529                              <1> 	;	EBX = FSINFO sector buffer address
   530                              <1> 	;  	;;If EBX > 0, it is FSINFO sector buffer address
   531                              <1> 	;	;;EBX = 0, if FSINFO sector is not loaded
   532                              <1> 	; OUTPUT->
   533                              <1> 	;	ESI = Logical DOS Drive Description Table address
   534                              <1> 	;  	If EBX > 0, it is FSINFO sector buffer address
   535                              <1> 	;	EBX = 0, if FSINFO sector could not be loaded
   536                              <1> 	; 	CF = 1 -> Error code in AL (EAX)
   537                              <1> 	;	CF = 0 -> first free cluster is successfully updated 
   538                              <1> 
   539                              <1> 	;cmp	byte [esi+LD_FATType], 3
   540                              <1> 	;jb	short loc_sffc_invalid_drive
   541                              <1> 
   542                              <1> 	; Save First Free Cluster value for 'update_cluster'
   543 000079BA 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; First free Cluster	
   544                              <1> 
   545                              <1> 	;or	ebx, ebx
   546                              <1> 	;jnz	short loc_sffc_read_fsinfo_sector
   547                              <1> 
   548 000079BD 813B52526141        <1> 	cmp     dword [ebx], 41615252h
   549 000079C3 753B                <1> 	jne	short loc_sffc_read_fsinfo_sector
   550 000079C5 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
   550 000079CE 61                  <1>
   551 000079CF 752F                <1> 	jne	short loc_sffc_read_fsinfo_sector
   552                              <1> 
   553 000079D1 3B83EC010000        <1> 	cmp	eax, [ebx+492]  ; FSI_Next_Free
   554 000079D7 741F                <1> 	je	short loc_sffc_retn
   555                              <1> 
   556                              <1> loc_sffc_write_fsinfo_sector:
   557                              <1> 	; EBX = FSINFO sector buffer
   558                              <1> 	; [CFS_FAT32FSINFOSEC] is set in 'get_fat32_fsinfo_sector_parms'
   559 000079D9 8983EC010000        <1> 	mov	[ebx+492], eax
   560 000079DF A1[70B30000]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC] 
   561 000079E4 B901000000          <1> 	mov	ecx, 1
   562 000079E9 53                  <1> 	push	ebx
   563 000079EA E8451C0000          <1> 	call	disk_write
   564 000079EF 7208                <1> 	jc      short loc_sffc_read_fsinfo_sector_err1
   565 000079F1 5B                  <1> 	pop	ebx
   566                              <1> 
   567 000079F2 8B83EC010000        <1> 	mov	eax, [ebx+492] ; First (Next) Free Cluster
   568                              <1> 
   569                              <1> loc_sffc_retn:
   570 000079F8 C3                  <1> 	retn
   571                              <1> 
   572                              <1> ;loc_sffc_invalid_drive:
   573                              <1> ;	mov	eax, 0Fh ; MSDOS Error : Invalid drive
   574                              <1> ;	push	edx
   575                              <1> 
   576                              <1> loc_sffc_read_fsinfo_sector_err1:
   577 000079F9 BB00000000          <1> 	mov	ebx, 0
   578                              <1> loc_sffc_read_fsinfo_sector_err2:
   579 000079FE 5A                  <1> 	pop	edx
   580 000079FF C3                  <1> 	retn
   581                              <1> 	
   582                              <1> loc_sffc_read_fsinfo_sector:
   583 00007A00 50                  <1> 	push	eax
   584                              <1> 
   585 00007A01 E86E050000          <1> 	call	get_fat32_fsinfo_sector_parms
   586 00007A06 72F6                <1> 	jc	short loc_sffc_read_fsinfo_sector_err2
   587                              <1> 
   588 00007A08 58                  <1> 	pop	eax
   589                              <1> 	; EDX = First (Next) Free Cluster value from FSINFO sector
   590                              <1> 	; EAX = First Free Cluster value from 'get_next_cluster'
   591                              <1> 	; (edx = old value)
   592 00007A09 39D0                <1> 	cmp	eax, edx ; First free Cluster (eax = new value) 
   593 00007A0B 75CC                <1> 	jne	short loc_sffc_write_fsinfo_sector
   594                              <1> 
   595 00007A0D C3                  <1> 	retn	
   596                              <1> 
   597                              <1> update_cluster:
   598                              <1> 	; 02/03/2016
   599                              <1> 	; 01/03/2016
   600                              <1> 	; 29/02/2016
   601                              <1> 	; 27/02/2016
   602                              <1> 	; 26/02/2016
   603                              <1> 	; 22/02/2016 (TRDOS 386 =  TRDOS v2.0)
   604                              <1> 	; 11/08/2011  
   605                              <1> 	; 09/02/2005
   606                              <1> 	; INPUT ->
   607                              <1> 	;	EAX = Cluster Number
   608                              <1> 	;	ECX = New Cluster Value
   609                              <1> 	;	ESI = Logical Dos Drive Parameters Table
   610                              <1> 	;
   611                              <1> 	;	/// dword [FAT_ClusterCounter] ///
   612                              <1> 	;
   613                              <1> 	; OUTPUT ->
   614                              <1> 	;	cf = 0 -> No Error, EAX is valid
   615                              <1> 	;	cf = 1 & EAX = 0 -> End Of Cluster Chain
   616                              <1> 	; 	cf = 1 & EAX > 0 -> Error
   617                              <1> 	;		(ECX -> any value)
   618                              <1> 	; 	EAX = Next Cluster
   619                              <1> 	;	ECX = New Cluster Value
   620                              <1> 	;
   621                              <1> 	;	/// [FAT_ClusterCounter] is updated,
   622                              <1> 	;	/// decreased when a free cluster is assigned,
   623                              <1> 	;	/// increased if an assigned cluster is freed.	
   624                              <1> 	;		
   625                              <1> 	;
   626                              <1> 	; (Modified registers: EAX, EBX, -ECX-, EDX)
   627                              <1> 	
   628 00007A0E A3[C1B00000]        <1> 	mov	[FAT_CurrentCluster], eax
   629 00007A13 890D[64B30000]      <1> 	mov	[ClusterValue], ecx
   630                              <1> 
   631                              <1> loc_update_cluster_check_fat_buffer:
   632 00007A19 8A1E                <1> 	mov	bl, [esi+LD_Name]
   633 00007A1B 381D[C6B00000]      <1> 	cmp	[FAT_BuffDrvName], bl
   634 00007A21 741A                <1> 	je	short loc_update_cluster_check_fat_type
   635 00007A23 803D[C5B00000]02    <1> 	cmp	byte [FAT_BuffValidData], 2
   636 00007A2A 0F84C2000000        <1>         je      loc_uc_save_fat_buffer
   637                              <1> 
   638                              <1> loc_uc_reset_fat_buffer_validation:
   639 00007A30 C605[C5B00000]00    <1> 	mov	byte [FAT_BuffValidData], 0
   640                              <1> 
   641                              <1> loc_uc_check_fat_type_reset_drvname:
   642 00007A37 881D[C6B00000]      <1> 	mov	[FAT_BuffDrvName], bl
   643                              <1> 
   644                              <1> loc_update_cluster_check_fat_type:
   645 00007A3D 29D2                <1> 	sub	edx, edx ; 26/02/2016
   646 00007A3F 8A5E03              <1> 	mov	bl, [esi+LD_FATType]
   647 00007A42 83F802              <1> 	cmp	eax, 2
   648 00007A45 0F82BE000000        <1>         jb      update_cluster_inv_data
   649 00007A4B 80FB02              <1> 	cmp	bl, 2 
   650 00007A4E 0F877A010000        <1>         ja      update_fat32_cluster
   651                              <1> 	;or	bl, bl
   652                              <1> 	;jz	short update_cluster_inv_data
   653 00007A54 8B4E78              <1> 	mov	ecx, [esi+LD_Clusters]
   654 00007A57 41                  <1> 	inc	ecx  
   655 00007A58 890D[D1B00000]      <1> 	mov	[LastCluster], ecx
   656 00007A5E 39C8                <1> 	cmp	eax, ecx ; dword [LastCluster]
   657 00007A60 0F87A6000000        <1>         ja      return_uc_fat_stc
   658                              <1> 	; TRDOS v1 has a FATal bug here ! 
   659                              <1> 		; or bl, bl ; cmp bl, 0
   660                              <1> 		; jz short update_fat12_cluster
   661                              <1> 	; !! It would destroy FAT12 floppy disk fs here !!
   662                              <1> 	; ('A:' disks of TRDOS v1 operating system project
   663                              <1> 	; had 'singlix fs', so, I could not differ this mistake
   664                              <1> 	; on a drive 'A:')
   665 00007A66 80FB01              <1> 	cmp	bl, 1 ; correct comparison is this !
   666 00007A69 0F86A2000000        <1>         jna     update_fat12_cluster 
   667                              <1> 
   668                              <1> update_fat16_cluster:
   669                              <1> pass_uc_fat16_errc:
   670                              <1> 	;sub	edx, edx
   671 00007A6F BB00030000          <1> 	mov	ebx, 300h ;768
   672 00007A74 F7F3                <1> 	div	ebx
   673                              <1> 	; EAX = Count of 3 FAT sectors
   674                              <1> 	; DX = Cluster offset in FAT buffer
   675 00007A76 6689D3              <1> 	mov	bx, dx  
   676 00007A79 66D1E3              <1> 	shl	bx, 1 ; Multiply by 2
   677 00007A7C 66BA0300            <1> 	mov	dx, 3
   678 00007A80 F7E2                <1> 	mul	edx  
   679                              <1> 	; EAX = FAT Sector
   680                              <1> 	; EDX = 0
   681                              <1> 	; EBX = Byte offset in FAT buffer
   682 00007A82 8A0D[C5B00000]      <1> 	mov	cl, [FAT_BuffValidData]
   683 00007A88 80F902              <1> 	cmp	cl, 2
   684 00007A8B 750A                <1> 	jne	short loc_uc_check_fat16_buff_sector_load
   685                              <1> 
   686                              <1> loc_uc_check_fat16_buff_sector_save:
   687 00007A8D 3B05[C9B00000]      <1> 	cmp	eax, [FAT_BuffSector]
   688 00007A93 755D                <1> 	jne	short loc_uc_save_fat_buffer
   689 00007A95 EB15                <1> 	jmp	short loc_update_fat16_cell
   690                              <1> 
   691                              <1> loc_uc_check_fat16_buff_sector_load:
   692 00007A97 80F901              <1> 	cmp	cl, 1 ; byte [FAT_BuffValidData]
   693 00007A9A 0F85F7010000        <1>         jne     loc_uc_load_fat_sectors
   694 00007AA0 3B05[C9B00000]      <1> 	cmp	eax, [FAT_BuffSector]
   695 00007AA6 0F85EB010000        <1>         jne     loc_uc_load_fat_sectors
   696                              <1> 
   697                              <1> loc_update_fat16_cell:
   698                              <1> loc_update_fat16_buffer:
   699 00007AAC 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   700                              <1> 	;movzx	eax, word [ebx]
   701 00007AB2 668B03              <1> 	mov	ax, [ebx]
   702                              <1> 	; 01/03/2016
   703 00007AB5 89C2                <1> 	mov	edx, eax ; old value of the cluster
   704 00007AB7 A3[C1B00000]        <1> 	mov	[FAT_CurrentCluster], eax
   705 00007ABC 8B0D[64B30000]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   706 00007AC2 66890B              <1> 	mov	[ebx], cx ; 16 bits !
   707                              <1> 
   708 00007AC5 C605[C5B00000]02    <1> 	mov	byte [FAT_BuffValidData], 2
   709                              <1> 	
   710 00007ACC 6683F802            <1> 	cmp	ax, 2
   711 00007AD0 723A                <1> 	jb	short return_uc_fat_stc
   712 00007AD2 3B05[D1B00000]      <1> 	cmp	eax, [LastCluster]
   713 00007AD8 7732                <1> 	ja	short return_uc_fat_stc
   714                              <1> 
   715                              <1> loc_fat_buffer_updated:
   716                              <1> 	; 01/03/2016
   717 00007ADA F8                  <1> 	clc
   718                              <1> loc_fat_buffer_stc_1:
   719 00007ADB 9C                  <1> 	pushf
   720 00007ADC 21C9                <1> 	and	ecx, ecx
   721 00007ADE 7506                <1> 	jnz	short loc_fat_buffer_updated_1
   722                              <1> 
   723                              <1> 	; 01/03/2016 
   724                              <1> 	; new value of the cluster = 0 (free)
   725                              <1> 	; increase free(d) cluster count
   726 00007AE0 FF05[CDB00000]      <1> 	inc	dword [FAT_ClusterCounter]
   727                              <1> 
   728                              <1> loc_fat_buffer_updated_1: ; new value of the cluster > 0
   729 00007AE6 09D2                <1> 	or	edx, edx ; 02/03/2016
   730 00007AE8 7506                <1> 	jnz	short loc_fat_buffer_updated_2
   731                              <1> 	; old value of the cluster = 0 (it was free cluster)
   732                              <1> 	; decrease free(d) cluster count
   733 00007AEA FF0D[CDB00000]      <1> 	dec	dword [FAT_ClusterCounter] ; it may be negative number
   734                              <1> 
   735                              <1> loc_fat_buffer_updated_2:
   736 00007AF0 9D                  <1> 	popf
   737 00007AF1 C3                  <1> 	retn
   738                              <1> 
   739                              <1> loc_uc_save_fat_buffer:
   740                              <1> 	; byte [FAT_BuffValidData] = 2 
   741 00007AF2 E8D0010000          <1> 	call	save_fat_buffer
   742 00007AF7 0F8293010000        <1>         jc      loc_fat_sectors_rw_error2
   743                              <1> 	;mov	byte [FAT_BuffValidData], 1
   744 00007AFD A1[C1B00000]        <1> 	mov	eax, [FAT_CurrentCluster]
   745                              <1> 	;mov	ecx, [ClusterValue]
   746                              <1> 	;jmp	short loc_update_cluster_check_fat_buffer
   747 00007B02 8A1E                <1> 	mov	bl, [esi+LD_Name] ; 01/03/2016
   748 00007B04 E927FFFFFF          <1>         jmp     loc_uc_reset_fat_buffer_validation
   749                              <1> 
   750                              <1> update_cluster_inv_data:
   751                              <1> 	;mov	eax, 0Dh
   752 00007B09 B00D                <1> 	mov	al, 0Dh  ; Invalid Data
   753 00007B0B C3                  <1> 	retn 
   754                              <1> 
   755                              <1> return_uc_fat_stc:
   756                              <1> 	; 01/03/2016
   757 00007B0C 31C0                <1> 	xor	eax, eax
   758 00007B0E F9                  <1> 	stc
   759 00007B0F EBCA                <1> 	jmp	short loc_fat_buffer_stc_1
   760                              <1> 
   761                              <1> update_fat12_cluster:
   762                              <1> pass_uc_fat12_errc:
   763                              <1> 	;sub	edx, edx
   764 00007B11 BB00040000          <1> 	mov	ebx, 400h ;1024
   765 00007B16 F7F3                <1> 	div	ebx
   766                              <1> 	; EAX = Count of 3 FAT sectors
   767                              <1> 	; DX = Cluster offset in FAT buffer
   768 00007B18 66B90300            <1> 	mov	cx, 3
   769 00007B1C 6689C3              <1> 	mov	bx, ax
   770 00007B1F 6689C8              <1> 	mov	ax, cx ; 3
   771 00007B22 66F7E2              <1> 	mul	dx     ; Multiply by 3
   772 00007B25 66D1E8              <1> 	shr	ax, 1  ; Divide by 2
   773 00007B28 6693                <1> 	xchg	bx, ax
   774                              <1> 	; EAX = Count of 3 FAT sectors
   775                              <1> 	; EBX = Byte Offset in FAT buffer   
   776 00007B2A 66F7E1              <1> 	mul	cx  ; 3 * AX
   777                              <1> 	; EAX = FAT Beginning Sector
   778                              <1> 	; EDX = 0
   779 00007B2D 8A0D[C5B00000]      <1> 	mov	cl, [FAT_BuffValidData]
   780                              <1> 	; TRDOS v1 has a FATal bug here ! 
   781                              <1> 	; (it does not have 'cmp cl, 2' instruction here !
   782                              <1> 	;  while 'jne' is existing !)
   783 00007B33 80F902              <1> 	cmp	cl, 2 ; 2 = dirty buffer (must be written to disk)
   784 00007B36 750A                <1> 	jne	short loc_uc_check_fat12_buff_sector_load
   785                              <1> 
   786                              <1> loc_uc_check_fat12_buff_sector_save:
   787 00007B38 3B05[C9B00000]      <1> 	cmp	eax, [FAT_BuffSector]
   788 00007B3E 75B2                <1>         jne     short loc_uc_save_fat_buffer
   789 00007B40 EB15                <1> 	jmp	short loc_update_fat12_cell
   790                              <1> 
   791                              <1> loc_uc_check_fat12_buff_sector_load:
   792 00007B42 80F901              <1> 	cmp	cl, 1 ; byte ptr [FAT_BuffValidData]
   793 00007B45 0F854C010000        <1>         jne     loc_uc_load_fat_sectors
   794 00007B4B 3B05[C9B00000]      <1> 	cmp	eax, [FAT_BuffSector]
   795 00007B51 0F8540010000        <1>         jne     loc_uc_load_fat_sectors
   796                              <1> 
   797                              <1> loc_update_fat12_cell:
   798 00007B57 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   799 00007B5D 668B0D[C1B00000]    <1> 	mov	cx, [FAT_CurrentCluster]
   800 00007B64 66D1E9              <1> 	shr	cx, 1
   801 00007B67 668B03              <1> 	mov	ax, [ebx]
   802 00007B6A 6689C2              <1> 	mov	dx, ax
   803 00007B6D 7344                <1> 	jnc	short uc_fat12_nc_even
   804                              <1> 
   805 00007B6F 6683E00F            <1> 	and	ax, 0Fh
   806 00007B73 8B0D[64B30000]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   807 00007B79 66C1E104            <1> 	shl	cx, 4
   808 00007B7D 6609C1              <1> 	or	cx, ax
   809 00007B80 6689D0              <1> 	mov	ax, dx
   810 00007B83 66890B              <1> 	mov	[ebx], cx  ; 16 bits !
   811 00007B86 66C1E804            <1> 	shr	ax, 4 ; al(bit4..7)+ah(bit0..7)
   812                              <1> 
   813                              <1> update_fat12_buffer:
   814 00007B8A A3[C1B00000]        <1> 	mov	[FAT_CurrentCluster], eax
   815 00007B8F 89C2                <1> 	mov	edx, eax ; 01/03/2016
   816 00007B91 C605[C5B00000]02    <1> 	mov	byte [FAT_BuffValidData], 2
   817 00007B98 6683F802            <1> 	cmp	ax, 2
   818 00007B9C 0F826AFFFFFF        <1>         jb      return_uc_fat_stc
   819 00007BA2 3B05[D1B00000]      <1> 	cmp	eax, [LastCluster]
   820 00007BA8 0F875EFFFFFF        <1>         ja      return_uc_fat_stc
   821 00007BAE E927FFFFFF          <1>         jmp     loc_fat_buffer_updated
   822                              <1> 
   823                              <1> uc_fat12_nc_even:
   824 00007BB3 662500F0            <1> 	and	ax, 0F000h
   825 00007BB7 8B0D[64B30000]      <1> 	mov	ecx, [ClusterValue] ; 32 bits
   826 00007BBD 80E50F              <1> 	and	ch, 0Fh
   827 00007BC0 6609C1              <1> 	or	cx, ax
   828 00007BC3 6689D0              <1> 	mov	ax, dx
   829 00007BC6 66890B              <1> 	mov	[ebx], cx ; 16 bits !
   830 00007BC9 80E40F              <1> 	and	ah, 0Fh ; al(bit0..7)+ah(bit0..3)
   831 00007BCC EBBC                <1> 	jmp	short update_fat12_buffer
   832                              <1> 
   833                              <1> update_fat32_cluster:
   834 00007BCE 8B4E78              <1> 	mov	ecx, [esi+LD_Clusters]
   835 00007BD1 41                  <1> 	inc	ecx
   836 00007BD2 890D[D1B00000]      <1> 	mov	[LastCluster], ecx
   837                              <1> 
   838 00007BD8 39C8                <1> 	cmp	eax, ecx
   839 00007BDA 0F872CFFFFFF        <1>         ja      return_uc_fat_stc
   840                              <1> 
   841                              <1> pass_uc_fat32_errc:
   842                              <1> 	;sub	edx, edx
   843 00007BE0 BB80010000          <1> 	mov	ebx, 180h ;384
   844 00007BE5 F7F3                <1> 	div	ebx
   845                              <1> 	; EAX = Count of 3 FAT sectors
   846                              <1> 	; DX = Cluster offset in FAT buffer
   847 00007BE7 89D3                <1> 	mov	ebx, edx
   848 00007BE9 C1E302              <1> 	shl	ebx, 2 ; Multiply by 4
   849 00007BEC BA03000000          <1> 	mov	edx, 3	
   850 00007BF1 F7E2                <1> 	mul	edx
   851                              <1> 	; EBX = Cluster Offset in FAT buffer
   852                              <1> 	; EAX = FAT Sector
   853                              <1> 	; EDX = 0
   854 00007BF3 8A0D[C5B00000]      <1> 	mov	cl, [FAT_BuffValidData]
   855 00007BF9 80F902              <1> 	cmp	cl, 2
   856 00007BFC 750E                <1> 	jne	short loc_uc_check_fat32_buff_sector_load
   857                              <1> 
   858                              <1> loc_uc_check_fat32_buff_sector_save:
   859 00007BFE 3B05[C9B00000]      <1> 	cmp	eax, [FAT_BuffSector]
   860 00007C04 0F85E8FEFFFF        <1>         jne     loc_uc_save_fat_buffer
   861 00007C0A EB11                <1> 	jmp	short loc_update_fat32_cell
   862                              <1> 
   863                              <1> loc_uc_check_fat32_buff_sector_load:
   864 00007C0C 80F901              <1> 	cmp	cl, 1 ; byte [FAT_BuffValidData]
   865 00007C0F 0F8582000000        <1>         jne     loc_uc_load_fat_sectors
   866 00007C15 3B05[C9B00000]      <1> 	cmp	eax, [FAT_BuffSector]
   867 00007C1B 757A                <1>         jne     loc_uc_load_fat_sectors
   868                              <1> 
   869                              <1> loc_update_fat32_cell:
   870                              <1> loc_update_fat32_buffer:
   871 00007C1D 81C3001C0900        <1> 	add	ebx, FAT_Buffer ; 26/02/2016
   872 00007C23 8B03                <1> 	mov	eax, [ebx]
   873 00007C25 25FFFFFF0F          <1> 	and	eax, 0FFFFFFFh ; 28 bit cluster value
   874                              <1> 	
   875 00007C2A 8B15[C1B00000]      <1> 	mov	edx, [FAT_CurrentCluster] ; 01/03/2016
   876                              <1> 
   877 00007C30 A3[C1B00000]        <1> 	mov 	[FAT_CurrentCluster], eax
   878 00007C35 8B0D[64B30000]      <1> 	mov	ecx, [ClusterValue]
   879 00007C3B 890B                <1> 	mov	[ebx], ecx ; 29/02/2016 
   880                              <1> 
   881 00007C3D C605[C5B00000]02    <1> 	mov	byte [FAT_BuffValidData], 2
   882                              <1> 
   883                              <1> 	; 01/03/2016
   884 00007C44 21C0                <1> 	and	eax, eax ; was it free cluster ?
   885 00007C46 7514                <1> 	jnz	short loc_upd_fat32_c0
   886                              <1> 
   887                              <1> 	;or	ecx, ecx ; it will be left free ?!
   888                              <1> 	;jz	short loc_upd_fat32_c3
   889                              <1> 
   890 00007C48 3B563E              <1> 	cmp	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free cluster
   891 00007C4B 7520                <1> 	jne	short loc_upd_fat32_c3
   892                              <1> 
   893 00007C4D 3B15[D1B00000]      <1> 	cmp	edx, [LastCluster]
   894 00007C53 7207                <1> 	jb	short loc_upd_fat32_c0
   895                              <1> 
   896 00007C55 BA02000000          <1> 	mov	edx, 2 ; rewind !
   897 00007C5A EB0E                <1> 	jmp	short loc_upd_fat32_c2
   898                              <1> 
   899                              <1> loc_upd_fat32_c0:
   900 00007C5C FF463E              <1> 	inc	dword [esi+LD_BPB+BPB_Reserved+4] ; set it to next cluster		
   901 00007C5F EB0C                <1> 	jmp	short loc_upd_fat32_c3
   902                              <1> 
   903                              <1> loc_upd_fat32_c1:
   904 00007C61 09C9                <1> 	or	ecx, ecx ; will it be free cluster ?
   905 00007C63 7508                <1> 	jnz	short loc_upd_fat32_c3
   906                              <1> 
   907 00007C65 3B563E              <1> 	cmp	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free cluster
   908 00007C68 7303                <1> 	jnb	short loc_upd_fat32_c3
   909                              <1> 
   910                              <1> loc_upd_fat32_c2:	
   911 00007C6A 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx			
   912                              <1> 
   913                              <1> loc_upd_fat32_c3:
   914 00007C6D 89C2                <1> 	mov	edx, eax
   915                              <1> 
   916                              <1> loc_upd_fat32_c4:
   917 00007C6F 83F802              <1> 	cmp	eax, 2
   918 00007C72 0F8294FEFFFF        <1>         jb      return_uc_fat_stc
   919                              <1> 
   920                              <1> pass_uc_fat32_c_zero_check_2:
   921 00007C78 3B05[D1B00000]      <1> 	cmp	eax, [LastCluster]
   922 00007C7E 0F8788FEFFFF        <1>         ja      return_uc_fat_stc
   923                              <1> 	
   924 00007C84 E951FEFFFF          <1> 	jmp     loc_fat_buffer_updated
   925                              <1> 
   926                              <1> loc_fat_sectors_rw_error1:
   927 00007C89 C605[C5B00000]00    <1> 	mov	byte [FAT_BuffValidData], 0
   928                              <1> 
   929                              <1> loc_fat_sectors_rw_error2:
   930                              <1> 	;mov	eax, error code
   931                              <1> 	;mov	edx, 0
   932 00007C90 8B0D[64B30000]      <1> 	mov	ecx, [ClusterValue]
   933 00007C96 C3                  <1> 	retn
   934                              <1> 
   935                              <1> loc_uc_load_fat_sectors:
   936 00007C97 A3[C9B00000]        <1> 	mov	[FAT_BuffSector], eax
   937                              <1> 
   938                              <1> load_uc_fat_sectors_zero:
   939 00007C9C 034660              <1> 	add	eax, [esi+LD_FATBegin]
   940 00007C9F BB001C0900          <1> 	mov	ebx, FAT_Buffer
   941 00007CA4 B903000000          <1> 	mov	ecx, 3
   942 00007CA9 E895190000          <1> 	call	disk_read
   943 00007CAE 72D9                <1> 	jc	short loc_fat_sectors_rw_error1
   944                              <1> 
   945 00007CB0 C605[C5B00000]01    <1>         mov     byte [FAT_BuffValidData], 1
   946 00007CB7 A1[C1B00000]        <1> 	mov 	eax, [FAT_CurrentCluster]
   947 00007CBC 8B0D[64B30000]      <1> 	mov	ecx, [ClusterValue]
   948 00007CC2 E976FDFFFF          <1>         jmp     loc_update_cluster_check_fat_type
   949                              <1> 
   950                              <1> save_fat_buffer:
   951                              <1> 	; 01/03/2016
   952                              <1> 	; 22/02/2016 (TRDOS 386 =  TRDOS v2.0)
   953                              <1> 	; 11/08/2011
   954                              <1> 	; 09/02/2005 
   955                              <1> 	; INPUT ->
   956                              <1> 	;	None
   957                              <1> 	; OUTPUT ->
   958                              <1> 	;	cf = 0 -> OK.
   959                              <1> 	;	cf = 1 -> error code in AL (EAX)
   960                              <1> 	;
   961                              <1> 	; (EAX, EDX, ECX will be modified)
   962                              <1> 	; EBX = FAT_Buffer address
   963                              <1> 
   964                              <1> 	;cmp	byte [FAT_BuffValidData], 2 
   965                              <1> 	;je	short loc_save_fat_buff
   966                              <1> 
   967                              <1> ;loc_save_fat_buffer_retn:
   968                              <1> ;	xor	eax, eax
   969                              <1> ;	retn
   970                              <1> 
   971                              <1> loc_save_fat_buff:
   972 00007CC7 31D2                <1> 	xor	edx, edx
   973 00007CC9 8A35[C6B00000]      <1> 	mov	dh, [FAT_BuffDrvName]
   974 00007CCF 80FE41              <1> 	cmp	dh, 'A'
   975 00007CD2 722E                <1> 	jb	short loc_save_fat_buffer_inv_data_retn
   976 00007CD4 80EE41              <1> 	sub	dh, 'A'
   977 00007CD7 56                  <1> 	push	esi ; *
   978 00007CD8 BE00010900          <1>         mov     esi, Logical_DOSDisks
   979 00007CDD 01D6                <1> 	add	esi, edx
   980                              <1> 	
   981 00007CDF 8A5603              <1> 	mov	dl, [esi+LD_FATType]
   982 00007CE2 20D2                <1> 	and	dl, dl
   983 00007CE4 741B                <1> 	jz	short loc_save_fat_buffer_inv_data_pop_retn 
   984                              <1> 
   985 00007CE6 A1[C9B00000]        <1> 	mov	eax, [FAT_BuffSector]
   986 00007CEB 80FA02              <1> 	cmp	dl, 2
   987 00007CEE 770A                <1> 	ja	short loc_save_fat32_buff
   988                              <1> 
   989                              <1> loc_save_fat_12_16_buff:
   990                              <1> 	; 01/03/2016
   991                              <1> 	; TRDOS v1 has a FATal bug here!
   992                              <1> 	; Correct code: mov dx, word ptr [FAT_BuffSector]+2
   993                              <1> 	; (DX:AX in TRDOS v1 -> EAX in TRDOS v2)
   994                              <1> 	;
   995 00007CF0 0FB74E1C            <1> 	movzx	ecx, word [esi+LD_BPB+FATSecs] 
   996 00007CF4 29C1                <1> 	sub	ecx, eax
   997                              <1> 	; TRDOS v1 has a bug here... ('pop esi' was forgotten!)
   998                              <1> 	;jna	short loc_save_fat_buffer_inv_data_retn ; wrong addr!
   999 00007CF6 7609                <1> 	jna	short loc_save_fat_buffer_inv_data_pop_retn ; correct addr.
  1000 00007CF8 EB15                <1> 	jmp	short loc_save_fat_buffer_check_rs3
  1001                              <1> 
  1002                              <1> loc_save_fat32_buff:
  1003 00007CFA 8B4E2A              <1> 	mov	ecx, [esi+LD_BPB+FAT32_FAT_Size]
  1004 00007CFD 29C1                <1> 	sub	ecx, eax
  1005 00007CFF 770E                <1> 	ja	short loc_save_fat_buffer_check_rs3
  1006                              <1> 
  1007                              <1> loc_save_fat_buffer_inv_data_pop_retn:
  1008 00007D01 5E                  <1> 	pop	esi ; *
  1009                              <1> loc_save_fat_buffer_inv_data_retn:
  1010 00007D02 B80D000000          <1> 	mov	eax, 0Dh ; Invalid DATA
  1011 00007D07 C3                  <1> 	retn
  1012                              <1> 
  1013                              <1> loc_save_fat_buff_remain_sectors_3:
  1014 00007D08 B903000000          <1> 	mov	ecx, 3
  1015 00007D0D EB05                <1> 	jmp	short loc_save_fat_buff_continue
  1016                              <1> 
  1017                              <1> loc_save_fat_buffer_check_rs3:
  1018 00007D0F 83F903              <1> 	cmp	ecx, 3
  1019 00007D12 77F4                <1> 	ja	short loc_save_fat_buff_remain_sectors_3
  1020                              <1> 
  1021                              <1> loc_save_fat_buff_continue:
  1022 00007D14 BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1023 00007D19 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1024 00007D1C 51                  <1> 	push	ecx
  1025 00007D1D E812190000          <1> 	call	disk_write
  1026 00007D22 59                  <1> 	pop	ecx
  1027 00007D23 722B                <1> 	jc	short loc_save_FAT_buff_write_err
  1028                              <1> 	
  1029 00007D25 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1030 00007D29 7605                <1> 	jna	short loc_calc_2nd_fat12_16_addr
  1031                              <1> 
  1032                              <1> loc_calc_2nd_fat32_addr:
  1033 00007D2B 8B462A              <1> 	mov	eax, [esi+LD_BPB+FAT32_FAT_Size]
  1034 00007D2E EB04                <1> 	jmp	short loc_calc_2nd_fat_addr
  1035                              <1> 
  1036                              <1> loc_calc_2nd_fat12_16_addr:
  1037 00007D30 0FB7461C            <1> 	movzx	eax, word [esi+LD_BPB+FATSecs]
  1038                              <1> 
  1039                              <1> loc_calc_2nd_fat_addr:
  1040 00007D34 034660              <1> 	add	eax, [esi+LD_FATBegin]
  1041 00007D37 0305[C9B00000]      <1> 	add	eax, [FAT_BuffSector]
  1042 00007D3D BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1043                              <1> 	; ecx = 1 to 3
  1044 00007D42 E8ED180000          <1> 	call	disk_write
  1045 00007D47 7207                <1> 	jc	short loc_save_FAT_buff_write_err
  1046                              <1>  	; Valid  buffer (1 = valid but do not save)
  1047 00007D49 C605[C5B00000]01    <1> 	mov	byte [FAT_BuffValidData], 1
  1048                              <1> 
  1049                              <1> loc_save_FAT_buff_write_err:
  1050 00007D50 5E                  <1> 	pop	esi ; *
  1051 00007D51 BB001C0900          <1> 	mov	ebx, FAT_Buffer
  1052 00007D56 C3                  <1> 	retn
  1053                              <1> 
  1054                              <1> calculate_fat_freespace:
  1055                              <1> 	; 02/03/2016
  1056                              <1> 	; 01/03/2016
  1057                              <1> 	; 29/02/2016
  1058                              <1> 	; 22/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1059                              <1> 	; 30/04/2011
  1060                              <1> 	; 03/04/2010
  1061                              <1> 	; 2005
  1062                              <1> 	; INPUT ->
  1063                              <1> 	;	EAX = Cluster count to be added or subtracted
  1064                              <1> 	; 	If BH = FFh, ESI = TR-DOS Logical Drive Description Table
  1065                              <1> 	; 	If BH < FFh, BH = TR-DOS Logical Drive Number
  1066                              <1> 	; 	BL: 
  1067                              <1> 	;	0 = Calculate, 1 = Add, 2 = Subtract, 3 = Get (Not Set/Calc)
  1068                              <1> 	; OUTPUT ->
  1069                              <1> 	;	EAX = Free Space in sectors
  1070                              <1> 	;	ESI = Logical Dos Drive Description Table address
  1071                              <1> 	;	BH = Logical Dos Drive Number (same with input value of BH)
  1072                              <1> 	;	BL = Type of operation (same with input value of BL)
  1073                              <1> 	;	ECX = 0 -> valid
  1074                              <1> 	;	ECX > 0 -> error or invalid
  1075                              <1> 	;	If EAX = FFFFFFFFh, it is 're-calculation needed'
  1076                              <1> 	;			          sign due to r/w error   
  1077                              <1> 
  1078 00007D57 66891D[6AB30000]    <1> 	mov	[CFS_OPType], bx
  1079 00007D5E A3[6CB30000]        <1> 	mov	[CFS_CC], eax
  1080                              <1> 	
  1081 00007D63 80FFFF              <1> 	cmp	bh, 0FFh
  1082 00007D66 740B                <1> 	je	short pass_calculate_freespace_get_drive_dt_offset
  1083                              <1> 
  1084                              <1> loc_calculate_freespace_get_drive_dt_offset:     
  1085 00007D68 31C0                <1> 	xor	eax, eax
  1086 00007D6A 88FC                <1>         mov     ah, bh
  1087 00007D6C BE00010900          <1> 	mov	esi, Logical_DOSDisks
  1088 00007D71 01C6                <1>         add     esi, eax
  1089                              <1> 
  1090                              <1> pass_calculate_freespace_get_drive_dt_offset:
  1091 00007D73 08DB                <1> 	or	bl, bl
  1092 00007D75 742D                <1> 	jz	short loc_reset_fcc
  1093                              <1> 	
  1094                              <1> loc_get_free_sectors:
  1095 00007D77 8B4674              <1> 	mov	eax, [esi+LD_FreeSectors]
  1096 00007D7A 31C9                <1> 	xor	ecx, ecx
  1097 00007D7C 49                  <1> 	dec	ecx ; 0FFFFFFFFh
  1098 00007D7D 39C8                <1> 	cmp	eax, ecx ; 29/02/2016
  1099 00007D7F 7406                <1> 	je	short loc_get_free_sectors_retn ; recalculation is needed!
  1100                              <1> 
  1101                              <1> loc_get_free_sectors_check_optype:
  1102 00007D81 80FB03              <1> 	cmp	bl, 3
  1103 00007D84 7202                <1> 	jb	short loc_set_fcc
  1104 00007D86 41                  <1> 	inc	ecx ; 0
  1105                              <1> loc_get_free_sectors_retn:
  1106 00007D87 C3                  <1> 	retn	
  1107                              <1> 
  1108                              <1> loc_set_fcc:
  1109 00007D88 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1110 00007D8C 0F87DF000000        <1>         ja      loc_update_FAT32_fs_info_fcc
  1111                              <1> 
  1112                              <1> 	;mov	eax, [esi+LD_FreeSectors]
  1113 00007D92 0FB64E13            <1> 	movzx	ecx, byte [esi+LD_BPB+SecPerClust]
  1114 00007D96 29D2                <1> 	sub	edx, edx
  1115 00007D98 F7F1                <1> 	div	ecx
  1116                              <1> 	;or	dx, dx 
  1117                              <1> 	;	; DX -> Remain sectors < SecPerClust
  1118                              <1> 	;	; DX > 0 -> invalid free sector count
  1119                              <1> 	;jnz	short loc_reset_fcc 
  1120                              <1> 
  1121                              <1> ;pass_set_fcc_div32:
  1122 00007D9A A3[E3B00000]        <1> 	mov	[FreeClusterCount], eax
  1123 00007D9F E988000000          <1>         jmp     loc_set_free_sectors_FAT12_FAT16
  1124                              <1> 
  1125                              <1> loc_reset_fcc:
  1126 00007DA4 31C0                <1> 	xor	eax, eax
  1127 00007DA6 A3[E3B00000]        <1> 	mov	[FreeClusterCount], eax ; 0
  1128 00007DAB 8B5678              <1> 	mov	edx, [esi+LD_Clusters]
  1129 00007DAE 42                  <1> 	inc	edx
  1130 00007DAF 8915[D1B00000]      <1> 	mov	[LastCluster], edx
  1131                              <1> 
  1132 00007DB5 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1133 00007DB9 7647                <1> 	jna	short loc_count_free_fat_clusters_0  
  1134                              <1> 
  1135 00007DBB 48                  <1> 	dec	eax ; FFFFFFFFh
  1136 00007DBC A3[74B30000]        <1> 	mov	[CFS_FAT32FC], eax
  1137                              <1> 
  1138                              <1> 	; 29/02/2016
  1139 00007DC1 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; reset
  1140 00007DC4 89463E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], eax ; reset
  1141                              <1> 	
  1142 00007DC7 B802000000          <1> 	mov 	eax, 2
  1143                              <1> 
  1144                              <1> loc_count_fc_next_cluster_0:
  1145 00007DCC 50                  <1> 	push	eax
  1146 00007DCD E820F9FFFF          <1> 	call	get_next_cluster
  1147 00007DD2 7310                <1> 	jnc	short loc_check_fat32_ff_cluster
  1148 00007DD4 09C0                <1> 	or	eax, eax
  1149 00007DD6 741E                <1> 	jz	short pass_inc_cfs_fcc_0
  1150                              <1> 
  1151                              <1> loc_put_fcc_unknown_sign:
  1152 00007DD8 58                  <1> 	pop	eax
  1153                              <1> 	; "Free count is Unknown" sign
  1154                              <1> 	;mov	dword [FreeClusterCount], 0FFFFFFFFh
  1155                              <1> 
  1156                              <1> 	; 29/02/2016
  1157                              <1> 	; Save Free Cluster Count value in FAT32 'BPB_Reserved' area
  1158                              <1> 	;mov	[esi+LD_BPB+BPB_Reserved], 0FFFFFFFFh ; unknown!
  1159 00007DD9 8B15[74B30000]      <1> 	mov	edx, [CFS_FAT32FC] ; First Free Cluster
  1160                              <1> 	; Save First Free Cluster value in FAT32 'BPB_Reserved+4' area
  1161 00007DDF 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx
  1162                              <1> 	
  1163 00007DE2 EB7D                <1>         jmp     loc_put_fcc_invalid_sign
  1164                              <1> 
  1165                              <1> loc_check_fat32_ff_cluster:
  1166 00007DE4 09C0                <1> 	or	eax, eax
  1167 00007DE6 750E                <1> 	jnz	short pass_inc_cfs_fcc_0
  1168 00007DE8 58                  <1> 	pop	eax
  1169 00007DE9 A3[74B30000]        <1> 	mov	[CFS_FAT32FC], eax
  1170                              <1> 	;mov	dword [FreeClusterCount], 1
  1171 00007DEE FF05[E3B00000]      <1> 	inc	dword [FreeClusterCount]
  1172 00007DF4 EB27                <1> 	jmp	short pass_inc_cfs_fcc_1
  1173                              <1> 
  1174                              <1> pass_inc_cfs_fcc_0:
  1175 00007DF6 58                  <1> 	pop	eax
  1176                              <1> 
  1177                              <1> pass_inc_cfs_fcc_0c:
  1178 00007DF7 40                  <1> 	inc	eax ; add eax, 1
  1179 00007DF8 3B05[D1B00000]      <1> 	cmp	eax, [LastCluster]
  1180 00007DFE 76CC                <1> 	jna 	short loc_count_fc_next_cluster_0
  1181 00007E00 EB6F                <1> 	jmp	short loc_update_FAT32_fs_info_fcc
  1182                              <1> 
  1183                              <1> loc_count_free_fat_clusters_0:
  1184                              <1> 	;mov	eax, 2
  1185 00007E02 B002                <1> 	mov	al, 2
  1186                              <1> 
  1187                              <1> loc_count_fc_next_cluster:
  1188 00007E04 50                  <1> 	push	eax
  1189 00007E05 E8E8F8FFFF          <1> 	call	get_next_cluster
  1190 00007E0A 720C                <1> 	jc	short loc_count_fcc_stc
  1191                              <1> 
  1192                              <1> loc_count_free_clusters_1:
  1193 00007E0C 21C0                <1> 	and	eax, eax
  1194 00007E0E 750C                <1> 	jnz	short pass_inc_cfs_fcc
  1195                              <1> 
  1196 00007E10 FF05[E3B00000]      <1> 	inc	dword [FreeClusterCount]
  1197 00007E16 EB04                <1> 	jmp	short pass_inc_cfs_fcc
  1198                              <1> 
  1199                              <1> loc_count_fcc_stc:
  1200 00007E18 09C0                <1> 	or	eax, eax
  1201 00007E1A 75BC                <1> 	jnz	short loc_put_fcc_unknown_sign ; 29/02/2016
  1202                              <1> 
  1203                              <1> pass_inc_cfs_fcc:
  1204 00007E1C 58                  <1> 	pop	eax
  1205                              <1> 
  1206                              <1> pass_inc_cfs_fcc_1:
  1207 00007E1D 40                  <1> 	inc	eax ; add eax, 1
  1208 00007E1E 3B05[D1B00000]      <1> 	cmp	eax, [LastCluster]
  1209 00007E24 76DE                <1> 	jna	short loc_count_fc_next_cluster
  1210                              <1> 
  1211                              <1> loc_set_free_sectors:
  1212 00007E26 807E0302            <1> 	cmp	byte [esi+LD_FATType], 2
  1213 00007E2A 7745                <1> 	ja	short loc_update_FAT32_fs_info_fcc
  1214                              <1> 
  1215                              <1> loc_set_free_sectors_FAT12_FAT16:
  1216 00007E2C 803D[6AB30000]00    <1> 	cmp	byte [CFS_OPType], 0
  1217 00007E33 761C                <1> 	jna	short pass_FAT_add_sub_fcc
  1218 00007E35 A1[6CB30000]        <1> 	mov	eax, [CFS_CC]
  1219 00007E3A 803D[6AB30000]01    <1> 	cmp	byte [CFS_OPType], 1
  1220 00007E41 7708                <1> 	ja	short pass_FAT_add_fcc
  1221 00007E43 0105[E3B00000]      <1> 	add 	[FreeClusterCount], eax
  1222 00007E49 EB06                <1> 	jmp	short pass_FAT_add_sub_fcc
  1223                              <1> 
  1224                              <1> pass_FAT_add_fcc:
  1225 00007E4B 2905[E3B00000]      <1> 	sub	[FreeClusterCount], eax
  1226                              <1> 
  1227                              <1> pass_FAT_add_sub_fcc:
  1228 00007E51 0FB64613            <1> 	movzx	eax, byte [esi+LD_BPB+SecPerClust]
  1229 00007E55 8B15[E3B00000]      <1> 	mov	edx, [FreeClusterCount]
  1230 00007E5B F7E2                <1> 	mul	edx
  1231                              <1> 
  1232 00007E5D 31C9                <1> 	xor	ecx, ecx 
  1233 00007E5F EB05                <1> 	jmp	short loc_cfs_retn_params
  1234                              <1> 
  1235                              <1> loc_put_fcc_invalid_sign:
  1236 00007E61 29C0                <1>        	sub	eax, eax ; 0
  1237 00007E63 48                  <1> 	dec	eax ; FFFFFFFFh
  1238                              <1> loc_fat32_ffc_recalc_needed:
  1239 00007E64 89C1                <1> 	mov	ecx, eax
  1240                              <1> 
  1241                              <1> loc_cfs_retn_params:
  1242 00007E66 894674              <1> 	mov 	[esi+LD_FreeSectors], eax
  1243 00007E69 0FB71D[6AB30000]    <1> 	movzx	ebx, word [CFS_OPType]
  1244 00007E70 C3                  <1> 	retn
  1245                              <1> 
  1246                              <1> loc_update_FAT32_fs_info_fcc:
  1247                              <1> loc_check_fcc_FSINFO_op:
  1248                              <1> 	; 29/02/2016
  1249                              <1> 	; EAX = Free cluster count (before this update) ; value from disk
  1250                              <1> 	; EDX = First Free Cluster (before this update) ; value from disk
  1251 00007E71 803D[6AB30000]01    <1> 	cmp	byte [CFS_OPType], 1
  1252 00007E78 7221                <1> 	jb	short loc_cfs_FAT32_get_rcalc_parms ; 0 = recalculated
  1253 00007E7A 7406                <1> 	je	short loc_check_fcc_FSINFO_op1 ; 1 = add
  1254                              <1> loc_check_fcc_FSINFO_op2: ; subtract
  1255 00007E7C F71D[6CB30000]      <1> 	neg	dword [CFS_CC] ; prepare to subtract ; 2 = sub (add negative)
  1256                              <1> loc_check_fcc_FSINFO_op1:
  1257                              <1> 	; 01/03/2016
  1258 00007E82 31D2                <1> 	xor	edx, edx ; 0
  1259 00007E84 4A                  <1> 	dec	edx ; 0FFFFFFFFh
  1260 00007E85 8B463A              <1> 	mov	eax, [esi+LD_BPB+BPB_Reserved]
  1261 00007E88 39D0                <1> 	cmp	eax, edx
  1262 00007E8A 73D5                <1> 	jnb	short loc_put_fcc_invalid_sign
  1263 00007E8C 0305[6CB30000]      <1>         add     eax, [CFS_CC] ; free cluster count on disk + current count
  1264 00007E92 72CD                <1> 	jc	short loc_put_fcc_invalid_sign
  1265                              <1> 	
  1266 00007E94 A3[E3B00000]        <1> 	mov	[FreeClusterCount], eax
  1267 00007E99 EB0E                <1> 	jmp	short loc_cfs_write_FSINFO_sector
  1268                              <1> 
  1269                              <1> loc_cfs_FAT32_get_rcalc_parms:
  1270 00007E9B 8B15[74B30000]      <1> 	mov	edx, [CFS_FAT32FC]
  1271 00007EA1 A1[E3B00000]        <1> 	mov	eax, [FreeClusterCount]
  1272 00007EA6 89563E              <1> 	mov	[esi+LD_BPB+BPB_Reserved+4], edx ; First Free Cluster
  1273                              <1> loc_cfs_write_FSINFO_sector:
  1274 00007EA9 89463A              <1> 	mov	[esi+LD_BPB+BPB_Reserved], eax ; Free cluster count
  1275                              <1> 	; 01/03/2016
  1276 00007EAC E89A000000          <1> 	call	set_fat32_fsinfo_sector_parms
  1277 00007EB1 72AE                <1>         jc      short loc_put_fcc_invalid_sign
  1278                              <1> 
  1279                              <1> loc_set_FAT32_free_sectors:
  1280                              <1> 	; 29/02/2016
  1281                              <1> 	;mov	eax, [FreeClusterCount]
  1282                              <1> 	;mov	ecx, eax
  1283                              <1> 	;cmp	eax, 0FFFFFFFFh ; Invalid !
  1284                              <1> 	;je	short loc_cfs_retn_params
  1285                              <1> 	;
  1286 00007EB3 8B0D[E3B00000]      <1> 	mov	ecx, [FreeClusterCount]
  1287 00007EB9 0FB64613            <1> 	movzx	eax, byte [esi+LD_BPB+SecPerClust]
  1288 00007EBD F7E1                <1> 	mul	ecx
  1289                              <1> 	; 29/02/2016
  1290 00007EBF 31C9                <1> 	xor	ecx, ecx ; 0
  1291 00007EC1 09D2                <1> 	or	edx, edx ; 0 ?
  1292 00007EC3 759C                <1>         jnz     loc_put_fcc_invalid_sign
  1293 00007EC5 394670              <1> 	cmp	[esi+LD_TotalSectors], eax ; Volume size in sectors
  1294 00007EC8 7697                <1>         jna     short loc_put_fcc_invalid_sign
  1295                              <1> 	;
  1296                              <1> loc_set_FAT32_free_sectors_ok:
  1297 00007ECA 31D2                <1> 	xor	edx, edx ; 0
  1298 00007ECC EB98                <1>         jmp     short loc_cfs_retn_params 
  1299                              <1> 	;
  1300                              <1> 
  1301                              <1> get_last_cluster:
  1302                              <1> 	; 27/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1303                              <1> 	; 12/06/2010 (DRV_FAT.ASM, 'proc_get_last_custer')
  1304                              <1> 	; 06/06/2010
  1305                              <1> 	; INPUT ->
  1306                              <1> 	;	EAX = First Cluster Number
  1307                              <1> 	; 	ESI = Logical Dos Drive Parameters Table
  1308                              <1> 	; OUTPUT ->
  1309                              <1> 	;	cf = 0 -> No Error, EAX is valid
  1310                              <1> 	;	cf = 1 -> EAX > 0 -> Error
  1311                              <1> 	;	EAX = Last Cluster Number
  1312                              <1> 	;       ECX = Previous Cluster -just before the last cluster-
  1313                              <1> 	;
  1314                              <1> 	; (Modified registers: EAX, ECX, EBX, EDX)
  1315                              <1> 
  1316 00007ECE 89C1                <1> 	mov	ecx, eax	
  1317                              <1> 
  1318                              <1> loc_glc_get_next_cluster_1:
  1319 00007ED0 890D[78B30000]      <1> 	mov	[glc_prevcluster], ecx
  1320                              <1> 
  1321                              <1> loc_glc_get_next_cluster_2:
  1322 00007ED6 E817F8FFFF          <1> 	call	get_next_cluster
  1323                              <1> 	; ecx = current/previous cluster 
  1324                              <1> 	; eax = next/last cluster
  1325 00007EDB 73F3                <1> 	jnc	short loc_glc_get_next_cluster_1
  1326                              <1> 
  1327 00007EDD 09C0                <1> 	or	eax, eax
  1328 00007EDF 7509                <1> 	jnz	short loc_glc_stc_retn
  1329                              <1> 
  1330                              <1> 	; ecx = previous cluster
  1331 00007EE1 89C8                <1>         mov	eax, ecx
  1332                              <1> 
  1333                              <1> 	; previous cluster becomes last cluster (ecx -> eax)
  1334                              <1> 	; previous of previous cluster becomes previous cluster (ecx)
  1335                              <1> 
  1336                              <1> loc_glc_prev_cluster_retn:
  1337 00007EE3 8B0D[78B30000]      <1> 	mov	ecx, [glc_prevcluster] 
  1338 00007EE9 C3                  <1> 	retn
  1339                              <1> 
  1340                              <1> loc_glc_stc_retn:
  1341 00007EEA F5                  <1> 	cmc	;stc
  1342 00007EEB EBF6                <1>         jmp	short loc_glc_prev_cluster_retn
  1343                              <1> 
  1344                              <1> truncate_cluster_chain:
  1345                              <1> 	; 01/03/2016
  1346                              <1> 	; 28/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1347                              <1> 	; 22/01/2011 (DRV_FAT.ASM, 'proc_truncate_cluster_chain')
  1348                              <1> 	; 11/09/2010
  1349                              <1> 	; INPUT ->
  1350                              <1> 	;	ESI = Logical dos drive description table address
  1351                              <1> 	;	EAX = First cluster to be truncated/unlinked 
  1352                              <1> 	; OUTPUT ->
  1353                              <1> 	;	ESI = Logical dos drive description table address
  1354                              <1> 	; 	ECX = Count of truncated/removed clusters
  1355                              <1> 	; 	CF = 0 -> EAX = Free sectors
  1356                              <1> 	; 	CF = 1 -> Error code in EAX (AL)
  1357                              <1> 
  1358                              <1> 	; NOTE: This procedure does not update lm date&time ! 
  1359                              <1> 
  1360                              <1> loc_truncate_cc:	
  1361 00007EED 31C9                <1> 	xor	ecx, ecx ; mov ecx, 0
  1362                              <1> 	;mov	byte [FAT_BuffValidData], 0
  1363 00007EEF 890D[CDB00000]      <1> 	mov	[FAT_ClusterCounter], ecx ; 0 ; reset
  1364                              <1> 
  1365                              <1> loc_tcc_unlink_clusters:
  1366 00007EF5 E814FBFFFF          <1> 	call	update_cluster
  1367                              <1> 	; EAX = Next Cluster
  1368                              <1> 	; ECX = Cluster Value
  1369                              <1> 	; Note:
  1370                              <1> 	; Returns count of unlinked clusters in
  1371                              <1> 	; dword ptr FAT_ClusterCounter
  1372 00007EFA 73F9                <1> 	jnc short loc_tcc_unlink_clusters
  1373                              <1> 
  1374                              <1> pass_tcc_unlink_clusters:
  1375 00007EFC A2[7FB30000]        <1> 	mov	byte [TCC_FATErr], al
  1376 00007F01 803D[C5B00000]02    <1> 	cmp	byte [FAT_BuffValidData], 2
  1377 00007F08 750E                <1> 	jne	short loc_tcc_calculate_FAT_freespace
  1378 00007F0A E8B8FDFFFF          <1> 	call	save_fat_buffer
  1379 00007F0F 7307                <1> 	jnc	short loc_tcc_calculate_FAT_freespace
  1380 00007F11 A2[7FB30000]        <1> 	mov	byte [TCC_FATErr], al ; Error
  1381                              <1> 	;mov	byte [FAT_BuffValidData], 0
  1382                              <1> 
  1383                              <1> 	; 01/03/2016
  1384 00007F16 EB12                <1> 	jmp	short loc_tcc_recalculate_FAT_freespace
  1385                              <1> 
  1386                              <1> loc_tcc_calculate_FAT_freespace:
  1387 00007F18 A1[CDB00000]        <1> 	mov	eax, [FAT_ClusterCounter] ; signed (+-) number
  1388 00007F1D 66BB01FF            <1> 	mov	bx, 0FF01h ; BH = FFh -> ESI = Dos drv desc. table
  1389                              <1> 			   ; BL = 1 -> add cluster
  1390 00007F21 E831FEFFFF          <1> 	call	calculate_fat_freespace
  1391 00007F26 21C9                <1> 	and	ecx, ecx ; cx = 0 -> valid free sector count
  1392 00007F28 7409                <1> 	jz	short pass_truncate_cc_recalc_FAT_freespace
  1393                              <1> 
  1394                              <1> loc_tcc_recalculate_FAT_freespace:
  1395 00007F2A 66BB00FF            <1> 	mov	bx, 0FF00h ; recalculate !
  1396 00007F2E E824FEFFFF          <1> 	call	calculate_fat_freespace
  1397                              <1>               
  1398                              <1> loc_tcc_calculate_FAT_freespace_err:
  1399                              <1> pass_truncate_cc_recalc_FAT_freespace:
  1400 00007F33 8B0D[CDB00000]      <1> 	mov	ecx, [FAT_ClusterCounter]
  1401                              <1> 
  1402 00007F39 803D[7FB30000]00    <1> 	cmp	byte [TCC_FATErr], 0
  1403 00007F40 7608                <1> 	jna	short loc_tcc_unlink_clusters_retn
  1404                              <1> 
  1405                              <1> loc_tcc_unlink_clusters_error:
  1406 00007F42 0FB605[7FB30000]    <1> 	movzx	eax, byte [TCC_FATErr]
  1407 00007F49 F9                  <1> 	stc
  1408                              <1> loc_tcc_unlink_clusters_retn:
  1409 00007F4A C3                  <1> 	retn
  1410                              <1> 
  1411                              <1> set_fat32_fsinfo_sector_parms:
  1412                              <1> 	; 29/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1413                              <1> 	; INPUT ->
  1414                              <1> 	;	ESI = Logical dos drive description table address
  1415                              <1> 	;	[esi+LD_BPB+BPB_Reserved] = Free Cluster Count
  1416                              <1> 	;	[esi+LD_BPB+BPB_Reserved+4] = First Free Cluster 
  1417                              <1> 	; OUTPUT ->
  1418                              <1> 	;	ESI = Logical dos drive description table address
  1419                              <1> 	; 	CF = 0 -> OK..
  1420                              <1> 	; 	CF = 1 -> Error code in EAX (AL)
  1421                              <1> 	;
  1422                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX)
  1423                              <1> 
  1424 00007F4B E824000000          <1> 	call	get_fat32_fsinfo_sector_parms
  1425 00007F50 7221                <1> 	jc	short update_fat32_fsinfo_sector_retn
  1426                              <1> 
  1427 00007F52 8B463A              <1> 	mov	eax, [esi+LD_BPB+BPB_Reserved] ; Free Cluster Count
  1428 00007F55 8B563E              <1> 	mov	edx, [esi+LD_BPB+BPB_Reserved+4] ; First free Cluster	
  1429                              <1> 
  1430                              <1>         ;mov	ebx, DOSBootSectorBuff
  1431 00007F58 8983E8010000        <1> 	mov	[ebx+488], eax
  1432 00007F5E 8993EC010000        <1> 	mov	[ebx+492], edx	
  1433                              <1> 
  1434 00007F64 A1[70B30000]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC]
  1435 00007F69 B901000000          <1> 	mov	ecx, 1
  1436 00007F6E E8C1160000          <1> 	call	disk_write
  1437                              <1>        ;jc      short update_fat32_fsinfo_sector_retn
  1438                              <1> 
  1439                              <1> update_fat32_fsinfo_sector_retn:
  1440 00007F73 C3                  <1> 	retn
  1441                              <1> 
  1442                              <1> get_fat32_fsinfo_sector_parms:
  1443                              <1> 	; 01/03/2016
  1444                              <1> 	; 29/02/2016 (TRDOS 386 =  TRDOS v2.0)
  1445                              <1> 	; INPUT ->
  1446                              <1> 	;	ESI = Logical dos drive description table address
  1447                              <1> 	; OUTPUT ->
  1448                              <1> 	;	ESI = Logical dos drive description table address
  1449                              <1> 	;	EBX = FSINFO sector buffer address (DOSBootSectorBuff)	
  1450                              <1> 	;	CF = 0 -> OK..
  1451                              <1> 	;	   EAX = FsInfo sector address
  1452                              <1> 	;	   ECX = Free cluster count
  1453                              <1> 	;	   EDX = First free cluster 	
  1454                              <1> 	;	CF = 1 -> Error code in AL (EAX)
  1455                              <1> 	;	   EBX = 0
  1456                              <1> 	;	
  1457                              <1> 	;	[CFS_FAT32FSINFOSEC] = FAT32 FSINFO sector address
  1458                              <1>         ;
  1459                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX)
  1460                              <1> 
  1461 00007F74 0FB74636            <1> 	movzx	eax, word [esi+LD_BPB+FAT32_FSInfoSec]
  1462 00007F78 03466C              <1> 	add	eax, [esi+LD_StartSector]
  1463 00007F7B A3[70B30000]        <1> 	mov	[CFS_FAT32FSINFOSEC], eax
  1464                              <1> 	
  1465 00007F80 BB[C1AE0000]        <1>         mov     ebx, DOSBootSectorBuff
  1466 00007F85 B901000000          <1> 	mov	ecx, 1
  1467 00007F8A E8B4160000          <1> 	call	disk_read
  1468 00007F8F 7230                <1> 	jc	short loc_read_FAT32_fsinfo_sec_err
  1469                              <1> 
  1470 00007F91 BB[C1AE0000]        <1> 	mov	ebx, DOSBootSectorBuff
  1471                              <1> 
  1472 00007F96 813B52526141        <1> 	cmp	dword [ebx], 41615252h
  1473 00007F9C 751E                <1> 	jne	short loc_read_FAT32_fsinfo_sec_stc
  1474                              <1> 
  1475 00007F9E 81BBE4010000727241- <1> 	cmp	dword [ebx+484], 61417272h
  1475 00007FA7 61                  <1>
  1476 00007FA8 7512                <1> 	jne	short loc_read_FAT32_fsinfo_sec_stc
  1477                              <1> 
  1478 00007FAA A1[70B30000]        <1> 	mov	eax, [CFS_FAT32FSINFOSEC]
  1479 00007FAF 8B8BE8010000        <1> 	mov	ecx, [ebx+488] ; free cluster count
  1480 00007FB5 8B93EC010000        <1> 	mov	edx, [ebx+492] ; first (next) free cluster	
  1481                              <1> 
  1482 00007FBB C3                  <1> 	retn
  1483                              <1> 
  1484                              <1> loc_read_FAT32_fsinfo_sec_stc:
  1485 00007FBC B80B000000          <1> 	mov	 eax, 0Bh ; Invalid format!
  1486                              <1> loc_read_FAT32_fsinfo_sec_err:
  1487 00007FC1 29DB                <1> 	sub	ebx, ebx ; 0
  1488 00007FC3 F9                  <1> 	stc
  1489 00007FC4 C3                  <1> 	retn
  1918                                  %include 'trdosk6.s' ; 24/01/2016
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - MAIN PROGRAM : trdosk6.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 24/01/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    11                              <1> ; XXXXXXXX.ASM (XX/XX/2011)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ; u1.s (27/17/2015)
    15                              <1> ; ****************************************************************************
    16                              <1> 
    17                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - u1.s
    18                              <1> ; Last Modification: 27/12/2015
    19                              <1> 
    20                              <1> sysent: ; < enter to system call >
    21                              <1> 	 ;19/10/2015
    22                              <1> 	; 21/09/2015
    23                              <1> 	; 01/07/2015
    24                              <1> 	; 19/05/2015
    25                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
    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 00007FC5 368925[B8B70000]    <1>         mov     [ss:u.sp], esp ; Kernel stack points to return address
    54                              <1> 	; save user registers
    55 00007FCC 1E                  <1> 	push	ds
    56 00007FCD 06                  <1> 	push	es
    57 00007FCE 0FA0                <1> 	push	fs
    58 00007FD0 0FA8                <1> 	push	gs
    59 00007FD2 60                  <1> 	pushad  ; eax, ecx, edx, ebx, esp -before pushad-, ebp, esi, edi
    60                              <1> 	;
    61                              <1> 	; ESPACE = esp - [ss:u.sp] ; 4*12 = 48 ; 17/09/2015
    62                              <1> 	; 	(ESPACE is size of space in kernel stack 
    63                              <1> 	;	for saving/restoring user registers.)
    64                              <1> 	;
    65 00007FD3 50                  <1> 	push	eax ; 01/07/2015
    66 00007FD4 66B81000            <1> 	mov     ax, KDATA
    67 00007FD8 8ED8                <1>         mov     ds, ax
    68 00007FDA 8EC0                <1>         mov     es, ax
    69 00007FDC 8EE0                <1>         mov     fs, ax
    70 00007FDE 8EE8                <1>         mov     gs, ax
    71 00007FE0 A1[E8A70000]        <1> 	mov	eax, [k_page_dir]
    72 00007FE5 0F22D8              <1> 	mov	cr3, eax
    73 00007FE8 58                  <1> 	pop	eax ; 01/07/2015
    74                              <1> 	; 19/10/2015
    75 00007FE9 FC                  <1> 	cld
    76                              <1> 	;
    77 00007FEA FE05[B5B70000]      <1> 	inc	byte [sysflg]
    78                              <1> 		; incb sysflg / indicate a system routine is in progress
    79 00007FF0 FB                  <1>         sti 	; 18/01/2014
    80 00007FF1 0F8596BCFFFF        <1> 	jnz     panic ; 24/05/2013
    81                              <1> 		; beq 1f
    82                              <1> 		; jmp panic ; / called if trap inside system
    83                              <1> ;1:
    84                              <1> 	; 16/04/2015
    85 00007FF7 A3[C0B70000]        <1> 	mov	[u.r0], eax
    86 00007FFC 8925[BCB70000]      <1> 	mov	[u.usp], esp ; kernel stack points to user's registers
    87                              <1> 	;
    88                              <1> 		; mov $s.syst+2,clockp
    89                              <1> 		; mov r0,-(sp) / save user registers 
    90                              <1> 		; mov sp,u.r0 / pointer to bottom of users stack 
    91                              <1> 			   ; / in u.r0
    92                              <1> 		; mov r1,-(sp)
    93                              <1> 		; mov r2,-(sp)
    94                              <1> 		; mov r3,-(sp)
    95                              <1> 		; mov r4,-(sp)
    96                              <1> 		; mov r5,-(sp)
    97                              <1> 		; mov ac,-(sp) / "accumulator" register for extended
    98                              <1> 		             ; / arithmetic unit
    99                              <1> 		; mov mq,-(sp) / "multiplier quotient" register for the
   100                              <1> 		             ; / extended arithmetic unit
   101                              <1> 		; mov sc,-(sp) / "step count" register for the extended
   102                              <1> 		             ; / arithmetic unit
   103                              <1> 		; mov sp,u.sp / u.sp points to top of users stack
   104                              <1> 		; mov 18.(sp),r0 / store pc in r0
   105                              <1> 		; mov -(r0),r0 / sys inst in r0      10400xxx
   106                              <1> 		; sub $sys,r0 / get xxx code
   107 00008002 C1E002              <1> 	shl	eax, 2
   108                              <1> 		; asl r0 / multiply by 2 to jump indirect in bytes
   109 00008005 3D94000000          <1> 	cmp	eax, end_of_syscalls - syscalls
   110                              <1> 		; cmp r0,$2f-1f / limit of table (35) exceeded
   111                              <1> 	;jnb	short badsys
   112                              <1> 		; bhis badsys / yes, bad system call
   113 0000800A F5                  <1> 	cmc
   114 0000800B 9C                  <1> 	pushf	
   115 0000800C 50                  <1> 	push	eax
   116 0000800D 8B2D[B8B70000]      <1>  	mov 	ebp, [u.sp] ; Kernel stack at the beginning of sys call
   117 00008013 B0FE                <1> 	mov	al, 0FEh ; 11111110b
   118 00008015 1400                <1> 	adc	al, 0 ; al = al + cf
   119 00008017 204508              <1> 	and	[ebp+8], al ; flags (reset carry flag)
   120                              <1> 		; bic $341,20.(sp) / set users processor priority to 0 
   121                              <1> 				 ; / and clear carry bit
   122 0000801A 5D                  <1> 	pop	ebp ; eax
   123 0000801B 9D                  <1> 	popf
   124 0000801C 0F8248010000        <1>         jc      badsys
   125 00008022 A1[C0B70000]        <1> 	mov	eax, [u.r0]
   126                              <1> 	; system call registers: EAX, EDX, ECX, EBX, ESI, EDI
   127 00008027 FFA5[2D800000]      <1> 	jmp	dword [ebp+syscalls]
   128                              <1> 		; jmp *1f(r0) / jump indirect thru table of addresses
   129                              <1> 		            ; / to proper system routine.
   130                              <1> syscalls: ; 1:
   131                              <1> 	; 21/09/2015
   132                              <1> 	; 01/07/2015
   133                              <1> 	; 16/04/2015 (32 bit address modification) 
   134 0000802D [34810000]          <1> 	dd sysrele	; / 0
   135 00008031 [DA810000]          <1> 	dd sysexit 	; / 1
   136 00008035 [FF820000]          <1> 	dd sysfork 	; / 2
   137 00008039 [12840000]          <1> 	dd sysread 	; / 3
   138 0000803D [2D840000]          <1> 	dd syswrite 	; / 4
   139 00008041 [97840000]          <1> 	dd sysopen 	; / 5
   140 00008045 [D1850000]          <1> 	dd sysclose 	; / 6
   141 00008049 [81820000]          <1> 	dd syswait 	; / 7
   142 0000804D [47850000]          <1> 	dd syscreat 	; / 8
   143 00008051 [F8880000]          <1> 	dd syslink 	; / 9
   144 00008055 [BA890000]          <1> 	dd sysunlink 	; / 10
   145 00008059 [8D8A0000]          <1> 	dd sysexec 	; / 11
   146 0000805D [F4900000]          <1> 	dd syschdir 	; / 12
   147 00008061 [D8910000]          <1> 	dd systime 	; / 13
   148 00008065 [88850000]          <1> 	dd sysmkdir 	; / 14
   149 00008069 [46910000]          <1> 	dd syschmod 	; / 15
   150 0000806D [A8910000]          <1> 	dd syschown 	; / 16
   151 00008071 [0B920000]          <1> 	dd sysbreak 	; / 17
   152 00008075 [658E0000]          <1> 	dd sysstat 	; / 18
   153 00008079 [D0920000]          <1> 	dd sysseek 	; / 19
   154 0000807D [E2920000]          <1> 	dd systell 	; / 20
   155 00008081 [E3930000]          <1> 	dd sysmount 	; / 21
   156 00008085 [95940000]          <1> 	dd sysumount 	; / 22
   157 00008089 [60930000]          <1> 	dd syssetuid 	; / 23
   158 0000808D [91930000]          <1> 	dd sysgetuid 	; / 24
   159 00008091 [E7910000]          <1> 	dd sysstime 	; / 25
   160 00008095 [54930000]          <1> 	dd sysquit 	; / 26
   161 00008099 [48930000]          <1> 	dd sysintr 	; / 27
   162 0000809D [418E0000]          <1> 	dd sysfstat 	; / 28
   163 000080A1 [ED850000]          <1> 	dd sysemt 	; / 29
   164 000080A5 [1B860000]          <1> 	dd sysmdate 	; / 30
   165 000080A9 [66860000]          <1> 	dd sysstty 	; / 31
   166 000080AD [E5870000]          <1> 	dd sysgtty 	; / 32
   167 000080B1 [16860000]          <1> 	dd sysilgins 	; / 33
   168 000080B5 [F0940000]          <1> 	dd syssleep 	; 34 ; Retro UNIX 8086 v1 feature only !
   169                              <1> 			     ; 11/06/2014
   170 000080B9 [1F950000]          <1> 	dd sysmsg	; 35 ; Retro UNIX 386 v1 feature only !
   171                              <1> 			     ; 01/07/2015
   172 000080BD [F6950000]          <1> 	dd sysgeterr	; 36 ; Retro UNIX 386 v1 feature only !
   173                              <1> 			     ; 21/09/2015 - get last error number
   174                              <1> end_of_syscalls:
   175                              <1> 
   176                              <1> error:
   177                              <1> 	; 17/09/2015
   178                              <1> 	; 03/09/2015
   179                              <1> 	; 01/09/2015
   180                              <1> 	; 09/06/2015
   181                              <1> 	; 13/05/2015
   182                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
   183                              <1> 	; 10/04/2013 - 07/08/2013 (Retro UNIX 8086 v1)
   184                              <1> 	;
   185                              <1> 	; 'error' merely sets the error bit off the processor status (c-bit)
   186                              <1> 	; then falls right into the 'sysret', 'sysrele' return sequence.
   187                              <1> 	;
   188                              <1> 	; INPUTS -> none
   189                              <1> 	; OUTPUTS ->
   190                              <1> 	;	processor status - carry (c) bit is set (means error)
   191                              <1> 	;
   192                              <1> 	; 26/05/2013 (Stack pointer must be reset here! 
   193                              <1> 	; 	      Because, jumps to error procedure
   194                              <1> 	;	      disrupts push-pop nesting balance)
   195                              <1> 	;
   196 000080C1 8B2D[B8B70000]      <1> 	mov	ebp, [u.sp] ; interrupt (system call) return (iretd) address
   197 000080C7 804D0801            <1> 	or	byte [ebp+8], 1  ; set carry bit of flags register
   198                              <1> 				 ; (system call will return with cf = 1)
   199                              <1> 		; bis $1,20.(r1) / set c bit in processor status word below
   200                              <1> 		               ; / users stack
   201                              <1> 	; 17/09/2015
   202 000080CB 83ED30              <1> 	sub	ebp, ESPACE ; 48 ; total size of stack frame ('sysdefs.inc')
   203                              <1> 				 ; for saving/restoring user registers	
   204                              <1> 	;cmp	ebp, [u.usp]
   205                              <1> 	;je	short err0	
   206 000080CE 892D[BCB70000]      <1> 	mov	[u.usp], ebp
   207                              <1> ;err0:
   208                              <1> 	; 01/09/2015
   209 000080D4 8B25[BCB70000]      <1> 	mov	esp, [u.usp] 	    ; Retro Unix 8086 v1 modification!
   210                              <1> 				    ; 10/04/2013
   211                              <1> 				    ; (If an I/O error occurs during disk I/O,
   212                              <1> 				    ; related procedures will jump to 'error'
   213                              <1> 				    ; procedure directly without returning to 
   214                              <1> 				    ; the caller procedure. So, stack pointer
   215                              <1>                                     ; must be restored here.)
   216                              <1> 	; 13/05/2015
   217                              <1> 	; NOTE: (The last) error code is in 'u.error', it can be retrieved by
   218                              <1> 	;	'get last error' system call later. 	
   219                              <1> 
   220                              <1> 	; 03/09/2015 - 09/06/2015 - 07/08/2013
   221 000080DA C605[27B80000]00    <1> 	mov 	byte [u.kcall], 0 ; namei_r, mkdir_w reset
   222                              <1> 
   223                              <1> sysret: ; < return from system call>
   224                              <1> 	; 10/09/2015
   225                              <1> 	; 29/07/2015
   226                              <1> 	; 25/06/2015
   227                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
   228                              <1> 	; 10/04/2013 - 23/02/2014 (Retro UNIX 8086 v1)
   229                              <1> 	;
   230                              <1> 	; 'sysret' first checks to see if process is about to be 
   231                              <1> 	; terminated (u.bsys). If it is, 'sysexit' is called.
   232                              <1> 	; If not, following happens:	 
   233                              <1> 	; 	1) The user's stack pointer is restored.
   234                              <1> 	;	2) r1=0 and 'iget' is called to see if last mentioned
   235                              <1> 	;	   i-node has been modified. If it has, it is written out
   236                              <1> 	;	   via 'ppoke'.
   237                              <1> 	;	3) If the super block has been modified, it is written out
   238                              <1> 	;	   via 'ppoke'.				
   239                              <1> 	;	4) If the dismountable file system's super block has been
   240                              <1> 	;	   modified, it is written out to the specified device
   241                              <1> 	;	   via 'ppoke'.
   242                              <1> 	;	5) A check is made if user's time quantum (uquant) ran out
   243                              <1> 	;	   during his execution. If so, 'tswap' is called to give
   244                              <1> 	;	   another user a chance to run.
   245                              <1> 	;	6) 'sysret' now goes into 'sysrele'. 
   246                              <1> 	;	    (See 'sysrele' for conclusion.)		
   247                              <1> 	;
   248                              <1> 	; Calling sequence:
   249                              <1> 	;	jump table or 'br sysret'
   250                              <1> 	; Arguments: 
   251                              <1> 	;	-	
   252                              <1> 	; ...............................................................
   253                              <1> 	;	
   254                              <1> 	; ((AX=r1 for 'iget' input))
   255                              <1> 	;	
   256 000080E1 6631C0              <1> 	xor	ax, ax ; 04/05/2013
   257                              <1> sysret0: ; 29/07/2015 (eax = 0, jump from sysexec)
   258 000080E4 FEC0                <1> 	inc	al ; 04/05/2013
   259 000080E6 3805[0EB80000]      <1> 	cmp	[u.bsys], al ; 1
   260                              <1> 		; tstb u.bsys / is a process about to be terminated because
   261 000080EC 0F83E8000000        <1>         jnb     sysexit ; 04/05/2013
   262                              <1> 		; bne sysexit / of an error? yes, go to sysexit
   263                              <1> 	;mov	esp, [u.usp] ; 24/05/2013 (that is not needed here)
   264                              <1> 		; mov u.sp,sp / no point stack to users stack
   265 000080F2 FEC8                <1> 	dec 	al ; mov ax, 0
   266                              <1> 		; clr r1 / zero r1 to check last mentioned i-node
   267 000080F4 E820150000          <1> 	call	iget
   268                              <1> 		; jsr r0,iget / if last mentioned i-node has been modified
   269                              <1> 		            ; / it is written out
   270 000080F9 6631C0              <1> 	xor 	ax, ax ; 0
   271 000080FC 3805[B3B70000]      <1> 	cmp	[smod], al ; 0
   272                              <1> 		; tstb	smod / has the super block been modified
   273 00008102 7614                <1> 	jna	short sysret1
   274                              <1> 		; beq	1f / no, 1f
   275 00008104 A2[B3B70000]        <1> 	mov	[smod], al ; 0
   276                              <1> 		; clrb smod / yes, clear smod
   277 00008109 BB[65C00000]        <1> 	mov	ebx, sb0 ;; 07/08//2013
   278 0000810E 66810B0002          <1>    	or	word [ebx], 200h ;;
   279                              <1> 	;or	word [sb0], 200h ; write bit, bit 9
   280                              <1> 		; bis $1000,sb0 / set write bit in I/O queue for super block
   281                              <1> 		      	      ; / output
   282                              <1> 	; AX = 0
   283 00008113 E802150000          <1> 	call 	poke ; 07/08/2013
   284                              <1> 	; call	ppoke
   285                              <1> 	; AX = 0
   286                              <1> 		; jsr r0,ppoke / write out modified super block to disk
   287                              <1> sysret1: ;1:
   288 00008118 3805[B4B70000]      <1> 	cmp	[mmod], al ; 0
   289                              <1> 		; tstb	mmod / has the super block for the dismountable file
   290                              <1> 		           ; / system
   291 0000811E 7614                <1> 	jna	short sysrel0
   292                              <1> 		; beq 1f / been modified?  no, 1f
   293 00008120 A2[B4B70000]        <1> 	mov	[mmod], al ; 0	
   294                              <1> 		; clrb	mmod / yes, clear mmod
   295                              <1>         ;mov    ax, [mntd]
   296                              <1>         ;;mov   al, [mdev] ; 26/04/2013
   297 00008125 BB[6DC20000]        <1> 	mov	ebx, sb1 ;; 07/08//2013
   298                              <1>         ;;mov	[ebx], al
   299                              <1> 	;mov    [sb1], al
   300                              <1> 		; movb	mntd,sb1 / set the I/O queue
   301 0000812A 66810B0002          <1> 	or	word [ebx], 200h
   302                              <1> 	;or	word [sb1], 200h ; write bit, bit 9
   303                              <1> 		; bis $1000,sb1 / set write bit in I/O queue for detached sb
   304 0000812F E8E6140000          <1> 	call	poke ; 07/08/2013
   305                              <1> 	;call	ppoke 
   306                              <1> 		; jsr r0,ppoke / write it out to its device
   307                              <1>         ;xor    al, al ; 26/04/2013       
   308                              <1> ;1:
   309                              <1> 		; tstb uquant / is the time quantum 0?
   310                              <1> 		; bne 1f / no, don't swap it out
   311                              <1> 
   312                              <1> sysrele: ; < release >
   313                              <1> 	; 14/10/2015
   314                              <1> 	; 01/09/2015
   315                              <1> 	; 24/07/2015
   316                              <1> 	; 14/05/2015
   317                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
   318                              <1> 	; 10/04/2013 - 07/03/2014 (Retro UNIX 8086 v1)
   319                              <1> 	;
   320                              <1> 	; 'sysrele' first calls 'tswap' if the time quantum for a user is
   321                              <1> 	;  zero (see 'sysret'). It then restores the user's registers and
   322                              <1> 	; turns off the system flag. It then checked to see if there is
   323                              <1> 	; an interrupt from the user by calling 'isintr'. If there is, 
   324                              <1> 	; the output gets flashed (see isintr) and interrupt action is
   325                              <1> 	; taken by a branch to 'intract'. If there is no interrupt from
   326                              <1> 	; the user, a rti is made.
   327                              <1> 	;
   328                              <1> 	; Calling sequence:
   329                              <1> 	;	Fall through a 'bne' in 'sysret' & ?
   330                              <1> 	; Arguments:
   331                              <1> 	;	-	
   332                              <1> 	; ...............................................................
   333                              <1> 	;	
   334                              <1> 	; 23/02/2014 (swapret)
   335                              <1> 	; 22/09/2013
   336                              <1> sysrel0: ;1:
   337 00008134 803D[02B80000]00    <1> 	cmp	byte [u.quant], 0 ; 16/05/2013
   338                              <1> 		; tstb uquant / is the time quantum 0?
   339 0000813B 7705                <1>         ja      short swapret
   340                              <1> 		; bne 1f / no, don't swap it out
   341                              <1> sysrelease: ; 07/12/2013 (jump from 'clock')
   342 0000813D E8D9140000          <1> 	call	tswap
   343                              <1> 		; jsr r0,tswap / yes, swap it out
   344                              <1> ;
   345                              <1> ; Retro Unix 8086 v1 feature: return from 'swap' to 'swapret' address.
   346                              <1> swapret: ;1:
   347                              <1> 	; 10/09/2015
   348                              <1> 	; 01/09/2015
   349                              <1> 	; 14/05/2015
   350                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit, pm modifications)
   351                              <1> 	; 26/05/2013 (Retro UNIX 8086 v1)
   352                              <1> 	; cli
   353                              <1> 	; 24/07/2015
   354                              <1> 	;
   355                              <1> 	;; 'esp' must be already equal to '[u.usp]' here ! 
   356                              <1> 	;; mov	esp, [u.usp]
   357                              <1> 
   358                              <1> 	; 22/09/2013
   359 00008142 E8D5140000          <1> 	call	isintr
   360                              <1> 	; 20/10/2013
   361 00008147 7405                <1> 	jz	short sysrel1
   362 00008149 E875000000          <1> 	call	intract
   363                              <1> 		; jsr r0,isintr / is there an interrupt from the user
   364                              <1> 		;     br intract / yes, output gets flushed, take interrupt
   365                              <1> 		               ; / action
   366                              <1> sysrel1:
   367 0000814E FA                  <1> 	cli ; 14/10/2015
   368 0000814F FE0D[B5B70000]      <1> 	dec	byte [sysflg]
   369                              <1> 		; decb sysflg / turn system flag off
   370 00008155 A1[19B80000]        <1> 	mov     eax, [u.pgdir]
   371 0000815A 0F22D8              <1> 	mov	cr3, eax  ; 1st PDE points to Kernel Page Table 0 (1st 4 MB)
   372                              <1> 			  ; (others are different than kernel page tables) 
   373                              <1> 	; 10/09/2015
   374 0000815D 61                  <1> 	popad ; edi, esi, ebp, temp (icrement esp by 4), ebx, edx, ecx, eax
   375                              <1> 		; mov (sp)+,sc / restore user registers
   376                              <1> 		; mov (sp)+,mq
   377                              <1> 		; mov (sp)+,ac
   378                              <1> 		; mov (sp)+,r5
   379                              <1> 		; mov (sp)+,r4
   380                              <1> 		; mov (sp)+,r3
   381                              <1> 		; mov (sp)+,r2
   382                              <1> 	;
   383 0000815E A1[C0B70000]        <1> 	mov	eax, [u.r0]  ; ((return value in EAX))
   384 00008163 0FA9                <1> 	pop	gs
   385 00008165 0FA1                <1> 	pop	fs
   386 00008167 07                  <1> 	pop	es
   387 00008168 1F                  <1> 	pop	ds
   388 00008169 CF                  <1> 	iretd	
   389                              <1> 		; rti / no, return from interrupt
   390                              <1> 
   391                              <1> badsys:
   392                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
   393                              <1> 	; (Major Modification: 'core' dumping procedure in
   394                              <1>         ;       original UNIX v1 and Retro UNIX 8086 v1
   395                              <1> 	;	has been changed to print 'Invalid System Call !'
   396                              <1> 	;	message on the user's console tty.)
   397                              <1> 	; (EIP, EAX values will be shown on screen with error message)
   398                              <1> 	; (EIP = Return address just after the system call -INT 30h-)
   399                              <1> 	; (EAX = Function number)  
   400                              <1> 	;
   401 0000816A FE05[0EB80000]      <1> 	inc	byte [u.bsys]
   402                              <1> 	;
   403 00008170 8B1D[B8B70000]      <1> 	mov	ebx, [u.sp] ; esp at the beginning of 'sysent'
   404 00008176 8B03                <1> 	mov	eax, [ebx] ; EIP (return address, not 'INT 30h' address)
   405 00008178 E86998FFFF          <1> 	call	dwordtohex
   406 0000817D 8915[13A50000]      <1> 	mov	[bsys_msg_eip], edx
   407 00008183 A3[17A50000]        <1> 	mov	[bsys_msg_eip+4], eax
   408 00008188 A1[C0B70000]        <1> 	mov	eax, [u.r0]
   409 0000818D E85498FFFF          <1> 	call	dwordtohex
   410 00008192 8915[03A50000]      <1> 	mov	[bsys_msg_eax], edx
   411 00008198 A3[07A50000]        <1> 	mov	[bsys_msg_eax+4], eax
   412 0000819D 31C0                <1> 	xor	eax, eax
   413 0000819F C705[E0B70000]-     <1>         mov     dword [u.base], badsys_msg ; "Invalid System call !"
   413 000081A5 [E4A40000]          <1>
   414 000081A9 8B1D[D0B70000]      <1> 	mov	ebx, [u.fofp]
   415 000081AF 8903                <1> 	mov	[ebx], eax
   416                              <1> 	;mov	eax, 1 ; inode number of console tty (for user)	
   417 000081B1 40                  <1> 	inc	eax
   418 000081B2 C705[E4B70000]3B00- <1> 	mov	dword [u.count], BSYS_M_SIZE
   418 000081BA 0000                <1>
   419                              <1> 		; writei
   420                              <1> 		; INPUTS ->
   421                              <1> 		;    r1 - inode number
   422                              <1> 		;    u.count - byte count to be written
   423                              <1> 		;    u.base - points to user buffer
   424                              <1> 		;    u.fofp - points to word with current file offset
   425                              <1> 		; OUTPUTS ->
   426                              <1> 		;    u.count - cleared
   427                              <1> 		;    u.nread - accumulates total bytes passed back	
   428                              <1> 		;
   429                              <1> 		; ((Modified registers: EDX, EBX, ECX, ESI, EDI, EBP)) 	
   430 000081BC E85C140000          <1> 	call	writei
   431                              <1> 	;mov	eax, 1
   432 000081C1 EB17                <1> 	jmp	sysexit
   433                              <1> 
   434                              <1> 		; incb u.bsys / turn on the user's bad-system flag
   435                              <1> 		; mov $3f,u.namep / point u.namep to "core\0\0"
   436                              <1> 		; jsr r0,namei / get the i-number for the core image file
   437                              <1> 		; br 1f / error
   438                              <1> 		; neg r1 / negate the i-number to open the core image file
   439                              <1> 		       ; / for writing
   440                              <1> 		; jsr r0,iopen / open the core image file
   441                              <1> 		; jsr r0,itrunc / free all associated blocks
   442                              <1> 		; br 2f
   443                              <1> ;1:
   444                              <1> 		; mov $17,r1 / put i-node mode (17) in r1
   445                              <1> 		; jsr r0,maknod / make an i-node
   446                              <1> 		; mov u.dirbuf,r1 / put i-node number in r1
   447                              <1> ;2:
   448                              <1> 		; mov $core,u.base / move address core to u.base
   449                              <1> 		; mov $ecore-core,u.count / put the byte count in u.count
   450                              <1> 		; mov $u.off,u.fofp / more user offset to u.fofp
   451                              <1> 		; clr u.off / clear user offset
   452                              <1> 		; jsr r0,writei / write out the core image to the user
   453                              <1> 		; mov $user,u.base / pt. u.base to user
   454                              <1> 		; mov $64.,u.count / u.count = 64
   455                              <1> 		; jsr r0,writei / write out all the user parameters
   456                              <1> 		; neg r1 / make i-number positive
   457                              <1> 		; jsr r0,iclose / close the core image file
   458                              <1> 		; br sysexit /
   459                              <1> ;3:
   460                              <1> 		; <core\0\0>
   461                              <1> 
   462                              <1> intract: ; / interrupt action
   463                              <1> 	; 14/10/2015
   464                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
   465                              <1> 	; 09/05/2013 - 07/12/2013 (Retro UNIX 8086 v1)
   466                              <1> 	;
   467                              <1> 	; Retro UNIX 8086 v1 modification !
   468                              <1> 	; (Process/task switching and quit routine by using
   469                              <1> 	; Retro UNIX 8086 v1 keyboard interrupt output.))
   470                              <1> 	;
   471                              <1> 	; input -> 'u.quit'  (also value of 'u.intr' > 0)
   472                              <1> 	; output -> If value of 'u.quit' = FFFFh ('ctrl+brk' sign)
   473                              <1> 	;		'intract' will jump to 'sysexit'.
   474                              <1> 	;	    Intract will return to the caller 
   475                              <1> 	;		if value of 'u.quit' <> FFFFh. 	 
   476                              <1> 	; 14/10/2015
   477 000081C3 FB                  <1> 	sti
   478                              <1> 	; 07/12/2013	
   479 000081C4 66FF05[06B80000]    <1> 	inc 	word [u.quit]
   480 000081CB 7408                <1> 	jz	short intrct0 ; FFFFh -> 0
   481 000081CD 66FF0D[06B80000]    <1> 	dec	word [u.quit]
   482                              <1> 	; 16/04/2015
   483 000081D4 C3                  <1> 	retn
   484                              <1> intrct0:	
   485 000081D5 58                  <1> 	pop	eax ; call intract -> retn
   486                              <1> 	;
   487 000081D6 31C0                <1> 	xor 	eax, eax
   488 000081D8 FEC0                <1> 	inc	al  ; mov ax, 1
   489                              <1> ;;;
   490                              <1> 	; UNIX v1 original 'intract' routine... 
   491                              <1> 	; / interrupt action
   492                              <1> 		;cmp *(sp),$rti / are you in a clock interrupt?
   493                              <1> 		; bne 1f / no, 1f
   494                              <1> 		; cmp (sp)+,(sp)+ / pop clock pointer
   495                              <1> 	; 1: / now in user area
   496                              <1> 		; mov r1,-(sp) / save r1
   497                              <1> 		; mov u.ttyp,r1 
   498                              <1> 			; / pointer to tty buffer in control-to r1
   499                              <1> 		; cmpb 6(r1),$177
   500                              <1> 			; / is the interrupt char equal to "del"
   501                              <1> 		; beq 1f / yes, 1f
   502                              <1> 		; clrb 6(r1) 
   503                              <1> 		        ; / no, clear the byte 
   504                              <1> 			; / (must be a quit character)
   505                              <1> 		; mov (sp)+,r1 / restore r1
   506                              <1> 		; clr u.quit / clear quit flag
   507                              <1> 		; bis $20,2(sp) 
   508                              <1> 		    	; / set trace for quit (sets t bit of 
   509                              <1> 			; / ps-trace trap)
   510                              <1> 		; rti   ;  / return from interrupt
   511                              <1> 	; 1: / interrupt char = del
   512                              <1> 		; clrb 6(r1) / clear the interrupt byte 
   513                              <1> 			   ; / in the buffer
   514                              <1> 		; mov (sp)+,r1 / restore r1
   515                              <1> 		; cmp u.intr,$core / should control be 
   516                              <1> 				; / transferred to loc core?
   517                              <1> 		; blo 1f
   518                              <1> 		; jmp *u.intr / user to do rti yes, 
   519                              <1> 				; / transfer to loc core
   520                              <1> 	; 1:
   521                              <1> 		; sys 1 / exit
   522                              <1> 
   523                              <1> sysexit: ; <terminate process>
   524                              <1> 	; 01/09/2015
   525                              <1> 	; 31/08/2015
   526                              <1> 	; 14/05/2015
   527                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
   528                              <1> 	; 19/04/2013 - 14/02/2014 (Retro UNIX 8086 v1)
   529                              <1> 	;
   530                              <1> 	; 'sysexit' terminates a process. First each file that
   531                              <1> 	; the process has opened is closed by 'flose'. The process
   532                              <1> 	; status is then set to unused. The 'p.pid' table is then
   533                              <1> 	; searched to find children of the dying process. If any of
   534                              <1> 	; children are zombies (died by not waited for), they are
   535                              <1> 	; set free. The 'p.pid' table is then searched to find the
   536                              <1> 	; dying process's parent. When the parent is found, it is
   537                              <1> 	; checked to see if it is free or it is a zombie. If it is
   538                              <1> 	; one of these, the dying process just dies. If it is waiting
   539                              <1> 	; for a child process to die, it notified that it doesn't 
   540                              <1> 	; have to wait anymore by setting it's status from 2 to 1
   541                              <1> 	; (waiting to active). It is awakened and put on runq by
   542                              <1> 	; 'putlu'. The dying process enters a zombie state in which
   543                              <1> 	; it will never be run again but stays around until a 'wait'
   544                              <1> 	; is completed by it's parent process. If the parent is not
   545                              <1> 	; found, process just dies. This means 'swap' is called with
   546                              <1> 	; 'u.uno=0'. What this does is the 'wswap' is not called
   547                              <1> 	; to write out the process and 'rswap' reads the new process
   548                              <1> 	; over the one that dies..i.e., the dying process is 
   549                              <1> 	; overwritten and destroyed.	
   550                              <1>  	;
   551                              <1> 	; Calling sequence:
   552                              <1> 	;	sysexit or conditional branch.
   553                              <1> 	; Arguments:
   554                              <1> 	;	-	
   555                              <1> 	; ...............................................................
   556                              <1> 	;	
   557                              <1> 	; Retro UNIX 8086 v1 modification: 
   558                              <1> 	;       System call number (=1) is in EAX register.
   559                              <1> 	;
   560                              <1> 	;       Other parameters are in EDX, EBX, ECX, ESI, EDI, EBP
   561                              <1> 	;       registers depending of function details.
   562                              <1> 	;
   563                              <1> 	; ('swap' procedure is mostly different than original UNIX v1.)
   564                              <1> 	;
   565                              <1> ; / terminate process
   566                              <1> 	; AX = 1
   567 000081DA 6648                <1> 	dec 	ax ; 0
   568 000081DC 66A3[04B80000]      <1> 	mov	[u.intr], ax ; 0
   569                              <1> 		; clr u.intr / clear interrupt control word
   570                              <1> 		; clr r1 / clear r1
   571                              <1> 	; AX = 0
   572                              <1> sysexit_1: ; 1:
   573                              <1> 	; AX = File descriptor
   574                              <1> 		; / r1 has file descriptor (index to u.fp list)
   575                              <1> 		; / Search the whole list
   576 000081E2 E8140D0000          <1> 	call	fclose
   577                              <1> 		; jsr r0,fclose / close all files the process opened
   578                              <1> 	;; ignore error return
   579                              <1> 		; br .+2 / ignore error return
   580                              <1> 	;inc	ax
   581 000081E7 FEC0                <1> 	inc	al
   582                              <1> 		; inc r1 / increment file descriptor
   583                              <1> 	;cmp	ax, 10
   584 000081E9 3C0A                <1> 	cmp	al, 10
   585                              <1> 		; cmp r1,$10. / end of u.fp list?
   586 000081EB 72F5                <1> 	jb	short sysexit_1
   587                              <1> 		; blt 1b / no, go back
   588 000081ED 0FB61D[0FB80000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
   589                              <1> 		; movb	u.uno,r1 / yes, move dying process's number to r1
   590 000081F4 88A3[43B50000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
   591                              <1> 		; clrb p.stat-1(r1) / free the process
   592                              <1> 	;shl	bx, 1
   593 000081FA D0E3                <1> 	shl	bl, 1
   594                              <1> 		; asl r1 / use r1 for index into the below tables
   595 000081FC 668B8B[B2B40000]    <1> 	mov	cx, [ebx+p.pid-2]
   596                              <1> 		; mov p.pid-2(r1),r3 / move dying process's name to r3
   597 00008203 668B93[D2B40000]    <1> 	mov	dx, [ebx+p.ppid-2]
   598                              <1> 		; mov p.ppid-2(r1),r4 / move its parents name to r4
   599                              <1> 	; xor 	bx, bx ; 0
   600 0000820A 30DB                <1> 	xor	bl, bl ; 0
   601                              <1> 		; clr r2
   602 0000820C 31F6                <1> 	xor	esi, esi ; 0
   603                              <1> 		; clr r5 / initialize reg
   604                              <1> sysexit_2: ; 1:
   605                              <1> 	        ; / find children of this dying process, 
   606                              <1> 		; / if they are zombies, free them
   607                              <1> 	;add	bx, 2
   608 0000820E 80C302              <1> 	add	bl, 2
   609                              <1> 		; add $2,r2 / search parent process table 
   610                              <1> 		          ; / for dying process's name
   611 00008211 66398B[D2B40000]    <1> 	cmp	[ebx+p.ppid-2], cx
   612                              <1> 		; cmp p.ppid-2(r2),r3 / found it?
   613 00008218 7513                <1> 	jne	short sysexit_4
   614                              <1> 		; bne 3f / no
   615                              <1> 	;shr	bx, 1
   616 0000821A D0EB                <1> 	shr	bl, 1
   617                              <1> 		; asr r2 / yes, it is a parent
   618 0000821C 80BB[43B50000]03    <1> 	cmp	byte [ebx+p.stat-1], 3 ; SZOMB, 05/02/2014
   619                              <1> 		; cmpb p.stat-1(r2),$3 / is the child of this 
   620                              <1> 				     ; / dying process a zombie
   621 00008223 7506                <1> 	jne	short sysexit_3 
   622                              <1> 		; bne 2f / no
   623 00008225 88A3[43B50000]      <1> 	mov	[ebx+p.stat-1], ah ; 0, SFREE, 05/02/2014
   624                              <1> 		; clrb p.stat-1(r2) / yes, free the child process
   625                              <1> sysexit_3: ; 2:
   626                              <1> 	;shr	bx, 1
   627 0000822B D0E3                <1> 	shl	bl, 1
   628                              <1> 		; asl r2
   629                              <1> sysexit_4: ; 3:
   630                              <1> 		; / search the process name table 
   631                              <1> 		; / for the dying process's parent
   632 0000822D 663993[B2B40000]    <1> 	cmp	[ebx+p.pid-2], dx ; 17/09/2013	
   633                              <1> 		; cmp p.pid-2(r2),r4 / found it?
   634 00008234 7502                <1> 	jne	short sysexit_5
   635                              <1> 		; bne 3f / no
   636 00008236 89DE                <1> 	mov	esi, ebx
   637                              <1> 		; mov r2,r5 / yes, put index to p.pid table (parents
   638                              <1> 		          ; / process # x2) in r5
   639                              <1> sysexit_5: ; 3:
   640                              <1> 	;cmp	bx, nproc + nproc
   641 00008238 80FB20              <1> 	cmp	bl, nproc + nproc
   642                              <1> 		; cmp r2,$nproc+nproc / has whole table been searched?
   643 0000823B 72D1                <1> 	jb	short sysexit_2
   644                              <1> 		; blt 1b / no, go back
   645                              <1> 		; mov r5,r1 / yes, r1 now has parents process # x2
   646 0000823D 21F6                <1> 	and	esi, esi ; r5=r1
   647 0000823F 7431                <1> 	jz	short sysexit_6
   648                              <1> 		; beq 2f / no parent has been found. 
   649                              <1> 		       ; / The process just dies
   650 00008241 66D1EE              <1> 	shr	si, 1
   651                              <1> 		; asr r1 / set up index to p.stat
   652 00008244 8A86[43B50000]      <1> 	mov	al, [esi+p.stat-1]
   653                              <1> 		; movb p.stat-1(r1),r2 / move status of parent to r2
   654 0000824A 20C0                <1> 	and	al, al
   655 0000824C 7424                <1> 	jz	short sysexit_6
   656                              <1> 		; beq 2f / if its been freed, 2f
   657 0000824E 3C03                <1> 	cmp	al, 3
   658                              <1> 		; cmp r2,$3 / is parent a zombie?
   659 00008250 7420                <1> 	je	short sysexit_6
   660                              <1> 		; beq 2f / yes, 2f
   661                              <1> 	; BH = 0
   662 00008252 8A1D[0FB80000]      <1> 	mov	bl, [u.uno]
   663                              <1> 		; movb u.uno,r3 / move dying process's number to r3
   664 00008258 C683[43B50000]03    <1> 	mov	byte [ebx+p.stat-1], 3  ; SZOMB, 05/02/2014
   665                              <1> 		; movb $3,p.stat-1(r3) / make the process a zombie
   666                              <1> 	; 05/02/2014
   667 0000825F 3C01                <1> 	cmp	al, 1 ; SRUN
   668 00008261 740F                <1> 	je	short sysexit_6
   669                              <1> 	;cmp	al, 2
   670                              <1> 		; cmp r2,$2 / is the parent waiting for 
   671                              <1> 			  ; / this child to die
   672                              <1> 	;jne	short sysexit_6	
   673                              <1> 		; bne 2f / yes, notify parent not to wait any more
   674                              <1> 	; 05/02/2014
   675                              <1> 	; p.stat = 2 --> waiting
   676                              <1> 	; p.stat = 4 --> sleeping
   677 00008263 C686[43B50000]01    <1> 	mov	byte [esi+p.stat-1], 1 ; SRUN ; 05/02/2014
   678                              <1> 	;dec	byte [esi+p.stat-1]
   679                              <1> 		; decb	p.stat-1(r1) / awaken it by putting it (parent)
   680 0000826A 6689F0              <1> 	mov	ax, si ; r1  (process number in AL)
   681                              <1> 	; 
   682                              <1> 	;mov	ebx, runq + 4
   683                              <1> 		; mov $runq+4,r2 / on the runq
   684 0000826D E8AD130000          <1> 	call	putlu
   685                              <1> 		; jsr r0, putlu
   686                              <1> sysexit_6: ; 2:
   687                              <1> 	; 31/08/2015
   688                              <1> 		; / the process dies
   689 00008272 C605[0FB80000]00    <1> 	mov	byte [u.uno], 0
   690                              <1> 		; clrb u.uno / put zero as the process number, 
   691                              <1> 	           ; / so "swap" will
   692 00008279 E8A2130000          <1> 	call	swap
   693                              <1> 		; jsr r0,swap / overwrite process with another process
   694                              <1> hlt_sys:
   695                              <1> 	;sti ; 18/01/2014
   696                              <1> hlts0:
   697 0000827E F4                  <1> 	hlt
   698 0000827F EBFD                <1> 	jmp	short hlts0
   699                              <1> 		; 0 / and thereby kill it; halt?
   700                              <1> 
   701                              <1> 
   702                              <1> syswait: ; < wait for a processs to die >
   703                              <1> 	; 17/09/2015
   704                              <1> 	; 02/09/2015
   705                              <1> 	; 01/09/2015
   706                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - Beginning)
   707                              <1> 	; 24/05/2013 - 05/02/2014 (Retro UNIX 8086 v1)
   708                              <1> 	;
   709                              <1> 	; 'syswait' waits for a process die. 
   710                              <1> 	; It works in following way:
   711                              <1> 	;    1) From the parent process number, the parent's 
   712                              <1> 	; 	process name is found. The p.ppid table of parent
   713                              <1> 	;	names is then searched for this process name.
   714                              <1> 	;	If a match occurs, r2 contains child's process
   715                              <1> 	;	number. The child status is checked to see if it is
   716                              <1> 	;	a zombie, i.e; dead but not waited for (p.stat=3)
   717                              <1> 	;	If it is, the child process is freed and it's name
   718                              <1> 	;	is put in (u.r0). A return is then made via 'sysret'.
   719                              <1> 	;	If the child is not a zombie, nothing happens and
   720                              <1> 	;	the search goes on through the p.ppid table until
   721                              <1> 	;	all processes are checked or a zombie is found.
   722                              <1> 	;    2) If no zombies are found, a check is made to see if
   723                              <1> 	;	there are any children at all. If there are none,
   724                              <1> 	;	an error return is made. If there are, the parent's
   725                              <1> 	;	status is set to 2 (waiting for child to die),
   726                              <1> 	;	the parent is swapped out, and a branch to 'syswait'
   727                              <1> 	;	is made to wait on the next process.
   728                              <1> 	;
   729                              <1> 	; Calling sequence:
   730                              <1> 	;	?
   731                              <1> 	; Arguments:
   732                              <1> 	;	-
   733                              <1> 	; Inputs: - 
   734                              <1> 	; Outputs: if zombie found, it's name put in u.r0.	
   735                              <1> 	; ...............................................................
   736                              <1> 	;				
   737                              <1> 	
   738                              <1> ; / wait for a process to die
   739                              <1> 
   740                              <1> syswait_0:
   741 00008281 0FB61D[0FB80000]    <1> 	movzx	ebx, byte [u.uno] ; 01/09/2015
   742                              <1> 		; movb u.uno,r1 / put parents process number in r1
   743 00008288 D0E3                <1> 	shl	bl, 1
   744                              <1> 	;shl	bx, 1
   745                              <1> 		; asl r1 / x2 to get index into p.pid table
   746 0000828A 668B83[B2B40000]    <1> 	mov	ax, [ebx+p.pid-2]
   747                              <1> 		; mov p.pid-2(r1),r1 / get the name of this process
   748 00008291 31F6                <1> 	xor	esi, esi
   749                              <1> 		; clr r2
   750 00008293 31C9                <1> 	xor	ecx, ecx ; 30/10/2013
   751                              <1> 	;xor 	cl, cl
   752                              <1> 		; clr r3 / initialize reg 3
   753                              <1> syswait_1: ; 1:
   754 00008295 6683C602            <1> 	add	si, 2
   755                              <1> 		; add $2,r2 / use r2 for index into p.ppid table
   756                              <1> 			  ; / search table of parent processes 
   757                              <1> 			  ; / for this process name
   758 00008299 663B86[D2B40000]    <1> 	cmp	ax, [esi+p.ppid-2]
   759                              <1> 		; cmp p.ppid-2(r2),r1 / r2 will contain the childs 
   760                              <1> 			            ; / process number
   761 000082A0 7535                <1> 	jne	short syswait_3
   762                              <1> 		;bne 3f / branch if no match of parent process name
   763                              <1> 	;inc	cx
   764 000082A2 FEC1                <1> 	inc	cl
   765                              <1> 		;inc r3 / yes, a match, r3 indicates number of children
   766 000082A4 66D1EE              <1> 	shr	si, 1
   767                              <1> 		; asr r2 / r2/2 to get index to p.stat table
   768                              <1> 	; The possible states ('p.stat' values) of a process are:
   769                              <1> 	;	0 = free or unused
   770                              <1> 	;	1 = active
   771                              <1> 	;	2 = waiting for a child process to die
   772                              <1> 	;	3 = terminated, but not yet waited for (zombie).	
   773 000082A7 80BE[43B50000]03    <1> 	cmp	byte [esi+p.stat-1], 3 ; SZOMB, 05/02/2014
   774                              <1> 		; cmpb p.stat-1(r2),$3 / is the child process a zombie?
   775 000082AE 7524                <1> 	jne	short syswait_2
   776                              <1> 		; bne 2f / no, skip it
   777 000082B0 88BE[43B50000]      <1> 	mov	[esi+p.stat-1], bh ; 0
   778                              <1> 		; clrb p.stat-1(r2) / yes, free it
   779 000082B6 66D1E6              <1> 	shl	si, 1
   780                              <1> 		; asl r2 / r2x2 to get index into p.pid table
   781 000082B9 0FB786[B2B40000]    <1> 	movzx	eax, word [esi+p.pid-2]
   782 000082C0 A3[C0B70000]        <1> 	mov	[u.r0], eax
   783                              <1> 		; mov p.pid-2(r2),*u.r0 
   784                              <1> 			      ; / put childs process name in (u.r0)
   785                              <1> 	;
   786                              <1> 	; Retro UNIX 386 v1 modification ! (17/09/2015)
   787                              <1> 	;
   788                              <1> 	; Parent process ID -p.ppid- field (of the child process)
   789                              <1> 	; must be cleared in order to prevent infinitive 'syswait'
   790                              <1> 	; system call loop from the application/program if it calls
   791                              <1> 	; 'syswait' again (mistakenly) while there is not a zombie
   792                              <1> 	; or running child process to wait. ('forktest.s', 17/09/2015)
   793                              <1> 	;
   794                              <1> 	; Note: syswait will return with error if there is not a
   795                              <1> 	;       zombie or running process to wait.	
   796                              <1> 	;
   797 000082C5 6629C0              <1> 	sub	ax, ax
   798 000082C8 668986[D2B40000]    <1> 	mov 	[esi+p.ppid-2], ax ; 0 ; 17/09/2015
   799 000082CF E910FEFFFF          <1> 	jmp	sysret0 ; ax = 0
   800                              <1> 	;
   801                              <1> 	;jmp	sysret
   802                              <1> 		; br sysret1 / return cause child is dead
   803                              <1> syswait_2: ; 2:
   804 000082D4 66D1E6              <1> 	shl	si, 1
   805                              <1> 		; asl r2 / r2x2 to get index into p.ppid table
   806                              <1> syswait_3: ; 3:
   807 000082D7 6683FE20            <1> 	cmp	si, nproc+nproc
   808                              <1> 		; cmp r2,$nproc+nproc / have all processes been checked?
   809 000082DB 72B8                <1> 	jb	short syswait_1
   810                              <1> 		; blt 1b / no, continue search
   811                              <1> 	;and	cx, cx
   812 000082DD 20C9                <1> 	and	cl, cl
   813                              <1> 		; tst r3 / one gets here if there are no children 
   814                              <1> 		       ; / or children that are still active
   815                              <1> 	; 30/10/2013
   816 000082DF 750B                <1> 	jnz	short syswait_4
   817                              <1> 	;jz	error
   818                              <1> 		; beq error1 / there are no children, error
   819 000082E1 890D[C0B70000]      <1> 	mov	[u.r0], ecx ; 0
   820 000082E7 E9D5FDFFFF          <1> 	jmp	error
   821                              <1> syswait_4:
   822 000082EC 8A1D[0FB80000]      <1> 	mov	bl, [u.uno]
   823                              <1> 		; movb u.uno,r1 / there are children so put 
   824                              <1> 			      ; / parent process number in r1
   825 000082F2 FE83[43B50000]      <1> 	inc	byte [ebx+p.stat-1] ; 2, SWAIT, 05/02/2014
   826                              <1> 		; incb p.stat-1(r1) / it is waiting for 
   827                              <1> 				  ; / other children to die
   828                              <1> 	; 04/11/2013
   829 000082F8 E823130000          <1> 	call	swap
   830                              <1> 		; jsr r0,swap / swap it out, because it's waiting
   831 000082FD EB82                <1> 	jmp	syswait_0
   832                              <1> 		; br syswait / wait on next process
   833                              <1> 
   834                              <1> sysfork: ; < create a new process >
   835                              <1> 	; 18/09/2015
   836                              <1> 	; 04/09/2015
   837                              <1> 	; 02/09/2015
   838                              <1> 	; 01/09/2015
   839                              <1> 	; 28/08/2015
   840                              <1> 	; 14/05/2015
   841                              <1> 	; 10/05/2015
   842                              <1> 	; 09/05/2015
   843                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 - Beginning)
   844                              <1> 	; 24/05/2013 - 14/02/2014 (Retro UNIX 8086 v1)
   845                              <1> 	;
   846                              <1> 	; 'sysfork' creates a new process. This process is referred
   847                              <1> 	; to as the child process. This new process core image is
   848                              <1> 	; a copy of that of the caller of 'sysfork'. The only
   849                              <1> 	; distinction is the return location and the fact that (u.r0)
   850                              <1> 	; in the old process (parent) contains the process id (p.pid)
   851                              <1> 	; of the new process (child). This id is used by 'syswait'.
   852                              <1> 	; 'sysfork' works in the following manner: 	
   853                              <1> 	;    1) The process status table (p.stat) is searched to find
   854                              <1> 	;	a process number that is unused. If none are found
   855                              <1> 	;	an error occurs.
   856                              <1> 	;    2) when one is found, it becomes the child process number
   857                              <1> 	;	and it's status (p.stat) is set to active.
   858                              <1> 	;    3) If the parent had a control tty, the interrupt 
   859                              <1> 	;	character in that tty buffer is cleared.
   860                              <1> 	;    4) The child process is put on the lowest priority run 
   861                              <1> 	;	queue via 'putlu'.
   862                              <1> 	;    5) A new process name is gotten from 'mpid' (actually 
   863                              <1> 	;	it is a unique number) and is put in the child's unique
   864                              <1> 	;	identifier; process id (p.pid).
   865                              <1> 	;    6) The process name of the parent is then obtained and
   866                              <1> 	;	placed in the unique identifier of the parent process
   867                              <1> 	;	name is then put in 'u.r0'.	
   868                              <1> 	;    7) The child process is then written out on disk by
   869                              <1> 	;	'wswap',i.e., the parent process is copied onto disk
   870                              <1> 	;	and the child is born. (The child process is written 
   871                              <1> 	;	out on disk/drum with 'u.uno' being the child process
   872                              <1> 	;	number.)
   873                              <1> 	;    8) The parent process number is then restored to 'u.uno'.
   874                              <1> 	;    9) The child process name is put in 'u.r0'.
   875                              <1> 	;   10) The pc on the stack sp + 18 is incremented by 2 to
   876                              <1> 	;	create the return address for the parent process.
   877                              <1> 	;   11) The 'u.fp' list as then searched to see what files
   878                              <1> 	;	the parent has opened. For each file the parent has
   879                              <1> 	;	opened, the corresponding 'fsp' entry must be updated
   880                              <1> 	;	to indicate that the child process also has opened
   881                              <1> 	;	the file. A branch to 'sysret' is then made.	 			 				
   882                              <1> 	;
   883                              <1> 	; Calling sequence:
   884                              <1> 	;	from shell ?
   885                              <1> 	; Arguments:
   886                              <1> 	;	-
   887                              <1> 	; Inputs: -
   888                              <1> 	; Outputs: *u.r0 - child process name
   889                              <1> 	; ...............................................................
   890                              <1> 	;	
   891                              <1> 	; Retro UNIX 8086 v1 modification: 
   892                              <1> 	;	AX = r0 = PID (>0) (at the return of 'sysfork')
   893                              <1> 	;	= process id of child a parent process returns
   894                              <1> 	;	= process id of parent when a child process returns
   895                              <1> 	;
   896                              <1> 	;       In original UNIX v1, sysfork is called and returns as
   897                              <1> 	;	in following manner: (with an example: c library, fork)
   898                              <1> 	;	
   899                              <1> 	;	1:
   900                              <1> 	;		sys	fork
   901                              <1> 	;			br 1f  / child process returns here
   902                              <1> 	;		bes	2f     / parent process returns here
   903                              <1> 	;		/ pid of new process in r0
   904                              <1> 	;		rts	pc
   905                              <1> 	;	2: / parent process condionally branches here
   906                              <1> 	;		mov	$-1,r0 / pid = -1 means error return
   907                              <1> 	;		rts	pc
   908                              <1> 	;
   909                              <1> 	;	1: / child process brances here
   910                              <1> 	;		clr	r0   / pid = 0 in child process
   911                              <1> 	;		rts	pc
   912                              <1> 	;
   913                              <1> 	;	In UNIX v7x86 (386) by Robert Nordier (1999)
   914                              <1> 	;		// pid = fork();
   915                              <1> 	;		//
   916                              <1> 	;		// pid == 0 in child process; 
   917                              <1> 	;		// pid == -1 means error return
   918                              <1> 	;		// in child, 
   919                              <1> 	;		//	parents id is in par_uid if needed
   920                              <1> 	;		
   921                              <1> 	;		_fork:
   922                              <1> 	;			mov	$.fork,eax
   923                              <1> 	;			int	$0x30
   924                              <1> 	;			jmp	1f
   925                              <1> 	;			jnc	2f
   926                              <1> 	;			jmp	cerror
   927                              <1> 	;		1:
   928                              <1> 	;			mov	eax,_par_uid
   929                              <1> 	;			xor	eax,eax
   930                              <1> 	;		2:
   931                              <1> 	;			ret
   932                              <1> 	;
   933                              <1> 	;	In Retro UNIX 8086 v1,
   934                              <1> 	;	'sysfork' returns in following manner:
   935                              <1> 	;	
   936                              <1> 	;		mov	ax, sys_fork
   937                              <1> 	;		mov	bx, offset @f ; routine for child
   938                              <1> 	;		int	20h
   939                              <1> 	;		jc	error
   940                              <1> 	;		
   941                              <1> 	;	; Routine for parent process here (just after 'jc')
   942                              <1> 	;		mov	word ptr [pid_of_child], ax
   943                              <1> 	;		jmp	next_routine_for_parent	
   944                              <1> 	;
   945                              <1> 	;	@@: ; routine for child process here				
   946                              <1> 	;		....	
   947                              <1> 	;	NOTE: 'sysfork' returns to specified offset
   948                              <1> 	;	       for child process by using BX input.
   949                              <1> 	;	      (at first, parent process will return then 
   950                              <1> 	;	      child process will return -after swapped in-
   951                              <1> 	;	      'syswait' is needed in parent process
   952                              <1> 	;	      if return from child process will be waited for.)
   953                              <1> 	;	  				
   954                              <1> 	
   955                              <1> ; / create a new process
   956                              <1> 	; EBX = return address for child process 
   957                              <1> 	     ; (Retro UNIX 8086 v1 modification !)
   958 000082FF 31F6                <1> 	xor 	esi, esi
   959                              <1> 		; clr r1
   960                              <1> sysfork_1: ; 1: / search p.stat table for unused process number
   961 00008301 46                  <1> 	inc	esi
   962                              <1> 		; inc r1
   963 00008302 80BE[43B50000]00    <1> 	cmp	byte [esi+p.stat-1], 0 ; SFREE, 05/02/2014
   964                              <1> 		; tstb p.stat-1(r1) / is process active, unused, dead
   965 00008309 760B                <1> 	jna	short sysfork_2	
   966                              <1> 		; beq 1f / it's unused so branch
   967 0000830B 6683FE10            <1> 	cmp	si, nproc
   968                              <1> 		; cmp r1,$nproc / all processes checked
   969 0000830F 72F0                <1> 	jb	short sysfork_1
   970                              <1> 		; blt 1b / no, branch back
   971                              <1> 	;
   972                              <1> 	; Retro UNIX 8086 v1. modification:
   973                              <1> 	;	Parent process returns from 'sysfork' to address 
   974                              <1> 	;	which is just after 'sysfork' system call in parent
   975                              <1> 	;	process. Child process returns to address which is put
   976                              <1> 	;	in BX register by parent process for 'sysfork'. 
   977                              <1> 	;
   978                              <1> 		;add $2,18.(sp) / add 2 to pc when trap occured, points
   979                              <1> 		             ; / to old process return
   980                              <1> 		; br error1 / no room for a new process
   981 00008311 E9ABFDFFFF          <1> 	jmp	error
   982                              <1> sysfork_2: ; 1:
   983 00008316 E8ECADFFFF          <1> 	call	allocate_page
   984 0000831B 0F82A0FDFFFF        <1> 	jc	error
   985 00008321 50                  <1> 	push	eax   ; UPAGE (user structure page) address
   986                              <1> 	; Retro UNIX 386 v1 modification!
   987 00008322 E8E9AFFFFF          <1> 	call	duplicate_page_dir
   988                              <1> 		; EAX = New page directory 
   989 00008327 730B                <1> 	jnc	short sysfork_3
   990 00008329 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
   991 0000832A E8B0AFFFFF          <1> 	call 	deallocate_page
   992 0000832F E98DFDFFFF          <1> 	jmp	error
   993                              <1> sysfork_3:
   994                              <1> 	; Retro UNIX 386 v1 modification !
   995 00008334 56                  <1> 	push	esi
   996 00008335 E8E7120000          <1> 	call	wswap ; save current user (u) structure, user registers
   997                              <1> 		      ; and interrupt return components (for IRET)
   998 0000833A 8705[19B80000]      <1> 	xchg	eax, [u.pgdir] ; page directory of the child process
   999 00008340 A3[1DB80000]        <1> 	mov	[u.ppgdir], eax ; page directory of the parent process
  1000 00008345 5E                  <1> 	pop	esi
  1001 00008346 58                  <1> 	pop	eax   ; UPAGE (user structure page) address
  1002                              <1> 		; [u.usp] = esp
  1003 00008347 89F7                <1> 	mov	edi, esi
  1004 00008349 66C1E702            <1> 	shl	di, 2
  1005 0000834D 8987[50B50000]      <1> 	mov	[edi+p.upage-4], eax ; memory page for 'user' struct
  1006 00008353 A3[10B80000]        <1> 	mov	[u.upage], eax ; memory page for 'user' struct (child)
  1007                              <1> 	; 28/08/2015
  1008 00008358 0FB605[0FB80000]    <1> 	movzx	eax, byte [u.uno] ; parent process number
  1009                              <1> 		; movb u.uno,-(sp) / save parent process number
  1010 0000835F 89C7                <1> 	mov	edi, eax
  1011 00008361 50                  <1>         push	eax ; ** 
  1012 00008362 8A87[13B50000]      <1> 	mov     al, [edi+p.ttyc-1] ; console tty (parent)
  1013                              <1> 	; 18/09/2015
  1014                              <1> 	;mov     [esi+p.ttyc-1], al ; set child's console tty
  1015                              <1> 	;mov     [esi+p.waitc-1], ah ; 0 ; reset child's wait channel
  1016 00008368 668986[13B50000]    <1> 	mov     [esi+p.ttyc-1], ax ; al - set child's console tty
  1017                              <1> 				   ; ah - reset child's wait channel	
  1018 0000836F 89F0                <1> 	mov	eax, esi
  1019 00008371 A2[0FB80000]        <1> 	mov	[u.uno], al ; child process number
  1020                              <1> 		;movb r1,u.uno / set child process number to r1
  1021 00008376 FE86[43B50000]      <1>         inc     byte [esi+p.stat-1] ; 1, SRUN, 05/02/2014
  1022                              <1> 		; incb p.stat-1(r1) / set p.stat entry for child 
  1023                              <1> 				; / process to active status
  1024                              <1> 		; mov u.ttyp,r2 / put pointer to parent process' 
  1025                              <1> 			      ; / control tty buffer in r2
  1026                              <1>                 ; beq 2f / branch, if no such tty assigned
  1027                              <1> 		; clrb 6(r2) / clear interrupt character in tty buffer
  1028                              <1> 	; 2:
  1029 0000837C 53                  <1> 	push	ebx  ; * return address for the child process
  1030                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
  1031                              <1> 	; (Retro UNIX 8086 v1 modification!)
  1032                              <1> 		; mov $runq+4,r2
  1033 0000837D E89D120000          <1> 	call	putlu 
  1034                              <1>  		; jsr r0,putlu / put child process on lowest priority 
  1035                              <1> 			   ; / run queue
  1036 00008382 66D1E6              <1> 	shl	si, 1
  1037                              <1> 		; asl r1 / multiply r1 by 2 to get index 
  1038                              <1> 		       ; / into p.pid table
  1039 00008385 66FF05[ACB70000]    <1> 	inc	word [mpid]
  1040                              <1> 		; inc mpid / increment m.pid; get a new process name
  1041 0000838C 66A1[ACB70000]      <1> 	mov	ax, [mpid]
  1042 00008392 668986[B2B40000]    <1> 	mov	[esi+p.pid-2], ax
  1043                              <1> 		;mov mpid,p.pid-2(r1) / put new process name 
  1044                              <1> 				    ; / in child process' name slot
  1045 00008399 5A                  <1> 	pop	edx  ; * return address for the child process
  1046                              <1> 		     ; * Retro UNIX 8086 v1 feature only !	
  1047 0000839A 5B                  <1>   	pop	ebx  ; **
  1048                              <1> 	;mov	ebx, [esp] ; ** parent process number
  1049                              <1> 		; movb (sp),r2 / put parent process number in r2
  1050 0000839B 66D1E3              <1> 	shl 	bx, 1
  1051                              <1> 		;asl r2 / multiply by 2 to get index into below tables
  1052                              <1> 	;movzx eax, word [ebx+p.pid-2]
  1053 0000839E 668B83[B2B40000]    <1> 	mov	ax, [ebx+p.pid-2]
  1054                              <1> 		; mov p.pid-2(r2),r2 / get process name of parent
  1055                              <1> 				   ; / process
  1056 000083A5 668986[D2B40000]    <1> 	mov	[esi+p.ppid-2], ax
  1057                              <1> 		; mov r2,p.ppid-2(r1) / put parent process name 
  1058                              <1> 			  ; / in parent process slot for child
  1059 000083AC A3[C0B70000]        <1> 	mov	[u.r0], eax	
  1060                              <1> 		; mov r2,*u.r0 / put parent process name on stack 
  1061                              <1> 			     ; / at location where r0 was saved
  1062 000083B1 8B2D[B8B70000]      <1> 	mov 	ebp, [u.sp] ; points to return address (EIP for IRET)
  1063 000083B7 895500              <1> 	mov	[ebp], edx ; *, CS:EIP -> EIP
  1064                              <1> 			   ; * return address for the child process
  1065                              <1> 		; mov $sysret1,-(sp) /
  1066                              <1> 		; mov sp,u.usp / contents of sp at the time when 
  1067                              <1> 			      ; / user is swapped out
  1068                              <1> 		; mov $sstack,sp / point sp to swapping stack space
  1069                              <1> 	; 04/09/2015 - 01/09/2015
  1070                              <1> 	; [u.usp] = esp
  1071 000083BA 68[E1800000]        <1> 	push	sysret ; ***
  1072 000083BF 8925[BCB70000]      <1> 	mov	[u.usp], esp ; points to 'sysret' address (***)
  1073                              <1> 			     ; (for child process)	
  1074 000083C5 31C0                <1> 	xor 	eax, eax
  1075 000083C7 66A3[F0B70000]      <1> 	mov 	[u.ttyp], ax ; 0
  1076                              <1> 	;
  1077 000083CD E84F120000          <1> 	call	wswap ; Retro UNIX 8086 v1 modification !
  1078                              <1> 		;jsr r0,wswap / put child process out on drum
  1079                              <1> 		;jsr r0,unpack / unpack user stack
  1080                              <1> 		;mov u.usp,sp / restore user stack pointer
  1081                              <1> 		; tst (sp)+ / bump stack pointer
  1082                              <1> 	; Retro UNIX 386 v1 modification !
  1083 000083D2 58                  <1> 	pop	eax ; ***
  1084 000083D3 66D1E3              <1> 	shl	bx, 1
  1085 000083D6 8B83[50B50000]      <1> 	mov     eax, [ebx+p.upage-4] ; UPAGE address ; 14/05/2015
  1086 000083DC E841120000          <1> 	call	rswap ; restore parent process 'u' structure, 
  1087                              <1> 		      ; registers and return address (for IRET)
  1088                              <1> 		;movb (sp)+,u.uno / put parent process number in u.uno
  1089 000083E1 0FB705[ACB70000]    <1>         movzx   eax, word [mpid]
  1090 000083E8 A3[C0B70000]        <1> 	mov	[u.r0], eax
  1091                              <1> 		; mov mpid,*u.r0 / put child process name on stack 
  1092                              <1> 			       ; / where r0 was saved
  1093                              <1> 		; add $2,18.(sp) / add 2 to pc on stack; gives parent
  1094                              <1> 			          ; / process return
  1095                              <1> 	;xor	ebx, ebx
  1096 000083ED 31F6                <1> 	xor     esi, esi
  1097                              <1> 		;clr r1
  1098                              <1> sysfork_4: ; 1: / search u.fp list to find the files 
  1099                              <1> 	      ; / opened by the parent process
  1100                              <1> 	; 01/09/2015
  1101                              <1> 	;xor	bh, bh
  1102                              <1> 	;mov 	bl, [esi+u.fp]
  1103 000083EF 8A86[C6B70000]      <1> 	mov 	al, [esi+u.fp]
  1104                              <1> 		; movb u.fp(r1),r2 / get an open file for this process
  1105                              <1>         ;or      bl, bl
  1106 000083F5 08C0                <1> 	or	al, al
  1107 000083F7 740D                <1> 	jz	short sysfork_5	
  1108                              <1> 		; beq 2f / file has not been opened by parent, 
  1109                              <1> 		       ; / so branch
  1110 000083F9 B40A                <1> 	mov	ah, 10 ; Retro UNIX 386 v1 fsp structure size = 10 bytes
  1111 000083FB F6E4                <1> 	mul	ah
  1112                              <1> 	;movzx	ebx, ax
  1113 000083FD 6689C3              <1> 	mov	bx, ax
  1114                              <1> 	;shl     bx, 3
  1115                              <1> 		; asl r2 / multiply by 8
  1116                              <1>        		; asl r2 / to get index into fsp table
  1117                              <1>        		; asl r2
  1118 00008400 FE83[92B50000]      <1>   	inc     byte [ebx+fsp-2]
  1119                              <1> 		; incb fsp-2(r2) / increment number of processes
  1120                              <1> 			     ; / using file, because child will now be
  1121                              <1> 			     ; / using this file
  1122                              <1> sysfork_5: ; 2:
  1123 00008406 46                  <1>         inc     esi
  1124                              <1> 		; inc r1 / get next open file
  1125 00008407 6683FE0A            <1>         cmp     si, 10
  1126                              <1> 		; cmp r1,$10. / 10. files is the maximum number which
  1127                              <1> 			  ; / can be opened
  1128 0000840B 72E2                <1> 	jb	short sysfork_4	
  1129                              <1> 		; blt 1b / check next entry
  1130 0000840D E9CFFCFFFF          <1> 	jmp	sysret
  1131                              <1> 		; br sysret1
  1132                              <1> 
  1133                              <1> sysread: ; < read from file >
  1134                              <1> 	; 13/05/2015
  1135                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  1136                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
  1137                              <1> 	;
  1138                              <1> 	; 'sysread' is given a buffer to read into and the number of
  1139                              <1> 	; characters to be read. If finds the file from the file
  1140                              <1> 	; descriptor located in *u.r0 (r0). This file descriptor
  1141                              <1> 	; is returned from a successful open call (sysopen).
  1142                              <1> 	; The i-number of file is obtained via 'rw1' and the data
  1143                              <1> 	; is read into core via 'readi'.
  1144                              <1> 	;
  1145                              <1> 	; Calling sequence:
  1146                              <1> 	;	sysread; buffer; nchars
  1147                              <1> 	; Arguments:
  1148                              <1> 	;	buffer - location of contiguous bytes where 
  1149                              <1> 	;		 input will be placed.
  1150                              <1> 	;	nchars - number of bytes or characters to be read.
  1151                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
  1152                              <1> 	; Outputs: *u.r0 - number of bytes read.	
  1153                              <1> 	; ...............................................................
  1154                              <1> 	;				
  1155                              <1> 	; Retro UNIX 8086 v1 modification: 
  1156                              <1> 	;       'sysread' system call has three arguments; so,
  1157                              <1> 	;	* 1st argument, file descriptor is in BX register
  1158                              <1> 	;	* 2nd argument, buffer address/offset in CX register
  1159                              <1> 	;	* 3rd argument, number of bytes is in DX register
  1160                              <1> 	;
  1161                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1162                              <1> 	;	to the user with number of bytes read. 
  1163                              <1> 	;
  1164 00008412 E83D000000          <1> 	call	rw1
  1165 00008417 0F82A4FCFFFF        <1> 	jc	error ; 13/05/2015, ax < 1
  1166                              <1> 		; jsr r0,rw1 / get i-number of file to be read into r1
  1167 0000841D F6C480              <1> 	test	ah, 80h
  1168                              <1> 		; tst r1 / negative i-number?
  1169 00008420 0F859BFCFFFF        <1> 	jnz	error
  1170                              <1> 		; ble error1 / yes, error 1 to read
  1171                              <1> 			   ; / it should be positive
  1172 00008426 E8F3110000          <1> 	call	readi
  1173                              <1> 		; jsr r0,readi / read data into core
  1174 0000842B EB18                <1> 	jmp	short rw0
  1175                              <1> 		; br 1f
  1176                              <1> syswrite: ; < write to file >
  1177                              <1> 	; 13/05/2015
  1178                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  1179                              <1> 	; 23/05/2013 (Retro UNIX 8086 v1)
  1180                              <1> 	;
  1181                              <1> 	; 'syswrite' is given a buffer to write onto an output file
  1182                              <1> 	; and the number of characters to write. If finds the file
  1183                              <1> 	; from the file descriptor located in *u.r0 (r0). This file 
  1184                              <1> 	; descriptor is returned from a successful open or create call
  1185                              <1> 	; (sysopen or syscreat). The i-number of file is obtained via
  1186                              <1> 	; 'rw1' and buffer is written on the output file via 'write'.
  1187                              <1> 	;
  1188                              <1> 	; Calling sequence:
  1189                              <1> 	;	syswrite; buffer; nchars
  1190                              <1> 	; Arguments:
  1191                              <1> 	;	buffer - location of contiguous bytes to be writtten.
  1192                              <1> 	;	nchars - number of characters to be written.
  1193                              <1> 	; Inputs: *u.r0 - file descriptor (& arguments)
  1194                              <1> 	; Outputs: *u.r0 - number of bytes written.	
  1195                              <1> 	; ...............................................................
  1196                              <1> 	;				
  1197                              <1> 	; Retro UNIX 8086 v1 modification: 
  1198                              <1> 	;       'syswrite' system call has three arguments; so,
  1199                              <1> 	;	* 1st argument, file descriptor is in BX register
  1200                              <1> 	;	* 2nd argument, buffer address/offset in CX register
  1201                              <1> 	;	* 3rd argument, number of bytes is in DX register
  1202                              <1> 	;
  1203                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1204                              <1> 	;	to the user with number of bytes written. 
  1205                              <1> 	;
  1206 0000842D E822000000          <1> 	call	rw1
  1207 00008432 0F8289FCFFFF        <1> 	jc	error ; 13/05/2015, ax < 1
  1208                              <1> 		; jsr r0,rw1 / get i-number in r1 of file to write
  1209 00008438 F6C480              <1>         test	ah, 80h
  1210                              <1> 		; tst r1 / positive i-number ?
  1211 0000843B 744E                <1>         jz	short rw3 ; 13/05/2015
  1212                              <1> 	;jz	error
  1213                              <1> 		; bge error1 / yes, error 1 
  1214                              <1> 			   ; / negative i-number means write
  1215 0000843D 66F7D8              <1>         neg	ax
  1216                              <1> 		; neg r1 / make it positive
  1217 00008440 E8D8110000          <1> 	call	writei
  1218                              <1>         	; jsr r0,writei / write data
  1219                              <1> rw0: ; 1:
  1220 00008445 A1[E8B70000]        <1>         mov	eax, [u.nread]
  1221 0000844A A3[C0B70000]        <1> 	mov	[u.r0], eax
  1222                              <1> 		; mov u.nread,*u.r0 / put no. of bytes transferred
  1223                              <1> 				  ; / into (u.r0)
  1224 0000844F E98DFCFFFF          <1> 	jmp	sysret
  1225                              <1>         	; br sysret1
  1226                              <1> rw1:	
  1227                              <1> 	; 14/05/2015
  1228                              <1> 	; 13/05/2015
  1229                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  1230                              <1> 	; 23/05/2013 - 24/05/2013 (Retro UNIX 8086 v1)
  1231                              <1> 	; System call registers: bx, cx, dx (through 'sysenter')
  1232                              <1> 	;
  1233                              <1> 	;mov	[u.base], ecx 	; buffer address/offset 
  1234                              <1> 				;(in the user's virtual memory space)
  1235                              <1> 	;mov	[u.count], edx 
  1236                              <1> 		; jsr r0,arg; u.base / get buffer pointer
  1237                              <1>         	; jsr r0,arg; u.count / get no. of characters
  1238                              <1> 	;;mov	eax, ebx ; file descriptor
  1239                              <1> 		; mov *u.r0,r1 / put file descriptor 
  1240                              <1> 		             ; / (index to u.fp table) in r1
  1241                              <1> 	; 13/05/2015
  1242 00008454 C705[C0B70000]0000- <1> 	mov	dword [u.r0], 0 ; r/w transfer count = 0 (reset)
  1242 0000845C 0000                <1>
  1243                              <1> 	;
  1244                              <1> 	;; call	getf
  1245                              <1>         ; eBX = File descriptor
  1246 0000845E E8E30A0000          <1> 	call	getf1 ; calling point in 'getf' from 'rw1'
  1247                              <1> 		; jsr r0,getf / get i-number of the file in r1
  1248                              <1> 	; AX = I-number of the file ; negative i-number means write
  1249                              <1> 	; 13/05/2015
  1250 00008463 6683F801            <1> 	cmp 	ax, 1
  1251 00008467 7217                <1> 	jb	short rw2
  1252                              <1> 	;
  1253 00008469 890D[E0B70000]      <1> 	mov	[u.base], ecx 	; buffer address/offset 
  1254                              <1> 				;(in the user's virtual memory space)
  1255 0000846F 8915[E4B70000]      <1> 	mov	[u.count], edx 
  1256                              <1> 	; 14/05/2015
  1257 00008475 C705[15B80000]0000- <1>         mov     dword [u.error], 0 ; reset the last error code
  1257 0000847D 0000                <1>
  1258 0000847F C3                  <1> 	retn
  1259                              <1>         	; rts r0
  1260                              <1> rw2:
  1261                              <1> 	; 13/05/2015
  1262 00008480 C705[15B80000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
  1262 00008488 0000                <1>
  1263 0000848A C3                  <1> 	retn
  1264                              <1> rw3: 
  1265                              <1> 	; 13/05/2015
  1266 0000848B C705[15B80000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  1266 00008493 0000                <1>
  1267 00008495 F9                  <1> 	stc
  1268 00008496 C3                  <1> 	retn
  1269                              <1> 
  1270                              <1> sysopen: ;<open file>
  1271                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1272                              <1> 	; 22/05/2013 - 27/05/2013 (Retro UNIX 8086 v1)
  1273                              <1> 	;
  1274                              <1> 	; 'sysopen' opens a file in following manner:
  1275                              <1> 	;    1) The second argument in a sysopen says whether to
  1276                              <1> 	;	open the file ro read (0) or write (>0).
  1277                              <1> 	;    2) I-node of the particular file is obtained via 'namei'.
  1278                              <1> 	;    3) The file is opened by 'iopen'.
  1279                              <1> 	;    4) Next housekeeping is performed on the fsp table
  1280                              <1> 	;	and the user's open file list - u.fp.
  1281                              <1> 	;	a) u.fp and fsp are scanned for the next available slot.
  1282                              <1> 	;	b) An entry for the file is created in the fsp table.
  1283                              <1> 	;	c) The number of this entry is put on u.fp list.
  1284                              <1> 	;	d) The file descriptor index to u.fp list is pointed
  1285                              <1> 	;	   to by u.r0.
  1286                              <1> 	;
  1287                              <1> 	; Calling sequence:
  1288                              <1> 	;	sysopen; name; mode
  1289                              <1> 	; Arguments:
  1290                              <1> 	;	name - file name or path name
  1291                              <1> 	;	mode - 0 to open for reading
  1292                              <1> 	;	       1 to open for writing
  1293                              <1> 	; Inputs: (arguments)
  1294                              <1> 	; Outputs: *u.r0 - index to u.fp list (the file descriptor)
  1295                              <1> 	;		  is put into r0's location on the stack.	
  1296                              <1> 	; ...............................................................
  1297                              <1> 	;				
  1298                              <1> 	; Retro UNIX 8086 v1 modification: 
  1299                              <1> 	;       'sysopen' system call has two arguments; so,
  1300                              <1> 	;	* 1st argument, name is pointed to by BX register
  1301                              <1> 	;	* 2nd argument, mode is in CX register
  1302                              <1> 	;
  1303                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1304                              <1> 	;	to the user with the file descriptor/number 
  1305                              <1> 	;	(index to u.fp list).
  1306                              <1> 	;
  1307                              <1> 	;call	arg2
  1308                              <1> 	; * name - 'u.namep' points to address of file/path name
  1309                              <1> 	;          in the user's program segment ('u.segmnt')
  1310                              <1> 	;          with offset in BX register (as sysopen argument 1).
  1311                              <1> 	; * mode - sysopen argument 2 is in CX register 
  1312                              <1> 	;          which is on top of stack.
  1313                              <1> 	;
  1314                              <1> 	; jsr r0,arg2 / get sys args into u.namep and on stack
  1315                              <1> 	;
  1316                              <1>        	; system call registers: ebx, ecx (through 'sysenter')
  1317                              <1> 
  1318 00008497 891D[D8B70000]      <1> 	mov	[u.namep], ebx
  1319 0000849D 6651                <1> 	push	cx
  1320 0000849F E8D90A0000          <1> 	call	namei
  1321                              <1> 		; jsr r0,namei / i-number of file in r1
  1322                              <1>      	;and	ax, ax
  1323                              <1> 	;jz	error ; File not found
  1324 000084A4 723B                <1> 	jc	short fnotfound ; 14/05/2015
  1325                              <1> 	;jc	error ; 27/05/2013
  1326                              <1> 		; br  error2 / file not found
  1327 000084A6 665A                <1>    	pop	dx ; mode
  1328 000084A8 6652                <1> 	push	dx
  1329                              <1> 	;or	dx, dx
  1330 000084AA 08D2                <1> 	or	dl, dl
  1331                              <1> 		; tst (sp) / is mode = 0 (2nd arg of call; 
  1332                              <1> 		         ; / 0 means, open for read)
  1333 000084AC 7403                <1> 	jz	short sysopen_0
  1334                              <1> 		; beq 1f / yes, leave i-number positive
  1335                              <1> syscreat_0: ; 27/12/2015
  1336 000084AE 66F7D8              <1> 	neg	ax
  1337                              <1>         	; neg r1 / open for writing so make i-number negative
  1338                              <1> sysopen_0: ;1:
  1339 000084B1 E86D110000          <1> 	call	iopen
  1340                              <1> 		;jsr r0,iopen / open file whose i-number is in r1
  1341 000084B6 665A                <1> 	pop	dx
  1342                              <1> 	;and	dx, dx
  1343 000084B8 20D2                <1> 	and	dl, dl
  1344                              <1>         	; tst (sp)+ / pop the stack and test the mode
  1345 000084BA 7403                <1> 	jz	short sysopen_2
  1346                              <1>         	; beq op1 / is open for read op1
  1347                              <1> sysopen_1: ;op0:
  1348 000084BC 66F7D8              <1> 	neg	ax
  1349                              <1>         	; neg r1 
  1350                              <1> 		     ;/ make i-number positive if open for writing [???]
  1351                              <1> 	;; NOTE: iopen always make i-number positive.
  1352                              <1> 	;; Here i-number becomes negative again. [22/05/2013]
  1353                              <1> sysopen_2: ;op1:
  1354 000084BF 31F6                <1>         xor     esi, esi
  1355                              <1>         	; clr r2 / clear registers
  1356 000084C1 31DB                <1>         xor     ebx, ebx
  1357                              <1> 		; clr r3
  1358                              <1> sysopen_3: ;1: / scan the list of entries in fsp table
  1359 000084C3 389E[C6B70000]      <1>         cmp     [esi+u.fp], bl ; 0
  1360                              <1> 		; tstb u.fp(r2) / test the entry in the u.fp list
  1361 000084C9 7625                <1>         jna      short sysopen_4
  1362                              <1> 		; beq 1f / if byte in list is 0 branch
  1363 000084CB 46                  <1>         inc     esi
  1364                              <1> 		; inc r2 / bump r2 so next byte can be checked
  1365 000084CC 6683FE0A            <1>         cmp     si, 10
  1366                              <1> 		; cmp r2,$10. / reached end of list?
  1367 000084D0 72F1                <1> 	jb	short sysopen_3
  1368                              <1> 		; blt 1b / no, go back
  1369                              <1> toomanyf:
  1370                              <1> 	; 14/05/2015
  1371 000084D2 C705[15B80000]0D00- <1> 	mov	dword [u.error], ERR_TOO_MANY_FILES ; too many open files !
  1371 000084DA 0000                <1>
  1372 000084DC E9E0FBFFFF          <1> 	jmp	error
  1373                              <1>         	; br error2 / yes, error (no files open)
  1374                              <1> fnotfound: 
  1375                              <1> 	; 14/05/2015
  1376 000084E1 C705[15B80000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; file not found !
  1376 000084E9 0000                <1>
  1377 000084EB E9D1FBFFFF          <1> 	jmp	error
  1378                              <1> 
  1379                              <1> sysopen_4: ; 1:
  1380 000084F0 6683BB[94B50000]00  <1>         cmp     word [ebx+fsp], 0
  1381                              <1> 		; tst fsp(r3) / scan fsp entries
  1382 000084F8 7610                <1>         jna     short sysopen_5
  1383                              <1> 		; beq 1f / if 0 branch
  1384                              <1> 	; 14/05/2015 - Retro UNIX 386 v1 modification !
  1385 000084FA 6683C30A            <1>         add     bx, 10 ; fsp structure size = 10 bytes/entry
  1386                              <1> 		; add $8.,r3 / add 8 to r3 
  1387                              <1> 			; / to bump it to next entry mfsp table
  1388 000084FE 6681FBF401          <1>         cmp     bx, nfiles*10
  1389                              <1> 		; cmp r3,$[nfiles*8.] / done scanning
  1390 00008503 72EB                <1> 	jb	short sysopen_4
  1391                              <1>        		; blt 1b / no, back
  1392 00008505 E9B7FBFFFF          <1> 	jmp	error
  1393                              <1>         	; br error2 / yes, error
  1394                              <1> sysopen_5: ; 1: / r2 has index to u.fp list; r3, has index to fsp table
  1395 0000850A 668983[94B50000]    <1>         mov     [ebx+fsp], ax
  1396                              <1> 		; mov r1,fsp(r3) / put i-number of open file 
  1397                              <1> 			; / into next available entry in fsp table,
  1398 00008511 668B3D[A4B70000]    <1> 	mov	di, [cdev] ; word ? byte ?
  1399 00008518 6689BB[96B50000]    <1>         mov     [ebx+fsp+2], di ; device number
  1400                              <1> 		; mov cdev,fsp+2(r3) / put # of device in next word
  1401 0000851F 31FF                <1>         xor	edi, edi
  1402 00008521 89BB[98B50000]      <1>         mov     [ebx+fsp+4], edi ; offset pointer (0)
  1403                              <1> 		; clr fsp+4(r3)
  1404 00008527 6689BB[9CB50000]    <1>         mov     [ebx+fsp+8], di ; open count (0), deleted flag (0)
  1405                              <1>        		; clr fsp+6(r3) / clear the next two words
  1406 0000852E 89D8                <1>   	mov	eax, ebx
  1407 00008530 B30A                <1> 	mov	bl, 10
  1408 00008532 F6F3                <1> 	div	bl 
  1409                              <1> 		; asr r3
  1410                              <1> 		; asr r3 / divide by 8 
  1411                              <1> 		; asr r3 ; / to get number of the fsp entry-1
  1412 00008534 FEC0                <1> 	inc	al
  1413                              <1>         	; inc r3 / add 1 to get fsp entry number
  1414 00008536 8886[C6B70000]      <1>         mov     [esi+u.fp], al
  1415                              <1> 		; movb r3,u.fp(r2) / move entry number into 
  1416                              <1> 			; / next available slot in u.fp list
  1417 0000853C 8935[C0B70000]      <1>         mov     [u.r0], esi
  1418                              <1> 		; mov r2,*u.r0 / move index to u.fp list 
  1419                              <1> 			     ; / into r0 loc on stack
  1420 00008542 E99AFBFFFF          <1>         jmp	sysret
  1421                              <1> 		; br sysret2
  1422                              <1> 
  1423                              <1> 	;
  1424                              <1> 	; 'fsp' table (10 bytes/entry)
  1425                              <1> 	; bit 15				   bit 0
  1426                              <1> 	; ---|-------------------------------------------
  1427                              <1> 	; r/w|		i-number of open file
  1428                              <1> 	; ---|-------------------------------------------
  1429                              <1> 	;		   device number
  1430                              <1> 	; -----------------------------------------------
  1431                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
  1432                              <1> 	; -----------------------------------------------
  1433                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
  1434                              <1> 	; ----------------------|------------------------
  1435                              <1> 	;  flag that says file 	| number of processes
  1436                              <1> 	;   has been deleted	| that have file open 
  1437                              <1> 	; ----------------------|------------------------
  1438                              <1> 	;
  1439                              <1> 
  1440                              <1> syscreat: ; < create file >
  1441                              <1> 	; 27/12/2015 (Retro UNIX 386 v1.1)
  1442                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1443                              <1> 	; 27/05/2013 (Retro UNIX 8086 v1)
  1444                              <1> 	;
  1445                              <1> 	; 'syscreat' called with two arguments; name and mode.
  1446                              <1> 	; u.namep points to name of the file and mode is put
  1447                              <1> 	; on the stack. 'namei' is called to get i-number of the file.		
  1448                              <1> 	; If the file aready exists, it's mode and owner remain 
  1449                              <1> 	; unchanged, but it is truncated to zero length. If the file
  1450                              <1> 	; did not exist, an i-node is created with the new mode via
  1451                              <1> 	; 'maknod' whether or not the file already existed, it is
  1452                              <1> 	; open for writing. The fsp table is then searched for a free
  1453                              <1> 	; entry. When a free entry is found, proper data is placed
  1454                              <1> 	; in it and the number of this entry is put in the u.fp list.
  1455                              <1> 	; The index to the u.fp (also know as the file descriptor)
  1456                              <1> 	; is put in the user's r0. 			
  1457                              <1> 	;
  1458                              <1> 	; Calling sequence:
  1459                              <1> 	;	syscreate; name; mode
  1460                              <1> 	; Arguments:
  1461                              <1> 	;	name - name of the file to be created
  1462                              <1> 	;	mode - mode of the file to be created
  1463                              <1> 	; Inputs: (arguments)
  1464                              <1> 	; Outputs: *u.r0 - index to u.fp list 
  1465                              <1> 	;		   (the file descriptor of new file)
  1466                              <1> 	; ...............................................................
  1467                              <1> 	;				
  1468                              <1> 	; Retro UNIX 8086 v1 modification: 
  1469                              <1> 	;       'syscreate' system call has two arguments; so,
  1470                              <1> 	;	* 1st argument, name is pointed to by BX register
  1471                              <1> 	;	* 2nd argument, mode is in CX register
  1472                              <1> 	;
  1473                              <1> 	;	AX register (will be restored via 'u.r0') will return
  1474                              <1> 	;	to the user with the file descriptor/number 
  1475                              <1> 	;	(index to u.fp list).
  1476                              <1> 	;
  1477                              <1> 	;call	arg2
  1478                              <1> 	; * name - 'u.namep' points to address of file/path name
  1479                              <1> 	;          in the user's program segment ('u.segmnt')
  1480                              <1> 	;          with offset in BX register (as sysopen argument 1).
  1481                              <1> 	; * mode - sysopen argument 2 is in CX register 
  1482                              <1> 	;          which is on top of stack.
  1483                              <1> 	;
  1484                              <1>         	; jsr r0,arg2 / put file name in u.namep put mode 
  1485                              <1> 			    ; / on stack
  1486 00008547 891D[D8B70000]      <1> 	mov	[u.namep], ebx ; file name address
  1487 0000854D 6651                <1> 	push	cx ; mode
  1488 0000854F E8290A0000          <1> 	call 	namei        	
  1489                              <1> 		; jsr r0,namei / get the i-number
  1490                              <1>         ;and	ax, ax
  1491                              <1> 	;jz	short syscreat_1	       	
  1492 00008554 721E                <1> 	jc	short syscreat_1
  1493                              <1> 		; br  2f / if file doesn't exist 2f
  1494                              <1> 	; 27/12/2015
  1495 00008556 6683F829            <1> 	cmp	ax, 41 ; device inode ?
  1496 0000855A 0F824EFFFFFF        <1>         jb      syscreat_0 ; yes
  1497                              <1> 	;
  1498 00008560 66F7D8              <1> 	neg 	ax
  1499                              <1>         	; neg r1 / if file already exists make i-number 
  1500                              <1> 		       ; / negative (open for writing)
  1501 00008563 E8BB100000          <1> 	call	iopen
  1502                              <1>         	; jsr r0,iopen /
  1503 00008568 E8B8100000          <1> 	call	itrunc
  1504                              <1>         	; jsr r0,itrunc / truncate to 0 length
  1505 0000856D 6659                <1> 	pop	cx ; pop mode (did not exist in original Unix v1 !?)
  1506 0000856F E948FFFFFF          <1>         jmp     sysopen_1
  1507                              <1>         	; br op0
  1508                              <1> syscreat_1: ; 2: / file doesn't exist
  1509 00008574 6658                <1> 	pop	ax
  1510                              <1>         	; mov (sp)+,r1 / put the mode in r1
  1511 00008576 30E4                <1> 	xor	ah, ah	
  1512                              <1>         	; bic $!377,r1 / clear upper byte
  1513 00008578 E8D30C0000          <1> 	call 	maknod
  1514                              <1>         	; jsr r0,maknod / make an i-node for this file
  1515 0000857D 66A1[F2B70000]      <1> 	mov	ax, [u.dirbuf]
  1516                              <1>         	; mov u.dirbuf,r1 / put i-number 
  1517                              <1> 			        ; / for this new file in r1
  1518 00008583 E934FFFFFF          <1>         jmp     sysopen_1
  1519                              <1>         	; br op0 / open the file
  1520                              <1> 
  1521                              <1> sysmkdir: ; < make directory >
  1522                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1523                              <1> 	; 27/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  1524                              <1> 	;
  1525                              <1> 	; 'sysmkdir' creates an empty directory whose name is
  1526                              <1> 	; pointed to by arg 1. The mode of the directory is arg 2.	
  1527                              <1> 	; The special entries '.' and '..' are not present.
  1528                              <1> 	; Errors are indicated if the directory already exists or		
  1529                              <1> 	; user is not the super user. 
  1530                              <1> 	;
  1531                              <1> 	; Calling sequence:
  1532                              <1> 	;	sysmkdir; name; mode
  1533                              <1> 	; Arguments:
  1534                              <1> 	;	name - points to the name of the directory
  1535                              <1> 	;	mode - mode of the directory
  1536                              <1> 	; Inputs: (arguments)
  1537                              <1> 	; Outputs: -
  1538                              <1> 	;    (sets 'directory' flag to 1; 
  1539                              <1> 	;    'set user id on execution' and 'executable' flags to 0)
  1540                              <1> 	; ...............................................................
  1541                              <1> 	;				
  1542                              <1> 	; Retro UNIX 8086 v1 modification: 
  1543                              <1> 	;       'sysmkdir' system call has two arguments; so,
  1544                              <1> 	;	* 1st argument, name is pointed to by BX register
  1545                              <1> 	;	* 2nd argument, mode is in CX register
  1546                              <1> 	;
  1547                              <1> 		
  1548                              <1> ; / make a directory
  1549                              <1> 
  1550                              <1> 	;call	arg2
  1551                              <1> 	; * name - 'u.namep' points to address of file/path name
  1552                              <1> 	;          in the user's program segment ('u.segmnt')
  1553                              <1> 	;          with offset in BX register (as sysopen argument 1).
  1554                              <1> 	; * mode - sysopen argument 2 is in CX register 
  1555                              <1> 	;          which is on top of stack.
  1556                              <1> 
  1557                              <1> 		; jsr r0,arg2 / put file name in u.namep put mode 
  1558                              <1> 			    ; / on stack
  1559 00008588 891D[D8B70000]      <1> 	mov	[u.namep], ebx
  1560 0000858E 6651                <1> 	push	cx ; mode
  1561 00008590 E8E8090000          <1> 	call	namei
  1562                              <1>         	; jsr r0,namei / get the i-number
  1563                              <1>         	;     br .+4 / if file not found branch around error
  1564                              <1>         ;xor 	ax, ax
  1565                              <1> 	;jnz	error
  1566 00008595 731C                <1> 	jnc	short dir_exists ; 14/05/2015
  1567                              <1> 	;jnc	error	
  1568                              <1> 		; br  error2 / directory already exists (error)
  1569 00008597 803D[0CB80000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
  1570                              <1>         	;tstb u.uid / is user the super user
  1571 0000859E 7622                <1> 	jna	short dir_access_err ; 14/05/2015
  1572                              <1> 	;jna	error
  1573                              <1>         	;bne error2 / no, not allowed
  1574 000085A0 6658                <1> 	pop	ax
  1575                              <1>         	;mov (sp)+,r1 / put the mode in r1
  1576 000085A2 6683E0CF            <1> 	and	ax, 0FFCFh ; 1111111111001111b
  1577                              <1>         	;bic $!317,r1 / all but su and ex
  1578                              <1> 	;or	ax , 4000h ; 1011111111111111b
  1579 000085A6 80CC40              <1> 	or	ah, 40h ; Set bit 14 to 1
  1580                              <1>         	;bis $40000,r1 / directory flag
  1581 000085A9 E8A20C0000          <1> 	call	maknod
  1582                              <1>         	;jsr r0,maknod / make the i-node for the directory
  1583 000085AE E92EFBFFFF          <1> 	jmp	sysret
  1584                              <1>         	;br sysret2 /
  1585                              <1> dir_exists:
  1586                              <1> 	; 14/05/2015
  1587 000085B3 C705[15B80000]0E00- <1> 	mov	dword [u.error], ERR_DIR_EXISTS ; dir. already exists !
  1587 000085BB 0000                <1>
  1588 000085BD E9FFFAFFFF          <1> 	jmp	error
  1589                              <1> dir_access_err:
  1590                              <1> 	; 14/05/2015
  1591 000085C2 C705[15B80000]0B00- <1> 	mov	dword [u.error], ERR_DIR_ACCESS ; permission denied !
  1591 000085CA 0000                <1>
  1592 000085CC E9F0FAFFFF          <1> 	jmp	error
  1593                              <1> 
  1594                              <1> sysclose: ;<close file>
  1595                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1596                              <1> 	; 22/05/2013 - 26/05/2013 (Retro UNIX 8086 v1)
  1597                              <1> 	;
  1598                              <1> 	; 'sysclose', given a file descriptor in 'u.r0', closes the
  1599                              <1> 	; associated file. The file descriptor (index to 'u.fp' list)
  1600                              <1> 	; is put in r1 and 'fclose' is called.
  1601                              <1> 	;
  1602                              <1> 	; Calling sequence:
  1603                              <1> 	;	sysclose
  1604                              <1> 	; Arguments:
  1605                              <1> 	;	-  
  1606                              <1> 	; Inputs: *u.r0 - file descriptor
  1607                              <1> 	; Outputs: -
  1608                              <1> 	; ...............................................................
  1609                              <1> 	;				
  1610                              <1> 	; Retro UNIX 8086 v1 modification:
  1611                              <1> 	;	 The user/application program puts file descriptor
  1612                              <1> 	;        in BX register as 'sysclose' system call argument.
  1613                              <1> 	; 	 (argument transfer method 1)
  1614                              <1> 
  1615                              <1> 	; / close the file
  1616                              <1> 	
  1617 000085D1 89D8                <1> 	mov 	eax, ebx
  1618 000085D3 E823090000          <1> 	call 	fclose
  1619                              <1> 		; mov *u.r0,r1 / move index to u.fp list into r1
  1620                              <1> 		; jsr r0,fclose / close the file
  1621                              <1>                	; br error2 / unknown file descriptor
  1622                              <1> 		; br sysret2
  1623                              <1> 	; 14/05/2015
  1624 000085D8 0F8303FBFFFF        <1> 	jnc	sysret
  1625 000085DE C705[15B80000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN ; file not open !
  1625 000085E6 0000                <1>
  1626 000085E8 E9D4FAFFFF          <1> 	jmp	error
  1627                              <1> 
  1628                              <1> sysemt:
  1629                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1630                              <1> 	; 10/12/2013 - 20/04/2014 (Retro UNIX 8086 v1)
  1631                              <1> 	;
  1632                              <1> 	; Retro UNIX 8086 v1 modification: 
  1633                              <1> 	;	'Enable Multi Tasking'  system call instead 
  1634                              <1> 	;	of 'Emulator Trap' in original UNIX v1 for PDP-11.
  1635                              <1> 	;
  1636                              <1> 	; Retro UNIX 8086 v1 feature only!
  1637                              <1> 	;	Using purpose: Kernel will start without time-out
  1638                              <1> 	;	(internal clock/timer) functionality.
  1639                              <1> 	;	Then etc/init will enable clock/timer for
  1640                              <1> 	;	multi tasking. (Then it will not be disabled again
  1641                              <1> 	;	except hardware reset/restart.)
  1642                              <1> 	;
  1643                              <1> 
  1644 000085ED 803D[0CB80000]00    <1> 	cmp	byte [u.uid], 0 ; root ?
  1645                              <1> 	;ja	error
  1646 000085F4 0F8770FBFFFF        <1> 	ja	badsys ; 14/05/2015
  1647                              <1> emt_0:
  1648 000085FA FA                  <1> 	cli
  1649 000085FB 21DB                <1> 	and	ebx, ebx
  1650 000085FD 7410                <1> 	jz	short emt_2
  1651                              <1> 	; Enable multi tasking -time sharing-
  1652 000085FF B8[26960000]        <1> 	mov	eax, clock
  1653                              <1> emt_1:
  1654 00008604 A3[C2070000]        <1> 	mov	[x_timer], eax
  1655 00008609 FB                  <1> 	sti
  1656 0000860A E9D2FAFFFF          <1> 	jmp	sysret
  1657                              <1> emt_2:
  1658                              <1> 	; Disable multi tasking -time sharing-
  1659 0000860F B8[CA070000]        <1> 	mov	eax, u_timer
  1660 00008614 EBEE                <1> 	jmp	short emt_1
  1661                              <1> 
  1662                              <1> 	; Original UNIX v1 'sysemt' routine
  1663                              <1> ;sysemt:
  1664                              <1>         ;
  1665                              <1> 	;jsr    r0,arg; 30 / put the argument of the sysemt call 
  1666                              <1> 			 ; / in loc 30
  1667                              <1>         ;cmp    30,$core / was the argument a lower address 
  1668                              <1> 			; / than core
  1669                              <1>         ;blo    1f / yes, rtssym
  1670                              <1>         ;cmp    30,$ecore / no, was it higher than "core" 
  1671                              <1> 			; / and less than "ecore"
  1672                              <1>         ;blo    2f / yes, sysret2
  1673                              <1> ;1:
  1674                              <1>         ;mov    $rtssym,30
  1675                              <1> ;2:
  1676                              <1>         ;br     sysret2
  1677                              <1> 
  1678                              <1> sysilgins:
  1679                              <1> 	; 14/05/2015 (Retro UNIX 386 v1 - Beginning)
  1680                              <1> 	; 03/06/2013
  1681                              <1> 	; Retro UNIX 8086 v1 modification: 
  1682                              <1> 	;	not a valid system call ! (not in use)
  1683                              <1> 	;
  1684 00008616 E94FFBFFFF          <1> 	jmp	badsys
  1685                              <1> 	;jmp	error
  1686                              <1> 	;;jmp 	sysret
  1687                              <1> 
  1688                              <1> 	; Original UNIX v1 'sysemt' routine
  1689                              <1> ;sysilgins: / calculate proper illegal instruction trap address
  1690                              <1>         ;jsr    r0,arg; 10 / take address from sysilgins call
  1691                              <1> 			  ;/ put it in loc 8.,
  1692                              <1>         ;cmp    10,$core / making it the illegal instruction 
  1693                              <1> 		       ; / trap address
  1694                              <1>         ;blo    1f / is the address a user core address?  
  1695                              <1> 		; / yes, go to 2f
  1696                              <1>         ;cmp    10,$ecore
  1697                              <1>         ;blo    2f
  1698                              <1> ;1:
  1699                              <1>         ;mov    $fpsym,10 / no, make 'fpsum' the illegal 
  1700                              <1> 		    ; / instruction trap address for the system
  1701                              <1> ;2:
  1702                              <1>         ;br     sysret2 / return to the caller via 'sysret'
  1703                              <1> 
  1704                              <1> sysmdate: ; < change the modification time of a file >
  1705                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
  1706                              <1> 	; 03/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  1707                              <1> 	;
  1708                              <1> 	; 'sysmdate' is given a file name. It gets inode of this 
  1709                              <1> 	; file into core. The user is checked if he is the owner 
  1710                              <1> 	; or super user. If he is neither an error occurs.
  1711                              <1> 	; 'setimod' is then called to set the i-node modification
  1712                              <1> 	; byte and the modification time, but the modification time
  1713                              <1> 	; is overwritten by whatever get put on the stack during
  1714                              <1> 	; a 'systime' system call. This calls are restricted to
  1715                              <1> 	; the super user.		
  1716                              <1> 	;
  1717                              <1> 	; Calling sequence:
  1718                              <1> 	;	sysmdate; name
  1719                              <1> 	; Arguments:
  1720                              <1> 	;	name - points to the name of file
  1721                              <1> 	; Inputs: (arguments)
  1722                              <1> 	; Outputs: -
  1723                              <1> 	; ...............................................................
  1724                              <1> 	;				
  1725                              <1> 	; Retro UNIX 8086 v1 modification: 
  1726                              <1> 	;	 The user/application program puts address 
  1727                              <1> 	;	 of the file name in BX register 
  1728                              <1> 	;	 as 'sysmdate' system call argument.
  1729                              <1> 	;
  1730                              <1> ; / change the modification time of a file
  1731                              <1> 		; jsr r0,arg; u.namep / point u.namep to the file name
  1732 0000861B 891D[D8B70000]      <1>         mov	[u.namep], ebx
  1733 00008621 E857090000          <1> 	call	namei
  1734                              <1> 		; jsr r0,namei / get its i-number
  1735 00008626 0F82B5FEFFFF        <1>         jc	fnotfound ; file not found !
  1736                              <1> 	;jc	error       
  1737                              <1> 		; br error2 / no, such file
  1738 0000862C E8E80F0000          <1> 	call	iget
  1739                              <1> 		; jsr r0,iget / get i-node into core
  1740 00008631 A0[0CB80000]        <1> 	mov	al, [u.uid]
  1741 00008636 3A05[97B40000]      <1> 	cmp	al, [i.uid]
  1742                              <1>         	; cmpb u.uid,i.uid / is user same as owner
  1743 0000863C 7413                <1> 	je	short mdate_1
  1744                              <1>         	; beq 1f / yes
  1745 0000863E 20C0                <1> 	and	al, al
  1746                              <1> 		; tstb u.uid / no, is user the super user
  1747                              <1> 	;jnz	error
  1748                              <1> 		; bne error2 / no, error
  1749 00008640 740F                <1> 	jz	short mdate_1
  1750 00008642 C705[15B80000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  1750 0000864A 0000                <1>
  1751 0000864C E970FAFFFF          <1> 	jmp	error
  1752                              <1> mdate_1: ;1:
  1753 00008651 E8D10F0000          <1> 	call	setimod
  1754                              <1>         	; jsr r0,setimod / fill in modification data,
  1755                              <1> 		               ; / time etc.
  1756 00008656 BE[32A80000]        <1> 	mov	esi, p_time
  1757 0000865B BF[AEB40000]        <1> 	mov	edi, i.mtim
  1758 00008660 A5                  <1> 	movsd
  1759                              <1> 		; mov 4(sp),i.mtim / move present time to
  1760                              <1>         	; mov 2(sp),i.mtim+2 / modification time
  1761 00008661 E97BFAFFFF          <1>         jmp	sysret
  1762                              <1> 		; br sysret2
  1763                              <1> 
  1764                              <1> sysstty: ; < set tty status and mode >
  1765                              <1> 	; 17/11/2015
  1766                              <1> 	; 12/11/2015
  1767                              <1> 	; 29/10/2015
  1768                              <1> 	; 17/10/2015
  1769                              <1> 	; 13/10/2015
  1770                              <1> 	; 29/06/2015
  1771                              <1> 	; 27/06/2015 (Retro UNIX 386 v1 - Beginning)
  1772                              <1> 	; 02/06/2013 - 12/07/2014 (Retro UNIX 8086 v1)
  1773                              <1> 	;
  1774                              <1> 	; 'sysstty' sets the status and mode of the typewriter 
  1775                              <1> 	; whose file descriptor is in (u.r0).
  1776                              <1> 	;
  1777                              <1> 	; Calling sequence:
  1778                              <1> 	;	sysstty; arg
  1779                              <1> 	; Arguments:
  1780                              <1> 	;	arg - address of 3 consequitive words that contain
  1781                              <1> 	;	      the source of status data	
  1782                              <1> 	; Inputs: ((*u.r0 - file descriptor & argument))
  1783                              <1> 	; Outputs: ((status in address which is pointed to by arg))
  1784                              <1> 	; ...............................................................
  1785                              <1> 	;	
  1786                              <1> 	; Retro UNIX 8086 v1 modification: 
  1787                              <1> 	;	'sysstty' system call will set the tty
  1788                              <1> 	;	(clear keyboard buffer and set cursor position)
  1789                              <1> 	;	 in following manner:
  1790                              <1> 	;   NOTE: All of tty setting functions are here (16/01/2014)
  1791                              <1> 	;
  1792                              <1> 	; Inputs:
  1793                              <1> 	;	BX = 0 --> means
  1794                              <1> 	;	   If CL = FFh
  1795                              <1> 	;	      set cursor position for console tty, only 
  1796                              <1> 	;	      CH will be ignored (char. will not be written)	
  1797                              <1> 	;	   If CH = 0 (CL < FFh)
  1798                              <1> 	;	      set console tty for (current) process
  1799                              <1> 	;	      CL = tty number (0 to 9)
  1800                              <1> 	;	      (If CH = 0, character will not be written)			
  1801                              <1> 	;          If CH > 0 (CL < FFh)	
  1802                              <1> 	;             CL = tty number (0 to 9)
  1803                              <1> 	;	      CH = character will be written
  1804                              <1> 	;	        at requested cursor position (in DX)	
  1805                              <1> 	;	   DX = cursor position for tty number 0 to 7.	
  1806                              <1>   	;		(only tty number 0 to 7) 
  1807                              <1> 	;          DL = communication parameters (for serial ports) 
  1808                              <1> 	;	        (only for COM1 and COM2 serial ports)
  1809                              <1> 	;	   DH < 0FFh -> DL is valid, initialize serial port
  1810                              <1> 	;			or set cursor position	
  1811                              <1> 	;	   DH = 0FFh -> DL is not valid
  1812                              <1> 	;		do not set serial port parameters 
  1813                              <1> 	;		or do not set cursor position
  1814                              <1> 	;
  1815                              <1> 	;	BX > 0 --> points to name of tty
  1816                              <1> 	;    	   CH > 0 -->
  1817                              <1> 	;		CH = character will be written in current 
  1818                              <1> 	;            	cursor position (for tty number from 0 to 7)
  1819                              <1> 	;	     	or character will be sent to serial port
  1820                              <1> 	;	     	(for tty number 8 or 9)
  1821                              <1> 	;		CL = color of the character if tty number < 8.
  1822                              <1> 	;    	   CH = 0 --> Do not write a character, 
  1823                              <1> 	;		set mode (tty 8 to 9) or 
  1824                              <1> 	;		set current cursor positions (tty 0 to 7) only. 
  1825                              <1> 	;   	   DX = cursor position for tty number 0 to 7.
  1826                              <1> 	;    	   DH = FFh --> Do not set cursor pos (or comm. params.)
  1827                              <1> 	;		(DL is not valid)
  1828                              <1> 	;	   DL = communication parameters 
  1829                              <1> 	;		for tty number 8 or 9 (COM1 or COM2).
  1830                              <1> 	; Outputs:
  1831                              <1> 	;	cf = 0 -> OK
  1832                              <1> 	;	     AL = tty number (0 to 9)
  1833                              <1> 	;	     AH = line status if tty number is 8 or 9
  1834                              <1> 	;	     AH = process number (of the caller) 	
  1835                              <1> 	;	cf = 1 means error (requested tty is not ready)
  1836                              <1> 	;	     AH = FFh if the tty is locked 
  1837                              <1> 	;		  (owned by another process)
  1838                              <1> 	;	        = process number (of the caller) 
  1839                              <1> 	;		  (if < FFh and tty number < 8)
  1840                              <1> 	;	     AL = tty number (0FFh if it does not exist)
  1841                              <1> 	;	     AH = line status if tty number is 8 or 9
  1842                              <1> 	;	NOTE: Video page will be cleared if cf = 0.
  1843                              <1> 	;
  1844                              <1> 	; 27/06/2015 (32 bit modifications)
  1845                              <1> 	; 14/01/2014
  1846 00008666 31C0                <1> 	xor 	eax, eax
  1847 00008668 6648                <1> 	dec	ax ; 17/10/2015
  1848 0000866A A3[C0B70000]        <1> 	mov	[u.r0], eax ; 0FFFFh
  1849 0000866F 21DB                <1> 	and	ebx, ebx
  1850 00008671 0F85CB000000        <1>         jnz     sysstty_6
  1851                              <1> ; set console tty
  1852                              <1> 	; 29/10/2015
  1853                              <1> 	; 17/01/2014 
  1854 00008677 80F909              <1> 	cmp	cl, 9
  1855 0000867A 7613                <1> 	jna	short sysstty_0
  1856                              <1> 	; 17/11/2015
  1857 0000867C 80F9FF              <1> 	cmp	cl, 0FFh
  1858 0000867F 7202                <1> 	jb	short sysstty_13
  1859 00008681 88CD                <1> 	mov	ch, cl ; force CH value to FFh 
  1860                              <1> sysstty_13:
  1861 00008683 8A1D[0FB80000]      <1> 	mov	bl, [u.uno] ; process number
  1862 00008689 8A8B[13B50000]      <1> 	mov	cl, [ebx+p.ttyc-1] ; current/console tty
  1863                              <1> sysstty_0:
  1864                              <1> 	; 29/06/2015
  1865 0000868F 6652                <1> 	push	dx
  1866 00008691 6651                <1> 	push	cx
  1867 00008693 30D2                <1> 	xor 	dl, dl	; sysstty call sign
  1868 00008695 88C8                <1> 	mov	al, cl
  1869 00008697 A2[C0B70000]        <1> 	mov	[u.r0], al ; tyy number (0 to 9)
  1870 0000869C E8870F0000          <1> 	call	ottyp
  1871 000086A1 6659                <1> 	pop	cx
  1872 000086A3 665A                <1> 	pop	dx
  1873                              <1> 	;
  1874 000086A5 7257                <1> 	jc	short sysstty_pd_err
  1875                              <1> 	;
  1876 000086A7 80F908              <1> 	cmp	cl, 8
  1877 000086AA 7222                <1> 	jb	short sysstty_2
  1878                              <1> 	;
  1879 000086AC 80FEFF              <1> 	cmp	dh, 0FFh
  1880 000086AF 741D                <1> 	je	short sysstty_2
  1881                              <1> 		; set communication parameters for serial ports
  1882                              <1> 	; 29/10/2015
  1883 000086B1 88D4                <1> 	mov	ah, dl ; communication parameters
  1884                              <1> 		; ah = 0E3h = 11100011b = 115200 baud,
  1885                              <1> 		;			 THRE int + RDA int 
  1886                              <1> 		; ah = 23h = 00100011b = 9600 baud,
  1887                              <1> 		;			 THRE int + RDA int 
  1888 000086B3 28C0                <1> 	sub	al, al ; 0
  1889                              <1> 	; 12/07/2014
  1890 000086B5 80F909              <1> 	cmp	cl, 9
  1891 000086B8 7202                <1> 	jb	short sysstty_1
  1892 000086BA FEC0                <1> 	inc	al
  1893                              <1> sysstty_1:
  1894 000086BC 6651                <1> 	push	cx
  1895                              <1> 	; 29/06/2015	
  1896 000086BE E821120000          <1> 	call 	sp_setp ; Set serial port communication parameters
  1897 000086C3 66890D[C1B70000]    <1> 	mov	[u.r0+1], cx ; Line status (ah)
  1898                              <1> 			     ; Modem status (EAX bits 16 to 23)
  1899 000086CA 6659                <1> 	pop	cx
  1900 000086CC 7265                <1>         jc      short sysstty_tmout_err ; 29/10/2015
  1901                              <1> sysstty_2:
  1902                              <1> 	; 17/01/2014
  1903 000086CE 20ED                <1> 	and	ch, ch 	; set cursor position 
  1904                              <1> 			; or comm. parameters ONLY
  1905 000086D0 750D                <1> 	jnz	short sysstty_3
  1906 000086D2 0FB61D[0FB80000]    <1> 	movzx	ebx, byte [u.uno] ; process number
  1907 000086D9 888B[13B50000]      <1> 	mov	[ebx+p.ttyc-1], cl ; console tty
  1908                              <1> sysstty_3:
  1909                              <1> 	; 16/01/2014
  1910 000086DF 88E8                <1> 	mov	al, ch ; character  ; 0 to FFh
  1911                              <1> 	; 17/11/2015
  1912 000086E1 B507                <1> 	mov 	ch, 7  ; Default color (light gray)
  1913 000086E3 38E9                <1> 	cmp	cl, ch ; 7 (tty number)
  1914 000086E5 0F86C5000000        <1>         jna     sysstty_9
  1915                              <1> sysstty_12:
  1916                              <1> 	;; BX = 0, CL = 8 or CL = 9
  1917                              <1> 	; (Set specified serial port as console tty port)
  1918                              <1> 	; CH = character to be written
  1919                              <1> 	; 15/04/2014
  1920                              <1> 	; CH = 0 --> initialization only
  1921                              <1> 	; AL = character
  1922                              <1> 	; 26/06/2014
  1923 000086EB 880D[14B80000]      <1> 	mov	[u.ttyn], cl
  1924                              <1> 	; 12/07/2014
  1925 000086F1 88CC                <1> 	mov	ah, cl ; tty number (8 or 9)
  1926 000086F3 20C0                <1> 	and	al, al
  1927 000086F5 7416                <1> 	jz	short sysstty_4 ; al = ch = 0
  1928                              <1>  	; 04/07/2014
  1929 000086F7 E82E0F0000          <1> 	call 	sndc
  1930                              <1> 	; 12/07/2014
  1931 000086FC EB1B                <1> 	jmp	short sysstty_5
  1932                              <1> sysstty_pd_err: ; 29/06/2015
  1933                              <1> 	; 'permission denied !' error
  1934 000086FE C705[15B80000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER
  1934 00008706 0000                <1>
  1935 00008708 E9B4F9FFFF          <1> 	jmp	error
  1936                              <1> sysstty_4:
  1937                              <1> 	; 12/07/2014
  1938                              <1> 	;xchg 	ah, al	; al = 0 -> al = ah, ah = 0
  1939 0000870D 88E0                <1> 	mov	al, ah ; 29/06/2015
  1940 0000870F 2C08                <1> 	sub	al, 8
  1941                              <1> 	; 27/06/2015
  1942 00008711 E8C6110000          <1> 	call	sp_status ; get serial port status
  1943                              <1> 	; AL = Line status, AH = Modem status
  1944                              <1> 	; 12/11/2015
  1945 00008716 3C80                <1> 	cmp	al, 80h
  1946 00008718 F5                  <1> 	cmc
  1947                              <1> sysstty_5:
  1948 00008719 66A3[C1B70000]      <1> 	mov	[u.r0+1], ax ; ah = line status
  1949                              <1> 		     ; EAX bits 16-23 = modem status	
  1950 0000871F 9C                  <1> 	pushf
  1951 00008720 30D2                <1> 	xor	dl, dl ; sysstty call sign
  1952 00008722 A0[14B80000]        <1> 	mov	al, [u.ttyn] ; 26/06/2014
  1953 00008727 E8FD0E0000          <1> 	call	cttyp
  1954 0000872C 9D                  <1> 	popf
  1955 0000872D 0F83AEF9FFFF        <1> 	jnc	sysret	; time out error 
  1956                              <1> 
  1957                              <1> sysstty_tmout_err:
  1958 00008733 C705[15B80000]1900- <1> 	mov	dword [u.error], ERR_TIME_OUT
  1958 0000873B 0000                <1>
  1959 0000873D E97FF9FFFF          <1> 	jmp	error
  1960                              <1> sysstty_6:
  1961 00008742 6652                <1> 	push	dx
  1962 00008744 6651                <1> 	push	cx
  1963 00008746 891D[D8B70000]      <1> 	mov	[u.namep], ebx
  1964 0000874C E82C080000          <1> 	call	namei
  1965 00008751 6659                <1> 	pop	cx
  1966 00008753 665A                <1> 	pop	dx
  1967 00008755 720E                <1> 	jc	short sysstty_inv_dn
  1968                              <1> 	;
  1969 00008757 6683F813            <1> 	cmp	ax, 19  ; inode number of /dev/COM2
  1970 0000875B 7708                <1> 	ja	short sysstty_inv_dn ; 27/06/2015
  1971                              <1> 	;
  1972 0000875D 3C0A                <1> 	cmp	al, 10 ; /dev/tty0 .. /dev/tty7
  1973                              <1> 		       ; /dev/COM1, /dev/COM2
  1974 0000875F 7213                <1> 	jb	short sysstty_7
  1975 00008761 2C0A                <1> 	sub	al, 10
  1976 00008763 EB20                <1> 	jmp	short sysstty_8
  1977                              <1> sysstty_inv_dn: 
  1978                              <1> 	; 27/06/2015
  1979                              <1> 	; Invalid device name (not a tty) ! error
  1980                              <1> 	; (Device is not a tty or device name not found)
  1981 00008765 C705[15B80000]1800- <1> 	mov	dword [u.error], ERR_INV_DEV_NAME
  1981 0000876D 0000                <1>
  1982 0000876F E94DF9FFFF          <1> 	jmp	error 
  1983                              <1> sysstty_7:
  1984 00008774 3C01                <1> 	cmp	al, 1 ; /dev/tty
  1985 00008776 75ED                <1> 	jne	short sysstty_inv_dn ; 27/06/2015
  1986 00008778 0FB61D[0FB80000]    <1> 	movzx	ebx, byte [u.uno] ; process number
  1987 0000877F 8A83[13B50000]      <1> 	mov	al, [ebx+p.ttyc-1] ; console tty
  1988                              <1> sysstty_8:	
  1989 00008785 A2[C0B70000]        <1> 	mov	[u.r0], al
  1990 0000878A 6652                <1> 	push	dx
  1991 0000878C 6650                <1> 	push	ax
  1992 0000878E 6651                <1> 	push	cx	
  1993 00008790 E8930E0000          <1> 	call	ottyp
  1994 00008795 6659                <1> 	pop	cx
  1995 00008797 6658                <1> 	pop	ax
  1996 00008799 665A                <1> 	pop	dx
  1997 0000879B 0F825DFFFFFF        <1>         jc      sysstty_pd_err ; 'permission denied !'
  1998                              <1> 	; 29/10/2015
  1999 000087A1 86E9                <1> 	xchg 	ch, cl
  2000                              <1> 		; cl = character, ch = color code
  2001 000087A3 86C1                <1> 	xchg	al, cl
  2002                              <1> 		; al = character, cl = tty number
  2003 000087A5 80F907              <1> 	cmp	cl, 7
  2004 000087A8 0F873DFFFFFF        <1>         ja      sysstty_12
  2005                              <1> 	;
  2006                              <1> 	; 16/01/2014
  2007 000087AE 30FF                <1> 	xor	bh, bh
  2008                              <1> 	;
  2009                              <1> sysstty_9: 	; tty 0 to tty 7
  2010                              <1> 	; al = character
  2011 000087B0 80FEFF              <1> 	cmp	dh, 0FFh ; Do not set cursor position
  2012 000087B3 740F                <1> 	je	short sysstty_10
  2013 000087B5 6651                <1> 	push	cx
  2014 000087B7 6650                <1> 	push	ax	
  2015                              <1> 	; movzx, ebx, cl
  2016 000087B9 88CB                <1> 	mov	bl, cl ; (tty number = video page number)
  2017 000087BB E88A90FFFF          <1> 	call	_set_cpos
  2018 000087C0 6658                <1> 	pop	ax
  2019 000087C2 6659                <1> 	pop	cx
  2020                              <1> sysstty_10: 
  2021                              <1> 	; 29/10/2015
  2022 000087C4 08C0                <1> 	or	al, al ; character
  2023 000087C6 740F                <1> 	jz      short sysstty_11 ; al = 0
  2024                              <1> 	; 17/11/2015
  2025 000087C8 3CFF                <1> 	cmp	al, 0FFh
  2026 000087CA 730B                <1> 	jnb	short sysstty_11
  2027                              <1> 		; ch > 0 and ch < FFh
  2028                              <1> 	; write a character at current cursor position
  2029 000087CC 88EC                <1> 	mov	ah, ch ; color/attribute
  2030                              <1> 	; 12/07/2014
  2031 000087CE 6651                <1> 	push	cx
  2032 000087D0 E8B08FFFFF          <1> 	call	_write_c_current
  2033 000087D5 6659                <1> 	pop	cx
  2034                              <1> sysstty_11:
  2035                              <1> 	; 14/01/2014
  2036 000087D7 30D2                <1> 	xor	dl, dl ; sysstty call sign
  2037                              <1> 	; 18/01/2014
  2038                              <1> 	;movzx	eax, cl ; 27/06/2015
  2039 000087D9 88C8                <1> 	mov	al, cl
  2040 000087DB E8490E0000          <1> 	call	cttyp
  2041 000087E0 E9FCF8FFFF          <1> 	jmp	sysret
  2042                              <1> 
  2043                              <1> ; Original UNIX v1 'sysstty' routine:
  2044                              <1> ; gtty:
  2045                              <1> ;sysstty: / set mode of typewriter; 3 consequtive word arguments
  2046                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block, 
  2047                              <1> 	; 		/ r2 has source
  2048                              <1>         ;mov    r2,-(sp)
  2049                              <1>         ;mov    r1,-(sp) / put r1 and r2 on the stack
  2050                              <1> ;1: / flush the clist wait till typewriter is quiescent
  2051                              <1>         ;mov    (sp),r1 / restore r1 to tty block offset
  2052                              <1>         ;movb   tty+3(r1),0f / put cc offset into getc argument
  2053                              <1>         ;mov    $240,*$ps / set processor priority to 5
  2054                              <1>         ;jsr    r0,getc; 0:../ put character from clist in r1
  2055                              <1>         ;       br .+4 / list empty, skip branch
  2056                              <1>         ;br     1b / get another character until list is empty
  2057                              <1>         ;mov    0b,r1 / move cc offset to r1
  2058                              <1>         ;inc    r1 / bump it for output clist
  2059                              <1>         ;tstb   cc(r1) / is it 0
  2060                              <1>         ;beq    1f / yes, no characters to output
  2061                              <1>  	;mov    r1,0f / no, put offset in sleep arg
  2062                              <1>         ;jsr    r0,sleep; 0:.. / put tty output process to sleep
  2063                              <1>         ;br     1b / try to calm it down again
  2064                              <1> ;1:
  2065                              <1>         ;mov    (sp)+,r1
  2066                              <1>         ;mov    (sp)+,r2 / restore registers
  2067                              <1> 	;mov    (r2)+,r3 / put reader control status in r3
  2068                              <1>         ;beq    1f / if 0, 1f
  2069                              <1>         ;mov    r3,rcsr(r1) / move r.c. status to reader
  2070                              <1>         ;                   / control status register
  2071                              <1> ;1:
  2072                              <1>         ;mov    (r2)+,r3 / move pointer control status to r3
  2073                              <1>         ;beq    1f / if 0 1f
  2074                              <1>         ;mov    r3,tcsr(r1) / move p.c. status to printer 
  2075                              <1> 	;		    / control status reg
  2076                              <1> ;1:
  2077                              <1>         ;mov    (r2)+,tty+4(r1) / move to flag byte of tty block
  2078                              <1>         ;jmp     sysret2 / return to user
  2079                              <1> 
  2080                              <1> sysgtty: ; < get tty status >
  2081                              <1> 	; 23/11/2015
  2082                              <1> 	; 29/10/2015
  2083                              <1> 	; 17/10/2015
  2084                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - Beginning)
  2085                              <1> 	; 30/05/2013 - 12/07/2014 (Retro UNIX 8086 v1)
  2086                              <1> 	;
  2087                              <1> 	; 'sysgtty' gets the status of tty in question. 
  2088                              <1> 	; It stores in the three words addressed by it's argument
  2089                              <1> 	; the status of the typewriter whose file descriptor
  2090                              <1> 	; in (u.r0).
  2091                              <1> 	;
  2092                              <1> 	; Calling sequence:
  2093                              <1> 	;	sysgtty; arg
  2094                              <1> 	; Arguments:
  2095                              <1> 	;	arg - address of 3 words destination of the status
  2096                              <1> 	; Inputs: ((*u.r0 - file descriptor))
  2097                              <1> 	; Outputs: ((status in address which is pointed to by arg))
  2098                              <1> 	; ...............................................................
  2099                              <1> 	;	
  2100                              <1> 	; Retro UNIX 8086 v1 modification: 
  2101                              <1> 	;	'sysgtty' system call will return status of tty
  2102                              <1> 	;	(keyboard, serial port and video page status)
  2103                              <1> 	;	 in following manner:
  2104                              <1> 	;
  2105                              <1> 	; Inputs:
  2106                              <1> 	;	BX = 0 --> means 
  2107                              <1> 	;	     CH = 0 -->	'return status of the console tty' 
  2108                              <1> 	;	                 for (current) process
  2109                              <1> 	;	     CL = 0 --> return keyboard status (tty 0 to 9)
  2110                              <1> 	;	     CL = 1 --> return video page status (tty 0 to 7)
  2111                              <1> 	;	     CL = 1 --> return serial port status (tty 8 & 9)		
  2112                              <1> 	;	     CH > 0 -->	tty number + 1
  2113                              <1> 	;
  2114                              <1> 	;	BX > 0 --> points to name of tty
  2115                              <1> 	;	     CL = 0 --> return keyboard status
  2116                              <1> 	;	     CL = 1 --> return video page status
  2117                              <1> 	;	     CH = undefined		 
  2118                              <1> 	;
  2119                              <1> 	; Outputs:
  2120                              <1> 	;	cf = 0 ->
  2121                              <1> 	;
  2122                              <1> 	;	     AL = tty number from 0 to 9
  2123                              <1> 	;		  (0 to 7 is also the video page of the tty)	
  2124                              <1> 	;	     AH = 0 if the tty is free/unused
  2125                              <1> 	;	     AH = the process number of the caller 
  2126                              <1>  	;	     AH = FFh if the tty is locked by another process
  2127                              <1> 	;
  2128                              <1> 	;	  (if calling is for serial port status)
  2129                              <1> 	;	     BX = serial port status if tty number is 8 or 9
  2130                              <1> 	;		  (BH = modem status, BL = Line status)
  2131                              <1> 	;	     CX = 0FFFFh (if data is ready)
  2132                              <1> 	;	     CX = 0 (if data is not ready or undefined)		
  2133                              <1> 	;
  2134                              <1> 	;	  (if calling is for keyboard status)
  2135                              <1> 	;	     BX = current character in tty/keyboard buffer
  2136                              <1> 	;		  (BH = scan code, BL = ascii code)
  2137                              <1> 	;		  (BX=0 if there is not a waiting character)
  2138                              <1> 	;	     CX  is undefined
  2139                              <1> 	;
  2140                              <1> 	;	  (if calling is for video page status)	
  2141                              <1> 	;	     BX = cursor position on the video page
  2142                              <1> 	;		  if tty number < 8
  2143                              <1> 	;		  (BH = row, BL = column)
  2144                              <1> 	;	     CX = current character (in cursor position)
  2145                              <1> 	;		  on the video page of the tty 
  2146                              <1> 	;		  if tty number < 8
  2147                              <1> 	;		  (CH = color, CL = character)
  2148                              <1> 	;	
  2149                              <1> 	;	cf = 1 means error (requested tty is not ready)
  2150                              <1> 	;
  2151                              <1> 	;	     AH = FFh if the caller is not owner of
  2152                              <1> 	;		  specified tty or console tty
  2153                              <1> 	;	     AL = tty number (0FFh if it does not exist)
  2154                              <1> 	;	     BX, CX are undefined if cf = 1
  2155                              <1> 	;
  2156                              <1> 	;	  (If tty number is 8 or 9)
  2157                              <1> 	;	     AL = tty number 
  2158                              <1> 	;	     AH = the process number of the caller 
  2159                              <1> 	;	     BX = serial port status
  2160                              <1> 	;  		 (BH = modem status, BL = Line status)
  2161                              <1> 	;	     CX = 0
  2162                              <1> 	;
  2163                              <1> 		
  2164                              <1> gtty:   ; get (requested) tty number
  2165                              <1> 	; 17/10/2015
  2166                              <1> 	; 28/06/2015 (Retro UNIX 386 v1 - 32 bit modifications)
  2167                              <1> 	; 30/05/2013 - 12/07/2014
  2168                              <1> 	; Retro UNIX 8086 v1 modification ! 
  2169                              <1> 	;
  2170                              <1> 	; ((Modified regs: eAX, eBX, eCX, eDX, eSI, eDI, eBP))
  2171                              <1> 	;
  2172                              <1> 	; 28/06/2015 (32 bit modifications)
  2173                              <1> 	; 16/01/2014
  2174 000087E5 31C0                <1> 	xor 	eax, eax
  2175 000087E7 6648                <1> 	dec	ax ; 17/10/2015
  2176 000087E9 A3[C0B70000]        <1> 	mov 	[u.r0], eax ; 0FFFFh
  2177 000087EE 80F901              <1> 	cmp	cl, 1
  2178 000087F1 760F                <1> 	jna	short sysgtty_0
  2179                              <1> sysgtty_invp:
  2180                              <1> 	; 28/06/2015
  2181 000087F3 C705[15B80000]1700- <1>         mov     dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
  2181 000087FB 0000                <1>
  2182 000087FD E9BFF8FFFF          <1> 	jmp	error
  2183                              <1> sysgtty_0:	
  2184 00008802 21DB                <1> 	and	ebx, ebx
  2185 00008804 7430                <1> 	jz	short sysgtty_1
  2186                              <1> 	;
  2187 00008806 891D[D8B70000]      <1> 	mov	[u.namep], ebx
  2188 0000880C 6651                <1> 	push	cx ; 23/11/2015
  2189 0000880E E86A070000          <1> 	call	namei
  2190 00008813 6659                <1> 	pop	cx ; 23/11/2015
  2191 00008815 7210                <1> 	jc 	short sysgtty_inv_dn ; 28/06/2015
  2192                              <1> 	;
  2193 00008817 6683F801            <1> 	cmp	ax, 1
  2194 0000881B 7622                <1> 	jna	short sysgtty_2
  2195 0000881D 6683E80A            <1> 	sub	ax, 10
  2196 00008821 6683F809            <1> 	cmp	ax, 9
  2197                              <1> 	;ja	short sysgtty_inv_dn
  2198                              <1> 	;mov	ch, al
  2199                              <1> 	;jmp	short sysgtty_4
  2200                              <1> 	; 23/11/2015
  2201 00008825 7629                <1> 	jna	short sysgtty_4
  2202                              <1> sysgtty_inv_dn: 
  2203                              <1> 	; 28/06/2015
  2204                              <1> 	; Invalid device name (not a tty) ! error
  2205                              <1> 	; (Device is not a tty or device name not found)
  2206 00008827 C705[15B80000]1800- <1> 	mov	dword [u.error], ERR_INV_DEV_NAME
  2206 0000882F 0000                <1>
  2207 00008831 E98BF8FFFF          <1> 	jmp	error 
  2208                              <1> sysgtty_1:
  2209                              <1> 	; 16/01/2014
  2210 00008836 80FD0A              <1> 	cmp	ch, 10
  2211 00008839 77B8                <1> 	ja	short sysgtty_invp ; 28/06/2015
  2212 0000883B FECD                <1> 	dec	ch ; 0 -> FFh (negative)
  2213 0000883D 790F                <1> 	jns	short sysgtty_3 ; not negative
  2214                              <1> 	;
  2215                              <1> sysgtty_2:
  2216                              <1> 	; get tty number of console tty
  2217 0000883F 8A25[0FB80000]      <1> 	mov	ah, [u.uno]
  2218                              <1>  	; 28/06/2015
  2219 00008845 0FB6DC              <1> 	movzx 	ebx, ah
  2220 00008848 8AAB[13B50000]      <1> 	mov	ch, [ebx+p.ttyc-1]
  2221                              <1> sysgtty_3:
  2222 0000884E 88E8                <1> 	mov	al, ch
  2223                              <1> sysgtty_4:
  2224 00008850 A2[C0B70000]        <1> 	mov	[u.r0], al
  2225                              <1>  	; 28/06/2015
  2226                              <1> 	;cmp	al, 9
  2227                              <1> 	;ja	short sysgtty_invp
  2228 00008855 8B2D[BCB70000]      <1> 	mov	ebp, [u.usp]
  2229                              <1> 	; 23/11/2015
  2230 0000885B 20C9                <1> 	and	cl, cl
  2231 0000885D 7436                <1> 	jz	short sysgtty_6 ; keyboard status
  2232 0000885F 3C08                <1> 	cmp	al, 8 ; cmp ch, 8
  2233 00008861 7232                <1> 	jb	short sysgtty_6 ; video page status
  2234                              <1> 	; serial port status
  2235                              <1> 	; 12/07/2014
  2236                              <1> 	;mov	dx, 0
  2237                              <1> 	;je	short sysgtty_5
  2238                              <1> 	;inc	dl
  2239                              <1> ;sysgtty_5:
  2240                              <1> 	; 28/06/2015
  2241 00008863 2C08                <1> 	sub	al, 8
  2242 00008865 E872100000          <1> 	call	sp_status ; serial (COM) port (line) status
  2243                              <1> 	; AL = Line status, AH = Modem status
  2244 0000886A 66894510            <1> 	mov	[ebp+16], ax ; serial port status (in EBX)
  2245 0000886E 8A25[0FB80000]      <1> 	mov	ah, [u.uno]
  2246 00008874 8825[C1B70000]      <1>         mov     [u.r0+1], ah
  2247 0000887A 66C745180000        <1> 	mov	word [ebp+24], 0 ; data status (0 = not ready)	
  2248                              <1> 				; (in ECX)
  2249 00008880 A880                <1> 	test	al, 80h
  2250 00008882 7565                <1> 	jnz	short sysgtty_dnr_err ; 29/06/2015
  2251 00008884 A801                <1> 	test	al, 1
  2252 00008886 0F8455F8FFFF        <1> 	jz	sysret
  2253 0000888C 66FF4D18            <1> 	dec	word [ebp+24] ; data status (FFFFh = ready)	
  2254 00008890 E94CF8FFFF          <1> 	jmp	sysret
  2255                              <1> sysgtty_6:
  2256 00008895 A2[14B80000]        <1> 	mov	[u.ttyn], al ; tty number
  2257                              <1> 	;movzx	ebx, al
  2258 0000889A 88C3                <1> 	mov 	bl, al ; tty number (0 to 9)
  2259 0000889C D0E3                <1> 	shl 	bl, 1  ; aligned to word
  2260                              <1> 	; 22/04/2014 - 29/06/2015
  2261 0000889E 81C3[36A80000]      <1>         add     ebx, ttyl
  2262 000088A4 8A23                <1>  	mov	ah, [ebx]
  2263 000088A6 3A25[0FB80000]      <1> 	cmp	ah, [u.uno]
  2264 000088AC 7404                <1> 	je	short sysgtty_7
  2265 000088AE 20E4                <1> 	and	ah, ah
  2266                              <1> 	;jz	short sysgtty_7
  2267 000088B0 7506                <1> 	jnz	short sysgtty_8
  2268                              <1> 	;mov	ah, 0FFh
  2269                              <1> sysgtty_7:
  2270 000088B2 8825[C1B70000]      <1>         mov     [u.r0+1], ah
  2271                              <1> sysgtty_8:
  2272 000088B8 08C9                <1> 	or	cl, cl
  2273 000088BA 7510                <1> 	jnz	short sysgtty_9
  2274 000088BC B401                <1> 	mov	ah, 1  ; test a key is available
  2275 000088BE E82483FFFF          <1> 	call	int16h ; 24/01/2016
  2276 000088C3 66894510            <1> 	mov	[ebp+16], ax ; bx, character
  2277 000088C7 E915F8FFFF          <1> 	jmp	sysret
  2278                              <1> sysgtty_9:
  2279 000088CC 8A1D[14B80000]      <1> 	mov	bl, [u.ttyn]
  2280                              <1> 	; bl = video page number
  2281 000088D2 E8A58CFFFF          <1> 	call 	get_cpos
  2282                              <1> 	; dx = cursor position
  2283 000088D7 66895510            <1> 	mov	[ebp+16], dx ; bx
  2284                              <1> 	;mov	bl, [u.ttyn]
  2285                              <1> 	; bl = video page number
  2286 000088DB E85B8EFFFF          <1> 	call	_read_ac_current ; 24/01/2016
  2287                              <1> 	; ax = character and attribute/color
  2288 000088E0 66894518            <1> 	mov	[ebp+24], ax ; cx
  2289 000088E4 E9F8F7FFFF          <1> 	jmp	sysret
  2290                              <1> sysgtty_dnr_err:
  2291                              <1> 	; 'device not responding !' error	
  2292                              <1> 	;mov 	dword [u.error], ERR_TIME_OUT ; 25
  2293 000088E9 C705[15B80000]1900- <1> 	mov 	dword [u.error], ERR_DEV_NOT_RESP ;  25				
  2293 000088F1 0000                <1>
  2294 000088F3 E9C9F7FFFF          <1> 	jmp	error	
  2295                              <1> 
  2296                              <1> ; Original UNIX v1 'sysgtty' routine:
  2297                              <1> ; sysgtty:
  2298                              <1>         ;jsr    r0,gtty / r1 will have offset to tty block,
  2299                              <1> 	;	       / r2 has destination
  2300                              <1>         ;mov    rcsr(r1),(r2)+ / put reader control status 
  2301                              <1> 	;                     / in 1st word of dest
  2302                              <1>         ;mov    tcsr(r1),(r2)+ / put printer control status
  2303                              <1> 	;                     / in 2nd word of dest
  2304                              <1>         ;mov    tty+4(r1),(r2)+ / put mode in 3rd word
  2305                              <1>         ;jmp    sysret2 / return to user
  2306                              <1> 	
  2307                              <1> ; Original UNIX v1 'gtty' routine:
  2308                              <1> ; gtty:
  2309                              <1>         ;jsr    r0,arg; u.off / put first arg in u.off
  2310                              <1>         ;mov    *u.r0,r1 / put file descriptor in r1
  2311                              <1>         ;jsr    r0,getf / get the i-number of the file
  2312                              <1>         ;tst    r1 / is it open for reading
  2313                              <1>         ;bgt    1f / yes
  2314                              <1>         ;neg    r1 / no, i-number is negative, 
  2315                              <1> 	;          / so make it positive
  2316                              <1> ;1:
  2317                              <1>         ;sub    $14.,r1 / get i-number of tty0
  2318                              <1>         ;cmp    r1,$ntty-1 / is there such a typewriter
  2319                              <1>         ;bhis   error9 / no, error
  2320                              <1>         ;asl    r1 / 0%2
  2321                              <1>         ;asl    r1 / 0%4 / yes
  2322                              <1>         ;asl    r1 / 0%8 / multiply by 8 so r1 points to 
  2323                              <1> 	;	       ; / tty block
  2324                              <1>         ;mov    u.off,r2 / put argument in r2
  2325                              <1>         ;rts    r0 / return
  2326                              <1> 
  2327                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - u2.s
  2328                              <1> ; Last Modification: 03/01/2016
  2329                              <1> 
  2330                              <1> syslink:
  2331                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2332                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  2333                              <1> 	;
  2334                              <1> 	; 'syslink' is given two arguments, name 1 and name 2.
  2335                              <1> 	; name 1 is a file that already exists. name 2 is the name
  2336                              <1> 	; given to the entry that will go in the current directory.
  2337                              <1> 	; name2 will then be a link to the name 1 file. The i-number
  2338                              <1> 	; in the name 2 entry of current directory is the same
  2339                              <1> 	; i-number for the name 1 file.
  2340                              <1> 	;
  2341                              <1> 	; Calling sequence:
  2342                              <1> 	;	syslink; name 1; name 2
  2343                              <1> 	; Arguments:
  2344                              <1> 	;	name 1 - file name to which link will be created.
  2345                              <1> 	;	name 2 - name of entry in current directory that
  2346                              <1> 	;		 links to name 1.
  2347                              <1> 	; Inputs: -
  2348                              <1> 	; Outputs: -
  2349                              <1> 	; ...............................................................
  2350                              <1> 	;	
  2351                              <1> 	; Retro UNIX 8086 v1 modification: 
  2352                              <1> 	;       'syslink' system call has two arguments; so,
  2353                              <1> 	;	* 1st argument, name 1 is pointed to by BX register
  2354                              <1> 	;	* 2nd argument, name 2 is pointed to by CX register
  2355                              <1> 	;
  2356                              <1> 		; / name1, name2
  2357                              <1> 		;jsr r0,arg2 / u.namep has 1st arg u.off has 2nd
  2358 000088F8 891D[D8B70000]      <1> 	mov	[u.namep], ebx
  2359 000088FE 51                  <1> 	push	ecx
  2360 000088FF E879060000          <1> 	call	namei
  2361                              <1> 		; jsr r0,namei / find the i-number associated with
  2362                              <1> 			     ; / the 1st path name
  2363                              <1>      	;;and	ax, ax
  2364                              <1> 	;;jz	error ; File not found
  2365                              <1> 	;jc	error 
  2366                              <1> 		; br error9 / cannot be found
  2367 00008904 730F                <1> 	jnc	short syslink0
  2368                              <1> 	;pop 	ecx
  2369                              <1> 	; 'file not found !' error
  2370 00008906 C705[15B80000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  2370 0000890E 0000                <1>
  2371 00008910 E9ACF7FFFF          <1> 	jmp	error
  2372                              <1> syslink0:
  2373 00008915 E8FF0C0000          <1> 	call	iget
  2374                              <1> 		; jsr r0,iget / get the i-node into core
  2375 0000891A 8F05[D8B70000]      <1> 	pop	dword [u.namep] ; ecx
  2376                              <1> 		; mov (sp)+,u.namep / u.namep points to 2nd name
  2377 00008920 6650                <1> 	push	ax
  2378                              <1> 		; mov r1,-(sp) / put i-number of name1 on the stack
  2379                              <1> 			    ; / (a link to this file is to be created)
  2380 00008922 66FF35[A4B70000]    <1> 	push	word [cdev]
  2381                              <1> 		; mov cdev,-(sp) / put i-nodes device on the stack
  2382 00008929 E855000000          <1> 	call	isdir
  2383                              <1> 		; jsr r0,isdir / is it a directory
  2384 0000892E E84A060000          <1> 	call	namei
  2385                              <1> 		; jsr r0,namei / no, get i-number of name2
  2386                              <1> 	;jnc	error
  2387                              <1> 		; br .+4   / not found 
  2388                              <1> 			 ; / so r1 = i-number of current directory
  2389                              <1> 			 ; / ii = i-number of current directory
  2390                              <1> 		; br error9 / file already exists., error
  2391 00008933 720F                <1> 	jc	short syslink1
  2392                              <1> 	; pop ax
  2393                              <1> 	; pop ax
  2394                              <1> 	; 'file exists !' error
  2395 00008935 C705[15B80000]0E00- <1> 	mov	dword [u.error], ERR_FILE_EXISTS ; 14
  2395 0000893D 0000                <1>
  2396 0000893F E97DF7FFFF          <1> 	jmp	error
  2397                              <1> syslink1:
  2398 00008944 6659                <1> 	pop	cx
  2399                              <1> 	;cmp	cx, [cdev]
  2400 00008946 3A0D[A4B70000]      <1> 	cmp	cl, [cdev]
  2401                              <1> 	;jne	error
  2402                              <1> 		; cmp (sp)+,cdev / u.dirp now points to 
  2403                              <1> 			       ; / end of current directory
  2404                              <1> 	        ; bne error9
  2405 0000894C 740F                <1> 	je	short syslink2
  2406                              <1> 	; 'not same drive !' error
  2407 0000894E C705[15B80000]1500- <1> 	mov	dword [u.error],  ERR_DRV_NOT_SAME ; 21
  2407 00008956 0000                <1>
  2408 00008958 E964F7FFFF          <1> 	jmp	error
  2409                              <1> syslink2:
  2410 0000895D 6658                <1> 	pop	ax
  2411 0000895F 6650                <1> 	push	ax
  2412 00008961 66A3[F2B70000]      <1> 	mov	[u.dirbuf], ax
  2413                              <1> 		; mov (sp),u.dirbuf / i-number of name1 into u.dirbuf
  2414 00008967 E8A8000000          <1> 	call	mkdir
  2415                              <1> 		; jsr r0,mkdir / make directory entry for name2 
  2416                              <1> 		 	     ; / in current directory
  2417 0000896C 6658                <1> 	pop	ax
  2418                              <1> 		; mov (sp)+,r1 / r1 has i-number of name1
  2419 0000896E E8A60C0000          <1> 	call	iget
  2420                              <1> 		; jsr r0,iget / get i-node into core
  2421 00008973 FE05[96B40000]      <1> 	inc	byte [i.nlks]
  2422                              <1> 		; incb i.nlks / add 1 to its number of links
  2423 00008979 E8A90C0000          <1> 	call	setimod
  2424                              <1> 		; jsr r0,setimod / set the i-node modified flag
  2425 0000897E E95EF7FFFF          <1> 	jmp	sysret
  2426                              <1> 
  2427                              <1> isdir:
  2428                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  2429                              <1> 	; 04/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  2430                              <1> 	;
  2431                              <1> 	; 'isdir' check to see if the i-node whose i-number is in r1
  2432                              <1> 	;  is a directory. If it is, an error occurs, because 'isdir'
  2433                              <1> 	;  called by syslink and sysunlink to make sure directories
  2434                              <1> 	;  are not linked. If the user is the super user (u.uid=0),
  2435                              <1> 	; 'isdir' does not bother checking. The current i-node
  2436                              <1> 	;  is not disturbed.			
  2437                              <1> 	;		
  2438                              <1> 	; INPUTS ->
  2439                              <1> 	;    r1 - contains the i-number whose i-node is being checked.
  2440                              <1> 	;    u.uid - user id
  2441                              <1> 	; OUTPUTS ->
  2442                              <1> 	;    r1 - contains current i-number upon exit
  2443                              <1> 	;    	 (current i-node back in core) 
  2444                              <1> 	;	
  2445                              <1> 	; ((AX = R1))
  2446                              <1> 	;
  2447                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  2448                              <1> 	;
  2449                              <1> 
  2450                              <1> 	; / if the i-node whose i-number is in r1 is a directory 
  2451                              <1> 	; / there is an error unless super user made the call
  2452                              <1> 	
  2453 00008983 803D[0CB80000]00    <1> 	cmp	byte [u.uid], 0 
  2454                              <1> 		; tstb u.uid / super user
  2455 0000898A 762D                <1> 	jna	short isdir1
  2456                              <1> 		; beq 1f / yes, don't care
  2457 0000898C 66FF35[A0B70000]    <1> 	push	word [ii]
  2458                              <1> 		; mov ii,-(sp) / put current i-number on stack
  2459 00008993 E8810C0000          <1> 	call	iget
  2460                              <1> 		; jsr r0,iget / get i-node into core (i-number in r1)
  2461 00008998 66F705[94B40000]00- <1> 	test 	word [i.flgs], 4000h ; Bit 14 : Directory flag
  2461 000089A0 40                  <1>
  2462                              <1> 		; bit $40000,i.flgs / is it a directory
  2463                              <1> 	;jnz	error
  2464                              <1> 		; bne error9 / yes, error
  2465 000089A1 740F                <1> 	jz	short isdir0
  2466 000089A3 C705[15B80000]0B00- <1> 	mov 	dword [u.error], ERR_NOT_FILE  ; 11 ; ERR_DIR_ACCESS 
  2466 000089AB 0000                <1>
  2467                              <1> 				; 'permission denied !' error
  2468                              <1> 	; pop	ax
  2469 000089AD E90FF7FFFF          <1> 	jmp	error	
  2470                              <1> isdir0:	
  2471 000089B2 6658                <1> 	pop	ax
  2472                              <1> 		; mov (sp)+,r1 / no, put current i-number in r1 (ii)
  2473 000089B4 E8600C0000          <1> 	call	iget
  2474                              <1> 		; jsr r0,iget / get it back in
  2475                              <1> isdir1: ; 1:
  2476 000089B9 C3                  <1> 	retn
  2477                              <1> 		; rts r0
  2478                              <1> 
  2479                              <1> sysunlink:
  2480                              <1> 	; 04/12/2015 (14 byte file names)
  2481                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2482                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  2483                              <1> 	;
  2484                              <1> 	; 'sysunlink' removes the entry for the file pointed to by
  2485                              <1> 	; name from its directory. If this entry was the last link
  2486                              <1> 	; to the file, the contents of the file are freed and the
  2487                              <1> 	; file is destroyed. If, however, the file was open in any
  2488                              <1> 	; process, the actual destruction is delayed until it is 
  2489                              <1> 	; closed, even though the directory entry has disappeared.
  2490                              <1> 	; 
  2491                              <1> 	; The error bit (e-bit) is set to indicate that the file	
  2492                              <1> 	; does not exist or that its directory can not be written.
  2493                              <1> 	; Write permission is not required on the file itself.
  2494                              <1> 	; It is also illegal to unlink a directory (except for
  2495                              <1> 	; the superuser).
  2496                              <1> 	;
  2497                              <1> 	; Calling sequence:
  2498                              <1> 	;	sysunlink; name
  2499                              <1> 	; Arguments:
  2500                              <1> 	;	name - name of directory entry to be removed 
  2501                              <1> 	; Inputs: -
  2502                              <1> 	; Outputs: -
  2503                              <1> 	; ...............................................................
  2504                              <1> 	;				
  2505                              <1> 	; Retro UNIX 8086 v1 modification:
  2506                              <1> 	;	 The user/application program puts address of the name
  2507                              <1> 	;        in BX register as 'sysunlink' system call argument.
  2508                              <1> 
  2509                              <1> 	; / name - remove link name
  2510 000089BA 891D[D8B70000]      <1> 	mov	[u.namep], ebx
  2511                              <1> 		;jsr r0,arg; u.namep / u.namep points to name
  2512 000089C0 E8B8050000          <1> 	call	namei
  2513                              <1> 		; jsr r0,namei / find the i-number associated 
  2514                              <1> 			     ; / with the path name
  2515                              <1> 	;jc	error
  2516                              <1> 		; br error9 / not found
  2517 000089C5 730F                <1> 	jnc	short sysunlink1
  2518                              <1> 	; 'file not found !' error
  2519 000089C7 C705[15B80000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  2519 000089CF 0000                <1>
  2520 000089D1 E9EBF6FFFF          <1> 	jmp	error
  2521                              <1> sysunlink1:
  2522 000089D6 6650                <1> 	push	ax
  2523                              <1> 		; mov r1,-(sp) / put its i-number on the stack
  2524 000089D8 E8A6FFFFFF          <1> 	call	isdir
  2525                              <1> 		; jsr r0,isdir / is it a directory
  2526 000089DD 6631C0              <1> 	xor 	ax, ax
  2527 000089E0 66A3[F2B70000]      <1> 	mov	[u.dirbuf], ax ; 0
  2528                              <1> 		; clr u.dirbuf / no, clear the location that will
  2529                              <1> 			   ; / get written into the i-number portion
  2530                              <1> 			 ; / of the entry
  2531 000089E6 832D[DCB70000]10    <1> 	sub	dword [u.off], 16 ; 04/12/2015 (10 -> 16) 
  2532                              <1> 		; sub $10.,u.off / move u.off back 1 directory entry
  2533 000089ED E86E000000          <1> 	call	wdir
  2534                              <1> 		; jsr r0,wdir / free the directory entry
  2535 000089F2 6658                <1> 	pop	ax
  2536                              <1> 		; mov (sp)+,r1 / get i-number back
  2537 000089F4 E8200C0000          <1> 	call	iget
  2538                              <1> 		; jsr r0,iget / get i-node
  2539 000089F9 E8290C0000          <1> 	call	setimod
  2540                              <1> 		; jsr r0,setimod / set modified flag
  2541 000089FE FE0D[96B40000]      <1> 	dec	byte [i.nlks]
  2542                              <1> 		; decb i.nlks / decrement the number of links
  2543 00008A04 0F85D7F6FFFF        <1> 	jnz	sysret
  2544                              <1> 		; bgt sysret9 / if this was not the last link
  2545                              <1> 			    ; / to file return
  2546                              <1> 	; AX = r1 = i-number
  2547 00008A0A E893090000          <1> 	call	anyi
  2548                              <1> 		; jsr r0,anyi / if it was, see if anyone has it open.
  2549                              <1> 			 ; / Then free contents of file and destroy it.
  2550 00008A0F E9CDF6FFFF          <1> 	jmp	sysret
  2551                              <1> 		; br sysret9
  2552                              <1> 
  2553                              <1> mkdir:
  2554                              <1> 	; 04/12/2015 (14 byte directory names)
  2555                              <1> 	; 12/10/2015
  2556                              <1> 	; 17/06/2015 (Retro UNIX 386 v1 - Beginning)
  2557                              <1> 	; 29/04/2013 - 01/08/2013 (Retro UNIX 8086 v1)
  2558                              <1> 	;
  2559                              <1> 	; 'mkdir' makes a directory entry from the name pointed to
  2560                              <1> 	; by u.namep into the current directory.
  2561                              <1> 	;
  2562                              <1> 	; INPUTS ->
  2563                              <1> 	;    u.namep - points to a file name 
  2564                              <1> 	;	           that is about to be a directory entry.
  2565                              <1> 	;    ii - current directory's i-number.	
  2566                              <1> 	; OUTPUTS ->
  2567                              <1> 	;    u.dirbuf+2 - u.dirbuf+10 - contains file name. 
  2568                              <1> 	;    u.off - points to entry to be filled 
  2569                              <1> 	;	     in the current directory		
  2570                              <1> 	;    u.base - points to start of u.dirbuf.
  2571                              <1> 	;    r1 - contains i-number of current directory 
  2572                              <1> 	;	
  2573                              <1> 	; ((AX = R1)) output
  2574                              <1> 	;
  2575                              <1> 	;    (Retro UNIX Prototype : 11/11/2012, UNIXCOPY.ASM)
  2576                              <1>         ;    ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  2577                              <1> 	;
  2578                              <1> 
  2579                              <1> 	; 17/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
  2580 00008A14 31C0                <1> 	xor 	eax, eax
  2581 00008A16 BF[F4B70000]        <1> 	mov     edi, u.dirbuf+2
  2582 00008A1B 89FE                <1> 	mov	esi, edi
  2583 00008A1D AB                  <1> 	stosd
  2584 00008A1E AB                  <1> 	stosd
  2585                              <1> 	; 04/12/2015 (14 byte directory names)
  2586 00008A1F AB                  <1> 	stosd
  2587 00008A20 66AB                <1> 	stosw
  2588                              <1> 		; jsr r0,copyz; u.dirbuf+2; u.dirbuf+10. / clear this
  2589 00008A22 89F7                <1> 	mov	edi, esi ; offset to u.dirbuf
  2590                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
  2591                              <1> 	;mov 	ebp, [u.namep]
  2592 00008A24 E899060000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
  2593                              <1> 		; esi = physical address (page start + offset)
  2594                              <1> 		; ecx = byte count in the page (1 - 4096)
  2595                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
  2596                              <1> 		; mov u.namep,r2 / r2 points to name of directory entry
  2597                              <1> 		; mov $u.dirbuf+2,r3 / r3 points to u.dirbuf+2
  2598                              <1> mkdir_1: ; 1: 
  2599 00008A29 45                  <1> 	inc	ebp ; 12/10/2015
  2600                              <1> 	;
  2601                              <1> 	; / put characters in the directory name in u.dirbuf+2 - u.dirbuf+10
  2602                              <1> 	 ; 01/08/2013
  2603 00008A2A AC                  <1> 	lodsb
  2604                              <1> 		; movb (r2)+,r1 / move character in name to r1
  2605 00008A2B 20C0                <1> 	and 	al, al
  2606 00008A2D 7427                <1> 	jz 	short mkdir_3 	  
  2607                              <1> 		; beq 1f / if null, done
  2608 00008A2F 3C2F                <1> 	cmp	al, '/'
  2609                              <1> 		; cmp r1,$'/ / is it a "/"?
  2610 00008A31 7414                <1> 	je	short mkdir_err
  2611                              <1> 	;je	error
  2612                              <1> 		; beq error9 / yes, error
  2613                              <1> 	; 12/10/2015
  2614 00008A33 6649                <1> 	dec	cx
  2615 00008A35 7505                <1> 	jnz	short mkdir_2
  2616                              <1> 	; 12/10/2015 ([u.namep] -> ebp)
  2617 00008A37 E88C060000          <1> 	call	trans_addr_nm ; convert virtual address to physical
  2618                              <1> 		; esi = physical address (page start + offset)
  2619                              <1> 		; ecx = byte count in the page
  2620                              <1> 	; edi = offset to u.dirbuf (edi is not modified in trans_addr_nm)
  2621                              <1> mkdir_2:
  2622 00008A3C 81FF[02B80000]      <1> 	cmp     edi, u.dirbuf+16 ; ; 04/12/2015 (10 -> 16) 
  2623                              <1> 		; cmp r3,$u.dirbuf+10. / have we reached the last slot for
  2624                              <1> 				     ; / a char?
  2625 00008A42 74E5                <1> 	je	short mkdir_1
  2626                              <1> 		; beq 1b / yes, go back
  2627 00008A44 AA                  <1> 	stosb
  2628                              <1> 		; movb r1,(r3)+ / no, put the char in the u.dirbuf
  2629 00008A45 EBE2                <1> 	jmp 	short mkdir_1
  2630                              <1> 		; br 1b / get next char
  2631                              <1> mkdir_err:
  2632                              <1> 	; 17/06/2015
  2633 00008A47 C705[15B80000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
  2633 00008A4F 0000                <1>
  2634 00008A51 E96BF6FFFF          <1> 	jmp	error
  2635                              <1> 
  2636                              <1> mkdir_3: ; 1:
  2637 00008A56 A1[D4B70000]        <1> 	mov	eax, [u.dirp]
  2638 00008A5B A3[DCB70000]        <1> 	mov	[u.off], eax
  2639                              <1> 		; mov u.dirp,u.off / pointer to empty current directory
  2640                              <1> 				 ; / slot to u.off
  2641                              <1> wdir: ; 29/04/2013
  2642 00008A60 C705[E0B70000]-     <1>         mov     dword [u.base], u.dirbuf
  2642 00008A66 [F2B70000]          <1>
  2643                              <1> 		; mov $u.dirbuf,u.base / u.base points to created file name
  2644 00008A6A C705[E4B70000]1000- <1>         mov     dword [u.count], 16 ; 04/12/2015 (10 -> 16) 
  2644 00008A72 0000                <1>
  2645                              <1> 		; mov $10.,u.count / u.count = 10
  2646 00008A74 66A1[A0B70000]      <1> 	mov	ax, [ii] 
  2647                              <1> 		; mov ii,r1 / r1 has i-number of current directory
  2648 00008A7A B201                <1> 	mov	dl, 1 ; owner flag mask ; RETRO UNIX 8086 v1 modification !
  2649 00008A7C E8AA0B0000          <1> 	call 	access
  2650                              <1> 		; jsr r0,access; 1 / get i-node and set its file up 
  2651                              <1> 				 ; / for writing
  2652                              <1> 	; AX = i-number of current directory
  2653                              <1> 	; 01/08/2013
  2654 00008A81 FE05[27B80000]      <1> 	inc     byte [u.kcall] ; the caller is 'mkdir' sign	
  2655 00008A87 E8910B0000          <1> 	call	writei
  2656                              <1> 		; jsr r0,writei / write into directory
  2657 00008A8C C3                  <1> 	retn	
  2658                              <1> 		; rts r0
  2659                              <1> 
  2660                              <1> sysexec:
  2661                              <1> 	; 23/10/2015
  2662                              <1> 	; 19/10/2015
  2663                              <1> 	; 18/10/2015
  2664                              <1> 	; 10/10/2015
  2665                              <1> 	; 26/08/2015
  2666                              <1> 	; 05/08/2015
  2667                              <1> 	; 29/07/2015
  2668                              <1> 	; 25/07/2015
  2669                              <1> 	; 24/07/2015
  2670                              <1> 	; 21/07/2015
  2671                              <1> 	; 20/07/2015
  2672                              <1> 	; 02/07/2015
  2673                              <1> 	; 01/07/2015
  2674                              <1> 	; 25/06/2015
  2675                              <1> 	; 24/06/2015
  2676                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  2677                              <1> 	; 03/06/2013 - 06/12/2013 (Retro UNIX 8086 v1)
  2678                              <1> 	;
  2679                              <1> 	; 'sysexec' initiates execution of a file whose path name if
  2680                              <1> 	; pointed to by 'name' in the sysexec call. 
  2681                              <1> 	; 'sysexec' performs the following operations:
  2682                              <1> 	;    1. obtains i-number of file to be executed via 'namei'.
  2683                              <1> 	;    2. obtains i-node of file to be exceuted via 'iget'.
  2684                              <1> 	;    3. sets trap vectors to system routines.
  2685                              <1> 	;    4. loads arguments to be passed to executing file into
  2686                              <1> 	;	highest locations of user's core
  2687                              <1> 	;    5. puts pointers to arguments in locations immediately
  2688                              <1> 	;	following arguments.
  2689                              <1> 	;    6.	saves number of arguments in next location.
  2690                              <1> 	;    7. intializes user's stack area so that all registers
  2691                              <1> 	;	will be zeroed and the PS is cleared and the PC set
  2692                              <1> 	;	to core when 'sysret' restores registers 
  2693                              <1> 	;	and does an rti.
  2694                              <1> 	;    8. inializes u.r0 and u.sp
  2695                              <1> 	;    9. zeros user's core down to u.r0
  2696                              <1> 	;   10.	reads executable file from storage device into core
  2697                              <1> 	;	starting at location 'core'.
  2698                              <1> 	;   11.	sets u.break to point to end of user's code with
  2699                              <1> 	;	data area appended.
  2700                              <1> 	;   12.	calls 'sysret' which returns control at location
  2701                              <1> 	;	'core' via 'rti' instruction. 		  		
  2702                              <1> 	;
  2703                              <1> 	; Calling sequence:
  2704                              <1> 	;	sysexec; namep; argp
  2705                              <1> 	; Arguments:
  2706                              <1> 	;	namep - points to pathname of file to be executed
  2707                              <1> 	;	argp  - address of table of argument pointers
  2708                              <1> 	;	argp1... argpn - table of argument pointers
  2709                              <1> 	;	argp1:<...0> ... argpn:<...0> - argument strings
  2710                              <1> 	; Inputs: (arguments)
  2711                              <1> 	; Outputs: -	
  2712                              <1> 	; ...............................................................
  2713                              <1> 	;
  2714                              <1> 	; Retro UNIX 386 v1 modification: 
  2715                              <1> 	;	User application runs in it's own virtual space 
  2716                              <1> 	;	which is izolated from kernel memory (and other
  2717                              <1> 	;	memory pages) via 80386	paging in ring 3 
  2718                              <1> 	;	privilige mode. Virtual start address is always 0.
  2719                              <1> 	;	User's core memory starts at linear address 400000h
  2720                              <1> 	;	(the end of the 1st 4MB).
  2721                              <1> 	;
  2722                              <1> 	; Retro UNIX 8086 v1 modification: 
  2723                              <1> 	;	user/application segment and system/kernel segment
  2724                              <1> 	;	are different and sysenter/sysret/sysrele routines
  2725                              <1> 	;	are different (user's registers are saved to 
  2726                              <1> 	;	and then restored from system's stack.)
  2727                              <1> 	;
  2728                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
  2729                              <1> 	;	      arguments which were in these registers;
  2730                              <1> 	;	      but, it returns by putting the 1st argument
  2731                              <1> 	;	      in 'u.namep' and the 2nd argument
  2732                              <1> 	;	      on top of stack. (1st argument is offset of the
  2733                              <1> 	;	      file/path name in the user's program segment.)		 	
  2734                              <1> 	
  2735                              <1> 	;call	arg2
  2736                              <1> 	; * name - 'u.namep' points to address of file/path name
  2737                              <1> 	;          in the user's program segment ('u.segmnt')
  2738                              <1> 	;          with offset in BX register (as sysopen argument 1).
  2739                              <1> 	; * argp - sysexec argument 2 is in CX register 
  2740                              <1> 	;          which is on top of stack.
  2741                              <1> 	;
  2742                              <1> 		; jsr r0,arg2 / arg0 in u.namep,arg1 on top of stack
  2743                              <1> 
  2744                              <1> 	; 23/06/2015 (32 bit modifications)
  2745                              <1> 
  2746 00008A8D 891D[D8B70000]      <1> 	mov	[u.namep], ebx ; argument 1
  2747                              <1>         ; 18/10/2015
  2748 00008A93 890D[40B80000]      <1> 	mov     [argv], ecx  ; * ; argument 2
  2749 00008A99 E8DF040000          <1> 	call	namei
  2750                              <1> 		; jsr r0,namei / namei returns i-number of file 
  2751                              <1> 			     ; / named in sysexec call in r1
  2752                              <1> 	;jc	error
  2753                              <1> 		; br error9
  2754 00008A9E 731E                <1> 	jnc	short sysexec_0
  2755                              <1> 	;
  2756                              <1> 	; 'file not found !' error
  2757 00008AA0 C705[15B80000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND
  2757 00008AA8 0000                <1>
  2758 00008AAA E912F6FFFF          <1> 	jmp	error 
  2759                              <1> sysexec_not_exf:
  2760                              <1> 	; 'not executable file !' error
  2761 00008AAF C705[15B80000]1600- <1> 	mov	dword [u.error], ERR_NOT_EXECUTABLE
  2761 00008AB7 0000                <1>
  2762 00008AB9 E903F6FFFF          <1> 	jmp	error 
  2763                              <1> sysexec_0:
  2764 00008ABE E8560B0000          <1> 	call	iget
  2765                              <1> 		; jsr r0,iget / get i-node for file to be executed
  2766 00008AC3 66F705[94B40000]10- <1>         test    word [i.flgs], 10h
  2766 00008ACB 00                  <1>
  2767                              <1> 		; bit $20,i.flgs / is file executable
  2768 00008ACC 74E1                <1> 	jz	short sysexec_not_exf
  2769                              <1> 	;jz	error
  2770                              <1> 		; beq error9
  2771                              <1> 	;;
  2772 00008ACE E8500B0000          <1> 	call	iopen
  2773                              <1> 		; jsr r0,iopen / gets i-node for file with i-number
  2774                              <1> 			     ; / given in r1 (opens file)
  2775                              <1> 	; AX = i-number of the file
  2776 00008AD3 66F705[94B40000]20- <1> 	test	word [i.flgs], 20h
  2776 00008ADB 00                  <1>
  2777                              <1> 		; bit $40,i.flgs / test user id on execution bit
  2778 00008ADC 7415                <1> 	jz	short sysexec_1
  2779                              <1> 		; beq 1f
  2780 00008ADE 803D[0CB80000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013
  2781                              <1> 		; tstb u.uid / test user id
  2782 00008AE5 760C                <1> 	jna	short sysexec_1
  2783                              <1> 		; beq 1f / super user
  2784 00008AE7 8A0D[97B40000]      <1> 	mov	cl, [i.uid]
  2785 00008AED 880D[0CB80000]      <1> 	mov	[u.uid], cl ; 02/08/2013
  2786                              <1> 		; movb i.uid,u.uid / put user id of owner of file
  2787                              <1> 				 ; / as process user id
  2788                              <1> sysexec_1:
  2789                              <1> 	; 18/10/2215
  2790                              <1> 	; 10/10/2015
  2791                              <1> 	; 24/07/2015
  2792                              <1> 	; 21/07/2015
  2793                              <1> 	; 25/06/2015
  2794                              <1> 	; 24/06/2015
  2795                              <1>         ; Moving arguments to the end of [u.upage]
  2796                              <1> 	; (by regarding page borders in user's memory space)
  2797                              <1> 	;
  2798                              <1> 	; 10/10/2015
  2799                              <1> 	; 21/07/2015
  2800 00008AF3 89E5                <1> 	mov	ebp, esp ; (**)
  2801                              <1> 	; 18/10/2015
  2802 00008AF5 89EF                <1> 	mov 	edi, ebp
  2803 00008AF7 B900010000          <1> 	mov 	ecx, MAX_ARG_LEN ; 256
  2804                              <1> 	;sub	edi, MAX_ARG_LEN ; 256
  2805 00008AFC 29CF                <1> 	sub	edi, ecx
  2806 00008AFE 89FC                <1> 	mov	esp, edi
  2807 00008B00 31C0                <1> 	xor	eax, eax
  2808 00008B02 A3[E8B70000]        <1> 	mov 	[u.nread], eax ; 0
  2809 00008B07 49                  <1> 	dec	ecx ; 256 - 1
  2810 00008B08 890D[E4B70000]      <1> 	mov 	[u.count], ecx ; MAX_ARG_LEN - 1 ; 255
  2811                              <1> 	;mov 	dword [u.count], MAX_ARG_LEN - 1 ; 255
  2812                              <1> sysexec_2:
  2813 00008B0E 8B35[40B80000]      <1> 	mov	esi, [argv] ; 18/10/2015 
  2814 00008B14 E873020000          <1> 	call	get_argp
  2815 00008B19 B904000000          <1> 	mov	ecx, 4 ; mov ecx, 4
  2816                              <1> sysexec_3:
  2817 00008B1E 21C0                <1> 	and	eax, eax
  2818 00008B20 7456                <1> 	jz	short sysexec_6
  2819                              <1> 	; 18/10/2015
  2820 00008B22 010D[40B80000]      <1> 	add	[argv], ecx ; 4
  2821 00008B28 66FF05[3EB80000]    <1> 	inc	word [argc]
  2822                              <1> 	;
  2823 00008B2F A3[E0B70000]        <1> 	mov	[u.base], eax
  2824                              <1>  	; 23/10/2015
  2825 00008B34 66C705[25B80000]00- <1> 	mov	word [u.pcount], 0
  2825 00008B3C 00                  <1>
  2826                              <1> sysexec_4:
  2827 00008B3D E8EA0A0000          <1> 	call	cpass ; get a character from user's core memory
  2828 00008B42 750B                <1>         jnz      short sysexec_5
  2829                              <1> 		; (max. 255 chars + null)
  2830                              <1> 	; 18/10/2015
  2831 00008B44 28C0                <1> 	sub 	al, al
  2832 00008B46 AA                  <1> 	stosb
  2833 00008B47 FF05[E8B70000]      <1> 	inc	dword [u.nread]
  2834 00008B4D EB29                <1> 	jmp	short sysexec_6
  2835                              <1> sysexec_5:
  2836 00008B4F AA                  <1> 	stosb
  2837 00008B50 20C0                <1> 	and 	al, al
  2838 00008B52 75E9                <1> 	jnz	short sysexec_4
  2839 00008B54 B904000000          <1> 	mov	ecx, 4
  2840 00008B59 390D[3CB80000]      <1> 	cmp	[ncount], ecx ; 4
  2841 00008B5F 72AD                <1> 	jb	short sysexec_2
  2842 00008B61 8B35[38B80000]      <1> 	mov	esi, [nbase]
  2843 00008B67 010D[38B80000]      <1> 	add	[nbase], ecx ; 4	
  2844 00008B6D 66290D[3CB80000]    <1> 	sub	[ncount], cx 
  2845 00008B74 8B06                <1> 	mov	eax, [esi]
  2846 00008B76 EBA6                <1> 	jmp	short sysexec_3
  2847                              <1> sysexec_6:
  2848                              <1> 	; 18/10/2015
  2849                              <1> 	; argument list transfer from user's core memory to
  2850                              <1> 	; kernel stack frame is OK here.
  2851                              <1> 	; [u.nread] = ; argument list length
  2852                              <1> 	;mov	[argv], esp ; start address of argument list 	
  2853                              <1> 	;
  2854                              <1> 	; 18/10/2015
  2855                              <1> 	; 24/07/2015
  2856                              <1>         ; 21/07/2015
  2857                              <1> 	; 02/07/2015
  2858                              <1> 	; 25/06/2015
  2859                              <1> 	; 24/06/2015
  2860                              <1> 	; 23/06/2015
  2861                              <1> 	;
  2862 00008B78 8B1D[1DB80000]      <1> 	mov	ebx, [u.ppgdir] ; parent's page directory
  2863 00008B7E 21DB                <1> 	and 	ebx, ebx  ; /etc/init ? (u.ppgdir = 0)	
  2864 00008B80 740A                <1> 	jz	short sysexec_7
  2865 00008B82 A1[19B80000]        <1> 	mov	eax, [u.pgdir] ; physical address of page directory
  2866 00008B87 E8B4A6FFFF          <1> 	call	deallocate_page_dir
  2867                              <1> sysexec_7:
  2868 00008B8C E8E4A5FFFF          <1> 	call	make_page_dir
  2869                              <1> 	;jc	short sysexec_14
  2870 00008B91 0F82F6B0FFFF        <1> 	jc	panic  ; allocation error 
  2871                              <1> 		       ; after a deallocation would be nonsence !?
  2872                              <1> 	; 24/07/2015
  2873                              <1> 	; map kernel pages (1st 4MB) to PDE 0
  2874                              <1> 	;     of the user's page directory
  2875                              <1> 	;     (It is needed for interrupts!)
  2876                              <1> 	; 18/10/2015
  2877 00008B97 8B15[E8A70000]      <1> 	mov	edx, [k_page_dir] ; Kernel's page directory
  2878 00008B9D 8B02                <1> 	mov	eax, [edx] ; physical address of
  2879                              <1> 			   ; kernel's first page table (1st 4 MB)
  2880                              <1> 			   ; (PDE 0 of kernel's page directory)
  2881 00008B9F 8B15[19B80000]      <1> 	mov 	edx, [u.pgdir]
  2882 00008BA5 8902                <1> 	mov	[edx], eax ; PDE 0 (1st 4MB)
  2883                              <1> 	;
  2884                              <1> 	; 20/07/2015
  2885 00008BA7 BB00004000          <1> 	mov	ebx, CORE ; start address = 0 (virtual) + CORE
  2886                              <1> 	; 18/10/2015
  2887 00008BAC BE[30B80000]        <1> 	mov	esi, pcore ; physical start address
  2888                              <1> sysexec_8:	
  2889 00008BB1 B907000000          <1> 	mov	ecx, PDE_A_USER + PDE_A_WRITE + PDE_A_PRESENT
  2890 00008BB6 E8D8A5FFFF          <1> 	call	make_page_table
  2891 00008BBB 0F82CCB0FFFF        <1> 	jc	panic
  2892                              <1> 	;mov	ecx, PTE_A_USER + PTE_A_WRITE + PTE_A_PRESENT
  2893 00008BC1 E8DBA5FFFF          <1> 	call	make_page ; make new page, clear and set the pte 
  2894 00008BC6 0F82C1B0FFFF        <1> 	jc	panic
  2895                              <1> 	;
  2896 00008BCC 8906                <1> 	mov	[esi], eax ; 24/06/2015
  2897                              <1> 	; ebx = virtual address (24/07/2015)
  2898 00008BCE E8F1AAFFFF          <1> 	call 	add_to_swap_queue
  2899                              <1> 	; 18/10/2015
  2900 00008BD3 81FE[34B80000]      <1> 	cmp	esi, ecore ; user's stack (last) page ?
  2901 00008BD9 740C                <1> 	je	short sysexec_9 ; yes
  2902 00008BDB BE[34B80000]        <1> 	mov	esi, ecore  ; physical address of the last page 
  2903                              <1> 	; 20/07/2015
  2904 00008BE0 BB00F0FFFF          <1> 	mov	ebx, (ECORE - PAGE_SIZE) + CORE
  2905                              <1> 	; ebx = virtual end address + segment base address - 4K
  2906 00008BE5 EBCA                <1>         jmp     short sysexec_8
  2907                              <1> 
  2908                              <1> sysexec_9:
  2909                              <1> 	; 18/10/2015
  2910                              <1> 	; 26/08/2015
  2911                              <1> 	; 25/06/2015
  2912                              <1> 	; move arguments from kernel stack to [ecore]
  2913                              <1> 	; (argument list/line will be copied from kernel stack
  2914                              <1> 	; frame to the last (stack) page of user's core memory)
  2915                              <1> 	; 18/10/2015
  2916 00008BE7 8B3D[34B80000]      <1> 	mov	edi, [ecore]
  2917 00008BED 81C700100000        <1> 	add	edi, PAGE_SIZE
  2918 00008BF3 0FB705[3EB80000]    <1> 	movzx	eax, word [argc]
  2919 00008BFA 09C0                <1> 	or	eax, eax
  2920 00008BFC 7509                <1> 	jnz	short sysexec_10
  2921 00008BFE 89FB                <1> 	mov 	ebx, edi
  2922 00008C00 83EB04              <1> 	sub	ebx, 4 
  2923 00008C03 8903                <1> 	mov	[ebx], eax ; 0
  2924 00008C05 EB40                <1> 	jmp 	short sysexec_13
  2925                              <1> sysexec_10:
  2926 00008C07 8B0D[E8B70000]      <1> 	mov	ecx, [u.nread]
  2927                              <1> 	;mov 	esi, [argv}
  2928 00008C0D 89E6                <1> 	mov	esi, esp ; start address of argument list
  2929 00008C0F 29CF                <1> 	sub	edi, ecx ; page end address - argument list length
  2930 00008C11 89C2                <1> 	mov	edx, eax
  2931 00008C13 FEC2                <1> 	inc	dl ; argument count + 1 for argc value  
  2932 00008C15 C0E202              <1> 	shl 	dl, 2  ; 4 * (argument count + 1)
  2933 00008C18 89FB                <1> 	mov	ebx, edi
  2934 00008C1A 80E3FC              <1> 	and	bl, 0FCh ; 32 bit (dword) alignment
  2935 00008C1D 29D3                <1> 	sub 	ebx, edx
  2936 00008C1F 89FA                <1> 	mov	edx, edi
  2937 00008C21 F3A4                <1> 	rep	movsb
  2938 00008C23 89D6                <1> 	mov 	esi, edx
  2939 00008C25 89DF                <1> 	mov 	edi, ebx
  2940 00008C27 BA00F0BFFF          <1> 	mov	edx, ECORE - PAGE_SIZE ; virtual addr. of the last page
  2941 00008C2C 2B15[34B80000]      <1> 	sub 	edx, [ecore] ; difference (virtual - physical) 
  2942 00008C32 AB                  <1> 	stosd	; eax = argument count	
  2943                              <1> sysexec_11:
  2944 00008C33 89F0                <1> 	mov	eax, esi
  2945 00008C35 01D0                <1> 	add	eax, edx
  2946 00008C37 AB                  <1> 	stosd  ; eax = virtual address
  2947 00008C38 FE0D[3EB80000]      <1> 	dec	byte [argc]
  2948 00008C3E 7407                <1> 	jz	short sysexec_13
  2949                              <1> sysexec_12:
  2950 00008C40 AC                  <1> 	lodsb
  2951 00008C41 20C0                <1> 	and	al, al
  2952 00008C43 75FB                <1> 	jnz	short sysexec_12
  2953 00008C45 EBEC                <1> 	jmp	short sysexec_11
  2954                              <1> 	;
  2955                              <1> 	; 1:
  2956                              <1> 		; mov (sp)+,r5 / r5 now contains address of list of 
  2957                              <1> 			     ; / pointers to arguments to be passed
  2958                              <1> 		; mov $1,u.quit / u.quit determines handling of quits;
  2959                              <1> 			      ; / u.quit = 1 take quit
  2960                              <1> 		; mov $1,u.intr / u.intr determines handling of 
  2961                              <1> 			     ; / interrupts; u.intr = 1 take interrupt
  2962                              <1> 		; mov $rtssym,30 / emt trap vector set to take 
  2963                              <1> 			       ; / system routine
  2964                              <1> 		; mov $fpsym,*10 / reserved instruction trap vector 
  2965                              <1> 			       ; / set to take system routine
  2966                              <1> 		; mov $sstack,sp / stack space used during swapping
  2967                              <1> 		; mov r5,-(sp) / save arguments pointer on stack
  2968                              <1> 		; mov $ecore,r5 / r5 has end of core
  2969                              <1> 		; mov $core,r4 / r4 has start of users core
  2970                              <1> 		; mov r4,u.base / u.base has start of users core
  2971                              <1> 		; mov (sp),r2 / move arguments list pointer into r2
  2972                              <1> 	; 1:
  2973                              <1> 		; tst (r2)+ / argument char = "nul"
  2974                              <1> 		; bne 1b
  2975                              <1> 		; tst -(r2) / decrement r2 by 2; r2 has addr of 
  2976                              <1> 			  ; / end of argument pointer list
  2977                              <1> 	; 1:
  2978                              <1> 	     ; / move arguments to bottom of users core
  2979                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
  2980                              <1> 		; cmp r2,(sp) / is r2 = beginning of argument
  2981                              <1> 			    ; / ptr list
  2982                              <1> 		; blo 1f / branch to 1f when all arguments
  2983                              <1> 		       ; / are moved
  2984                              <1> 		; mov -(r2),r3 / (r3) last non zero argument ptr
  2985                              <1> 	; 2:
  2986                              <1> 		; tstb (r3)+
  2987                              <1> 		; bne 2b / scan argument for \0 (nul)
  2988                              <1> 
  2989                              <1> 	; 2:
  2990                              <1> 		; movb -(r3),-(r5) / move argument char 
  2991                              <1> 				 ; / by char starting at "ecore"
  2992                              <1> 		; cmp r3,(r2) / moved all characters in 
  2993                              <1> 			    ; / this argument
  2994                              <1> 		; bhi 2b / branch 2b if not
  2995                              <1> 		; mov r5,(r4)+ / move r5 into top of users core;
  2996                              <1> 			     ; / r5 has pointer to nth arg
  2997                              <1> 		; br 1b / string
  2998                              <1> 	; 1:
  2999                              <1> 		; clrb -(r5)
  3000                              <1> 		; bic $1,r5 / make r5 even, r5 points to 
  3001                              <1> 			; / last word of argument strings
  3002                              <1> 		; mov $core,r2
  3003                              <1> 	
  3004                              <1> 	; 1: / move argument pointers into core following 
  3005                              <1> 	      ; / argument strings
  3006                              <1> 		; cmp r2,r4
  3007                              <1> 		; bhis 1f / branch to 1f when all pointers
  3008                              <1> 			; / are moved
  3009                              <1> 		; mov (r2)+,-(r5)
  3010                              <1> 		; br 1b
  3011                              <1> 	; 1:
  3012                              <1> 		; sub $core,r4 / gives number of arguments *2
  3013                              <1> 		; asr r4 / divide r4 by 2 to calculate 
  3014                              <1> 		       ; / the number of args stored
  3015                              <1> 		; mov r4,-(r5) / save number of arguments ahead
  3016                              <1> 			     ; / of the argument pointers
  3017                              <1> sysexec_13:
  3018                              <1> 	; 19/10/2015
  3019                              <1> 	; 18/10/2015
  3020                              <1> 	; 29/07/2015
  3021                              <1> 	; 25/07/2015
  3022                              <1> 	; 24/07/2015
  3023                              <1> 	; 20/07/2015
  3024                              <1> 	; 25/06/2015
  3025                              <1> 	; 24/06/2015
  3026                              <1> 	; 23/06/2015
  3027                              <1> 	;
  3028                              <1> 	; moving arguments to [ecore] is OK here..
  3029                              <1> 	; 18/10/2015
  3030 00008C47 89EC                <1> 	mov 	esp, ebp ; (**) restore kernel stack pointer
  3031                              <1> 	; ebx = beginning addres of argument list pointers
  3032                              <1> 	;	in user's stack
  3033                              <1> 	; 19/10/2015
  3034 00008C49 2B1D[34B80000]      <1> 	sub 	ebx, [ecore]
  3035 00008C4F 81C300F0BFFF        <1> 	add     ebx, (ECORE - PAGE_SIZE)
  3036                              <1> 			; end of core - 4096 (last page)
  3037                              <1> 			; (virtual address)
  3038 00008C55 891D[40B80000]      <1> 	mov	[argv], ebx
  3039 00008C5B 891D[ECB70000]      <1> 	mov	[u.break], ebx ; available user memory
  3040                              <1> 	;
  3041 00008C61 29C0                <1> 	sub	eax, eax
  3042 00008C63 C705[E4B70000]2000- <1> 	mov	dword [u.count], 32 ; Executable file header size
  3042 00008C6B 0000                <1>
  3043                              <1> 		; mov $14,u.count
  3044 00008C6D C705[D0B70000]-     <1> 	mov	dword [u.fofp], u.off
  3044 00008C73 [DCB70000]          <1>
  3045                              <1> 		; mov $u.off,u.fofp
  3046 00008C77 A3[DCB70000]        <1> 	mov	[u.off], eax ; 0
  3047                              <1> 		; clr u.off / set offset in file to be read to zero
  3048                              <1> 	; 25/07/2015
  3049 00008C7C A3[E0B70000]        <1> 	mov	[u.base], eax ; 0, start of user's core (virtual)
  3050                              <1> 	; 25/06/2015 
  3051 00008C81 66A1[A0B70000]      <1> 	mov	ax, [ii]
  3052                              <1> 	; AX = i-number of the executable file
  3053 00008C87 E892090000          <1> 	call	readi
  3054                              <1> 		; jsr r0,readi / read in first six words of 
  3055                              <1> 			; / user's file, starting at $core
  3056                              <1> 		; mov sp,r5 / put users stack address in r5
  3057                              <1> 		; sub $core+40.,r5 / subtract $core +40, 
  3058                              <1> 				; / from r5 (leaves number of words
  3059                              <1> 				; / less 26 available for
  3060                              <1> 			     	; / program in user core
  3061                              <1> 		; mov r5,u.count /
  3062                              <1> 	; 25/06/2015
  3063 00008C8C 8B0D[ECB70000]      <1> 	mov	ecx, [u.break] ; top of user's stack (physical addr.)
  3064 00008C92 890D[E4B70000]      <1> 	mov	[u.count], ecx ; save for overrun check
  3065                              <1> 	;
  3066 00008C98 8B0D[E8B70000]      <1> 	mov	ecx, [u.nread]
  3067 00008C9E 890D[ECB70000]      <1> 	mov	[u.break], ecx ; virtual address (offset from start)
  3068 00008CA4 80F920              <1> 	cmp	cl, 32
  3069 00008CA7 7540                <1>         jne     short sysexec_15
  3070                              <1> 	;:
  3071                              <1> 	; 25/06/2015
  3072                              <1> 	; Retro UNIX 386 v1 (32 bit) executable file header format
  3073                              <1> 	; 18/10/2015
  3074 00008CA9 8B35[30B80000]      <1> 	mov	esi, [pcore] ; start address of user's core memory 
  3075                              <1> 		             ; (phys. start addr. of the exec. file)
  3076 00008CAF AD                  <1> 	lodsd
  3077 00008CB0 663DEB1E            <1> 	cmp	ax, 1EEBh ; EBH, 1Eh -> jump to +32
  3078 00008CB4 7533                <1> 	jne	short sysexec_15
  3079                              <1> 		; cmp core,$405 / br .+14 is first instruction 
  3080                              <1> 			      ; / if file is standard a.out format
  3081                              <1> 		; bne 1f / branch, if not standard format
  3082 00008CB6 AD                  <1> 	lodsd
  3083 00008CB7 89C1                <1> 	mov	ecx, eax ; text (code) section size
  3084 00008CB9 AD                  <1> 	lodsd
  3085 00008CBA 01C1                <1> 	add	ecx, eax ; + data section size (initialized data)
  3086                              <1> 		; mov core+2,r5 / put 2nd word of users program in r5;
  3087                              <1> 		              ; / number of bytes in program text	
  3088                              <1> 		; sub $14,r5 / subtract 12
  3089 00008CBC 89CB                <1> 	mov	ebx, ecx
  3090                              <1> 	;
  3091                              <1> 	; 25/06/2015
  3092                              <1> 	; NOTE: These are for next versions of Retro UNIX 386
  3093                              <1> 	;	and SINGLIX operating systems (as code template).
  3094                              <1> 	;	Current Retro UNIX 386 v1 files can be max. 64KB
  3095                              <1> 	;	due to RUFS (floppy disk file system) restriction...
  3096                              <1> 	;	Overrun is not possible for current version. 	
  3097                              <1> 	;
  3098 00008CBE AD                  <1> 	lodsd	
  3099 00008CBF 01C3                <1> 	add	ebx, eax ; + bss section size (for overrun checking)
  3100 00008CC1 3B1D[E4B70000]      <1> 	cmp	ebx, [u.count]
  3101 00008CC7 7711                <1> 	ja	short sysexec_14  ; program overruns stack !
  3102                              <1> 	;
  3103                              <1> 	; 24/07/2015
  3104                              <1> 	; add bss section size to [u.break]
  3105 00008CC9 0105[ECB70000]      <1> 	add 	[u.break], eax
  3106                              <1> 	;
  3107 00008CCF 83E920              <1> 	sub	ecx, 32  ; header size (already loaded)
  3108                              <1> 	;cmp	ecx, [u.count]
  3109                              <1> 	;jnb	short sysexec_16
  3110                              <1> 		; cmp r5,u.count /
  3111                              <1> 		; bgt 1f / branch if r5 greater than u.count
  3112 00008CD2 890D[E4B70000]      <1> 	mov	[u.count], ecx ; required read count
  3113                              <1> 		; mov r5,u.count
  3114                              <1> 	;
  3115 00008CD8 EB2A                <1> 	jmp	short sysexec_16
  3116                              <1> 	;
  3117                              <1> sysexec_14:
  3118                              <1> 	; 23/06/2015
  3119                              <1> 	; insufficient (out of) memory
  3120 00008CDA C705[15B80000]0100- <1> 	mov	dword [u.error], ERR_MINOR_IM ; 1
  3120 00008CE2 0000                <1>
  3121 00008CE4 E9D8F3FFFF          <1> 	jmp	error
  3122                              <1> 	;
  3123                              <1> sysexec_15:
  3124                              <1> 	; 25/06/2015
  3125 00008CE9 0FB715[98B40000]    <1>         movzx   edx, word [i.size] ; file size
  3126 00008CF0 29CA                <1> 	sub	edx, ecx ; file size - loaded bytes
  3127 00008CF2 7627                <1> 	jna	short sysexec_17 ; no need to next read
  3128 00008CF4 01D1                <1> 	add	ecx, edx ; [i.size]
  3129 00008CF6 3B0D[E4B70000]      <1> 	cmp	ecx, [u.count] ; overrun check (!)
  3130 00008CFC 77DC                <1> 	ja	short sysexec_14
  3131 00008CFE 8915[E4B70000]      <1> 	mov	[u.count], edx
  3132                              <1> sysexec_16:
  3133 00008D04 66A1[A0B70000]      <1> 	mov	ax, [ii] ; i-number
  3134 00008D0A E80F090000          <1> 	call	readi
  3135                              <1> 		; add core+10,u.nread / add size of user data area 
  3136                              <1> 		                    ; / to u.nread
  3137                              <1> 		; br 2f
  3138                              <1> 	; 1:
  3139                              <1> 		; jsr r0,readi / read in rest of file
  3140                              <1> 	; 2:
  3141 00008D0F 8B0D[E8B70000]      <1> 	mov	ecx, [u.nread]
  3142 00008D15 010D[ECB70000]      <1> 	add	[u.break], ecx
  3143                              <1> 		; mov u.nread,u.break / set users program break to end of 
  3144                              <1> 				    ; / user code
  3145                              <1> 		; add $core+14,u.break / plus data area
  3146                              <1> sysexec_17: ; 20/07/2015
  3147                              <1> 	;mov	ax, [ii] ;rgc i-number
  3148 00008D1B E804090000          <1> 	call	iclose
  3149                              <1> 		; jsr r0,iclose / does nothing
  3150 00008D20 31C0                <1>         xor     eax, eax
  3151 00008D22 FEC0                <1> 	inc	al
  3152 00008D24 66A3[04B80000]      <1> 	mov	[u.intr], ax ; 1 (interrupt/time-out is enabled)
  3153 00008D2A 66A3[06B80000]      <1> 	mov	[u.quit], ax ; 1 ('crtl+brk' signal is enabled) 
  3154                              <1> 	; 02/07/2015
  3155 00008D30 833D[1DB80000]00    <1>         cmp	dword [u.ppgdir], 0  ; is the caller sys_init (kernel) ?
  3156 00008D37 770C                <1> 	ja	short sysexec_18 ; no, the caller is user process
  3157                              <1> 	; If the caller is kernel (sys_init), 'sysexec' will come here
  3158 00008D39 8B15[E8A70000]      <1> 	mov	edx, [k_page_dir] ; kernel's page directory
  3159 00008D3F 8915[1DB80000]      <1> 	mov	[u.ppgdir], edx ; next time 'sysexec' must not come here 
  3160                              <1> sysexec_18:
  3161                              <1> 	; 18/10/2015
  3162                              <1> 	; 05/08/2015
  3163                              <1> 	; 29/07/2015
  3164 00008D45 8B2D[40B80000]      <1> 	mov	ebp, [argv] ; user's stack pointer must point to argument
  3165                              <1> 			    ; list pointers (argument count)
  3166 00008D4B FA                  <1> 	cli
  3167 00008D4C 8B25[84A70000]      <1>         mov     esp, [tss.esp0]  ; ring 0 (kernel) stack pointer
  3168                              <1> 	;mov   	esp, [u.sp] ; Restore Kernel stack
  3169                              <1> 			    ; for this process	 
  3170                              <1> 	;add	esp, 20 ; --> EIP, CS, EFLAGS, ESP, SS
  3171                              <1> 	;xor	eax, eax ; 0
  3172 00008D52 FEC8                <1> 	dec	al ; eax = 0
  3173 00008D54 66BA2300            <1> 	mov	dx, UDATA
  3174 00008D58 6652                <1> 	push	dx  ; user's stack segment
  3175 00008D5A 55                  <1> 	push	ebp ; user's stack pointer
  3176                              <1> 		    ; (points to number of arguments)
  3177 00008D5B FB                  <1> 	sti
  3178 00008D5C 9C                  <1> 	pushfd	; EFLAGS
  3179                              <1> 		; Set IF for enabling interrupts in user mode	
  3180                              <1> 	;or	dword [esp], 200h 
  3181                              <1> 	;
  3182                              <1> 	;mov	bx, UCODE
  3183                              <1> 	;push	bx ; user's code segment
  3184 00008D5D 6A1B                <1> 	push	UCODE
  3185                              <1> 	;push	0
  3186 00008D5F 50                  <1> 	push	eax ; EIP (=0) - start address -	
  3187                              <1> 		; clr -(r5) / popped into ps when rti in 
  3188                              <1> 			  ; / sysrele is executed
  3189                              <1> 		; mov $core,-(r5) / popped into pc when rti 
  3190                              <1> 		                ; / in sysrele is executed
  3191                              <1> 		;mov r5,0f / load second copyz argument
  3192                              <1> 		;tst -(r5) / decrement r5
  3193 00008D60 8925[B8B70000]      <1> 	mov	[u.sp], esp ; 29/07/2015
  3194                              <1> 	; 05/08/2015
  3195                              <1> 	; Remedy of a General Protection Fault during 'iretd' is here !
  3196                              <1> 	; ('push dx' would cause to general protection fault, 
  3197                              <1> 	; after 'pop ds' etc.)
  3198                              <1> 	;
  3199                              <1> 	;; push dx ; ds (UDATA)
  3200                              <1> 	;; push dx ; es (UDATA)
  3201                              <1> 	;; push dx ; fs (UDATA)
  3202                              <1> 	;; push dx ; gs (UDATA)
  3203                              <1> 	;
  3204                              <1> 	; This is a trick to prevent general protection fault
  3205                              <1> 	; during 'iretd' intruction at the end of 'sysrele' (in u1.s):
  3206 00008D66 8EC2                <1> 	mov 	es, dx ; UDATA
  3207 00008D68 06                  <1> 	push 	es ; ds (UDATA)
  3208 00008D69 06                  <1> 	push 	es ; es (UDATA)
  3209 00008D6A 06                  <1> 	push 	es ; fs (UDATA)
  3210 00008D6B 06                  <1> 	push	es ; gs (UDATA)
  3211 00008D6C 66BA1000            <1> 	mov	dx, KDATA
  3212 00008D70 8EC2                <1> 	mov	es, dx
  3213                              <1> 	;
  3214                              <1> 	;; pushad simulation
  3215 00008D72 89E5                <1> 	mov	ebp, esp ; esp before pushad
  3216 00008D74 50                  <1> 	push	eax ; eax (0)
  3217 00008D75 50                  <1> 	push	eax ; ecx (0)
  3218 00008D76 50                  <1> 	push	eax ; edx (0)
  3219 00008D77 50                  <1> 	push	eax ; ebx (0)
  3220 00008D78 55                  <1> 	push	ebp ; esp before pushad
  3221 00008D79 50                  <1> 	push	eax ; ebp (0)
  3222 00008D7A 50                  <1> 	push	eax ; esi (0)		
  3223 00008D7B 50                  <1> 	push	eax ; edi (0)	
  3224                              <1> 	;
  3225 00008D7C A3[C0B70000]        <1> 	mov	[u.r0], eax ; eax = 0
  3226 00008D81 8925[BCB70000]      <1> 	mov	[u.usp], esp
  3227                              <1> 		; mov r5,u.r0 /
  3228                              <1> 		; sub $16.,r5 / skip 8 words
  3229                              <1> 		; mov r5,u.sp / assign user stack pointer value, 
  3230                              <1> 		;             / effectively zeroes all regs
  3231                              <1> 			    ; / when sysrele is executed
  3232                              <1> 		; jsr r0,copyz; core; 0:0 / zero user's core
  3233                              <1> 		; clr u.break
  3234                              <1> 		; mov r5,sp / point sp to user's stack
  3235                              <1> 	;
  3236 00008D87 E958F3FFFF          <1> 	jmp	sysret0
  3237                              <1> 	;jmp	sysret
  3238                              <1> 		; br sysret3 / return to core image at $core
  3239                              <1> 
  3240                              <1> get_argp:
  3241                              <1> 	; 18/10/2015 (nbase, ncount)
  3242                              <1> 	; 21/07/2015
  3243                              <1> 	; 24/06/2015 (Retro UNIX 386 v1)
  3244                              <1> 	; Get (virtual) address of argument from user's core memory
  3245                              <1> 	;
  3246                              <1> 	; INPUT:
  3247                              <1> 	;	esi = virtual address of argument pointer
  3248                              <1> 	; OUTPUT:
  3249                              <1> 	;	eax = virtual address of argument
  3250                              <1> 	;
  3251                              <1> 	; Modified registers: EAX, EBX, ECX, EDX, ESI 
  3252                              <1> 	;
  3253 00008D8C 833D[1DB80000]00    <1>  	cmp     dword [u.ppgdir], 0 ; /etc/init ?
  3254                              <1> 				    ; (the caller is kernel)
  3255 00008D93 7667                <1>         jna     short get_argpk 
  3256                              <1> 	;
  3257 00008D95 89F3                <1>      	mov	ebx, esi
  3258 00008D97 E8FEA9FFFF          <1> 	call	get_physical_addr ; get physical address
  3259 00008D9C 0F8289000000        <1>         jc      get_argp_err
  3260 00008DA2 A3[38B80000]        <1> 	mov 	[nbase], eax ; physical address	
  3261 00008DA7 66890D[3CB80000]    <1> 	mov	[ncount], cx ; remain byte count in page (1-4096)
  3262 00008DAE B804000000          <1> 	mov	eax, 4 ; 21/07/2015
  3263 00008DB3 6639C1              <1> 	cmp	cx, ax ; 4
  3264 00008DB6 735D                <1> 	jnb	short get_argp2
  3265 00008DB8 89F3                <1> 	mov	ebx, esi
  3266 00008DBA 01CB                <1> 	add	ebx, ecx
  3267 00008DBC E8D9A9FFFF          <1> 	call	get_physical_addr ; get physical address
  3268 00008DC1 7268                <1> 	jc	short get_argp_err
  3269                              <1> 	;push	esi
  3270 00008DC3 89C6                <1> 	mov	esi, eax
  3271 00008DC5 66870D[3CB80000]    <1> 	xchg	cx, [ncount]
  3272 00008DCC 8735[38B80000]      <1> 	xchg	esi, [nbase]
  3273 00008DD2 B504                <1> 	mov	ch, 4
  3274 00008DD4 28CD                <1> 	sub	ch, cl
  3275                              <1> get_argp0:
  3276 00008DD6 AC                  <1> 	lodsb
  3277 00008DD7 6650                <1> 	push	ax
  3278 00008DD9 FEC9                <1> 	dec	cl
  3279 00008DDB 75F9                <1>         jnz     short get_argp0
  3280 00008DDD 8B35[38B80000]      <1> 	mov	esi, [nbase]
  3281                              <1> 	; 21/07/2015
  3282 00008DE3 0FB6C5              <1> 	movzx	eax, ch
  3283 00008DE6 0105[38B80000]      <1> 	add	[nbase], eax
  3284 00008DEC 662905[3CB80000]    <1> 	sub	[ncount], ax
  3285                              <1> get_argp1:
  3286 00008DF3 AC                  <1> 	lodsb
  3287 00008DF4 FECD                <1> 	dec	ch
  3288 00008DF6 743D                <1>         jz      short get_argp3
  3289 00008DF8 6650                <1>         push	ax
  3290 00008DFA EBF7                <1> 	jmp     short get_argp1
  3291                              <1> get_argpk:
  3292                              <1> 	; Argument is in kernel's memory space
  3293 00008DFC 66C705[3CB80000]00- <1> 	mov	word [ncount], PAGE_SIZE ; 4096
  3293 00008E04 10                  <1>
  3294 00008E05 8935[38B80000]      <1> 	mov	[nbase], esi
  3295 00008E0B 8305[38B80000]04    <1> 	add	dword [nbase], 4
  3296 00008E12 8B06                <1> 	mov	eax, [esi] ; virtual addr. = physcal addr.
  3297 00008E14 C3                  <1> 	retn
  3298                              <1> get_argp2:
  3299                              <1> 	; 21/07/2015
  3300                              <1> 	;mov	eax, 4
  3301 00008E15 8B15[38B80000]      <1> 	mov 	edx, [nbase] ; 18/10/2015
  3302 00008E1B 0105[38B80000]      <1> 	add	[nbase], eax
  3303 00008E21 662905[3CB80000]    <1> 	sub	[ncount], ax
  3304                              <1> 	;
  3305 00008E28 8B02                <1> 	mov	eax, [edx]
  3306 00008E2A C3                  <1> 	retn
  3307                              <1> get_argp_err:
  3308 00008E2B A3[15B80000]        <1> 	mov	[u.error], eax
  3309 00008E30 E98CF2FFFF          <1> 	jmp	error
  3310                              <1> get_argp3:
  3311 00008E35 B103                <1> 	mov	cl, 3
  3312                              <1> get_argp4:
  3313 00008E37 C1E008              <1> 	shl	eax, 8
  3314 00008E3A 665A                <1> 	pop	dx
  3315 00008E3C 88D0                <1> 	mov 	al, dl
  3316 00008E3E E2F7                <1>         loop    get_argp4
  3317                              <1> 	;pop	esi
  3318 00008E40 C3                  <1> 	retn	
  3319                              <1> 
  3320                              <1> sysfstat: 
  3321                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3322                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  3323                              <1> 	;
  3324                              <1> 	; 'sysfstat' is identical to 'sysstat' except that it operates
  3325                              <1> 	; on open files instead of files given by name. It puts the
  3326                              <1> 	; buffer address on the stack, gets the i-number and
  3327                              <1> 	; checks to see if the file is open for reading or writing.
  3328                              <1> 	; If the file is open for writing (i-number is negative)
  3329                              <1> 	; the i-number is set positive and a branch into 'sysstat'
  3330                              <1> 	; is made.	
  3331                              <1> 	;
  3332                              <1> 	; Calling sequence:
  3333                              <1> 	;	sysfstat; buf
  3334                              <1> 	; Arguments:
  3335                              <1> 	;	buf - buffer address
  3336                              <1> 	;
  3337                              <1> 	; Inputs: *u.r0 - file descriptor
  3338                              <1> 	; Outputs: buffer is loaded with file information
  3339                              <1> 	; ...............................................................
  3340                              <1> 	;				
  3341                              <1> 	; Retro UNIX 8086 v1 modification:
  3342                              <1> 	;       'sysfstat' system call has two arguments; so,
  3343                              <1> 	;	* 1st argument, file descriptor is in BX register
  3344                              <1> 	;	* 2nd argument, buf is pointed to by CX register
  3345                              <1> 
  3346                              <1> 	; / set status of open file
  3347                              <1> 		; jsr r0,arg; u.off / put buffer address in u.off
  3348 00008E41 51                  <1> 	push	ecx
  3349                              <1> 		; mov u.off,-(sp) / put buffer address on the stack
  3350                              <1> 		; mov *u.r0,r1 / put file descriptor in r1
  3351                              <1> 		; jsr r0,getf / get the files i-number
  3352                              <1> 	; BX = file descriptor (file number)
  3353 00008E42 E8FF000000          <1> 	call	getf1
  3354 00008E47 6621C0              <1> 	and	ax, ax ; i-number of the file
  3355                              <1> 		; tst	r1 / is it 0?
  3356                              <1> 	;jz	error
  3357                              <1> 		; beq error3 / yes, error
  3358 00008E4A 750F                <1> 	jnz	short sysfstat1
  3359 00008E4C C705[15B80000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
  3359 00008E54 0000                <1>
  3360 00008E56 E966F2FFFF          <1> 	jmp	error
  3361                              <1> sysfstat1:
  3362 00008E5B 80FC80              <1> 	cmp	ah, 80h
  3363 00008E5E 7223                <1>         jb      short sysstat1
  3364                              <1> 		; bgt 1f / if i-number is negative (open for writing)
  3365 00008E60 66F7D8              <1> 	neg	ax
  3366                              <1> 		; neg r1 / make it positive, then branch
  3367 00008E63 EB1E                <1> 	jmp	short sysstat1
  3368                              <1> 		; br 1f / to 1f
  3369                              <1> sysstat:
  3370                              <1> 	; 18/10/2015
  3371                              <1> 	; 07/10/2015
  3372                              <1> 	; 02/09/2015
  3373                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3374                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  3375                              <1> 	;
  3376                              <1> 	; 'sysstat' gets the status of a file. Its arguments are the
  3377                              <1> 	; name of the file and buffer address. The buffer is 34 bytes
  3378                              <1> 	; long and information about the file placed in it.	
  3379                              <1> 	; sysstat calls 'namei' to get the i-number of the file.
  3380                              <1> 	; Then 'iget' is called to get i-node in core. The buffer
  3381                              <1> 	; is then loaded and the results are given in the UNIX
  3382                              <1> 	; Programmers Manual sysstat (II).	
  3383                              <1> 	;
  3384                              <1> 	; Calling sequence:
  3385                              <1> 	;	sysstat; name; buf
  3386                              <1> 	; Arguments:
  3387                              <1> 	;	name - points to the name of the file
  3388                              <1> 	;	buf - address of a 34 bytes buffer
  3389                              <1> 	; Inputs: -
  3390                              <1> 	; Outputs: buffer is loaded with file information
  3391                              <1> 	; ...............................................................
  3392                              <1> 	;				
  3393                              <1> 	; Retro UNIX 8086 v1 modification: 
  3394                              <1> 	;       'sysstat' system call has two arguments; so,
  3395                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
  3396                              <1> 	;	to get sysstat system call arguments from the user;
  3397                              <1> 	;	* 1st argument, name is pointed to by BX register
  3398                              <1> 	;	* 2nd argument, buf is pointed to by CX register
  3399                              <1> 	;
  3400                              <1> 	;	NOTE: Retro UNIX 8086 v1 'arg2' routine gets these
  3401                              <1> 	;	      arguments which were in these registers;
  3402                              <1> 	;	      but, it returns by putting the 1st argument
  3403                              <1> 	;	      in 'u.namep' and the 2nd argument
  3404                              <1> 	;	      on top of stack. (1st argument is offset of the
  3405                              <1> 	;	      file/path name in the user's program segment.)		 	
  3406                              <1> 	
  3407                              <1> 	; / ; name of file; buffer - get files status
  3408                              <1> 		; jsr r0,arg2 / get the 2 arguments
  3409 00008E65 891D[D8B70000]      <1> 	mov	[u.namep], ebx
  3410 00008E6B 51                  <1> 	push	ecx
  3411 00008E6C E80C010000          <1> 	call	namei
  3412                              <1> 		; jsr r0,namei / get the i-number for the file
  3413                              <1> 	;jc	error
  3414                              <1> 		; br error3 / no such file, error
  3415 00008E71 7310                <1> 	jnc	short sysstat1
  3416                              <1> 	; pop 	ecx
  3417                              <1> sysstat_err0:
  3418                              <1> 	; 'file not found !' error
  3419 00008E73 C705[15B80000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  3419 00008E7B 0000                <1>
  3420 00008E7D E93FF2FFFF          <1> 	jmp	error
  3421                              <1> 
  3422 00008E82 00                  <1> statx: db 0
  3423                              <1> 
  3424                              <1> sysstat1: ; 1:
  3425 00008E83 E891070000          <1> 	call	iget
  3426                              <1> 		; jsr r0,iget / get the i-node into core
  3427                              <1> 	; 07/10/2015 (ax = [ii], inode number)
  3428                              <1> 	; 02/09/2015
  3429 00008E88 8F05[E0B70000]      <1> 	pop	dword [u.base]
  3430                              <1> 		; mov (sp)+,r3 / move u.off to r3 (points to buffer)
  3431 00008E8E E858000000          <1> 	call	sysstat_gpa ; get physical address
  3432 00008E93 730A                <1> 	jnc 	short sysstat2
  3433                              <1> sysstat_err1:
  3434 00008E95 A3[15B80000]        <1> 	mov	dword [u.error], eax ; error code
  3435 00008E9A E922F2FFFF          <1> 	jmp	error
  3436                              <1> sysstat2:
  3437 00008E9F A0[A0B70000]        <1> 	mov 	al, [ii] ; 07/10/2015 (result of 'iget' call, above)
  3438 00008EA4 AA                  <1> 	stosb
  3439 00008EA5 FF05[E0B70000]      <1> 	inc 	dword [u.base]
  3440 00008EAB 6649                <1> 	dec 	cx
  3441 00008EAD 7505                <1> 	jnz	short sysstat3
  3442 00008EAF E837000000          <1> 	call	sysstat_gpa
  3443                              <1> 	;jc	short sysstat_err1
  3444                              <1> sysstat3:
  3445 00008EB4 A0[A1B70000]        <1> 	mov 	al, [ii+1] ; 07/10/2015 (result of 'iget' call, above)
  3446 00008EB9 AA                  <1> 	stosb
  3447                              <1> 		; mov r1,(r3)+ / put i-number in 1st word of buffer
  3448 00008EBA FF05[E0B70000]      <1> 	inc 	dword [u.base]
  3449                              <1> 	;dec 	word [u.pcount]
  3450 00008EC0 6649                <1> 	dec	cx
  3451 00008EC2 7505                <1> 	jnz	short sysstat4
  3452 00008EC4 E822000000          <1> 	call	sysstat_gpa
  3453                              <1> 	;jc	short sysstat_err1	
  3454                              <1> sysstat4:
  3455 00008EC9 BE[94B40000]        <1> 	mov	esi, inode
  3456                              <1> 		; mov $inode,r2 / r2 points to i-node
  3457                              <1> sysstat5: ; 1:
  3458 00008ECE A4                  <1> 	movsb
  3459                              <1> 		; mov (r2)+,(r3)+ / move rest of i-node to buffer
  3460 00008ECF FF05[E0B70000]      <1> 	inc 	dword [u.base]
  3461                              <1> 	;dec 	word [u.pcount]
  3462 00008ED5 6649                <1> 	dec	cx
  3463 00008ED7 7505                <1> 	jnz	short sysstat6
  3464 00008ED9 E80D000000          <1> 	call	sysstat_gpa
  3465                              <1> 	;jc	short sysstat_err1
  3466                              <1> sysstat6:		
  3467 00008EDE 81FE[B4B40000]      <1> 	cmp	esi, inode + 32
  3468                              <1> 		; cmp r2,$inode+32 / done?
  3469 00008EE4 75E8                <1> 	jne	short sysstat5
  3470                              <1> 		; bne 1b / no, go back
  3471 00008EE6 E9F6F1FFFF          <1> 	jmp	sysret
  3472                              <1> 		; br sysret3 / return through sysret
  3473                              <1> 	;
  3474                              <1> sysstat_gpa: ; get physical address of file status buffer
  3475                              <1> 	; 02/09/2015
  3476 00008EEB 8B1D[E0B70000]      <1> 	mov 	ebx, [u.base]
  3477                              <1> 	; 07/10/2015
  3478 00008EF1 E8A4A8FFFF          <1> 	call	get_physical_addr ; get physical address
  3479                              <1> 	;jc	short sysstat_gpa1
  3480 00008EF6 729D                <1> 	jc	short sysstat_err1
  3481                              <1> 	; 18/10/2015
  3482 00008EF8 89C7                <1> 	mov	edi, eax ; physical address
  3483                              <1> 	;mov	[u.pcount], cx ; remain bytes in page
  3484                              <1> ;sysstat_gpa1:
  3485 00008EFA C3                  <1> 	retn
  3486                              <1> 
  3487                              <1> fclose:
  3488                              <1> 	; 18/06/2015 (Retro UNIX 386 v1 - Beginning)
  3489                              <1> 	;            (32 bit offset pointer modification)
  3490                              <1> 	; 19/04/2013 - 12/01/2014 (Retro UNIX 8086 v1)
  3491                              <1> 	;
  3492                              <1> 	; Given the file descriptor (index to the u.fp list)
  3493                              <1> 	; 'fclose' first gets the i-number of the file via 'getf'.
  3494                              <1> 	; If i-node is active (i-number > 0) the entry in 
  3495                              <1> 	; u.fp list is cleared. If all the processes that opened
  3496                              <1> 	; that file close it, then fsp etry is freed and the file
  3497                              <1> 	; is closed. If not a return is taken. 
  3498                              <1> 	; If the file has been deleted while open, 'anyi' is called
  3499                              <1> 	; to see anyone else has it open, i.e., see if it is appears
  3500                              <1> 	; in another entry in the fsp table. Upon return from 'anyi'
  3501                              <1> 	; a check is made to see if the file is special.	
  3502                              <1> 	;
  3503                              <1> 	; INPUTS ->
  3504                              <1> 	;    r1 - contains the file descriptor (value=0,1,2...)
  3505                              <1> 	;    u.fp - list of entries in the fsp table
  3506                              <1> 	;    fsp - table of entries (4 words/entry) of open files.	 
  3507                              <1> 	; OUTPUTS ->
  3508                              <1> 	;    r1 - contains the same file descriptor
  3509                              <1> 	;    r2 - contains i-number
  3510                              <1> 	;
  3511                              <1> 	; ((AX = R1))
  3512                              <1> 	; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))
  3513                              <1> 	;
  3514                              <1> 	; Retro UNIX 8086 v1 modification : CF = 1
  3515                              <1> 	;              if i-number of the file is 0. (error)  	
  3516                              <1> 	;
  3517 00008EFB 0FB7D0              <1> 	movzx	edx, ax ; **
  3518 00008EFE 6650                <1> 	push	ax ; ***
  3519                              <1> 		; mov r1,-(sp) / put r1 on the stack (it contains 
  3520                              <1> 			     ; / the index to u.fp list)
  3521 00008F00 E83F000000          <1> 	call	getf
  3522                              <1> 		; jsr r0,getf / r1 contains i-number, 
  3523                              <1> 			    ; / cdev has device =, u.fofp 
  3524                              <1> 			    ; / points to 3rd word of fsp entry
  3525 00008F05 6683F801            <1> 	cmp	ax, 1 ; r1
  3526                              <1> 		; tst r1 / is i-number 0?
  3527 00008F09 7236                <1> 	jb	short fclose_2
  3528                              <1> 		; beq 1f / yes, i-node not active so return
  3529                              <1> 		; tst (r0)+ / no, jump over error return
  3530 00008F0B 89D3                <1> 	mov	ebx, edx ; **
  3531 00008F0D 6689C2              <1> 	mov 	dx, ax ; *
  3532                              <1> 		; mov r1,r2 / move i-number to r2 ;*
  3533                              <1> 		; mov (sp),r1 / restore value of r1 from the stack
  3534                              <1> 			    ; / which is index to u.fp ; **
  3535 00008F10 C683[C6B70000]00    <1> 	mov	byte [ebx+u.fp], 0
  3536                              <1> 		; clrb u.fp(r1) / clear that entry in the u.fp list
  3537 00008F17 8B1D[D0B70000]      <1> 	mov	ebx, [u.fofp]
  3538                              <1> 		; mov u.fofp,r1 / r1 points to 3rd word in fsp entry
  3539                              <1> fclose_0:
  3540 00008F1D FE4B04              <1> 	dec	byte [ebx+4] ; 18/06/2015
  3541                              <1> 		; decb 2(r1) / decrement the number of processes 
  3542                              <1> 			   ; / that have opened the file
  3543 00008F20 791F                <1> 	jns	short fclose_2 ; jump if not negative (jump if bit 7 is 0)	 
  3544                              <1> 		; bge 1f / if all processes haven't closed the file, return
  3545                              <1> 	;
  3546 00008F22 6652                <1> 	push	dx ;*
  3547                              <1> 		; mov r2,-(sp) / put r2 on the stack (i-number)
  3548 00008F24 6631C0              <1> 	xor	ax, ax ; 0
  3549 00008F27 668943FC            <1> 	mov	[ebx-4], ax ; 0
  3550                              <1> 		; clr -4(r1) / clear 1st word of fsp entry
  3551 00008F2B 8A4305              <1> 	mov	al, [ebx+5] ; 18/06/2015
  3552                              <1> 		; tstb	3(r1) / has this file been deleted
  3553 00008F2E 20C0                <1> 	and	al, al
  3554 00008F30 7408                <1> 	jz	short fclose_1
  3555                              <1> 		; beq 2f / no, branch
  3556 00008F32 6689D0              <1> 	mov	ax, dx ; *
  3557                              <1> 		; mov r2,r1 / yes, put i-number back into r1
  3558                              <1> 	; AX = inode number
  3559 00008F35 E868040000          <1> 	call	anyi
  3560                              <1> 		; jsr r0,anyi / free all blocks related to i-number
  3561                              <1> 			    ; / check if file appears in fsp again
  3562                              <1> fclose_1: ; 2:
  3563 00008F3A 6658                <1> 	pop	ax ; *
  3564                              <1> 		; mov (sp)+,r1 / put i-number back into r1
  3565 00008F3C E8E3060000          <1> 	call	iclose ; close if it is special file 
  3566                              <1> 		; jsr r0,iclose / check to see if its a special file
  3567                              <1> fclose_2: ; 1:
  3568 00008F41 6658                <1> 	pop	ax ; ***
  3569                              <1> 		; mov (sp)+,r1 / put index to u.fp back into r1
  3570 00008F43 C3                  <1> 	retn
  3571                              <1> 		; rts r0
  3572                              <1> 
  3573                              <1> getf:	; / get the device number and the i-number of an open file
  3574                              <1> 	; 13/05/2015
  3575                              <1> 	; 11/05/2015 (Retro UNIX 386 v1 - Beginning)
  3576                              <1> 	; 19/04/2013 - 18/11/2013 (Retro UNIX 8086 v1)
  3577                              <1> 	;
  3578 00008F44 89C3                <1> 	mov	ebx, eax
  3579                              <1> getf1: ;; Calling point from 'rw1' (23/05/2013)
  3580 00008F46 83FB0A              <1> 	cmp	ebx, 10
  3581                              <1> 		; cmp r1,$10. / user limited to 10 open files
  3582 00008F49 730A                <1>         jnb	short getf2 ; 13/05/2015
  3583                              <1> 	;jnb     error
  3584                              <1> 		; bhis error3 / u.fp is table of users open files, 
  3585                              <1> 			    ; / index in fsp table
  3586 00008F4B 8A9B[C6B70000]      <1> 	mov	bl, [ebx+u.fp]
  3587                              <1> 		; movb	u.fp(r1),r1 / r1 contains number of entry 
  3588                              <1> 		                  ; / in fsp table
  3589 00008F51 08DB                <1> 	or	bl, bl
  3590 00008F53 7503                <1> 	jnz	short getf3
  3591                              <1> 	;jz	short getf4
  3592                              <1> 		; beq 1f / if its zero return
  3593                              <1> getf2:
  3594                              <1> 	; 'File not open !' error (ax=0)
  3595 00008F55 29C0                <1> 	sub	eax, eax
  3596 00008F57 C3                  <1> 	retn
  3597                              <1> getf3:	
  3598                              <1> 	; Retro UNIX 386 v1 modification ! (11/05/2015)
  3599                              <1> 	;
  3600                              <1> 	; 'fsp' table (10 bytes/entry)
  3601                              <1> 	; bit 15				   bit 0
  3602                              <1> 	; ---|-------------------------------------------
  3603                              <1> 	; r/w|		i-number of open file
  3604                              <1> 	; ---|-------------------------------------------
  3605                              <1> 	;		   device number
  3606                              <1> 	; -----------------------------------------------
  3607                              <1> 	; offset pointer, r/w pointer to file (bit 0-15)
  3608                              <1> 	; -----------------------------------------------
  3609                              <1> 	; offset pointer, r/w pointer to file (bit 16-31)
  3610                              <1> 	; ----------------------|------------------------
  3611                              <1> 	;  flag that says file 	| number of processes
  3612                              <1> 	;   has been deleted	| that have file open 
  3613                              <1> 	; ----------------------|------------------------
  3614                              <1> 	;
  3615 00008F58 B80A000000          <1> 	mov	eax, 10
  3616 00008F5D F6E3                <1> 	mul	bl
  3617 00008F5F BB[8EB50000]        <1> 	mov	ebx, fsp - 6 ; the 3rd word in the fsp entry
  3618 00008F64 01C3                <1> 	add	ebx, eax
  3619                              <1> 		; asl r1
  3620                              <1> 		; asl r1 / multiply by 8 to get index into 
  3621                              <1> 		       ; / fsp table entry
  3622                              <1> 		; asl r1
  3623                              <1> 		; add $fsp-4,r1 / r1 is pointing at the 3rd word 
  3624                              <1> 			      ; / in the fsp entry
  3625 00008F66 891D[D0B70000]      <1> 	mov	[u.fofp], ebx
  3626                              <1> 		; mov r1,u.fofp / save address of 3rd word 
  3627                              <1> 			      ; / in fsp entry in u.fofp
  3628 00008F6C 4B                  <1> 	dec	ebx
  3629 00008F6D 4B                  <1> 	dec	ebx
  3630 00008F6E 668B03              <1> 	mov	ax, [ebx]
  3631                              <1> 	;mov	[cdev], al ; ;;Retro UNIX 8086 v1 ! 
  3632 00008F71 66A3[A4B70000]      <1> 	mov	[cdev], ax ; ;;in fact (!) 
  3633                              <1> 			     ;;dev number is in 1 byte
  3634                              <1> 		; mov -(r1),cdev / remove the device number  cdev
  3635 00008F77 4B                  <1> 	dec	ebx
  3636 00008F78 4B                  <1> 	dec	ebx
  3637 00008F79 668B03              <1> 	mov	ax, [ebx]
  3638                              <1> 		; mov -(r1),r1 / and the i-number  r1
  3639                              <1> getf4:	; 1:
  3640 00008F7C C3                  <1> 	retn
  3641                              <1> 		; rts r0
  3642                              <1> 
  3643                              <1> namei:
  3644                              <1> 	; 04/12/2015 (14 byte file names)
  3645                              <1> 	; 18/10/2015 (nbase, ncount)
  3646                              <1> 	; 12/10/2015
  3647                              <1> 	; 21/08/2015
  3648                              <1> 	; 18/07/2015
  3649                              <1> 	; 02/07/2015
  3650                              <1> 	; 17/06/2015
  3651                              <1> 	; 16/06/2015 (Retro UNIX 386 v1 - Beginning)
  3652                              <1> 	; 24/04/2013 - 31/07/2013 (Retro UNIX 8086 v1)
  3653                              <1> 	;
  3654                              <1> 	; 'namei' takes a file path name and returns i-number of
  3655                              <1> 	; the file in the current directory or the root directory
  3656                              <1> 	; (if the first character of the pathname is '/').	
  3657                              <1> 	;
  3658                              <1> 	; INPUTS ->
  3659                              <1> 	;    u.namep - points to a file path name
  3660                              <1> 	;    u.cdir - i-number of users directory
  3661                              <1> 	;    u.cdev - device number on which user directory resides	
  3662                              <1> 	; OUTPUTS ->
  3663                              <1> 	;    r1 - i-number of file
  3664                              <1> 	;    cdev
  3665                              <1> 	;    u.dirbuf - points to directory entry where a match 
  3666                              <1> 	;               occurs in the search for file path name.
  3667                              <1> 	;	        If no match u.dirb points to the end of 
  3668                              <1> 	;               the directory and r1 = i-number of the current
  3669                              <1> 	;	        directory.	
  3670                              <1> 	; ((AX = R1))
  3671                              <1> 	;
  3672                              <1> 	; (Retro UNIX Prototype : 07/10/2012 - 05/01/2013, UNIXCOPY.ASM)
  3673                              <1>         ; ((Modified registers: eDX, eBX, eCX, eSI, eDI, eBP))  
  3674                              <1> 	;
  3675                              <1> 
  3676 00008F7D 66A1[C4B70000]      <1> 	mov	ax, [u.cdir]
  3677                              <1> 		; mov u.cdir,r1 / put the i-number of current directory
  3678                              <1> 			      ; / in r1
  3679 00008F83 668B15[0AB80000]    <1> 	mov	dx, [u.cdrv]
  3680 00008F8A 668915[A4B70000]    <1> 	mov	[cdev], dx 	    ; NOTE: Retro UNIX 8086 v1 
  3681                              <1> 				    ; device/drive number is in 1 byte, 
  3682                              <1> 				    ; not in 1 word!
  3683                              <1> 		; mov u.cdev,cdev / device number for users directory 
  3684                              <1> 				; / into cdev
  3685                              <1> 	; 12/10/2015
  3686                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
  3687                              <1>       	 ; convert virtual (pathname) addr to physical address
  3688 00008F91 E82C010000          <1> 	call    trans_addr_nmbp ; 12/10/2015
  3689                              <1> 		; esi = physical address of [u.namep]
  3690                              <1> 		; ecx = byte count in the page
  3691 00008F96 803E2F              <1> 	cmp	byte [esi], '/'
  3692                              <1> 		; cmpb *u.namep,$'/ / is first char in file name a /
  3693 00008F99 751E                <1> 	jne	short namei_1
  3694                              <1> 		; bne 1f
  3695 00008F9B FF05[D8B70000]      <1> 	inc	dword [u.namep]
  3696                              <1> 		; inc u.namep / go to next char
  3697 00008FA1 6649                <1> 	dec	cx ; remain byte count in the page
  3698 00008FA3 7506                <1> 	jnz	short namei_0
  3699                              <1> 	; 12/10/2015
  3700 00008FA5 E818010000          <1> 	call	trans_addr_nmbp ; convert virtual address to physical
  3701                              <1> 		; esi = physical address (page start + offset)
  3702                              <1> 		; ecx = byte count in the page
  3703 00008FAA 4E                  <1> 	dec	esi
  3704                              <1> namei_0:
  3705 00008FAB 46                  <1> 	inc 	esi  ; go to next char
  3706 00008FAC 66A1[AEB70000]      <1> 	mov	ax, [rootdir] ; 09/07/2013
  3707                              <1> 		; mov rootdir,r1 / put i-number of rootdirectory in r1
  3708 00008FB2 C605[A4B70000]00    <1> 	mov	byte [cdev], 0
  3709                              <1> 		; clr cdev / clear device number
  3710                              <1> namei_1: ; 1:
  3711 00008FB9 F606FF              <1> 	test	byte [esi], 0FFh
  3712 00008FBC 74BE                <1> 	jz	short getf4
  3713                              <1> 	;jz      nig
  3714                              <1> 		; tstb *u.namep / is the character in file name a nul
  3715                              <1> 		; beq nig / yes, end of file name reached; 
  3716                              <1> 			; / branch to "nig"
  3717                              <1> namei_2: ; 1:
  3718                              <1> 	; 18/10/2015
  3719 00008FBE 8935[38B80000]      <1> 	mov 	[nbase], esi
  3720 00008FC4 66890D[3CB80000]    <1> 	mov 	[ncount], cx
  3721                              <1> 	;
  3722                              <1> 	;mov	dx, 2
  3723 00008FCB B202                <1> 	mov	dl, 2 ; user flag (read, non-owner)
  3724 00008FCD E859060000          <1> 	call	access
  3725                              <1> 		; jsr r0,access; 2 / get i-node with i-number r1
  3726                              <1> 	; 'access' will not return here if user has not "r" permission !
  3727 00008FD2 66F705[94B40000]00- <1> 	test 	word [i.flgs], 4000h
  3727 00008FDA 40                  <1>
  3728                              <1> 		; bit $40000,i.flgs / directory i-node?
  3729 00008FDB 746A                <1>         jz      short namei_err
  3730                              <1> 		; beq error3 / no, got an error
  3731                              <1> 	; 16/06/2015 - 32 bit modifications (Retro UNIX 386 v1)
  3732 00008FDD 31C0                <1> 	xor	eax, eax
  3733 00008FDF A3[DCB70000]        <1> 	mov	[u.off], eax ; 0
  3734 00008FE4 66A1[98B40000]      <1> 	mov	ax, [i.size]
  3735 00008FEA A3[D4B70000]        <1> 	mov	[u.dirp], eax
  3736                              <1> 		; mov i.size,u.dirp / put size of directory in u.dirp
  3737                              <1> 		; clr u.off / u.off is file offset used by user
  3738 00008FEF C705[D0B70000]-     <1> 	mov	dword [u.fofp], u.off
  3738 00008FF5 [DCB70000]          <1>
  3739                              <1> 		; mov $u.off,u.fofp / u.fofp is a pointer to 
  3740                              <1> 				  ; / the offset portion of fsp entry
  3741                              <1> namei_3: ; 2:
  3742 00008FF9 C705[E0B70000]-     <1> 	mov	dword [u.base], u.dirbuf
  3742 00008FFF [F2B70000]          <1>
  3743                              <1> 		; mov $u.dirbuf,u.base / u.dirbuf holds a file name 
  3744                              <1> 				    ; / copied from a directory
  3745 00009003 C705[E4B70000]1000- <1> 	mov 	dword [u.count], 16 ; 04/12/2015 (10 -> 16) 	
  3745 0000900B 0000                <1>
  3746                              <1>  		; mov $10.,u.count / u.count is byte count 
  3747                              <1> 				 ; / for reads and writes
  3748 0000900D 66A1[A0B70000]      <1> 	mov 	ax, [ii]
  3749                              <1> 	; 31/07/2013 ('namei_r') - 16/06/2015 ('u.kcall')
  3750 00009013 FE05[27B80000]      <1>  	inc     byte [u.kcall] ; the caller is 'namei' sign	
  3751 00009019 E800060000          <1>     	call	readi
  3752                              <1> 		; jsr r0,readi / read 10. bytes of file 
  3753                              <1> 		      ; with i-number (r1); i.e. read a directory entry
  3754 0000901E 8B0D[E8B70000]      <1> 	mov 	ecx, [u.nread]
  3755 00009024 09C9                <1> 	or 	ecx, ecx
  3756                              <1> 		; tst u.nread
  3757 00009026 741B                <1> 	jz	short nib
  3758                              <1> 		; ble nib / gives error return
  3759                              <1> 	;
  3760 00009028 668B1D[F2B70000]    <1> 	mov 	bx, [u.dirbuf]
  3761 0000902F 6621DB              <1> 	and 	bx, bx       
  3762                              <1> 		; tst u.dirbuf /
  3763 00009032 7522                <1> 	jnz	short namei_4
  3764                              <1> 		; bne 3f / branch when active directory entry 
  3765                              <1> 		       ; / (i-node word in entry non zero)
  3766 00009034 A1[DCB70000]        <1> 	mov	eax, [u.off]
  3767 00009039 83E810              <1> 	sub	eax, 16 ; 04/12/2015 (10 -> 16) 
  3768 0000903C A3[D4B70000]        <1> 	mov	[u.dirp], eax
  3769                              <1> 		; mov u.off,u.dirp
  3770                              <1> 		; sub $10.,u.dirp
  3771 00009041 EBB6                <1> 	jmp	short namei_3
  3772                              <1> 		; br 2b
  3773                              <1> 
  3774                              <1> 	; 18/07/2013
  3775                              <1> nib: 
  3776 00009043 31C0                <1> 	xor	eax, eax  ; xor ax, ax ; ax = 0 -> file not found 
  3777 00009045 F9                  <1> 	stc
  3778                              <1> nig:
  3779 00009046 C3                  <1> 	retn
  3780                              <1> 
  3781                              <1> namei_err:
  3782                              <1> 	; 16/06/2015
  3783 00009047 C705[15B80000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a directory !' error
  3783 0000904F 0000                <1>
  3784 00009051 E96BF0FFFF          <1> 	jmp	error
  3785                              <1> 
  3786                              <1> namei_4: ; 3:
  3787                              <1> 	; 18/10/2015
  3788                              <1> 	; 12/10/2015
  3789                              <1> 	; 21/08/2015
  3790                              <1> 	; 18/07/2015
  3791 00009056 8B2D[D8B70000]      <1> 	mov	ebp, [u.namep]
  3792                              <1> 		; mov u.namep,r2 / u.namep points into a file name string
  3793 0000905C BF[F4B70000]        <1> 	mov 	edi, u.dirbuf + 2
  3794                              <1> 		; mov $u.dirbuf+2,r3 / points to file name of directory entry
  3795                              <1> 	; 18/10/2015
  3796 00009061 8B35[38B80000]      <1> 	mov	esi, [nbase]	
  3797 00009067 668B0D[3CB80000]    <1> 	mov	cx, [ncount]
  3798                              <1> 	;
  3799 0000906E 6621C9              <1> 	and	cx, cx
  3800 00009071 7505                <1> 	jnz	short namei_5	
  3801                              <1> 	;
  3802 00009073 E850000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
  3803                              <1> 		; esi = physical address (page start + offset)
  3804                              <1> 		; ecx = byte count in the page
  3805                              <1> namei_5: ; 3:
  3806 00009078 45                  <1> 	inc	ebp ; 18/07/2015
  3807 00009079 AC                  <1> 	lodsb   ; mov al, [esi] ; inc esi (al = r4)
  3808                              <1> 		; movb (r2)+,r4 / move a character from u.namep string into r4
  3809 0000907A 08C0                <1> 	or 	al, al
  3810 0000907C 741D                <1> 	jz 	short namei_7
  3811                              <1> 		; beq 3f / if char is nul, then the last char in string
  3812                              <1> 			; / has been moved
  3813 0000907E 3C2F                <1> 	cmp	al, '/'
  3814                              <1> 		; cmp r4,$'/ / is char a </>
  3815 00009080 7419                <1> 	je 	short namei_7
  3816                              <1> 		; beq 3f	
  3817                              <1> 	; 12/10/2015
  3818 00009082 6649                <1> 	dec	cx ; remain byte count in the page
  3819 00009084 7505                <1> 	jnz	short namei_6
  3820 00009086 E83D000000          <1> 	call	trans_addr_nm ; convert virtual address to physical
  3821                              <1> 		; esi = physical address (page start + offset)
  3822                              <1> 		; ecx = byte count in the page
  3823                              <1> namei_6:
  3824 0000908B 81FF[02B80000]      <1>         cmp     edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
  3825                              <1> 		; cmp r3,$u.dirbuf+10. / have I checked
  3826                              <1> 				     ; / all 8 bytes of file name
  3827 00009091 74E5                <1> 	je	short namei_5
  3828                              <1> 		; beq 3b
  3829 00009093 AE                  <1> 	scasb	
  3830                              <1> 		; cmpb (r3)+,r4 / compare char in u.namep string to file name 
  3831                              <1> 			      ; / char read from directory
  3832 00009094 74E2                <1> 	je 	short namei_5
  3833                              <1> 		; beq 3b / branch if chars match
  3834                              <1> 
  3835 00009096 E95EFFFFFF          <1>         jmp    namei_3 ; 2b
  3836                              <1> 		; br 2b / file names do not match go to next directory entry
  3837                              <1> namei_7: ; 3:
  3838 0000909B 81FF[02B80000]      <1> 	cmp	edi, u.dirbuf + 16 ; 04/12/2015 (10 -> 16) 
  3839                              <1> 		; cmp r3,$u.dirbuf+10. / if equal all 8 bytes were matched
  3840 000090A1 740A                <1> 	je	short namei_8
  3841                              <1> 		; beq 3f
  3842 000090A3 8A27                <1> 	mov 	ah, [edi]
  3843                              <1> 	;inc 	edi 
  3844 000090A5 20E4                <1> 	and 	ah, ah
  3845                              <1> 		; tstb (r3)+ /
  3846 000090A7 0F854CFFFFFF        <1>         jnz     namei_3
  3847                              <1> 		; bne 2b
  3848                              <1> namei_8: ; 3
  3849 000090AD 892D[D8B70000]      <1> 	mov	[u.namep], ebp ; 18/07/2015
  3850                              <1> 		; mov r2,u.namep / u.namep points to char 
  3851                              <1> 			       ; / following a / or nul
  3852                              <1> 	;mov	bx, [u.dirbuf]
  3853                              <1> 		; mov u.dirbuf,r1 / move i-node number in directory 
  3854                              <1> 				; / entry to r1
  3855 000090B3 20C0                <1> 	and 	al, al
  3856                              <1> 		; tst r4 / if r4 = 0 the end of file name reached,
  3857                              <1> 		      ;  / if r4 = </> then go to next directory
  3858                              <1> 	; mov	ax, bx
  3859 000090B5 66A1[F2B70000]      <1> 	mov 	ax, [u.dirbuf] ; 17/06/2015
  3860 000090BB 0F85FDFEFFFF        <1>         jnz     namei_2 
  3861                              <1> 		; bne 1b
  3862                              <1> 	; AX = i-number of the file
  3863                              <1> ;;nig:
  3864 000090C1 C3                  <1> 	retn
  3865                              <1> 		; tst (r0)+ / gives non-error return
  3866                              <1> ;;nib:
  3867                              <1> ;;	xor	ax, ax ; Retro UNIX 8086 v1 modification !
  3868                              <1> 		       ; ax = 0 -> file not found 
  3869                              <1> ;;	stc	; 27/05/2013
  3870                              <1> ;;	retn
  3871                              <1> 		; rts r0
  3872                              <1> 
  3873                              <1> trans_addr_nmbp:
  3874                              <1> 	; 18/10/2015
  3875                              <1> 	; 12/10/2015
  3876 000090C2 8B2D[D8B70000]      <1> 	mov 	ebp, [u.namep]
  3877                              <1> trans_addr_nm: 
  3878                              <1> 	; Convert virtual (pathname) address to physical address
  3879                              <1> 	; (Retro UNIX 386 v1 feature only !)
  3880                              <1> 	; 18/10/2015
  3881                              <1> 	; 12/10/2015 (u.pnbase & u.pncount has been removed from code)
  3882                              <1> 	; 02/07/2015
  3883                              <1> 	; 17/06/2015
  3884                              <1> 	; 16/06/2015
  3885                              <1> 	;
  3886                              <1> 	; INPUTS: 
  3887                              <1> 	;	ebp = pathname address (virtual) ; [u.namep]
  3888                              <1> 	;	[u.pgdir] = user's page directory
  3889                              <1> 	; OUTPUT:
  3890                              <1> 	;       esi = physical address of the pathname
  3891                              <1> 	;	ecx = remain byte count in the page
  3892                              <1> 	;
  3893                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX, ESI)
  3894                              <1> 	;
  3895 000090C8 833D[1DB80000]00    <1>         cmp     dword [u.ppgdir], 0  ; /etc/init ? (sysexec)
  3896 000090CF 7618                <1> 	jna	short trans_addr_nmk ; the caller is os kernel;
  3897                              <1> 				     ; it is already physical address
  3898 000090D1 50                  <1>    	push	eax	
  3899 000090D2 89EB                <1> 	mov	ebx, ebp ; [u.namep] ; pathname address (virtual)
  3900 000090D4 E8C1A6FFFF          <1>        	call	get_physical_addr ; get physical address
  3901 000090D9 7204                <1> 	jc	short tr_addr_nm_err
  3902                              <1> 	; 18/10/2015
  3903                              <1> 	; eax = physical address 
  3904                              <1> 	; cx = remain byte count in page (1-4096) 
  3905                              <1> 		; 12/10/2015 (cx = [u.pncount])
  3906 000090DB 89C6                <1> 	mov	esi, eax ; 12/10/2015 (esi=[u.pnbase])
  3907 000090DD 58                  <1> 	pop	eax 
  3908 000090DE C3                  <1> 	retn
  3909                              <1> 
  3910                              <1> tr_addr_nm_err:
  3911 000090DF A3[15B80000]        <1> 	mov	[u.error], eax
  3912                              <1> 	;pop 	eax
  3913 000090E4 E9D8EFFFFF          <1> 	jmp	error
  3914                              <1> 
  3915                              <1> trans_addr_nmk:
  3916                              <1> 	; 12/10/2015
  3917                              <1> 	; 02/07/2015
  3918 000090E9 8B35[D8B70000]      <1> 	mov	esi, [u.namep]  ; [u.pnbase]
  3919 000090EF 66B90010            <1> 	mov	cx, PAGE_SIZE ; 4096 ; [u.pncount]
  3920 000090F3 C3                  <1> 	retn
  3921                              <1> 
  3922                              <1> syschdir:
  3923                              <1> 	; / makes the directory specified in the argument
  3924                              <1> 	; / the current directory
  3925                              <1> 	;
  3926                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3927                              <1> 	; 19/06/2013 (Retro UNIX 8086 v1)
  3928                              <1> 	;
  3929                              <1> 	; 'syschdir' makes the directory specified in its argument
  3930                              <1> 	; the current working directory.
  3931                              <1> 	;
  3932                              <1> 	; Calling sequence:
  3933                              <1> 	;	syschdir; name
  3934                              <1> 	; Arguments:
  3935                              <1> 	;	name - address of the path name of a directory
  3936                              <1> 	;	       terminated by nul byte.	
  3937                              <1> 	; Inputs: -
  3938                              <1> 	; Outputs: -
  3939                              <1> 	; ...............................................................
  3940                              <1> 	;				
  3941                              <1> 	; Retro UNIX 8086 v1 modification:
  3942                              <1> 	;	 The user/application program puts address of 
  3943                              <1> 	;	 the path name in BX register as 'syschdir' 
  3944                              <1> 	; 	 system call argument.
  3945                              <1> 
  3946 000090F4 891D[D8B70000]      <1> 	mov	[u.namep], ebx
  3947                              <1> 		;jsr r0,arg; u.namep / u.namep points to path name
  3948 000090FA E87EFEFFFF          <1> 	call	namei
  3949                              <1> 		; jsr r0,namei / find its i-number
  3950                              <1> 	;jc	error
  3951                              <1> 		; br error3
  3952 000090FF 730F                <1> 	jnc	short syschdir0
  3953                              <1> 	; 'directory not found !' error
  3954 00009101 C705[15B80000]0C00- <1> 	mov	dword [u.error], ERR_DIR_NOT_FOUND ; 12
  3954 00009109 0000                <1>
  3955 0000910B E9B1EFFFFF          <1> 	jmp	error
  3956                              <1> syschdir0:
  3957 00009110 E816050000          <1> 	call	access
  3958                              <1> 		; jsr r0,access; 2 / get i-node into core
  3959 00009115 66F705[94B40000]00- <1> 	test	word [i.flgs], 4000h
  3959 0000911D 40                  <1>
  3960                              <1> 		; bit $40000,i.flgs / is it a directory?
  3961                              <1> 	;jz	error 
  3962                              <1> 		; beq error3 / no error
  3963 0000911E 750F                <1> 	jnz	short syschdir1
  3964 00009120 C705[15B80000]1300- <1> 	mov	dword [u.error], ERR_NOT_DIR ; 'not a valid directory !'
  3964 00009128 0000                <1>
  3965 0000912A E992EFFFFF          <1> 	jmp	error
  3966                              <1> syschdir1:
  3967 0000912F 66A3[C4B70000]      <1> 	mov	[u.cdir], ax
  3968                              <1> 		; mov r1,u.cdir / move i-number to users 
  3969                              <1> 			      ; / current directory
  3970 00009135 66A1[A4B70000]      <1> 	mov	ax, [cdev]
  3971 0000913B 66A3[0AB80000]      <1> 	mov	[u.cdrv], ax
  3972                              <1> 		; mov cdev,u.cdev / move its device to users 
  3973                              <1> 			        ; / current device
  3974 00009141 E99BEFFFFF          <1> 	jmp	sysret
  3975                              <1> 		; br sysret3
  3976                              <1> 	
  3977                              <1> syschmod: ; < change mode of file >
  3978                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  3979                              <1> 	; 20/06/2013 - 07/07/2013 (Retro UNIX 8086 v1)
  3980                              <1> 	;
  3981                              <1> 	; 'syschmod' changes mode of the file whose name is given as
  3982                              <1> 	; null terminated string pointed to by 'name' has it's mode 
  3983                              <1> 	; changed to 'mode'.
  3984                              <1> 	;
  3985                              <1> 	; Calling sequence:
  3986                              <1> 	;	syschmod; name; mode
  3987                              <1> 	; Arguments:
  3988                              <1> 	;	name - address of the file name
  3989                              <1> 	;	       terminated by null byte.
  3990                              <1> 	;	mode - (new) mode/flags < attributes >
  3991                              <1> 	;	
  3992                              <1> 	; Inputs: -
  3993                              <1> 	; Outputs: -
  3994                              <1> 	; ...............................................................
  3995                              <1> 	;				
  3996                              <1> 	; Retro UNIX 8086 v1 modification: 
  3997                              <1> 	;       'syschmod' system call has two arguments; so,
  3998                              <1> 	;	* 1st argument, name is pointed to by BX register
  3999                              <1> 	;	* 2nd argument, mode is in CX register
  4000                              <1> 	;
  4001                              <1> 	; Mode bits (Flags):
  4002                              <1> 	;	bit 0 - write permission for non-owner (1)
  4003                              <1> 	;	bit 1 - read permission for non-owner (2)
  4004                              <1> 	;	bit 2 - write permission for owner (4)
  4005                              <1> 	;	bit 3 - read permission for owner (8)
  4006                              <1> 	;	bit 4 - executable flag (16) 	
  4007                              <1> 	;	bit 5 - set user ID on execution flag (32) 
  4008                              <1> 	;	bit 6,7,8,9,10,11 are not used (undefined)
  4009                              <1> 	;	bit 12 - large file flag (4096)
  4010                              <1> 	;	bit 13 - file has modified flag (always on) (8192)
  4011                              <1> 	;	bit 14 - directory flag (16384)
  4012                              <1> 	;	bit 15 - 'i-node is allocated' flag (32768)
  4013                              <1> 
  4014                              <1> 	; / name; mode
  4015 00009146 E814000000          <1> 	call	isown
  4016                              <1> 		;jsr r0,isown / get the i-node and check user status
  4017 0000914B 66F705[94B40000]00- <1> 	test	word [i.flgs], 4000h
  4017 00009153 40                  <1>
  4018                              <1> 		; bit	$40000,i.flgs / directory?
  4019 00009154 7402                <1> 	jz	short syschmod1
  4020                              <1> 		; beq 2f / no
  4021                              <1> 	; AL = (new) mode
  4022 00009156 24CF                <1> 	and	al, 0CFh ; 11001111b (clears bit 4 & 5)
  4023                              <1> 		; bic $60,r2 / su & ex / yes, clear set user id and 
  4024                              <1> 			   ; / executable modes
  4025                              <1> syschmod1: ; 2:
  4026 00009158 A2[94B40000]        <1> 	mov	[i.flgs], al	
  4027                              <1> 		; movb r2,i.flgs / move remaining mode to i.flgs
  4028 0000915D EB42                <1> 	jmp	short isown1
  4029                              <1> 		; br 1f
  4030                              <1> 
  4031                              <1> isown:
  4032                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4033                              <1> 	; 04/05/2013 - 07/07/2013 (Retro UNIX 8086 v1)
  4034                              <1> 	;
  4035                              <1> 	; 'isown' is given a file name (the 1st argument).
  4036                              <1> 	;  It find the i-number of that file via 'namei' 
  4037                              <1> 	;  then gets the i-node into core via 'iget'.
  4038                              <1> 	;  It then tests to see if the user is super user. 
  4039                              <1> 	;  If not, it cheks to see if the user is owner of 
  4040                              <1> 	;  the file. If he is not an error occurs.
  4041                              <1> 	;  If user is the owner 'setimod' is called to indicate
  4042                              <1> 	;  the inode has been modificed and the 2nd argument of
  4043                              <1> 	;  the call is put in r2.
  4044                              <1> 	;
  4045                              <1> 	; INPUTS ->
  4046                              <1> 	;    arguments of syschmod and syschown calls
  4047                              <1> 	; OUTPUTS ->
  4048                              <1> 	;    u.uid - id of user
  4049                              <1> 	;    imod - set to a 1
  4050                              <1> 	;    r2 - contains second argument of the system call				 	
  4051                              <1> 	;
  4052                              <1> 	;   ((AX=R2) output as 2nd argument)
  4053                              <1> 	;
  4054                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  4055                              <1> 	;
  4056                              <1> 		; jsr r0,arg2 / u.namep points to file name
  4057                              <1> 	;; ! 2nd argument on top of stack !
  4058                              <1> 	;; 22/06/2015 - 32 bit modifications
  4059                              <1> 	;; 07/07/2013
  4060 0000915F 891D[D8B70000]      <1> 	mov	[u.namep], ebx ;; 1st argument
  4061 00009165 51                  <1> 	push 	ecx ;; 2nd argument
  4062                              <1> 	;;
  4063 00009166 E812FEFFFF          <1> 	call	namei
  4064                              <1> 		; jsr r0,namei / get its i-number
  4065                              <1>        ; Retro UNIX 8086 v1 modification !
  4066                              <1>        ; ax = 0 -> file not found 
  4067                              <1> 	;and	ax, ax
  4068                              <1> 	;jz	error
  4069                              <1> 	;jc	error ; 27/05/2013
  4070                              <1> 		; br error3
  4071 0000916B 730F                <1> 	jnc	short isown0
  4072                              <1> 	; 'file not found !' error
  4073 0000916D C705[15B80000]0C00- <1> 	mov	dword [u.error], ERR_FILE_NOT_FOUND ; 12
  4073 00009175 0000                <1>
  4074 00009177 E945EFFFFF          <1> 	jmp	error
  4075                              <1> isown0:
  4076 0000917C E898040000          <1> 	call	iget
  4077                              <1> 		; jsr r0,iget / get i-node into core
  4078 00009181 A0[0CB80000]        <1> 	mov	al, [u.uid] ; 02/08/2013
  4079 00009186 08C0                <1> 	or	al, al
  4080                              <1> 		; tstb u.uid / super user?
  4081 00009188 7417                <1> 	jz	short isown1
  4082                              <1> 		; beq 1f / yes, branch
  4083 0000918A 3A05[97B40000]      <1> 	cmp	al, [i.uid]
  4084                              <1> 		; cmpb i.uid,u.uid / no, is this the owner of
  4085                              <1> 				 ; / the file
  4086                              <1> 	;jne	error
  4087                              <1> 		; beq 1f / yes
  4088                              <1> 		; jmp error3 / no, error
  4089 00009190 740F                <1> 	je	short isown1
  4090                              <1> 
  4091 00009192 C705[15B80000]0B00- <1> 	mov	dword [u.error], ERR_NOT_OWNER  ; 11
  4091 0000919A 0000                <1>
  4092                              <1> 			;  'permission denied !' error
  4093 0000919C E920EFFFFF          <1> 	jmp	error
  4094                              <1> isown1: ; 1:
  4095 000091A1 E881040000          <1> 	call	setimod
  4096                              <1> 		; jsr r0,setimod / indicates 
  4097                              <1> 		;	       ; / i-node has been modified
  4098 000091A6 58                  <1> 	pop	eax ; 2nd argument
  4099                              <1> 		; mov (sp)+,r2 / mode is put in r2 
  4100                              <1> 		       ; / (u.off put on stack with 2nd arg)
  4101 000091A7 C3                  <1> 	retn
  4102                              <1> 		; rts r0
  4103                              <1> 
  4104                              <1> ;;arg:  ; < get system call arguments >
  4105                              <1> 	; 'arg' extracts an argument for a routine whose call is 
  4106                              <1> 	; of form:
  4107                              <1> 	;	sys 'routine' ; arg1
  4108                              <1> 	;		or
  4109                              <1> 	;	sys 'routine' ; arg1 ; arg2
  4110                              <1> 	;		or
  4111                              <1> 	;	sys 'routine' ; arg1;...;arg10 (sys exec) 
  4112                              <1> 	;	
  4113                              <1> 	; INPUTS ->
  4114                              <1> 	;    u.sp+18 - contains a pointer to one of arg1..argn
  4115                              <1> 	;	This pointers's value is actually the value of
  4116                              <1> 	;	update pc at the the trap to sysent (unkni) is
  4117                              <1> 	;	made to process the sys instruction
  4118                              <1> 	;    r0 - contains the return address for the routine
  4119                              <1> 	;	that called arg. The data in the word pointer 
  4120                              <1> 	;	to by the return address is used as address
  4121                              <1> 	;	in which the extracted argument is stored   		
  4122                              <1> 	;    	
  4123                              <1> 	; OUTPUTS ->
  4124                              <1> 	;    'address' - contains the extracted argument 
  4125                              <1> 	;    u.sp+18 - is incremented by 2 
  4126                              <1> 	;    r1 - contains the extracted argument
  4127                              <1> 	;    r0 - points to the next instruction to be
  4128                              <1> 	;	 executed in the calling routine.
  4129                              <1> 	;
  4130                              <1>   
  4131                              <1> 	; mov u.sp,r1
  4132                              <1> 	; mov *18.(r1),*(r0)+ / put argument of system call
  4133                              <1> 			; / into argument of arg2
  4134                              <1> 	; add $2,18.(r1) / point pc on stack 
  4135                              <1> 			      ; / to next system argument
  4136                              <1> 	; rts r0
  4137                              <1> 
  4138                              <1> ;;arg2: ; < get system calls arguments - with file name pointer>
  4139                              <1> 	; 'arg2' takes first argument in system call
  4140                              <1> 	;  (pointer to name of the file) and puts it in location
  4141                              <1> 	;  u.namep; takes second argument and puts it in u.off
  4142                              <1> 	;  and on top of the stack
  4143                              <1> 	;	
  4144                              <1> 	; INPUTS ->
  4145                              <1> 	;    u.sp, r0
  4146                              <1> 	;    	
  4147                              <1> 	; OUTPUTS ->
  4148                              <1> 	;    u.namep
  4149                              <1> 	;    u.off 
  4150                              <1> 	;    u.off pushed on stack
  4151                              <1> 	;    r1
  4152                              <1> 	;
  4153                              <1> 
  4154                              <1> 	; jsr	r0,arg; u.namep / u.namep contains value of
  4155                              <1> 				; / first arg in sys call
  4156                              <1> 	; jsr r0,arg; u.off / u.off contains value of 
  4157                              <1> 				; / second arg in sys call
  4158                              <1> 	; mov r0,r1 / r0 points to calling routine
  4159                              <1> 	; mov (sp),r0 / put operation code back in r0
  4160                              <1> 	; mov u.off,(sp) / put pointer to second argument 
  4161                              <1> 			; / on stack
  4162                              <1> 	; jmp (r1) / return to calling routine
  4163                              <1> 
  4164                              <1> syschown: ; < change owner of file >
  4165                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  4166                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  4167                              <1> 	;
  4168                              <1> 	; 'syschown' changes the owner of the file whose name is given
  4169                              <1> 	; as null terminated string pointed to by 'name' has it's owner
  4170                              <1> 	; changed to 'owner'
  4171                              <1> 	;
  4172                              <1> 	; Calling sequence:
  4173                              <1> 	;	syschown; name; owner
  4174                              <1> 	; Arguments:
  4175                              <1> 	;	name - address of the file name
  4176                              <1> 	;	       terminated by null byte.
  4177                              <1> 	;	owner - (new) owner (number/ID)
  4178                              <1> 	;	
  4179                              <1> 	; Inputs: -
  4180                              <1> 	; Outputs: -
  4181                              <1> 	; ...............................................................
  4182                              <1> 	;				
  4183                              <1> 	; Retro UNIX 8086 v1 modification: 
  4184                              <1> 	;       'syschown' system call has two arguments; so,
  4185                              <1> 	;	* 1st argument, name is pointed to by BX register
  4186                              <1> 	;	* 2nd argument, owner number is in CX register
  4187                              <1> 	;
  4188                              <1> 	; / name; owner
  4189 000091A8 E8B2FFFFFF          <1> 	call	isown
  4190                              <1> 		; jsr r0,isown / get the i-node and check user status
  4191 000091AD 803D[0CB80000]00    <1> 	cmp 	byte [u.uid], 0 ; 02/08/2013 
  4192                              <1> 		; tstb u.uid / super user
  4193 000091B4 7418                <1> 	jz	short syschown1
  4194                              <1> 		; beq 2f / yes, 2f
  4195 000091B6 F605[94B40000]20    <1>         test    byte [i.flgs], 20h ; 32
  4196                              <1> 		; bit $40,i.flgs / no, set userid on execution?
  4197                              <1> 	;jnz	error
  4198                              <1> 		; bne 3f / yes error, could create Trojan Horses
  4199 000091BD 740F                <1> 	jz	short syschown1
  4200                              <1> 	; 'permission denied !'
  4201 000091BF C705[15B80000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS  ; 11
  4201 000091C7 0000                <1>
  4202 000091C9 E9F3EEFFFF          <1> 	jmp	error
  4203                              <1> syschown1: ; 2:
  4204                              <1> 	; AL = owner (number/ID)
  4205 000091CE A2[97B40000]        <1> 	mov	[i.uid], al ; 23/06/2015
  4206                              <1> 		;  movb	r2,i.uid / no, put the new owners id 
  4207                              <1> 			       ; / in the i-node
  4208 000091D3 E909EFFFFF          <1> 	jmp	sysret
  4209                              <1> 	; 1: 
  4210                              <1> 		; jmp sysret4
  4211                              <1> 	; 3:
  4212                              <1> 		; jmp	error
  4213                              <1> 
  4214                              <1> systime: ; / get time of year
  4215                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  4216                              <1> 	; 20/06/2013 (Retro UNIX 8086 v1)
  4217                              <1> 	;
  4218                              <1> 	; 20/06/2013
  4219                              <1> 	; 'systime' gets the time of the year.
  4220                              <1> 	; The present time is put on the stack.
  4221                              <1> 	;
  4222                              <1> 	; Calling sequence:
  4223                              <1> 	;	systime
  4224                              <1> 	; Arguments: -
  4225                              <1> 	;	
  4226                              <1> 	; Inputs: -
  4227                              <1> 	; Outputs: sp+2, sp+4 - present time
  4228                              <1> 	; ...............................................................
  4229                              <1> 	;	
  4230                              <1> 	; Retro UNIX 8086 v1 modification: 
  4231                              <1> 	;       'systime' system call will return to the user
  4232                              <1> 	;	with unix time (epoch) in DX:AX register pair
  4233                              <1> 	;
  4234                              <1> 	; 	!! Major modification on original Unix v1 'systime' 
  4235                              <1> 	;	system call for PC compatibility !!		 	
  4236                              <1> 
  4237 000091D8 E851040000          <1> 	call 	epoch
  4238 000091DD A3[C0B70000]        <1> 	mov 	[u.r0], eax
  4239                              <1> 		; mov s.time,4(sp)
  4240                              <1> 		; mov s.time+2,2(sp) / put the present time 
  4241                              <1> 				   ; / on the stack
  4242                              <1> 		; br sysret4
  4243 000091E2 E9FAEEFFFF          <1> 	jmp	sysret 
  4244                              <1> 
  4245                              <1> sysstime: ; / set time
  4246                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  4247                              <1> 	; 20/06/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  4248                              <1> 	;
  4249                              <1> 	; 'sysstime' sets the time. Only super user can use this call.
  4250                              <1> 	;
  4251                              <1> 	; Calling sequence:
  4252                              <1> 	;	sysstime
  4253                              <1> 	; Arguments: -
  4254                              <1> 	;	
  4255                              <1> 	; Inputs: sp+2, sp+4 - time system is to be set to.
  4256                              <1> 	; Outputs: -
  4257                              <1> 	; ...............................................................
  4258                              <1> 	;	
  4259                              <1> 	; Retro UNIX 8086 v1 modification: 
  4260                              <1> 	;	the user calls 'sysstime' with unix (epoch) time
  4261                              <1> 	;	(to be set) is in CX:BX register pair as two arguments.
  4262                              <1> 	; 
  4263                              <1> 	;	Retro UNIX 8086 v1 argument transfer method 2 is used
  4264                              <1> 	;	to get sysstime system call arguments from the user;
  4265                              <1> 	;	* 1st argument, lowword of unix time is in BX register
  4266                              <1> 	;	* 2nd argument, highword of unix time is in CX register		 	
  4267                              <1> 	;
  4268                              <1> 	; 	!! Major modification on original Unix v1 'sysstime' 
  4269                              <1> 	;	system call for PC compatibility !!	
  4270                              <1> 
  4271 000091E7 803D[0CB80000]00    <1> 	cmp	byte [u.uid], 0
  4272                              <1> 		; tstb u.uid / is user the super user
  4273                              <1> 	;ja	error
  4274                              <1> 		; bne error4 / no, error
  4275 000091EE 760F                <1> 	jna	short systime1
  4276                              <1> 	; 'permission denied !'
  4277 000091F0 C705[15B80000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11 
  4277 000091F8 0000                <1>
  4278 000091FA E9C2EEFFFF          <1> 	jmp	error
  4279                              <1> systime1:
  4280                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - 32 bit version)
  4281                              <1> 	; EBX = unix (epoch) time (from user)
  4282 000091FF 89D8                <1> 	mov	eax, ebx
  4283 00009201 E829040000          <1> 	call 	set_date_time
  4284                              <1> 		; mov 4(sp),s.time
  4285                              <1> 		; mov 2(sp),s.time+2 / set the system time
  4286 00009206 E9D6EEFFFF          <1> 	jmp	sysret
  4287                              <1> 		; br sysret4
  4288                              <1> 
  4289                              <1> sysbreak:
  4290                              <1> 	; 18/10/2015
  4291                              <1> 	; 07/10/2015
  4292                              <1> 	; 23/06/2015 (Retro UNIX 386 v1 - Beginning)
  4293                              <1> 	; 20/06/2013 - 24/03/2014 (Retro UNIX 8086 v1)
  4294                              <1> 	;
  4295                              <1> 	; 'sysbreak' sets the programs break points. 
  4296                              <1> 	; It checks the current break point (u.break) to see if it is
  4297                              <1> 	; between "core" and the stack (sp). If it is, it is made an
  4298                              <1> 	; even address (if it was odd) and the area between u.break
  4299                              <1> 	; and the stack is cleared. The new breakpoint is then put
  4300                              <1> 	; in u.break and control is passed to 'sysret'.
  4301                              <1> 	;
  4302                              <1> 	; Calling sequence:
  4303                              <1> 	;	sysbreak; addr
  4304                              <1> 	; Arguments: -
  4305                              <1> 	;	
  4306                              <1> 	; Inputs: u.break - current breakpoint
  4307                              <1> 	; Outputs: u.break - new breakpoint 
  4308                              <1> 	;	area between old u.break and the stack (sp) is cleared.
  4309                              <1> 	; ...............................................................
  4310                              <1> 	;	
  4311                              <1> 	; Retro UNIX 8086 v1 modification:
  4312                              <1> 	;	The user/application program puts breakpoint address
  4313                              <1> 	;       in BX register as 'sysbreak' system call argument.
  4314                              <1> 	; 	(argument transfer method 1)
  4315                              <1> 	;
  4316                              <1> 	;  NOTE: Beginning of core is 0 in Retro UNIX 8086 v1 !
  4317                              <1> 	; 	((!'sysbreak' is not needed in Retro UNIX 8086 v1!))
  4318                              <1> 	;  NOTE:
  4319                              <1> 	; 	'sysbreak' clears extended part (beyond of previous
  4320                              <1> 	;	'u.break' address) of user's memory for original unix's
  4321                              <1> 	;	'bss' compatibility with Retro UNIX 8086 v1 (19/11/2013)
  4322                              <1> 
  4323                              <1> 		; mov u.break,r1 / move users break point to r1
  4324                              <1> 		; cmp r1,$core / is it the same or lower than core?
  4325                              <1> 		; blos 1f / yes, 1f
  4326                              <1> 	; 23/06/2015
  4327 0000920B 8B2D[ECB70000]      <1> 	mov	ebp, [u.break] ; virtual address (offset)
  4328                              <1> 	;and	ebp, ebp
  4329                              <1> 	;jz	short sysbreak_3 
  4330                              <1> 	; Retro UNIX 386 v1 NOTE: u.break points to virtual address !!!
  4331                              <1> 	; (Even break point address is not needed for Retro UNIX 386 v1)
  4332 00009211 8B15[B8B70000]      <1> 	mov	edx, [u.sp] ; kernel stack at the beginning of sys call
  4333 00009217 83C20C              <1> 	add	edx, 12 ; EIP -4-> CS -4-> EFLAGS -4-> ESP (user) 
  4334                              <1> 	; 07/10/2015
  4335 0000921A 891D[ECB70000]      <1> 	mov	[u.break], ebx ; virtual address !!!
  4336                              <1> 	;
  4337 00009220 3B1A                <1> 	cmp	ebx, [edx] ; compare new break point with 
  4338                              <1> 			   ; with top of user's stack (virtual!)
  4339 00009222 7327                <1> 	jnb	short sysbreak_3
  4340                              <1> 		; cmp r1,sp / is it the same or higher 
  4341                              <1> 			  ; / than the stack?
  4342                              <1> 		; bhis 1f / yes, 1f
  4343 00009224 89DE                <1> 	mov	esi, ebx
  4344 00009226 29EE                <1> 	sub	esi, ebp ; new break point - old break point
  4345 00009228 7621                <1> 	jna	short sysbreak_3 
  4346                              <1> 	;push	ebx
  4347                              <1> sysbreak_1:
  4348 0000922A 89EB                <1> 	mov	ebx, ebp  
  4349 0000922C E869A5FFFF          <1> 	call	get_physical_addr ; get physical address
  4350 00009231 0F82A8FEFFFF        <1> 	jc	tr_addr_nm_err
  4351                              <1> 	; 18/10/2015
  4352 00009237 89C7                <1> 	mov	edi, eax 
  4353 00009239 29C0                <1> 	sub	eax, eax ; 0
  4354                              <1> 		 ; ECX = remain byte count in page (1-4096)
  4355 0000923B 39CE                <1> 	cmp	esi, ecx
  4356 0000923D 7302                <1> 	jnb	short sysbreak_2
  4357 0000923F 89F1                <1> 	mov	ecx, esi
  4358                              <1> sysbreak_2:
  4359 00009241 29CE                <1> 	sub	esi, ecx
  4360 00009243 01CD                <1> 	add	ebp, ecx
  4361 00009245 F3AA                <1> 	rep 	stosb
  4362 00009247 09F6                <1> 	or	esi, esi
  4363 00009249 75DF                <1> 	jnz	short sysbreak_1
  4364                              <1> 	;
  4365                              <1> 		; bit $1,r1 / is it an odd address
  4366                              <1> 		; beq 2f / no, its even
  4367                              <1> 		; clrb (r1)+ / yes, make it even
  4368                              <1> 	; 2: / clear area between the break point and the stack
  4369                              <1> 		; cmp r1,sp / is it higher or same than the stack
  4370                              <1> 		; bhis 1f / yes, quit
  4371                              <1> 		; clr (r1)+ / clear word
  4372                              <1> 		; br 2b / go back
  4373                              <1> 	;pop	ebx
  4374                              <1> sysbreak_3: ; 1:
  4375                              <1> 	;mov	[u.break], ebx ; virtual address !!!
  4376                              <1> 		; jsr r0,arg; u.break / put the "address" 
  4377                              <1> 			; / in u.break (set new break point)
  4378                              <1> 		; br sysret4 / br sysret
  4379 0000924B E991EEFFFF          <1> 	jmp	sysret
  4380                              <1> 
  4381                              <1> 
  4382                              <1> maknod: 
  4383                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4384                              <1> 	; 02/05/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  4385                              <1> 	;
  4386                              <1> 	; 'maknod' creates an i-node and makes a directory entry
  4387                              <1> 	; for this i-node in the current directory.
  4388                              <1> 	;
  4389                              <1> 	; INPUTS ->
  4390                              <1> 	;    r1 - contains mode
  4391                              <1> 	;    ii - current directory's i-number	
  4392                              <1> 	;    	
  4393                              <1> 	; OUTPUTS ->
  4394                              <1> 	;    u.dirbuf - contains i-number of free i-node 
  4395                              <1> 	;    i.flgs - flags in new i-node 
  4396                              <1> 	;    i.uid - filled with u.uid
  4397                              <1> 	;    i.nlks - 1 is put in the number of links
  4398                              <1> 	;    i.ctim - creation time				
  4399                              <1> 	;    i.ctim+2 - modification time
  4400                              <1> 	;    imod - set via call to setimod
  4401                              <1> 	;	
  4402                              <1> 	; ((AX = R1)) input
  4403                              <1> 	;
  4404                              <1> 	; (Retro UNIX Prototype : 
  4405                              <1> 	;	30/10/2012 - 01/03/2013, UNIXCOPY.ASM)
  4406                              <1>         ; ((Modified registers: eAX, eDX, eBX, eCX, eSI, eDI, eBP))  
  4407                              <1> 
  4408                              <1> 	; / r1 contains the mode
  4409 00009250 80CC80              <1> 	or 	ah, 80h  ; 10000000b
  4410                              <1> 		; bis	$100000,r1 / allocate flag set
  4411 00009253 6650                <1> 	push	ax
  4412                              <1> 		; mov r1,-(sp) / put mode on stack
  4413                              <1> 	; 31/07/2013
  4414 00009255 66A1[A0B70000]      <1> 	mov	ax, [ii] ; move current i-number to AX/r1
  4415                              <1> 		; mov ii,r1 / move current i-number to r1
  4416 0000925B B201                <1> 	mov	dl, 1 ; owner flag mask
  4417 0000925D E8C9030000          <1> 	call	access	
  4418                              <1> 		; jsr r0,access; 1 / get its i-node into core
  4419 00009262 6650                <1> 	push	ax
  4420                              <1> 		; mov r1,-(sp) / put i-number on stack
  4421 00009264 66B82800            <1> 	mov	ax, 40
  4422                              <1> 		; mov $40.,r1 / r1 = 40
  4423                              <1> maknod1: ; 1: / scan for a free i-node (next 4 instructions)
  4424 00009268 6640                <1> 	inc	ax
  4425                              <1> 		; inc r1 / r1 = r1 + 1
  4426 0000926A E8C1030000          <1> 	call	imap
  4427                              <1> 		; jsr r0,imap / get byte address and bit position in 
  4428                              <1> 			    ; /	inode map in r2 & m
  4429                              <1>           ; DX (MQ) has a 1 in the calculated bit position
  4430                              <1>           ; eBX (R2) has byte address of the byte with allocation bit
  4431                              <1> 	; 22/06/2015 - NOTE for next Retro UNIX version: 
  4432                              <1> 	;	       Inode count must be checked here
  4433                              <1> 	; (Original UNIX v1 did not check inode count here !?) 	
  4434 0000926F 8413                <1> 	test	[ebx], dl
  4435                              <1> 		; bitb mq,(r2) / is the i-node active
  4436 00009271 75F5                <1> 	jnz	short maknod1
  4437                              <1> 		; bne 1b / yes, try the next one
  4438 00009273 0813                <1> 	or	[ebx], dl
  4439                              <1> 		; bisb mq,(r2) / no, make it active 
  4440                              <1> 			     ; / (put a 1 in the bit map)
  4441 00009275 E89F030000          <1> 	call	iget
  4442                              <1> 		; jsr r0,iget / get i-node into core
  4443 0000927A 66F705[94B40000]00- <1> 	test	word [i.flgs], 8000h 
  4443 00009282 80                  <1>
  4444                              <1> 		; tst i.flgs / is i-node already allocated
  4445 00009283 75E3                <1> 	jnz	short maknod1	
  4446                              <1> 		; blt 1b / yes, look for another one
  4447 00009285 66A3[F2B70000]      <1> 	mov	[u.dirbuf], ax
  4448                              <1> 		; mov r1,u.dirbuf / no, put i-number in u.dirbuf
  4449 0000928B 6658                <1> 	pop	ax
  4450                              <1> 		; mov (sp)+,r1 / get current i-number back
  4451 0000928D E887030000          <1> 	call	iget
  4452                              <1> 		; jsr r0,iget / get i-node in core
  4453 00009292 E87DF7FFFF          <1> 	call	mkdir
  4454                              <1> 		; jsr r0,mkdir / make a directory entry 
  4455                              <1> 			     ; / in current directory
  4456 00009297 66A1[F2B70000]      <1> 	mov	ax, [u.dirbuf]
  4457                              <1> 		; mov u.dirbuf,r1 / r1 = new inode number
  4458 0000929D E877030000          <1> 	call	iget
  4459                              <1> 		; jsr r0,iget / get it into core
  4460                              <1> 		; jsr r0,copyz; inode; inode+32. / 0 it out
  4461 000092A2 B908000000          <1> 	mov	ecx, 8 
  4462 000092A7 31C0                <1> 	xor	eax, eax ; 0
  4463 000092A9 BF[94B40000]        <1> 	mov	edi, inode 
  4464 000092AE F3AB                <1> 	rep	stosd
  4465                              <1> 	;
  4466 000092B0 668F05[94B40000]    <1> 	pop	word [i.flgs]
  4467                              <1> 		; mov (sp)+,i.flgs / fill flags
  4468 000092B7 8A0D[0CB80000]      <1> 	mov 	cl, [u.uid] ; 02/08/2013
  4469 000092BD 880D[97B40000]      <1> 	mov 	[i.uid], cl
  4470                              <1> 		; movb u.uid,i.uid / user id	
  4471 000092C3 C605[96B40000]01    <1> 	mov     byte [i.nlks], 1
  4472                              <1> 		; movb $1,i.nlks / 1 link
  4473                              <1> 	;call	epoch ; Retro UNIX 8086 v1 modification !
  4474                              <1> 	;mov	eax, [s.time]
  4475                              <1> 	;mov 	[i.ctim], eax
  4476                              <1> 	 	; mov s.time,i.ctim / time created
  4477                              <1> 	 	; mov s.time+2,i.ctim+2 / time modified
  4478                              <1> 	; Retro UNIX 8086 v1 modification !
  4479                              <1> 	; i.ctime=0, i.ctime+2=0 and
  4480                              <1>         ; 'setimod' will set ctime of file via 'epoch'
  4481 000092CA E858030000          <1> 	call setimod
  4482                              <1> 		; jsr r0,setimod / set modified flag
  4483 000092CF C3                  <1> 	retn
  4484                              <1> 		; rts r0 / return
  4485                              <1> 
  4486                              <1> sysseek: ; / moves read write pointer in an fsp entry
  4487                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4488                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  4489                              <1> 	;
  4490                              <1> 	; 'sysseek' changes the r/w pointer of (3rd word of in an
  4491                              <1> 	; fsp entry) of an open file whose file descriptor is in u.r0.
  4492                              <1> 	; The file descriptor refers to a file open for reading or
  4493                              <1> 	; writing. The read (or write) pointer is set as follows:
  4494                              <1> 	;	* if 'ptrname' is 0, the pointer is set to offset.
  4495                              <1> 	;	* if 'ptrname' is 1, the pointer is set to its
  4496                              <1> 	;	  current location plus offset.
  4497                              <1> 	;	* if 'ptrname' is 2, the pointer is set to the
  4498                              <1> 	;	  size of file plus offset.
  4499                              <1> 	; The error bit (e-bit) is set for an undefined descriptor.
  4500                              <1> 	;
  4501                              <1> 	; Calling sequence:
  4502                              <1> 	;	sysseek; offset; ptrname
  4503                              <1> 	; Arguments:
  4504                              <1> 	;	offset - number of bytes desired to move 
  4505                              <1> 	;		 the r/w pointer
  4506                              <1> 	;	ptrname - a switch indicated above
  4507                              <1> 	;
  4508                              <1> 	; Inputs: r0 - file descriptor 
  4509                              <1> 	; Outputs: -
  4510                              <1> 	; ...............................................................
  4511                              <1> 	;	
  4512                              <1> 	; Retro UNIX 8086 v1 modification: 
  4513                              <1> 	;       'sysseek' system call has three arguments; so,
  4514                              <1> 	;	* 1st argument, file descriptor is in BX (BL) register
  4515                              <1> 	;	* 2nd argument, offset is in CX register
  4516                              <1> 	;	* 3rd argument, ptrname/switch is in DX (DL) register	
  4517                              <1> 	;	
  4518                              <1> 
  4519 000092D0 E823000000          <1> 	call	seektell
  4520                              <1> 	; AX = u.count
  4521                              <1> 	; BX = *u.fofp
  4522                              <1> 		; jsr r0,seektell / get proper value in u.count
  4523                              <1> 		; add u.base,u.count / add u.base to it
  4524 000092D5 0305[E0B70000]      <1> 	add	eax, [u.base] ; add offset (u.base) to base
  4525 000092DB 8903                <1> 	mov	[ebx], eax
  4526                              <1> 		; mov u.count,*u.fofp / put result into r/w pointer
  4527 000092DD E9FFEDFFFF          <1> 	jmp	sysret
  4528                              <1> 		; br sysret4
  4529                              <1> 
  4530                              <1> systell: ; / get the r/w pointer
  4531                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4532                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  4533                              <1> 	;
  4534                              <1> 	; Retro UNIX 8086 v1 modification:
  4535                              <1> 	; ! 'systell' does not work in original UNIX v1,
  4536                              <1> 	; 	    it returns with error !
  4537                              <1> 	; Inputs: r0 - file descriptor 
  4538                              <1> 	; Outputs: r0 - file r/w pointer
  4539                              <1> 
  4540                              <1> 	;xor	ecx, ecx ; 0
  4541 000092E2 BA01000000          <1> 	mov	edx, 1 ; 05/08/2013
  4542                              <1> 	;call 	seektell
  4543 000092E7 E812000000          <1> 	call 	seektell0 ; 05/08/2013
  4544                              <1> 	;mov	ebx, [u.fofp]
  4545 000092EC 8B03                <1> 	mov	eax, [ebx]
  4546 000092EE A3[C0B70000]        <1> 	mov	[u.r0], eax
  4547 000092F3 E9E9EDFFFF          <1> 	jmp	sysret
  4548                              <1> 
  4549                              <1> ; Original unix v1 'systell' system call:
  4550                              <1> 		; jsr r0,seektell
  4551                              <1> 		; br error4
  4552                              <1> 
  4553                              <1> seektell:
  4554                              <1> 	; 03/01/2016
  4555                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4556                              <1> 	; 07/07/2013 - 05/08/2013 (Retro UNIX 8086 v1)
  4557                              <1> 	;
  4558                              <1> 	; 'seektell' puts the arguments from sysseek and systell
  4559                              <1> 	; call in u.base and u.count. It then gets the i-number of
  4560                              <1> 	; the file from the file descriptor in u.r0 and by calling
  4561                              <1> 	; getf. The i-node is brought into core and then u.count
  4562                              <1> 	; is checked to see it is a 0, 1, or 2.
  4563                              <1> 	; If it is 0 - u.count stays the same
  4564                              <1> 	;          1 - u.count = offset (u.fofp)
  4565                              <1> 	;	   2 - u.count = i.size (size of file)
  4566                              <1> 	; 	 		
  4567                              <1> 	; !! Retro UNIX 8086 v1 modification:
  4568                              <1> 	;	Argument 1, file descriptor is in BX;
  4569                              <1> 	;	Argument 2, offset is in CX;
  4570                              <1> 	;	Argument 3, ptrname/switch is in DX register.	
  4571                              <1> 	;
  4572                              <1> 	; mov 	ax, 3 ; Argument transfer method 3 (three arguments)	
  4573                              <1> 	; call 	arg
  4574                              <1> 	;
  4575                              <1> 	; ((Return -> ax = base for offset (position= base+offset))
  4576                              <1> 	;
  4577 000092F8 890D[E0B70000]      <1> 	mov 	[u.base], ecx ; offset
  4578                              <1> 		; jsr r0,arg; u.base / puts offset in u.base
  4579                              <1> seektell0:
  4580 000092FE 8915[E4B70000]      <1> 	mov 	[u.count], edx
  4581                              <1> 		; jsr r0,arg; u.count / put ptr name in u.count
  4582                              <1> 	; mov	ax, bx
  4583                              <1> 		; mov *u.r0,r1 / file descriptor in r1 
  4584                              <1> 			     ; / (index in u.fp list)
  4585                              <1> 	; call	getf
  4586                              <1> 		; jsr r0,getf / u.fofp points to 3rd word in fsp entry
  4587                              <1> 	; BX = file descriptor (file number)
  4588 00009304 E83DFCFFFF          <1> 	call	getf1
  4589 00009309 6609C0              <1> 	or	ax, ax ; i-number of the file
  4590                              <1> 		; mov r1,-(sp) / r1 has i-number of file, 
  4591                              <1> 		             ; / put it on the stack
  4592                              <1> 	;jz	error
  4593                              <1> 		; beq error4 / if i-number is 0, not active so error
  4594 0000930C 750F                <1> 	jnz	short seektell1
  4595 0000930E C705[15B80000]0A00- <1> 	mov	dword [u.error], ERR_FILE_NOT_OPEN  ; 'file not open !'
  4595 00009316 0000                <1>
  4596 00009318 E9A4EDFFFF          <1> 	jmp	error
  4597                              <1> seektell1:
  4598                              <1> 	;push	eax
  4599 0000931D 80FC80              <1> 	cmp	ah, 80h
  4600 00009320 7203                <1> 	jb	short seektell2
  4601                              <1> 		; bgt .+4 / if its positive jump
  4602 00009322 66F7D8              <1> 	neg	ax
  4603                              <1> 		; neg r1 / if not make it positive
  4604                              <1> seektell2:
  4605 00009325 E8EF020000          <1> 	call	iget
  4606                              <1> 		; jsr r0,iget / get its i-node into core
  4607 0000932A 8B1D[D0B70000]      <1>         mov     ebx, [u.fofp] ; 05/08/2013
  4608 00009330 803D[E4B70000]01    <1> 	cmp	byte [u.count], 1
  4609                              <1> 		; cmp u.count,$1 / is ptr name =1
  4610 00009337 7705                <1> 	ja	short seektell3
  4611                              <1> 		; blt 2f / no its zero
  4612 00009339 740A                <1> 	je	short seektell_4
  4613                              <1> 		; beq 1f / yes its 1
  4614 0000933B 31C0                <1> 	xor	eax, eax
  4615                              <1> 	;jmp	short seektell_5
  4616 0000933D C3                  <1> 	retn
  4617                              <1> seektell3:
  4618                              <1> 	; 03/01/2016
  4619                              <1> 	;movzx	eax, word [i.size]
  4620 0000933E 66A1[98B40000]      <1>         mov   	ax, [i.size]
  4621                              <1>                 ; mov i.size,u.count /  put number of bytes 
  4622                              <1>                                    ; / in file in u.count
  4623                              <1> 	;jmp	short seektell_5
  4624                              <1> 		; br 2f
  4625 00009344 C3                  <1> 	retn
  4626                              <1> seektell_4: ; 1: / ptrname =1
  4627                              <1> 	;mov	ebx, [u.fofp]
  4628 00009345 8B03                <1> 	mov	eax, [ebx]
  4629                              <1> 		; mov *u.fofp,u.count / put offset in u.count
  4630                              <1> ;seektell_5: ; 2: / ptrname =0
  4631                              <1> 	;mov	[u.count], eax
  4632                              <1> 	;pop	eax 
  4633                              <1> 		; mov (sp)+,r1 / i-number on stack  r1
  4634 00009347 C3                  <1> 	retn
  4635                              <1> 		; rts r0
  4636                              <1> 
  4637                              <1> sysintr: ; / set interrupt handling
  4638                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4639                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
  4640                              <1> 	;
  4641                              <1> 	; 'sysintr' sets the interrupt handling value. It puts
  4642                              <1> 	; argument of its call in u.intr then branches into 'sysquit'
  4643                              <1> 	; routine. u.tty is checked if to see if a control tty exists.
  4644                              <1> 	; If one does the interrupt character in the tty buffer is
  4645                              <1> 	; cleared and 'sysret'is called. If one does not exits
  4646                              <1> 	; 'sysret' is just called.	
  4647                              <1> 	;
  4648                              <1> 	; Calling sequence:
  4649                              <1> 	;	sysintr; arg
  4650                              <1> 	; Argument:
  4651                              <1> 	;	arg - if 0, interrupts (ASCII DELETE) are ignored.
  4652                              <1> 	;	    - if 1, intterupts cause their normal result
  4653                              <1> 	;		 i.e force an exit.
  4654                              <1> 	;	    - if arg is a location within the program,
  4655                              <1> 	;		control is passed to that location when
  4656                              <1> 	;		an interrupt occurs.	
  4657                              <1> 	; Inputs: -
  4658                              <1> 	; Outputs: -
  4659                              <1> 	; ...............................................................
  4660                              <1> 	;	
  4661                              <1> 	; Retro UNIX 8086 v1 modification: 
  4662                              <1> 	;       'sysintr' system call sets u.intr to value of BX
  4663                              <1> 	;	then branches into sysquit.
  4664                              <1> 	;
  4665 00009348 66891D[04B80000]    <1> 	mov	[u.intr], bx
  4666                              <1> 		; jsr r0,arg; u.intr / put the argument in u.intr
  4667                              <1> 		; br 1f / go into quit routine
  4668 0000934F E98DEDFFFF          <1> 	jmp	sysret
  4669                              <1> 
  4670                              <1> sysquit:
  4671                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4672                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
  4673                              <1> 	;
  4674                              <1> 	; 'sysquit' turns off the quit signal. it puts the argument of
  4675                              <1> 	; the call in u.quit. u.tty is checked if to see if a control 
  4676                              <1> 	; tty exists. If one does the interrupt character in the tty
  4677                              <1> 	; buffer is cleared and 'sysret'is called. If one does not exits
  4678                              <1> 	; 'sysret' is just called.	
  4679                              <1> 	;
  4680                              <1> 	; Calling sequence:
  4681                              <1> 	;	sysquit; arg
  4682                              <1> 	; Argument:
  4683                              <1> 	;	arg - if 0, this call diables quit signals from the
  4684                              <1> 	;		typewriter (ASCII FS)
  4685                              <1> 	;	    - if 1, quits are re-enabled and cause execution to
  4686                              <1> 	;		cease and a core image to be produced.
  4687                              <1> 	;		 i.e force an exit.
  4688                              <1> 	;	    - if arg is an addres in the program,
  4689                              <1> 	;		a quit causes control to sent to that
  4690                              <1> 	;		location.	
  4691                              <1> 	; Inputs: -
  4692                              <1> 	; Outputs: -
  4693                              <1> 	; ...............................................................
  4694                              <1> 	;	
  4695                              <1> 	; Retro UNIX 8086 v1 modification: 
  4696                              <1> 	;       'sysquit' system call sets u.quit to value of BX
  4697                              <1> 	;	then branches into 'sysret'.
  4698                              <1> 	;
  4699 00009354 66891D[06B80000]    <1> 	mov	[u.quit], bx
  4700 0000935B E981EDFFFF          <1> 	jmp	sysret
  4701                              <1> 		; jsr r0,arg; u.quit / put argument in u.quit
  4702                              <1> 	;1:
  4703                              <1> 		; mov u.ttyp,r1 / move pointer to control tty buffer
  4704                              <1> 			      ; / to r1
  4705                              <1> 		; beq sysret4 / return to user
  4706                              <1> 		; clrb 6(r1) / clear the interrupt character 
  4707                              <1> 			   ; / in the tty buffer
  4708                              <1> 		; br sysret4 / return to user
  4709                              <1> 
  4710                              <1> syssetuid: ; / set process id
  4711                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4712                              <1> 	; 07/07/2013 - 02/08/2013 (Retro UNIX 8086 v1)
  4713                              <1> 	;
  4714                              <1> 	; 'syssetuid' sets the user id (u.uid) of the current process
  4715                              <1> 	; to the process id in (u.r0). Both the effective user and 
  4716                              <1> 	; u.uid and the real user u.ruid are set to this. 
  4717                              <1> 	; Only the super user can make this call.	
  4718                              <1> 	;
  4719                              <1> 	; Calling sequence:
  4720                              <1> 	;	syssetuid
  4721                              <1> 	; Arguments: -
  4722                              <1> 	;
  4723                              <1> 	; Inputs: (u.r0) - contains the process id.
  4724                              <1> 	; Outputs: -
  4725                              <1> 	; ...............................................................
  4726                              <1> 	;	
  4727                              <1> 	; Retro UNIX 8086 v1 modification: 
  4728                              <1> 	;       BL contains the (new) user ID of the current process
  4729                              <1> 
  4730                              <1> 		; movb *u.r0,r1 / move process id (number) to r1
  4731 00009360 3A1D[0DB80000]      <1> 	cmp	bl, [u.ruid] 
  4732                              <1> 		; cmpb r1,u.ruid / is it equal to the real user 
  4733                              <1> 			       ; / id number
  4734 00009366 741E                <1> 	je	short setuid1
  4735                              <1> 		; beq 1f / yes
  4736 00009368 803D[0CB80000]00    <1> 	cmp	byte [u.uid], 0 ; 02/08/2013
  4737                              <1> 		; tstb u.uid / no, is current user the super user?
  4738                              <1> 	;ja	error
  4739                              <1> 		; bne error4 / no, error
  4740 0000936F 760F                <1> 	jna	short setuid0
  4741 00009371 C705[15B80000]0B00- <1> 	mov	dword [u.error], ERR_NOT_SUPERUSER  ; 11
  4741 00009379 0000                <1>
  4742                              <1> 				;  'permission denied !' error
  4743 0000937B E941EDFFFF          <1> 	jmp	error
  4744                              <1> setuid0:
  4745 00009380 881D[0DB80000]      <1> 	mov	[u.ruid], bl
  4746                              <1> setuid1: ; 1:
  4747 00009386 881D[0CB80000]      <1> 	mov	[u.uid], bl ; 02/08/2013
  4748                              <1> 		; movb r1,u.uid / put process id in u.uid
  4749                              <1> 		; movb r1,u.ruid / put process id in u.ruid
  4750 0000938C E950EDFFFF          <1> 	jmp	sysret
  4751                              <1> 		; br sysret4 / system return
  4752                              <1> 
  4753                              <1> sysgetuid: ; < get user id >
  4754                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4755                              <1> 	; 07/07/2013 (Retro UNIX 8086 v1)
  4756                              <1> 	;
  4757                              <1> 	; 'sysgetuid' returns the real user ID of the current process.
  4758                              <1> 	; The real user ID identifies the person who is logged in,
  4759                              <1> 	; in contradistinction to the effective user ID, which
  4760                              <1> 	; determines his access permission at each moment. It is thus
  4761                              <1> 	; useful to programs which operate using the 'set user ID'
  4762                              <1> 	; mode, to find out who invoked them.	
  4763                              <1> 	;
  4764                              <1> 	; Calling sequence:
  4765                              <1> 	;	syssetuid
  4766                              <1> 	; Arguments: -
  4767                              <1> 	;
  4768                              <1> 	; Inputs: -
  4769                              <1> 	; Outputs: (u.r0) - contains the real user's id.
  4770                              <1> 	; ...............................................................
  4771                              <1> 	;	
  4772                              <1> 	; Retro UNIX 8086 v1 modification: 
  4773                              <1> 	;       AL contains the real user ID at return.
  4774                              <1> 	;
  4775 00009391 0FB605[0DB80000]    <1> 	movzx 	eax, byte [u.ruid]
  4776 00009398 A3[C0B70000]        <1> 	mov	[u.r0], eax
  4777                              <1> 		; movb	u.ruid,*u.r0 / move the real user id to (u.r0)
  4778 0000939D E93FEDFFFF          <1> 	jmp	sysret
  4779                              <1> 		; br sysret4 / systerm return, sysret
  4780                              <1> 
  4781                              <1> anyi: 
  4782                              <1> 	; 22/06/2015 (Retro UNIX 386 v1 - Beginning)
  4783                              <1> 	; 25/04/2013 (Retro UNIX 8086 v1)
  4784                              <1> 	;
  4785                              <1> 	; 'anyi' is called if a file deleted while open.
  4786                              <1> 	; "anyi" checks to see if someone else has opened this file.
  4787                              <1> 	;
  4788                              <1> 	; INPUTS ->
  4789                              <1> 	;    r1 - contains an i-number
  4790                              <1> 	;    fsp - start of table containing open files
  4791                              <1> 	;
  4792                              <1> 	; OUTPUTS ->
  4793                              <1> 	;    "deleted" flag set in fsp entry of another occurrence of
  4794                              <1> 	;	   this file and r2 points 1st word of this fsp entry.
  4795                              <1> 	;    if file not found - bit in i-node map is cleared
  4796                              <1> 	;    			 (i-node is freed)
  4797                              <1> 	;               all blocks related to i-node are freed
  4798                              <1> 	;	        all flags in i-node are cleared
  4799                              <1> 	; ((AX = R1)) input
  4800                              <1> 	;
  4801                              <1> 	;    (Retro UNIX Prototype : 02/12/2012, UNIXCOPY.ASM)
  4802                              <1>         ;    ((Modified registers: eDX, eCX, eBX, eSI, eDI, eBP))  
  4803                              <1> 	;
  4804                              <1> 		; / r1 contains an i-number
  4805 000093A2 BB[94B50000]        <1> 	mov	ebx, fsp
  4806                              <1> 		; mov $fsp,r2 / move start of fsp table to r2
  4807                              <1> anyi_1: ; 1:
  4808 000093A7 663B03              <1> 	cmp	ax, [ebx]
  4809                              <1> 		; cmp r1,(r2) / do i-numbers match?
  4810 000093AA 7433                <1> 	je	short anyi_3
  4811                              <1> 		; beq 1f / yes, 1f
  4812 000093AC 66F7D8              <1> 	neg	ax
  4813                              <1> 		; neg r1 / no complement r1
  4814 000093AF 663B03              <1> 	cmp	ax, [ebx]
  4815                              <1> 		; cmp r1,(r2) / do they match now?
  4816 000093B2 742B                <1> 	je	short anyi_3
  4817                              <1> 		; beq 1f / yes, transfer
  4818                              <1> 		; / i-numbers do not match
  4819 000093B4 83C30A              <1> 	add	ebx, 10 ; fsp table size is 10 bytes
  4820                              <1> 			; in Retro UNIX 386 v1 (22/06/2015)
  4821                              <1> 		; add $8,r2 / no, bump to next entry in fsp table
  4822 000093B7 81FB[88B70000]      <1> 	cmp	ebx, fsp + (nfiles*10) ; 22/06/2015 
  4823                              <1> 		; cmp r2,$fsp+[nfiles*8] 
  4824                              <1> 				; / are we at last entry in the table
  4825 000093BD 72E8                <1> 	jb	short anyi_1
  4826                              <1> 		; blt 1b / no, check next entries i-number
  4827                              <1> 	;cmp	ax, 32768
  4828 000093BF 80FC80              <1> 	cmp	ah, 80h ; negative number check
  4829                              <1> 		; tst r1 / yes, no match
  4830                              <1> 		; bge .+4
  4831 000093C2 7203                <1> 	jb	short anyi_2
  4832 000093C4 66F7D8              <1> 	neg	ax
  4833                              <1> 		; neg r1 / make i-number positive
  4834                              <1> anyi_2:	
  4835 000093C7 E864020000          <1> 	call	imap
  4836                              <1> 		; jsr r0,imap / get address of allocation bit 
  4837                              <1> 			    ; / in the i-map in r2
  4838                              <1> 	;; DL/DX (MQ) has a 1 in the calculated bit position
  4839                              <1>         ;; eBX (R2) has address of the byte with allocation bit
  4840                              <1>  	; not	dx
  4841 000093CC F6D2                <1> 	not 	dl ;; 0 at calculated bit position, other bits are 1
  4842                              <1>         ;and	[ebx], dx
  4843 000093CE 2013                <1> 	and 	[ebx], dl 
  4844                              <1> 		; bicb mq,(r2) / clear bit for i-node in the imap
  4845 000093D0 E850020000          <1> 	call	itrunc
  4846                              <1> 		; jsr r0,itrunc / free all blocks related to i-node
  4847 000093D5 66C705[94B40000]00- <1>  	mov 	word [i.flgs], 0
  4847 000093DD 00                  <1>
  4848                              <1> 		; clr i.flgs / clear all flags in the i-node
  4849 000093DE C3                  <1> 	retn
  4850                              <1> 		;rts	r0 / return
  4851                              <1> anyi_3: ; 1: / i-numbers match
  4852 000093DF FE4309              <1> 	inc 	byte [ebx+9] ; 22/06/2015
  4853                              <1> 		;incb 7(r2) / increment upper byte of the 4th word
  4854                              <1> 		   ; / in that fsp entry (deleted flag of fsp entry)
  4855 000093E2 C3                  <1> 	retn
  4856                              <1> 		; rts r0
  4857                              <1> 
  4858                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - u7.s
  4859                              <1> ; Last Modification: 14/11/2015
  4860                              <1> 
  4861                              <1> sysmount: ; / mount file system; args special; name
  4862                              <1> 	; 14/11/2015
  4863                              <1> 	; 24/10/2015
  4864                              <1> 	; 13/10/2015
  4865                              <1> 	; 10/07/2015
  4866                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
  4867                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
  4868                              <1> 	;
  4869                              <1> 	; 'sysmount' anounces to the system that a removable 
  4870                              <1> 	; file system has been mounted on a special file.
  4871                              <1> 	; The device number of the special file is obtained via
  4872                              <1> 	; a call to 'getspl'. It is put in the I/O queue entry for
  4873                              <1> 	; dismountable file system (sb1) and the I/O queue entry is
  4874                              <1> 	; set up to read (bit 10 is set). 'ppoke' is then called to
  4875                              <1> 	; to read file system into core, i.e. the first block on the
  4876                              <1> 	; mountable file system is read in. This block is super block
  4877                              <1> 	; for the file system. This call is super user restricted.	
  4878                              <1> 	;
  4879                              <1> 	; Calling sequence:
  4880                              <1> 	;	sysmount; special; name
  4881                              <1> 	; Arguments:
  4882                              <1> 	;	special - pointer to name of special file (device)
  4883                              <1> 	;	name -  pointer to name of the root directory of the
  4884                              <1> 	;		newly mounted file system. 'name' should 
  4885                              <1> 	;		always be a directory.
  4886                              <1> 	; Inputs: - 
  4887                              <1> 	; Outputs: -
  4888                              <1> 	; ...............................................................
  4889                              <1> 	;				
  4890                              <1> 	; Retro UNIX 8086 v1 modification: 
  4891                              <1> 	;       'sysmount' system call has two arguments; so,
  4892                              <1> 	;	* 1st argument, special is pointed to by BX register
  4893                              <1> 	;	* 2nd argument, name is in CX register
  4894                              <1> 	;
  4895                              <1> 	;	NOTE: Device numbers, names and related procedures are 
  4896                              <1> 	;	       already modified for IBM PC compatibility and 
  4897                              <1> 	;	       Retro UNIX 8086 v1 device configuration.	
  4898                              <1> 	
  4899                              <1> 	;call	arg2
  4900                              <1> 		; jsr r0,arg2 / get arguments special and name
  4901 000093E3 891D[D8B70000]      <1> 	mov	[u.namep], ebx
  4902 000093E9 51                  <1> 	push	ecx ; directory name
  4903 000093EA 66833D[AAB70000]00  <1> 	cmp	word [mnti], 0
  4904                              <1> 		; tst mnti / is the i-number of the cross device file
  4905                              <1> 			 ; / zero?
  4906                              <1> 	;ja	error
  4907                              <1>         	; bne errora / no, error
  4908 000093F2 0F87E9000000        <1> 	ja	sysmnt_err0
  4909                              <1> 	;
  4910 000093F8 E8CC000000          <1> 	call	getspl
  4911                              <1> 		; jsr r0,getspl / get special files device number in r1
  4912                              <1> 	; 13/10/2015
  4913 000093FD 0FB7D8              <1> 	movzx	ebx, ax ; ; Retro UNIX 8086 v1 device number (0 to 5)
  4914 00009400 F683[0AA30000]80    <1>         test    byte [ebx+drv.status], 80h ; 24/10/2015 
  4915 00009407 750F                <1> 	jnz	short sysmnt_1
  4916                              <1> sysmnt_err1:
  4917 00009409 C705[15B80000]0F00- <1>         mov     dword [u.error], ERR_DRV_NOT_RDY ; drive not ready !
  4917 00009411 0000                <1>
  4918 00009413 E9A9ECFFFF          <1> 	jmp	error
  4919                              <1> sysmnt_1:
  4920 00009418 8F05[D8B70000]      <1> 	pop	dword [u.namep]
  4921                              <1>         	; mov (sp)+,u.namep / put the name of file to be placed
  4922                              <1> 				  ; / on the device
  4923                              <1> 	; 14/11/2015
  4924 0000941E 53                  <1> 	push	ebx ; 13/10/2015
  4925                              <1> 		; mov r1,-(sp) / save the device number
  4926                              <1>         ;
  4927 0000941F E859FBFFFF          <1> 	call	namei
  4928                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
  4929                              <1> 		       ; ax = 0 -> file not found 	
  4930                              <1> 	;jz	error
  4931                              <1> 	;jc	error
  4932                              <1> 		; jsr r0,namei / get the i-number of the file
  4933                              <1>                	; br errora
  4934 00009424 730F                <1> 	jnc	short sysmnt_2
  4935                              <1> sysmnt_err2:
  4936 00009426 C705[15B80000]0C00- <1>         mov     dword [u.error], ERR_FILE_NOT_FOUND ; drive not ready !
  4936 0000942E 0000                <1>
  4937 00009430 E98CECFFFF          <1> 	jmp	error
  4938                              <1> sysmnt_2:	
  4939 00009435 66A3[AAB70000]      <1> 	mov	[mnti], ax
  4940                              <1>         	; mov r1,mnti / put it in mnti
  4941                              <1> ;	mov	ebx, sb1 ; super block buffer (of mounted disk)
  4942                              <1> sysmnt_3: ;1:
  4943                              <1>         ;cmp	byte [ebx+1], 0
  4944                              <1> 		; tstb sb1+1 / is 15th bit of I/O queue entry for
  4945                              <1> 			   ; / dismountable device set?
  4946                              <1>         ;jna	short sysmnt_4		
  4947                              <1> 		; bne 1b / (inhibit bit) yes, skip writing
  4948                              <1> 	;call	idle 	; (wait for hardware interrupt)
  4949                              <1> 	;jmp	short sysmnt_3
  4950                              <1> sysmnt_4:   
  4951 0000943B 58                  <1> 	pop	eax ; Retro UNIX 8086 v1 device number/ID (0 to 5)     
  4952 0000943C A2[A7B70000]        <1> 	mov	[mdev], al
  4953                              <1> 		; mov  (sp),mntd / no, put the device number in mntd
  4954 00009441 8803                <1> 	mov	[ebx], al
  4955                              <1>         	; movb (sp),sb1 / put the device number in the lower byte
  4956                              <1> 			      ; / of the I/O queue entry
  4957                              <1> 	;mov	byte [cdev], 1 ; mounted device/drive
  4958                              <1>         	; mov (sp)+,cdev / put device number in cdev
  4959 00009443 66810B0004          <1>         or	word [ebx], 400h ; Bit 10, 'read' flag/bit
  4960                              <1> 		; bis $2000,sb1 / set the read bit
  4961                              <1> 	; Retro UNIX 386 v1 modification : 
  4962                              <1> 	;	32 bit block number at buffer header offset 4
  4963 00009448 C7430401000000      <1> 	mov	dword [ebx+4], 1 ; physical block number = 1
  4964 0000944F E8DD010000          <1> 	call 	diskio
  4965 00009454 731C                <1> 	jnc	short sysmnt_5
  4966 00009456 31C0                <1> 	xor 	eax, eax
  4967 00009458 66A3[AAB70000]      <1> 	mov	[mnti], ax ; 0
  4968 0000945E A2[A7B70000]        <1> 	mov	[mdev], al ; 0
  4969                              <1> 	;mov	[cdev], al ; 0
  4970                              <1> sysmnt_invd:
  4971                              <1> 	; 14/11/2015
  4972 00009463 FEC8                <1> 	dec 	al
  4973 00009465 8903                <1> 	mov	[ebx], eax ; 000000FFh
  4974 00009467 FEC0                <1> 	inc	al
  4975 00009469 48                  <1> 	dec	eax
  4976 0000946A 894304              <1> 	mov	[ebx+4], eax ; 0FFFFFFFFh
  4977 0000946D E94FECFFFF          <1> 	jmp	error
  4978                              <1> sysmnt_5:
  4979                              <1> 	; 14/11/2015 (Retro UNIX 386 v1 modification)
  4980                              <1> 	; (Following check is needed to prevent mounting an
  4981                              <1> 	; in valid valid file system (in valid super block).
  4982                              <1> 	; 
  4983 00009472 0FB603              <1> 	movzx	eax, byte [ebx] ; device number
  4984 00009475 C0E002              <1> 	shl	al, 2 ; 4*index
  4985 00009478 8B88[EEA20000]      <1> 	mov	ecx, [eax+drv.size] ; volume (fs) size
  4986 0000947E C1E103              <1> 	shl 	ecx, 3
  4987 00009481 0FB715[71C20000]    <1> 	movzx	edx, word [sb1+4] ; the 1st data word
  4988 00009488 39D1                <1> 	cmp	ecx, edx ; compare free map bits and volume size
  4989                              <1> 			 ; (in sectors), if they are not equal
  4990                              <1> 			 ; the disk to be mounted is an...	
  4991 0000948A 75D7                <1> 	jne	short sysmnt_invd ; invalid disk !
  4992                              <1> 			 ; (which has not got a valid super block)
  4993                              <1> 	;
  4994 0000948C C6430100            <1> 	mov	byte [ebx+1], 0
  4995                              <1> 	       	; jsr r0,ppoke / read in entire file system
  4996                              <1> ;sysmnt_6: ;1:
  4997                              <1> 	;;cmp	byte [sb1+1], 0
  4998                              <1> 		; tstb   sb1+1 / done reading?
  4999                              <1>    	;;jna	sysret
  5000                              <1> 	;;call	idle ; (wait for hardware interrupt)
  5001                              <1> 	;;jmp	short sysmnt_6
  5002                              <1> 		;bne 1b / no, wait
  5003                              <1>         	;br sysreta / yes
  5004 00009490 E94CECFFFF          <1> 	jmp	sysret
  5005                              <1> 
  5006                              <1> sysumount: ; / special dismount file system
  5007                              <1> 	; 16/05/2015 (Retro UNIX 386 v1 - Beginning)
  5008                              <1> 	; 09/07/2013 - 04/11/2013 (Retro UNIX 8086 v1)
  5009                              <1> 	;
  5010                              <1> 	; 04/11/2013
  5011                              <1> 	; 09/07/2013
  5012                              <1> 	; 'sysumount' anounces to the system that the special file, 
  5013                              <1> 	; indicated as an argument is no longer contain a removable
  5014                              <1> 	; file system. 'getspl' gets the device number of the special
  5015                              <1> 	; file. If no file system was mounted on that device an error
  5016                              <1> 	; occurs. 'mntd' and 'mnti' are cleared and control is passed
  5017                              <1> 	; to 'sysret'.
  5018                              <1> 	;
  5019                              <1> 	; Calling sequence:
  5020                              <1> 	;	sysmount; special
  5021                              <1> 	; Arguments:
  5022                              <1> 	;	special - special file to dismount (device)
  5023                              <1> 	;
  5024                              <1> 	; Inputs: - 
  5025                              <1> 	; Outputs: -
  5026                              <1> 	; ...............................................................
  5027                              <1> 	;				
  5028                              <1> 	; Retro UNIX 8086 v1 modification: 
  5029                              <1> 	;       'sysumount' system call has one argument; so,
  5030                              <1> 	;	* Single argument, special is pointed to by BX register
  5031                              <1> 	;
  5032                              <1> 	
  5033                              <1> 	;mov 	ax, 1 ; one/single argument, put argument in BX	
  5034                              <1> 	;call	arg
  5035                              <1> 		; jsr r0,arg; u.namep / point u.namep to special
  5036 00009495 891D[D8B70000]      <1>         mov	[u.namep], ebx
  5037 0000949B E829000000          <1> 	call	getspl
  5038                              <1> 		; jsr r0,getspl / get the device number in r1
  5039 000094A0 3A05[A7B70000]      <1> 	cmp	al, [mdev]
  5040                              <1> 		; cmp r1,mntd / is it equal to the last device mounted?
  5041 000094A6 7539                <1> 	jne	short sysmnt_err0 ; 'permission denied !' error
  5042                              <1> 	;jne	error
  5043                              <1>         	; bne errora / no error
  5044 000094A8 30C0                <1> 	xor	al, al ; ah = 0
  5045                              <1> sysumnt_0: ;1:
  5046 000094AA 3805[6EC20000]      <1>      	cmp 	[sb1+1], al ; 0
  5047                              <1> 		; tstb sb1+1 / yes, is the device still doing I/O 
  5048                              <1> 			   ; / (inhibit bit set)?
  5049 000094B0 7607                <1> 	jna	short sysumnt_1		
  5050                              <1> 		; bne 1b / yes, wait
  5051 000094B2 E87B010000          <1> 	call	idle ; (wait for hardware interrupt)
  5052 000094B7 EBF1                <1> 	jmp	short sysumnt_0
  5053                              <1> sysumnt_1:        
  5054 000094B9 A2[A7B70000]        <1> 	mov	[mdev], al
  5055                              <1> 	     	; clr mntd / no, clear these
  5056 000094BE 66A3[AAB70000]      <1>    	mov	[mnti], ax
  5057                              <1>         	; clr mnti
  5058 000094C4 E918ECFFFF          <1>         jmp	sysret
  5059                              <1> 		; br sysreta / return
  5060                              <1> 
  5061                              <1> getspl: ; / get device number from a special file name
  5062 000094C9 E8AFFAFFFF          <1> 	call	namei
  5063                              <1> 	;or	ax, ax ; Retro UNIX 8086 v1 modification !
  5064                              <1> 		       ; ax = 0 -> file not found 	
  5065 000094CE 0F8252FFFFFF        <1>         jc      sysmnt_err2 ; 'file not found !' error
  5066                              <1> 	;jz	error
  5067                              <1> 	;jc	error
  5068                              <1> 		; jsr r0,namei / get the i-number of the special file
  5069                              <1>                 ; br errora / no such file
  5070 000094D4 6683E803            <1>         sub	ax, 3 ; Retro UNIX 8086 v1 modification !
  5071                              <1> 		      ;	i-number-3, 0 = fd0, 5 = hd3 
  5072                              <1> 		; sub $4,r1 / i-number-4 rk=1,tap=2+n
  5073 000094D8 7207                <1>         jc	short sysmnt_err0 ; 'permission denied !' error
  5074                              <1> 	;jc	error
  5075                              <1> 		; ble errora / less than 0?  yes, error
  5076 000094DA 6683F805            <1>         cmp	ax, 5 ;
  5077                              <1> 		; cmp  r1,$9. / greater than 9  tap 7
  5078 000094DE 7701                <1> 	ja	short sysmnt_err0 ; 'permission denied !' error
  5079                              <1> 	;ja	error
  5080                              <1>         	; bgt errora / yes, error
  5081                              <1>         ; AX = Retro UNIX 8086 v1 Device Number (0 to 5)
  5082                              <1> iopen_retn:
  5083 000094E0 C3                  <1> 	retn
  5084                              <1> 		; rts    r0 / return with device number in r1
  5085                              <1> sysmnt_err0:
  5086 000094E1 C705[15B80000]0B00- <1> 	mov	dword [u.error], ERR_FILE_ACCESS ; permission denied !
  5086 000094E9 0000                <1>
  5087 000094EB E9D1EBFFFF          <1> 	jmp	error
  5088                              <1> 
  5089                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS9.INC
  5090                              <1> ; Last Modification: 09/12/2015
  5091                              <1> 
  5092                              <1> syssleep:
  5093                              <1> 	; 29/06/2015 - (Retro UNIX 386 v1)
  5094                              <1> 	; 11/06/2014 - (Retro UNIX 8086 v1)
  5095                              <1> 	;
  5096                              <1> 	; Retro UNIX 8086 v1 feature only
  5097                              <1> 	; (INPUT -> none)
  5098                              <1> 	;
  5099 000094F0 0FB61D[0FB80000]    <1> 	movzx	ebx, byte [u.uno] ; process number
  5100 000094F7 8AA3[13B50000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; current/console tty
  5101 000094FD E831010000          <1> 	call	sleep
  5102 00009502 E9DAEBFFFF          <1> 	jmp	sysret
  5103                              <1> 
  5104                              <1> vp_clr:
  5105                              <1> 	; Reset/Clear Video Page
  5106                              <1> 	;
  5107                              <1> 	; 30/06/2015 - (Retro UNIX 386 v1)
  5108                              <1> 	; 21/05/2013 - 30/10/2013(Retro UNIX 8086 v1) (U0.ASM)
  5109                              <1> 	;
  5110                              <1> 	; Retro UNIX 8086 v1 feature only !
  5111                              <1> 	;
  5112                              <1> 	; INPUTS -> 
  5113                              <1> 	;   BL = video page number	 
  5114                              <1> 	;
  5115                              <1> 	; OUTPUT ->
  5116                              <1> 	;   none
  5117                              <1> 	; ((Modified registers: eAX, BH, eCX, eDX, eSI, eDI))
  5118                              <1> 	;
  5119                              <1> 	; 04/12/2013
  5120 00009507 28C0                <1> 	sub	al, al
  5121                              <1> 	; al = 0 (clear video page)
  5122                              <1> 	; bl = video page
  5123 00009509 B407                <1> 	mov	ah, 07h
  5124                              <1> 	; ah = 7 (attribute/color)
  5125 0000950B 6631C9              <1> 	xor 	cx, cx ; 0, left upper column (cl) & row (cl)
  5126 0000950E 66BA4F18            <1> 	mov	dx, 184Fh ; right lower column & row (dl=24, dh=79)
  5127 00009512 E8F580FFFF          <1> 	call	_scroll_up
  5128                              <1> 	; bl = video page
  5129 00009517 6631D2              <1> 	xor	dx, dx ; 0 (cursor position) 
  5130 0000951A E92B83FFFF          <1> 	jmp 	_set_cpos
  5131                              <1> 
  5132                              <1> sysmsg:
  5133                              <1> 	; 11/11/2015
  5134                              <1> 	; 01/07/2015 - (Retro UNIX 386 v1 feature only!)
  5135                              <1> 	; Print user-application message on user's console tty
  5136                              <1> 	;
  5137                              <1> 	; Input -> EBX = Message address
  5138                              <1> 	;	   ECX = Message length (max. 255)
  5139                              <1> 	;	   DL = Color (IBM PC Rombios color attributes)
  5140                              <1> 	;
  5141 0000951F 81F9FF000000        <1> 	cmp	ecx, MAX_MSG_LEN ; 255
  5142 00009525 0F87B6EBFFFF        <1> 	ja	sysret ; nothing to do with big message size
  5143 0000952B 08C9                <1> 	or	cl, cl
  5144 0000952D 0F84AEEBFFFF        <1> 	jz	sysret
  5145 00009533 20D2                <1> 	and	dl, dl
  5146 00009535 7502                <1> 	jnz	short sysmsg0
  5147 00009537 B207                <1> 	mov	dl, 07h ; default color
  5148                              <1> 		; (black background, light gray character) 
  5149                              <1> sysmsg0:
  5150 00009539 891D[E0B70000]      <1> 	mov	[u.base], ebx
  5151 0000953F 8815[19A80000]      <1> 	mov	[ccolor], dl ; color attributes
  5152 00009545 89E5                <1> 	mov	ebp, esp
  5153 00009547 31DB                <1> 	xor	ebx, ebx ; 0
  5154 00009549 891D[E8B70000]      <1> 	mov	[u.nread], ebx ; 0
  5155                              <1> 	;
  5156 0000954F 381D[27B80000]      <1> 	cmp	[u.kcall], bl ; 0
  5157 00009555 7769                <1> 	ja	short sysmsgk ; Temporary (01/07/2015)
  5158                              <1> 	;
  5159 00009557 890D[E4B70000]      <1> 	mov	[u.count], ecx
  5160 0000955D 41                  <1> 	inc	ecx ; + 00h ; ASCIZZ
  5161 0000955E 29CC                <1> 	sub	esp, ecx
  5162 00009560 89E7                <1> 	mov	edi, esp
  5163 00009562 89E6                <1> 	mov	esi, esp
  5164 00009564 66891D[25B80000]    <1> 	mov	[u.pcount], bx ; reset page (phy. addr.) counter
  5165                              <1> 	; 11/11/2015
  5166 0000956B 8A25[F0B70000]      <1> 	mov 	ah, [u.ttyp] ; recent open tty
  5167                              <1> 	; 0 = none
  5168 00009571 FECC                <1> 	dec	ah
  5169 00009573 790C                <1> 	jns	short sysmsg1 
  5170 00009575 8A1D[0FB80000]      <1> 	mov	bl, [u.uno] ; process number	
  5171 0000957B 8AA3[13B50000]      <1> 	mov	ah, [ebx+p.ttyc-1] ; user's (process's) console tty
  5172                              <1> sysmsg1:
  5173 00009581 8825[14B80000]      <1> 	mov	[u.ttyn], ah
  5174                              <1> sysmsg2:
  5175 00009587 E8A0000000          <1> 	call	cpass
  5176 0000958C 7416                <1> 	jz	short sysmsg5
  5177 0000958E AA                  <1> 	stosb
  5178 0000958F 20C0                <1> 	and	al, al
  5179 00009591 75F4                <1> 	jnz	short sysmsg2
  5180                              <1> sysmsg3:
  5181 00009593 80FC07              <1> 	cmp	ah, 7 ; tty number
  5182 00009596 7711                <1> 	ja	short sysmsg6 ; serial port
  5183 00009598 E83E000000          <1> 	call	print_cmsg
  5184                              <1> sysmsg4:
  5185 0000959D 89EC                <1> 	mov	esp, ebp	
  5186 0000959F E93DEBFFFF          <1> 	jmp	sysret
  5187                              <1> sysmsg5:
  5188 000095A4 C60700              <1> 	mov	byte [edi], 0
  5189 000095A7 EBEA                <1> 	jmp	short sysmsg3
  5190                              <1> sysmsg6:
  5191 000095A9 8A06                <1> 	mov	al, [esi]
  5192 000095AB E87A000000          <1> 	call	sndc
  5193 000095B0 72EB                <1> 	jc	short sysmsg4
  5194 000095B2 803E00              <1> 	cmp	byte [esi], 0  ; 0 is stop character
  5195 000095B5 76E6                <1> 	jna	short sysmsg4
  5196 000095B7 46                  <1> 	inc 	esi
  5197 000095B8 8A25[14B80000]      <1> 	mov	ah, [u.ttyn]
  5198 000095BE EBE9                <1> 	jmp	short sysmsg6
  5199                              <1> 
  5200                              <1> sysmsgk: ; Temporary (01/07/2015)
  5201                              <1> 	; The message has been sent by Kernel (ASCIIZ string)
  5202                              <1> 	; (ECX -character count- will not be considered)
  5203 000095C0 8B35[E0B70000]      <1> 	mov	esi, [u.base]
  5204 000095C6 8A25[18A80000]      <1> 	mov	ah, [ptty] ; present/current screen (video page)
  5205 000095CC 8825[14B80000]      <1> 	mov	[u.ttyn], ah
  5206 000095D2 C605[27B80000]00    <1> 	mov	byte [u.kcall], 0
  5207 000095D9 EBB8                <1> 	jmp	short sysmsg3
  5208                              <1> 	
  5209                              <1> 
  5210                              <1> print_cmsg: 
  5211                              <1> 	; 01/07/2015 (retro UNIX 386 v1 feature only !)
  5212                              <1> 	;
  5213                              <1> 	; print message (on user's console tty) 
  5214                              <1> 	;	with requested color
  5215                              <1> 	;
  5216                              <1> 	; INPUTS:
  5217                              <1> 	;	esi = message address
  5218                              <1> 	;	[u.ttyn] = tty number (0 to 7)
  5219                              <1> 	;	[ccolor] = color attributes (IBM PC BIOS colors)
  5220                              <1> 	;
  5221 000095DB AC                  <1> 	lodsb
  5222                              <1> pcmsg1:
  5223 000095DC 56                  <1> 	push 	esi
  5224 000095DD 0FB61D[14B80000]    <1>         movzx   ebx, byte [u.ttyn]
  5225 000095E4 8A25[19A80000]      <1> 	mov	ah, [ccolor]
  5226 000095EA E8C781FFFF          <1> 	call 	WRITE_TTY
  5227 000095EF 5E                  <1> 	pop	esi
  5228 000095F0 AC                  <1> 	lodsb
  5229 000095F1 20C0                <1> 	and 	al, al  ; 0
  5230 000095F3 75E7                <1> 	jnz 	short pcmsg1
  5231 000095F5 C3                  <1> 	retn
  5232                              <1> 
  5233                              <1> sysgeterr:
  5234                              <1> 	; 09/12/2015
  5235                              <1> 	; 21/09/2015 - (Retro UNIX 386 v1 feature only!)
  5236                              <1> 	; Get last error number or page fault count
  5237                              <1> 	; (for debugging)
  5238                              <1> 	;
  5239                              <1> 	; Input -> EBX = return type
  5240                              <1> 	;	   0 = last error code (which is in 'u.error')	
  5241                              <1> 	;	   FFFFFFFFh = page fault count for running process
  5242                              <1> 	;	   FFFFFFFEh = total page fault count
  5243                              <1> 	;	   1 .. FFFFFFFDh = undefined 
  5244                              <1> 	;
  5245                              <1> 	; Output -> EAX = last error number or page fault count
  5246                              <1> 	;	   (depending on EBX input)
  5247                              <1> 	; 	
  5248 000095F6 21DB                <1> 	and 	ebx, ebx
  5249 000095F8 750B                <1> 	jnz	short glerr_2
  5250                              <1> glerr_0:
  5251 000095FA A1[15B80000]        <1> 	mov	eax, [u.error]
  5252                              <1> glerr_1:
  5253 000095FF A3[C0B70000]        <1> 	mov	[u.r0], eax
  5254 00009604 C3                  <1>  	retn
  5255                              <1> glerr_2:
  5256 00009605 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0, FFFFFFFEh -> FFFFFFFFh
  5257 00009606 74FD                <1> 	jz	short glerr_2 ; page fault count for process
  5258 00009608 43                  <1> 	inc	ebx ; FFFFFFFFh -> 0	
  5259 00009609 75EF                <1> 	jnz	short glerr_0
  5260 0000960B A1[94C40000]        <1> 	mov	eax, [PF_Count] ; total page fault count
  5261 00009610 EBED                <1>         jmp     short glerr_1
  5262                              <1> glerr_3:
  5263 00009612 A1[29B80000]        <1> 	mov 	eax, [u.pfcount]
  5264 00009617 EBE6                <1> 	jmp	short glerr_1
  5265                              <1> 
  5266                              <1> ; temporary - 24/01/2016
  5267                              <1> 
  5268                              <1> iget:
  5269 00009619 C3                  <1> 	retn
  5270                              <1> poke:
  5271 0000961A C3                  <1> 	retn
  5272                              <1> tswap:
  5273 0000961B C3                  <1> 	retn
  5274                              <1> isintr:
  5275 0000961C C3                  <1> 	retn
  5276                              <1> writei:
  5277 0000961D C3                  <1> 	retn
  5278                              <1> readi:
  5279 0000961E C3                  <1> 	retn
  5280                              <1> putlu:
  5281 0000961F C3                  <1> 	retn
  5282                              <1> swap:
  5283 00009620 C3                  <1> 	retn
  5284                              <1> wswap:
  5285 00009621 C3                  <1> 	retn
  5286                              <1> rswap:
  5287 00009622 C3                  <1> 	retn
  5288                              <1> iopen:
  5289 00009623 C3                  <1> 	retn
  5290                              <1> iclose:
  5291 00009624 C3                  <1> 	retn
  5292                              <1> itrunc:
  5293 00009625 C3                  <1> 	retn
  5294                              <1> clock:
  5295 00009626 C3                  <1> 	retn
  5296                              <1> setimod:
  5297 00009627 C3                  <1> 	retn
  5298                              <1> ottyp:
  5299 00009628 C3                  <1> 	retn
  5300                              <1> cttyp:
  5301 00009629 C3                  <1> 	retn
  5302                              <1> sndc:
  5303 0000962A C3                  <1> 	retn
  5304                              <1> access:
  5305 0000962B C3                  <1> 	retn
  5306                              <1> cpass:
  5307 0000962C C3                  <1> 	retn
  5308                              <1> passc:
  5309 0000962D C3                  <1> 	retn
  5310                              <1> epoch:
  5311 0000962E C3                  <1> 	retn
  5312                              <1> set_date_time:
  5313 0000962F C3                  <1> 	retn
  5314                              <1> imap:
  5315 00009630 C3                  <1> 	retn
  5316                              <1> diskio:
  5317 00009631 C3                  <1> 	retn
  5318                              <1> idle:
  5319 00009632 C3                  <1> 	retn
  5320                              <1> sleep:
  5321 00009633 C3                  <1> 	retn
  5322                              <1> 
  5323                              <1> 
  5324                              <1> 
  1919                                  %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> 
    16                              <1> disk_write:
    17                              <1> 	; 25/02/2016
    18                              <1> 	; 24/02/2016
    19                              <1> 	; 23/02/2016
    20 00009634 807E0500            <1> 	cmp	byte [esi+LD_LBAYes], 0
    21 00009638 777B                <1>         ja      short lba_write
    22                              <1> 
    23                              <1> chs_write:
    24                              <1> 	; 25/02/2016
    25                              <1> 	; 23/02/2016
    26 0000963A C605[A1B10000]03    <1> 	mov	byte [disk_rw_op], 3 ; CHS write
    27 00009641 EB0D                <1> 	jmp	short chs_rw
    28                              <1> 
    29                              <1> disk_read:
    30                              <1> 	; 25/02/2016
    31                              <1> 	; 24/02/2016
    32                              <1> 	; 23/02/2016
    33                              <1> 	; 17/02/2016
    34                              <1> 	; 14/02/2016
    35                              <1> 	; 31/01/2016 (TRDOS 386 =  TRDOS v2.0)
    36                              <1> 	; 17/10/2010
    37                              <1> 	; 18/04/2010
    38                              <1> 	;
    39                              <1> 	; INPUT -> EAX = Logical Block Address
    40                              <1> 	;	   ESI = Logical Dos Disk Table Offset (DRV)	
    41                              <1> 	;	   ECX = Sector Count	
    42                              <1> 	; 	   EBX = Destination Buffer
    43                              <1> 	; OUTPUT -> 
    44                              <1> 	;	   cf = 0 or cf = 1
    45                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX)
    46                              <1> 
    47 00009643 807E0500            <1> 	cmp	byte [esi+LD_LBAYes], 0
    48 00009647 7775                <1>         ja      short lba_read
    49                              <1> 
    50                              <1> chs_read:
    51                              <1> 	; 25/02/2016
    52                              <1> 	; 24/02/2016
    53                              <1> 	; 23/02/2016
    54                              <1> 	; 31/01/2016 (TRDOS 386 =  TRDOS v2.0)
    55                              <1> 	; 20/07/2011
    56                              <1> 	; 04/07/2009
    57                              <1> 	;
    58                              <1> 	; INPUT -> EAX = Logical Block Address
    59                              <1> 	;	   ECX = Number of sectors to read
    60                              <1> 	; 	   ESI = Logical Dos Disk Table Offset (DRV)
    61                              <1> 	; 	   EBX = Destination Buffer
    62                              <1> 	; OUTPUT -> 
    63                              <1> 	;	   cf = 0 or cf = 1
    64                              <1> 	; (Modified registers: EAX; EBX, ECX, EDX)
    65                              <1> 
    66                              <1> 	; 23/02/2016
    67 00009649 C605[A1B10000]02    <1> 	mov	byte [disk_rw_op], 2 ; CHS read
    68                              <1> 
    69                              <1> chs_rw:
    70                              <1> 	;;movzx	edx, word [esi+LD_BPB+SecPerTrack]
    71                              <1> 	;movzx	edx, byte [esi+LD_BPB+SecPerTrack] ; <= 63
    72                              <1> 	;mov	[disk_rw_spt], dl
    73                              <1> 
    74                              <1> chs_read_next_sector:
    75 00009650 C605[A2B10000]04    <1> 	mov	byte [retry_count], 4
    76                              <1>      
    77                              <1> chs_read_retry:
    78                              <1> 	;mov	[sector_count], ecx ; 23/02/2016
    79                              <1> 
    80 00009657 50                  <1> 	push	eax			; Linear sector #
    81 00009658 51                  <1> 	push	ecx			; # of FAT/FILE/DIR sectors
    82                              <1>                 
    83 00009659 0FB74E1E            <1> 	movzx	ecx, word [esi+LD_BPB+SecPerTrack]
    84                              <1> 	;movzx	ecx, byte [disk_rw_spt] ; 23/02/2016
    85 0000965D 29D2                <1> 	sub	edx, edx
    86 0000965F F7F1                <1> 	div	ecx
    87                              <1> 	; eax = track, dx (dl ) = sector (on track)
    88                              <1> 	;sub	cl, dl ; 24/02/2016 (spt - sec)
    89                              <1> 	;push	ecx ; *
    90 00009661 6689D1              <1> 	mov	cx, dx			; Sector (zero based)
    91 00009664 6641                <1> 	inc	cx			; To make it 1 based
    92 00009666 6651                <1> 	push	cx
    93 00009668 668B4E20            <1> 	mov	cx, [esi+LD_BPB+Heads]
    94 0000966C 6629D2              <1> 	sub	dx, dx
    95 0000966F F7F1                <1> 	div	ecx			; Convert track to head & cyl
    96                              <1> 	; eax (ax) = cylinder, dx (dl) = head (max. FFh)
    97 00009671 88D6                <1> 	mov	dh, dl
    98 00009673 6659                <1> 	pop	cx			; AX=Cyl, DH=Head, CX=Sector
    99 00009675 8A5602              <1> 	mov	dl, [esi+LD_PhyDrvNo]
   100                              <1> 
   101 00009678 88C5                <1> 	mov	ch, al			; NOTE: max. 1023 cylinders !                   
   102 0000967A C0CC02              <1> 	ror	ah, 2			; Rotate 2 bits right
   103 0000967D 08E1                <1> 	or	cl, ah
   104                              <1> 
   105                              <1> 	; 24/02/2016
   106                              <1> 	;pop	eax ; * (spt - sec) (example: 63 - 0 = 63)
   107                              <1> 	;cmp	eax, [sector_count]
   108                              <1> 	;jb	short chs_write_sectors
   109                              <1> 	;je	short chs_read_sectors
   110                              <1> 	;; (# of sectors to read is more than remaining sectors on the track)
   111                              <1> 	;mov	al, [sector_count]
   112                              <1> ;chs_read_sectors: ; read or write !
   113 0000967F B001                <1> 	mov	al, 1 ; 25/02/2016
   114 00009681 8A25[A1B10000]      <1> 	mov	ah, [disk_rw_op]  ; 02h = chs read, 03h = chs write 
   115                              <1> 	;
   116 00009687 E83F92FFFF          <1> 	call	int13h			; BIOS Service func ( ah ) = 2
   117                              <1>                                         ; Read disk sectors
   118                              <1>                                         ; AL-sec num CH-track CL-sec
   119                              <1>                                         ; DH-head DL-drive ES:BX-buffer
   120                              <1>                                         ; CF-flag AH-stat AL-sec read
   121                              <1> 	                                ; If CF = 1 then (If AH > 0)
   122 0000968C 8825[A3B10000]      <1> 	mov	[disk_rw_err], ah
   123                              <1> 	
   124 00009692 59                  <1> 	pop	ecx
   125 00009693 58                  <1> 	pop	eax
   126 00009694 7314                <1> 	jnc	short chs_read_ok
   127                              <1> 
   128 00009696 803D[A3B10000]09    <1> 	cmp	byte [disk_rw_err], 09h ; DMA crossed 64K segment boundary
   129 0000969D 7408                <1> 	je	short chs_read_error_retn
   130                              <1>              
   131 0000969F FE0D[A2B10000]      <1> 	dec	byte [retry_count]
   132 000096A5 75B0                <1> 	jnz	short chs_read_retry
   133                              <1> 
   134                              <1> chs_read_error_retn:
   135 000096A7 F9                  <1> 	stc
   136                              <1> 	;retn
   137 000096A8 EB69                <1> 	jmp	short update_drv_error_byte
   138                              <1> 
   139                              <1> ;chs_write_sectors: ; read or write 
   140                              <1> 	;; (# of sectors to read is less than remaining sectors on the track)
   141                              <1> 	;mov	[sector_count], al
   142                              <1> 	;jmp	short chs_read_sectors
   143                              <1> 
   144                              <1> chs_read_ok:
   145                              <1> 	;; 23/02/2016
   146                              <1> 	;movzx	edx, byte [sector_count] ; sector count (<= spt)	
   147                              <1>         ;sub    ecx, edx  ; remaining sector count
   148                              <1> 	;jna	short update_drv_error_byte	
   149                              <1> 	;add	eax, edx ; next disk sector
   150                              <1> 	;shl	edx, 9 ; 512 * sector count
   151                              <1> 	;add	ebx, edx ; next buffer byte address 
   152                              <1>         ;jmp     chs_read_next_sector        
   153                              <1> 	; 25/02/2016
   154 000096AA 40                  <1> 	inc	eax ; next sector
   155 000096AB 81C300020000        <1> 	add	ebx, 512
   156 000096B1 E29D                <1> 	loop	chs_read_next_sector
   157 000096B3 EB5E                <1> 	jmp	short update_drv_error_byte
   158                              <1> 
   159                              <1> lba_write:
   160                              <1> 	; 23/02/2016
   161 000096B5 C605[A1B10000]1C    <1> 	mov	byte [disk_rw_op], 1Ch ; LBA write
   162 000096BC EB07                <1> 	jmp	short lba_rw
   163                              <1> 
   164                              <1> lba_read:
   165                              <1> 	; 23/02/2016
   166                              <1> 	; 17/02/2016
   167                              <1> 	; 14/02/2016
   168                              <1> 	; 13/02/2016
   169                              <1> 	; 31/01/2016 (TRDOS 386 =  TRDOS v2.0)
   170                              <1> 	; 10/07/2015 (Retro UNIX 386 v1)
   171                              <1> 	;
   172                              <1> 	; INPUT -> EAX = Logical Block Address
   173                              <1> 	;	   ESI = Logical Dos Disk Table Offset (DRV)	
   174                              <1> 	;	   ECX = Sector Count	
   175                              <1> 	; 	   EBX = Destination Buffer
   176                              <1> 	; OUTPUT -> 
   177                              <1> 	;	   cf = 0 or cf = 1
   178                              <1> 	; (Modified registers: EAX, EBX, ECX, EDX)
   179                              <1> 
   180                              <1> 	; LBA read/write (with private LBA function) 
   181                              <1> 	;((Retro UNIX 386 v1 - DISK I/O code by Erdogan Tan))
   182                              <1> 
   183                              <1> 
   184                              <1> 	; 23/02/2016
   185 000096BE C605[A1B10000]1B    <1> 	mov	byte [disk_rw_op], 1Bh ; LBA read
   186                              <1> 
   187                              <1> lba_rw:
   188                              <1> 	; 17/02/2016
   189 000096C5 57                  <1> 	push	edi
   190                              <1> 
   191 000096C6 890D[A4B10000]      <1> 	mov	[sector_count], ecx ; total sector (read) count
   192                              <1> 
   193 000096CC 8A5602              <1> 	mov	dl, [esi+LD_PhyDrvNo]
   194                              <1> 	; dl = physical drive number (0,1, 80h, 81h, 82h, 83h)
   195                              <1> 
   196                              <1> lba_read_next:
   197 000096CF 81F900010000        <1> 	cmp	ecx, 256
   198 000096D5 7605                <1> 	jna	short lba_read_rsc
   199 000096D7 B900010000          <1> 	mov	ecx, 256 ; 17/02/2016
   200                              <1> lba_read_rsc:
   201 000096DC 290D[A4B10000]      <1> 	sub	[sector_count], ecx ; remain sectors
   202                              <1> 
   203 000096E2 89CF                <1> 	mov	edi, ecx 
   204 000096E4 89C1                <1> 	mov	ecx, eax ; sector number/address
   205                              <1> 
   206 000096E6 C605[A2B10000]04    <1> 	mov	byte [retry_count], 4
   207                              <1> lba_read_retry:
   208 000096ED 89F8                <1> 	mov	eax, edi
   209                              <1> 	;
   210                              <1> 	; ecx = sector number
   211                              <1> 	; al = sector count (0 - 255) /// (0 = 256)
   212                              <1> 	; dl = drive number
   213                              <1> 	; ebx = buffer offset
   214                              <1> 	;
   215                              <1> 	; Function 1Bh = LBA read, 1Ch = LBA write
   216                              <1> 	; 23/02/2016
   217 000096EF 8A25[A1B10000]      <1> 	mov	ah, [disk_rw_op] ; 1Bh = LBA read, 1Ch = LBA write
   218 000096F5 E8D191FFFF          <1> 	call	int13h
   219                              <1> 	; al = ? (changed)
   220                              <1> 	; ah = error code
   221 000096FA 8825[A3B10000]      <1> 	mov	[disk_rw_err], ah
   222 00009700 7334                <1> 	jnc	short lba_read_ok
   223 00009702 80FC80              <1> 	cmp	ah, 80h ; time out?
   224 00009705 740A                <1>         je      short lba_read_stc_retn
   225 00009707 FE0D[A2B10000]      <1> 	dec	byte [retry_count]
   226 0000970D 7FDE                <1> 	jg	short lba_read_retry
   227 0000970F 743A                <1> 	jz	short lba_read_reset
   228                              <1> 	; sf =  1
   229                              <1> 
   230                              <1> lba_read_stc_retn:
   231 00009711 F9                  <1> 	stc
   232                              <1> lba_read_retn:
   233 00009712 5F                  <1> 	pop	edi
   234                              <1> 
   235                              <1> update_drv_error_byte:
   236 00009713 9C                  <1> 	pushf
   237 00009714 53                  <1> 	push	ebx
   238 00009715 6651                <1> 	push	cx
   239                              <1> 	;or	ecx, ecx
   240                              <1> 	;jz	short udrv_errb0
   241 00009717 8A0D[A3B10000]      <1> 	mov	cl, [disk_rw_err]
   242                              <1> udrv_errb0:
   243 0000971D 0FB65E02            <1> 	movzx	ebx, byte [esi+LD_PhyDrvNo]
   244 00009721 80FB02              <1> 	cmp	bl, 2
   245 00009724 7203                <1>         jb      short udrv_errb1
   246 00009726 80EB7E              <1> 	sub	bl, 7Eh
   247                              <1> 	;cmp	bl, 5
   248                              <1> 	;ja	short udrv_errb2	
   249                              <1> udrv_errb1:
   250 00009729 81C3[11A30000]      <1>         add     ebx, drv.error ; 13/02/2016
   251 0000972F 880B                <1> 	mov	[ebx], cl ; error code
   252                              <1> udrv_errb2:
   253 00009731 6659                <1> 	pop	cx
   254 00009733 5B                  <1> 	pop	ebx
   255 00009734 9D                  <1> 	popf
   256 00009735 C3                  <1> 	retn
   257                              <1> 
   258                              <1> lba_read_ok:
   259 00009736 89C8                <1> 	mov	eax, ecx ; sector number
   260 00009738 01F8                <1> 	add	eax, edi ; sector number (next)
   261 0000973A C1E709              <1> 	shl	edi, 9 ; sector count * 512
   262 0000973D 01FB                <1> 	add	ebx, edi ; next buffer offset
   263                              <1> 
   264 0000973F 8B0D[A4B10000]      <1> 	mov	ecx, [sector_count] ; remaining sectors
   265 00009745 09C9                <1> 	or	ecx, ecx
   266 00009747 7586                <1> 	jnz	short lba_read_next
   267 00009749 EBC7                <1> 	jmp	short lba_read_retn
   268                              <1> 
   269                              <1> lba_read_reset:
   270 0000974B B40D                <1> 	mov	ah, 0Dh ; Alternate reset
   271 0000974D E87991FFFF          <1>         call	int13h
   272                              <1> 	; al = ? (changed)
   273                              <1> 	; ah = error code
   274 00009752 7399                <1> 	jnc	short lba_read_retry
   275 00009754 EBBC                <1> 	jmp	short lba_read_retn
  1920                                  %include 'trdosk8.s' ; 24/01/2016
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - MAIN PROGRAM : trdosk8.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 24/01/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    11                              <1> ; XXXXXXXX.ASM (XX/XX/2011)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ; u0.s (20/11/2015)
    15                              <1> ; ****************************************************************************
    16                              <1> 
    17                              <1> INT4Ah:
    18                              <1> 	; 24/01/2016
    19                              <1> 	; this procedure will be called by 'RTC_INT' (in 'timer.s')
    20 00009756 C3                  <1> 	retn
    21                              <1> 
    22                              <1> ; u0.s
    23                              <1> ; Retro UNIX 386 v1 Kernel (v0.2) - SYS0.INC
    24                              <1> ; Last Modification: 20/11/2015
    25                              <1> 
    26                              <1> com2_int:
    27                              <1> 	; 07/11/2015 
    28                              <1> 	; 24/10/2015
    29                              <1> 	; 23/10/2015
    30                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
    31                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
    32                              <1> 	; < serial port 2 interrupt handler >
    33                              <1> 	;
    34 00009757 890424              <1> 	mov 	[esp], eax ; overwrite call return address
    35                              <1> 	;push	eax
    36 0000975A 66B80900            <1> 	mov	ax, 9
    37 0000975E EB07                <1> 	jmp	short comm_int
    38                              <1> com1_int:
    39                              <1> 	; 07/11/2015
    40                              <1> 	; 24/10/2015
    41 00009760 890424              <1> 	mov 	[esp], eax ; overwrite call return address
    42                              <1> 	; 23/10/2015
    43                              <1> 	;push	eax
    44 00009763 66B80800            <1> 	mov	ax, 8
    45                              <1> comm_int:
    46                              <1> 	; 20/11/2015
    47                              <1> 	; 18/11/2015
    48                              <1> 	; 17/11/2015
    49                              <1> 	; 16/11/2015
    50                              <1> 	; 09/11/2015
    51                              <1> 	; 08/11/2015
    52                              <1> 	; 07/11/2015
    53                              <1> 	; 06/11/2015 (serial4.asm, 'serial')	
    54                              <1> 	; 01/11/2015
    55                              <1> 	; 26/10/2015
    56                              <1> 	; 23/10/2015
    57 00009767 53                  <1> 	push	ebx
    58 00009768 56                  <1> 	push	esi
    59 00009769 57                  <1> 	push	edi
    60 0000976A 1E                  <1> 	push 	ds
    61 0000976B 06                  <1> 	push 	es
    62                              <1> 	; 18/11/2015
    63 0000976C 0F20DB              <1> 	mov	ebx, cr3
    64 0000976F 53                  <1> 	push	ebx ; ****
    65                              <1> 	;
    66 00009770 51                  <1> 	push	ecx ; ***
    67 00009771 52                  <1> 	push	edx ; **
    68                              <1> 	;
    69 00009772 BB10000000          <1> 	mov	ebx, KDATA
    70 00009777 8EDB                <1> 	mov	ds, bx
    71 00009779 8EC3                <1> 	mov	es, bx
    72                              <1> 	;
    73 0000977B 8B0D[E8A70000]      <1> 	mov	ecx, [k_page_dir]
    74 00009781 0F22D9              <1> 	mov	cr3, ecx
    75                              <1> 	; 20/11/2015
    76                              <1> 	; Interrupt identification register
    77 00009784 66BAFA02            <1> 	mov	dx, 2FAh ; COM2
    78                              <1> 	;
    79 00009788 3C08                <1> 	cmp 	al, 8 
    80 0000978A 7702                <1> 	ja 	short com_i0
    81                              <1> 	;
    82                              <1> 	; 20/11/2015
    83                              <1> 	; 17/11/2015
    84                              <1> 	; 16/11/2015
    85                              <1> 	; 15/11/2015
    86                              <1> 	; 24/10/2015
    87                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - Beginning)
    88                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1)
    89                              <1> 	; < serial port 1 interrupt handler >
    90                              <1> 	;
    91 0000978C FEC6                <1> 	inc	dh ; 3FAh ; COM1 Interrupt id. register
    92                              <1> com_i0:
    93                              <1> 	;push	eax ; *
    94                              <1> 	; 07/11/2015
    95 0000978E A2[58A80000]        <1> 	mov 	byte [ccomport], al
    96                              <1> 	; 09/11/2015
    97 00009793 0FB7D8              <1> 	movzx	ebx, ax ; 8 or 9
    98                              <1> 	; 17/11/2015
    99                              <1>  	; reset request for response status
   100 00009796 88A3[4EA80000]      <1> 	mov	[ebx+req_resp-8], ah ; 0
   101                              <1> 	;
   102                              <1> 	; 20/11/2015
   103 0000979C EC                  <1> 	in	al, dx		; read interrupt id. register
   104 0000979D EB00                <1> 	JMP	$+2	   	; I/O DELAY
   105 0000979F 2404                <1> 	and	al, 4		; received data available?	
   106 000097A1 7470                <1> 	jz	short com_eoi	; (transmit. holding reg. empty)
   107                              <1> 	;
   108                              <1> 	; 20/11/2015
   109 000097A3 80EA02              <1> 	sub	dl, 3FAh-3F8h	; data register (3F8h, 2F8h)
   110 000097A6 EC                  <1> 	in	al, dx     	; read character
   111                              <1> 	;JMP	$+2	   	; I/O DELAY
   112                              <1> 	; 08/11/2015
   113                              <1> 	; 07/11/2015
   114 000097A7 89DE                <1> 	mov	esi, ebx 
   115 000097A9 89DF                <1> 	mov	edi, ebx
   116 000097AB 81C6[52A80000]      <1> 	add 	esi, rchar - 8 ; points to last received char
   117 000097B1 81C7[54A80000]      <1> 	add	edi, schar - 8 ; points to last sent char
   118 000097B7 8806                <1> 	mov	[esi], al ; received char (current char)
   119                              <1> 	; query
   120 000097B9 20C0                <1> 	and	al, al
   121 000097BB 7527                <1> 	jnz	short com_i2
   122                              <1>    	; response
   123                              <1> 	; 17/11/2015
   124                              <1> 	; set request for response status
   125 000097BD FE83[4EA80000]      <1>         inc     byte [ebx+req_resp-8] ; 1 
   126                              <1> 	;
   127 000097C3 6683C205            <1> 	add	dx, 3FDh-3F8h	; (3FDh, 2FDh)
   128 000097C7 EC                  <1> 	in	al, dx	   	; read line status register 
   129 000097C8 EB00                <1> 	JMP	$+2	   	; I/O DELAY
   130 000097CA 2420                <1> 	and	al, 20h	   	; transmitter holding reg. empty?
   131 000097CC 7445                <1> 	jz	short com_eoi 	; no
   132 000097CE B0FF                <1> 	mov 	al, 0FFh   	; response			
   133 000097D0 6683EA05            <1> 	sub	dx, 3FDh-3F8h 	; data port (3F8h, 2F8h)
   134 000097D4 EE                  <1> 	out	dx, al	   	; send on serial port
   135                              <1> 	; 17/11/2015
   136 000097D5 803F00              <1> 	cmp 	byte [edi], 0   ; query ? (schar)
   137 000097D8 7502                <1> 	jne 	short com_i1    ; no
   138 000097DA 8807                <1> 	mov	[edi], al 	; 0FFh (responded)
   139                              <1> com_i1:
   140                              <1> 	; 17/11/2015
   141                              <1> 	; reset request for response status (again)
   142 000097DC FE8B[4EA80000]      <1>         dec     byte [ebx+req_resp-8] ; 0 
   143 000097E2 EB2F                <1> 	jmp	short com_eoi
   144                              <1> com_i2:	
   145                              <1> 	; 08/11/2015
   146 000097E4 3CFF                <1> 	cmp 	al, 0FFh	; (response ?)
   147 000097E6 7417                <1> 	je	short com_i3	; (check for response signal)
   148                              <1> 	; 07/11/2015
   149 000097E8 3C04                <1> 	cmp	al, 04h	; EOT
   150 000097EA 751C                <1> 	jne	short com_i4	
   151                              <1> 	; EOT = 04h (End of Transmit) - 'CTRL + D'
   152                              <1> 	;(an EOT char is supposed as a ctrl+brk from the terminal)
   153                              <1> 	; 08/11/2015
   154                              <1> 		; ptty -> tty 0 to 7 (pseudo screens)
   155 000097EC 861D[18A80000]      <1> 	xchg	bl, [ptty]  ; tty number (8 or 9)
   156 000097F2 E8BBA4FFFF          <1> 	call 	ctrlbrk
   157 000097F7 861D[18A80000]      <1> 	xchg	[ptty], bl ; (restore ptty value and BL value)
   158                              <1> 	;mov	al, 04h ; EOT
   159                              <1> 	; 08/11/2015
   160 000097FD EB09                <1> 	jmp	short com_i4	
   161                              <1> com_i3:
   162                              <1> 	; 08/11/2015
   163                              <1> 	; If 0FFh has been received just after a query
   164                              <1> 	; (schar, ZERO), it is a response signal.
   165                              <1> 	; 17/11/2015
   166 000097FF 803F00              <1>         cmp     byte [edi], 0 ; query ? (schar)
   167 00009802 7704                <1> 	ja	short com_i4 ; no
   168                              <1> 	; reset query status (schar)
   169 00009804 8807                <1> 	mov	[edi], al ; 0FFh
   170 00009806 FEC0                <1> 	inc	al ; 0
   171                              <1> com_i4:
   172                              <1> 	; 27/07/2014
   173                              <1> 	; 09/07/2014
   174 00009808 D0E3                <1> 	shl	bl, 1	
   175 0000980A 81C3[1AA80000]      <1> 	add	ebx, ttychr
   176                              <1> 	; 23/07/2014 (always overwrite)
   177                              <1> 	;;cmp	word [ebx], 0
   178                              <1> 	;;ja	short com_eoi
   179                              <1> 	;
   180 00009810 668903              <1> 	mov	[ebx], ax   ; Save ascii code
   181                              <1> 			    ; scan code = 0
   182                              <1> com_eoi:
   183                              <1> 	;mov	al, 20h
   184                              <1> 	;out	20h, al	   ; end of interrupt
   185                              <1> 	;
   186                              <1> 	; 07/11/2015
   187                              <1>       	;pop	eax ; *
   188 00009813 A0[58A80000]        <1> 	mov	al, byte [ccomport] ; current COM port
   189                              <1> 	 ; al = tty number (8 or 9)
   190 00009818 E85E010000          <1>         call	wakeup
   191                              <1> com_iret:
   192                              <1> 	; 23/10/2015
   193 0000981D 5A                  <1> 	pop	edx ; **
   194 0000981E 59                  <1> 	pop	ecx ; ***
   195                              <1> 	; 18/11/2015
   196                              <1> 	;pop	eax ; ****
   197                              <1> 	;mov	cr3, eax
   198                              <1> 	;jmp	iiret
   199 0000981F E93772FFFF          <1> 	jmp	iiretp
   200                              <1> 
   201                              <1> ;iiretp: ; 01/09/2015
   202                              <1> ;	; 28/08/2015
   203                              <1> ;	pop	eax ; (*) page directory
   204                              <1> ;	mov	cr3, eax
   205                              <1> ;iiret:
   206                              <1> ;	; 22/08/2014
   207                              <1> ;	mov	al, 20h ; END OF INTERRUPT COMMAND TO 8259
   208                              <1> ;	out	20h, al	; 8259 PORT
   209                              <1> ;	;
   210                              <1> ;	pop	es
   211                              <1> ;	pop	ds
   212                              <1> ;	pop	edi
   213                              <1> ;	pop	esi
   214                              <1> ;	pop	ebx ; 29/08/2014
   215                              <1> ;	pop 	eax
   216                              <1> ;	iretd
   217                              <1> 
   218                              <1> sp_init:
   219                              <1> 	; 07/11/2015
   220                              <1> 	; 29/10/2015
   221                              <1> 	; 26/10/2015
   222                              <1> 	; 23/10/2015
   223                              <1> 	; 29/06/2015
   224                              <1> 	; 14/03/2015 (Retro UNIX 386 v1 - 115200 baud)
   225                              <1> 	; 28/07/2014 (Retro UNIX 8086 v1 - 9600 baud)
   226                              <1> 	; Initialization of Serial Port Communication Parameters
   227                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
   228                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
   229                              <1> 	;
   230                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
   231                              <1> 	;
   232                              <1> 	; INPUT:  (29/06/2015)
   233                              <1> 	;	AL = 0 for COM1
   234                              <1> 	;	     1 for COM2
   235                              <1> 	;	AH = Communication parameters	
   236                              <1> 	;
   237                              <1> 	;  (*) Communication parameters (except BAUD RATE):
   238                              <1> 	;	Bit	4	3	2	1	0
   239                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
   240                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
   241                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
   242                              <1> 	;		11 = even
   243                              <1> 	;  Baud rate setting bits: (29/06/2015)
   244                              <1> 	;		Retro UNIX 386 v1 feature only !
   245                              <1> 	;	Bit	7    6    5  | Baud rate
   246                              <1> 	;		------------------------
   247                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
   248                              <1> 	;		0    0    1  | 9600 (12)
   249                              <1> 	;		0    1    0  | 19200 (6) 
   250                              <1> 	;		0    1	  1  | 38400 (3) 
   251                              <1> 	;		1    0	  0  | 14400 (8)
   252                              <1> 	;		1    0	  1  | 28800 (4)
   253                              <1> 	;		1    1    0  | 57600 (2)
   254                              <1> 	;		1    1    1  | 115200 (1) 	
   255                              <1> 	
   256                              <1> 	; References:	
   257                              <1> 	; (1) IBM PC-XT Model 286 BIOS Source Code
   258                              <1> 	;     RS232.ASM --- 10/06/1985 COMMUNICATIONS BIOS (RS232)
   259                              <1> 	; (2) Award BIOS 1999 - ATORGS.ASM
   260                              <1> 	; (3) http://wiki.osdev.org/Serial_Ports
   261                              <1> 	;
   262                              <1> 	; Set communication parameters for COM1 (= 03h)	
   263                              <1> 	;
   264 00009824 BB[54A80000]        <1> 	mov	ebx, com1p		; COM1 parameters  
   265 00009829 66BAF803            <1> 	mov	dx, 3F8h		; COM1
   266                              <1> 	 ; 29/10/2015
   267 0000982D 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
   268 00009831 E86F000000          <1> 	call	sp_i3	; call A4	
   269 00009836 A880                <1> 	test	al, 80h
   270 00009838 7410                <1> 	jz	short sp_i0 ; OK..
   271                              <1> 		; Error !
   272                              <1> 	;mov	dx, 3F8h
   273 0000983A 80EA05              <1> 	sub	dl, 5 ; 3FDh -> 3F8h
   274 0000983D 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
   275 00009841 E85F000000          <1> 	call	sp_i3	; call A4	
   276 00009846 A880                <1> 	test	al, 80h
   277 00009848 7508                <1> 	jnz	short sp_i1
   278                              <1> sp_i0:
   279                              <1>         ; (Note: Serial port interrupts will be disabled here...)	
   280                              <1>         ; (INT 14h initialization code disables interrupts.)
   281                              <1> 	;
   282 0000984A C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
   283 0000984D E8DC000000          <1> 	call	sp_i5 ; 29/06/2015
   284                              <1> sp_i1:
   285 00009852 43                  <1> 	inc	ebx
   286 00009853 66BAF802            <1> 	mov	dx, 2F8h		; COM2
   287                              <1> 	 ; 29/10/2015
   288 00009857 66B90103            <1> 	mov	cx, 301h  ; divisor = 1 (115200 baud)
   289 0000985B E845000000          <1> 	call	sp_i3	; call A4	
   290 00009860 A880                <1> 	test	al, 80h
   291 00009862 7410                <1> 	jz	short sp_i2 ; OK..
   292                              <1> 		; Error !
   293                              <1> 	;mov	dx, 2F8h
   294 00009864 80EA05              <1> 	sub	dl, 5 ; 2FDh -> 2F8h
   295 00009867 66B90E03            <1> 	mov	cx, 30Eh  ; divisor = 12 (9600 baud)
   296 0000986B E835000000          <1> 	call	sp_i3	; call A4	
   297 00009870 A880                <1> 	test	al, 80h
   298 00009872 7530                <1> 	jnz	short sp_i7
   299                              <1> sp_i2:
   300 00009874 C603E3              <1> 	mov	byte [ebx], 0E3h ; 11100011b
   301                              <1> sp_i6:
   302                              <1> 	;; COM2 - enabling IRQ 3
   303                              <1> 	; 07/11/2015
   304                              <1> 	; 26/10/2015
   305 00009877 9C                  <1> 	pushf
   306 00009878 FA                  <1> 	cli
   307                              <1> 	;
   308 00009879 66BAFC02            <1> 	mov	dx, 2FCh   		; modem control register
   309 0000987D EC                  <1> 	in	al, dx 	   		; read register
   310 0000987E EB00                <1> 	JMP	$+2	   		; I/O DELAY
   311 00009880 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
   312 00009882 EE                  <1> 	out	dx, al     		; write back to register
   313 00009883 EB00                <1> 	JMP	$+2	   		; I/O DELAY
   314 00009885 66BAF902            <1> 	mov	dx, 2F9h   		; interrupt enable register
   315 00009889 EC                  <1> 	in	al, dx     		; read register
   316 0000988A EB00                <1> 	JMP	$+2	   		; I/O DELAY
   317                              <1> 	;or	al, 1      		; receiver data interrupt enable and
   318 0000988C 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
   319 0000988E EE                  <1> 	out	dx, al 	   		; write back to register
   320 0000988F EB00                <1> 	JMP	$+2        		; I/O DELAY
   321 00009891 E421                <1> 	in	al, 21h    		; read interrupt mask register
   322 00009893 EB00                <1> 	JMP	$+2	   		; I/O DELAY
   323 00009895 24F7                <1> 	and	al, 0F7h   		; enable IRQ 3 (COM2)
   324 00009897 E621                <1> 	out	21h, al    		; write back to register
   325                              <1> 	;
   326                              <1> 	; 23/10/2015
   327 00009899 B8[57970000]        <1> 	mov 	eax, com2_int
   328 0000989E A3[76990000]        <1> 	mov	[com2_irq3], eax
   329                              <1> 	; 26/10/2015
   330 000098A3 9D                  <1> 	popf	
   331                              <1> sp_i7:
   332 000098A4 C3                  <1> 	retn
   333                              <1> 
   334                              <1> sp_i3:
   335                              <1> ;A4:  	;-----	INITIALIZE THE COMMUNICATIONS PORT
   336                              <1> 	; 28/10/2015
   337 000098A5 FEC2                <1> 	inc	dl	; 3F9h (2F9h)	; 3F9h, COM1 Interrupt enable register 
   338 000098A7 B000                <1> 	mov	al, 0
   339 000098A9 EE                  <1> 	out	dx, al			; disable serial port interrupt
   340 000098AA EB00                <1> 	JMP	$+2			; I/O DELAY
   341 000098AC 80C202              <1> 	add	dl, 2 	; 3FBh (2FBh)	; COM1 Line control register (3FBh)
   342 000098AF B080                <1> 	mov	al, 80h			
   343 000098B1 EE                  <1> 	out	dx, al			; SET DLAB=1 ; divisor latch access bit
   344                              <1> 	;-----	SET BAUD RATE DIVISOR
   345                              <1> 	; 26/10/2015
   346 000098B2 80EA03              <1> 	sub 	dl, 3   ; 3F8h (2F8h)	; register for least significant byte
   347                              <1> 					; of the divisor value
   348 000098B5 88C8                <1> 	mov	al, cl	; 1
   349 000098B7 EE                  <1> 	out	dx, al			; 1 = 115200 baud (Retro UNIX 386 v1)
   350                              <1> 					; 2 = 57600 baud
   351                              <1> 					; 3 = 38400 baud
   352                              <1> 					; 6 = 19200 baud
   353                              <1> 					; 12 = 9600 baud (Retro UNIX 8086 v1)
   354 000098B8 EB00                <1> 	JMP	$+2			; I/O DELAY
   355 000098BA 28C0                <1> 	sub	al, al
   356 000098BC FEC2                <1> 	inc	dl      ; 3F9h (2F9h)	; register for most significant byte
   357                              <1> 					; of the divisor value
   358 000098BE EE                  <1> 	out	dx, al ; 0
   359 000098BF EB00                <1> 	JMP	$+2			; I/O DELAY
   360                              <1> 	;	
   361 000098C1 88E8                <1> 	mov	al, ch ; 3		; 8 data bits, 1 stop bit, no parity
   362                              <1> 	;and	al, 1Fh ; Bits 0,1,2,3,4	
   363 000098C3 80C202              <1> 	add	dl, 2	; 3FBh (2FBh)	; Line control register
   364 000098C6 EE                  <1> 	out	dx, al			
   365 000098C7 EB00                <1> 	JMP	$+2			; I/O DELAY
   366                              <1> 	; 29/10/2015
   367 000098C9 FECA                <1> 	dec 	dl 	; 3FAh (2FAh)	; FIFO Control register (16550/16750)
   368 000098CB 30C0                <1> 	xor	al, al			; 0
   369 000098CD EE                  <1> 	out	dx, al			; Disable FIFOs (reset to 8250 mode)
   370 000098CE EB00                <1> 	JMP	$+2	
   371                              <1> sp_i4:
   372                              <1> ;A18:	;-----	COMM PORT STATUS ROUTINE
   373                              <1> 	; 29/06/2015 (line status after modem status)
   374 000098D0 80C204              <1> 	add	dl, 4	; 3FEh (2FEh)	; Modem status register
   375                              <1> sp_i4s:
   376 000098D3 EC                  <1> 	in	al, dx			; GET MODEM CONTROL STATUS
   377 000098D4 EB00                <1> 	JMP	$+2			; I/O DELAY
   378 000098D6 88C4                <1> 	mov	ah, al			; PUT IN (AH) FOR RETURN
   379 000098D8 FECA                <1> 	dec	dl	; 3FDh (2FDh)	; POINT TO LINE STATUS REGISTER
   380                              <1> 					; dx = 3FDh for COM1, 2FDh for COM2
   381 000098DA EC                  <1> 	in	al, dx			; GET LINE CONTROL STATUS
   382                              <1> 	; AL = Line status, AH = Modem status
   383 000098DB C3                  <1> 	retn
   384                              <1> 
   385                              <1> sp_status:
   386                              <1> 	; 29/06/2015
   387                              <1> 	; 27/06/2015 (Retro UNIX 386 v1)
   388                              <1> 	; Get serial port status
   389 000098DC 66BAFE03            <1> 	mov	dx, 3FEh		; Modem status register (COM1)
   390 000098E0 28C6                <1> 	sub	dh, al			; dh = 2 for COM2 (al = 1)
   391                              <1> 					; dx = 2FEh for COM2
   392 000098E2 EBEF                <1> 	jmp	short sp_i4s
   393                              <1> 
   394                              <1> sp_setp: ; Set serial port communication parameters
   395                              <1> 	; 07/11/2015
   396                              <1> 	; 29/10/2015
   397                              <1> 	; 29/06/2015
   398                              <1> 	; Retro UNIX 386 v1 feature only !	
   399                              <1> 	;
   400                              <1> 	; INPUT:
   401                              <1> 	;	AL = 0 for COM1
   402                              <1> 	;	     1 for COM2
   403                              <1> 	;	AH = Communication parameters (*)
   404                              <1> 	; OUTPUT:
   405                              <1> 	;	CL = Line status
   406                              <1> 	;	CH = Modem status
   407                              <1> 	;   If cf = 1 -> Error code in [u.error]
   408                              <1> 	;		 'invalid parameter !' 
   409                              <1> 	;		 	 or
   410                              <1> 	;		 'device not ready !' error
   411                              <1> 	;	
   412                              <1> 	;  (*) Communication parameters (except BAUD RATE):
   413                              <1> 	;	Bit	4	3	2	1	0
   414                              <1> 	;		-PARITY--   STOP BIT  -WORD LENGTH-	 		 
   415                              <1> 	;  this one -->	00 = none    0 = 1 bit  11 = 8 bits
   416                              <1> 	;		01 = odd     1 = 2 bits	10 = 7 bits
   417                              <1> 	;		11 = even
   418                              <1> 	;  Baud rate setting bits: (29/06/2015)
   419                              <1> 	;		Retro UNIX 386 v1 feature only !
   420                              <1> 	;	Bit	7    6    5  | Baud rate
   421                              <1> 	;		------------------------
   422                              <1> 	;	value	0    0    0  | Default (Divisor = 1)
   423                              <1> 	;		0    0    1  | 9600 (12)
   424                              <1> 	;		0    1    0  | 19200 (6) 
   425                              <1> 	;		0    1	  1  | 38400 (3) 
   426                              <1> 	;		1    0	  0  | 14400 (8)
   427                              <1> 	;		1    0	  1  | 28800 (4)
   428                              <1> 	;		1    1    0  | 57600 (2)
   429                              <1> 	;		1    1    1  | 115200 (1) 
   430                              <1> 	;
   431                              <1> 	; (COM1 base port address = 3F8h, COM1 Interrupt = IRQ 4)
   432                              <1> 	; (COM2 base port address = 2F8h, COM1 Interrupt = IRQ 3)
   433                              <1> 	;
   434                              <1> 	; ((Modified registers: EAX, ECX, EDX, EBX))
   435                              <1> 	;
   436 000098E4 66BAF803            <1> 	mov	dx, 3F8h
   437 000098E8 BB[54A80000]        <1> 	mov	ebx, com1p ; COM1 control byte offset
   438 000098ED 3C01                <1> 	cmp	al, 1
   439 000098EF 776B                <1> 	ja 	short sp_invp_err
   440 000098F1 7203                <1> 	jb	short sp_setp1 ;  COM1 (AL = 0)
   441 000098F3 FECE                <1> 	dec	dh ; 2F8h
   442 000098F5 43                  <1> 	inc	ebx ; COM2 control byte offset
   443                              <1> sp_setp1:
   444                              <1> 	; 29/10/2015
   445 000098F6 8823                <1> 	mov	[ebx], ah
   446 000098F8 0FB6CC              <1> 	movzx 	ecx, ah
   447 000098FB C0E905              <1> 	shr	cl, 5 ; -> baud rate index
   448 000098FE 80E41F              <1> 	and	ah, 1Fh ; communication parameters except baud rate
   449 00009901 8A81[6B990000]      <1> 	mov	al, [ecx+b_div_tbl]
   450 00009907 6689C1              <1> 	mov	cx, ax
   451 0000990A E896FFFFFF          <1> 	call	sp_i3
   452 0000990F 6689C1              <1> 	mov	cx, ax ; CL = Line status, CH = Modem status
   453 00009912 A880                <1> 	test	al, 80h
   454 00009914 740F                <1> 	jz	short sp_setp2
   455 00009916 C603E3              <1>         mov     byte [ebx], 0E3h ; Reset to initial value (11100011b)
   456                              <1> stp_dnr_err:
   457 00009919 C705[15B80000]0F00- <1> 	mov	dword [u.error], ERR_DEV_NOT_RDY ; 'device not ready !'
   457 00009921 0000                <1>
   458                              <1> 	; CL = Line status, CH = Modem status
   459 00009923 F9                  <1> 	stc
   460 00009924 C3                  <1> 	retn
   461                              <1> sp_setp2:
   462 00009925 80FE02              <1> 	cmp	dh, 2 ; COM2 (2F?h)
   463 00009928 0F8649FFFFFF        <1>         jna     sp_i6 
   464                              <1> 		      ; COM1 (3F?h)
   465                              <1> sp_i5: 
   466                              <1> 	; 07/11/2015
   467                              <1> 	; 26/10/2015
   468                              <1> 	; 29/06/2015
   469                              <1> 	;
   470                              <1> 	;; COM1 - enabling IRQ 4
   471 0000992E 9C                  <1> 	pushf
   472 0000992F FA                  <1> 	cli
   473 00009930 66BAFC03            <1> 	mov	dx, 3FCh   		; modem control register
   474 00009934 EC                  <1> 	in	al, dx 	   		; read register
   475 00009935 EB00                <1> 	JMP	$+2			; I/O DELAY
   476 00009937 0C08                <1> 	or	al, 8      		; enable bit 3 (OUT2)
   477 00009939 EE                  <1> 	out	dx, al     		; write back to register
   478 0000993A EB00                <1> 	JMP	$+2			; I/O DELAY
   479 0000993C 66BAF903            <1> 	mov	dx, 3F9h   		; interrupt enable register
   480 00009940 EC                  <1> 	in	al, dx     		; read register
   481 00009941 EB00                <1> 	JMP	$+2			; I/O DELAY
   482                              <1> 	;or	al, 1      		; receiver data interrupt enable and
   483 00009943 0C03                <1> 	or	al, 3	   		; transmitter empty interrupt enable
   484 00009945 EE                  <1> 	out	dx, al 	   		; write back to register
   485 00009946 EB00                <1> 	JMP	$+2        		; I/O DELAY
   486 00009948 E421                <1> 	in	al, 21h    		; read interrupt mask register
   487 0000994A EB00                <1> 	JMP	$+2			; I/O DELAY
   488 0000994C 24EF                <1> 	and	al, 0EFh   		; enable IRQ 4 (COM1)
   489 0000994E E621                <1> 	out	21h, al    		; write back to register
   490                              <1> 	;
   491                              <1> 	; 23/10/2015
   492 00009950 B8[60970000]        <1> 	mov 	eax, com1_int
   493 00009955 A3[72990000]        <1> 	mov	[com1_irq4], eax
   494                              <1> 	; 26/10/2015
   495 0000995A 9D                  <1> 	popf
   496 0000995B C3                  <1> 	retn
   497                              <1> 
   498                              <1> sp_invp_err:
   499 0000995C C705[15B80000]1700- <1> 	mov	dword [u.error], ERR_INV_PARAMETER ; 'invalid parameter !' 
   499 00009964 0000                <1>
   500 00009966 31C9                <1> 	xor	ecx, ecx
   501 00009968 49                  <1> 	dec	ecx ; 0FFFFh
   502 00009969 F9                  <1> 	stc
   503 0000996A C3                  <1> 	retn
   504                              <1> 
   505                              <1> ; 29/10/2015
   506                              <1> b_div_tbl: ; Baud rate divisor table (115200/divisor)
   507 0000996B 010C0603080401      <1> 	db 1, 12, 6, 3, 8, 4, 1
   508                              <1> 
   509                              <1> 
   510                              <1> ; 23/10/2015
   511                              <1> com1_irq4:
   512 00009972 [7A990000]          <1> 	dd dummy_retn
   513                              <1> com2_irq3:
   514 00009976 [7A990000]          <1> 	dd dummy_retn
   515                              <1> 
   516                              <1> dummy_retn:
   517 0000997A C3                  <1> 	retn
   518                              <1> 
   519                              <1> wakeup:
   520                              <1> 	; 24/01/2016
   521 0000997B C3                  <1> 	retn
  1921                                  %include 'trdosk9.s' ; 04/01/2016
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - INITIALIZED DATA : trdosk9.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 06/03/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 04/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; ----------------------------------------------------------------------------
     9                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
    10                              <1> ; ----------------------------------------------------------------------------
    11                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    12                              <1> ; TRDOS2.ASM (09/11/2011)
    13                              <1> ; ****************************************************************************
    14                              <1> ; DRV_INIT.ASM [26/09/2009] Last Update: 07/08/2011
    15                              <1> ; MAINPROG.ASM [17/01/2004] Last Update: 09/11/2011
    16                              <1> ; CMD_INTR.ASM [29/01/2005] Last Update: 09/11/2011
    17                              <1> ; FILE.ASM [29/10/2009] Last Update: 09/10/2011
    18                              <1> 
    19                              <1> ; 12/02/2016
    20                              <1> Last_DOS_DiskNo: 
    21 0000997C 01                  <1> 		db 1 ; A: = 0 & B: = 1
    22                              <1> 
    23                              <1> Restore_CDIR:	
    24 0000997D FF                  <1> 		db 0FFh ; Initial value -> any number except 0
    25                              <1> 
    26                              <1> msg_CRLF_temp:  
    27 0000997E 070D0A00            <1> 		db  07h, 0Dh, 0Ah, 0
    28                              <1> 
    29                              <1> Magic_Bytes:
    30 00009982 04                  <1> 		db 4
    31 00009983 01                  <1> 		db 1
    32                              <1> mainprog_Version:
    33 00009984 07                  <1> 		db 7
    34 00009985 5B5452444F535D204D- <1> 		db "[TRDOS] Main Program v2.0.060316"
    34 0000998E 61696E2050726F6772- <1>
    34 00009997 616D2076322E302E30- <1>
    34 000099A0 3630333136          <1>
    35 000099A5 0D0A                <1> 		db 0Dh, 0Ah
    36 000099A7 286329204572646F67- <1> 		db "(c) Erdogan Tan 2005-2016"
    36 000099B0 616E2054616E203230- <1>
    36 000099B9 30352D32303136      <1>
    37 000099C0 0D0A00              <1> 		db 0Dh, 0Ah, 0
    38                              <1> 
    39                              <1> MainProgCfgFile:
    40 000099C3 4D41494E50524F472E- <1> 		db "MAINPROG.CFG", 0
    40 000099CC 43464700            <1>
    41                              <1> 
    42                              <1> TRDOSPromptLabel:
    43 000099D0 5452444F53          <1> 		db "TRDOS"
    44 000099D5 00                  <1> 		db 0
    45 000099D6 00<rept>            <1>                 times 5 db 0
    46 000099DB 00                  <1> 		db 0
    47                              <1> 
    48                              <1> ; INTERNAL COMMANDS
    49                              <1> Command_List:
    50 000099DC 44495200            <1> Cmd_Dir:	db "DIR", 0
    51 000099E0 434400              <1> Cmd_Cd:		db "CD", 0
    52 000099E3 433A00              <1> Cmd_Drive:	db "C:", 0
    53 000099E6 56455200            <1> Cmd_Ver:	db "VER", 0
    54 000099EA 4558495400          <1> Cmd_Exit:	db "EXIT", 0
    55 000099EF 50524F4D505400      <1> Cmd_Prompt:	db "PROMPT", 0
    56 000099F6 564F4C554D4500      <1> Cmd_Volume:	db "VOLUME", 0
    57 000099FD 4C4F4E474E414D4500  <1> Cmd_LongName:	db "LONGNAME", 0
    58 00009A06 4441544500          <1> Cmd_Date:	db "DATE", 0
    59 00009A0B 54494D4500          <1> Cmd_Time:	db "TIME", 0
    60 00009A10 52554E00            <1> Cmd_Run:	db "RUN", 0
    61 00009A14 53455400            <1> Cmd_Set:	db "SET", 0 
    62 00009A18 434C5300            <1> Cmd_Cls:	db "CLS", 0
    63 00009A1C 53484F5700          <1> Cmd_Show:	db "SHOW", 0
    64 00009A21 44454C00            <1> Cmd_Del:	db "DEL", 0
    65 00009A25 41545452494200      <1> Cmd_Attrib:	db "ATTRIB", 0
    66 00009A2C 52454E414D4500      <1> Cmd_Rename:	db "RENAME", 0
    67 00009A33 524D44495200        <1> Cmd_Rmdir:	db "RMDIR", 0
    68 00009A39 4D4B44495200        <1> Cmd_Mkdir:	db "MKDIR", 0
    69 00009A3F 434F505900          <1> Cmd_Copy:	db "COPY", 0
    70 00009A44 4D4F564500          <1> Cmd_Move:	db "MOVE", 0
    71 00009A49 5041544800          <1> Cmd_Path:	db "PATH", 0
    72 00009A4E 4D454D00            <1> Cmd_Mem:	db "MEM", 0
    73 00009A52 00                  <1> 		db 0
    74 00009A53 46494E4400          <1> Cmd_Find:	db "FIND", 0
    75 00009A58 5245414446494C4500  <1> Cmd_ReadFile:	db "READFILE", 0
    76 00009A61 4543484F00          <1> Cmd_Echo:	db "ECHO", 0
    77 00009A66 2A00                <1> Cmd_Remark:	db "*", 0
    78 00009A68 3F00                <1> Cmd_Help:	db "?", 0
    79 00009A6A 44455649434500      <1> Cmd_Device:	db "DEVICE", 0
    80 00009A71 4445564C49535400    <1> Cmd_DevList:	db "DEVLIST", 0
    81 00009A79 434844495200        <1> Cmd_Chdir:	db "CHDIR", 0
    82 00009A7F 4245455000          <1> Cmd_Beep:	db "BEEP", 0
    83                              <1> 		
    84 00009A84 00                  <1> 		db 0
    85                              <1> 
    86                              <1> ; 15/02/2016 (FILE.ASM, 09/10/2011)
    87                              <1> invalid_fname_chars:
    88 00009A85 222728292A2B2C2F    <1> 		db 22h, 27h, 28h, 29h, 2Ah, 2Bh, 2Ch, 2Fh
    89 00009A8D 3A3B3C3D3E3F40      <1> 		db 3Ah, 3Bh, 3Ch, 3Dh, 3Eh, 3Fh, 40h
    90 00009A94 5B5C5D5E60          <1> 		db 5Bh, 5Ch, 5Dh, 5Eh, 60h
    91                              <1> sizeInvFnChars  equ ($ - invalid_fname_chars)                
    92                              <1> ;
    93                              <1> 
    94                              <1> Msg_Enter_Date:
    95 00009A99 456E746572206E6577- <1>                 db 'Enter new date (dd-mm-yy): '
    95 00009AA2 206461746520286464- <1>
    95 00009AAB 2D6D6D2D7979293A20  <1>
    96 00009AB4 00                  <1>                 db 0
    97                              <1> Msg_Show_Date:
    98 00009AB5 43757272656E742064- <1>                 db   'Current date is '
    98 00009ABE 61746520697320      <1>
    99 00009AC5 30                  <1> Day:            db   '0'
   100 00009AC6 30                  <1> 		db   '0'
   101 00009AC7 2F                  <1>                 db   '/'
   102 00009AC8 30                  <1> Month:          db   '0'
   103 00009AC9 30                  <1> 		db   '0'
   104 00009ACA 2F                  <1>                 db   '/'
   105 00009ACB 30                  <1> Century:        db   '0'
   106 00009ACC 30                  <1>                 db   '0'
   107 00009ACD 30                  <1> Year:           db   '0'
   108 00009ACE 30                  <1> 		db   '0'
   109 00009ACF 0D0A00              <1>                 db   0Dh, 0Ah, 0
   110                              <1> 
   111                              <1> Msg_Enter_Time:
   112 00009AD2 456E746572206E6577- <1> 		db 'Enter new time: '
   112 00009ADB 2074696D653A20      <1>
   113 00009AE2 00                  <1> 		db 0
   114                              <1> Msg_Show_Time:
   115 00009AE3 43757272656E742074- <1> 		db   'Current time is '
   115 00009AEC 696D6520697320      <1>
   116 00009AF3 30                  <1> Hour:           db   '0'
   117 00009AF4 30                  <1> 		db   '0'
   118 00009AF5 3A                  <1> 		db   ':'
   119 00009AF6 30                  <1> Minute:         db   '0'
   120 00009AF7 30                  <1> 		db   '0'
   121 00009AF8 3A                  <1> 		db   ':'
   122 00009AF9 30                  <1> Second:         db   '0'
   123 00009AFA 30                  <1> 		db   '0'
   124 00009AFB 0D0A00              <1> 		db   0Dh, 0Ah, 0
   125                              <1> 
   126                              <1> ;VolSize_Unit1:   dd 0
   127                              <1> ;VolSize_Unit2:   dd 0
   128                              <1> 
   129                              <1> VolSize_KiloBytes:
   130 00009AFE 206B696C6F62797465- <1> 		db " kilobytes", 0Dh, 0Ah, 0
   130 00009B07 730D0A00            <1>
   131                              <1> VolSize_Bytes:
   132 00009B0B 2062797465730D0A00  <1> 		db " bytes", 0Dh, 0Ah, 0
   133                              <1> Volume_in_drive:
   134 00009B14 0D0A                <1> 		db 0Dh, 0Ah
   135                              <1> Vol_FS_Name:
   136 00009B16 54522046533120      <1> 		db "TR FS1 "
   137 00009B1D 566F6C756D6520696E- <1> 		db "Volume in drive "
   137 00009B26 20647269766520      <1>
   138 00009B2D 30                  <1> Vol_Drv_Name:   db 30h
   139 00009B2E 3A                  <1> 		db ":"
   140 00009B2F 20697320            <1> 		db " is "
   141 00009B33 0D0A00              <1> 		db 0Dh, 0Ah, 0
   142                              <1> Dir_Drive_Str:
   143 00009B36 54522D444F53204472- <1>                 db "TR-DOS Drive "
   143 00009B3F 69766520            <1>
   144                              <1> Dir_Drive_Name:
   145 00009B43 303A                <1>                 db "0:"
   146 00009B45 0D0A                <1>                 db  0Dh, 0Ah
   147                              <1> Vol_Str_Header:
   148 00009B47 566F6C756D65204E61- <1>                 db "Volume Name: "
   148 00009B50 6D653A20            <1>
   149                              <1> Vol_Name:
   150 00009B54 00<rept>            <1> 		times 64 db 0
   151 00009B94 00                  <1> 		db 0
   152                              <1> Vol_Serial_Header:
   153 00009B95 0D0A                <1> 		db 0Dh, 0Ah
   154 00009B97 566F6C756D65205365- <1> 		db "Volume Serial No: "
   154 00009BA0 7269616C204E6F3A20  <1>
   155                              <1> Vol_Serial1:
   156 00009BA9 30303030            <1> 		db "0000"
   157 00009BAD 2D                  <1> 		db "-"
   158                              <1> Vol_Serial2:
   159 00009BAE 30303030            <1> 		db "0000"
   160 00009BB2 0D0A00              <1> 		db 0Dh, 0Ah, 0
   161                              <1> 
   162                              <1> ;Vol_Tot_Sec_Str_Start:
   163                              <1> ;		dd 0
   164                              <1> Vol_Total_Sector_Header:
   165 00009BB5 0D0A                <1> 		db 0Dh, 0Ah
   166 00009BB7 566F6C756D65205369- <1> 		db "Volume Size : ", 0
   166 00009BC0 7A65203A2000        <1>
   167                              <1> ;Vol_Tot_Sec_Str: 
   168                              <1> ;		db "0000000000"
   169                              <1> ;Vol_Tot_Sec_Str_End:
   170                              <1> ;		db 0
   171                              <1> ;Vol_Free_Sectors_Str_Start:
   172                              <1> ;		dd 0
   173                              <1> Vol_Free_Sectors_Header:
   174 00009BC6 467265652053706163- <1> 		db "Free Space  : ", 0
   174 00009BCF 6520203A2000        <1>
   175                              <1> ;Vol_Free_Sectors_Str:
   176                              <1> ;		db "0000000000"
   177                              <1> ;Vol_Free_Sectors_Str_End:
   178                              <1> ;		db 0
   179                              <1> 
   180                              <1> Dir_Str_Header:
   181 00009BD5 4469726563746F7279- <1>                 db "Directory: "
   181 00009BDE 3A20                <1>
   182 00009BE0 2F                  <1> Dir_Str_Root:   db "/"
   183 00009BE1 00<rept>            <1> Dir_Str:        times 64 db 0
   184 00009C21 00000000            <1>                 dd 0
   185 00009C25 00                  <1>                 db 0
   186                              <1> 
   187                              <1> Msg_Bad_Command:
   188 00009C26 42616420636F6D6D61- <1>                 db "Bad command or file name!"
   188 00009C2F 6E64206F722066696C- <1>
   188 00009C38 65206E616D6521      <1>
   189 00009C3F 0D0A00              <1>                 db 0Dh, 0Ah, 0
   190                              <1> 
   191                              <1> msgl_drv_not_ready: 
   192 00009C42 070D0A              <1> 		db 07h, 0Dh, 0Ah
   193                              <1> 
   194                              <1> ; CMD_INTR.ASM - 09/11/2011 - Messages
   195                              <1> 
   196                              <1> Msg_Not_Ready_Read_Err:
   197 00009C45 4472697665206E6F74- <1>                 db "Drive not ready or read error!"
   197 00009C4E 207265616479206F72- <1>
   197 00009C57 207265616420657272- <1>
   197 00009C60 6F7221              <1>
   198 00009C63 0D0A00              <1>                 db 0Dh, 0Ah, 0
   199                              <1> 
   200                              <1> Msg_Not_Ready_Write_Err:
   201 00009C66 4472697665206E6F74- <1>                 db "Drive not ready or write error!"
   201 00009C6F 207265616479206F72- <1>
   201 00009C78 207772697465206572- <1>
   201 00009C81 726F7221            <1>
   202 00009C85 0D0A00              <1>                 db 0Dh, 0Ah, 0
   203                              <1> 
   204                              <1> Msg_Dir_Not_Found:
   205 00009C88 4469726563746F7279- <1>                 db "Directory not found!"
   205 00009C91 206E6F7420666F756E- <1>
   205 00009C9A 6421                <1>
   206 00009C9C 0D0A00              <1>                 db 0Dh, 0Ah, 0
   207                              <1> 
   208                              <1> Msg_File_Not_Found:
   209 00009C9F 46696C65206E6F7420- <1>                 db "File not found!"
   209 00009CA8 666F756E6421        <1>
   210 00009CAE 0D0A00              <1>                 db 0Dh, 0Ah, 0
   211                              <1> 
   212                              <1> Msg_File_Directory_Not_Found:
   213 00009CB1 46696C65206F722064- <1>                 db "File or directory not found!"
   213 00009CBA 69726563746F727920- <1>
   213 00009CC3 6E6F7420666F756E64- <1>
   213 00009CCC 21                  <1>
   214 00009CCD 0D0A00              <1>                 db 0Dh, 0Ah, 0
   215                              <1> 
   216                              <1> Msg_LongName_Not_Found:
   217 00009CD0 4C6F6E67206E616D65- <1>                 db "Long name not found!"
   217 00009CD9 206E6F7420666F756E- <1>
   217 00009CE2 6421                <1>
   218 00009CE4 0D0A00              <1>                 db 0Dh, 0Ah, 0
   219                              <1> 
   220                              <1> Msg_Insufficient_Memory:
   221 00009CE7 496E73756666696369- <1>                 db "Insufficient memory!"
   221 00009CF0 656E74206D656D6F72- <1>
   221 00009CF9 7921                <1>
   222 00009CFB 0D0A00              <1>                 db 0Dh, 0Ah, 0
   223                              <1> 
   224                              <1> Msg_Error_Code:
   225 00009CFE 436F6D6D616E642066- <1>                 db 'Command failed! Error code : '
   225 00009D07 61696C656421204572- <1>
   225 00009D10 726F7220636F646520- <1>
   225 00009D19 3A20                <1>
   226 00009D1B 303068              <1> Error_Code:     db '00h'
   227 00009D1E 0A0A00              <1>                 db 0Ah, 0Ah, 0
   228                              <1> 
   229 00009D21 90                  <1> align 2
   230                              <1> 
   231                              <1> ; 10/02/2016
   232                              <1> ; DIR.ASM - 09/10/2011
   233                              <1> 
   234 00009D22 3C4449523E20202020- <1> Type_Dir:       db '<DIR>     ' ; 10 bytes
   234 00009D2B 20                  <1>
   235                              <1> 
   236                              <1> File_Name:
   237 00009D2C 20<rept>            <1>                 times 12 db 20h
   238 00009D38 20                  <1> 		db 20h
   239                              <1> Dir_Or_FileSize:
   240 00009D39 20<rept>            <1>                 times 10 db 20h
   241 00009D43 20                  <1> 		db 20h
   242                              <1> File_Attribute:
   243 00009D44 20202020            <1> 		dd 20202020h
   244 00009D48 20                  <1> 		db 20h
   245                              <1> File_Day:
   246 00009D49 3030                <1>                 db '0','0'
   247 00009D4B 2F                  <1> 		db '/'
   248                              <1> File_Month:
   249 00009D4C 3030                <1>                 db '0','0'
   250 00009D4E 2F                  <1> 		db '/'
   251                              <1> File_Year:
   252 00009D4F 30303030            <1>                 db '0','0','0','0'
   253 00009D53 20                  <1> 		db 20h
   254                              <1> File_Hour:
   255 00009D54 3030                <1>                 db '0','0'
   256 00009D56 3A                  <1> 		db ':'
   257                              <1> File_Minute:
   258 00009D57 3030                <1>                 db '0','0'
   259 00009D59 00                  <1> 		db 0
   260                              <1> 
   261                              <1> Decimal_File_Count_Header:
   262 00009D5A 0D0A                <1> 		db 0Dh, 0Ah
   263                              <1> Decimal_File_Count:
   264 00009D5C 00<rept>            <1> 		times 6 db 0
   265                              <1> 
   266 00009D62 2066696C6528732920- <1> str_files:	db " file(s) & "
   266 00009D6B 2620                <1>
   267                              <1> Decimal_Dir_Count: 
   268 00009D6D 00<rept>            <1> 		times 6 db 0
   269                              <1> str_dirs:       
   270 00009D73 206469726563746F72- <1> 		db " directory(s) "
   270 00009D7C 7928732920          <1>
   271 00009D81 0D0A00              <1> 		db 0Dh, 0Ah, 0
   272                              <1> 
   273 00009D84 206279746528732920- <1> str_bytes:	db " byte(s) in file(s)"
   273 00009D8D 696E2066696C652873- <1>
   273 00009D96 29                  <1>
   274 00009D97 0D0A00              <1> 		db 0Dh, 0Ah, 0
   275                              <1> 
   276                              <1> ; CMD_INTR.ASM - 09/11/2011
   277                              <1> ; 07/10/2010
   278                              <1> Msg_invalid_name_chars:
   279 00009D9A 496E76616C69642066- <1>                 db "Invalid file or directory name characters!"
   279 00009DA3 696C65206F72206469- <1>
   279 00009DAC 726563746F7279206E- <1>
   279 00009DB5 616D65206368617261- <1>
   279 00009DBE 637465727321        <1>
   280 00009DC4 0D0A00              <1>         	db 0Dh, 0Ah, 0
   281                              <1> ; 21/02/2016
   282 00009DC7 46696C65206F722064- <1> Msg_Name_Exists: db "File or directory name exists!"
   282 00009DD0 69726563746F727920- <1>
   282 00009DD9 6E616D652065786973- <1>
   282 00009DE2 747321              <1>
   283 00009DE5 0D0A00              <1>                 db 0Dh, 0Ah, 0
   284                              <1> Msg_DoYouWantMkdir:
   285 00009DE8 446F20796F75207761- <1>                 db "Do you want to make directory ", 0
   285 00009DF1 6E7420746F206D616B- <1>
   285 00009DFA 65206469726563746F- <1>
   285 00009E03 72792000            <1>
   286 00009E07 2028592F4E29203F20- <1> Msg_YesNo:      db " (Y/N) ? ", 0  
   286 00009E10 00                  <1>
   287 00009E11 000D0A00            <1> Y_N_nextline:	db 0, 0Dh, 0Ah, 0 
   288 00009E15 4F4B2E0D0A00        <1> Msg_OK:		db "OK.", 0Dh, 0Ah, 0
   289                              <1> 
   290                              <1> ; 27/02/2016
   291                              <1> Msg_DoYouWantRmDir:
   292 00009E1B 446F20796F75207761- <1>                 db "Do you want to delete directory ", 0
   292 00009E24 6E7420746F2064656C- <1>
   292 00009E2D 657465206469726563- <1>
   292 00009E36 746F72792000        <1>
   293                              <1> Msg_Dir_Not_Empty:
   294 00009E3C 4469726563746F7279- <1>                 db "Directory not empty!"
   294 00009E45 206E6F7420656D7074- <1>
   294 00009E4E 7921                <1>
   295 00009E50 0D0A00              <1>                 db 0Dh, 0Ah, 0
   296                              <1> 
   297                              <1> Msg_DoYouWantDelete:
   298 00009E53 446F20796F75207761- <1>                 db "Do you want to delete file ",0
   298 00009E5C 6E7420746F2064656C- <1>
   298 00009E65 6574652066696C6520- <1>
   298 00009E6E 00                  <1>
   299                              <1> 
   300 00009E6F 44656C657465642E2E- <1> Msg_Deleted:    db "Deleted...", 0Dh, 0Ah, 0
   300 00009E78 2E0D0A00            <1>
   301                              <1> 
   302                              <1> Msg_Permission_Denied:
   303 00009E7C 07                  <1>                 db 7
   304 00009E7D 5065726D697373696F- <1>                 db "Permission denied!", 0Dh, 0Ah, 0
   304 00009E86 6E2064656E69656421- <1>
   304 00009E8F 0D0A00              <1>
   305                              <1> 
   306                              <1> ; 04/03/2016
   307 00009E92 4E657720            <1> Msg_New:        db "New "
   308 00009E96 00                  <1>                 db 0
   309                              <1> Str_Attributes:
   310 00009E97 417474726962757465- <1>                 db "Attributes : "
   310 00009EA0 73203A20            <1>
   311 00009EA4 4E4F524D414C        <1> Attr_Chars:     db "NORMAL"
   312 00009EAA 00                  <1>                 db 0
   313                              <1> 
   314                              <1> ; 06/03/2016
   315                              <1> ; CMD_INTR.ASM - 16/11/2010 
   316                              <1> Msg_DoYouWantRename:
   317 00009EAB 446F20796F75207761- <1>                 db "Do you want to rename ", 0
   317 00009EB4 6E7420746F2072656E- <1>
   317 00009EBD 616D652000          <1>
   318 00009EC2 66696C652000        <1> Rename_File:    db "file ", 0
   319 00009EC8 6469726563746F7279- <1> Rename_Directory: db "directory ", 0
   319 00009ED1 2000                <1>
   320 00009ED3 00<rept>            <1> Rename_OldName: times 13 db 0
   321 00009EE0 20617320            <1> Msg_File_rename_as: db " as "
   322 00009EE4 00<rept>            <1> Rename_NewName: times 13 db 0
  1922                                  
  1923                                  ; 07/03/2015
  1924                                  ; Temporary Code
  1925                                  display_disks:
  1926 00009EF1 803D[BEA20000]00        	cmp 	byte [fd0_type], 0
  1927 00009EF8 7605                    	jna 	short ddsks1
  1928 00009EFA E87D000000              	call	pdskm
  1929                                  ddsks1:
  1930 00009EFF 803D[BFA20000]00        	cmp	byte [fd1_type], 0
  1931 00009F06 760C                    	jna	short ddsks2
  1932 00009F08 C605[B5A40000]31        	mov	byte [dskx], '1'
  1933 00009F0F E868000000              	call	pdskm
  1934                                  ddsks2:
  1935 00009F14 803D[C0A20000]00        	cmp	byte [hd0_type], 0
  1936 00009F1B 7654                    	jna	short ddsk6
  1937 00009F1D 66C705[B3A40000]68-     	mov	word [dsktype], 'hd'
  1937 00009F25 64                 
  1938 00009F26 C605[B5A40000]30        	mov	byte [dskx], '0'
  1939 00009F2D E84A000000              	call	pdskm
  1940                                  ddsks3:
  1941 00009F32 803D[C1A20000]00        	cmp	byte [hd1_type], 0
  1942 00009F39 7636                    	jna	short ddsk6
  1943 00009F3B C605[B5A40000]31        	mov	byte [dskx], '1'
  1944 00009F42 E835000000              	call	pdskm
  1945                                  ddsks4:
  1946 00009F47 803D[C2A20000]00        	cmp	byte [hd2_type], 0
  1947 00009F4E 7621                    	jna	short ddsk6
  1948 00009F50 C605[B5A40000]32        	mov	byte [dskx], '2'
  1949 00009F57 E820000000              	call	pdskm
  1950                                  ddsks5:
  1951 00009F5C 803D[C3A20000]00        	cmp	byte [hd3_type], 0
  1952 00009F63 760C                    	jna	short ddsk6
  1953 00009F65 C605[B5A40000]33        	mov	byte [dskx], '3'
  1954 00009F6C E80B000000              	call	pdskm
  1955                                  ddsk6:
  1956 00009F71 BE[C6A40000]            	mov	esi, nextline
  1957 00009F76 E806000000              	call	pdskml
  1958                                  pdskm_ok:
  1959 00009F7B C3                      	retn
  1960                                  pdskm:
  1961 00009F7C BE[B1A40000]            	mov	esi, dsk_ready_msg
  1962                                  pdskml:	
  1963 00009F81 AC                      	lodsb
  1964 00009F82 08C0                    	or	al, al
  1965 00009F84 74F5                    	jz	short pdskm_ok
  1966 00009F86 56                      	push	esi
  1967 00009F87 31DB                    	xor	ebx, ebx ; 0
  1968                                  			; Video page 0 (bl=0)
  1969 00009F89 B407                    	mov	ah, 07h ; Black background, 
  1970                                  			; light gray forecolor
  1971 00009F8B E82678FFFF              	call	WRITE_TTY
  1972 00009F90 5E                      	pop	esi
  1973 00009F91 EBEE                    	jmp	short pdskml
  1974                                  
  1975 00009F93 90<rept>                align 16
  1976                                  
  1977                                  gdt:	; Global Descriptor Table
  1978                                  	; (30/07/2015, conforming cs)
  1979                                  	; (26/03/2015)
  1980                                  	; (24/03/2015, tss)
  1981                                  	; (19/03/2015)
  1982                                  	; (29/12/2013)
  1983                                  	;
  1984 00009FA0 0000000000000000        	dw 0, 0, 0, 0		; NULL descriptor
  1985                                  	; 18/08/2014
  1986                                  			; 8h kernel code segment, base = 00000000h		
  1987 00009FA8 FFFF0000009ACF00        	dw 0FFFFh, 0, 9A00h, 00CFh	; KCODE
  1988                                  			; 10h kernel data segment, base = 00000000h	
  1989 00009FB0 FFFF00000092CF00        	dw 0FFFFh, 0, 9200h, 00CFh	; KDATA
  1990                                  			; 1Bh user code segment, base address = 400000h ; CORE
  1991 00009FB8 FFFB000040FACF00        	dw 0FBFFh, 0, 0FA40h, 00CFh	; UCODE 
  1992                                  			; 23h user data segment, base address = 400000h ; CORE
  1993 00009FC0 FFFB000040F2CF00        	dw 0FBFFh, 0, 0F240h, 00CFh	; UDATA
  1994                                  			; Task State Segment
  1995 00009FC8 6700                    	dw 0067h ; Limit = 103 ; (104-1, tss size = 104 byte, 
  1996                                  			       ;  no IO permission in ring 3)
  1997                                  gdt_tss0:
  1998 00009FCA 0000                    	dw 0  ; TSS base address, bits 0-15 
  1999                                  gdt_tss1:
  2000 00009FCC 00                      	db 0  ; TSS base address, bits 16-23 
  2001                                  	      		; 49h	
  2002 00009FCD E9                      	db 11101001b ; E9h => P=1/DPL=11/0/1/0/B/1 --> B = Task is busy (1)
  2003 00009FCE 00                      	db 0 ; G/0/0/AVL/LIMIT=0000 ; (Limit bits 16-19 = 0000) (G=0, 1 byte)
  2004                                  gdt_tss2:
  2005 00009FCF 00                      	db 0  ; TSS base address, bits 24-31 
  2006                                  
  2007                                  gdt_end:
  2008                                  	;; 9Ah = 1001 1010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
  2009                                  					;; Type= 1 (code)/C=0/R=1/A=0
  2010                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
  2011                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
  2012                                  
  2013                                  	;; 92h = 1001 0010b (GDT byte 5) P=1/DPL=00/1/TYPE=1010, 
  2014                                  					;; Type= 0 (data)/E=0/W=1/A=0
  2015                                  		; P= Present, DPL=0=ring 0,  1= user (0= system)
  2016                                  		; 0= Data E= Expansion direction (1= down, 0= up)
  2017                                  		; W= Writeable, A= Accessed
  2018                                  	
  2019                                  	;; FAh = 1111 1010b (GDT byte 5) P=1/DPL=11/1/TYPE=1010, 
  2020                                  					;; Type= 1 (code)/C=0/R=1/A=0
  2021                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
  2022                                  		; 1= Code C= non-Conforming, R= Readable, A = Accessed
  2023                                  
  2024                                  	;; F2h = 1111 0010b (GDT byte 5) P=1/DPL=11/1/TYPE=0010, 
  2025                                  					;; Type= 0 (data)/E=0/W=1/A=0
  2026                                  		; P= Present, DPL=3=ring 3,  1= user (0= system)
  2027                                  		; 0= Data E= Expansion direction (1= down, 0= up)
  2028                                  	
  2029                                  	;; CFh = 1100 1111b (GDT byte 6) G=1/B=1/0/AVL=0, Limit=1111b (3)
  2030                                  
  2031                                  		;; Limit = FFFFFh (=> FFFFFh+1= 100000h) // bits 0-15, 48-51 //
  2032                                  		;	 = 100000h * 1000h (G=1) = 4GB
  2033                                  		;; Limit = FFBFFh (=> FFBFFh+1= FFC00h) // bits 0-15, 48-51 //
  2034                                  		;	 = FFC00h * 1000h (G=1) = 4GB - 4MB
  2035                                  		; G= Granularity (1= 4KB), B= Big (32 bit), 
  2036                                  		; AVL= Available to programmers	
  2037                                  
  2038                                  gdtd:
  2039 00009FD0 2F00                            dw gdt_end - gdt - 1    ; Limit (size)
  2040 00009FD2 [A09F0000]                      dd gdt			; Address of the GDT
  2041                                  
  2042                                  	; 20/08/2014
  2043                                  idtd:
  2044 00009FD6 FF01                            dw idt_end - idt - 1    ; Limit (size)
  2045 00009FD8 [80A50000]                      dd idt			; Address of the IDT
  2046                                  
  2047                                  Align 4
  2048                                  
  2049                                  	; 21/08/2014
  2050                                  ilist:
  2051                                  	;times 	32 dd cpu_except ; INT 0 to INT 1Fh
  2052                                  	;
  2053                                  	; Exception list
  2054                                  	; 25/08/2014	
  2055 00009FDC [DB080000]              	dd	exc0	; 0h,  Divide-by-zero Error
  2056 00009FE0 [E2080000]              	dd	exc1	
  2057 00009FE4 [E9080000]              	dd 	exc2	
  2058 00009FE8 [F0080000]              	dd	exc3	
  2059 00009FEC [F4080000]              	dd	exc4	
  2060 00009FF0 [F8080000]              	dd	exc5	
  2061 00009FF4 [FC080000]              	dd 	exc6	; 06h,  Invalid Opcode
  2062 00009FF8 [00090000]              	dd	exc7	
  2063 00009FFC [04090000]              	dd	exc8	
  2064 0000A000 [08090000]              	dd	exc9	
  2065 0000A004 [0C090000]              	dd 	exc10	
  2066 0000A008 [10090000]              	dd	exc11
  2067 0000A00C [14090000]              	dd	exc12
  2068 0000A010 [18090000]              	dd	exc13	; 0Dh, General Protection Fault
  2069 0000A014 [1C090000]              	dd 	exc14	; 0Eh, Page Fault
  2070 0000A018 [20090000]              	dd	exc15
  2071 0000A01C [24090000]              	dd	exc16
  2072 0000A020 [28090000]              	dd	exc17
  2073 0000A024 [2C090000]              	dd 	exc18
  2074 0000A028 [30090000]              	dd	exc19
  2075 0000A02C [34090000]              	dd 	exc20
  2076 0000A030 [38090000]              	dd	exc21
  2077 0000A034 [3C090000]              	dd	exc22
  2078 0000A038 [40090000]              	dd	exc23
  2079 0000A03C [44090000]              	dd 	exc24
  2080 0000A040 [48090000]              	dd	exc25
  2081 0000A044 [4C090000]              	dd	exc26
  2082 0000A048 [50090000]              	dd	exc27
  2083 0000A04C [54090000]              	dd 	exc28
  2084 0000A050 [58090000]              	dd	exc29
  2085 0000A054 [5C090000]              	dd 	exc30
  2086 0000A058 [60090000]              	dd	exc31
  2087                                  	; Interrupt list
  2088 0000A05C [11070000]              	dd	timer_int	; INT 20h
  2089                                  		;dd	irq0	
  2090 0000A060 [AD0D0000]              	dd	kb_int		; 24/01/2016
  2091                                  		;dd	irq1
  2092 0000A064 [31080000]              	dd	irq2
  2093                                  		; COM2 int
  2094 0000A068 [35080000]              	dd	irq3
  2095                                  		; COM1 int
  2096 0000A06C [40080000]              	dd	irq4
  2097 0000A070 [4B080000]              	dd	irq5
  2098                                  ;DISKETTE_INT: ;06/02/2015
  2099 0000A074 [76280000]              	dd	fdc_int		; 16/02/2015, IRQ 6 handler	
  2100                                  		;dd	irq6
  2101                                  ; Default IRQ 7 handler against spurious IRQs (from master PIC)
  2102                                  ; 25/02/2015 (source: http://wiki.osdev.org/8259_PIC)
  2103 0000A078 [C70B0000]              	dd	default_irq7	; 25/02/2015
  2104                                  		;dd	irq7
  2105                                  ; Real Time Clock Interrupt
  2106 0000A07C [6A0A0000]              	dd	rtc_int		; 23/02/2015, IRQ 8 handler
  2107                                  		;dd	irq8	; INT 28h
  2108 0000A080 [5B080000]              	dd	irq9
  2109 0000A084 [5F080000]              	dd	irq10
  2110 0000A088 [63080000]              	dd	irq11
  2111 0000A08C [67080000]              	dd	irq12
  2112 0000A090 [6B080000]              	dd	irq13
  2113                                  ;HDISK_INT1:  ;06/02/2015 	
  2114 0000A094 [BA300000]              	dd	hdc1_int 	; 21/02/2015, IRQ 14 handler		
  2115                                  		;dd	irq14
  2116                                  ;HDISK_INT2:  ;06/02/2015
  2117 0000A098 [E1300000]              	dd	hdc2_int 	; 21/02/2015, IRQ 15 handler		
  2118                                  		;dd	irq15	; INT 2Fh
  2119                                  		; 14/08/2015
  2120 0000A09C [C57F0000]              	dd	sysent		; INT 30h (system calls)
  2121                                  	
  2122                                  	;dd	ignore_int
  2123 0000A0A0 00000000                	dd	0
  2124                                  
  2125                                  ;;;
  2126                                  ;;; 11/03/2015
  2127                                  %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 0000A0A4 524F50514B          <1> K30:	db	82,79,80,81,75
    36 0000A0A9 4C4D474849          <1> 	db	76,77,71,72,73		; 10 NUMBER ON KEYPAD
    37                              <1> ;-----	SUPER-SHIFT-TABLE 
    38 0000A0AE 101112131415        <1> 	db	16,17,18,19,20,21	; A-Z TYPEWRITER CHARS
    39 0000A0B4 161718191E1F        <1> 	db	22,23,24,25,30,31
    40 0000A0BA 202122232425        <1> 	db	32,33,34,35,36,37
    41 0000A0C0 262C2D2E2F30        <1> 	db	38,44,45,46,47,48
    42 0000A0C6 3132                <1> 	db	49,50
    43                              <1> 
    44                              <1> ;-----	TABLE OF SHIFT KEYS AND MASK VALUES
    45                              <1> ;-----	KEY_TABLE 
    46 0000A0C8 52                  <1> _K6:    db      INS_KEY                 ; INSERT KEY
    47 0000A0C9 3A4546381D          <1> 	db	CAPS_KEY,NUM_KEY,SCROLL_KEY,ALT_KEY,CTL_KEY
    48 0000A0CE 2A36                <1>         db      LEFT_KEY,RIGHT_KEY
    49                              <1> _K6L    equ     $-_K6
    50                              <1> 
    51                              <1> ;-----	MASK_TABLE
    52 0000A0D0 80                  <1> _K7:    db      INS_SHIFT               ; INSERT MODE SHIFT
    53 0000A0D1 4020100804          <1> 	db	CAPS_SHIFT,NUM_SHIFT,SCROLL_SHIFT,ALT_SHIFT,CTL_SHIFT
    54 0000A0D6 0201                <1> 	db	LEFT_SHIFT,RIGHT_SHIFT
    55                              <1> 
    56                              <1> ;-----	TABLES FOR CTRL CASE		;---- CHARACTERS ------
    57 0000A0D8 1BFF00FFFFFF        <1> _K8:	db	27,-1,0,-1,-1,-1	; Esc, 1, 2, 3, 4, 5
    58 0000A0DE 1EFFFFFFFF1F        <1> 	db 	30,-1,-1,-1,-1,31	; 6, 7, 8, 9, 0, -
    59 0000A0E4 FF7FFF111705        <1> 	db	-1,127,-1,17,23,5	; =, Bksp, Tab, Q, W, E
    60 0000A0EA 12141915090F        <1> 	db	18,20,25,21,9,15	; R, T, Y, U, I, O
    61 0000A0F0 101B1D0AFF01        <1> 	db	16,27,29,10,-1,1	; P, [, ], Enter, Ctrl, A
    62 0000A0F6 13040607080A        <1> 	db	19,4,6,7,8,10		; S, D, F, G, H, J
    63 0000A0FC 0B0CFFFFFFFF        <1> 	db	11,12,-1,-1,-1,-1	; K, L, :, ', `, LShift
    64 0000A102 1C1A18031602        <1> 	db	28,26,24,3,22,2		; Bkslash, Z, X, C, V, B
    65 0000A108 0E0DFFFFFFFF        <1> 	db	14,13,-1,-1,-1,-1	; N, M, ,, ., /, RShift
    66 0000A10E 96FF20FF            <1> 	db	150,-1,' ',-1		; *, ALT, Spc, CL
    67                              <1> 	;				;----- FUNCTIONS ------		
    68 0000A112 5E5F60616263        <1> 	db 	94,95,96,97,98,99	; F1 - F6
    69 0000A118 64656667FFFF        <1> 	db	100,101,102,103,-1,-1	; F7 - F10, NL, SL
    70 0000A11E 778D848E738F        <1> 	db	119,141,132,142,115,143	; Home, Up, PgUp, -, Left, Pad5
    71 0000A124 749075917692        <1> 	db 	116,144,117,145,118,146 ; Right, +, End, Down, PgDn, Ins
    72 0000A12A 93FFFFFF898A        <1> 	db	147,-1,-1,-1,137,138	; Del, SysReq, Undef, WT, F11, F12
    73                              <1> 
    74                              <1> ;-----	TABLES FOR LOWER CASE ----------
    75 0000A130 1B3132333435363738- <1> K10:	db 	27,'1234567890-=',8,9
    75 0000A139 39302D3D0809        <1>
    76 0000A13F 71776572747975696F- <1> 	db 	'qwertyuiop[]',13,-1,'asdfghjkl;',39
    76 0000A148 705B5D0DFF61736466- <1>
    76 0000A151 67686A6B6C3B27      <1>
    77 0000A158 60FF5C7A786376626E- <1> 	db	96,-1,92,'zxcvbnm,./',-1,'*',-1,' ',-1
    77 0000A161 6D2C2E2FFF2AFF20FF  <1>
    78                              <1> ;-----	LC TABLE SCAN
    79 0000A16A 3B3C3D3E3F          <1> 	db	59,60,61,62,63		; BASE STATE OF F1 - F10
    80 0000A16F 4041424344          <1> 	db	64,65,66,67,68
    81 0000A174 FFFF                <1> 	db	-1,-1			; NL, SL
    82                              <1> 
    83                              <1> ;-----	KEYPAD TABLE
    84 0000A176 474849FF4BFF        <1> K15:	db	71,72,73,-1,75,-1	; BASE STATE OF KEYPAD KEYS
    85 0000A17C 4DFF4F50515253      <1> 	db	77,-1,79,80,81,82,83
    86 0000A183 FFFF5C8586          <1> 	db	-1,-1,92,133,134	; SysRq, Undef, WT, F11, F12
    87                              <1> 
    88                              <1> ;-----	TABLES FOR UPPER CASE ----------
    89 0000A188 1B21402324255E262A- <1> K11:	db 	27,'!@#$%',94,'&*()_+',8,0
    89 0000A191 28295F2B0800        <1>
    90 0000A197 51574552545955494F- <1> 	db 	'QWERTYUIOP{}',13,-1,'ASDFGHJKL:"'
    90 0000A1A0 507B7D0DFF41534446- <1>
    90 0000A1A9 47484A4B4C3A22      <1>
    91 0000A1B0 7EFF7C5A584356424E- <1> 	db	126,-1,'|ZXCVBNM<>?',-1,'*',-1,' ',-1
    91 0000A1B9 4D3C3E3FFF2AFF20FF  <1>
    92                              <1> ;-----	UC TABLE SCAN
    93 0000A1C2 5455565758          <1> K12:	db	84,85,86,87,88		; SHIFTED STATE OF F1 - F10
    94 0000A1C7 595A5B5C5D          <1> 	db	89,90,91,92,93
    95 0000A1CC FFFF                <1> 	db	-1,-1			; NL, SL
    96                              <1> 
    97                              <1> ;-----	NUM STATE TABLE
    98 0000A1CE 3738392D3435362B31- <1> K14:	db 	'789-456+1230.'		; NUMLOCK STATE OF KEYPAD KEYS
    98 0000A1D7 3233302E            <1>
    99                              <1> 	;
   100 0000A1DB 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 0000A1E0 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 0000A1E1 00                  <1> KB_FLAG		db	0		; KEYBOARD SHIFT STATE AND STATUS FLAGS
   118 0000A1E2 00                  <1> KB_FLAG_1	db	0		; SECOND BYTE OF KEYBOARD STATUS
   119 0000A1E3 00                  <1> KB_FLAG_2	db	0		; KEYBOARD LED FLAGS
   120 0000A1E4 00                  <1> KB_FLAG_3	db	0		; KEYBOARD MODE STATE AND TYPE FLAGS
   121 0000A1E5 00                  <1> ALT_INPUT	db	0		; STORAGE FOR ALTERNATE KEY PAD ENTRY
   122 0000A1E6 [F6A10000]          <1> BUFFER_START	dd	KB_BUFFER 	; OFFSET OF KEYBOARD BUFFER START
   123 0000A1EA [16A20000]          <1> BUFFER_END	dd	KB_BUFFER + 32	; OFFSET OF END OF BUFFER
   124 0000A1EE [F6A10000]          <1> BUFFER_HEAD	dd	KB_BUFFER 	; POINTER TO HEAD OF KEYBOARD BUFFER
   125 0000A1F2 [F6A10000]          <1> BUFFER_TAIL	dd	KB_BUFFER 	; POINTER TO TAIL OF KEYBOARD BUFFER
   126                              <1> ; ------	HEAD = TAIL	INDICATES THAT THE BUFFER IS EMPTY
   127 0000A1F6 0000<rept>          <1> KB_BUFFER	times	16 dw 0		; ROOM FOR 16 SCAN CODE ENTRIES
   128                              <1> 
   129                              <1> ; /// End Of KEYBOARD DATA ///
  2128                                  %include 'vidata.s'	; VIDEO (BIOS) DATA
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - vidata.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 30/01/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 16/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Turkish Rational DOS
    11                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ; vidata.inc (11/03/2015)
    15                              <1> ;
    16                              <1> ; Derived from 'IBM PC-AT' BIOS source code (1985) 
    17                              <1> ; ****************************************************************************
    18                              <1> 
    19                              <1> ; Retro UNIX 386 v1 Kernel - VIDATA.S
    20                              <1> ; Last Modification: 11/03/2015
    21                              <1> ;		    (Data section for 'VIDEO.INC')	
    22                              <1> ;
    23                              <1> ; ///////// VIDEO DATA ///////////////
    24                              <1> 
    25                              <1> ;-----	COLUMNS
    26                              <1> ;M6:
    27                              <1> ;	db	40, 40, 80, 80, 40, 40, 80, 80
    28                              <1> 
    29                              <1> ;-----	C_REG_TAB
    30                              <1> ;M7:
    31                              <1> ;	db	2Ch, 28h, 2Dh, 29h, 2Ah, 2Eh, 1Eh, 29h	; TABLE OF MODE SETS
    32                              <1> 
    33                              <1> ;----------------------------------------
    34                              <1> ;	VIDEO DISPLAY DATA AREA		;
    35                              <1> ;----------------------------------------
    36 0000A216 03                  <1> CRT_MODE	db	3	; CURRENT DISPLAY MODE (TYPE)
    37 0000A217 29                  <1> CRT_MODE_SET	db	29h	; CURRENT SETTING OF THE 3X8 REGISTER
    38                              <1> 				; (29h default setting for video mode 3)
    39                              <1> 				; Mode Select register Bits
    40                              <1> 				;   BIT 0 - 80x25 (1), 40x25 (0)
    41                              <1> 				;   BIT 1 - ALPHA (0), 320x200 GRAPHICS (1)
    42                              <1> 				;   BIT 2 - COLOR (0), BW (1)
    43                              <1> 				;   BIT 3 - Video Sig. ENABLE (1), DISABLE (0)
    44                              <1> 				;   BIT 4 - 640x200 B&W Graphics Mode (1)
    45                              <1> 				;   BIT 5 - ALPHA mode BLINKING (1)
    46                              <1> 				;   BIT 6, 7 - Not Used
    47                              <1> 
    48                              <1> ; Mode 0 - 2Ch = 101100b	; 40x25 text, 16 gray colors
    49                              <1> ; Mode 1 - 28h = 101000b	; 40x25 text, 16 fore colors, 8 back colors
    50                              <1> ; Mode 2 - 2Dh = 101101b	; 80x25 text, 16 gray colors	
    51                              <1> ; MODE 3 - 29h = 101001b	; 80x25 text, 16 fore color, 8 back color
    52                              <1> ; Mode 4 - 2Ah = 101010b	; 320x200 graphics, 4 colors
    53                              <1> ; Mode 5 - 2Eh = 101110b	; 320x200 graphics, 4 gray colors
    54                              <1> ; Mode 6 - 1Eh = 011110b	; 640x200 graphics, 2 colors
    55                              <1> ; Mode 7 - 29h = 101001b	; 80x25 text, black & white colors
    56                              <1> ; Mode & 37h = Video signal OFF
    57                              <1> 			
    58                              <1> video_params:
    59                              <1> 	; 02/09/2014 (Retro UNIX 386 v1)
    60                              <1> 	;ORGS.ASM ----- 06/10/85   COMPATIBILITY MODULE
    61                              <1> 	; VIDEO MODE 3
    62 0000A218 71505A0A1F0619      <1> 	db	71h,50h,5Ah,0Ah,1Fh,6,19h	; SET UP FOR 80X25
    63 0000A21F 1C02070607          <1> 	db	1Ch,2,7,6,7	; cursor start = 6, cursor stop = 7
    64 0000A224 00000000            <1> 	db	0,0,0,0
    65                              <1> 
    66                              <1> ; 16/01/2016
    67                              <1> chr_attrib:  ; Character color/attributes for viode pages (0 to 7)
    68 0000A228 0707070707070707    <1> 	db	07h, 07h, 07h, 07h, 07h, 07h, 07h, 07h
    69                              <1> ; 30/01/2016
    70                              <1> vmode:
    71 0000A230 0303030303030303    <1> 	db	3,3,3,3,3,3,3,3 ; video modes for pseudo screens 
    72                              <1> 
    73                              <1> ; /// End Of VIDEO DATA ///
  2129                                  %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 0000A238 [9BA20000]          <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 0000A23C 01                  <1> 		DB	01		;DRIVE TYPE, MEDIA TABLE
   113                              <1>                 ;DW      MD_TBL1
   114 0000A23D [5AA20000]          <1> 		dd	MD_TBL1
   115 0000A241 82                  <1> 		DB	02+BIT7ON
   116                              <1> 		;DW      MD_TBL2
   117 0000A242 [67A20000]          <1>                 dd      MD_TBL2
   118 0000A246 02                  <1> DR_DEFAULT:	DB	02
   119                              <1>                 ;DW      MD_TBL3
   120 0000A247 [74A20000]          <1> 		dd      MD_TBL3
   121 0000A24B 03                  <1> 		DB	03
   122                              <1>                 ;DW      MD_TBL4
   123 0000A24C [81A20000]          <1> 		dd      MD_TBL4
   124 0000A250 84                  <1> 		DB	04+BIT7ON
   125                              <1>                 ;DW      MD_TBL5
   126 0000A251 [8EA20000]          <1> 		dd      MD_TBL5
   127 0000A255 04                  <1> 		DB	04
   128                              <1>                 ;DW      MD_TBL6
   129 0000A256 [9BA20000]          <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 0000A25A DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   141 0000A25B 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   142 0000A25C 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   143 0000A25D 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   144 0000A25E 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   145 0000A25F 2A                  <1> 	DB	02AH		; GAP LENGTH
   146 0000A260 FF                  <1> 	DB	0FFH		; DTL
   147 0000A261 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   148 0000A262 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   149 0000A263 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   150 0000A264 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   151 0000A265 27                  <1> 	DB	39		; MAX. TRACK NUMBER
   152 0000A266 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 0000A267 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   158 0000A268 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   159 0000A269 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   160 0000A26A 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   161 0000A26B 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   162 0000A26C 2A                  <1> 	DB	02AH		; GAP LENGTH
   163 0000A26D FF                  <1> 	DB	0FFH		; DTL
   164 0000A26E 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   165 0000A26F F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   166 0000A270 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   167 0000A271 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   168 0000A272 27                  <1> 	DB	39		; MAX. TRACK NUMBER
   169 0000A273 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 0000A274 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   175 0000A275 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   176 0000A276 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   177 0000A277 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   178 0000A278 0F                  <1> 	DB	15		; EOT (LAST SECTOR ON TRACK)
   179 0000A279 1B                  <1> 	DB	01BH		; GAP LENGTH
   180 0000A27A FF                  <1> 	DB	0FFH		; DTL
   181 0000A27B 54                  <1> 	DB	054H		; GAP LENGTH FOR FORMAT
   182 0000A27C F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   183 0000A27D 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   184 0000A27E 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   185 0000A27F 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   186 0000A280 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 0000A281 DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   192 0000A282 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   193 0000A283 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   194 0000A284 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   195 0000A285 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   196 0000A286 2A                  <1> 	DB	02AH		; GAP LENGTH
   197 0000A287 FF                  <1> 	DB	0FFH		; DTL
   198 0000A288 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   199 0000A289 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   200 0000A28A 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   201 0000A28B 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   202 0000A28C 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   203 0000A28D 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 0000A28E DF                  <1> 	DB	11011111B	; SRT=D, HD UNLOAD=0F - 1ST SPECIFY BYTE
   209 0000A28F 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   210 0000A290 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   211 0000A291 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   212 0000A292 09                  <1> 	DB	09		; EOT (LAST SECTOR ON TRACK)
   213 0000A293 2A                  <1> 	DB	02AH		; GAP LENGTH
   214 0000A294 FF                  <1> 	DB	0FFH		; DTL
   215 0000A295 50                  <1> 	DB	050H		; GAP LENGTH FOR FORMAT
   216 0000A296 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   217 0000A297 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   218 0000A298 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   219 0000A299 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   220 0000A29A 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 0000A29B AF                  <1> 	DB	10101111B	; SRT=A, HD UNLOAD=0F - 1ST SPECIFY BYTE
   226 0000A29C 02                  <1> 	DB	2		; HD LOAD=1, MODE=DMA - 2ND SPECIFY BYTE
   227 0000A29D 25                  <1> 	DB	MOTOR_WAIT	; WAIT TIME AFTER OPERATION TILL MOTOR OFF
   228 0000A29E 02                  <1> 	DB	2		; 512 BYTES/SECTOR
   229 0000A29F 12                  <1> 	DB	18		; EOT (LAST SECTOR ON TRACK)
   230 0000A2A0 1B                  <1> 	DB	01BH		; GAP LENGTH
   231 0000A2A1 FF                  <1> 	DB	0FFH		; DTL
   232 0000A2A2 6C                  <1> 	DB	06CH		; GAP LENGTH FOR FORMAT
   233 0000A2A3 F6                  <1> 	DB	0F6H		; FILL BYTE FOR FORMAT
   234 0000A2A4 0F                  <1> 	DB	15		; HEAD SETTLE TIME (MILLISECONDS)
   235 0000A2A5 08                  <1> 	DB	8		; MOTOR START TIME (1/8 SECONDS)
   236 0000A2A6 4F                  <1> 	DB	79		; MAX. TRACK NUMBER
   237 0000A2A7 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 0000A2A8 E0                  <1> 	db	NO_ERR
   280 0000A2A9 024001BB            <1> 	db	BAD_ADDR_MARK,BAD_SEEK,BAD_CMD,UNDEF_ERR
   281 0000A2AD 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 0000A2B1 00                  <1> cfd:		db 0			; current floppy drive (for GET_PARM)
   286                              <1> ; 17/12/2014				; instead of 'DISK_POINTER'
   287 0000A2B2 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 0000A2B3 90                  <1> align 2
   293                              <1> 
   294 0000A2B4 F001                <1> HF_PORT:	dw 	1F0h  ; Default = 1F0h
   295                              <1> 			      ; (170h)
   296 0000A2B6 F603                <1> HF_REG_PORT:	dw	3F6h  ; HF_PORT + 206h
   297                              <1> 
   298                              <1> ; 05/01/2015 
   299 0000A2B8 00                  <1> hf_m_s:         db      0     ; (0 = Master, 1 = Slave)
   300                              <1> 
   301                              <1> ; *****************************************************************************
  2130                                  ;;;
  2131                                  
  2132 0000A2B9 90                      Align 2
  2133                                  
  2134                                  ; 12/11/2014 (Retro UNIX 386 v1)
  2135 0000A2BA 00                      boot_drv:    db 0 ; boot drive number (physical)
  2136                                  ; 24/11/2014
  2137 0000A2BB 00                      drv:	     db 0 
  2138 0000A2BC 00                      last_drv:    db 0 ; last hdd
  2139 0000A2BD 00                      hdc:         db 0  ; number of hard disk drives
  2140                                  		     ; (present/detected)
  2141                                  ;
  2142                                  ; 24/11/2014 (Retro UNIX 386 v1)
  2143                                  ; Physical drive type & flags
  2144 0000A2BE 00                      fd0_type:    db 0  ; floppy drive type
  2145 0000A2BF 00                      fd1_type:    db 0  ; 4 = 1.44 Mb, 80 track, 3.5" (18 spt)
  2146                                  		     ; 6 = 2.88 Mb, 80 track, 3.5" (36 spt)
  2147                                  		     ; 3 = 720 Kb, 80 track, 3.5" (9 spt)
  2148                                  		     ; 2 = 1.2 Mb, 80 track, 5.25" (15 spt)
  2149                                  		     ; 1 = 360 Kb, 40 track, 5.25" (9 spt)		
  2150 0000A2C0 00                      hd0_type:    db 0  ; EDD status for hd0 (bit 7 = present flag)
  2151 0000A2C1 00                      hd1_type:    db 0  ; EDD status for hd1 (bit 7 = present flag)
  2152 0000A2C2 00                      hd2_type:    db 0  ; EDD status for hd2 (bit 7 = present flag)
  2153 0000A2C3 00                      hd3_type:    db 0  ; EDD status for hd3 (bit 7 = present flag)
  2154                                  		     ; bit 0 - Fixed disk access subset supported
  2155                                  		     ; bit 1 - Drive locking and ejecting
  2156                                  		     ; bit 2 - Enhanced disk drive support
  2157                                  		     ; bit 3 = Reserved (64 bit EDD support)
  2158                                  		     ; (If bit 0 is '1' Retro UNIX 386 v1
  2159                                  		     ; will interpret it as 'LBA ready'!)		
  2160                                  
  2161                                  ; 11/03/2015 - 10/07/2015
  2162 0000A2C4 000000000000000000-     drv.cylinders: dw 0,0,0,0,0,0,0
  2162 0000A2CD 0000000000         
  2163 0000A2D2 000000000000000000-     drv.heads:     dw 0,0,0,0,0,0,0
  2163 0000A2DB 0000000000         
  2164 0000A2E0 000000000000000000-     drv.spt:       dw 0,0,0,0,0,0,0
  2164 0000A2E9 0000000000         
  2165 0000A2EE 000000000000000000-     drv.size:      dd 0,0,0,0,0,0,0
  2165 0000A2F7 000000000000000000-
  2165 0000A300 000000000000000000-
  2165 0000A309 00                 
  2166 0000A30A 00000000000000          drv.status:    db 0,0,0,0,0,0,0
  2167 0000A311 00000000000000          drv.error:     db 0,0,0,0,0,0,0		
  2168                                  ;
  2169                                  
  2170                                  ; 27/08/2014
  2171                                  scr_row:
  2172 0000A318 E0810B00                	dd 0B8000h + 0A0h + 0A0h + 0A0h ; Row 3
  2173                                  scr_col:
  2174 0000A31C 00000000                	dd 0
  2175                                  
  2176                                  ; 20/08/2014
  2177                                    ; /* This is the default interrupt "handler" :-) */ 
  2178                                    ; Linux v0.12 (head.s)
  2179                                  int_msg:
  2180 0000A320 556E6B6E6F776E2069-     	db "Unknown interrupt ! ", 0
  2180 0000A329 6E7465727275707420-
  2180 0000A332 212000             
  2181                                  
  2182                                  
  2183                                  ; 21/08/2014
  2184                                  timer_msg:
  2185 0000A335 49525120302028494E-     	db "IRQ 0 (INT 20h) ! Timer Interrupt : "
  2185 0000A33E 542032306829202120-
  2185 0000A347 54696D657220496E74-
  2185 0000A350 657272757074203A20 
  2186                                  tcountstr:
  2187 0000A359 303030303020            	db "00000 "
  2188 0000A35F 00                      	db 0
  2189                                  
  2190                                  Align 2
  2191                                  	; 21/08/2014
  2192                                  exc_msg:
  2193 0000A360 435055206578636570-     	db "CPU exception ! "
  2193 0000A369 74696F6E202120     
  2194                                  excnstr: 		; 25/08/2014
  2195 0000A370 3F3F68202045495020-     	db "??h", "  EIP : "
  2195 0000A379 3A20               
  2196                                  EIPstr: ; 29/08/2014
  2197 0000A37B 00<rept>                	times 12 db 0
  2198                                  rtc_msg:
  2199 0000A387 5265616C2054696D65-     	db "Real Time Clock - "
  2199 0000A390 20436C6F636B202D20 
  2200                                  datestr:
  2201 0000A399 30302F30302F303030-     	db "00/00/0000"
  2201 0000A3A2 30                 
  2202 0000A3A3 20                      	db " "
  2203                                  daystr:
  2204 0000A3A4 44415920                	db "DAY "
  2205                                  timestr:	
  2206 0000A3A8 30303A30303A3030                db "00:00:00"
  2207 0000A3B0 20                      	db " "
  2208 0000A3B1 00                      	db 0 
  2209                                  
  2210                                  daytmp:
  2211                                  	; 28/02/2015
  2212 0000A3B2 3F3F3F2053554E204D-     	db "??? SUN MON TUE WED THU FRI SAT "
  2212 0000A3BB 4F4E20545545205745-
  2212 0000A3C4 442054485520465249-
  2212 0000A3CD 2053415420         
  2213                                  
  2214 0000A3D2 FF                      ptime_seconds: db 0FFh
  2215                                  
  2216                                  	; 23/02/2015
  2217                                  	; 25/08/2014
  2218                                  ;scounter:
  2219                                  ;	db 5
  2220                                  ;	db 19
  2221                                  
  2222                                  ; 05/11/2014
  2223                                  msg_out_of_memory:
  2224 0000A3D3 070D0A                  	db 	07h, 0Dh, 0Ah
  2225 0000A3D6 496E73756666696369-             db      'Insufficient memory ! (Minimum 2 MB memory is needed.)'
  2225 0000A3DF 656E74206D656D6F72-
  2225 0000A3E8 79202120284D696E69-
  2225 0000A3F1 6D756D2032204D4220-
  2225 0000A3FA 6D656D6F7279206973-
  2225 0000A403 206E65656465642E29 
  2226 0000A40C 0D0A00                   	db	0Dh, 0Ah, 0
  2227                                  	;
  2228                                  setup_error_msg:
  2229 0000A40F 0D0A                    	db 0Dh, 0Ah
  2230 0000A411 4469736B2053657475-     	db 'Disk Setup Error!' 
  2230 0000A41A 70204572726F7221   
  2231 0000A422 0D0A00                  	db 0Dh, 0Ah,0
  2232                                  
  2233                                  ; 06/11/2014
  2234                                  ; Memory Information message
  2235                                  ; 14/08/2015
  2236                                  msg_memory_info:
  2237 0000A425 07                      	db	07h
  2238 0000A426 0D0A                    	db	0Dh, 0Ah
  2239                                  	;db 	"MEMORY ALLOCATION INFO", 0Dh, 0Ah, 0Dh, 0Ah
  2240 0000A428 546F74616C206D656D-     	db	"Total memory : "
  2240 0000A431 6F7279203A20       
  2241                                  mem_total_b_str: ; 10 digits
  2242 0000A437 303030303030303030-     	db	"0000000000 bytes", 0Dh, 0Ah
  2242 0000A440 302062797465730D0A 
  2243 0000A449 202020202020202020-     	db	"               ", 20h, 20h, 20h
  2243 0000A452 202020202020202020 
  2244                                  mem_total_p_str: ; 7 digits
  2245 0000A45B 303030303030302070-     	db	"0000000 pages", 0Dh, 0Ah
  2245 0000A464 616765730D0A       
  2246 0000A46A 0D0A                    	db 	0Dh, 0Ah
  2247 0000A46C 46726565206D656D6F-     	db	"Free memory  : "
  2247 0000A475 727920203A20       
  2248                                  free_mem_b_str:  ; 10 digits
  2249 0000A47B 3F3F3F3F3F3F3F3F3F-     	db	"?????????? bytes", 0Dh, 0Ah
  2249 0000A484 3F2062797465730D0A 
  2250 0000A48D 202020202020202020-     	db	"               ", 20h, 20h, 20h
  2250 0000A496 202020202020202020 
  2251                                  free_mem_p_str:  ; 7 digits
  2252 0000A49F 3F3F3F3F3F3F3F2070-     	db	"??????? pages", 0Dh, 0Ah
  2252 0000A4A8 616765730D0A       
  2253 0000A4AE 0D0A00                  	db	0Dh, 0Ah, 0
  2254                                  
  2255                                  dsk_ready_msg:
  2256 0000A4B1 0D0A                    	db 	0Dh, 0Ah
  2257                                  dsktype:
  2258 0000A4B3 6664                    	db	'fd'
  2259                                  dskx:
  2260 0000A4B5 30                      	db	'0'
  2261 0000A4B6 20                      	db	20h
  2262 0000A4B7 697320524541445920-     	db 	'is READY ...'
  2262 0000A4C0 2E2E2E             
  2263 0000A4C3 00                      	db 	0
  2264                                  
  2265                                  next2line: ; 08/02/2016
  2266 0000A4C4 0D0A                    	db	0Dh, 0Ah
  2267                                  nextline:
  2268 0000A4C6 0D0A00                  	db 	0Dh, 0Ah, 0
  2269                                  
  2270                                  ; KERNEL - SYSINIT Messages
  2271                                  ; 24/08/2015
  2272                                  ; 13/04/2015 - (Retro UNIX 386 v1 Beginning)
  2273                                  ; 14/07/2013
  2274                                  ;kernel_init_err_msg:
  2275                                  ;	db 0Dh, 0Ah
  2276                                  ;	db 07h
  2277                                  ;	db 'Kernel initialization ERROR !'
  2278                                  ;	db 0Dh, 0Ah, 0 
  2279                                  
  2280                                  ;welcome_msg: 
  2281                                  ;	db 0Dh, 0Ah
  2282                                  ;	db 07h
  2283                                  ;	db 'Welcome to TRDOS 386 Operating System !'
  2284                                  ;	db 0Dh, 0Ah
  2285                                  ;	db 'by Erdogan Tan - 06/03/2016 (v2.0.0)'
  2286                                  ;	db 0Dh, 0Ah, 0
  2287                                  
  2288                                  panic_msg:
  2289 0000A4C9 0D0A07                  	db 0Dh, 0Ah, 07h
  2290 0000A4CC 4552524F523A204B65-     	db 'ERROR: Kernel Panic !'
  2290 0000A4D5 726E656C2050616E69-
  2290 0000A4DE 632021             
  2291 0000A4E1 0D0A00                  	db 0Dh, 0Ah, 0
  2292                                  
  2293                                  ; 10/05/2015
  2294                                  badsys_msg:
  2295 0000A4E4 0D0A                    	db 0Dh, 0Ah
  2296 0000A4E6 07                      	db 07h
  2297 0000A4E7 496E76616C69642053-     	db 'Invalid System Call !'
  2297 0000A4F0 797374656D2043616C-
  2297 0000A4F9 6C2021             
  2298 0000A4FC 0D0A                    	db 0Dh, 0Ah
  2299 0000A4FE 4541583A20              	db 'EAX: '
  2300                                  bsys_msg_eax:
  2301 0000A503 303030303030303068      	db '00000000h'
  2302 0000A50C 0D0A                    	db 0Dh, 0Ah
  2303 0000A50E 4549503A20              	db 'EIP: '
  2304                                  bsys_msg_eip:
  2305 0000A513 303030303030303068      	db '00000000h' 
  2306 0000A51C 0D0A00                  	db 0Dh, 0Ah, 0
  2307                                  
  2308                                  BSYS_M_SIZE equ $ - badsys_msg
  2309                                  
  2310                                  
  2311 0000A51F 90                      align 2
  2312                                  
  2313                                  ; EPOCH Variables
  2314                                  ; 13/04/2015 - Retro UNIX 386 v1 Beginning
  2315                                  ; 09/04/2013 epoch variables
  2316                                  ; Retro UNIX 8086 v1 Prototype: UNIXCOPY.ASM, 10/03/2013
  2317                                  ;
  2318 0000A520 B207                    year: 	dw 1970
  2319 0000A522 0100                    month: 	dw 1
  2320 0000A524 0100                    day: 	dw 1
  2321 0000A526 0000                    hour: 	dw 0
  2322 0000A528 0000                    minute: dw 0
  2323 0000A52A 0000                    second: dw 0
  2324                                  
  2325                                  DMonth:
  2326 0000A52C 0000                    	dw 0
  2327 0000A52E 1F00                    	dw 31
  2328 0000A530 3B00                    	dw 59
  2329 0000A532 5A00                    	dw 90
  2330 0000A534 7800                    	dw 120
  2331 0000A536 9700                    	dw 151
  2332 0000A538 B500                    	dw 181
  2333 0000A53A D400                    	dw 212
  2334 0000A53C F300                    	dw 243
  2335 0000A53E 1101                    	dw 273
  2336 0000A540 3001                    	dw 304
  2337 0000A542 4E01                    	dw 334
  2338                                  
  2339                                  ; 04/11/2014 (Retro UNIX 386 v1)
  2340 0000A544 0000                    mem_1m_1k:   dw 0  ; Number of contiguous KB between
  2341                                                       ; 1 and 16 MB, max. 3C00h = 15 MB.
  2342 0000A546 0000                    mem_16m_64k: dw 0  ; Number of contiguous 64 KB blocks
  2343                                  		   ;   between 16 MB and 4 GB.
  2344                                  
  2345                                  starting_msg:
  2346 0000A548 5475726B6973682052-     	db "Turkish Rational DOS v2.0 [06/03/2016] ...", 0
  2346 0000A551 6174696F6E616C2044-
  2346 0000A55A 4F532076322E30205B-
  2346 0000A563 30362F30332F323031-
  2346 0000A56C 365D202E2E2E00     
  2347                                  NextLine:
  2348 0000A573 0D0A00                  	db 0Dh, 0Ah, 0
  2349                                  
  2350                                  ;msgl_drv_not_ready: 
  2351                                  ;	db 07h, 0Dh, 0Ah
  2352                                  ;       db 'Drive not ready or read error !'
  2353                                  ;       db 0Dh, 0Ah, 0
  2354                                  
  2355 0000A576 90<rept>                align 16
  2356                                  
  2357                                  bss_start:
  2358                                  
  2359                                  ABSOLUTE bss_start
  2360                                  
  2361                                  	; 11/03/2015
  2362                                  	; Interrupt Descriptor Table (20/08/2014)
  2363                                  idt:
  2364 0000A580 <res 00000200>          	resb	64*8 ; INT 0 to INT 3Fh
  2365                                  idt_end:
  2366                                  
  2367                                  ;alignb 4
  2368                                  
  2369                                  task_state_segment:
  2370                                  	; 24/03/2015
  2371 0000A780 <res 00000002>          tss.link:   resw 1
  2372 0000A782 <res 00000002>          	    resw 1
  2373                                  ; tss offset 4	
  2374 0000A784 <res 00000004>          tss.esp0:   resd 1
  2375 0000A788 <res 00000002>          tss.ss0:    resw 1
  2376 0000A78A <res 00000002>          	    resw 1	
  2377 0000A78C <res 00000004>          tss.esp1:   resd 1
  2378 0000A790 <res 00000002>          tss.ss1:    resw 1
  2379 0000A792 <res 00000002>          	    resw 1 	
  2380 0000A794 <res 00000004>          tss.esp2:   resd 1
  2381 0000A798 <res 00000002>          tss.ss2:    resw 1
  2382 0000A79A <res 00000002>          	    resw 1
  2383                                  ; tss offset 28
  2384 0000A79C <res 00000004>          tss.CR3:    resd 1
  2385 0000A7A0 <res 00000004>          tss.eip:    resd 1
  2386 0000A7A4 <res 00000004>          tss.eflags: resd 1
  2387                                  ; tss offset 40
  2388 0000A7A8 <res 00000004>          tss.eax:    resd 1		 		
  2389 0000A7AC <res 00000004>          tss.ecx:    resd 1
  2390 0000A7B0 <res 00000004>          tss.edx:    resd 1
  2391 0000A7B4 <res 00000004>          tss.ebx:    resd 1
  2392 0000A7B8 <res 00000004>          tss.esp:    resd 1
  2393 0000A7BC <res 00000004>          tss.ebp:    resd 1
  2394 0000A7C0 <res 00000004>          tss.esi:    resd 1
  2395 0000A7C4 <res 00000004>          tss.edi:    resd 1
  2396                                  ; tss offset 72
  2397 0000A7C8 <res 00000002>          tss.ES:     resw 1
  2398 0000A7CA <res 00000002>          	    resw 1	
  2399 0000A7CC <res 00000002>          tss.CS:	    resw 1
  2400 0000A7CE <res 00000002>          	    resw 1
  2401 0000A7D0 <res 00000002>          tss.SS:	    resw 1
  2402 0000A7D2 <res 00000002>          	    resw 1
  2403 0000A7D4 <res 00000002>          tss.DS:	    resw 1
  2404 0000A7D6 <res 00000002>          	    resw 1
  2405 0000A7D8 <res 00000002>          tss.FS:	    resw 1
  2406 0000A7DA <res 00000002>          	    resw 1
  2407 0000A7DC <res 00000002>          tss.GS:	    resw 1
  2408 0000A7DE <res 00000002>          	    resw 1		
  2409 0000A7E0 <res 00000002>          tss.LDTR:   resw 1
  2410 0000A7E2 <res 00000002>          	    resw 1
  2411                                  ; tss offset 100		
  2412 0000A7E4 <res 00000002>          	    resw 1		
  2413 0000A7E6 <res 00000002>          tss.IOPB:   resw 1
  2414                                  ; tss offset 104 
  2415                                  tss_end:
  2416                                  
  2417 0000A7E8 <res 00000004>          k_page_dir:  resd 1 ; Kernel's (System) Page Directory address
  2418                                  		    ; (Physical address = Virtual address)	 	
  2419 0000A7EC <res 00000004>          memory_size: resd 1 ; memory size in pages
  2420 0000A7F0 <res 00000004>          free_pages:  resd 1 ; number of free pages		
  2421 0000A7F4 <res 00000004>          next_page:   resd 1 ; offset value in M.A.T. for
  2422                                  		    ; first free page search
  2423 0000A7F8 <res 00000004>          last_page:   resd 1 ; offset value in M.A.T. which
  2424                                  		    ; next free page search will be
  2425                                  		    ; stopped after it. (end of M.A.T.)
  2426 0000A7FC <res 00000004>          first_page:  resd 1 ; offset value in M.A.T. which
  2427                                  		    ; first free page search
  2428                                  		    ; will be started on it. (for user)
  2429 0000A800 <res 00000004>          mat_size:    resd 1 ; Memory Allocation Table size in pages		
  2430                                  
  2431                                  ; 02/09/2014 (Retro UNIX 386 v1)
  2432                                  ; 04/12/2013 (Retro UNIX 8086 v1)
  2433 0000A804 <res 00000002>          CRT_START:   resw 1 	  ; starting address in regen buffer
  2434                                  			  ; NOTE: active page only	
  2435 0000A806 <res 00000002>          CURSOR_MODE: resw 1 ; 24/01/2016
  2436 0000A808 <res 00000010>          CURSOR_POSN: resw 8 ; cursor positions for video pages
  2437                                  ACTIVE_PAGE: 
  2438 0000A818 <res 00000001>          ptty: 	     resb 1 ; current tty
  2439                                  ; 01/07/2015 - 29/01/2016
  2440 0000A819 <res 00000001>          ccolor:	     resb 1 ; current color attribute
  2441                                  ; 26/10/2015
  2442                                  ; 07/09/2014
  2443 0000A81A <res 00000014>          ttychr:      resw ntty+2 ; Character buffer (multiscreen)
  2444                                  
  2445                                  ; 21/08/2014
  2446 0000A82E <res 00000004>          tcount:	     resd 1
  2447                                  
  2448                                  ; 18/05/2015 (03/06/2013 - Retro UNIX 8086 v1 feature only!)
  2449 0000A832 <res 00000004>          p_time:      resd 1     ; present time (for systime & sysmdate)
  2450                                  
  2451                                  ; 18/05/2015 (16/08/2013 - Retro UNIX 8086 v1 feature only !)
  2452                                  ; (open mode locks for pseudo TTYs)
  2453                                  ; [ major tty locks (return error in any conflicts) ]
  2454 0000A836 <res 00000014>          ttyl:        resw ntty+2 ; opening locks for TTYs.
  2455                                  
  2456                                  ; 15/04/2015 (Retro UNIX 386 v1)
  2457                                  ; 22/09/2013 (Retro UNIX 8086 v1)
  2458 0000A84A <res 0000000A>          wlist:       resb ntty+2 ; wait channel list (0 to 9 for TTYs)
  2459                                  ; 15/04/2015 (Retro UNIX 386 v1)
  2460                                  ;; 12/07/2014 -> sp_init set comm. parameters as 0E3h
  2461                                  ;; 0 means serial port is not available 
  2462                                  ;;comprm: ; 25/06/2014
  2463 0000A854 <res 00000001>          com1p:       resb 1  ;;0E3h
  2464 0000A855 <res 00000001>          com2p:       resb 1  ;;0E3h
  2465                                  
  2466                                  ; 17/11/2015
  2467                                  ; request for response (from the terminal)	
  2468 0000A856 <res 00000002>          req_resp:    resw 1 			
  2469                                  ; 07/11/2015
  2470 0000A858 <res 00000001>          ccomport:    resb 1 ; current COM (serial) port
  2471                                  		    ; (0= COM1, 1= COM2)
  2472                                  ; 09/11/2015
  2473 0000A859 <res 00000001>          comqr:	     resb 1 ; 'query or response' sign (u9.s, 'sndc')
  2474                                  ; 07/11/2015
  2475 0000A85A <res 00000002>          rchar:	     resw 1 ; last received char for COM 1 and COM 2		
  2476 0000A85C <res 00000002>          schar:	     resw 1 ; last sent char for COM 1 and COM 2
  2477                                  
  2478                                  ; 22/08/2014 (RTC)
  2479                                  ; (Packed BCD)
  2480 0000A85E <res 00000001>          time_seconds: resb 1
  2481 0000A85F <res 00000001>          time_minutes: resb 1
  2482 0000A860 <res 00000001>          time_hours:   resb 1
  2483 0000A861 <res 00000001>          date_wday:    resb 1
  2484 0000A862 <res 00000001>          date_day:     resb 1
  2485 0000A863 <res 00000001>          date_month:   resb 1			
  2486 0000A864 <res 00000001>          date_year:    resb 1
  2487 0000A865 <res 00000001>          date_century: resb 1
  2488                                  
  2489                                  ; 24/01/2016
  2490 0000A866 <res 00000004>          RTC_LH:	       resd 1
  2491 0000A86A <res 00000001>          RTC_WAIT_FLAG: resb 1
  2492 0000A86B <res 00000001>          USER_FLAG:     resb 1
  2493                                  
  2494                                  
  2495                                  %include 'diskbss.s'	; UNINITIALIZED DISK (BIOS) DATA
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel) - v2.0.0 - diskbss.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 24/01/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Turkish Rational DOS
    11                              <1> ; Operating System Project v2.0 by ERDOGAN TAN (Beginning: 04/01/2016)
    12                              <1> ;
    13                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    14                              <1> ; diskbss.inc (10/07/2015)
    15                              <1> ;
    16                              <1> ; Derived from 'IBM PC-XT-286' BIOS source code (1986) 
    17                              <1> ; ****************************************************************************
    18                              <1> 
    19                              <1> ; Retro UNIX 386 v1 Kernel - DISKBSS.INC
    20                              <1> ; Last Modification: 10/07/2015
    21                              <1> ;	(Unnitialized Disk Parameters Data section for 'DISKIO.INC') 
    22                              <1> 
    23                              <1> alignb 2
    24                              <1> 
    25                              <1> ;----------------------------------------
    26                              <1> ;	TIMER DATA AREA 		:
    27                              <1> ;----------------------------------------
    28                              <1> 
    29                              <1> TIMER_LH:	; 16/02/205
    30 0000A86C <res 00000002>      <1> TIMER_LOW:      resw	1               ; LOW WORD OF TIMER COUNT
    31 0000A86E <res 00000002>      <1> TIMER_HIGH:     resw	1               ; HIGH WORD OF TIMER COUNT
    32 0000A870 <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 0000A871 <res 00000001>      <1> SEEK_STATUS:	resb	1
    39 0000A872 <res 00000001>      <1> MOTOR_STATUS:	resb	1
    40 0000A873 <res 00000001>      <1> MOTOR_COUNT:	resb	1
    41 0000A874 <res 00000001>      <1> DSKETTE_STATUS:	resb	1
    42 0000A875 <res 00000007>      <1> NEC_STATUS:	resb	7
    43                              <1> 
    44                              <1> ;----------------------------------------
    45                              <1> ;	ADDITIONAL MEDIA DATA		:
    46                              <1> ;----------------------------------------
    47                              <1> 
    48 0000A87C <res 00000001>      <1> LASTRATE:	resb 	1
    49 0000A87D <res 00000001>      <1> HF_STATUS:	resb 	1
    50 0000A87E <res 00000001>      <1> HF_ERROR:	resb 	1
    51 0000A87F <res 00000001>      <1> HF_INT_FLAG:	resb 	1
    52 0000A880 <res 00000001>      <1> HF_CNTRL:	resb 	1
    53 0000A881 <res 00000004>      <1> DSK_STATE:	resb 	4
    54 0000A885 <res 00000002>      <1> DSK_TRK:	resb 	2
    55                              <1> 
    56                              <1> ;----------------------------------------
    57                              <1> ;	FIXED DISK DATA AREAS		:
    58                              <1> ;----------------------------------------
    59                              <1> 
    60 0000A887 <res 00000001>      <1> DISK_STATUS1:	resb 	1		; FIXED DISK STATUS
    61 0000A888 <res 00000001>      <1> HF_NUM:		resb 	1		; COUNT OF FIXED DISK DRIVES
    62 0000A889 <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 0000A88A <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 0000A88C <res 00000004>      <1> HDPM_TBL_VEC:	resd	1 		; Primary master disk param. tbl. pointer
    73 0000A890 <res 00000004>      <1> HDPS_TBL_VEC:	resd	1		; Primary slave disk param. tbl. pointer
    74 0000A894 <res 00000004>      <1> HDSM_TBL_VEC:	resd	1 		; Secondary master disk param. tbl. pointer
    75 0000A898 <res 00000004>      <1> HDSS_TBL_VEC:	resd	1		; Secondary slave disk param. tbl. pointer
    76                              <1> 
    77                              <1> ; 03/01/2015
    78 0000A89C <res 00000001>      <1> LBAMode:     	resb	1
    79                              <1> 
    80                              <1> ; *****************************************************************************
  2496                                  
  2497                                  ;;; Real Mode Data (10/07/2015 - BSS)
  2498                                  
  2499                                  ;alignb 2
  2500                                  
  2501                                  ; 10/01/2016
  2502                                  %include 'trdoskx.s'	; UNINITIALIZED KERNEL (Logical Drive & FS) DATA
     1                              <1> ; ****************************************************************************
     2                              <1> ; TRDOS386.ASM (TRDOS 386 Kernel - v2.0.0) - UNINITIALIZED DATA : trdoskx.s
     3                              <1> ; ----------------------------------------------------------------------------
     4                              <1> ; Last Update: 06/03/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 04/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from TRDOS Operating System v1.0 (8086) source code by Erdogan Tan
    11                              <1> ; TRDOS2.ASM (09/11/2011)
    12                              <1> ; ****************************************************************************
    13                              <1> ; DRV_INIT.ASM [26/09/2009] Last Update: 07/08/2011
    14                              <1> ; MAINPROG.ASM [17/01/2004] Last Update: 09/11/2011
    15                              <1> ; DIR.ASM      [17/01/2004] Last Update: 09/10/2011
    16                              <1> ; CMD_INTR.ASM [29/01/2005] Last update: 09/11/2011
    17                              <1> ; DRV_FAT.ASM  [07/07/2009] Last update: 21/08/2011
    18                              <1> 
    19 0000A89D <res 00000003>      <1> alignb 4
    20                              <1> 
    21 0000A8A0 <res 00000002>      <1> MainProgCfg_FileSize:   resw 1
    22 0000A8A2 <res 00000002>      <1> MainProgCfg_LineOffset: resw 1 
    23                              <1> 
    24 0000A8A4 <res 00000004>      <1> Current_VolSerial: resd 1
    25                              <1> 
    26 0000A8A8 <res 00000004>      <1> Current_Dir_FCluster: resd 1
    27                              <1> 
    28 0000A8AC <res 00000001>      <1> Current_Dir_Level: resb 1
    29 0000A8AD <res 00000001>      <1> Current_FATType: resb 1
    30 0000A8AE <res 00000001>      <1> Current_Drv: resb 1
    31 0000A8AF <res 00000001>      <1> Current_Dir_Drv:   resb 1 ; '?'
    32 0000A8B0 <res 00000001>      <1>                    resb 1 ; ':'
    33 0000A8B1 <res 00000001>      <1> Current_Dir_Root:  resb 1 ; '/' 
    34 0000A8B2 <res 0000005A>      <1> Current_Directory: resb 90
    35 0000A90C <res 00000001>      <1> End_Of_Current_Dir_Str: resb 1
    36 0000A90D <res 00000001>      <1> Current_Dir_StrLen: resb 1   
    37                              <1> 
    38 0000A90E <res 00000001>      <1> CursorColumn: 	resb 1
    39 0000A90F <res 00000001>      <1> CmdArgStart:    resb 1
    40                              <1> 
    41                              <1> Remark: ; 03/02/2016
    42 0000A910 <res 0000004E>      <1> 		resb 78
    43                              <1> 
    44 0000A95E <res 00000050>      <1> CommandBuffer: 	resb 80
    45                              <1> 
    46 0000A9AE <res 00000100>      <1> TextBuffer: resb 256
    47                              <1> 
    48                              <1> MasterBootBuff:
    49 0000AAAE <res 000001BE>      <1> MasterBootCode: resb 1BEh
    50 0000AC6C <res 00000040>      <1> PartitionTable: resb 64
    51 0000ACAC <res 00000002>      <1> MBIDCode: resw 1
    52                              <1> 
    53                              <1> PTable_Buffer:
    54 0000ACAE <res 00000040>      <1> PTable_hd0: resb 64
    55 0000ACEE <res 00000040>      <1> PTable_hd1: resb 64
    56 0000AD2E <res 00000040>      <1> PTable_hd2: resb 64
    57 0000AD6E <res 00000040>      <1> PTable_hd3: resb 64
    58 0000ADAE <res 00000040>      <1> PTable_ep0: resb 64
    59 0000ADEE <res 00000040>      <1> PTable_ep1: resb 64
    60 0000AE2E <res 00000040>      <1> PTable_ep2: resb 64
    61 0000AE6E <res 00000040>      <1> PTable_ep3: resb 64
    62                              <1> 
    63 0000AEAE <res 00000001>      <1> HD_LBA_yes: resb 1
    64 0000AEAF <res 00000001>      <1> PP_Counter: resb 1
    65 0000AEB0 <res 00000001>      <1> EP_Counter: resb 1
    66                              <1> 
    67 0000AEB1 <res 00000004>      <1> EP_StartSector: resd 1
    68 0000AEB5 <res 00000004>      <1>                 resd 1
    69 0000AEB9 <res 00000004>      <1>                 resd 1
    70 0000AEBD <res 00000004>      <1>                 resd 1
    71                              <1> 
    72 0000AEC1 <res 00000200>      <1> DOSBootSectorBuff: resb 512
    73                              <1> 
    74                              <1> FAT_BuffDescriptor:
    75 0000B0C1 <res 00000004>      <1> FAT_CurrentCluster: resd 1
    76 0000B0C5 <res 00000001>      <1> FAT_BuffValidData: resb 1
    77 0000B0C6 <res 00000001>      <1> FAT_BuffDrvName: resb 1
    78 0000B0C7 <res 00000002>      <1> FAT_BuffOffset: resw 1
    79 0000B0C9 <res 00000004>      <1> FAT_BuffSector: resd 1
    80                              <1> 
    81 0000B0CD <res 00000004>      <1> FAT_ClusterCounter: resd 1
    82 0000B0D1 <res 00000004>      <1> LastCluster: resd 1
    83                              <1> 
    84 0000B0D5 <res 00000001>      <1> resb 1
    85                              <1> 
    86                              <1> Dir_BuffDescriptor:
    87 0000B0D6 <res 00000001>      <1> DirBuff_DRV: resb 1
    88 0000B0D7 <res 00000001>      <1> DirBuff_FATType: resb 1
    89 0000B0D8 <res 00000001>      <1> DirBuff_ValidData: resb 1
    90 0000B0D9 <res 00000002>      <1> DirBuff_CurrentEntry: resw 1
    91 0000B0DB <res 00000002>      <1> DirBuff_LastEntry: resw 1
    92 0000B0DD <res 00000004>      <1> DirBuff_Cluster: resd 1 
    93 0000B0E1 <res 00000002>      <1> DirBuffer_Size: resw 1
    94                              <1> ;DirBuff_EntryCounter: resw 1
    95                              <1> 
    96                              <1> ; 01/02/2016
    97                              <1> ; these are on (real mode) segment 8000h and later
    98                              <1> ; FAT_Buffer:	resb 1536 ; 3 sectors
    99                              <1> ; Dir_Buffer:	resb 512*32
   100                              <1> ; Logical_DOSDisks:  resb 6656 ; 26 * 256 bytes
   101                              <1> 
   102                              <1> ; 18/01/2016
   103                              <1> 
   104 0000B0E3 <res 00000004>      <1> FreeClusterCount: resd 1
   105                              <1> 
   106 0000B0E7 <res 00000004>      <1> VolSize_Unit1:   resd 1
   107 0000B0EB <res 00000004>      <1> VolSize_Unit2:   resd 1
   108                              <1> 
   109 0000B0EF <res 00000004>      <1> Vol_Tot_Sec_Str_Start:	    resd 1
   110 0000B0F3 <res 0000000A>      <1> Vol_Tot_Sec_Str: 	    resb 10
   111 0000B0FD <res 00000001>      <1> Vol_Tot_Sec_Str_End:	    resb 1
   112 0000B0FE <res 00000001>      <1> resb 1
   113 0000B0FF <res 00000004>      <1> Vol_Free_Sectors_Str_Start: resd 1
   114 0000B103 <res 0000000A>      <1> Vol_Free_Sectors_Str:	    resb 10				
   115 0000B10D <res 00000001>      <1> Vol_Free_Sectors_Str_End:   resb 1
   116                              <1> 
   117                              <1> ; 10/02/2016
   118 0000B10E <res 00000001>      <1> RUN_CDRV: resb 1 ; CMD_INTR.ASM  ; 09/11/2011
   119                              <1> 
   120                              <1> ; 24/01/2016
   121 0000B10F <res 00000080>      <1> PATH_Array:     resb 128 ; DIR.ASM ; 09/10/2011
   122                              <1> ; 06/02/2016
   123 0000B18F <res 00000004>      <1> CCD_DriveDT:	resd 1 ; DIR.ASM ; (word)
   124 0000B193 <res 00000001>      <1> CCD_Level:	resb 1 ; DIR.ASM
   125 0000B194 <res 00000001>      <1> Last_Dir_Level:	resb 1 ; DIR.ASM
   126                              <1> ;
   127 0000B195 <res 00000002>      <1> CDLF_AttributesMask: resw 1 ; DIR.ASM
   128 0000B197 <res 00000004>      <1> CDLF_FNAddress:	resd 1 ; DIR.ASM (word)
   129 0000B19B <res 00000002>      <1> CDLF_DEType:	resw 1 ; DIR.ASM
   130                              <1> ;
   131 0000B19D <res 00000001>      <1> CD_COMMAND:	resb 1 ; DIR.ASM
   132                              <1> 
   133 0000B19E <res 00000002>      <1> alignb 4
   134                              <1> 
   135                              <1> ; 29/01/2016
   136 0000B1A0 <res 00000001>      <1> Program_Exit:	resb 1 ; CMD_INTR.ASM  ; 09/11/2011
   137                              <1> 
   138                              <1> ;alignb 4
   139                              <1> ; 23/02/2016
   140 0000B1A1 <res 00000001>      <1> disk_rw_op:	resb 1 ;  0 = disk read, 1 = disk write
   141                              <1> ;disk_rw_spt:	resb 1 ; sectors per track (<= 63) /// (<256)
   142                              <1> ; 31/01/2016
   143 0000B1A2 <res 00000001>      <1> retry_count: 	resb 1 ; DISK_IO.ASM ; 20/07/2011 (CHS_RetryCount)
   144 0000B1A3 <res 00000001>      <1> disk_rw_err: 	resb 1 ; DISK_IO.ASM ; (Disk_IO_err_code)
   145 0000B1A4 <res 00000004>      <1> sector_count:	resd 1 ; DISK_IO.ASM ; (Disk_RW_SectorCount)
   146                              <1> 
   147                              <1> ; 06/02/2016 (long name)
   148 0000B1A8 <res 00000002>      <1> FDE_AttrMask:	   resw 1 ; DIR.ASM
   149 0000B1AA <res 00000002>      <1> AmbiguousFileName: resw 1 ; DIR.ASM
   150 0000B1AC <res 00000001>      <1> PreviousAttr:	   resb 1 ; DIR.ASM
   151                              <1> ;	
   152 0000B1AD <res 00000001>      <1> LongNameFound:   resb 1	  ; DIR.ASM
   153 0000B1AE <res 00000001>      <1> LFN_EntryLength: resb 1   ; DIR.ASM
   154 0000B1AF <res 00000001>      <1> LFN_CheckSum:    resb 1   ; DIR.ASM
   155 0000B1B0 <res 00000084>      <1> LongFileName:    resb 132 ; DIR.ASM
   156                              <1> 
   157                              <1> ;PATH_Array_Ptr: resw 1 ; DIR.ASM
   158 0000B234 <res 00000001>      <1> PATH_CDLevel:	 resb 1 ; DIR.ASM
   159 0000B235 <res 00000001>      <1> PATH_Level:	 resb 1 ; DIR.ASM
   160                              <1> 
   161                              <1> ; 07/02/2016
   162 0000B236 <res 0000000D>      <1> Dir_File_Name:	resb 13 ; DIR.ASM ; 09/10/2011
   163                              <1> 
   164                              <1> ; 10/02/2016
   165                              <1> Dir_Entry_Name:
   166 0000B243 <res 0000000D>      <1> 		resb 13 ; DIR.ASM
   167                              <1> 
   168                              <1> alignb 2
   169                              <1> 
   170 0000B250 <res 00000002>      <1> AttributesMask: resw 1 ; CMD_INTR.ASM ; 09/11/2011
   171                              <1> 
   172                              <1> ; 10/02/2016 (128 bytes -> 126 bytes)
   173                              <1> ; 08/02/2016
   174                              <1> ;FFF Structure (128 bytes) ; DIR.ASM ; 09/10/2011
   175 0000B252 <res 00000001>      <1> FindFile_Drv:		  resb 1
   176 0000B253 <res 00000041>      <1> FindFile_Directory:	  resb 65
   177 0000B294 <res 0000000D>      <1> FindFile_Name:		  resb 13
   178                              <1> FindFile_LongNameEntryLength:
   179 0000B2A1 <res 00000001>      <1> FindFile_LongNameYes: 	  resb 1 ; Sign for longname procedures
   180                              <1> ;Above 80 bytes form
   181                              <1> ;TR-DOS Source/Destination File FullName Format/Structure
   182 0000B2A2 <res 00000002>      <1> FindFile_AttributesMask:  resw 1
   183 0000B2A4 <res 00000020>      <1> FindFile_DirEntry:	  resb 32
   184 0000B2C4 <res 00000004>      <1> FindFile_DirFirstCluster: resd 1
   185 0000B2C8 <res 00000004>      <1> FindFile_DirCluster:	  resd 1
   186 0000B2CC <res 00000002>      <1> FindFile_DirEntryNumber:  resw 1
   187 0000B2CE <res 00000002>      <1> FindFile_MatchCounter:	  resw 1
   188 0000B2D0 <res 00000002>      <1> FindFile_Reserved:	  resw 1 ; 06/03/2016
   189                              <1> 
   190 0000B2D2 <res 00000004>      <1> First_Path_Pos: resd 1	; DIR.ASM ; 09/10/2011
   191 0000B2D6 <res 00000004>      <1> Last_Slash_Pos: resd 1	; DIR.ASM 
   192                              <1> 
   193                              <1> ; 10/02/2016
   194 0000B2DA <res 00000002>      <1> File_Count:     resw 1 	; DIR.ASM ; 09/10/2011
   195 0000B2DC <res 00000002>      <1> Dir_Count:      resw 1
   196 0000B2DE <res 00000004>      <1> Total_FSize:    resd 1
   197 0000B2E2 <res 00000004>      <1> TFS_Dec_Begin:  resd 1
   198 0000B2E6 <res 0000000A>      <1>                 resb 10
   199 0000B2F0 <res 00000001>      <1> TFS_Dec_End:    resb 1
   200                              <1> 
   201 0000B2F1 <res 00000001>      <1> PrintDir_RowCounter: resb 1
   202                              <1> 
   203 0000B2F2 <res 00000002>      <1> alignb 4
   204                              <1> ; 15/02/2015 ('show' command variables)
   205 0000B2F4 <res 00000004>      <1> Show_FDT:	resd 1
   206 0000B2F8 <res 00000004>      <1> Show_LDDDT:	resd 1
   207 0000B2FC <res 00000004>      <1> Show_Cluster:	resd 1
   208 0000B300 <res 00000004>      <1> Show_FileSize:	resd 1
   209 0000B304 <res 00000004>      <1> Show_FilePointer: resd 1
   210 0000B308 <res 00000002>      <1> Show_ClusterPointer: resw 1
   211 0000B30A <res 00000002>      <1> Show_ClusterSize: resw 1
   212 0000B30C <res 00000001>      <1> Show_RowCount:	resb 1
   213                              <1> 
   214 0000B30D <res 00000003>      <1> alignb 4
   215                              <1> ; 21/02/2016
   216 0000B310 <res 00000004>      <1> DelFile_FNPointer:	resd 1 ; ; CMD_INTR.ASM (word) ; 09/11/2011
   217                              <1> ; 27/02/2016
   218                              <1> ; DIR.ASM (09/10/2011)
   219 0000B314 <res 00000004>      <1> DelFile_FCluster:	resd 1
   220 0000B318 <res 00000002>      <1> DelFile_EntryCounter:	resw 1
   221 0000B31A <res 00000001>      <1> DelFile_LNEL:		resb 1
   222 0000B31B <res 00000001>      <1> resb 1
   223                              <1> 
   224                              <1> ; DIR.ASM
   225 0000B31C <res 00000004>      <1> mkdir_DirName_Offset: 	resd 1
   226 0000B320 <res 00000004>      <1> mkdir_FFCluster:	resd 1
   227 0000B324 <res 00000004>      <1> mkdir_LastDirCluster:	resd 1
   228 0000B328 <res 00000004>      <1> mkdir_FreeSectors:	resd 1
   229 0000B32C <res 00000002>      <1> mkdir_attrib:		resw 1 
   230 0000B32E <res 00000001>      <1> mkdir_SecPerClust:	resb 1
   231 0000B32F <res 00000001>      <1> mkdir_add_new_cluster:	resb 1
   232 0000B330 <res 0000000D>      <1> mkdir_Name:		resb 13
   233 0000B33D <res 00000002>      <1> resw 1 ; 01/03/2016
   234                              <1> ; 27/02/2016
   235 0000B33F <res 00000001>      <1> RmDir_MultiClusters:	resb 1  
   236 0000B340 <res 00000004>      <1> RmDir_DirEntryOffset:	resd 1 ; 01/03/2016 (word -> dword)
   237 0000B344 <res 00000004>      <1> RmDir_ParentDirCluster: resd 1
   238 0000B348 <res 00000004>      <1> RmDir_DirLastCluster:   resd 1
   239 0000B34C <res 00000004>      <1> RmDir_PreviousCluster:  resd 1
   240                              <1> ; 22/02/2016
   241 0000B350 <res 00000001>      <1> UPDLMDT_CDirLevel:	resb 1
   242 0000B351 <res 00000004>      <1> UPDLMDT_CDirFCluster:	resd 1
   243                              <1> 	
   244 0000B355 <res 00000003>      <1> alignb 4
   245                              <1> ; DRV_FAT.ASM ; 21/08/2011
   246 0000B358 <res 00000004>      <1> gffc_next_free_cluster:  resd 1
   247 0000B35C <res 00000004>      <1> gffc_first_free_cluster: resd 1
   248 0000B360 <res 00000004>      <1> gffc_last_free_cluster:  resd 1
   249                              <1> 
   250                              <1> ; 22/02/2016
   251 0000B364 <res 00000004>      <1> ClusterValue:	resd 1
   252                              <1> ; 04/03/2016
   253 0000B368 <res 00000001>      <1> Attributes:	resb 1 
   254                              <1> ;;CFS_error:  resb 1 ;; 01/03/2016
   255 0000B369 <res 00000001>      <1> resb 1
   256 0000B36A <res 00000001>      <1> CFS_OPType: resb 1
   257 0000B36B <res 00000001>      <1> CFS_Drv:    resb 1
   258 0000B36C <res 00000004>      <1> CFS_CC:	    resd 1
   259 0000B370 <res 00000004>      <1> CFS_FAT32FSINFOSEC: resd 1
   260 0000B374 <res 00000004>      <1> CFS_FAT32FC: resd 1
   261                              <1> 
   262                              <1> ; 27/02/2016
   263                              <1> ;alignb 4
   264 0000B378 <res 00000004>      <1> glc_prevcluster: resd 1 ; DRV_FAT.ASM (21/08/2011)
   265                              <1> 
   266                              <1> ; DIR.ASM
   267 0000B37C <res 00000002>      <1> DLN_EntryNumber: resw 1
   268 0000B37E <res 00000001>      <1> DLN_40h:	 resb 1
   269                              <1> ; 28/02/2016
   270 0000B37F <res 00000001>      <1> TCC_FATErr:	 resb 1 ; DRV_FAT.ASM
   271                              <1> 
   272                              <1> alignb 4
   273                              <1> ; DIR.ASM (09/10/2011)
   274 0000B380 <res 00000002>      <1> LCDE_EntryIndex: resw 1 ; LCDE_EntryOffset
   275 0000B382 <res 00000002>      <1> LCDE_ClusterSN:  resw 1
   276 0000B384 <res 00000004>      <1> LCDE_Cluster: 	 resd 1
   277 0000B388 <res 00000004>      <1> LCDE_ByteOffset: resd 1
   278                              <1> 
   279                              <1> ;alignb4
   280                              <1> ; 06/03/2016 (word -> dword)
   281                              <1> ; CMD_INTR.ASM (01/08/2010)
   282 0000B38C <res 00000004>      <1> SourceFilePath:	     resd 1
   283 0000B390 <res 00000004>      <1> DestinationFilePath: resd 1
   284                              <1> 
   285                              <1> ;alignb 4
   286                              <1> ; 06/03/2016
   287                              <1> ; FILE.ASM (09/10/2011)
   288                              <1> ;Source File Structure (same with 'Find File' Structure)
   289 0000B394 <res 00000001>      <1> SourceFile_Drv:			resb 1
   290 0000B395 <res 00000041>      <1> SourceFile_Directory:		resb 65
   291 0000B3D6 <res 0000000D>      <1> SourceFile_Name:		resb 13
   292                              <1> SourceFile_LongNameEntryLength: 
   293 0000B3E3 <res 00000001>      <1> SourceFile_LongNameYes:		resb 1 ; Sign for longname procedures
   294                              <1> ;Above 80 bytes
   295                              <1> ;is TR-DOS Source File FullName Format/Structure
   296 0000B3E4 <res 00000002>      <1> SourceFile_AttributesMask:	resw 1
   297 0000B3E6 <res 00000020>      <1> SourceFile_DirEntry:		resb 32
   298 0000B406 <res 00000004>      <1> SourceFile_DirFirstCluster:	resd 1
   299 0000B40A <res 00000004>      <1> SourceFile_DirCluster:		resd 1
   300 0000B40E <res 00000002>      <1> SourceFile_DirEntryNumber:	resw 1
   301 0000B410 <res 00000002>      <1> SourceFile_MatchCounter:	resw 1
   302 0000B412 <res 00000002>      <1> SourceFile_Reserved:		resw 1
   303                              <1> ; Above is 128 bytes
   304                              <1> 
   305                              <1> ;Destination File Structure (same with 'Find File' Structure)
   306 0000B414 <res 00000001>      <1> DestinationFile_Drv:		resb 1
   307 0000B415 <res 00000041>      <1> DestinationFile_Directory: 	resb 65
   308 0000B456 <res 0000000D>      <1> DestinationFile_Name:		resb 13
   309                              <1> DestinationFile_LongNameEntryLength:
   310 0000B463 <res 00000001>      <1> DestinationFile_LongNameYes:	resb 1 ; Sign for longname procedures
   311                              <1> ;Above 80 bytes
   312                              <1> ;is TR-DOS Destination File FullName Format/Structure
   313 0000B464 <res 00000002>      <1> DestinationFile_AttributesMask: resw 1
   314 0000B466 <res 00000020>      <1> DestinationFile_DirEntry:	resb 32
   315 0000B486 <res 00000004>      <1> DestinationFile_DirFirstCluster: resd 1
   316 0000B48A <res 00000004>      <1> DestinationFile_DirCluster:	resd 1
   317 0000B48E <res 00000002>      <1> DestinationFile_DirEntryNumber: resw 1
   318 0000B490 <res 00000002>      <1> DestinationFile_MatchCounter:	resw 1
   319 0000B492 <res 00000002>      <1> DestinationFile_Reserved:	resw 1
   320                              <1> ; Above is 128 bytes
  2503                                  ; 24/01/2016
  2504                                  %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: 24/01/2016
     5                              <1> ; ----------------------------------------------------------------------------
     6                              <1> ; Beginning: 24/01/2016
     7                              <1> ; ----------------------------------------------------------------------------
     8                              <1> ; Assembler: NASM version 2.11 (trdos386.s)
     9                              <1> ; ----------------------------------------------------------------------------
    10                              <1> ; Derived from 'Retro UNIX 386 Kernel - v0.2.1.0' source code by Erdogan Tan
    11                              <1> ; 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 0000B494 <res 00000002>      <1> 	i.flgs:	 resw 1
    37 0000B496 <res 00000001>      <1> 	i.nlks:	 resb 1
    38 0000B497 <res 00000001>      <1> 	i.uid:	 resb 1
    39 0000B498 <res 00000002>      <1>         i.size:  resw 1 ; size
    40 0000B49A <res 00000010>      <1> 	i.dskp:	 resw 8 ; 16 bytes
    41 0000B4AA <res 00000004>      <1> 	i.ctim:	 resd 1
    42 0000B4AE <res 00000004>      <1> 	i.mtim:	 resd 1
    43 0000B4B2 <res 00000002>      <1> 	i.rsvd:  resw 1 ; Reserved (ZERO/Undefined word for UNIX v1.)
    44                              <1> 
    45                              <1> I_SIZE	equ $ - inode 
    46                              <1> 
    47                              <1> process:
    48                              <1> 	; 06/05/2015
    49                              <1> 	; 11/03/2013 - 05/02/2014
    50                              <1> 	;Derived from UNIX v1 source code 'proc' structure (ux).
    51                              <1> 	;p.
    52                              <1> 	
    53 0000B4B4 <res 00000020>      <1>         p.pid:   resw nproc
    54 0000B4D4 <res 00000020>      <1>         p.ppid:  resw nproc
    55 0000B4F4 <res 00000020>      <1>         p.break: resw nproc
    56 0000B514 <res 00000010>      <1>         p.ttyc:  resb nproc ; console tty in Retro UNIX 8086 v1.
    57 0000B524 <res 00000010>      <1> 	p.waitc: resb nproc ; waiting channel in Retro UNIX 8086 v1.
    58 0000B534 <res 00000010>      <1> 	p.link:	 resb nproc
    59 0000B544 <res 00000010>      <1> 	p.stat:	 resb nproc
    60                              <1> 
    61                              <1> 	; 06/05/2015 (Retro UNIX 386 v1 fetaure only !) 
    62 0000B554 <res 00000040>      <1> 	p.upage: resd nproc ; Physical address of the process's
    63                              <1> 			    ; 'user' structure	
    64                              <1> 
    65                              <1> 
    66                              <1> P_SIZE	equ $ - process
    67                              <1> 
    68                              <1> 
    69                              <1> ; fsp table (original UNIX v1)
    70                              <1> ;
    71                              <1> ;Entry
    72                              <1> ;          15                                      0
    73                              <1> ;  1     |---|---------------------------------------|
    74                              <1> ;        |r/w|       i-number of open file           |
    75                              <1> ;        |---|---------------------------------------| 
    76                              <1> ;        |               device number               |
    77                              <1> ;        |-------------------------------------------|
    78                              <1> ;    (*) | offset pointer, i.e., r/w pointer to file |
    79                              <1> ;        |-------------------------------------------| 
    80                              <1> ;        |  flag that says    | number of processes  |
    81                              <1> ;        |   file deleted     | that have file open  |
    82                              <1> ;        |-------------------------------------------| 
    83                              <1> ;  2     |                                           |
    84                              <1> ;        |-------------------------------------------| 
    85                              <1> ;        |                                           |
    86                              <1> ;        |-------------------------------------------|
    87                              <1> ;        |                                           |
    88                              <1> ;        |-------------------------------------------|
    89                              <1> ;        |                                           |
    90                              <1> ;        |-------------------------------------------| 
    91                              <1> ;  3     |                                           | 
    92                              <1> ;        |                                           |  
    93                              <1> ;
    94                              <1> ; (*) Retro UNIX 386 v1 modification: 32 bit offset pointer 
    95                              <1> 
    96                              <1> 
    97                              <1> ; 15/04/2015
    98 0000B594 <res 000001F4>      <1> fsp:	 resb nfiles * 10 ; 11/05/2015 (8 -> 10)
    99 0000B788 <res 00000018>      <1> bufp:	 resd (nbuf+2) ; will be initialized 
   100 0000B7A0 <res 00000002>      <1> ii:	 resw 1
   101 0000B7A2 <res 00000002>      <1> idev:	 resw 1 ; device number is 1 byte in Retro UNIX 8086 v1 !
   102 0000B7A4 <res 00000002>      <1> cdev:    resw 1 ; device number is 1 byte in Retro UNIX 8086 v1 !
   103                              <1> ; 18/05/2015
   104                              <1> ; 26/04/2013 device/drive parameters (Retro UNIX 8086 v1 feature only!)
   105                              <1> ; 'UNIX' device numbers (as in 'cdev' and 'u.cdrv')
   106                              <1> ;	0 -> root device (which has Retro UNIX 8086 v1 file system)
   107                              <1> ; 	1 -> mounted device (which has Retro UNIX 8086 v1 file system)
   108                              <1> ; 'Retro UNIX 8086 v1' device numbers: (for disk I/O procedures)
   109                              <1> ;	0 -> fd0 (physical drive, floppy disk 1), physical drive number = 0
   110                              <1> ;	1 -> fd1 (physical drive, floppy disk 2), physical drive number = 1
   111                              <1> ;	2 -> hd0 (physical drive, hard disk 1), physical drive number = 80h
   112                              <1> ;	3 -> hd1 (physical drive, hard disk 2), physical drive number = 81h
   113                              <1> ;	4 -> hd2 (physical drive, hard disk 3), physical drive number = 82h
   114                              <1> ;	5 -> hd3 (physical drive, hard disk 4), physical drive number = 83h
   115 0000B7A6 <res 00000001>      <1> rdev:	 resb 1 ; root device number ; Retro UNIX 8086 v1 feature only!
   116                              <1> 	        ; as above, for physical drives numbers in following table
   117 0000B7A7 <res 00000001>      <1> mdev:	 resb 1 ; mounted device number ; Retro UNIX 8086 v1 feature only!
   118                              <1> ; 15/04/2015
   119 0000B7A8 <res 00000001>      <1> active:	 resb 1 
   120 0000B7A9 <res 00000001>      <1> 	 resb 1 ; 09/06/2015
   121 0000B7AA <res 00000002>      <1> mnti:	 resw 1
   122 0000B7AC <res 00000002>      <1> mpid:	 resw 1
   123 0000B7AE <res 00000002>      <1> rootdir: resw 1
   124                              <1> ; 14/02/2014
   125                              <1> ; Major Modification: Retro UNIX 8086 v1 feature only!
   126                              <1> ;		      Single level run queue
   127                              <1> ;		      (in order to solve sleep/wakeup lock)
   128 0000B7B0 <res 00000002>      <1> runq:	 resw 1
   129 0000B7B2 <res 00000001>      <1> imod:	 resb 1
   130 0000B7B3 <res 00000001>      <1> smod:	 resb 1
   131 0000B7B4 <res 00000001>      <1> mmod:	 resb 1
   132 0000B7B5 <res 00000001>      <1> sysflg:	 resb 1
   133                              <1> 
   134 0000B7B6 <res 00000002>      <1> alignb 4
   135                              <1> 
   136                              <1> user:
   137                              <1> 	; 04/12/2015 
   138                              <1> 	; 18/10/2015
   139                              <1> 	; 12/10/2015
   140                              <1> 	; 21/09/2015
   141                              <1> 	; 24/07/2015
   142                              <1> 	; 16/06/2015
   143                              <1> 	; 09/06/2015
   144                              <1> 	; 11/05/2015
   145                              <1> 	; 16/04/2015 (Retro UNIX 386 v1 - 32 bit modifications)
   146                              <1> 	; 10/10/2013
   147                              <1> 	; 11/03/2013. 
   148                              <1> 	;Derived from UNIX v1 source code 'user' structure (ux).
   149                              <1> 	;u.
   150                              <1> 
   151 0000B7B8 <res 00000004>      <1> 	u.sp:	  resd 1 ; esp (kernel stack at the beginning of 'sysent')
   152 0000B7BC <res 00000004>      <1> 	u.usp:	  resd 1 ; esp (kernel stack points to user's registers)
   153 0000B7C0 <res 00000004>      <1> 	u.r0:	  resd 1 ; eax
   154 0000B7C4 <res 00000002>      <1> 	u.cdir:	  resw 1
   155 0000B7C6 <res 0000000A>      <1> 	u.fp:	  resb 10
   156 0000B7D0 <res 00000004>      <1> 	u.fofp:	  resd 1
   157 0000B7D4 <res 00000004>      <1> 	u.dirp:	  resd 1
   158 0000B7D8 <res 00000004>      <1> 	u.namep:  resd 1
   159 0000B7DC <res 00000004>      <1> 	u.off:	  resd 1
   160 0000B7E0 <res 00000004>      <1> 	u.base:	  resd 1
   161 0000B7E4 <res 00000004>      <1> 	u.count:  resd 1
   162 0000B7E8 <res 00000004>      <1> 	u.nread:  resd 1
   163 0000B7EC <res 00000004>      <1> 	u.break:  resd 1 ; break
   164 0000B7F0 <res 00000002>      <1> 	u.ttyp:	  resw 1 
   165 0000B7F2 <res 00000010>      <1> 	u.dirbuf: resb 16 ; 04/12/2015 (10 -> 16) 
   166                              <1> 	;u.pri:	  resw 1 ; 14/02/2014
   167 0000B802 <res 00000001>      <1> 	u.quant:  resb 1 ; Retro UNIX 8086 v1 Feature only ! (uquant)
   168 0000B803 <res 00000001>      <1> 	u.pri:	  resb 1 ; 
   169 0000B804 <res 00000002>      <1> 	u.intr:	  resw 1
   170 0000B806 <res 00000002>      <1> 	u.quit:	  resw 1
   171                              <1> 	;u.emt:	  resw 1 ; 10/10/2013
   172 0000B808 <res 00000002>      <1> 	u.ilgins: resw 1
   173 0000B80A <res 00000002>      <1> 	u.cdrv:	  resw 1 ; cdev
   174 0000B80C <res 00000001>      <1> 	u.uid:	  resb 1 ; uid
   175 0000B80D <res 00000001>      <1> 	u.ruid:	  resb 1
   176 0000B80E <res 00000001>      <1> 	u.bsys:	  resb 1
   177 0000B80F <res 00000001>      <1> 	u.uno:	  resb 1
   178 0000B810 <res 00000004>      <1>         u.upage:  resd 1 ; 16/04/2015 - Retro Unix 386 v1 feature only !
   179                              <1> 	; tty number (rtty, rcvt, wtty)
   180 0000B814 <res 00000001>      <1> 	u.ttyn:	  resb 1 ; 28/07/2013 - Retro Unix 8086 v1 feature only !
   181                              <1> 	; last error number
   182 0000B815 <res 00000004>      <1> 	u.error:  resd 1 ; 28/07/2013 - 09/03/2015 
   183                              <1> 		        ; Retro UNIX 8086/386 v1 feature only!
   184 0000B819 <res 00000004>      <1> 	u.pgdir:  resd 1 ; 09/03/2015 (page dir addr of process)
   185 0000B81D <res 00000004>      <1> 	u.ppgdir: resd 1 ; 06/05/2015 (page dir addr of the parent process)
   186 0000B821 <res 00000004>      <1> 	u.pbase:  resd 1 ; 20/05/2015 (physical base/transfer address)
   187 0000B825 <res 00000002>      <1> 	u.pcount: resw 1 ; 20/05/2015 (byte -transfer- count for page)
   188                              <1> 	;u.pncount: resw 1 
   189                              <1> 		; 16/06/2015 (byte -transfer- count for page, 'namei', 'mkdir')
   190                              <1> 	;u.pnbase:  resd 1 
   191                              <1> 		; 16/06/2015 (physical base/transfer address, 'namei', 'mkdir')
   192                              <1> 			 ; 09/06/2015
   193 0000B827 <res 00000001>      <1> 	u.kcall:  resb 1 ; The caller is 'namei' (dskr) or 'mkdir' (dskw) sign		
   194 0000B828 <res 00000001>      <1> 	u.brwdev: resb 1 ; Block device number for direct I/O (bread & bwrite)
   195                              <1> 			 ; 24/07/2015 - 24/06/2015
   196                              <1> 	;u.args:  resd 1 ; arguments list (line) offset from start of [u.upage]
   197                              <1> 			 ; (arg list/line is from offset [u.args] to 4096 in [u.upage])
   198                              <1> 			 ; ([u.args] points to argument count -argc- address offset)
   199                              <1>  			 ; 24/06/2015	  	
   200                              <1> 	;u.core:  resd 1 ; physical start address of user's memory space (for sys exec)
   201                              <1> 	;u.ecore: resd 1 ; physical end address of user's memory space (for sys exec)
   202                              <1> 			 ; 21/09/2015 (debugging - page fault analyze)
   203 0000B829 <res 00000004>      <1> 	u.pfcount: resd 1 ; page fault count for (this) process (for sys geterr)
   204                              <1> 
   205 0000B82D <res 00000003>      <1> alignb 4
   206                              <1> 
   207                              <1> U_SIZE	equ $ - user
   208                              <1> 
   209                              <1> ; 18/10/2015 - Retro UNIX 386 v1 (local variables for 'namei' and 'sysexec')
   210 0000B830 <res 00000004>      <1> pcore:  resd 1 ; physical start address of user's memory space (for sys exec)
   211 0000B834 <res 00000004>      <1> ecore:  resd 1 ; physical start address of user's memory space (for sys exec)
   212 0000B838 <res 00000004>      <1> nbase:	resd 1	; physical base address for 'namei' & 'sysexec'
   213 0000B83C <res 00000002>      <1> ncount: resw 1	; remain byte count in page for 'namei' & 'sysexec'
   214 0000B83E <res 00000002>      <1> argc:	resw 1	; argument count for 'sysexec'
   215 0000B840 <res 00000004>      <1> argv:	resd 1	; argument list (recent) address for 'sysexec'
   216                              <1> 
   217                              <1> ; 03/06/2015 - Retro UNIX 386 v1 Beginning
   218                              <1> ; 07/04/2013 - 31/07/2013 - Retro UNIX 8086 v1
   219 0000B844 <res 00000001>      <1> rw: 	 resb 1 ;; Read/Write sign (iget)
   220                              <1> 
   221                              <1> ;alignb 4
   222                              <1> 
   223                              <1> ; 22/08/2015
   224 0000B845 <res 00000820>      <1> buffer: resb nbuf * 520
   225                              <1> 
   226 0000C065 <res 00000008>      <1> sb0:	resd 2
   227                              <1> ;s:
   228                              <1> ; (root disk) super block buffer
   229                              <1> systm:
   230                              <1> 	; 13/11/2015 (Retro UNIX 386 v1)	
   231                              <1> 	; 11/03/2013. 
   232                              <1> 	;Derived from UNIX v1 source code 'systm' structure (ux).
   233                              <1> 	;s.
   234                              <1> 
   235 0000C06D <res 00000002>      <1> 	resw 1
   236 0000C06F <res 00000168>      <1> 	resb 360 ; 2880 sectors ; original UNIX v1 value: 128
   237 0000C1D7 <res 00000002>      <1> 	resw 1
   238 0000C1D9 <res 00000020>      <1> 	resb 32	 ; 256+40 inodes ; original UNIX v1 value: 64
   239 0000C1F9 <res 00000004>      <1> 	s.time:	 resd 1
   240 0000C1FD <res 00000004>      <1> 	s.syst:	 resd 1
   241 0000C201 <res 00000004>      <1>         s.wait_: resd 1 ; wait
   242 0000C205 <res 00000004>      <1> 	s.idlet: resd 1
   243 0000C209 <res 00000004>      <1> 	s.chrgt: resd 1
   244 0000C20D <res 00000002>      <1> 	s.drerr: resw 1
   245                              <1> 
   246                              <1> S_SIZE	equ $ - systm
   247                              <1> 
   248 0000C20F <res 0000005E>      <1> 	resb 512-S_SIZE ; 03/06/2015	 
   249                              <1> 
   250 0000C26D <res 00000008>      <1> sb1:	resd 2
   251                              <1> ; (mounted disk) super block buffer
   252                              <1> mount:	
   253 0000C275 <res 00000200>      <1> 	resb 512  ; 03/06/2015
   254                              <1> 
   255                              <1> ;/ ux -- unix
   256                              <1> ;
   257                              <1> ;systm:
   258                              <1> ;
   259                              <1> ;	.=.+2
   260                              <1> ;	.=.+128.
   261                              <1> ;	.=.+2
   262                              <1> ;	.=.+64.
   263                              <1> ;	s.time: .=.+4
   264                              <1> ;	s.syst: .=.+4
   265                              <1> ;	s.wait: .=.+4
   266                              <1> ;	s.idlet:.=.+4
   267                              <1> ;	s.chrgt:.=.+4
   268                              <1> ;	s.drerr:.=.+2
   269                              <1> ;inode:
   270                              <1> ;	i.flgs: .=.+2
   271                              <1> ;	i.nlks: .=.+1
   272                              <1> ;	i.uid:  .=.+1
   273                              <1> ;	i.size: .=.+2
   274                              <1> ;	i.dskp: .=.+16.
   275                              <1> ;	i.ctim: .=.+4
   276                              <1> ;	i.mtim: .=.+4
   277                              <1> ;	. = inode+32.
   278                              <1> ;mount:	.=.+1024.
   279                              <1> ;proc:
   280                              <1> ;	p.pid:  .=.+[2*nproc]
   281                              <1> ;	p.dska: .=.+[2*nproc]
   282                              <1> ;	p.ppid: .=.+[2*nproc]
   283                              <1> ;	p.break:.=.+[2*nproc]
   284                              <1> ;	p.link: .=.+nproc
   285                              <1> ;	p.stat: .=.+nproc
   286                              <1> ;tty:
   287                              <1> ;	. = .+[ntty*8.]
   288                              <1> ;fsp:	.=.+[nfiles*8.]
   289                              <1> ;bufp:	.=.+[nbuf*2]+6
   290                              <1> ;sb0:	.=.+8
   291                              <1> ;sb1:	.=.+8
   292                              <1> ;swp:	.=.+8
   293                              <1> ;ii:	.=.+2
   294                              <1> ;idev:	.=.+2
   295                              <1> ;cdev:	.=.+2
   296                              <1> ;deverr: .=.+12.
   297                              <1> ;active: .=.+2
   298                              <1> ;rfap:	.=.+2
   299                              <1> ;rkap:	.=.+2
   300                              <1> ;tcap:	.=.+2
   301                              <1> ;tcstate:.=.+2
   302                              <1> ;tcerrc: .=.+2
   303                              <1> ;mnti:	.=.+2
   304                              <1> ;mntd:	.=.+2
   305                              <1> ;mpid:	.=.+2
   306                              <1> ;clockp: .=.+2
   307                              <1> ;rootdir:.=.+2
   308                              <1> ;toutt:	.=.+16.
   309                              <1> ;touts: .=.+32.
   310                              <1> ;runq:	.=.+6
   311                              <1> ;
   312                              <1> ;wlist:	.=.+40.
   313                              <1> ;cc:	.=.+30.
   314                              <1> ;cf:	.=.+31.
   315                              <1> ;cl:	.=.+31.
   316                              <1> ;clist:	.=.+510.
   317                              <1> ;imod:	.=.+1
   318                              <1> ;smod:	.=.+1
   319                              <1> ;mmod:	.=.+1
   320                              <1> ;uquant: .=.+1
   321                              <1> ;sysflg: .=.+1
   322                              <1> ;pptiflg:.=.+1
   323                              <1> ;ttyoch: .=.+1
   324                              <1> ; .even
   325                              <1> ; .=.+100.; sstack:
   326                              <1> ;buffer: .=.+[ntty*140.]
   327                              <1> ;	.=.+[nbuf*520.]
   328                              <1> ;
   329                              <1> ; . = core-64.
   330                              <1> ;user:
   331                              <1> ;	u.sp:    .=.+2
   332                              <1> ;	u.usp:   .=.+2
   333                              <1> ;	u.r0:    .=.+2
   334                              <1> ;	u.cdir:  .=.+2
   335                              <1> ;	u.fp:    .=.+10.
   336                              <1> ;	u.fofp:  .=.+2
   337                              <1> ;	u.dirp:  .=.+2
   338                              <1> ;	u.namep: .=.+2
   339                              <1> ;	u.off:   .=.+2
   340                              <1> ;	u.base:  .=.+2
   341                              <1> ;	u.count: .=.+2
   342                              <1> ;	u.nread: .=.+2
   343                              <1> ;	u.break: .=.+2
   344                              <1> ;	u.ttyp:  .=.+2
   345                              <1> ;	u.dirbuf:.=.+10.
   346                              <1> ;	u.pri:   .=.+2
   347                              <1> ;	u.intr:  .=.+2
   348                              <1> ;	u.quit:  .=.+2
   349                              <1> ;	u.emt:   .=.+2
   350                              <1> ;	u.ilgins:.=.+2
   351                              <1> ;	u.cdev:  .=.+2
   352                              <1> ;	u.uid:   .=.+1
   353                              <1> ;	u.ruid:  .=.+1
   354                              <1> ;	u.bsys:  .=.+1
   355                              <1> ;	u.uno:   .=.+1
   356                              <1> ;. = core
  2505                                  
  2506                                  ;; Memory (swap) Data (11/03/2015)
  2507                                  ; 09/03/2015
  2508 0000C475 <res 00000002>          swpq_count: resw 1 ; count of pages on the swap queue
  2509 0000C477 <res 00000004>          swp_drv:    resd 1 ; logical drive description table address of the swap drive/disk
  2510 0000C47B <res 00000004>          swpd_size:  resd 1 ; size of swap drive/disk (volume) in sectors (512 bytes). 		  				
  2511 0000C47F <res 00000004>          swpd_free:  resd 1 ; free page blocks (4096 bytes) on swap disk/drive (logical)
  2512 0000C483 <res 00000004>          swpd_next:  resd 1 ; next free page block
  2513 0000C487 <res 00000004>          swpd_last:  resd 1 ; last swap page block	
  2514                                  
  2515 0000C48B <res 00000001>          alignb 4
  2516                                  
  2517                                  ; 10/07/2015
  2518                                  ; 28/08/2014
  2519 0000C48C <res 00000004>          error_code:	resd 1
  2520                                  ; 29/08/2014
  2521 0000C490 <res 00000004>          FaultOffset: 	resd 1
  2522                                  ; 21/09/2015
  2523 0000C494 <res 00000004>          PF_Count:	resd 1	; total page fault count
  2524                                  		       	; (for debugging - page fault analyze)
  2525                                  		 	; 'page_fault_handler' (memory.inc)
  2526                                  			; 'sysgeterr' (u9.s)
  2527                                  ;; 21/08/2015
  2528                                  ;;buffer: resb (nbuf*520) ;; sysdefs.inc, ux.s
  2529                                  ;; ((NOTE: nbuf = 6, buffer r/w problem/bug here !? when nbuf > 4))
  2530                                  
  2531                                  bss_end:
  2532                                  
  2533                                  ; 27/12/2013
  2534                                  _end:  ; end of kernel code
