
#
#    Mecrisp-Quintus - A native code Forth implementation for RISC-V
#    Copyright (C) 2018  Matthias Koch
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#


Mecrisp-Quintus: A native code RISC-V Forth, currently for RISC-V 32 IM.

HIC SUNT DRACONES - HIC SUNT DRACONES - HIC SUNT DRACONES

This still an early experimental release, so beware: Monsters may be inside !


# -----------------------------------------------------------------------------
  Similarities to Mecrisp-Stellaris and Differences:
# -----------------------------------------------------------------------------

Functionally mostly compatible with Mecrisp-Stellaris,
just with less strong optimisations at this early release.

Everything is 4-aligned, no h, and no c, available.

Shifts decode the lowest 5 bits only on Risc-V.
Therefore, ar/r/lshift behave like "31 and ar/r/lshift".
32 lshift does nothing.

Mecrisp-Quintus makes heavy use of PC-relative calls, which render inlining harmful.
If you port code from Mecrisp-Stellaris, remove "inline" flags.

Specials available in Mecrisp-Quintus which are not found in Mecrisp-Stellaris:

        reset           ( -- ) Soft reboot
        leds            ( x -- ) Display bits on LEDs on HX8K board
        h@signed        ( addr -- n ) Fetch halfword with sign extension
        c@signed        ( addr -- n ) Fetch byte     with sign extension
        addrinflash?    ( addr -- ? ) Location in flash memory ?
        addrinram?      ( addr -- ? ) Location in ram memory ?
        skipdefinition  ( addr -- addr* ) Skip after the next ret opcode
        uj-encoding?    ( x -- bitmask true | x false ) Opcode contruction tool for unconditional jumps
        sb-endocing?    ( x -- bitmask true | x false ) Opcode contruction tool for   conditional jumps
        r.s             ( many -- many R: many -- many ) Prints return stack contents

# -----------------------------------------------------------------------------
  How to assemble:
# -----------------------------------------------------------------------------

You need RISC-V binutils, which are included for convenience:

  riscv64-unknown-elf-as
  riscv64-unknown-elf-ld
  riscv64-unknown-elf-objcopy
  riscv64-unknown-elf-objdump

Assemble as usual:

  make clean all

You find the originals of the precompiled binutils here:

  "SiFive GNU Embedded Toolchain"
  https://www.sifive.com/products/tools/
  https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-20171231-x86_64-linux-centos6.tar.gz

# -----------------------------------------------------------------------------
  How to run in emulator:
# -----------------------------------------------------------------------------

fpc -XX -O3 quintusemu
./quintusemu mecrisp-quintus-picosoc.bin

# -----------------------------------------------------------------------------
  How to run (very slow) on Picosoc/PicoRV32 by Clifford Wolf in a HX8K breakout board:
# -----------------------------------------------------------------------------

The included Picosoc is synthesised with 14 kb RAM and hardware multiply & divide.

iceprog -b picosoc-hx8k.bin
iceprog -o 1M mecrisp-quintus-picosoc.bin
picocom -b 115200 /dev/ttyUSB1 --imap lfcrlf,crcrlf --omap delbs,crlf --send-cmd "ascii-xfr -s -l 2000 -c 3 -n"

Picosoc and PicoRV32 are by Clifford Wolf, included here only for convenience.

"PicoRV32 is free and open hardware licensed under the ISC license (a license that is similar in terms to the MIT license or the 2-clause BSD license)."

Get the original here:
https://github.com/cliffordwolf/picorv32

# -----------------------------------------------------------------------------
  How to run on a TI Stellaris Launchpad, LM4F120
# -----------------------------------------------------------------------------

Includes Mamihlapinatapai, an instruction set emulator for ARM Cortex M3/M4.

lm4flash mecrisp-quintus-lm4f120-mamihlapinatapai-with-disassembler-and-pll.bin

picocom -b 115200 /dev/ttyACM0 --imap lfcrlf,crcrlf --omap delbs,crlf --send-cmd "ascii-xfr -s -l 500 -c 3 -n"

# -----------------------------------------------------------------------------
  How to run on a HiFive1 (Rev. A)
# -----------------------------------------------------------------------------

Flashing is done in the hifive1 folder this way:

../toolchain/openocd-hifive1 -f flash-hifive1.cfg

Open terminal:

./terminal

Different, much more complicated method:

If you have the very large freedom-e-sdk installed, you can flash Mecrisp-Quintus this way:
(https://github.com/sifive/freedom-e-sdk)

In one terminal:
  cd freedom-e-sdk
  make run_openocd

In another terminal:
  cd freedom-e-sdk
  make run_gdb

    monitor flash protect 0 64 last off
    load mecrisp-quintus-0.4-experimental/hifive1/mecrisp-quintus-hifive1-with-disassembler.hex
    jump *0x20400000


picocom -b 115200 /dev/ttyUSB1 --imap lfcrlf,crcrlf --omap delbs,crlf --send-cmd "ascii-xfr -s -l 250 -n"

# -----------------------------------------------------------------------------
  Hacking
# -----------------------------------------------------------------------------

If you replace the definitions in multiplydivide.s it will run on basic RV32I.
Only the low 16 registers are in use, so you can easily change this for RV32E, too.
If you add interrupts, save x5 and x6 upon ISR entry.

Register usage:

  x0 : Hardwired to zero
  x1 : Return address register, holds link back
  x2 : Stack pointer
  x3 : TOS
  x4 : PSP data stack pointer
  x5 : Free scratch register, not saved across calls
  x6 : Free scratch register, not saved across calls
  x7 : Scratch register, needs to be saved
  x8 : Loop index
  x9 : Loop limit

  x10-x15 : Scratch register, needs to be saved
  x16-x31 : Unused
