Page 5 of 6

Re: EJC (C-Compiler) experiments

Posted: Tue Jul 07, 2020 4:42 pm
by ql_freak
@NormanDunbar:

I know, but in this case this shouldn't be dangerous, cause the input is read from a CON-channel which normally does not have a buffer length > 256 charcters. Of course if it is used with redirection (<)... DON'T DO IT!

@Peter:

I have now looked at PDQC and I'm afraid you are wrong. But this would be offtopic in this thread about EJC, so I have created a new thread "Development Systems and Created Code (reentrant, ROMable, ...)", where I will elaborate on that.

Re: EJC (C-Compiler) experiments

Posted: Tue Jul 07, 2020 8:31 pm
by NormanDunbar
ql_freak wrote:@NormanDunbar:
I know, but in this case this shouldn't be dangerous, cause the input is read from a CON-channel which normally does not have a buffer length > 256 charcters. Of course if it is used with redirection (<)... DON'T DO IT!
:D

So, now we need to build in a check on startup, that stdin is a con channel. If the application allows something to happen, someone will do it. I've seen too many "nobody would be silly enough to do that" problems in my working life.


Cheers,
Norm.

Re: EJC (C-Compiler) experiments

Posted: Thu Jul 09, 2020 1:16 am
by ql_freak
I'm now nearly sure, that Erling has patched the Lattice Compiler, so that it supports the TK2 default directories, at least for the source file name. Cause if I execute phase 1 directly with e.g.:

Code: Select all

ex'QLC_1';'=8192 %81920 >RAM1_QLC1_err_txt -b -ccu -dregister -dQDOS=1 -n  scalc''
the compiler creates scalc_q (_q is the output of the first compiler phase). The original Lattice C compiler from MCDK doesn't know anything about TK2 default directories. At the time MCDK was released TK2 didn't even exist, just the Toolkit 1 existed. Albeit it already had default directories (PROG_USE and DATA_USE only), it wasn't very common AND could not be used on an unexpanded QL when compiling C programs, due to memory requirements of the Lattice Compiler, which even had to use part of the screen memory (part of screen was destroyed!) to be able to run.

Another problem. EJC.txt says the compiler AND the program which shall be compiled must be in DATAD$ (1), which is uncomfortable. At the time EJC was developed, there was no PTH device (thank you Phil Borman!). So I tried to set DATAD§ to my C source directory and added the EJC directory to the Path (PTH_ADD 1,'WIN1_bin_ejc_':REMark because of a bug in PTH_ADD, 0 is not possible). When I now call my ecc (or the original cc) the error listing is not output (because the listing file is not written), albeit QLC_1 gets the same command line as as the above direct execution of QLC_1. Strange.

It must have something to do with the function pipeline(), which is used in EJC to start executable programs. BTW, my approach would not work, because the compiler doesn't find the standard header files. In original MCDK you could not use e.g. #include <stdio_h>, you MUST use (e.g.) #include <FLP1_stdio_h>.

I think I must extend my ecc. I will have a look to the C68 sources how to access the environment variables (which also don't exist, when EJC was developed). Than I will change the compiler driver so that the (base) source directory may be specified via an environment variable.

BTW: Does anyone have the sources of the cc compiler driver of PDQC? Then I would try, if it's possible to use the newer Lattice Compiler (via the TOS emulator) with the EJC libs. But I don't know how to call the Lattice compiler phases of PDQD (phase 1 and 2 are no executable files). I assume they must be started via "pdqc", which I assume is the TOS emulator needed to run the Atari ST version of the Lattice compiler.
--
1) Albeit I have found it's possible to pass an absolute filename to cc/ecc (e.g. WIN1_home_hps_c_scalc).

Re: EJC (C-Compiler) experiments

Posted: Thu Jul 09, 2020 2:51 am
by ql_freak
YEAH! I have found out, how to start the Lattice C compiler from PDQC from SuperBASIC:

Code: Select all

OPEN#3,"CON_512x256a0x0_256"
ex"WIN1_bin_pdqc_pdqc'",#3,#3,#3;"WIN1_bin_pdqc_p1"
Prints to #3:

Lattice 68000 C Compiler (Phase 1) V3.04
Copyright ...
File name missing

S E R I O U S W A R N I N G : If you start it with ex'WIN1_...",#3;"..." the channel (#3) will be closed! So don't do it witch channels #0 to #2 inclusive.

:-)))

Re: EJC (C-Compiler) experiments

Posted: Fri Jul 10, 2020 1:03 am
by ql_freak
Yippie! I have compiled the "simplecalc" (for the experiment called scalc) with the Lattice compiler (plus TOS emulator) from PDQC with EJC.

I have compiled it with direct calls via the TOS emulator "pdqc" from PDQC for phase 1 and 2:

Code: Select all

ex 'WIN1_bin_pdqc_pdqc' , #3 , #3 , #3 ; 'WIN1_bin_pdqc_p1 scalc'
ex 'WIN1_bin_pdqc_pdqc' , #3 , #3 , #3 ; 'WIN1_bin_pdqc_p2 scalc'
Then I have got an scalc_o file. Then I entered:

ex'cc' ; 'cc WIN1_home_hps_c_scalc' and got:

Code: Select all

WSTAT 'WIN1_home_hps_c_scalc'
...
home_hps_c_SCALC
	20716  2020 Jul 10 01:42:03
So it sems to be possible to use the Atari ST Lattice C compiler from PDQC with the EJC libraries :-)))

The Atari Lattice (V3.04) seems to support some newer features like const, which the QL Lattice (V3.01) does not :-)

Re: EJC (C-Compiler) experiments

Posted: Fri Jul 10, 2020 1:04 am
by ql_freak
ql_freak wrote:Yippie! I have compiled the "simplecalc" (for the experiment called scalc) with the Lattice compiler (plus TOS emulator) from PDQC with EJC.

I have compiled it with direct calls via the TOS emulator "pdqc" from PDQC for phase 1 and 2:

Code: Select all

ex 'WIN1_bin_pdqc_pdqc' , #3 , #3 , #3 ; 'WIN1_bin_pdqc_p1 scalc'
ex 'WIN1_bin_pdqc_pdqc' , #3 , #3 , #3 ; 'WIN1_bin_pdqc_p2 scalc'
Then I have got an scalc_o file. Then I entered:

ex'cc' ; 'cc WIN1_home_hps_c_scalc' and got:

Code: Select all

WSTAT 'WIN1_home_hps_c_scalc'
...
home_hps_c_SCALC
	20716  2020 Jul 10 01:42:03
So it sems to be possible to use the Atari ST Lattice C compiler from PDQC with the EJC libraries :-)))

The Atari Lattice (V3.04) seems to support some newer features like const, which the QL Lattice (V3.01) does not :-)
Shit, again so late. I think I have to go to bed now immediatly...

Re: EJC (C-Compiler) experiments

Posted: Sat Jul 18, 2020 8:39 pm
by ql_freak
I have now found this interessting site:

http://www.atarimania.com/utility-atari-st-lattice-c_32417.html

From there you can download three files which seem to be Atari ST single sided disk images:

lattice_c_3_04_01_metacombo_a.ST, lattice_c_3_04_01_metacombo_b.ST, lattice_c_3_04_01_metacombo_c.ST

I assume they hold the Metacomco Lattice C Development Kit for the Atari ST :-))) I currently don't know how to extract these images to a floppy or extract the files from it (only compiler phase 1 and 2 are required to use it with PDQC). PDQC itself is free, except phase 1 and 2 of the compiler.

Code: Select all

D O E S   A N Y O N E   K N O W   H O W   TO   M A K E   A   F L O P P Y   F R O M   T H E S E   D i S K   I m a g e s, or how to access the files from these images?
I have now a version of the EJC compiler driver (I have named it lcc) which is working with p1 and p2 of PDQC. Unfortunately the compiler seems to produce wrong code :-( The produced executable has exactly the same size and is nearly the same as the code produced with the Lattice C compiler delivered with EJC (i. e. the Lattice C V3.01 delivered with Metacomco C Development Kit). For my hello world program the exception (at offset $08d0(bp)) is:

Code: Select all

QL-Lattice                            Atari-Lattice
08D0(bp) 486D8026   pea $8026(a5) <-> 08D0(bp) 486D9CB8   pea $9CB8(a5)
08D4(bp) 4EBA0014   jsr $08EA(bp)     08D4(bp) 4EBA0014   jsr $08EA(bp)
08D8(bp) 588F       addq.l #04,a7     08D8(bp) 588F       addq.l #04,a7
08DA(bp) 486D81C8   pea $81c8(a5) <-> 08DA(bp) 486D9E5A   pea $9E5A(a5)
08DE(bp) 4EBA06AC   jsr $0F8C(bp)     08DE(bp) 4EBA06AC   jsr $0F8C(bp)
If I start hello compiled with Atari-Lattice nothing happens (but I assume, it can crash the QL, cause memory is overwritten). If I enter (in Computer1 Monitor):

Code: Select all

du 9cb8(a5)
I get a different result, than with

Code: Select all

du 8026(a5)
in the QL-Lattice version, but if I use the latter on the Atari-Lattice version I get the same result as with the Lattice compiler from EJC. So it seems the 2 pea instructions created from Atari Lattice are wrong :-(

They are definitely wrong :- I have now debugged the program with C1Mon and poked at 08D0 and 08DA the values from the version created with QL-Lattice C and then the program runs.The first jsr (after pea) prints out "Hello world" and the second is the input with:

c = getchar()

so that the window does not disappear.

Re: EJC (C-Compiler) experiments

Posted: Mon Jul 20, 2020 11:18 pm
by ql_freak
Good news:

I have now succeeded in creating an Atari ST disk from the floppy image files for the Atari Metacomco C (with Lattice C Compiler).

Bad news:

It's exactly the same as the one delivered with PDQC (which has IMHO a bug, see my previous message). So it seems it can unfortunately not be used with EJC, which would be a big improvement, cause the Atari Lattice C e.g. supports an -i switch (up to 9 -i) to pass directories for the include files.

Download Links:

Atari ST Metacomco C with Lattice C V3.04.01

Description with links for software how to create a disk from Atari ST disk image files (.ST files) on a PC (unfortunately a real floppy disk, not USB and ideally an DOS operating system is required).

EJC without the (QL) Lattice C Compiler (Note currently this version is missing the adapted lcc compiler driver compatible with the Atari Lattice C compiler).

Last but not least (thank you Dilwyn): PDQC-Manual

If anyone is interested in PDQC I can upload it without the compiler phases p1 and p2 on my homepage. In the Atari Metacomco C these files are on Disk 1 in directory "COMMANDS" and are named LC1.TTP and LC2.TTP. The Atari Disk (create it with MAKEDISK.EXE on the PC) can be read with QPC2 – well done Marcel :-)

Re: EJC (C-Compiler) experiments

Posted: Fri Jul 24, 2020 12:17 am
by ql_freak
As I dunno, how I can get the Atari ST Lattice C compiler to work (CORRECTLY) with EJC, I'm now trying to use EJC with the QL Lattice C. First thing, cause it's very usefull, is to use the <ansi.h> header file from C68 (and also PDQC) - NOTE: This seems to be NO standard C header(!). At least it seems to be compatible with EJC (no compiler errors when it is included). But it doesn't work as expected. With "#if (LATTICE == 1)" the output is "hello world" and not "hello ANSI":

Code: Select all

#include <ansi.h>
#include <stdio.h>

int main() {
    int c; /* character to get for the last getchar(), so that window doesn't close */

/* NOTE: Only one of the next 3 lines is allowed to be real code, the other two lines MUST be commented: */
/* #ifdef COMPILER */ /* This is OK */
#if (COMPILER == QLC) /* This is OK */
/* #if (LATTICE == 1) */ /* This is NOT - WHY??? */

    printf("hello ANSI\n");

#else

    printf("hello world\n");

#endif

    c = getchar();
    return 0;
}
This is <ansi.h>:

Code: Select all

/* The <ansi.h> header checks whether the compiler claims conformance to ANSI
 * Standard C. If so, the symbol _ANSI is defined as 1, otherwise it is 
 * defined as 0.  Based on the result, a macro
 *
 *  _PROTOTYPE(function, params)
 *
 * is defined.  This macro expands in different ways, generating either
 * ANSI Standard C prototypes or old-style K&R (Kernighan & Ritchie) 
 * prototypes, as needed.  Finally, some programs use _CONST, _VOIDSTAR etc
 * in such a way that they are portable over both ANSI and K&R compilers.
 * The appropriate macros are defined here.
 */

#ifndef _ANSI_H
#define _ANSI_H

/* ANSI C requires __STDC__ to be defined as 1 for an ANSI C compiler.
 * Some half-ANSI compilers define it as 0.  Get around this here.
 */

#define _ANSI              0    /* 0 if compiler is not ANSI C, 1 if it is */

/*
 *  Try and determine the compiler being used
 */
#ifdef TOS
#define COMPILER    PDQC
#define LATTICE     1
#define __STDC__    0
#else
#ifdef QDOS
#if (COMPILER == C68)
#define C68         1
#else
#ifdef CPM68
#define COMPILER    QLC
#define LATTICE     1
#define __STDC__    0
#endif /* CPM68 */
#endif /* C68 */
#endif /* QDOS */
#endif /* TOS */
#ifndef QDOS
#define QDOS    1
#endif
#ifndef COMPILER
#define COMPILER    UNKNOWN
#endif

#ifdef __STDC__         /* __STDC__ defined for (near) ANSI compilers*/
#if __STDC__ == 1       /* __STDC__ == 1 for conformant compilers */
#undef _ANSI            /* get rid of above definition */
#define _ANSI   1       /* _ANSI = 1 for ANSI C compilers */
#endif
#endif

/* At this point, _ANSI has been set correctly to 0 or 1. Define the
 * _PROTOTYPE macro to either expand both of its arguments (ANSI prototypes),
 * only the function name (K&R prototypes).
 */

#if _ANSI || LATTICE
#define _PROTOTYPE(function, params)    function params
#define _VOIDSTAR   void *
#define _VOID       void
#define _CONST      const
#define _VOLATILE   volatile
#define _SIZET      size_t

#else

#define _PROTOTYPE(function, params)    function()
#define _VOIDSTAR   void *
#define _VOID       void
#define _CONST
#define _VOLATILE
#define _SIZET      int

#endif /* _ANSI */

#endif /* ANSI_H */
I do not understand why the "#if (LATTICE == 1)" does not work (I've tried also #if LATTICE, ...)

Help needed.

p.s: My SuperBASIC "Helper" program for using EJC for QPC2 (resolution 1280x1024):

Code: Select all

1000 : REMark [hps] Support procedures, functions, strings, ... for working with EJC
1002 REMark W A R N I N G :  Runs only on QPC2
1010 OPEN#3,'CON_512x482a50x308':REMark BIG CON channel, e.g. for listing
1020 PAPER#3,7:INK#3,0:REMark Black ink on white paper
1060 :
1100 DEFine PROCedure ecc(cmd$):EX'ecc',#3,#3,#3;'ecc '&cmd$:END DEFine
1200 :
1240 DEFine FuNction qlc1:RETurn 'QLC_1':END DEFine :REMark Phase 1 of Lattice C
1280 DEFine FuNction qlc2:RETurn 'QLC_2':END DEFine :REMark Phase 2 of Lattice C
1320 DEFine FuNction cc:RETurn 'cc':END DEFine :REMark Original cc for EJC
1360 REMark DEFine FuNction ecc:RETurn 'ecc':END DEFine :REMark hps "cc" for EJC
1400 DEFine PROCedure clsA:CLS:END DEFine
1440 DEFine PROCedure clsB:CLS#2:END DEFine
1480 DEFine PROCedure clsC:CLS#3:END DEFine
1520 DEFine PROCedure con3:OPEN#3,'CON_512x462a50x308':clsC:END DEFine
1560 DEFine PROCedure p1(c$):EX'pdqc',#3,#3,#3;'p1 '&c$:END DEFine
1600 DEFine PROCedure lc1(c$)
1620   EX'qlc_1';'>RAM1_err_txt '&c$:VIEW#3,'RAM1_err_txt'
1640 END DEFine
1680 DEFine PROCedure ecc(c$):EX'ecc',#3,#3,#3;'ecc '&c$:END DEFine
1920 :
1998 :
2000 DEFine PROCedure clsch: REMark Clear channels #1, #2 and #3
2040   CLS#1:CLS#2:CLS#3
2080 END DEFine
2120 :
2160 DEFine PROCedure lcc(cmd$):EX'lcc',#3,#3,#3;'p1 '&cmd$:END DEFine
9900 :
9917 GO TO 9999:REMark STOP (exit) the program
9920 :
9960 :
9999 STOP

Re: EJC (C-Compiler) experiments

Posted: Tue Aug 11, 2020 11:48 pm
by ql_freak
IF ALL ELSE FAILS, READ THE MANUAL!

Shame on YOU! No one answered me, that C68 is capable of creating reentrant code:

C-Source:

Code: Select all

#include<stdio.h>

char hello_world[] = "hello world";

int main() {
	hello_world[0] = 'H';
	printf(hello_world);
}
The assembler (..._s) output from C68:

Code: Select all

! Generated by c68 4.5 (31/10/98) 31 Oct 98 (Nov  8 1998) from "WIN1_jasc_include_stdio_h"
	.sect	.text
	.sect	.rom
	.sect	.data
	.sect	.bss
	.sect	.data
	.extern _hello_world
_hello_world:
	.ascii	"hello world"
	.data1	0x0
	.sect	.text
	.align	2
	.extern _main
_main:
	bra	I_1
I_2:
	move.b	#72,_hello_world-.Xdata(a5)
	pea	_hello_world-.Xdata(a5)
I_3:
	jsr	_printf-I_3+2(pc)
	unlk	a6
	rts
I_1:
	link	a6,#0
	bra	I_2
	.sect	.data
This looks very exciting!

Unfortunately until now I have not (yet?) succeeded to link the produced object code from as68 with the EJC-Library and startup code (but this is IMHO just a problem of the cc or my ecc compiler driver). But at least the source code for C68 is available :-)