• Disassembly of old Turbo Pascal (V3) code - how to create data

    From Robert Prins@21:1/5 to All on Sat Apr 17 13:48:02 2021
    Hi all,

    I would like to disassemble the final version of a self-written Turbo Pascal V3 program, i.e. a simple .COM file, and to that effect I've dug out my old (AD 2004) registered copy of IDA Pro (V4.7.0.831). Not having used it for more than 10 years, and no longer having access to their forum, I'm now stuck. The .COM file loads, IDA happily disassembles it, but it just creates one single segment,
    and I have no (longer) a clue on how to create the data segment. There's a bit of info in the TP3 Manual, and using David Lindauer's GRDB in DOXBox-X allows me
    to single-step through the RTL initialisation code and that shows me it sets up up DS and SS, but it doesn't help me in setting up these segments in IDA.

    I've tried the "Create Segment" option, but I'm lost entering the required values for start address, end address and base, "class" is probably "DATA", the once for the single "seg000" that IDA creates are CODE, start @ 0x0100, end @ 0xD623, which leads me to assume that a to-be-created "seg001" should start at 0x0000, end at 0xffff, and have a base of 0xd63 (paragraphs), but that results in a "Bad segment base: segment would have bytes with a negative offset" pop-up.

    Trying start @ 0xd630, end @ 0x1d630, with a base 0x0000 creates a segment, but it looks like

    seg000:D622
    seg001:C8C00 ; --------------------------------------------------------------------------- seg001:C8C00
    seg001:C8C00 ; Segment type: Regular
    seg001:C8C00 seg001 segment byte public '' use16
    seg001:C8C00 assume cs:seg001
    seg001:C8C00 ;org 0C8C00h
    seg001:C8C00 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing

    Which may be correct, but the "org 0c8c00" makes absolutely no sense to me.

    If you can help me I would be grateful, and to help you, I've uploaded a RAR archive with the full sources, the resulting "lift.com" executable and the input
    file to my Google drive @ <https://drive.google.com/drive/folders/0B0oygbfs7DsVVWNBZWpqaHRHX3c?usp=sharing>,
    look for lift16bit.rar Please note that the code will not compile with anything more advanced than Turbo Pascal 3, and in my case it was compiled with TP 3.01a.

    Thanks,

    Robert
    --
    Robert AH Prins
    robert(a)prino(d)org
    The hitchhiking grandfather - https://prino.neocities.org/indez.html
    Some REXX code for use on z/OS - https://prino.neocities.org/zOS/zOS-Tools.html

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Sjouke Burry@21:1/5 to Robert Prins on Sat Apr 17 20:32:10 2021
    On 17.04.21 15:48, Robert Prins wrote:
    Hi all,

    I would like to disassemble the final version of a self-written Turbo Pascal V3
    program, i.e. a simple .COM file, and to that effect I've dug out my old (AD 2004) registered copy of IDA Pro (V4.7.0.831). Not having used it for more than
    10 years, and no longer having access to their forum, I'm now stuck. The .COM file loads, IDA happily disassembles it, but it just creates one single segment,
    and I have no (longer) a clue on how to create the data segment. There's a bit
    of info in the TP3 Manual, and using David Lindauer's GRDB in DOXBox-X allows me
    to single-step through the RTL initialisation code and that shows me it sets up
    up DS and SS, but it doesn't help me in setting up these segments in IDA.

    I've tried the "Create Segment" option, but I'm lost entering the required values for start address, end address and base, "class" is probably "DATA", the
    once for the single "seg000" that IDA creates are CODE, start @ 0x0100, end @ 0xD623, which leads me to assume that a to-be-created "seg001" should start at
    0x0000, end at 0xffff, and have a base of 0xd63 (paragraphs), but that results
    in a "Bad segment base: segment would have bytes with a negative offset" pop-up.

    Trying start @ 0xd630, end @ 0x1d630, with a base 0x0000 creates a segment, but
    it looks like

    seg000:D622
    seg001:C8C00 ; --------------------------------------------------------------------------- seg001:C8C00
    seg001:C8C00 ; Segment type: Regular
    seg001:C8C00 seg001 segment byte public '' use16
    seg001:C8C00 assume cs:seg001
    seg001:C8C00 ;org 0C8C00h
    seg001:C8C00 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing

    Which may be correct, but the "org 0c8c00" makes absolutely no sense to me.

    If you can help me I would be grateful, and to help you, I've uploaded a RAR archive with the full sources, the resulting "lift.com" executable and the input
    file to my Google drive @ <https://drive.google.com/drive/folders/0B0oygbfs7DsVVWNBZWpqaHRHX3c?usp=sharing>,
    look for lift16bit.rar Please note that the code will not compile with anything
    more advanced than Turbo Pascal 3, and in my case it was compiled with TP 3.01a.

    Thanks,

    Robert

    A com file is a simplyfied exe, without a lot of exe things.
    Just a solid block of code and data.
    And not to much of that either.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From wolfgang kern@21:1/5 to Robert Prins on Sat Apr 17 21:30:24 2021
    On 17.04.2021 15:48, Robert Prins wrote:
    Hi all,
    Hello,
    I would like to disassemble the final version of a self-written Turbo
    Pascal V3 program, i.e. a simple .COM file,
    ...

    .com files haven't any segment-info.
    you can try DOS-debug (if you have one) or the NASM disassembler.

    DOS.COM-files are usually organized to start at cs:0x0100.
    If you post a hex-dump of your code I could disassemble it.
    __
    wolfgang

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Prins@21:1/5 to wolfgang kern on Sat Apr 17 22:07:15 2021
    On 2021-04-17 19:30, wolfgang kern wrote:
    On 17.04.2021 15:48, Robert Prins wrote:
    Hi all,
    Hello,
    I would like to disassemble the final version of a self-written Turbo Pascal >> V3 program, i.e. a simple .COM file,
    ...

    .com files haven't any segment-info.
    you can try DOS-debug (if you have one) or the NASM disassembler.

    DOS.COM-files are usually organized to start at cs:0x0100.
    If you post a hex-dump of your code I could disassemble it.

    To you, Wolfgang, and Sjouke Berry,

    Turbo Pascal V3 (and probably versions 1 & 2 too) created .COM files are not run-of-the-mill .COM files. The startup-code actually sets up DS to point to a separate data segment, and SS to a separate stack. For what it's worth, I've put
    'LIFT.COM' temporarily on my website <https://prino.neocities.com/temp/lift.com>, so feel free to have a go at it. The code that sets up the environment starts at 0x2d7c (assuming the program is loaded at 0x100)

    And as I wrote, IDA Pro happily disassembles it, but my problem is, not having ever disassembled a TP3 generated .COM file, how to create a second (= data) segment. I see it being created running the program in GRDB, but GRDB <> IDA Pro.

    Getting a new version of IDA Pro (to again get access to their forum) is a no-no, the Pro version costs USD 1879 (or more than 10% of my annual income), the Home version costs USD 365, but no longer has a perpetual license and can only disassemble selected instruction sets...

    Robert

    PS: Maybe I should give this NSA thing, Ghidra, a try?
    --
    Robert AH Prins
    robert(a)prino(d)org
    The hitchhiking grandfather - https://prino.neocities.org/indez.html
    Some REXX code for use on z/OS - https://prino.neocities.org/zOS/zOS-Tools.html

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Frank Kotler@21:1/5 to Robert Prins on Sat Apr 17 17:50:15 2021
    On 04/17/2021 06:07 PM, Robert Prins wrote:

    ...
    Turbo Pascal V3 (and probably versions 1 & 2 too) created .COM files are
    not run-of-the-mill .COM files.

    As I recall, DOS doesn't care what the file is named. If the first two
    bytes are "MZ", it's an exe. Perhaps we should not call it .COM?

    Best,
    Frank

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Prins@21:1/5 to Frank Kotler on Sun Apr 18 09:09:25 2021
    On 2021-04-17 21:50, Frank Kotler wrote:
    On 04/17/2021 06:07 PM, Robert Prins wrote:

    ...
    Turbo Pascal V3 (and probably versions 1 & 2 too) created .COM files are not >> run-of-the-mill .COM files.

    As I recall, DOS doesn't care what the file is named. If the first two bytes are
    "MZ", it's an exe. Perhaps we should not call it .COM?

    They are not MZ files, they are real COM files, be it that they do strange things once loaded.

    Not that strange, given that "turbo.com", the original "IDE" did also handle multiple segments (itself, and the image of the compiled program, when set to run from memory) Anders Hejlsberg, who originally wrote it, was (and still is) pretty brilliant guy.

    Robert
    --
    Robert AH Prins
    robert(a)prino(d)org
    The hitchhiking grandfather - https://prino.neocities.org/indez.html
    Some REXX code for use on z/OS - https://prino.neocities.org/zOS/zOS-Tools.html

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From wolfgang kern@21:1/5 to Robert Prins on Sun Apr 18 11:29:37 2021
    On 18.04.2021 11:09, Robert Prins wrote:
    On 2021-04-17 21:50, Frank Kotler wrote:
    On 04/17/2021 06:07 PM, Robert Prins wrote:

    ...
    Turbo Pascal V3 (and probably versions 1 & 2 too) created .COM files
    are not run-of-the-mill .COM files.

    As I recall, DOS doesn't care what the file is named. If the first two
    bytes are "MZ", it's an exe. Perhaps we should not call it .COM?

    They are not MZ files, they are real COM files, be it that they do
    strange things once loaded.

    Not that strange, given that "turbo.com", the original "IDE" did also
    handle multiple segments (itself, and the image of the compiled program,
    when set to run from memory) Anders Hejlsberg, who originally wrote it,
    was (and still is) pretty brilliant guy.

    if they are real COM files then the segment info is found in the code.

    often seen start in com-files:

    org 0100h ;to override DOS default segment setting
    push CS ;the COM-loader grant a few bytes stack
    pop SS
    mov SP.xxxx ;wherever it's wanted to be
    push CS
    pop DS
    push 0
    pop ES
    ....
    __
    wolfgang

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Terje Mathisen@21:1/5 to Robert Prins on Sun Apr 18 14:39:10 2021
    Robert Prins wrote:
    On 2021-04-17 21:50, Frank Kotler wrote:
    On 04/17/2021 06:07 PM, Robert Prins wrote:

    ...
    Turbo Pascal V3 (and probably versions 1 & 2 too) created .COM files
    are not run-of-the-mill .COM files.

    As I recall, DOS doesn't care what the file is named. If the first two
    bytes are "MZ", it's an exe. Perhaps we should not call it .COM?

    They are not MZ files, they are real COM files, be it that they do
    strange things once loaded.

    Not that strange, given that "turbo.com", the original "IDE" did also
    handle multiple segments (itself, and the image of the compiled program,
    when set to run from memory) Anders Hejlsberg, who originally wrote it,
    was (and still is) pretty brilliant guy.

    I agree 100%.

    The 35-37 kB needed for Turbo.com is one of the all-time great hacks:

    A compiler (non-optimizing but still), editor, debugger and RTL in that
    space?

    Terje

    --
    - <Terje.Mathisen at tmsw.no>
    "almost all programming can be viewed as an exercise in caching"

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Prins@21:1/5 to wolfgang kern on Mon Apr 19 01:26:54 2021
    On 2021-04-18 09:29, wolfgang kern wrote:
    On 18.04.2021 11:09, Robert Prins wrote:
    On 2021-04-17 21:50, Frank Kotler wrote:
    On 04/17/2021 06:07 PM, Robert Prins wrote:

    ...
    Turbo Pascal V3 (and probably versions 1 & 2 too) created .COM files are not
    run-of-the-mill .COM files.

    As I recall, DOS doesn't care what the file is named. If the first two bytes
    are "MZ", it's an exe. Perhaps we should not call it .COM?

    They are not MZ files, they are real COM files, be it that they do strange >> things once loaded.

    Not that strange, given that "turbo.com", the original "IDE" did also handle >> multiple segments (itself, and the image of the compiled program, when set to
    run from memory) Anders Hejlsberg, who originally wrote it, was (and still is)
    pretty brilliant guy.

    if they are real COM files then the segment info is found in the code.

    often seen start in com-files:

    org 0100h       ;to override DOS default segment setting
    push CS        ;the COM-loader grant a few bytes stack
    pop  SS
    mov  SP.xxxx   ;wherever it's wanted to be
    push CS
    pop  DS
    push  0
    pop  ES
    ....

    The info is there, but it's not as trivial as what you show. I'm sure that I will be able to get at it at some stage to automagically create an skeleton IDC file to generate the segments, after all I also got this bit of REXX,

    === CUT ===
    data = charin(file, 1, chars(file))

    data = overlay(reverse(x2c(d2x(date('T', now, 'I') + 12 * 3600, 8))), data, pos('PE' || x2c(00 00), data) + 8)

    call charout file, data, 1
    === CUT ===

    that sets the timestamp in the PE files coming out of Virtual Pascal to 12:00 with "now" being the date of the newest source file.

    Robert
    --
    Robert AH Prins
    robert(a)prino(d)org
    The hitchhiking grandfather - https://prino.neocities.org/indez.html
    Some REXX code for use on z/OS - https://prino.neocities.org/zOS/zOS-Tools.html

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Prins@21:1/5 to Robert Prins on Fri May 7 22:10:54 2021
    On 2021-04-17 13:48, Robert Prins wrote:
    Hi all,

    I would like to disassemble the final version of a self-written Turbo Pascal
    V3 program, i.e. a simple .COM file, and to that effect I've dug out my old (AD 2004) registered copy of IDA Pro (V4.7.0.831). Not having used it for more than 10 years, and no longer having access to their forum, I'm now stuck. The .COM file loads, IDA happily disassembles it, but it just creates one single segment,
    and I have no (longer) a clue on how to create the data segment. There's a bit of info in the TP3 Manual, and using David Lindauer's GRDB in DOXBox-X allows me
    to single-step through the RTL initialisation code and that shows me it sets up up DS and SS, but it doesn't help me in setting up these segments in IDA.

    I've tried the "Create Segment" option, but I'm lost entering the required
    values for start address, end address and base, "class" is probably "DATA", the once for the single "seg000" that IDA creates are CODE, start @ 0x0100, end @ 0xD623, which leads me to assume that a to-be-created "seg001" should start at 0x0000, end at 0xffff, and have a base of 0xd63 (paragraphs), but that results in a "Bad segment base: segment would have bytes with a negative offset" pop-up.

    Trying start @ 0xd630, end @ 0x1d630, with a base 0x0000 creates a segment,
    but it looks like

    seg000:D622
    seg001:C8C00 ;
    ---------------------------------------------------------------------------
    seg001:C8C00
    seg001:C8C00 ; Segment type: Regular
    seg001:C8C00 seg001 segment byte public '' use16
    seg001:C8C00 assume cs:seg001
    seg001:C8C00 ;org 0C8C00h
    seg001:C8C00 assume es:nothing, ss:nothing, ds:nothing,
    fs:nothing, gs:nothing

    Which may be correct, but the "org 0c8c00" makes absolutely no sense to me.

    I've had a bit, or rather, a huge, amount of help from Hex-Rays' Ilfak Guilfanov, and using the names in "scg.zip" (found @ <https://www.pcengines.ch/tp3.htm>, I've got a complete disassembly of the compiler. I cut down the IDA generated .IDC file to include just the info about the RTL, manually changed some data, which at some stage should be done with built-in IDC functions, wrote a bit of REXX to add identifiers to every Pascal procedure (basically inline statements that jump over upper-cased procedure names in Pascal-string format) and got myself a nice assembly listing, with code
    that's obviously working, but very "simple" (Let's just leave it at that...)

    I could let IDA generate an assembler listing, hack that to pieces, most likely in some automated way, as there are dozens of procedures that look like

    cseg:4E77 proc day_ptr_is_td_top near
    cseg:4E77
    cseg:4E77 push bp
    cseg:4E78 mov bp, sp
    cseg:4E7A push bp
    cseg:4E7B jmp $+3
    cseg:4E7E ; ------------------------------------------------------------ cseg:4E7E
    cseg:4E7E @01:
    cseg:4E7E jmp short @02
    cseg:4E7E ; ------------------------------------------------------------ cseg:4E80 db 17,'DAY_PTR_IS_TD_TOP'
    cseg:4E92 ; ------------------------------------------------------------ cseg:4E92
    cseg:4E92 @02:
    cseg:4E92 mov eax, [td_top]
    cseg:4E96 mov [day_ptr], eax
    cseg:4E9A mov [winday_top], eax
    cseg:4E9E call _day_list_is_day_ptr
    cseg:4EA1 jmp $+3
    cseg:4EA4 ; ------------------------------------------------------------ cseg:4EA4
    cseg:4EA4 @03:
    cseg:4EA4 mov sp, bp
    cseg:4EA6 pop bp
    cseg:4EA7 retn
    cseg:4EA7 endp day_ptr_is_td_top

    where a stack-frame isn't required, and likewise for the "jmp $+3"'s.

    However, right now I've started to think about something else, making a few tweaks to the compiler itself. IDA Pro has a built-in assemble command, and can save a changed .COM file, but that would result in an output file with just a lot of NOP instructions, like 20+ in the random number generator

    x(n+1) = (x(n) * 129 + 907633385) mod 2^32

    32-bit multiplication and addition are easier on a 32-bit CPU than on a 16-bit one...

    But of course it would be more interesting to see if it's possible to retrofit Norbert Juffa's enhanced 6-byte-real IEEE-compliant (as far as that's possible in this format) arithmetic to the RTL. That however would not realistically possible via the assemble command, but would require a real reassembly. IDA Pro provides two options for generating source, "generic" (aka MASM?) or TASM "Ideal" mode.

    Now I can probably figure out what to change where to let Turbo set up its segmentation magic, but my disassembly contains a data segment with the uninitialised RTL variables, and I don't want/need that in a .COM file. The assembler listing generated by the program in the above-mentiond scg.zip and to be assembled with "AS" from the same just has a series of "var = value" to set up these variables. So is there a way to create in TASM/MASM some kind of "dummy" data segment just to set up variable names/offsets? Googling on dummy/virtual segment doesn't come up with anything helpful, but I'm sure that this is not an uncommon situations.

    Robert
    --
    Robert AH Prins
    robert(a)prino(d)org
    The hitchhiking grandfather - https://prino.neocities.org/indez.html
    Some REXX code for use on z/OS - https://prino.neocities.org/zOS/zOS-Tools.html

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Prins@21:1/5 to Robert Prins on Fri May 7 22:09:21 2021
    On 2021-04-17 13:48, Robert Prins wrote:
    Hi all,

    I would like to disassemble the final version of a self-written Turbo Pascal
    V3 program, i.e. a simple .COM file, and to that effect I've dug out my old (AD 2004) registered copy of IDA Pro (V4.7.0.831). Not having used it for more than 10 years, and no longer having access to their forum, I'm now stuck. The .COM file loads, IDA happily disassembles it, but it just creates one single segment,
    and I have no (longer) a clue on how to create the data segment. There's a bit of info in the TP3 Manual, and using David Lindauer's GRDB in DOXBox-X allows me
    to single-step through the RTL initialisation code and that shows me it sets up up DS and SS, but it doesn't help me in setting up these segments in IDA.

    I've tried the "Create Segment" option, but I'm lost entering the required
    values for start address, end address and base, "class" is probably "DATA", the once for the single "seg000" that IDA creates are CODE, start @ 0x0100, end @ 0xD623, which leads me to assume that a to-be-created "seg001" should start at 0x0000, end at 0xffff, and have a base of 0xd63 (paragraphs), but that results in a "Bad segment base: segment would have bytes with a negative offset" pop-up.

    Trying start @ 0xd630, end @ 0x1d630, with a base 0x0000 creates a segment,
    but it looks like

    seg000:D622
    seg001:C8C00 ;
    ---------------------------------------------------------------------------
    seg001:C8C00
    seg001:C8C00 ; Segment type: Regular
    seg001:C8C00 seg001 segment byte public '' use16
    seg001:C8C00 assume cs:seg001
    seg001:C8C00 ;org 0C8C00h
    seg001:C8C00 assume es:nothing, ss:nothing, ds:nothing,
    fs:nothing, gs:nothing

    Which may be correct, but the "org 0c8c00" makes absolutely no sense to me.

    I've had a bit, or rather, a huge, amount of help from Hex-Rays' Ilfak Guilfanov, and using the names in "scg.zip" (found @ <https://www.pcengines.ch/tp3.htm>, I've got a complete disassembly of the compiler. I cut down the IDA generated .IDC file to include just the info about the RTL, manually changed some data, which at some stage should be done with built-in IDC functions, wrote a bit of REXX to add identifiers to every Pascal procedure (basically inline statements that jump over upper-cased procedure names in Pascal-string format) and got myself a nice assembly listing, with code
    that's obviously working, but very "simple" (Let's just leave it at that...)

    I could let IDA generate an assembler listing, hack that to pieces, most likely in some automated way, as there are dozens of procedures that look like

    cseg:4E77 proc day_ptr_is_td_top near
    cseg:4E77
    cseg:4E77 push bp
    cseg:4E78 mov bp, sp
    cseg:4E7A push bp
    cseg:4E7B jmp $+3
    cseg:4E7E ; ------------------------------------------------------------ cseg:4E7E
    cseg:4E7E @01:
    cseg:4E7E jmp short @02
    cseg:4E7E ; ------------------------------------------------------------ cseg:4E80 db 17,'DAY_PTR_IS_TD_TOP'
    cseg:4E92 ; ------------------------------------------------------------ cseg:4E92
    cseg:4E92 @02:
    cseg:4E92 mov eax, [td_top]
    cseg:4E96 mov [day_ptr], eax
    cseg:4E9A mov [winday_top], eax
    cseg:4E9E call _day_list_is_day_ptr
    cseg:4EA1 jmp $+3
    cseg:4EA4 ; ------------------------------------------------------------ cseg:4EA4
    cseg:4EA4 @03:
    cseg:4EA4 mov sp, bp
    cseg:4EA6 pop bp
    cseg:4EA7 retn
    cseg:4EA7 endp day_ptr_is_td_top

    where a stack-frame isn't required, and likewise for the "jmp $+3"'s.

    However, right now I've started to think about something else, making a few tweaks to the compiler itself. IDA Pro has a built-in assemble command, and can save a changed .COM file, but that would result in an output file with just a lot of NOP instructions, like 20+ in the random number generator

    x(n+1) = (x(n) * 129 + 907633385) mod 2^32

    32-bit multiplication and addition are easier on a 32-bit CPU than on a 16-bit one...

    But of course it would be more interesting to see if it's possible to retrofit Norbert Juffa's enhanced 6-byte-real IEEE-compliant (as far as that's possible in this format) arithmetic to the RTL. That however would not realistically possible via the assemble command, but would require a real reassembly. IDA Pro provides two options for generating source, "generic" (aka MASM?) or TASM "Ideal" mode.

    Now I can probably figure out what to change where to let Turbo set up its segmentation magic, but my disassembly contains a data segment with the uninitialised RTL variables, and I don't want/need that in a .COM file. The assembler listing generated by the program in the above-mentiond scg.zip and to be assembled with "AS" from the same just has a series of "var = value" to set up these variables. So is there a way to create in TASM/MASM some kind of "dummy" data segment just to set up variable names/offsets? Googling on dummy/virtual segment doesn't come up with anything helpful, but I'm sure that this is not an uncommon situations.

    Robert
    --
    Robert AH Prins
    robert(a)prino(d)org
    The hitchhiking grandfather - https://prino.neocities.org/indez.html
    Some REXX code for use on z/OS - https://prino.neocities.org/zOS/zOS-Tools.html

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)