home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / mbug / mbug056.arc / MENU.ASM < prev    next >
Assembly Source File  |  1979-12-31  |  10KB  |  510 lines

  1. ;            MENU PROGRAM
  2. ;               FOR
  3. ;        MACHINE LANGUAGE OR BASIC PROGRAMS
  4. ;
  5. ;               BY
  6. ;            JAMES J. FRANTZ
  7. ;              MAY 31, 1979    
  8. ;
  9. ;Modified by Jim Woolley, FOG Disk Librarian, 11/82
  10. ;
  11. ;Calling syntax:
  12. ;
  13. ;    MENU        menu of .COM files on default drive
  14. ;    MENU d:        menu of .COM files on drive d:
  15. ;
  16. ;    BMENU         menu of .BAS (MBASIC) files on default drive
  17. ;            MBASIC.COM assumed to be on default drive, also
  18. ;    BMENU d:    menu of .BAS (MBASIC) files on drive d:
  19. ;            MBASIC.COM assumed to be on default drive
  20. ;    BMENU d1: d2:    menu of .BAS (MBASIC) files on drive d1:
  21. ;            MBASIC.COM found on drive d2:
  22. ;
  23. ;    CMENU         menu of .INT (CBASIC) files on default drive
  24. ;            CRUN2.COM assumed to be on default drive, also
  25. ;    CMENU d:    menu of .INT (CBASIC) files on drive d:
  26. ;            CRUN2.COM assumed to be on default drive
  27. ;    CMENU d1: d2:    menu of .INT (CBASIC) files on drive d1:
  28. ;            CRUN2.COM found on drive d2:
  29. ;
  30. ;CORRECTIONS BY K. COYE SEPT 11, 1982
  31. ;
  32. ;1. SEARCH.FCB WAS TOO SHORT CAUSING OVERWRITE OF DIR$TABLE
  33. ;2. MENU$BUF WAS 5 CHARS LONG INSTEAD OF THE REQUIRED 6
  34. ;
  35.     ORG    0100H
  36. ;
  37. ;
  38. true        equ    1
  39. false        equ    0
  40. com$prog    equ    true        ;for .COM files
  41. cbas$prog    equ    false        ;for CBASIC files
  42. MBAS$PROG    EQU    false        ;for MBASIC files
  43. ;
  44.     LXI    SP,STACK$AREA        ;SET UP A STACK
  45.     lda    def$fcb
  46.     sta    menu$drive
  47. ;
  48.     if    mbas$prog or cbas$prog
  49.     lda    def$fcb+16
  50.     sta    bas$drive
  51.     endif
  52. ;
  53.     lxi    d,def$fcb+1
  54.     lxi    h,srch$fcb
  55.     mvi    c,srch$fcb$len
  56.     call    block$move
  57.     MVI    C,17            ;'SEARCH FIRST' COMMAND
  58. ;
  59. SORT$LOOP:
  60.     LXI    D,def$fcb        ;POINT FILE CONTROL BLOCK
  61.     CALL    BDOS            ;USE CP/M ENTRY POINT
  62. ;
  63. ;
  64.     ORA    A            ;TEST FOR -1
  65.     JM    ASSIGN$MENU$NBR        ;PRINT EMPTY
  66.     RRC                ;THIS IS THE SAME AS
  67.     RRC                ;5 "ADD A'S"
  68.     RRC
  69.     ANI    60H             ;MASK CORRECT BITS
  70.     ADI    80H            ;ADD BASE ADDRESS(0080H)
  71.     MOV    E,A            ;PUT POINTER IN (DE)
  72.     MVI    D,0            ;AS 16 BIT VALUE
  73.     LXI    H,DIRTABLE        ;POINT START OF TABLE OF
  74.                     ;SORTED NAMES
  75.     INX    D            ;POINT PAST ERASE FIELD
  76. ;
  77. COMPARE$LOOP:
  78. ;
  79.     PUSH    D            ;SAVE POINTER TO NEXT
  80.                     ;ENTRY FROM DISK DIRECTORY
  81.     MVI    C,8            ;LENGTH OF COMPARE
  82.     PUSH    H            ;SAVE POINTER TO TABLE
  83. ;
  84. COMPARE1:
  85.     LDAX    D            ;GET TRIAL NAME CHAR
  86.     CMP    M            ;MATCH?
  87.     JNZ    END$COMPARE        ;IF NOT, TRY NEXT ENTRY
  88.     INX    H            ;ADVANCE POINTERS
  89.     INX    D                
  90.     DCR    C            ;ONE LESS CHAR TO COMPARE    
  91.     JNZ    COMPARE1        ;KEEP TESTING    
  92. END$COMPARE:    
  93.     POP    B            ;RESTORE TABLE POINTER
  94.     JC    INSERT$NAME        ;DIRECTORY NAME GOES IN    
  95.                     ;FRONT OF CURRENT TABLE
  96.                     ;ENTRY IF LOWER(CY=1)
  97.     LXI    H,14            ;LENGTH OF TABLE ENTRY
  98.     DAD    B            ;(HL) TO NEXT TABLE ENTRY
  99.     POP    D            ;RECOVER TRAILER NAME POINT
  100.     JMP    COMPARE$LOOP        ;LOOP AGAIN
  101. ;    
  102. ;
  103. INSERT$NAME:
  104.     LXI    H,FILE$COUNT        ;COUNT THE NUMBER OF FILES
  105.     INR    M            ;TO BE DISPLAYED
  106.     LHLD    END$OF$TABLE        ;GET POINTER TO TABLE
  107.     XCHG
  108.     LXI    H,14            ;DISTANCE TO MOVE
  109.     DAD    D            ;(HL) POINT DESTINATION
  110.     SHLD    END$OF$TABLE        ;SAVE THE NEW END OF TABLE
  111.     INX    H
  112.     INX    D
  113. MOVE$UP:
  114.     DCX    D
  115.     DCX    H
  116.     LDAX    D            ;GET BYTE TO MOVE
  117.     MOV    M,A            ;PUT IN NEW SPOT
  118.     MOV    A,C            ;TEST FOR DONE
  119.     CMP    E            ;(BC)=(DE)?
  120.     JNZ    MOVE$UP
  121.     MOV    A,B
  122.     CMP    D
  123.     JNZ    MOVE$UP
  124.     POP    H            ;RECOVER POINTER
  125.     MVI    C,8
  126.     CALL    BLOCK$MOVE        ;INSERT NAME IN TABLE
  127. ;
  128.     LXI    H,MENU$BUFF        ;POINT MENU NUMBER BLOCK
  129.     MVI    C,6            ;LENGTH OF MOVEK
  130.     CALL    BLOCK$MOVE        ;INSERT TEXT IN TABLE
  131. ;
  132.     MVI    C,18            ;'SEARCH NEXT' COMMAND
  133.     JMP    SORT$LOOP
  134. ;
  135. ASSIGN$MENU$NBR:
  136.     LDA    FILE$COUNT
  137.     MOV    B,A            ;SAVE IN (B)
  138.     PUSH    PSW            ;AND ON STACK
  139.     MVI    C,0            ;INITIAL FILE NUMBER
  140.     LXI    H,DIRTABLE+11        ;POINT FIRST FILE NUMBER
  141.     LXI    D,13            ;OFFSET TO OTHER NUMBERS
  142. ;
  143. NUMBER$FILES:
  144.     MOV    A,C            ;PUT FILE NUMBER IN (A)
  145.     ADI    1            ;INCREMENT
  146.     DAA                ;DECIMAL CONVERT
  147.     MOV    C,A            ;RESAVE    IN (C)
  148.     RRC                ;GET TENS DIGIT INTO
  149.     RRC                ;PROPER PLACE
  150.     RRC                ;
  151.     RRC
  152.     ANI    0FH            ;ADD MASK
  153.     JZ    USE$BLANK        ;SUPRESS LEADING ZERO BY
  154.     ADI    10H            ;ADD EITHER 20H(ASCII ' ')
  155. USE$BLANK:
  156.     ADI    ' '            ;OR 20H + 10H FOR NUMERAL
  157.     MOV    M,A            ;PUT IN TEXT STREAM
  158.     MOV    A,C            ;GET UNITS PORTION
  159.     ANI    0FH            ;MASK OFF TENS PORTION
  160.     ADI    '0'            ;CONVERT TO ASCII
  161.     INX    H            
  162.     MOV    M,A
  163.     DAD    D            ;REPEAT UNTIL ALL FILES
  164.     DCR    B            ;ARE SEQUENTIALLY NUMBERED
  165.     JNZ    NUMBER$FILES
  166. ;    
  167.     POP    PSW            ;GET FILE$COUNT FROM STACK
  168.     PUSH    PSW            ;AND SAVE AGAIN FOR LATER
  169. ;
  170. ;
  171.     ADI    NBR$COL-1
  172.     MVI    B,255            ;(B) ACCUMULATES QUOTIENT
  173.                     ;SO SET TO -1 FOR AT LEAST
  174.                     ;1 PASS THRU GIVES 0
  175. ;
  176. DIVX:
  177.     INR    B            ;
  178.     SUI    NBR$COL            ;DIVIDE BY FOUT TO GET OFFSET1
  179. ;
  180.     JP    DIVX
  181.     ADI    NBR$COL            ;SUBSTRACTED ONCE TOO MUCH
  182.                     ;SO ADD IT BACK ON
  183.     LXI    H,OFFSET1        
  184.     MOV    M,B            ;INSERT OFFSET1 INTO TABLE
  185.     INX    H            ;POINT OFFSET2 LOCATION
  186.     ora    a
  187.     JNZ    SETOFFSET2        ;SAME AS OFFSET1 IF NON-
  188.                     ;ZERO REMAINDER
  189.     DCR    B            ;ELSE OFFSET2=OFFSET1-1
  190. ;:
  191. SETOFFSET2:
  192.     MOV    M,B            ;PUT OFFSET2 IN TABLE
  193.     INX    H            ;POINT OFFSET    FOR COL 3
  194.     DCR    A            ;TEST FOR REMAINDER OF 1
  195.     JNZ    SETOFFSET3        ;IF REMAINDER <> 1, USE
  196.                     ;OFFSET3=OFFSET2-1
  197.     DCR    B            ;ELSE OFFSET3=OFFSET2-1Y
  198. ;
  199. SETOFFSET3:
  200.     MOV    M,B            ;ELSE OFFSET TO COLUMN 4
  201. ;    
  202. ;    
  203. REPRINT:
  204.     POP    PSW            ;RECOVER FILE COUNT
  205. ;
  206. REPRINT1:    
  207.     PUSH    PSW            ;SAVE AGAIN FOR LATER USE
  208.     STA    FILE$COUNT        ;SAVE FOR COUNTING    
  209.     MVI    A,SCREEN$HGT        ;SET FOR VIDEO DISPLAY SIZE
  210.     STA    LINE$COUNT        ;
  211.     LXI    D,HEADING
  212.     MVI    C,9            ;BUFFER PRINTER COMMAND
  213.     CALL    BDOS            ;CP/M PRINTS HEADING
  214. ;    
  215.     LXI    H,DIR$TABLE - 14    ;POINT DUMMY 0TH ENTRY
  216. ;    
  217. PRINT$LINE:
  218.     PUSH    H            ;SAVE BASE ADDRESS
  219.     LXI    D,OFFSET0        ;POINT OFFSET TABLE
  220.     MVI    A,NBR$COL        ;COLUMN PER LINE
  221. ;
  222. PRINT$NAME:
  223.     STA    COLUMN$CNT        ;SAVE COUNT OF COLUMNS
  224.     LDAX    D            ;GET OFFSET VALUE
  225. ;
  226.     LXI    B,14            ;EACH NAME IS 14 LONG
  227. ;
  228. MULT$14:
  229.     DAD    B            ;ADD 14 FOR EACH OFFSET
  230.     DCR    A            ;UNTIL OFFSET = 0
  231.     JNZ    MULT$14
  232.     PUSH    H            ;SAVE NEW NAME POINTER
  233.     PUSH    D            ;SAVE OFFSET POINTER
  234.     XCHG                ;POINTER NAME TO PRINT W/(DE)
  235.     MVI    C,9            ;PRINT BUFFER
  236.     CALL    BDOS            ;PRINT FILE NAME
  237.                     ;AND IT'S MENU NO.
  238.     LXI    D,DOUBL$SPACE        ;PRINT 2 BLANKS
  239.     MVI    C,9            ;'PRINT BUFFER' COMMAND
  240.     CALL    BDOS            ;USE CP/M 
  241. ;
  242. TEST$FINISH:
  243.     LXI    H,FILE$COUNT        ;SEE IF DONE PRINTING
  244.     DCR    M            ;BY TESTING COUNT OF FILES
  245.     POP    D            ;GET OFFSET POINTER
  246.     POP    H            ;GET POINTER TO LAST NAME
  247.     JZ    FINISH            ;NO MORE TO PRINT
  248.     INX    D            ;ADVANCE OFFSET POINTER
  249.     LDA    COLUMN$CNT
  250.     DCR    A            ;SEE IF COLUMN LEFT = 0
  251.     JNZ    PRINT$NAME        ;PRINT ANOTHER SAVE LINE 
  252.     lda    line$count
  253.     dcr    a
  254.     jnz    test$fin$2
  255.     lxi    d,more$msg
  256.     mvi    c,9
  257.     call    bdos
  258.     mvi    c,1            ;console input
  259.     call    bdos
  260.     cpi    'y'
  261.     jz    test$fin$2
  262.     cpi    'Y'
  263.     jnz    finish
  264. test$fin$2:
  265.     CALL    CRLF
  266.     POP    H            ;GET BASE OF PREVIOUS LINE
  267.     LXI    D,14            ;ADD OFFSET
  268.     DAD    D    
  269.     JMP    PRINT$LINE
  270. ;
  271. ;
  272. ;
  273. FINISH:
  274.     POP    H            ;UNJUNK STACK
  275. ;
  276. LF$LOOP:
  277.     CALL    CRLF
  278.     CALL    CRLF
  279.     LXI    D,PROMPT        ;POINT INSTRUCTION MESSAGE
  280.     MVI    C,9            
  281.     CALL    BDOS
  282.     LXI    D,INPUT$BUFF
  283.     MVI    A,10            ;10 CHRS MAX
  284.     STAX    D
  285.     MVI    C,10            ;'READ BUFFER' COMMAND
  286.     CALL    BDOS
  287. ;
  288. ;
  289. ;
  290.     LXI    H,INPUT$BUFF+1        ;POINT TO CHR COUNTER
  291.     MOV    A,M            ;GET IT AND SEE IF >2 
  292.     CPI    3
  293.     JNC    REPRINT            ;REPRINT THE MENU
  294.     MOV    C,A            ;COUNT OF DIGITS TO (C)
  295.     MVI    B,0
  296. ;
  297. GET$MENU$NBR:
  298.     INX    H            ;POINT ASCII DIGIT
  299.     MOV    A,M            ;GET IT
  300.     CALL    ASCII$CONVERT        ;CONVERT TO BINARY
  301.     JC    REPRINT            ;RE-DISPLAY ON ERROR
  302.     DCR    C        
  303.     JNZ    GET$MENU$NBR
  304. ;
  305. ;
  306.     POP    PSW            ;RECOVER FILE COUNTER
  307.     CMP    B            ;FILE$ COUNT- REQUEST NO.
  308.     JC    REPRINT1        ;REDISPLAY MENU IF ILLEGAL
  309. ;
  310.     LXI    D,14            ;INC BETWEEN NAMES
  311.     LXI    H,DIR$TABLE-14        ;POINT DUMMY 0TH ENTRY
  312. ;
  313. FIND$NAME:
  314.     DAD    D            ;ADD OFFSET B TIMES
  315.     DCR    B            
  316.     JNZ    FIND$NAME
  317. ;
  318. ;
  319.     XCHG                ;SAVE POINTER TO FILE NAME
  320.     LHLD    1            ;GET BDOS ENTRY POINT
  321.     mvi    l,0
  322.     LXI    B,-CCP$LEN        ;OFFSET TO START OF ccp
  323.     DAD    B
  324.     PUSH    H            ;SAVE ccp ENTRY POINT
  325.                     ;ON STACK FOR BRANCH
  326.     LXI    B,8            ;OFFSET TO COMMAND BUFFER
  327.     DAD    B            ;(HL) POINTS PLACE TO PUT 
  328.                     ;NAME OF .COM FILE TO BE
  329.                     ;EXECUTED
  330.     PUSH    D            ;SAVE POINTER TO FILE NAME
  331.     XCHG                ;(DE) POINTS COMMAND BUDFER
  332. ;
  333. ;
  334. ;
  335.     LXI    H,cmd$buf$len            ;OFFSET TO END OF CMD BUFF
  336.                     ;WHERE POINTER IS STORED
  337.     DAD    D            ;(HL) POIN TS STORAGE PLACE
  338.     MOV    M,E            ;UPDATE BUFFER POINTER TO
  339.     INX    H            ;THE START OF THE COMMAND
  340.     MOV    M,D            ;BUFF SO CP/M WILL READ
  341. ;    
  342.     if    mbas$prog or cbas$prog
  343.     lda    bas$drive
  344.     call    drive$sub
  345.     endif
  346. ;
  347.     IF    MBAS$PROG
  348.     LXI    H,mbcom$name        ;POINT COMMAND NAME
  349.     MVI    C,mbcom$len        ;LENGHT OF COMMAND NAME
  350.     CALL    BLOCK$MOVE
  351.     ENDIF
  352. ;
  353.     if cbas$prog
  354.     lxi    h,cbcom$name
  355.     mvi    c,cbcom$len
  356.     call    block$move
  357.     endif
  358. ;
  359.     lda    menu$drive        ;drive for menu selection
  360.     call    drive$sub
  361. ;
  362.     POP    H            ;POINT SELECTED FILE NAME
  363.     MVI    C,8            ;LENGTH OF FILE NAME
  364.     CALL    BLOCK$MOVE
  365. ;
  366. ;
  367.     XRA    A            ;NEEDS A 0 AT END
  368.     STAX    D            ;OF COMMAND LINE
  369.     lda    4            ;select default drive
  370.     mov    c,a
  371.  
  372. ;
  373.     RET
  374. ;
  375. ;
  376. ;SUBROUTINES
  377. ;
  378. BLOCK$MOVE:
  379.     MOV    A,M
  380.     STAX    D
  381.     INX    D
  382.     INX    H
  383.     DCR    C
  384.     JNZ    BLOCK$MOVE
  385.     RET
  386. ;
  387. drive$sub:
  388.     ora    a
  389.     jz    end$drive$sub
  390.     adi    'A'-1            ;make ASCII
  391.     xchg                ;make H point to command buffer
  392.     mov    m,a
  393.     inx    h
  394.     mvi    m,':'
  395.     inx    h
  396.     xchg
  397. end$drive$sub:
  398.     ret
  399. ;
  400. ASCII$CONVERT:
  401.     SUI    '0'            ;SUBTRACT ASCII BIAS
  402.     CPI    9+1            ;BE SURE IT'S NUMERIC
  403.     CMC
  404.     RC
  405.     MOV    D,A
  406.     MOV    A,B
  407.     RLC
  408.     RLC
  409.     RLC
  410.     ADD    B
  411.     RC
  412.     ADD    B
  413.     RC
  414.     ADD    D
  415.     MOV    B,A
  416.     RET
  417. ;
  418. CRLF:
  419.     LXI    D,CRLFMSG
  420.     MVI    C,9
  421.     CALL    BDOS
  422.     LXI    H,LINE$COUNT
  423.     DCR    M
  424.     RET
  425. ;
  426. ;
  427. CRLFMSG    DB    0DH,0AH,'$'
  428. ;
  429. more$msg:
  430.     db    0dh,0ah,'More (Y/N)? $'
  431. ;
  432. HEADING    DB    0AH,'MENU:',0DH,0AH,0AH,'$'
  433. ;
  434.     IF    MBAS$PROG
  435. mbcom$name:
  436.     DB    'MBASIC '
  437. mbcom$len:    EQU    $-mbcom$name
  438.     ENDIF
  439. ;
  440.     if    cbas$prog
  441. cbcom$name:
  442.     db    'CRUN2 '
  443. cbcom$len:    equ    $-cbcom$name
  444.     endif
  445. ;
  446. PROMPT:
  447.     DB    'ENTER MENU NUMBER & PRESS RETURN: $'
  448. ;
  449. DOUBL$SPACE:
  450.     DB    '    $'        ;REALLY 4 SPACES
  451. ;
  452. MENU$BUFF:
  453.     DB    ' - 00$'
  454. ;
  455. OFFSET0    DB    1
  456. OFFSET1    DB    0,0,0
  457. ;
  458. END$OF$TABLE:
  459.     DW    DIRTABLE
  460. ;
  461. FILE$COUNT:
  462.     DB    0
  463. COLUMN$CNT:
  464.     DB    0
  465. LINE$COUNT:
  466.     DB    0
  467. ;
  468. def$fcb    equ    5ch
  469. menu$drive:
  470.     ds    1
  471. ;
  472.     IF    MBAS$PROG
  473. bas$drive:
  474.     ds    1
  475. SRCH$FCB:
  476.     DB    '????????BAS',0
  477.     ENDIF
  478. ;
  479.     if    cbas$prog
  480. bas$drive:
  481.     ds    1
  482. srch$fcb:
  483.     db    '????????INT',0
  484.     endif
  485. ;
  486.     if    com$prog
  487. SRCH$FCB:
  488.     DB    '????????COM',0
  489.     endif
  490. ;
  491. srch$fcb$len:    equ    $-srch$fcb
  492. ;
  493. DIR$TABLE:
  494.     DB    255
  495. ;
  496. STACK$AREA    EQU    200*14 + 30
  497. ;
  498. INPUT$BUFF    EQU    STACK$AREA
  499. ;
  500. ;
  501. ;    EQUATES:
  502. ;
  503. BDOS    EQU    5
  504. NBR$COL    EQU    3
  505. CCP$LEN    EQU    0e00h+0800h
  506. SCREEN$HGT:    EQU    20
  507. cmd$buf$len:    equ    128
  508. ;
  509.     END
  510.