Subversion Repositories Kolibri OS

Rev

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