BASIC(1)             General Commands Manual            BASIC(1)

*** USAGE ***
       BASIC [FILE ...]

       NMH-BASIC is a minimum BASIC interpreter for systems with
       little core memory.  On {PC,MS,whatever}DOS  it  requires
       only 12 kilobytes to run.  It provides a small but power-
       ful command set, a builtin editor, and a  simple  tracing
       facility.  Programs  may either be typed in interactively
       or read from an external file or device.
       NMH-BASIC is intended for quick and dirty prototyping and
       writing small and non-time-critical application programs.

       NMH-BASIC  treats each statup parameter that is passed to
       it as a file name and  attempts  to  open  the  requested
       files.  It  prints each file name and the unit number as-
       signed to it. When it fails to open a file, it prints  an
       exclamation mark (!) followed by the file name.

*** EDITING ***
       There is a simple builtin editor that allows the program-
       mer to enter and modify programs interactively.
       NMH-BASIC program memory consists of a sequence  of  num-
       bered  lines. Each command that starts with a number will
       not be executed immediately but is inserted into  program
       memory  instead.  When entering a line with a line number
       that already exists, the given line will be replaced. En-
       tering  a  line number with no following text will delete
       the given line.
       The length of each line  is  limited  to  64  characters.
       Longer lines will cause an error.
       The LIST command may be used to view lines stored in pro-
       gram memory.
       The NMH-BASIC editor  performs  some  on  the  fly  error
       checking. It checks only at scanner level, but this helps
       to catch many typos while entering a  program.  When  the
       editor finds an error, it discards the current line.

*** PROGRAMS ***
       A  program  consists  of a number of lines, and each line
       contains at least one BASIC statement, also  known  as  a
       command.   Multiple  statements may be placed in a single
       line by separating them with colons (:).

       An expression is everything that evaluates to  a  numeric
       value  at  run time.  NMH-BASIC recognizes the four basic
       math operators (+, -, *, /) and  some  other  arithmetic,
       comparison,  and  logic  operators. Operators are used to
       combine factors  (binary  operators)  or  modify  factors
       (unary operators). Valid factors are: numbers, variables,
       and function values.

       Numbers are numeric  literals  in  the  range  -32767  to
       32767. They represent themselves.
       Variables  are  two-character  sequences that represent a
       variable numeric value.  There are  260  numeric  integer
       variables  in NMH-BASIC that are named A0...Z9. The first
       character must always be a letter, and the second  one  a
       digit. Variables of the form X0 can also be written X.
       Function  values  are  the  values  returned  by function
       calls.  A function is called by typing the function name,
       followed  by a left parenthesis, some function arguments,
       and a right parenthesis.

       NMH-BASIC accepts the following operators:

        |Oper. | Type | Description                           |
        | ( )  |  4   | expression grouping, array subscripts |
        | #    | U4   | logical NOT                           |
        | -    | U4   | unary minus, negative prefix          |
        | *    | B3   | multiplication                        |
        | /    | B3   | division                              |
        | \    | B3   | division remainder                    |
        | +    | B2   | addition                              |
        | -    | B2   | subtraction                           |
        | =    | B1   | equal to                              |
        | <<>   | B1   | not equal to                          |
        | <<    | B1   | less than                             |
        | >>    | B1   | greater than                          |
        | <<=   | B1   | less than or equal to                 |
        | >>=   | B1   | greater than or equal to              |
        | =    | B0   | assignment (only in LET commands)     |
       Types: U = unary, B = binary, number = precedence level

*** ARRAYS ***
       Normally there are 260 integer variables. All these vari-
       ables  have  a unique name (A0...Z9). Sometimes, however,
       it is more practical to access variables like vector ele-
       ments  (through  an index, or subscript).  Each NMH-BASIC
       variable may be treated as an array  without  making  any
       special  declarations.  `A', for example, may also be ad-
       dressed as `A(0)', A1 is equal to A(1), A(9) is equal  to
       A9. Larger subscripts cause on overflow to the next vari-
       able letter: the address of A(10) would be equal  to  the
       one of B0. Z(10), finally, will cause a subscript error.

       When  more  space is needed, or no variables letters must
       be `wasted', there is the possibility to dimension an ar-
       ray. Usually, the Z-variables are used to build an array,
       because they cannot have  common  memory  locations  with
       other variables.
       The statement
              DIM Z(200)
       will  increase  the size of Z0 to 200 elements. Note that
       the free space for program text will be decreased by this
       Dimensioning  a  different  variable will not occupy that
       much dynamic memory because the space  for  variables  is
       used  up  first.  Using  A0 as an array with 200 elements
       [DIM A(200)], for example, will not  occupy  any  dynamic
       memory,  but  will  make the variables A1...T9 aliases of

       The second NMH-BASIC data type is  the  string.   Strings
       are fixed-length memory locations that can be filled with
       characters. They are used to store ASCII text.
       There is only one operation  that  may  be  performed  on
       strings: the concatenation, which is done by the + opera-
       Valid factors in string expressions are text literals and
       string variables.
       A  text  literal  is  a  string of characters enclosed by
       apostrophes.  A literal apostrophe may be insert by  typ-
       ing  it two times in succession.  Text literals, like nu-
       meric literals, represent themselves.
       A string variable is a variable letter followed by a dol-
       lar sign ($).  There are 36 string variables: A$...Z$ and
       0$...9$. String variables may  not  be  dimensioned,  but
       they  can be treated as arrays. For example, A$(1) is the
       same as B$ or B$(0). Typically 0$ is used as an array  of
       10 strings.
       The  length of NMH-BASIC strings is limited to 64 charac-

       A statement (also called a "command") is the smallest ex-
       ecutable  element  of  a  basic  program.  Each statement
       starts with a keyword and is usually followed by some pa-
       rameters  and additional keywords.  There are three kinds
       of statements: simple statements, conditional statements,
       and loop statements.

       Most  statements in NMH-BASIC are simple statements.  Ex-
       amples are:
              LET I=195
              GOTO 420
              PRINT VAL(A$)

       Conditional statements will only be executed when a  con-
       dition is true. There is only one form of the conditional
              IF condition statement : ...
       The keyword IF is followed by  a  condition.   Only  when
       this  condition evaluates to a true (non-zero) value, the
       statement part will be executed. For example,
              IF A<0 PRINT 'NEGATIVE'
       will print 'NEGATIVE' only if A is less than zero.
       Multiple conditions may be separated by commas.  In  this
       case  the statement(s) will only be executed, if all con-
       ditions are true. E.g.:
              IF A<1, B<1 PRINT 'BOTH NEGATIVE'
       Note that all statements specified after  IF  are  condi-
       tional, so
              IF 1 PRINT 'FOO' : PRINT 'BAR'
       will print both FOO and BAR.

       Loop  statements  consist of three parts, the introducing
       statement (FOR), a  body  consisting  of  any  number  of
       statements,  and a scope terminator (NEXT).  In NMH-BASIC
       there is only one block statement and it looks like this:
              FOR I=1 TO 100
                PRINT I,
       It implements a counting loop.  In the  example  the  en-
       closed  statement  "PRINT I," will be executed 100 times.
       Each time the loop is passed, the variable I will be  in-
       creased  by  one  (at  the end of the loop). So this loop
       will print the numbers from 1 to 100.
       NEXT is the scope terminator. When  it  is  reached,  the
       counting  variable  is  incremented,  and  if  it has not
       passed the limit, the enclosed  statements  are  executed
       When a step size if specified in FOR, the given step size
       will be added to the counting variable  instead  of  one.
              FOR I=1 TO 100 STEP 2 : PRINT I, : NEXT
       will print only odd numbers and stop at 99. The step size
       may be negative.

*** COMMANDS ***
       CALL addr
            Call the  machine  language  subroutine  at  address
            addr.  Not implemented.

            Clear  all variables and array dimensions. After is-
            suing CLEAR variables will be set to zero and string
            variables will contain empty strings.

       DATA list
            Define  a  list  of  initialization data.  List is a
            space-separated list of constant data items  of  any
            type  (numeric  or  string).  Data lists are read by
            READ statements.

       DIM var(size), ...
            Define variable var as an array with size  elements.
            DIM  does  not  actually  allocate memory to arrays.
            When A is dimensioned with 100 elements,  for  exam-
            ple,  the  space used by the following variables (C,
            D, ..., J) is used, so A(10) becomes an alias of  B0
            and A(20) an alias of C0, etc.  Only when the end of
            the array moves beyond Z9, the space  for  variables
            is extended (and program memory is reduced).

            End  program  execution  and  return  to interactive

       FOR var=start TO limit [STEP increment]
            Introduce a counting loop. First the variable var is
            set to the value start, and then all statements fol-
            lowing FOR are executed. When  a  matching  NEXT  is
            found,  var  is  incremented  by  increment and then
            checked against limit.  When  var  is  smaller  than
            limit,  all statements between FOR and NEXT are exe-
            cuted again.
            When no increment is specified (the STEP  clause  is
            omitted),  a  step  size of one is assumed. When the
            increment is negative, the loop  is  repeated  until
            var becomes less than the limit.
            The  start,  limit,  and  increment parts may be any
            valid expression. They will only be  evaluated  once
            before the first iteration of the loop.

       GOSUB line
            Perform a jump (like GOTO) to the given line number,
            remembering the return address.  The return  address
            is pushed onto an internal stack. A RETURN statement
            may be used to pop this address off  the  stack  and
            continue  execution at the statement immediately af-
            ter GOSUB. Subroutine calls may be nested.

       GOTO line
            Jump to the given line number.  Execution  continues
            with the first statement in the specified line.

       IF condition command : ...
            Evaluate  condition, and execute the command(s) only
            if the condition  evaluates  to  a  true  (non-zero)
            value.  When  the condition is false, execution con-
            tinues with the first  statement  in  the  following
            line  (if  any).  The condition may be any valid ex-
            pression.  Multiple conditions may be  separated  by
            commas.  In this case all conditions have to be true
            in order for the command(s) to be executed.

       INPUT #expr
            Redirec input to the given unit number.  All  subse-
            quent input will be read from the file or device as-
            sociated with the unit number.

       INPUT var, ...
            Read input from the terminal  (or  redirected  unit)
            and  assign  each line of input to a variable. Input
            will be automatically converted to the  proper  for-
            When  reading  a  string  A$  from  a  unit that has
            reached its EOF marker, the  string  will  have  the
            character 255 in its first slot, i.e. ASC(A$) = 255.
            The INPUT command does not emit a prompt. Use
            PRINT 'prompt';
            for that.

       LET var=expr
            Evaluate  expr  and  assign the result to var.  When
            var is a text variable, expr must be a text  expres-
            sion, and otherwise it must be a numeric expression.

       LET var(expr1) = expr2
            Evaluate expr2 and assign the result to the expr1'th
            slot of var.

       LIST [line,[last]]
            List all specified lines (default: all).  When  only
            one line is given, list just that line.

       LOAD #expr
            Redirect input to the specified unit number and pass
            each line of input to the interpreter. When the  end
            of input is reached, redirect input back to the ter-
            When done, LOAD leaves the file pointer at  the  EOF
            of the given unit.
            LOAD  does not erase the program memory, so multiple
            programs can be merged with  LOAD  (merged  programs
            should not share common line numbers).

            Erase  the  currently  loaded  program and clear all
            variables and array dimensions.

            Terminate the scope of a FOR-NEXT loop. (See FOR.)

       POKE addr, value
            Write value to  memory  location  addr.   POKE  only
            writes  a  byte  to  the given address, so the upper
            eight bits of value are ignored.  DO NOT USE!   This
            will most probably crash the interpreter.

            Print a newline character.

       PRINT #expr
            Redirect all output to the given unit number.

       PRINT expr [,|; expr ...] [,|;]
            Evaluate  each given expression (string or numeric),
            and write its value to  the  output  unit  (default:
            terminal).   Expressions  may be separated by commas
            or semicolons. A comma emits a horizontal TAB and  a
            semicolon pastes output together.
            A  newline  character  is emitted after the last ex-
            pression unless the  print  statement  ends  with  a
            comma or semicolon.

       READ var, ...
            Read  DATA  items  into the specified variables. The
            items are taken from a DATA list (see  there)  which
            may  be  specified  at any place in the program (but
            are typically at the end).
            Each item in the list must have the same type as the
            corresponding  variable in READ or an error will oc-
            cur. Each READ operation advances the  data  pointer
            by  n  items,  where n is the number of variables in
            the READ statement.
            When the data pointer is moved past the end  of  the
            list while READ executes, the operation will fail.

       REM 'nasenbaer'
            Everything  after  REM is ignored by the interpreter
            (including colons!). If the text  following  REM  is
            not  a  valid NMH-BASIC program, it must be enclosed
            in apostrophes.

            Reset the data pointer to the beginning of the  init
            list  (the first element of the first DATA statement
            in the program (see also READ and DATA).

            Pop a return address off the internal  return  stack
            and  jump to that address.  RETURN is used to return
            from a subroutine that has previously been called by
            When the return stack is empty, RETURN causes an er-

            Clear all variables and dimensions and then run  the
            program in program memory.

       SAVE #expr
            Redirect  output  to  the given unit number and then
            call LIST to write the program in program memory  to
            the  associated  file  or  device. After writing the
            program, redirect output back to the terminal.
            SAVE leaves the file pointer of the unit at the  end
            of the listing.

            Used  to specify an increment other than 1 in a FOR-
            NEXT statement. See FOR.

            List the line in which the STOP statement occurs and
            stop program execution.

            Part of the FOR statement (q.v.).

            Exit from the interpreter. SYSTEM works in both, in-
            teractive and program execution mode.

            Turn off tracing.

            Turn on tracing. When running a program,  print  the
            current  line  number in square brackets before exe-
            cuting a new line.

       Functions that have a dollar sign ($) in their  name  re-
       turn strings, all other functions return integers.

       Return  the  ASCII code of the first character in string.
       Return 0 for an empty string.
       ASC(X$)=255 indicates that the  string  variable  X$  was
       filled  by  an INPUT command reading a unit's EOF marker,
       i.e. it can be used to check for the end of  input  on  a

       Return a one-character string that contains the character
       corresponding to the ASCII code value.

  CMPS(string1, string2)
       Compare the characters in string1 and string2 and  return
       an  integer  that  indicates  the difference of the first
       non-equal characters. A value less than zero  means  that
       string1 comes before string2, when sorted alphabetically,
       a value above zero means  that  string1  is  comes  after
       string2, and zero indicates that both strings are equal.
       The end of a string has the smallest possible value.

       Return the number of free bytes in program memory.

  IOCTL(n, service)
       Request the specified service for unit number n.
       Possible values for service are:

            100   rewind unit n (move to beginning of file)
            101   append to unit n (move to EOF)
            102   truncate unit n at current position

       IOCTL returns a code that indicates the status of the re-
       quested operation.  Generally,  zero  means  success  and
       non-zero means failure.
       When  a  bad  service number is passed to IOCTL, an error

       Return the length of the given string.  An  empty  string
       will deliver zero.

  MID$(string, position, length)
       Extract  a substring from string and return it.  Position
       specifies the first character to be extracted and  length
       gives the length of the desired substring.
       When  position  is greater then the length of the string,
       an empty string will be returned.   When  position+length
       is greater than the length of string, all characters from
       position up to the end of the string are returned.
       The first character in a string is at position  one,  not
       zero, but zero is treated as an alias for one.

       Return  the  value at memory location address.  PEEK only
       reads bytes, and therefore its return value  will  always
       be less than 256.

       Convert  the  specified  value to a string and return it.
       Negative numbers will have a leading minus sign.

       Compute the value of the specified string and return  it.
       A  leading  minus  sign is recognized. Trailing non-digit
       characters are ignored.  Non-numeric  input  will  return

       When  NMH-BASIC  detects  an error, it will print a three
       letter code, followed by a colon and the line that caused
       the  error.  When  an error occurs in execution mode, the
       program will be stopped.

            Line too long - a line exceeds the maximum length of
            64 characters.

            Overflow - a numeric literal does not fit in 15 bits
            + 1 sign bit.  The valid range for numeric  literals
            is -32767 to 32767.

            Syntax  error  - the most common error with an infi-
            nite number of possible causes .  Frequently  caused
            by  typos. Generally, the input that causes this er-
            ror is not a valid basic statement.

            Invalid line number - a GOTO or GOSUB statement con-
            tains a non-existant line number.

            Division by zero. Also caused by X \ 0.

            String  buffer  overflow  - the concatenation of two
            strings is longer than 64 characters.

            Bad subscript - caused by an  attempt  to  access  a
            non-existant  array  element.   This happens when an
            element beyond Z(9) is referenced without first  al-
            locating storage to it via DIM.

            Insufficient  memory - caused by DIM or by inserting
            lines into program memory.

            Not implemented - oops.

            Stack error - the internal return  stack  has  over-
            flown.  Caused  by  nesting  subroutines or FOR-NEXT
            loops too deeply.

            Nesting error - a RETURN statement  occurs  where  a
            NEXT  has  been expected, or vice versa. Also occurs
            when a statement that is being  LOADed  attempts  to
            LOAD  another  program  (LOAD  may not be nested) or
            when the return stack is not empty  when  a  program

            Type mismatch - a variable in a READ statement has a
            different type than the current  item  in  the  init
            list (DATA).

            End  of  data - a READ statement contains more vari-
            ables than remaining items in the init list (DATA).

            Bad argument - an  invalid  service  code  has  been
            passed to IOCTL.

            Stop  -  program execution terminated by a STOP com-

            Break - caused by  pressing  Control-C  or  Control-

            Argh!  - interpreter in hopeless confusion - time to
            bail out!

*** EXAMPLES ***
       Print a sixbit ASCII table.
              100 FOR I = 32 TO 95
              110 PRINT CHR$(I); ' '; I - 32 ,
              120 NEXT

       Load (and merge) programs from units 3 and 4,  then  save
       the  merged program to unit 5. The IOCTL calls rewind and
       truncate unit 5.
              LOAD #3
              LOAD #4
              PRINT IOCTL(5, 100) , IOCTL(5, 102)
              SAVE #5

       Print data from unit 5. The IOCTL call rewinds the unit.
              100 LET X = IOCTL(5, 100) : INPUT #5
              110 INPUT A$ : IF ASC( A$ ) = 255 INPUT #0 : END
              120 PRINT A$ : GOTO 110

*** NOTE ***
       Some versions of the interpreter expect programs  in  DOS
       file  format, i.e.  lines terminated with CR,LF. All ver-
       sions of the interpreter do accept DOS format, some  also
       accept Unix (LF) format.

*** LICENSE ***
       By Nils M Holm, 1991-1994,2023
       MAIL: (DEFUNCT!)

       NMH-BASIC is free software, do whatever you want with it.
       If it breaks something, don't blame me!


contact  |  privacy