Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. #include <sys/segments.h>
  21. #include <go32.h>
  22. #include <unistd.h>
  23. #include <sys/nearptr.h>
  24. #include <dos.h>
  25. #include <string.h>
  26. #include <dpmi.h>
  27. // #include <osfcn.h>
  28. #include <bios.h>
  29.  
  30. #include "dosisms.h"
  31.  
  32. _go32_dpmi_registers hmm;
  33.  
  34. // globals
  35. regs_t regs;
  36. void (*dos_error_func)(char *msg, ...);
  37.  
  38. static unsigned conventional_memory = -1;
  39.  
  40. __dpmi_regs callback_regs;
  41.  
  42. void map_in_conventional_memory(void)
  43. {
  44.         if (conventional_memory == -1)
  45.         {
  46.                 if (__djgpp_nearptr_enable())
  47.                 {
  48.                         conventional_memory = __djgpp_conventional_base;
  49.                 }
  50.         }
  51. }
  52.  
  53. unsigned int ptr2real(void *ptr)
  54. {
  55.         map_in_conventional_memory();
  56.         return (int)ptr - conventional_memory;
  57. }
  58.  
  59. void *real2ptr(unsigned int real)
  60. {
  61.         map_in_conventional_memory();
  62.         return (void *) (real + conventional_memory);
  63. }
  64.  
  65. void *far2ptr(unsigned int farptr)
  66. {
  67.         return real2ptr(((farptr & ~0xffff) >>12) + (farptr&0xffff));
  68. }
  69.  
  70. unsigned int ptr2far(void *ptr)
  71. {
  72.         return ((ptr2real(ptr)&~0xf) << 12) + (ptr2real(ptr) & 0xf);
  73. }
  74.  
  75. int dos_inportb(int port)
  76. {
  77.         return inportb(port);
  78. }
  79.  
  80. int dos_inportw(int port)
  81. {
  82.         return inportw(port);
  83. }
  84.  
  85. void dos_outportb(int port, int val)
  86. {
  87.         outportb(port, val);
  88. }
  89.  
  90. void dos_outportw(int port, int val)
  91. {
  92.         outportw(port, val);
  93. }
  94.  
  95. void dos_irqenable(void)
  96. {
  97.         enable();
  98. }
  99.  
  100. void dos_irqdisable(void)
  101. {
  102.         disable();
  103. }
  104.  
  105. //
  106. // Returns 0 on success
  107. //
  108.  
  109. int     dos_int86(int vec)
  110. {
  111.     int rc;
  112.     regs.x.ss = regs.x.sp = 0;
  113.     rc = _go32_dpmi_simulate_int(vec, (_go32_dpmi_registers *) &regs);
  114.     return rc || (regs.x.flags & 1);
  115. }
  116.  
  117. int     dos_int386(int vec, regs_t *inregs, regs_t *outregs)
  118. {
  119.         int rc;
  120.         memcpy(outregs, inregs, sizeof(regs_t));
  121.         outregs->x.ss = outregs->x.sp = 0;
  122.         rc = _go32_dpmi_simulate_int(vec, (_go32_dpmi_registers *) outregs);
  123.         return rc || (outregs->x.flags & 1);
  124. }
  125.  
  126. //
  127. // Because of a quirk in dj's alloc-dos-memory wrapper, you need to keep
  128. // the seginfo structure around for when you free the mem.
  129. //
  130.  
  131. static _go32_dpmi_seginfo seginfo[10];
  132.  
  133. void *dos_getmemory(int size)
  134. {
  135.  
  136.         int rc;
  137.         _go32_dpmi_seginfo info;
  138.         static int firsttime=1;
  139.         int i;
  140.  
  141.         if (firsttime)
  142.         {
  143.                 memset(seginfo, 0, sizeof(seginfo));
  144.                 firsttime = 0;
  145.         }
  146.  
  147.         info.size = (size+15) / 16;
  148.         rc = _go32_dpmi_allocate_dos_memory(&info);
  149.         if (rc)
  150.                 return 0;
  151.  
  152.         for (i=0;i<10;i++)
  153.                 if (!seginfo[i].rm_segment) break;
  154.         seginfo[i] = info;
  155.         return real2ptr((int) info.rm_segment << 4);
  156.  
  157. }
  158.  
  159. void dos_freememory(void *ptr)
  160. {
  161.  
  162.         int i;
  163.         int segment;
  164.  
  165.         segment = ptr2real(ptr) >> 4;
  166.         for (i=0 ; i<10 ; i++)
  167.                 if (seginfo[i].rm_segment == segment)
  168.                 {
  169.                         _go32_dpmi_free_dos_memory(&seginfo[i]);
  170.                         seginfo[i].rm_segment = 0;
  171.                         break;
  172.                 }
  173.  
  174. }
  175.  
  176. static struct handlerhistory_s
  177. {
  178.         int intr;
  179.         _go32_dpmi_seginfo pm_oldvec;
  180. } handlerhistory[4];
  181.  
  182. static int handlercount=0;
  183.  
  184. void    dos_registerintr(int intr, void (*handler)(void))
  185. {
  186.         _go32_dpmi_seginfo info;
  187.         struct handlerhistory_s *oldstuff;
  188.  
  189.         oldstuff = &handlerhistory[handlercount];
  190.  
  191. // remember old handler
  192.         _go32_dpmi_get_protected_mode_interrupt_vector(intr, &oldstuff->pm_oldvec);
  193.         oldstuff->intr = intr;
  194.  
  195.         info.pm_offset = (int) handler;
  196.         _go32_dpmi_allocate_iret_wrapper(&info);
  197.  
  198. // set new protected mode handler
  199.         _go32_dpmi_set_protected_mode_interrupt_vector(intr, &info);
  200.  
  201.         handlercount++;
  202.  
  203. }
  204.  
  205. void    dos_restoreintr(int intr)
  206. {
  207.  
  208.         int i;
  209.         struct handlerhistory_s *oldstuff;
  210.  
  211. // find and reinstall previous interrupt
  212.         for (i=0 ; i<handlercount ; i++)
  213.         {
  214.                 oldstuff = &handlerhistory[i];
  215.                 if (oldstuff->intr == intr)
  216.                 {
  217.                         _go32_dpmi_set_protected_mode_interrupt_vector(intr,
  218.                                 &oldstuff->pm_oldvec);
  219.                         oldstuff->intr = -1;
  220.                         break;
  221.                 }
  222.         }
  223.  
  224. }
  225.  
  226. void    dos_usleep(int usecs)
  227. {
  228.         usleep(usecs);
  229. }
  230.  
  231. int dos_getheapsize(void)
  232. {
  233.         return _go32_dpmi_remaining_physical_memory();
  234. }
  235.  
  236. int dos_lockmem(void *addr, int size)
  237. {
  238.         __dpmi_meminfo info;
  239.         info.address = (long) addr + __djgpp_base_address;
  240.         info.size = size;
  241.         if (__dpmi_lock_linear_region(&info))
  242.                 return __dpmi_error;
  243.         else
  244.                 return 0;
  245. }
  246.  
  247. int dos_unlockmem(void *addr, int size)
  248. {
  249.         __dpmi_meminfo info;
  250.         info.address = (long) addr + __djgpp_base_address;
  251.         info.size = size;
  252.         if (__dpmi_unlock_linear_region(&info))
  253.                 return __dpmi_error;
  254.         else
  255.                 return 0;
  256. }
  257.  
  258.