Explorar el Código

- RISC-V: Add controller types for common RV32 MCUs.
- Adds initial controller units for these MCUs.

Code contributed by Michael Ring

git-svn-id: trunk@43935 -

Jeppe Johansen hace 5 años
padre
commit
2678522db5

+ 4 - 0
.gitattributes

@@ -10472,6 +10472,10 @@ rtl/embedded/dos.pp svneol=native#text/plain
 rtl/embedded/empty.cfg svneol=native#text/plain
 rtl/embedded/empty.cfg svneol=native#text/plain
 rtl/embedded/heapmgr.pp svneol=native#text/pascal
 rtl/embedded/heapmgr.pp svneol=native#text/pascal
 rtl/embedded/i386/multiboot.pp svneol=native#text/plain
 rtl/embedded/i386/multiboot.pp svneol=native#text/plain
+rtl/embedded/riscv32/fe310g000.pp svneol=native#text/pascal
+rtl/embedded/riscv32/fe310g002.pp svneol=native#text/pascal
+rtl/embedded/riscv32/gd32vf103xx.pp svneol=native#text/pascal
+rtl/embedded/riscv32/riscv32_start.inc svneol=native#text/pascal
 rtl/embedded/rtl.cfg svneol=native#text/plain
 rtl/embedded/rtl.cfg svneol=native#text/plain
 rtl/embedded/rtldefs.inc svneol=native#text/plain
 rtl/embedded/rtldefs.inc svneol=native#text/plain
 rtl/embedded/sysdir.inc svneol=native#text/plain
 rtl/embedded/sysdir.inc svneol=native#text/plain

+ 2 - 2
compiler/riscv/agrvgas.pas

@@ -232,8 +232,8 @@ unit agrvgas;
       const
       const
         arch_str: array[boolean,tcputype] of string[10] = (
         arch_str: array[boolean,tcputype] of string[10] = (
 {$ifdef RISCV32}
 {$ifdef RISCV32}
-          ('','rv32ima','rv32im','rv32i'),
-          ('','rv32imafd','rv32imfd','rv32ifd')
+          ('','rv32imac','rv32ima','rv32im','rv32i'),
+          ('','rv32imafdc','rv32imafd','rv32imfd','rv32ifd')
 {$endif RISCV32}
 {$endif RISCV32}
 {$ifdef RISCV64}
 {$ifdef RISCV64}
           ('','rv64imac','rv64ima','rv64im','rv64i'),
           ('','rv64imac','rv64ima','rv64im','rv64i'),

+ 48 - 3
compiler/riscv32/cpuinfo.pas

@@ -37,6 +37,7 @@ Type
    { possible supported processors for this target }
    { possible supported processors for this target }
    tcputype =
    tcputype =
       (cpu_none,
       (cpu_none,
+       cpu_rv32imac,
        cpu_rv32ima,
        cpu_rv32ima,
        cpu_rv32im,
        cpu_rv32im,
        cpu_rv32i
        cpu_rv32i
@@ -50,7 +51,27 @@ Type
      );
      );
 
 
    tcontrollertype =
    tcontrollertype =
-     (ct_none
+     (ct_none,
+      ct_fe310g000,
+      ct_fe310g002,
+      ct_hifive1,
+      ct_hifive1revb,
+      ct_redfive,
+      ct_redfivething,
+      ct_gd32vf103c4,
+      ct_gd32vf103c6,
+      ct_gd32vf103c8,
+      ct_gd32vf103cb,
+      ct_gd32vf103r4,
+      ct_gd32vf103r6,
+      ct_gd32vf103r8,
+      ct_gd32vf103rb,
+      ct_gd32vf103t4,
+      ct_gd32vf103t6,
+      ct_gd32vf103t8,
+      ct_gd32vf103tb,
+      ct_gd32vf103v8,
+      ct_gd32vf103vb
      );
      );
 
 
    tcontrollerdatatype = record
    tcontrollerdatatype = record
@@ -63,7 +84,7 @@ Type
 Const
 Const
    { Is there support for dealing with multiple microcontrollers available }
    { Is there support for dealing with multiple microcontrollers available }
    { for this platform? }
    { for this platform? }
-   ControllerSupport = false;
+   ControllerSupport = true;
 
 
    { We know that there are fields after sramsize
    { We know that there are fields after sramsize
      but we don't care about this warning }
      but we don't care about this warning }
@@ -71,7 +92,29 @@ Const
     {$WARN 3177 OFF}
     {$WARN 3177 OFF}
    embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
    embedded_controllers : array [tcontrollertype] of tcontrollerdatatype =
    (
    (
-      (controllertypestr:''; controllerunitstr:''; cputype:cpu_none; fputype:fpu_none; flashbase:0; flashsize:0; srambase:0; sramsize:0));
+      (controllertypestr:''            ; controllerunitstr:''; cputype:cpu_none; fputype:fpu_none; flashbase:0; flashsize:0; srambase:0; sramsize:0),
+      (controllertypestr:'FE310G000'   ; controllerunitstr:'FE310G000';   cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$20400000; flashsize:$01000000; srambase:$80000000; sramsize:$00004000),
+      (controllertypestr:'FE310G002'   ; controllerunitstr:'FE310G002';   cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$20010000; flashsize:$00400000; srambase:$80000000; sramsize:$00004000),
+      (controllertypestr:'HIFIVE1'     ; controllerunitstr:'FE310G000';   cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$20400000; flashsize:$01000000; srambase:$80000000; sramsize:$00004000),
+      (controllertypestr:'HIFIVE1REVB' ; controllerunitstr:'FE310G002';   cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$20010000; flashsize:$00400000; srambase:$80000000; sramsize:$00004000),
+      (controllertypestr:'REDFIVE'     ; controllerunitstr:'FE310G002';   cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$20010000; flashsize:$00400000; srambase:$80000000; sramsize:$00004000),
+      (controllertypestr:'REDFIVETHING'; controllerunitstr:'FE310G002';   cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$20010000; flashsize:$02400000; srambase:$80000000; sramsize:$00004000),
+
+      (controllertypestr:'GD32VF103C4' ; controllerunitstr:'GD32VF103XX'; cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001800),
+      (controllertypestr:'GD32VF103C6' ; controllerunitstr:'GD32VF103XX'; cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00002800),
+      (controllertypestr:'GD32VF103C8' ; controllerunitstr:'GD32VF103XX'; cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00005000),
+      (controllertypestr:'GD32VF103CB' ; controllerunitstr:'GD32VF103XX'; cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00008000),
+      (controllertypestr:'GD32VF103R4' ; controllerunitstr:'GD32VF103XX'; cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001800),
+      (controllertypestr:'GD32VF103R6' ; controllerunitstr:'GD32VF103XX'; cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00002800),
+      (controllertypestr:'GD32VF103R8' ; controllerunitstr:'GD32VF103XX'; cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00005000),
+      (controllertypestr:'GD32VF103RB' ; controllerunitstr:'GD32VF103XX'; cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00008000),
+      (controllertypestr:'GD32VF103T4' ; controllerunitstr:'GD32VF103XX'; cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$08000000; flashsize:$00004000; srambase:$20000000; sramsize:$00001800),
+      (controllertypestr:'GD32VF103T6' ; controllerunitstr:'GD32VF103XX'; cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$08000000; flashsize:$00008000; srambase:$20000000; sramsize:$00002800),
+      (controllertypestr:'GD32VF103T8' ; controllerunitstr:'GD32VF103XX'; cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00005000),
+      (controllertypestr:'GD32VF103TB' ; controllerunitstr:'GD32VF103XX'; cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00008000),
+      (controllertypestr:'GD32VF103V8' ; controllerunitstr:'GD32VF103XX'; cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$08000000; flashsize:$00010000; srambase:$20000000; sramsize:$00005000),
+      (controllertypestr:'GD32VF103VB' ; controllerunitstr:'GD32VF103XX'; cputype:cpu_rv32imac; fputype:fpu_none; flashbase:$08000000; flashsize:$00020000; srambase:$20000000; sramsize:$00008000)
+   );
    {$POP}
    {$POP}
 
 
    { calling conventions supported by the code generator }
    { calling conventions supported by the code generator }
@@ -87,6 +130,7 @@ Const
    ];
    ];
 
 
    cputypestr : array[tcputype] of string[10] = ('',
    cputypestr : array[tcputype] of string[10] = ('',
+     'RV32IMAC',
      'RV32IMA',
      'RV32IMA',
      'RV32IM',
      'RV32IM',
      'RV32I'
      'RV32I'
@@ -124,6 +168,7 @@ Const
  const
  const
    cpu_capabilities : array[tcputype] of set of tcpuflags =
    cpu_capabilities : array[tcputype] of set of tcpuflags =
      ( { cpu_none      } [],
      ( { cpu_none      } [],
+       { cpu_rv32imac  } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC,CPURV_HAS_COMPACT],
        { cpu_rv32ima   } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC],
        { cpu_rv32ima   } [CPURV_HAS_MUL,CPURV_HAS_ATOMIC],
        { cpu_rv32im    } [CPURV_HAS_MUL],
        { cpu_rv32im    } [CPURV_HAS_MUL],
        { cpu_rv32i     } []     
        { cpu_rv32i     } []     

+ 102 - 1
compiler/systems/t_embed.pas

@@ -96,7 +96,7 @@ Var
 begin
 begin
   WriteResponseFile:=False;
   WriteResponseFile:=False;
   linklibc:=(SharedLibFiles.Find('c')<>nil);
   linklibc:=(SharedLibFiles.Find('c')<>nil);
-{$if defined(ARM) or defined(i386) or defined(x86_64) or defined(AVR) or defined(MIPSEL)}
+{$if defined(ARM) or defined(i386) or defined(x86_64) or defined(AVR) or defined(MIPSEL) or defined(RISCV32)}
   prtobj:='';
   prtobj:='';
 {$else}
 {$else}
   prtobj:='prt0';
   prtobj:='prt0';
@@ -1241,6 +1241,107 @@ begin
     end;
     end;
 {$endif MIPSEL}
 {$endif MIPSEL}
 
 
+{$ifdef RISCV32}
+  with linkres do
+    begin
+      Add('OUTPUT_ARCH("riscv")');
+      Add('ENTRY(_START)');
+      Add('MEMORY');
+      with embedded_controllers[current_settings.controllertype] do
+        begin
+          Add('{');
+          Add('  flash      (rx)   : ORIGIN = 0x'+IntToHex(flashbase,6)+', LENGTH = 0x'+IntToHex(flashsize,6));
+          Add('  ram        (rw!x) : ORIGIN = 0x'+IntToHex(srambase,6)+', LENGTH = 0x'+IntToHex(sramsize,6));
+          Add('}');
+          Add('_stack_top = 0x' + IntToHex(srambase+sramsize-1,4) + ';');
+        end;
+      Add('SECTIONS');
+      Add('{');
+      Add('  .text :');
+      Add('  {');
+      Add('    _text_start = .;');
+      Add('    KEEP(*(.init .init.*))');
+      Add('    *(.text .text.*)');
+      Add('    *(.strings)');
+      Add('    *(.rodata .rodata.*)');
+      Add('    *(.comment)');
+      Add('    . = ALIGN(4);');
+      Add('    _etext = .;');
+      if embedded_controllers[current_settings.controllertype].flashsize<>0 then
+        begin
+          Add('  } >flash');
+          //Add('    .note.gnu.build-id : { *(.note.gnu.build-id) } >flash ');
+        end
+      else
+        begin
+          Add('  } >ram');
+          //Add('    .note.gnu.build-id : { *(.note.gnu.build-id) } >ram ');
+        end;
+
+      Add('  .data :');
+      Add('  {');
+      Add('    _data = .;');
+      Add('    *(.data .data.*)');
+      Add('    KEEP (*(.fpc .fpc.n_version .fpc.n_links))');
+      Add('    _edata = .;');
+      if embedded_controllers[current_settings.controllertype].flashsize<>0 then
+        begin
+          Add('  } >ram AT >flash');
+        end
+      else
+        begin
+          Add('  } >ram');
+        end;
+      Add('  .bss :');
+      Add('  {');
+      Add('    _bss_start = .;');
+      Add('    *(.bss .bss.*)');
+      Add('    *(COMMON)');
+      Add('  } >ram');
+      Add('  . = ALIGN(4);');
+      Add('  _bss_end = . ;');
+      Add('  /* Stabs debugging sections.  */');
+      Add('  .stab          0 : { *(.stab) }');
+      Add('  .stabstr       0 : { *(.stabstr) }');
+      Add('  .stab.excl     0 : { *(.stab.excl) }');
+      Add('  .stab.exclstr  0 : { *(.stab.exclstr) }');
+      Add('  .stab.index    0 : { *(.stab.index) }');
+      Add('  .stab.indexstr 0 : { *(.stab.indexstr) }');
+      Add('  .comment       0 : { *(.comment) }');
+      Add('  /* DWARF debug sections.');
+      Add('     Symbols in the DWARF debugging sections are relative to the beginning');
+      Add('     of the section so we begin them at 0.  */');
+      Add('  /* DWARF 1 */');
+      Add('  .debug          0 : { *(.debug) }');
+      Add('  .line           0 : { *(.line) }');
+      Add('  /* GNU DWARF 1 extensions */');
+      Add('  .debug_srcinfo  0 : { *(.debug_srcinfo) }');
+      Add('  .debug_sfnames  0 : { *(.debug_sfnames) }');
+      Add('  /* DWARF 1.1 and DWARF 2 */');
+      Add('  .debug_aranges  0 : { *(.debug_aranges) }');
+      Add('  .debug_pubnames 0 : { *(.debug_pubnames) }');
+      Add('  /* DWARF 2 */');
+      Add('  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }');
+      Add('  .debug_abbrev   0 : { *(.debug_abbrev) }');
+      Add('  .debug_line     0 : { *(.debug_line) }');
+      Add('  .debug_frame    0 : { *(.debug_frame) }');
+      Add('  .debug_str      0 : { *(.debug_str) }');
+      Add('  .debug_loc      0 : { *(.debug_loc) }');
+      Add('  .debug_macinfo  0 : { *(.debug_macinfo) }');
+      Add('  /* SGI/MIPS DWARF 2 extensions */');
+      Add('  .debug_weaknames 0 : { *(.debug_weaknames) }');
+      Add('  .debug_funcnames 0 : { *(.debug_funcnames) }');
+      Add('  .debug_typenames 0 : { *(.debug_typenames) }');
+      Add('  .debug_varnames  0 : { *(.debug_varnames) }');
+      Add('  /* DWARF 3 */');
+      Add('  .debug_pubtypes 0 : { *(.debug_pubtypes) }');
+      Add('  .debug_ranges   0 : { *(.debug_ranges) }');
+
+      Add('}');
+      Add('_end = .;');
+
+    end;
+  {$endif RISCV32}
 
 
   { Write and Close response }
   { Write and Close response }
   linkres.writetodisk;
   linkres.writetodisk;

+ 5 - 2
rtl/embedded/Makefile

@@ -454,8 +454,11 @@ endif
 endif
 endif
 ifeq ($(ARCH),riscv32)
 ifeq ($(ARCH),riscv32)
 CPU_SPECIFIC_COMMON_UNITS=sysutils math classes fgl macpas typinfo types rtlconsts getopts lineinfo
 CPU_SPECIFIC_COMMON_UNITS=sysutils math classes fgl macpas typinfo types rtlconsts getopts lineinfo
-CPU_UNITS=
+ifeq ($(SUBARCH),rv32imac)
+override FPCOPT+=-Cprv32imac
+CPU_UNITS=fe310g000 fe310g002 gd32vf103xx
 CPU_UNITS_DEFINED=1
 CPU_UNITS_DEFINED=1
+endif
 ifeq ($(CPU_UNITS_DEFINED),)
 ifeq ($(CPU_UNITS_DEFINED),)
 $(error No CPUs enabled for given SUBARCH, pass either a SUBARCH or set CPU_UNITS_DEFINED=1 if you know what you are doing)
 $(error No CPUs enabled for given SUBARCH, pass either a SUBARCH or set CPU_UNITS_DEFINED=1 if you know what you are doing)
 endif
 endif
@@ -2508,7 +2511,7 @@ fpc_shared:
 ifdef HASSHAREDLIB
 ifdef HASSHAREDLIB
 	$(MAKE) all CREATESHARED=1 LINKSHARED=1 CREATESMART=1
 	$(MAKE) all CREATESHARED=1 LINKSHARED=1 CREATESMART=1
 ifneq ($(SHARED_BUILD),n)
 ifneq ($(SHARED_BUILD),n)
-	$(PPUMOVE) -q $(SHARED_LIBUNITS) -i$(COMPILER_UNITTARGETDIR) -o$(SHARED_FULLNAME) -d$(COMPILER_UNITTARGETDIR)
+	$(PPUMOVE) -q $(SHARED_LIBUNITS) -i$(COMPILER_UNITTARGETDIR) -o$(SHARED_FULLNAME) -d$(COMPILER_UNITTARGETDIR) -P$(BINUTILSPREFIX)
 endif
 endif
 else
 else
 	@$(ECHO) Shared Libraries not supported
 	@$(ECHO) Shared Libraries not supported

+ 4 - 1
rtl/embedded/Makefile.fpc

@@ -177,8 +177,11 @@ endif
 
 
 ifeq ($(ARCH),riscv32)
 ifeq ($(ARCH),riscv32)
 CPU_SPECIFIC_COMMON_UNITS=sysutils math classes fgl macpas typinfo types rtlconsts getopts lineinfo
 CPU_SPECIFIC_COMMON_UNITS=sysutils math classes fgl macpas typinfo types rtlconsts getopts lineinfo
-CPU_UNITS=
+ifeq ($(SUBARCH),rv32imac)
+override FPCOPT+=-Cprv32imac
+CPU_UNITS=fe310g000 fe310g002 gd32vf103xx
 CPU_UNITS_DEFINED=1
 CPU_UNITS_DEFINED=1
+endif
 ifeq ($(CPU_UNITS_DEFINED),)
 ifeq ($(CPU_UNITS_DEFINED),)
 $(error No CPUs enabled for given SUBARCH, pass either a SUBARCH or set CPU_UNITS_DEFINED=1 if you know what you are doing)
 $(error No CPUs enabled for given SUBARCH, pass either a SUBARCH or set CPU_UNITS_DEFINED=1 if you know what you are doing)
 endif
 endif

+ 628 - 0
rtl/embedded/riscv32/fe310g000.pp

@@ -0,0 +1,628 @@
+unit fe310g000;
+interface
+{$PACKRECORDS 2}
+{$GOTO ON}
+{$MODESWITCH ADVANCEDRECORDS}
+
+type
+  TIRQn_Enum   = (
+    NonMaskableInt_IRQn = -14,        // 2 Non Maskable Interrupt
+    MemoryManagement_IRQn = -12,      // 4 Cortex-M4 Memory Management Interrupt
+    BusFault_IRQn = -11,              // 5 Cortex-M4 Bus Fault Interrupt
+    UsageFault_IRQn = -10,            // 6 Cortex-M4 Usage Fault Interrupt
+    SVCall_IRQn = -5,                 // 11 Cortex-M4 SV Call Interrupt
+    DebugMonitor_IRQn = -4,           // 12 Cortex-M4 Debug Monitor Interrupt
+    PendSV_IRQn = -2,                 // 14 Cortex-M4 Pend SV Interrupt
+    SysTick_IRQn = -1,                // 15 Cortex-M4 System Tick Interrupt
+    WWDG_IRQn  = 0,                   // Window WatchDog Interrupt
+    PVD_IRQn   = 1,                   // PVD through EXTI Line detection Interrupt
+    TAMP_STAMP_IRQn = 2,              // Tamper and TimeStamp interrupts through the EXTI line
+    RTC_WKUP_IRQn = 3,                // RTC Wakeup interrupt through the EXTI line
+    FLASH_IRQn = 4,                   // FLASH global Interrupt
+    RCC_IRQn   = 5,                   // RCC global Interrupt
+    EXTI0_IRQn = 6,                   // EXTI Line0 Interrupt
+    EXTI1_IRQn = 7,                   // EXTI Line1 Interrupt
+    EXTI2_IRQn = 8,                   // EXTI Line2 Interrupt
+    EXTI3_IRQn = 9,                   // EXTI Line3 Interrupt
+    EXTI4_IRQn = 10,                  // EXTI Line4 Interrupt
+    DMA1_Stream0_IRQn = 11,           // DMA1 Stream 0 global Interrupt
+    DMA1_Stream1_IRQn = 12,           // DMA1 Stream 1 global Interrupt
+    DMA1_Stream2_IRQn = 13,           // DMA1 Stream 2 global Interrupt
+    DMA1_Stream3_IRQn = 14,           // DMA1 Stream 3 global Interrupt
+    DMA1_Stream4_IRQn = 15,           // DMA1 Stream 4 global Interrupt
+    DMA1_Stream5_IRQn = 16,           // DMA1 Stream 5 global Interrupt
+    DMA1_Stream6_IRQn = 17,           // DMA1 Stream 6 global Interrupt
+    ADC_IRQn   = 18,                  // ADC1, ADC2 and ADC3 global Interrupts
+    CAN1_TX_IRQn = 19,                // CAN1 TX Interrupt
+    CAN1_RX0_IRQn = 20,               // CAN1 RX0 Interrupt
+    CAN1_RX1_IRQn = 21,               // CAN1 RX1 Interrupt
+    CAN1_SCE_IRQn = 22,               // CAN1 SCE Interrupt
+    EXTI9_5_IRQn = 23,                // External Line[9:5] Interrupts
+    TIM1_BRK_TIM9_IRQn = 24,          // TIM1 Break interrupt and TIM9 global interrupt
+    TIM1_UP_TIM10_IRQn = 25,          // TIM1 Update Interrupt and TIM10 global interrupt
+    TIM1_TRG_COM_TIM11_IRQn = 26,     // TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt
+    TIM1_CC_IRQn = 27,                // TIM1 Capture Compare Interrupt
+    TIM2_IRQn  = 28,                  // TIM2 global Interrupt
+    TIM3_IRQn  = 29,                  // TIM3 global Interrupt
+    TIM4_IRQn  = 30,                  // TIM4 global Interrupt
+    I2C1_EV_IRQn = 31,                // I2C1 Event Interrupt
+    I2C1_ER_IRQn = 32,                // I2C1 Error Interrupt
+    I2C2_EV_IRQn = 33,                // I2C2 Event Interrupt
+    I2C2_ER_IRQn = 34,                // I2C2 Error Interrupt
+    SPI1_IRQn  = 35,                  // SPI1 global Interrupt
+    SPI2_IRQn  = 36,                  // SPI2 global Interrupt
+    USART1_IRQn = 37,                 // USART1 global Interrupt
+    USART2_IRQn = 38,                 // USART2 global Interrupt
+    USART3_IRQn = 39,                 // USART3 global Interrupt
+    EXTI15_10_IRQn = 40,              // External Line[15:10] Interrupts
+    RTC_Alarm_IRQn = 41,              // RTC Alarm (A and B) through EXTI Line Interrupt
+    OTG_FS_WKUP_IRQn = 42,            // USB OTG FS Wakeup through EXTI line interrupt
+    TIM8_BRK_TIM12_IRQn = 43,         // TIM8 Break Interrupt and TIM12 global interrupt
+    TIM8_UP_TIM13_IRQn = 44,          // TIM8 Update Interrupt and TIM13 global interrupt
+    TIM8_TRG_COM_TIM14_IRQn = 45,     // TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt
+    TIM8_CC_IRQn = 46,                // TIM8 Capture Compare Interrupt
+    DMA1_Stream7_IRQn = 47,           // DMA1 Stream7 Interrupt
+    FSMC_IRQn  = 48,                  // FSMC global Interrupt
+    SDIO_IRQn  = 49,                  // SDIO global Interrupt
+    TIM5_IRQn  = 50,                  // TIM5 global Interrupt
+    SPI3_IRQn  = 51,                  // SPI3 global Interrupt
+    UART4_IRQn = 52,                  // UART4 global Interrupt
+    UART5_IRQn = 53,                  // UART5 global Interrupt
+    TIM6_DAC_IRQn = 54,               // TIM6 global and DAC1&2 underrun error  interrupts
+    TIM7_IRQn  = 55,                  // TIM7 global interrupt
+    DMA2_Stream0_IRQn = 56,           // DMA2 Stream 0 global Interrupt
+    DMA2_Stream1_IRQn = 57,           // DMA2 Stream 1 global Interrupt
+    DMA2_Stream2_IRQn = 58,           // DMA2 Stream 2 global Interrupt
+    DMA2_Stream3_IRQn = 59,           // DMA2 Stream 3 global Interrupt
+    DMA2_Stream4_IRQn = 60,           // DMA2 Stream 4 global Interrupt
+    ETH_IRQn   = 61,                  // Ethernet global Interrupt
+    ETH_WKUP_IRQn = 62,               // Ethernet Wakeup through EXTI line Interrupt
+    CAN2_TX_IRQn = 63,                // CAN2 TX Interrupt
+    CAN2_RX0_IRQn = 64,               // CAN2 RX0 Interrupt
+    CAN2_RX1_IRQn = 65,               // CAN2 RX1 Interrupt
+    CAN2_SCE_IRQn = 66,               // CAN2 SCE Interrupt
+    OTG_FS_IRQn = 67,                 // USB OTG FS global Interrupt
+    DMA2_Stream5_IRQn = 68,           // DMA2 Stream 5 global interrupt
+    DMA2_Stream6_IRQn = 69,           // DMA2 Stream 6 global interrupt
+    DMA2_Stream7_IRQn = 70,           // DMA2 Stream 7 global interrupt
+    USART6_IRQn = 71,                 // USART6 global interrupt
+    I2C3_EV_IRQn = 72,                // I2C3 event interrupt
+    I2C3_ER_IRQn = 73,                // I2C3 error interrupt
+    OTG_HS_EP1_OUT_IRQn = 74,         // USB OTG HS End Point 1 Out global interrupt
+    OTG_HS_EP1_IN_IRQn = 75,          // USB OTG HS End Point 1 In global interrupt
+    OTG_HS_WKUP_IRQn = 76,            // USB OTG HS Wakeup through EXTI interrupt
+    OTG_HS_IRQn = 77,                 // USB OTG HS global interrupt
+    DCMI_IRQn  = 78,                  // DCMI global interrupt
+    HASH_RNG_IRQn = 80,               // Hash and RNG global interrupt
+    FPU_IRQn   = 81                   // FPU global interrupt
+  );
+
+  TGPIO_Registers = record
+    VALUE     : longWord;
+    INPUT_EN  : longword;
+    OUTPUT_EN : longword;
+    PORT      : longword;
+    PUE       : longword;
+    DS        : longword;
+    RISE_IE   : longword;
+    RISE_IP   : longword;
+    FALL_IE   : longword;
+    FALL_IP   : longword;
+    HIGH_IE   : longword;
+    HIGH_IP   : longword;
+    LOW_IE    : longword;
+    LOW_IP    : longword;
+    IOF_EN    : longword;
+    IOF_SEL   : longword;
+    OUT_XOR   : longword;
+  end;
+
+  // Watchdog Registers
+  TWDT_Registers = record
+    WDOGCFG   : longWord;
+    RESERVED0 : longWord;
+    WDOGCOUNT : longWord;
+    Reserved1 : longWord;
+    WDOGS     : longWord;
+    RESERVED2 : longWord;
+    WDOGFEED  : longWord;
+    WDOGKEY   : longWord;
+    WDOGCMP   : longWord;
+  end;
+
+  // RTC Registers
+  TRTCRegisters = record
+    RTCCFG    : longWord;
+    RESERVED0 : longWord;
+    RTCLO_HI  : longWord;
+    RESERVED1 : longWord;
+    RTCS      : longWord;
+    RESERVED2 : longWord;
+    RESERVED3 : longWord;
+    RESERVED4 : longWord;
+    RTCCMP    : longWord;
+  end;
+
+  TLFROSC_Registers = record
+    LFROSCCFG : longWord;
+  end;
+
+  // Backup Registers
+  TBackup_Registers = record
+    BACKUP : array[0..31] of longWord;
+  end;
+
+  // PMU Registers
+  TPMU_Registers = record
+    PMU_WAKEUP_BASE : longWord;
+    RESERVED0       : array[1..7] of longWord;
+    PWM_SLEEP_BASE  : longWord;
+    RESERVED1       : array[1..7] of longWord;
+    PMUIE           : longWord;
+    PMUCAUSE        : longWord;
+    PMUSLEEP        : longWord;
+    PMUKEY          : longWord;
+  end;
+
+  TI2C_Registers = record
+    PRESCALE_LOW     : longWord;
+    PRESCALE_HIGH    : longWord;
+    CONTROL          :longWord;
+    TRANSMIT_RECEIVE : longWord;
+    COMMAND_STATUS   : longWord;
+  end;
+
+  TPWM_Registers = record
+    PWMCFG    : longWord;
+    RESERVED0 : longWord;
+    PWMCOUNT  : longWord;
+    RESERVED1 : longWord;
+    PWMS      : longWord;
+    RESERVED2 : array[1..3] of longWord;
+    PWMCMP    : array[0..3] of longWord;
+  end;
+
+  TSPI_Registers = record
+    SCKDIV    : longWord;
+    SCKMODE   : longWord;
+    RESERVED0 : longWord;
+    RESERVED1 : longWord;
+    CSID      : longWord;
+    CSDEF     : longWord;
+    CSMODE    : longWord;
+    RESERVED2 : longWord;
+    RESERVED3 : array[1..2] of longWord;
+    DELAY0    : longWord;
+    DELAY1    : longWord;
+    RESERVED4 : array[1..4] of longWord;
+    FMT       : longWord;
+    RESERVED5 : longWord;
+    TXDATA    : longWord;
+    RXDATA    : longWord;
+    TXMARK    : longWord;
+    RESERVED6 : longWord;
+    RXMARK    : longWord;
+    RESERVED7 : array[1..2] of longWord;
+
+    // TODO: Only include if the device supports a direct-map flash interface
+    FCTRL     : longWord;
+    FFMT      : longWord;
+    RESERVED8 : array[1..2] of longWord;
+    IE        : longWord;
+    RESERVED9 : longWord;
+    IP        : longWord;
+  end;
+
+  TUART_Registers = record
+    TXDATA : longWord;
+    RXDATA : longWord;
+    TXCTRL : longWord;
+    RXCTRL : longWord;
+    IE     : longWord;
+    IP     : longWord;
+    &DIV   : longWord;
+  end;
+
+const
+  GPIOA_BASE = $10012000;
+  UART0_BASE = $10013000;
+  SPI0_BASE  = $10014000;
+  PWM0_BASE  = $10015000;
+  I2C0_BASE  = $10016000;
+  UART1_BASE = $10023000;
+  SPI1_BASE  = $10024000;
+  PWM1_BASE  = $10025000;
+  SPI2_BASE  = $10034000;
+  PWM2_BASE  = $10035000;
+  DTIM_BASE  = $80000000;
+
+var
+  GPIOA         : TGPIO_Registers absolute GPIOA_BASE;
+  I2C0          : TI2C_Registers absolute I2C0_BASE;
+  PWM0          : TPWM_Registers absolute PWM0_BASE;
+  PWM1          : TPWM_Registers absolute PWM1_BASE;
+  PWM2          : TPWM_Registers absolute PWM2_BASE;
+  SPI0          : TSPI_Registers absolute SPI0_BASE;
+  SPI1          : TSPI_Registers absolute SPI1_BASE;
+  SPI2          : TSPI_Registers absolute SPI2_BASE;
+  UART0         : TUART_Registers absolute UART0_BASE;
+  UART1         : TUART_Registers absolute UART1_BASE;
+
+implementation
+
+procedure NonMaskableInt_interrupt; external name 'NonMaskableInt_interrupt';
+procedure MemoryManagement_interrupt; external name 'MemoryManagement_interrupt';
+procedure BusFault_interrupt; external name 'BusFault_interrupt';
+procedure UsageFault_interrupt; external name 'UsageFault_interrupt';
+procedure SVCall_interrupt; external name 'SVCall_interrupt';
+procedure DebugMonitor_interrupt; external name 'DebugMonitor_interrupt';
+procedure PendSV_interrupt; external name 'PendSV_interrupt';
+procedure SysTick_interrupt; external name 'SysTick_interrupt';
+procedure WWDG_interrupt; external name 'WWDG_interrupt';
+procedure PVD_interrupt; external name 'PVD_interrupt';
+procedure TAMP_STAMP_interrupt; external name 'TAMP_STAMP_interrupt';
+procedure RTC_WKUP_interrupt; external name 'RTC_WKUP_interrupt';
+procedure FLASH_interrupt; external name 'FLASH_interrupt';
+procedure RCC_interrupt; external name 'RCC_interrupt';
+procedure EXTI0_interrupt; external name 'EXTI0_interrupt';
+procedure EXTI1_interrupt; external name 'EXTI1_interrupt';
+procedure EXTI2_interrupt; external name 'EXTI2_interrupt';
+procedure EXTI3_interrupt; external name 'EXTI3_interrupt';
+procedure EXTI4_interrupt; external name 'EXTI4_interrupt';
+procedure DMA1_Stream0_interrupt; external name 'DMA1_Stream0_interrupt';
+procedure DMA1_Stream1_interrupt; external name 'DMA1_Stream1_interrupt';
+procedure DMA1_Stream2_interrupt; external name 'DMA1_Stream2_interrupt';
+procedure DMA1_Stream3_interrupt; external name 'DMA1_Stream3_interrupt';
+procedure DMA1_Stream4_interrupt; external name 'DMA1_Stream4_interrupt';
+procedure DMA1_Stream5_interrupt; external name 'DMA1_Stream5_interrupt';
+procedure DMA1_Stream6_interrupt; external name 'DMA1_Stream6_interrupt';
+procedure ADC_interrupt; external name 'ADC_interrupt';
+procedure CAN1_TX_interrupt; external name 'CAN1_TX_interrupt';
+procedure CAN1_RX0_interrupt; external name 'CAN1_RX0_interrupt';
+procedure CAN1_RX1_interrupt; external name 'CAN1_RX1_interrupt';
+procedure CAN1_SCE_interrupt; external name 'CAN1_SCE_interrupt';
+procedure EXTI9_5_interrupt; external name 'EXTI9_5_interrupt';
+procedure TIM1_BRK_TIM9_interrupt; external name 'TIM1_BRK_TIM9_interrupt';
+procedure TIM1_UP_TIM10_interrupt; external name 'TIM1_UP_TIM10_interrupt';
+procedure TIM1_TRG_COM_TIM11_interrupt; external name 'TIM1_TRG_COM_TIM11_interrupt';
+procedure TIM1_CC_interrupt; external name 'TIM1_CC_interrupt';
+procedure TIM2_interrupt; external name 'TIM2_interrupt';
+procedure TIM3_interrupt; external name 'TIM3_interrupt';
+procedure TIM4_interrupt; external name 'TIM4_interrupt';
+procedure I2C1_EV_interrupt; external name 'I2C1_EV_interrupt';
+procedure I2C1_ER_interrupt; external name 'I2C1_ER_interrupt';
+procedure I2C2_EV_interrupt; external name 'I2C2_EV_interrupt';
+procedure I2C2_ER_interrupt; external name 'I2C2_ER_interrupt';
+procedure SPI1_interrupt; external name 'SPI1_interrupt';
+procedure SPI2_interrupt; external name 'SPI2_interrupt';
+procedure USART1_interrupt; external name 'USART1_interrupt';
+procedure USART2_interrupt; external name 'USART2_interrupt';
+procedure USART3_interrupt; external name 'USART3_interrupt';
+procedure EXTI15_10_interrupt; external name 'EXTI15_10_interrupt';
+procedure RTC_Alarm_interrupt; external name 'RTC_Alarm_interrupt';
+procedure OTG_FS_WKUP_interrupt; external name 'OTG_FS_WKUP_interrupt';
+procedure TIM8_BRK_TIM12_interrupt; external name 'TIM8_BRK_TIM12_interrupt';
+procedure TIM8_UP_TIM13_interrupt; external name 'TIM8_UP_TIM13_interrupt';
+procedure TIM8_TRG_COM_TIM14_interrupt; external name 'TIM8_TRG_COM_TIM14_interrupt';
+procedure TIM8_CC_interrupt; external name 'TIM8_CC_interrupt';
+procedure DMA1_Stream7_interrupt; external name 'DMA1_Stream7_interrupt';
+procedure FSMC_interrupt; external name 'FSMC_interrupt';
+procedure SDIO_interrupt; external name 'SDIO_interrupt';
+procedure TIM5_interrupt; external name 'TIM5_interrupt';
+procedure SPI3_interrupt; external name 'SPI3_interrupt';
+procedure UART4_interrupt; external name 'UART4_interrupt';
+procedure UART5_interrupt; external name 'UART5_interrupt';
+procedure TIM6_DAC_interrupt; external name 'TIM6_DAC_interrupt';
+procedure TIM7_interrupt; external name 'TIM7_interrupt';
+procedure DMA2_Stream0_interrupt; external name 'DMA2_Stream0_interrupt';
+procedure DMA2_Stream1_interrupt; external name 'DMA2_Stream1_interrupt';
+procedure DMA2_Stream2_interrupt; external name 'DMA2_Stream2_interrupt';
+procedure DMA2_Stream3_interrupt; external name 'DMA2_Stream3_interrupt';
+procedure DMA2_Stream4_interrupt; external name 'DMA2_Stream4_interrupt';
+procedure ETH_interrupt; external name 'ETH_interrupt';
+procedure ETH_WKUP_interrupt; external name 'ETH_WKUP_interrupt';
+procedure CAN2_TX_interrupt; external name 'CAN2_TX_interrupt';
+procedure CAN2_RX0_interrupt; external name 'CAN2_RX0_interrupt';
+procedure CAN2_RX1_interrupt; external name 'CAN2_RX1_interrupt';
+procedure CAN2_SCE_interrupt; external name 'CAN2_SCE_interrupt';
+procedure OTG_FS_interrupt; external name 'OTG_FS_interrupt';
+procedure DMA2_Stream5_interrupt; external name 'DMA2_Stream5_interrupt';
+procedure DMA2_Stream6_interrupt; external name 'DMA2_Stream6_interrupt';
+procedure DMA2_Stream7_interrupt; external name 'DMA2_Stream7_interrupt';
+procedure USART6_interrupt; external name 'USART6_interrupt';
+procedure I2C3_EV_interrupt; external name 'I2C3_EV_interrupt';
+procedure I2C3_ER_interrupt; external name 'I2C3_ER_interrupt';
+procedure OTG_HS_EP1_OUT_interrupt; external name 'OTG_HS_EP1_OUT_interrupt';
+procedure OTG_HS_EP1_IN_interrupt; external name 'OTG_HS_EP1_IN_interrupt';
+procedure OTG_HS_WKUP_interrupt; external name 'OTG_HS_WKUP_interrupt';
+procedure OTG_HS_interrupt; external name 'OTG_HS_interrupt';
+procedure DCMI_interrupt; external name 'DCMI_interrupt';
+procedure HASH_RNG_interrupt; external name 'HASH_RNG_interrupt';
+procedure FPU_interrupt; external name 'FPU_interrupt';
+
+{$i riscv32_start.inc}
+
+procedure Vectors; assembler; nostackframe;
+label interrupt_vectors;
+asm
+  .section ".init.interrupt_vectors"
+  interrupt_vectors:
+  .long _stack_top
+  .long Startup
+  .long NonMaskableInt_interrupt
+  .long 0
+  .long MemoryManagement_interrupt
+  .long BusFault_interrupt
+  .long UsageFault_interrupt
+  .long 0
+  .long 0
+  .long 0
+  .long 0
+  .long SVCall_interrupt
+  .long DebugMonitor_interrupt
+  .long 0
+  .long PendSV_interrupt
+  .long SysTick_interrupt
+  .long WWDG_interrupt
+  .long PVD_interrupt
+  .long TAMP_STAMP_interrupt
+  .long RTC_WKUP_interrupt
+  .long FLASH_interrupt
+  .long RCC_interrupt
+  .long EXTI0_interrupt
+  .long EXTI1_interrupt
+  .long EXTI2_interrupt
+  .long EXTI3_interrupt
+  .long EXTI4_interrupt
+  .long DMA1_Stream0_interrupt
+  .long DMA1_Stream1_interrupt
+  .long DMA1_Stream2_interrupt
+  .long DMA1_Stream3_interrupt
+  .long DMA1_Stream4_interrupt
+  .long DMA1_Stream5_interrupt
+  .long DMA1_Stream6_interrupt
+  .long ADC_interrupt
+  .long CAN1_TX_interrupt
+  .long CAN1_RX0_interrupt
+  .long CAN1_RX1_interrupt
+  .long CAN1_SCE_interrupt
+  .long EXTI9_5_interrupt
+  .long TIM1_BRK_TIM9_interrupt
+  .long TIM1_UP_TIM10_interrupt
+  .long TIM1_TRG_COM_TIM11_interrupt
+  .long TIM1_CC_interrupt
+  .long TIM2_interrupt
+  .long TIM3_interrupt
+  .long TIM4_interrupt
+  .long I2C1_EV_interrupt
+  .long I2C1_ER_interrupt
+  .long I2C2_EV_interrupt
+  .long I2C2_ER_interrupt
+  .long SPI1_interrupt
+  .long SPI2_interrupt
+  .long USART1_interrupt
+  .long USART2_interrupt
+  .long USART3_interrupt
+  .long EXTI15_10_interrupt
+  .long RTC_Alarm_interrupt
+  .long OTG_FS_WKUP_interrupt
+  .long TIM8_BRK_TIM12_interrupt
+  .long TIM8_UP_TIM13_interrupt
+  .long TIM8_TRG_COM_TIM14_interrupt
+  .long TIM8_CC_interrupt
+  .long DMA1_Stream7_interrupt
+  .long FSMC_interrupt
+  .long SDIO_interrupt
+  .long TIM5_interrupt
+  .long SPI3_interrupt
+  .long UART4_interrupt
+  .long UART5_interrupt
+  .long TIM6_DAC_interrupt
+  .long TIM7_interrupt
+  .long DMA2_Stream0_interrupt
+  .long DMA2_Stream1_interrupt
+  .long DMA2_Stream2_interrupt
+  .long DMA2_Stream3_interrupt
+  .long DMA2_Stream4_interrupt
+  .long ETH_interrupt
+  .long ETH_WKUP_interrupt
+  .long CAN2_TX_interrupt
+  .long CAN2_RX0_interrupt
+  .long CAN2_RX1_interrupt
+  .long CAN2_SCE_interrupt
+  .long OTG_FS_interrupt
+  .long DMA2_Stream5_interrupt
+  .long DMA2_Stream6_interrupt
+  .long DMA2_Stream7_interrupt
+  .long USART6_interrupt
+  .long I2C3_EV_interrupt
+  .long I2C3_ER_interrupt
+  .long OTG_HS_EP1_OUT_interrupt
+  .long OTG_HS_EP1_IN_interrupt
+  .long OTG_HS_WKUP_interrupt
+  .long OTG_HS_interrupt
+  .long DCMI_interrupt
+  .long 0
+  .long HASH_RNG_interrupt
+  .long FPU_interrupt
+  .weak NonMaskableInt_interrupt
+  .weak MemoryManagement_interrupt
+  .weak BusFault_interrupt
+  .weak UsageFault_interrupt
+  .weak SVCall_interrupt
+  .weak DebugMonitor_interrupt
+  .weak PendSV_interrupt
+  .weak SysTick_interrupt
+  .weak WWDG_interrupt
+  .weak PVD_interrupt
+  .weak TAMP_STAMP_interrupt
+  .weak RTC_WKUP_interrupt
+  .weak FLASH_interrupt
+  .weak RCC_interrupt
+  .weak EXTI0_interrupt
+  .weak EXTI1_interrupt
+  .weak EXTI2_interrupt
+  .weak EXTI3_interrupt
+  .weak EXTI4_interrupt
+  .weak DMA1_Stream0_interrupt
+  .weak DMA1_Stream1_interrupt
+  .weak DMA1_Stream2_interrupt
+  .weak DMA1_Stream3_interrupt
+  .weak DMA1_Stream4_interrupt
+  .weak DMA1_Stream5_interrupt
+  .weak DMA1_Stream6_interrupt
+  .weak ADC_interrupt
+  .weak CAN1_TX_interrupt
+  .weak CAN1_RX0_interrupt
+  .weak CAN1_RX1_interrupt
+  .weak CAN1_SCE_interrupt
+  .weak EXTI9_5_interrupt
+  .weak TIM1_BRK_TIM9_interrupt
+  .weak TIM1_UP_TIM10_interrupt
+  .weak TIM1_TRG_COM_TIM11_interrupt
+  .weak TIM1_CC_interrupt
+  .weak TIM2_interrupt
+  .weak TIM3_interrupt
+  .weak TIM4_interrupt
+  .weak I2C1_EV_interrupt
+  .weak I2C1_ER_interrupt
+  .weak I2C2_EV_interrupt
+  .weak I2C2_ER_interrupt
+  .weak SPI1_interrupt
+  .weak SPI2_interrupt
+  .weak USART1_interrupt
+  .weak USART2_interrupt
+  .weak USART3_interrupt
+  .weak EXTI15_10_interrupt
+  .weak RTC_Alarm_interrupt
+  .weak OTG_FS_WKUP_interrupt
+  .weak TIM8_BRK_TIM12_interrupt
+  .weak TIM8_UP_TIM13_interrupt
+  .weak TIM8_TRG_COM_TIM14_interrupt
+  .weak TIM8_CC_interrupt
+  .weak DMA1_Stream7_interrupt
+  .weak FSMC_interrupt
+  .weak SDIO_interrupt
+  .weak TIM5_interrupt
+  .weak SPI3_interrupt
+  .weak UART4_interrupt
+  .weak UART5_interrupt
+  .weak TIM6_DAC_interrupt
+  .weak TIM7_interrupt
+  .weak DMA2_Stream0_interrupt
+  .weak DMA2_Stream1_interrupt
+  .weak DMA2_Stream2_interrupt
+  .weak DMA2_Stream3_interrupt
+  .weak DMA2_Stream4_interrupt
+  .weak ETH_interrupt
+  .weak ETH_WKUP_interrupt
+  .weak CAN2_TX_interrupt
+  .weak CAN2_RX0_interrupt
+  .weak CAN2_RX1_interrupt
+  .weak CAN2_SCE_interrupt
+  .weak OTG_FS_interrupt
+  .weak DMA2_Stream5_interrupt
+  .weak DMA2_Stream6_interrupt
+  .weak DMA2_Stream7_interrupt
+  .weak USART6_interrupt
+  .weak I2C3_EV_interrupt
+  .weak I2C3_ER_interrupt
+  .weak OTG_HS_EP1_OUT_interrupt
+  .weak OTG_HS_EP1_IN_interrupt
+  .weak OTG_HS_WKUP_interrupt
+  .weak OTG_HS_interrupt
+  .weak DCMI_interrupt
+  .weak HASH_RNG_interrupt
+  .weak FPU_interrupt
+  .set NonMaskableInt_interrupt, HaltProc
+  .set MemoryManagement_interrupt, HaltProc
+  .set BusFault_interrupt, HaltProc
+  .set UsageFault_interrupt, HaltProc
+  .set SVCall_interrupt, HaltProc
+  .set DebugMonitor_interrupt, HaltProc
+  .set PendSV_interrupt, HaltProc
+  .set SysTick_interrupt, HaltProc
+  .set WWDG_interrupt, HaltProc
+  .set PVD_interrupt, HaltProc
+  .set TAMP_STAMP_interrupt, HaltProc
+  .set RTC_WKUP_interrupt, HaltProc
+  .set FLASH_interrupt, HaltProc
+  .set RCC_interrupt, HaltProc
+  .set EXTI0_interrupt, HaltProc
+  .set EXTI1_interrupt, HaltProc
+  .set EXTI2_interrupt, HaltProc
+  .set EXTI3_interrupt, HaltProc
+  .set EXTI4_interrupt, HaltProc
+  .set DMA1_Stream0_interrupt, HaltProc
+  .set DMA1_Stream1_interrupt, HaltProc
+  .set DMA1_Stream2_interrupt, HaltProc
+  .set DMA1_Stream3_interrupt, HaltProc
+  .set DMA1_Stream4_interrupt, HaltProc
+  .set DMA1_Stream5_interrupt, HaltProc
+  .set DMA1_Stream6_interrupt, HaltProc
+  .set ADC_interrupt, HaltProc
+  .set CAN1_TX_interrupt, HaltProc
+  .set CAN1_RX0_interrupt, HaltProc
+  .set CAN1_RX1_interrupt, HaltProc
+  .set CAN1_SCE_interrupt, HaltProc
+  .set EXTI9_5_interrupt, HaltProc
+  .set TIM1_BRK_TIM9_interrupt, HaltProc
+  .set TIM1_UP_TIM10_interrupt, HaltProc
+  .set TIM1_TRG_COM_TIM11_interrupt, HaltProc
+  .set TIM1_CC_interrupt, HaltProc
+  .set TIM2_interrupt, HaltProc
+  .set TIM3_interrupt, HaltProc
+  .set TIM4_interrupt, HaltProc
+  .set I2C1_EV_interrupt, HaltProc
+  .set I2C1_ER_interrupt, HaltProc
+  .set I2C2_EV_interrupt, HaltProc
+  .set I2C2_ER_interrupt, HaltProc
+  .set SPI1_interrupt, HaltProc
+  .set SPI2_interrupt, HaltProc
+  .set USART1_interrupt, HaltProc
+  .set USART2_interrupt, HaltProc
+  .set USART3_interrupt, HaltProc
+  .set EXTI15_10_interrupt, HaltProc
+  .set RTC_Alarm_interrupt, HaltProc
+  .set OTG_FS_WKUP_interrupt, HaltProc
+  .set TIM8_BRK_TIM12_interrupt, HaltProc
+  .set TIM8_UP_TIM13_interrupt, HaltProc
+  .set TIM8_TRG_COM_TIM14_interrupt, HaltProc
+  .set TIM8_CC_interrupt, HaltProc
+  .set DMA1_Stream7_interrupt, HaltProc
+  .set FSMC_interrupt, HaltProc
+  .set SDIO_interrupt, HaltProc
+  .set TIM5_interrupt, HaltProc
+  .set SPI3_interrupt, HaltProc
+  .set UART4_interrupt, HaltProc
+  .set UART5_interrupt, HaltProc
+  .set TIM6_DAC_interrupt, HaltProc
+  .set TIM7_interrupt, HaltProc
+  .set DMA2_Stream0_interrupt, HaltProc
+  .set DMA2_Stream1_interrupt, HaltProc
+  .set DMA2_Stream2_interrupt, HaltProc
+  .set DMA2_Stream3_interrupt, HaltProc
+  .set DMA2_Stream4_interrupt, HaltProc
+  .set ETH_interrupt, HaltProc
+  .set ETH_WKUP_interrupt, HaltProc
+  .set CAN2_TX_interrupt, HaltProc
+  .set CAN2_RX0_interrupt, HaltProc
+  .set CAN2_RX1_interrupt, HaltProc
+  .set CAN2_SCE_interrupt, HaltProc
+  .set OTG_FS_interrupt, HaltProc
+  .set DMA2_Stream5_interrupt, HaltProc
+  .set DMA2_Stream6_interrupt, HaltProc
+  .set DMA2_Stream7_interrupt, HaltProc
+  .set USART6_interrupt, HaltProc
+  .set I2C3_EV_interrupt, HaltProc
+  .set I2C3_ER_interrupt, HaltProc
+  .set OTG_HS_EP1_OUT_interrupt, HaltProc
+  .set OTG_HS_EP1_IN_interrupt, HaltProc
+  .set OTG_HS_WKUP_interrupt, HaltProc
+  .set OTG_HS_interrupt, HaltProc
+  .set DCMI_interrupt, HaltProc
+  .set HASH_RNG_interrupt, HaltProc
+  .set FPU_interrupt, HaltProc
+  .text
+end;
+end.

+ 631 - 0
rtl/embedded/riscv32/fe310g002.pp

@@ -0,0 +1,631 @@
+unit fe310g002;
+interface
+{$PACKRECORDS 2}
+{$GOTO ON}
+{$MODESWITCH ADVANCEDRECORDS}
+
+type
+  TIRQn_Enum   = (
+    NonMaskableInt_IRQn = -14,        // 2 Non Maskable Interrupt
+    MemoryManagement_IRQn = -12,      // 4 Cortex-M4 Memory Management Interrupt
+    BusFault_IRQn = -11,              // 5 Cortex-M4 Bus Fault Interrupt
+    UsageFault_IRQn = -10,            // 6 Cortex-M4 Usage Fault Interrupt
+    SVCall_IRQn = -5,                 // 11 Cortex-M4 SV Call Interrupt
+    DebugMonitor_IRQn = -4,           // 12 Cortex-M4 Debug Monitor Interrupt
+    PendSV_IRQn = -2,                 // 14 Cortex-M4 Pend SV Interrupt
+    SysTick_IRQn = -1,                // 15 Cortex-M4 System Tick Interrupt
+    WWDG_IRQn  = 0,                   // Window WatchDog Interrupt
+    PVD_IRQn   = 1,                   // PVD through EXTI Line detection Interrupt
+    TAMP_STAMP_IRQn = 2,              // Tamper and TimeStamp interrupts through the EXTI line
+    RTC_WKUP_IRQn = 3,                // RTC Wakeup interrupt through the EXTI line
+    FLASH_IRQn = 4,                   // FLASH global Interrupt
+    RCC_IRQn   = 5,                   // RCC global Interrupt
+    EXTI0_IRQn = 6,                   // EXTI Line0 Interrupt
+    EXTI1_IRQn = 7,                   // EXTI Line1 Interrupt
+    EXTI2_IRQn = 8,                   // EXTI Line2 Interrupt
+    EXTI3_IRQn = 9,                   // EXTI Line3 Interrupt
+    EXTI4_IRQn = 10,                  // EXTI Line4 Interrupt
+    DMA1_Stream0_IRQn = 11,           // DMA1 Stream 0 global Interrupt
+    DMA1_Stream1_IRQn = 12,           // DMA1 Stream 1 global Interrupt
+    DMA1_Stream2_IRQn = 13,           // DMA1 Stream 2 global Interrupt
+    DMA1_Stream3_IRQn = 14,           // DMA1 Stream 3 global Interrupt
+    DMA1_Stream4_IRQn = 15,           // DMA1 Stream 4 global Interrupt
+    DMA1_Stream5_IRQn = 16,           // DMA1 Stream 5 global Interrupt
+    DMA1_Stream6_IRQn = 17,           // DMA1 Stream 6 global Interrupt
+    ADC_IRQn   = 18,                  // ADC1, ADC2 and ADC3 global Interrupts
+    CAN1_TX_IRQn = 19,                // CAN1 TX Interrupt
+    CAN1_RX0_IRQn = 20,               // CAN1 RX0 Interrupt
+    CAN1_RX1_IRQn = 21,               // CAN1 RX1 Interrupt
+    CAN1_SCE_IRQn = 22,               // CAN1 SCE Interrupt
+    EXTI9_5_IRQn = 23,                // External Line[9:5] Interrupts
+    TIM1_BRK_TIM9_IRQn = 24,          // TIM1 Break interrupt and TIM9 global interrupt
+    TIM1_UP_TIM10_IRQn = 25,          // TIM1 Update Interrupt and TIM10 global interrupt
+    TIM1_TRG_COM_TIM11_IRQn = 26,     // TIM1 Trigger and Commutation Interrupt and TIM11 global interrupt
+    TIM1_CC_IRQn = 27,                // TIM1 Capture Compare Interrupt
+    TIM2_IRQn  = 28,                  // TIM2 global Interrupt
+    TIM3_IRQn  = 29,                  // TIM3 global Interrupt
+    TIM4_IRQn  = 30,                  // TIM4 global Interrupt
+    I2C1_EV_IRQn = 31,                // I2C1 Event Interrupt
+    I2C1_ER_IRQn = 32,                // I2C1 Error Interrupt
+    I2C2_EV_IRQn = 33,                // I2C2 Event Interrupt
+    I2C2_ER_IRQn = 34,                // I2C2 Error Interrupt
+    SPI1_IRQn  = 35,                  // SPI1 global Interrupt
+    SPI2_IRQn  = 36,                  // SPI2 global Interrupt
+    USART1_IRQn = 37,                 // USART1 global Interrupt
+    USART2_IRQn = 38,                 // USART2 global Interrupt
+    USART3_IRQn = 39,                 // USART3 global Interrupt
+    EXTI15_10_IRQn = 40,              // External Line[15:10] Interrupts
+    RTC_Alarm_IRQn = 41,              // RTC Alarm (A and B) through EXTI Line Interrupt
+    OTG_FS_WKUP_IRQn = 42,            // USB OTG FS Wakeup through EXTI line interrupt
+    TIM8_BRK_TIM12_IRQn = 43,         // TIM8 Break Interrupt and TIM12 global interrupt
+    TIM8_UP_TIM13_IRQn = 44,          // TIM8 Update Interrupt and TIM13 global interrupt
+    TIM8_TRG_COM_TIM14_IRQn = 45,     // TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt
+    TIM8_CC_IRQn = 46,                // TIM8 Capture Compare Interrupt
+    DMA1_Stream7_IRQn = 47,           // DMA1 Stream7 Interrupt
+    FSMC_IRQn  = 48,                  // FSMC global Interrupt
+    SDIO_IRQn  = 49,                  // SDIO global Interrupt
+    TIM5_IRQn  = 50,                  // TIM5 global Interrupt
+    SPI3_IRQn  = 51,                  // SPI3 global Interrupt
+    UART4_IRQn = 52,                  // UART4 global Interrupt
+    UART5_IRQn = 53,                  // UART5 global Interrupt
+    TIM6_DAC_IRQn = 54,               // TIM6 global and DAC1&2 underrun error  interrupts
+    TIM7_IRQn  = 55,                  // TIM7 global interrupt
+    DMA2_Stream0_IRQn = 56,           // DMA2 Stream 0 global Interrupt
+    DMA2_Stream1_IRQn = 57,           // DMA2 Stream 1 global Interrupt
+    DMA2_Stream2_IRQn = 58,           // DMA2 Stream 2 global Interrupt
+    DMA2_Stream3_IRQn = 59,           // DMA2 Stream 3 global Interrupt
+    DMA2_Stream4_IRQn = 60,           // DMA2 Stream 4 global Interrupt
+    ETH_IRQn   = 61,                  // Ethernet global Interrupt
+    ETH_WKUP_IRQn = 62,               // Ethernet Wakeup through EXTI line Interrupt
+    CAN2_TX_IRQn = 63,                // CAN2 TX Interrupt
+    CAN2_RX0_IRQn = 64,               // CAN2 RX0 Interrupt
+    CAN2_RX1_IRQn = 65,               // CAN2 RX1 Interrupt
+    CAN2_SCE_IRQn = 66,               // CAN2 SCE Interrupt
+    OTG_FS_IRQn = 67,                 // USB OTG FS global Interrupt
+    DMA2_Stream5_IRQn = 68,           // DMA2 Stream 5 global interrupt
+    DMA2_Stream6_IRQn = 69,           // DMA2 Stream 6 global interrupt
+    DMA2_Stream7_IRQn = 70,           // DMA2 Stream 7 global interrupt
+    USART6_IRQn = 71,                 // USART6 global interrupt
+    I2C3_EV_IRQn = 72,                // I2C3 event interrupt
+    I2C3_ER_IRQn = 73,                // I2C3 error interrupt
+    OTG_HS_EP1_OUT_IRQn = 74,         // USB OTG HS End Point 1 Out global interrupt
+    OTG_HS_EP1_IN_IRQn = 75,          // USB OTG HS End Point 1 In global interrupt
+    OTG_HS_WKUP_IRQn = 76,            // USB OTG HS Wakeup through EXTI interrupt
+    OTG_HS_IRQn = 77,                 // USB OTG HS global interrupt
+    DCMI_IRQn  = 78,                  // DCMI global interrupt
+    HASH_RNG_IRQn = 80,               // Hash and RNG global interrupt
+    FPU_IRQn   = 81                   // FPU global interrupt
+  );
+
+  TADC_Registers = record
+  end;
+
+  TGPIO_Registers = record
+    VALUE     : longWord;
+    INPUT_EN  : longword;
+    OUTPUT_EN : longword;
+    PORT      : longword;
+    PUE       : longword;
+    DS        : longword;
+    RISE_IE   : longword;
+    RISE_IP   : longword;
+    FALL_IE   : longword;
+    FALL_IP   : longword;
+    HIGH_IE   : longword;
+    HIGH_IP   : longword;
+    LOW_IE    : longword;
+    LOW_IP    : longword;
+    IOF_EN    : longword;
+    IOF_SEL   : longword;
+    OUT_XOR   : longword;
+  end;
+
+  // Watchdog Registers
+  TWDT_Registers = record
+    WDOGCFG   : longWord;
+    RESERVED0 : longWord;
+    WDOGCOUNT : longWord;
+    Reserved1 : longWord;
+    WDOGS     : longWord;
+    RESERVED2 : longWord;
+    WDOGFEED  : longWord;
+    WDOGKEY   : longWord;
+    WDOGCMP   : longWord;
+  end;
+
+  // RTC Registers
+  TRTCRegisters = record
+    RTCCFG    : longWord;
+    RESERVED0 : longWord;
+    RTCLO_HI  : longWord;
+    RESERVED1 : longWord;
+    RTCS      : longWord;
+    RESERVED2 : longWord;
+    RESERVED3 : longWord;
+    RESERVED4 : longWord;
+    RTCCMP    : longWord;
+  end;
+
+  TLFROSC_Registers = record
+    LFROSCCFG : longWord;
+  end;
+
+  // Backup Registers
+  TBackup_Registers = record
+    BACKUP : array[0..31] of longWord;
+  end;
+
+  // PMU Registers
+  TPMU_Registers = record
+    PMU_WAKEUP_BASE : longWord;
+    RESERVED0       : array[1..7] of longWord;
+    PWM_SLEEP_BASE  : longWord;
+    RESERVED1       : array[1..7] of longWord;
+    PMUIE           : longWord;
+    PMUCAUSE        : longWord;
+    PMUSLEEP        : longWord;
+    PMUKEY          : longWord;
+  end;
+
+  TI2C_Registers = record
+    PRESCALE_LOW     : longWord;
+    PRESCALE_HIGH    : longWord;
+    CONTROL          :longWord;
+    TRANSMIT_RECEIVE : longWord;
+    COMMAND_STATUS   : longWord;
+  end;
+
+  TPWM_Registers = record
+    PWMCFG    : longWord;
+    RESERVED0 : longWord;
+    PWMCOUNT  : longWord;
+    RESERVED1 : longWord;
+    PWMS      : longWord;
+    RESERVED2 : array[1..3] of longWord;
+    PWMCMP    : array[0..3] of longWord;
+  end;
+
+  TSPI_Registers = record
+    SCKDIV    : longWord;
+    SCKMODE   : longWord;
+    RESERVED0 : longWord;
+    RESERVED1 : longWord;
+    CSID      : longWord;
+    CSDEF     : longWord;
+    CSMODE    : longWord;
+    RESERVED2 : longWord;
+    RESERVED3 : array[1..2] of longWord;
+    DELAY0    : longWord;
+    DELAY1    : longWord;
+    RESERVED4 : array[1..4] of longWord;
+    FMT       : longWord;
+    RESERVED5 : longWord;
+    TXDATA    : longWord;
+    RXDATA    : longWord;
+    TXMARK    : longWord;
+    RESERVED6 : longWord;
+    RXMARK    : longWord;
+    RESERVED7 : array[1..2] of longWord;
+
+    // TODO: Only include if the device supports a direct-map flash interface
+    FCTRL     : longWord;
+    FFMT      : longWord;
+    RESERVED8 : array[1..2] of longWord;
+    IE        : longWord;
+    RESERVED9 : longWord;
+    IP        : longWord;
+  end;
+
+  TUART_Registers = record
+    TXDATA : longWord;
+    RXDATA : longWord;
+    TXCTRL : longWord;
+    RXCTRL : longWord;
+    IE     : longWord;
+    IP     : longWord;
+    &DIV   : longWord;
+  end;
+
+const
+  GPIOA_BASE = $10012000;
+  UART0_BASE = $10013000;
+  SPI0_BASE  = $10014000;
+  PWM0_BASE  = $10015000;
+  I2C0_BASE  = $10016000;
+  UART1_BASE = $10023000;
+  SPI1_BASE  = $10024000;
+  PWM1_BASE  = $10025000;
+  SPI2_BASE  = $10034000;
+  PWM2_BASE  = $10035000;
+  DTIM_BASE  = $80000000;
+
+var
+  GPIOA         : TGPIO_Registers absolute GPIOA_BASE;
+  I2C0          : TI2C_Registers absolute I2C0_BASE;
+  PWM0          : TPWM_Registers absolute PWM0_BASE;
+  PWM1          : TPWM_Registers absolute PWM1_BASE;
+  PWM2          : TPWM_Registers absolute PWM2_BASE;
+  SPI0          : TSPI_Registers absolute SPI0_BASE;
+  SPI1          : TSPI_Registers absolute SPI1_BASE;
+  SPI2          : TSPI_Registers absolute SPI2_BASE;
+  UART0         : TUART_Registers absolute UART0_BASE;
+  UART1         : TUART_Registers absolute UART1_BASE;
+
+implementation
+
+procedure NonMaskableInt_interrupt; external name 'NonMaskableInt_interrupt';
+procedure MemoryManagement_interrupt; external name 'MemoryManagement_interrupt';
+procedure BusFault_interrupt; external name 'BusFault_interrupt';
+procedure UsageFault_interrupt; external name 'UsageFault_interrupt';
+procedure SVCall_interrupt; external name 'SVCall_interrupt';
+procedure DebugMonitor_interrupt; external name 'DebugMonitor_interrupt';
+procedure PendSV_interrupt; external name 'PendSV_interrupt';
+procedure SysTick_interrupt; external name 'SysTick_interrupt';
+procedure WWDG_interrupt; external name 'WWDG_interrupt';
+procedure PVD_interrupt; external name 'PVD_interrupt';
+procedure TAMP_STAMP_interrupt; external name 'TAMP_STAMP_interrupt';
+procedure RTC_WKUP_interrupt; external name 'RTC_WKUP_interrupt';
+procedure FLASH_interrupt; external name 'FLASH_interrupt';
+procedure RCC_interrupt; external name 'RCC_interrupt';
+procedure EXTI0_interrupt; external name 'EXTI0_interrupt';
+procedure EXTI1_interrupt; external name 'EXTI1_interrupt';
+procedure EXTI2_interrupt; external name 'EXTI2_interrupt';
+procedure EXTI3_interrupt; external name 'EXTI3_interrupt';
+procedure EXTI4_interrupt; external name 'EXTI4_interrupt';
+procedure DMA1_Stream0_interrupt; external name 'DMA1_Stream0_interrupt';
+procedure DMA1_Stream1_interrupt; external name 'DMA1_Stream1_interrupt';
+procedure DMA1_Stream2_interrupt; external name 'DMA1_Stream2_interrupt';
+procedure DMA1_Stream3_interrupt; external name 'DMA1_Stream3_interrupt';
+procedure DMA1_Stream4_interrupt; external name 'DMA1_Stream4_interrupt';
+procedure DMA1_Stream5_interrupt; external name 'DMA1_Stream5_interrupt';
+procedure DMA1_Stream6_interrupt; external name 'DMA1_Stream6_interrupt';
+procedure ADC_interrupt; external name 'ADC_interrupt';
+procedure CAN1_TX_interrupt; external name 'CAN1_TX_interrupt';
+procedure CAN1_RX0_interrupt; external name 'CAN1_RX0_interrupt';
+procedure CAN1_RX1_interrupt; external name 'CAN1_RX1_interrupt';
+procedure CAN1_SCE_interrupt; external name 'CAN1_SCE_interrupt';
+procedure EXTI9_5_interrupt; external name 'EXTI9_5_interrupt';
+procedure TIM1_BRK_TIM9_interrupt; external name 'TIM1_BRK_TIM9_interrupt';
+procedure TIM1_UP_TIM10_interrupt; external name 'TIM1_UP_TIM10_interrupt';
+procedure TIM1_TRG_COM_TIM11_interrupt; external name 'TIM1_TRG_COM_TIM11_interrupt';
+procedure TIM1_CC_interrupt; external name 'TIM1_CC_interrupt';
+procedure TIM2_interrupt; external name 'TIM2_interrupt';
+procedure TIM3_interrupt; external name 'TIM3_interrupt';
+procedure TIM4_interrupt; external name 'TIM4_interrupt';
+procedure I2C1_EV_interrupt; external name 'I2C1_EV_interrupt';
+procedure I2C1_ER_interrupt; external name 'I2C1_ER_interrupt';
+procedure I2C2_EV_interrupt; external name 'I2C2_EV_interrupt';
+procedure I2C2_ER_interrupt; external name 'I2C2_ER_interrupt';
+procedure SPI1_interrupt; external name 'SPI1_interrupt';
+procedure SPI2_interrupt; external name 'SPI2_interrupt';
+procedure USART1_interrupt; external name 'USART1_interrupt';
+procedure USART2_interrupt; external name 'USART2_interrupt';
+procedure USART3_interrupt; external name 'USART3_interrupt';
+procedure EXTI15_10_interrupt; external name 'EXTI15_10_interrupt';
+procedure RTC_Alarm_interrupt; external name 'RTC_Alarm_interrupt';
+procedure OTG_FS_WKUP_interrupt; external name 'OTG_FS_WKUP_interrupt';
+procedure TIM8_BRK_TIM12_interrupt; external name 'TIM8_BRK_TIM12_interrupt';
+procedure TIM8_UP_TIM13_interrupt; external name 'TIM8_UP_TIM13_interrupt';
+procedure TIM8_TRG_COM_TIM14_interrupt; external name 'TIM8_TRG_COM_TIM14_interrupt';
+procedure TIM8_CC_interrupt; external name 'TIM8_CC_interrupt';
+procedure DMA1_Stream7_interrupt; external name 'DMA1_Stream7_interrupt';
+procedure FSMC_interrupt; external name 'FSMC_interrupt';
+procedure SDIO_interrupt; external name 'SDIO_interrupt';
+procedure TIM5_interrupt; external name 'TIM5_interrupt';
+procedure SPI3_interrupt; external name 'SPI3_interrupt';
+procedure UART4_interrupt; external name 'UART4_interrupt';
+procedure UART5_interrupt; external name 'UART5_interrupt';
+procedure TIM6_DAC_interrupt; external name 'TIM6_DAC_interrupt';
+procedure TIM7_interrupt; external name 'TIM7_interrupt';
+procedure DMA2_Stream0_interrupt; external name 'DMA2_Stream0_interrupt';
+procedure DMA2_Stream1_interrupt; external name 'DMA2_Stream1_interrupt';
+procedure DMA2_Stream2_interrupt; external name 'DMA2_Stream2_interrupt';
+procedure DMA2_Stream3_interrupt; external name 'DMA2_Stream3_interrupt';
+procedure DMA2_Stream4_interrupt; external name 'DMA2_Stream4_interrupt';
+procedure ETH_interrupt; external name 'ETH_interrupt';
+procedure ETH_WKUP_interrupt; external name 'ETH_WKUP_interrupt';
+procedure CAN2_TX_interrupt; external name 'CAN2_TX_interrupt';
+procedure CAN2_RX0_interrupt; external name 'CAN2_RX0_interrupt';
+procedure CAN2_RX1_interrupt; external name 'CAN2_RX1_interrupt';
+procedure CAN2_SCE_interrupt; external name 'CAN2_SCE_interrupt';
+procedure OTG_FS_interrupt; external name 'OTG_FS_interrupt';
+procedure DMA2_Stream5_interrupt; external name 'DMA2_Stream5_interrupt';
+procedure DMA2_Stream6_interrupt; external name 'DMA2_Stream6_interrupt';
+procedure DMA2_Stream7_interrupt; external name 'DMA2_Stream7_interrupt';
+procedure USART6_interrupt; external name 'USART6_interrupt';
+procedure I2C3_EV_interrupt; external name 'I2C3_EV_interrupt';
+procedure I2C3_ER_interrupt; external name 'I2C3_ER_interrupt';
+procedure OTG_HS_EP1_OUT_interrupt; external name 'OTG_HS_EP1_OUT_interrupt';
+procedure OTG_HS_EP1_IN_interrupt; external name 'OTG_HS_EP1_IN_interrupt';
+procedure OTG_HS_WKUP_interrupt; external name 'OTG_HS_WKUP_interrupt';
+procedure OTG_HS_interrupt; external name 'OTG_HS_interrupt';
+procedure DCMI_interrupt; external name 'DCMI_interrupt';
+procedure HASH_RNG_interrupt; external name 'HASH_RNG_interrupt';
+procedure FPU_interrupt; external name 'FPU_interrupt';
+
+{$i riscv32_start.inc}
+
+procedure Vectors; assembler; nostackframe;
+label interrupt_vectors;
+asm
+  .section ".init.interrupt_vectors"
+  interrupt_vectors:
+  jal _stack_top
+  jal Startup
+  jal NonMaskableInt_interrupt
+  .long 0
+  .long MemoryManagement_interrupt
+  .long BusFault_interrupt
+  .long UsageFault_interrupt
+  .long 0
+  .long 0
+  .long 0
+  .long 0
+  .long SVCall_interrupt
+  .long DebugMonitor_interrupt
+  .long 0
+  .long PendSV_interrupt
+  .long SysTick_interrupt
+  .long WWDG_interrupt
+  .long PVD_interrupt
+  .long TAMP_STAMP_interrupt
+  .long RTC_WKUP_interrupt
+  .long FLASH_interrupt
+  .long RCC_interrupt
+  .long EXTI0_interrupt
+  .long EXTI1_interrupt
+  .long EXTI2_interrupt
+  .long EXTI3_interrupt
+  .long EXTI4_interrupt
+  .long DMA1_Stream0_interrupt
+  .long DMA1_Stream1_interrupt
+  .long DMA1_Stream2_interrupt
+  .long DMA1_Stream3_interrupt
+  .long DMA1_Stream4_interrupt
+  .long DMA1_Stream5_interrupt
+  .long DMA1_Stream6_interrupt
+  .long ADC_interrupt
+  .long CAN1_TX_interrupt
+  .long CAN1_RX0_interrupt
+  .long CAN1_RX1_interrupt
+  .long CAN1_SCE_interrupt
+  .long EXTI9_5_interrupt
+  .long TIM1_BRK_TIM9_interrupt
+  .long TIM1_UP_TIM10_interrupt
+  .long TIM1_TRG_COM_TIM11_interrupt
+  .long TIM1_CC_interrupt
+  .long TIM2_interrupt
+  .long TIM3_interrupt
+  .long TIM4_interrupt
+  .long I2C1_EV_interrupt
+  .long I2C1_ER_interrupt
+  .long I2C2_EV_interrupt
+  .long I2C2_ER_interrupt
+  .long SPI1_interrupt
+  .long SPI2_interrupt
+  .long USART1_interrupt
+  .long USART2_interrupt
+  .long USART3_interrupt
+  .long EXTI15_10_interrupt
+  .long RTC_Alarm_interrupt
+  .long OTG_FS_WKUP_interrupt
+  .long TIM8_BRK_TIM12_interrupt
+  .long TIM8_UP_TIM13_interrupt
+  .long TIM8_TRG_COM_TIM14_interrupt
+  .long TIM8_CC_interrupt
+  .long DMA1_Stream7_interrupt
+  .long FSMC_interrupt
+  .long SDIO_interrupt
+  .long TIM5_interrupt
+  .long SPI3_interrupt
+  .long UART4_interrupt
+  .long UART5_interrupt
+  .long TIM6_DAC_interrupt
+  .long TIM7_interrupt
+  .long DMA2_Stream0_interrupt
+  .long DMA2_Stream1_interrupt
+  .long DMA2_Stream2_interrupt
+  .long DMA2_Stream3_interrupt
+  .long DMA2_Stream4_interrupt
+  .long ETH_interrupt
+  .long ETH_WKUP_interrupt
+  .long CAN2_TX_interrupt
+  .long CAN2_RX0_interrupt
+  .long CAN2_RX1_interrupt
+  .long CAN2_SCE_interrupt
+  .long OTG_FS_interrupt
+  .long DMA2_Stream5_interrupt
+  .long DMA2_Stream6_interrupt
+  .long DMA2_Stream7_interrupt
+  .long USART6_interrupt
+  .long I2C3_EV_interrupt
+  .long I2C3_ER_interrupt
+  .long OTG_HS_EP1_OUT_interrupt
+  .long OTG_HS_EP1_IN_interrupt
+  .long OTG_HS_WKUP_interrupt
+  .long OTG_HS_interrupt
+  .long DCMI_interrupt
+  .long 0
+  .long HASH_RNG_interrupt
+  .long FPU_interrupt
+  .weak NonMaskableInt_interrupt
+  .weak MemoryManagement_interrupt
+  .weak BusFault_interrupt
+  .weak UsageFault_interrupt
+  .weak SVCall_interrupt
+  .weak DebugMonitor_interrupt
+  .weak PendSV_interrupt
+  .weak SysTick_interrupt
+  .weak WWDG_interrupt
+  .weak PVD_interrupt
+  .weak TAMP_STAMP_interrupt
+  .weak RTC_WKUP_interrupt
+  .weak FLASH_interrupt
+  .weak RCC_interrupt
+  .weak EXTI0_interrupt
+  .weak EXTI1_interrupt
+  .weak EXTI2_interrupt
+  .weak EXTI3_interrupt
+  .weak EXTI4_interrupt
+  .weak DMA1_Stream0_interrupt
+  .weak DMA1_Stream1_interrupt
+  .weak DMA1_Stream2_interrupt
+  .weak DMA1_Stream3_interrupt
+  .weak DMA1_Stream4_interrupt
+  .weak DMA1_Stream5_interrupt
+  .weak DMA1_Stream6_interrupt
+  .weak ADC_interrupt
+  .weak CAN1_TX_interrupt
+  .weak CAN1_RX0_interrupt
+  .weak CAN1_RX1_interrupt
+  .weak CAN1_SCE_interrupt
+  .weak EXTI9_5_interrupt
+  .weak TIM1_BRK_TIM9_interrupt
+  .weak TIM1_UP_TIM10_interrupt
+  .weak TIM1_TRG_COM_TIM11_interrupt
+  .weak TIM1_CC_interrupt
+  .weak TIM2_interrupt
+  .weak TIM3_interrupt
+  .weak TIM4_interrupt
+  .weak I2C1_EV_interrupt
+  .weak I2C1_ER_interrupt
+  .weak I2C2_EV_interrupt
+  .weak I2C2_ER_interrupt
+  .weak SPI1_interrupt
+  .weak SPI2_interrupt
+  .weak USART1_interrupt
+  .weak USART2_interrupt
+  .weak USART3_interrupt
+  .weak EXTI15_10_interrupt
+  .weak RTC_Alarm_interrupt
+  .weak OTG_FS_WKUP_interrupt
+  .weak TIM8_BRK_TIM12_interrupt
+  .weak TIM8_UP_TIM13_interrupt
+  .weak TIM8_TRG_COM_TIM14_interrupt
+  .weak TIM8_CC_interrupt
+  .weak DMA1_Stream7_interrupt
+  .weak FSMC_interrupt
+  .weak SDIO_interrupt
+  .weak TIM5_interrupt
+  .weak SPI3_interrupt
+  .weak UART4_interrupt
+  .weak UART5_interrupt
+  .weak TIM6_DAC_interrupt
+  .weak TIM7_interrupt
+  .weak DMA2_Stream0_interrupt
+  .weak DMA2_Stream1_interrupt
+  .weak DMA2_Stream2_interrupt
+  .weak DMA2_Stream3_interrupt
+  .weak DMA2_Stream4_interrupt
+  .weak ETH_interrupt
+  .weak ETH_WKUP_interrupt
+  .weak CAN2_TX_interrupt
+  .weak CAN2_RX0_interrupt
+  .weak CAN2_RX1_interrupt
+  .weak CAN2_SCE_interrupt
+  .weak OTG_FS_interrupt
+  .weak DMA2_Stream5_interrupt
+  .weak DMA2_Stream6_interrupt
+  .weak DMA2_Stream7_interrupt
+  .weak USART6_interrupt
+  .weak I2C3_EV_interrupt
+  .weak I2C3_ER_interrupt
+  .weak OTG_HS_EP1_OUT_interrupt
+  .weak OTG_HS_EP1_IN_interrupt
+  .weak OTG_HS_WKUP_interrupt
+  .weak OTG_HS_interrupt
+  .weak DCMI_interrupt
+  .weak HASH_RNG_interrupt
+  .weak FPU_interrupt
+  .set NonMaskableInt_interrupt, HaltProc
+  .set MemoryManagement_interrupt, HaltProc
+  .set BusFault_interrupt, HaltProc
+  .set UsageFault_interrupt, HaltProc
+  .set SVCall_interrupt, HaltProc
+  .set DebugMonitor_interrupt, HaltProc
+  .set PendSV_interrupt, HaltProc
+  .set SysTick_interrupt, HaltProc
+  .set WWDG_interrupt, HaltProc
+  .set PVD_interrupt, HaltProc
+  .set TAMP_STAMP_interrupt, HaltProc
+  .set RTC_WKUP_interrupt, HaltProc
+  .set FLASH_interrupt, HaltProc
+  .set RCC_interrupt, HaltProc
+  .set EXTI0_interrupt, HaltProc
+  .set EXTI1_interrupt, HaltProc
+  .set EXTI2_interrupt, HaltProc
+  .set EXTI3_interrupt, HaltProc
+  .set EXTI4_interrupt, HaltProc
+  .set DMA1_Stream0_interrupt, HaltProc
+  .set DMA1_Stream1_interrupt, HaltProc
+  .set DMA1_Stream2_interrupt, HaltProc
+  .set DMA1_Stream3_interrupt, HaltProc
+  .set DMA1_Stream4_interrupt, HaltProc
+  .set DMA1_Stream5_interrupt, HaltProc
+  .set DMA1_Stream6_interrupt, HaltProc
+  .set ADC_interrupt, HaltProc
+  .set CAN1_TX_interrupt, HaltProc
+  .set CAN1_RX0_interrupt, HaltProc
+  .set CAN1_RX1_interrupt, HaltProc
+  .set CAN1_SCE_interrupt, HaltProc
+  .set EXTI9_5_interrupt, HaltProc
+  .set TIM1_BRK_TIM9_interrupt, HaltProc
+  .set TIM1_UP_TIM10_interrupt, HaltProc
+  .set TIM1_TRG_COM_TIM11_interrupt, HaltProc
+  .set TIM1_CC_interrupt, HaltProc
+  .set TIM2_interrupt, HaltProc
+  .set TIM3_interrupt, HaltProc
+  .set TIM4_interrupt, HaltProc
+  .set I2C1_EV_interrupt, HaltProc
+  .set I2C1_ER_interrupt, HaltProc
+  .set I2C2_EV_interrupt, HaltProc
+  .set I2C2_ER_interrupt, HaltProc
+  .set SPI1_interrupt, HaltProc
+  .set SPI2_interrupt, HaltProc
+  .set USART1_interrupt, HaltProc
+  .set USART2_interrupt, HaltProc
+  .set USART3_interrupt, HaltProc
+  .set EXTI15_10_interrupt, HaltProc
+  .set RTC_Alarm_interrupt, HaltProc
+  .set OTG_FS_WKUP_interrupt, HaltProc
+  .set TIM8_BRK_TIM12_interrupt, HaltProc
+  .set TIM8_UP_TIM13_interrupt, HaltProc
+  .set TIM8_TRG_COM_TIM14_interrupt, HaltProc
+  .set TIM8_CC_interrupt, HaltProc
+  .set DMA1_Stream7_interrupt, HaltProc
+  .set FSMC_interrupt, HaltProc
+  .set SDIO_interrupt, HaltProc
+  .set TIM5_interrupt, HaltProc
+  .set SPI3_interrupt, HaltProc
+  .set UART4_interrupt, HaltProc
+  .set UART5_interrupt, HaltProc
+  .set TIM6_DAC_interrupt, HaltProc
+  .set TIM7_interrupt, HaltProc
+  .set DMA2_Stream0_interrupt, HaltProc
+  .set DMA2_Stream1_interrupt, HaltProc
+  .set DMA2_Stream2_interrupt, HaltProc
+  .set DMA2_Stream3_interrupt, HaltProc
+  .set DMA2_Stream4_interrupt, HaltProc
+  .set ETH_interrupt, HaltProc
+  .set ETH_WKUP_interrupt, HaltProc
+  .set CAN2_TX_interrupt, HaltProc
+  .set CAN2_RX0_interrupt, HaltProc
+  .set CAN2_RX1_interrupt, HaltProc
+  .set CAN2_SCE_interrupt, HaltProc
+  .set OTG_FS_interrupt, HaltProc
+  .set DMA2_Stream5_interrupt, HaltProc
+  .set DMA2_Stream6_interrupt, HaltProc
+  .set DMA2_Stream7_interrupt, HaltProc
+  .set USART6_interrupt, HaltProc
+  .set I2C3_EV_interrupt, HaltProc
+  .set I2C3_ER_interrupt, HaltProc
+  .set OTG_HS_EP1_OUT_interrupt, HaltProc
+  .set OTG_HS_EP1_IN_interrupt, HaltProc
+  .set OTG_HS_WKUP_interrupt, HaltProc
+  .set OTG_HS_interrupt, HaltProc
+  .set DCMI_interrupt, HaltProc
+  .set HASH_RNG_interrupt, HaltProc
+  .set FPU_interrupt, HaltProc
+  .text
+end;
+end.

+ 796 - 0
rtl/embedded/riscv32/gd32vf103xx.pp

@@ -0,0 +1,796 @@
+unit gd32vf103xx;
+interface
+{$PACKRECORDS 2}
+{$GOTO ON}
+{$MODESWITCH ADVANCEDRECORDS}
+
+//Interrupt Number Definition
+type
+  TIRQn_Enum = (
+    CLIC_RESERVED_IRQn  = 0,     // RISC-V reserved
+    CLIC_SFT_IRQn       = 3,     // Software interrupt
+    CLIC_TMR_IRQn       = 7,     // CPU Timer interrupt
+    CLIC_BWEI_IRQn      = 17,    // Bus Error interrupt
+    CLIC_PMOVI_IRQn     = 18,    // Performance Monitor
+
+    // interruput numbers
+    WWDGT_IRQn          = 19,    // window watchDog timer interrupt 
+    LVD_IRQn            = 20,    // LVD through EXTI line detect interrupt 
+    TAMPER_IRQn         = 21,    // tamper through EXTI line detect 
+    RTC_IRQn            = 22,    // RTC alarm interrupt 
+    FMC_IRQn            = 23,    // FMC interrupt 
+    RCU_CTC_IRQn        = 24,    // RCU and CTC interrupt 
+    EXTI0_IRQn          = 25,    // EXTI line 0 interrupts 
+    EXTI1_IRQn          = 26,    // EXTI line 1 interrupts 
+    EXTI2_IRQn          = 27,    // EXTI line 2 interrupts 
+    EXTI3_IRQn          = 28,    // EXTI line 3 interrupts 
+    EXTI4_IRQn          = 29,    // EXTI line 4 interrupts 
+    DMA0_Channel0_IRQn  = 30,    // DMA0 channel0 interrupt 
+    DMA0_Channel1_IRQn  = 31,    // DMA0 channel1 interrupt 
+    DMA0_Channel2_IRQn  = 32,    // DMA0 channel2 interrupt 
+    DMA0_Channel3_IRQn  = 33,    // DMA0 channel3 interrupt 
+    DMA0_Channel4_IRQn  = 34,    // DMA0 channel4 interrupt 
+    DMA0_Channel5_IRQn  = 35,    // DMA0 channel5 interrupt 
+    DMA0_Channel6_IRQn  = 36,    // DMA0 channel6 interrupt 
+    ADC0_1_IRQn         = 37,    // ADC0 and ADC1 interrupt 
+    CAN0_TX_IRQn        = 38,    // CAN0 TX interrupts 
+    CAN0_RX0_IRQn       = 39,    // CAN0 RX0 interrupts 
+    CAN0_RX1_IRQn       = 40,    // CAN0 RX1 interrupts 
+    CAN0_EWMC_IRQn      = 41,    // CAN0 EWMC interrupts 
+    EXTI5_9_IRQn        = 42,    // EXTI[9:5] interrupts 
+    TIMER0_BRK_IRQn     = 43,    // TIMER0 break interrupts 
+    TIMER0_UP_IRQn      = 44,    // TIMER0 update interrupts 
+    TIMER0_TRG_CMT_IRQn = 45,    // TIMER0 trigger and commutation interrupts 
+    TIMER0_Channel_IRQn = 46,    // TIMER0 channel capture compare interrupts 
+    TIMER1_IRQn         = 47,    // TIMER1 interrupt 
+    TIMER2_IRQn         = 48,    // TIMER2 interrupt 
+    TIMER3_IRQn         = 49,    // TIMER3 interrupts 
+    I2C0_EV_IRQn        = 50,    // I2C0 event interrupt 
+    I2C0_ER_IRQn        = 51,    // I2C0 error interrupt 
+    I2C1_EV_IRQn        = 52,    // I2C1 event interrupt 
+    I2C1_ER_IRQn        = 53,    // I2C1 error interrupt 
+    SPI0_IRQn           = 54,    // SPI0 interrupt 
+    SPI1_IRQn           = 55,    // SPI1 interrupt 
+    USART0_IRQn         = 56,    // USART0 interrupt 
+    USART1_IRQn         = 57,    // USART1 interrupt 
+    USART2_IRQn         = 58,    // USART2 interrupt 
+    EXTI10_15_IRQn      = 59,    // EXTI[15:10] interrupts 
+    RTC_ALARM_IRQn      = 60,    // RTC alarm interrupt EXTI 
+    USBFS_WKUP_IRQn     = 61,    // USBFS wakeup interrupt 
+
+    EXMC_IRQn           = 67,    // EXMC global interrupt 
+
+    TIMER4_IRQn         = 69,    // TIMER4 global interrupt 
+    SPI2_IRQn           = 70,    // SPI2 global interrupt 
+    UART3_IRQn          = 71,    // UART3 global interrupt 
+    UART4_IRQn          = 72,    // UART4 global interrupt 
+    TIMER5_IRQn         = 73,    // TIMER5 global interrupt 
+    TIMER6_IRQn         = 74,    // TIMER6 global interrupt 
+    DMA1_Channel0_IRQn  = 75,    // DMA1 channel0 global interrupt 
+    DMA1_Channel1_IRQn  = 76,    // DMA1 channel1 global interrupt 
+    DMA1_Channel2_IRQn  = 77,    // DMA1 channel2 global interrupt 
+    DMA1_Channel3_IRQn  = 78,    // DMA1 channel3 global interrupt 
+    DMA1_Channel4_IRQn  = 79,    // DMA1 channel3 global interrupt 
+
+    CAN1_TX_IRQn        = 82,    // CAN1 TX interrupt 
+    CAN1_RX0_IRQn       = 83,    // CAN1 RX0 interrupt 
+    CAN1_RX1_IRQn       = 84,    // CAN1 RX1 interrupt 
+    CAN1_EWMC_IRQn      = 85,    // CAN1 EWMC interrupt 
+    USBFS_IRQn          = 86     // USBFS global interrupt 
+  );
+
+//Analog to Digital Converter
+
+  TADC_Registers = record
+    STAT      : longword;        // ADC status register 
+    CTL0      : longword;        // ADC control register 0 
+    CTL1      : longword;        // ADC control register 1 
+    SAMPT0    : longword;        // ADC sampling time register 0 
+    SAMPT1    : longword;        // ADC sampling time register 1 
+    IOFF0     : longword;        // ADC inserted channel data offset register 0 
+    IOFF1     : longword;        // ADC inserted channel data offset register 1 
+    IOFF2     : longword;        // ADC inserted channel data offset register 2 
+    IOFF3     : longword;        // ADC inserted channel data offset register 3 
+    WDHT      : longword;        // ADC watchdog high threshold register 
+    WDLT      : longword;        // ADC watchdog low threshold register 
+    RSQ0      : longword;        // ADC regular sequence register 0 
+    RSQ1      : longword;        // ADC regular sequence register 1 
+    RSQ2      : longword;        // ADC regular sequence register 2 
+    ISQ       : longword;        // ADC inserted sequence register 
+    IDATA0    : longword;        // ADC inserted data register 0 
+    IDATA1    : longword;        // ADC inserted data register 1 
+    IDATA2    : longword;        // ADC inserted data register 2 
+    IDATA3    : longword;        // ADC inserted data register 3 
+    RDATA     : longword;        // ADC regular data register 
+    RESERVED0 : array[1..12] of longword;
+    OVSCR     : longword;        // ADC oversample control register 
+  end;
+
+  TCAN_MAILBOX_Registers = record
+    TMI       : longword;        // CAN transmit mailbox0 identifier register 
+    TMP       : longword;        // CAN transmit mailbox0 property register 
+    TMDATA0   : longword;        // CAN transmit mailbox0 data0 register 
+    TMDATA1   : longword;        // CAN transmit mailbox0 data1 register 
+  end;
+
+  TCAN_FIFO_Registers = record
+    RFIFOMI   : longword;        // CAN receive FIFO0 mailbox identifier register 
+    RFIFOMP0  : longword;        // CAN receive FIFO0 mailbox property register 
+    RFIFOMDATA0 : longword;      // CAN receive FIFO0 mailbox data0 register 
+    RFIFOMDATA1 : longword;      // CAN receive FIFO0 mailbox data1 register 
+  end;
+
+  TCAN_FILTER_Registers = record
+    DATA0     : longword;
+    DATA1     : longword;
+  end;
+
+(*
+  TCAN_Registers = record
+    CTL       : longword;        // CAN control register 
+    STAT      : longword;        // CAN status register 
+    TSTAT     : longword;        // CAN transmit status register 
+    RFIFO0    : longword;        // CAN receive FIFO0 register 
+    RFIFO1    : longword;        // CAN receive FIFO1 register 
+    INTEN     : longword;        // CAN interrupt enable register 
+    ERR       : longword;        // CAN error register 
+    BT        : longword;        // CAN bit timing register 
+    RESERVED0 : array[1..12] of longword;
+    TXMAILBOX : array[0..2] of TCAN_MAILBOX_Registers 
+    RXFIFO    : array[0..1] of TCAN_FIFO_Registers 
+
+    1CC        // CAN receive FIFO1 mailbox data1 register 
+    RESERVED0 : array[] of longword; 
+
+    FCTL      : longword;        // CAN filter control register 
+    FMCFG     : longword;        // CAN filter mode register 
+    RESERVED1 : longword;
+    FSCFG     : longword;        // CAN filter scale register 
+    RESERVED2 : longword;
+    FAFIFO    : longword;        // CAN filter associated FIFO register 
+    RESERVED3 : longword;
+    FW        : longword;    21C // CAN filter working register 
+
+    F : array[0..27] of TCAN_FILTER_Registers;
+
+/* CAN transmit mailbox bank 
+    TMI(canx, bank)                REG32((canx) + 0x180U + ((bank) * 0x10U))               // CAN transmit mailbox identifier register 
+    TMP(canx, bank)                REG32((canx) + 0x184U + ((bank) * 0x10U))               // CAN transmit mailbox property register 
+    TMDATA0(canx, bank)            REG32((canx) + 0x188U + ((bank) * 0x10U))               // CAN transmit mailbox data0 register 
+    TMDATA1(canx, bank)            REG32((canx) + 0x18CU + ((bank) * 0x10U))               // CAN transmit mailbox data1 register 
+
+/* CAN filter bank 
+    FDATA0 : longword;        // CAN filter data 0 register 
+    FDATA1 : longword;        // CAN filter data 1 register 
+
+/* CAN receive fifo mailbox bank 
+    RFIFOMI(canx, bank)            REG32((canx) + 0x1B0U + ((bank) * 0x10U))               // CAN receive FIFO mailbox identifier register 
+    RFIFOMP(canx, bank)            REG32((canx) + 0x1B4U + ((bank) * 0x10U))               // CAN receive FIFO mailbox property register 
+    RFIFOMDATA0(canx, bank)        REG32((canx) + 0x1B8U + ((bank) * 0x10U))               // CAN receive FIFO mailbox data0 register 
+    RFIFOMDATA1(canx, bank)        REG32((canx) + 0x1BCU + ((bank) * 0x10U))               // CAN receive FIFO mailbox data1 register 
+  end;
+
+*)
+
+  TCRC_Registers = record
+    DATA      : longword;        // CRC data register 
+    FDATA     : longword;        // CRC free data register 
+    CTL       : longword;        // CRC control register 
+  end;
+
+  TDAC_Registers = record
+    CTL       : longword;        // DAC control register 
+    SWT       : longword;        // DAC software trigger register 
+    DAC0_R12DH: longword;        // DAC0 12-bit right-aligned data holding register 
+    DAC0_L12DH: longword;        // DAC0 12-bit left-aligned data holding register 
+    DAC0_R8DH : longword;        // DAC0 8-bit right-aligned data holding register 
+    DAC1_R12DH: longword;        // DAC1 12-bit right-aligned data holding register 
+    DAC1_L12DH: longword;        // DAC1 12-bit left-aligned data holding register 
+    DAC1_R8DH : longword;        // DAC1 8-bit right-aligned data holding register 
+    DACC_R12DH: longword;        // DAC concurrent mode 12-bit right-aligned data holding register 
+    DACC_L12DH: longword;        // DAC concurrent mode 12-bit left-aligned data holding register 
+    DACC_R8DH : longword;        // DAC concurrent mode 8-bit right-aligned data holding register 
+    DAC0_DO   : longword;        // DAC0 data output register 
+    DAC1_DO   : longword;        // DAC1 data output register   
+  end;
+
+//DMA Controller
+
+  TDMA_Channel_Registers = record
+    CTL       : longword;        // DMA channel 0 control register 
+    CNT       : longword;        // DMA channel 0 counter register 
+    PADDR     : longword;        // DMA channel 0 peripheral base address register 
+    MADDR     : longword;        // DMA channel 0 memory base address register 
+    RESERVED0 : longword;
+  end;
+
+  TDMA_Registers = record
+    INTF      : longword;        // DMA interrupt flag register 
+    INTC      : longword;        // DMA interrupt flag clear register 
+    CHANNEL   : array[1..6] of TDMA_Channel_Registers;
+  end;
+
+//External Interrupt/Event Controller
+
+  TEXMC_Registers = record
+    SNCTL0    : longword;        // EXMC SRAM/NOR flash control register 0 
+    SNTCFG0   : longword;        // EXMC SRAM/NOR flash timing configuration register 0 
+    RESERVED0 : array[0..$3f0] of longword;
+    SNWTCFG0  : longword;        // EXMC SRAM/NOR flash write timing configuration register 0 
+  end;
+
+  TEXTI_Registers = record
+    INTEN     : longword;        // interrupt enable register 
+    EVEN      : longword;        // event enable register 
+    RTEN      : longword;        // rising edge trigger enable register 
+    FTEN      : longword;        // falling trigger enable register 
+    SWIEV     : longword;        // software interrupt event register 
+    PD        : longword;        // pending register 
+  end;
+
+  TFMC_Registers = record
+    WS        : longword;        // FMC wait state register 
+    KEY       : longword;        // FMC unlock key register 
+    OBKEY     : longword;        // FMC option bytes unlock key register 
+    STAT      : longword;        // FMC status register 
+    CTL       : longword;        // FMC control register 
+    ADDR      : longword;        // FMC address register 
+    RESERVED0 : longword;
+    OBSTAT    : longword;        // FMC option bytes status register 
+    WP        : longword;        // FMC erase/program protection register 
+    RESERVED1 : array[0..$df] of longword;
+    PID       : longword;        // FMC product ID register 
+  end;
+
+  TOB_Registers = record
+    SPC       : word;            // option byte security protection value 
+    USER      : word;            // option byte user value 
+    RESERVED0 : word;
+    RESERVED1 : word;
+    WP0       : word;            // option byte write protection 0 
+    WP1       : word;            // option byte write protection 1 
+    WP2       : word;            // option byte write protection 2 
+    WP3       : word;            // option byte write protection 3 
+  end;
+
+  TFWDGT_Registers = record
+    CTL       : longword;        // FWDGT control register 
+    PSC       : longword;        // FWDGT prescaler register 
+    RLD       : longword;        // FWDGT reload register 
+    STAT      : longword;        // FWDGT status register 
+  end;
+
+  TGPIO_Registers = record
+    CTL0      : longword;        // GPIO port control register 0 
+    CTL1      : longword;        // GPIO port control register 1 
+    ISTAT     : longword;        // GPIO port input status register 
+    OCTL      : longword;        // GPIO port output control register 
+    BOP       : longword;        // GPIO port bit operation register 
+    BC        : longword;        // GPIO bit clear register 
+    LOCK      : longword;        // GPIO port configuration lock register 
+  end;
+
+  TAFIO_Registers = record
+    EC        : longword;        // AFIO event control register 
+    PCF0      : longword;        // AFIO port configuration register 0 
+    EXTISS0   : longword;        // AFIO port EXTI sources selection register 0 
+    EXTISS1   : longword;        // AFIO port EXTI sources selection register 1 
+    EXTISS2   : longword;        // AFIO port EXTI sources selection register 2 
+    EXTISS3   : longword;        // AFIO port EXTI sources selection register 3 
+    PCF1      : longword;        // AFIO port configuration register 1 
+  end;
+
+  TI2C_Registers = record
+    CTL0      : longword;        // I2C control register 0 
+    CTL1      : longword;        // I2C control register 1 
+    SADDR0    : longword;        // I2C slave address register 0 
+    SADDR1    : longword;        // I2C slave address register 
+    DATA      : longword;        // I2C transfer buffer register 
+    STAT0     : longword;        // I2C transfer status register 0 
+    STAT1     : longword;        // I2C transfer status register 
+    CKCFG     : longword;        // I2C clock configure register 
+    RT        : longword;        // I2C rise time register 
+    RESERVED0 : array[0..$6f] of longword;
+    FMPCFG    : longword;        // I2C fast-mode-plus configure register 
+  end;
+
+  TPMU_Registers = record
+    CTL       : longword;        // PMU control register 
+    CS        : longword;        // PMU control and status register 
+  end;
+
+  TRCU_Registers = record
+    CTL       : longword;        // control register 
+    CFG0      : longword;        // clock configuration register 0 
+    INT       : longword;        // clock interrupt register 
+    APB2RST   : longword;        // APB2 reset register 
+    APB1RST   : longword;        // APB1 reset register 
+    AHBEN     : longword;        // AHB1 enable register 
+    APB2EN    : longword;        // APB2 enable register 
+    APB1EN    : longword;        // APB1 enable register 
+    BDCTL     : longword;        // backup domain control register 
+    RSTSCK    : longword;        // reset source / clock register 
+    AHBRST    : longword;        // AHB reset register 
+    CFG1      : longword;        // clock configuration register 1 
+    RESERVED0 : longword;
+    DSV       : longword;        // deep-sleep mode voltage register 
+ end;
+
+//Real-Time Clock
+
+  TRTC_Registers = record
+    INTEN     : longword;        // interrupt enable register 
+    CTL       : longword;        // control register 
+    PSCH      : longword;        // prescaler high register 
+    PSCL      : longword;        // prescaler low register 
+    DIVH      : longword;        // divider high register 
+    DIVL      : longword;        // divider low register 
+    CNTH      : longword;        // counter high register 
+    CNTL      : longword;        // counter low register 
+    ALRMH     : longword;        // alarm high register 
+    ALRML     : longword;        // alarm low register 
+  end;
+
+//Serial Peripheral Interface
+
+  TSPI_Registers = record
+    CTL0      : longword;        // SPI control register 0 
+    CTL1      : longword;        // SPI control register 1 
+    STAT      : longword;        // SPI status register 
+    DATA      : longword;        // SPI data register 
+    CRCPOLY   : longword;        // SPI CRC polynomial register 
+    RCRC      : longword;        // SPI receive CRC register 
+    TCRC      : longword;        // SPI transmit CRC register 
+    I2SCTL    : longword;        // SPI I2S control register 
+    I2SPSC    : longword;        // SPI I2S clock prescaler register 
+  end;
+
+//TIM
+
+  TTIMER_Registers = record
+    CTL0      : longword;        // TIMER control register 0 
+    CTL1      : longword;        // TIMER control register 1 
+    SMCFG     : longword;        // TIMER slave mode configuration register 
+    DMAINTEN  : longword;        // TIMER DMA and interrupt enable register 
+    INTF      : longword;        // TIMER interrupt flag register 
+    SWEVG     : longword;        // TIMER software event generation register 
+    CHCTL0    : longword;        // TIMER channel control register 0 
+    CHCTL1    : longword;        // TIMER channel control register 1 
+    CHCTL2    : longword;        // TIMER channel control register 2 
+    CNT       : longword;        // TIMER counter register 
+    PSC       : longword;        // TIMER prescaler register 
+    CAR       : longword;        // TIMER counter auto reload register 
+    CREP      : longword;        // TIMER counter repetition register 
+    CH0CV     : longword;        // TIMER channel 0 capture/compare value register 
+    CH1CV     : longword;        // TIMER channel 1 capture/compare value register 
+    CH2CV     : longword;        // TIMER channel 2 capture/compare value register 
+    CH3CV     : longword;        // TIMER channel 3 capture/compare value register 
+    CCHP      : longword;        // TIMER channel complementary protection register 
+    DMACFG    : longword;        // TIMER DMA configuration register 
+    DMATB     : longword;        // TIMER DMA transfer buffer register 
+  end;
+
+//Universal Synchronous Asynchronous Receiver Transmitter
+
+  TUSART_Registers = record
+    STAT      : longword;        // USART status register 
+    DATA      : longword;        // USART data register 
+    BAUD      : longword;        // USART baud rate register 
+    CTL0      : longword;        // USART control register 0 
+    CTL1      : longword;        // USART control register 1 
+    CTL2      : longword;        // USART control register 2 
+    GP        : longword;        // USART guard time and prescaler register 
+  end;
+
+//Window WATCHDOG
+
+  TWWDGT_Registers = record
+    CTL       : longword;        // WWDGT control register 
+    CFG       : longword;        // WWDGT configuration register 
+    STAT      : longword;        // WWDGT status register 
+  end;
+
+const
+  FLASH_BASE  = $08000000;       // FLASH base address in the alias region
+  SRAM_BASE   = $20000000;       // SRAM base address in the alias region
+  OB_BASE     = $1FFFF800;       // OB base address
+  DBG_BASE    = $E0042000;       // DBG base address
+  EXMC_BASE   = $A0000000;       // EXMC register base address
+
+// peripheral memory map
+  APB1_BUS_BASE = $40000000;     // apb1 base address
+  APB2_BUS_BASE = $40010000;     // apb2 base address
+  AHB1_BUS_BASE = $40018000;     // ahb1 base address
+  AHB3_BUS_BASE = $60000000;     // ahb3 base address
+
+// advanced peripheral bus 1 memory map
+  TIMER_BASE  = APB1_BUS_BASE + $00000000;  // TIMER base address
+  TIMER0_BASE = TIMER_BASE + $00012C00;
+  TIMER1_BASE = TIMER_BASE + $00000000;
+  TIMER2_BASE = TIMER_BASE + $00000400;
+  TIMER3_BASE = TIMER_BASE + $00000800;
+  TIMER4_BASE = TIMER_BASE + $00000C00;
+  TIMER5_BASE = TIMER_BASE + $00001000;
+  TIMER6_BASE = TIMER_BASE + $00001400;
+
+  RTC_BASE    = APB1_BUS_BASE + $00002800; // RTC base address
+  WWDGT_BASE  = APB1_BUS_BASE + $00002C00; // WWDGT base address
+  FWDGT_BASE  = APB1_BUS_BASE + $00003000; // FWDGT base address
+
+  SPI_BASE    = APB1_BUS_BASE + $00003800; // SPI base address
+  SPI0_BASE   = SPI_BASE + $0000F800;      // SPI base address
+  SPI1_BASE   = SPI_BASE;                  // SPI base address
+  SPI2_BASE   = SPI_BASE + $00000400;      // SPI base address
+
+  USART_BASE  = APB1_BUS_BASE + $00004400; // USART base address
+  USART0_BASE = USART_BASE+$0000F400;      // USART0 base address 
+  USART1_BASE = USART_BASE;                // USART1 base address 
+  USART2_BASE = USART_BASE+$00000400;      // USART2 base address 
+  UART3_BASE  = USART_BASE+$00000800;      // UART3 base address 
+  UART4_BASE  = USART_BASE+$00000C00;      // UART4 base address 
+
+  I2C_BASE    = APB1_BUS_BASE + $00005400; // I2C base address
+  I2C0_BASE   = I2C_BASE;                  // I2C0 base address
+  I2C1_BASE   = I2C_BASE + $00000400;      // I2C1 base address
+
+  CAN_BASE    = APB1_BUS_BASE + $00006400; // CAN base address
+  CAN0_BASE   = CAN_BASE;                  // CAN0 base address */
+  CAN1_BASE   = CAN_BASE + $00000400;      // CAN1 base address */
+
+  BKP_BASE    = APB1_BUS_BASE + $00006C00; // BKP base address
+  PMU_BASE    = APB1_BUS_BASE + $00007000; // PMU base address
+  DAC_BASE    = APB1_BUS_BASE + $00007400; // DAC base address
+
+// advanced peripheral bus 2 memory map
+  AFIO_BASE   = APB2_BUS_BASE + $00000000;  // AFIO base address
+  EXTI_BASE   = APB2_BUS_BASE + $00000400;  // EXTI base address
+
+  GPIO_BASE   = APB2_BUS_BASE + $00000800;  // GPIO base address
+  GPIOA_BASE  = GPIO_BASE + $00000000;
+  GPIOB_BASE  = GPIO_BASE + $00000400;
+  GPIOC_BASE  = GPIO_BASE + $00000800;
+  GPIOD_BASE  = GPIO_BASE + $00000C00;
+  GPIOE_BASE  = GPIO_BASE + $00001000;
+
+  ADC_BASE    = APB2_BUS_BASE + $00002400;  // ADC base address
+  ADC0_BASE   = ADC_BASE;                   // ADC0 base address
+  ADC1_BASE   = ADC_BASE + $00000400;       // ADC1 base address
+
+// advanced high performance bus 1 memory map
+  DMA_BASE    = AHB1_BUS_BASE + $00008000;  // DMA base address
+  DMA0_BASE   = DMA_BASE;                   // DMA base address
+  DMA1_BASE   = DMA_BASE + $00000400;       // DMA base address
+  RCU_BASE    = AHB1_BUS_BASE + $00009000;  // RCU base address
+  FMC_BASE    = AHB1_BUS_BASE + $0000A000;  // FMC base address
+  CRC_BASE    = AHB1_BUS_BASE + $0000B000;  // CRC base address
+  USBFS_BASE  = AHB1_BUS_BASE + $0FFE8000;  // USBFS base address
+
+var
+  ADC0        : TADC_Registers   absolute ADC0_BASE;
+  ADC1        : TADC_Registers   absolute ADC1_BASE;
+  CRC         : TCRC_Registers   absolute CRC_BASE;
+  DAC         : TDAC_Registers   absolute DAC_BASE;
+  DMA0        : TDMA_Registers   absolute DMA1_BASE;
+  DMA1        : TDMA_Registers   absolute DMA1_BASE;
+  GPIOA       : TGPIO_Registers  absolute GPIOA_BASE;
+  GPIOB       : TGPIO_Registers  absolute GPIOB_BASE;
+  GPIOC       : TGPIO_Registers  absolute GPIOC_BASE;
+  GPIOD       : TGPIO_Registers  absolute GPIOD_BASE;
+  GPIOE       : TGPIO_Registers  absolute GPIOE_BASE;
+  I2C0        : TI2C_Registers   absolute I2C0_BASE;
+  I2C1        : TI2C_Registers   absolute I2C1_BASE;
+  OB          : TOB_Registers    absolute OB_BASE;
+  RTC         : TRTC_Registers   absolute RTC_BASE;
+  SPI0        : TSPI_Registers   absolute SPI0_BASE;
+  SPI1        : TSPI_Registers   absolute SPI1_BASE;
+  SPI2        : TSPI_Registers   absolute SPI2_BASE;
+  TIMER0      : TTIMER_Registers absolute TIMER0_BASE;
+  TIMER1      : TTIMER_Registers absolute TIMER1_BASE;
+  TIMER2      : TTIMER_Registers absolute TIMER2_BASE;
+  TIMER3      : TTIMER_Registers absolute TIMER3_BASE;
+  TIMER4      : TTIMER_Registers absolute TIMER4_BASE;
+  TIMER5      : TTIMER_Registers absolute TIMER5_BASE;
+  TIMER6      : TTIMER_Registers absolute TIMER6_BASE;
+  USART0      : TUSART_Registers absolute USART0_BASE;
+  USART1      : TUSART_Registers absolute USART1_BASE;
+  USART2      : TUSART_Registers absolute USART2_BASE;
+  UART3       : TUSART_Registers absolute UART3_BASE;
+  UART4       : TUSART_Registers absolute UART4_BASE;
+  WWDGT       : TWWDGT_Registers absolute WWDGT_BASE;
+
+implementation
+  procedure CLIC_RESERVED_ISR; external name 'CLIC_RESERVED_ISR';
+  procedure CLIC_SFT_ISR;      external name 'CLIC_SFT_ISR';
+  procedure CLIC_TMR_ISR;      external name 'CLIC_TMR_ISR';
+  procedure CLIC_BWEI_ISR;     external name 'CLIC_BWEI_ISR';
+  procedure CLIC_PMOVI_ISR;    external name 'CLIC_PMOVI_ISR';
+  procedure WWDGT_ISR;         external name 'WWDGT_ISR';
+  procedure LVD_ISR;           external name 'LVD_ISR';
+  procedure TAMPER_ISR;        external name 'TAMPER_ISR';
+  procedure RTC_ISR;           external name 'RTC_ISR';
+  procedure FMC_ISR;           external name 'FMC_ISR';
+  procedure RCU_CTC_ISR;       external name 'RCU_CTC_ISR';
+  procedure EXTI0_ISR;         external name 'EXTI0_ISR';
+  procedure EXTI1_ISR;         external name 'EXTI1_ISR';
+  procedure EXTI2_ISR;         external name 'EXTI2_ISR';
+  procedure EXTI3_ISR;         external name 'EXTI3_ISR';
+  procedure EXTI4_ISR;         external name 'EXTI4_ISR';
+  procedure DMA0_Channel0_ISR; external name 'DMA0_Channel0_ISR';
+  procedure DMA0_Channel1_ISR; external name 'DMA0_Channel1_ISR';
+  procedure DMA0_Channel2_ISR; external name 'DMA0_Channel2_ISR';
+  procedure DMA0_Channel3_ISR; external name 'DMA0_Channel3_ISR';
+  procedure DMA0_Channel4_ISR; external name 'DMA0_Channel4_ISR';
+  procedure DMA0_Channel5_ISR; external name 'DMA0_Channel5_ISR';
+  procedure DMA0_Channel6_ISR; external name 'DMA0_Channel6_ISR';
+  procedure ADC0_1_ISR;        external name 'ADC0_1_ISR';
+  procedure CAN0_TX_ISR;       external name 'CAN0_TX_ISR';
+  procedure CAN0_RX0_ISR;      external name 'CAN0_RX0_ISR';
+  procedure CAN0_RX1_ISR;      external name 'CAN0_RX1_ISR';
+  procedure CAN0_EWMC_ISR;     external name 'CAN0_EWMC_ISR';
+  procedure EXTI5_9_ISR;       external name 'EXTI5_9_ISR';
+  procedure TIMER0_BRK_ISR;    external name 'TIMER0_BRK_ISR';
+  procedure TIMER0_UP_ISR;     external name 'TIMER0_UP_ISR';
+  procedure TIMER0_TRG_CMT_ISR;external name 'TIMER0_TRG_CMT_ISR';
+  procedure TIMER0_Channel_ISR;external name 'TIMER0_Channel_ISR';
+  procedure TIMER1_ISR;        external name 'TIMER1_ISR';
+  procedure TIMER2_ISR;        external name 'TIMER2_ISR';
+  procedure TIMER3_ISR;        external name 'TIMER3_ISR';
+  procedure I2C0_EV_ISR;       external name 'I2C0_EV_ISR';
+  procedure I2C0_ER_ISR;       external name 'I2C0_ER_ISR';
+  procedure I2C1_EV_ISR;       external name 'I2C1_EV_ISR';
+  procedure I2C1_ER_ISR;       external name 'I2C1_ER_ISR';
+  procedure SPI0_ISR;          external name 'SPI0_ISR';
+  procedure SPI1_ISR;          external name 'SPI1_ISR';
+  procedure USART0_ISR;        external name 'USART0_ISR';
+  procedure USART1_ISR;        external name 'USART1_ISR';
+  procedure USART2_ISR;        external name 'USART2_ISR';
+  procedure EXTI10_15_ISR;     external name 'EXTI10_15_ISR';
+  procedure RTC_ALARM_ISR;     external name 'RTC_ALARM_ISR';
+  procedure USBFS_WKUP_ISR;    external name 'USBFS_WKUP_ISR';
+  procedure EXMC_ISR;          external name 'EXMC_ISR';
+  procedure TIMER4_ISR;        external name 'TIMER4_ISR';
+  procedure SPI2_ISR;          external name 'SPI2_ISR';
+  procedure UART3_ISR;         external name 'UART3_ISR';
+  procedure UART4_ISR;         external name 'UART4_ISR';
+  procedure TIMER5_ISR;        external name 'TIMER5_ISR';
+  procedure TIMER6_ISR;        external name 'TIMER6_ISR';
+  procedure DMA1_Channel0_ISR; external name 'DMA1_Channel0_ISR';
+  procedure DMA1_Channel1_ISR; external name 'DMA1_Channel1_ISR';
+  procedure DMA1_Channel2_ISR; external name 'DMA1_Channel2_ISR';
+  procedure DMA1_Channel3_ISR; external name 'DMA1_Channel3_ISR';
+  procedure DMA1_Channel4_ISR; external name 'DMA1_Channel4_ISR';
+  procedure CAN1_TX_ISR;       external name 'CAN1_TX_ISR';
+  procedure CAN1_RX0_ISR;      external name 'CAN1_RX0_ISR';
+  procedure CAN1_RX1_ISR;      external name 'CAN1_RX1_ISR';
+  procedure CAN1_EWMC_ISR;     external name 'CAN1_EWMC_ISR';
+  procedure USBFS_ISR;         external name 'USBFS_ISR';
+  
+  {$i riscv32_start.inc}
+
+  procedure Vectors; assembler; nostackframe;
+  label interrupt_vectors;
+  asm
+     .section ".init.interrupt_vectors"
+  interrupt_vectors:
+    .long CLIC_RESERVED_ISR
+    .long 0
+    .long 0
+    .long CLIC_SFT_ISR
+    .long 0
+    .long 0
+    .long 0
+    .long CLIC_TMR_ISR
+    .long 0
+    .long 0
+    .long 0
+    .long 0
+    .long 0
+    .long 0
+    .long 0
+    .long 0
+    .long 0
+    .long CLIC_BWEI_ISR
+    .long CLIC_PMOVI_ISR
+    .long WWDGT_ISR
+    .long LVD_ISR
+    .long TAMPER_ISR
+    .long RTC_ISR
+    .long FMC_ISR
+    .long RCU_CTC_ISR
+    .long EXTI0_ISR
+    .long EXTI1_ISR
+    .long EXTI2_ISR
+    .long EXTI3_ISR
+    .long EXTI4_ISR
+    .long DMA0_Channel0_ISR
+    .long DMA0_Channel1_ISR
+    .long DMA0_Channel2_ISR
+    .long DMA0_Channel3_ISR
+    .long DMA0_Channel4_ISR
+    .long DMA0_Channel5_ISR
+    .long DMA0_Channel6_ISR
+    .long ADC0_1_ISR
+    .long CAN0_TX_ISR
+    .long CAN0_RX0_ISR
+    .long CAN0_RX1_ISR
+    .long CAN0_EWMC_ISR
+    .long EXTI5_9_ISR
+    .long TIMER0_BRK_ISR
+    .long TIMER0_UP_ISR
+    .long TIMER0_TRG_CMT_ISR
+    .long TIMER0_Channel_ISR
+    .long TIMER1_ISR
+    .long TIMER2_ISR
+    .long TIMER3_ISR
+    .long I2C0_EV_ISR
+    .long I2C0_ER_ISR
+    .long I2C1_EV_ISR
+    .long I2C1_ER_ISR
+    .long SPI0_ISR
+    .long SPI1_ISR
+    .long USART0_ISR
+    .long USART1_ISR
+    .long USART2_ISR
+    .long EXTI10_15_ISR
+    .long RTC_ALARM_ISR
+    .long USBFS_WKUP_ISR
+    .long 0
+    .long 0
+    .long 0
+    .long 0
+    .long 0
+    .long EXMC_ISR
+    .long 0
+    .long TIMER4_ISR
+    .long SPI2_ISR
+    .long UART3_ISR
+    .long UART4_ISR
+    .long TIMER5_ISR
+    .long TIMER6_ISR
+    .long DMA1_Channel0_ISR
+    .long DMA1_Channel1_ISR
+    .long DMA1_Channel2_ISR
+    .long DMA1_Channel3_ISR
+    .long DMA1_Channel4_ISR
+    .long 0
+    .long 0
+    .long CAN1_TX_ISR
+    .long CAN1_RX0_ISR
+    .long CAN1_RX1_ISR
+    .long CAN1_EWMC_ISR
+    .long USBFS_ISR
+
+    .weak CLIC_RESERVED_ISR
+    .weak CLIC_SFT_ISR
+    .weak CLIC_TMR_ISR
+    .weak CLIC_BWEI_ISR
+    .weak CLIC_PMOVI_ISR
+    .weak WWDGT_ISR
+    .weak LVD_ISR
+    .weak TAMPER_ISR
+    .weak RTC_ISR
+    .weak FMC_ISR
+    .weak RCU_CTC_ISR
+    .weak EXTI0_ISR
+    .weak EXTI1_ISR
+    .weak EXTI2_ISR
+    .weak EXTI3_ISR
+    .weak EXTI4_ISR
+    .weak DMA0_Channel0_ISR
+    .weak DMA0_Channel1_ISR
+    .weak DMA0_Channel2_ISR
+    .weak DMA0_Channel3_ISR
+    .weak DMA0_Channel4_ISR
+    .weak DMA0_Channel5_ISR
+    .weak DMA0_Channel6_ISR
+    .weak ADC0_1_ISR
+    .weak CAN0_TX_ISR
+    .weak CAN0_RX0_ISR
+    .weak CAN0_RX1_ISR
+    .weak CAN0_EWMC_ISR
+    .weak EXTI5_9_ISR
+    .weak TIMER0_BRK_ISR
+    .weak TIMER0_UP_ISR
+    .weak TIMER0_TRG_CMT_ISR
+    .weak TIMER0_Channel_ISR
+    .weak TIMER1_ISR
+    .weak TIMER2_ISR
+    .weak TIMER3_ISR
+    .weak I2C0_EV_ISR
+    .weak I2C0_ER_ISR
+    .weak I2C1_EV_ISR
+    .weak I2C1_ER_ISR
+    .weak SPI0_ISR
+    .weak SPI1_ISR
+    .weak USART0_ISR
+    .weak USART1_ISR
+    .weak USART2_ISR
+    .weak EXTI10_15_ISR
+    .weak RTC_ALARM_ISR
+    .weak USBFS_WKUP_ISR
+    .weak EXMC_ISR
+    .weak TIMER4_ISR
+    .weak SPI2_ISR
+    .weak UART3_ISR
+    .weak UART4_ISR
+    .weak TIMER5_ISR
+    .weak TIMER6_ISR
+    .weak DMA1_Channel0_ISR
+    .weak DMA1_Channel1_ISR
+    .weak DMA1_Channel2_ISR
+    .weak DMA1_Channel3_ISR
+    .weak DMA1_Channel4_ISR
+    .weak CAN1_TX_ISR
+    .weak CAN1_RX0_ISR
+    .weak CAN1_RX1_ISR
+    .weak CAN1_EWMC_ISR
+    .weak USBFS_ISR
+
+    .set CLIC_RESERVED_ISR, HaltProc
+    .set CLIC_SFT_ISR, HaltProc
+    .set CLIC_TMR_ISR, HaltProc
+    .set CLIC_BWEI_ISR, HaltProc
+    .set CLIC_PMOVI_ISR, HaltProc
+    .set WWDGT_ISR, HaltProc
+    .set LVD_ISR, HaltProc
+    .set TAMPER_ISR, HaltProc
+    .set RTC_ISR, HaltProc
+    .set FMC_ISR, HaltProc
+    .set RCU_CTC_ISR, HaltProc
+    .set EXTI0_ISR, HaltProc
+    .set EXTI1_ISR, HaltProc
+    .set EXTI2_ISR, HaltProc
+    .set EXTI3_ISR, HaltProc
+    .set EXTI4_ISR, HaltProc
+    .set DMA0_Channel0_ISR, HaltProc
+    .set DMA0_Channel1_ISR, HaltProc
+    .set DMA0_Channel2_ISR, HaltProc
+    .set DMA0_Channel3_ISR, HaltProc
+    .set DMA0_Channel4_ISR, HaltProc
+    .set DMA0_Channel5_ISR, HaltProc
+    .set DMA0_Channel6_ISR, HaltProc
+    .set ADC0_1_ISR, HaltProc
+    .set CAN0_TX_ISR, HaltProc
+    .set CAN0_RX0_ISR, HaltProc
+    .set CAN0_RX1_ISR, HaltProc
+    .set CAN0_EWMC_ISR, HaltProc
+    .set EXTI5_9_ISR, HaltProc
+    .set TIMER0_BRK_ISR, HaltProc
+    .set TIMER0_UP_ISR, HaltProc
+    .set TIMER0_TRG_CMT_ISR, HaltProc
+    .set TIMER0_Channel_ISR, HaltProc
+    .set TIMER1_ISR, HaltProc
+    .set TIMER2_ISR, HaltProc
+    .set TIMER3_ISR, HaltProc
+    .set I2C0_EV_ISR, HaltProc
+    .set I2C0_ER_ISR, HaltProc
+    .set I2C1_EV_ISR, HaltProc
+    .set I2C1_ER_ISR, HaltProc
+    .set SPI0_ISR, HaltProc
+    .set SPI1_ISR, HaltProc
+    .set USART0_ISR, HaltProc
+    .set USART1_ISR, HaltProc
+    .set USART2_ISR, HaltProc
+    .set EXTI10_15_ISR, HaltProc
+    .set RTC_ALARM_ISR, HaltProc
+    .set USBFS_WKUP_ISR, HaltProc
+    .set EXMC_ISR, HaltProc
+    .set TIMER4_ISR, HaltProc
+    .set SPI2_ISR, HaltProc
+    .set UART3_ISR, HaltProc
+    .set UART4_ISR, HaltProc
+    .set TIMER5_ISR, HaltProc
+    .set TIMER6_ISR, HaltProc
+    .set DMA1_Channel0_ISR, HaltProc
+    .set DMA1_Channel1_ISR, HaltProc
+    .set DMA1_Channel2_ISR, HaltProc
+    .set DMA1_Channel3_ISR, HaltProc
+    .set DMA1_Channel4_ISR, HaltProc
+    .set CAN1_TX_ISR, HaltProc
+    .set CAN1_RX0_ISR, HaltProc
+    .set CAN1_RX1_ISR, HaltProc
+    .set CAN1_EWMC_ISR, HaltProc
+    .set USBFS_ISR, HaltProc
+    .text
+  end;
+end.

+ 105 - 0
rtl/embedded/riscv32/riscv32_start.inc

@@ -0,0 +1,105 @@
+var
+ _stack_top: record end; external name '_stack_top';
+ _data: record end; external name '_data';
+ _edata: record end; external name '_edata';
+ _text_start: record end; external name '_text_start';
+ _etext: record end; external name '_etext';
+ _bss_start: record end; external name '_bss_start';
+ _bss_end: record end; external name '_bss_end';
+
+procedure Pascalmain; external name 'PASCALMAIN';
+
+procedure HaltProc; noreturn; public name'_haltproc';
+begin
+  while true do;
+end;
+
+procedure Startup;
+var
+  pdest, psrc, pend: PLongWord;
+begin
+  pdest:=@_data;
+  psrc:=@_etext;
+  pend:=@_bss_start;
+
+  while pdest<pend do
+    begin
+      pdest^:=psrc^;
+      inc(pdest);
+      inc(psrc);
+    end;
+
+  pend:=@_bss_end;
+  while pdest<pend do
+    begin
+      pdest^:=0;
+      inc(pdest);
+    end;
+
+  PASCALMAIN;
+  HaltProc;
+end;
+
+procedure LowlevelStartup; assembler; nostackframe; [public, alias: '_START'];
+asm
+  { Initialize global Pointer }
+  .option push
+  .option norelax
+  lui   gp, %hi(_bss_start+0x800)
+  addi  gp, gp, %lo(_bss_start+0x800)
+  .option pop
+
+  { Initialize Stack Pointer }
+.L1:
+  auipc sp, %pcrel_hi(_stack_top)
+  addi  sp, sp, %pcrel_lo(.L1)
+
+  { Initialise FP to zero }
+  addi  fp, x0, 0
+
+  jal x0, Startup
+//   { Copy Initialized vars}
+//   lui   x10,%hi(_data)
+//   addi  x10,x10,%lo(_data)
+//   lui   x11,%hi(_edata)
+//   addi  x11,x11,%lo(_edata)
+//   sltu  x12,x10,x11
+//   beq   x12,x0,.L2
+//   lui   x12,%hi(_etext)
+//   addi  x12,x12,%lo(_etext)
+//   addi  x10,x10,-1
+//   addi  x12,x12,-1
+// .L1:
+//   addi  x10,x10,1
+//   addi  x12,x12,1
+//   lb    x13,0(x10)
+//   sb    x13,0(x12)
+//   bne   x10,x11,.L1
+// .L2:
+// { Initialize Memory}
+//   lui   x10,%hi(_bss_start)
+//   addi  x10,x10,%lo(_bss_start)
+//   lui   x11,%hi(_bss_end)
+//   addi  x11,x11,%lo(_bss_end)
+//   sltu  x12,x10,x11
+//   beq   x12,x0,.L4
+//   addi  x10,x10,-1
+// .L3:
+//   addi  x10,x10,1
+//   sb    x0,0(x10)
+//   bne   x10,x11,.L3
+// .L4:
+//   jal   x0,PASCALMAIN
+//   jal   x0,HaltProc
+// .L_bss_start:
+//   .long _bss_start
+// .L_bss_end:
+//   .long _bss_end
+// .L_etext:
+//   .long _etext
+// .L_data:
+//   .long _data
+// .L_edata:
+//   .long _edata
+// .text
+end;