AHCDEMO

Script File User Guide

Versions 3A5 and higher

Copyright 2010-2019 Hale Landis. All rights reserved.

Note: Also see files AHCDEMO.HTM and CMD-SUM.HTM.

WARNING: Some email programs think that *.DSF files are "screen saver" files. *.DSF or *.TXT might be a better naming convention on on systems with these stupid email programs.

TABLE OF CONTENTS

(Go To TOC)

OVERVIEW

Script files are supported only in the commercial/full version of AHCDEMO. A script file is an easy way to have AHCDEMO issue a series of commands in a "batch" mode.

Most commands allowed in a script file are identical to the commands that may be entered from the keyboard. There are several additional commands that are valid only within script files.

Use the AHCDEMO SCR= command line option or the SCRIPT command to start the execution of a script file.

If the script file terminates due to an EXit command or if ONERRor EXit is active when an error happens, AHCDEMO will also terminate. If the script file terminates due to a QUit command or if ONERRor QUit is active when an error happens, AHCDEMO will terminate the script file and enter keyboard mode. If the end of the script file is reached and there is no QUit or EXit command, AHCDEMO will enter keyboard mode.

A group of scripts can be made into a test suite using the Script List described in the AHCDEMO User Guide.

(Go To TOC)

BASIC LAYOUT OF A SCRIPT FILE

Create a script file with your favorite ASCII text editor. Each line of a script file may contain one AHCDEMO command or a comment line.

In lines of a script file a TAB character is equivalent to a SPACE character. Whitespace is one or more TAB and/or SPACE characters. Excess whitespace before and within and at the end of a script file line are ignored. All characters following a semicolon (;) are ignored. All characters following the two slash characters (//) are ignored. Lines containing only whitespace are ignored.

All scripts files contain a main part and zero, one or more subroutine definitions.

The main part is executed immediately when the script file is loaded successfully. The main part execution terminates when the first BEGINSub, EXit or QUit command is encountered.

The following shows the basic layout:



   ; This is the "main" part.  Execution of the script file
   ; starts with the first line of the main part.  Execution
   ; of the main part ends if a BEGINSub, EXit or QUit command
   ; is encountered.

   SAY This is the main part of this script!"
   IF dev_num     ; just an example of an IF command
      CALL ALPHA     ; the main part can call a subroutine
   ELSE
      CALL BETA      ; the main part can call a subroutine
   ENDIF
   QUIT           ; main part execution ends here

   ; The main part can be followed by zero, one or more subroutine
   ; definitions.  Each subroutine definition starts with a
   ; BEGINSub command and ends with a ENDSub statement.

   BEGINSUB ALPHA

      ; Statements within subroutine ALPHA.
      SAY This is subroutine ALPHA!

   ENDSUB

   BEGINSUB BETA

      ; Statements within subroutine BETA.
      SAY This is subroutine BETA!

   ENDSUB

   ; More subroutine definitions...

A script file may contain a #NEXT directive that causes processing of the current script file to stop and processing of a new script file to begin. This is similar to but not the same as #INCLUDE directives found in other programming languages as the script compiler never returns to processing the file containing the #NEXT directive. Use #NEXT to append a file of common subroutines to a main script file.

When #NEXT is used all files appended to the root script file are considered to be part of the root script file for line numbering.

(Go To TOC)

USING SCRIPT FILES

Example 1

A simple script file can be used to automate a task. This script file executes a number of non-data commands to an ATA device. It contains only a main part that is executed as soon as the script file is loaded and compiled.



   ; This is a sample AHCDEMO script file.
   ; This is a commment line;
   ; The following line is also ignored (all whitespace).

   dev1        ; switch to device 1
   showcb      ; show the ATA Command block registers

   DEV 0       ; switch to device 0

   id          ; issue an Identify command

   LBA                  ; switch to LBA sector addressing
   afternoerror showcb  ; if any error do a showcb
   nd 70H 0 0 5000      ; seek to LBA 5000
   afternoerror         ; turn off the showcb after an error

   eXpEcTeRrOr    ; the next command should fail
                  ; repeat an invalid command (NOP) 5 times
                  ; expecting an error each time
   repeat 5 nd 0 0 0 0

   onerror CoNtInUe     ; continue even if the next command fails
   nd 7f 0 0 987654321  ; a strange seek command

   onerror QUit   ; stop script file if any error
                  ; read sector at LBA=0
                  ; repeat the read command 10 times
   repeat 10 pDi 020 0 0 0

   quit           ; end of the script file

Example 2

The main part can be used to set up modes and variables used throughout the entire script file, for example see the DEMO.DSF and EXAMPLE.DSF files. These sample script files also show how subroutines can be used to create complex scripts. The DEMO.DSF file also shows how the AHCDEMO WINdow command can be used to create menus.

Example 3

A script file can used to define subroutines that act as if they are new AHCDEMO commands. In this case the main part would probably contain only a QUIT statement. When this script is loaded, the subroutines are defined and can be called from the keyboard by using the CAll command. For example, AHCDEMO does not have a high level command for all the ATA SMART commands. A subroutine could be created that looks like the SMART commands:



   QUit     ; main part starts and ends here

   BEGINSub SMARTON public
      ; note how the command parameters are passed using
      ; CHS address mode...
      CHS
      ND b0H 0 d9H c24fH 0 0
   ENDSub SMARTON

   BEGINSub SMARTOFF public
      ; note how the command parameters are passed using
      ; CHS address mode...
      CHS
      ND b0H 0 d8H c24fH 0 0
   ENDSub SMARTOFF

   BEGINSub SMARTSTATUS public
      ; note how the command parameters are passed using
      ; CHS address mode...
      CHS
      ND b0H 0 daH c24fH 0 0
      ; check the value returned by the drive...
      if ( reg_cl == f4H )
         say SMART THRESHOLD EXCEEDED
      ENDIF
   ENDSub SMARTSTATUS

These subroutines can then be executed when AHCDEMO is in keyboard mode by entering the command:

CALL SMARTON

or just by entering the command:

SMARTON

Example 4

Be careful when selecting subroutine names. Any AHCDEMO command, including commands like QUit and Exit, can be replaced by a PUBlic subroutine of the same name. For example, the R10 command could be redefined as:



   QUit     ; main part starts and ends here

   BEGINSub R10 public
      SAY --- Read 10, TL {sub_param1} LBA {sub_param2} ---
      R10 sub_param1 sub_param2 sub_param3
      SAY --- Read 10 done ---
   ENDSub R10

Note that many AHCDEMO commands have short spellings. To effectively replace these commands, multiple subroutines would need to be defined. For example, to replace the EXit command the following could be used:



   QUit     ; main part starts and ends here

   BEGINSub EX PUBLIC
      call myexit
   ENDSub

   BEGINSub EXI PUBLIC
      call myexit
   ENDSub

   BEGINSub EXIT PUBLIC
      call myexit
   ENDSub

   BEGINSub myexit private
      SAY ***** Exiting with return code {sub_param1} *****
      EXit sub_param1
   ENDSub

Note that subroutine "myexit" is private and can not be called from the keyboard.

Example 5

Multiple scripts that work together can be created to automate complex tasks or to do things that would be too large for a single script. A script file can "call" another script file using the SCRipt command. This replaces the script file commands that are currently loaded but it does not alter the value of variables (expect script_flag). Variables can be passed between the scripts as they are loaded by one another. Note that when a script is completed a SCRipt command must be used to reload the calling script again. For example:



   ; script INIT.DSF, script that initializes everything
   ; and call the loop control script.

   ; initialize variables, etc, here

   set loopcntr = 0
   set errcode = 0

   ; call the script that runs the "main loop".

   script loop.dsf



   ; script LOOP.DSF, the script that loops calling
   ;                script ONE and TWO.

   ; check for any error when ONE.DSF or TWO.DSF call
   ; this script.

   if errcode
      if ( loopcntr & 0x01 )
         say SCRIPT ONE.DSF LOOP {loopcntr} error {errcode}.
      else
         say SCRIPT TWO.DSF LOOP {loopcntr} error {errcode}.
      endif
      quit
   endif

   ; update loop counter, check for end

   set loopcntr = ( loopcntr + 1 )
   if ( loopcntr > 10 )
      quit
   endif

   ; call ONE.DSF or TWO.DSF based on bit 0 of "loopcntr"

   if ( loopcntr & 0x01 )
      script ONE.DSF
   else
      script TWO.DSF
   endif



   ; script ONE.DSF, called by the loop control script

   ; do something in this script.
   ; set errcode to a non-zero value if there is any error that
   ;   should stop looping.

   ; this script should contain no QUit or EXit commands.  It
   ; should return by using the following SCRipt command.

   call message

   script LOOP.DSF

   beginsub message
      say Hi, this is ONE.DSF talking.
   endsub message



   ; script TWO.DSF, called by the loop control script

   ; do something in this script.
   ; set errcode to a non-zero value if there is any error that
   ;   should stop looping.

   ; this script should contain no QUit or EXit commands.  It
   ; should return by using the following SCRipt command.

   call message

   script LOOP.DSF

   beginsub message
      say Hi, this is TWO.DSF talking.
   endsub message

Example 6

This is an example of the #NEXT directive.

The "root" script file:



   // this is the "root" script file containing the main part

   say I am the root script file.

   say I am calling a subroutine in another file.
   call sub1

   // end of "root" -- append my subroutines

   #next mysubs.dsf

My subroutines script file:



   // this is the mysubs.dsf script file

   beginsub sub1

      say I am subroutine sub1

   endsub sub1

   beginsub  sub2

      say I am subroutine sub2

   endsub sub2

(Go To TOC)

QUESTIONS OR PROBLEMS?

Technical support can be found at:

http://www.ata-atapi.com/techsupp.html

-end-