Advertisement
Shaun_B

Fast Scrolly v2.0.3 for the Sinclair ZX81 + 16K

Nov 28th, 2012
557
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.01 KB | None | 0 0
  1. /**
  2.  * This is a dual scrolly text programme which will display
  3.  * a 'marquee', as they say these days, on the bottom and
  4.  * top lines of BASIC screen area of a ZX81; In this example
  5.  * the top line is inversed, and the bottom line is not.
  6.  * This is a quicker method than shifting the characters
  7.  * with wrap around and updating the display.
  8.  * Written in Z88DK and tested on EightOne emulator.
  9.  *
  10.  * @author Shaun B
  11.  * @date 2012-11-28
  12.  * @version 2.0.3
  13.  */
  14. #include <zx81.h>
  15. #include <stdio.h>
  16. #include <input.h>
  17. // This will flip the characters to 'inverse' mode:
  18. #define INVERSE(a)  (0x80 | a)
  19. // This is used for the printat routine:
  20. #define SCRLOC(x,y) (x<<8 | y)
  21. // Definitions for ROM calls:
  22. #define PRINTAT     0x08f5
  23. #define PRINT       0x10
  24. // This will define out character sets, meaning that there's
  25. // no longer a need to convert the bytes on the fly, which
  26. // should therefore save some timing states:
  27. #define CLEAR       0x00
  28. // Here's some characters:
  29. #define TL          0x01
  30. #define TR          0x02
  31. #define TOP         0x03
  32. #define BL          0x04
  33. #define LEFT        0x05
  34. #define CHECKER     0x06
  35. #define CORNER      0x07
  36. #define CHESSB      0x08
  37. #define CHESSBOT    0x09
  38. #define CHESSTOP    0x0a
  39. #define QUOTE       0x0b
  40. #define POUND       0x0c
  41. #define DOLLAR      0x0d
  42. #define COLON       0x0e
  43. #define QM          0x0f
  44. #define OBRACKET    0x10
  45. #define CBRACKET    0x11
  46. #define GRT         0x12
  47. #define LST         0x13
  48. #define EQUALS      0x14
  49. #define PLUS        0x15
  50. #define DASH        0x16
  51. #define STAR        0x17
  52. #define SLASH       0x18
  53. #define SEMI        0x19
  54. #define COMMA       0x1a
  55. #define DOT         0x1b
  56. // Defines start of numbers:
  57. #define ZERO        0x1c
  58. #define ONE         0x1d
  59. #define TWO         0x1e
  60. #define THREE       0x1f
  61. #define FOUR        0x20
  62. #define FIVE        0x21
  63. #define SIX         0x22
  64. #define SEVEN       0x23
  65. #define EIGHT       0x24
  66. #define NINE        0x25
  67. // ZX81 alphabet:
  68. #define _A          0x26
  69. #define _B          0x27
  70. #define _C          0x28
  71. #define _D          0x29
  72. #define _E          0x2a
  73. #define _F          0x2b
  74. #define _G          0x2c
  75. #define _H          0x2d
  76. #define _I          0x2e
  77. #define _J          0x2f
  78. #define _K          0x30
  79. #define _L          0x31
  80. #define _M          0x32
  81. #define _N          0x33
  82. #define _O          0x34
  83. #define _P          0x35
  84. #define _Q          0x36
  85. #define _R          0x37
  86. #define _S          0x38
  87. #define _T          0x39
  88. #define _U          0x3a
  89. #define _V          0x3b
  90. #define _W          0x3c
  91. #define _X          0x3d
  92. #define _Y          0x3e
  93. #define _Z          0x3f
  94. // Function prototypes:
  95. // Here is our main entry:
  96. void main(void);
  97. // This will output our character to the screen:
  98. void print(short ch);
  99. // Here's our PRINT AT equivalent:
  100. void printat(short xy);
  101. // Things now move much quicker, so we need to slow
  102. // the scroll update down a bit:
  103. // In this example, it is unused, but it should cost
  104. // around 30-something timing states per unit sent to
  105. // the function at a guess because of how C uses the
  106. // stack - accepts numbers between 0 and 255
  107. void pause(char x);
  108. // Globals for x and y axis:
  109. // Reusable counters:
  110. static char i=0;
  111. static short c=0;
  112. static char x=0;
  113. static char y=0;
  114. // Used for reading the keyboard:
  115. static char key=0;
  116. // Scrolly:
  117. static char scrolly[478]=
  118. {
  119.     _D,_O,_N,_K,_E,_Y,_S,_O,_F,_T,CLEAR,_M,_M,_X,_I,_I,CLEAR,
  120.     _P,_R,_E,_S,_E,_N,_T,_S,CLEAR,_A,CLEAR,_L,_I,_T,_T,_L,_E,
  121.     CLEAR,_R,_O,_U,_T,_I,_N,_E,CLEAR,_F,_O,_R,CLEAR,_T,_H,_E,
  122.     CLEAR,_S,_I,_N,_C,_L,_A,_I,_R,CLEAR,_Z,_X,EIGHT,ONE,CLEAR,
  123.     PLUS,CLEAR,ONE,SIX,_K,COMMA,CLEAR,_F,_A,_S,_T,CLEAR,
  124.     _S,_C,_R,_O,_L,_L,_Y,CLEAR,_V,TWO,DOT,ZERO,DOT,THREE,COMMA,
  125.     CLEAR,_W,_R,_I,_T,_T,_E,_N,CLEAR,_I,_N,CLEAR,_C,CLEAR,_A,_N,_D,
  126.     CLEAR,_C,_O,_M,_P,_I,_L,_E,_D,CLEAR,_I,_N,CLEAR,_Z,EIGHT,EIGHT,
  127.     _D,_K,CLEAR,DASH,CLEAR,_H,_T,_T,_P,COLON,SLASH,SLASH,_W,_W,_W,
  128.     DOT,_Z,EIGHT,EIGHT,_D,_K,DOT,_O,_R,_G,CLEAR,DASH,CLEAR,
  129.     _F,_A,_S,_T,CLEAR,_S,_C,_R,_O,_L,_L,_Y,CLEAR,_I,_S,CLEAR,
  130.     _S,_I,_G,_N,_I,_F,_I,_C,_A,_N,_T,_L,_Y,CLEAR,_F,_A,_S,_T,_E,_R,
  131.     CLEAR,_T,_H,_A,_N,CLEAR,_M,_Y,CLEAR,_U,_S,_U,_A,_L,CLEAR,
  132.     _M,_E,_T,_H,_O,_D,CLEAR,_O,_F,CLEAR,_T,_H,_I,_S,CLEAR,
  133.     _S,_O,_R,_T,CLEAR,_O,_F,CLEAR,_T,_H,_I,_N,_G,COMMA,CLEAR,
  134.     _W,_H,_I,_C,_H,CLEAR,_I,_N,_V,_O,_L,_V,_E,_S,CLEAR,
  135.     _S,_H,_I,_F,_T,_I,_N,_G,CLEAR,_T,_H,_E,CLEAR,_B,_Y,_T,_E,_S,
  136.     CLEAR,_A,_N,_D,CLEAR,_U,_P,_D,_A,_T,_I,_N,_G,CLEAR,_T,_H,_E,
  137.     CLEAR,_S,_C,_R,_E,_E,_N,CLEAR,_A,_T,CLEAR,_T,_H,_E,CLEAR,
  138.     _L,_O,_C,_A,_T,_I,_O,_N,CLEAR,_T,_H,_A,_T,CLEAR,_I,CLEAR,
  139.     _W,_A,_N,_T,CLEAR,_T,_H,_E,CLEAR,_T,_E,_X,_T,CLEAR,DASH,CLEAR,
  140.     _O,_R,CLEAR,_A,_T,CLEAR,_L,_E,_A,_S,_T,CLEAR,_I,_T,CLEAR,_I,_S,
  141.     CLEAR,_Q,_U,_I,_C,_K,_E,_R,CLEAR,_O,_N,CLEAR,_T,_H,_E,CLEAR,
  142.     _O,_L,_D,CLEAR,_Z,_X,CLEAR,_A,_N,_Y,_W,_A,_Y,_S,CLEAR,COLON,
  143.     DASH,CBRACKET,CLEAR,_G,_R,_E,_E,_T,_Z,CLEAR,_T,_O,CLEAR,
  144.     _J,_O,_N,_A,_T,_H,_A,_N,CLEAR,_C,COMMA,CLEAR,_B,_O,_B,_S,COMMA,
  145.     CLEAR,_T,_M,_R,COMMA,CLEAR,_A,_N,_D,_Y,CLEAR,_R,_E,_A,COMMA,
  146.     CLEAR,_S,_I,_M,_O,_N,CLEAR,_U,_L,_L,_Y,_A,_T,_T,CLEAR,_A,_N,_D,
  147.     CLEAR,_E,_V,_E,_R,_Y,_O,_N,_E,CLEAR,_O,_N,CLEAR,_T,_H,_E,CLEAR,
  148.     _R,_W,_A,_P,CLEAR,_F,_O,_R,_U,_M,_S,DOT,CLEAR,_B,_Y,_E,_Z,DOT
  149. };
  150. // Main function:
  151. void main()
  152. {
  153.     // This is quite a nice way of waiting for a keyboard input
  154.     // before dropping out of the programme and returning (in
  155.     // this case) to BASIC.
  156.     while(!(key=in_Inkey()))
  157.     {
  158.         // y should already be initialised to zero from start-up
  159.         // see the global-scope variables above:
  160.         if(y==0)
  161.         {
  162.             c=y;
  163.             y=32;
  164.         }
  165.         // Prints at location 0,0 (top row):
  166.         printat(SCRLOC(0,0));
  167.         // If we're not past the first 32 characters of the scrolly
  168.         // yet, we want to print out spaces and then start the
  169.         // message so that it magically appears onto the screen:
  170.         if(c<32)
  171.         {
  172.             // This will print the number of blanks needed (inversed):
  173.             for(i=32; i>c; i--)
  174.             {
  175.                 print(INVERSE(CLEAR));
  176.             }
  177.             x=i;
  178.             // The remainder in x will then output the first characters
  179.             // of the scrolly text message:
  180.             for(i=0; i<x; i++)
  181.             {
  182.                 print(INVERSE(scrolly[i]));
  183.             }
  184.             // Puts cursor at location 0,21 (bottom row) and we'll do the
  185.             // same as above, but not inverse:
  186.             printat(SCRLOC(0,21));
  187.             for(i=32; i>c; i--)
  188.             {
  189.                 print(CLEAR);
  190.             }
  191.             x=i;
  192.             for(i=0; i<x; i++)
  193.             {
  194.                 print(scrolly[i]);
  195.             }
  196.             // To slow down the text, use:
  197.             // pause(12);
  198.             // for instance. You'll also have to put a similar
  199.             // pause below so that the the characters don't scroll
  200.             // onto the screen slower than they do usually.
  201.         }
  202.         // Okay, so now we just want the characters in the scrolly text
  203.         // to be displayed, but we have a 32-char off-set because of the
  204.         // way that the logic works, as our counter will be 32 ahead
  205.         // of where we need to be:
  206.         else
  207.         {
  208.             // Because this is an else condition, we set printat(0,0)
  209.             // above:
  210.             for(i=0; i<y; i++)
  211.             {
  212.                 print(INVERSE(scrolly[c+i-32]));
  213.             }
  214.             // Puts cursor at location 0,21 (bottom row):
  215.             printat(SCRLOC(0,21));
  216.             for(i=0; i<y; i++)
  217.             {
  218.                 print(scrolly[c+i-32]);
  219.             }
  220.         }
  221.         // This will print out up to 32 spaces after the scrolly text
  222.         // so there's a total of 64 spaces between the beginning and
  223.         // the end of the text:
  224.         if(y<32)
  225.         {
  226.             // We need to set the cursor to y across and then the line
  227.             // in which we'll output the characters:
  228.             printat(SCRLOC(y,0));
  229.             // Counts up to y:
  230.             for(i=y; i<32; i++)
  231.             {
  232.                 print(INVERSE(CLEAR));
  233.             }
  234.             // Same as above, but this time at the bottom of the screen
  235.             // without inverse:
  236.             printat(SCRLOC(y,21));
  237.             for(i=y; i<32; i++)
  238.             {
  239.                 print(CLEAR);
  240.             }
  241.         }
  242.         // This will count to the end of the scrolly text: if we're at
  243.         // the end, y will decrease to say how many spaces will be
  244.         // padded out at the end:
  245.         if(c>=478 && y>0)
  246.         {
  247.             y--;
  248.         }
  249.         // Increase our counter:
  250.         c++;
  251.         // Loops back around while there's been no key-press.
  252.     }
  253. }
  254. // This will print out a char, which is pushed onto the stack:
  255. void print(short ch)
  256. {
  257.     #asm
  258.     EXX
  259.     LD      HL,$0002
  260.     ADD     HL,SP
  261.     LD      A,(HL)
  262.     RST     PRINT
  263.     EXX
  264.     #endasm
  265. }
  266. void printat(short xy)
  267. {
  268.     #asm
  269.     EXX
  270.     LD      HL,$0002
  271.     ADD     HL,SP
  272.     LD      B,(HL)
  273.     INC     L
  274.     LD      C,(HL)
  275.     CALL    PRINTAT
  276.     EXX
  277.     #endasm
  278. }
  279. void pause(char x)
  280. {
  281.     while(x)
  282.     {
  283.         #asm
  284.         NOP
  285.         #endasm
  286.         x--;
  287.     }
  288. }
  289. // Compile with:
  290. // zcc +zx81 -startup=2 -create-app -DTEXT -o FS Scroller.c
  291. // (C) 2012 Donkeysoft
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement