diff --git a/rp2040-hal/src/sio.rs b/rp2040-hal/src/sio.rs
index 111376b..063df57 100644
--- a/rp2040-hal/src/sio.rs
+++ b/rp2040-hal/src/sio.rs
@@ -12,22 +12,34 @@
 //! let pins = pac.IO_BANK0.split(pac.PADS_BANK0, sio.gpio_bank0, &mut pac.RESETS);
 //! ```
 use super::*;
-use core::marker::PhantomData;
 
 /// Marker struct for ownership of SIO gpio bank0
 pub struct SioGpioBank0 {
-    _private: PhantomData<u32>,
+    _private: (),
+}
+
+/// Marker struct for ownership of divide/modulo module
+pub struct HwDivider {
+    _private: (),
+}
+
+/// Result of divide/modulo operation
+pub struct DivResult<T> {
+    /// The remainder of divide/modulo operation
+    pub remainder: T,
+    /// The quotient of divide/modulo operation
+    pub quotient: T,
 }
 
 /// Struct containing ownership markers for managing ownership of the SIO registers.
 pub struct Sio {
     _sio: pac::SIO,
-
     /// GPIO Bank 0 registers
     pub gpio_bank0: SioGpioBank0,
+    /// 8-cycle hardware divide/modulo module
+    pub hwdivider: HwDivider,
     // we can hand out other things here, for example:
     // gpio_qspi
-    // divider
     // interp0
     // interp1
 }
@@ -37,9 +49,51 @@ impl Sio {
         Self {
             _sio: sio,
 
-            gpio_bank0: SioGpioBank0 {
-                _private: PhantomData,
-            },
+            gpio_bank0: SioGpioBank0 { _private: () },
+
+            hwdivider: HwDivider { _private: () },
+        }
+    }
+}
+
+impl HwDivider {
+    /// Perform hardware unsigned divide/modulo operation
+    pub fn unsigned(&self, dividend: u32, divisor: u32) -> DivResult<u32> {
+        let sio = unsafe { &(*pac::SIO::ptr()) };
+        sio.div_sdividend.write(|w| unsafe { w.bits(dividend) });
+
+        sio.div_sdivisor.write(|w| unsafe { w.bits(divisor) });
+
+        cortex_m::asm::delay(8);
+
+        // Note: quotient must be read last
+        let remainder = sio.div_remainder.read().bits();
+        let quotient = sio.div_quotient.read().bits();
+
+        DivResult {
+            remainder,
+            quotient,
+        }
+    }
+
+    /// Perform hardware signed divide/modulo operation
+    pub fn signed(&self, dividend: i32, divisor: i32) -> DivResult<i32> {
+        let sio = unsafe { &(*pac::SIO::ptr()) };
+        sio.div_sdividend
+            .write(|w| unsafe { w.bits(dividend as u32) });
+
+        sio.div_sdivisor
+            .write(|w| unsafe { w.bits(divisor as u32) });
+
+        cortex_m::asm::delay(8);
+
+        // Note: quotient must be read last
+        let remainder = sio.div_remainder.read().bits() as i32;
+        let quotient = sio.div_quotient.read().bits() as i32;
+
+        DivResult {
+            remainder,
+            quotient,
         }
     }
 }