home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Zone / VRZONE.ISO / mac / PC / PCGLOVE / GLOVE / OBJGLV.ZIP / SRC / DEMO4B / JUST3D.CPP < prev    next >
C/C++ Source or Header  |  1993-04-21  |  5KB  |  228 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <dos.h>
  4. #include <bios.h>
  5. #include <signal.h>
  6. #include <string.h>
  7.  
  8. #include "segasupp.hpp"
  9. #include "rend386.hpp"
  10. #include "vd2.hpp"
  11.  
  12. int sega_port_image = 0;
  13.  
  14. /****************** SWITCHER DRIVER INTERFACE *************/
  15.  
  16.  
  17. #define SW_INIT        0
  18. #define SW_QUIT        1
  19. #define SW_ADV_SWITCH  2
  20. #define SW_SYNC_SWITCH 3
  21.  
  22. #define sub_exit        atexit
  23.  
  24. static int (*switch_driver)(int, int) = NULL;
  25.  
  26. static void sdriver_quit()
  27. {
  28.     if (switch_driver) switch_driver(SW_QUIT, 0);
  29. }
  30.  
  31. typedef int (*driver_func)(int, int);
  32.  
  33. Boolean init_switch_driver(char *sdname)
  34. {
  35.     if (!stricmp(sdname, "sega"))
  36.     {
  37.         sub_exit(sega_off);
  38.         return True;
  39.     }
  40.  
  41.     switch_driver = (driver_func)load_driver(sdname);
  42.  
  43.     if (switch_driver == NULL)
  44.     {
  45.         fprintf(stderr,"Cannot read switcher driver %s\n", sdname);
  46.         return False;
  47.         // exit(0);
  48.     }
  49.  
  50.     switch_driver = (driver_func)(MK_FP(FP_SEG(switch_driver), 16+FP_OFF(switch_driver))); /* entry point */
  51.     switch_driver(SW_INIT, 0);
  52.     sub_exit(sdriver_quit);
  53.     return True;
  54. }
  55.  
  56.  
  57. /********************* SEGA GLASSES CONTROL *****************/
  58.  
  59. int left_page = 0; /* left image */
  60. int right_page = 1; /* right image */
  61. int has_switched; /* = 3 once both switched in */
  62.  
  63. static int adv_has_switched = 0;
  64.  
  65. #define SEGA_LEFT  0x30
  66. #define SEGA_RIGHT 0x20
  67. #define SEGA_OFF   0x00
  68.  
  69. #define SEGA_MASK  0x30         /* bits writeable for Sega */
  70.  
  71. #define COMPORT 0x3fc           /* com1 = 0x3fc, com2 = 0x2fc */
  72.  
  73. int sega_left = SEGA_LEFT;
  74. int sega_right = SEGA_RIGHT;
  75. int sega_address = COMPORT;
  76. int sega_mask = SEGA_MASK;
  77. int sega_doff = SEGA_OFF;
  78.  
  79. static int phase = 1; /* current image */
  80.  
  81. void select_sega_port(int port)
  82. {
  83.     sega_address = port;
  84. }
  85.  
  86. static void sega_write(int data)  /* write Sega data w/o disturbance */
  87. {
  88.     disable();
  89.     // can also handle glove, Sega on same port
  90.     // oops not anymore.
  91. /*****
  92.     if (sega_address == glove_out_port)
  93.         sega_port_image = port_image =
  94.             (port_image & (~sega_mask)) | (data & sega_mask);
  95.     else
  96. *****/
  97.         sega_port_image = (sega_port_image & (~sega_mask)) | (data & sega_mask);
  98.     outportb(sega_address, sega_port_image);
  99.     enable();
  100. }
  101.  
  102. void switch_sega(int to_go)  /* now gets arg, sync at 0, 1 = advanced signal */
  103. {                            /* 2-step switching ensures adr. load of VGA    */
  104.     if (switch_driver)
  105.     {
  106.         if (to_go == 1)
  107.         {
  108.             if (phase == sega_left)
  109.             {
  110.                 phase = sega_right;
  111.                 if (switch_driver(SW_ADV_SWITCH, 0) )
  112.                     set_vpage(right_page);
  113.                 adv_has_switched = 1;
  114.             }
  115.             else
  116.                 {
  117.                 phase = sega_left;
  118.                 if (switch_driver(SW_ADV_SWITCH, 1) )
  119.                     set_vpage(left_page);
  120.                 adv_has_switched = 2;
  121.             }
  122.         }
  123.         if (to_go == 0)
  124.         {
  125.             switch_driver(SW_SYNC_SWITCH, (phase == sega_left) ? 1 : 0);
  126.             has_switched |= adv_has_switched;
  127.             adv_has_switched = 0;
  128.         }
  129.     }
  130.     else
  131.         {
  132.         if (to_go == 1)
  133.         {
  134.             if (phase == sega_left)
  135.             {
  136.                 phase = sega_right;
  137.                 set_vpage(right_page);
  138.                 adv_has_switched = 1;
  139.             }
  140.             else
  141.                 {
  142.                 phase = sega_left;
  143.                 set_vpage(left_page);
  144.                 adv_has_switched = 2;
  145.             }
  146.         }
  147.         if (to_go == 0)
  148.         {
  149.             sega_write(phase);
  150.             has_switched |= adv_has_switched;
  151.             adv_has_switched = 0;
  152.         }
  153.     }
  154. }
  155.  
  156.  
  157. void sega_off()
  158. {
  159.     sega_write(sega_doff); /* turn glasses driver off to save lcds! */
  160. }
  161.  
  162. #include "isr.hpp"
  163. #include "timerdef.h"
  164.  
  165. #define LATCH_COUNT 0x00        // command to latch count
  166. // Time (microseconds) of advance in vert. interrupt.  Will act as
  167. // "vertical hold" adjustment.
  168. #define ADVANCE 100
  169.  
  170. void BaseSegaISR::handleGlasses()
  171. {
  172.     frame_interrupt_routine(glovecount-1);
  173.  
  174.     if (--glovecount <= 0) glovecount = glove_rate;
  175.     else return;
  176.  
  177.  
  178.     syncount--;
  179.     if (syncount < 0)
  180.     {
  181.         syncount = SYNC_INTERVAL;
  182.         // stop timer
  183.         outportb(TIMER_CONTROL, TIMER_MODE);
  184.         outportb(TIMER_0, 255);
  185.         outportb(TIMER_0, 255);
  186.         enable();
  187.         disable();
  188.         vsync();
  189.         // restart timer
  190.         outportb(TIMER_CONTROL, TIMER_MODE);
  191.         outportb(TIMER_0, clock_rate_lo);
  192.         outportb(TIMER_0, clock_rate_hi);
  193.     }
  194. }
  195.  
  196. // BaseSegaISR::findSegaSpeed()
  197. //      Routine to compute vertical frame time.
  198. //      Call after setting video mode.
  199. //
  200. int BaseSegaISR::findSegaSpeed()  // "vertical hold" adjustment
  201. {
  202.     // Routine to compute vertical frame
  203.     unsigned int sp_old, sp_new;
  204.  
  205.     vsync();
  206.     outportb(TIMER_CONTROL, TIMER_MODE);
  207.     outportb(TIMER_0, 0);
  208.     outportb(TIMER_0, 0); // timer must count modulo 65536
  209.  
  210.     disable(); // time of vert. retrace
  211.     vsync();
  212.     outportb(TIMER_CONTROL,LATCH_COUNT);
  213.     enable();
  214.     sp_old = inportb(TIMER_0) & 0xFF;
  215.     sp_old |= (inportb(TIMER_0) << 8);
  216.  
  217.     vsync(); // time 2 vert. retraces later
  218.     disable();
  219.     vsync();
  220.     outportb(TIMER_CONTROL,LATCH_COUNT);
  221.     enable();
  222.     sp_new = inportb(TIMER_0) & 0xFF;
  223.     sp_new |= (inportb(TIMER_0) << 8);
  224.  
  225.     return ((sp_old-sp_new)>>1) - ADVANCE; // compute interrupt rate
  226. }
  227.  
  228.