LCC for the Gigatron. Take two.

Using, learning, programming and modding the Gigatron and anything related.
Forum rules
Be nice. No drama.
lb3361
Posts: 235
Joined: 17 Feb 2021, 23:07

Re: LCC for the Gigatron. Take two.

Post by lb3361 »

veekoo wrote: 10 Oct 2022, 12:27 Am I running out of memory? No warnings here when compiling. I am using two dimensional array size of 38kb. I have 64k machine.

The sm array in your program is a local variable. Such variables are allocated on the stack. They are also uninitialized, and this explains why the first program did not work. You could simply make it static to allocate it in the data segment. But if you do so, the compiler is going to complain that there is no space to allocate a contiguous array of 38kb. A simple fix would be to make it an array of chars instead of ints. Another fix would be to make it a bitmap: See the _bitset_xxx() functions of the glcc c library. Declarations in <gigatron/libc.h>, implementation at https://github.com/lb3361/gigatron-lcc/ ... /_bitset.c

The stack is not checked: it can grow over the data or even the program. Checking would be far too expensive. You can use option --frags to know where program and data live. The malloc heap and the stack then share the rest. If you do not use malloc, the --frags option tells you what you have. If you use malloc, the map file still reserves a little bit of space for he stack. For --map=64, the stack grows downwards from 0xfffc and space is reserved until 0xfc00. The last scanline of the screen memory is at 0x7f00-0x7f9f. That leaves a maximum of 32860 bytes for the stack. For map=-32k, do not expect the stack to have more than 256 bytes!

The map files define all this. For instance the 64k map, https://github.com/lb3361/gigatron-lcc/ ... 64k/map.py, defines all the usable segments with

Code: Select all

# ------------size----addr----step----end---- flags (1=nocode, 2=nodata, 4=noheap)
segments = [ (0x0060, 0x08a0, 0x0100, 0x80a0, 0),
             (0x00fa, 0x0200, 0x0100, 0x0500, 0),
             (0x0200, 0x0500, None,   None,   0),
             (0x0100, 0x8100, None,   None,   0),
             (0x79c0, 0x8240, None,   None,   0)   ]

initsp = 0xfffc
Each row describes one or more segments. For instance the first row defines segments of length 0x60 starting at 0x8a0 and repeating every 0x100 bytes : 0x9a0, 0xaa0, ... until 0x80a0 excluded. These are the holes in the screen memory. The flags indicate what the segment is (not) suitable for. The linker first allocate code fragments, then allocate data fragments, and finally construct the list of segments usable by malloc. You can see that the last segment ends at 0x8240+0x79c0=0xfc00. The following line defines the initial stack pointer. The stack grows downwards. Therefore it can extend from 0xfffc to 0xfc00 without overwriting code or data. Code and data segments may be allocated below 0xfc00. Problems can be expected...
veekoo
Posts: 86
Joined: 07 Jun 2021, 07:07

Re: LCC for the Gigatron. Take two.

Post by veekoo »

Followed your advice and now its drawing ok. I am suprised how 32k machine can hold some games if there is so little memory left.
Screenshot from 2022-10-11 23-49-15.png
Screenshot from 2022-10-11 23-49-15.png (121.73 KiB) Viewed 306 times
lb3361
Posts: 235
Joined: 17 Feb 2021, 23:07

Re: LCC for the Gigatron. Take two.

Post by lb3361 »

veekoo wrote: 12 Oct 2022, 06:54 I am suprised how 32k machine can hold some games if there is so little memory left.

Invaders and pucmon fit in a 32k gigatron because at67 spent a lot of time on them! Even though the main loop is written in basic, a lot of the work (graphics, music) is done by carefully hand coded routines. He must also have spent a lot of time minimizing the associated data (sprites, soundtracks). Every byte counts!

A good trick is to steal a couple scanlines from the screen in parts that remain black or can be shared. This works a bit like -map=conx but has to be customized for the specific screen layout of the game. One can steal a few kb this way...
lb3361
Posts: 235
Joined: 17 Feb 2021, 23:07

Re: LCC for the Gigatron. Take two.

Post by lb3361 »

I just added a test to catch functions that take unrealistic amounts of stack.

Code: Select all

$ glcc -map=64k rndbrot.c -o rndbrot.gt1
rndbrot.c:93: main() framesize (38462) too large for a gigatron
rndbrot.c:93: 1 error(s)
Framesizes greater than 32k cause this error, because we can be certain that this will never work. Although much smaller framesizes can cause problems, this coarse test can catch some cases. The linker could catch more cases because it knows the size of the dedicated stack space. However this is too pessimistic because the ordering of the segment lists in map files ensures that the space threatened by the stack is used last when allocating code or data fragments. The malloc library routine does the same in fact. For instance, the main function in rndbrot.c could allocate an array 'char sm[HEIGHT][WIDTH]` on the stack (19K) and things would work. But 38K was definitely more than the Gigatron can handle in even the most optimistic scenario.
veekoo
Posts: 86
Joined: 07 Jun 2021, 07:07

Re: LCC for the Gigatron. Take two.

Post by veekoo »

I took the latest glcc and I always try after make to do make test. Now it seems to stop in rom v4 tests. It hangs up at this line.
My enviroment is linux ubuntu 22.04.1 LTS. 2 processors and 4gb memory in virtual.
Allthough the test stops, but every compiled program works.

Could this be problem in glcc program or my enviroment?

Code: Select all

cmp build/tst/struct.xx1 gigatron/tst/struct.1bk
build/glcc -map=sim,allout -rom=v4 -o build/tst/switch.gt1 tst/switch.c 2>"build/tst/switch.xx2"
lb3361
Posts: 235
Joined: 17 Feb 2021, 23:07

Re: LCC for the Gigatron. Take two.

Post by lb3361 »

veekoo wrote: 14 Oct 2022, 07:43 I took the latest glcc and I always try after make to do make test. Now it seems to stop in rom v4 tests. It hangs up at this line.
What a nasty bug!

Basically the code has a _LDI(datalabel-constant) which is an instruction that either uses LDI or LDWI depending on its argument. But in this case, the constant was close to the attempted location of 'datalabel' resulting in using LDI. This in turned made the routine smaller allowing the compiler to move the fragment containing `datalabel' just after the routine. But in the process, the expression datalabel-constant no longer fits in a byte. We're back to using LDWI, resulting in relocating the data fragment where it was, allowing the use of LDI, and looping forever. The fix is to let the compiler decide whether to use LDI or LDWI based on static analysis (type of the argument, known zero page pointer, etc) instead of relying on the actual value defined during relaxation.

Thanks for finding this.
veekoo
Posts: 86
Joined: 07 Jun 2021, 07:07

Re: LCC for the Gigatron. Take two.

Post by veekoo »

Question about screen modes.

Default mode draws 3/4 of the lines
Half mode draws 2/4 of the line
Quarter mode draws 1/4 of the lines and is the fastest (btw. blank screen is very fast?)
Full mode 4/4 of the lines and is the slowest

Drawing something like the fractals, I use quarter mode while calculating. When it's finished, I switch to full mode.

I do this by pressing the key, but question is: Is there a command in glcc to do this change?
lb3361
Posts: 235
Joined: 17 Feb 2021, 23:07

Re: LCC for the Gigatron. Take two.

Post by lb3361 »

SYS_SetMode(int) is a wrapper for the eponymous SYS call. Declaration is at https://github.com/lb3361/gigatron-lcc/ ... sys.h#L138. The SYS call itself is documented at https://github.com/kervinck/gigatron-ro ... m.py#L2840

Another interesting tool to control the video generation is the variable videoTop_v5 at location 0x1f9. It should always contain an even number which is twice the number of pixel rows that should be be left black at the top of the screen and made fully available for the vCPU. This is safer than using the magic SetMode(1975) because it still does other important stuff (music, blinkenlights, keyboard reset, etc.)
veekoo
Posts: 86
Joined: 07 Jun 2021, 07:07

Re: LCC for the Gigatron. Take two.

Post by veekoo »

Thanks for info. I tested zoomed in version of burning ship. Previously it took 1 hour to draw the screen, but with zombie mode it managed to do it in 33 minutes. That was only for testing it and I don't plan to use it in future.
at67
Posts: 501
Joined: 14 May 2018, 08:29

Re: LCC for the Gigatron. Take two.

Post by at67 »

lb3361 wrote: 19 Oct 2022, 17:58 Another interesting tool to control the video generation is the variable videoTop_v5 at location 0x1f9. It should always contain an even number which is twice the number of pixel rows that should be be left black at the top of the screen and made fully available for the vCPU. This is safer than using the magic SetMode(1975) because it still does other important stuff (music, blinkenlights, keyboard reset, etc.)
It is an excellent tool in gaining more vCPU time for your application, the only real issue with it is that the final output of the mixed 4 channel audio samples is never output to XOUT during the blanked scanlines. So depending on your application, how much audio it uses and how many scanlines you blank, some audio distortion will invariably be introduced.

This is currently an issue from ROMv5 and DEVROM.
Post Reply