#ifndef FW_H
#define FW_H

#include "compiler.h"
#include "picorv32.h"
#include "irq.h"

/* Sometimes useful combination types */
typedef union {
    uint8_t  b[8];
    uint16_t h[4];
    uint32_t l[2];
    uint64_t q;
} qword_t;
typedef union {
    uint8_t  b[4];
    uint16_t h[2];
    uint32_t l;
} lword_t;
typedef union {
    uint8_t  b[2];
    uint16_t h;
} hword_t;

extern const size_t __rom_offset;
extern const uint32_t __dram_checksum;
extern const char __datestamp[];

extern no_return _die(void);
extern no_return exit(int);
extern no_return _exit(int);

/* Value of an absolute symbol with one more _ than here given */
#define abssymval(x)				\
    static inline size_t x (void) {		\
	extern const char _ ## x [];		\
	return (size_t) _ ## x;			\
    }

extern const uint8_t _end[];
extern void *_sbrk(size_t);

extern uint32_t timer_irq_start;
static inline uint32_t timer_count(void)
{
    extern volatile uint32_t timer_irq_count;
    return timer_irq_count;
}

extern void init(void);

extern void mount_abcdrives(void);

extern void read_rtc(void);
extern void write_rtc(void);
extern bool do_write_rtc;
extern void rtc_abc_init(void);
extern void rtc_abc_io_poll(void);
extern void disk_cache_init(void);

extern void pun80_init(void);

extern void romcopy_download(void *, size_t, size_t);
extern void romcopy_bzero(void *, size_t);
extern void rom_print_serial(void);
extern qword_t rom_serial;

extern void run_test_image(void);

#endif /* FW_H */
