Gigatron 512k and more
Forum rules
Be nice. No drama.
Be nice. No drama.
Re: Gigatron 512k and more
Great project!
I'd like to understand more about this since if I go for the 100 Mhz Gigatron project, I don't want to create conflicting standards. I'd like to know how banking works, for instance, and how others are going past 64K. I'd love to incorporate something like this.
On my snooper idea, I considered snooping all the time and letting the FPGA or whatever evaluate what is coming in and work rather asynchronously.
And it seems like you could snoop the sound/lights too and remove that code from ROM.
I'd like to understand more about this since if I go for the 100 Mhz Gigatron project, I don't want to create conflicting standards. I'd like to know how banking works, for instance, and how others are going past 64K. I'd love to incorporate something like this.
On my snooper idea, I considered snooping all the time and letting the FPGA or whatever evaluate what is coming in and work rather asynchronously.
And it seems like you could snoop the sound/lights too and remove that code from ROM.
Re: Gigatron 512k and more
His Github writeups seem like a good place to start.
Re: Gigatron 512k and more
The repository is at https://github.com/lb3361/gigatron-lb/t ... sion-crazy (attention, special branch).Sugarplum wrote: ↑21 Jan 2022, 06:35 I'd like to understand more about this since if I go for the 100 Mhz Gigatron project, I don't want to create conflicting standards. I'd like to know how banking works, for instance, and how others are going past 64K. I'd love to incorporate something like this.
On my snooper idea, I considered snooping all the time and letting the FPGA or whatever evaluate what is coming in and work rather asynchronously.
And it seems like you could snoop the sound/lights too and remove that code from ROM.
One of my goals was to have something that still works with the normal rom but gives additional benefits from a patched one.
Therefore the Gigatron is still doing all the timing. It just does not have to send the pixels (but no harm if it does).
Warning: I have to change the banking scheme because of https://forum.gigatron.io/viewtopic.php?p=2838#p2838
Re: Gigatron 512k and more
The application I propose such functionality for would be a custom near-Gigatron that would require a ROM rewrite from the start. Since the LUT-based CU would replace the useless/redundant instructions (59+) and the LUT-based ALU could provide more operations, the ROM would need to be rewritten to use those to gain any benefits. If you have more registers, shifting, multiplication, etc., one should use them. So there would be 2 ways to go. One would be to bit-bang much like now and more tightly interleave the vCPU. That could be an option. The other is to go the snooping route even then. The goal wouldn't be so much speed as it would be to add flexibility and features. A video "chip" could add things like text mode. So all you do is send it ASCII and let the controller convert that.lb3361 wrote: ↑21 Jan 2022, 12:13 The repository is at https://github.com/lb3361/gigatron-lb/t ... sion-crazy (attention, special branch).
One of my goals was to have something that still works with the normal ROM but gives additional benefits from a patched one.
Therefore the Gigatron is still doing all the timing. It just does not have to send the pixels (but no harm if it does).
Warning: I have to change the banking scheme because of https://forum.gigatron.io/viewtopic.php?p=2838#p2838
The nice part about sending character set codes is that one could include more drawing characters and you can use multiple character sets. And with the drawing characters, one could have a text mode that includes the best drawing and other characters of all the retro machines, such as Atari, Commodore, and the original PC, giving more flexibility in text-only games and games that use characters as graphics (like much of the C64 games).
So like I posted in the other thread, it would probably be wise to make a Hackaday page for this.
Re: Gigatron 512k and more
Awesome project, so much potential, will take a while to digest.
My midi code doesn't know or understand what it is playing on the sound channels, so if you setup emulation or hardware properly, it will playback 6bit or 8bit audio just fine, (four 6bit channels mix into 8bit samples).
Just change the channel samples to 6bit Sinusoids, either programmatically or using the audio editor built into my editor, with a modified ROM you'll hear the difference between 4bit and 6bit, both in emulation and on real hardware. https://forum.gigatron.io/viewtopic.php ... 8&start=30lb3361 wrote: ↑17 Jan 2022, 20:24 [*] There is already support for a pulse modulation output that can provide 6 bits audio https://github.com/lb3361/gigatron-lb/t ... gs/pwmtest. This cannot be as good as a dedicated DAC with a well controlled power plane, but it comes for free. Hans61 has already carried out some tests. It is not obvious to find a sound program that actually makes use of the six available bits. At67's midi code is optimized for 4 bit outputs. His expertise would be invaluable.
My midi code doesn't know or understand what it is playing on the sound channels, so if you setup emulation or hardware properly, it will playback 6bit or 8bit audio just fine, (four 6bit channels mix into 8bit samples).
Re: Gigatron 512k and more
New native instructions
I did not realize this was possible until a couple day ago when I finally found the time to fix my flawed extended memory banking scheme (see https://forum.gigatron.io/viewtopic.php?p=2838#p2838). This fix required lots of changes: the extended ctrl codes, the verilog, the rom, the demo programs, and even the compiler which gained support to place vCPU routines in specific memory ranges, which can be useful when one swap memory banks. Then I realized that when a ctrl instruction is executing --which I know because the SRAM signals /OE and /WE are both low--, I can also see the value of the AC register on the ALU pins of the output register. This happens because ctrl() is just a st() instruction in disguise.
This gave me the idea to extend the set of native operations in order to provide direct access to the whole 512K ram instead of banking things around. To do so, I am stealing parts of the extended ctrl code space that cannot be used from vCPU because the SYS_ExpanderControl call clears the low two bits of the ctrl code. Since all usable extended ctrl codes end with 0000, we can use 0001, 0010, and 0011 for additional opcodes.
The current CPLD program (see https://github.com/lb3361/gigatron-lb/b ... /rtl/top.v, only 314 lines) implements a new Z register and a couple new native instructions.
But how then do we use the register Z? Well, we use prefix instructions that change the addressing mode of the next Gigatron opcode which can be a load or store. For instance, instruction ld([Y,X]) becomes ld([Z,Y,X]) which uses bits from the Z register to form a large enough address to access all the RAM as a big linear space. More exactly the prefixes change the addressing mode of the next instruction as follow:
The prefix instruction are the same as the instructions above with an additional bit that indicates that the addressing mode
of the next executed instruction must be changed.
All this seems nice but is far from being tested. I wrote the new CPLD program and checked that the Gigatron still runs normally. I have to write a native SYS call to exercise these new opcodes and see how well this works. Overall I am quite confident except for the ld(AC,Z) instructions because I am not sure the ALU has already produced AC when I process the ctrl() instruction. The next step is to update the native assembler to understand things like adda([Z,Y,0x23],X) and generate the correct program. We could then provide new vCPU instructions that work with the large linear address space. Or maybe convince at67 to have a look at this
The CPLD is now 94% full with 9/144 macrocells remaining. What can we do with these?
[Update] - Going from 6 bits audio to 8 bits audio takes two more macrocells. Let's see whether it helps.
I did not realize this was possible until a couple day ago when I finally found the time to fix my flawed extended memory banking scheme (see https://forum.gigatron.io/viewtopic.php?p=2838#p2838). This fix required lots of changes: the extended ctrl codes, the verilog, the rom, the demo programs, and even the compiler which gained support to place vCPU routines in specific memory ranges, which can be useful when one swap memory banks. Then I realized that when a ctrl instruction is executing --which I know because the SRAM signals /OE and /WE are both low--, I can also see the value of the AC register on the ALU pins of the output register. This happens because ctrl() is just a st() instruction in disguise.
This gave me the idea to extend the set of native operations in order to provide direct access to the whole 512K ram instead of banking things around. To do so, I am stealing parts of the extended ctrl code space that cannot be used from vCPU because the SYS_ExpanderControl call clears the low two bits of the ctrl code. Since all usable extended ctrl codes end with 0000, we can use 0001, 0010, and 0011 for additional opcodes.
The current CPLD program (see https://github.com/lb3361/gigatron-lb/b ... /rtl/top.v, only 314 lines) implements a new Z register and a couple new native instructions.
Code: Select all
ENCODING OPCODE DESCRIPTION
C141/ctrl(0x41) -- no operation
C1*2/ctrl(0x*2) ld(*,Z) load immediate * into register Z
C151/ctrl(0x51) ld(AC,Z) copy AC into register Z
C961/ctrl(Y,0x61) ld(Y,Z) copy Y into register Z
C171/ctrl(0x71) ld(V,Z) copy three upper bits of the current video bank into Z,
using AC<7> to decide whether targeting even or odd pixels.
Code: Select all
[d],AC --> [Z,0,d],AC
[X],AC --> [Z,0,X],AC
[Y,d],AC --> [Z,Y,d],AC
[Y,X],AC --> [Z,Y,X],AC
[d],X --> [Z,0,d],X
[d],Y --> [Z,0,d],Y
[d],OUT --> [Z,0,d],OUT (load only)
[Y,X++],OUT --> [Z,Y,X++],OUT (load only)
[Y,X++] --> [Z,Y,X++] (store only)
of the next executed instruction must be changed.
Code: Select all
ENCODING OPCODE DESCRIPTION
C1c1/ctrl(0xc1) far() prefix for next insn
C1d3/ctrl(0x*3) far(*,Z) same as ld(*,Z) + prefix
C1d1/ctrl(0xd1) far(AC,Z) same as ld(AC,Z) + prefix
C9e1/ctrl(Y,0xe1) far(Y,Z) same as ld(Y,Z) + prefix
C1f1/ctrl(0xf1) far(V,Z) same as ld(V,Z) + prefix
The CPLD is now 94% full with 9/144 macrocells remaining. What can we do with these?
[Update] - Going from 6 bits audio to 8 bits audio takes two more macrocells. Let's see whether it helps.
Last edited by lb3361 on 09 Sep 2022, 02:59, edited 8 times in total.
Re: Gigatron 512k and more
High resolution Mandelbrot
This is a rewritten version of the Mandelbrot program in 320x240 resolution. I had to change the fixed point format to have 8 bits of fractional part because one cannot otherwise separate the pixels for the zoomed displays. Although it has been rewritten in vCPU + C https://github.com/lb3361/gigatron-lb/t ... mandelbrot, it remains quite close to the original. I also use qwertyface's multiplication trick to great effect because we now have plenty of memory to store a table of squares.
Speedwise, we have to compute four times more pixels per screen, but the Gigatron 512k is about four times faster than a standard Gigatron in default mode 1. The big speedup remains qwertyface's multiplication trick which goes about five times faster than the old code in this application (big table, no overflow checks, no fallback to normal multiplication.)
I surprise myself thinking that 320x240 is high resolution
The GT1 file is 6KB long. I am not including it here because it certainly won't work on a normal Gigatron.
For the curious, here is the memory map. Note the 8KB buffer containing squares at address 0x1e00 (the screen buffer is now elsewhere, in banks 12 to 15). Most of the code is related to using the cprintf to display the time. Although it is lighter than it used to be, it links plenty of code that this program does not use directly (memset, division) and also the console support which is useful because it sets up the high-res display, something I would have to do otherwise.
This is a rewritten version of the Mandelbrot program in 320x240 resolution. I had to change the fixed point format to have 8 bits of fractional part because one cannot otherwise separate the pixels for the zoomed displays. Although it has been rewritten in vCPU + C https://github.com/lb3361/gigatron-lb/t ... mandelbrot, it remains quite close to the original. I also use qwertyface's multiplication trick to great effect because we now have plenty of memory to store a table of squares.
Speedwise, we have to compute four times more pixels per screen, but the Gigatron 512k is about four times faster than a standard Gigatron in default mode 1. The big speedup remains qwertyface's multiplication trick which goes about five times faster than the old code in this application (big table, no overflow checks, no fallback to normal multiplication.)
I surprise myself thinking that 320x240 is high resolution
The GT1 file is 6KB long. I am not including it here because it certainly won't work on a normal Gigatron.
For the curious, here is the memory map. Note the 8KB buffer containing squares at address 0x1e00 (the screen buffer is now elsewhere, in banks 12 to 15). Most of the code is related to using the cprintf to display the time. Although it is lighter than it used to be, it links plenty of code that this program does not use directly (memset, division) and also the console support which is useful because it sets up the high-res display, something I would have to do otherwise.
Code: Select all
$ glcc -map=32k,./mandelbrot.ovl -rom=v5a mandelbrot.o fixed8.s ../libcon_h/libcon_h.a -o mandelbrot.gt1 --frags
Fragment map
0200-0223 (36 bytes) CODE _gt1exec _gt1exec.s
0224-0277 (84 bytes) CODE _cons_set_bank libcon_h.a(cons_bank.s)
0278-02d8 (97 bytes) CODE _console_printchars libcon_h.a(cons_printchar.s)
02da-02db (2 bytes) DATA lastFrame mandelbrot.c
02dc-02dc (1 byte) DATA separator mandelbrot.c
02de-02df (2 bytes) DATA clock0 mandelbrot.c
02e0-02e1 (2 bytes) DATA clockM mandelbrot.c
02e2-02e3 (2 bytes) DATA clockH mandelbrot.c
02e4-02e7 (4 bytes) DATA bayer mandelbrot.c
02e8-02f2 (11 bytes) DATA .56 mandelbrot.c
02f4-02f7 (4 bytes) DATA __glink_magic_init libcon_h.a(cons_output.c)
02f8-02f9 (2 bytes) DATA __glink_magic_init libc.a(_start.s)
0300-035b (92 bytes) CODE _printonechar libcon_h.a(cons_printchar.s)
035c-03a4 (73 bytes) CODE _console_clear libcon_h.a(cons_clear.s)
03a5-03e4 (64 bytes) DATA levels mandelbrot.c
03e6-03ed (8 bytes) DATA .6 libcon_h.a(cons_setup.c)
03ee-03f5 (8 bytes) DATA console_state libcon_h.a(cons_output.c)
03f6-03f7 (2 bytes) DATA __glink_magic_fini libc.a(_start.s)
03f8-03f9 (2 bytes) DATA .79 libc.a(_doprint.c)
0400-0420 (33 bytes) DATA .37 mandelbrot.c
0422-0443 (34 bytes) DATA console_info libcon_h.a(cons_geom.c)
0444-0454 (17 bytes) DATA .msg libc.a(raise_zdiv.s)
0455-045d (9 bytes) DATA .13 libc.a(_doprint.c)
045e-0465 (8 bytes) DATA .14 libc.a(_doprint.c)
0466-0476 (17 bytes) DATA .108 libc.a(_doprint.c)
0477-0486 (16 bytes) DATA .109 libc.a(_doprint.c)
0487-0489 (3 bytes) DATA .95 libc.a(_doprint.c)
048a-048c (3 bytes) DATA .82 libc.a(_doprint.c)
048d-048e (2 bytes) DATA .70 libc.a(_doprint.c)
048f-0490 (2 bytes) DATA .67 libc.a(_doprint.c)
0491-0491 (1 byte) DATA .64 libc.a(_doprint.c)
0492-0497 (6 bytes) DATA bell libc.a(cons_ctrl.c)
0498-04a5 (14 bytes) DATA .31 libc.a(cons_ctrl.c)
04a6-04a7 (2 bytes) DATA __glink_magic_bss libc.a(_init1.c)
0800-0864 (101 bytes) CODE move_pen mandelbrot.c
0865-08fe (154 bytes) CODE worm (1/2) mandelbrot.c
0900-0949 (74 bytes) CODE worm (2/2) mandelbrot.c
094a-09cc (131 bytes) CODE prep_squares mandelbrot.c
09cd-09fe (50 bytes) CODE update_clock (1/2) mandelbrot.c
0a00-0ac2 (195 bytes) CODE update_clock (2/2) mandelbrot.c
0ac3-0aff (61 bytes) CODE do_pixel mandelbrot.c
0b00-0b7e (127 bytes) CODE do_grayout mandelbrot.c
0b7f-0bcc (78 bytes) CODE go mandelbrot.c
0bcd-0bff (51 bytes) CODE main (1/2) mandelbrot.c
0c00-0c5f (96 bytes) CODE main (2/2) mandelbrot.c
0c60-0c9b (60 bytes) CODE slowmul fixed8.s(slowmul.s)
0c9c-0cff (100 bytes) CODE mul2 fixed8.s(mul2.s)
0d00-0d4a (75 bytes) CODE calc_pixel fixed8.s(calcpixel.s)
0d4b-0d90 (70 bytes) CODE check_calc fixed8.s(checkcalc.s)
0d91-0dff (111 bytes) CODE console_exitm_msgfunc (1/2) libcon_h.a(cons_setup.c)
0e00-0e1e (31 bytes) CODE console_exitm_msgfunc (2/2) libcon_h.a(cons_setup.c)
0e1f-0e40 (34 bytes) CODE _console_setup libcon_h.a(cons_setup.c)
0e41-0e88 (72 bytes) CODE cons_addr libcon_h.a(cons_output.c)
0e89-0eb8 (48 bytes) CODE console_clear_screen libcon_h.a(cons_output.c)
0eb9-0eeb (51 bytes) CODE console_clear_to_eol libcon_h.a(cons_output.c)
0eec-0ef5 (10 bytes) CODE SYS_ExpanderControl libc.a(sys_expandercontrol.s)
0ef6-0eff (10 bytes) CODE _@_modu libc.a(rt_modu.s)
0f00-0f60 (97 bytes) CODE scroll libcon_h.a(cons_output.c)
0f61-0ffd (157 bytes) CODE console_print (1/2) libcon_h.a(cons_output.c)
1000-1063 (100 bytes) CODE console_print (2/2) libcon_h.a(cons_output.c)
1064-10f8 (149 bytes) CODE _console_reset libcon_h.a(cons_geom.c)
1100-1148 (73 bytes) CODE memset libc.a(memset.s)
1149-1170 (40 bytes) CODE _memscan0 libc.a(memchr.s)
1171-11c1 (81 bytes) CODE memchr libc.a(memchr.s)
11c2-11e6 (37 bytes) CODE .callchain libc.a(_start.s)
11e7-11f3 (13 bytes) CODE _@_raise_zdiv libc.a(raise_zdiv.s)
11f4-11fe (11 bytes) CODE _doprint_double libc.a(_doprint_double.s)
1200-125a (91 bytes) CODE _start libc.a(_start.s)
125b-1265 (11 bytes) CODE _doprint_long libc.a(_doprint_long.s)
1266-1299 (52 bytes) CODE raise libc.a(raise.s)
129a-12ce (53 bytes) CODE utoa libc.a(utoa.s)
12cf-12ec (30 bytes) CODE itoa libc.a(itoa.s)
1300-1357 (88 bytes) CODE _doprint_putc libc.a(_doprint.c)
1358-13b4 (93 bytes) CODE _doprint_puts libc.a(_doprint.c)
13b5-13ff (75 bytes) CODE parsespec (1/2) libc.a(_doprint.c)
1400-14c4 (197 bytes) CODE parsespec (2/2) libc.a(_doprint.c)
14c5-14fe (58 bytes) CODE do_str (1/2) libc.a(_doprint.c)
1500-1585 (134 bytes) CODE do_str (2/2) libc.a(_doprint.c)
1586-15ac (39 bytes) CODE upcase libc.a(_doprint.c)
15ad-15fc (80 bytes) CODE _doprint_num (1/3) libc.a(_doprint.c)
1600-16ff (256 bytes) CODE _doprint_num (2/3) libc.a(_doprint.c)
1700-174b (76 bytes) CODE _doprint_num (3/3) libc.a(_doprint.c)
174c-17bc (113 bytes) CODE do_int libc.a(_doprint.c)
17bd-17fa (62 bytes) CODE _doprint (1/3) libc.a(_doprint.c)
1800-1846 (71 bytes) CODE _doprint_conv_info libc.a(_doprint.c)
1847-18ff (185 bytes) CODE _doprint (2/3) libc.a(_doprint.c)
1900-19ad (174 bytes) CODE _doprint (3/3) libc.a(_doprint.c)
19ae-19e3 (54 bytes) CODE strlen libc.a(strlen.c)
19e4-19fa (23 bytes) CODE _@_wcopy libc.a(rt_wcopy.s)
1a00-1ae0 (225 bytes) CODE _console_ctrl libc.a(cons_ctrl.c)
1ae1-1afd (29 bytes) CODE _@_bcopy libc.a(rt_bcopy.s)
1b00-1b2c (45 bytes) CODE dpf libc.a(cprintf.c)
1b2d-1b76 (74 bytes) CODE vcprintf libc.a(cprintf.c)
1b77-1bb0 (58 bytes) CODE cprintf libc.a(cprintf.c)
1bb1-1bfd (77 bytes) CODE _@_save_ff libc.a(rt_save.s)
1c00-1c54 (85 bytes) CODE _init_bss libc.a(_init1.c)
1c55-1ca0 (76 bytes) CODE _@_rtrn_ff libc.a(rt_save.s)
1ca1-1cd0 (48 bytes) CODE __@divworker libc.a(rt_divworker.s)
1cd1-1cec (28 bytes) CODE __@shrsysfn libc.a(rt_shrtable.s)
1d00-1d3d (62 bytes) CODE _@_divu libc.a(rt_divu.s)
1d3e-1d5f (34 bytes) CODE _@_shru libc.a(rt_shru.s)
1d60-1d7f (32 bytes) CODE _@_shrs libc.a(rt_shru.s)
1e00-3dff (8192 bytes) BSS squares mandelbrot.c
Re: Gigatron 512k and more
Very impressive ! Where do you capture the banking information (address 4d)? Is it done somewhere in the libraries or directly by the CLPD?
Also the Z register concept for providing far pointers sounds very exciting. In your description above do you actually mean ld([Y,X]) will become ld([Z,Y,X]) ?
Also the Z register concept for providing far pointers sounds very exciting. In your description above do you actually mean ld([Y,X]) will become ld([Z,Y,X]) ?
Re: Gigatron 512k and more
I am not sure what you mean by "capturing the banking information" and in which context.
Update: Just realized that address 4d is the "bank" variable of the Mandelbrot program. This is used by 'SYS_ExpanderControl(ctrl)' in 'do_pixel()' or 'do_grayout()' because address 4d is the high byte of the int variable 'ctrl'. Going to add a comment in the code.
Correct. I will edit the post.
Re: Gigatron 512k and more
Cool upgrade! This must replace multiple hardware updates what we have seen. I am currently working with 64K RAM update and burning ROM. The surface mount tech is really beyond what I can do.