home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / lambda / soundpot / f / ospeed.lbr / OSPD.CZ / OSPD.C
Encoding:
C/C++ Source or Header  |  1993-10-26  |  19.3 KB  |  716 lines

  1. /* Program ospeed.c --- displays Osborne 1 disk speed */
  2. /* Copyright 1984 by Bob Briggs */
  3. /* May be copied freely but not for profit */
  4.  
  5. /* Based on counting clock cycles through one rotation of index hole */
  6. /* Period is 200 milliseconds (300 RPM), Osborne clock is 15.9744/4 MHz */
  7. /* Software loop is 80 T (clock) cycles */
  8. /* Correct count of times through software loop */
  9. /* per index hole is 200*15974.4/4/80 = 9984 */
  10. /* Calculated speed = 300*9984/(measured count) RPM */
  11.  
  12. /* Compiles with Software Toolworks C/80 */
  13.  
  14. /* Must assemble above 4000 Hex. */
  15. /*    In C/80, modify CLIBRARY.ASM as follows: */
  16. /*    After ORG 256, add lines: */
  17. /*    (space) JMP 4000H */
  18. /*    (space) ORG 4000H */
  19. /*  */
  20. /* To reduce size of .COM file, move program to lower memory with DDT  */
  21. /* after assembly and then insert move routine to move back to 4000H at */
  22. /* runtime.  The following accomplishes this */
  23. /* 1.  Load the program and DDT with the command DDT OSPD.COM */
  24. /* 2.  Move the program to lower memory with the command M4000,5C00,110 */
  25. /* 3.  Use DDT commands to load in the following block move and SAVE */
  26. /*     S100
  27. /*     0100 C3 21        LD HL,0110H    ;SOURCE
  28. /*     0101 00 10        LD DE,4000H    ;DESTINATION
  29. /*     0102 40 01        LD BC,1C00H    ;BLOCK SIZE
  30. /*     0103 00 11        LDIR        ;MOVE IT
  31. /*     0104 00 00        JMP 4000H    ;CONTINUE
  32. /*     0105 00 40
  33. /*     0106 00 01
  34. /*     0107 00 00
  35. /*     0108 00 1C
  36. /*     0109 00 ED
  37. /*     010A 00 B0
  38. /*     010B 00 C3
  39. /*     010C 00 00
  40. /*     010D 00 40
  41. /*     010E 00 .
  42. /*     - ^C            exits DDT
  43. /*     SAVE 28 OSPD.COM    creates new file */
  44. /*  */
  45. #define HOME 0xF000    /* upper left of Osborne screen  RAM */
  46. #define LINE 128    /* screen line width */
  47. #define NULL 0
  48. #define STODIM 015DH    /* ROM location of dim control routine */
  49. #define WIDCON 0X2400    /* Screenwidth control port in bank 2 */
  50.  
  51. main()
  52. {
  53.    int speed, pd;    /* disk speed, period */
  54.    int d;        /* current logged drive */
  55.    int m;        /* motor to be started */
  56.    int c, i;        /* dummy variables */
  57.    char *p;        /* text pointer */
  58.    int w;        /* screenwidth = 52, 80, or 100 */
  59.  
  60.  
  61.  cls();            /* clear screen and reset screen window */
  62.  w = 52;        /* screen width 52 columns */
  63.  setwid(w);        /* set screenwidth */
  64.  d = getdsk() + 1;    /* current logged drive, A = 1, B = 2 */
  65.  while(1)        /* keep looping on menu */
  66.  {
  67.    blanksc();    /* fill screen with spaces (avoids BDOS keybd chk) */
  68.    for(i = 0; i < 100; ++i) while(keychk() != NULL);    /* wait for key release */
  69.    brite();    /* undim screen */
  70.    greet();    /* sign on message asks for L or R key */
  71.    motor(0);    /* turn off disk drive motor(s) */
  72.  
  73.    for(i = 0; i < 100; ++i) while(keychk() != NULL);    /* wait for key release */
  74.                             /* needed after first time */
  75.                             /* through menu loop       */
  76.  
  77.    do                /* choose left or right disk */
  78.      switch(c = lrkey())    /* get l or r key from keyboard input */
  79.      {
  80.     case 'l':
  81.        blanksc();    /* fill screen with spaces */
  82.        p = "   Left Disk: hold down SPACE BAR to stop"; i = 21;
  83.        putstr(p,i);
  84.        p = "   Correct speed = 300 RPM  (295 - 305 OK)"; i = 22;
  85.        putstr(p,i);
  86.        m = 1;    /* left motor */
  87.        motor(m);    /* start left motor */
  88.        break;    /* out of switch */
  89.     case 'r':
  90.        blanksc();    /* fill screen with spaces */
  91.        p = "   Right Disk: hold down SPACE BAR to stop"; i = 21;
  92.        putstr(p,i);
  93.        p = "   Correct speed = 300 RPM  (295 - 305 OK)"; i = 22;
  94.        putstr(p,i);
  95.        m = 2;    /* right motor */
  96.        motor(m);    /* start right motor */
  97.        break;
  98.     case -1:    /* not l or r key so exit */
  99.        blanksc();    /* fill screen with spaces */
  100.        p = "    Stopped on keyboard command"; i = 18;
  101.        putstr(p,i);
  102.            for(i = 0; i < 100; ++i) while(keychk() != NULL);    /* wait for key release */
  103.        brite();    /* undim screen */
  104.        setwid(80);    /* set screenwidth to 80 columns */
  105.        motor(0);    /* stop motors */
  106.        for(i = 0; i < 10; ++i) rdcon();    /* clear console buffer */
  107.        motor(d);    /* start current logged drive motor */
  108.        exit();    /* exit to current disk */
  109.        break;
  110.     default:
  111.        c = NULL;    /* not a valid key */
  112.        break;
  113.      }
  114. /* endo */   while(c == NULL);    /* wait for valid key */
  115.  
  116.    for(i = 0; i < 100; ++i) while(keychk() != NULL);    /* wait for key release */
  117.  
  118.    while(pd = getpd())        /* get disk rotation period */
  119.    {   speed = 602 - pd/33;    /* approximation for speed = 300*9984/pd */
  120.        intdisp(speed);        /* display speed on screen */
  121.        britedim();        /* alternate display intensity */
  122.        motor(m);        /* restart motor stopped by timeout */
  123.                 /*   can't disable timeout because  */
  124.                 /*   ROM STODIM routine has EI        */
  125.    }
  126.  }
  127. }
  128.  
  129. cls()    /* clear screen */
  130. {
  131.     #asm
  132.     MVI    E,1AH
  133.     MVI    C,2
  134.     CALL    5
  135.     #endasm
  136. }
  137.  
  138. blanksc()    /* blank screen rows 1 - 23, columns 1 - 60 */
  139. {
  140.    char *p,*q;
  141.  
  142.    for(p = HOME; p < (HOME + 24*LINE); p += LINE)
  143.    for(q = p; q <= (p + 60); ++q)
  144.     *q = ' ';
  145. }
  146.  
  147. greet()
  148. {
  149.     char *p;    /* character pointer */
  150.     int l;        /* line number */
  151.  
  152.     p = "    Disk speed test program for Osborne 1"; l = 5;
  153.     putstr(p,l);
  154.  
  155.     p = "Make sure drives to be tested contain disks"; l = 12;
  156.     putstr(p,l);
  157.  
  158.     p = "Press L or R to select Left or Right Disk Drive"; l = 16;
  159.     putstr(p,l);
  160.  
  161.     p = "Any other key terminates program"; l = 18;
  162.     putstr(p,l);
  163. }
  164.  
  165. putstr(p,lin)    /* output string to screen at line number lin */
  166. char *p;
  167. int lin;
  168. {
  169.     char *q;
  170.  
  171.     q = HOME + lin*LINE + 2;
  172.     while(*p) *q++ = *p++;
  173. }
  174.  
  175. intdisp(n) int n;    /* displays integer in decimal format */
  176. {
  177.     int i;
  178.     i = 3;
  179.  
  180.     while(n > 0)    /* display right hand digit first */
  181.     {    dispbig(n%10,i--);    /* use big digits */
  182.         n /= 10;
  183.     }
  184. }
  185.  
  186. /* lrkey() checks for keys L or l or R or r */
  187. lrkey()
  188. {    int i;
  189.  
  190.     if(keychk() == 0)    return(0);
  191.     else if(lkey() == 1) return('l');
  192.     else if(rkey() == 1) return('r');
  193.     else return(-1);    /* some other key was pressed */
  194. }
  195.  
  196. motor(i)
  197. int i;
  198. {
  199.    if(i == 0)
  200.     #asm
  201.                 ;turn motors off
  202.     CALL SETROM        ;ENTER SHADOW MODE
  203.     LDA 2C02H        ;GET PIA STATUS
  204.     ANI 03FH        ;RESET BITS 6,7
  205.     STA 2C02H        ;BOTH DRIVES OFF
  206.     CALL SETRAM        ;EXIT SHADOW MODE
  207.     EI            ;ENABLE INTERRUPTS
  208.     #endasm
  209.     ;
  210.    if(i == 1)
  211.     #asm
  212.                 ;select left drive
  213.     CALL SETROM        ;ENTER SHADOW MODE
  214.     LDA 2C02H        ;GET PIA STATUS
  215.     ORI 40H            ;SET BIT 6 
  216.     ANI 07FH        ;RESET BIT 7
  217.     STA 2C02H        ;LEFT DRIVE ON, RIGHT 0FF
  218.     CALL SETRAM        ;EXIT SHADOW MODE
  219.     #endasm
  220.     ;
  221.  
  222.    if(i == 2)
  223.     #asm
  224.                 ;select right drive
  225.     CALL SETROM        ;ENTER SHADOW MODE
  226.     LDA 2C02H        ;GET PIA STATUS
  227.     ORI 80H            ;SET BIT 7 
  228.     ANI 0BFH        ;RESET BIT 6
  229.     STA 2C02H        ;LEFT DRIVE OFF, RIGHT ON
  230.     CALL SETRAM        ;EXIT SHADOW MODE
  231.     #endasm
  232.     ;
  233. }
  234.  
  235. getdsk()    /* get logged disk drive */
  236. {
  237.     #asm
  238.     MVI C,19H    ;return current disk function
  239.     CALL 5
  240.     LXI H,0
  241.     MOV L,A        ;answer returned in HL
  242.     #endasm
  243. }
  244.  
  245. getpd()        /* get period of disk rotation */
  246. {
  247.     #asm
  248.  
  249.                 ;send cmd type 1 to
  250.                 ;access index status
  251.     CALL SETROM        ;ENTER SHADOW
  252.     MVI A,03H        ;RESTORE COMMAND
  253.     STA 2100H        ;NEED TYPE 1 CMD TO
  254.                 ;ENABLE INDEX STATUS
  255. ;
  256.     DI            ;OTHERWISE DISK TIMEOUT
  257.                 ;CAN CRASH PROGRAM
  258. STAT1    LDA 2100H        ;GET DISK STATUS
  259.     ANI 02H            ;MASK INDEX HOLE
  260.     JZ STAT1        ;WAIT FOR INDEX
  261. ;
  262. STAT2    LDA 2100H        ;GET DISK STATUS
  263.     ANI 02H            ;MASK INDEX HOLE
  264.     JNZ STAT2        ;WAIT FOR NO INDEX
  265. ;
  266.     LXI H,00H        ;INITIALIZE CNTR1
  267. ;
  268. COUNT1    INX H            ;BUMP CNTR1
  269.     LDA 2220H        ;KYBD ROW 5
  270.     ANI 08H            ;SPACE BAR
  271.     JZ EXIT            ;EXIT IF PRESSED
  272.     LDA 2100H        ;GET DISK STATUS
  273.     ANI 02H            ;MASK INDEX HOLE
  274.     JZ COUNT1        ;WAIT FOR INDEX
  275. ;
  276. COUNT2    INX H            ;6  CLOCK CYCLES
  277.     LDA 2220H        ;13
  278.     ANI 08H            ;7
  279.     JZ EXIT            ;10
  280.     LDA 2100H        ;13
  281.     ANI 02H            ;7
  282.     JNZ COUNT2        ;10
  283. ;            TOTAL:     66 CLOCK CYCLES
  284. ;                    PLUS 14 WAIT STATES
  285. ;                    EQUALS 80 CYCLES IN LOOP
  286.     JMP END            ;DONE
  287. ;
  288. SETROM    DI            ;SWITCH TO ROM BANK
  289.     PUSH PSW        ;SAVE A, FLAGS
  290.     OUT 0            ;SET ROMBANK
  291.     XRA A            ;CLEAR A
  292.     STA 0EF08H        ;STORE FLAG
  293.     POP PSW            ;RESTORE A, FLAGS
  294. ;    EI            ;LEAVE DISABLED OR
  295.                 ;DISK TIMEOUT CAN
  296.                 ;CRASH PROGRAM
  297.     RET
  298.  
  299. SETRAM    DI            ;SWITCH TO RAM BANK
  300.     PUSH PSW        ;SAVE A, FLAGS
  301.     OUT 01            ;SET RAMBANK
  302.     MVI A,1            ;FLAG
  303.     STA 0EF08H        ;STORE FLAG
  304.     POP PSW
  305. ;    EI
  306.     RET
  307. ;
  308.  
  309. EXIT    LXI H,0            ;KEY PRESSED
  310. END    CALL SETRAM        ;EXIT SHADOW MODE
  311. ;    EI            ;ENABLE INTERRUPTS
  312.     #endasm            ;disk speed returned in HL
  313. }
  314.  
  315. /* keychk() checks if any key down */
  316. /* Cannot call BDOS because disk stops */
  317. keychk()
  318. {
  319.      #asm
  320.     CALL SETROM        ;leaves interrupts disabled
  321.     LXI H,0            ;initialize HL
  322.     LDA 227EH        ;keyboard, all rows but capslock
  323.     CPI 0FFH        ;any key
  324.     CALL SETRAM
  325.     RZ            ;return 0 if no keydown
  326.     MVI L,01        ;return 1 if keydown
  327.      #endasm
  328. }
  329.  
  330. /* lkey() checks for key L or key l */
  331. lkey()
  332. {
  333.      #asm
  334.     CALL SETROM
  335.     LXI H,0
  336.     LDA 2240H        ;keyboard row containing 'L'
  337.     CPI 0BFH        ;seventh column contains 'L'
  338.     CALL SETRAM
  339.     RNZ            ;return 0 if not 'L' or 'l'
  340.     MVI L,01        ;return 1 if 'L' or 'l'
  341.      #endasm
  342. }
  343.  
  344. /* rkey() checks for key R or key r */
  345. rkey()
  346. {
  347.      #asm
  348.     CALL SETROM
  349.     LXI H,0
  350.     LDA 2204H        ;keyboard row containing 'R'
  351.     CPI 0F7H        ;fourth column contains 'R'
  352.     CALL SETRAM
  353.     RNZ            ;return 0 if not 'R' or 'r'
  354.     MVI L,01        ;return 1 if 'R' or 'r'
  355.      #endasm
  356. }
  357.  
  358. /* dispbig(n,m) displays a number n in big font at position m = 1, 2, or 3 */
  359. dispbig(n,m) int n,m;
  360. {
  361.    char *p;
  362.    int r,c,o;    /* row, column, offset */
  363.  
  364.    static char one[20][11] =
  365.    {    {32,32,32,32,32,32,32,32,32,32,32},
  366.     {32,32,32,32,32,32,22,32,32,32,32},
  367.     {32,32,32,32,32,22,22,32,32,32,32},
  368.     {32,32,32,32,22,22,22,32,32,32,32},
  369.     {32,32,32,32,32,22,22,32,32,32,32},
  370.     {32,32,32,32,32,22,22,32,32,32,32},
  371.     {32,32,32,32,32,22,22,32,32,32,32},
  372.     {32,32,32,32,32,22,22,32,32,32,32},
  373.     {32,32,32,32,32,22,22,32,32,32,32},
  374.     {32,32,32,32,32,22,22,32,32,32,32},
  375.     {32,32,32,32,32,22,22,32,32,32,32},
  376.     {32,32,32,32,32,22,22,32,32,32,32},
  377.     {32,32,32,32,32,22,22,32,32,32,32},
  378.     {32,32,32,32,32,22,22,32,32,32,32},
  379.     {32,32,32,32,32,22,22,32,32,32,32},
  380.     {32,32,32,32,32,22,22,32,32,32,32},
  381.     {32,32,32,32,32,22,22,32,32,32,32},
  382.     {32,32,32,32,32,22,22,32,32,32,32},
  383.     {32,32,32,22,22,22,22,22,22,32,32},
  384.     {32,32,32,22,22,22,22,22,22,32,32}
  385.    };
  386.  
  387.    static char two[20][11] =
  388.    {    {32,32,32,32,32,32,32,32,32,32,32},
  389.     {32,32,32,22,22,22,22,32,32,32,32},
  390.     {32,32,22,22,22,22,22,22,32,32,32},
  391.     {32,22,22,32,32,32,32,22,22,32,32},
  392.     {32,22,22,32,32,32,32,22,22,32,32},
  393.     {22,22,32,32,32,32,32,32,22,22,32},
  394.     {22,22,32,32,32,32,32,32,22,22,32},
  395.     {32,32,32,32,32,32,32,32,22,22,32},
  396.     {32,32,32,32,32,32,32,22,22,22,32},
  397.     {32,32,32,32,32,32,22,22,22,32,32},
  398.     {32,32,32,32,32,22,22,22,32,32,32},
  399.     {32,32,32,32,22,22,22,32,32,32,32},
  400.     {32,32,32,22,22,22,32,32,32,32,32},
  401.     {32,32,22,22,22,32,32,32,32,32,32},
  402.     {32,22,22,22,32,32,32,32,32,32,32},
  403.     {32,22,22,32,32,32,32,32,32,32,32},
  404.     {22,22,22,32,32,32,32,32,32,32,32},
  405.     {22,22,32,32,32,32,32,32,22,22,32},
  406.     {22,22,22,22,22,22,22,22,22,22,32},
  407.     {22,22,22,22,22,22,22,22,22,22,32}
  408.    };
  409.  
  410.    static char three[20][11] =
  411.    {    {32,32,32,32,32,32,32,32,32,32,32},
  412.     {32,32,32,32,22,22,22,32,32,32,32},
  413.     {32,32,22,22,22,22,22,22,32,32,32},
  414.     {32,32,22,22,32,32,32,22,22,32,32},
  415.     {32,32,32,32,32,32,32,22,22,32,32},
  416.     {32,32,32,32,32,32,32,32,22,22,32},
  417.     {32,32,32,32,32,32,32,32,22,22,32},
  418.     {32,32,32,32,32,32,32,22,22,32,32},
  419.     {32,32,32,32,32,32,32,22,22,32,32},
  420.     {32,32,32,32,22,22,22,22,32,32,32},
  421.     {32,32,32,32,22,22,22,22,32,32,32},
  422.     {32,32,32,32,32,32,32,32,22,22,32},
  423.     {32,32,32,32,32,32,32,32,22,22,32},
  424.     {32,32,32,32,32,32,32,32,32,22,22},
  425.     {32,32,32,32,32,32,32,32,32,22,22},
  426.     {32,32,32,32,32,32,32,32,32,22,22},
  427.     {32,32,32,32,32,32,32,32,32,22,22},
  428.     {32,22,22,32,32,32,32,32,22,22,32},
  429.     {32,22,22,22,22,22,22,22,22,22,32},
  430.     {32,32,32,22,22,22,22,22,32,32,32}
  431.    };
  432.  
  433.    static char four[20][11] =
  434.    {    {32,32,32,32,32,32,32,32,32,32,32},
  435.     {32,32,32,32,32,32,22,22,32,32,32},
  436.     {32,32,32,32,32,32,22,22,32,32,32},
  437.     {32,32,32,32,32,22,22,22,32,32,32},
  438.     {32,32,32,32,22,22,22,22,32,32,32},
  439.     {32,32,32,22,22,32,22,22,32,32,32},
  440.     {32,32,32,22,22,32,22,22,32,32,32},
  441.     {32,32,22,22,32,32,22,22,32,32,32},
  442.     {32,22,22,32,32,32,22,22,32,32,32},
  443.     {32,22,22,32,32,32,22,22,32,32,32},
  444.     {22,22,32,32,32,32,22,22,32,32,32},
  445.     {22,22,22,22,22,22,22,22,22,22,32},
  446.     {22,22,22,22,22,22,22,22,22,22,32},
  447.     {32,32,32,32,32,32,22,22,32,32,32},
  448.     {32,32,32,32,32,32,22,22,32,32,32},
  449.     {32,32,32,32,32,32,22,22,32,32,32},
  450.     {32,32,32,32,32,32,22,22,32,32,32},
  451.     {32,32,32,32,32,32,22,22,32,32,32},
  452.     {32,32,32,32,32,22,22,22,22,32,32},
  453.     {32,32,32,32,32,22,22,22,22,32,32}
  454.    };
  455.  
  456.    static char five[20][11] =
  457.    {    {32,32,32,32,32,32,32,32,32,32,32},
  458.     {32,32,32,22,22,22,22,22,22,22,22},
  459.     {32,32,22,22,22,22,22,22,22,22,22},
  460.     {32,32,22,22,32,32,32,32,32,32,32},
  461.     {32,22,22,32,32,32,32,32,32,32,32},
  462.     {32,22,22,32,32,32,32,32,32,32,32},
  463.     {22,22,32,32,32,32,32,32,32,32,32},
  464.     {22,22,32,32,32,32,32,32,32,32,32},
  465.     {22,22,22,22,22,22,22,22,32,32,32},
  466.     {22,22,22,22,22,22,22,22,22,32,32},
  467.     {32,32,32,32,32,32,32,22,22,22,32},
  468.     {32,32,32,32,32,32,32,32,22,22,32},
  469.     {32,32,32,32,32,32,32,32,32,22,22},
  470.     {32,32,32,32,32,32,32,32,32,22,22},
  471.     {32,32,32,32,32,32,32,32,32,22,22},
  472.     {22,22,32,32,32,32,32,32,32,22,22},
  473.     {22,22,32,32,32,32,32,32,32,22,22},
  474.     {32,22,22,32,32,32,32,32,22,22,32},
  475.     {32,22,22,22,22,22,22,22,22,22,32},
  476.     {32,32,32,22,22,22,22,22,32,32,32}
  477.    };
  478.  
  479.    static char six[20][11] =
  480.    {    {32,32,32,32,32,32,32,32,32,32,32},
  481.     {32,32,32,22,22,22,22,22,32,32,32},
  482.     {32,32,22,22,22,22,22,22,22,32,32},
  483.     {32,22,22,22,32,32,32,22,22,22,32},
  484.     {22,22,22,32,32,32,32,32,22,22,32},
  485.     {22,22,32,32,32,32,32,32,32,32,32},
  486.     {22,22,32,32,32,32,32,32,32,32,32},
  487.     {22,22,32,32,32,32,32,32,32,32,32},
  488.     {22,22,32,22,22,22,22,22,32,32,32},
  489.     {22,22,22,22,22,22,22,22,22,32,32},
  490.     {22,22,22,22,32,32,32,22,22,22,32},
  491.     {22,22,22,32,32,32,32,32,22,22,32},
  492.     {22,22,32,32,32,32,32,32,32,22,22},
  493.     {22,22,32,32,32,32,32,32,32,22,22},
  494.     {22,22,32,32,32,32,32,32,32,22,22},
  495.     {22,22,32,32,32,32,32,32,32,22,22},
  496.     {22,22,22,32,32,32,32,32,22,22,22},
  497.     {32,22,22,22,32,32,32,22,22,22,32},
  498.     {32,22,22,22,22,22,22,22,22,22,32},
  499.     {32,32,32,22,22,22,22,22,32,32,32}
  500.    };
  501.  
  502.    static char seven[20][11] =
  503.    {    {32,32,32,32,32,32,32,32,32,32,32},
  504.     {22,22,22,22,22,22,22,22,22,22,32},
  505.     {22,22,22,22,22,22,22,22,22,22,32},
  506.     {22,22,32,32,32,32,32,32,22,22,32},
  507.     {32,32,32,32,32,32,32,32,22,22,32},
  508.     {32,32,32,32,32,32,32,22,22,22,32},
  509.     {32,32,32,32,32,32,22,22,22,32,32},
  510.     {32,32,32,32,32,22,22,22,32,32,32},
  511.     {32,32,32,32,22,22,22,32,32,32,32},
  512.     {32,32,32,22,22,22,32,32,32,32,32},
  513.     {32,32,32,22,22,32,32,32,32,32,32},
  514.     {32,32,22,22,22,32,32,32,32,32,32},
  515.     {32,32,22,22,32,32,32,32,32,32,32},
  516.     {32,22,22,22,32,32,32,32,32,32,32},
  517.     {32,22,22,32,32,32,32,32,32,32,32},
  518.     {22,22,22,32,32,32,32,32,32,32,32},
  519.     {22,22,32,32,32,32,32,32,32,32,32},
  520.     {22,22,32,32,32,32,32,32,32,32,32},
  521.     {22,22,32,32,32,32,32,32,32,32,32},
  522.     {22,22,32,32,32,32,32,32,32,32,32}
  523.    };
  524.  
  525.    static char eight[20][11] =
  526.    {    {32,32,32,32,32,32,32,32,32,32,32},
  527.     {32,32,32,32,22,22,22,32,32,32,32},
  528.     {32,32,32,22,22,22,22,22,32,32,32},
  529.     {32,32,22,22,32,32,32,22,22,32,32},
  530.     {32,32,22,22,32,32,32,22,22,32,32},
  531.     {32,22,22,32,32,32,32,32,22,22,32},
  532.     {32,22,22,32,32,32,32,32,22,22,32},
  533.     {32,32,22,22,32,32,32,22,22,32,32},
  534.     {32,32,22,22,32,32,32,22,22,32,32},
  535.     {32,32,32,22,22,22,22,22,32,32,32},
  536.     {32,32,22,22,22,22,22,22,22,32,32},
  537.     {32,22,22,32,32,32,32,32,22,22,32},
  538.     {32,22,22,32,32,32,32,32,22,22,32},
  539.     {22,22,32,32,32,32,32,32,32,22,22},
  540.     {22,22,32,32,32,32,32,32,32,22,22},
  541.     {22,22,32,32,32,32,32,32,32,22,22},
  542.     {32,22,22,32,32,32,32,32,22,22,32},
  543.     {32,22,22,32,32,32,32,32,22,22,32},
  544.     {32,32,22,22,22,22,22,22,22,32,32},
  545.     {32,32,32,22,22,22,22,22,32,32,32}
  546.    };
  547.  
  548.    static char nine[20][11] =
  549.    {    {32,32,32,32,32,32,32,32,32,32,32},
  550.     {32,32,32,22,22,22,22,32,32,32,32},
  551.     {32,32,22,22,22,22,22,22,32,32,32},
  552.     {32,22,22,22,32,32,22,22,22,32,32},
  553.     {32,22,22,32,32,32,32,22,22,32,32},
  554.     {22,22,32,32,32,32,32,32,22,22,32},
  555.     {22,22,32,32,32,32,32,32,22,22,32},
  556.     {22,22,32,32,32,32,32,32,22,22,32},    
  557.     {32,22,22,32,32,32,32,22,22,22,32},
  558.     {32,22,22,22,32,32,22,22,22,22,32},
  559.     {32,32,22,22,22,22,22,22,22,22,32},
  560.     {32,32,32,22,22,22,22,32,22,22,32},
  561.     {32,32,32,32,32,32,32,32,22,22,32},
  562.     {32,32,32,32,32,32,32,32,22,22,32},
  563.     {32,32,32,32,32,32,32,32,22,22,32},
  564.     {22,22,32,32,32,32,32,32,22,22,32},
  565.     {22,22,32,32,32,32,32,22,22,32,32},
  566.     {32,22,22,32,32,32,32,22,22,32,32},
  567.     {32,32,22,22,22,22,22,22,32,32,32},
  568.     {32,32,32,22,22,22,22,32,32,32,32}
  569.    };
  570.  
  571.    static char zero[20][11] =
  572.    {    {32,32,32,32,32,32,32,32,32,32,32},
  573.     {32,32,32,22,22,22,22,22,32,32,32},
  574.     {32,32,22,22,22,22,22,22,22,32,32},
  575.     {32,22,22,32,32,32,32,32,22,22,32},
  576.     {32,22,22,32,32,32,32,32,22,22,32},
  577.     {22,22,32,32,32,32,32,32,32,22,22},
  578.     {22,22,32,32,32,32,32,32,32,22,22},
  579.     {22,22,32,32,32,32,32,32,32,22,22},
  580.     {22,22,32,32,32,32,32,32,32,22,22},
  581.     {22,22,32,32,32,32,32,32,32,22,22},
  582.     {22,22,32,32,32,32,32,32,32,22,22},
  583.     {22,22,32,32,32,32,32,32,32,22,22},
  584.     {22,22,32,32,32,32,32,32,32,22,22},
  585.     {22,22,32,32,32,32,32,32,32,22,22},
  586.     {22,22,32,32,32,32,32,32,32,22,22},
  587.     {22,22,32,32,32,32,32,32,32,22,22},
  588.     {32,22,22,32,32,32,32,32,22,22,32},
  589.     {32,22,22,32,32,32,32,32,22,22,32},
  590.     {32,32,22,22,22,22,22,22,22,32,32},
  591.     {32,32,32,22,22,22,22,22,32,32,32}
  592.    };
  593.  
  594.    if(m == 1) o = 02;    /* character starting offset */
  595.    if(m == 2) o = 19;
  596.    if(m == 3) o = 36;
  597.  
  598.    for(r = 0; r < 20; ++r)
  599.    {  p = HOME + o + r*LINE;
  600.       for(c = 0; c < 11; ++c)
  601.     switch (n)
  602.     {  case 1:   *p++ = one[r][c];   break;
  603.        case 2:   *p++ = two[r][c];   break;
  604.        case 3:   *p++ = three[r][c]; break;
  605.        case 4:   *p++ = four[r][c];  break;
  606.        case 5:   *p++ = five[r][c];  break;
  607.        case 6:   *p++ = six[r][c];   break;
  608.        case 7:   *p++ = seven[r][c]; break;
  609.        case 8:   *p++ = eight[r][c]; break;
  610.        case 9:   *p++ = nine[r][c];  break;
  611.        case 0:   *p++ = zero[r][c];  break;
  612.        default:  *p++ = zero[r][c];  break;
  613.     }
  614.    }
  615. }
  616.  
  617. britedim()    /* alternate intensity of screen rows 1 - 20, columns 1 - 60 */
  618. {
  619.    static int i = 0;
  620.  
  621.    (i == 0) ? (i = 1) : (i = 0);    /* reverse i */
  622.  
  623.    if(i == 0) brite();
  624.    else dim();
  625. }
  626.  
  627. brite()        /* make screen bright */
  628. {
  629.     char *p,*q;
  630.  
  631.     for(p = HOME; p < (HOME + 21*LINE); p += LINE)
  632.     for(q = p; q <= (p + 60); ++q)
  633.         stobrite(q);
  634. }
  635.  
  636. dim()        /* make screen dim */
  637. {
  638.     char *p,*q;
  639.     for(p = HOME; p < (HOME + 21*LINE); p += LINE)
  640.     for(q = p; q <= (p + 60); ++q)
  641.         stodim(q);
  642. }
  643.  
  644. stobrite(q) char *q;
  645. {
  646.     q;        /* put q in HL */
  647.  
  648.     #asm
  649.     CALL SETROM    ;switch to ROM
  650.     MVI B,0FFH    ;all bits hi
  651.     CALL STODIM    ;put in dimRAM
  652.     CALL SETRAM    ;switch back to RAM
  653.     #endasm
  654. }
  655.  
  656. /* STODIM is in ROM and looks like this:
  657.  
  658. 015D    JMP O6D5
  659. 06D5    DI
  660.     OUT 2
  661.     MOV M,B
  662.     OUT 3
  663.     EI
  664.     RET
  665.  */ 
  666.  
  667. stodim(q) char *q;
  668. {
  669.     q;        /* put q in HL */
  670.  
  671.     #asm
  672.     CALL SETROM    ;switch to ROM
  673.     MVI B,07FH    ;bit 8 lo
  674.     CALL STODIM    ;put in dimRAM
  675.     CALL SETRAM    ;switch back to RAM
  676.     #endasm
  677. }
  678.  
  679. setwid(w) int w;    /* sets screenwidth to 52, 80, or 100 columns */
  680. {
  681.     char c;        /* screen width: 1 = 100 columns */
  682.             /*          2 = 52 columns */
  683.             /*          3 = 80 columns */
  684.  
  685.     char *pw;    /* pointer to screen width control port */
  686.  
  687.     pw = WIDCON;    /* points to screenwidth control port */
  688.  
  689.     switch(w)
  690.     {   case 52:    c = 2; break;
  691.         case 80:    c = 3; break;
  692.         case 100:    c = 1; break;
  693.         default:    c = 3;
  694.     }
  695.  
  696.     #asm
  697.     CALL SETROM    ;switch to ROM
  698.     #endasm
  699.  
  700.     *pw = c;    /* set screenwidth */
  701.  
  702.     #asm
  703.     CALL SETRAM    ;switch back to RAM
  704.     #endasm
  705. }
  706.  
  707. rdcon()    /* read console */
  708. {
  709.     #asm
  710.     MVI    E,0FFH
  711.     MVI    C,6
  712.     CALL    5
  713.     #endasm
  714. }
  715.  
  716.