Page 2 of 4

Re: LUCIDATA Pascal for 6502

Posted: Thu Oct 14, 2021 3:14 am
by BillG
Sean wrote:
You also might want to look at the ISO 7185 Standard Pascal website. It has several versions of the portable Pascal-P compiler/interpreter. I believe Pascal-P2 served as the basis for UCSD Pascal.
I looked at the interpreters for P2 and P4. Neither resembled LUCIDATA.

Re: LUCIDATA Pascal for 6502

Posted: Thu Oct 14, 2021 3:18 am
by BillG
resman wrote:
Randy Hyde wrote a great book about the Apple Pascal p-code interpreter: https://archive.org/details/Hyde_P-Sour ... ystem_1983

Very useful if the LUCIDATA is based off of UCSD, but still a great read regardless.
Thanks!

Some of that information should apply to all P-code implementations.

Data Becker published some GREAT technical books in their time. One of my favorites is Turbo Pascal 6 System Programming.

Re: LUCIDATA Pascal for 6502

Posted: Thu Oct 14, 2021 3:49 am
by BillG
drogon wrote:
I'd be interested in seeing if this might run on my Ruby system - but one big issue might well be what sort of underlying operating system it needs to handle e.g. files and so-on.
The LUCIDATA system switches into "paging" mode when a program is too large to load into available memory. Theoretically, a version for the 65816 may be possible to use an entire 64K bank for data (the stack) and other memory above the base 64K for the program. The question then would be internal size limits of the compiler. For instance, the "program counter" is 16-bits as are offsets into the stack.

Re: LUCIDATA Pascal for 6502

Posted: Thu Oct 14, 2021 4:19 am
by Sean
BillG wrote:
Sean wrote:
You also might want to look at the ISO 7185 Standard Pascal website. It has several versions of the portable Pascal-P compiler/interpreter. I believe Pascal-P2 served as the basis for UCSD Pascal.
I looked at the interpreters for P2 and P4. Neither resembled LUCIDATA.
Interesting. Since it doesn't look like P2 or P4, and it doesn't look like UCSD, you make me wonder if the developer of LUCIDATA went for a fresh implementation from the language spec.

Re: LUCIDATA Pascal for 6502

Posted: Thu Oct 14, 2021 6:22 am
by BillG
The manual says the compiler was written by David R. Gibby and the run-time system by Nigel W. Bennee.

A web search does not reveal much except possibly versions for CP/M and Heathkit DOS. I have heard of neither of these before.

Re: LUCIDATA Pascal for 6502

Posted: Thu Oct 14, 2021 11:18 am
by BigEd
Which disassembler are you using BillG? Just possibly py8dis will be of interest.
https://stardot.org.uk/forums/viewtopic ... 55&t=23335

Re: LUCIDATA Pascal for 6502

Posted: Thu Oct 14, 2021 11:28 am
by drogon
BillG wrote:
drogon wrote:
I'd be interested in seeing if this might run on my Ruby system - but one big issue might well be what sort of underlying operating system it needs to handle e.g. files and so-on.
The LUCIDATA system switches into "paging" mode when a program is too large to load into available memory. Theoretically, a version for the 65816 may be possible to use an entire 64K bank for data (the stack) and other memory above the base 64K for the program. The question then would be internal size limits of the compiler. For instance, the "program counter" is 16-bits as are offsets into the stack.
Hm. I was half hoping I may be able to run it like I run the cintcode VM - which is is 32-bit mode with no bank/page restrictions, but if that's effectively built into the system then it might be awkward.

I'll get Pascal going one day, even if I have to finish off the compiler I started writing - with the intention of having it compile into the bcpl cintcode, then it can directly work on the system with the possibility of cross calling from Pascal to BCPL and back.... Back to Jack Crenshaws papers!

Cheers,

-Gordon

Re: LUCIDATA Pascal for 6502

Posted: Thu Oct 14, 2021 1:13 pm
by BillG
BigEd wrote:
Which disassembler are you using BillG? Just possibly py8dis will be of interest.
https://stardot.org.uk/forums/viewtopic ... 55&t=23335
None. I start with the hex dump, manually group the bytes into clumps of four for each instruction and add a comment if I know the meaning.

Unless LUCIDATA had an internal tool, I doubt anyone knows the instruction set to write one.

Re: LUCIDATA Pascal for 6502

Posted: Sun Oct 17, 2021 5:04 am
by BillG
So I morphed the debugger from the 8080 simulator into a P-code debugger.
Hello65.png
Now to build a foundation below it to execute those instructions...

Re: LUCIDATA Pascal for 6502

Posted: Tue Oct 19, 2021 11:23 am
by BillG
Let the deed shaw...
Hello6502.png
Hello6502Debug.png

Re: LUCIDATA Pascal for 6502

Posted: Tue Oct 19, 2021 1:06 pm
by drogon
Looks like good progress!

Things I found tricky about Pascal were sets/ranges but with this sort of incremental approach it might not be too hard to work out what's going on under the bonnet...

Cheers,


-Gordon

Re: LUCIDATA Pascal for 6502

Posted: Wed Oct 20, 2021 12:01 pm
by BillG
This has been but a few bites of a rather large elephant.

Without an understanding of the frame pointer and activation records, there will be little further progress as everything else keys on that.

Re: LUCIDATA Pascal for 6502

Posted: Thu Oct 28, 2021 11:36 am
by BillG
Still trying to gain an understanding of the stack frames and activation records. In pursuit thereof, I came up with this test program:

Code: Select all

PROGRAM TEST;

  VAR
    I : INTEGER;

  PROCEDURE DEEP;

    VAR
      J : INTEGER;

    PROCEDURE DEEPER;

      VAR
        K : INTEGER;

      PROCEDURE DEEPEST;

        VAR
          L : INTEGER;

        BEGIN
          L := 4;

          WRITE(I);
          WRITE(J);
          WRITE(K);
          WRITELN(L)
        END;

      BEGIN
        K := 3;

        DEEPEST
      END;

    BEGIN
      J := 2;

      DEEPER
    END;

  BEGIN
    I := 1;

    DEEP
  END.
It's P-code is:

Code: Select all

Hexadecimal dump of nested.bin

00000000: 00 2E 00 7C 00 01 00 01-00 06 01 00 00 68 01 00  |...|.........h..|
00000010: 00 54 01 00 00 40 06 00-00 02 07 02 00 04 27 00  |.T...@........'.|
00000020: 00 08 26 03 00 08 2E 02-06 01 26 02 00 08 2E 02  |..&.......&.....|
00000030: 06 01 26 01 00 08 2E 02-06 01 26 00 00 08 2E 02  |..&.......&.....|
00000040: 06 01 1C 02 00 00 05 00-00 00 06 00 00 02 07 02  |................|
00000050: 00 03 27 00 00 08 04 80-00 0C 05 00 00 00 06 00  |..'.............|
00000060: 00 02 07 02 00 02 27 00-00 08 04 80 00 40 05 00  |......'......@..|
00000070: 00 00 06 00 00 08 07 02-00 01 27 00 00 08 04 80  |..........'.....|
00000080: 00 54 00 00 00 00 00 00-00 00 00 00 00 00 00 00  |.T..............|


0000: 01 00 00 68 ; Jump $0068

0004: 01 00 00 54 ; Jump $0054

0008: 01 00 00 40 ; Jump $0040

000C: 06 00 00 02 ; SP := SP + 2
0010: 07 02 00 04 ; Push integer "0004"
0014: 27 00 00 08 ; Pop L
0018: 26 03 00 08 ; Push I
001C: 2E 02 06 01 ; Write integer
0020: 26 02 00 08 ; Push J
0024: 2E 02 06 01 ; Write integer
0028: 26 01 00 08 ; Push K
002C: 2E 02 06 01 ; Write integer
0030: 26 00 00 08 ; Push L
0034: 2E 02 06 01 ; Write integer
0038: 1C 02 00 00 ; Writeln
003C: 05 00 00 00 ; Return

0040: 06 00 00 02 ; SP := SP + 2
0044: 07 02 00 03 ; Push integer "0003"
0048: 27 00 00 08 ; Pop K
004C: 04 80 00 0C ; Call DEEPEST
0050: 05 00 00 00 ; Return

0054: 06 00 00 02 ; SP := SP + 2
0058: 07 02 00 02 ; Push integer "0002"
005C: 27 00 00 08 ; Pop J
0060: 04 80 00 40 ; Call DEEPER
0064: 05 00 00 00 ; Return

0068: 06 00 00 08 ; SP := SP + 8
006C: 07 02 00 01 ; Push integer "0001"
0070: 27 00 00 08 ; Pop I
0074: 04 80 00 54 ; Call DEEP
0078: 00 00 00 00 ; Halt
P-code instructions are a multiple of four bytes; all except for pushing a constant string are only four bytes.

The first byte is an opcode identifying the instruction. The second byte often serves as a "mode" indicator to allow for variations of an operation or for multiple operations to share an opcode. The third and fourth bytes are extra information.

From the posted test program, the second byte of a push variable instruction appears to be the procedure nesting level. The "main program" is treated as just another enveloping procedure, so there are no physical global variables. The logical global variables of a program are allocated in the activation record of the main program. This is what the SP := SP + 6 (or more) instruction which starts every program allocates.


In the meantime, other P-code instructions may be exercised solely by pushing constants onto the stack and operating on them. About a half of the instructions have been done. The dispatch table now looks like this:

Code: Select all

 2B33                     02211 Instructions
 2B33 2AAB                02212          fdb    I_Halt    ; $00
 2B35 2AD2                02213          fdb    I_Jump    ; $01
 2B37 2AE5                02214          fdb    I_IfFalse ; $02
 2B39 2BB3                02215          fdb    Unimplemented ; $03
 2B3B 2BB3                02216          fdb    Unimplemented ; $04
 2B3D 2BB3                02217          fdb    Unimplemented ; $05
 2B3F 2E8A                02218          fdb    I_ManageStack ; $06
 2B41 2EC7                02219          fdb    I_PushConstant ; $07
 2B43 2BB3                02220          fdb    Unimplemented ; $08
 2B45 2F20                02221          fdb    I_IfNotAndOr ; $09
 2B47 2BB3                02222          fdb    Unimplemented ; $0A
 2B49 2BB3                02223          fdb    Unimplemented ; $0B
 2B4B 2BB3                02224          fdb    Unimplemented ; $0C
 2B4D 2BB3                02225          fdb    Unimplemented ; $0D
 2B4F 2BB3                02226          fdb    Unimplemented ; $0E
 2B51 2BB3                02227          fdb    Unimplemented ; $0F
 2B53 2F4A                02228          fdb    I_CompareBytesForEQ ; $10
 2B55 2F78                02229          fdb    I_CompareBytesForNE ; $11
 2B57 2BB3                02230          fdb    Unimplemented ; $12
 2B59 2BB3                02231          fdb    Unimplemented ; $13
 2B5B 2BB3                02232          fdb    Unimplemented ; $14
 2B5D 2BB3                02233          fdb    Unimplemented ; $15
 2B5F 2BB3                02234          fdb    Unimplemented ; $16
 2B61 2BB3                02235          fdb    Unimplemented ; $17
 2B63 2BB3                02236          fdb    Unimplemented ; $18
 2B65 2F91                02237          fdb    I_ConvertIntegerToByte ; $19
 2B67 2FCD                02238          fdb    I_Convert ; $1A
 2B69 2BB3                02239          fdb    Unimplemented ; $1B
 2B6B 3010                02240          fdb    I_Writeln ; $1C
 2B6D 301D                02241          fdb    I_Readln  ; $1D
 2B6F 3073                02242          fdb    I_WriteString ; $1E
 2B71 2BB3                02243          fdb    Unimplemented ; $1F
 2B73 310B                02244          fdb    I_CompareIntegersForEQ ; $20
 2B75 312E                02245          fdb    I_CompareIntegersForNE ; $21
 2B77 313C                02246          fdb    I_CompareIntegersForLT ; $22
 2B79 315A                02247          fdb    I_CompareIntegersForGT ; $23
 2B7B 317B                02248          fdb    I_CompareIntegersForLE ; $24
 2B7D 319C                02249          fdb    I_CompareIntegersForGE ; $25
 2B7F 2BB3                02250          fdb    Unimplemented ; $26
 2B81 2BB3                02251          fdb    Unimplemented ; $27
 2B83 2BB3                02252          fdb    Unimplemented ; $28
 2B85 2BB3                02253          fdb    Unimplemented ; $29
 2B87 2BB3                02254          fdb    Unimplemented ; $2A
 2B89 2BB3                02255          fdb    Unimplemented ; $2B
 2B8B 2BB3                02256          fdb    Unimplemented ; $2C
 2B8D 2BB3                02257          fdb    Unimplemented ; $2D
 2B8F 31BB                02258          fdb    I_WriteInteger ; $2E
 2B91 2BB3                02259          fdb    Unimplemented ; $2F
 2B93 2BB3                02260          fdb    Unimplemented ; $30
 2B95 2BB3                02261          fdb    Unimplemented ; $31
 2B97 32EB                02262          fdb    I_CreateAddMemberToSet ; $32
 2B99 3334                02263          fdb    I_SetOperations ; $33
 2B9B 3373                02264          fdb    I_DetermineSetMembership ; $34
 2B9D 33AB                02265          fdb    I_CompareSets ; $35
 2B9F 33F8                02266          fdb    I_CompareAlfaForEQ ; $36
 2BA1 3412                02267          fdb    I_CompareAlfaForNE ; $37
 2BA3 3421                02268          fdb    I_CompareAlfaForLT ; $38
 2BA5 3440                02269          fdb    I_CompareAlfaForGT ; $39
 2BA7 3460                02270          fdb    I_CompareAlfaForLE ; $3A
 2BA9 347F                02271          fdb    I_CompareAlfaForGE ; $3B
 2BAB 2BB3                02272          fdb    Unimplemented ; $3C
 2BAD 2BB3                02273          fdb    Unimplemented ; $3D
 2BAF 2BB3                02274          fdb    Unimplemented ; $3E
 2BB1 2BB3                02275          fdb    Unimplemented ; $3F

Re: LUCIDATA Pascal for 6502

Posted: Sun Oct 31, 2021 12:57 pm
by BillG
After many tricks, I finally get a treat. This program runs:

Code: Select all

PROGRAM TEST;

  VAR
    C : CHAR;
    I : INTEGER;

  BEGIN
    WRITE("Enter a character ");
    READLN(C);
    WRITELN;
    WRITELN("'",C,"'");
    REPEAT
      WRITE("Enter an integer (0 or <CR> to quit) ");
      READLN(I);
      WRITELN(I)
    UNTIL I = 0
  END.
Access to variables work within the current activation record, in this case, program global variables.

The big pieces of functionality still left to do include:

* arrays
* add, subtract, multiply, divide
* subroutine call and return
* files on disk
* paged mode

The last one is not needed to try running the compiler.

Re: LUCIDATA Pascal for 6502

Posted: Sun Oct 31, 2021 5:59 pm
by Sean
BillG wrote:
After many tricks, I finally get a treat. This program runs:
Congratulations on your progress. That's an important milestone.