Browse Source

RP2040 support based on modification by Michael Ring (https://github.com/michael-ring/freepascal).

ccrause 2 years ago
parent
commit
652f21b656

+ 16 - 0
compiler/arm/cpuinfo.pas

@@ -519,6 +519,14 @@ Type
       { Raspberry Pi 2 }
       ct_raspi2,
 
+      { Raspberry rp2040 }
+      ct_rp2040,
+      ct_rppico,
+      ct_feather_rp2040,
+      ct_itzybitzy_rp2040,
+      ct_tiny_2040,
+      ct_qtpy_rp2040,
+
       // generic Thumb2 target
       ct_thumb2bare
      );
@@ -1050,6 +1058,14 @@ Const
       { Raspberry Pi 2 }
       (controllertypestr:'RASPI2'; controllerunitstr:'RASPI2'; cputype:cpu_armv7a; fputype:fpu_vfpv4; flashbase:$00000000; flashsize:$00000000; srambase:$00008000; sramsize:$10000000),
 
+      { Raspberry rp2040 }
+      (controllertypestr:'RP2040'          ; controllerunitstr:'RP2040'; cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$10000000; flashsize:$00000000;      srambase:$20000000; sramsize:$00042000),
+      (controllertypestr:'RASPI_PICO'      ; controllerunitstr:'RP2040'; cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$10000000; flashsize:$00200000;      srambase:$20000000; sramsize:$00042000),
+      (controllertypestr:'FEATHER_RP2040'  ; controllerunitstr:'RP2040'; cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$10000000; flashsize:$00800000;      srambase:$20000000; sramsize:$00042000),
+      (controllertypestr:'ITZYBITZY_RP2040'; controllerunitstr:'RP2040'; cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$10000000; flashsize:$00400000;      srambase:$20000000; sramsize:$00042000),
+      (controllertypestr:'QTPY_RP2040'     ; controllerunitstr:'RP2040'; cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$10000000; flashsize:$00400000;      srambase:$20000000; sramsize:$00042000),
+      (controllertypestr:'TINY_2040'       ; controllerunitstr:'RP2040'; cputype:cpu_armv6m; fputype:fpu_soft; flashbase:$10000000; flashsize:$00800000;      srambase:$20000000; sramsize:$00042000),
+
       { Bare bones }
       (controllertypestr:'THUMB2_BARE';	controllerunitstr:'THUMB2_BARE';	cputype:cpu_armv7m; fputype:fpu_soft; flashbase:$00000000;	flashsize:$00002000;	srambase:$20000000;	sramsize:$00000400)
     );

+ 50 - 32
compiler/systems/t_embed.pas

@@ -769,6 +769,14 @@ begin
       { Raspberry Pi 2 }
       ct_raspi2,
 
+      { Raspberry rp2040 }
+      ct_rp2040,
+      ct_rppico,
+      ct_feather_rp2040,
+      ct_itzybitzy_rp2040,
+      ct_tiny_2040,
+      ct_qtpy_rp2040,
+
       ct_thumb2bare:
         begin
          with embedded_controllers[current_settings.controllertype] do
@@ -798,7 +806,6 @@ begin
               Add('_stack_top = 0x' + IntToHex(sramsize+srambase,8) + ';');
 
               // Add Checksum Calculation for LPC Controllers so that the bootloader starts the uploaded binary
-              writeln(controllerunitstr);
               if (controllerunitstr = 'LPC8xx') or (controllerunitstr = 'LPC11XX') or (controllerunitstr = 'LPC122X') then
                 Add('Startup_Checksum = 0 - (_stack_top + _START + 1 + NonMaskableInt_interrupt + 1 + Hardfault_interrupt + 1);');
               if (controllerunitstr = 'LPC13XX') then
@@ -814,6 +821,19 @@ begin
     begin
       Add('SECTIONS');
       Add('{');
+      if (embedded_controllers[current_settings.controllertype].controllerunitstr='RP2040') then
+      begin
+        Add('    .boot2 :');
+        Add('    {');
+        Add('    _boot2_start = .;');
+        Add('    KEEP(*(.boot2))');
+        Add('    ASSERT(!( . == _boot2_start ), "RP2040: Error, a device specific 2nd stage bootloader is required for booting");');
+        Add('    ASSERT(( . == _boot2_start + 256 ), "RP2040: Error, 2nd stage bootloader in section .boot2 is required to be 256 bytes");');
+        if embedded_controllers[current_settings.controllertype].flashsize<>0 then
+          Add('    } >flash')
+        else
+          Add('    } >ram');
+      end;
       Add('     .text :');
       Add('    {');
       Add('    _text_start = .;');
@@ -1890,7 +1910,8 @@ const
     (k:'STM32L4';v:$00ff6919),
     (k:'STM32L5';v:$04240bdf),
     (k:'STM32WB';v:$70d16653),
-    (k:'STM32WL';v:$21460ff0)
+    (k:'STM32WL';v:$21460ff0),
+    (k:'RP2040' ;v:$e48bff56)
   );
 
 var
@@ -1917,36 +1938,33 @@ begin
       familyId := Families[i].v;
   end;
 
-  if (baseAddress and $07ffffff) <> 0 then
-  begin
-    totalRead := 0;
-    numRead := 0;
-    assign(f,binfile);
-    reset(f,1);
-    assign(g,uf2file);
-    rewrite(g,1);
-
-    repeat
-      fillchar(uf2block,sizeof(uf2block),0);
-      uf2block.magicStart0 := $0A324655; // "UF2\n"
-      uf2block.magicStart1 := $9E5D5157; // Randomly selected
-      if familyId = 0 then
-        uf2block.flags := 0
-      else
-        uf2block.flags := $2000;
-      uf2block.targetAddr := baseAddress + totalread;
-      uf2block.payloadSize := 256;
-      uf2block.blockNo := (totalRead div sizeOf(uf2block.data));
-      uf2block.numBlocks := (filesize(f) + 255) div 256;
-      uf2block.familyId := familyId;
-      uf2block.magicEnd := $0AB16F30; // Randomly selected
-      blockRead(f,uf2block.data,sizeof(uf2block.data),numRead);
-      blockwrite(g,uf2block,sizeof(uf2block));
-      inc(totalRead,numRead);
-    until (numRead=0) or (NumRead<>sizeOf(uf2block.data));
-    close(f);
-    close(g);
-  end;
+  totalRead := 0;
+  numRead := 0;
+  assign(f,binfile);
+  reset(f,1);
+  assign(g,uf2file);
+  rewrite(g,1);
+
+  repeat
+    fillchar(uf2block,sizeof(uf2block),0);
+    uf2block.magicStart0 := $0A324655; // "UF2\n"
+    uf2block.magicStart1 := $9E5D5157; // Randomly selected
+    if familyId = 0 then
+      uf2block.flags := 0
+    else
+      uf2block.flags := $2000;
+    uf2block.targetAddr := baseAddress + totalread;
+    uf2block.payloadSize := 256;
+    uf2block.blockNo := (totalRead div sizeOf(uf2block.data));
+    uf2block.numBlocks := (filesize(f) + 255) div 256;
+    uf2block.familyId := familyId;
+    uf2block.magicEnd := $0AB16F30; // Randomly selected
+    blockRead(f,uf2block.data,sizeof(uf2block.data),numRead);
+    blockwrite(g,uf2block,sizeof(uf2block));
+    inc(totalRead,numRead);
+  until (numRead=0) or (NumRead<>sizeOf(uf2block.data));
+  close(f);
+  close(g);
   Result := true;
 end;
 

+ 3 - 1
rtl/embedded/Makefile

@@ -548,6 +548,7 @@ PROFILEUNIT=DOSApi.Profile
 RASPI2UNIT=EmbeddedApi.raspi2
 RASPI3UNIT=EmbeddedApi.raspi3
 RASPIUARTUNIT=EmbeddedApi.raspiuart
+RP2040UNIT=EmbeddedApi.rp2040
 RTLCONSTSUNIT=System.RtlConsts
 SAM3X8EUNIT=EmbeddedApi.sam3x8e
 SAMD51P19AUNIT=EmbeddedApi.samd51p19a
@@ -795,6 +796,7 @@ PROFILEUNIT=profile
 RASPI2UNIT=raspi2
 RASPI3UNIT=raspi3
 RASPIUARTUNIT=raspiuart
+RP2040UNIT=rp2040
 RTLCONSTSUNIT=rtlconsts
 SAM3X8EUNIT=sam3x8e
 SAMD51P19AUNIT=samd51p19a
@@ -931,7 +933,7 @@ CPU_UNITS=$(LPC21X4UNIT) $(AT91SAM7X256UNIT) $(SC32442BUNIT)
 CPU_UNITS_DEFINED=1
 endif
 ifeq ($(SUBARCH),armv6m)
-CPU_UNITS=$(LPC8XXUNIT) $(LPC11XXUNIT) $(LPC122XUNIT) $(STM32F0XXUNIT) $(NRF51UNIT) $(CORTEXM0UNIT)
+CPU_UNITS=$(LPC8XXUNIT) $(LPC11XXUNIT) $(LPC122XUNIT) $(STM32F0XXUNIT) $(NRF51UNIT) $(CORTEXM0UNIT) $(RP2040UNIT)
 CPU_UNITS_DEFINED=1
 endif
 ifeq ($(SUBARCH),armv7a)

+ 1 - 1
rtl/embedded/Makefile.fpc

@@ -95,7 +95,7 @@ CPU_UNITS=$(LPC21X4UNIT) $(AT91SAM7X256UNIT) $(SC32442BUNIT)
 CPU_UNITS_DEFINED=1
 endif
 ifeq ($(SUBARCH),armv6m)
-CPU_UNITS=$(LPC8XXUNIT) $(LPC11XXUNIT) $(LPC122XUNIT) $(STM32F0XXUNIT) $(NRF51UNIT) $(CORTEXM0UNIT)
+CPU_UNITS=$(LPC8XXUNIT) $(LPC11XXUNIT) $(LPC122XUNIT) $(STM32F0XXUNIT) $(NRF51UNIT) $(CORTEXM0UNIT) $(RP2040UNIT)
 CPU_UNITS_DEFINED=1
 endif
 ifeq ($(SUBARCH),armv7a)

+ 114 - 0
rtl/embedded/arm/cortexm0p_start.inc

@@ -0,0 +1,114 @@
+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 _NonMaskableInt_Handler; assembler; nostackframe; public name '_NonMaskableInt_Handler';
+asm
+.Lloop:
+   bkpt
+   b .Lloop
+end;
+
+procedure _NMI_Handler; assembler; nostackframe; public name '_NMI_Handler';
+asm
+.Lloop:
+   bkpt
+   b .Lloop
+end;
+
+procedure _HardFault_Handler; assembler; nostackframe; public name '_HardFault_Handler';
+asm
+.Lloop:
+   bkpt
+   b .Lloop
+end;
+
+procedure _SVC_Handler; assembler; nostackframe; public name '_SVC_Handler';
+asm
+.Lloop:
+   bkpt
+   b .Lloop
+end;
+
+procedure _PendSV_Handler; assembler; nostackframe; public name '_PendSV_Handler';
+asm
+.Lloop:
+   bkpt
+   b .Lloop
+end;
+
+procedure _SysTick_Handler; assembler; nostackframe; public name '_SysTick_Handler';
+asm
+.Lloop:
+   bkpt
+   b .Lloop
+end;
+
+procedure HaltProc; assembler; nostackframe; public name'_haltproc';
+asm
+.Lloop:
+   bkpt
+   b .Lloop
+end;
+
+procedure Startup; assembler; nostackframe; [public, alias: '_START'];
+asm
+  ldr r1,.L_etext
+  ldr r2,.L_data
+  ldr r3,.L_edata
+  mov r4,#4
+.Lcopyloop:
+//  cmp r2,r3
+//  ittt ls
+//  ldrls r0,[r1],#4
+//  strls r0,[r2],#4
+//  bls .Lcopyloop
+    ldr r0,[r1]
+    str r0,[r2]
+    add r1,r1,r4
+    add r2,r2,r4
+    cmp r2,r3
+    bls .Lcopyloop
+  // clear onboard ram
+  ldr r1,.L_bss_start
+  ldr r2,.L_bss_end
+  mov r0,#0
+.Lzeroloop:
+  //cmp r1,r2
+  //itt ls
+  //strls r0,[r1],#4
+  //bls .Lzeroloop
+  str r0,[r1]
+  add r1,r1,r4
+  cmp r1,r2
+  bls .Lzeroloop
+
+  ldr r0, .Lvtor
+  ldr r1, .Ltext_start
+  str r1, [r0]
+
+  bl PASCALMAIN
+  b HaltProc
+  .balign 4
+.L_bss_start:
+  .long _bss_start
+.L_bss_end:
+  .long _bss_end
+.L_etext:
+  .long _etext
+.L_data:
+  .long _data
+.L_edata:
+  .long _edata
+.Lvtor:
+  .long 0xE000ED08
+.Ltext_start:
+  .long _text_start
+end;

+ 830 - 0
rtl/embedded/arm/rp2040.pp

@@ -0,0 +1,830 @@
+unit rp2040;
+interface
+{$PACKRECORDS C}
+{$GOTO ON}
+{$SCOPEDENUMS ON}
+
+type
+  TIRQn_Enum = (
+    NonMaskableInt_IRQn = -14,        
+    HardFault_IRQn = -13,             
+    SVC_IRQn    = -5,                 
+    PendSV_IRQn = -2,                 
+    SysTick_IRQn = -1,                
+    TIMER_IRQ_0 = 0,
+    TIMER_IRQ_1 = 1,
+    TIMER_IRQ_2 = 2,
+    TIMER_IRQ_3 = 3,
+    PWM_IRQ_WRAP =4,
+    USBCTRL_IRQ =5,
+    XIP_IRQ     =6,
+    PIO0_IRQ_0  =7,
+    PIO0_IRQ_1  =8,
+    PIO1_IRQ_0  =9,
+    PIO1_IRQ_1  =10,
+    DMA_IRQ_0   =11,
+    DMA_IRQ_1   =12,
+    IO_IRQ_BANK0=13,
+    IO_IRQ_QSPI  =14,
+    SIO_IRQ_PROC0=15,
+    SIO_IRQ_PROC1 =16,
+    CLOCKS_IRQ =17,
+    SPI0_IRQ =18,
+    SPI1_IRQ =19,
+    UART0_IRQ =20,
+    UART1_IRQ =21,
+    ADC0_IRQ_FIFO=22,
+    I2C0_IRQ=23,
+    I2C1_IRQ=24,
+    RTC_IRQ=25
+  );
+
+type
+  TADC_Registers = record
+    cs : longWord;
+    result : longWord;
+    fcs : longWord;
+    fifo : longWord;
+    &div : longWord;
+    intr : longWord;
+    inte : longWord;
+    intf : longWord;
+    ints : longWord;
+  end;
+
+  TBUSCTRL_Registers = record
+    priority : longWord;
+    priority_ack : longWord;
+    perf : array[0..3] of record
+      ctr : longWord;
+      sel : longWord;
+    end;
+  end;
+
+  TCLOCK_Registers = record
+    ctrl : longWord;
+    &div : longWord;
+    selected : longWord;
+  end;
+
+  TFC_Registers = record
+    ref_khz : longWord;
+    min_khz : longWord;
+    max_khz : longWord;
+    delay : longWord;
+    interval : longWord;
+    src : longWord;
+    status : longWord;
+    result : longWord;
+  end;
+
+  TCLOCKS_Registers = record
+    clk_gpout : array[0..3] of TCLOCK_Registers;
+    clk_ref : TCLOCK_Registers;
+    clk_sys : TCLOCK_Registers;
+    clk_peri : TCLOCK_Registers;
+    clk_usb : TCLOCK_Registers;
+    clk_adc : TCLOCK_Registers;
+    clk_rtc : TCLOCK_Registers;
+    clk_sys_resus : record
+      ctrl : longWord;
+      status : longWord;
+    end;
+    fc0 : TFC_Registers;
+    wake_en0 : longWord;
+    wake_en1 : longWord;
+    sleep_en0 : longWord;
+    sleep_en1 : longWord;
+    enabled0 : longWord;
+    enabled1 : longWord;
+    intr : longWord;
+    inte : longWord;
+    intf : longWord;
+    ints : longWord;
+  end;
+
+  TDMACHANNEL_Registers = record
+    read_addr : longWord;
+    write_addr : longWord;
+    transfer_count : longWord;
+    ctrl_trig : longWord;
+    al1_ctrl : longWord;
+    al1_read_addr : longWord;
+    al1_write_addr : longWord;
+    al1_transfer_count_trig : longWord;
+    al2_ctrl : longWord;
+    al2_transfer_count : longWord;
+    al2_read_addr : longWord;
+    al2_write_addr_trig : longWord;
+    al3_ctrl : longWord;
+    al3_write_addr : longWord;
+    al3_transfer_count : longWord;
+    al3_read_addr_trig : longWord;
+  end;
+
+  TDMA_Registers = record
+    ch : array[0..11] of TDMACHANNEL_Registers;
+    RESERVED0 : array[0..63] of longWord;
+    intr : longWord;
+    inte0 : longWord;
+    intf0 : longWord;
+    ints0 : longWord;
+    RESERVED1 : longWord;
+    inte1 : longWord;
+    intf1 : longWord;
+    ints1 : longWord;
+    timer : array[0..1] of longWord;
+    RESERVED2 : array[0..1] of longWord;
+    multi_channel_trigger : longWord;
+    sniff_ctrl : longWord;
+    sniff_data : longWord;
+    RESERVED3 : longWord;
+    fifo_levels : longWord;
+    abort : longWord;
+  end;
+
+  TDMADEBUG_Registers = record
+    ch : array[0..11] of record
+      ctrdeq : longWord;
+      tcr : longWord;
+      RESERVED0 : array[0..13] of longWord;
+    end;
+  end;
+
+  TI2C_Registers = record
+    con : longWord;
+    tar : longWord;
+    sar : longWord;
+    RESERVED0 : longWord;
+    data_cmd : longWord;
+    ss_scl_hcnt : longWord;
+    ss_scl_lcnt : longWord;
+    fs_scl_hcnt : longWord;
+    fs_scl_lcnt : longWord;
+    RESERVED1 : array[0..1] of longWord;
+    intr_stat : longWord;
+    intr_mask : longWord;
+    raw_intr_stat : longWord;
+    rx_tl : longWord;
+    tx_tl : longWord;
+    clr_intr : longWord;
+    clr_rx_under : longWord;
+    clr_rx_over : longWord;
+    clr_tx_over : longWord;
+    clr_rd_req : longWord;
+    clr_tx_abrt : longWord;
+    clr_rx_done : longWord;
+    clr_activity : longWord;
+    clr_stop_det : longWord;
+    clr_start_det : longWord;
+    clr_gen_call : longWord;
+    enable : longWord;
+    status : longWord;
+    txflr : longWord;
+    rxflr : longWord;
+    sda_hold : longWord;
+    tx_abrt_source : longWord;
+    slv_data_nack_only : longWord;
+    dma_cr : longWord;
+    dma_tdlr : longWord;
+    dma_rdlr : longWord;
+    sda_setup : longWord;
+    ack_general_call : longWord;
+    enable_status : longWord;
+    fs_spklen : longWord;
+    RESERVED2 : longWord;
+    clr_restart_det : longWord;
+    RESERVED3 : array[0..17] of longWord;
+    comp_param_1 : longWord;
+    comp_version : longWord;
+    comp_type : longWord;
+  end;
+
+  TIOIRQCTRL_Registers = record
+    inte : array[0..3] of longWord;
+    intf : array[0..3] of longWord;
+    ints : array[0..3] of longWord;
+  end;
+
+  TIOBANK0_Registers = record
+    io : array[0..29] of record
+      status : longWord;
+      ctrl : longWord;
+    end;
+    intr : array[0..3] of longWord;
+    proc0_irq_ctrl : TIOIRQCTRL_Registers;
+    proc1_irq_ctrl : TIOIRQCTRL_Registers;
+    dormant_wake_irq_ctrl : TIOIRQCTRL_Registers;
+  end;
+
+  TIOQSPI_Registers = record
+    io : array[0..5] of record
+      status : longWord;
+      ctrl : longWord;
+    end;
+  end;
+
+  TPADSQSPI_Registers = record
+    voltage_select : longWord;
+    io : array[0..5] of longWord;
+  end;
+
+  TPADSBANK0_Registers = record
+    voltage_select : longWord;
+    io : array[0..29] of longWord;
+  end;
+
+  TPIO_Registers = record
+    ctrl : longWord;
+    fstat : longWord;
+    fdebug : longWord;
+    flevel : longWord;
+    txf : array[0..1] of longWord;
+    rxf : array[0..1] of longWord;
+    irq : longWord;
+    irq_force : longWord;
+    input_sync_bypass : longWord;
+    dbg_padout : longWord;
+    dbg_padoe : longWord;
+    dbg_cfginfo : longWord;
+    instr_mem : array[0..31] of longWord;
+    sm : array[0..1] of record
+      clkdiv : longWord;
+      execctrl : longWord;
+      shiftctrl : longWord;
+      addr : longWord;
+      instr : longWord;
+      pinctrl : longWord;
+    end;
+    intr : longWord;
+    inte0 : longWord;
+    intf0 : longWord;
+    ints0 : longWord;
+    inte1 : longWord;
+    intf1 : longWord;
+    ints1 : longWord;
+  end;
+
+  TPLL_Registers = record
+    cs : longWord;
+    pwr : longWord;
+    fbdiv_int : longWord;
+    prim : longWord;
+  end;
+
+  TPSM_Registers = record
+    frce_on : longWord;
+    frce_off : longWord;
+    wdsel : longWord;
+    done : longWord;
+  end;
+
+  TPWMSLICE_Registers = record
+    csr : longWord;
+    &div : longWord;
+    ctr : longWord;
+    cc : longWord;
+    top : longWord;
+  end;
+
+  TPWM_Registers = record
+    slice : array[0..7] of TPWMSLICE_Registers;
+    en : longWord;
+    intr : longWord;
+    inte : longWord;
+    intf : longWord;
+    ints : longWord;
+  end;
+
+  TRESETS_Registers = record
+    reset : longWord;
+    wdsel : longWord;
+    reset_done : longWord;
+  end;
+
+  TROSC_Registers = record
+    ctrl : longWord;
+    freqa : longWord;
+    freqb : longWord;
+    dormant : longWord;
+    &div : longWord;
+    phase : longWord;
+    status : longWord;
+    randombit : longWord;
+    count : longWord;
+    dftx : longWord;
+  end;
+
+  TRTC_Registers = record
+    clkdiv_m1 : longWord;
+    setup_0 : longWord;
+    setup_1 : longWord;
+    ctrl : longWord;
+    irq_setup_0 : longWord;
+    irq_setup_1 : longWord;
+    rtc_1 : longWord;
+    rtc_0 : longWord;
+    intr : longWord;
+    inte : longWord;
+    intf : longWord;
+    ints : longWord;
+  end;
+
+  TINTERP_Registers = record
+    accum : array[0..1] of longWord;
+    base : array[0..2] of longWord;
+    pop : array[0..2] of longWord;
+    peek : array[0..2] of longWord;
+    ctrl : array[0..1] of longWord;
+    add_raw : array[0..1] of longWord;
+    base01 : longWord;
+  end;
+
+  TSIO_Registers = record
+    cpuid : longWord;
+    gpio_in : longWord;
+    gpio_hi_in : longWord;
+    RESERVED0 : longWord;
+    gpio_out : longWord;
+    gpio_set : longWord;
+    gpio_clr : longWord;
+    gpio_togl : longWord;
+    gpio_oe : longWord;
+    gpio_oe_set : longWord;
+    gpio_oe_clr : longWord;
+    gpio_oe_togl : longWord;
+    gpio_hi_out : longWord;
+    gpio_hi_set : longWord;
+    gpio_hi_clr : longWord;
+    gpio_hi_togl : longWord;
+    gpio_hi_oe : longWord;
+    gpio_hi_oe_set : longWord;
+    gpio_hi_oe_clr : longWord;
+    gpio_hi_oe_togl : longWord;
+    fifo_st : longWord;
+    fifo_wr : longWord;
+    fifo_rd : longWord;
+    spinlock_st : longWord;
+    div_udividend : longWord;
+    div_udivisor : longWord;
+    div_sdividend : longWord;
+    div_sdivisor : longWord;
+    div_quotient : longWord;
+    div_remainder : longWord;
+    div_csr : longWord;
+    RESERVED1 : longWord;
+    interp : array[0..1] of TINTERP_Registers;
+    spinlock : array[0..31] of longWord;
+  end;
+
+  TSPI_Registers = record
+    cr0 : longWord;
+    cr1 : longWord;
+    dr : longWord;
+    sr : longWord;
+    cpsr : longWord;
+    imsc : longWord;
+    ris : longWord;
+    mis : longWord;
+    icr : longWord;
+    dmacr : longWord;
+  end;
+
+  TSSI_Registers = record
+    ctrlr0 : longWord;
+    ctrlr1 : longWord;
+    ssienr : longWord;
+    mwcr : longWord;
+    ser : longWord;
+    baudr : longWord;
+    txftlr : longWord;
+    rxftlr : longWord;
+    txflr : longWord;
+    rxflr : longWord;
+    sr : longWord;
+    imr : longWord;
+    isr : longWord;
+    risr : longWord;
+    txoicr : longWord;
+    rxoicr : longWord;
+    rxuicr : longWord;
+    msticr : longWord;
+    icr : longWord;
+    dmacr : longWord;
+    dmatdlr : longWord;
+    dmardlr : longWord;
+    idr : longWord;
+    ssi_version_id : longWord;
+    dr0 : longWord;
+    RESERVED0 : array[0..34] of longWord;
+    rx_sample_dly : longWord;
+    spi_ctrlr0 : longWord;
+    txd_drive_edge : longWord;
+  end;
+
+  TSYSCFG_Registers = record
+    proc0_nmi_mask : longWord;
+    proc1_nmi_mask : longWord;
+    proc_config : longWord;
+    proc_in_sync_bypass : longWord;
+    proc_in_sync_bypass_hi : longWord;
+    dbgforce : longWord;
+    mempowerdown : longWord;
+  end;
+
+  TSYSINFO_Registers = record
+    chip_id : longWord;
+    platform : longWord;
+    reserved0 : array[0..$3F-$08] of longWord;
+    gitref_rp2040 : longWord;
+  end;
+
+  TTIMER_Registers = record
+    timehw : longWord;
+    timelw : longWord;
+    timehr : longWord;
+    timelr : longWord;
+    alarm : array[0..3] of longWord;
+    armed : longWord;
+    timerawh : longWord;
+    timerawl : longWord;
+    dbgpause : longWord;
+    pause : longWord;
+    intr : longWord;
+    inte : longWord;
+    intf : longWord;
+    ints : longWord;
+  end;
+
+  TUART_Registers = record
+    dr : longWord;
+    rsr : longWord;
+    RESERVED0 : array[0..3] of longWord;
+    fr : longWord;
+    RESERVED1 : longWord;
+    ilpr : longWord;
+    ibrd : longWord;
+    fbrd : longWord;
+    lcr_h : longWord;
+    cr : longWord;
+    ifls : longWord;
+    imsc : longWord;
+    ris : longWord;
+    mis : longWord;
+    icr : longWord;
+    dmacr : longWord;
+  end;
+
+  TUSBDEVICEDPRAM = record
+    setup_packet : array[0..7] of byte;
+    ep_ctrl : array[0..14] of record
+      &in : longWord;
+      &out : longWord;
+    end;
+    ep_buf_ctrl : array[0..15] of record
+      &in : longWord;
+      &out : longWord;
+    end;
+    ep0_buf_a : array[0..63] of byte;
+    ep0_buf_b : array[0..63] of byte;
+    epx_data : array[0..(4096-$180)-1] of byte;
+  end;
+
+  TUSBHOSTDPRAM = record
+    setup_packet : array[0..7] of byte;
+    int_ep_ctrl : array[0..14] of record
+      ctrl : longWord;
+      spare : longWord;
+    end;
+    epx_buf_ctrl : longWord;
+    _spare0 : longWord;
+    int_ep_buffer_ctrl : array[0..14] of record
+      ctrl : longWord;
+      spare : longWord;
+    end;
+    epx_ctrl : longWord;
+    _spare1 : array[0..123] of byte;
+    epx_data : array[0..(4096-$180)-1] of byte;
+  end;
+
+  TUSB_Registers = record
+    dev_addr_ctrl : longWord;
+    int_ep_addr_ctrl : array[1..15] of longWord;
+    main_ctrl : longWord;
+    sof_wr : longWord;
+    sof_rd : longWord;
+    sie_ctrl : longWord;
+    sie_status : longWord;
+    int_ep_ctrl : longWord;
+    buf_status : longWord;
+    buf_cpu_should_handle : longWord;
+    abort : longWord;
+    abort_done : longWord;
+    ep_stall_arm : longWord;
+    nak_poll : longWord;
+    ep_nak_stall_status : longWord;
+    muxing : longWord;
+    pwr : longWord;
+    phy_direct : longWord;
+    phy_direct_override : longWord;
+    phy_trim : longWord;
+    linestate_tuning : longWord;
+    intr : longWord;
+    inte : longWord;
+    intf : longWord;
+    ints : longWord;
+  end;
+
+  TVREGANDCHIPRESET_Registers = record
+    vreg : longWord;
+    bod : longWord;
+    chip_reset : longWord;
+  end;
+
+  TWATCHDOG_Registers = record
+    ctrl : longWord;
+    load : longWord;
+    reason : longWord;
+    scratch : array[0..7] of longWord;
+    tick : longWord;
+  end;
+
+  TXIPCTRL_Registers = record
+    ctrl : longWord;
+    flush : longWord;
+    stat : longWord;
+    ctr_hit : longWord;
+    ctr_acc : longWord;
+    stream_addr : longWord;
+    stream_ctr : longWord;
+    stream_fifo : longWord;
+  end;
+
+  TXOSC_Registers = record
+    ctrl : longWord;
+    status : longWord;
+    dormant : longWord;
+    startup : longWord;
+    RESERVED0 : array[0..2] of longWord;
+    count : longWord;
+  end;
+
+  TMPU_Registers = record
+    _type : longWord;
+    ctrl : longWord;
+    rnr : longWord;
+    rbar : longWord;
+    rasr : longWord;
+  end;
+
+  TSYSTICK_Registers = record
+    csr : longWord;
+    rvr : longWord;
+    cvr : longWord;
+    calib : longWord;
+  end;
+
+  TSCB_Reqisters = record
+    cpuid : longWord;
+    icsr : longWord;
+    vtor : longWord;
+    aircr : longWord;
+    scr : longWord;
+  end;
+
+const
+  __NVIC_PRIO_BITS= 2;
+  SRAM0_BASE      = $21000000;
+  SRAM1_BASE      = $21010000;
+  SRAM2_BASE      = $21020000;
+  SRAM3_BASE      = $21030000;
+  SYSINFO_BASE    = $40000000;
+  SYSCFG_BASE     = $40004000;
+  CLOCKS_BASE     = $40008000;
+  RESETS_BASE     = $4000c000;
+  PSM_BASE        = $40010000;
+  IO_BANK0_BASE   = $40014000;
+  IO_QSPI_BASE    = $40018000;
+  PADS_BANK0_BASE = $4001c000;
+  PADS_QSPI_BASE  = $40020000;
+  XOSC_BASE       = $40024000;
+  PLL_SYS_BASE    = $40028000;
+  PLL_USB_BASE    = $4002c000;
+  BUSCTRL_BASE    = $40030000;
+  UART0_BASE      = $40034000;
+  UART1_BASE      = $40038000;
+  SPI0_BASE       = $4003c000;
+  SPI1_BASE       = $40040000;
+  I2C0_BASE       = $40044000;
+  I2C1_BASE       = $40048000;
+  ADC_BASE        = $4004c000;
+  PWM_BASE        = $40050000;
+  TIMER_BASE      = $40054000;
+  WATCHDOG_BASE   = $40058000;
+  RTC_BASE        = $4005c000;
+  ROSC_BASE       = $40060000;
+  VREG_AND_CHIP_RESET_BASE = $40064000;
+  TBMAN_BASE      = $4006c000;
+  DMA_BASE        = $50000000;
+  USBCTRL_BASE    = $50100000;
+  USBCTRL_DPRAM_BASE = $50100000;
+  USBCTRL_REGS_BASE = $50110000;
+  PIO0_BASE       = $50200000;
+  PIO1_BASE       = $50300000;
+  XIP_AUX_BASE    = $50400000;
+  SIO_BASE        = $d0000000;
+  PPB_BASE        = $e0000000;
+
+var
+  SysInfo : TSysInfo_Registers absolute SYSINFO_BASE;
+  SysCfg : TSYSCFG_REGISTERS absolute SYSCFG_BASE;
+  Clocks : TCLOCKS_Registers absolute CLOCKS_BASE;
+  Resets : TRESETS_Registers absolute RESETS_BASE;
+  PSM : TPSM_Registers absolute PSM_BASE;
+  IOBANK0 : TIOBANK0_Registers absolute IO_BANK0_BASE;
+  IOQSPI : TIOQSPI_Registers absolute IO_QSPI_BASE;
+  PADSBANK0 : TPADSBANK0_Registers absolute PADS_BANK0_BASE;
+  PADSQSPI : TPADSQSPI_Registers absolute PADS_QSPI_BASE;
+  XOSC : TXOSC_Registers absolute XOSC_BASE;
+  PLLSYS : TPLL_Registers absolute PLL_SYS_BASE;
+  PLLUSB : TPLL_Registers absolute PLL_USB_BASE;
+  BUSCTRL : TBUSCTRL_Registers absolute BUSCTRL_BASE;
+  UART0 : TUART_Registers absolute UART0_BASE;
+  UART1 : TUART_Registers absolute UART1_BASE;
+  SPI0 : TSPI_Registers absolute SPI0_BASE;
+  SPI1 : TSPI_Registers absolute SPI1_BASE;
+  I2C0 : TI2C_Registers absolute I2C0_BASE;
+  I2C1 : TI2C_Registers absolute I2C1_BASE;
+  ADC : TADC_Registers absolute ADC_BASE;
+  PWM : TPWM_Registers absolute PWM_BASE;
+  TIMER : TTIMER_Registers absolute TIMER_BASE;
+  WATCHDOG : TWATCHDOG_Registers absolute WATCHDOG_BASE;
+  RTC : TRTC_Registers absolute RTC_BASE;
+  ROSC : TROSC_Registers absolute ROSC_BASE;
+  VREGANDCHIPRESET : TVREGANDCHIPRESET_Registers absolute VREG_AND_CHIP_RESET_BASE;
+  DMA : TDMA_Registers absolute DMA_BASE;
+  //USBCTRL_BASE = $50100000
+  //USBCTRL_DPRAM_BASE = $50100000
+  USB : TUSB_Registers absolute USBCTRL_REGS_BASE;
+  PIO0 : TPIO_Registers absolute PIO0_BASE;
+  PIO1 : TPIO_Registers absolute PIO1_BASE;
+  //XIP_AUX_BASE = $50400000
+  SIO : TSIO_Registers absolute SIO_BASE;
+
+implementation
+
+procedure NMI_Handler; external name 'NMI_Handler';
+procedure HardFault_Handler; external name 'HardFault_Handler';
+procedure SVC_Handler; external name 'SVC_Handler';
+procedure PendSV_Handler; external name 'PendSV_Handler';
+procedure SysTick_Handler; external name 'SysTick_Handler';
+procedure TIMER_IRQ_0_Handler;  external name 'TIMER_IRQ_0_Handler';
+procedure TIMER_IRQ_1_Handler;  external name 'TIMER_IRQ_1_Handler';
+procedure TIMER_IRQ_2_Handler;  external name 'TIMER_IRQ_2_Handler';
+procedure TIMER_IRQ_3_Handler;  external name 'TIMER_IRQ_3_Handler';
+procedure PWM_IRQ_WRAP_Handler;  external name 'PWM_IRQ_WRAP_Handler';
+procedure USBCTRL_IRQ_Handler;  external name 'USBCTRL_IRQ_Handler';
+procedure XIP_IRQ_Handler;  external name 'XIP_IRQ_Handler';
+procedure PIO0_IRQ_0_Handler;  external name 'PIO0_IRQ_0_Handler';
+procedure PIO0_IRQ_1_Handler;  external name 'PIO0_IRQ_1_Handler';
+procedure PIO1_IRQ_0_Handler;  external name 'PIO1_IRQ_0_Handler';
+procedure PIO1_IRQ_1_Handler; external name 'PIO1_IRQ_1_Handler';
+procedure DMA_IRQ_0_Handler; external name 'DMA_IRQ_0_Handler';
+procedure DMA_IRQ_1_Handler; external name 'DMA_IRQ_1_Handler';
+procedure IO_IRQ_BANK0_Handler; external name 'IO_IRQ_BANK0_Handler';
+procedure IO_IRQ_QSPI_Handler; external name 'IO_IRQ_QSPI_Handler';
+procedure SIO_IRQ_PROC0_Handler; external name 'SIO_IRQ_PROC0_Handler';
+procedure SIO_IRQ_PROC1_Handler; external name 'SIO_IRQ_PROC1_Handler';
+procedure CLOCKS_IRQ_Handler; external name 'CLOCKS_IRQ_Handler';
+procedure SPI0_IRQ_Handler; external name 'SPI0_IRQ_Handler';
+procedure SPI1_IRQ_Handler; external name 'SPI1_IRQ_Handler';
+procedure UART0_IRQ_Handler; external name 'UART0_IRQ_Handler';
+procedure UART1_IRQ_Handler; external name 'UART1_IRQ_Handler';
+procedure ADC_IRQ_FIFO_Handler; external name 'ADC_IRQ_FIFO_Handler';
+procedure I2C0_IRQ_Handler; external name 'I2C0_IRQ_Handler';
+procedure I2C1_IRQ_Handler; external name 'I2C1_IRQ_Handler';
+procedure RTC_IRQ_Handler; external name 'RTC_IRQ_Handler';
+
+{$i cortexm0p_start.inc}
+
+procedure Vectors; assembler; nostackframe;
+label interrupt_vectors;
+asm
+  .section ".init.interrupt_vectors"
+  interrupt_vectors:
+  .long _stack_top
+  .long Startup
+  .long NMI_Handler
+  .long HardFault_Handler
+  .long 0
+  .long 0
+  .long 0
+  .long 0
+  .long 0
+  .long 0
+  .long 0
+  .long SVC_Handler
+  .long 0
+  .long 0
+  .long PendSV_Handler
+  .long SysTick_Handler
+  .long TIMER_IRQ_0_Handler
+  .long TIMER_IRQ_1_Handler
+  .long TIMER_IRQ_2_Handler
+  .long TIMER_IRQ_3_Handler
+  .long PWM_IRQ_WRAP_Handler
+  .long USBCTRL_IRQ_Handler
+  .long XIP_IRQ_Handler
+  .long PIO0_IRQ_0_Handler
+  .long PIO0_IRQ_1_Handler
+  .long PIO1_IRQ_0_Handler
+  .long PIO1_IRQ_1_Handler
+  .long DMA_IRQ_0_Handler
+  .long DMA_IRQ_1_Handler
+  .long IO_IRQ_BANK0_Handler
+  .long IO_IRQ_QSPI_Handler
+  .long SIO_IRQ_PROC0_Handler
+  .long SIO_IRQ_PROC1_Handler
+  .long CLOCKS_IRQ_Handler
+  .long SPI0_IRQ_Handler
+  .long SPI1_IRQ_Handler
+  .long UART0_IRQ_Handler
+  .long UART1_IRQ_Handler
+  .long ADC_IRQ_FIFO_Handler
+  .long I2C0_IRQ_Handler
+  .long I2C1_IRQ_Handler
+  .long RTC_IRQ_Handler
+  .long 0
+  .long 0
+  .long 0
+  .long 0
+  .long 0
+  .long 0
+
+
+  .weak NMI_Handler
+  .weak HardFault_Handler
+  .weak SVC_Handler
+  .weak PendSV_Handler
+  .weak SysTick_Handler
+  .weak TIMER_IRQ_0_Handler
+  .weak TIMER_IRQ_1_Handler
+  .weak TIMER_IRQ_2_Handler
+  .weak TIMER_IRQ_3_Handler
+  .weak PWM_IRQ_WRAP_Handler
+  .weak USBCTRL_IRQ_Handler
+  .weak XIP_IRQ_Handler
+  .weak PIO0_IRQ_0_Handler
+  .weak PIO0_IRQ_1_Handler
+  .weak PIO1_IRQ_0_Handler
+  .weak PIO1_IRQ_1_Handler
+  .weak DMA_IRQ_0_Handler
+  .weak DMA_IRQ_1_Handler
+  .weak IO_IRQ_BANK0_Handler
+  .weak IO_IRQ_QSPI_Handler
+  .weak SIO_IRQ_PROC0_Handler
+  .weak SIO_IRQ_PROC1_Handler
+  .weak CLOCKS_IRQ_Handler
+  .weak SPI0_IRQ_Handler
+  .weak SPI1_IRQ_Handler
+  .weak UART0_IRQ_Handler
+  .weak UART1_IRQ_Handler
+  .weak ADC_IRQ_FIFO_Handler
+  .weak I2C0_IRQ_Handler
+  .weak I2C1_IRQ_Handler
+  .weak RTC_IRQ_Handler
+
+  .set NMI_Handler, _NMI_Handler
+  .set HardFault_Handler, _HardFault_Handler
+  .set SVC_Handler, _SVC_Handler
+  .set PendSV_Handler, _PendSV_Handler
+  .set SysTick_Handler, _SysTick_Handler
+  .set TIMER_IRQ_0_Handler, Haltproc
+  .set TIMER_IRQ_1_Handler, Haltproc
+  .set TIMER_IRQ_2_Handler, Haltproc
+  .set TIMER_IRQ_3_Handler, Haltproc
+  .set PWM_IRQ_WRAP_Handler, Haltproc
+  .set USBCTRL_IRQ_Handler, Haltproc
+  .set XIP_IRQ_Handler, Haltproc
+  .set PIO0_IRQ_0_Handler, Haltproc
+  .set PIO0_IRQ_1_Handler, Haltproc
+  .set PIO1_IRQ_0_Handler, Haltproc
+  .set PIO1_IRQ_1_Handler, Haltproc
+  .set DMA_IRQ_0_Handler, Haltproc
+  .set DMA_IRQ_1_Handler, Haltproc
+  .set IO_IRQ_BANK0_Handler, Haltproc
+  .set IO_IRQ_QSPI_Handler, Haltproc
+  .set SIO_IRQ_PROC0_Handler, Haltproc
+  .set SIO_IRQ_PROC1_Handler, Haltproc
+  .set CLOCKS_IRQ_Handler, Haltproc
+  .set SPI0_IRQ_Handler, Haltproc
+  .set SPI1_IRQ_Handler, Haltproc
+  .set UART0_IRQ_Handler, Haltproc
+  .set UART1_IRQ_Handler, Haltproc
+  .set ADC_IRQ_FIFO_Handler, Haltproc
+  .set I2C0_IRQ_Handler, Haltproc
+  .set I2C1_IRQ_Handler, Haltproc
+  .set RTC_IRQ_Handler, Haltproc
+  .text
+  end;
+end.