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 / BEEHIVE / GAMES / CRAM36.ARC / CRAM.MAC < prev   
Text File  |  1990-07-21  |  24KB  |  932 lines

  1. TITLE'CRAM vs 3.6'
  2. ;***********************************************************
  3. ;*                                *
  4. ;*  PROGRAM NAME:    CRAM.MAC                       *
  5. ;*                                                         *
  6. ;*  VERSION     :    3.6   08/05/87                        *
  7. ;*                                                         *
  8. ;*  FUNCTION    :    Graphics Demonstration Game           *
  9. ;*                                                         *
  10. ;***********************************************************
  11.  
  12.     .Z80
  13.     ASEG
  14.     .SALL
  15.  
  16. ; CP/M FUNCTIONS AND ADDRESSES
  17.  
  18. BDOS    EQU    5        ; SYSTEM CALL ENTRY
  19. WCONF    EQU    2        ; WRITE (A) TO CON:
  20. DCON    EQU    6        ; DIRECT CONSOLE I/O
  21. CONMOD    EQU    06DH        ; SET CONSOLE MODE
  22. OPENF    EQU    15        ; OPEN A FILE
  23. CLOSF    EQU    16        ; CLOSE A FILE AFTER WRITE
  24. WRITF    EQU    21        ; WRITE ONE RECORD TO FILE
  25. SETDMA    EQU    26        ; SET DMA ADDRESS
  26. SETMSC    EQU    44        ; SET MULTI-SECTOR COUNT
  27. TFCB    EQU    5CH        ; TRANSIENT FCB
  28. FCBCR    EQU    TFCB+32        ; CURRENT RECORD IN TFCB
  29.  
  30. VIDEO    EQU    0F800H        ; START OF VIDEO RAM
  31.  
  32. POSXY    MACRO    X,Y        ; MACRO FOR DIRECT CURSOR
  33.     DB    1BH,3DH        ; POSITIONING
  34.     DB    Y+20H        ; 0<=X<=79
  35.     DB    X+20H        ; 0<=Y<=24
  36.     ENDM            ; 
  37.  
  38.     ORG    100H        ; TRANSIENT PROGRAM AREA
  39.  
  40. DBUFF    EQU    $        ; HIGH SCORE BUFFER
  41.  
  42. BEGIN:    JP    INIT        ; JUMP OVER HIGH SCORE AREA
  43.     REPT    9        ; HIGH SCORE TABLE
  44.     DEFB    0,0,'                          '
  45.     ENDM
  46. VOL:    DEFB    5        ; VOLUME CONTROL
  47.  
  48. INIT:    LD    (CPMSP),SP    ; SAVE CP/M STACK
  49.     LD    SP,STAK        ; SET UP LOCAL STACK
  50.     LD    C,20H        ; TURN OFF BONDWELL CURSOR
  51.     CALL    CURSOR
  52.     LD    A,R        ; SEED RANDOM NUMBER ROUTINE
  53.     LD    (SEED),A
  54.     LD    A,R
  55.     LD    (SEED+1),A
  56.  
  57.     LD    C,CONMOD    ; SET CONSOLE MODE TO 
  58.     LD    DE,00000010B    ; DISABLE ^S
  59.     CALL    BDOS
  60.  
  61. ; ***** MAIN PROGRAM LOOP *********************************
  62.  
  63. START:    CALL    TITLE        ; TITLE ROUTINE
  64.     CALL    SETUP        ; SETUP GAME BOARD
  65.     CALL    PLAY        ; PLAY GAME
  66.     CALL    END        ; END OF GAME ROUTINE
  67.     JR    START        ; LOOP BACK
  68.  
  69. ; ***** HIGH LEVEL SUBROUTINES ****************************
  70.  
  71. TITLE:    CALL    CLS        ; CLEAR SCREEN
  72.     CALL    PTITLE        ; PRINT TITLE
  73.     CALL    SHWSCR        ; AND PREVIOUS SCORE
  74. TITL10:    CALL    FLASH        ; FLASH SCREEN
  75.     CALL    TONE        ; PLAY TONE
  76.     LD    BC,2800H    ; DELAY VALUE
  77.     CALL    DELAY        ; WAIT A BIT
  78.     CALL    GETENT        ; CHECK FOR <RETURN>
  79.     JR    Z,TITL10    ; LOOP IF NOT PRESSED
  80.     CALL    GETDIF        ; GET DIFFICULTY LEVEL
  81.     RET
  82.  
  83. SETUP:    CALL    GRPHCL        ; CLEAR SCREEN
  84.     CALL    FRAME        ; FRAME SCREEN
  85.     LD    A,(MODBUF)    ; GET MODE
  86.     CP    1        ; ? MODE 1
  87.     CALL    Z,BLOCK        ; SETUP OBSTICLES FOR MODE 1
  88.     CALL    SETCRS        ; SET CURSOR AND COUNTER
  89.     CALL    SET        ; DISPLAY STARTING POS.
  90.     CALL    GAMMSG        ; SHOW GAME MESSAGE
  91. SETUP10:
  92.     CALL    GARR20        ; GET KEYSTROKE
  93.     JR    Z,SETUP10    ; LOOP UNTIL KEYSTROKE
  94.     CALL    FRAME        ; COMPLETE FRAME AGAIN
  95.     RET
  96.  
  97. PLAY:    CALL    GETARR        ; GET ARROWS PRESSED
  98.     CALL    FPOSN        ; FIND NEW POSITION
  99.     CALL    POINT        ; CHECK IF GAME OVER
  100.     RET    NZ        ; RET TO DRIVE IF IT IS
  101.     CALL    SET        ; DISPLAY NEW POSITION
  102.     LD    A,(MODBUF)    ; CHECK FOR MODE 2
  103.     CP    2
  104.     CALL    Z,BL40        ; SET BLOCK IF IT IS
  105.     CALL    SCORE        ; UPDATE SCORE
  106.     CALL    SHWSCR        ; DISPLAY SCORE
  107.     CALL    PAUSE        ; PAUSE BETWEEN MOVES
  108.     JR    PLAY        ; LOOP BACK AND START OVER
  109.  
  110. END:    LD    B,35        ; COUNTER FOR FLASHES
  111. END10:    PUSH    BC        ; SAVE COUNTER
  112.     CALL    FLASH        ; FLASH SCREEN
  113.     CALL    NOISE        ; FUNNY SOUND
  114.     POP    BC        ; GET END COUNTER
  115.     DJNZ    END10        ; REPEAT 35 TIMES
  116.     CALL    CLKEY        ; CLEAR KEY BUFFER
  117.     CALL    HSCORE        ; CHECK FOR HIGH SCORE
  118.     RET
  119.  
  120. ; ***** LOW LEVEL SUBROUTINES *****************************    
  121.  
  122. ; MESSAGE POINTED TO BY STACK OUT TO CONSOLE
  123. SPMSG:    EX    (SP),HL        ; GET RETURN ADDRESS TO HL
  124.     LD    A,(HL)        ; GET ONE MESSAGE CHARACTER
  125.     OR    A        ; ?0 END OF STRING
  126.     INC    HL        ; POINT TO NEXT
  127.     EX    (SP),HL        ; RESTORE STACK FOR
  128.     RET    Z        ;   RETURN IF DONE
  129.     CALL    CO        ;   ELSE DISPLAY CHARACTER
  130.     JR    SPMSG        ;   AND DO ANOTHER
  131.  
  132. ; SEND THE CONTENTS OF A TO THE CP/M CON: DEVICE
  133. CO:    PUSH    BC        ; SAVE REGISTERS
  134.     PUSH    DE
  135.     PUSH    HL
  136.     LD    C,WCONF        ; SELECT FUNCTION
  137.     LD    E,A        ; CHARACTER TO E
  138.     CALL    BDOS        ; OUTPUT BY CP/M
  139.     POP    HL
  140.     POP    DE
  141.     POP    BC
  142.     RET    
  143.  
  144. CLS:    CALL    SPMSG        ; USES CP/M BIOS ROUTINES
  145.     DEFB    1BH,2AH,00H    ; TO CLEAR THE SCREEN
  146.     RET    
  147.  
  148. DELAY:    DEC    BC
  149.     LD    A,B        ; TEST FOR 0
  150.     OR    C
  151.     JR    NZ,DELAY
  152.     RET
  153.  
  154. GRPHCL:    LD    HL,VIDEO    ; BEGINNING OF SCREEN
  155.     LD    DE,VIDEO+1    ; NEXT SPACE
  156.     LD    BC,1999        ; # POSITIONS - 1
  157.     LD    (HL),00        ; SET FIRST POSITION
  158.     LDIR            ; AND COPY IT
  159.     RET
  160.  
  161. PTITLE:    CALL    SPMSG        ;PRINT TITLE
  162.     .XLIST
  163. ;1ST LINE OF GRAPHIC "CRAM"
  164.     POSXY    20,2
  165.     DEFB    32,80H,80H,80H,80H,80H,'   ',80H,80H,80H,80H,80H,80H
  166.     DEFB    '      ',80H,80H,80H,'     ',80H,80H,'     ',80H,80H
  167. ;2ND LINE
  168.     POSXY    20,3
  169.     DEFB    80H,'     ',80H,'  ',80H,'     ',80H,'    ',80H,'   '
  170.     DEFB    80H,'    ',80H,32,80H,'   ',80H,32,80H
  171. ;3RD LINE
  172.     POSXY    20,4    
  173.     DEFB    80H,'        ',80H,'     ',80H,'   ',80H,'     ',80H
  174.     DEFB    '   ',80H,'  ',80H,32,80H,'  ',80H
  175. ;4TH LINE
  176.     POSXY    20,5
  177.     DEFB    80H,'        ',80H,80H,80H,80H,80H,80H,'    ',80H,80H
  178.     DEFB    80H,80H,80H,80H,80H,'   ',80H,'   ',80H,'   ',80H
  179. ;5TH LINE
  180.     POSXY    20,6
  181.     DEFB    80H,'        ',80H,'   ',80H,'     ',80H,'     ',80H
  182.     DEFB    '   ',80H,'   ',80H,'   ',80H
  183. ;6TH LINE
  184.     POSXY    20,7
  185.     DEFB    80H,'     ',80H,'  ',80H,'    ',80H,'    ',80H,'     '
  186.     DEFB    80H,'   ',80H,'   ',80H,'   ',80H
  187. ;7TH LINE
  188.     POSXY    20,8
  189.     DEFB    32,80H,80H,80H,80H,80H,'   ',80H,'     ',80H,'   ',80H
  190.     DEFB    '     ',80H,'   ',80H,'   ',80H,'   ',80H
  191. ;
  192.     POSXY    13,10
  193.     DEFM    'Version 3.6 for Bondwell 14 by Robert Johanson, 1987'
  194.     POSXY    11,11
  195.     DEFM    'Originally written by Hardin Brothers (80 Micro 2/84:108)'
  196.     POSXY    59,13
  197.     DEFM    '<RETURN> to play'
  198.     POSXY    59,14
  199.     DEFM    '<ARROWS> for volume'
  200.     POSXY    59,15
  201.     DEFM    ' or <^C> to quit'
  202.     POSXY    25,13
  203.     DEFM    '==>> Previous High Scores <<=='
  204.     POSXY    25,14
  205.     DEFM    'Level     Score        Name   '
  206.     POSXY    25,15
  207.     DEFM    '=============================='
  208.     DEFB    0
  209.     .LIST
  210. HSCR:    LD    B,0        ; PRINT HIGH SCORE TABLE
  211.     LD    HL,0F800H+1307    ; START OF HIGH SCORE TABLE ON SCREEN
  212. HSC10:    PUSH    BC
  213.     PUSH    HL
  214.     LD    A,B
  215.     CALL    GD40        ; GET LEVEL OFFSET IN DBUFF
  216.     POP    HL
  217.     POP    BC
  218.     LD    A,B
  219.     ADD    A,31H        ; CONVERT TO ASCII DIFF LEVEL
  220.     LD    (HL),A        ;  (1 - 9)
  221.     PUSH    HL        ; SAVE ADDRESS
  222.     PUSH    BC        ; AND LEVEL #
  223.     LD    DE,08        ; MOVE TO START OF SCORE
  224.     ADD    HL,DE
  225.     PUSH    HL        ; SAVE ADDRESS OF SCREEN (+10 TO NAME)
  226.     PUSH    HL
  227.     POP    IX        ; IX POINTS TO RESULT BUFFER
  228.     LD    IY,PWRTAB    ; IY POWER TABLE
  229.     LD    D,0
  230.     LD    A,(OFFSET)    ; OFFSET FOR CURRENT LEVEL
  231.     LD    E,A
  232.     LD    HL,DBUFF
  233.     ADD    HL,DE        ; HL POINTS TO SCORE POSITION IN FILE BUFFER
  234.     PUSH    HL         ; SAVE ADDRESS (+2 TO NAME)
  235.     LD    E,(HL)
  236.     INC    HL
  237.     LD    D,(HL)
  238.     EX    DE,HL
  239.     CALL    XLA10        ; TRANSLATE SCORE TO ASCII
  240.     POP    BC
  241.     INC    BC
  242.     INC    BC
  243.     LD    HL,10
  244.     POP    DE
  245.     ADD    HL,DE
  246.     EX    DE,HL
  247.     PUSH    BC
  248.     POP    HL
  249.     LD    BC,26
  250.     LDIR
  251.     POP    BC        ; LEVEL # IN B:
  252.     POP    HL        ; READY FOR NEXT ADDRESS
  253.     INC    B        ; NEXT LEVEL
  254.     LD    A,9
  255.     CP    B
  256.     RET    Z        ; IF B=9 THEN FINISHED
  257.     LD    DE,80        ; OTHERWISE POINT TO NEXT
  258.     ADD    HL,DE
  259.     JR    HSC10        ; AND GO AGAIN
  260.  
  261.  
  262. HSCORE:    LD    DE,DBUFF    ; CHECK SCORE AGAINST HIGH SCORE
  263.     LD    H,0
  264.     LD    A,(OFFSET)    ; FOR THAT LEVEL
  265.     LD    L,A
  266.     ADD    HL,DE        ; ADDRESS OF HIGH SCORE
  267.     PUSH    HL
  268.     LD    E,(HL)        ; DE = HIGH SCORE
  269.     INC    HL
  270.     LD    D,(HL)
  271.     EX    DE,HL        ; NOW HL
  272.     LD    BC,(SCRBUF)    ; SCORE IN BC
  273.     OR    A        ; CLEAR CARRY
  274.     SBC    HL,BC        ; COMPARE NEW WITH OLD
  275.     POP    HL        ; ADDRESS OF HIGH SCORE
  276.     RET    NC        ; NOT HIGHER - RETURN
  277.     LD    (HL),C        ; SAVE NEW SCORE IN DBUFF
  278.     INC    HL
  279.     LD    (HL),B
  280.     INC    HL        ; HL->ADDRESS OF NAME IN DBUFF
  281.     PUSH    HL        ; SAVE ON STACK
  282.     LD    A,0FFH        ; SET HSCORE CHANGED FLAG
  283.     LD    (SCRFLAG),A
  284.     CALL    CLS        ; CLEAR SCREEN
  285.     CALL    SPMSG        ; PRINT MESSAGE
  286.     .XLIST
  287.     POSXY    6,5
  288.     DEFM    'Congratulations.... You have just become a World'
  289.     DEFM    ' Champion CRAMMER !!!'
  290.     POSXY    16,7
  291.     DEFM    'Enter your name for the Official Hall of Fame :'
  292.     POSXY    27,9
  293.     DEFM    '=========================='
  294.     POSXY    22,10
  295.     DEFM    '(max 26 characters, CP/M 3 editing)',0DH,0AH
  296.     POSXY    25,8
  297.     DEFM    '->',0
  298.     .LIST
  299.     LD    C,60H        ; TURN ON CURSOR FOR INPUT
  300.     CALL    CURSOR
  301.     LD    DE,CONBUFF    ; GET NAME USING
  302.     LD    C,0AH        ; READ CONSOLE BUFFER FUNCTION
  303.     CALL    BDOS
  304.     LD    C,20H        ; TURN CURSOR OFF AGAIN
  305.     CALL    CURSOR
  306.     POP    DE        ; ADDRESS IN DBUFF FOR NAME
  307.     LD    HL,CONBUFF+2    ; CONBUFF INPUT
  308.     LD    B,0
  309.     LD    A,(CONBUFF+1)    ; GET # CHARACTERS INPUT
  310.     LD    C,A        ; INTO BC
  311.     OR    A        ; ? 0 CHARACTERS (LDIR DOESN'T LIKE
  312.     JR    Z,HS05        ; BC OF 0). JUST PAD WITH SPACES
  313.     PUSH    BC        ; SAVE FOR RON
  314.     LDIR            ; MOVE TO DBUFF POSITION
  315.      POP    BC
  316. HS05:    LD    A,26        ; MAX NUMBER IN NAME
  317.     SUB    C        ; GET NUMBER TO FILL
  318.     RET    Z        ; C=26, NO NEED TO FILL
  319.     LD    B,A
  320.     LD    A,32
  321. HS10:    LD    (DE),A        ; FILL WITH SPACES
  322.     INC    DE
  323.     DJNZ    HS10        ; GO UNTIL B=0
  324.     RET            ; THEN RETURN
  325.  
  326. CLKEY:    CALL    GETKEY
  327.     JR    NZ,CLKEY
  328. CLK01:    LD    C,11        ; CLEAR ANY LEFT OVER ARROW KEYS
  329.     CALL    BDOS
  330.     OR    A
  331.     RET    Z        ; NO MORE KEYS - RETURN
  332.     LD    C,01        ; KEY STILL THERE - GET IT
  333.     CALL    BDOS
  334.     JR    CLK01        ; CHECK FOR ANY MORE
  335.  
  336. FLASH:    LD    BC,2000        ; # CHARS ON SCREEN
  337.     LD    HL,VIDEO    ; HL = BEGINNING OF SCREEN
  338. FL10:    LD    A,(HL)        ; GET CHAR FROM SCREEN
  339.     BIT    7,A        ; IS IT HIGH OR LOW
  340.     JR    Z,FL20        ; LOW ==> HIGH
  341.     RES    7,A        ; HIGH ==> LOW
  342.     JR    FL30
  343. FL20:    SET    7,A
  344. FL30:    LD    (HL),A
  345.     INC    HL        ; STORE INVERTED CHAR
  346.     DEC    BC        ; TEST FOR END OF SCREEN
  347.     LD    A,B
  348.     OR    C
  349.     RET    Z
  350.     JR    FL10
  351.  
  352. TONE:    LD    IX,(TONPTR)    ; IX==>NEXT TONE VALUE
  353.     LD    A,(IX)        ; GET VALUE
  354.     OR    A        ; SET FLAGS
  355.     JR    NZ,TONE10    ; GO IF NOT ZERO
  356.     LD    IX,TONTOP    ; ELSE = TOP OF LIST
  357. TONE10:    CALL    MAKTON        ; MAKE THE TONE
  358.     INC    IX        ; BUMP POINTER
  359.     INC    IX        ; TWICE
  360.     LD    (TONPTR),IX    ; AND SAVE IT
  361.     RET            ; RET TO CALLER
  362.  
  363. MAKTON:    DI            ; TURN OFF INTERRUPTS
  364.     LD    C,(IX)        ; DURATION IN C
  365. MAK10:    LD    B,(IX+1)    ; GET FREQ VALUE
  366.     LD    A,(VOL)        ; VARIABLE VOLUME
  367.     OUT    (50H),A        ; AUDIO REGISTER
  368. MAK20:    DJNZ    MAK20        ; DELAY FOR 1/2 CYCLE
  369.     LD    B,(IX+1)    ; FREQ. VALUE AGAIN
  370.     XOR    A
  371.     OUT    (50H),A
  372. MAK30:    DJNZ    MAK30
  373.     DEC    C        ; DROP DURATION
  374.     JR    NZ,MAK10    ; LOOP UNTIL C=0
  375.     EI            ; INTERRUPTS BACK ON
  376.     RET            ; AND RETURN
  377.  
  378. NOISE:    LD    B,10        ; NO TO REPEAT
  379.     LD    IX,NOTE        ; POINT TO DATA AREA
  380.     LD    (IX),10        ; DURATION OF RANDOM NOTE
  381. NOIS10:    PUSH    BC        ; SAVE ON STACK
  382.     LD    A,R        ; GET RANDOM NUMBER (0-127)
  383.     LD    (IX+1),A    ; FREQ OF RANDOM NOTE
  384.     CALL    MAKTON
  385.     POP    BC        ; GO 10 TIMES
  386.     DJNZ    NOIS10
  387.     RET
  388.  
  389. ; GETENT CHECKS FOR <RETURN> - RETURNS NZ IF <RETURN> IS PRESSED
  390. ; OTHERWISE, Z.
  391. ; VS 3.0 ^C WILL ABORT AND RETURN TO CP/M
  392. ; VS 3.5 CHECKS FOR DIFF LEVELS AND BY-PASSES CALL GETDIF
  393. ;         (IE WILL SAVE A KEY-STROKE FOR EXPERIENCED PLAYERS)
  394. ; VS 3.6 CHECKS FOR UP OR DOWN ARROWS TO VARY SOUND VOLUME
  395.  
  396. GETENT:    CALL    GETKEY        ; DIRECT CONSOLE I/O
  397.     RET    Z
  398.     CP    0DH        ; ?<RETURN> (CR)
  399.     JR    NZ,GET10
  400.     OR    A        ; SET NZ FOR CR
  401.     RET
  402. GET10:    CP    03H        ; ?^C FOR FINISH
  403.     JP    Z,DONE        ; BACK TO CP/M
  404.     CP    '1'        ; IS IT A KEY 1 - 9
  405.     JR    C,GET20
  406.     CP    '9'+1
  407.     JR    NC,GET20
  408.     POP    HL        ; WASTE RETURN ADDRESS SO
  409.     JP    GD15        ; NEXT RET WILL BE TO MAIN
  410.                 ; PROGRAM LOOP
  411. GET20:    CP    05H        ; ? UP ARROW
  412.     JR    Z,GET30
  413.     CP    18H        ; ? DOWN ARROW
  414.     JR    Z,GET40
  415. GET25:    XOR    A        ; NOT A VALID KEY - SET Z
  416.     RET            ; AND RETURN
  417. GET30:    LD    A,(VOL)        ; INCREASE VOLUME
  418.     CP    0FFH        ; ?ALREADY MAX VOLUME
  419.     RET    Z        ; YES - RETURN
  420.     INC    A        ; NO - INCREASE IT
  421.     JR    GET50
  422. GET40:    LD    A,(VOL)        ; DECREASE VOLUME
  423.     OR    A        ; CHECK FOR ZERO
  424.     RET    Z        ; YES - RETURN
  425.     DEC    A        ; NO - DECREASE IT
  426. GET50:    LD    (VOL),A
  427.     LD    A,0FFH        ; SET CHANGE FLAG
  428.     LD    (SCRFLAG),A
  429.     XOR    A        ; AND RETURN WITH Z
  430.     RET
  431.  
  432. GETDIF:    CALL    CLS
  433.     CALL    SPMSG
  434.     .XLIST
  435.     DEFM    'Select Difficulty Level'
  436.     DEFW    0D0AH
  437.     DEFW    0A0AH
  438.     DEFM    ' 1  (Very Easy)  to  9  (Very Difficult)'
  439.     DEFM    ' .....    '
  440.     DEFB    0
  441.     .LIST
  442. GD10:    LD    C,DCON        ; GET KEY INPUT
  443.     LD    E,0FDH        ; RETURN WHEN KEY IS PRESSED
  444.     CALL    BDOS        ; WITH VALUE IN A
  445.     CP    '1'
  446.     JR    C,GD10
  447.     CP    '9'+1
  448.     JR    NC,GD10
  449. GD15:    SUB    31H        ; PUT IN 0 - 8 RANGE    
  450.     LD    (DIFBUF),A    ; STORE DIFFICULTY
  451.     PUSH    AF        ; AND PUT ON STACK
  452.     LD    B,3
  453.     LD    C,0
  454. GD20:    SUB    B        ; FIND MODE AND SPEED
  455.     JR    C,GD30
  456.     INC    C        ; COUNT DIVISION
  457.     JR    GD20
  458. GD30:    ADD    A,B        ; GET REMAINDER
  459.     LD    (MODBUF),A    ; STORE MODE (0,1,2)
  460.     LD    HL,DTABLE    ; ADDRESS OF DELAY TABLE
  461.     LD    D,0        ; C IS SPEED (0,1,2)
  462.     LD    E,C        ; DE IS TABLE OFFSET
  463.     ADD    HL,DE
  464.     LD    A,(HL)        ; A HAS DELAY VALUE
  465.     LD    (SPDBUF),A    ; STORE IN SPDBUF
  466.     LD    HL,BLKTAB    ; ADDRESS OF BLOCK TABLE
  467.     ADD    HL,DE        ; DE IS TABLE OFFSET
  468.     LD    A,(HL)        ; A HAS # BLOCKS * 6
  469.     LD    (BLKBUF),A    ; STORE IN BLKBUF
  470.     POP    AF        ; A IS DIFF 0-8
  471. GD40:    LD    D,0        ; JOIN HERE FOR PTITLE CODE
  472.     LD    E,A
  473.     LD    HL,OSTAB    ; ADDRESS OF OFFSET TABLE
  474.     ADD    HL,DE
  475.     LD    A,(HL)        ; A HAS CURRENT OFFSET
  476.     LD    (OFFSET),A    ; PUT IN OFFSET BUFFER
  477.     RET
  478.  
  479.  
  480. FRAME:    LD    HL,VIDEO-1    ; HL->SCREEN TOP-1
  481.     LD    B,81        ; TOP POSITIONS +1
  482.     LD    A,80H        ; FULL GRAPHICS CHARACTER
  483. FR10:    INC    HL        ; POINT TO NEXT POSITION
  484.     LD    (HL),A        ; SET GRAPHICS BLOCK
  485.     DJNZ    FR10        ; REPEAT FOR TOP LINE + 1
  486.     LD    B,23        ; B=# OF LINES
  487.     LD    DE,79        ; OFFSET FOR EACH LINE
  488. FR20:    ADD    HL,DE        ; SKIP MIDDLE OF SCREEN
  489.     LD    (HL),A        ; SET BLOCK
  490.     INC    HL
  491.     LD    (HL),A
  492.     DJNZ    FR20
  493.     LD    B,79        ; SPACES ON BOTTOM LINE - 1
  494. FR30:    INC    HL
  495.     LD    (HL),A
  496.     DJNZ    FR30        ; REPEAT FOR BOTTOM
  497.     RET            ; AND RETURN
  498.  
  499. SETCRS:    LD    HL,6000        ; HL->MIDDLE OF SCREEN
  500.     LD    (CRSPOS),HL    ; SET CURSOR POSITION
  501.     XOR    A
  502.     LD    (SCRBUF),A    ; ZERO CURRENT SCORE
  503.     LD    (SCRBUF+1),A
  504.     LD    A,13H        ; SET STARTING DIRECTION
  505.     LD    (SAVARR),A
  506.     LD    HL,TONTOP    ; SET TO TOP OF TONE TABLE
  507.     LD    (TONPTR),HL
  508.     RET            ; AND RETURN
  509.  
  510.  
  511. GAMMSG:    CALL    SPMSG
  512.     .XLIST
  513.     POSXY    28,24        ; PRINT GAME MESSAGE
  514.     DEFM    ' USE ARROW KEYS TO MOVE '
  515.     DEFB    00H
  516.     .LIST
  517.     RET            ; AND RETURN
  518.  
  519. GETKEY:    LD    C,DCON        ; STOBE KEYBOARD - RETURNS
  520.     LD    E,0FFH        ; VALUE OF KEY, OR Z IF NO
  521.     CALL    BDOS        ; KEY PRESSED
  522.     OR    A        ; SET FLAGS
  523.     RET
  524.  
  525. GETARR:    CALL    GETKEY        ; ? ARROWS PRESSED
  526.     RET    Z        ; NO - RETURN
  527.     CP    05H
  528.     JR    Z,GARR10
  529.     CP    18H
  530.     JR    Z,GARR10
  531.     CP    13H
  532.     JR    Z,GARR10
  533.     CP    04H
  534.     JR    Z,GARR10
  535.     XOR    A
  536.     RET
  537. GARR10:    LD    (SAVARR),A    ; SAVE ARROW KEY
  538.     OR    A        ; RESET Z
  539.     RET
  540.  
  541. GARR20:    CALL    GETKEY        ; THIS IS SIMILAR TO
  542.     RET    Z        ; GETARR, HOWEVER
  543.     CP    05H        ; RETURNS Z IF NO KEY
  544.     JR    Z,GARR10    ; PRESSED, NZ IF ANY KEY
  545.     CP    18H        ; PRESSED, AND UPDATES
  546.     JR    Z,GARR10    ; SAVARR IF THE KEY
  547.     CP    13H        ; HAPPENED TO BE AN
  548.     JR    Z,GARR10    ; ARROW
  549.     CP    04H
  550.     JR    Z,GARR10
  551.     RET
  552.  
  553. FPOSN:    LD    HL,(CRSPOS)    ; CURRENT SCREEN POSITION
  554.     LD    DE,160        ; OFFSET BETWEEN LINES
  555.     LD    A,(SAVARR)    ; GET ARROW DIRECTION
  556.     CP    05H        ; CHECK FOR UP ARROW
  557.     JR    NZ,FPO10    ; GO IF NOT
  558.     SBC    HL,DE        ; ELSE MOVE UP ONE LINE
  559. FPO10:    CP    18H        ; CHECK FOR DOWN ARROW
  560.     JR    NZ,FPO20    ; GO IF NOT
  561.     ADD    HL,DE        ; MOVE DOWN A LINE
  562. FPO20:    CP    13H        ; CHECK FOR LEFT ARROW
  563.     JR    NZ,FPO30    ; GO IF NOT
  564.     DEC    HL        ; MOVE LEFT ONE SPACE
  565. FPO30:    CP    04H        ; CHECK FOR RIGHT ARROW
  566.     JR    NZ,FPO40    ; GO IF NOT
  567.     INC    HL        ; MOVE RIGHT ONE SPACE
  568. FPO40:    LD    (CRSPOS),HL    ; SAVE NEW POSITION
  569.     RET            ; AND RETURN
  570.  
  571. SCORE:    LD    HL,(SCRBUF)    ; GET CURRENT SCORE
  572.     INC    HL        ; ADD ONE
  573.     LD    (SCRBUF),HL    ; PUT IT BACK
  574.     RET            ; AND RETURN
  575.  
  576. SHWSCR:    CALL    XLATE        ; TRANSLATE BIN -> ASCII
  577.     CALL    SPMSG
  578.     POSXY    36,0
  579.     DEFB    ' '
  580. ASCORE:    DEFB    '00000 ',0
  581.     RET
  582.  
  583. XLATE:    LD    HL,(SCRBUF)    ; GET BIN SCORE FROM BUFF
  584.     LD    IY,PWRTAB    ; IY->POWERS OF TEN
  585.     LD    IX,ASCORE    ; IX->ASCII SCORE BUFFER
  586. XLA10:    LD    E,(IY+0)    ; GET LSB OF POWER
  587.     LD    D,(IY+1)    ; GET MSB OF POWER
  588.     XOR    A
  589. XLA20:    OR    A        ; RESET CARRY
  590.     SBC    HL,DE        ; SUBTRACT CURRENT POWER
  591.     JR    C,XLA30        ; GO IF CARRY
  592.     INC    A        ; ELSE INCREMENT COUNTER
  593.     JR    XLA20        ; AND DO AGAIN
  594. XLA30:    ADD    HL,DE        ; HL=VALUE BEFORE CARRY
  595.     ADD    A,30H        ; CHANGE TO ASCII
  596.     LD    (IX),A        ; SAVE ASCII VALUE
  597.     LD    A,E        ; GET LSB OF POWER
  598.     CP    1        ; IS IT 1?
  599.     RET    Z        ; IF SO, RETURN
  600.     INC    IX        ; ELSE IX->NEXT CHAR
  601.     INC    IY        ; IY->NEXT POWER
  602.     INC    IY
  603.     JR    XLA10        ; AND GO AGAIN
  604.  
  605. BLOCK:    LD    A,(BLKBUF)    ; # OF BLOCKS TO SET IN A
  606.     LD    B,A        ; THEN INTO B
  607. BL20:    PUSH    BC
  608.     CALL    RAND        ; GET RANDOM NUMBER
  609.     CALL    SCALE        ; CHECK IF IN RANGE
  610.     JR    Z,BL30        ; JUMP IF OUT OF RANGE
  611.     LD    BC,(CRSPOS)    ; SAVE GAME CRSPOS
  612.     PUSH    BC
  613.     LD    (CRSPOS),HL    ; SAVE IN CRSPOS
  614.     CALL    SET        ; AND TURN ON PIXEL
  615.     POP    BC        ; GET GAME CRSPOS
  616.     LD    (CRSPOS),BC    ; AND PUT IT BACK
  617. BL30:    POP    BC
  618.     DJNZ    BL20        ; DO UNTIL B=0
  619.     RET
  620.  
  621. BL40:    LD    B,1        ; SET ONE BLOCK (MODE 2)
  622.     JR    BL20        ; JOIN MODE 1 BLOCK ROUTINE
  623.  
  624. PAUSE:    LD    A,(SPDBUF)    ; GET DIFFICULTY VALUE
  625.     LD    B,A        ; INTO B
  626. PAUS10:    PUSH    BC        ; SAVE VALUE
  627.     LD    BC,050H        ; DELAY VALUE
  628.     CALL    DELAY        ; WAIT A BIT
  629.     CALL    GETARR        ; GET ARROW KEYS
  630.     POP    BC        ; RECOVER VALUE
  631.     DJNZ    PAUS10        ; REPEAT UNTIL ZERO
  632.     RET            ; THEN RETURN
  633.  
  634. CURSOR:    LD    A,0AH        ; CONTROL BONDWELL CURSOR
  635.     OUT    (10H),A        ; THROUGH 6845 REGISTERS
  636.     LD    A,C        ; C=20H FOR NO CURSOR
  637.     OUT    (11H),A        ; C=60H FOR SLOW BLINK
  638.     RET
  639.  
  640. ; ***** 16-BIT PSEUDO-RANDOM NUMBER GENERATOR ******************
  641. ;       FROM APC SUBSET FEB 83:50
  642.  
  643. RAND:    LD    HL,(SEED)    ; GET SEED (OR LAST NUMBER)
  644.     LD    D,H
  645.     LD    E,L        ; DE<-HL
  646.     ADD    HL,HL
  647.     ADD    HL,HL
  648.     ADD    HL,HL
  649.     ADD    HL,HL        ; HL<-HL*16
  650.     PUSH    HL
  651.     ADD    HL,HL        ; HL<-HL*32
  652.     EX    (SP),HL
  653.     OR    A        ; CLEAR CARRY
  654.     SBC    HL,DE        ; HL<-HL*15
  655.     POP    BC        ; BC<-HL*32
  656.     ADD    HL,BC        ; HL<-HL*(32+15)
  657.     ADD    HL,HL
  658.     ADD    HL,HL
  659.     ADD    HL,HL        ; HL<-HL*376
  660.     ADD    HL,DE        ; HL<-HL*377
  661.     ADD    HL,HL
  662.     ADD    HL,HL        ; HL<-HL*1508
  663.     ADD    HL,DE        ; HL<-HL*1509
  664.     LD    DE,41
  665.     ADD    HL,DE        ; HL<-HL*1509+41
  666.     LD    (SEED),HL
  667.     RET
  668.  
  669. SCALE:    PUSH    HL        ; RANDOM # IN HL
  670.     LD    DE,480        ; ?LOWER THAN 480
  671.     XOR    A        ; CLEAR CARRY (A<-0)
  672.     SBC    HL,DE        
  673.     POP    HL
  674.     JR    C,SCAL50    ; LOWER
  675.     PUSH    HL
  676.     LD    DE,11520    ; ?HIGHER THAN 11519
  677.     XOR    A
  678.     SBC    HL,DE
  679.     POP    HL
  680.     JR    NC,SCAL50    ; HIGHER
  681.     INC    A        ; NZ IF WITHIN RANGE
  682.     RET
  683. SCAL50:    XOR    A        ; Z IF OUT OF RANGE
  684.     RET
  685.  
  686. ; ***** SUBROUTINES THAT ALLOW PIXEL LEVEL GRAPHICS ***********
  687. ;
  688. ;    BY: ROBERT JOHANSON    20/04/87
  689. ;
  690. ;
  691. ; CALL MEMPOS WITH PIXEL NUMBER STORED IN (CRSPOS), OR
  692. ; CALL MEMPOS+3 WITH NUMBER IN HL
  693. ; ADDRESS IN WHICH PIXEL IS HELD IS RETURNED IN
  694. ; HL, AND IS ALSO STORED IN (SCRADD)
  695.  
  696. MEMPOS:    LD    HL,(CRSPOS)    ; PIXEL NUMBER IN HL
  697.     PUSH    HL        ; SAVE FOR LATER
  698.     LD    BC,0000H    ; (0<=PIXEL<=11,999)
  699.     LD    DE,480        ; # PIXELS PER LINE
  700. MEM10:    AND    A        ; CLEAR CARRY
  701.     SBC    HL,DE        ; 80*INT(N/480)
  702.     JR    C,MEM20        ; EXIT WITH RESULT IN BC
  703.     PUSH    HL        ; OR ADD 80 TO BC
  704.     LD    HL,80
  705.     ADD    HL,BC
  706.     PUSH    HL
  707.     POP    BC
  708.     POP    HL
  709.     JR    MEM10
  710. MEM20:    POP    HL        ; GET ORIGINAL # IN HL
  711.     LD    DE,160        ; # PIXELS PER ROW
  712.     AND    A        ; CLEAR CARRY
  713. MEM30:    SBC    HL,DE        ; INT((N MOD 160)/2)
  714.     JR    NC,MEM30    ; SUB UNTIL RESULT IS NEGATIVE
  715.     ADD    HL,DE        ; N MOD 160 IN HL
  716.     AND    A        ; CLEAR CARRY
  717.     RR    L        ; L/2
  718.     LD    H,0F8H        ; GENERATE SCREEN ADDRESS
  719.     ADD    HL,BC
  720.     LD    (SCRADD),HL    ; AND STORE RESULT
  721.     RET            ; FINALLY RETURN
  722.     
  723.  
  724. ; CALL MASK WITH PIXEL # IN (CRSPOS), OR CALL MASK+3 WITH VALUE
  725. ; IN HL. RETURNS MASK IN A. USES ALL REGISTERS.
  726.  
  727. MASK:    LD    HL,(CRSPOS)    ; GET PIXEL # IN HL
  728.     PUSH    HL        ; SAVE FOR LATER
  729.     LD    DE,480        ; # PIXELS PER LINE
  730.     AND    A        ; CLEAR CARRY
  731. MASK10:    SBC    HL,DE
  732.     JR    NC,MASK10    ; SUB UNTIL RESULT IS NEGATIVE
  733.     ADD    HL,DE        ; HL=N MOD 480
  734.     LD    BC,0000H
  735.     LD    DE,160        ; # PIXELS PER ROW
  736.     AND    A
  737. MASK20:    SBC    HL,DE
  738.     JR    C,MASK30    ; EXIT WITH INT(HL/160) IN BC
  739.     INC    BC
  740.     JR    MASK20        ; SUB UNTIL RESULT IS NEGATIVE
  741. MASK30:    RLC    C        ; C*2 =0, 2, OR 4
  742.     LD    A,01
  743.     ADD    A,C
  744.     POP    HL        ; ? PIXEL # ODD OR EVEN
  745.     BIT    0,L        ; TEST BIT 0
  746.     JR    NZ,MASK40    ; RIGHT COLUMN OF CHARACTER
  747.     INC    A        ; LEFT COLUMN OF CHARACTER
  748. MASK40:    LD    B,A        ; B=BIT POSITION + 1
  749.     LD    A,10000000B    ; BIT POSITION 0 WILL GIVE 00000001
  750. MASK50:    RLCA            ; BIT POSITION 5 WILL GIVE 00010000
  751.     DJNZ    MASK50
  752.     RET            ; AND RETURN
  753.  
  754. ; CALL RANGE WITH NUMBER TO BE CHECKED IN A. WILL RETURN
  755. ; Z IF A CONTAINS A VALID GRAPHIC CHARACTER, NZ IF IT ISN'T.
  756. ; ALSO WILL RETURN C IF THE VALID CHARACTER IS >7F (IE REQUIRES
  757. ; XOR 0BFH TO BE USED), NC IF CHARACTER IS <20.
  758.  
  759. RANGE:    PUSH    AF        ; SAVE FOR LATER
  760.     CP    20H        ; ?<=1FH
  761.     JR    C,RANG10    ; YES - Z & NC
  762.     CP    80H        ; ?<=7FH
  763.     JR    C,RANG20    ; YES - NZ
  764.     CP    0A0H        ; ?<=9FH
  765.     JR    C,RANG30    ; YES - Z & C
  766. RANG20:    POP    AF        ; (A >9FH) OR (1FH<A<80H) - NZ
  767.     OR    A        ; SET NZ
  768.     RET            ; AND RETURN
  769. RANG10:    XOR    A        ; (A<20H) - Z & NC
  770.     POP    BC        ; GET A OFF STACK
  771.     LD    A,B        ; WITHOUT CHANGING FLAGS
  772.     RET            ; AND RETURN
  773. RANG30:    XOR    A        ; (7FH<A<A0H) - Z
  774.     CCF            ; & C
  775.     POP    BC        ; GET A OFF STACK
  776.     LD    A,B        ; WITHOUT CHANGING FLAGS
  777.     RET            ; AND RETURN
  778.  
  779. ; CALL SET WITH PIXEL NUMBER TO BE TURNED ON IN (CRSPOS)
  780.  
  781. SET:    CALL    MEMPOS        ; GET SCREEN ADDRESS OF PIXEL
  782.     LD    A,(HL)        ; GET THE CURRENT CHARACTER THERE
  783.     CALL    RANGE        ; IS IT GRAPHIC
  784.     JR    Z,SET10        ; YES
  785.     LD    A,00H        ; NO - MAKE IT A GRAPHIC SPACE
  786.     AND    A        ; CLEAR CARRY
  787. SET10:    JR    NC,SET20    ; IS IT >7FH
  788.     XOR    0BFH        ; YES - ADJUST IT
  789. SET20:    PUSH    AF        ; SAVE CHARACTER ON STACK
  790.     CALL    MASK        ; GET BIT MASK
  791.     POP    BC        ; CHARACTER IN B
  792.     OR    B        ; MASK OR CHARACTER = NEW CHARACTER
  793. RSET:    CP    20H        ; ?>1FH - COMMON CODE WITH RESET
  794.     JR    C,RSET10    ; NO - NO NEED TO ADJUST
  795.     XOR    0BFH        ; ADJUST FOR >1FH
  796. RSET10:    LD    HL,(SCRADD)    ; GET CURRENT SCREEN ADDRESS
  797.     LD    (HL),A        ; AND PUT NEW CHARACTER THERE
  798.     RET            ; AND RETURN
  799.  
  800. ; CALL POINT WITH PIXEL NUMBER TO BE TESTED IN (CRSPOS)
  801.  
  802. POINT:    CALL    MEMPOS        ; GET SCREEN ADDRESS OF PIXEL
  803.     LD    A,(HL)        ; GET THE CURRENT CHARACTER INTO A
  804.     CALL    RANGE        ; IS IT GRAPHIC
  805.     JR    Z,POINT10    ; YES
  806.     RET            ; NON GRAPHIC - SAME AS PIXEL SET
  807.                 ; FOR THIS GAME
  808. POINT10:
  809.     JR    NC,POINT20    ; GRAPHIC, NO NEED TO ADJUST
  810.     XOR    0BFH        ; GRAPHIC ADJUST
  811. POINT20:
  812.     PUSH    AF        ; SAVE CHARACTER ON STACK
  813.     CALL    MASK        ; GET BIT MASK
  814.     POP    BC        ; CHARACTER IN B
  815.     AND    B        ; CHARACTER AND MASK
  816.     RET            ; Z & NC = PIXEL NOT SET
  817.                 ; NZ = PIXEL SET
  818.  
  819. ; ***** END OF PROGRAM EXECUTION *******************************
  820.  
  821.  
  822. DONE:    CALL    CLS        ; CLEAR SCREEN
  823.     LD    A,(SCRFLAG)    ; SEE IF HIGH SCORES HAVE TO BE RESAVED
  824.     OR    A        ; Z IF OK, NZ IF NEED TO SAVE
  825.     JR    Z,DO10
  826.  
  827. ; WRITE THE ALTERED RECORDS BACK OUT TO THE DISK
  828.  
  829.     LD    C,SETDMA    ; SET DMA TO DBUFF
  830.     LD    DE,DBUFF
  831.     CALL    BDOS
  832.     LD    C,SETMSC    ; SET MULTI-SECTOR COUNT
  833.     LD    E,2        ; FOR 2 SECTORS
  834.     CALL    BDOS
  835.     LD    HL,FCB        ; HL=ADDRESS OF SOURCE
  836.     LD    DE,TFCB        ; DE=ADDRESS OF DEST.
  837.     PUSH    DE        ; SAVE FOR RON.
  838.     LD    BC,13        ; BC=# BYTES TO MOVE
  839.     LDIR            ; MOVE IT
  840.     LD    A,(50H)        ; CONTAINS DRIVE CODE FROM
  841.                 ; WHICH PROGRAM WAS LOADED
  842.     LD    (TFCB),A    ; PUT IN TFCB
  843.     POP    DE        ; OPEN THE FILE
  844.     LD    C,OPENF
  845.     CALL    BDOS        ; A=FFH IF ERROR
  846.     INC    A        ; NOW A = 00 IF ERROR
  847.     JR    Z,ERROR        ; IF SO, HALT PROGRAM.
  848.     LD    HL,FCBCR    ; SET RECORD # TO ZERO
  849.     LD    (HL),0
  850.     LD    DE,TFCB        ; WRITE OUT THE 2 RECORDS
  851.     LD    C,WRITF
  852.     CALL    BDOS        ; A=0 IF SUCCESSFUL
  853.     OR    A
  854.     JR    NZ,ERROR    ; OTHERWISE HALT PROG
  855.     LD    DE,TFCB        ; CLOSE THE FILE
  856.     LD    C,CLOSF
  857.     CALL    BDOS
  858.     OR    A        ; A=0 IF SUCCESSFUL
  859.     JR    NZ,ERROR
  860. DO10:    LD    C,60H        ; TURN CURSOR BACK ON
  861.     CALL    CURSOR
  862.     LD    SP,(CPMSP)    ; RESTORE CP/M STACK
  863.     RET            ; RETURN TO CP/M
  864.  
  865. ERROR:    CALL    SPMSG        ; DISK ERROR HAS OCCURED
  866.     .XLIST
  867.     DEFB    0DH,0AH,0AH
  868.     DEFB    'CRAM has tried to save the new High Scores '
  869.     DEFB    'but has been unsuccessful.',0DH,0AH,0AH
  870.     DEFB    'This could be due to a real disk I/O error, '
  871.     DEFB    'but will also occur if you ',0DH,0AH
  872.     DEFB    'have RENamed this program. It must be called '
  873.     DEFB    'CRAM.COM for successful ',0DH,0AH,'operation.'
  874.     DEFB    0DH,0AH,0AH,0
  875.     .LIST
  876.     JP    DO10        ; BACK TO CP/M
  877.  
  878. ; ***** DATA BUFFERS *******************************************
  879.  
  880. FCB:    DEFB    0,'CRAM    COM',0
  881. SCRADD:    DEFW    0F800H        ; ADDRESS OF PIXEL
  882. DIFBUF:    DEFS    1        ; CURRENT DIFICULTY 0 - 8
  883. MODBUF:    DEFS    1        ; GAME MODE 0,1,2
  884. SPDBUF: DEFS    1        ; SPEED (DELAY COUNT)
  885. DTABLE:    DEFB    40,25,10    ; DELAY TABLE
  886. BLKBUF:    DEFS    1        ; # BLOCKS FOR MODE 2
  887. BLKTAB:    DEFB    90,180,240    ; BLOCK TABLE
  888. CRSPOS:    DEFS    2        ; CURRENT PIXEL #
  889. SCRBUF:    DEFW    0000H        ; CURRENT SCORE
  890. SAVARR:    DEFB    13H        ; CURRENT DIRECTION
  891. TONPTR:    DEFW    TONTOP        ; CURRENT NOTE TO PLAY
  892. PWRTAB:    DEFW    10000
  893.     DEFW    1000
  894.     DEFW    100
  895.     DEFW    10
  896.     DEFW    1
  897. SEED:    DEFS    2        ; RANDOM NUMBER SEED
  898. NOTE:    DEFW    0000H        ; RANDOM NOTE DURATION 
  899.                 ; AND FREQUENCY
  900. SCRFLAG:
  901.     DEFB    00H        ; FLAG FOR HIGH SCORE CHANGE
  902. OFFSET:    DEFB    00H        ; OFFSET IN DBUFF FOR CURRENT 
  903.                 ; DIFFICULTY LEVEL
  904. OSTAB:    DEFB    0*28+3        ; OFFSETS FOR 0-8 LEVELS
  905.     DEFB    1*28+3
  906.     DEFB    2*28+3
  907.     DEFB    3*28+3
  908.     DEFB    4*28+3
  909.     DEFB    5*28+3
  910.     DEFB    6*28+3
  911.     DEFB    7*28+3
  912.     DEFB    8*28+3 
  913. CONBUFF:            ; CONSOLE BUFFER FOR NAME
  914.     DEFB    26,0,0,0,0,0,0,0,0,0,0,0,0
  915.     DEFB    0,0,0,0,0,0,0,0,0,0
  916.     DEFB    0,0,0,0,0,0
  917.  
  918. ; **** TONE LIST ****
  919. TONTOP:    DEFB    150        ; DURATION OF FIRST NOTE
  920.     DEFB    214        ; FREQ.
  921.     DEFB    200
  922.     DEFB    161
  923.     DEFB    169
  924.     DEFB    191
  925.     DEFB    126
  926.     DEFB    255
  927.     DEFW    0000H        ; MARK END OF LIST
  928.  
  929. CPMSP:    DEFW    0        ; CP/M STACK POINTER
  930. STAK    EQU    CPMSP+130    ; PLENTY OF STACK ROOM
  931.     END    BEGIN
  932.