understanding decode

understanding decode
matching parameters

tracking RiBBS errors

The files generated by decode are:

<procedure>Raw.txtRaw I-Code Output - what you see in the First Pass Decode window
<procedure>Vars.txtVariable Reference List - sorted variables
<procedure>Lines.txtLine Reference List - sorted line numbers
<procedure>VDT.txtVDT Validation List - Symbol Table Validation
<procedure>DSAT.txtDSAT Validation List - Definitions Area Validation
<procedure>.B09Source File

I am using the modules elapsed and connect from the RiBBS program for the purposes of describing the output of decode. elapsed is a very small procedure and decodes in less than a minute. connect is a very large procedure and takes about forty-five minutes to decode. The times are listed in the table below for comparison:

For a list of RiBBS modules, and the errors generated by decode's current output for each module, look here.

Displays Version
elapsedconnect
14:49:24Start Time14:50:51Start Time~16-17 minutes before source output begins
00:00:34Elapsed Time00:45:34Elapsed Time
No Displays Version
elapsedconnect
14:37:14Start Time15:40:47Start Time~16-17 minutes before source output begins
14:37:45Completion Time16:24:57Completion Time
00:00:31Elapsed Time00:44:10Elapsed Time

The output of decode can be confusing. Here I will endeavor to help bring understanding to what decode's source output shows, and provide a template for doing the work decode cannot do.

The first bit of confusion I want to help dispell is the multitude of open and close parentheses found in decode's output. This is totally normal, and does not negatively affect Basic09's ability to compile and pack the source code. What is happening is simple. decode has no way of knowing what precedence orders might have been changed using parentheses in the original source. In order to avoid error, I decided it was better to let Basic09 sort it out and just wrap every expression in parentheses. Expressions within expressions include multiple levels of parentheses. Basic09 removes all unnecessary parentheses as it compiles the source on load. [ex: decode output | after loading into Basic09 | Basic09 Pretty-Print of source ]

The next bit of confusion I want to help dispell is the variable naming convention used in decode. Obviously, decode has no way of knowing what your original variable names and line numbers were.

In the case of line numbers, decode uses the list of validated line references to determine how many line numbers there are. Then it numbers them in increments of 10, the same convention used by default in Basic09 for line numbering.

For variable names, I found it easier to name them according to what basic type, what number that reference is in the list of validated variable references, and whether or not the variable is an array and/or a parameter. Field variables are named similarly, and the number of field variables is counted separately. The format follows:

Number value is in a range of 000-999 for field variables, and 0000-9999 for variables.

TYPE
VariableField
BbBYTE
IiINTEGER
RrREAL
LlBOOLEAN
SsSTRING
CcreCord
AaArray
P PARAMeter

Examples:

PB0001 is a PARAMeter BYTE variable, and is the first variable defined
r005 is a REAL field variable, and is the fifth field variable defined
C0005.l021 is a reCord variable, fifth variable defined, and is specifying a BOOLEAN field variable, which is the twenty-first field defined
PIA0043() is a PARAMeter INTEGER Array variable, forty-third variable defined

decode still has a couple of issues with TYPE, DIM and PARAM statements. First, it does not always correctly associate a record variable with it's TYPE statement. In addition, there seem to be times when STRING variables are not being associated properly to their size parameter, so that a 12 character string is DIM'd as STRING instead of STRING[12]. To correct these problems, decode creates a file named <procedure>Vars.txt, where <procedure> is the name of the procedure being decoded. It requires manually scrolling through the file and comparing each STRING variable with its associated DIMension statement in the source output, and making corrections as necessary. [ex: connect variables ]

Using connect as our example, below is a section of connectVars.txt, showing the STRING variables in a TYPE statement in connect.B09:

Uncorrected TYPE statement (asterisks indicate incorrect DIMension)
TYPE TYP4=i009,i010,i011,i012,i013:INTEGER; s014:STRING*; s015:STRING[20]; b016,b017,b018,b019,b020,b021,b022,b023:BYTE; s024:STRING*; s025:STRING[8]; b026,b027:BYTE; s028:STRING*; i029:INTEGER
connect Vars entries for the STRING variables in this TYPE statement
RNum _Instr_ VDT__________VDT_ DSAT___________DSAT Data_Mmry __Field__ Parm Expd
325 Tk Pntr Addr Tk Pntr Size Addr Pntr Size Size Addr Size Addr Size Addr Size VES_ TES_ MES_ SRSz Array Size String Variable/Subroutine Name StrLen
  15 89 0027 0027 44 001F 0003 001F 000A 003C 0004 ---- ---- 000A 003C ---- ---- ---- ---- ---- ---- ------------------- s014                          [60]   
  16 F6 0027 0027 44 001F 0003 001F 000A 003C 0004 ---- ---- 000A 003C ---- ---- ---- ---- ---- ---- ------------------- s014                          [60]   
  17 89 002A 002A 44 0023 0003 0023 0046 0014 0004 ---- ---- 0046 0014 ---- ---- ---- ---- ---- ---- ------------------- s015                          [20]   
  18 F6 002A 002A 44 0023 0003 0023 0046 0014 0004 ---- ---- 0046 0014 ---- ---- ---- ---- ---- ---- ------------------- s015                          [20]   
  31 F6 0045 0045 44 0027 0003 0027 0062 0008 0004 ---- ---- 0062 0008 ---- ---- ---- ---- ---- ---- ------------------- s024                          [8]    
  32 89 0045 0045 44 0027 0003 0027 0062 0008 0004 ---- ---- 0062 0008 ---- ---- ---- ---- ---- ---- ------------------- s024                          [8]    
  33 F6 0048 0048 44 002B 0003 002B 006A 0008 0004 ---- ---- 006A 0008 ---- ---- ---- ---- ---- ---- ------------------- s025                          [8]    
  36 F6 0051 0051 44 002F 0003 002F 0074 000C 0004 ---- ---- 0074 000C ---- ---- ---- ---- ---- ---- ------------------- s028                          [12]   
Corrected TYPE statement
TYPE TYP4=i009,i010,i011,i012,i013:INTEGER; s014:STRING[60]; s015:STRING[20]; b016,b017,b018,b019,b020,b021,b022,b023:BYTE; s024,s025:STRING[8]; b026,b027:BYTE; s028:STRING[12]; i029:INTEGER

For record variable and TYPE statement corrections, more work is needed, so decode creates two more files, named <procedure>VDT.txt and <procedure>DSAT.txt. Using these two files it is possible to make all the necessary corrections to your TYPE statements and record variables, including unused fields in a TYPE statement (with limitations). [ex: connect VDT | connect DSAT ]

The .B09 output file included on this site has the TYPE, DIM and PARAM statements corrected. So you can see what I had to change, below are the uncorrected statements (not all statements, only the ones with errors). After updating this page yesterday, I found that there is a single error in the output of the connectDSAT.txt file. One record array variable (CA0009) was identified as i053. This will not affect the code generation of decode. This code was just added so you could see what variable was validated at that position in the DSAT. I will have to search out why this one instance is incorrect. The other DSAT files in the archive are correct as I modified the previous output of decode in those files manually.

Uncorrected:
TYPE TYP1=i001,*i002:INTEGER
TYPE TYP4=i009,i010,i011,i012,i013:INTEGER; s014:STRING*; s015:STRING[20]; b016,b017,b018,b019,b020,b021,b022,b023:BYTE; s024:STRING*; s025:STRING[8]; b026,b027:BYTE; s028:STRING*; i029:INTEGER
TYPE TYP5=s030:STRING*; l031,l032:BOOLEAN
TYPE TYP8=i040,i041:INTEGER; s042*:STRING*
TYPE TYP9=b043,b044:BYTE*; i045,i046,i047:INTEGER
Corrected:
TYPE TYP1=i001,ui01,ui02,ui03,i002:INTEGER
TYPE TYP4=i009,i010,i011,i012,i013:INTEGER; s014:STRING[60]; s015:STRING[20]; b016,b017,b018,b019,b020,b021,b022,b023:BYTE; s024,s025:STRING[8]; b026,b027:BYTE; s028:STRING[12]; i029:INTEGER
TYPE TYP5=s030:STRING[80]; l031,l032:BOOLEAN
TYPE TYP8=ui07,i040,i041:INTEGER; s042,us08,us09,us10:STRING[8]
TYPE TYP9=ub11,b043,b044,ub12:BYTE; i045,i046,i047:INTEGER

"Hey! Wait a minute! What are those 'ui' and 'us' things???" Those are unused field variables. Sometimes you can figure out what certain field variables are by looking at the size of the TYPE and the number of total fields and which fields are used. In the case of TYP1, the record is 10 ($0A) bytes in length, and is comprised of five (5) fields, two (2) of which are used in connect. Ten minus four (10 - 4) leaves six (6) bytes. The offsets of the two used fields indicate that they are the first and last fields in the record. With three (3) remaining fields, and six (6) bytes of space, this means that the three unused fields are all INTEGER type variables, hence, ui (for unused integer field) and 01, 02 and 03 so that unused fields and variables are counted separately from the others.

The unused STRING field variables in TYP8 were found in the DSAT. It was these entries that allowed me to define the shape of TYP8 more completely.

DSAT entry for TYP8:
008F 0006 0008 s042 Validated
0093 000E 0008                                    008 bytes STRING
0097 0016 0008                                    008 bytes STRING
009B 001E 0008                                    008 bytes STRING
009F 0026 6461 79 0181 0188 0190 0195 019B 01A1   038 bytes 07 fields = C0007:TYP8

TYP9 is shown in the instructions as being the registers record, using registers a,b,x,y and u. Unused are the cc and dp BYTE registers.

C0008.i045=20 \
B0039=$0A \
RUN syscall(B0039,C0008)

I am going to break in here with elapsed. I have mentioned it above, but have not shown anything concerning its DSAT issue. In the case of elapsed, there is a record being passed to it (as evidenced in RiBBSMain's RUN statement for elapsed) that does not occur in the source output:

310 RUN elapsed(C0002,S0081,R0058)
RETURN

C0002 is defined in RiBBSMain as:

TYPE TYP1=i001,i002:INTEGER
DIM C0002:TYP1

Further investigation into RiBBSMain will reveal that C0002 is a 5-INTEGER record. It is being passed to multiple modules. The code in elapsed never utilized the code beyond including the PARAM statement to receive it. As such, it remained unknown until looking at its DSAT:

0000 000A00BB0A00100016001C0022002A000A Unidentified
0011 002E 000E PS0004 Validated
0015 0016 000E S0001 Validated
 
There is/are 1 Unidentified Gap(s) in the DSAT
Offset: 0000  Size:   17

That gap resolves to:

Ofst Size ---- 01 _02_ _03_ _04_ _05_
0000 000A 00BB 0A 0010 0016 001C 0022
Ofst Size
002A 000A

This is a 5-INTEGER record, and the Ofst for the variable is $002A. Resolving the DMA (Data Memory Allocation) for elapsed, we find:

DMA_ MSiz VSiz VarName Description
0016 000E      S0001   (STRING variable 0001)
0024 0002      I0002   (INTEGER variable 0002)
0026 0002      I0003   (INTEGER variable 0003)
0028 0002      UI01    (Unused INTEGER variable 01)
002A 0004 000A UPC02   (Unused PARAMeter reCord variable 02)
002E 0004 000E PS0004  (PARAMeter STRING variable 0004)
0032 0004 0005 PR0005  (PARAMeter REAL variable 0005)

This underscores the necessity of matching up parameters between calling and called procedures. It is this step that will be the most time-consuming where rebuilding a complete source file set for any multi-procedure program is the goal. This completes this section of the Understanding decode guide. The next page to be added will begin the process of building a list of RUN and PARAM statements for each calling and matching called procedure using the RUN and PARAM statements. I will build this list from the source code generated for each procedure in the RiBBS module set. Only the Basic09 I-Code modules will be completely matched, as I have no understanding of assembly, and I can only use disasm to decompile the object code subroutines. It will be up to others to deal with that.

matching parameters