• Welcome to the new COTI server. We've moved the Citizens to a new server. Please let us know in the COTI Website issue forum if you find any problems.
  • We, the systems administration staff, apologize for this unexpected outage of the boards. We have resolved the root cause of the problem and there should be no further disruptions.

BASIC subroutine library for Traveller

robject

SOC-14 10K
Admin Award
Marquis
This is a thread for useful subroutines... in BASIC. Because I'm a glutton for nostalgic punishment.

Submissions to this library SHALL MAKE EFFORTS TO BE:

(0) One subroutine per post, just for sanity's sake. Does this make sense?

(1) Traveller-oriented. Useful for Traveller.

(2) Good citizens. Remarks will state expectations for IN variables, and note what OUT variables will be clobbered and what that data will look like.

(3) Lightly commented where needed. Because BASIC is not the best self-documenting code out there.

(4) Reasonably short.

(5) Line-number free. Labels will take the place of line numbers. I use C64List's notation for this:

Code:
{:Label Name}
   ...BASIC goes here...
   GOTO {:My Other Cool Label}
   ... and so on...

But the requirement is just for it to be obvious.
 
DISTANCE BETWEEN TWO WORLDS

Code:
{:Find Distance}
        '------------------------------------------------------------
        '
        ' Calculate the distance in parsecs between any two systems.
        '
        ' IN: R1%, C1%: row and col of current subsector hex
        ' IN: SR%, SC%: row and col of current subsector
        ' IN: R2%, C2%: row and col of target subsector hex
        ' IN: SS%, SD%: row and col of target subsector
        '
        ' OUT: D% distance in parsecs
        '
        ' TEMP: A1, A2, D2, D3, R3%, C3%, R4%, C4%
        '
        '------------------------------------------------------------
        R3% = R1% + SR% *10
        C3% = C1% + SC% *8
        R4% = R2% + SS% *10
        C4% = C2% + SD% *8
        A1 = R3% + C3%/2
        A2 = R4% + C4%/2
        D% = ABS(A1-A2)
        D2 = ABS(C3%-C4%)
        D3 = ABS(A1-C3%-A2+C4%)
        IF D2 >D% THEN D% = D2
        IF D3 >D% THEN D% = D3
        RETURN
 
This is a thread for useful subroutines... in BASIC. Because I'm a glutton for nostalgic punishment.

BASIC's biggest advantage is its transparency. The 35 year old complaint about the performance hits inherent to being an interpretive language stopped being valid 25 years ago. Spaghetti coding is, of course, still a risk.
 
Last edited:
BASIC's biggest advantage is its transparency. The 35 year old complaint about the performance hits inherent to being an interpretive language stopped being valid 25 years ago. Spaghetti coding is, of course, still a risk.

Many basics are not interpreted, and that's been true since the late 1970's.

Kaypro shipped the Kaypro II (CP/M) with three basic flavors - MBasic, OBasic, and SBasic - M was microsoft, O was some older version, and S was Smart Basic, a compiled basic.

M$ QuickBasic from 4 (possibly earlier) on was run-time compiled, with the paid version compiled; M$ QBasicPDS was compiled completely.

Only recently has the availability of compiling BASIC flavors become again rare.
 
Basic09 all the way.

But if you're going to post BASIC code here, post it as it is programmed. Why the pseudo-code?

This is legal BASIC... and this is the way I (and my Perl code generators) write it, since 2017. Because sometime between 1986 and 2017, someone wrote a nice cross-transpiler for Commodore developers that lets us drop the line numbers (in favor of labels), inline assembly code, and do other handy things.
 
This is legal BASIC... and this is the way I (and my Perl code generators) write it, since 2017. Because sometime between 1986 and 2017, someone wrote a nice cross-transpiler for Commodore developers that lets us drop the line numbers (in favor of labels), inline assembly code, and do other handy things.
Ok. As long as it's Run-able.
 
HEX-to-SUBSECTOR

' Name: h2ss (hex to subsector)
'
' Purpose: determine the subsector in which a hex "resides"
'
' Parameters: a (typically) 4-digit hex number, for example 1221 (3 digits if the first digit is zero)
'
' Example use: intSubsector = h2ss(1221)
'
' Returns: a number from 1 to 16, representing the subsector in which the hex "resides"
'
' Why: When generating random sectors, I use the subsector letter and hex number to name the system.
' For example, hex 0101 will be named A-0101 if there is something in the system.
'
' I also use it when searching for systems in a specific Subsector for mapping purposes.
'
' To convert to the letter value, using the call above, I could simply do this:
'
' charSubsector = chr$(64 + intSubsector) ' letters A thru P
'
' Note: the "\" below represents INTEGER DIVISION.

Code:
function h2ss(intHex as integer) as integer
     return  (((intHex \ 100) - 1) / 8) + 1 + (((intHex Mod 100) - 1)  \ 10) * 4
end function
=====

' If your Basic doesn't support the form above, try this version:

return Int(Int((intHex / 100) - 1) / 8) + 1 + Int(((intHex Mod 100) - 1) / 10) * 4
 
Last edited by a moderator:
UNPACK BITFIELDS FROM A BYTE

This one was interesting to write. It applies division as a shift operation, then a bitmask to grab the correct bits. The results are stored in an array.

Code:
{:decode byte}
        '------------------------------------------------
        '
        ' Breaks a byte down into numeric bitfields
        '
        ' IN: IN$ is the input character
        ' IN: BN% is the number of fields
        ' IN: BD% is the "divisor" array (simulates shift)
        ' IN: BW% is the bitmask array 
        '
        ' TEMP: M
        '
        ' OUT: BO% is the output array
        '------------------------------------------------
        BB% = ASC(IN$)
{:decode byte inner loop}
        IF BN% = 0 THEN RETURN
        BN% = BN%-1
        BO%(BN%) = INT(BB%/BD%(BN%)) AND BW%(BN%) 
        GOTO {:decode byte inner loop}
 
Last edited:
BASIC's biggest advantage is its transparency. The 35 year old complaint about the performance hits inherent to being an interpretive language stopped being valid 25 years ago. Spaghetti coding is, of course, still a risk.

Actually, at the time, BASIC's biggest advantage was development time.

While the interpreter suffered runtime performance, development performance was pretty much unmatched. You could be far more productive, much more quickly, in BASIC.

You could easily enter and change code, test code, debug and restart code. Compiling and linking code was simply glacial back in the day. Really, truly awful.

On the PDP, under RSTS/E, BASIC and Macro (assembly) were the two primary languages. All of the system utilities and what not were written in BASIC.

Unfortunately, the nature of the language would fight against it in larger programs, simply by early BASIC's global scoping, lack of structured programming, reliance on absolute line numbers, and lack of higher level data structures.

All of these were mitigated over time, but eventually computers and development environments got faster to where BASICs advantage couldn't over come its early limitations and reputation.
 
Also with interpreted languages, you get the ability to try things outside the program on the command line, to see their behavior before you put them into a program. That can be a game-changer as a programming technique.
 
All of these were mitigated over time, but eventually computers and development environments got faster to where BASICs advantage couldn't over come its early limitations and reputation.

You were accurate up to this paragraph. Its limitations in current implementations vary by implementation, not by the language. QB64, for example is both human readable and quite powerful. It's someone reimplementing MS Quick Basic language with modern 64-bit capability.

There are still several dozen flavors of BASIC that compile - and compile to machine code. Some even cross-platform. Like the one Robject is using. Like QB64.

There's a good reason BASIC doesn't die - only a few other languages are as close or closer to natural language, and most of those are primarily interpreted. (Inform6, Inform 7, Python come to mind).
 
Basic programming classes were moving over to Pascal programming classes. Then when Pascal quickly was replaced by C, hobby students had a choice still for their programming, Basic or C. Basic ran on all computers still at the time. C programming would take much more effort, and hardware.

Python kind of brought back that Basic interpreter feel to programmers, once computers everywhere began running the language. Hardcore C programmers aren't all that interested in interpreter language programming environments for coding in. Hardcore Basic programmers are few and far between. Will be interesting to see where Python 4 goes without its BDFL.
 
Back
Top