home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / ENTERPRS / CPM / UTILS / S / UZI.ARK / MACHDEP.C < prev    next >
Text File  |  1988-11-30  |  8KB  |  416 lines

  1. /**************************************************
  2. UZI (Unix Z80 Implementation) Kernel:  machdep.c
  3. ***************************************************/
  4.  
  5.  
  6. #include "unix.h"
  7. #include "extern.h"
  8.  
  9.  
  10. /* This is called at the very beginning to initialize everything. */
  11. /* It is the equivalent of main() */
  12.  
  13. fs_init()
  14. {
  15.     di();
  16.     stkreset();
  17.     /* Initialize the interrupt vector */
  18.     initvec();
  19.     inint = 0;
  20.     udata.u_insys = 1;
  21.     /* Turn off clock */
  22.     out(0,0xf1);
  23.     ei();
  24.  
  25.     init2();   /* in process.c */
  26. }
  27.  
  28.  
  29. /* This checks to see if a user-suppled address is legitimate */
  30. valadr(base,size)
  31. char *base;
  32. uint16 size;
  33. {
  34.     if (base < PROGBASE || base+size >= (char *)&udata)
  35.     {
  36.         udata.u_error = EFAULT;
  37.         return(0);
  38.     }
  39.     return(1);
  40. }
  41.  
  42.  
  43. /* This adds two tick counts together.
  44. The t_time field holds up to one second of ticks,
  45. while the t_date field counts minutes */
  46.  
  47. addtick(t1,t2)
  48. time_t *t1, *t2;
  49. {
  50.  
  51.     t1->t_time += t2->t_time;
  52.     t1->t_date += t2->t_date;
  53.     if (t1->t_time >= 60*TICKSPERSEC)
  54.     {
  55.         t1->t_time -= 60*TICKSPERSEC;
  56.         ++t1->t_date;
  57.     }
  58. }
  59.  
  60. incrtick(t)
  61. time_t *t;
  62. {
  63.     if (++t->t_time == 60*TICKSPERSEC)
  64.     {
  65.         t->t_time = 0;
  66.         ++t->t_date;
  67.     }
  68. }
  69.  
  70.  
  71. stkreset()
  72. {
  73. #asm 8080
  74.         POP     H
  75.         LXI     SP,udata?-2
  76.         PCHL
  77. #endasm
  78. }
  79.  
  80.  
  81. tempstack()
  82. {
  83. #asm 8080
  84.         POP     H
  85.         LXI     SP,100H
  86.         PCHL
  87. #endasm
  88. }
  89.  
  90.  
  91.  
  92. initvec()
  93. {
  94. #asm 8080
  95.         LXI     H,vector?
  96.         INX     H
  97.         MOV     A,L
  98.         ANI     0FEH
  99.         MOV     L,A     ;set hl to first even address in vector[].
  100.         MOV     A,H
  101. .Z80
  102.         LD      I,A     ;SET INTERRUPT REGISTER TO UPPER 8 BITS
  103. .8080
  104.         MOV     A,L
  105.         OUT     076H    ;set external vector register with low order byte
  106.         LXI     D,service?
  107.         MOV     M,E
  108.         INX     H
  109.         MOV     M,D     ;STORE ADDRESS OF SERVICE ROUTINE IN vector[].
  110.         RET
  111. #endasm
  112. }
  113.  
  114. extern int unix();
  115.  
  116.  
  117. doexec()
  118. {
  119. #asm 8080
  120.         POP     H
  121.         POP     H       ;get argument
  122.         SPHL            ;set stack pointer to it
  123.         MVI     A,0C3H  ;jump inst
  124.         STA     0030H   ;dest of RST6 instruction.
  125.         LXI     H,unix? ;entry address
  126.         SHLD    0031H
  127.         XRA     A
  128.         STA     udata? + ?OSYS
  129.         JMP     0100H
  130. #endasm
  131. }
  132.  
  133.  
  134. static int cursig;
  135. static int (*curvec)();
  136.  
  137. /* This interrupt device routine calls the service routine of each device
  138. that could have interrupted. */
  139.  
  140. service()
  141. {
  142.  
  143.     ;
  144. #asm 8080
  145.         PUSH    PSW
  146.         PUSH    B
  147.         PUSH    D
  148.         PUSH    H
  149. .Z80
  150.         PUSH    IX
  151.         PUSH    IY
  152. .8080
  153. #endasm
  154.  
  155.     inint = 1;
  156.  
  157.     if (tty_int())
  158.         goto found;
  159.     if (clk_int())
  160.         goto found;
  161. /*  if (  ) ...   */
  162.  
  163.     warning("Spurious interrupt");
  164.  
  165. found:
  166.     inint = 0;
  167.  
  168.     /* Deal with a pending caught signal, if any */
  169.     if (!udata.u_insys)
  170.         calltrap();
  171.     ;
  172.  
  173. #asm 8080
  174. .Z80
  175.         POP     IY
  176.         POP     IX
  177. .8080
  178.         POP     H
  179.         POP     D
  180.         POP     B
  181.         POP     PSW
  182.         EI
  183.         RET
  184. #endasm
  185.  
  186. }
  187.  
  188.  
  189.  
  190. calltrap()
  191. {
  192.     /* Deal with a pending caught signal, if any. */
  193.         /* udata.u_insys should be false, and interrupts enabled.
  194.         remember, the user may never return from the trap routine */
  195.  
  196.     if (udata.u_cursig)
  197.     {
  198.         cursig = udata.u_cursig;
  199.         curvec = udata.u_sigvec[cursig];
  200.         udata.u_cursig = 0;
  201.         udata.u_sigvec[cursig] = SIG_DFL;   /* Reset to default */
  202.         ei();
  203.         (*curvec)(cursig);
  204.         di();
  205.     } 
  206. }
  207.  
  208.  
  209.  
  210. /* Port addresses of clock chip registers. */
  211.  
  212. #define SECS 0xe2
  213. #define MINS 0xe3
  214. #define HRS 0xe4
  215. #define DAY 0xe6
  216. #define MON 0xe7
  217. #define YEAR 86
  218.  
  219. sttime()
  220. {
  221.     panic("Calling sttime");
  222. }
  223.  
  224.  
  225. rdtime(tloc)
  226. time_t *tloc;
  227. {
  228.     di();
  229.     tloc->t_time = tod.t_time;
  230.     tloc->t_date = tod.t_date;
  231.     ei();
  232. }
  233.  
  234.  
  235. /* Update global time of day */
  236. rdtod()
  237. {
  238.     tod.t_time = (tread(SECS)>>1) | (tread(MINS)<<5) | (tread(HRS)<<11);
  239.     tod.t_date = tread(DAY) | (tread(MON)<<5) | (YEAR<<9);
  240. }
  241.  
  242.  
  243. /* Read BCD clock register, convert to binary. */
  244. tread(port)
  245. uint16 port;
  246. {
  247.     int n;
  248.  
  249.     n = in(port);
  250.     return ( 10*((n>>4)&0x0f) + (n&0x0f) );
  251. }
  252.  
  253.  
  254. /* Disable interrupts */
  255. di()
  256. {
  257. #asm 8080
  258.         DI      ;disable interrupts
  259. #endasm
  260. }
  261.  
  262. /* Enable interrupts if we are not in service routine */
  263. ei()
  264. {
  265.     if (inint)
  266.         return;
  267.     ;   /* Empty statement necessary to fool compiler */
  268.  
  269. #asm 8080
  270.         EI      ;disable interrupts
  271. #endasm
  272. }
  273.  
  274.  
  275.  
  276. /* This shifts an unsigned int right 8 places. */
  277.  
  278. shift8()
  279. {
  280. #asm 8080
  281.         POP     D       ;ret addr
  282.         POP     H
  283.         MOV     L,H
  284.         MVI     H,0
  285.         MOV     A,L
  286.         ANA     A       ;set Z flag on result
  287.         PUSH    H
  288.         PUSH    D       ;restore stack
  289. #endasm
  290. }
  291.  
  292.  
  293. /* This prints an error message and dies. */
  294.  
  295. panic(s)
  296. char *s;
  297. {
  298.     di();
  299.     inint = 1;
  300.     kprintf("PANIC: %s\n",s);
  301.     idump();
  302.     abort();
  303. }
  304.  
  305.  
  306. warning(s)
  307. char *s;
  308. {
  309.     kprintf("WARNING: %s\n",s);
  310. }
  311.  
  312.  
  313. puts(s)
  314. char *s;
  315. {
  316.     while (*s)
  317.         kputchar(*(s++));
  318. }
  319.  
  320. kputchar(c)
  321. int c;
  322. {
  323.     if (c == '\n')
  324.         _putc('\r');
  325.     _putc(c);
  326.     if (c == '\t')
  327.         puts("\177\177\177\177\177\177\177\177\177\177");
  328. }
  329.  
  330.  
  331.  
  332. idump()
  333. {
  334.     inoptr ip;
  335.     ptptr pp;
  336.     extern struct cinode i_tab[];
  337.  
  338.     kprintf(
  339.         "\tMAGIC\tDEV\tNUM\tMODE\tNLINK\t(DEV)\tREFS\tDIRTY err %d root %d\n",
  340.             udata.u_error, root - i_tab);
  341.  
  342.     for (ip=i_tab; ip < i_tab+ITABSIZE; ++ip)
  343.     {
  344.         kprintf("%d\t%d\t%d\t%u\t0%o\t%d\t%d\t%d\t%d\n",
  345.                ip-i_tab, ip->c_magic,ip->c_dev, ip->c_num,
  346.                ip->c_node.i_mode,ip->c_node.i_nlink,ip->c_node.i_addr[0],
  347.                ip->c_refs,ip->c_dirty);
  348. /*****
  349.         ifnot (ip->c_magic)     
  350.             break;
  351. ******/
  352.     }
  353.  
  354.     kprintf("\n\tSTAT\tWAIT\tPID\tPPTR\tALARM\tPENDING\tIGNORED\n");
  355.     for (pp=ptab; pp < ptab+PTABSIZE; ++pp)
  356.     {
  357.         kprintf("%d\t%d\t0x%x\t%d\t%d\t%d\t0x%x\t0x%x\n",
  358.                pp-ptab, pp->p_status, pp->p_wait,  pp->p_pid,
  359.                pp->p_pptr-ptab, pp->p_alarm, pp->p_pending,
  360.                 pp->p_ignored);
  361.         ifnot(pp->p_pptr)
  362.             break;
  363.     }   
  364.     
  365.     bufdump();
  366.  
  367.     kprintf("\ninsys %d ptab %d call %d cwd %d sp 0x%x\n",
  368.         udata.u_insys,udata.u_ptab-ptab, udata.u_callno, udata.u_cwd-i_tab,
  369.        udata.u_sp);
  370. }
  371.  
  372.  
  373.  
  374. /* Short version of printf to save space */
  375. kprintf(nargs)
  376.         {
  377.         register char **arg, *fmt;
  378.         register c, base;
  379.         char s[7], *itob();
  380.  
  381.         arg = (char **)&nargs + nargs;
  382.         fmt = *arg;
  383.         while (c = *fmt++) {
  384.                 if (c != '%') {
  385.                         kputchar(c);
  386.                         continue;
  387.                         }
  388.                 switch (c = *fmt++) {
  389.                 case 'c':
  390.                         kputchar(*--arg);
  391.                         continue;
  392.                 case 'd':
  393.                         base = -10;
  394.                         goto prt;
  395.                 case 'o':
  396.                         base = 8;
  397.                         goto prt;
  398.                 case 'u':
  399.                         base = 10;
  400.                         goto prt;
  401.                 case 'x':
  402.                         base = 16;
  403.                 prt:
  404.                         puts(itob(*--arg, s, base));
  405.                         continue;
  406.                 case 's':
  407.                         puts(*--arg);
  408.                         continue;
  409.                 default:
  410.                         kputchar(c);
  411.                         continue;
  412.                         }
  413.                 }
  414.         }
  415.  
  416.