11//! The Neotron SDK
22//!
33//! Defines the API supplied to applications that run on Neotron OS
4+ //!
5+ //! You should use this crate when writing applications that run on Neotron OS.
6+ //!
7+ //! This SDK attempts to detect targets that support UNIX or Windows, and
8+ //! implements some code to talk to the appropriate UNIX or Windows API. This
9+ //! allows some level of portable, mainly to support application testing on
10+ //! those OSes.
11+ //!
12+ //! On a *bare-metal* target (i.e. where the OS is `none`), the SDK expects the
13+ //! Neotron OS to pass the callback table to the entry point
14+ //! ([`app_entry()`](app_entry)). Once initialised, the SDK then expects you
15+ //! application to provide an `extern "C"` `no-mangle` function called
16+ //! `neotron_main`, which the SDK will call.
417
518#![ cfg_attr( target_os = "none" , no_std) ]
619
@@ -52,6 +65,9 @@ static ARG_COUNT: AtomicUsize = AtomicUsize::new(0);
5265/// Start of the argument list
5366static ARG_PTR : AtomicPtr < FfiString > = AtomicPtr :: new ( core:: ptr:: null_mut ( ) ) ;
5467
68+ /// Random number generator state
69+ static RAND_STATE : core:: sync:: atomic:: AtomicU16 = core:: sync:: atomic:: AtomicU16 :: new ( 0 ) ;
70+
5571// ============================================================================
5672// Types
5773// ============================================================================
@@ -261,16 +277,25 @@ impl Drop for ReadDir {
261277 }
262278}
263279
280+ /// The result of a *Wait for Key* operation.
281+ #[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
282+ pub enum WaitForKey {
283+ /// User wants more data
284+ More ,
285+ /// User wants to quit
286+ Quit ,
287+ }
288+
264289// ============================================================================
265290// Functions
266291// ============================================================================
267292
268293/// The function the OS calls to start the application.
269294///
270- /// Will jump to the application entry point, and `extern "C"` function
271- /// called `main `.
295+ /// Will initialise the SDK and then jump to the application entry point, which
296+ /// is an `extern "C"` function called `neotron_main `.
272297#[ no_mangle]
273- extern "C" fn app_entry ( api : * const Api , argc : usize , argv : * const FfiString ) -> i32 {
298+ pub extern "C" fn app_entry ( api : * const Api , argc : usize , argv : * const FfiString ) -> i32 {
274299 let _check: AppStartFn = app_entry;
275300 API . store ( api as * mut Api , Ordering :: Relaxed ) ;
276301 ARG_COUNT . store ( argc, Ordering :: Relaxed ) ;
@@ -304,21 +329,29 @@ pub fn arg(n: usize) -> Option<String> {
304329}
305330
306331/// Get information about a file on disk.
332+ ///
333+ /// **Note:** This function is not implemented currently.
307334pub fn stat ( _path : path:: Path ) -> Result < api:: file:: Stat > {
308335 todo ! ( )
309336}
310337
311338/// Delete a file from disk
339+ ///
340+ /// **Note:** This function is not implemented currently.
312341pub fn delete ( _path : path:: Path ) -> Result < ( ) > {
313342 todo ! ( )
314343}
315344
316345/// Change the current working directory to the given path.
346+ ///
347+ /// **Note:** This function is not implemented currently.
317348pub fn chdir ( _path : path:: Path ) -> Result < ( ) > {
318349 todo ! ( )
319350}
320351
321352/// Change the current working directory to that given by the handle.
353+ ///
354+ /// **Note:** This function is not implemented currently.
322355pub fn dchdir ( _dir : api:: dir:: Handle ) -> Result < ( ) > {
323356 todo ! ( )
324357}
@@ -331,11 +364,15 @@ pub fn pwd<F: FnOnce(Result<path::Path>)>(callback: F) {
331364}
332365
333366/// Alllocate some memory
367+ ///
368+ /// **Note:** This function is not implemented currently.
334369pub fn malloc ( _size : usize , _alignment : usize ) -> Result < * mut core:: ffi:: c_void > {
335370 todo ! ( )
336371}
337372
338373/// Free some previously allocated memory.
374+ ///
375+ /// **Note:** This function is not implemented currently.
339376pub fn free ( _ptr : * mut core:: ffi:: c_void , _size : usize , _alignment : usize ) {
340377 todo ! ( )
341378}
@@ -355,33 +392,29 @@ pub const fn stderr() -> File {
355392 File ( api:: file:: Handle :: new_stderr ( ) )
356393}
357394
358- /// Delay for some milliseconds
395+ /// Delay for some given duration before returning.
396+ ///
397+ /// Currently this does a badly calibrated nop busy-wait.
359398#[ cfg( target_os = "none" ) ]
360399pub fn delay ( period : core:: time:: Duration ) {
361- // TODO: sleep on real hardware ?
400+ // TODO: call OS sleep API ?
362401 for _ in 0 ..period. as_micros ( ) {
363402 for _ in 0 ..50 {
364403 unsafe { core:: arch:: asm!( "nop" ) }
365404 }
366405 }
367406}
368407
369- /// Delay for some milliseconds
408+ /// Delay for some given duration before returning.
370409#[ cfg( not( target_os = "none" ) ) ]
371410pub fn delay ( period : core:: time:: Duration ) {
372411 std:: thread:: sleep ( period) ;
373412}
374413
375- /// The result of a *Wait for Key* operation.
376- #[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
377- pub enum WaitForKey {
378- /// User wants more data
379- More ,
380- /// User wants to quit
381- Quit ,
382- }
383-
384414/// Wait for a key
415+ ///
416+ /// Prints `Press Space for more, 'q' to quit...` with a spinner, and waits
417+ /// for you to press the appropriate key.
385418pub fn wait_for_key ( ) -> WaitForKey {
386419 use core:: fmt:: Write ;
387420 let mut ticker = "|/-\\ " . chars ( ) . cycle ( ) ;
@@ -415,8 +448,6 @@ pub fn wait_for_key() -> WaitForKey {
415448 result
416449}
417450
418- static RAND_STATE : core:: sync:: atomic:: AtomicU16 = core:: sync:: atomic:: AtomicU16 :: new ( 0 ) ;
419-
420451/// Seed the 16-bit psuedorandom number generator
421452pub fn srand ( seed : u16 ) {
422453 RAND_STATE . store ( seed, core:: sync:: atomic:: Ordering :: Relaxed ) ;
0 commit comments