%TITLE          "Pc Directory to XL/XE .ATR Disk Image File Creator - CHiPS bv 1998"
;**********************************************************************
;**                                                                  **
;**  Program   : D_SPARTA (v05.06.00)                                **
;**  Purpose   : Pc Directory to XL/XE .ATR Disk Image Creator       **
;**                                                                  **
;**  Author    : B.F. Schreurs                                       **
;**              Computer High Performance Software (CHiPS) bv       **
;**  Date      : November 12th, 1998                                 **
;**                                                                  **
;**  Calls     : APPEND   - Glue 2 strings together                  **
;**              APPENDX  - Glue 2 strings together using "\" target **
;**              DC_DIRS  - Determine Current Directories            **
;**              DC_FILES - Determine Current Files                  **
;**              FMSIO    - File Management System Handler           **
;**              HEX2DIGI - Convert Hex Data To Digits (Text)        **
;**              WSIO     - Screen Handler                           **
;**                                                                  **
;**  Parameter : 1. Pass the address of the directory path where the **
;**                 files reside to be placed on an ATR disk image.  **
;**                 Size is PATH_LENGTH.                             **
;**  Parameter : 2. Pass the address of the directory path where the **
;**                 ATR disk image(s) will be stored.                **
;**                 Size is PATH_LENGTH.                             **
;**  Parameter : 3. Pass the address of the Disk format to use       **
;**                 Size is 1                                        **
;**  Parameter : 4. Pass the address of the Disk density to use      **
;**                 Size is 1                                        **
;**  Parameter : 5. Pass the address of the Create ATR or XFD disk   **
;**                 Size is 1                                        **
;**  Parameter : 6. Pass the address of the SpartaDos DOS path       **
;**                 Size is PATH_LENGTH.                             **
;**  Parameter : 7. Pass the address of the DOS included YN field    **
;**                 Size is 1                                        **
;**  Parameter : 8. Pass the address of the MAIN DIR usage YN field  **
;**                 Size is 1                                        **
;**  Parameter : 9. Pass the address of the Dir_Map Segment          **
;**                 Size is Dir_Map_Length                           **
;**  Parameter :10. Pass the address of the usage of a CLI           **
;**                 Size is 1                                        **
;**  Parameter :11. Pass the address of including subdirs Yes or No  **
;**                 Size is 1                                        **
;**                                                                  **
;**  Language  : Turbo Assembler                                     **
;**                                                                  **
;**********************************************************************
        IDEAL
        JUMPS

;----------------------------------------------------------------------
;--  Functions which can be called                                   --
;----------------------------------------------------------------------
        PUBLIC  D_SPARTA

;----------------------------------------------------------------------
;--  Equates                                                         --
;----------------------------------------------------------------------
include ".\equ\attrib.equ"
include ".\equ\dos.equ"
include ".\equ\fmsio.equ"
include ".\equ\keyboard.equ"
include ".\equ\sysdep.equ"
include ".\equ\video.equ"
include ".\equ\wsio.equ"

EXTRA_TABLE_FIELDS                      EQU     16

EIGHTBIT_VTOC_ENTRY_SIZE                EQU     23
EIGHTBIT_VTOC_ENTRY_DIRECTORY           EQU     40
EIGHTBIT_VTOC_ENTRY_FILE                EQU      8
EIGHTBIT_FILE_NAME_LENGTH               EQU     11
DISK_VOLUME_NAME_LENGTH                 EQU      8
SECTOR_OFFSET_LINK_SECTOR_START         EQU      4
NR_OF_SECTORS_PER_BITMAP_BYTE           EQU      8
RESERVE_NR_OF_SECTORS_VTOC_SPACE        EQU      2

EIGHTBIT_SECTOR_SIZE                    EQU    128
EIGHTBIT_SECTOR_SIZE_DOUBLE             EQU    256

PC_DATE_YEAR_OFFSET                     EQU     80      ; Year 1980 for Pc date

ATR_HEADER_SIZE                         EQU     16
MINIMUM_NR_OF_VTOC_SECTORS              EQU     12
MINIMUM_NR_OF_VTOC_SECTORS_DOUBLE       EQU      6
LINK_SECTOR_POINTER_SIZE                EQU      2
DIR_NR_CURR                             EQU      2
DIR_NR_FROM                             EQU      2
WS_E2_ERROR_MESSAGE_SIZE                EQU     40

DIR_ENTRY_FILES_MAX_SPARTADOS           EQU    126
DIR_ENTRY_FILES_MAX_SPARTADOSX          EQU   1024
DIR_ENTRY_FILES_MAX_BEWEDOS             EQU   1424

SECTOR_COUNT_LINK_SECTOR_SINGLE         EQU     62
SECTOR_COUNT_LINK_SECTOR_DOUBLE         EQU    126

DIR_MAP_LENGTH                          EQU ( MAX_DIRS_AND_FILES + EXTRA_TABLE_FIELDS ) * DIR_ENTRY_LENGTH
FILE_MAP_LENGTH                         EQU   MAX_FILES * FILE_ENTRY_LENGTH
PC_DIR_MAP_ENTRY_LENGTH                 EQU   PATH_LENGTH + DIR_NR_CURR + DIR_NR_FROM + LINK_SECTOR_POINTER_SIZE
PC_DIR_MAP_OFFSET_DIR_FROM              EQU   PATH_LENGTH + DIR_NR_CURR
PC_DIR_MAP_OFFSET_LINK_SECTOR           EQU   PATH_LENGTH + DIR_NR_CURR + DIR_NR_FROM
PC_DIR_MAP_LENGTH                       EQU   MAX_DIRS * PC_DIR_MAP_ENTRY_LENGTH
VTOC_MAP_LENGTH                         EQU   DIR_ENTRY_FILES_MAX_BEWEDOS * EIGHTBIT_VTOC_ENTRY_SIZE
BITMAP_BUFFER_LENGTH                    EQU   32 * EIGHTBIT_SECTOR_SIZE_DOUBLE

DISK_BOOTCODE_SIZE                      EQU    384
DISK_BOOTCODE_SECTOR_SIZE               EQU      3
;---------------------------
DISK_MEDIA_TYPE_SINGLE                  EQU     "S"
DISK_SECTORS_SINGLE                     EQU    720
;---------------------------
DISK_MEDIA_TYPE_MEDIUM                  EQU     "M"
DISK_SECTORS_MEDIUM                     EQU   1040
;---------------------------
DISK_MEDIA_TYPE_DOUBLE                  EQU     "D"
DISK_SECTORS_DOUBLE                     EQU    720
;---------------------------
DISK_MEDIA_TYPE_QUAD                    EQU     "Q"
DISK_SECTORS_QUAD                       EQU   1440
;---------------------------
DISK_MEDIA_TYPE_720KB                   EQU     "7"
DISK_SECTORS_720KB                      EQU   2880
;---------------------------
DISK_MEDIA_TYPE_1440KB                  EQU     "1"
DISK_SECTORS_1440KB                     EQU   5760
;---------------------------
DISK_MEDIA_TYPE_HARDDISK                EQU     "H"
DISK_SECTORS_HARDDISK                   EQU  65535
;---------------------------

DISK_FORMAT_BEWEDOS                     EQU     "B"
DISK_FORMAT_SPARTADOS                   EQU     "S"
DISK_FORMAT_SPARTADOSX                  EQU     "X"
DISK_FORMAT_MYOWNDOS                    EQU     "Y"

;
; SpartaDos specific stuff
;
BOOTCODE_OFFSET_MAIN_DIR_LINK_SECTOR    EQU      9
BOOTCODE_OFFSET_SECTORS_ON_DISK         EQU     11
BOOTCODE_OFFSET_FREE_SECTORS            EQU     13
BOOTCODE_OFFSET_NR_OF_BITMAPS           EQU     15
BOOTCODE_OFFSET_FIRST_BITMAP_SECTOR     EQU     16
BOOTCODE_OFFSET_FIRST_FREE_DATA_SECTOR  EQU     18
BOOTCODE_OFFSET_FIRST_FREE_DIR_SECTOR   EQU     20
BOOTCODE_OFFSET_VOLUME_NAME             EQU     22
BOOTCODE_OFFSET_SIZE_OF_SECTOR          EQU     31
BOOTCODE_OFFSET_DOS_BOOT_SECTOR         EQU     40

;**********************************************************************
SEGMENT SSeg Para Stack 'STACK'
;**********************************************************************

        db       256 dup (0)            ; Stack

ENDS    SSeg

;**********************************************************************
SEGMENT DSeg Word Public 'DATA'
;**********************************************************************

;----------------------------------------------------------------------
;--  Structures                                                      --
;----------------------------------------------------------------------
include ".\str\direntry.str"
include ".\str\dta.str"
include ".\str\fmsio.str"
include ".\str\position.str"
include ".\str\wsio.str"

;----------------------------------------------------------------------
;--  SELECT and FD                                                   --
;----------------------------------------------------------------------
;
; Atari Disk Image
;
ATARI____File                   FMS_Area <>
ATARI____Pathname               DB  PATH_LENGTH        dup (SPACE)
                                DB    1 dup (0)

;
; Extracted Atari Disk Image (pc) File
;
PC_ATARI_File                   FMS_Area <>
PC_ATARI_Pathname               DB  PATH_LENGTH        dup (SPACE)
                                DB    1 dup (0)

;----------------------------------------------------------------------
;--  Working Storage                                                 --
;----------------------------------------------------------------------
GLOBAL Return_Code:Byte:1

Parm_Dir_From_ptr_es            DW    1 dup (NULL)
Parm_Dir_From_ptr_di            DW    1 dup (NULL)

Parm_Disk_To_ptr_es             DW    1 dup (NULL)
Parm_Disk_To_ptr_di             DW    1 dup (NULL)

Parm_DOS_Path_ptr_es            DW    1 dup (NULL)
Parm_DOS_Path_ptr_di            DW    1 dup (NULL)

Parm_INCLUDE_DOS_ptr_es         DW    1 dup (NULL)
Parm_INCLUDE_DOS_ptr_di         DW    1 dup (NULL)

Parm_MAIN_DIR_ptr_es            DW    1 dup (NULL)
Parm_MAIN_DIR_ptr_di            DW    1 dup (NULL)

Parm_Dir_Map_ptr_es             DW    1 dup (NULL)
Parm_Dir_Map_ptr_di             DW    1 dup (NULL)

Parm_CLI_Used_ptr_es            DW    1 dup (NULL)
Parm_CLI_Used_ptr_di            DW    1 dup (NULL)

Parm_InclDirs_ptr_es            DW    1 dup (NULL)
Parm_InclDirs_ptr_di            DW    1 dup (NULL)

CLI_Used                        DB    LOGIC_NO
CLI_Include_Subdirs             DB    LOGIC_NO

Disk_Present                    DB    LOGIC_NO

SpartaDos_Date_YY               DB    0
SpartaDos_Date_MM               DB    0
SpartaDos_Date_DD               DB    0
SpartaDos_Time_HH               DB    0
SpartaDos_Time_MM               DB    0

Include_DOS_Files               DB    LOGIC_NO
Too_Many_Files_In_Dir           DB    LOGIC_NO
Disk_Image_Not_Large_Enough     DB    LOGIC_NO
Dir_Entry_Fits_On_Image         DB    LOGIC_NO
Parm_XFD_Format                 DB    LOGIC_NO
Dir2atr_Error                   DB    LOGIC_NO          ; 0=No Error
                                                        ; 1=Error Encountered
Atari_File_Name_Invalid_Char    DB    KEY_VALID_DOS     ; Translate to "_"
                                DB    NULL

Disk_Media_Type                 DB    DISK_MEDIA_TYPE_SINGLE    ; Supported Densities: "S"=Singe, "M"=Medium, "D"=Double, "Q"=Quad, "7"=720 KB, "1"=1.44 MB, "H"=Harddisk 16 MB
Disk_Format                     DB    DISK_FORMAT_SPARTADOS     ; Supported DOS format types: "D"=DOS 2.5, "M"=MYDOS 4.53, "O"=User's DOS - MYDOS format, "B"=BEWEDOS, "S"=SPARTADOS 3.3a, "X"=SPARTADOS/X, "Y"=User's DOS - SPARTADOS format

Requested_Format_LibFil         DB   "1"                ; 1 = DIRENTRY format    etc.
                                                        ; 2 = "..           <DIR>      "
                                                        ;     "ATARI        <DIR>      "

Media_Id_Buffer                 DB   25                 dup (NULL)
Search_Dirs_Path                DB  PATH_LENGTH         dup (SPACE)
                                DB  NULL                ; To satisfy DOS find file
Search_Filemask                 DB  FILE_NAME_LENGTH    dup (SPACE)
PC_ATARI_DOS_Pathname           DB  PATH_LENGTH         dup (SPACE)
                                DB  NULL

Dir_SPARTADOS                   DB   "SPARTA\      "
Dir_SPARTADOSX                  DB   "SPARTAX\     "
Dir_BEWEDOS                     DB   "BEWEDOS\     "
Dir_MYOWNDOS                    DB   "MYOWNDOS\    "

File_Name_BOOTCODE              DB   "BOOTCODE     "
File_Name_DOS_SYS               DB   "DOS.SYS      "

Sectors_Per_Progress_Bar        DW    ? 

Main_Directory_Name             DB   "MAIN\        "
Root_Directory_Name             DB   "Root\        "

Rewrite_Curr_Dir_VTOC_Size      DW    ?
Rewrite_Coming_From_Dir_ptr     DW    ?

Path_Spec                       DB   PATH_LENGTH dup (SPACE)
File_Map_Entry                  Dir_Entry <>
Save_File_Map_Entry             Dir_Entry <>

VTOC_Map_Entry_Nr               DW    0

Dir_Entry_Files                 DW    0
Dir_Entry_File_Size             DW    0
Dir_Entry_ptr_es                DW    1 dup (NULL)
Dir_Entry_ptr_di                DW    1 dup (NULL)
Save_ptr_es                     DW    1 dup (NULL)
Save_ptr_di                     DW    1 dup (NULL)

Ws_CF_Progress_Bar_Cnt_Prev             DB    0
Ws_CF_Progress_Bar_Cnt_Max              DB   32
Ws_CF_Progress_Bar_Cnt_Sectors_Hi       DW    0
Ws_CF_Progress_Bar_Cnt_Sectors_Lo       DW    0
Ws_CF_Progress_Bar_Sectors_Hi           DW    0
Ws_CF_Progress_Bar_Sectors_Lo           DW    0

Ws_FF_Progress_Bar_Cnt_Prev             DB    0
Ws_FF_Progress_Bar_Cnt_Max              DB   34
Ws_FF_Progress_Bar_Cnt_Sectors          DW    0
Ws_FF_Progress_Bar_Sectors              DW    0

Disk_Sector_Size                DW    ?

ATR_Header                      DB   096h,002h,080h,020h,080h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
ATR_Header_Single               DB   096h,002h,080h,016h,080h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
ATR_Header_Medium               DB   096h,002h,080h,020h,080h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
ATR_Header_Double               DB   096h,002h,0E8h,02Ch,000h,001h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
ATR_Header_Quad                 DB   096h,002h,000h,05Ah,000h,001h,000h,000h,000h,000h,000h,000h,000h,000h,000h,001h
ATR_Header_720KB                DB   096h,002h,000h,0B4h,000h,001h,000h,000h,000h,000h,000h,000h,000h,000h,000h,001h
ATR_Header_1440KB               DB   096h,002h,000h,068h,000h,001h,001h,000h,000h,000h,000h,000h,000h,000h,000h,001h
ATR_Header_Harddisk             DB   096h,002h,0F0h,0FFh,000h,001h,00Fh,000h,000h,000h,000h,000h,000h,000h,000h,001h

Last_Sector_In_Bitmap           DW    0

Disk_Name                       DB  "        "
                                DB  ".ATR"
Disk_Seq_Nr                     DW    0
Disk_Seq_Nr_Present             DW    0

Passed_Parameters               DB  PATH_LENGTH dup (0)

Disk_Mask                       DB   "*.ATR       "
File_Mask                       DB   "*.*         "
ATR_Disk_Image_Open             DB    1 dup (FALSE)
File_Size_In_Bytes_Hi           DW     0
File_Size_In_Bytes_Lo           DW     0
File_Size_In_Sectors            DW     0
Max_File_Size_In_Sectors        DW     0
VTOC_Size_In_Sectors            DW     0
VTOC_Sectors_To_Write           DW     0

Disk_Sector_Start               DW     4
Disk_Sector_Current             DW     4
Disk_Sector_Bitmap_Current      DW     4
Disk_Sector_VTOC_Current        DW    18

Disk_Sectors                    DW     0
Disk_Sectors_Usable             DW     0
Disk_Sectors_Left               DW     0
Disk_Sectors_Available          DW     0
Disk_Sectors_Free               DW     0
Disk_Sectors_VTOC               DW     0
Disk_Sectors_Bitmap             DW     0
Disk_Sectors_Calculated         DW     0

Sector_Counter                  DW     0                        ; Count in 128 bytes per sector
Sector_Counter_VTOC             DW     0                        ; Count in 128 bytes per sector
Dir_Dir_Counter                 DW     0
Dir_File_Counter                DW     0
Dir_Dir_File_Counter_Max        DW     0

Disk_Link_Sector_Current        DW     0
Disk_Link_Sector_Next           DW     0
Disk_Link_Sector_Prev           DW     0
Sector_Count_Link_Sector        DB     0
Sector_Offset_Link_Sector       DB     0

Old_Dta_Seg                     DW    ?                 ; Old Dta Segment Address
Old_Dta_Ofs                     DW    ?                 ; Old Dta Segment Offset
Own_Dta                         Dta <>

Disk_I_O_Buffer                 DB  EIGHTBIT_SECTOR_SIZE_DOUBLE dup (0)
Disk_Bitmap_Buffer              DB  BITMAP_BUFFER_LENGTH        dup (0)
Disk_Link_Sector_Buffer         DB  EIGHTBIT_SECTOR_SIZE_DOUBLE dup (0)

Remainder_Bytes                 DW     0

; Continue adding disks after highest disk number found? N=NO Y=YES
Disk_Adding                     DB  "N"

Bootcode_Data                   DB  EIGHTBIT_SECTOR_SIZE dup (0)
                                DB  EIGHTBIT_SECTOR_SIZE dup (0)
                                DB  EIGHTBIT_SECTOR_SIZE dup (0)

Dir_Curr_ptr                    DW    0
Dir_To_ptr                      DW    0

VTOC_Map_ptr_es                 DW    1 dup (NULL)      ; Segment 3
VTOC_Map_ptr_di                 DW    1 dup (NULL)

Pc_Dir_Map_ptr_es               DW    1 dup (NULL)      ; Segment 4
Pc_Dir_Map_ptr_di               DW    1 dup (NULL)



;----------------------------------------------------------------------
;--                                                                  --
;-- G e n e r a l   D i s k   I m a g e   L a y o u t                --
;--                                                                  --
;----------------------------------------------------------------------
;
;       +---------------------------------------------------------------+
;       ³    1 Boot sector (always 128 bytes/sector)                    ³
;       ³   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   ³
;       ³    pos. thru description                                      ³
;       ³     7        hex 80, indentifies SpartaDos                    ³
;       ³     9    10  sector link sector of "main" directory           ³
;       ³              "0500" means sector 5                            ³
;       ³    11    12  nr of sectors on disk                            ³
;       ³    13    14  nr of free sectors                               ³
;       ³    15        nr of bitmap sectors                             ³
;       ³    16    17  sector nr of 1st bitmap sector                   ³
;       ³    18    19  1st free data sector nr                          ³
;       ³    20    21  1st free directory sector nr                     ³
;       ³    22    29  volume name                                      ³
;       ³    31        disk sector size                                 ³
;       ³              128 bytes/sector = hex 80 = decimal 128          ³
;       ³              256 bytes/sector = hex 00 = decimal   0          ³
;       ³    32        disk format version                              ³
;       ³              SpartaDOS version 1.x = hex 11 = decimal 17      ³
;       ³              SpartaDOS version 2.x = hex 20 = decimal 32      ³
;       ³              BeWe-DOS can only access disks formatted with    ³
;       ³              SpartaDOS 2.x and up                             ³
;       ³    33    37  Reserved for different SpartaDOS versions        ³
;       ³    38        Sequential number of the disk, which is          ³
;       ³              incremented when making changes to the disk      ³
;       ³              when you're using BeWe-DOS                       ³
;       ³    39        Random number of the disk. This number is        ³
;       ³              created while formatting the disk                ³
;       ³    40    41  DOS boot start at sector nr                      ³
;       ³    42    47  Reserved for different SpartaDOS versions        ³
;       ³...............................................................³
;       ³    2 remaining Boot sectors (always 128 bytes/sector)         ³
;       +---------------------------------------------------------------+
;       ³    1 thru 32 Bitmap sectors                                   ³
;       ³   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   ³
;       ³    disk      sector  sector   bitmap    disk                  ³
;       ³    type       count    size  sectors    size                  ³
;       ³    single       720     128        1      92 KB               ³
;       ³    medium     1,040     128        1     133 KB               ³
;       ³    double       720     256        1     184 KB               ³
;       ³    quad       1,440     256        1     368 KB               ³
;       ³    720 KB     2,880     256        2     720 KB               ³
;       ³    1.44 MB    5,760     256        2    1.44 MB               ³
;       ³    harddisk  65,535     256       32      16 MB               ³
;       +---------------------------------------------------------------+
;       ³    n number of VTOC sectors                                   ³
;       ³   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   ³
;       ³    VTOC sector                                                ³
;       ³ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ³
;       ³       .       contains n VTOC entries                       . ³
;       ³ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ³
;       ³       .       sector link sector                            . ³
;       ³       .              contains  62 sectors pointers          . ³
;       ³       .                       for single density            . ³
;       ³       .              or       126 sectors pointers          . ³
;       ³       .                       for double density            . ³
;       ³       ./////////////////////////////////////////////////////. ³
;       ³       .       pos.  description                             . ³
;       ³       .        1    sector nr of next link sector           . ³
;       ³       .        3    sector nr of prev link sector           . ³
;       ³       .        5    vtoc link sector nr   1                 . ³
;       ³       .        7    vtoc link sector nr   2                 . ³
;       ³       .      nnn    vtoc link sector nr ...                 . ³
;       ³       .      126    vtoc link sector nr  62                 . ³
;       ³       .   or 254    vtoc link sector nr 126                 . ³
;       ³       ....................................................... ³
;       ³       .       VTOC data sector(s)                           . ³
;       ³       ....................................................... ³
;       ³       .       sector link sector                            . ³
;       ³       ./////////////////////////////////////////////////////. ³
;       ³       .       pos.  description                             . ³
;       ³       .        1    sector nr of next link sector           . ³
;       ³       .        3    sector nr of prev link sector           . ³
;       ³       .        5    vtoc link sector nr   1                 . ³
;       ³       .        7    vtoc link sector nr   2                 . ³
;       ³       .      nnn    vtoc link sector nr ...                 . ³
;       ³       .      126    vtoc link sector nr  62                 . ³
;       ³       .   or 254    vtoc link sector nr 126                 . ³
;       ³       ....................................................... ³
;       ³       .       VTOC data sector(s), etc.                     . ³
;       ³       .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  . ³
;       ³       .       SpartaDOS   supports a maximum of  126 entries. ³
;       ³       .        .          per directory                     . ³
;       ³       .       SpartaDOS/X supports a maximum of 1024 entries. ³
;       ³       .        .          per directory                     . ³
;       ³       .       BeWe-DOS    supports a maximum of 1424 entries. ³
;       ³       .        .          per directory                     . ³
;       ³       ./////////////////////////////////////////////////////. ³
;       ³       .        .       VTOC very first entry                . ³
;       ³       .        .............................................. ³
;       ³       .        .       pos.  description                    . ³
;       ³       .        .        1    Status byte                    . ³
;       ³       .        .             hex 28 indicates dir entry     . ³
;       ³       .        .             bit settings: "00101000"       . ³
;       ³       .        .                              ³³³  ³        . ³
;       ³       .        .             Directory entry--+³³  ³        . ³
;       ³       .        .             Deleted entry  ---+³  ³        . ³
;       ³       .        .             Active entry   ----+  ³        . ³
;       ³       .        .             File protected -------+        . ³
;       ³       .        .             "0"=False, "1"=True            . ³
;       ³       .        .        2    sector nr of previous dir      . ³
;       ³       .        .        4    VTOC directory size in bytes   . ³
;       ³       .        .        7    directory name                 . ³
;       ³       .        .       18    hex 00 00 00 00 00 00          . ³
;       ³       .        .////////////////////////////////////////////. ³
;       ³       .        .       VTOC entry directory                 . ³
;       ³       .        .............................................. ³
;       ³       .        .       pos.  description                    . ³
;       ³       .        .        1    Status byte                    . ³
;       ³       .        .             hex 28 indicates dir entry     . ³
;       ³       .        .             bit settings: "00101000"       . ³
;       ³       .        .        2    sector nr of dir VTOC sector   . ³
;       ³       .        .        4    hex 00 00 00                   . ³
;       ³       .        .        7    directory name                 . ³
;       ³       .        .       18    date/time stamp                . ³
;       ³       .        .////////////////////////////////////////////. ³
;       ³       .        .       VTOC entry file                      . ³
;       ³       .        .............................................. ³
;       ³       .        .       pos.  description                    . ³
;       ³       .        .        1    Status byte                    . ³
;       ³       .        .             hex 08 indicates file entry    . ³
;       ³       .        .             bit settings: "00001000"       . ³
;       ³       .        .        2    sector nr where data starts    . ³
;       ³       .        .        4    file size (3 bytes)            . ³
;       ³       .        .             hex    28 33 00                . ³
;       ³       .        .             means size is hex 003328       . ³
;       ³       .        .                        is dec  13096 bytes . ³
;       ³       .        .        7    file name                      . ³
;       ³       .        .       18    date/time stamp (6 bytes)      . ³
;       ³       .        .             hex    0D 09 62 14 22 00       . ³
;       ³       .        .             format dd mm yy hh mm          . ³
;       ³       .        .             means  13/09/98  8:34p         . ³
;       ³       .        .             hh is a 24 hour clock          . ³
;       +---------------------------------------------------------------+
;       ³    n number of File sectors                                   ³
;       ³   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   ³
;       ³    File sector                                                ³
;       ³ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ³
;       ³       .       sector link sector                            . ³
;       ³       .              contains  62 sectors pointers          . ³
;       ³       .                       for single density            . ³
;       ³       .              or       126 sectors pointers          . ³
;       ³       .                       for double density            . ³
;       ³       ./////////////////////////////////////////////////////. ³
;       ³       .       pos.  description                             . ³
;       ³       .        1    sector nr of next link sector           . ³
;       ³       .        3    sector nr of prev link sector           . ³
;       ³       .        5    data link sector nr   1                 . ³
;       ³       .        7    data link sector nr   2                 . ³
;       ³       .      nnn    data link sector nr ...                 . ³
;       ³       .      126    data link sector nr  62                 . ³
;       ³       .   or 254    data link sector nr 126                 . ³
;       ³       ....................................................... ³
;       ³       .       data sector(s)                                . ³
;       ³       ....................................................... ³
;       ³       .       sector link sector                            . ³
;       ³       ./////////////////////////////////////////////////////. ³
;       ³       .       pos.  description                             . ³
;       ³       .        1    sector nr of next link sector           . ³
;       ³       .        3    sector nr of prev link sector           . ³
;       ³       .        5    data link sector nr  63 or 127          . ³
;       ³       .        7    data link sector nr  64 or 128          . ³
;       ³       .      nnn    data link sector nr ... or ...          . ³
;       ³       .      126    data link sector nr 124 or 188          . ³
;       ³       .   or 254    data link sector nr        252          . ³
;       ³       ....................................................... ³
;       ³       .       data sector(s), etc.                          . ³
;       +---------------------------------------------------------------+



;----------------------------------------------------------------------
;--                                                                  --
;--  S C R E E N S   S E C T I O N                                   --
;--                                                                  --
;----------------------------------------------------------------------
Filler                  DB   16 dup (" ")

;**********************************************************************
; I n c l u d e   S u b d i r e c t o r i e s   ( S p a r t a D o s ) *
;**********************************************************************
Ws_IS                   DB    WSIO_OPEN
                        DB    8                 ; Start of screen ROW
                        DB   31                 ; Start of screen COLUMN
                        DB   18                 ; End of screen ROW
                        DB   77                 ; End of screen COLUMN
                        DB    ATTRIB_GREEN_WHITE ; Screen attribute
                        DB    ATTRIB_BLUE_WHITE ; Field attribute
                        DB    ATTRIB_BLUE_WHITE ; Input attribute
                        DB    0                 ; Error attribute
                        DB    1                 ; Mouse support
                        DB    0                 ; Locate cursor at field
                        DB    0                 ; Locate cursor at occurrence
                        DB    0                 ; Locate cursor at position
                        DB    LOGIC_NO          ; Screen not changed
                        DB    0                 ; Go to first          
                        DB    0                 ; modifiable field
                        DW    ?                 ; Screen Name Address HIGH
                        DW    ?                 ; Screen Name Address LOW
                        DW    ?                 ; Text        Address HIGH
                        DW    ?                 ; Text        Address LOW
                        DW    NULL              ; Attribute   Address HIGH
                        DW    NULL              ; Attribute   Address LOW
                        DW    ?                 ; Valid Keys  Address HIGH
                        DW    ?                 ; Valid Keys  Address LOW
                        DW    ?                 ; Enter Keys  Address HIGH
                        DW    ?                 ; Enter Keys  Address LOW
                        DW    ?                 ; Field Area  Address HIGH
                        DW    ?                 ; Field Area  Address LOW
Ws_IS_Name              DB    "SUBDIRS "
Ws_IS_Keys              DB    KEY_ESC, KEY_ENTER
                        DB    NULL
;                                       1         2         3         4         5         6         7         8
;                              ....5....0....5....0....5....0....5....0....5....0....5....0....5....0....5....0
Ws_IS_Text              DB                                  "ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ[Subdirectories]ÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»"
                        DB                                  "º                                             º"
                        DB                                  "º Process the (sub)directories as well?       º"
                        DB                                  "º                                             º"
                        DB                                  "º  [ ] Y=Yes, all files and (sub)directories  º"
                        DB                                  "º             MUST fit on ONE disk image!!!   º"
                        DB                                  "º      N=No , if files don't fit on one disk, º"
                        DB                                  "º             another disk will be created.   º"
                        DB                                  "º                                             º"
                        DB                                  "ºENTER=Specify   Esc=Cancel                   º"
                        DB                                  "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼"
                        DB    NULL
;------------
; F I E L D S
;------------
;
; Include (sub)directories or not (only for SpartaDos)
;
Ws_IS_F_Subdirs_Yes_No  DB    5                 ; Relative ROW, NULL=End
                        DB    5                 ; Relative COLUMN 
                        DB    1                 ; Field Size
                        DB    1                 ; Nr of occurrences
                        DW    0                 ; This is not a table
                        DB    1                 ; Modifiable
                        DB    KEY_ENTER         ; Emulate Enter
                        DB    0                 ; Edit External
                        DB    1                 ; Blanks Trailing
                        DB    0                 ; Uppercase
                        DB    0                 ; Backspace destructive
                        DB    0                 ; <Digits before dot>
                        DB    0                 ; <Digits after dot>
                        DB    0                 ; <Negative number option>
                        DB    0                 ; <Decimal point character>
                        DB    0                 ; <Date Time Format>
                        DB    LOGIC_NO          ; Field changed indicator
                        DW    ?                 ; Source Hi
                        DW    ?                 ; ...... Lo
                        DW    NULL              ; <Object Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Attrib Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Keys Hi>
                        DW    NULL              ; <.... Lo>

Ws_IS_F_Key_Enter       DB   10                 ; Relative ROW, NULL=End
                        DB    2                 ; Relative COLUMN 
                        DB   13                 ; Field Size
                        DB    1                 ; Nr of occurrences
                        DW    0                 ; This is not a table
                        DB    0                 ; Protected
                        DB    KEY_ENTER         ; Emulate Enter
                        DB    0                 ; Edit External
                        DB    0                 ; Blanks Anywhere
                        DB    0                 ; Uppercase
                        DB    0                 ; Backspace destructive
                        DB    0                 ; <Digits before dot>
                        DB    0                 ; <Digits after dot>
                        DB    0                 ; <Negative number option>
                        DB    0                 ; <Decimal point character>
                        DB    0                 ; <Date Time Format>
                        DB    LOGIC_NO          ; Field changed indicator
                        DW    ?                 ; Source Hi
                        DW    ?                 ; ...... Lo
                        DW    NULL              ; <Object Hi>
                        DW    NULL              ; <...... Lo>
                        DW    ?                 ; <Attrib Hi>
                        DW    ?                 ; <...... Lo>
                        DW    NULL              ; <Keys Hi>
                        DW    NULL              ; <.... Lo>

Ws_IS_F_Key_Esc         DB   10                 ; Relative ROW, NULL=End
                        DB   18                 ; Relative COLUMN 
                        DB   10                 ; Field Size
                        DB    1                 ; Nr of occurrences
                        DW    0                 ; This is not a table
                        DB    0                 ; Protected
                        DB    KEY_ESC           ; Emulate Enter
                        DB    0                 ; Edit External
                        DB    0                 ; Blanks Anywhere
                        DB    0                 ; Uppercase
                        DB    0                 ; Backspace destructive
                        DB    0                 ; <Digits before dot>
                        DB    0                 ; <Digits after dot>
                        DB    0                 ; <Negative number option>
                        DB    0                 ; <Decimal point character>
                        DB    0                 ; <Date Time Format>
                        DB    LOGIC_NO          ; Field changed indicator
                        DW    ?                 ; Source Hi
                        DW    ?                 ; ...... Lo
                        DW    NULL              ; <Object Hi>
                        DW    NULL              ; <...... Lo>
                        DW    ?                 ; <Attrib Hi>
                        DW    ?                 ; <...... Lo>
                        DW    NULL              ; <Keys Hi>
                        DW    NULL              ; <.... Lo>

Ws_IS_No_More_Fields    DB    NULL

;--------
; D A T A
;--------
Ws_IS_D_Subdirs_Yes_No  DB    SPACE

Yes_No_Field            DB   "YN"
                        DB    NULL

Ws_IS_D_Key_Enter       DB   "Enter=Specify"
Ws_IS_D_Key_Esc         DB   "Esc=Cancel"



;**********************************************************************
; S p a r t a D o s   V o l u m e n a m e                             *
;**********************************************************************
Ws_SV                   DB    WSIO_OPEN
                        DB   10                 ; Start of screen ROW
                        DB   32                 ; Start of screen COLUMN
                        DB   16                 ; End of screen ROW
                        DB   77                 ; End of screen COLUMN
                        DB    ATTRIB_GREEN_WHITE ; Screen attribute
                        DB    ATTRIB_BLUE_WHITE ; Field attribute
                        DB    ATTRIB_BLUE_WHITE ; Input attribute
                        DB    0                 ; Error attribute
                        DB    1                 ; Mouse support
                        DB    0                 ; Locate cursor at field
                        DB    0                 ; Locate cursor at occurrence
                        DB    0                 ; Locate cursor at position
                        DB    LOGIC_NO          ; Screen not changed
                        DB    0                 ; Go to first          
                        DB    0                 ; modifiable field
                        DW    ?                 ; Screen Name Address HIGH
                        DW    ?                 ; Screen Name Address LOW
                        DW    ?                 ; Text        Address HIGH
                        DW    ?                 ; Text        Address LOW
                        DW    NULL              ; Attribute   Address HIGH
                        DW    NULL              ; Attribute   Address LOW
                        DW    ?                 ; Valid Keys  Address HIGH
                        DW    ?                 ; Valid Keys  Address LOW
                        DW    ?                 ; Enter Keys  Address HIGH
                        DW    ?                 ; Enter Keys  Address LOW
                        DW    ?                 ; Field Area  Address HIGH
                        DW    ?                 ; Field Area  Address LOW
Ws_SV_Name              DB    "VOLUME  "
Ws_SV_Keys              DB    KEY_ESC, KEY_ENTER
                        DB    NULL
;                                       1         2         3         4         5         6         7         8
;                              ....5....0....5....0....5....0....5....0....5....0....5....0....5....0....5....0
Ws_SV_Text              DB                                   "ÉÍÍÍÍÍÍÍÍÍÍ[SpartaDos Volume Name]ÍÍÍÍÍÍÍÍÍÍÍ»"
                        DB                                   "º                                            º"
                        DB                                   "º Please specify the SpartaDos Volume Name:  º"
                        DB                                   "º                  xxxxxxxx                  º"
                        DB                                   "º                                            º"
                        DB                                   "ºENTER=Specify   Esc=Cancel                  º"
                        DB                                   "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼"
                        DB    NULL
;------------
; F I E L D S
;------------
;
; Include (sub)directories or not (only for SpartaDos)
;
Ws_SV_F_Volume_Name     DB    4                 ; Relative ROW, NULL=End
                        DB   20                 ; Relative COLUMN 
                        DB    8                 ; Field Size
                        DB    1                 ; Nr of occurrences
                        DW    0                 ; This is not a table
                        DB    1                 ; Modifiable
                        DB    KEY_ENTER         ; Emulate Enter
                        DB    6                 ; Edit Filemask
                        DB    1                 ; Blanks Trailing
                        DB    0                 ; Uppercase
                        DB    0                 ; Backspace destructive
                        DB    0                 ; <Digits before dot>
                        DB    0                 ; <Digits after dot>
                        DB    0                 ; <Negative number option>
                        DB    0                 ; <Decimal point character>
                        DB    0                 ; <Date Time Format>
                        DB    LOGIC_NO          ; Field changed indicator
                        DW    ?                 ; Source Hi
                        DW    ?                 ; ...... Lo
                        DW    NULL              ; <Object Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Attrib Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Keys Hi>
                        DW    NULL              ; <.... Lo>

Ws_SV_F_Key_Enter       DB    6                 ; Relative ROW, NULL=End
                        DB    2                 ; Relative COLUMN 
                        DB   13                 ; Field Size
                        DB    1                 ; Nr of occurrences
                        DW    0                 ; This is not a table
                        DB    0                 ; Protected
                        DB    KEY_ENTER         ; Emulate Enter
                        DB    0                 ; Edit External
                        DB    0                 ; Blanks Anywhere
                        DB    0                 ; Uppercase
                        DB    0                 ; Backspace destructive
                        DB    0                 ; <Digits before dot>
                        DB    0                 ; <Digits after dot>
                        DB    0                 ; <Negative number option>
                        DB    0                 ; <Decimal point character>
                        DB    0                 ; <Date Time Format>
                        DB    LOGIC_NO          ; Field changed indicator
                        DW    ?                 ; Source Hi
                        DW    ?                 ; ...... Lo
                        DW    NULL              ; <Object Hi>
                        DW    NULL              ; <...... Lo>
                        DW    ?                 ; <Attrib Hi>
                        DW    ?                 ; <...... Lo>
                        DW    NULL              ; <Keys Hi>
                        DW    NULL              ; <.... Lo>

Ws_SV_F_Key_Esc         DB    6                 ; Relative ROW, NULL=End
                        DB   18                 ; Relative COLUMN 
                        DB   10                 ; Field Size
                        DB    1                 ; Nr of occurrences
                        DW    0                 ; This is not a table
                        DB    0                 ; Protected
                        DB    KEY_ESC           ; Emulate Enter
                        DB    0                 ; Edit External
                        DB    0                 ; Blanks Anywhere
                        DB    0                 ; Uppercase
                        DB    0                 ; Backspace destructive
                        DB    0                 ; <Digits before dot>
                        DB    0                 ; <Digits after dot>
                        DB    0                 ; <Negative number option>
                        DB    0                 ; <Decimal point character>
                        DB    0                 ; <Date Time Format>
                        DB    LOGIC_NO          ; Field changed indicator
                        DW    ?                 ; Source Hi
                        DW    ?                 ; ...... Lo
                        DW    NULL              ; <Object Hi>
                        DW    NULL              ; <...... Lo>
                        DW    ?                 ; <Attrib Hi>
                        DW    ?                 ; <...... Lo>
                        DW    NULL              ; <Keys Hi>
                        DW    NULL              ; <.... Lo>

Ws_SV_No_More_Fields    DB    NULL

;--------
; D A T A
;--------
Ws_SV_D_Volume_Name     DB   8 dup (SPACE)

Ws_SV_D_Key_Enter       DB   "Enter=Specify"
Ws_SV_D_Key_Esc         DB   "Esc=Cancel"



;**********************************************************************
; A d d   D i s k n u m b e r s   a f t e r   l a s t   d i s k n r   *
;**********************************************************************
Ws_AD                   DB    WSIO_OPEN
                        DB   10                 ; Start of screen ROW
                        DB   40                 ; Start of screen COLUMN
                        DB   16                 ; End of screen ROW
                        DB   68                 ; End of screen COLUMN
                        DB    ATTRIB_GREEN_WHITE ; Screen attribute
                        DB    ATTRIB_BLUE_WHITE ; Field attribute
                        DB    ATTRIB_BLUE_WHITE ; Input attribute
                        DB    0                 ; Error attribute
                        DB    1                 ; Mouse support
                        DB    0                 ; Locate cursor at field
                        DB    0                 ; Locate cursor at occurrence
                        DB    0                 ; Locate cursor at position
                        DB    LOGIC_NO          ; Screen not changed
                        DB    0                 ; Go to first          
                        DB    0                 ; modifiable field
                        DW    ?                 ; Screen Name Address HIGH
                        DW    ?                 ; Screen Name Address LOW
                        DW    ?                 ; Text        Address HIGH
                        DW    ?                 ; Text        Address LOW
                        DW    NULL              ; Attribute   Address HIGH
                        DW    NULL              ; Attribute   Address LOW
                        DW    ?                 ; Valid Keys  Address HIGH
                        DW    ?                 ; Valid Keys  Address LOW
                        DW    ?                 ; Enter Keys  Address HIGH
                        DW    ?                 ; Enter Keys  Address LOW
                        DW    ?                 ; Field Area  Address HIGH
                        DW    ?                 ; Field Area  Address LOW
Ws_AD_Name              DB    "ADDDISKS"
Ws_AD_Keys              DB    KEY_ESC, KEY_ENTER
                        DB    NULL
;                                       1         2         3         4         5         6         7         8
;                              ....5....0....5....0....5....0....5....0....5....0....5....0....5....0....5....0
Ws_AD_Text              DB                                           "ÉÍÍÍÍÍ[Add from where]ÍÍÍÍÍÍ»"
                        DB                                           "º                           º"
                        DB                                           "º  [ ] E=Add at end         º"
                        DB                                           "º      B=Add from begin     º"
                        DB                                           "º                           º"
                        DB                                           "ºENTER=Specify    Esc=Cancelº"
                        DB                                           "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼"
                        DB    NULL
;------------
; F I E L D S
;------------
;
; DOS to include
;
Ws_AD_F_Add_Where       DB    3                 ; Relative ROW, NULL=End
                        DB    5                 ; Relative COLUMN 
                        DB    1                 ; Field Size
                        DB    1                 ; Nr of occurrences
                        DW    0                 ; This is not a table
                        DB    1                 ; Modifiable
                        DB    KEY_ENTER         ; Emulate Enter
                        DB    0                 ; Edit External
                        DB    1                 ; Blanks Trailing 
                        DB    0                 ; Uppercase
                        DB    0                 ; Backspace destructive
                        DB    0                 ; <Digits before dot>
                        DB    0                 ; <Digits after dot>
                        DB    0                 ; <Negative number option>
                        DB    0                 ; <Decimal point character>
                        DB    0                 ; <Date Time Format>
                        DB    LOGIC_NO          ; Field changed indicator
                        DW    ?                 ; Source Hi
                        DW    ?                 ; ...... Lo
                        DW    NULL              ; <Object Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Attrib Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Keys Hi>
                        DW    NULL              ; <.... Lo>

Ws_AD_F_Key_Enter       DB    6                 ; Relative ROW, NULL=End
                        DB    2                 ; Relative COLUMN 
                        DB   13                 ; Field Size
                        DB    1                 ; Nr of occurrences
                        DW    0                 ; This is not a table
                        DB    0                 ; Protected
                        DB    KEY_ENTER         ; Emulate Enter
                        DB    0                 ; Edit External
                        DB    0                 ; Blanks Anywhere
                        DB    0                 ; Uppercase
                        DB    0                 ; Backspace destructive
                        DB    0                 ; <Digits before dot>
                        DB    0                 ; <Digits after dot>
                        DB    0                 ; <Negative number option>
                        DB    0                 ; <Decimal point character>
                        DB    0                 ; <Date Time Format>
                        DB    LOGIC_NO          ; Field changed indicator
                        DW    ?                 ; Source Hi
                        DW    ?                 ; ...... Lo
                        DW    NULL              ; <Object Hi>
                        DW    NULL              ; <...... Lo>
                        DW    ?                 ; <Attrib Hi>
                        DW    ?                 ; <...... Lo>
                        DW    NULL              ; <Keys Hi>
                        DW    NULL              ; <.... Lo>

Ws_AD_F_Key_Esc         DB    6                 ; Relative ROW, NULL=End
                        DB   19                 ; Relative COLUMN 
                        DB   10                 ; Field Size
                        DB    1                 ; Nr of occurrences
                        DW    0                 ; This is not a table
                        DB    0                 ; Protected
                        DB    KEY_ESC           ; Emulate Enter
                        DB    0                 ; Edit External
                        DB    0                 ; Blanks Anywhere
                        DB    0                 ; Uppercase
                        DB    0                 ; Backspace destructive
                        DB    0                 ; <Digits before dot>
                        DB    0                 ; <Digits after dot>
                        DB    0                 ; <Negative number option>
                        DB    0                 ; <Decimal point character>
                        DB    0                 ; <Date Time Format>
                        DB    LOGIC_NO          ; Field changed indicator
                        DW    ?                 ; Source Hi
                        DW    ?                 ; ...... Lo
                        DW    NULL              ; <Object Hi>
                        DW    NULL              ; <...... Lo>
                        DW    ?                 ; <Attrib Hi>
                        DW    ?                 ; <...... Lo>
                        DW    NULL              ; <Keys Hi>
                        DW    NULL              ; <.... Lo>

Ws_AD_No_More_Fields    DB    NULL

;--------
; D A T A
;--------
Ws_AD_D_Add_Where       DB    "E"

End_Begin_Field         DB    "EB"
                        DB    NULL

Ws_AD_D_Key_Enter       DB   "Enter=Specify"
Ws_AD_D_Key_Esc         DB   "Esc=Cancel"



;**********************************************************************
; C r e a t i n g   x l   d i s k   F i l e s                         *
;**********************************************************************
Ws_CF                   DB    WSIO_DISPLAY_ONLY
                        DB   10                 ; Start of screen ROW
                        DB   36                 ; Start of screen COLUMN
                        DB   17                 ; End of screen ROW
                        DB   71                 ; End of screen COLUMN
                        DB    ATTRIB_GREEN_WHITE ; Screen attribute
                        DB    ATTRIB_GREEN_WHITE ; Field attribute
                        DB    0                 ; Input attribute
                        DB    0                 ; Error attribute
                        DB    0                 ; Mouse support
                        DB    0                 ; Locate cursor at field
                        DB    0                 ; Locate cursor at occurrence
                        DB    0                 ; Locate cursor at position
                        DB    LOGIC_NO          ; Screen not changed
                        DB    CURSOR_OFF_SCREEN ; No cursor
                        DB    CURSOR_OFF_SCREEN ; to display
                        DW    ?                 ; Screen Name Address HIGH
                        DW    ?                 ; Screen Name Address LOW
                        DW    ?                 ; Text        Address HIGH
                        DW    ?                 ; Text        Address LOW
                        DW    NULL              ; Attribute   Address HIGH
                        DW    NULL              ; Attribute   Address LOW
                        DW    NULL              ; Valid Keys  Address HIGH
                        DW    NULL              ; Valid Keys  Address LOW
                        DW    NULL              ; Enter Keys  Address HIGH
                        DW    NULL              ; Enter Keys  Address LOW
                        DW    ?                 ; Field Area  Address HIGH
                        DW    ?                 ; Field Area  Address LOW
Ws_CF_Name              DB    "CFILES  "

;                                       1         2         3         4         5         6         7         8
;                              ....5....0....5....0....5....0....5....0....5....0....5....0....5....0....5....0
Ws_CF_Text              DB                                       "ÉÍÍ[Adding files to disk images]ÍÍÍ»"
                        DB                                       "º                                  º"
                        DB                                       "º xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx º"
                        DB                                       "º                                  º"
                        DB                                       "º Processing disk: xxxxxxxxxxxx    º"
                        DB                                       "º Processing dir : xxxxxxxxxxxx    º"
                        DB                                       "º xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx º"
                        DB                                       "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼"
                        DB    NULL
;------------
; F I E L D S
;------------
;
; Progress bar
;
Ws_CF_F_Progress_Bar    DB    3                 ; Relative ROW, NULL=End
                        DB    3                 ; Relative COLUMN 
                        DB   32                 ; Field Size
                        DB    1                 ; Nr of occurrences
                        DW    0                 ; This is not a table
                        DB    0                 ; Protected
                        DB    0                 ; <Mouse Sensitive>
                        DB    0                 ; <Edit option>
                        DB    0                 ; <Blanks option>
                        DB    0                 ; <Uppercase/Lowercase option>
                        DB    0                 ; <Backspace option>
                        DB    0                 ; <Digits before dot>
                        DB    0                 ; <Digits after dot>
                        DB    0                 ; <Negative number option>
                        DB    0                 ; <Decimal point character>
                        DB    0                 ; <Date Time Format>
                        DB    LOGIC_NO          ; Field changed indicator
                        DW    ?                 ; Source Hi
                        DW    ?                 ; ...... Lo
                        DW    NULL              ; <Object Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Attrib Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Keys Hi>
                        DW    NULL              ; <.... Lo>

;
; Process disk
;
Ws_CF_F_Add_Disk        DB    5                 ; Relative ROW, NULL=End
                        DB   20                 ; Relative COLUMN 
                        DB   12                 ; Field Size
                        DB    1                 ; Nr of occurrences
                        DW    0                 ; This is not a table
                        DB    0                 ; Protected
                        DB    0                 ; <Mouse Sensitive>
                        DB    0                 ; <Edit option>
                        DB    0                 ; <Blanks option>
                        DB    0                 ; <Uppercase/Lowercase option>
                        DB    0                 ; <Backspace option>
                        DB    0                 ; <Digits before dot>
                        DB    0                 ; <Digits after dot>
                        DB    0                 ; <Negative number option>
                        DB    0                 ; <Decimal point character>
                        DB    0                 ; <Date Time Format>
                        DB    LOGIC_NO          ; Field changed indicator
                        DW    ?                 ; Source Hi
                        DW    ?                 ; ...... Lo
                        DW    NULL              ; <Object Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Attrib Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Keys Hi>
                        DW    NULL              ; <.... Lo>

;
; Process directory
;
Ws_CF_F_Add_Dir         DB    6                 ; Relative ROW, NULL=End
                        DB   20                 ; Relative COLUMN 
                        DB   12                 ; Field Size
                        DB    1                 ; Nr of occurrences
                        DW    0                 ; This is not a table
                        DB    0                 ; Protected
                        DB    0                 ; <Mouse Sensitive>
                        DB    0                 ; <Edit option>
                        DB    0                 ; <Blanks option>
                        DB    0                 ; <Uppercase/Lowercase option>
                        DB    0                 ; <Backspace option>
                        DB    0                 ; <Digits before dot>
                        DB    0                 ; <Digits after dot>
                        DB    0                 ; <Negative number option>
                        DB    0                 ; <Decimal point character>
                        DB    0                 ; <Date Time Format>
                        DB    LOGIC_NO          ; Field changed indicator
                        DW    ?                 ; Source Hi
                        DW    ?                 ; ...... Lo
                        DW    NULL              ; <Object Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Attrib Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Keys Hi>
                        DW    NULL              ; <.... Lo>

;
; Process file
;
Ws_CF_F_Add_File        DB    7                 ; Relative ROW, NULL=End
                        DB    3                 ; Relative COLUMN 
                        DB   32                 ; Field Size
                        DB    1                 ; Nr of occurrences
                        DW    0                 ; This is not a table
                        DB    0                 ; Protected
                        DB    0                 ; <Mouse Sensitive>
                        DB    0                 ; <Edit option>
                        DB    0                 ; <Blanks option>
                        DB    0                 ; <Uppercase/Lowercase option>
                        DB    0                 ; <Backspace option>
                        DB    0                 ; <Digits before dot>
                        DB    0                 ; <Digits after dot>
                        DB    0                 ; <Negative number option>
                        DB    0                 ; <Decimal point character>
                        DB    0                 ; <Date Time Format>
                        DB    LOGIC_NO          ; Field changed indicator
                        DW    ?                 ; Source Hi
                        DW    ?                 ; ...... Lo
                        DW    NULL              ; <Object Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Attrib Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Keys Hi>
                        DW    NULL              ; <.... Lo>

Ws_CF_No_More_Fields    DB    NULL

;--------
; D A T A
;--------
Ws_CF_D_Progress_Bar            DB   32 dup (0B0h)
Ws_CF_D_Progress_Bar_Attr       DB   ATTRIB_CYAN_WHITE
Ws_CF_D_Add_Disk                DB   12 dup (SPACE)
Ws_CF_D_Add_Dir                 DB   12 dup (SPACE)
Ws_CF_D_Add_File                DB   "Processing file: "
Ws_CF_D_Add_File_File           DB   12 dup (SPACE)
                                DB   "   "
Ws_CF_D_No_Message              DB   32 dup (SPACE)
Ws_CF_D_Formatting_Disk         DB   "Formatting disk, please wait... "

;**********************************************************************
; F o r m a t t i n g   x l   d i s k   F i l e s                     *
;**********************************************************************
Ws_FF                   DB    WSIO_DISPLAY_ONLY
                        DB   11                 ; Start of screen ROW
                        DB   36                 ; Start of screen COLUMN
                        DB   13                 ; End of screen ROW
                        DB   71                 ; End of screen COLUMN
                        DB    ATTRIB_BLUE_WHITE ; Screen attribute
                        DB    ATTRIB_BLUE_WHITE ; Field attribute
                        DB    0                 ; Input attribute
                        DB    0                 ; Error attribute
                        DB    0                 ; Mouse support
                        DB    0                 ; Locate cursor at field
                        DB    0                 ; Locate cursor at occurrence
                        DB    0                 ; Locate cursor at position
                        DB    LOGIC_NO          ; Screen not changed
                        DB    CURSOR_OFF_SCREEN ; No cursor
                        DB    CURSOR_OFF_SCREEN ; to display
                        DW    ?                 ; Screen Name Address HIGH
                        DW    ?                 ; Screen Name Address LOW
                        DW    ?                 ; Text        Address HIGH
                        DW    ?                 ; Text        Address LOW
                        DW    NULL              ; Attribute   Address HIGH
                        DW    NULL              ; Attribute   Address LOW
                        DW    NULL              ; Valid Keys  Address HIGH
                        DW    NULL              ; Valid Keys  Address LOW
                        DW    NULL              ; Enter Keys  Address HIGH
                        DW    NULL              ; Enter Keys  Address LOW
                        DW    ?                 ; Field Area  Address HIGH
                        DW    ?                 ; Field Area  Address LOW
Ws_FF_Name              DB    "FORMAT  "

;                                       1         2         3         4         5         6         7         8
;                              ....5....0....5....0....5....0....5....0....5....0....5....0....5....0....5....0
Ws_FF_Text              DB                                       "ÉÍÍÍÍÍ[Formatting Disk Image]ÍÍÍÍÍÍ»"
                        DB                                       "ºxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxº"
                        DB                                       "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼"
                        DB    NULL
;------------
; F I E L D S
;------------
;
; Progress bar
;
Ws_FF_F_Progress_Bar    DB    2                 ; Relative ROW, NULL=End
                        DB    2                 ; Relative COLUMN 
                        DB   34                 ; Field Size
                        DB    1                 ; Nr of occurrences
                        DW    0                 ; This is not a table
                        DB    0                 ; Protected
                        DB    0                 ; <Mouse Sensitive>
                        DB    0                 ; <Edit option>
                        DB    0                 ; <Blanks option>
                        DB    0                 ; <Uppercase/Lowercase option>
                        DB    0                 ; <Backspace option>
                        DB    0                 ; <Digits before dot>
                        DB    0                 ; <Digits after dot>
                        DB    0                 ; <Negative number option>
                        DB    0                 ; <Decimal point character>
                        DB    0                 ; <Date Time Format>
                        DB    LOGIC_NO          ; Field changed indicator
                        DW    ?                 ; Source Hi
                        DW    ?                 ; ...... Lo
                        DW    NULL              ; <Object Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Attrib Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Keys Hi>
                        DW    NULL              ; <.... Lo>

Ws_FF_No_More_Fields    DB    NULL

;--------
; D A T A
;--------
Ws_FF_D_Progress_Bar            DB   34 dup (0B0h)
Ws_FF_D_Progress_Bar_Attr       DB   ATTRIB_CYAN_WHITE

;**********************************************************************
; A N a l y z i n g   D i r e c t o r y   S t r u c t u r e           *
;**********************************************************************
Ws_AN                   DB    WSIO_DISPLAY_ONLY
                        DB   10                 ; Start of screen ROW
                        DB   36                 ; Start of screen COLUMN
                        DB   17                 ; End of screen ROW
                        DB   71                 ; End of screen COLUMN
                        DB    ATTRIB_BLUE_WHITE ; Screen attribute
                        DB    ATTRIB_BLUE_WHITE ; Field attribute
                        DB    0                 ; Input attribute
                        DB    0                 ; Error attribute
                        DB    0                 ; Mouse support
                        DB    0                 ; Locate cursor at field
                        DB    0                 ; Locate cursor at occurrence
                        DB    0                 ; Locate cursor at position
                        DB    LOGIC_NO          ; Screen not changed
                        DB    CURSOR_OFF_SCREEN ; No cursor
                        DB    CURSOR_OFF_SCREEN ; to display
                        DW    ?                 ; Screen Name Address HIGH
                        DW    ?                 ; Screen Name Address LOW
                        DW    ?                 ; Text        Address HIGH
                        DW    ?                 ; Text        Address LOW
                        DW    NULL              ; Attribute   Address HIGH
                        DW    NULL              ; Attribute   Address LOW
                        DW    NULL              ; Valid Keys  Address HIGH
                        DW    NULL              ; Valid Keys  Address LOW
                        DW    NULL              ; Enter Keys  Address HIGH
                        DW    NULL              ; Enter Keys  Address LOW
                        DW    NULL              ; Field Area  Address HIGH
                        DW    NULL              ; Field Area  Address LOW
Ws_AN_Name              DB    "ANALYZE "

;                                       1         2         3         4         5         6         7         8
;                              ....5....0....5....0....5....0....5....0....5....0....5....0....5....0....5....0
Ws_AN_Text              DB                                       "ÉÍÍÍÍÍÍÍÍÍÍÍÍ[Analyzing]ÍÍÍÍÍÍÍÍÍÍÍ»"
                        DB                                       "º                                  º"
                        DB                                       "º                                  º"
                        DB                                       "º            Please wait,          º"
                        DB                                       "º Analyzing Directory Structure... º"
                        DB                                       "º                                  º"
                        DB                                       "º                                  º"
                        DB                                       "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼"
                        DB    NULL

;**********************************************************************
; C r e a t i n g   V t o c   D i r e c t o r y   S t r u c t u r e   *
;**********************************************************************
Ws_VS                   DB    WSIO_DISPLAY_ONLY
                        DB   10                 ; Start of screen ROW
                        DB   36                 ; Start of screen COLUMN
                        DB   17                 ; End of screen ROW
                        DB   71                 ; End of screen COLUMN
                        DB    ATTRIB_BLUE_WHITE ; Screen attribute
                        DB    ATTRIB_BLUE_WHITE ; Field attribute
                        DB    0                 ; Input attribute
                        DB    0                 ; Error attribute
                        DB    0                 ; Mouse support
                        DB    0                 ; Locate cursor at field
                        DB    0                 ; Locate cursor at occurrence
                        DB    0                 ; Locate cursor at position
                        DB    LOGIC_NO          ; Screen not changed
                        DB    CURSOR_OFF_SCREEN ; No cursor
                        DB    CURSOR_OFF_SCREEN ; to display
                        DW    ?                 ; Screen Name Address HIGH
                        DW    ?                 ; Screen Name Address LOW
                        DW    ?                 ; Text        Address HIGH
                        DW    ?                 ; Text        Address LOW
                        DW    NULL              ; Attribute   Address HIGH
                        DW    NULL              ; Attribute   Address LOW
                        DW    NULL              ; Valid Keys  Address HIGH
                        DW    NULL              ; Valid Keys  Address LOW
                        DW    NULL              ; Enter Keys  Address HIGH
                        DW    NULL              ; Enter Keys  Address LOW
                        DW    NULL              ; Field Area  Address HIGH
                        DW    NULL              ; Field Area  Address LOW
Ws_VS_Name              DB    "VTOC    "

;                                       1         2         3         4         5         6         7         8
;                              ....5....0....5....0....5....0....5....0....5....0....5....0....5....0....5....0
Ws_VS_Text              DB                                       "ÉÍÍÍÍÍÍÍÍÍÍ[VTOC creation]ÍÍÍÍÍÍÍÍÍ»"
                        DB                                       "º                                  º"
                        DB                                       "º                                  º"
                        DB                                       "º            Please wait,          º"
                        DB                                       "º  Creating Directory Structure... º"
                        DB                                       "º                                  º"
                        DB                                       "º                                  º"
                        DB                                       "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼"
                        DB    NULL

;**********************************************************************
; E R R O R - D R I V E   N O T   R E A D Y                           *
;**********************************************************************
Ws_E1                   DB    WSIO_DISPLAY_ONLY
                        DB   10                 ; Start of screen ROW
                        DB   42                 ; Start of screen COLUMN
                        DB   16                 ; End of screen ROW
                        DB   65                 ; End of screen COLUMN
                        DB    ATTRIB_RED_WHITE  ; Screen attribute
                        DB    0                 ; Field attribute
                        DB    0                 ; Select attribute
                        DB    0                 ; Error attribute
                        DB    0                 ; Mouse support
                        DB    0                 ; Locate cursor at field
                        DB    0                 ; Locate cursor at occurrence
                        DB    0                 ; Locate cursor at position
                        DB    LOGIC_NO          ; Screen not changed
                        DB    CURSOR_OFF_SCREEN ; Cursor Position Row
                        DB    CURSOR_OFF_SCREEN ; Cursor Position Col
                        DW    ?                 ; Screen Name Address HIGH
                        DW    ?                 ; Screen Name Address LOW
                        DW    ?                 ; Text        Address HIGH
                        DW    ?                 ; Text        Address LOW
                        DW    NULL              ; Attribute   Address HIGH
                        DW    NULL              ; Attribute   Address LOW
                        DW    ?                 ; Valid Keys  Address HIGH
                        DW    ?                 ; Valid Keys  Address LOW
                        DW    ?                 ; Enter Keys  Address HIGH
                        DW    ?                 ; Enter Keys  Address LOW
                        DW    NULL              ; Field Area  Address HIGH
                        DW    NULL              ; Field Area  Address LOW
Ws_E1_Name              DB    "ERROR1  "
Ws_E1_Keys              DB    KEY_ANY
                        DB    NULL
;                                       1         2         3         4         5         6         7         8
;                              ....5....0....5....0....5....0....5....0....5....0....5....0....5....0....5....0
Ws_E1_Text              DB                                             "ÉÍÍ[Drive Not Ready]ÍÍÍ»"
                        DB                                             "º                      º"
                        DB                                             "º There is NO media in º"
                        DB                                             "º the requested drive! º"
                        DB                                             "º                      º"
                        DB                                             "ºEsc or Any key=Confirmº"
                        DB                                             "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼"
                        DB    NULL



;**********************************************************************
; E R R O R - G E N E R A L   I / O   E R R O R                       *
;**********************************************************************
Ws_E2                   DB    WSIO_DISPLAY_ONLY
                        DB    9                 ; Start of screen ROW
                        DB   32                 ; Start of screen COLUMN
                        DB   16                 ; End of screen ROW
                        DB   75                 ; End of screen COLUMN
                        DB    ATTRIB_RED_WHITE  ; Screen attribute
                        DB    0                 ; Field attribute
                        DB    0                 ; Select attribute
                        DB    0                 ; Error attribute
                        DB    0                 ; Mouse support
                        DB    0                 ; Locate cursor at field
                        DB    0                 ; Locate cursor at occurrence
                        DB    0                 ; Locate cursor at position
                        DB    LOGIC_NO          ; Screen not changed
                        DB    CURSOR_OFF_SCREEN ; Cursor Position Row
                        DB    CURSOR_OFF_SCREEN ; Cursor Position Col
                        DW    ?                 ; Screen Name Address HIGH
                        DW    ?                 ; Screen Name Address LOW
                        DW    ?                 ; Text        Address HIGH
                        DW    ?                 ; Text        Address LOW
                        DW    NULL              ; Attribute   Address HIGH
                        DW    NULL              ; Attribute   Address LOW
                        DW    ?                 ; Valid Keys  Address HIGH
                        DW    ?                 ; Valid Keys  Address LOW
                        DW    ?                 ; Enter Keys  Address HIGH
                        DW    ?                 ; Enter Keys  Address LOW
                        DW    NULL              ; Field Area  Address HIGH
                        DW    NULL              ; Field Area  Address LOW
Ws_E2_Name              DB    "ERROR2  "
Ws_E2_Keys              DB    KEY_ANY
                        DB    NULL
;                                       1         2         3         4         5         6         7         8
;                              ....5....0....5....0....5....0....5....0....5....0....5....0....5....0....5....0
Ws_E2_Text              DB                                   "ÉÍÍÍÍÍÍÍÍÍÍÍ[I / O   E r r o r]ÍÍÍÍÍÍÍÍÍÍÍÍ»"
                        DB                                   "º                                          º"
                        DB                                   "º                                          º"
                        DB                                   "º xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx º"
                        DB                                   "º                                          º"
                        DB                                   "º                                          º"
                        DB                                   "º Enter=Acknowledge Error                  º"
                        DB                                   "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼"
                        DB    NULL
;------------
; F I E L D S
;------------
;
; Error message
;
Ws_E2_F_Error_Message   DB    4                 ; Relative ROW, NULL=End
                        DB    3                 ; Relative COLUMN 
                        DB   40                 ; Field Size
                        DB    1                 ; Nr of occurrences
                        DW    0                 ; This is not a table
                        DB    0                 ; Protected
                        DB    0                 ; <Mouse Sensitive>
                        DB    0                 ; <Edit option>
                        DB    0                 ; <Blanks option>
                        DB    0                 ; <Uppercase/Lowercase option>
                        DB    0                 ; <Backspace option>
                        DB    0                 ; <Digits before dot>
                        DB    0                 ; <Digits after dot>
                        DB    0                 ; <Negative number option>
                        DB    0                 ; <Decimal point character>
                        DB    0                 ; <Date Time Format>
                        DB    LOGIC_NO          ; Field changed indicator
                        DW    ?                 ; Source Hi
                        DW    ?                 ; ...... Lo
                        DW    NULL              ; <Object Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Attrib Hi>
                        DW    NULL              ; <...... Lo>
                        DW    NULL              ; <Keys Hi>
                        DW    NULL              ; <.... Lo>

Ws_E2_No_More_Fields    DB    NULL

;--------
; D A T A
;--------
Ws_E2_Error_Message             DB   "                                        "
Ws_E2_D_General_I_O_Error       DB   "I/O ERROR - Reason Unknown!             "
Ws_E2_D_BOOTCODE_Not_Found      DB   "BOOTCODE file not found!                "
Ws_E2_D_DOS_SYS_Not_Found       DB   "DOS.SYS file not found!                 "
Ws_E2_D_DUP_SYS_Not_Found       DB   "DUP.SYS file not found!                 "
Ws_E2_D_Disk_Full               DB   "The destination drive is full!          "
Ws_E2_D_Opening_File            DB   "Opening                                 "
Ws_E2_D_Reading_File            DB   "Reading                                 "
Ws_E2_D_Opening_Image           DB   "ATR disk image could not be opened!     "
Ws_E2_D_Positioning_Image       DB   "ATR disk image sector positioning error!"
Ws_E2_D_Sector_Allocation       DB   "ATR disk image sector allocation error! "
Ws_E2_D_Writing_Image           DB   "ATR disk image sector writing error!    "

;**********************************************************************
; E R R O R - T O O   M A N Y   F I L E S   I N   D I R E C T O R Y   *
;**********************************************************************
Ws_E5                   DB    WSIO_OPEN
                        DB    9                 ; Start of screen ROW
                        DB   32                 ; Start of screen COLUMN
                        DB   18                 ; End of screen ROW
                        DB   75                 ; End of screen COLUMN
                        DB    ATTRIB_RED_WHITE  ; Screen attribute
                        DB    ATTRIB_RED_WHITE  ; Field attribute
                        DB    ATTRIB_RED_WHITE  ; Input attribute
                        DB    0                 ; Error attribute
                        DB    1                 ; Mouse support
                        DB    0                 ; Locate cursor at field
                        DB    0                 ; Locate cursor at occurrence
                        DB    0                 ; Locate cursor at position
                        DB    LOGIC_NO          ; Screen not changed
                        DB    CURSOR_OFF_SCREEN ; No cursor
                        DB    CURSOR_OFF_SCREEN ; to display
                        DW    ?                 ; Screen Name Address HIGH
                        DW    ?                 ; Screen Name Address LOW
                        DW    ?                 ; Text        Address HIGH
                        DW    ?                 ; Text        Address LOW
                        DW    NULL              ; Attribute   Address HIGH
                        DW    NULL              ; Attribute   Address LOW
                        DW    ?                 ; Valid Keys  Address HIGH
                        DW    ?                 ; Valid Keys  Address LOW
                        DW    ?                 ; Enter Keys  Address HIGH
                        DW    ?                 ; Enter Keys  Address LOW
                        DW    ?                 ; Field Area  Address HIGH
                        DW    ?                 ; Field Area  Address LOW
Ws_E5_Name              DB    "ERROR5  "
Ws_E5_Keys              DB    KEY_ESC, KEY_ENTER
                        DB    NULL
;                                       1         2         3         4         5         6         7         8
;                              ....5....0....5....0....5....0....5....0....5....0....5....0....5....0....5....0
Ws_E5_Text              DB                                   "ÉÍÍÍÍÍÍÍÍÍÍ[Too Many Files Error]ÍÍÍÍÍÍÍÍÍÍ»"
                        DB                                   "º                                          º"
                        DB                                   "º There are too many files encountered in  º"
                        DB                                   "º a (sub)directory to support the selected º"
                        DB                                   "º DOS format. When creating the disk image º"
                        DB                                   "º not all (sub)directory files will be     º"
                        DB                                   "º placed on the disk image, is that ok?    º"
                        DB                                   "º                                          º"
                        DB                                   "ºEnter=Ok   Esc=Cancel disk image creation º"
                        DB                                   "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼"
                        DB    NULL
;------------
; F I E L D S
;------------
Ws_E5_F_Key_Enter       DB    9                 ; Relative ROW, NULL=End
                        DB    2                 ; Relative COLUMN 
                        DB    8                 ; Field Size
                        DB    1                 ; Nr of occurrences
                        DW    0                 ; This is not a table
                        DB    0                 ; Protected
                        DB    KEY_ENTER         ; Emulate Enter
                        DB    0                 ; Edit External
                        DB    0                 ; Blanks Anywhere
                        DB    0                 ; Uppercase
                        DB    0                 ; Backspace destructive
                        DB    0                 ; <Digits before dot>
                        DB    0                 ; <Digits after dot>
                        DB    0                 ; <Negative number option>
                        DB    0                 ; <Decimal point character>
                        DB    0                 ; <Date Time Format>
                        DB    LOGIC_NO          ; Field changed indicator
                        DW    ?                 ; Source Hi
                        DW    ?                 ; ...... Lo
                        DW    NULL              ; <Object Hi>
                        DW    NULL              ; <...... Lo>
                        DW    ?                 ; <Attrib Hi>
                        DW    ?                 ; <...... Lo>
                        DW    NULL              ; <Keys Hi>
                        DW    NULL              ; <.... Lo>

Ws_E5_F_Key_Esc         DB    9                 ; Relative ROW, NULL=End
                        DB   13                 ; Relative COLUMN 
                        DB   30                 ; Field Size
                        DB    1                 ; Nr of occurrences
                        DW    0                 ; This is not a table
                        DB    0                 ; Protected
                        DB    KEY_ESC           ; Emulate Enter
                        DB    0                 ; Edit External
                        DB    0                 ; Blanks Anywhere
                        DB    0                 ; Uppercase
                        DB    0                 ; Backspace destructive
                        DB    0                 ; <Digits before dot>
                        DB    0                 ; <Digits after dot>
                        DB    0                 ; <Negative number option>
                        DB    0                 ; <Decimal point character>
                        DB    0                 ; <Date Time Format>
                        DB    LOGIC_NO          ; Field changed indicator
                        DW    ?                 ; Source Hi
                        DW    ?                 ; ...... Lo
                        DW    NULL              ; <Object Hi>
                        DW    NULL              ; <...... Lo>
                        DW    ?                 ; <Attrib Hi>
                        DW    ?                 ; <...... Lo>
                        DW    NULL              ; <Keys Hi>
                        DW    NULL              ; <.... Lo>

Ws_E5_No_More_Fields    DB    NULL

;--------
; D A T A
;--------
Ws_E5_D_Key_Enter       DB   "Enter=Ok"
Ws_E5_D_Key_Esc         DB   "Esc=Cancel disk image creation"



;**********************************************************************
; E R R O R - D I R E C T O R I E S / F I L E S   W O N ' T   F I T   *
;**********************************************************************
Ws_E6                   DB    WSIO_DISPLAY_ONLY
                        DB    9                 ; Start of screen ROW
                        DB   32                 ; Start of screen COLUMN
                        DB   17                 ; End of screen ROW
                        DB   75                 ; End of screen COLUMN
                        DB    ATTRIB_RED_WHITE  ; Screen attribute
                        DB    0                 ; Field attribute
                        DB    0                 ; Select attribute
                        DB    0                 ; Error attribute
                        DB    0                 ; Mouse support
                        DB    0                 ; Locate cursor at field
                        DB    0                 ; Locate cursor at occurrence
                        DB    0                 ; Locate cursor at position
                        DB    LOGIC_NO          ; Screen not changed
                        DB    CURSOR_OFF_SCREEN ; Cursor Position Row
                        DB    CURSOR_OFF_SCREEN ; Cursor Position Col
                        DW    ?                 ; Screen Name Address HIGH
                        DW    ?                 ; Screen Name Address LOW
                        DW    ?                 ; Text        Address HIGH
                        DW    ?                 ; Text        Address LOW
                        DW    NULL              ; Attribute   Address HIGH
                        DW    NULL              ; Attribute   Address LOW
                        DW    ?                 ; Valid Keys  Address HIGH
                        DW    ?                 ; Valid Keys  Address LOW
                        DW    ?                 ; Enter Keys  Address HIGH
                        DW    ?                 ; Enter Keys  Address LOW
                        DW    NULL              ; Field Area  Address HIGH
                        DW    NULL              ; Field Area  Address LOW
Ws_E6_Name              DB    "ERROR6  "
Ws_E6_Keys              DB    KEY_ANY
                        DB    NULL
;                                       1         2         3         4         5         6         7         8
;                              ....5....0....5....0....5....0....5....0....5....0....5....0....5....0....5....0
Ws_E6_Text              DB                                   "ÉÍÍÍÍÍÍÍÍÍÍÍ[Disk Density Error]ÍÍÍÍÍÍÍÍÍÍÍ»"
                        DB                                   "º                                          º"
                        DB                                   "º The directories/files in the selected    º"
                        DB                                   "º directory or directories will not fit on º"
                        DB                                   "º the disk image which you have selected.  º"
                        DB                                   "º Please choose another disk density.      º"
                        DB                                   "º                                          º"
                        DB                                   "ºEsc or Any key=Confirm                    º"
                        DB                                   "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼"
                        DB    NULL



;**********************************************************************
; E R R O R - D I R E C T O R I E S / F I L E S   N E V E R   F I T   *
;**********************************************************************
Ws_E7                   DB    WSIO_DISPLAY_ONLY
                        DB    9                 ; Start of screen ROW
                        DB   32                 ; Start of screen COLUMN
                        DB   17                 ; End of screen ROW
                        DB   75                 ; End of screen COLUMN
                        DB    ATTRIB_RED_WHITE  ; Screen attribute
                        DB    0                 ; Field attribute
                        DB    0                 ; Select attribute
                        DB    0                 ; Error attribute
                        DB    0                 ; Mouse support
                        DB    0                 ; Locate cursor at field
                        DB    0                 ; Locate cursor at occurrence
                        DB    0                 ; Locate cursor at position
                        DB    LOGIC_NO          ; Screen not changed
                        DB    CURSOR_OFF_SCREEN ; Cursor Position Row
                        DB    CURSOR_OFF_SCREEN ; Cursor Position Col
                        DW    ?                 ; Screen Name Address HIGH
                        DW    ?                 ; Screen Name Address LOW
                        DW    ?                 ; Text        Address HIGH
                        DW    ?                 ; Text        Address LOW
                        DW    NULL              ; Attribute   Address HIGH
                        DW    NULL              ; Attribute   Address LOW
                        DW    ?                 ; Valid Keys  Address HIGH
                        DW    ?                 ; Valid Keys  Address LOW
                        DW    ?                 ; Enter Keys  Address HIGH
                        DW    ?                 ; Enter Keys  Address LOW
                        DW    NULL              ; Field Area  Address HIGH
                        DW    NULL              ; Field Area  Address LOW
Ws_E7_Name              DB    "ERROR7  "
Ws_E7_Keys              DB    KEY_ANY
                        DB    NULL
;                                       1         2         3         4         5         6         7         8
;                              ....5....0....5....0....5....0....5....0....5....0....5....0....5....0....5....0
Ws_E7_Text              DB                                   "ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍ[FATAL ERROR!]ÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»"
                        DB                                   "º                                          º"
                        DB                                   "º The directories/files in the selected    º"
                        DB                                   "º directory or directories will not fit on º"
                        DB                                   "º any available disk density at all!       º"
                        DB                                   "º Please reduce the number of files/dirs.  º"
                        DB                                   "º                                          º"
                        DB                                   "ºEsc or Any key=Confirm                    º"
                        DB                                   "ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼"
                        DB    NULL

ENDS    DSeg



;**********************************************************************
;               Extended Segments
;**********************************************************************
SEGMENT DSeg3 Word Public 'VTOCMAP'
VTOC_Map                DB   VTOC_MAP_LENGTH dup (SPACE)
ENDS    DSeg3



;**********************************************************************
;               Extended Segments
;**********************************************************************
; Example Dir to analyze: C:\MAIN\
; Example Dir structure : .......\A\
;                         .......\B\
;                         .......\B\F\
;                         .......\C\
;                         .......\D\
;                         .......\D\G\
;                         .......\D\H\
;                         .......\D\H\J
;                         .......\D\I\
;                         .......\E\
;                         .......\E\K
;
; Corresponding Global Table Layout:
;+---------------------+----------+----------+------------------+
;³ Directory Path Name ³ Dir Nr   ³ Dir Nr   ³ Dir Sector Link  ³
;³                     ³ Current  ³ From     ³ Starts At Sector ³
;+---------------------+----------+----------+------------------+
;³ C:\MAIN\*.*         ³   0001   ³   0000   ³       0005       ³
;³ C:\MAIN\A\*.*       ³   0002   ³   0001   ³       0007       ³
;³ C:\MAIN\B\*.*       ³   0003   ³   0001   ³       0011       ³
;³ C:\MAIN\C\*.*       ³   0004   ³   0001   ³       0013       ³
;³ C:\MAIN\D\*.*       ³   0005   ³   0001   ³       0016       ³
;³ C:\MAIN\E\*.*       ³   0006   ³   0001   ³       0018       ³
;³ C:\MAIN\B\F\*.*     ³   0007   ³   0003   ³       0020       ³
;³ C:\MAIN\D\G\*.*     ³   0008   ³   0005   ³       0022       ³
;³ C:\MAIN\D\H\*.*     ³   0009   ³   0005   ³       0024       ³
;³ C:\MAIN\D\I\*.*     ³   0010   ³   0005   ³       0026       ³
;³ C:\MAIN\D\H\J\*.*   ³   0011   ³   0009   ³       0035       ³
;³ C:\MAIN\E\K\*.*     ³   0012   ³   0006   ³       0037       ³
;+---------------------+----------+----------+------------------+
;
SEGMENT DSeg4 Word Public 'DIRS'
Pc_Dir_Map              DB   PC_DIR_MAP_LENGTH dup (SPACE)
ENDS    DSeg4



;**********************************************************************
SEGMENT CSeg Word Public 'CODE'
;**********************************************************************
;----------------------------------------------------------------------
;--  External Variables                                              --
;----------------------------------------------------------------------
        EXTRN   APPEND:proc             ; Glue 2 strings together
        EXTRN   APPENDX:proc            ; Glue 2 strings together using "\" as target
        EXTRN   DC_DIRS:proc            ; Determine Current Directories
        EXTRN   DC_FILES:proc           ; Determine Current Files
        EXTRN   FMSIO:proc              ; File Management System Handler
        EXTRN   HEX2DIGI:proc           ; Convert Hex Data To Digits (Text)
        EXTRN   WSIO:proc               ; Screen Handler



;**********************************************************************
PROC    D_SPARTA
;**********************************************************************
        ASSUME  cs:CSeg
        ASSUME  ds:DSeg
        mov     ax, DSeg                        ; Initialize DS to address
        mov     ds, ax                          ; of data segment

        mov     bx, sp

;
; Parameter Directory to ATR
;
        mov     di, [ss:bx+42]
        mov     es, [ss:bx+44]

        mov     [Parm_Dir_From_ptr_es], es
        mov     [Parm_Dir_From_ptr_di], di

;
; Parameter Disk Location
;
        mov     di, [ss:bx+38]
        mov     es, [ss:bx+40]

        mov     [Parm_Disk_To_ptr_es], es
        mov     [Parm_Disk_To_ptr_di], di

;
; Parameter To Disk Format
;
        mov     di, [ss:bx+34]
        mov     es, [ss:bx+36]

        mov     al, [byte es:di]
        mov     [Disk_Format], al

;
; Parameter To Disk Density
;
        mov     di, [ss:bx+30]
        mov     es, [ss:bx+32]

        mov     al, [byte es:di]
        mov     [Disk_Media_Type], al

;
; Parameter To ATR or XFD
;
        mov     [Parm_XFD_Format], LOGIC_NO

        mov     di, [ss:bx+26]
        mov     es, [ss:bx+28]

        mov     al, [byte es:di]
        cmp     [byte es:di], "X"                       ; XFD format?
        jne     @@10                                    ; No
                                                        ; Yes, so
        mov     [Parm_XFD_Format], LOGIC_YES

@@10:
;
; Parameter To DOS Path
;
        mov     di, [ss:bx+22]
        mov     es, [ss:bx+24]

        mov     [Parm_DOS_Path_ptr_es], es
        mov     [Parm_DOS_Path_ptr_di], di

;
; Parameter To Include DOS
;
        mov     di, [ss:bx+18]
        mov     es, [ss:bx+20]

        mov     [Parm_INCLUDE_DOS_ptr_es], es
        mov     [Parm_INCLUDE_DOS_ptr_di], di

;
; Parameter To Use MAIN DIR SpartaDos
;
        mov     di, [ss:bx+14]
        mov     es, [ss:bx+16]

        mov     [Parm_MAIN_DIR_ptr_es], es
        mov     [Parm_MAIN_DIR_ptr_di], di

;
; Parameter Directory Map
;
        mov     di, [ss:bx+10]
        mov     es, [ss:bx+12]

        mov     [Parm_Dir_Map_ptr_es], es
        mov     [Parm_Dir_Map_ptr_di], di

;
; Parameter To CLI Used Yes or No
;
        mov     di, [ss:bx+6]
        mov     es, [ss:bx+8]

        mov     [Parm_CLI_Used_ptr_es], es
        mov     [Parm_CLI_Used_ptr_di], di
        mov     cl, [byte es:di]
        mov     [CLI_Used], cl

;
; Parameter To Include Subdirectories (in case of CLI)
;
        mov     di, [ss:bx+2]
        mov     es, [ss:bx+4]

        mov     [Parm_InclDirs_ptr_es], es
        mov     [Parm_InclDirs_ptr_di], di
        mov     cl, [byte es:di]
        mov     [CLI_Include_Subdirs], cl

        call    Init_Program
        call    Init_Screens
        call    Init_Files

@@20:
;-------------------------------------------
; Check for the presence of (sub)directories
;-------------------------------------------
        call    Check_Presence_Of_Pc_Subdirs

;
; Error encountered or Cancel pressed?
;
        cmp     al, KEY_ESC
        je      @@99

;------------------------
; Display Progress Screen
;------------------------
        call    Set_Up_Progress_Bar

;
; Initialize disk image name
;
        mov     si, offset Ws_CF_D_Add_Disk
        push    ds si
        pop     di es
        mov     cx, FILE_NAME_LENGTH
        xor     ax, ax
        mov     al, SPACE
        rep     stosb

;
; Message "None"
;
        mov     si, offset Ws_CF_F_Add_File
        push    ds si
        pop     di es

        mov     si, offset Ws_CF_D_No_Message
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@25                                    ; Yes
                                                        ; No, so
;
; Display it
;
        mov     si, offset Ws_CF
        mov     [byte ds:si], WSIO_DISPLAY_ONLY

        push    ds si
        call    WSIO
        pop     si ds

@@25:
;----------------------------------
; Process Files or (sub)directories
;----------------------------------
        cmp     [Ws_IS_D_Subdirs_Yes_No], "N"           ; Include Subdirectories
        je      @@40                                    ; No
                                                        ; Yes, so
@@30:
;-----------------------------------------------
; Process the (sub)directories (and their files)
;-----------------------------------------------
        call    Create_Disk_Image_With_Dirs
        jmp     @@99

@@40:
;-------------------
; Process Files Only
;-------------------
        call    Create_Disk_Image_No_Dirs

@@99:
        ret

ENDP    D_SPARTA



;**********************************************************************
PROC    Init_Program
;**********************************************************************
        xor     ax, ax
        mov	ah, DOS_SET_MEMORY_BLOCK_SIZE           ; resize the psp memory
        xor     bx, bx
        int	DOS_SERVICE

        ASSUME  ds:DSeg3
        mov     ax, DSeg3                               ; Initialize ds to address
        mov     ds, ax                                  ; of data segment
 
        mov     si, offset VTOC_Map
        push    ds si
        pop     di es

        ASSUME  ds:DSeg
        mov     ax, DSeg                                ; Initialize ds to address
        mov     ds, ax                                  ; of data segment

        mov     [VTOC_Map_ptr_es], es
        mov     [VTOC_Map_ptr_di], di

        ASSUME  ds:DSeg4
        mov     ax, DSeg4                               ; Initialize ds to address
        mov     ds, ax                                  ; of data segment
 
        mov     si, offset Pc_Dir_Map
        push    ds si
        pop     di es

        ASSUME  ds:DSeg
        mov     ax, DSeg                                ; Initialize ds to address
        mov     ds, ax                                  ; of data segment

        mov     [Pc_Dir_Map_ptr_es], es
        mov     [Pc_Dir_Map_ptr_di], di

        mov     [Disk_Sector_Size], EIGHTBIT_SECTOR_SIZE

        cmp     [Disk_Media_Type], DISK_MEDIA_TYPE_SINGLE
        je      @@10                                    ; Yes
                                                        ; No, so
        cmp     [Disk_Media_Type], DISK_MEDIA_TYPE_MEDIUM
        je      @@10                                    ; Yes
                                                        ; No, so
        mov     [Disk_Sector_Size], EIGHTBIT_SECTOR_SIZE_DOUBLE

@@10:
        mov     [Include_DOS_Files], LOGIC_NO
        mov     es, [Parm_INCLUDE_DOS_ptr_es]
        mov     di, [Parm_INCLUDE_DOS_ptr_di]
        cmp     [byte es:di], SPACE
        je      @@20                            ; No
                                                ; Yes, so
        mov     [Include_DOS_Files], LOGIC_YES

@@20:
        call    Setup_Pathname_ATARI_DOS

@@99:
        ret

ENDP    Init_Program



;**********************************************************************
PROC    Init_Screens
;**********************************************************************
;
; Init screen IS=Include Subdirectories
;
        mov     si, offset Ws_IS
        push    ds si
        pop     di es

        mov     si, offset Ws_IS_Name
        mov     [(Wsio_Area ptr di).Name_Address_Hi], ds
        mov     [(WSio_Area ptr di).Name_Address_Lo], si

        mov     si, offset Ws_IS_Keys
        mov     [(Wsio_Area ptr di).Keys_Address_Hi], ds
        mov     [(WSio_Area ptr di).Keys_Address_Lo], si

        mov     si, offset Ws_IS_Text
        mov     [(Wsio_Area ptr di).Text_Address_Hi], ds
        mov     [(WSio_Area ptr di).Text_Address_Lo], si

        mov     si, offset Ws_IS_F_Subdirs_Yes_No
        mov     [(Wsio_Area ptr di).Field_Address_Hi], ds
        mov     [(WSio_Area ptr di).Field_Address_Lo], si

        push    ds si
        pop     di es

        mov     si, offset Ws_IS_D_Subdirs_Yes_No
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si
        mov     si, offset Yes_No_Field
        mov     [(Wsio_Field ptr di).Keys_Address_Hi], ds
        mov     [(WSio_Field ptr di).Keys_Address_Lo], si

        mov     si, offset Ws_IS_F_Key_Enter

        push    ds si
        pop     di es

        mov     si, offset Ws_IS_D_Key_Enter
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

        mov     si, offset Ws_IS_F_Key_Esc

        push    ds si
        pop     di es

        mov     si, offset Ws_IS_D_Key_Esc
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

;
; Init screen SV=SpartaDos Volume name
;
        mov     si, offset WS_SV
        push    ds si
        pop     di es

        mov     si, offset WS_SV_Name
        mov     [(Wsio_Area ptr di).Name_Address_Hi], ds
        mov     [(WSio_Area ptr di).Name_Address_Lo], si

        mov     si, offset WS_SV_Keys
        mov     [(Wsio_Area ptr di).Keys_Address_Hi], ds
        mov     [(WSio_Area ptr di).Keys_Address_Lo], si

        mov     si, offset WS_SV_Text
        mov     [(Wsio_Area ptr di).Text_Address_Hi], ds
        mov     [(WSio_Area ptr di).Text_Address_Lo], si

        mov     si, offset Ws_SV_F_Volume_Name
        mov     [(Wsio_Area ptr di).Field_Address_Hi], ds
        mov     [(WSio_Area ptr di).Field_Address_Lo], si

        push    ds si
        pop     di es

        mov     si, offset Ws_SV_D_Volume_Name
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

        mov     si, offset Ws_SV_F_Key_Enter

        push    ds si
        pop     di es

        mov     si, offset Ws_SV_D_Key_Enter
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

        mov     si, offset Ws_SV_F_Key_Esc

        push    ds si
        pop     di es

        mov     si, offset Ws_SV_D_Key_Esc
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

;
; Init screen AD=AddDisks
;
        mov     si, offset Ws_AD
        push    ds si
        pop     di es

        mov     si, offset Ws_AD_Name
        mov     [(Wsio_Area ptr di).Name_Address_Hi], ds
        mov     [(WSio_Area ptr di).Name_Address_Lo], si

        mov     si, offset Ws_AD_Keys
        mov     [(Wsio_Area ptr di).Keys_Address_Hi], ds
        mov     [(WSio_Area ptr di).Keys_Address_Lo], si

        mov     si, offset Ws_AD_Text
        mov     [(Wsio_Area ptr di).Text_Address_Hi], ds
        mov     [(WSio_Area ptr di).Text_Address_Lo], si

        mov     si, offset Ws_AD_F_Add_Where
        mov     [(Wsio_Area ptr di).Field_Address_Hi], ds
        mov     [(WSio_Area ptr di).Field_Address_Lo], si

        push    ds si
        pop     di es

        mov     si, offset Ws_AD_D_Add_Where
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si
        mov     si, offset End_Begin_Field
        mov     [(Wsio_Field ptr di).Keys_Address_Hi], ds
        mov     [(WSio_Field ptr di).Keys_Address_Lo], si

        mov     si, offset Ws_AD_F_Key_Enter

        push    ds si
        pop     di es

        mov     si, offset Ws_AD_D_Key_Enter
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

        mov     si, offset Ws_AD_F_Key_Esc

        push    ds si
        pop     di es

        mov     si, offset Ws_AD_D_Key_Esc
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

;
; Init screen CF=Create ATR Disk Image containing pc Files
;
        mov     si, offset Ws_CF
        push    ds si
        pop     di es

        mov     si, offset Ws_CF_Name
        mov     [(Wsio_Area ptr di).Name_Address_Hi], ds
        mov     [(WSio_Area ptr di).Name_Address_Lo], si

        mov     si, offset Ws_CF_Text
        mov     [(Wsio_Area ptr di).Text_Address_Hi], ds
        mov     [(WSio_Area ptr di).Text_Address_Lo], si

; Field 1
        mov     si, offset Ws_CF_F_Progress_Bar
        mov     [(Wsio_Area ptr di).Field_Address_Hi], ds
        mov     [(WSio_Area ptr di).Field_Address_Lo], si

        push    ds si
        pop     di es

        mov     si, offset Ws_CF_D_Progress_Bar
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

        mov     si, offset Ws_CF_D_Progress_Bar_Attr
        mov     [(Wsio_Field ptr di).Attrib_Address_Hi], ds
        mov     [(WSio_Field ptr di).Attrib_Address_Lo], si

; Field 2
        mov     si, offset Ws_CF_F_Add_Disk
        push    ds si
        pop     di es

        mov     si, offset Ws_CF_D_Add_Disk
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

; Field 3
        mov     si, offset Ws_CF_F_Add_Dir
        push    ds si
        pop     di es

        mov     si, offset Ws_CF_D_Add_Dir
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

; Field 4
        mov     si, offset Ws_CF_F_Add_File
        push    ds si
        pop     di es

        mov     si, offset Ws_CF_D_Add_File
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

;
; Init screen FF=Format ATR Disk Image
;
        mov     si, offset Ws_FF
        push    ds si
        pop     di es

        mov     si, offset Ws_FF_Name
        mov     [(Wsio_Area ptr di).Name_Address_Hi], ds
        mov     [(WSio_Area ptr di).Name_Address_Lo], si

        mov     si, offset Ws_FF_Text
        mov     [(Wsio_Area ptr di).Text_Address_Hi], ds
        mov     [(WSio_Area ptr di).Text_Address_Lo], si

; Field 1
        mov     si, offset Ws_FF_F_Progress_Bar
        mov     [(Wsio_Area ptr di).Field_Address_Hi], ds
        mov     [(WSio_Area ptr di).Field_Address_Lo], si

        push    ds si
        pop     di es

        mov     si, offset Ws_FF_D_Progress_Bar
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

        mov     si, offset Ws_FF_D_Progress_Bar_Attr
        mov     [(Wsio_Field ptr di).Attrib_Address_Hi], ds
        mov     [(WSio_Field ptr di).Attrib_Address_Lo], si

;
; Init screen AN=Analyzing Disk
;
        mov     si, offset Ws_AN
        push    ds si
        pop     di es

        mov     si, offset Ws_AN_Name
        mov     [(Wsio_Area ptr di).Name_Address_Hi], ds
        mov     [(WSio_Area ptr di).Name_Address_Lo], si

        mov     si, offset Ws_AN_Text
        mov     [(Wsio_Area ptr di).Text_Address_Hi], ds
        mov     [(WSio_Area ptr di).Text_Address_Lo], si

;
; Init screen VS=Vtoc Structure
;
        mov     si, offset Ws_VS
        push    ds si
        pop     di es

        mov     si, offset Ws_VS_Name
        mov     [(Wsio_Area ptr di).Name_Address_Hi], ds
        mov     [(WSio_Area ptr di).Name_Address_Lo], si

        mov     si, offset Ws_VS_Text
        mov     [(Wsio_Area ptr di).Text_Address_Hi], ds
        mov     [(WSio_Area ptr di).Text_Address_Lo], si

;
; Init screen E1=Error Screen - Drive Not Ready
;
        mov     si, offset Ws_E1
        push    ds si
        pop     di es

        mov     si, offset Ws_E1_Name
        mov     [(Wsio_Area ptr di).Name_Address_Hi], ds
        mov     [(WSio_Area ptr di).Name_Address_Lo], si

        mov     si, offset Ws_E1_Keys
        mov     [(Wsio_Area ptr di).Keys_Address_Hi], ds
        mov     [(WSio_Area ptr di).Keys_Address_Lo], si

        mov     si, offset Ws_E1_Text
        mov     [(Wsio_Area ptr di).Text_Address_Hi], ds
        mov     [(WSio_Area ptr di).Text_Address_Lo], si

;
; Init screen E2=Error Screen - I/O ERROR
;
        mov     si, offset Ws_E2
        push    ds si
        pop     di es

        mov     si, offset Ws_E2_Name
        mov     [(Wsio_Area ptr di).Name_Address_Hi], ds
        mov     [(WSio_Area ptr di).Name_Address_Lo], si

        mov     si, offset Ws_E2_Keys
        mov     [(Wsio_Area ptr di).Keys_Address_Hi], ds
        mov     [(WSio_Area ptr di).Keys_Address_Lo], si

        mov     si, offset Ws_E2_Text
        mov     [(Wsio_Area ptr di).Text_Address_Hi], ds
        mov     [(WSio_Area ptr di).Text_Address_Lo], si

        mov     si, offset Ws_E2_F_Error_Message
        mov     [(Wsio_Area ptr di).Field_Address_Hi], ds
        mov     [(WSio_Area ptr di).Field_Address_Lo], si

        push    ds si
        pop     di es

        mov     si, offset Ws_E2_D_General_I_O_Error
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

;
; Init screen E5=Too many files in a directory encountered for this DOS format
;
        mov     si, offset Ws_E5
        push    ds si
        pop     di es

        mov     si, offset Ws_E5_Name
        mov     [(Wsio_Area ptr di).Name_Address_Hi], ds
        mov     [(WSio_Area ptr di).Name_Address_Lo], si

        mov     si, offset Ws_E5_Keys
        mov     [(Wsio_Area ptr di).Keys_Address_Hi], ds
        mov     [(WSio_Area ptr di).Keys_Address_Lo], si

        mov     si, offset Ws_E5_Text
        mov     [(Wsio_Area ptr di).Text_Address_Hi], ds
        mov     [(WSio_Area ptr di).Text_Address_Lo], si

        mov     si, offset Ws_E5_F_Key_Enter
        mov     [(Wsio_Area ptr di).Field_Address_Hi], ds
        mov     [(WSio_Area ptr di).Field_Address_Lo], si

        push    ds si
        pop     di es

        mov     si, offset Ws_E5_D_Key_Enter
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

        mov     si, offset Ws_E5_F_Key_Esc

        push    ds si
        pop     di es

        mov     si, offset Ws_E5_D_Key_Esc
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

;
; Init screen E6=Directories/Files won't fit on disk
;
        mov     si, offset Ws_E6
        push    ds si
        pop     di es

        mov     si, offset Ws_E6_Name
        mov     [(Wsio_Area ptr di).Name_Address_Hi], ds
        mov     [(WSio_Area ptr di).Name_Address_Lo], si

        mov     si, offset Ws_E6_Keys
        mov     [(Wsio_Area ptr di).Keys_Address_Hi], ds
        mov     [(WSio_Area ptr di).Keys_Address_Lo], si

        mov     si, offset Ws_E6_Text
        mov     [(Wsio_Area ptr di).Text_Address_Hi], ds
        mov     [(WSio_Area ptr di).Text_Address_Lo], si

;
; Init screen E7=Directories/Files won't fit on any disk
;
        mov     si, offset Ws_E7
        push    ds si
        pop     di es

        mov     si, offset Ws_E7_Name
        mov     [(Wsio_Area ptr di).Name_Address_Hi], ds
        mov     [(WSio_Area ptr di).Name_Address_Lo], si

        mov     si, offset Ws_E7_Keys
        mov     [(Wsio_Area ptr di).Keys_Address_Hi], ds
        mov     [(WSio_Area ptr di).Keys_Address_Lo], si

        mov     si, offset Ws_E7_Text
        mov     [(Wsio_Area ptr di).Text_Address_Hi], ds
        mov     [(WSio_Area ptr di).Text_Address_Lo], si

        ret

ENDP    Init_Screens



;**********************************************************************
PROC    Init_Files
;**********************************************************************
        mov     si, offset ATARI____File
        push    ds si
        pop     di es
        mov     si, offset ATARI____Pathname
        mov     [(FMS_Area ptr di).Path_Address_Hi], ds
        mov     [(FMS_Area ptr di).Path_Address_Lo], si
        mov     si, offset Disk_I_O_Buffer
        mov     [(FMS_Area ptr di).Data_Address_Hi], ds
        mov     [(FMS_Area ptr di).Data_Address_Lo], si
        mov     [(FMS_Area ptr di).Offset], ATR_HEADER_SIZE
        add     [(FMS_Area ptr di).Offset], DISK_BOOTCODE_SIZE

        mov     si, offset PC_ATARI_File
        push    ds si
        pop     di es
        mov     si, offset PC_ATARI_Pathname
        mov     [(FMS_Area ptr di).Path_Address_Hi], ds
        mov     [(FMS_Area ptr di).Path_Address_Lo], si
        ret

ENDP    Init_Files


;**********************************************************************
PROC    Set_Up_Progress_Bar
;**********************************************************************
        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@05                                    ; Yes
                                                        ; No, so
        mov     si, offset Ws_CF
        mov     [byte ds:si], WSIO_OPEN

        push    ds si
        call    WSIO
        pop     si ds

@@05:
;------------------------
; Initialize progress bar
;------------------------
        mov     si, offset Ws_CF_D_Progress_Bar
        push    ds si
        pop     di es
        xor     ax, ax
        mov     al, 0B0h
        xor     cx, cx
        mov     cl, [Ws_CF_Progress_Bar_Cnt_Max]
        rep     stosb

        mov     [Ws_CF_Progress_Bar_Cnt_Prev], 0
        mov     [Ws_CF_Progress_Bar_Cnt_Sectors_Hi], 0
        mov     [Ws_CF_Progress_Bar_Cnt_Sectors_Lo], 0
        mov     [Dir_Entry_Files], 0

@@99:
        ret

ENDP    Set_Up_Progress_Bar



;**********************************************************************
PROC    Check_Presence_Of_Pc_Subdirs
;**********************************************************************
        mov     [Ws_IS_D_Subdirs_Yes_No], "N"           ; Do Not Include Subdirectories

;-------------------------
; Clear Pc Directory Table
;-------------------------
        mov     es, [Pc_Dir_Map_ptr_es]
        mov     di, [Pc_Dir_Map_ptr_di]
        mov     cx, PC_DIR_MAP_LENGTH
        xor     ax, ax                                  ; Reset ax
        mov     al, NULL                                ; Fill character
        rep     stosb

;-----------------------
; Store "main" directory
;-----------------------
        push    ds si                                   ; Save program position

        mov     es, [Pc_Dir_Map_ptr_es]                 ; Store "main" directory
        mov     di, [Pc_Dir_Map_ptr_di]
        mov     ax, [Parm_Dir_From_ptr_es]
        mov     bx, [Parm_Dir_From_ptr_di]              ; Dir to ATR
        mov     cx, PATH_LENGTH
        push    ax bx
        pop     si ds
        rep     movsb                                   ; "Main" directory established

        mov     cx, 1                                   ; Very first directory
        mov     [es:di], cx

        pop     si ds                                   ; Restore program position

;------------------------------------------------------
; Determine maximum number of files per 8 bit directory
;------------------------------------------------------
        mov     [Dir_Dir_File_Counter_Max], DIR_ENTRY_FILES_MAX_SPARTADOS
        cmp     [Disk_Format], DISK_FORMAT_SPARTADOS    ; SpartaDos disk?
        je      @@05                                    ; Yes
                                                        ; No, so
        mov     [Dir_Dir_File_Counter_Max], DIR_ENTRY_FILES_MAX_SPARTADOSX
        cmp     [Disk_Format], DISK_FORMAT_SPARTADOSX   ; SpartaDos/X disk?
        je      @@05                                    ; Yes
                                                        ; No, so
        mov     [Dir_Dir_File_Counter_Max], DIR_ENTRY_FILES_MAX_BEWEDOS
        cmp     [Disk_Format], DISK_FORMAT_BEWEDOS      ; Bewe DOS disk?
        je      @@05                                    ; Yes
                                                        ; No, so
        mov     [Dir_Dir_File_Counter_Max], DIR_ENTRY_FILES_MAX_SPARTADOS

@@05:
;----------------------------------------------------
; Retrieve subdirectories in current pc path (if any)
;----------------------------------------------------
        mov     [Requested_Format_LibFil], "2"          ; Format "..           <DIR>      "
                                                        ;        "ATARI        <DIR>      "
        push    ds si                                   ; Save program entry

        mov     es, [Parm_Dir_From_ptr_es]              ; Determine path
        mov     di, [Parm_Dir_From_ptr_di]              ; disk to "read from" directory
        push    es di

        mov     si, offset Search_Dirs_Path
        push    ds si
        pop     di es

        pop     si ds
        mov     cx, PATH_LENGTH
        rep     movsb

        pop     si ds                                   ; Restore program entry

        call    Retrieve_Pc_Dirs                        ; Get dirs in directory

;----------------------------------
; Check for presence subdirectories
;----------------------------------
        mov     es, [Parm_Dir_Map_ptr_es]
        mov     di, [Parm_Dir_Map_ptr_di]               ; Directory Map

        jmp     @@20

@@10:
        add     di, DIR_ENTRY_LENGTH

@@20:
        cmp     [byte es:di], NULL                      ; Subdirectories absent?
        je      @@40                                    ; Yes
                                                        ; Maybe, so
        cmp     [byte es:di], DOT                       ; Root indicator?
        je      @@10                                    ; Yes
                                                        ; No, so
@@30:
        xor     ax, ax                                  ; Reset ax

        cmp     [CLI_Used], LOGIC_NO                    ; Command Line Interface used?
        je      @@35                                    ; No
                                                        ; Yes, so
        mov     cl, [CLI_Include_Subdirs]
        mov     [Ws_IS_D_Subdirs_Yes_No], cl
        
        cmp     [Ws_IS_D_Subdirs_Yes_No], "N"           ; Include Subdirs?
        je      @@90                                    ; No
                                                        ; Yes, so
        jmp     @@36

@@35:
;----------------------------------------
; Ask if we should include subdirectories
;----------------------------------------
        call    Display_Include_Subdirectories_Screen

        cmp     al, KEY_ESC
        je      @@99

@@36:
        cmp     [Ws_IS_D_Subdirs_Yes_No], "N"           ; Include Subdirectories
        je      @@40                                    ; No
                                                        ; Yes, so
;------------------------------------
; Retrieve SpartaDos Disk Volume Name
;------------------------------------
        call    Retrieve_SpartaDos_Volume_Name

        cmp     al, KEY_ESC
        je      @@30

        jmp     @@90

@@40:
        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@90                                    ; Yes
                                                        ; No, so
;-------------------------------------------------------------------------
; Ask if we should add the nnn.ATR images at the end or from the beginning
;-------------------------------------------------------------------------
        call    Check_Adding_Disk_Images_At_End

;--------------------
; Was Cancel pressed?
;--------------------
        cmp     al, KEY_ESC
        je      @@30

        cmp     [Disk_Adding], "N"
        je      @@90

        mov     ax, [Disk_Seq_Nr_Present]
        mov     [Disk_Seq_Nr], ax

@@90:
        push    ds si                                   ; Save program entry

        mov     es, [Parm_Dir_From_ptr_es]              ; Determine path
        mov     di, [Parm_Dir_From_ptr_di]              ; disk to "read from" directory
        push    es di

        mov     si, offset Search_Dirs_Path
        push    ds si
        pop     di es

        pop     si ds
        mov     cx, PATH_LENGTH
        rep     movsb

        pop     si ds                                   ; Restore program entry

        call    Analyze_Pc_Dirs_Files_Structure

@@99:
        ret

ENDP    Check_Presence_Of_Pc_Subdirs



;**********************************************************************
PROC    Display_Include_Subdirectories_Screen
;**********************************************************************
        mov     [Ws_IS_D_Subdirs_Yes_No], "Y"

        mov     si, offset Ws_IS
        mov     [byte ds:si], WSIO_OPEN

        push    ds si
        call    WSIO
        pop     di es

        mov     [(Wsio_Area ptr di).Cursor_Position_Row], NULL
        mov     [(WSio_Area ptr di).Cursor_Position_Col], NULL

@@50:
        mov     si, offset Ws_IS
        mov     [byte ds:si], WSIO_DISPLAY_AND_READ

        push    ds si
        call    WSIO
        pop     si ds

;--------------------
; Was Cancel pressed?
;--------------------
        cmp     al, KEY_ESC
        je      @@70

;------------------
; ENTER was pressed
;------------------
        cmp     ah, WSIO_MOUSE_PRESSED          ; Mouse pressed Enter?
        jne     @@70                            ; No
                                                ; Yes, so
;--------------------
; Mouse pressed ENTER
;--------------------
        push    ds si
        pop     di es
        xor     cx, cx
        mov     cl, [(Wsio_Area ptr di).Cursor_Position_Row]

;
; Check if a the Key Enter field was pressed
;
        cmp     cx, 17                          ; Enter key selected?
        je      @@70                            ; Yes
                                                ; No, so
;
; Subdirs Yes/No field was selected
;
        cmp     [Ws_IS_D_Subdirs_Yes_No], "Y"   ; Include subdirs?
        jne     @@60                            ; No
                                                ; Yes, so
        mov     [Ws_IS_D_Subdirs_Yes_No], "N"
        jmp     @@50

@@60:
        mov     [Ws_IS_D_Subdirs_Yes_No], "Y"
        jmp     @@50

@@70:
        push    ax

        mov     si, offset Ws_IS
        mov     [byte ds:si], WSIO_CLOSE

        push    ds si
        call    WSIO
        pop     si ds

        pop     ax

        ret

ENDP    Display_Include_Subdirectories_Screen



;**********************************************************************
PROC    Analyze_Pc_Dirs_Files_Structure
;**********************************************************************
        mov     [Too_Many_Files_In_Dir], LOGIC_NO
        mov     [Disk_Image_Not_Large_Enough], LOGIC_NO

        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@05                                    ; Yes
                                                        ; No, so
;----------------------------------------------
; Please wait, analyzing directory structure...
;----------------------------------------------
        mov     si, offset Ws_AN
        mov     [byte ds:si], WSIO_OPEN

        push    ds si
        call    WSIO
        pop     di es

        mov     si, offset Ws_AN
        mov     [byte ds:si], WSIO_DISPLAY_ONLY

        push    ds si
        call    WSIO
        pop     si ds

@@05:
;-----------------------------
; Initialize pointers/counters
;-----------------------------
        mov     [Ws_CF_Progress_Bar_Sectors_Hi], 0      ; Reset counter
        mov     [Ws_CF_Progress_Bar_Sectors_Lo], 0      ; Reset counter

;----------------------------------------------------------------------------
; 3 boot sectors and at least 1 bitmap sector = 4 sectors are always occupied
;----------------------------------------------------------------------------
        mov     [Sector_Counter_VTOC], 0                ; Reset counter
        mov     [Sector_Counter], DISK_BOOTCODE_SECTOR_SIZE
        mov     [Disk_Sectors_Bitmap], 1                ; At least 1 bitmap sector

        mov     [Disk_Sectors], DISK_SECTORS_SINGLE
        cmp     [Disk_Media_Type], DISK_MEDIA_TYPE_SINGLE
        je      @@10                                    ; Yes
                                                        ; No, so
        mov     [Disk_Sectors], DISK_SECTORS_MEDIUM
        cmp     [Disk_Media_Type], DISK_MEDIA_TYPE_MEDIUM
        je      @@10                                    ; Yes
                                                        ; No, so
        mov     [Disk_Sectors], DISK_SECTORS_DOUBLE
        cmp     [Disk_Media_Type], DISK_MEDIA_TYPE_DOUBLE

        je      @@10                                    ; Yes
                                                        ; No, so
        mov     [Disk_Sectors], DISK_SECTORS_QUAD
        cmp     [Disk_Media_Type], DISK_MEDIA_TYPE_QUAD
        je      @@10                                    ; Yes
                                                        ; No, so
        mov     [Disk_Sectors_Bitmap], 2                ; This size needs 2 bitmap sectors
        mov     [Disk_Sectors], DISK_SECTORS_720KB
        cmp     [Disk_Media_Type], DISK_MEDIA_TYPE_720KB
        je      @@10                                    ; Yes
                                                        ; No, so
        mov     [Disk_Sectors], DISK_SECTORS_1440KB
        cmp     [Disk_Media_Type], DISK_MEDIA_TYPE_1440KB
        je      @@10                                    ; Yes
                                                        ; No, so
        mov     [Disk_Sectors_Bitmap], 32               ; This size needs 32 bitmap sectors
        mov     [Disk_Sectors], DISK_SECTORS_HARDDISK   ; Harddisk 16 MB

@@10:
;-------------------------------------
; Add bitmap sectors to sector counter
;-------------------------------------
        mov     ax, [Disk_Sectors_Bitmap]
        add     [Sector_Counter], ax

;---------------------
; Include DOS (files)?
;---------------------
        cmp     [Include_DOS_Files], LOGIC_NO
        je      @@30                                    ; No
                                                        ; Yes, so
;--------------------------------------------------------
; Determine File Size in sectors (and remainder of bytes)
;--------------------------------------------------------
        call    Determine_Pathname_Filesize_XL_DOS_File

        cmp     [Dir2atr_Error], LOGIC_YES              ; Error encountered?
        je      @@30                                    ; Yes
                                                        ; No, so
        mov     ax, [File_Size_In_Sectors]
        add     [Sector_Counter], ax

@@30:
;----------------------------------------------------------
; Save maximum file size which will fit on this disk medium
;----------------------------------------------------------
        xor     dx, dx
        mov     ax, [Disk_Sectors]
        sub     ax, [Sector_Counter]
        sub     ax, MINIMUM_NR_OF_VTOC_SECTORS

        xor     cx, cx
        mov     bx, SECTOR_COUNT_LINK_SECTOR_SINGLE

        cmp     [Disk_Sector_Size], EIGHTBIT_SECTOR_SIZE
        je      @@35                                    ; Yes
                                                        ; No, so
        add     ax, MINIMUM_NR_OF_VTOC_SECTORS
        sub     ax, MINIMUM_NR_OF_VTOC_SECTORS_DOUBLE
        mov     bx, SECTOR_COUNT_LINK_SECTOR_DOUBLE

@@35:
;
; Take care of link sectors
;
        sub     ax, RESERVE_NR_OF_SECTORS_VTOC_SPACE
        mov     [Max_File_Size_In_Sectors], ax

        call    Calculate_Nr_Of_Link_Sectors

        sub     [Max_File_Size_In_Sectors], bx          ; Subtract link sectors

;----------------------------------------
; Analyze Directory (and Files) structure
;----------------------------------------
        call    Analyze_Pc_Dirs_Structure

        cmp     [Disk_Image_Not_Large_Enough], LOGIC_YES
        jne     @@50                                    ; No
                                                        ; Yes, so
        cmp     [Disk_Media_Type], DISK_MEDIA_TYPE_HARDDISK
        je      @@40                                    ; Yes
                                                        ; No, so
;
; Too many directories/files to fit on the selected disk image
;
        call    Error_E6_Too_Many_Files_Dirs
        jmp     @@50

@@40:
;
; Too many directories/files to fit on any disk image
;
        call    Error_E7_Too_Many_Files_Dirs

@@50:
        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@99                                    ; Yes
                                                        ; No, so
;-------------------------
; Close analyzation screen
;-------------------------
        push    ax

        mov     si, offset Ws_AN
        mov     [byte ds:si], WSIO_CLOSE

        push    ds si
        call    WSIO
        pop     di es

        pop     ax

@@99:
        ret

ENDP    Analyze_Pc_Dirs_Files_Structure



;**********************************************************************
PROC    Analyze_Pc_Dirs_Structure
;**********************************************************************
        mov     [Dir_Curr_ptr], 1                       ; Reset pointer
        mov     [Dir_To_ptr], 1                         ; Reset pointer
        mov     es, [Pc_Dir_Map_ptr_es]                 ; Directory to check
        mov     di, [Pc_Dir_Map_ptr_di]
        jmp     @@20

@@10:
        add     di, PC_DIR_MAP_ENTRY_LENGTH             ; Next entry into table
        inc     [Dir_Curr_ptr]                          ; Next dir entry

@@20:
        push    es di                                   ; Save current dir entry position
        cmp     [byte es:di], NULL                      ; Empty entry?
        je      @@80                                    ; Yes
                                                        ; No, so
        cmp     [Ws_IS_D_Subdirs_Yes_No], "N"           ; Include Subdirectories
        jne     @@25                                    ; Yes
                                                        ; No, so
;--------------------------------------
; Only check files in current directory
;--------------------------------------
        mov     [Disk_Sectors_VTOC], MINIMUM_NR_OF_VTOC_SECTORS

        cmp     [Disk_Sector_Size], EIGHTBIT_SECTOR_SIZE
        je      @@22                                    ; Yes
                                                        ; No, so
        mov     [Disk_Sectors_VTOC], MINIMUM_NR_OF_VTOC_SECTORS_DOUBLE

@@22:
        xor     ax, ax                                  ; Reset ax
        call    Analyze_Pc_Files_Structure
        jmp     @@90

@@25:
;-------------------------------------------------
; Retrieve all subdirectories in current directory
;-------------------------------------------------
        push    ds si                                   ; Save program entry
        push    es di                                   ; Save entry position

        mov     si, offset Search_Dirs_Path             ; Copy entry to search path
        push    ds si
        pop     di es

        pop     si ds                                   ; Restore entry position
        mov     cx, PATH_LENGTH
        rep     movsb

        pop     si ds                                   ; Restore program entry

        mov     [Requested_Format_LibFil], "2"          ; Format "..           <DIR>      "
                                                        ;        "ATARI        <DIR>      "
        call    Retrieve_Pc_Dirs

        mov     es, [Parm_Dir_Map_ptr_es]
        mov     di, [Parm_Dir_Map_ptr_di]               ; Directory Map

        mov     [Dir_Dir_Counter], 1                    ; Reset counter
        jmp     @@40

@@30:
        add     di, DIR_ENTRY_LENGTH

@@40:
        cmp     [byte es:di], NULL                      ; End of table reached?
        je      @@60                                    ; Yes
                                                        ; No, so
        cmp     [byte es:di], DOT                       ; Directory indicator?
        je      @@30                                    ; Yes
                                                        ; No, so
;----------------
; Directory entry
;----------------
        inc     [Dir_Dir_Counter]
        inc     [Dir_To_ptr]                            ; Next entry

        push    es di                                   ; Save directory entry position
        push    ds si                                   ; Save program entry
        push    es di                                   ; Save directory entry position

;-----------------------------------------
; Copy Directory entry to Pc Dir Map table
;-----------------------------------------
        mov     es, [Pc_Dir_Map_ptr_es]                 ; Directory to check
        mov     di, [Pc_Dir_Map_ptr_di]
        mov     cx, [Dir_To_ptr]                        ; Offset into table
        jmp     @@55

@@50:
        add     di, PC_DIR_MAP_ENTRY_LENGTH             ; Next entry into table

@@55:
        loop    @@50

        push    es di                                   ; Save To directory entry position
        pop     dx bx                                   ; Save in registers bx dx

        mov     si, offset Search_Dirs_Path
        mov     cx, PATH_LENGTH
        rep     movsb

;--------------------------
; Search "\" at end of path
;--------------------------
        std                                             ; Search direction is down
        mov     ax, BACKSLASH                           ; Search for "\"
        mov     cx, PATH_LENGTH
        repne   scasb                                   ; Search uses es:di
        cld                                             ; Cancel the std setting
        inc     di                                      ; Pointer adjustment after search
        inc     di                                      ; Position after "\"

;----------------------------------------
; Add directory entry name to end of path
;----------------------------------------
        pop     si ds                                   ; Restore directory entry position
        mov     cx, DIR_NAME_LENGTH
        rep     movsb                                   ; Copied

        pop     si ds                                   ; Restore program entry

;----------------------
; At "\" at end of path
;----------------------
        dec     di                                      ; Pointer correction after copy
        std                                             ; Search direction is down
        mov     ax, SPACE                               ; Search for non SPACE
        mov     cx, DIR_NAME_LENGTH
        repe    scasb                                   ; Search uses es:di
        cld                                             ; Cancel the std setting
        inc     di                                      ; Pointer adjustment after search
        inc     di                                      ; Position after last letter
        mov     [byte es:di], BACKSLASH                 ; Add "\" at end

;------------------------
; At "*.*" at end of path
;------------------------
        inc     di                                      ; Position after "\"
        mov     si, offset File_Mask
        mov     cx, FILE_NAME_LENGTH
        rep     movsb

        push    bx dx                                   ; Restore registers bx dx
        pop     di es                                   ; Restore To directory entry position
        add     di, PATH_LENGTH
        mov     cx, [Dir_To_ptr]                        ; Dir nr curr
        mov     [es:di], cx
        mov     cx, [Dir_Curr_ptr]                      ; Dir nr from
        mov     [es:di + 2], cx

        pop     di es                                   ; Restore directory entry position
        jmp     @@30                                    ; Check next entry

@@60:
;---------------------------------
; Check files in current directory
;---------------------------------
        xor     ax, ax                                  ; Reset ax
        call    Analyze_Pc_Files_Structure

;
; Check disk size
;
        cmp     [Disk_Image_Not_Large_Enough], LOGIC_YES
        je      @@99

        pop     di es                                   ; Restore entry into pc dir map table

        jmp     @@10

@@80:
;----------------------------------------------------------------------------
; When we include directories, we know the exact vtoc size due to calculation
;----------------------------------------------------------------------------
        mov     ax, [Sector_Counter_VTOC]

;
; Besides we reserve nnn sectors for additional (new) VTOC entries
;
        add     ax, RESERVE_NR_OF_SECTORS_VTOC_SPACE
        mov     [Disk_Sectors_VTOC], ax

@@90:
;----------------------------------------------------------------------------
; Check if the selected directories/files will fit on the selected disk image
;----------------------------------------------------------------------------
        clc                                             ; Clear carry
        mov     ax, [Disk_Sectors]                      ; Nr of sectors we have
        sub     ax, [Sector_Counter]                    ; Nr of sectors we need
        jnc     @@99                                    ; Enough sectors
                                                        ; No, so
        mov     [Disk_Image_Not_Large_Enough], LOGIC_YES

@@99:
        pop     di es

        ret

ENDP    Analyze_Pc_Dirs_Structure



;**********************************************************************
PROC    Analyze_Pc_Files_Structure
;**********************************************************************
        mov     [Requested_Format_LibFil], "1"          ; For format see DIRENTRY.STR
        call    Retrieve_Pc_Files

        mov     es, [Parm_Dir_Map_ptr_es]
        mov     di, [Parm_Dir_Map_ptr_di]               ; Directory Map

        mov     [Dir_File_Counter], 0                   ; Reset counter

        jmp     @@20

@@10:
        add     di, DIR_ENTRY_LENGTH

@@20:
        cmp     [byte es:di], NULL                      ; End of table reached?
        je      @@50                                    ; Yes
                                                        ; No, so
;-----------
; File entry
;-----------
        inc     [Dir_File_Counter]

        push    es di                                   ; Save file entry pointer

;---------------------------------------
; If file won't fit on image, we skip it
;---------------------------------------
        call    Check_If_File_Fits_On_Image

        pop     di es                                   ; Restore file entry position

        cmp     [Dir_Entry_Fits_On_Image], LOGIC_YES
        jne     @@10                                    ; No
                                                        ; Yes, so
;-------------------------------------------------
; Determine number of sectors for the progress bar
;-------------------------------------------------
        mov     ax, [File_Size_In_Sectors]
        clc                                             ; Clear carry
        add     [Ws_CF_Progress_Bar_Sectors_Lo], ax
        jnc     @@25
        inc     [Ws_CF_Progress_Bar_Sectors_Hi]

@@25:
;----------------------------------------------------------
; If no subdirectories are included, we don't count sectors
; because we can write multiple disk images
;----------------------------------------------------------
        cmp     [Ws_IS_D_Subdirs_Yes_No], "N"           ; Include Subdirectories
        je      @@10                                    ; No
                                                        ; Yes, so
        call    Calculate_Nr_Of_Link_Sectors

;---------------------
; File(s) sector count
;---------------------
        clc                                             ; Clear carry flag
        add     [Sector_Counter], ax
        jnc     @@30                                    ; Disk still large enough
        mov     [Disk_Image_Not_Large_Enough], LOGIC_YES
        jmp     @@99

@@30:
;----------------------------------------------------------------
; Check nr of files counted against maximum number of files value
;----------------------------------------------------------------
        mov     bx, [Dir_Dir_Counter]
        add     bx, [Dir_File_Counter]
        cmp     bx, [Dir_Dir_File_Counter_Max]          ; Files "fit" in directory?
        jle     @@10                                    ; Yes
                                                        ; No, so
        jmp     @@80

@@50:
;-----------------------------------------------------------------------------
; If no subdirectories are included, don't determine the size of the directory
;-----------------------------------------------------------------------------
        cmp     [Ws_IS_D_Subdirs_Yes_No], "N"           ; Include Subdirectories
        je      @@90                                    ; No
                                                        ; Yes, so
;-------------------------------------------------------------------------
; Determine the "size" of the directory being analyzed for this disk image
;-------------------------------------------------------------------------
        mov     ax, [Dir_Dir_Counter]
        add     ax, [Dir_File_Counter]
        xor     bx, bx                                  ; Reset bx
        mov     cx, EIGHTBIT_VTOC_ENTRY_SIZE
        xor     dx, dx                                  ; Reset dx

        mul     cx                                      ; Determine nr of bytes needed
                                                        ; ax contains nr of bytes
        add     ax, 6                                   ; "directory" header length
        xor     dx, dx                                  ; Reset dx
        mov     bx, [Disk_Sector_Size]
        xor     cx, cx                                  ; Reset cx

        div     bx                                      ; Determine nr of sectors

        cmp     dx, NULL                                ; No remainder?
        jz      @@60                                    ; No
                                                        ; Yes, so
        inc     ax                                      ; We need another sector

@@60:
        call    Calculate_Nr_Of_Link_Sectors
        add     [Sector_Counter_VTOC], ax               ; Number of sectors we need for the VTOC

        clc                                             ; Clear carry flag
        add     [Sector_Counter], ax
        jnc     @@90                                    ; Disk still large enough
        mov     [Disk_Image_Not_Large_Enough], LOGIC_YES
        jmp     @@99

@@80:
        sub     [Sector_Counter], ax
        dec     [Dir_File_Counter]
        cmp     [Too_Many_Files_In_Dir], LOGIC_YES
        je      @@99

;-----------------------------------------------
; Too many files in the directory being analyzed
;-----------------------------------------------
        call    Error_E5_Too_Many_Files_In_Dir
        jmp     @@99

@@90:
        call    Determine_Sectors_Per_Progress_Bar

@@99:
        ret

ENDP    Analyze_Pc_Files_Structure



;**********************************************************************
PROC    Calculate_Nr_Of_Link_Sectors
;**********************************************************************
        clc                                             ; Clear carry flag
        push    ax                                      ; Save sector count
        xor     dx, dx                                  ; Reset dx
        mov     bx, [Disk_Sector_Size]                  ; Nr of sector pointers we can store in a link sector
        sub     bx, 4                                   ; 4 bytes are used as linklist (prev/next ptr)
        ror     bx, 1                                   ; Divide by 2 (because each sector pointer occupies 2 bytes)
        xor     cx, cx                                  ; Reset cx

        div     bx                                      ; Determine nr of link sectors

        cmp     dx, NULL                                ; Remainder?
        jz      @@10                                    ; No
                                                        ; Yes, so
        inc     ax                                      ; We need another sector

@@10:
        mov     bx, ax                                  ; Save result in bx

        pop     ax                                      ; Restore sector count
        add     ax, bx                                  ; Add link sector count

        ret

ENDP    Calculate_Nr_Of_Link_Sectors



;**********************************************************************
PROC    Retrieve_SpartaDos_Volume_Name
;**********************************************************************
;------------------------------------------------
; Extract volume name from directory to be ATR-ed
;------------------------------------------------
        mov     es, [Parm_Dir_From_ptr_es]
        mov     di, [Parm_Dir_From_ptr_di]              ; Dir to ATR

        mov     cx, PATH_LENGTH
        dec     cx                                      ; To go to the last character
        add     di, cx                                  ; Go to end of path
        std                                             ; Search direction is down
        mov     ax, BACKSLASH                           ; Search for "\"
        repne   scasb                                   ; Search uses es:di
        cmp     [byte es:di], COLON                     ; Are we at the ":" of "C:\"?
        je      @@10                                    ; Yes
                                                        ; No, so
                                                        ; Search for next "\"
        repne   scasb                                   ; Search uses es:di

@@10:
        inc     di                                      ; Pointer at the "\" now
        inc     di                                      ; Pointer after the "\" now
        cld                                             ; Cancel the std setting

;-------------------------------------------------------
; Move "volume name" directory name to volume name field
;-------------------------------------------------------
        push    es di                                   ; Save pointer to volume name

        mov     si, offset Ws_SV_D_Volume_Name
        push    ds si
        pop     di es
        mov     cx, DISK_VOLUME_NAME_LENGTH
        xor     ax, ax                                  ; Reset ax
        mov     al, SPACE                               ; Fill character
        rep     stosb

        mov     cx, 8
        pop     di es                                   ; Restore pointer to volume name

@@20:
        mov     al, [byte es:di]
        cmp     al, SPACE                               ; End of volune name?
        je      @@30                                    ; Yes
                                                        ; Maybe, so
        cmp     al, BACKSLASH                           ; End of volune name?
        je      @@30                                    ; Yes
                                                        ; No, so
        mov     [byte ds:si], al
        inc     si
        inc     di
        loop    @@20

@@30:
        xor     ax, ax
        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@99                                    ; Yes
                                                        ; No, so
        mov     si, offset Ws_SV
        mov     [byte ds:si], WSIO_OPEN

        push    ds si
        call    WSIO
        pop     di es

        mov     [(Wsio_Area ptr di).Cursor_Position_Row], NULL
        mov     [(WSio_Area ptr di).Cursor_Position_Col], NULL

        mov     si, offset Ws_SV
        mov     [byte ds:si], WSIO_DISPLAY_AND_READ

        push    ds si
        call    WSIO
        pop     si ds

        push    ax

        mov     si, offset Ws_SV
        mov     [byte ds:si], WSIO_CLOSE

        push    ds si
        call    WSIO
        pop     si ds

        pop     ax

@@99:
        ret

ENDP    Retrieve_SpartaDos_Volume_Name



;**********************************************************************
PROC    Check_Adding_Disk_Images_At_End
;**********************************************************************
        mov     [Disk_Seq_Nr], 0
        mov     [Disk_Seq_Nr_Present], 0

;-------------------------------------------------
; Are there already disk images in this directory?
;-------------------------------------------------
        mov     [Disk_Adding], "N"                      ; Add disks from beginning
        mov     [Ws_AD_D_Add_Where], "B"                ; Assume add from begin

        mov     [Requested_Format_LibFil], "2"          ; = "MY.TXT               123"
                                                        ;   "YOURFILE.TXT       1,425"
        push    ds si

        mov     es, [Parm_Disk_To_ptr_es]               ; Determine path
        mov     di, [Parm_Disk_To_ptr_di]               ; disk to "write to" directory
        push    es di

        mov     si, offset Search_Dirs_Path
        push    ds si
        pop     di es

        pop     si ds
        mov     cx, PATH_LENGTH
        rep     movsb

        pop     si ds

        call    Retrieve_Pc_Files

        mov     es, [Parm_Dir_Map_ptr_es]
        mov     di, [Parm_Dir_Map_ptr_di]               ; Directory Map

        mov     cx, 999                                 ; Maximum nr of disks

@@10:
        cmp     [byte es:di], NULL                      ; End of table reached?
        je      @@99                                    ; Yes
                                                        ; No, so
@@20:
        cmp     [byte es:di], NULL                      ; More files?
        je      @@40                                    ; No
                                                        ; Yes, so
;--------------------------
; Check for valid disk name
;--------------------------
        cmp     [byte es:di], "0"
        jl      @@30
        cmp     [byte es:di], "9"
        jnle    @@30
        cmp     [byte es:di + 1], "0"
        jl      @@30
        cmp     [byte es:di + 1], "9"
        jnle    @@30
        cmp     [byte es:di + 2], "0"
        jl      @@30
        cmp     [byte es:di + 2], "9"
        jnle    @@30
        cmp     [byte es:di + 3], DOT
        jne     @@30

        xor     ax, ax
        xor     bx, bx
        xor     dx, dx
        mov     bl, [byte es:di + 2]
        sub     bl, ZERO
        mov     al, [byte es:di + 1]
        sub     al, ZERO
        mov     cx, 10
        mul     cx
        add     bx, ax
        xor     ax, ax
        mov     al, [byte es:di]
        sub     al, ZERO
        mov     cx, 100
        mul     cx
        add     bx, ax
        cmp     bx, [Disk_Seq_Nr_Present]
        jle     @@30
        
        mov     [Disk_Seq_Nr_Present], bx

@@30:
        add     di, DIR_ENTRY_LENGTH
        loop    @@20

@@40:
        cmp     [Disk_Seq_Nr_Present], 0                ; Already disk nrs present?
        je      @@99                                    ; No
                                                        ; Yes, so
        mov     [Ws_AD_D_Add_Where], "E"                ; Assume add at end

;-----------------------
; Add disknumber to end?
;-----------------------
        mov     si, offset Ws_AD
        mov     [byte ds:si], WSIO_OPEN

        push    ds si
        call    WSIO
        pop     di es

        mov     [(Wsio_Area ptr di).Cursor_Position_Row], NULL
        mov     [(WSio_Area ptr di).Cursor_Position_Col], NULL

@@50:
        mov     si, offset Ws_AD
        mov     [byte ds:si], WSIO_DISPLAY_AND_READ

        push    ds si
        call    WSIO
        pop     si ds

;--------------------
; Was Cancel pressed?
;--------------------
        cmp     al, KEY_ESC
        je      @@80

;------------------
; ENTER was pressed
;------------------
        cmp     ah, WSIO_MOUSE_PRESSED                  ; Mouse pressed Enter?
        jne     @@70                                    ; No
                                                        ; Yes, so
;--------------------
; Mouse pressed ENTER
;--------------------
        push    ds si
        pop     di es
        xor     cx, cx
        mov     cl, [(Wsio_Area ptr di).Cursor_Position_Row]

;
; Check if a the Key Enter field was pressed
;
        cmp     cx, 15                                  ; Enter key selected?
        je      @@70                                    ; Yes
                                                        ; No, so
;
; At End/From Begin field was selected
;
        cmp     [Ws_AD_D_Add_Where], "E"                ; Was it "add at end"?
        jne     @@60                                    ; No
                                                        ; Yes, so
        mov     [Ws_AD_D_Add_Where], "B"
        jmp     @@50

@@60:
        mov     [Ws_AD_D_Add_Where], "E"
        jmp     @@50

@@70:
;-----------------------------------
; Should we start adding at the end?
;-----------------------------------
        cmp     [Ws_AD_D_Add_Where], "E"                ; Add disks at end?
        jne     @@80                                    ; No
                                                        ; Yes, so
        mov     [Disk_Adding], "Y"                      ; Add disks at end

@@80:
        push    ax

        mov     si, offset Ws_AD
        mov     [byte ds:si], WSIO_CLOSE

        push    ds si
        call    WSIO
        pop     si ds

        pop     ax

@@99:
        ret

ENDP    Check_Adding_Disk_Images_At_End



;**********************************************************************
PROC    Create_Disk_Image_No_Dirs
;**********************************************************************
        call    Open_Disk_Image

        cmp     [Dir2atr_Error], LOGIC_YES              ; Error encountered?
        je      @@95                                    ; Yes
                                                        ; No, so
;---------------------------------------------------
; Retrieve files of "Main" entry in Pc Dir Map table
;---------------------------------------------------
        mov     [Dir_Curr_ptr], 1                       ; We start with 1st occurrence

        call    Update_8bit_VTOC_Directory_Current      ; Process directory name

;---------------------
; Include DOS (files)?
;---------------------
        cmp     [Include_DOS_Files], LOGIC_NO
        je      @@10                                    ; No
                                                        ; Yes, so
        call    Include_XL_DOS_Files_In_Disk_Image      ; Include DOS
        cmp     [Dir2atr_Error], LOGIC_YES              ; Error encountered?
        jne     @@10                                    ; No
                                                        ; Yes, so
        push    ax ax                                   ; To even out stack
        jmp     @@80

@@10:
        push    ds si                                   ; Save program entry

        mov     es, [Pc_Dir_Map_ptr_es]                 ; Directory to check
        mov     di, [Pc_Dir_Map_ptr_di]
        push    es di                                   ; Save entry into table

        mov     si, offset Search_Dirs_Path
        push    ds si                                   ; Save offset search dirs path
        pop     di es                                   ; Restore offset search dirs path

        pop     si ds                                   ; Restore entry into table

        mov     cx, PATH_LENGTH
        rep     movsb                                   ; Copy from entry to search dirs path

        pop     si ds                                   ; Restore program entry

;-----------------------------------------------
; Retrieve files of current pc dir map directory
;-----------------------------------------------
        mov     [Requested_Format_LibFil], "1"          ; For format see DIRENTRY.STR
        call    Retrieve_Pc_Files

;--------------------
; Process found files
;--------------------
        mov     es, [Parm_Dir_Map_ptr_es]
        mov     di, [Parm_Dir_Map_ptr_di]               ; Directory Map

        mov     [Dir_File_Counter], 0                   ; Reset counter

        cmp     [byte es:di], NULL                      ; Anything to process at all?
        je      @@95                                    ; No
                                                        ; Yes, so
@@20:
;-------------------------------------------------------
; Process a file using (or without) optimized disk usage
;-------------------------------------------------------

@@30:
        push    es di                                   ; Save Dir_Map pointer

        cmp     [byte es:di], NULL                      ; Something left to process?
        je      @@75                                    ; No
                                                        ; Yes, so
;---------------------------------------
; If file won't fit on image, we skip it
;---------------------------------------
        call    Check_If_File_Fits_On_Image

        cmp     [Dir_Entry_Fits_On_Image], LOGIC_YES
        jne     @@70                                    ; No
                                                        ; Yes, so
;--------------------------------------------------------------
; File fits on the remaining sectors of the current disk image?
;--------------------------------------------------------------
;
; File Size in sectors > remaining nr of sectors left?
;
        mov     cx, [Disk_Sectors_Left]
        clc                                             ; Clear carry
        sub     ax, [File_Size_In_Sectors]
        jc      @@40

;--------------------------------------------------
; Nr of files processed > nr of files in 8bit vtoc?
;--------------------------------------------------
        inc     [Dir_File_Counter]
        mov     cx, [Dir_File_Counter]
        cmp     cx, [Dir_Dir_File_Counter_Max]
        jl      @@50

@@40:
;---------------------------------------------------------------------
; File does not fit on current disk image, so write it to the next one
;---------------------------------------------------------------------
        call    Write_8bit_VTOC                         ; Write VTOC of current disk image
        call    Write_8bit_Bitmap                       ; Write Bitmap of current disk image
        call    Write_8bit_Bootcode                     ; Write Bootcode of current disk image

        cmp     [Dir2atr_Error], LOGIC_YES              ; Error encountered?
        je      @@85                                    ; Yes
                                                        ; No, so
        call    Close_Disk_Image                        ; Close current disk image
        call    Open_Disk_Image                         ; Create a new disk image

        cmp     [Dir2atr_Error], LOGIC_YES              ; Error encountered?
        je      @@90                                    ; Yes
                                                        ; No, so
        call    Update_8bit_VTOC_Directory_Current      ; Process directory name

;---------------------
; Include DOS (files)?
;---------------------
        cmp     [Include_DOS_Files], LOGIC_NO
        je      @@50                                    ; No
                                                        ; Yes, so
        call    Include_XL_DOS_Files_In_Disk_Image
        cmp     [Dir2atr_Error], LOGIC_YES              ; Error encountered?
        jne     @@50                                    ; No
                                                        ; Yes, so
        push    ax ax                                   ; To even out stack
        jmp     @@80

@@50:
;------------------------
; Determine Filename path
;------------------------
        push    ds si                                   ; Save program entry

        mov     si, offset PC_ATARI_Pathname
        push    ds si
        mov     es, [Parm_Dir_From_ptr_es]
        mov     di, [Parm_Dir_From_ptr_di]
        push    es di

        pop     si ds
        pop     di es
        mov     cx, PATH_LENGTH                         ; Copy length
        rep     movsb                                   ; Copy path to search path

        pop     si ds                                   ; Restore program entry

        call    Setup_PC_ATARI_Pathname

;-------------------
; Process 8 bit File
;-------------------
        call    Open_8bit_Pc_File

        cmp     [Dir2atr_Error], LOGIC_YES              ; Error encountered?
        je      @@85                                    ; Yes
                                                        ; No, so
        call    Move_Pc_File_To_Disk_Image

        cmp     [Dir2atr_Error], LOGIC_YES              ; Error encountered?
        jne     @@60                                    ; No
                                                        ; Yes, so
        call    Close_8bit_Pc_File

        jmp     @@85

@@60:
        call    Close_8bit_Pc_File
        call    Update_8bit_VTOC_File

@@70:
;
; Go to next entry
;
        pop     di es
        mov     [byte es:di], NULL                      ; Indicate file processed
        add     di, FILE_ENTRY_LENGTH

        jmp     @@20

@@75:
;------------------------------------
; Make sure the complete bar is drawn
;------------------------------------
        xor     bx, bx
        mov     ax, [Sectors_Per_Progress_Bar]
        xor     dx, dx
        xor     cx, cx
        mov     cl, [Ws_CF_Progress_Bar_Cnt_Max]
        mul     cx                                      ; multiply bx:ax by dx:cx

        mov     [Ws_CF_Progress_Bar_Cnt_Sectors_Hi], bx
        mov     [Ws_CF_Progress_Bar_Cnt_Sectors_Lo], ax

        call    Show_Progress_Bar

@@80:
        call    Write_8bit_VTOC                         ; Write VTOC of current disk image
        call    Write_8bit_Bitmap                       ; Write Bitmap of current disk image
        call    Write_8bit_Bootcode                     ; Write Bootcode of current disk image

@@85:
        call    Close_Disk_Image

@@90:
        pop     ax ax

@@95:
        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@99                                    ; Yes
                                                        ; No, so
        mov     si, offset Ws_CF
        mov     [byte ds:si], WSIO_CLOSE

        push    ds si
        call    WSIO
        pop     si ds

@@99:
        ret

ENDP    Create_Disk_Image_No_Dirs



;**********************************************************************
PROC    Create_Disk_Image_With_Dirs
;**********************************************************************
        call    Open_Disk_Image

        cmp     [Dir2atr_Error], LOGIC_YES              ; Error encountered?
        je      @@95                                    ; Yes
                                                        ; No, so
;----------------------------
; Initialize some values here
;----------------------------
        mov     [Dir_Curr_ptr], 0                       ; We start with 1st occurrence

@@05:
;----------------------------------------------------
; Retrieve files of next entry in Pc Dir Map table
;----------------------------------------------------
        mov     es, [Pc_Dir_Map_ptr_es]                 ; Directory to check
        mov     di, [Pc_Dir_Map_ptr_di]

        inc     [Dir_Curr_ptr]
        mov     cx, [Dir_Curr_ptr]                      ; Offset into table
        jmp     @@15

@@10:
        add     di, PC_DIR_MAP_ENTRY_LENGTH             ; Next entry into table

@@15:
        loop    @@10

        cmp     [byte es:di], NULL                      ; Anything (more) to process?
        je      @@75                                    ; No
                                                        ; Yes, so
;-------------------------------------
; Process current pc dir map directory
;-------------------------------------
        push    es di                                   ; Save entry into table
        call    Update_8bit_VTOC_Directory_Current      ; Process directory name
        pop     di es                                   ; Restore entry into table

        push    ds si                                   ; Save program entry

        push    es di                                   ; Save entry into table

        mov     si, offset Search_Dirs_Path
        push    ds si                                   ; Save offset search dirs path
        pop     di es                                   ; Restore offset search dirs path

        pop     si ds                                   ; Restore entry into table

        mov     cx, PATH_LENGTH
        rep     movsb                                   ; Copy from entry to search dirs path

        pop     si ds                                   ; Restore program entry

;-----------------------------------------------------
; Retrieve directories of current pc dir map directory
;-----------------------------------------------------
        call    Update_8bit_VTOC_Directories            ; Process directory names

;---------------------------------------------------------------
; Include DOS (files)? (check this only for the "main" directory
;---------------------------------------------------------------
        cmp     [Dir_Curr_ptr], 1                       ; "Main" directory?
        jne     @@20                                    ; No
                                                        ; Yes, so
        cmp     [Include_DOS_Files], LOGIC_NO           ; Include DOS?
        je      @@20                                    ; No
                                                        ; Yes, so
        call    Include_XL_DOS_Files_In_Disk_Image
        cmp     [Dir2atr_Error], LOGIC_YES              ; Error encountered?
        je      @@80                                    ; Yes
                                                        ; No, so
@@20:
;-----------------------------------------------
; Retrieve files of current pc dir map directory
;-----------------------------------------------
        mov     [Requested_Format_LibFil], "1"          ; For format see DIRENTRY.STR
        call    Retrieve_Pc_Files

        mov     es, [Parm_Dir_Map_ptr_es]
        mov     di, [Parm_Dir_Map_ptr_di]               ; Directory Map

        mov     [Dir_File_Counter], 0                   ; Reset counter

        cmp     [byte es:di], NULL                      ; Any files to process?
        jne     @@25                                    ; Yes
                                                        ; No, so
        call    Update_Pc_Dir_Map_Link_Sector_Pointer
        call    Write_8bit_VTOC                         ; Write VTOC of current directory
        jmp     @@05

@@25:
;-------------------------------------------------------
; Process a file using (or without) optimized disk usage
;-------------------------------------------------------

@@30:
        cmp     [byte es:di], NULL                      ; More files to process?
        jne     @@40                                    ; Yes
                                                        ; No, so
        call    Update_Pc_Dir_Map_Link_Sector_Pointer
        call    Write_8bit_VTOC                         ; Write VTOC of current directory
        jmp     @@05

@@40:
        push    es di                                   ; Save Dir_Map pointer

;---------------------------------------
; If file won't fit on image, we skip it
;---------------------------------------
        call    Check_If_File_Fits_On_Image

        cmp     [Dir_Entry_Fits_On_Image], LOGIC_YES
        jne     @@70                                    ; No
                                                        ; Yes, so
;--------------------------------------------------------------
; File fits on the remaining sectors of the current disk image?
;--------------------------------------------------------------
;
; File Size in sectors > remaining nr of sectors left?
;
        mov     cx, [Disk_Sectors_Left]
        clc                                             ; Clear carry
        sub     ax, [File_Size_In_Sectors]
        jc      @@70

;--------------------------------------------------
; Nr of files processed > nr of files in 8bit vtoc?
;--------------------------------------------------
        inc     [Dir_File_Counter]
        mov     cx, [Dir_File_Counter]
        add     cx, [Dir_Dir_Counter]
        cmp     [Dir_Dir_File_Counter_Max], cx
        jl      @@70

@@50:
;------------------------
; Determine Filename path
;------------------------
        mov     si, offset PC_ATARI_Pathname
        push    ds si
        pop     di es
        mov     si, offset Search_Dirs_Path
        mov     cx, PATH_LENGTH                         ; Copy length
        rep     movsb                                   ; Copy path to search path

        call    Setup_PC_ATARI_Pathname

;-------------------
; Process 8 bit File
;-------------------
        call    Open_8bit_Pc_File

        cmp     [Dir2atr_Error], LOGIC_YES              ; Error encountered?
        je      @@85                                    ; Yes
                                                        ; No, so
        call    Move_Pc_File_To_Disk_Image

        cmp     [Dir2atr_Error], LOGIC_YES              ; Error encountered?
        jne     @@60                                    ; No
                                                        ; Yes, so
        call    Close_8bit_Pc_File

        jmp     @@85

@@60:
        call    Close_8bit_Pc_File
        call    Update_8bit_VTOC_File

@@70:
;
; Go to next entry
;
        pop     di es
        mov     [byte es:di], NULL                      ; Indicate file processed
        add     di, FILE_ENTRY_LENGTH

        jmp     @@25

@@75:
;------------------------------------
; Make sure the complete bar is drawn
;------------------------------------
        xor     bx, bx
        mov     ax, [Sectors_Per_Progress_Bar]
        xor     dx, dx
        xor     cx, cx
        mov     cl, [Ws_CF_Progress_Bar_Cnt_Max]
        mul     cx                                      ; multiply bx:ax by dx:cx

        mov     [Ws_CF_Progress_Bar_Cnt_Sectors_Hi], bx
        mov     [Ws_CF_Progress_Bar_Cnt_Sectors_Lo], ax

        call    Show_Progress_Bar

@@80:
        call    Write_8bit_Bitmap                       ; Write Bitmap of current disk image
        call    Write_8bit_Bootcode                     ; Write Bootcode of current disk image

        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@81                                    ; Yes
                                                        ; No, so
        mov     si, offset Ws_CF
        mov     [byte ds:si], WSIO_CLOSE

        push    ds si
        call    WSIO
        pop     si ds

@@81:
        call    Rewrite_Dir_Link_8bit_VTOC              ; Because of directory linking
        call    Close_Disk_Image
        jmp     @@99

@@85:
        call    Close_Disk_Image

@@90:
        pop     ax ax

@@95:
        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@99                                    ; Yes
                                                        ; No, so
        mov     si, offset Ws_CF
        mov     [byte ds:si], WSIO_CLOSE

        push    ds si
        call    WSIO
        pop     si ds

@@99:
        ret

ENDP    Create_Disk_Image_With_Dirs



;**********************************************************************
PROC    Determine_Sectors_Per_Progress_Bar
;**********************************************************************
        mov     dx, [Ws_CF_Progress_Bar_Sectors_Hi]
        mov     ax, [Ws_CF_Progress_Bar_Sectors_Lo]
        xor     cx, cx
        xor     bx, bx
        mov     bl, [Ws_CF_Progress_Bar_Cnt_Max]
        div     bx                                      ; ax contains nr of sectors per bar
        cmp     dx, NULL                                ; Remainder?
        je      @@10                                    ; No
                                                        ; Yes, si
        inc     ax

@@10:
        mov     [Sectors_Per_Progress_Bar], ax

@@99:
        ret

ENDP    Determine_Sectors_Per_Progress_Bar



;**********************************************************************
PROC    Optimize_Disk_Image_Usage
;**********************************************************************
        ret

ENDP    Optimize_Disk_Image_Usage



;**********************************************************************
PROC    Check_If_File_Fits_On_Image
;**********************************************************************
        mov     [Dir_Entry_Fits_On_Image], LOGIC_NO

        push    ds si                                   ; Save Data pointer

        call    Copy_Entry_From_Dir_Map_To_File_Map

        pop     si ds                                   ; Restore Data pointer

        call    Set_SpartaDos_File_Date_And_Time

;
; Determine File Size in Sectors
;
        call    Determine_File_Size_In_Sectors

        mov     ax, [File_Size_In_Sectors]
        cmp     ax, HIGH_VALUES                         ; File too large?
        je      @@99                                    ; Yes
                                                        ; No, so
;
; Does file fit on the selected disk medium?
;
        mov     cx, [Max_File_Size_In_Sectors]
        clc                                             ; Clear carry
        sub     cx, ax
        jc      @@99

        mov     [Dir_Entry_Fits_On_Image], LOGIC_YES

@@99:
        ret

ENDP    Check_If_File_Fits_On_Image



;**********************************************************************
PROC    Copy_Entry_From_Dir_Map_To_File_Map
;**********************************************************************
        push    es di                                   ; Save entry position

        mov     si, offset File_Map_Entry
        push    ds si
        pop     di es

        pop     si ds                                   ; Restore entry position

        mov     cx, FILE_ENTRY_LENGTH
        rep     movsb

        ret

ENDP    Copy_Entry_From_Dir_Map_To_File_Map


;**********************************************************************
PROC    Determine_File_Size_In_Sectors
;**********************************************************************
        mov     [File_Size_In_Sectors], HIGH_VALUES

        mov     bx, [Disk_Sector_Size]
        mov     [Remainder_Bytes], bx

        mov     si, offset File_Map_Entry.File_Size
        mov     dh, [byte ds:si + 3]
        mov     dl, [byte ds:si + 2]
        mov     ah, [byte ds:si + 1]
        mov     al, [byte ds:si]
        xor     cx, cx                                  ; Reset cx

        cmp     dx, 07Bh                                ; Extremely large file?
        jnl     @@99                                    ; Yes
                                                        ; No, so
        div     bx                                      ; Determine nr of sectors
        cmp     dx, NULL                                ; Remainder?
        je      @@10                                    ; No
                                                        ; Yes, so
        inc     ax                                      ; We need another sector
        mov     [Remainder_Bytes], dx                   ; Save remainder
        xor     dx, dx                                  ; Reset dx

@@10:
        mov     [File_Size_In_Sectors], ax

@@99:
        ret

ENDP    Determine_File_Size_In_Sectors



;**********************************************************************
PROC    Show_Progress_Bar
;**********************************************************************
        mov     dx, [Ws_CF_Progress_Bar_Cnt_Sectors_Hi]
        mov     ax, [Ws_CF_Progress_Bar_Cnt_Sectors_Lo]
        xor     cx, cx
        mov     bx, [Sectors_Per_Progress_Bar]
        div     bx                                      ; Divide dx:ax by cx:bx (Nr of bars we've had)

        cmp     al, [Ws_CF_Progress_Bar_Cnt_Prev]
        je      @@99

@@20:
;---------------------------------
; Update progress bar, and show it
;---------------------------------
        mov     [Ws_CF_Progress_Bar_Cnt_Prev], al
        xor     cx, cx
        mov     cl, al

        mov     si, offset Ws_CF_D_Progress_Bar
        push    ds si
        pop     di es
        xor     ax, ax
        mov     al, 0DBh
        rep     stosb

        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@99                                    ; Yes
                                                        ; No, so
        mov     si, offset Ws_CF
        mov     [byte ds:si], WSIO_DISPLAY_FIELDS_ONLY
        push    ds si
        call    WSIO
        pop     si ds

@@99:
        ret

ENDP    Show_Progress_Bar



;**********************************************************************
PROC    Open_Disk_Image
;**********************************************************************
        mov     ax, [Disk_Sectors]
        mov     [Disk_Sectors_Free], ax

        sub     ax, DISK_BOOTCODE_SECTOR_SIZE
        sub     ax, [Disk_Sectors_Bitmap]
        sub     ax, [Disk_Sectors_VTOC]

        mov     [Disk_Sectors_Usable], ax
        mov     [Disk_Sectors_Available], ax
        mov     [Disk_Sectors_Left], ax

        mov     [ATR_Disk_Image_Open], FALSE

;-------------------
; Determine Diskname
;-------------------
        inc     [Disk_Seq_Nr]

        mov     si, offset Disk_Name
        push    ds si
        pop     di es

;---------------------------------------------------------------------
; When we include (sub)directories everything has to fit on 1 disk, so
; then we go through this routine only once.
; If we only process files, we might go through this routine more than
; once, because we may need more than 1 disk...
;---------------------------------------------------------------------
        cmp     [Ws_IS_D_Subdirs_Yes_No], "N"           ; Include Subdirectories
        je      @@10                                    ; No
                                                        ; Yes, so

;-----------------------------------------------------
; Determine Diskname, when processing with directories
;-----------------------------------------------------
        mov     si, offset Ws_SV_D_Volume_Name
        mov     cx, DISK_VOLUME_NAME_LENGTH
        rep     movsb                                   ; Copy SpartaDos volume name entered by the user
        jmp     @@20

@@10:
;-----------------------------------------------
; Determine Diskname, when processing files only
;-----------------------------------------------
        add     di, 2
        mov     ax, [Disk_Seq_Nr]
        mov     bx, 10                                  ; Extract digits

;
; Convert hexadecimal size to textual digits
;
        call    Extract_Digit                           ; Convert value below 10000
        call    Extract_Digit
        call    Extract_Digit

@@20:
;----------------------------------
; Show which disk we are working on
;----------------------------------
        mov     si, offset Ws_CF_D_Add_Disk
        push    ds si
        pop     di es
        mov     si, offset Disk_Name
        mov     cx, FILE_NAME_LENGTH
        rep     movsb

;----------------------------------
; Determine path of disk image file
;----------------------------------
        push    ds si                                   ; Save program position

        mov     si, offset ATARI____Pathname
        push    ds si
        pop     di es
        mov     ax, [Parm_Disk_To_ptr_es]
        mov     bx, [Parm_Disk_To_ptr_di]               ; Disk path
        mov     cx, PATH_LENGTH
        push    ax bx
        pop     si ds
        rep     movsb                                   ; Search path established

        pop     si ds                                   ; Restore program position

        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@22                                    ; Yes
                                                        ; No, so
        call    Setup_ATARI____Pathname

@@22:
;----------------------
; Create ATR Disk Image
;----------------------
        mov     si, offset ATARI____File
        push    ds si
        pop     di es
        mov     [(FMS_Area ptr di).Request], CMD_OPEN_OUTPUT

        push    es di
        call    FMSIO
        pop     di es

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        jne     @@90                                    ; Error!

        mov     [(FMS_Area ptr di).Request], CMD_ACCESS_WRITENEXT

;-----------------
; Reset I/O buffer
;-----------------
        mov     si, offset Disk_I_O_Buffer
        push    ds si
        pop     di es
        xor     ax, ax
        mov     cx, EIGHTBIT_SECTOR_SIZE_DOUBLE
        rep     stosb

;--------------------
; Reset Bitmap buffer
;--------------------
        mov     si, offset Disk_Bitmap_Buffer
        push    ds si
        pop     di es
        xor     ax, ax
        mov     cx, BITMAP_BUFFER_LENGTH
        rep     stosb

;-----------------------
; "Format" Bitmap buffer
;-----------------------
        mov     si, offset Disk_Bitmap_Buffer

        mov     ax, [Disk_Sectors]
        xor     dx, dx
        xor     cx, cx
        mov     bx, NR_OF_SECTORS_PER_BITMAP_BYTE       ; Nr of sector per bitmap byte

        div     bx                                      ; Divide dx:ax by cx:bx
                                                        ; ax=result dx=remainder
        mov     cx, ax                                  ; Nr of bytes to set to hex FF

@@25:
        mov     [byte ds:si], HIGH_VALUE                ; hex FF
        inc     si
        loop    @@25

;------------------------------
; Mark sectors which are in use
;------------------------------
        mov     cx, DISK_BOOTCODE_SECTOR_SIZE           ; Sectors used
        add     cx, [Disk_Sectors_Bitmap]
        inc     cx                                      ; Sector 0 is always in use

        mov     si, offset Disk_Bitmap_Buffer

        mov     [Disk_Sector_Current], 0                ; Start at sector 0

@@40:
        push    cx
        call    Update_8bit_Bitmap
        pop     cx
        inc     [Disk_Sector_Current]
        loop    @@40

;---------------------------------------
; Message "Formatting Disk, please wait"
;---------------------------------------
        mov     si, offset Ws_CF_F_Add_File
        push    ds si
        pop     di es

        mov     si, offset Ws_CF_D_Formatting_Disk
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@41                                    ; Yes
                                                        ; No, so
;------------------------
; Display progress screen
;------------------------
        mov     si, offset Ws_CF
        mov     [byte ds:si], WSIO_DISPLAY_FIELDS_ONLY

        push    ds si
        call    WSIO
        pop     si ds

@@41:
;-----------------------------------
; Initialize formatting progress bar
;-----------------------------------
        mov     si, offset Ws_FF_D_Progress_Bar
        push    ds si
        pop     di es
        xor     ax, ax
        mov     al, 0B0h
        xor     cx, cx
        mov     cl, [Ws_FF_Progress_Bar_Cnt_Max]
        rep     stosb

        mov     [Ws_FF_Progress_Bar_Cnt_Prev], 0
        mov     [Ws_FF_Progress_Bar_Cnt_Sectors], 0

;------------------------
; "Format" ATR Disk Image
;------------------------
        mov     si, offset ATARI____File
        push    ds si
        pop     di es

        mov     [(FMS_Area ptr di).Offset], DISK_BOOTCODE_SIZE

        cmp     [Parm_XFD_Format], LOGIC_YES            ; XFD format?
        je      @@50                                    ; Yes
                                                        ; No, so
;-------------------
; Header information
;-------------------
        add     [(FMS_Area ptr di).Offset], ATR_HEADER_SIZE

        mov     si, offset ATR_Header_Single
        cmp     [Disk_Media_Type], DISK_MEDIA_TYPE_SINGLE
        je      @@45                                    ; Yes
                                                        ; No, so
        mov     si, offset ATR_Header_Medium
        cmp     [Disk_Media_Type], DISK_MEDIA_TYPE_MEDIUM
        je      @@45                                    ; Yes
                                                        ; No, so
        mov     si, offset ATR_Header_Double
        cmp     [Disk_Media_Type], DISK_MEDIA_TYPE_DOUBLE
        je      @@45                                    ; Yes
                                                        ; No, so
        mov     si, offset ATR_Header_Quad
        cmp     [Disk_Media_Type], DISK_MEDIA_TYPE_QUAD
        je      @@45                                    ; Yes
                                                        ; No, so
        mov     si, offset ATR_Header_720KB
        cmp     [Disk_Media_Type], DISK_MEDIA_TYPE_720KB
        je      @@45                                    ; Yes
                                                        ; No, so
        mov     si, offset ATR_Header_1440KB
        cmp     [Disk_Media_Type], DISK_MEDIA_TYPE_1440KB
        je      @@45                                    ; Yes
                                                        ; No, so
        mov     si, offset ATR_Header_Harddisk
        cmp     [Disk_Media_Type], DISK_MEDIA_TYPE_HARDDISK
        je      @@45                                    ; Yes
                                                        ; No, so
@@45:
        mov     [(FMS_Area ptr di).Data_Address_Hi], ds
        mov     [(FMS_Area ptr di).Data_Address_Lo], si
        mov     [(FMS_Area ptr di).Record_Size], ATR_HEADER_SIZE

        push    es di
        call    FMSIO
        pop     di es

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        jne     @@91                                    ; Error!

@@50:
;----------------------
; Init bootcode sectors
;----------------------
        push    es di

        mov     si, offset Bootcode_Data
        push    ds si
        pop     di es
        xor     ax, ax
        mov     cx, DISK_BOOTCODE_SIZE
        rep     stosb

        pop     di es

;--------------------------------------
; For now, write empty bootcode sectors
;--------------------------------------
        mov     si, offset Bootcode_Data
        mov     [(FMS_Area ptr di).Data_Address_Hi], ds
        mov     [(FMS_Area ptr di).Data_Address_Lo], si
        mov     [(FMS_Area ptr di).Record_Size], DISK_BOOTCODE_SIZE

        push    es di
        call    FMSIO
        pop     di es

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        jne     @@91                                    ; Error!

        mov     cx, [Disk_Sector_Size]
        mov     [(FMS_Area ptr di).Record_Size], cx

;---------------------------------------
; Read bootcode from disk, if neccessary
;---------------------------------------
        mov     si, offset PC_ATARI_File
        push    ds si
        pop     di es

        mov     [(FMS_Area ptr di).Request], CMD_OPEN_INPUT
        mov     si, offset Bootcode_Data
        mov     [(FMS_Area ptr di).Data_Address_Hi], ds
        mov     [(FMS_Area ptr di).Data_Address_Lo], si
        mov     [(FMS_Area ptr di).Record_Size], DISK_BOOTCODE_SIZE

;------------------------
; Bootcode from disk file
;------------------------
        call    Setup_Pathname_ATARI_Bootcode_File

;------------------------
; Open 8bit bootcode file
;------------------------
        mov     si, offset PC_ATARI_File
        push    ds si
        call    FMSIO
        pop     di es

        mov     [(FMS_Area ptr di).Request], CMD_ACCESS_READNEXT

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        je      @@60                                    ; Yes
                                                        ; No, so
;----------------------------------------------------------------
; If no DOS files are to be included, we write empty bootsectors,
; else, the bootcode file must be present!
;----------------------------------------------------------------
        cmp     [Include_DOS_Files], LOGIC_NO
        je      @@65                                    ; No
                                                        ; Yes, so
        call    Open_8bit_Pc_File                       ; Show Bootcode File not found error
        jmp     @@95                                    ; Show error

@@60:
;------------------------
; Read 8bit bootcode file
;------------------------
        push    es di
        call    FMSIO
        pop     di es

;-------------------------
; Close 8bit bootcode file
;-------------------------
        mov     [(FMS_Area ptr di).Request], CMD_OPEN_CLOSE

        push    es di
        call    FMSIO
        pop     di es

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        jne     @@95                                    ; File read
                                                        ; Yes, so
@@65:
;------------------------------------------------------
; Store start sector of Main Directory in bootcode area
;------------------------------------------------------
        mov     si, offset Bootcode_Data
        add     si, BOOTCODE_OFFSET_MAIN_DIR_LINK_SECTOR
        mov     cx, DISK_BOOTCODE_SECTOR_SIZE
        add     cx, [Disk_Sectors_Bitmap]
        inc     cx                                      ; The next sector is occupied by the VTOC
        mov     [ds:si], cx                             ; Start of VTOC sectors

;---------------------------------------------
; Store nr of sectors on disk in bootcode area
;---------------------------------------------
        mov     si, offset Bootcode_Data
        add     si, BOOTCODE_OFFSET_SECTORS_ON_DISK
        mov     cx, [Disk_Sectors]
        mov     [ds:si], cx

;----------------------------------------
; Store disk volume name in bootcode area
;----------------------------------------
        mov     si, offset Bootcode_Data
        add     si, BOOTCODE_OFFSET_VOLUME_NAME
        push    ds si
        pop     di es
        mov     si, offset Disk_Name
        mov     cx, DISK_VOLUME_NAME_LENGTH
        rep     movsb

;---------------------------------------------
; Store sector size of sector in bootcode area
;---------------------------------------------
        mov     si, offset Bootcode_Data
        add     si, BOOTCODE_OFFSET_SIZE_OF_SECTOR
        mov     cx, [Disk_Sector_Size]
        mov     [byte ds:si], cl

        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@66                                    ; Yes
                                                        ; No, so
;----------------------
; Display format screen
;----------------------
        mov     si, offset Ws_FF
        mov     [byte ds:si], WSIO_OPEN

        push    ds si
        call    WSIO
        pop     si ds

        mov     si, offset Ws_FF
        mov     [byte ds:si], WSIO_DISPLAY_ONLY

        push    ds si
        call    WSIO
        pop     si ds

@@66:
;----------------------------
; Number of sectors to format
;----------------------------
        mov     si, offset ATARI____File
        push    ds si
        pop     di es

        mov     si, offset Disk_I_O_Buffer
        mov     [(FMS_Area ptr di).Data_Address_Hi], ds
        mov     [(FMS_Area ptr di).Data_Address_Lo], si

        mov     cx, [Disk_Sectors]
        sub     cx, DISK_BOOTCODE_SECTOR_SIZE
        mov     [Ws_FF_Progress_Bar_Sectors], cx

@@70:
        push    cx

;------------------------------------------------------
; Calculate progress bar size, and show it if necessary
;------------------------------------------------------
        mov     ax, [Ws_FF_Progress_Bar_Cnt_Sectors]
        xor     bx, bx
        xor     cx, cx
        mov     cl, [Ws_FF_Progress_Bar_Cnt_Max]
        xor     dx, dx
        mul     cx

        xor     cx, cx
        mov     bx, [Ws_FF_Progress_Bar_Sectors]
        div     bx

        cmp     al, [Ws_FF_Progress_Bar_Cnt_Prev]
        je      @@75

;---------------------------------
; Update progress bar, and show it
;---------------------------------
        mov     [Ws_FF_Progress_Bar_Cnt_Prev], al
        mov     cx, ax

        mov     si, offset Ws_FF_D_Progress_Bar
        push    ds si
        pop     di es
        xor     ax, ax
        mov     al, 0DBh
        rep     stosb

        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@75                                    ; Yes
                                                        ; No, so
        mov     si, offset Ws_FF
        mov     [byte ds:si], WSIO_DISPLAY_FIELDS_ONLY
        push    ds si
        call    WSIO
        pop     si ds

@@75:
        pop     cx
        push    cx

        mov     si, offset ATARI____File
        push    ds si
        call    FMSIO
        pop     di es

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        je      @@80                                    ; Yes
                                                        ; No, so
        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@93                                    ; Yes
                                                        ; No, so
        mov     si, offset Ws_FF
        mov     [byte ds:si], WSIO_CLOSE

        push    ds si
        call    WSIO
        pop     si ds

        jmp     @@93

@@80:
        inc     [Ws_FF_Progress_Bar_Cnt_Sectors]

        pop     cx
        loop    @@70

        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@85                                    ; Yes
                                                        ; No, so
        push    es di

        mov     si, offset Ws_FF
        mov     [byte ds:si], WSIO_CLOSE

        push    ds si
        call    WSIO
        pop     si ds

        pop     di es

@@85:
;---------------------
; Close ATR Disk Image
;---------------------
        mov     [(FMS_Area ptr di).Request], CMD_OPEN_CLOSE
        push    es di
        call    FMSIO
        pop     di es

;-------------------------------
; Refer to files being added now
;-------------------------------
        mov     si, offset Ws_CF_F_Add_File
        push    ds si
        pop     di es

        mov     si, offset Ws_CF_D_Add_File
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

;-------------------------------
; Open ATR Disk Image for update
;-------------------------------
        mov     si, offset ATARI____File
        push    ds si
        pop     di es
        mov     [(FMS_Area ptr di).Request], CMD_OPEN_I_O

        push    es di
        call    FMSIO
        pop     di es

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        jne     @@94                            ; Error!

        mov     [(FMS_Area ptr di).Request], CMD_ACCESS_WRITE

;--------------------------------------------------------------------
; Determine first Bitmap sector, VTOC sector and writable data sector
;--------------------------------------------------------------------
        mov     ax, 1                                   ; Start sector
        add     ax, DISK_BOOTCODE_SECTOR_SIZE
        mov     [Disk_Sector_Bitmap_Current], ax        ; First Bitmap sector
        add     ax, [Disk_Sectors_Bitmap]
        mov     [Disk_Sector_VTOC_Current], ax          ; First VTOC sector
        add     ax, [Disk_Sectors_VTOC]
        mov     [Disk_Sector_Current], ax               ; First Data sector

;--------------
; Update status
;--------------
        mov     [ATR_Disk_Image_Open], TRUE

        jmp     @@99

@@90:
;------------
; E R R O R S
;------------
        mov     si, offset Ws_E2_D_Disk_Full
        push    ds si
        jmp     @@97

@@91:
        mov     si, offset Ws_E2_D_Disk_Full
        push    ds si
        jmp     @@97

@@93:
        pop     cx
        mov     si, offset Ws_E2_D_Disk_Full
        push    ds si
        jmp     @@97

@@94:
        mov     si, offset Ws_E2_D_Opening_Image
        push    ds si
        jmp     @@97

@@95:
        mov     si, offset Ws_E2_D_BOOTCODE_Not_Found
        push    ds si

@@97:
        mov     si, offset Ws_E2_F_Error_Message
        mov     [(Wsio_Area ptr di).Field_Address_Hi], ds
        mov     [(WSio_Area ptr di).Field_Address_Lo], si

        push    ds si
        pop     di es

        pop     si ds
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

        call    General_I_O_Error

@@99:
        ret

ENDP    Open_Disk_Image



;**********************************************************************
PROC    Include_XL_DOS_Files_In_Disk_Image
;**********************************************************************
;-----------------------------------------------------------------------
; Save current values of PC_ATARI file to be written to ATARI disk image
;-----------------------------------------------------------------------
        mov     cx, [File_Size_In_Sectors]
        push    cx
        mov     cx, [Remainder_Bytes]
        push    cx

        mov     si, offset Save_File_Map_Entry
        push    ds si
        pop     di es
        mov     si, offset File_Map_Entry
        mov     cx, DIR_ENTRY_LENGTH
        rep     movsb

;------------------------------------------
; Store DOS boot sector nr in bootcode area
;------------------------------------------
        mov     si, offset Bootcode_Data
        add     si, BOOTCODE_OFFSET_DOS_BOOT_SECTOR
        mov     cx, [Disk_Sector_Current]
        mov     [ds:si], cx

;------------------------------
; Prepare to write DOS.SYS file
;------------------------------
        mov     si, offset File_Map_Entry.File_Name
        push    ds si
        pop     di es
        mov     si, offset File_Name_DOS_SYS
        mov     cx, FILE_NAME_LENGTH
        rep     movsb

;-------------------------------
; Setup pathname of DOS.SYS file
;-------------------------------
        call    Determine_Pathname_Filesize_XL_DOS_File
        cmp     [Dir2atr_Error], LOGIC_YES      ; Error encountered?
        je      @@90                            ; Yes
                                                ; No, so
;----------
; File size
;----------
        mov     si, offset File_Map_Entry.File_Size
        mov     dx, [File_Size_In_Bytes_Hi]
        mov     cx, [File_Size_In_Bytes_Lo]
        mov     [byte ds:si + 2], dl
        mov     [byte ds:si + 1], ch
        mov     [byte ds:si], cl

;----------------------------------------------------------------
; Remaining sectors on disk housekeeping, after writing DOS to it
;----------------------------------------------------------------
        mov     ax, [File_Size_In_Sectors]

        clc                                             ; Clear carry
        add     [Ws_CF_Progress_Bar_Sectors_Lo], ax
        jnc     @@25
        inc     [Ws_CF_Progress_Bar_Sectors_Hi]

@@25:
        sub     [Disk_Sectors_Available], ax
        mov     [File_Size_In_Sectors], ax

        call    Determine_Sectors_Per_Progress_Bar

;---------------------------------------
; Write DOS.SYS file to Atari disk image
;---------------------------------------
        call    Open_8bit_Pc_File
        call    Move_Pc_File_To_Disk_Image
        call    Close_8bit_Pc_File

        cmp     [Dir2atr_Error], LOGIC_YES              ; Error encountered?
        je      @@98                                    ; Yes
                                                        ; No, so
;
; Set fixed date/time to program release
;
        mov     [SpartaDos_Date_DD], 13
        mov     [SpartaDos_Date_MM], 1
        mov     [SpartaDos_Date_YY], 99
        mov     [SpartaDos_Time_HH], 18
        mov     [SpartaDos_Time_MM], 0

        call    Update_8bit_VTOC_File

@@30:
;--------------------------------------------------------------------------
; Restore current values of PC_ATARI file to be written to ATARI disk image
;--------------------------------------------------------------------------
        mov     si, offset File_Map_Entry
        push    ds si
        pop     di es
        mov     si, offset Save_File_Map_Entry
        mov     cx, DIR_ENTRY_LENGTH
        rep     movsb

        pop     cx
        mov     [Remainder_Bytes], cx
        pop     cx
        mov     [File_Size_In_Sectors], cx

        jmp     @@99

@@90:
;---------------
; Error routines
;---------------
        mov     si, offset Ws_E2_D_DOS_SYS_Not_Found
        push    ds si
        mov     si, offset Ws_E2_F_Error_Message
        mov     [(Wsio_Area ptr di).Field_Address_Hi], ds
        mov     [(WSio_Area ptr di).Field_Address_Lo], si

        push    ds si
        pop     di es

        pop     si ds
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

        call    General_I_O_Error

@@98:
        pop     cx
        pop     cx

@@99:
        ret

ENDP    Include_XL_DOS_Files_In_Disk_Image



;**********************************************************************
PROC    Determine_Pathname_Filesize_XL_DOS_File
;**********************************************************************
        call    Setup_Pathname_ATARI_DOS_SYS_File

;-----------------------------
; Open Atari 8bit DOS.SYS file
;-----------------------------
        call    Open_8bit_Pc_File
        cmp     [Dir2atr_Error], LOGIC_YES              ; Error encountered?
        je      @@99                                    ; Yes
                                                        ; No, so
;-----------------------------
; Determine File Size in bytes
;-----------------------------
        call    Determine_Pc_File_Size_In_Bytes

;--------------------------------------------------------
; Determine File Size in sectors (and remainder of bytes)
;--------------------------------------------------------
        mov     dx, [File_Size_In_Bytes_Hi]
        mov     ax, [File_Size_In_Bytes_Lo]
        xor     cx, cx                                  ; Reset cx
        mov     bx, [Disk_Sector_Size]
        mov     [Remainder_Bytes], bx
        div     bx
        cmp     dx, NULL                                ; Remainder?
        jz      @@20                                    ; No
                                                        ; Yes, so
        inc     ax                                      ; We need another sector
        mov     [Remainder_Bytes], dx                   ; Save remainder

@@20:
        mov     [File_Size_In_Sectors], ax

        call    Close_8bit_Pc_File

@@99:
        ret

ENDP    Determine_Pathname_Filesize_XL_DOS_File



;**********************************************************************
PROC    Determine_Pc_File_Size_In_Bytes
;**********************************************************************
        mov     si, offset PC_ATARI_File
        push    ds si
        pop     di es

;------------------
; Go to end of file
;------------------
        push    es di

        mov     ax, DOS_MOVE_FILE_POINTER_END
        mov     bx, [(FMS_Area ptr di).Disk_Handler]
        xor     cx, cx                                  ; Use offset 0000:0000
        xor     dx, dx
        int     DOS_SERVICE

        pop     di es

        mov     [File_Size_In_Bytes_Hi], dx
        mov     [File_Size_In_Bytes_Lo], ax

;--------------------
; Go to begin of file
;--------------------
        mov     ax, DOS_MOVE_FILE_POINTER_BEGIN
        mov     bx, [(FMS_Area ptr di).Disk_Handler]
        xor     cx, cx                                  ; Use offset 0000:0000
        xor     dx, dx
        int     DOS_SERVICE

        ret

ENDP    Determine_Pc_File_Size_In_Bytes



;**********************************************************************
PROC    Move_Pc_File_To_Disk_Image
;**********************************************************************
;-------------------------------------
; Initialize directory being processed
;-------------------------------------
        mov     si, offset Ws_CF_D_Add_Dir
        push    ds si
        pop     di es
        mov     cx, FILE_NAME_LENGTH
        xor     ax, ax
        mov     al, SPACE
        rep     stosb

;--------------------------
; Show dir we're working on
;--------------------------
        mov     si, offset PC_ATARI_Pathname
        push    ds si
        pop     di es
        add     di, PATH_LENGTH

;
; Search "\" at end of path
;
        std                                             ; Search direction is down
        mov     ax, BACKSLASH                           ; Search for "\"
        mov     cx, PATH_LENGTH
        repne   scasb                                   ; Search uses es:di
        cld                                             ; Cancel the std setting
        cmp     [byte es:di], COLON                     ; Are we at the root (i.e. C:\*.*)?
        jne     @@01                                    ; No
                                                        ; Yes, so
        mov     si, offset Root_Directory_Name          ; Point to "Root"
        push    ds si
        jmp     @@02

@@01:
;
; Search "\" before directory
;
        std                                             ; Search direction is down
        repne   scasb                                   ; Search uses es:di
        cld                                             ; Cancel the std setting
        inc     di                                      ; Pointer adjustment after search
        inc     di                                      ; Position after "\"

        push    es di                                   ; Save Dir we're working on

@@02:
;--------------------------
; Show dir we're working on
;--------------------------
        mov     si, offset Ws_CF_D_Add_Dir
        pop     di es                                   ; Restore dir we're working on

@@03:
        mov     cl, [byte es:di]                        ; Move dir bytes until we encouter a "\"
        cmp     cl, BACKSLASH                           ; Is it a "\"
        je      @@04                                    ; Yes
                                                        ; No, so
        mov     [byte ds:si], cl                        ; Move byte
        inc     si                                      ; Move to next byte
        inc     di                                      ; Move to next byte
        jmp     @@03                                    ; Check next byte

@@04:
;---------------------------
; Show file we're working on
;---------------------------
        mov     si, offset Ws_CF_D_Add_File_File
        push    ds si
        pop     di es
        mov     si, offset File_Map_Entry.File_Name
        mov     cx, FILE_NAME_LENGTH
        rep     movsb

        mov     si, offset Ws_CF_D_Add_File_File
        mov     cx, FILE_NAME_LENGTH

@@05:
        cmp     [byte ds:si], NULL
        jne     @@06
        mov     [byte ds:si], SPACE

@@06:
        inc     si
        loop    @@05

        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@07                                    ; Yes
                                                        ; No, so
;------------------------
; Display progress screen
;------------------------
        mov     si, offset Ws_CF
        mov     [byte ds:si], WSIO_DISPLAY_FIELDS_ONLY

        push    ds si
        call    WSIO
        pop     si ds

@@07:
        mov     [Sector_Count_Link_Sector], NULL
        mov     [Sector_Offset_Link_Sector], SECTOR_OFFSET_LINK_SECTOR_START
        mov     [Disk_Link_Sector_Current], NULL
        mov     [Disk_Link_Sector_Next], NULL
        mov     [Disk_Link_Sector_Prev], NULL

        mov     cx, [Disk_Sector_Current]
        mov     [Disk_Sector_Start], cx

        mov     cx, [File_Size_In_Sectors]

        cmp     cx, 0                                   ; Are we dealing with a "0" bytes file size?
        je      @@99                                    ; Yes
                                                        ; No, so
@@10:
;---------------
; Read 8bit file
;---------------
        push    cx

        mov     si, offset PC_ATARI_File
        push    ds si
        pop     di es

;-----------------
; Init data buffer
;-----------------
        push    es di

        mov     si, offset Disk_I_O_Buffer
        push    ds si
        pop     di es
        xor     ax, ax
        mov     cx, [Disk_Sector_Size]
        rep     stosb

        pop     di es

;------------------------------------------------------
; Are we processing the "last" sector of the 8bit file?
;------------------------------------------------------
        pop     cx
        push    cx

        cmp     cx, 1                                   ; Last sector?
        jne     @@20                                    ; No
                                                        ; Yes, so
        mov     cx, [Remainder_Bytes]
        mov     [(FMS_Area ptr di).Record_Size], cx
        
@@20:
;-----------------------------
; Process 8bit file data bytes
;-----------------------------
        push    es di
        call    FMSIO
        pop     di es

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        jne     @@90                            ; Error!

;-----------------------
; Write 8bit data sector
;-----------------------
        call    Write_8bit_Data_Sector

        cmp     [Dir2atr_Error], LOGIC_YES      ; Error encountered?
        je      @@91                            ; Yes
                                                ; No, so
;
; Calculate progress bar size, and show it if necessary
;
        clc                                             ; Clear carry
        inc     [Ws_CF_Progress_Bar_Cnt_Sectors_Lo]
        jnc     @@30
        inc     [Ws_CF_Progress_Bar_Cnt_Sectors_Hi]

@@30:
        call    Show_Progress_Bar

        pop     cx
        loop    @@10

;-----------------------------------------------
; Check if we have to write the last link sector
;-----------------------------------------------
        cmp     [Disk_Link_Sector_Current], NULL
        je      @@99                                    ; No
                                                        ; Yes, so
;
; Determine Disk Link Sector number
;
        mov     cx, [Disk_Sector_Current]
        mov     [Disk_Link_Sector_Next], cx

;
; Store next and previous link sector information
;
        mov     si, offset Disk_Link_Sector_Buffer
        mov     cx, NULL
        mov     [ds:si], cx
        mov     cx, [Disk_Link_Sector_Prev]
        mov     [ds:si + 2], cx

;
; Write Link Sector (and update bitmap)
;
        mov     cx, [Disk_Link_Sector_Current]
        mov     [Disk_Sector_Current], cx
        call    Write_8bit_Sector_Link_Sector

;
; Reset/Restore pointers
;
        mov     cx, [Disk_Link_Sector_Next]
        mov     [Disk_Sector_Current], cx

        mov     [Sector_Count_Link_Sector], NULL
        mov     [Disk_Link_Sector_Current], NULL
        mov     [Disk_Link_Sector_Next], NULL

        jmp     @@99

@@90:
;
; E R R O R S
;
        pop     cx

        mov     si, offset Ws_E2_Error_Message
        push    ds si
        pop     di es
        mov     si, offset Ws_E2_D_Reading_File
        mov     cx, WS_E2_ERROR_MESSAGE_SIZE
        rep     movsb

        mov     si, offset Ws_E2_Error_Message
        push    ds si
        mov     cx, WS_E2_ERROR_MESSAGE_SIZE
        push    cx
        mov     si, offset PC_ATARI_Pathname
        push    ds si
        mov     cx, WS_E2_ERROR_MESSAGE_SIZE - 7
        push    cx
        mov     cx, 1                           ; Append spaces
        push    cx

        call    APPEND
        pop     ax ax ax ax ax ax ax

        mov     si, offset Ws_E2_Error_Message
        push    ds si
        jmp     @@97

@@91:
        pop     cx
        mov     si, offset Ws_E2_D_Writing_Image
        push    ds si
        jmp     @@97

@@97:
        mov     si, offset Ws_E2_F_Error_Message
        mov     [(Wsio_Area ptr di).Field_Address_Hi], ds
        mov     [(WSio_Area ptr di).Field_Address_Lo], si

        push    ds si
        pop     di es

        pop     si ds
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

        call    General_I_O_Error

@@99:
        ret

ENDP    Move_Pc_File_To_Disk_Image



;**********************************************************************
PROC    Update_8bit_Link_Sector
;**********************************************************************
;----------------------------------------------
; Can we stuff sector link info in link sector?
;----------------------------------------------
        cmp     [Sector_Count_Link_Sector], NULL        ; Can we stuff info?
        jne     @@20                                    ; Yes
                                                        ; No, so
;----------------------------------------------
; Should we write this Link Sector information?
;----------------------------------------------
        cmp     [Disk_Link_Sector_Current], NULL
        je      @@10                                    ; No
                                                        ; Yes, so
;----------------------------------
; Determine Disk Link Sector number
;----------------------------------
        mov     cx, [Disk_Sector_Current]
        mov     [Disk_Link_Sector_Next], cx

;------------------------------------------------
; Store next and previous link sector information
;------------------------------------------------
        mov     si, offset Disk_Link_Sector_Buffer
        mov     cx, [Disk_Link_Sector_Next]
        mov     [ds:si], cx
        mov     cx, [Disk_Link_Sector_Prev]
        mov     [ds:si + 2], cx

;--------------------------------------
; Write Link Sector (and update bitmap)
;--------------------------------------
        mov     cx, [Disk_Link_Sector_Current]
        mov     [Disk_Sector_Current], cx
        call    Write_8bit_Sector_Link_Sector

;-------------------------------------------------------------
; Determine previous, current and next link sector number info
;-------------------------------------------------------------
        mov     cx, [Disk_Link_Sector_Current]
        mov     [Disk_Link_Sector_Prev], cx
        mov     cx, [Disk_Link_Sector_Next]
        mov     [Disk_Sector_Current], cx
        mov     [Disk_Link_Sector_Next], NULL

@@10:
;-------------------------
; Reset Link Sector buffer
;-------------------------
        mov     si, offset Disk_Link_Sector_Buffer + 4
        push    ds si
        pop     di es
        xor     ax, ax
        mov     cx, EIGHTBIT_SECTOR_SIZE_DOUBLE - 4
        rep     stosb

;--------------------------------------------
; Determine Disk Link Sector number, and more
;--------------------------------------------
        mov     cx, [Disk_Sector_Current]
        mov     [Disk_Link_Sector_Current], cx
        inc     [Disk_Sector_Current]

        mov     [Sector_Offset_Link_Sector], SECTOR_OFFSET_LINK_SECTOR_START
        mov     [Sector_Count_Link_Sector], SECTOR_COUNT_LINK_SECTOR_SINGLE
        cmp     [Disk_Sector_Size], EIGHTBIT_SECTOR_SIZE_DOUBLE
        jne     @@20                                    ; No
                                                        ; Yes, so
        mov     [Sector_Count_Link_Sector], SECTOR_COUNT_LINK_SECTOR_DOUBLE

@@20:
;-----------------------------------------------------------
; Store current data sector number in the link sector buffer
;-----------------------------------------------------------
        dec     [Sector_Count_Link_Sector]              ; One more info double byte used

;
; Determine correct position into link sector buffer
;
        mov     si, offset Disk_Link_Sector_Buffer
        xor     cx, cx
        mov     cl, [Sector_Offset_Link_Sector]
        add     si, cx

;
; Point to next position already
;
        inc     [Sector_Offset_Link_Sector]
        inc     [Sector_Offset_Link_Sector]

;
; Store information at determined offset within link sector buffer
;
        mov     cx, [Disk_Sector_Current]
        mov     [ds:si], cx

@@99:
        ret

ENDP    Update_8bit_Link_Sector



;**********************************************************************
PROC    Update_8bit_Bitmap
;**********************************************************************
        mov     si, offset Disk_Bitmap_Buffer
        mov     ax, [Disk_Sector_Current]       ; Which sector was processed

        xor     dx, dx
        xor     cx, cx
        mov     bx, 8                           ; Nr of sector per bitmap byte
        div     bx                              ; Divide dx:ax by cx:bx
                                                ; ax=result dx=remainder
        add     si, ax                          ; To move to correct bitmap byte in the bitmap sector
        xor     ax, ax
        mov     al, [byte ds:si]                ; Load bitmap byte

        mov     bx, 0100h                       ; To determine sector <-> bit relation
        mov     cx, dx                          ; To determine the bit position
        inc     cx                              ; the bit within the bitmap byte
        ror     bx, cl                          ; Go to correct bit
        mov     cx, ax                          ; Check if sector is used
        and     cx, bx
        cmp     cx, NULL                        ; Sector used?
        je      @@99                            ; Yes
                                                ; No, so
        xor     ax, bx                          ; Set bit to in use
        mov     [byte ds:si], al                ; Save bitmap byte

        dec     [Disk_Sectors_Free]             ; One less free disk sector

@@99:
        ret

ENDP    Update_8bit_Bitmap



;**********************************************************************
PROC    Update_Pc_Dir_Map_Link_Sector_Pointer
;**********************************************************************
        mov     cx, [Dir_Curr_ptr]                      ; Offset into table
        mov     es, [Pc_Dir_Map_ptr_es]                 ; Directory to check
        mov     di, [Pc_Dir_Map_ptr_di]
        jmp     @@20

@@10:
        add     di, PC_DIR_MAP_ENTRY_LENGTH             ; Next entry into table

@@20:
        loop    @@10

;---------------------------
; Update Link Sector Pointer
;---------------------------
        add     di, PC_DIR_MAP_OFFSET_LINK_SECTOR       ; Offset to Link sector
        mov     cx, [Disk_Sector_VTOC_Current]
        mov     [es:di], cx

@@99:
        ret

ENDP    Update_Pc_Dir_Map_Link_Sector_Pointer



;**********************************************************************
PROC    Update_8bit_VTOC_Directory_Current
;**********************************************************************
        mov     [VTOC_Map_Entry_Nr], 1                  ; Very first entry

        mov     cx, [Dir_Curr_ptr]                      ; Offset into table
        mov     es, [Pc_Dir_Map_ptr_es]                 ; Directory to check
        mov     di, [Pc_Dir_Map_ptr_di]
        jmp     @@20

@@10:
        add     di, PC_DIR_MAP_ENTRY_LENGTH             ; Next entry into table

@@20:
        loop    @@10

;----------------------
; Search directory name
;----------------------
        add     di, PATH_LENGTH

;
; Search "\" at end of path
;
        std                                             ; Search direction is down
        mov     ax, BACKSLASH                           ; Search for "\"
        mov     cx, PATH_LENGTH
        repne   scasb                                   ; Search uses es:di
        cld                                             ; Cancel the std setting
        cmp     [byte es:di], COLON                     ; Are we at the root (i.e. C:\*.*)?
        jne     @@25                                    ; No
                                                        ; Yes, so
        mov     si, offset Main_Directory_Name          ; Point to "MAIN"
        push    ds si                                   ; Save pc directory name
        jmp     @@28

@@25:
        cmp     [Dir_Curr_ptr], 1                       ; Are we at the "MAIN" directory?
        jne     @@27                                    ; No
                                                        ; Yes, so
        push    es di                                   ; Save File Path
        mov     es, [Parm_MAIN_DIR_ptr_es]
        mov     di, [Parm_MAIN_DIR_ptr_di]
        mov     al, [byte es:di]                        ; Load SpartaDos MAIN Dir answer
        pop     di es                                   ; Restore File Path

        cmp     al, SPACE                               ; Use SpartaDos MAIN Dir?
        je      @@27                                    ; No
                                                        ; Yes, so
        mov     si, offset Main_Directory_Name          ; Point to "MAIN"
        push    ds si                                   ; Save pc directory name
        jmp     @@28

@@27:
;
; Search "\" before directory
;
        mov     ax, BACKSLASH                           ; Search for "\"
        std                                             ; Search direction is down
        repne   scasb                                   ; Search uses es:di
        cld                                             ; Cancel the std setting
        inc     di                                      ; Pointer adjustment after search
        inc     di                                      ; Position after "\"

        push    es di                                   ; Save pc directory name

@@28:
;-----------------------------------
; Initialize 8bit directory VTOC map
;-----------------------------------
        mov     es, [VTOC_Map_ptr_es]                   ; 8bit VTOC directory
        mov     di, [VTOC_Map_ptr_di]
        push    es di                                   ; Save 8bit VTOC map address

        mov     cx, VTOC_MAP_LENGTH
        xor     ax, ax
        mov     al, NULL
        rep     stosb

        pop     di es                                   ; Restore 8bit VTOC map address


;       |       .///////////////////////////////////////////.   |
;       |       .       VTOC directory entry                .   |
;       |       .............................................   |
;       |       .       pos.  description                   .   |
;       |       .        1    hex 28 indicating dir entry   .   |
;       |       .        2    hex 00 00                     .   |
;       |       .        4    Directory size                .   |
;       |       .        7    directory name                .   |
;       |       .       18    hex 00 00 00 00 00 00         .   |
;       |       .///////////////////////////////////////////.   |

;
; Indicate directory type
;
        mov     [byte es:di], EIGHTBIT_VTOC_ENTRY_DIRECTORY

;
; Directory name
;
        add     di, 6                                   ; Go to directory name
        xor     cx, cx                                  ; Reset position counter

@@30:
        mov     [Save_ptr_es], es                       ; Save vtoc entry pos
        mov     [Save_ptr_di], di
        pop     di es                                   ; Restore pc directory name

        mov     al, [byte es:di]                        ; From field
        inc     di                                      ; Point to next character already

        push    es di
        mov     es, [Save_ptr_es]
        mov     di, [Save_ptr_di]

        cmp     al, BACKSLASH                           ; "\" character?
        je      @@60                                    ; Yes
                                                        ; No, so
        cmp     al, DOT                                 ; "." character?
        je      @@40                                    ; Yes
                                                        ; No, so
        call    W9x_Atari_File_Name_Correction

        mov     [byte es:di], al                        ; To field
        inc     di                                      ; To field next position
        inc     cx
        jmp     @@30                                    ; Next character

@@40:
        cmp     cx, 8                                   ; 8 characters processed?
        je      @@50                                    ; Yes
                                                        ; No, so
        mov     [byte es:di], SPACE                     ; To field
        inc     di                                      ; To field next position
        inc     cx
        jmp     @@40

@@50:
        mov     [Save_ptr_es], es                       ; Save vtoc entry pos
        mov     [Save_ptr_di], di
        pop     di es                                   ; Restore pc directory name

        mov     al, [byte es:di]                        ; From field
        inc     di                                      ; Point to next character already

        push    es di
        mov     es, [Save_ptr_es]
        mov     di, [Save_ptr_di]

        cmp     al, BACKSLASH                           ; "\" character?
        je      @@60                                    ; Yes
                                                        ; No, so
        call    W9x_Atari_File_Name_Correction

        mov     [byte es:di], al                        ; To field
        inc     di                                      ; To field next position
        inc     cx
        cmp     cx, EIGHTBIT_FILE_NAME_LENGTH           ; Filename completely processed?
        jne     @@50                                    ; No
                                                        ; Yes, so
        jmp     @@70

@@60:
        cmp     cx, EIGHTBIT_FILE_NAME_LENGTH           ; 11 characters processed?
        je      @@70                                    ; Yes
                                                        ; No, so
        mov     [byte es:di], SPACE                     ; To field
        inc     di                                      ; To field next position
        inc     cx
        jmp     @@60

@@70:
        pop     di es

@@99:
        ret

ENDP    Update_8bit_VTOC_Directory_Current



;**********************************************************************
PROC    Update_8bit_VTOC_Directories
;**********************************************************************
        mov     [Requested_Format_LibFil], "1"          ; See direntry format

        call    Retrieve_Pc_Dirs

        mov     [Dir_Dir_Counter], 1

        push    ds si                                   ; Save program entry

        xor     bx, bx                                  ; Nr of entries processed

        mov     es, [Parm_Dir_Map_ptr_es]
        mov     di, [Parm_Dir_Map_ptr_di]               ; Directory Map
        push    es di                                   ; Save found directories table

        mov     es, [VTOC_Map_ptr_es]                   ; 8bit VTOC directory
        mov     di, [VTOC_Map_ptr_di]
        add     di, EIGHTBIT_VTOC_ENTRY_SIZE            ; Skip very first entry

        pop     si ds                                   ; Restore found directories table

@@10:
        cmp     [byte ds:si], NULL                      ; (more) subdirectories present?
        je      @@99                                    ; No
                                                        ; Yes, so
        cmp     [byte ds:si], DOT                       ; Up to previous directory marker?
        jne     @@20                                    ; No
                                                        ; Yes, so
        add     si, DIR_ENTRY_LENGTH                    ; Go to next entry
        jmp     @@10

@@20:
        inc     [Dir_Dir_Counter]

;       |       .///////////////////////////////////////////.   |
;       |       .       VTOC directory entry                .   |
;       |       .............................................   |
;       |       .       pos.  description                   .   |
;       |       .        1    hex 28 indicating dir entry   .   |
;       |       .        2    sector nr of first link sector.   |
;       |       .        4    hex 00 00 00                  .   |
;       |       .        7    directory name                .   |
;       |       .       18    date/time stamp               .   |
;       |       .///////////////////////////////////////////.   |

        push    ds si es di                             ; Save table entry positions

        push    ds si
        pop     di es
        call    Copy_Entry_From_Dir_Map_To_File_Map
        call    Set_SpartaDos_File_Date_And_Time
 
        pop     di es si ds                             ; Restore table entry positions
        push    ds si es di                             ; Save table entry positions

;
; Indicate directory type
;
        mov     [byte es:di], EIGHTBIT_VTOC_ENTRY_DIRECTORY

;
; Directory name
;
        add     di, 6                                   ; Go to directory name
        xor     cx, cx                                  ; Reset position counter

@@30:
        cmp     cx, EIGHTBIT_FILE_NAME_LENGTH           ; 11 characters processed?
        je      @@70                                    ; Yes
                                                        ; No, so
        mov     al, [byte ds:si]                        ; From field
        cmp     al, "<"                                 ; "<" character? (from <DIR> text)
        je      @@70                                    ; Yes
                                                        ; No, so
        cmp     al, NULL                                ; Hex 00 character?
        je      @@40                                    ; Yes
                                                        ; No, so
        cmp     al, DOT                                 ; "." character?
        je      @@40                                    ; Yes
                                                        ; No, so
        call    W9x_Atari_File_Name_Correction
        mov     [byte es:di], al                        ; To field
        inc     di                                      ; To field next position
        inc     si                                      ; From field next position
        inc     cx
        jmp     @@30                                    ; Next character

@@40:
        cmp     cx, 8                                   ; 8 characters processed?
        je      @@50                                    ; Yes
                                                        ; No, so
        mov     [byte es:di], SPACE
        inc     di                                      ; To field next position
        inc     cx
        jmp     @@40

@@50:
        inc     si                                      ; From field next position
        mov     al, [byte ds:si]                        ; From field
        cmp     al, NULL                                ; Hex 00 character?
        jne     @@60                                    ; No
                                                        ; Yes so
        mov     al, SPACE                               ; Replace by " " character

@@60:
        call    W9x_Atari_File_Name_Correction
        mov     [byte es:di], al                        ; To field
        inc     di                                      ; To field next position
        inc     cx

@@70:
        cmp     cx, EIGHTBIT_FILE_NAME_LENGTH           ; Filename completely processed?
        jne     @@50                                    ; No
                                                        ; Yes, so
        pop     di es si ds                             ; Restore table entry positions
        push    ds si es di                             ; Save table entry positions

        add     di, 17                                  ; Go to date/time
        mov     cl, [SpartaDos_Date_DD]
        mov     [byte es:di], cl
        mov     cl, [SpartaDos_Date_MM]
        mov     [byte es:di + 1], cl
        mov     cl, [SpartaDos_Date_YY]
        mov     [byte es:di + 2], cl
        mov     cl, [SpartaDos_Time_HH]
        mov     [byte es:di + 3], cl
        mov     cl, [SpartaDos_Time_MM]
        mov     [byte es:di + 4], cl

        inc     bx                                      ; Another entry processed

        pop     di es si ds                             ; Restore table entry positions

        add     di, EIGHTBIT_VTOC_ENTRY_SIZE            ; Go to next entry
        add     si, DIR_ENTRY_LENGTH                    ; Go to next entry

        jmp     @@10

@@99:
        pop     si ds                                   ; Restore program entry

        mov     ax, [VTOC_Map_Entry_Nr]
        add     ax, bx                                  ; Add nr of processed entries
        mov     [VTOC_Map_Entry_Nr], ax

        ret

ENDP    Update_8bit_VTOC_Directories



;**********************************************************************
PROC    Update_8bit_VTOC_File
;**********************************************************************
        mov     es, [VTOC_Map_ptr_es]                   ; 8bit VTOC directory
        mov     di, [VTOC_Map_ptr_di]
        mov     cx, [VTOC_Map_Entry_Nr]

@@10:
        add     di, EIGHTBIT_VTOC_ENTRY_SIZE            ; Skip entry
        loop    @@10

;       |       .///////////////////////////////////////////.   |
;       |       .       VTOC entry file                     .   |
;       |       .............................................   |
;       |       .       pos.  description                   .   |
;       |       .        1    hex 08 indicating file entry  .   |
;       |       .        2    sector nr where data starts   .   |
;       |       .        4    file size                     .   |
;       |       .        7    file name                     .   |
;       |       .       18    date/time stamp               .   |
;       |       .///////////////////////////////////////////.   |

        push    es di                                   ; Save begin of entry

;
; Indicate file type
;
        mov     [byte es:di], EIGHTBIT_VTOC_ENTRY_FILE

;
; Start sector of data
;
        mov     ax, [Disk_Sector_Start]
        mov     [es:di + 1], ax

;
; File Size
;
        mov     si, offset File_Map_Entry.File_Size
        mov     dl, [byte ds:si + 2]
        mov     ah, [byte ds:si + 1]
        mov     al, [byte ds:si]

        mov     [es:di + 3], ax
        mov     [es:di + 5], dl

;
; File name
;
        mov     si, offset File_Map_Entry.File_Name
        add     di, 6                                   ; Go to directory name
        xor     cx, cx                                  ; Reset position counter

@@30:
        mov     al, [byte ds:si]                        ; From field
        cmp     al, DOT                                 ; "." character?
        je      @@40                                    ; Yes
                                                        ; No, so
        cmp     al, NULL                                ; Hex 00 character?
        je      @@40                                    ; Yes
                                                        ; No, so
        call    W9x_Atari_File_Name_Correction
        mov     [byte es:di], al                        ; To field
        inc     di                                      ; To field next position
        inc     si                                      ; From field next position
        inc     cx
        jmp     @@30                                    ; Next character

@@40:
        cmp     cx, 8                                   ; 8 characters processed?
        je      @@50                                    ; Yes
                                                        ; No, so
        mov     [byte es:di], SPACE
        inc     di                                      ; To field next position
        inc     cx
        jmp     @@40

@@50:
        inc     si                                      ; From field next position
        mov     al, [byte ds:si]                        ; From field
        cmp     al, NULL                                ; Hex 00 character?
        jne     @@60                                    ; No
                                                        ; Yes, so
        mov     al, SPACE                               ; Replace it by space

@@60:
        call    W9x_Atari_File_Name_Correction
        mov     [byte es:di], al                        ; To field
        inc     di                                      ; To field next position
        inc     cx
        cmp     cx, EIGHTBIT_FILE_NAME_LENGTH           ; Filename completely processed?
        jne     @@50                                    ; No
                                                        ; Yes, so
        pop     di es                                   ; Restore begin of entry
        add     di, 17                                  ; Go to date/time
        mov     cl, [SpartaDos_Date_DD]
        mov     [byte es:di], cl
        mov     cl, [SpartaDos_Date_MM]
        mov     [byte es:di + 1], cl
        mov     cl, [SpartaDos_Date_YY]
        mov     [byte es:di + 2], cl
        mov     cl, [SpartaDos_Time_HH]
        mov     [byte es:di + 3], cl
        mov     cl, [SpartaDos_Time_MM]
        mov     [byte es:di + 4], cl

        inc     [VTOC_Map_Entry_Nr]

        ret

ENDP    Update_8bit_VTOC_File



;**********************************************************************
PROC    Write_8bit_Data_Sector
;**********************************************************************
;-------------------------
; Update sector link table
;-------------------------
        call    Update_8bit_Link_Sector

;-----------------------------
; Determine sector to write to
;-----------------------------
        mov     si, offset ATARI____File
        push    ds si
        pop     di es

        mov     cx, [Disk_Sector_Current]
        sub     cx, DISK_BOOTCODE_SECTOR_SIZE
        mov     [(FMS_Area ptr di).Record_Nr], cx

        push    es di
        call    FMSIO
        pop     di es

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        jne     @@90                                    ; Error

        dec     [Disk_Sectors_Left]

        call    Update_8bit_Bitmap
        jmp     @@99

@@90:
;--------------------
; Indicate error here
;--------------------
        mov     [Dir2atr_Error], LOGIC_YES

@@99:
        inc     [Disk_Sector_Current]
        ret

ENDP    Write_8bit_Data_Sector



;**********************************************************************
PROC    Write_8bit_Sector_Link_Sector
;**********************************************************************
        mov     si, offset ATARI____File
        push    ds si
        pop     di es
        mov     si, offset Disk_Link_Sector_Buffer
        mov     [(FMS_Area ptr di).Data_Address_Hi], ds
        mov     [(FMS_Area ptr di).Data_Address_Lo], si

        mov     cx, [Disk_Sector_Current]
        sub     cx, DISK_BOOTCODE_SECTOR_SIZE
        mov     [(FMS_Area ptr di).Record_Nr], cx

        push    es di
        call    FMSIO
        pop     di es

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        jne     @@90                                    ; Error

        dec     [Disk_Sectors_Left]

        call    Update_8bit_Bitmap
        jmp     @@99

@@90:
;--------------------
; Indicate error here
;--------------------
        mov     [Dir2atr_Error], LOGIC_YES

@@99:
        mov     si, offset ATARI____File
        push    ds si
        pop     di es
        mov     si, offset Disk_I_O_Buffer
        mov     [(FMS_Area ptr di).Data_Address_Hi], ds
        mov     [(FMS_Area ptr di).Data_Address_Lo], si

        ret

ENDP    Write_8bit_Sector_Link_Sector



;**********************************************************************
PROC    Write_8bit_VTOC
;**********************************************************************
;-------------------------
; Save current disk sector
;-------------------------
        mov     cx, [Disk_Sector_Current]               ; Save current sector
        push    cx

        mov     [Sector_Count_Link_Sector], NULL
        mov     [Sector_Offset_Link_Sector], SECTOR_OFFSET_LINK_SECTOR_START
        mov     [Disk_Link_Sector_Current], NULL
        mov     [Disk_Link_Sector_Next], NULL
        mov     [Disk_Link_Sector_Prev], NULL

        mov     cx, [Disk_Sector_VTOC_Current]
        mov     [Disk_Sector_Current], cx
        mov     [Disk_Sector_Start], cx

;--------------------------------------------
; Determine size of VTOC (for this directory)
;--------------------------------------------
        mov     ax, [VTOC_Map_Entry_Nr]
        xor     bx, bx                                  ; Reset bx
        mov     cx, EIGHTBIT_VTOC_ENTRY_SIZE
        xor     dx, dx                                  ; Reset dx

        mul     cx                                      ; Determine VTOC size

        mov     es, [VTOC_Map_ptr_es]                   ; 8bit VTOC directory
        mov     di, [VTOC_Map_ptr_di]
        mov     [es:di + 3], ax                         ; Directory size
        mov     [es:di + 5], dl

;-------------------------------
; Determine VTOC size in sectors
;-------------------------------
        mov     bx, [Disk_Sector_Size]
        xor     cx, cx                                  ; Reset cx

        div     bx                                      ; Determine nr of sectors

        cmp     dx, NULL                                ; No remainder?
        jz      @@10                                    ; No
                                                        ; Yes, so
        inc     ax                                      ; We need another sector

@@10:
        mov     [VTOC_Size_In_Sectors], ax
        mov     [VTOC_Sectors_To_Write], ax

;------------------------------
; Nr of vtoc sectors to process
;------------------------------
        mov     cx, ax                                  ; VTOC size in sectors

@@20:
;--------------------------------------------
; Write VTOC information (for this directory)
;--------------------------------------------
        mov     si, offset ATARI____File
        push    ds si
        pop     di es
        mov     cx, [VTOC_Map_ptr_es]                   ; 8bit VTOC directory
        mov     dx, [VTOC_Map_ptr_di]

;---------------------------------------------
; Determine VTOC sector to write (of VTOC map)
;---------------------------------------------
        mov     bx, [VTOC_Size_In_Sectors]              ; VTOC size in sectors
        sub     bx, [VTOC_Sectors_To_Write]             ; Minus nr of sectors to write

@@23:
;--------------------------------------------
; (Offset) VTOC sector to write determination
;--------------------------------------------
        cmp     bx, NULL
        jz      @@25
        dec     bx
        clc
        add     dx, [Disk_Sector_Size]
        jnc     @@23
        inc     cx
        jmp     @@23

@@25:
;----------------------------------------
; VTOC sector to be written is determined
;----------------------------------------
        mov     [(FMS_Area ptr di).Data_Address_Hi], cx
        mov     [(FMS_Area ptr di).Data_Address_Lo], dx

@@30:
        call    Write_8bit_Data_Sector

        cmp     [Dir2atr_Error], LOGIC_YES              ; Error encountered?
        je      @@99                                    ; Yes
                                                        ; No, so
        dec     [VTOC_Sectors_To_Write]
        cmp     [VTOC_Sectors_To_Write], NULL           ; More VTOC sectors to write?
        jnz     @@20                                    ; Yes
                                                        ; No, so
        mov     cx, [Disk_Sector_Current]               ; Next VTOC sector
        mov     [Disk_Sector_VTOC_Current], cx

;-----------------------------------------------
; Check if we have to write the last link sector
;-----------------------------------------------
        cmp     [Disk_Link_Sector_Current], NULL
        je      @@99                                    ; No
                                                        ; Yes, so
;
; Determine Disk Link Sector number
;
        mov     cx, [Disk_Sector_Current]
        mov     [Disk_Link_Sector_Next], cx

;
; Store next and previous link sector information
;
        mov     si, offset Disk_Link_Sector_Buffer
        mov     cx, NULL
        mov     [ds:si], cx
        mov     cx, [Disk_Link_Sector_Prev]
        mov     [ds:si + 2], cx

;
; Write Link Sector (and update bitmap)
;
        mov     cx, [Disk_Link_Sector_Current]
        mov     [Disk_Sector_Current], cx
        call    Write_8bit_Sector_Link_Sector

@@99:
;----------------------------
; Restore current disk sector
;----------------------------
        pop     cx
        mov     [Disk_Sector_Current], cx

;------------------------------
; Restore standard I/O defaults
;------------------------------
        mov     si, offset ATARI____File
        push    ds si
        pop     di es
        mov     si, offset Disk_I_O_Buffer
        mov     [(FMS_Area ptr di).Data_Address_Hi], ds
        mov     [(FMS_Area ptr di).Data_Address_Lo], si

        ret

ENDP    Write_8bit_VTOC



;**********************************************************************
PROC    Write_8bit_Bitmap
;**********************************************************************
;-------------------------------
; Determine Bitmap size in bytes
;-------------------------------
        mov     ax, [Disk_Sectors_Bitmap]               ; Nr of bitmap sectors
        xor     bx, bx                                  ; Reset bx
        mov     cx, [Disk_Sector_Size]
        xor     dx, dx                                  ; Reset dx

        mul     cx                                      ; Determine nr of bytes needed
                                                        ; ax contains nr of bytes
;-------------------------
; Save current disk sector
;-------------------------
        mov     cx, [Disk_Sector_Current]               ; Save current sector
        push    cx

;-------------------------
; Write Bitmap information
;-------------------------
        mov     si, offset ATARI____File
        push    ds si
        pop     di es
        mov     si, offset Disk_Bitmap_Buffer
        mov     [(FMS_Area ptr di).Data_Address_Hi], ds
        mov     [(FMS_Area ptr di).Data_Address_Lo], si
        mov     [(FMS_Area ptr di).Record_Size], ax

        mov     cx, [Disk_Sector_Bitmap_Current]
        mov     [Disk_Sector_Current], cx
        sub     cx, DISK_BOOTCODE_SECTOR_SIZE
        mov     [(FMS_Area ptr di).Record_Nr], cx

        push    es di
        call    FMSIO
        pop     di es

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        je      @@10

;--------------------
; Indicate error here
;--------------------
        mov     [Dir2atr_Error], LOGIC_YES
        jmp     @@99

@@10:
;--------------------------------------------
; Store nr of bitmap sectors in bootcode area
;--------------------------------------------
        mov     si, offset Bootcode_Data
        add     si, BOOTCODE_OFFSET_NR_OF_BITMAPS
        mov     cx, [Disk_Sectors_Bitmap]
        mov     [byte ds:si], cl

;-------------------------------------------
; Store first bitmap sector in bootcode area
;-------------------------------------------
        mov     si, offset Bootcode_Data
        add     si, BOOTCODE_OFFSET_FIRST_BITMAP_SECTOR
        mov     cx, [Disk_Sector_Bitmap_Current]
        mov     [ds:si], cx

@@99:
;----------------------------
; Restore current disk sector
;----------------------------
        pop     cx
        mov     [Disk_Sector_Current], cx

        ret

ENDP    Write_8bit_Bitmap



;**********************************************************************
PROC    Write_8bit_Bootcode
;**********************************************************************
;------------------------------------------
; Store nr of free sectors in bootcode area
;------------------------------------------
        mov     si, offset Bootcode_Data
        add     si, BOOTCODE_OFFSET_FREE_SECTORS
        mov     cx, [Disk_Sectors_Free]
        mov     [ds:si], cx

;---------------------------------------------------
; Store first free directory sector in bootcode area
;---------------------------------------------------
        mov     si, offset Bootcode_Data
        add     si, BOOTCODE_OFFSET_FIRST_FREE_DIR_SECTOR
        mov     cx, [Disk_Sector_VTOC_Current]

        mov     bx, [Disk_Sectors_VTOC]
        sub     bx, [VTOC_Size_In_Sectors]
        cmp     bx, NULL                                ; VTOC sectors left?
        jnz     @@20                                    ; Yes
                                                        ; No, so
        mov     cx, [Disk_Sector_Current]
        inc     [Disk_Sector_Current]
        inc     [Disk_Sector_Current]                   ; Dir entry occupies 2 sectors

@@20:
        mov     [ds:si], cx

;----------------------------------------------
; Store first free data sector in bootcode area
;----------------------------------------------
        mov     si, offset Bootcode_Data
        add     si, BOOTCODE_OFFSET_FIRST_FREE_DATA_SECTOR
        mov     cx, [Disk_Sector_Current]
        mov     [ds:si], cx

;--------------------
; Write Bootcode data
;--------------------
        mov     si, offset ATARI____File
        push    ds si
        pop     di es
        mov     si, offset Bootcode_Data
        mov     [(FMS_Area ptr di).Data_Address_Hi], ds
        mov     [(FMS_Area ptr di).Data_Address_Lo], si
        mov     [(FMS_Area ptr di).Offset], NULL
        mov     [(FMS_Area ptr di).Record_Size], DISK_BOOTCODE_SIZE

        cmp     [Parm_XFD_Format], LOGIC_YES            ; XFD format?
        je      @@30                                    ; Yes
                                                        ; No, so
        mov     [(FMS_Area ptr di).Offset], ATR_HEADER_SIZE

@@30:
        push    es di
        call    FMSIO
        pop     di es

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        je      @@99

;--------------------
; Indicate error here
;--------------------
        mov     [Dir2atr_Error], LOGIC_YES

@@99:
        ret

ENDP    Write_8bit_Bootcode



;**********************************************************************
PROC    Rewrite_Dir_Link_8bit_VTOC
;**********************************************************************
        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@00                                    ; Yes
                                                        ; No, so
;-------------------------------------------
; Please wait, creating 8bit disk image vtoc
;-------------------------------------------
        mov     si, offset Ws_VS
        mov     [byte ds:si], WSIO_OPEN

        push    ds si
        call    WSIO
        pop     di es

        mov     si, offset Ws_VS
        mov     [byte ds:si], WSIO_DISPLAY_ONLY

        push    ds si
        call    WSIO
        pop     si ds

@@00:
        mov     [Dir_Curr_ptr], 0

@@05:
        inc     [Dir_Curr_ptr]
        mov     cx, [Dir_Curr_ptr]
        mov     es, [Pc_Dir_Map_ptr_es]
        mov     di, [Pc_Dir_Map_ptr_di]

        jmp     @@15

@@10:
        add     di, PC_DIR_MAP_ENTRY_LENGTH             ; Next entry into table

@@15:
        loop    @@10

        cmp     [byte es:di], NULL                      ; Anything left to process?
        je      @@95                                    ; No
                                                        ; Yes, so
;---------------------------------------------------------
; Retrieve "VTOC" with the help of specified sector - READ
;---------------------------------------------------------
        push    es di

        add     di, PC_DIR_MAP_OFFSET_DIR_FROM
        mov     cx, [es:di]
        mov     [Rewrite_Coming_From_Dir_ptr], cx

        pop     di es

;---------------------------------------------------------
; Retrieve "VTOC" with the help of specified sector - READ
;---------------------------------------------------------
        add     di, PC_DIR_MAP_OFFSET_LINK_SECTOR
        mov     cx, [es:di]
        inc     cx                                      ; VTOC lies 1 sector beyond Sector Lnk sector

        mov     si, offset ATARI____File
        push    ds si
        pop     di es
        mov     [(FMS_Area ptr di).Request], CMD_ACCESS_START
        mov     si, offset Disk_I_O_Buffer
        mov     [(FMS_Area ptr di).Data_Address_Hi], ds
        mov     [(FMS_Area ptr di).Data_Address_Lo], si
        mov     bx, [Disk_Sector_Size]
        mov     [(FMS_Area ptr di).Record_Size], bx
        mov     [(FMS_Area ptr di).Record_Nr], cx
        sub     [(FMS_Area ptr di).Record_Nr], DISK_BOOTCODE_SECTOR_SIZE

        mov     [(FMS_Area ptr di).Offset], DISK_BOOTCODE_SIZE
        cmp     [Parm_XFD_Format], LOGIC_YES            ; XFD format?
        je      @@20                                    ; Yes
                                                        ; No, so
        add     [(FMS_Area ptr di).Offset], ATR_HEADER_SIZE

@@20:
        push    es di
        call    FMSIO
        pop     di es

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        jne     @@95                                    ; Error

        mov     [(FMS_Area ptr di).Request], CMD_ACCESS_READNEXT

        push    es di
        call    FMSIO
        pop     di es

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        jne     @@95                                    ; Error

;-------------------------------------
; Get size of current directory's VTOC
;-------------------------------------
        mov     si, offset Disk_I_O_Buffer
        add     si, 3                                   ; VTOC size specified here
        mov     cx, [ds:si]
        mov     [Rewrite_Curr_Dir_VTOC_Size], cx

;-----------------------------------
; Initialize 8bit directory VTOC map
;-----------------------------------
        push    es di                                   ; Save FMSIO pointer

        mov     es, [VTOC_Map_ptr_es]                   ; 8bit VTOC directory
        mov     di, [VTOC_Map_ptr_di]

        mov     cx, VTOC_MAP_LENGTH
        xor     ax, ax
        mov     al, NULL
        rep     stosb

        pop     di es                                   ; Restore FMSIO pointer

;------------------------------------
; Start at VTOC record nr to retrieve
;------------------------------------
        mov     [(FMS_Area ptr di).Request], CMD_ACCESS_START

        push    es di
        call    FMSIO
        pop     di es

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        jne     @@95                                    ; Error

;-------------------------------------
; Scan through VTOC for this directory
;-------------------------------------
        mov     ax, [VTOC_Map_ptr_es]                   ; 8bit VTOC directory
        mov     bx, [VTOC_Map_ptr_di]
        mov     [(FMS_Area ptr di).Data_Address_Hi], ax
        mov     [(FMS_Area ptr di).Data_Address_Lo], bx

        mov     cx, [Rewrite_Curr_Dir_VTOC_Size]
        mov     [(FMS_Area ptr di).Record_Size], cx
        mov     [(FMS_Area ptr di).Request], CMD_ACCESS_READNEXT

        push    es di
        call    FMSIO
        pop     di es

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        jne     @@95                                    ; Error

;----------------------------------------------
; Determine from which entry we are coming from
;----------------------------------------------
        mov     es, [Pc_Dir_Map_ptr_es]                 ; Directory to check
        mov     di, [Pc_Dir_Map_ptr_di]
        mov     cx, [Rewrite_Coming_From_Dir_ptr]
        cmp     cx, NULL                                ; Are we at the "Main" directory?
        je      @@40                                    ; Yes
                                                        ; No, so
        jmp     @@35

@@30:
        add     di, PC_DIR_MAP_ENTRY_LENGTH             ; Next entry into table

@@35:
        loop    @@30

        add     di, PC_DIR_MAP_OFFSET_LINK_SECTOR

        mov     cx, [es:di]                             ; Copy from Sector Link sector
        mov     es, [VTOC_Map_ptr_es]                   ; 8bit VTOC directory
        mov     di, [VTOC_Map_ptr_di]
        mov     [es:di + 1], cx

@@40:
;-------------------------------------
; Scan through VTOC for this directory
;-------------------------------------
        mov     es, [VTOC_Map_ptr_es]                   ; 8bit VTOC directory
        mov     di, [VTOC_Map_ptr_di]
        add     di, EIGHTBIT_VTOC_ENTRY_SIZE            ; Skip very first entry

@@45:
        cmp     [byte es:di], EIGHTBIT_VTOC_ENTRY_DIRECTORY
        jne     @@90                                    ; No
                                                        ; Yes, so
;--------------------------------
; Scan through Pc Map Dir list...
;--------------------------------
        inc     di                                      ; Move to start link sector nr

        push    ds si                                   ; Save program entry
        push    es di                                   ; Save 8bit VTOC Map entry

        mov     bx, [Dir_Curr_ptr]                      ; Save Current directory nr
        mov     cx, [Dir_Curr_ptr]
        inc     cx                                      ; Directories to scan are beyond current directory
        mov     es, [Pc_Dir_Map_ptr_es]
        mov     di, [Pc_Dir_Map_ptr_di]

        jmp     @@55

@@50:
        add     di, PC_DIR_MAP_ENTRY_LENGTH             ; Next entry into table

@@55:
        loop    @@50

        add     di, PC_DIR_MAP_OFFSET_DIR_FROM

        pop     si ds                                   ; Restore 8bit VTOC Map entry

        jmp     @@70

@@60:
        add     di, PC_DIR_MAP_ENTRY_LENGTH             ; Next entry into table

@@70:
        cmp     [word es:di], NULL                      ; End of scan?
        je      @@80                                    ; Yes
                                                        ; No, so
        cmp     [es:di], bx                             ; Origin is current directory?
        jne     @@60

        mov     cx, [es:di + 2]                         ; Get Start Sector Link sector nr
        mov     [ds:si], cx                             ; Move into VTOC
        add     si, EIGHTBIT_VTOC_ENTRY_SIZE            ; Next VTOC entry
        jmp     @@60

@@80:
        pop     si ds                                   ; Restore program entry

@@90:
;-----------------------------------------------------------
; Store "VTOC" with the help of specified sector - (RE)WRITE
;-----------------------------------------------------------
        mov     si, offset ATARI____File
        push    ds si
        pop     di es

;------------------------------------
; Start at VTOC record nr to retrieve
;------------------------------------
        mov     bx, [Disk_Sector_Size]
        mov     [(FMS_Area ptr di).Record_Size], bx
        mov     [(FMS_Area ptr di).Request], CMD_ACCESS_START

        push    es di
        call    FMSIO
        pop     di es

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        jne     @@95                                    ; Error

        mov     cx, [Rewrite_Curr_Dir_VTOC_Size]
        mov     [(FMS_Area ptr di).Record_Size], cx
        mov     [(FMS_Area ptr di).Request], CMD_ACCESS_WRITENEXT

        push    es di
        call    FMSIO
        pop     di es

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        jne     @@95                                    ; Error

        jmp     @@05                                    ; Check next directory from Pc Dir Map list

@@95:
        cmp     [CLI_Used], LOGIC_YES                   ; Command Line Interface used?
        je      @@99                                    ; Yes
                                                        ; No, so
;---------------------------
; Close Vtoc creation screen
;---------------------------
        push    ax

        mov     si, offset Ws_VS
        mov     [byte ds:si], WSIO_CLOSE

        push    ds si
        call    WSIO
        pop     di es

        pop     ax

@@99:
        ret

ENDP    Rewrite_Dir_Link_8bit_VTOC



;**********************************************************************
PROC    Close_Disk_Image
;**********************************************************************
        cmp     [ATR_Disk_Image_Open], TRUE
        jne     @@99

;
; Close ATR Disk Image
;
        mov     si, offset ATARI____File
        push    ds si
        pop     di es

        mov     [(FMS_Area ptr di).Request], CMD_OPEN_CLOSE
        push    es di
        call    FMSIO
        pop     di es

;
; Update status
;
        mov     [ATR_Disk_Image_Open], FALSE

@@99:
        ret

ENDP    Close_Disk_Image



;**********************************************************************
PROC    Open_8bit_Pc_File
;**********************************************************************
        mov     si, offset PC_ATARI_File
        push    ds si
        pop     di es

        mov     si, offset Disk_I_O_Buffer
        mov     [(FMS_Area ptr di).Data_Address_Hi], ds
        mov     [(FMS_Area ptr di).Data_Address_Lo], si

        mov     [(FMS_Area ptr di).Request], CMD_OPEN_INPUT

        push    es di
        call    FMSIO
        pop     di es

        mov     [(FMS_Area ptr di).Request], CMD_ACCESS_READNEXT
        mov     cx, [Disk_Sector_Size]
        mov     [(FMS_Area ptr di).Record_Size], cx

        cmp     [(FMS_Area ptr di).Status], STATUS_OK
        je      @@99                            ; File opened
                                                ; No, so
;
; E R R O R S
;
        mov     si, offset Ws_E2_Error_Message
        push    ds si
        pop     di es
        mov     si, offset Ws_E2_D_Opening_File
        mov     cx, WS_E2_ERROR_MESSAGE_SIZE
        rep     movsb

        mov     si, offset Ws_E2_Error_Message
        push    ds si
        mov     cx, WS_E2_ERROR_MESSAGE_SIZE
        push    cx
        mov     si, offset PC_ATARI_Pathname
        push    ds si
        mov     cx, WS_E2_ERROR_MESSAGE_SIZE - 8
        push    cx
        mov     cx, 1                           ; Append spaces
        push    cx

        call    APPEND
        pop     ax ax ax ax ax ax ax

        mov     si, offset Ws_E2_Error_Message
        push    ds si

        mov     si, offset Ws_E2_F_Error_Message
        mov     [(Wsio_Area ptr di).Field_Address_Hi], ds
        mov     [(WSio_Area ptr di).Field_Address_Lo], si

        push    ds si
        pop     di es

        pop     si ds
        mov     [(Wsio_Field ptr di).Data_Address_Src_Hi], ds
        mov     [(WSio_Field ptr di).Data_Address_Src_Lo], si

        call    General_I_O_Error

@@99:
        ret

ENDP    Open_8bit_Pc_File



;**********************************************************************
PROC    Close_8bit_Pc_File
;**********************************************************************
        mov     si, offset PC_ATARI_File
        push    ds si
        pop     di es
        mov     [(FMS_Area ptr di).Request], CMD_OPEN_CLOSE

        push    es di
        call    FMSIO
        pop     di es

@@99:
        ret

ENDP    Close_8bit_Pc_File



;**********************************************************************
PROC    Setup_ATARI____Pathname
;**********************************************************************
        mov     di, offset ATARI____Pathname
        mov     cx, PATH_LENGTH                 ; Search length
        dec     cx                              ; To go to the last character
        add     di, cx                          ; Go to end of path
        std                                     ; Searh direction is down
        xor     ax, ax
        mov     al, BACKSLASH                   ; Search for the last "\"
        repne   scasb                           ; Search uses es:di
        cld                                     ; Cancel the std setting
        inc     di                              ; Pointer correction after search
        inc     di                              ; Location after the "\"

;
; Add Disk Specification
;
        mov     si, offset Disk_Name
        mov     cx, FILE_NAME_LENGTH        ; Copy length
        rep     movsb                       ; Copy path to search path

        ret

ENDP    Setup_ATARI____Pathname



;**********************************************************************
PROC    Setup_PC_ATARI_Pathname
;**********************************************************************
        mov     di, offset PC_ATARI_Pathname
        mov     cx, PATH_LENGTH                 ; Search length
        dec     cx                              ; To go to the last character
        add     di, cx                          ; Go to end of path
        std                                     ; Search direction is down
        xor     ax, ax
        mov     al, BACKSLASH                   ; Search for the last "\"
        repne   scasb                           ; Search uses es:di
        cld                                     ; Cancel the std setting
        inc     di                              ; Pointer correction after search
        inc     di                              ; Location after the "\"

;
; Add File Specification
;
        mov     si, offset File_Map_Entry.File_Name
        mov     cx, FILE_NAME_LENGTH        ; Copy length
        rep     movsb                       ; Copy path to search path

        ret

ENDP    Setup_PC_ATARI_Pathname



;**********************************************************************
PROC    Retrieve_Pc_Dirs
;**********************************************************************
;------------------
; Clear Files Table
;------------------
        mov     es, [Parm_Dir_Map_ptr_es]
        mov     di, [Parm_Dir_Map_ptr_di]
        mov     cx, DIR_MAP_LENGTH
        xor     ax, ax                                  ; Reset ax
        mov     al, NULL                                ; Fill character
        rep     stosb

;----------------------------------------------
; Check if drive we have to access drive A or B
;----------------------------------------------
        call    Verify_Disk_Presence_Drive_A_Or_B       ; If were reading drive A or B

        cmp     [Disk_Present], LOGIC_YES               ; Diskette present
        jne     @@99                                    ; No
                                                        ; Yes, so
        call    W9x_Search_Dirs_Path_Correction

;---------------------------------------
; Set up parameters for Directory search
;---------------------------------------
        mov     si, offset Requested_Format_LibFil      ; Parameter 1
        push    ds si

        mov     si, offset Search_Dirs_Path
        push    ds si                                   ; Parameter 2

        mov     es, [Parm_Dir_Map_ptr_es]
        mov     di, [Parm_Dir_Map_ptr_di]               ; Parameter 3
        push    es di
 
;-----------------------------------------
; Now retrieve Directory Map - Directories
;-----------------------------------------
        call    DC_DIRS
        pop     ax ax ax ax ax ax

@@99:
        ret

ENDP    Retrieve_Pc_Dirs



;**********************************************************************
PROC    Retrieve_Pc_Files
;**********************************************************************
;------------------
; Clear Files Table
;------------------
        mov     es, [Parm_Dir_Map_ptr_es]
        mov     di, [Parm_Dir_Map_ptr_di]
        mov     cx, DIR_MAP_LENGTH
        xor     ax, ax                                  ; Reset ax
        mov     al, NULL                                ; Fill character
        rep     stosb

;----------------------------------------------
; Check if drive we have to access drive A or B
;----------------------------------------------
        call    Verify_Disk_Presence_Drive_A_Or_B       ; If were reading drive A or B

        cmp     [Disk_Present], LOGIC_YES               ; Diskette present
        jne     @@99                                    ; No
                                                        ; Yes, so
        call    W9x_Search_Dirs_Path_Correction

;----------------------------------
; Set up parameters for File search
;----------------------------------
        mov     si, offset Requested_Format_LibFil      ; Parameter 1
        push    ds si

        mov     si, offset Search_Dirs_Path
        push    ds si                                   ; Parameter 2

        mov     es, [Parm_Dir_Map_ptr_es]
        mov     di, [Parm_Dir_Map_ptr_di]               ; Parameter 3
        push    es di
 
;-----------------------------------
; Now retrieve Directory Map - Files
;-----------------------------------
        call    DC_FILES
        pop     ax ax ax ax ax ax

@@99:
        ret

ENDP    Retrieve_Pc_Files



;**********************************************************************
PROC    Extract_Digit
;**********************************************************************
        xor     dx, dx                      ; Reset result
        div     bx                          ; Extract digit
        add     dx, 030h                    ; Turn digit into character
        cmp     [byte es:di], DECIMAL_SEPERATOR ; Character is decimal?
        jne     @@10                        ; No
                                            ; Yes, so
        dec     di                          ; Move to previous character

@@10:
        mov     [byte es:di], dl            ; Move character to text
        dec     di                          ; Move to previous character
        ret

ENDP    Extract_Digit



;**********************************************************************
PROC    Set_SpartaDos_File_Date_And_Time
;**********************************************************************
;---------------------------------------------------------
; Convert date from Pc Dir/File format to SpartaDos format
;---------------------------------------------------------
        mov     si, offset File_Map_Entry.File_Date
        mov     dx, [ds:si]

        mov     si, offset File_Map_Entry.File_Time
        mov     cx, [ds:si]

;
; Year
;
        mov     ax, dx                                  
        and     ax, 0FE00h                              ; Reset all bits except year bits
        ror     ax, 1                                   ; Year is located in ah (i.e. 12)
        add     ah, PC_DATE_YEAR_OFFSET                 ; Plus hex 50 = 80 (=1980)
        mov     [SpartaDos_Date_YY], ah                 ; Hex 5B = 92      (=1992)

;
; Month
;
        mov     ax, dx                                  
        and     ax, 01E0h                               ; Reset all bits except month bits
        ror     ax, 5                                   ; Month is located in al (i.e. 11)
        mov     [SpartaDos_Date_MM], al                 ; Hex 0B = 11

;
; Day
;
        mov     ax, dx                                  
        and     ax, 001Fh                               ; Reset all bits except day bits
        mov     [SpartaDos_Date_DD], al                 ; Hex 15 = 21

;---------------------------------------------------------
; Convert time from Pc Dir/File format to SpartaDos format
;---------------------------------------------------------
;
; Hours
;
        mov     ax, cx                                  
        and     ax, 0F800h                              ; Reset all bits except hours bits
        ror     ax, 3                                   ; Hours is located in ah (i.e. 14)
        mov     [SpartaDos_Time_HH], ah                 ; Hex 0E = 14

;
; Minutes
;
        mov     ax, cx                                  
        and     ax, 07E0h                               ; Reset all bits except hours bits
        ror     ax, 5                                   ; Hours is located in al (i.e. 56)
        mov     [SpartaDos_Time_MM], al                 ; Hex 38 = 56

        ret

ENDP    Set_SpartaDos_File_Date_And_Time



;**********************************************************************
PROC    Setup_Pathname_ATARI_Bootcode_File
;**********************************************************************
        mov     si, offset PC_ATARI_Pathname
        push    ds si
        pop     di es
        mov     si, offset PC_ATARI_DOS_Pathname
        mov     cx, PATH_LENGTH
        rep     movsb

;
; Filename BOOTCODE
;
        mov     si, offset PC_ATARI_Pathname            ; Append field 1
        push    ds si
        mov     cx, PATH_LENGTH                         ; Append field 1 size
        push    cx
        mov     si, offset File_Name_BOOTCODE           ; Append field 2
        push    ds si
        mov     cx, FILE_NAME_LENGTH                    ; Append field 2 size
        push    cx
        mov     cx, 0                                   ; Append spaces
        push    cx

        call    APPEND
        pop     ax ax ax ax ax ax ax

        ret

ENDP    Setup_Pathname_ATARI_Bootcode_File



;**********************************************************************
PROC    Setup_Pathname_ATARI_DOS_SYS_File
;**********************************************************************
        mov     si, offset PC_ATARI_Pathname
        push    ds si
        pop     di es
        mov     si, offset PC_ATARI_DOS_Pathname
        mov     cx, PATH_LENGTH
        rep     movsb

;
; Append DOS.SYS filename
;
        mov     si, offset PC_ATARI_Pathname    ; Append field 1
        push    ds si
        mov     cx, PATH_LENGTH                 ; Append field 1 size
        push    cx
        mov     si, offset File_Name_DOS_SYS    ; Append field 2
        push    ds si
        mov     cx, FILE_NAME_LENGTH            ; Append field 2 size
        push    cx
        mov     cx, 0                           ; Append spaces
        push    cx

        call    APPEND
        pop     ax ax ax ax ax ax ax

        ret

ENDP    Setup_Pathname_ATARI_DOS_SYS_File



;**********************************************************************
PROC    Setup_Pathname_ATARI_DOS
;**********************************************************************
        push    ds si                                   ; Save program entry

        mov     si, offset PC_ATARI_DOS_Pathname
        push    ds si
        pop     di es
        mov     si, [Parm_DOS_Path_ptr_di]
        mov     ds, [Parm_DOS_Path_ptr_es]
        mov     cx, PATH_LENGTH                         ; Copy length
        rep     movsb                                   ; Copy path to search path

        pop     si ds                                   ; Restore program entry

        mov     si, offset Dir_BEWEDOS                  ; Assume BeWeDOS
        cmp     [Disk_Format], DISK_FORMAT_BEWEDOS
        je      @@10

        mov     si, offset Dir_SPARTADOS                ; Assume SpartaDOS 3.3a
        cmp     [Disk_Format], DISK_FORMAT_SPARTADOS
        je      @@10

        mov     si, offset Dir_SPARTADOSX               ; Assume SpartaDOS/X
        cmp     [Disk_Format], DISK_FORMAT_SPARTADOSX
        je      @@10

        mov     si, offset Dir_MYOWNDOS                 ; Assume User's DOS

@@10:
;
; Append BeWeDOS, SPARTADOS 3.3a, SPARTADOS/X or MYOWNDOS directory filename
;
        push    ds si
        pop     bx ax

        mov     si, offset PC_ATARI_DOS_Pathname        ; Append field 1
        push    ds si
        mov     cx, PATH_LENGTH                         ; Append field 1 size
        push    cx
        push    ax bx                                   ; Append field 2
        mov     cx, FILE_NAME_LENGTH                    ; Append field 2 size
        push    cx
        mov     cx, 0                                   ; Append spaces
        push    cx

        call    APPEND
        pop     ax ax ax ax ax ax ax

        ret

ENDP    Setup_Pathname_ATARI_DOS



;**********************************************************************
PROC    W9x_Atari_File_Name_Correction
;**********************************************************************
        push    ds si es di
        mov     si, offset Atari_File_Name_Invalid_Char

@@10:
        cmp     [byte ds:si], NULL                      ; End of table reached?
        je      @@99                                    ; Yes
                                                        ; No, so
        cmp     [byte ds:si], al                        ; Invalid Atari 8bit character?
        je      @@20                                    ; Yes
                                                        ; No, so
        inc     si                                      ; Check next character from table
        jmp     @@10

@@20:
        mov     al, KEY_UNDERSCORE

@@99:
        pop     di es si ds
        ret

ENDP    W9x_Atari_File_Name_Correction



;**********************************************************************
PROC    W9x_Search_Dirs_Path_Correction
;**********************************************************************
        mov     si, offset Search_Dirs_Path
        add     si, PATH_LENGTH - 1
        push    ds si
        pop     di es

        std                                             ; Search direction is down
        mov     ax, SPACE                               ; Search for non SPACE
        mov     cx, PATH_LENGTH
        repe    scasb                                   ; Search uses es:di
        cld                                             ; Cancel the std setting
        inc     di                                      ; Pointer adjustment after search
        inc     di                                      ; Position after last letter

@@10:
        cmp     [byte es:di], SPACE                     ; Replace " "?
        jne     @@99                                    ; No
                                                        ; Yes, so
        mov     [byte es:di], NULL                      ; Replace by hex 00

@@99:
        ret

ENDP    W9x_Search_Dirs_Path_Correction



;**********************************************************************
PROC    General_I_O_Error
;**********************************************************************
        mov     si, offset Ws_E2
        mov     [byte ds:si], WSIO_OPEN

        push    ds si
        call    WSIO
        pop     si ds

        mov     si, offset Ws_E2
        mov     [byte ds:si], WSIO_DISPLAY_AND_READ

        push    ds si
        call    WSIO
        pop     si ds

        mov     si, offset Ws_E2
        mov     [byte ds:si], WSIO_CLOSE

        push    ds si
        call    WSIO
        pop     si ds

;
; Error encountered
;
        mov     [Dir2atr_Error], LOGIC_YES

        ret

ENDP    General_I_O_Error



;**********************************************************************
PROC    Verify_Disk_Presence_Drive_A_Or_B
;**********************************************************************
        mov     [Disk_Present], LOGIC_YES

;----------------------------------------------
; Check if drive we have to access drive A or B
;----------------------------------------------
        mov     si, offset Search_Dirs_Path
        cmp     [byte ds:si], "A"               ; Access drive A?
        je      @@10                            ; Yes
                                                ; No, so
        cmp     [byte ds:si], "B"               ; Access drive B?
        jne     @@99                            ; No
                                                ; Yes, so
@@10:
        xor     bx, bx                          ; Reset dx
        mov     bl, [byte ds:si]                ; Copy selected drive to path
        sub     bl, 64                          ; Turn drive into DOS drive
        mov     ax, DOS_SENSE_MEDIA_TYPE
        mov     al, 00Dh                        ; subfunction code
        mov     cx, DOS_GET_MEDIA_ID_CX
        mov     dx, offset Media_ID_Buffer
        int     DOS_SERVICE                     ; Check Drive Presence
        cmp     ax, DOS_DRIVE_NOT_READY         ; Drive ready?
        jne     @@99                            ; Yes
                                                ; No, so
        mov     [Disk_Present], LOGIC_NO

;------------------------
; ERROR - DRIVE NOT READY
;------------------------
        mov     si, offset Ws_E1
        mov     [byte ds:si], WSIO_OPEN
        push    ds si
        call    WSIO
        pop     si ds

        mov     si, offset Ws_E1
        mov     [byte ds:si], WSIO_DISPLAY_AND_READ
        push    ds si
        call    WSIO
        pop     si ds

        mov     si, offset Ws_E1
        mov     [byte ds:si], WSIO_CLOSE
        push    ds si
        call    WSIO
        pop     si ds

@@99:
        ret

ENDP    Verify_Disk_Presence_Drive_A_Or_B



;**********************************************************************
PROC    Error_E5_Too_Many_Files_In_Dir
;**********************************************************************
        mov     [Too_Many_Files_In_Dir], LOGIC_YES

        mov     si, offset Ws_E5
        mov     [byte ds:si], WSIO_OPEN

        push    ds si
        call    WSIO
        pop     di es

        mov     [(Wsio_Area ptr di).Cursor_Position_Row], CURSOR_OFF_SCREEN
        mov     [(WSio_Area ptr di).Cursor_Position_Col], CURSOR_OFF_SCREEN

        mov     si, offset Ws_E5
        mov     [byte ds:si], WSIO_DISPLAY_AND_READ

        push    ds si
        call    WSIO
        pop     si ds

        push    ax

        mov     si, offset Ws_E5
        mov     [byte ds:si], WSIO_CLOSE

        push    ds si
        call    WSIO
        pop     si ds

        pop     ax

        ret

ENDP    Error_E5_Too_Many_Files_In_Dir



;**********************************************************************
PROC    Error_E6_Too_Many_Files_Dirs
;**********************************************************************
;-------------------------------------------------------------
; Too many directories/files to fit on the selected disk image
;-------------------------------------------------------------
        mov     si, offset Ws_E6
        mov     [byte ds:si], WSIO_OPEN

        push    ds si
        call    WSIO
        pop     di es

        mov     [(Wsio_Area ptr di).Cursor_Position_Row], CURSOR_OFF_SCREEN
        mov     [(WSio_Area ptr di).Cursor_Position_Col], CURSOR_OFF_SCREEN

        mov     si, offset Ws_E6
        mov     [byte ds:si], WSIO_DISPLAY_AND_READ

        push    ds si
        call    WSIO
        pop     si ds

        mov     si, offset Ws_E6
        mov     [byte ds:si], WSIO_CLOSE

        push    ds si
        call    WSIO
        pop     si ds

;--------------------------
; Press Cancel for the user
;--------------------------
        mov     al, KEY_ESC                             ; Cancel processing

        ret

ENDP    Error_E6_Too_Many_Files_Dirs



;**********************************************************************
PROC    Error_E7_Too_Many_Files_Dirs
;**********************************************************************
;----------------------------------------------------
; Too many directories/files to fit on any disk image
;----------------------------------------------------
        mov     si, offset Ws_E7
        mov     [byte ds:si], WSIO_OPEN

        push    ds si
        call    WSIO
        pop     di es

        mov     [(Wsio_Area ptr di).Cursor_Position_Row], CURSOR_OFF_SCREEN
        mov     [(WSio_Area ptr di).Cursor_Position_Col], CURSOR_OFF_SCREEN

        mov     si, offset Ws_E7
        mov     [byte ds:si], WSIO_DISPLAY_AND_READ

        push    ds si
        call    WSIO
        pop     si ds

        mov     si, offset Ws_E7
        mov     [byte ds:si], WSIO_CLOSE

        push    ds si
        call    WSIO
        pop     si ds

;--------------------------
; Press Cancel for the user
;--------------------------
        mov     al, KEY_ESC                             ; Cancel processing

        ret

ENDP    Error_E7_Too_Many_Files_Dirs

ENDS    CSeg                                ; End of Code segment

END
