home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
mbug
/
mbug060.arc
/
CPM#006.LBR
/
LOAD-HEX.DOC
< prev
next >
Wrap
Text File
|
1979-12-31
|
9KB
|
325 lines
COPYRIGHT (C) 1984 BY GENE HEAD ALL RIGHTS RESERVED
SCHEDULED TO APPEAR IN THE AUGUST ISSUE OF DDJ
More dBASE II Programming Techniques Gene Head 6-13-84
In my last article (DDJ #92 - JUNE '84) I described a
machine language subroutine called ZIP-CHK.ASM that partially
validated zip codes and could be used by dBASE II using the
LOAD FILE, SET CALL TO ADDRESS, and CALL VARIABLE commands.
I now realize that older versions of dBASE II do not support the
LOAD FILE command that facilitate the loading of machine language
modules from assembled HEX files. However, most early versions of
dBASE II (pre 2.4) WILL support the SET CALL TO ADDRESS and CALL
VARIABLE even though these commands may be undocumented in the
user's manual.
In this article I will explain these and some other undocumented
features of early versions of dBASE II. I only have access to versions
2.3 and 2.4 so other versions are untested and should be checked
thoroughly to determine the feature actually works as I will
describe it. I would appreciate feed back to my home address or phone
number of any results you may have on versions prior to 2.3.
I will catalog your findings and pass them on in future articles.
In addition to the undocumented features I have included a
description of the HEX file format and a dBASE II command file that
will simulate the LOAD FILE command IF you can get the undocumented
PEEK and POKE to work. After reviewing the format of the HEX file
you should be able to write a LOAD simulator in any high level
language using LOAD-HEX.CMD as a guideline.
PRE-2.4 UNDOCUMENTED COMMANDS
-----------------------------
PEEK(aaaaa) will return the contents of a decimal address.
POKE aaaaa,nnn will fill a decimal address with a decimal value.
SET CALL TO aaaaa will set the call address to a decimal value.
CALL VARIABLE will call the address as defined in the SET CALL TO
command and pass the string VARIABLE as follows:
Upon entry of the subroutine the HL register pair will point
to the location of the passed variable. The variable
is stored in the format LENGTH BYTE followed by the actual
string characters. For example if the variable ZIP represents
the string '97330' then upon CALLing a subroutine HL would
point to a series of locations with the following data bytes
in hex: 05, 39, 37, 33, 33, 30. The HL pair points to the
05 and indicates there are five bytes in this string. The next
39, 37, 33, 33, 30 are the hex bytes that represent the ASCII
string '97330'. You can modify the string but you must NOT
increase the length of the variable. If the string becomes
shorter you should fill it with trailing blanks.
TEST(variable) will test the variable and return the following:
-6 if the value is NUMERIC type
0 if the variable does not exist
1 if the variable is LOGICAL type
nn (a number between 1 and 255) to indicate the length
of a STRING type variable.
LOADING A HEX FILE
------------------
The HEX file is simply an ASCII text file that holds information
about what bytes go where. The LOAD.COM program usually is used with
the HEX file to create an executable COM file. The format of any HEX
file is as follows:
:10A470002356235E22F0A401080021F2A47EFE07E9 <-- line 1
:10A48000CACFA4BACA8BA409C37DA4237EBBCA9633 <-- line 2
(30 lines were deleted in this example)
:10A672005756323437323638574935333035343914 <-- line 33
:09A68200575938323038333100E9 <-- line 34
:0000000000 <-- line 35
In a HEX file every line ends with a carriage return followed by
a line feed and begins with a colon. In the above example in line
one the next two bytes following the colon, '10', are two ASCII characters
that represent one HEX value in the range 00-FF (0 to 255 decimal).
I will call this value the NUMBER OF BYTE-PAIRS value. We will get
back to it in just a bit. (No pun intended.)
The next four bytes 'A470' are ASCII characters that represent a
HEX value in the range of 0000-FFFF (00000 to 65,535 decimal). I will
call this value the FIRST LOAD ADDRESS.
The next two bytes '00' are ASCII characters that are reserved.
That means I don't know what they are for but in every HEX file I
have ever looked at these two bytes are always '00' and for the scope
of this article I don't think it is necessary to define them exactly.
The same can be said for the last two bytes on each line ('E9' in
line 1). A checksum maybe?
The following bytes 02, 35, 62, 35 etc. should be viewed as
byte-pairs. Remember the NUMBER OF BYTE-PAIRS mentioned earlier?
Well that is exactly the number of these byte-pairs we will load into
consecutive memory starting at the FIRST LOAD ADDRESS. Each of these
byte-pairs are ASCII characters that represent a HEX value in the
range of 00-FF (0 to 255 decimal).
From the example of line 1 the address locations should be
filled with the corresponding byte values as follows:
A470 23 A478 08
A471 56 A479 00
A472 23 A47A 21
A473 5E A47B F2
A474 22 A47C A4
A475 F0 A47D 7E
A476 A4 A47E FE
A477 01 A47F 07
If your high level language does not support a LOAD function
you can simulate one if you can read a text file and PEEK at and
POKE into memory. The command file LOAD-HEX.CMD was written for
dBASE II. dBASE II only understands decimal numbers and
most of the code is converting two ASCII bytes to a decimal number
to be POKED into memory. Understanding the format of the HEX file
as outlined should enable you to write your own HEX loader simulator
in any language.
Using LOAD-HEX.CMD as guide, process line 1 of the HEX file.
Extract the load address (position 4-7 in the string), the number of
BYTE-PAIRS to POKE (position 2-3) and the individual BYTE-PAIRS
(beginning at position 10). POKE each BYTE-PAIR then process the next
line of the HEX file. Continue processing sequential lines until the
NUMBER OF BYTE-PAIRS is equal to zero. The HEX file is now loaded
into memory and ready to CALL as a machine language subroutine.
< < < < end of manuscript program listing follows > > > >
* LOAD-HEX.CMD
*
* File to simulate the LOAD feature of dBASE II 2.4 in
* earlier versions that do not support this feature.
*
* Verify that PEEK and POKE commands work before typing
* in this file and watch the syntax especially '(' & ')'.
*
* From: Head Quarters
* 2860 NW Skyline Drive
* Corvallis, Oregon 97330
* (503) 758-0279
*
* Copyright 1984 by Gene Head - All rights reserved
* For private, non-commercial use only.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
SET TALK OFF
* ---> First time initialization
*
* The following need be done only once
*
* First CREATE a file named HEXDATA.DBF with ONE
* field NAMED DATA of CHARACTER type, forty-four
* (44) characters in length.
*
* APPEND FROM the SUBROUTINE HEX file using the SDF option.
* If you were going to use the Subroutine ZIP-CHK.HEX file then:
*
* .
* .USE HEXLOAD
* .APPEND FROM ZIP-CHK.HEX SDF
* .
*
* <--- End of first time initialization
* Each line of HEX data will be in the field named DATA
USE HEXDATA
* POSITION IN THIS STRING IS THE DECIMAL VALUE OF THE HEX CHARACTER
* (SEARCHING FOR A '0' RETURNS 0)
STORE '123456789ABCDEF' TO HEX
* ---> COMPUTE THE BASE LOCATION OF THIS LOAD (THIS FUNCTION IS OPTIONAL)
STORE STR(((@($(DATA,4,1),HEX)*16 + @($(DATA,5,1),HEX)) * 256) +;
(@($(DATA,6,1),HEX)*16 + @($(DATA,7,1),HEX)),5) TO CALL:ADR
SET CALL TO &CALL:ADR
* <--- END OF LOCATION OPTION
DO WHILE $(DATA,2,2) <> '00'
* Compute how many bytes to POKE from this line of the HEX file
STORE (@($(DATA,2,1),HEX)*16 + @($(DATA,3,1),HEX)) TO COUNT
* Get the starting POKE address
STORE ((@($(DATA,4,1),HEX)*16 + @($(DATA,5,1),HEX)) * 256);
+ (@($(DATA,6,1),HEX)*16 + @($(DATA,7,1),HEX)) TO ADDRESS
* We POKE the last BYTE-PAIR on the line of the HEX file
* and work our way back to the first BYTE-PAIR on the line.
DO WHILE COUNT
STORE STR(ADDRESS+COUNT-1,5)+','+STR(@($(DATA,COUNT*2+8,1),;
HEX)*16+@($(DATA,COUNT*2+9,1),HEX),3) TO BYTE
POKE &BYTE
STORE COUNT -1 TO COUNT
ENDDO WHILE COUNT
* GET NEXT LINE OF HEX DATA
SKIP
ENDDO WHILE $(DATA,2,2) <> '00'
USE