Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. #ifndef UMKA_H_INCLUDED
  2. #define UMKA_H_INCLUDED
  3.  
  4. #include <inttypes.h>
  5. #include <stddef.h>
  6. #include <signal.h> // for irq0: siginfo_t
  7.  
  8. #define STDCALL __attribute__((__stdcall__))
  9.  
  10. #define BDFE_LEN_CP866 304
  11. #define BDFE_LEN_UNICODE 560
  12.  
  13. typedef struct {
  14.     uint32_t left, top, right, bottom;
  15. } rect_t;
  16.  
  17. typedef struct {
  18.     uint32_t left, top, width, height;
  19. } box_t;
  20.  
  21. typedef struct {
  22.     uint32_t dr0, dr1, dr2, dr3, dr7;
  23. } dbg_regs_t;
  24.  
  25. typedef struct {
  26.     uint32_t cpu_usage;
  27.     uint16_t window_stack_position;
  28.     uint16_t window_stack_value;
  29.     uint16_t pad;
  30.     char process_name[12];
  31.     uint32_t memory_start;
  32.     uint32_t used_memory;
  33.     uint32_t pid;
  34.     box_t box;
  35.     uint16_t slot_state;
  36.     uint16_t pad2;
  37.     box_t client_box;
  38.     uint8_t wnd_state;
  39.     uint8_t pad3[1024-71];
  40. } __attribute__((packed)) process_information_t;
  41.  
  42. _Static_assert(sizeof(process_information_t) == 0x400,
  43.                "must be 0x400 bytes long");
  44.  
  45. typedef struct {
  46.     box_t box;
  47.     uint32_t cl_workarea;
  48.     uint32_t cl_titlebar;
  49.     uint32_t cl_frames;
  50.     uint8_t z_modif;
  51.     uint8_t fl_wstate;
  52.     uint8_t fl_wdrawn;
  53.     uint8_t fl_redraw;
  54. } __attribute__((packed)) wdata_t;
  55.  
  56. _Static_assert(sizeof(wdata_t) == 0x20,
  57.                "must be 0x20 bytes long");
  58.  
  59. typedef struct {
  60.     uint32_t frame;
  61.     uint32_t grab;
  62.     uint32_t work_3d_dark;
  63.     uint32_t work_3d_light;
  64.     uint32_t grab_text;
  65.     uint32_t work;
  66.     uint32_t work_button;
  67.     uint32_t work_button_text;
  68.     uint32_t work_text;
  69.     uint32_t work_graph;
  70. } system_colors_t;
  71.  
  72. typedef enum {
  73.     DEFAULT_ENCODING,
  74.     CP866,
  75.     UTF16,
  76.     UTF8,
  77.     INVALID_ENCODING,
  78. } fs_enc_t;
  79.  
  80. typedef enum {
  81.     F70 = 70,
  82.     F80 = 80,
  83. } f70or80_t;
  84.  
  85. enum {
  86.     ERROR_SUCCESS,
  87.     ERROR_DISK_BASE,
  88.     ERROR_UNSUPPORTED_FS,
  89.     ERROR_UNKNOWN_FS,
  90.     ERROR_PARTITION,
  91.     ERROR_FILE_NOT_FOUND,
  92.     ERROR_END_OF_FILE,
  93.     ERROR_MEMORY_POINTER,
  94.     ERROR_DISK_FULL,
  95.     ERROR_FS_FAIL,
  96.     ERROR_ACCESS_DENIED,
  97.     ERROR_DEVICE,
  98.     ERROR_OUT_OF_MEMORY,
  99. };
  100.  
  101. typedef struct lhead lhead_t;
  102.  
  103. struct lhead {
  104.     lhead_t *next;
  105.     lhead_t *prev;
  106. };
  107.  
  108. typedef struct {
  109.     lhead_t  wait_list;
  110.     uint32_t count;
  111. } mutex_t;
  112.  
  113. typedef mutex_t rwsem_t;
  114.  
  115. typedef struct {
  116.     uint32_t flags;
  117.     uint32_t sector_size;
  118.     uint64_t capacity;  // in sectors
  119. } diskmediainfo_t;
  120.  
  121. typedef struct {
  122.     uintptr_t   pointer;
  123.     uint32_t    data_size;
  124.     uintptr_t   data;
  125.     uint32_t    sad_size;
  126.     uint32_t    search_start;
  127.     uint32_t    sector_size_log;
  128. } disk_cache_t;
  129.  
  130. typedef struct {
  131.     uint64_t first_sector;
  132.     uint64_t length;    // in sectors
  133.     void *disk;
  134.     void *fs_user_functions;
  135. } partition_t;
  136.  
  137. typedef struct disk_t disk_t;
  138.  
  139. typedef struct {
  140.     uint32_t  strucsize;
  141.     STDCALL void (*close)(void *userdata);
  142.     STDCALL void (*closemedia)(void *userdata);
  143.     STDCALL int (*querymedia)(void *userdata, diskmediainfo_t *info);
  144.     STDCALL int (*read)(void *userdata, void *buffer, off_t startsector,
  145.                         size_t *numsectors);
  146.     STDCALL int (*write)(void *userdata, void *buffer, off_t startsector,
  147.                          size_t *numsectors);
  148.     STDCALL int (*flush)(void *userdata);
  149.     STDCALL unsigned int (*adjust_cache_size)(void *userdata,
  150.                                               size_t suggested_size);
  151. } diskfunc_t;
  152.  
  153. struct disk_t {
  154.     disk_t *next;
  155.     disk_t *prev;
  156.     diskfunc_t *functions;
  157.     const char *name;
  158.     void *userdata;
  159.     uint32_t driver_flags;
  160.     uint32_t ref_count;
  161.     mutex_t media_lock;
  162.     uint8_t media_inserted;
  163.     uint8_t media_used;
  164.     uint16_t padding;
  165.     uint32_t media_ref_count;
  166.     diskmediainfo_t media_info;
  167.     uint32_t num_partitions;
  168.     partition_t **partitions;
  169.     uint32_t cache_size;
  170.     mutex_t cache_lock;
  171.     disk_cache_t sys_cache;
  172.     disk_cache_t app_cache;
  173. };
  174.  
  175. typedef struct {
  176.     uint32_t attr;
  177.     uint32_t enc;
  178.     uint32_t ctime;
  179.     uint32_t cdate;
  180.     uint32_t atime;
  181.     uint32_t adate;
  182.     uint32_t mtime;
  183.     uint32_t mdate;
  184.     uint64_t size;
  185.     char name[0x7777];  // how to handle this properly? FIXME
  186. } bdfe_t;
  187.  
  188. typedef struct {
  189.     int32_t status;
  190.     uint32_t count;
  191. } f7080ret_t;
  192.  
  193. typedef struct {
  194.     uint32_t sf;
  195.     uint64_t offset;
  196.     uint32_t count;
  197.     void *buf;
  198.     union {
  199.         struct {
  200.             uint8_t zero;
  201.             const char *path;
  202.         } __attribute__((packed)) f70;
  203.         struct {
  204.             uint32_t path_encoding;
  205.             const char *path;
  206.         } f80;
  207.     } u;
  208. } __attribute__((packed)) f7080s0arg_t;
  209.  
  210. typedef struct {
  211.     uint32_t sf;
  212.     uint32_t offset;
  213.     uint32_t encoding;
  214.     uint32_t size;
  215.     void *buf;
  216.     union {
  217.         struct {
  218.             uint8_t zero;
  219.             const char *path;
  220.         } __attribute__((packed)) f70;
  221.         struct {
  222.             uint32_t path_encoding;
  223.             const char *path;
  224.         } f80;
  225.     } u;
  226. } __attribute__((packed)) f7080s1arg_t;
  227.  
  228. typedef struct {
  229.     uint32_t version;
  230.     uint32_t cnt;
  231.     uint32_t total_cnt;
  232.     uint32_t zeroed[5];
  233.     bdfe_t bdfes[];
  234. } f7080s1info_t;
  235.  
  236. typedef struct {
  237.     uint32_t sf;
  238.     uint32_t reserved1;
  239.     uint32_t flags;
  240.     uint32_t reserved2;
  241.     void *buf;
  242.     union {
  243.         struct {
  244.             uint8_t zero;
  245.             const char *path;
  246.         } __attribute__((packed)) f70;
  247.         struct {
  248.             uint32_t path_encoding;
  249.             const char *path;
  250.         } f80;
  251.     } u;
  252. } __attribute__((packed)) f7080s5arg_t;
  253.  
  254. typedef struct {
  255.     uint32_t sf;
  256.     uint32_t flags;
  257.     char *params;
  258.     uint32_t reserved1;
  259.     uint32_t reserved2;
  260.     union {
  261.         struct {
  262.             uint8_t zero;
  263.             const char *path;
  264.         } __attribute__((packed)) f70;
  265.         struct {
  266.             uint32_t path_encoding;
  267.             const char *path;
  268.         } f80;
  269.     } u;
  270. } __attribute__((packed)) f7080s7arg_t;
  271.  
  272. #define KF_READONLY 0x01
  273. #define KF_HIDDEN   0x02
  274. #define KF_SYSTEM   0x04
  275. #define KF_LABEL    0x08
  276. #define KF_FOLDER   0x10
  277. #define KF_ATTR_CNT 5
  278.  
  279. #define HASH_SIZE 32
  280. typedef struct {
  281.     uint8_t hash[HASH_SIZE];
  282.     uint8_t opaque[1024-HASH_SIZE];
  283. } hash_context;
  284.  
  285. typedef struct {
  286.     uint32_t edi;
  287.     uint32_t esi;
  288.     uint32_t ebp;
  289.     uint32_t esp;
  290.     uint32_t ebx;
  291.     uint32_t edx;
  292.     uint32_t ecx;
  293.     uint32_t eax;
  294. } pushad_t;
  295.  
  296. #define NET_TYPE_ETH  1
  297. #define NET_TYPE_SLIP 2
  298.  
  299. // Link state
  300. #define ETH_LINK_DOWN    0x0    // Link is down
  301. #define ETH_LINK_UNKNOWN 0x1    // There could be an active link
  302. #define ETH_LINK_FD      0x2    // full duplex flag
  303. #define ETH_LINK_10M     0x4    // 10 mbit
  304. #define ETH_LINK_100M    0x8    // 100 mbit
  305. #define ETH_LINK_1G      0xc    // gigabit
  306.  
  307. // Ethernet protocol numbers
  308. #define ETHER_PROTO_ARP           0x0608
  309. #define ETHER_PROTO_IPv4          0x0008
  310. #define ETHER_PROTO_IPv6          0xDD86
  311. #define ETHER_PROTO_PPP_DISCOVERY 0x6388
  312. #define ETHER_PROTO_PPP_SESSION   0x6488
  313.  
  314. // Internet protocol numbers
  315. #define IP_PROTO_IP   0
  316. #define IP_PROTO_ICMP 1
  317. #define IP_PROTO_TCP  6
  318. #define IP_PROTO_UDP  17
  319. #define IP_PROTO_RAW  255
  320.  
  321. // IP options
  322. #define IP_TOS     1
  323. #define IP_TTL     2
  324. #define IP_HDRINCL 3
  325.  
  326. // PPP protocol numbers
  327. #define PPP_PROTO_IPv4     0x2100
  328. #define PPP_PROTO_IPV6     0x5780
  329. #define PPP_PROTO_ETHERNET 666
  330.  
  331. // Protocol family
  332. #define AF_INET4  AF_INET
  333.  
  334. typedef struct net_device_t net_device_t;
  335.  
  336. typedef struct {
  337.         void *next;     // pointer to next frame in list
  338.         void *prev;     // pointer to previous frame in list
  339.         net_device_t *device;   // ptr to NET_DEVICE structure
  340.         uint32_t type;  // encapsulation type: e.g. Ethernet
  341.         size_t length;  // size of encapsulated data
  342.         size_t offset;  // offset to actual data (24 bytes for default frame)
  343.         uint8_t data[];
  344. } net_buff_t;
  345.  
  346. struct net_device_t {
  347.     uint32_t device_type;   // type field
  348.     uint32_t mtu;           // Maximal Transmission Unit
  349.     char *name;             // ptr to 0 terminated string
  350.  
  351.     // ptrs to driver functions
  352.     STDCALL void (*unload) (void);
  353.     STDCALL void (*reset) (void);
  354.     STDCALL int (*transmit) (net_buff_t *);
  355.  
  356.     uint64_t bytes_tx;      // statistics, updated by the driver
  357.     uint64_t bytes_rx;
  358.     uint32_t packets_tx;
  359.     uint32_t packets_rx;
  360.  
  361.     uint32_t link_state;    // link state (0 = no link)
  362.     uint32_t hwacc;         // bitmask stating enabled HW accelerations (offload
  363.                             // engines)
  364.     uint8_t mac[6];
  365.     void *userdata;         // not in kolibri, umka-specific
  366. }; // NET_DEVICE
  367.  
  368. typedef struct {
  369.     uint32_t ip;
  370.     uint8_t mac[6];
  371.     uint16_t status;
  372.     uint16_t ttl;
  373. } arp_entry_t;
  374.  
  375. typedef struct acpi_node acpi_node_t;
  376. struct acpi_node {
  377.     uint32_t name;
  378.     int32_t refcount;
  379.     acpi_node_t *parent;
  380.     acpi_node_t *children;
  381.     acpi_node_t *next;
  382.     int32_t type;
  383. };
  384.  
  385. typedef struct {
  386.     acpi_node_t node;
  387.     uint64_t value;
  388. } kos_node_integer_t;
  389.  
  390. typedef struct {
  391.     acpi_node_t node;
  392.     acpi_node_t **list;
  393.     size_t el_cnt;
  394. } kos_node_package_t;
  395.  
  396. __attribute__((__noreturn__)) void
  397. kos_osloop(void);
  398.  
  399. void
  400. irq0(int signo, siginfo_t *info, void *context);
  401.  
  402. void
  403. umka_init(void);
  404.  
  405. void
  406. i40(void);
  407.  
  408. uint32_t
  409. kos_time_to_epoch(uint32_t *time);
  410.  
  411. STDCALL disk_t *
  412. disk_add(diskfunc_t *disk, const char *name, void *userdata, uint32_t flags);
  413.  
  414. STDCALL void *
  415. disk_media_changed(diskfunc_t *disk, int inserted);
  416.  
  417. STDCALL void
  418. disk_del(disk_t *disk);
  419.  
  420. void
  421. hash_oneshot(void *ctx, void *data, size_t len);
  422.  
  423. extern uint8_t xfs_user_functions[];
  424. extern uint8_t ext_user_functions[];
  425. extern uint8_t fat_user_functions[];
  426. extern uint8_t ntfs_user_functions[];
  427.  
  428. extern uint8_t kos_ramdisk[2880*512];
  429.  
  430. disk_t *
  431. kos_ramdisk_init(void);
  432.  
  433. STDCALL void
  434. kos_set_mouse_data(uint32_t btn_state, int32_t xmoving, int32_t ymoving,
  435.                    int32_t vscroll, int32_t hscroll);
  436.  
  437. static inline void
  438. umka_mouse_move(int lbheld, int mbheld, int rbheld, int xabs, int32_t xmoving,
  439.                 int yabs, int32_t ymoving, int32_t hscroll, int32_t vscroll) {
  440.     uint32_t btn_state = lbheld + (rbheld << 1) + (mbheld << 2) +
  441.                          (yabs << 30) + (xabs << 31);
  442.     kos_set_mouse_data(btn_state, xmoving, ymoving, vscroll, hscroll);
  443. }
  444.  
  445. STDCALL net_buff_t *
  446. kos_net_buff_alloc(size_t size);
  447.  
  448. static inline size_t
  449. umka_new_sys_threads(uint32_t flags, void (*entry)(), void *stack) {
  450.     size_t tid;
  451.     __asm__ __inline__ __volatile__ (
  452.         "push ebx;"
  453.         "push esi;"
  454.         "push edi;"
  455.         "call   kos_new_sys_threads;"
  456.         "pop edi;"
  457.         "pop esi;"
  458.         "pop ebx"
  459.         : "=a"(tid)
  460.         : "b"(flags),
  461.           "c"(entry),
  462.           "d"(stack)
  463.         : "memory", "cc");
  464.     return tid;
  465. }
  466.  
  467. static inline void
  468. kos_acpi_call_name(void *ctx, const char *name) {
  469.     __asm__ __inline__ __volatile__ (
  470.         "pushad;"
  471.         "push   %[name];"
  472.         "push   %[ctx];"
  473.         "call   acpi.call_name;"
  474.         "popad"
  475.         :
  476.         : [ctx] "r"(ctx), [name] "r"(name)
  477.         : "memory", "cc");
  478. }
  479.  
  480. #define KOS_ACPI_NODE_Uninitialized 1
  481. #define KOS_ACPI_NODE_Integer       2
  482. #define KOS_ACPI_NODE_String        3
  483. #define KOS_ACPI_NODE_Buffer        4
  484. #define KOS_ACPI_NODE_Package       5
  485. #define KOS_ACPI_NODE_OpRegionField 6
  486. #define KOS_ACPI_NODE_IndexField    7
  487. #define KOS_ACPI_NODE_BankField     8
  488. #define KOS_ACPI_NODE_Device        9
  489.  
  490. extern acpi_node_t *kos_acpi_root;
  491.  
  492. typedef struct {
  493.     int pew[0x100];
  494. } amlctx_t;
  495.  
  496. struct pci_dev {
  497.     struct pci_dev *next;
  498.     size_t bus;
  499.     size_t dev;
  500.     size_t fun;
  501.     void *acpi;
  502.     struct pci_dev *children;
  503.     struct pci_dev *parent;
  504.     void *prt;
  505.     size_t is_bridge;
  506.     size_t vendor_id;
  507.     size_t device_id;
  508.     size_t int_pin;
  509.     size_t gsi;
  510. };
  511.  
  512. extern struct pci_dev *kos_pci_root;
  513.  
  514. void
  515. kos_acpi_aml_init();
  516.  
  517. STDCALL void
  518. kos_aml_attach(acpi_node_t *parent, acpi_node_t *node);
  519.  
  520. STDCALL void
  521. kos_acpi_fill_pci_irqs(void *ctx);
  522.  
  523. STDCALL amlctx_t*
  524. kos_acpi_aml_new_thread();
  525.  
  526. STDCALL acpi_node_t*
  527. kos_aml_alloc_node(int32_t type);
  528.  
  529. STDCALL acpi_node_t*
  530. kos_aml_constructor_integer(void);
  531.  
  532. STDCALL acpi_node_t*
  533. kos_aml_constructor_package(size_t el_cnt);
  534.  
  535. STDCALL acpi_node_t*
  536. kos_acpi_lookup_node(acpi_node_t *root, char *name);
  537.  
  538. STDCALL void
  539. kos_acpi_print_tree(void *ctx);
  540.  
  541. #define MAX_PCI_DEVICES 256
  542.  
  543. extern void *kos_acpi_dev_data;
  544. extern size_t kos_acpi_dev_size;
  545. extern void *kos_acpi_dev_next;
  546.  
  547. STDCALL void*
  548. kos_kernel_alloc(size_t len);
  549.  
  550. STDCALL void
  551. kos_pci_walk_tree(struct pci_dev *node,
  552.                   STDCALL void* (*test)(struct pci_dev *node, void *arg),
  553.                   STDCALL void* (*clbk)(struct pci_dev *node, void *arg),
  554.                   void *arg);
  555.  
  556. typedef struct {
  557.     uint32_t value;
  558.     uint32_t errorcode;
  559. } f75ret_t;
  560.  
  561. typedef struct {
  562.     uint32_t eax;
  563.     uint32_t ebx;
  564. } f76ret_t;
  565.  
  566. static inline void
  567. umka_stack_init() {
  568.     __asm__ __inline__ __volatile__ (
  569.         "pushad;"
  570.         "call   kos_stack_init;"
  571.         "popad"
  572.         :
  573.         :
  574.         : "memory", "cc");
  575. }
  576.  
  577. static inline int32_t
  578. kos_net_add_device(net_device_t *dev) {
  579.     int32_t dev_num;
  580.     __asm__ __inline__ __volatile__ (
  581.         "call   net_add_device"
  582.         : "=a"(dev_num)
  583.         : "b"(dev)
  584.         : "ecx", "edx", "esi", "edi", "memory", "cc");
  585.  
  586.     return dev_num;
  587. }
  588.  
  589. STDCALL void
  590. kos_window_set_screen(ssize_t left, ssize_t top, ssize_t right, ssize_t bottom,
  591.                       ssize_t proc);
  592.  
  593. typedef struct {
  594.     int32_t x;
  595.     int32_t y;
  596.     size_t width;
  597.     size_t height;
  598.     size_t bits_per_pixel;
  599.     size_t vrefresh;
  600.     void *current_lfb;
  601.     size_t lfb_pitch;
  602.  
  603.     rwsem_t win_map_lock;
  604.     uint8_t *win_map;
  605.     size_t win_map_pitch;
  606.     size_t win_map_size;
  607.  
  608.     void *modes;
  609.     void *ddev;
  610.     void *connector;
  611.     void *crtc;
  612.  
  613.     void *cr_list_next;
  614.     void *cr_list_prev;
  615.  
  616.     void *cursor;
  617.  
  618.     void *init_cursor;
  619.     void *select_cursor;
  620.     void *show_cursor;
  621.     void *move_cursor;
  622.     void *restore_cursor;
  623.     void *disable_mouse;
  624.     size_t mask_seqno;
  625.     void *check_mouse;
  626.     void *check_m_pixel;
  627.  
  628.     size_t bytes_per_pixel;
  629. } __attribute__((packed)) display_t;
  630.  
  631. extern display_t kos_display;
  632.  
  633. typedef struct {
  634.     uint64_t addr;
  635.     uint64_t size;
  636.     uint32_t type;
  637. } e820entry_t;
  638.  
  639. #define MAX_MEMMAP_BLOCKS 32
  640.  
  641. typedef struct {
  642.     uint8_t bpp;    // bits per pixel
  643.     uint16_t pitch; // scanline length
  644.     uint8_t pad1[5];
  645.     uint16_t vesa_mode;
  646.     uint16_t x_res;
  647.     uint16_t y_res;
  648.     uint8_t pad2[6];
  649.     uint32_t bank_switch;   // Vesa 1.2 pm bank switch
  650.     void *lfb;  // Vesa 2.0 LFB address
  651.     uint8_t mtrr;   // 0 or 1: enable MTRR graphics acceleration
  652.     uint8_t launcher_start; // 0 or 1: start the first app (right now it's
  653.                             // LAUNCHER) after kernel is loaded
  654.     uint8_t debug_print;    // if nonzero, duplicates debug output to the screen
  655.     uint8_t dma;    // DMA write: 1=yes, 2=no
  656.     uint8_t pci_data[8];
  657.     uint8_t pad3[8];
  658.     uint8_t shutdown_type;  // see sysfn 18.9
  659.     uint8_t pad4[15];
  660.     uint32_t apm_entry; // entry point of APM BIOS
  661.     uint16_t apm_version;   // BCD
  662.     uint16_t apm_flags;
  663.     uint8_t pad5[8];
  664.     uint16_t apm_code_32;
  665.     uint16_t apm_code_16;
  666.     uint16_t apm_data_16;
  667.     uint8_t rd_load_from;   // Device to load ramdisk from, RD_LOAD_FROM_*
  668.     uint8_t pad6[1];
  669.     uint16_t kernel_restart;
  670.     uint16_t sys_disk;  // Device to mount on /sys/, see loader_doc.txt for details
  671.     void *acpi_rsdp;
  672.     char syspath[0x17];
  673.     void *devicesdat_data;
  674.     size_t devicesdat_size;
  675.     uint8_t bios_hd_cnt;    // number of BIOS hard disks
  676.     uint8_t bios_hd[0x80];  // BIOS hard disks
  677.     size_t memmap_block_cnt;    // available physical memory map: number of blocks
  678.     e820entry_t memmap_blocks[MAX_MEMMAP_BLOCKS];
  679.     uint8_t acpi_usage;
  680. } __attribute__((packed)) boot_data_t;
  681.  
  682. extern boot_data_t kos_boot;
  683.  
  684. void
  685. umka_cli(void);
  686.  
  687. void
  688. umka_sti(void);
  689.  
  690. extern uint8_t coverage_begin[];
  691. extern uint8_t coverage_end[];
  692.  
  693. typedef struct appobj_t appobj_t;
  694.  
  695. struct appobj_t {
  696.     uint32_t magic;
  697.     void *destroy;  // internal destructor
  698.     appobj_t *fd;   // next object in list
  699.     appobj_t *bk;   // prev object in list
  700.     uint32_t pid;   // owner id
  701. };
  702.  
  703. typedef struct {
  704.     uint32_t magic;
  705.     void *destroy;  // internal destructor
  706.     appobj_t *fd;   // next object in list
  707.     appobj_t *bk;   // prev object in list
  708.     uint32_t pid;   // owner id
  709.     uint32_t id;    // event uid
  710.     uint32_t state; // internal flags
  711.     uint32_t code;
  712.     uint32_t pad[5];
  713. } event_t;
  714.  
  715. typedef struct {
  716.     lhead_t list;
  717.     lhead_t thr_list;
  718.     mutex_t heap_lock;
  719.     void *heap_base;
  720.     void *heap_top;
  721.     uint32_t mem_used;
  722.     void *dlls_list_ptr;
  723.     void *pdt_0_phys;
  724.     void *pdt_1_phys;
  725.     void *io_map_0;
  726.     void *io_map_1;
  727.  
  728.     void *ht_lock;
  729.     void *ht_free;
  730.     void *ht_next;
  731.     void *htab[(1024-18*4)/4];
  732.     void *pdt_0[1024];
  733. } proc_t;
  734.  
  735. _Static_assert(sizeof(proc_t) == 0x1400, "must be 0x1400 bytes long");
  736.  
  737. typedef struct {
  738.     char app_name[11];
  739.     uint8_t pad1[5];
  740.  
  741.     lhead_t list;                  // +16
  742.     proc_t *process;               // +24
  743.     void *fpu_state;               // +28
  744.     void *exc_handler;             // +32
  745.     uint32_t except_mask;          // +36
  746.     void *pl0_stack;               // +40
  747.     void *cursor;                  // +44
  748.     event_t *fd_ev;                // +48
  749.     event_t *bk_ev;                // +52
  750.     appobj_t *fd_obj;              // +56
  751.     appobj_t *bk_obj;              // +60
  752.     void *saved_esp;               // +64
  753.     uint32_t io_map[2];            // +68
  754.     uint32_t dbg_state;            // +76
  755.     char *cur_dir;                 // +80
  756.     uint32_t wait_timeout;         // +84
  757.     uint32_t saved_esp0;           // +88
  758.     uint32_t wait_begin;           // +92
  759.     int (*wait_test)(void);        // +96
  760.     void *wait_param;              // +100
  761.     void *tls_base;                // +104
  762.     uint32_t event_mask;           // +108
  763.     uint32_t tid;                  // +112
  764.     uint32_t draw_bgr_x;           // +116
  765.     uint32_t draw_bgr_y;           // +120
  766.     uint8_t state;                 // +124
  767.     uint8_t pad2[3];               // +125
  768.     uint8_t *wnd_shape;            // +128
  769.     uint32_t wnd_shape_scale;      // +132
  770.     uint32_t mem_start;            // +136
  771.     uint32_t counter_sum;          // +140
  772.     box_t saved_box;               // +144
  773.     uint32_t *ipc_start;           // +160
  774.     size_t ipc_size;               // +164
  775.     uint32_t occurred_events;      // +168
  776.     uint32_t debugger_slot;        // +172
  777.     uint32_t terminate_protection; // +176
  778.     uint8_t keyboard_mode;         // +180
  779.     uint8_t captionEncoding;       // +181
  780.     uint8_t pad3[2];               // +182
  781.     char *exec_params;             // +184
  782.     void *dbg_event_mem;           // +188
  783.     dbg_regs_t dbg_regs;           // +192
  784.     char *wnd_caption;             // +212
  785.     box_t wnd_clientbox;           // +216
  786.     uint32_t priority;             // +232
  787.     lhead_t in_schedule;           // +236
  788.     uint32_t counter_add;          // +244
  789.     uint32_t cpu_usage;            // +248
  790.     uint32_t pad4;                 // +252
  791. } appdata_t;
  792.  
  793. _Static_assert(sizeof(appdata_t) == 256, "must be 0x100 bytes long");
  794.  
  795. typedef struct {
  796.     uint32_t event_mask;
  797.     uint32_t pid;
  798.     uint16_t pad1;
  799.     uint8_t state;
  800.     uint8_t pad2;
  801.     uint16_t pad3;
  802.     uint8_t wnd_number;
  803.     uint8_t pad4;
  804.     uint32_t mem_start;
  805.     uint32_t counter_sum;
  806.     uint32_t counter_add;
  807.     uint32_t cpu_usage;
  808. } taskdata_t;
  809.  
  810. _Static_assert(sizeof(taskdata_t) == 32, "must be 0x20 bytes long");
  811.  
  812. #define UMKA_SHELL 1u
  813. #define UMKA_FUSE  2u
  814. #define UMKA_OS    3u
  815.  
  816. #define MAX_PRIORITY    0 // highest, used for kernel tasks
  817. #define USER_PRIORITY   1 // default
  818. #define IDLE_PRIORITY   2 // lowest, only IDLE thread goes here
  819. #define NR_SCHED_QUEUES 3 // MUST equal IDLE_PRIORYTY + 1
  820.  
  821. extern appdata_t *kos_scheduler_current[NR_SCHED_QUEUES];
  822.  
  823. extern uint32_t umka_tool;
  824. extern uint32_t umka_initialized;
  825. extern uint8_t kos_redraw_background;
  826. extern size_t kos_task_count;
  827. extern taskdata_t *kos_task_base;
  828. extern wdata_t kos_window_data[];
  829. extern taskdata_t kos_task_table[];
  830. extern appdata_t kos_slot_base[];
  831. extern uint32_t kos_current_process;
  832. extern appdata_t *kos_current_slot;
  833. extern uint32_t kos_current_slot_idx;
  834. extern void umka_do_change_task(appdata_t *new);
  835. extern void scheduler_add_thread(void);
  836. extern void find_next_task(void);
  837. extern uint8_t kos_lfb_base[];
  838. extern uint16_t kos_win_stack[];
  839. extern uint16_t kos_win_pos[];
  840. extern uint32_t kos_acpi_ssdt_cnt;
  841. extern uint8_t *kos_acpi_ssdt_base[];
  842. extern size_t kos_acpi_ssdt_size[];
  843. extern void *acpi_ctx;
  844. extern uint32_t kos_acpi_usage;
  845. extern uint32_t kos_acpi_node_alloc_cnt;
  846. extern uint32_t kos_acpi_node_free_cnt;
  847. extern uint32_t kos_acpi_count_nodes(void *ctx) STDCALL;
  848. extern disk_t disk_list;
  849.  
  850. static inline void
  851. umka_scheduler_add_thread(appdata_t *thread, int32_t priority) {
  852.     __asm__ __inline__ __volatile__ (
  853.         "call   do_change_thread"
  854.         :
  855.         : "c"(priority),
  856.           "d"(thread)
  857.         : "memory", "cc");
  858.  
  859. }
  860.  
  861. #define MAX_PRIORITY    0
  862. #define USER_PRIORITY   1
  863. #define IDLE_PRIORITY   2
  864. #define NR_SCHED_QUEUES 3
  865.  
  866. #define SCHEDULE_ANY_PRIORITY 0
  867. #define SCHEDULE_HIGHER_PRIORITY 1
  868.  
  869. typedef struct {
  870.     appdata_t *appdata;
  871.     taskdata_t *taskdata;
  872.     int same;
  873. } find_next_task_t;
  874.  
  875. static inline find_next_task_t
  876. umka_find_next_task(int32_t priority) {
  877.     find_next_task_t fnt;
  878.     __asm__ __inline__ __volatile__ (
  879.         "call   find_next_task;"
  880.         "setz   al;"
  881.         "movzx  eax, al"
  882.         : "=b"(fnt.appdata),
  883.           "=D"(fnt.taskdata),
  884.           "=a"(fnt.same)
  885.         : "b"(priority)
  886.         : "memory", "cc");
  887.     return fnt;
  888. }
  889.  
  890. static inline void
  891. umka_i40(pushad_t *regs) {
  892.     __asm__ __inline__ __volatile__ (
  893.         "push   ebp;"
  894.         "mov    ebp, %[ebp];"
  895.         "call   i40;"
  896.         "pop    ebp"
  897.         : "=a"(regs->eax),
  898.           "=b"(regs->ebx)
  899.         : "a"(regs->eax),
  900.           "b"(regs->ebx),
  901.           "c"(regs->ecx),
  902.           "d"(regs->edx),
  903.           "S"(regs->esi),
  904.           "D"(regs->edi),
  905.           [ebp] "Rm"(regs->ebp)
  906.         : "memory");
  907. }
  908.  
  909. static inline void
  910. umka_sys_draw_window(size_t x, size_t xsize, size_t y, size_t ysize,
  911.                      uint32_t color, int has_caption, int client_relative,
  912.                      int fill_workarea, int gradient_fill, int movable,
  913.                      uint32_t style, const char *caption) {
  914.     __asm__ __inline__ __volatile__ (
  915.         "call   i40"
  916.         :
  917.         : "a"(0),
  918.           "b"((x << 16) + xsize),
  919.           "c"((y << 16) + ysize),
  920.           "d"((gradient_fill << 31) + (!fill_workarea << 30)
  921.               + (client_relative << 29) + (has_caption << 28) + (style << 24)
  922.               + color),
  923.           "S"(!movable << 24),
  924.           "D"(caption)
  925.         : "memory");
  926. }
  927.  
  928. static inline void
  929. umka_sys_set_pixel(size_t x, size_t y, uint32_t color, int invert) {
  930.     __asm__ __inline__ __volatile__ (
  931.         "call   i40"
  932.         :
  933.         : "a"(1),
  934.           "b"(x),
  935.           "c"(y),
  936.           "d"((invert << 24) + color)
  937.         : "memory");
  938. }
  939.  
  940. static inline void
  941. umka_sys_write_text(size_t x, size_t y, uint32_t color, int asciiz,
  942.                     int fill_background, int font_and_encoding,
  943.                     int draw_to_buffer, int scale_factor, const char *string,
  944.                     size_t length, uintptr_t background_color_or_buffer) {
  945.     __asm__ __inline__ __volatile__ (
  946.         "call   i40"
  947.         :
  948.         : "a"(4),
  949.           "b"((x << 16) + y),
  950.           "c"((asciiz << 31) + (fill_background << 30)
  951.               + (font_and_encoding << 28) + (draw_to_buffer << 27)
  952.               + (scale_factor << 24) + color),
  953.           "d"(string),
  954.           "S"(length),
  955.           "D"(background_color_or_buffer)
  956.         : "memory");
  957. }
  958.  
  959. static inline void
  960. umka_sys_put_image(void *image, size_t xsize, size_t ysize, size_t x,
  961.                    size_t y) {
  962.     __asm__ __inline__ __volatile__ (
  963.         "call   i40"
  964.         :
  965.         : "a"(7),
  966.           "b"(image),
  967.           "c"((xsize << 16) + ysize),
  968.           "d"((x << 16) + y)
  969.         : "memory");
  970. }
  971.  
  972. static inline void
  973. umka_sys_button(size_t x, size_t xsize, size_t y, size_t ysize,
  974.                 size_t button_id, int draw_button, int draw_frame,
  975.                 uint32_t color) {
  976.     __asm__ __inline__ __volatile__ (
  977.         "call   i40"
  978.         :
  979.         : "a"(8),
  980.           "b"((x << 16) + xsize),
  981.           "c"((y << 16) + ysize),
  982.           "d"((!draw_button << 30) + (!draw_frame << 29) + button_id),
  983.           "S"(color)
  984.         : "memory");
  985. }
  986.  
  987. static inline void
  988. umka_sys_process_info(int32_t pid, void *param) {
  989.     __asm__ __inline__ __volatile__ (
  990.         "call   i40"
  991.         :
  992.         : "a"(9),
  993.           "b"(param),
  994.           "c"(pid)
  995.         : "memory");
  996. }
  997.  
  998. static inline void
  999. umka_sys_window_redraw(int begin_end) {
  1000.     __asm__ __inline__ __volatile__ (
  1001.         "call   i40"
  1002.         :
  1003.         : "a"(12),
  1004.           "b"(begin_end)
  1005.         : "memory");
  1006. }
  1007.  
  1008. static inline void
  1009. umka_sys_draw_rect(size_t x, size_t xsize, size_t y, size_t ysize,
  1010.                    uint32_t color, int gradient) {
  1011.     __asm__ __inline__ __volatile__ (
  1012.         "call   i40"
  1013.         :
  1014.         : "a"(13),
  1015.           "b"((x << 16) + xsize),
  1016.           "c"((y << 16) + ysize),
  1017.           "d"((gradient << 31) + color)
  1018.         : "memory");
  1019. }
  1020.  
  1021. static inline void
  1022. umka_sys_get_screen_size(uint32_t *xsize, uint32_t *ysize) {
  1023.     uint32_t xysize;
  1024.     __asm__ __inline__ __volatile__ (
  1025.         "call   i40"
  1026.         : "=a"(xysize)
  1027.         : "a"(14)
  1028.         : "memory");
  1029.     *xsize = (xysize >> 16) + 1;
  1030.     *ysize = (xysize & 0xffffu) + 1;
  1031. }
  1032.  
  1033. static inline void
  1034. umka_sys_bg_set_size(uint32_t xsize, uint32_t ysize) {
  1035.     __asm__ __inline__ __volatile__ (
  1036.         "call   i40"
  1037.         :
  1038.         : "a"(15),
  1039.           "b"(1),
  1040.           "c"(xsize),
  1041.           "d"(ysize)
  1042.         : "memory");
  1043. }
  1044.  
  1045. static inline void
  1046. umka_sys_bg_put_pixel(uint32_t offset, uint32_t color) {
  1047.     __asm__ __inline__ __volatile__ (
  1048.         "call   i40"
  1049.         :
  1050.         : "a"(15),
  1051.           "b"(2),
  1052.           "c"(offset),
  1053.           "d"(color)
  1054.         : "memory");
  1055. }
  1056.  
  1057. static inline void
  1058. umka_sys_bg_redraw() {
  1059.     __asm__ __inline__ __volatile__ (
  1060.         "call   i40"
  1061.         :
  1062.         : "a"(15),
  1063.           "b"(3)
  1064.         : "memory");
  1065. }
  1066.  
  1067. static inline void
  1068. umka_sys_bg_set_mode(uint32_t mode) {
  1069.     __asm__ __inline__ __volatile__ (
  1070.         "call   i40"
  1071.         :
  1072.         : "a"(15),
  1073.           "b"(4),
  1074.           "c"(mode)
  1075.         : "memory");
  1076. }
  1077.  
  1078. static inline void
  1079. umka_sys_bg_put_img(void *image, size_t offset, size_t size) {
  1080.     __asm__ __inline__ __volatile__ (
  1081.         "call   i40"
  1082.         :
  1083.         : "a"(15),
  1084.           "b"(5),
  1085.           "c"(image),
  1086.           "d"(offset),
  1087.           "S"(size)
  1088.         : "memory");
  1089. }
  1090.  
  1091. static inline void *
  1092. umka_sys_bg_map() {
  1093.     void *addr;
  1094.     __asm__ __inline__ __volatile__ (
  1095.         "call   i40"
  1096.         : "=a"(addr)
  1097.         : "a"(15),
  1098.           "b"(6)
  1099.         : "memory");
  1100.     return addr;
  1101. }
  1102.  
  1103. static inline uint32_t
  1104. umka_sys_bg_unmap(void *addr) {
  1105.     uint32_t status;
  1106.     __asm__ __inline__ __volatile__ (
  1107.         "call   i40"
  1108.         : "=a"(status)
  1109.         : "a"(15),
  1110.           "b"(7),
  1111.           "c"(addr)
  1112.         : "memory");
  1113.     return status;
  1114. }
  1115.  
  1116. static inline void
  1117. umka_sys_set_cwd(const char *dir) {
  1118.     __asm__ __inline__ __volatile__ (
  1119.         "call   i40"
  1120.         :
  1121.         : "a"(30),
  1122.           "b"(1),
  1123.           "c"(dir)
  1124.         : "memory");
  1125. }
  1126.  
  1127. static inline void
  1128. umka_sys_get_cwd(const char *buf, size_t len) {
  1129.     __asm__ __inline__ __volatile__ (
  1130.         "call   i40"
  1131.         :
  1132.         : "a"(30),
  1133.           "b"(2),
  1134.           "c"(buf),
  1135.           "d"(len)
  1136.         : "memory");
  1137. }
  1138.  
  1139. static inline void
  1140. umka_sys_draw_line(size_t x, size_t xend, size_t y, size_t yend, uint32_t color,
  1141.                    int invert) {
  1142.     __asm__ __inline__ __volatile__ (
  1143.         "call   i40"
  1144.         :
  1145.         : "a"(38),
  1146.           "b"((x << 16) + xend),
  1147.           "c"((y << 16) + yend),
  1148.           "d"((invert << 24) + color)
  1149.         : "memory");
  1150. }
  1151.  
  1152. static inline void
  1153. umka_sys_display_number(int is_pointer, int base, int digits_to_display,
  1154.                         int is_qword, int show_leading_zeros,
  1155.                         int number_or_pointer, size_t x, size_t y,
  1156.                         uint32_t color, int fill_background, int font,
  1157.                         int draw_to_buffer, int scale_factor,
  1158.                         uintptr_t background_color_or_buffer) {
  1159.     __asm__ __inline__ __volatile__ (
  1160.         "call   i40"
  1161.         :
  1162.         : "a"(47),
  1163.           "b"(is_pointer + (base << 8) + (digits_to_display << 16)
  1164.               + (is_qword << 30) + (show_leading_zeros << 31)),
  1165.           "c"(number_or_pointer),
  1166.           "d"((x << 16) + y),
  1167.           "S"(color + (fill_background << 30) + (font << 28)
  1168.               + (draw_to_buffer << 27) + (scale_factor << 24)),
  1169.           "D"(background_color_or_buffer)
  1170.         : "memory");
  1171. }
  1172.  
  1173. static inline void
  1174. umka_sys_set_button_style(int style) {
  1175.     __asm__ __inline__ __volatile__ (
  1176.         "call   i40"
  1177.         :
  1178.         : "a"(48),
  1179.           "b"(1),
  1180.           "c"(style)
  1181.         : "memory");
  1182. }
  1183.  
  1184. static inline void
  1185. umka_sys_set_window_colors(void *colors) {
  1186.     __asm__ __inline__ __volatile__ (
  1187.         "call   i40"
  1188.         :
  1189.         : "a"(48),
  1190.           "b"(2),
  1191.           "c"(colors),
  1192.           "d"(40)
  1193.         : "memory");
  1194. }
  1195.  
  1196. static inline void
  1197. umka_sys_get_window_colors(void *colors) {
  1198.     __asm__ __inline__ __volatile__ (
  1199.         "call   i40"
  1200.         :
  1201.         : "a"(48),
  1202.           "b"(3),
  1203.           "c"(colors),
  1204.           "d"(40)
  1205.         : "memory");
  1206. }
  1207.  
  1208. static inline uint32_t
  1209. umka_sys_get_skin_height() {
  1210.     uint32_t skin_height;
  1211.     __asm__ __inline__ __volatile__ (
  1212.         "call   i40"
  1213.         : "=a"(skin_height)
  1214.         : "a"(48),
  1215.           "b"(4)
  1216.         : "memory");
  1217.     return skin_height;
  1218. }
  1219.  
  1220. static inline void
  1221. umka_sys_get_screen_area(rect_t *wa) {
  1222.     uint32_t eax, ebx;
  1223.     __asm__ __inline__ __volatile__ (
  1224.         "call   i40"
  1225.         : "=a"(eax),
  1226.           "=b"(ebx)
  1227.         : "a"(48),
  1228.           "b"(5)
  1229.         : "memory");
  1230.     wa->left   = eax >> 16;
  1231.     wa->right  = eax & 0xffffu;
  1232.     wa->top    = ebx >> 16;
  1233.     wa->bottom = ebx & 0xffffu;
  1234. }
  1235.  
  1236. static inline void
  1237. umka_sys_set_screen_area(rect_t *wa) {
  1238.     uint32_t ecx, edx;
  1239.     ecx = (wa->left << 16) + wa->right;
  1240.     edx = (wa->top << 16) + wa->bottom;
  1241.     __asm__ __inline__ __volatile__ (
  1242.         "call   i40"
  1243.         :
  1244.         : "a"(48),
  1245.           "b"(6),
  1246.           "c"(ecx),
  1247.           "d"(edx)
  1248.         : "memory");
  1249. }
  1250.  
  1251. static inline void
  1252. umka_sys_get_skin_margins(rect_t *wa) {
  1253.     uint32_t eax, ebx;
  1254.     __asm__ __inline__ __volatile__ (
  1255.         "call   i40"
  1256.         : "=a"(eax),
  1257.           "=b"(ebx)
  1258.         : "a"(48),
  1259.           "b"(7)
  1260.         : "memory");
  1261.     wa->left   = eax >> 16;
  1262.     wa->right  = eax & 0xffffu;
  1263.     wa->top    = ebx >> 16;
  1264.     wa->bottom = ebx & 0xffffu;
  1265. }
  1266.  
  1267. static inline int32_t
  1268. umka_sys_set_skin(const char *path) {
  1269.     int32_t status;
  1270.     __asm__ __inline__ __volatile__ (
  1271.         "call   i40"
  1272.         : "=a"(status)
  1273.         : "a"(48),
  1274.           "b"(8),
  1275.           "c"(path)
  1276.         : "memory");
  1277.     return status;
  1278. }
  1279.  
  1280. static inline int
  1281. umka_sys_get_font_smoothing() {
  1282.     int type;
  1283.     __asm__ __inline__ __volatile__ (
  1284.         "call   i40"
  1285.         : "=a"(type)
  1286.         : "a"(48),
  1287.           "b"(9)
  1288.         : "memory");
  1289.     return type;
  1290. }
  1291.  
  1292. static inline void
  1293. umka_sys_set_font_smoothing(int type) {
  1294.     __asm__ __inline__ __volatile__ (
  1295.         "call   i40"
  1296.         :
  1297.         : "a"(48),
  1298.           "b"(10),
  1299.           "c"(type)
  1300.         : "memory");
  1301. }
  1302.  
  1303. static inline int
  1304. umka_sys_get_font_size() {
  1305.     uint32_t size;
  1306.     __asm__ __inline__ __volatile__ (
  1307.         "call   i40"
  1308.         : "=a"(size)
  1309.         : "a"(48),
  1310.           "b"(11)
  1311.         : "memory");
  1312.     return size;
  1313. }
  1314.  
  1315. static inline void
  1316. umka_sys_set_font_size(uint32_t size) {
  1317.     __asm__ __inline__ __volatile__ (
  1318.         "call   i40"
  1319.         :
  1320.         : "a"(48),
  1321.           "b"(12),
  1322.           "c"(size)
  1323.         : "memory");
  1324. }
  1325.  
  1326. static inline void
  1327. umka_sys_put_image_palette(void *image, size_t xsize, size_t ysize,
  1328.                            size_t x, size_t y, size_t bpp, void *palette,
  1329.                            size_t row_offset) {
  1330.     __asm__ __inline__ __volatile__ (
  1331.         "push   ebp;"
  1332.         "mov    ebp, %[row_offset];"
  1333.         "call   i40;"
  1334.         "pop    ebp"
  1335.         :
  1336.         : "a"(65),
  1337.           "b"(image),
  1338.           "c"((xsize << 16) + ysize),
  1339.           "d"((x << 16) + y),
  1340.           "S"(bpp),
  1341.           "D"(palette),
  1342.           [row_offset] "Rm"(row_offset)
  1343.         : "memory");
  1344. }
  1345.  
  1346. static inline void
  1347. umka_sys_move_window(size_t x, size_t y, ssize_t xsize, ssize_t ysize) {
  1348.     __asm__ __inline__ __volatile__ (
  1349.         "call   i40"
  1350.         :
  1351.         : "a"(67),
  1352.           "b"(x),
  1353.           "c"(y),
  1354.           "d"(xsize),
  1355.           "S"(ysize)
  1356.         : "memory");
  1357. }
  1358.  
  1359. static inline void
  1360. umka_sys_lfn(void *f7080sXarg, f7080ret_t *r, f70or80_t f70or80) {
  1361.     __asm__ __inline__ __volatile__ (
  1362.         "call   i40"
  1363.         : "=a"(r->status),
  1364.           "=b" (r->count)
  1365.         : "a"(f70or80),
  1366.           "b"(f7080sXarg)
  1367.         : "memory");
  1368. }
  1369.  
  1370. static inline void
  1371. umka_sys_set_window_caption(const char *caption, int encoding) {
  1372.     __asm__ __inline__ __volatile__ (
  1373.         "call   i40"
  1374.         :
  1375.         : "a"(71),
  1376.           "b"(encoding ? 2 : 1),
  1377.           "c"(caption),
  1378.           "d"(encoding)
  1379.         : "memory");
  1380. }
  1381.  
  1382. static inline void
  1383. umka_sys_blit_bitmap(int operation, int background, int transparent,
  1384.                      int client_relative, void *params) {
  1385.     __asm__ __inline__ __volatile__ (
  1386.         "call   i40"
  1387.         :
  1388.         : "a"(73),
  1389.           "b"((client_relative << 29) + (transparent << 5) + (background << 4)
  1390.               + operation),
  1391.           "c"(params)
  1392.         : "memory");
  1393. }
  1394.  
  1395. static inline uint32_t
  1396. umka_sys_net_get_dev_count() {
  1397.     uint32_t count;
  1398.     __asm__ __inline__ __volatile__ (
  1399.         "call   i40"
  1400.         : "=a"(count)
  1401.         : "a"(74),
  1402.           "b"(255)
  1403.         : "memory");
  1404.     return count;
  1405. }
  1406.  
  1407. static inline int32_t
  1408. umka_sys_net_get_dev_type(uint8_t dev_num) {
  1409.     int32_t type;
  1410.     __asm__ __inline__ __volatile__ (
  1411.         "call   i40"
  1412.         : "=a"(type)
  1413.         : "a"(74),
  1414.           "b"((dev_num << 8) + 0)
  1415.         : "memory");
  1416.     return type;
  1417. }
  1418.  
  1419. static inline int32_t
  1420. umka_sys_net_get_dev_name(uint8_t dev_num, char *name) {
  1421.     int32_t status;
  1422.     __asm__ __inline__ __volatile__ (
  1423.         "call   i40"
  1424.         : "=a"(status)
  1425.         : "a"(74),
  1426.           "b"((dev_num << 8) + 1),
  1427.           "c"(name)
  1428.         : "memory");
  1429.     return status;
  1430. }
  1431.  
  1432. static inline int32_t
  1433. umka_sys_net_dev_reset(uint8_t dev_num) {
  1434.     int32_t status;
  1435.     __asm__ __inline__ __volatile__ (
  1436.         "call   i40"
  1437.         : "=a"(status)
  1438.         : "a"(74),
  1439.           "b"((dev_num << 8) + 2)
  1440.         : "memory");
  1441.     return status;
  1442. }
  1443.  
  1444. static inline int32_t
  1445. umka_sys_net_dev_stop(uint8_t dev_num) {
  1446.     int32_t status;
  1447.     __asm__ __inline__ __volatile__ (
  1448.         "call   i40"
  1449.         : "=a"(status)
  1450.         : "a"(74),
  1451.           "b"((dev_num << 8) + 3)
  1452.         : "memory");
  1453.     return status;
  1454. }
  1455.  
  1456. static inline intptr_t
  1457. umka_sys_net_get_dev(uint8_t dev_num) {
  1458.     intptr_t dev;
  1459.     __asm__ __inline__ __volatile__ (
  1460.         "call   i40"
  1461.         : "=a"(dev)
  1462.         : "a"(74),
  1463.           "b"((dev_num << 8) + 4)
  1464.         : "memory");
  1465.     return dev;
  1466. }
  1467.  
  1468. static inline uint32_t
  1469. umka_sys_net_get_packet_tx_count(uint8_t dev_num) {
  1470.     uint32_t count;
  1471.     __asm__ __inline__ __volatile__ (
  1472.         "call   i40"
  1473.         : "=a"(count)
  1474.         : "a"(74),
  1475.           "b"((dev_num << 8) + 6)
  1476.         : "memory");
  1477.     return count;
  1478. }
  1479.  
  1480. static inline uint32_t
  1481. umka_sys_net_get_packet_rx_count(uint8_t dev_num) {
  1482.     uint32_t count;
  1483.     __asm__ __inline__ __volatile__ (
  1484.         "call   i40"
  1485.         : "=a"(count)
  1486.         : "a"(74),
  1487.           "b"((dev_num << 8) + 7)
  1488.         : "memory");
  1489.     return count;
  1490. }
  1491.  
  1492. static inline uint32_t
  1493. umka_sys_net_get_byte_tx_count(uint8_t dev_num) {
  1494.     uint32_t count;
  1495.     __asm__ __inline__ __volatile__ (
  1496.         "call   i40"
  1497.         : "=a"(count)
  1498.         : "a"(74),
  1499.           "b"((dev_num << 8) + 8)
  1500.         : "memory");
  1501.     return count;
  1502. }
  1503.  
  1504. static inline uint32_t
  1505. umka_sys_net_get_byte_rx_count(uint8_t dev_num) {
  1506.     uint32_t count;
  1507.     __asm__ __inline__ __volatile__ (
  1508.         "call   i40"
  1509.         : "=a"(count)
  1510.         : "a"(74),
  1511.           "b"((dev_num << 8) + 9)
  1512.         : "memory");
  1513.     return count;
  1514. }
  1515.  
  1516. static inline uint32_t
  1517. umka_sys_net_get_link_status(uint8_t dev_num) {
  1518.     uint32_t status;
  1519.     __asm__ __inline__ __volatile__ (
  1520.         "call   i40"
  1521.         : "=a"(status)
  1522.         : "a"(74),
  1523.           "b"((dev_num << 8) + 10)
  1524.         : "memory");
  1525.     return status;
  1526. }
  1527.  
  1528. static inline f75ret_t
  1529. umka_sys_net_open_socket(uint32_t domain, uint32_t type, uint32_t protocol) {
  1530.     f75ret_t r;
  1531.     __asm__ __inline__ __volatile__ (
  1532.         "call   i40"
  1533.         : "=a"(r.value),
  1534.           "=b"(r.errorcode)
  1535.         : "a"(75),
  1536.           "b"(0),
  1537.           "c"(domain),
  1538.           "d"(type),
  1539.           "S"(protocol)
  1540.         : "memory");
  1541.     return r;
  1542. }
  1543.  
  1544. static inline f75ret_t
  1545. umka_sys_net_close_socket(uint32_t fd) {
  1546.     f75ret_t r;
  1547.     __asm__ __inline__ __volatile__ (
  1548.         "call   i40"
  1549.         : "=a"(r.value),
  1550.           "=b"(r.errorcode)
  1551.         : "a"(75),
  1552.           "b"(1),
  1553.           "c"(fd)
  1554.         : "memory");
  1555.     return r;
  1556. }
  1557.  
  1558. static inline f75ret_t
  1559. umka_sys_net_bind(uint32_t fd, void *sockaddr, size_t sockaddr_len) {
  1560.     f75ret_t r;
  1561.     __asm__ __inline__ __volatile__ (
  1562.         "call   i40"
  1563.         : "=a"(r.value),
  1564.           "=b"(r.errorcode)
  1565.         : "a"(75),
  1566.           "b"(2),
  1567.           "c"(fd),
  1568.           "d"(sockaddr),
  1569.           "S"(sockaddr_len)
  1570.         : "memory");
  1571.     return r;
  1572. }
  1573.  
  1574. static inline f75ret_t
  1575. umka_sys_net_listen(uint32_t fd, uint32_t backlog) {
  1576.     f75ret_t r;
  1577.     __asm__ __inline__ __volatile__ (
  1578.         "call   i40"
  1579.         : "=a"(r.value),
  1580.           "=b"(r.errorcode)
  1581.         : "a"(75),
  1582.           "b"(3),
  1583.           "c"(fd),
  1584.           "d"(backlog)
  1585.         : "memory");
  1586.     return r;
  1587. }
  1588.  
  1589. static inline f75ret_t
  1590. umka_sys_net_connect(uint32_t fd, void *sockaddr, size_t sockaddr_len) {
  1591.     f75ret_t r;
  1592.     __asm__ __inline__ __volatile__ (
  1593.         "call   i40"
  1594.         : "=a"(r.value),
  1595.           "=b"(r.errorcode)
  1596.         : "a"(75),
  1597.           "b"(4),
  1598.           "c"(fd),
  1599.           "d"(sockaddr),
  1600.           "S"(sockaddr_len)
  1601.         : "memory");
  1602.     return r;
  1603. }
  1604.  
  1605. static inline f75ret_t
  1606. umka_sys_net_accept(uint32_t fd, void *sockaddr, size_t sockaddr_len) {
  1607.     f75ret_t r;
  1608.     __asm__ __inline__ __volatile__ (
  1609.         "call   i40"
  1610.         : "=a"(r.value),
  1611.           "=b"(r.errorcode)
  1612.         : "a"(75),
  1613.           "b"(5),
  1614.           "c"(fd),
  1615.           "d"(sockaddr),
  1616.           "S"(sockaddr_len)
  1617.         : "memory");
  1618.     return r;
  1619. }
  1620.  
  1621. static inline f75ret_t
  1622. umka_sys_net_send(uint32_t fd, void *buf, size_t buf_len, uint32_t flags) {
  1623.     f75ret_t r;
  1624.     __asm__ __inline__ __volatile__ (
  1625.         "call   i40"
  1626.         : "=a"(r.value),
  1627.           "=b"(r.errorcode)
  1628.         : "a"(75),
  1629.           "b"(6),
  1630.           "c"(fd),
  1631.           "d"(buf),
  1632.           "S"(buf_len),
  1633.           "D"(flags)
  1634.         : "memory");
  1635.     return r;
  1636. }
  1637.  
  1638. static inline f75ret_t
  1639. umka_sys_net_receive(uint32_t fd, void *buf, size_t buf_len, uint32_t flags) {
  1640.     f75ret_t r;
  1641.     __asm__ __inline__ __volatile__ (
  1642.         "call   i40"
  1643.         : "=a"(r.value),
  1644.           "=b"(r.errorcode)
  1645.         : "a"(75),
  1646.           "b"(7),
  1647.           "c"(fd),
  1648.           "d"(buf),
  1649.           "S"(buf_len),
  1650.           "D"(flags)
  1651.         : "memory");
  1652.     return r;
  1653. }
  1654.  
  1655. static inline f76ret_t
  1656. umka_sys_net_eth_read_mac(uint32_t dev_num) {
  1657.     f76ret_t r;
  1658.     __asm__ __inline__ __volatile__ (
  1659.         "call   i40"
  1660.         : "=a"(r.eax),
  1661.           "=b"(r.ebx)
  1662.         : "a"(76),
  1663.           "b"((0 << 16) + (dev_num << 8) + 0)
  1664.         : "memory");
  1665.     return r;
  1666. }
  1667.  
  1668. // Function 76, Protocol 1 - IPv4, Subfunction 0, Read # Packets sent =
  1669. // Function 76, Protocol 1 - IPv4, Subfunction 1, Read # Packets rcvd =
  1670.  
  1671. static inline f76ret_t
  1672. umka_sys_net_ipv4_get_addr(uint32_t dev_num) {
  1673.     f76ret_t r;
  1674.     __asm__ __inline__ __volatile__ (
  1675.         "call   i40"
  1676.         : "=a"(r.eax),
  1677.           "=b"(r.ebx)
  1678.         : "a"(76),
  1679.           "b"((1 << 16) + (dev_num << 8) + 2)
  1680.         : "memory");
  1681.     return r;
  1682. }
  1683.  
  1684. static inline f76ret_t
  1685. umka_sys_net_ipv4_set_addr(uint32_t dev_num, uint32_t addr) {
  1686.     f76ret_t r;
  1687.     __asm__ __inline__ __volatile__ (
  1688.         "call   i40"
  1689.         : "=a"(r.eax),
  1690.           "=b"(r.ebx)
  1691.         : "a"(76),
  1692.           "b"((1 << 16) + (dev_num << 8) + 3),
  1693.           "c"(addr)
  1694.         : "memory");
  1695.     return r;
  1696. }
  1697.  
  1698. static inline f76ret_t
  1699. umka_sys_net_ipv4_get_dns(uint32_t dev_num) {
  1700.     f76ret_t r;
  1701.     __asm__ __inline__ __volatile__ (
  1702.         "call   i40"
  1703.         : "=a"(r.eax),
  1704.           "=b"(r.ebx)
  1705.         : "a"(76),
  1706.           "b"((1 << 16) + (dev_num << 8) + 4)
  1707.         : "memory");
  1708.     return r;
  1709. }
  1710.  
  1711. static inline f76ret_t
  1712. umka_sys_net_ipv4_set_dns(uint32_t dev_num, uint32_t dns) {
  1713.     f76ret_t r;
  1714.     __asm__ __inline__ __volatile__ (
  1715.         "call   i40"
  1716.         : "=a"(r.eax),
  1717.           "=b"(r.ebx)
  1718.         : "a"(76),
  1719.           "b"((1 << 16) + (dev_num << 8) + 5),
  1720.           "c"(dns)
  1721.         : "memory");
  1722.     return r;
  1723. }
  1724.  
  1725. static inline f76ret_t
  1726. umka_sys_net_ipv4_get_subnet(uint32_t dev_num) {
  1727.     f76ret_t r;
  1728.     __asm__ __inline__ __volatile__ (
  1729.         "call   i40"
  1730.         : "=a"(r.eax),
  1731.           "=b"(r.ebx)
  1732.         : "a"(76),
  1733.           "b"((1 << 16) + (dev_num << 8) + 6)
  1734.         : "memory");
  1735.     return r;
  1736. }
  1737.  
  1738. static inline f76ret_t
  1739. umka_sys_net_ipv4_set_subnet(uint32_t dev_num, uint32_t subnet) {
  1740.     f76ret_t r;
  1741.     __asm__ __inline__ __volatile__ (
  1742.         "call   i40"
  1743.         : "=a"(r.eax),
  1744.           "=b"(r.ebx)
  1745.         : "a"(76),
  1746.           "b"((1 << 16) + (dev_num << 8) + 7),
  1747.           "c"(subnet)
  1748.         : "memory");
  1749.     return r;
  1750. }
  1751.  
  1752. static inline f76ret_t
  1753. umka_sys_net_ipv4_get_gw(uint32_t dev_num) {
  1754.     f76ret_t r;
  1755.     __asm__ __inline__ __volatile__ (
  1756.         "call   i40"
  1757.         : "=a"(r.eax),
  1758.           "=b"(r.ebx)
  1759.         : "a"(76),
  1760.           "b"((1 << 16) + (dev_num << 8) + 8)
  1761.         : "memory");
  1762.     return r;
  1763. }
  1764.  
  1765. static inline f76ret_t
  1766. umka_sys_net_ipv4_set_gw(uint32_t dev_num, uint32_t gw) {
  1767.     f76ret_t r;
  1768.     __asm__ __inline__ __volatile__ (
  1769.         "call   i40"
  1770.         : "=a"(r.eax),
  1771.           "=b"(r.ebx)
  1772.         : "a"(76),
  1773.           "b"((1 << 16) + (dev_num << 8) + 9),
  1774.           "c"(gw)
  1775.         : "memory");
  1776.     return r;
  1777. }
  1778.  
  1779. // Function 76, Protocol 2 - ICMP, Subfunction 0, Read # Packets sent =
  1780. // Function 76, Protocol 2 - ICMP, Subfunction 1, Read # Packets rcvd =
  1781. // Function 76, Protocol 3 - UDP, Subfunction 0, Read # Packets sent ==
  1782. // Function 76, Protocol 3 - UDP, Subfunction 1, Read # Packets rcvd ==
  1783. // Function 76, Protocol 4 - TCP, Subfunction 0, Read # Packets sent ==
  1784. // Function 76, Protocol 4 - TCP, Subfunction 1, Read # Packets rcvd ==
  1785. // Function 76, Protocol 5 - ARP, Subfunction 0, Read # Packets sent ==
  1786. // Function 76, Protocol 5 - ARP, Subfunction 1, Read # Packets rcvd ==
  1787. static inline f76ret_t
  1788. umka_sys_net_arp_get_count(uint32_t dev_num) {
  1789.     f76ret_t r;
  1790.     __asm__ __inline__ __volatile__ (
  1791.         "call   i40"
  1792.         : "=a"(r.eax),
  1793.           "=b"(r.ebx)
  1794.         : "a"(76),
  1795.           "b"((5 << 16) + (dev_num << 8) + 2)
  1796.         : "memory");
  1797.     return r;
  1798. }
  1799.  
  1800. static inline f76ret_t
  1801. umka_sys_net_arp_get_entry(uint32_t dev_num, uint32_t arp_num, void *buf) {
  1802.     f76ret_t r;
  1803.     __asm__ __inline__ __volatile__ (
  1804.         "call   i40"
  1805.         : "=a"(r.eax),
  1806.           "=b"(r.ebx)
  1807.         : "a"(76),
  1808.           "b"((5 << 16) + (dev_num << 8) + 3),
  1809.           "c"(arp_num),
  1810.           "D"(buf)
  1811.         : "memory");
  1812.     return r;
  1813. }
  1814.  
  1815. static inline f76ret_t
  1816. umka_sys_net_arp_add_entry(uint32_t dev_num, void *buf) {
  1817.     f76ret_t r;
  1818.     __asm__ __inline__ __volatile__ (
  1819.         "call   i40"
  1820.         : "=a"(r.eax),
  1821.           "=b"(r.ebx)
  1822.         : "a"(76),
  1823.           "b"((5 << 16) + (dev_num << 8) + 4),
  1824.           "S"(buf)
  1825.         : "memory");
  1826.     return r;
  1827. }
  1828.  
  1829. static inline f76ret_t
  1830. umka_sys_net_arp_del_entry(uint32_t dev_num, int32_t arp_num) {
  1831.     f76ret_t r;
  1832.     __asm__ __inline__ __volatile__ (
  1833.         "call   i40"
  1834.         : "=a"(r.eax),
  1835.           "=b"(r.ebx)
  1836.         : "a"(76),
  1837.           "b"((5 << 16) + (dev_num << 8) + 5),
  1838.           "c"(arp_num)
  1839.         : "memory");
  1840.     return r;
  1841. }
  1842.  
  1843. // Function 76, Protocol 5 - ARP, Subfunction 6, Send ARP announce ==
  1844. // Function 76, Protocol 5 - ARP, Subfunction 7, Read # conflicts ===
  1845.  
  1846. #endif  // UMKA_H_INCLUDED
  1847.