Close
0%
0%

Merlin

68000 Retro Super Computer

Similar projects worth following
A flexible, open platform to learn or develop 32-bit hardware or software using either a physical or FPGA solution.

The project uses a modular design to allow you to extend or move in different directions should you so wish.

- 100 mhz 6800x CPU
- 200 mhz custom ieee754 FPU
- EVE GPU Support
- Dual OPL3 support
- Support for FAT32
- Hardware accelerated tcp/ip

https://github.com/mattuna15/merlin
https://www.facebook.com/groups/1609879555846636

A flexible, open platform to learn or develop 32-bit hardware or software using either a physical or FPGA solution.

The project uses a modular design to allow you to extend or move in different directions should you so wish. At it's heart is the core of a Multicomp system from Grant Searle. 

IDE:

VHDL:

https://github.com/mattuna15/zed-68k/tree/arty-gd

Hardware:

  • FPGA 68000/020 CPU
  • VGA/HDMI - Gameduino 3X Dazzler
  • Board - ARTY A7-35T
  • Sound - Twin OPL3 chips (FM) and/or Gameduino PCM
  • RTC
  • PS2 Keyboard

Storage:

  • DDR3 Ram support
  • FAT32 SDHC Card support with C Fat Library
  • TELNET Server with support for S-Record upload via Monitor rom

mcprtcdatasheet.pdf

RTC Data sheet

Adobe Portable Document Format - 980.03 kB - 07/07/2021 at 16:15

Preview
Download

arty_rm.pdf

Arty reference manual

Adobe Portable Document Format - 1.19 MB - 07/05/2021 at 09:28

Preview
Download

gd2book_v0.pdf

Gameduino library documentation

Adobe Portable Document Format - 9.10 MB - 07/05/2021 at 09:14

Preview
Download

gameduino-3x-dazzler.pdf

Dazzler specific extensions to gameduino

Adobe Portable Document Format - 6.69 MB - 07/05/2021 at 09:14

Preview
Download

FT81X_Series_Programmer_Guide.pdf

EVE Programmers guide. GPU for the dazzler

Adobe Portable Document Format - 3.88 MB - 07/05/2021 at 09:13

Preview
Download

View all 7 files

  • More FP

    Matthew Pearce08/16/2021 at 08:30 0 comments

    I have a 64-bit double precision FPU working now. It seems to be a big improvement on my first version. The main work now is to complete the new library for GCC to make use of the FPU.

    I have started to work on a set of wrapper functions which will override the existing soft-float routines.

    The first routine overrides muldf3:

    double __wrap___muldf3(double a, double b)
    {
    
      printf("\r\nmuldf3: start\r\n");
    
      *fpu_ctl = MUL;
    
      op_a.dbl = a;
      op_b.dbl = b;
    
      *opa = op_a.num;
      *opb = op_b.num;
    
      BIT_SET(*fpu_ctl, 0);
      BIT_CLEAR(*fpu_ctl, 0);
    
      while (!BIT_CHECK(*fpu_sts, 0) && !BIT_CHECK(*fpu_sts, 1))
      {
      }
    
      resf.num = *fpu_res;
    
      printf("\r\nmuldf3: stop\r\n");
    
      return resf.dbl;
    }

    It uses a union to convert the double to IEEE754 double-precision int.


    union FloatingPointIEEE754
    {
      struct
      {
        unsigned int sign : 1;
        unsigned short int exponent : 11;
        long long mantissa : 52;
      } raw;
      uint64_t num;
      double dbl;
    } ;



    The make file has an additional parameter to override the specified function.

     

    float-test.run: ieee754.c float-test.c
    	m68k-elf-gcc -Wall -m68000 -g -Os ieee754.c float-test.c 
    -Wl,--wrap=__muldf3 -o float-test.run ....

  • More FP

    Matthew Pearce08/16/2021 at 08:30 0 comments

    I have a 64-bit double precision FPU working now. It seems to be a big improvement on my first version. The main work now is to complete the new library for GCC to make use of the FPU.

    I have started to work on a set of wrapper functions which will override the existing soft-float routines.

    The first routine overrides muldf3:

    double __wrap___muldf3(double a, double b)
    {
    
      printf("\r\nmuldf3: start\r\n");
    
      *fpu_ctl = MUL;
    
      op_a.dbl = a;
      op_b.dbl = b;
    
      *opa = op_a.num;
      *opb = op_b.num;
    
      BIT_SET(*fpu_ctl, 0);
      BIT_CLEAR(*fpu_ctl, 0);
    
      while (!BIT_CHECK(*fpu_sts, 0) && !BIT_CHECK(*fpu_sts, 1))
      {
      }
    
      resf.num = *fpu_res;
    
      printf("\r\nmuldf3: stop\r\n");
    
      return resf.dbl;
    }

    It uses a union to convert the double to IEEE754 double-precision int.


    union FloatingPointIEEE754
    {
      struct
      {
        unsigned int sign : 1;
        unsigned short int exponent : 11;
        long long mantissa : 52;
      } raw;
      uint64_t num;
      double dbl;
    } ;



    The make file has an additional parameter to override the specified function.

     

    float-test.run: ieee754.c float-test.c
    	m68k-elf-gcc -Wall -m68000 -g -Os ieee754.c float-test.c 
    -Wl,--wrap=__muldf3 -o float-test.run ....

  • Floating Point

    Matthew Pearce07/28/2021 at 14:33 0 comments

    I have updated and modified an FPU from opencores. I removed the division/square root code and put in xilinix optimised code. It now runs at 200mhz as opposed to the original 100mhz.

    Using the FPU for this code:

    for (int i = 0; i<5000; i++) {
            res = (a+i)/(b-i);
            res = res * a * (i/b);
    
            if (res < 0) {
                res = res*-1.0;
            }
    
            res = sqrtf(res);
    
            printf("res = %0.3f\r\n",res);
        }
        

     I managed to improve the performance substantially over the already optimised 68k assembler code provided in the soft-float gcc library. Also tg68 has a hardware multiplier built in so this is quite a large improvement.
    I would expect larger improvements if just using ieee754 numbers rather than relying on conversion from floats all the time.

    Any way from the built in timer.

    time taken. fpu: 46149 sf: 51679 

  • Framebuffer

    Matthew Pearce07/20/2021 at 10:34 0 comments

    The Dazzler has 1mb of vram available to it. Normally you send commands down spi to create images, text and so on. But you can use a Paletted bitmap to create a 1280x720 framebuffer with a palette and around 120k left for other data.

    After raising a question on the gameduino forum James Bowman kindly wrote a quick demo on how to create a random image pixel by pixel. I've taken that example and have created a fractal generator which I'll share very soon. Here's a link to the arduino sketch demo from James.


    https://github.com/jamesbowman/gd2-lib/blob/master/examples/paletted.ino

  • OPL3 live!

    Matthew Pearce07/17/2021 at 12:07 0 comments

    I have implemented a millisecond timer and converted an Arduino OPL library. This demo shows the cards and you can hear a simple music track playing.

    Code available here:

    https://github.com/mattuna15/merlin-software/tree/master/ArduinoOPL2

  • Elite Cobra Demo

    Matthew Pearce07/17/2021 at 06:58 0 comments

    Spent a lot of time getting basic basically right, here is a demo using the C++ toolchain. This uses a set of vectors overlaid over a background bitmap with an animated sun moving across the background. The assets are loaded from SDCard after conversion by the GD2 asset converter.

    The c++ code is on the merlin software github.

    Cobra demo c++ code

  • Basic Bitmaps in Basic

    Matthew Pearce07/16/2021 at 11:51 0 comments

    I have now completed the first pass of bitmaps work. There are 2 new commands:

    VLOAD - this loads the .gd2 asset file from the SD Card directly into the GPU memory, saving on ram resources.

    BITMAP - passes the bitmap info such as the ID (handle) and alpha.

    The code to load and display a bitmap is now very simple:

    10 VLOAD "LOGO.GD2"                                                             
    20 CLS $FFFFFF: CLR                                                             
    25 SIZE 1                                                                       
    26 CURSOR 350,200                                                               
    30 BITMAP 0,0,2,3                                                               
    40 GDSWAP    

    This small program loads the GD logo into the centre of the screen. 

  • Sub-Directory support

    Matthew Pearce07/16/2021 at 06:42 0 comments

    I've added support for sub-directories to the Basic files commands. CDIR will allow you to switch directories. I've added this to allow me to keep the assets for the Dazzler separate. I've also added a VLOAD command but more of that later.

  • More than 1 thing at once

    Matthew Pearce07/12/2021 at 12:02 0 comments

    Colours and sizes have been added.

    LINEC, FILLC and SIZE can now be used to alter colours.

    5 CLS $FFFFFF: CLR                                                              
    10 SIZE 16                                                                      
    20 CURSOR 60,60                                                                 
    25 LINEC $FF0000                                                                
    30 GDPRINT"HELLO WORLD!"                                                        
    31 SIZE 1                                                                       
    32 LINEC $00FF00                                                                
    33 LINE 100,200,250,400,1                                                       
    34 POINT 20,20,1                                                                
    35 GDSWAP                                                                       
    40 PRINT"DONE"   

    The flag at the end of the line and point commands, tells the EVE code to switch modes ->

    GD.Begin(LINES);
    
    or
    
    GD.Begin(POINTS);

  • New Print Function

    Matthew Pearce07/12/2021 at 09:20 0 comments

    The EVE chip has a number of built in fonts. You can access them directly using the "cmd_text" command. I've added a new basic command in addition to the PRINT command - "GDPRINT"

    You can specify the font (#16-31), cursor position and colour, plus a string to be displayed on the screen rather than the console.

    5 CLS $FFFFFF: CLR                                                              
    10 SIZE 16                                                                      
    20 CURSOR 60,60                                                                 
    30 GDPRINT"HELLO WORLD!"                                                        
    35 GDSWAP                                                                       
    40 PRINT"DONE"                                                                  
                                                                                    
    

    This produces black text in the top left of a white screen.

    This was quite a fiddly change to make. The EVE text command needs a lot of parameters both strings and numbers - so I broke it down into multiple basic commands. Size & Cursor just add the data to the stack and GDPRINT sends everything to EVE. EhBasic interprets the line and gives you a pointer to the string and the length of the string. Passing them to 'C' means I need to cast the string pointer as a uintptr_t and then copy it to an initialised buffer.

    LAB_GDPRINT
    
    	MOVEM.L  A0-A2/D0-D7,-(A7)    * Save working registers
    
    	BSR		LAB_EVEX			* evaluate expression
    	BSR		LAB_GBYT			* scan memory
    	BNE		LAB_SNER			* if not [EOL] or [EOS] do syntax error and
    						* warm start
    
    	MOVE.l	(a4)+,gfxText(a3)			* string address from descriptor stack
    	MOVE.w	(a4)+,gfxTextLen(a3)			* string length from descriptor stack
    
    	pea gfxTextLen(a3)
    	pea gfxText(a3)
    	pea lineColor(a3)
    	pea lineSize(a3)
    	pea y1(a3)
    	pea x1(a3)
    	jsr gd_text
    	add #24,sp
    
    	MOVEM.L  (A7)+,A0-A2/D0-D7    * Restore working registers
    
    	rts
    void gd_text(uint32_t *x, uint32_t *y, uint32_t *font, uint32_t *color, uint32_t *text, uint32_t *len)
    {
    
        char string[256] = {0};
        uint8_t lenb = (uint8_t)((*len >> 16) & 0xff);
        uintptr_t ptr = (uintptr_t)*text;
        volatile char *buf = (char *)ptr;
    
        for (int i = 0; i < lenb; i++)
        {
            string[i] = *buf++;
        }
    
        GD.VertexFormat(0);
        GD.ColorRGB(*color);
    
        if (*font == 0 || *font < 16 || *font > 31)
            *font = 18;
    
        GD.cmd_text(*x, *y, *font, 0, string);
    }

    Next I'll need to add in a new command to set the text colour. I'll also reuse the 'MODE" command to switch between resolutions I think.

View all 19 project logs

  • 1
    First binary release

    Load the .bit file onto your Arty using Vivado

    When the monitor starts, press L, then load the firmware s-record via your favourite terminal

    https://github.com/mattuna15/merlin/releases/tag/1.0

  • 2
    Fire it up

    The Program Counter will be set to 0x000400 by default so just press J and Basic will load.

View all instructions

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates