home *** CD-ROM | disk | FTP | other *** search
- ; MENU PROGRAM
- ; FOR
- ; MACHINE LANGUAGE OR BASIC PROGRAMS
- ;
- ; BY
- ; JAMES J. FRANTZ
- ; MAY 31, 1979
- ;
- ;Modified by Jim Woolley, FOG Disk Librarian, 11/82
- ;
- ;Calling syntax:
- ;
- ; MENU menu of .COM files on default drive
- ; MENU d: menu of .COM files on drive d:
- ;
- ; BMENU menu of .BAS (MBASIC) files on default drive
- ; MBASIC.COM assumed to be on default drive, also
- ; BMENU d: menu of .BAS (MBASIC) files on drive d:
- ; MBASIC.COM assumed to be on default drive
- ; BMENU d1: d2: menu of .BAS (MBASIC) files on drive d1:
- ; MBASIC.COM found on drive d2:
- ;
- ; CMENU menu of .INT (CBASIC) files on default drive
- ; CRUN2.COM assumed to be on default drive, also
- ; CMENU d: menu of .INT (CBASIC) files on drive d:
- ; CRUN2.COM assumed to be on default drive
- ; CMENU d1: d2: menu of .INT (CBASIC) files on drive d1:
- ; CRUN2.COM found on drive d2:
- ;
- ;CORRECTIONS BY K. COYE SEPT 11, 1982
- ;
- ;1. SEARCH.FCB WAS TOO SHORT CAUSING OVERWRITE OF DIR$TABLE
- ;2. MENU$BUF WAS 5 CHARS LONG INSTEAD OF THE REQUIRED 6
- ;
- ORG 0100H
- ;
- ;
- true equ 1
- false equ 0
- com$prog equ true ;for .COM files
- cbas$prog equ false ;for CBASIC files
- MBAS$PROG EQU false ;for MBASIC files
- ;
- LXI SP,STACK$AREA ;SET UP A STACK
- lda def$fcb
- sta menu$drive
- ;
- if mbas$prog or cbas$prog
- lda def$fcb+16
- sta bas$drive
- endif
- ;
- lxi d,def$fcb+1
- lxi h,srch$fcb
- mvi c,srch$fcb$len
- call block$move
- MVI C,17 ;'SEARCH FIRST' COMMAND
- ;
- SORT$LOOP:
- LXI D,def$fcb ;POINT FILE CONTROL BLOCK
- CALL BDOS ;USE CP/M ENTRY POINT
- ;
- ;
- ORA A ;TEST FOR -1
- JM ASSIGN$MENU$NBR ;PRINT EMPTY
- RRC ;THIS IS THE SAME AS
- RRC ;5 "ADD A'S"
- RRC
- ANI 60H ;MASK CORRECT BITS
- ADI 80H ;ADD BASE ADDRESS(0080H)
- MOV E,A ;PUT POINTER IN (DE)
- MVI D,0 ;AS 16 BIT VALUE
- LXI H,DIRTABLE ;POINT START OF TABLE OF
- ;SORTED NAMES
- INX D ;POINT PAST ERASE FIELD
- ;
- COMPARE$LOOP:
- ;
- PUSH D ;SAVE POINTER TO NEXT
- ;ENTRY FROM DISK DIRECTORY
- MVI C,8 ;LENGTH OF COMPARE
- PUSH H ;SAVE POINTER TO TABLE
- ;
- COMPARE1:
- LDAX D ;GET TRIAL NAME CHAR
- CMP M ;MATCH?
- JNZ END$COMPARE ;IF NOT, TRY NEXT ENTRY
- INX H ;ADVANCE POINTERS
- INX D
- DCR C ;ONE LESS CHAR TO COMPARE
- JNZ COMPARE1 ;KEEP TESTING
- END$COMPARE:
- POP B ;RESTORE TABLE POINTER
- JC INSERT$NAME ;DIRECTORY NAME GOES IN
- ;FRONT OF CURRENT TABLE
- ;ENTRY IF LOWER(CY=1)
- LXI H,14 ;LENGTH OF TABLE ENTRY
- DAD B ;(HL) TO NEXT TABLE ENTRY
- POP D ;RECOVER TRAILER NAME POINT
- JMP COMPARE$LOOP ;LOOP AGAIN
- ;
- ;
- INSERT$NAME:
- LXI H,FILE$COUNT ;COUNT THE NUMBER OF FILES
- INR M ;TO BE DISPLAYED
- LHLD END$OF$TABLE ;GET POINTER TO TABLE
- XCHG
- LXI H,14 ;DISTANCE TO MOVE
- DAD D ;(HL) POINT DESTINATION
- SHLD END$OF$TABLE ;SAVE THE NEW END OF TABLE
- INX H
- INX D
- MOVE$UP:
- DCX D
- DCX H
- LDAX D ;GET BYTE TO MOVE
- MOV M,A ;PUT IN NEW SPOT
- MOV A,C ;TEST FOR DONE
- CMP E ;(BC)=(DE)?
- JNZ MOVE$UP
- MOV A,B
- CMP D
- JNZ MOVE$UP
- POP H ;RECOVER POINTER
- MVI C,8
- CALL BLOCK$MOVE ;INSERT NAME IN TABLE
- ;
- LXI H,MENU$BUFF ;POINT MENU NUMBER BLOCK
- MVI C,6 ;LENGTH OF MOVEK
- CALL BLOCK$MOVE ;INSERT TEXT IN TABLE
- ;
- MVI C,18 ;'SEARCH NEXT' COMMAND
- JMP SORT$LOOP
- ;
- ASSIGN$MENU$NBR:
- LDA FILE$COUNT
- MOV B,A ;SAVE IN (B)
- PUSH PSW ;AND ON STACK
- MVI C,0 ;INITIAL FILE NUMBER
- LXI H,DIRTABLE+11 ;POINT FIRST FILE NUMBER
- LXI D,13 ;OFFSET TO OTHER NUMBERS
- ;
- NUMBER$FILES:
- MOV A,C ;PUT FILE NUMBER IN (A)
- ADI 1 ;INCREMENT
- DAA ;DECIMAL CONVERT
- MOV C,A ;RESAVE IN (C)
- RRC ;GET TENS DIGIT INTO
- RRC ;PROPER PLACE
- RRC ;
- RRC
- ANI 0FH ;ADD MASK
- JZ USE$BLANK ;SUPRESS LEADING ZERO BY
- ADI 10H ;ADD EITHER 20H(ASCII ' ')
- USE$BLANK:
- ADI ' ' ;OR 20H + 10H FOR NUMERAL
- MOV M,A ;PUT IN TEXT STREAM
- MOV A,C ;GET UNITS PORTION
- ANI 0FH ;MASK OFF TENS PORTION
- ADI '0' ;CONVERT TO ASCII
- INX H
- MOV M,A
- DAD D ;REPEAT UNTIL ALL FILES
- DCR B ;ARE SEQUENTIALLY NUMBERED
- JNZ NUMBER$FILES
- ;
- POP PSW ;GET FILE$COUNT FROM STACK
- PUSH PSW ;AND SAVE AGAIN FOR LATER
- ;
- ;
- ADI NBR$COL-1
- MVI B,255 ;(B) ACCUMULATES QUOTIENT
- ;SO SET TO -1 FOR AT LEAST
- ;1 PASS THRU GIVES 0
- ;
- DIVX:
- INR B ;
- SUI NBR$COL ;DIVIDE BY FOUT TO GET OFFSET1
- ;
- JP DIVX
- ADI NBR$COL ;SUBSTRACTED ONCE TOO MUCH
- ;SO ADD IT BACK ON
- LXI H,OFFSET1
- MOV M,B ;INSERT OFFSET1 INTO TABLE
- INX H ;POINT OFFSET2 LOCATION
- ora a
- JNZ SETOFFSET2 ;SAME AS OFFSET1 IF NON-
- ;ZERO REMAINDER
- DCR B ;ELSE OFFSET2=OFFSET1-1
- ;:
- SETOFFSET2:
- MOV M,B ;PUT OFFSET2 IN TABLE
- INX H ;POINT OFFSET FOR COL 3
- DCR A ;TEST FOR REMAINDER OF 1
- JNZ SETOFFSET3 ;IF REMAINDER <> 1, USE
- ;OFFSET3=OFFSET2-1
- DCR B ;ELSE OFFSET3=OFFSET2-1Y
- ;
- SETOFFSET3:
- MOV M,B ;ELSE OFFSET TO COLUMN 4
- ;
- ;
- REPRINT:
- POP PSW ;RECOVER FILE COUNT
- ;
- REPRINT1:
- PUSH PSW ;SAVE AGAIN FOR LATER USE
- STA FILE$COUNT ;SAVE FOR COUNTING
- MVI A,SCREEN$HGT ;SET FOR VIDEO DISPLAY SIZE
- STA LINE$COUNT ;
- LXI D,HEADING
- MVI C,9 ;BUFFER PRINTER COMMAND
- CALL BDOS ;CP/M PRINTS HEADING
- ;
- LXI H,DIR$TABLE - 14 ;POINT DUMMY 0TH ENTRY
- ;
- PRINT$LINE:
- PUSH H ;SAVE BASE ADDRESS
- LXI D,OFFSET0 ;POINT OFFSET TABLE
- MVI A,NBR$COL ;COLUMN PER LINE
- ;
- PRINT$NAME:
- STA COLUMN$CNT ;SAVE COUNT OF COLUMNS
- LDAX D ;GET OFFSET VALUE
- ;
- LXI B,14 ;EACH NAME IS 14 LONG
- ;
- MULT$14:
- DAD B ;ADD 14 FOR EACH OFFSET
- DCR A ;UNTIL OFFSET = 0
- JNZ MULT$14
- PUSH H ;SAVE NEW NAME POINTER
- PUSH D ;SAVE OFFSET POINTER
- XCHG ;POINTER NAME TO PRINT W/(DE)
- MVI C,9 ;PRINT BUFFER
- CALL BDOS ;PRINT FILE NAME
- ;AND IT'S MENU NO.
- LXI D,DOUBL$SPACE ;PRINT 2 BLANKS
- MVI C,9 ;'PRINT BUFFER' COMMAND
- CALL BDOS ;USE CP/M
- ;
- TEST$FINISH:
- LXI H,FILE$COUNT ;SEE IF DONE PRINTING
- DCR M ;BY TESTING COUNT OF FILES
- POP D ;GET OFFSET POINTER
- POP H ;GET POINTER TO LAST NAME
- JZ FINISH ;NO MORE TO PRINT
- INX D ;ADVANCE OFFSET POINTER
- LDA COLUMN$CNT
- DCR A ;SEE IF COLUMN LEFT = 0
- JNZ PRINT$NAME ;PRINT ANOTHER SAVE LINE
- lda line$count
- dcr a
- jnz test$fin$2
- lxi d,more$msg
- mvi c,9
- call bdos
- mvi c,1 ;console input
- call bdos
- cpi 'y'
- jz test$fin$2
- cpi 'Y'
- jnz finish
- test$fin$2:
- CALL CRLF
- POP H ;GET BASE OF PREVIOUS LINE
- LXI D,14 ;ADD OFFSET
- DAD D
- JMP PRINT$LINE
- ;
- ;
- ;
- FINISH:
- POP H ;UNJUNK STACK
- ;
- LF$LOOP:
- CALL CRLF
- CALL CRLF
- LXI D,PROMPT ;POINT INSTRUCTION MESSAGE
- MVI C,9
- CALL BDOS
- LXI D,INPUT$BUFF
- MVI A,10 ;10 CHRS MAX
- STAX D
- MVI C,10 ;'READ BUFFER' COMMAND
- CALL BDOS
- ;
- ;
- ;
- LXI H,INPUT$BUFF+1 ;POINT TO CHR COUNTER
- MOV A,M ;GET IT AND SEE IF >2
- CPI 3
- JNC REPRINT ;REPRINT THE MENU
- MOV C,A ;COUNT OF DIGITS TO (C)
- MVI B,0
- ;
- GET$MENU$NBR:
- INX H ;POINT ASCII DIGIT
- MOV A,M ;GET IT
- CALL ASCII$CONVERT ;CONVERT TO BINARY
- JC REPRINT ;RE-DISPLAY ON ERROR
- DCR C
- JNZ GET$MENU$NBR
- ;
- ;
- POP PSW ;RECOVER FILE COUNTER
- CMP B ;FILE$ COUNT- REQUEST NO.
- JC REPRINT1 ;REDISPLAY MENU IF ILLEGAL
- ;
- LXI D,14 ;INC BETWEEN NAMES
- LXI H,DIR$TABLE-14 ;POINT DUMMY 0TH ENTRY
- ;
- FIND$NAME:
- DAD D ;ADD OFFSET B TIMES
- DCR B
- JNZ FIND$NAME
- ;
- ;
- XCHG ;SAVE POINTER TO FILE NAME
- LHLD 1 ;GET BDOS ENTRY POINT
- mvi l,0
- LXI B,-CCP$LEN ;OFFSET TO START OF ccp
- DAD B
- PUSH H ;SAVE ccp ENTRY POINT
- ;ON STACK FOR BRANCH
- LXI B,8 ;OFFSET TO COMMAND BUFFER
- DAD B ;(HL) POINTS PLACE TO PUT
- ;NAME OF .COM FILE TO BE
- ;EXECUTED
- PUSH D ;SAVE POINTER TO FILE NAME
- XCHG ;(DE) POINTS COMMAND BUDFER
- ;
- ;
- ;
- LXI H,cmd$buf$len ;OFFSET TO END OF CMD BUFF
- ;WHERE POINTER IS STORED
- DAD D ;(HL) POIN TS STORAGE PLACE
- MOV M,E ;UPDATE BUFFER POINTER TO
- INX H ;THE START OF THE COMMAND
- MOV M,D ;BUFF SO CP/M WILL READ
- ;
- if mbas$prog or cbas$prog
- lda bas$drive
- call drive$sub
- endif
- ;
- IF MBAS$PROG
- LXI H,mbcom$name ;POINT COMMAND NAME
- MVI C,mbcom$len ;LENGHT OF COMMAND NAME
- CALL BLOCK$MOVE
- ENDIF
- ;
- if cbas$prog
- lxi h,cbcom$name
- mvi c,cbcom$len
- call block$move
- endif
- ;
- lda menu$drive ;drive for menu selection
- call drive$sub
- ;
- POP H ;POINT SELECTED FILE NAME
- MVI C,8 ;LENGTH OF FILE NAME
- CALL BLOCK$MOVE
- ;
- ;
- XRA A ;NEEDS A 0 AT END
- STAX D ;OF COMMAND LINE
- lda 4 ;select default drive
- mov c,a
-
- ;
- RET
- ;
- ;
- ;SUBROUTINES
- ;
- BLOCK$MOVE:
- MOV A,M
- STAX D
- INX D
- INX H
- DCR C
- JNZ BLOCK$MOVE
- RET
- ;
- drive$sub:
- ora a
- jz end$drive$sub
- adi 'A'-1 ;make ASCII
- xchg ;make H point to command buffer
- mov m,a
- inx h
- mvi m,':'
- inx h
- xchg
- end$drive$sub:
- ret
- ;
- ASCII$CONVERT:
- SUI '0' ;SUBTRACT ASCII BIAS
- CPI 9+1 ;BE SURE IT'S NUMERIC
- CMC
- RC
- MOV D,A
- MOV A,B
- RLC
- RLC
- RLC
- ADD B
- RC
- ADD B
- RC
- ADD D
- MOV B,A
- RET
- ;
- CRLF:
- LXI D,CRLFMSG
- MVI C,9
- CALL BDOS
- LXI H,LINE$COUNT
- DCR M
- RET
- ;
- ;
- CRLFMSG DB 0DH,0AH,'$'
- ;
- more$msg:
- db 0dh,0ah,'More (Y/N)? $'
- ;
- HEADING DB 0AH,'MENU:',0DH,0AH,0AH,'$'
- ;
- IF MBAS$PROG
- mbcom$name:
- DB 'MBASIC '
- mbcom$len: EQU $-mbcom$name
- ENDIF
- ;
- if cbas$prog
- cbcom$name:
- db 'CRUN2 '
- cbcom$len: equ $-cbcom$name
- endif
- ;
- PROMPT:
- DB 'ENTER MENU NUMBER & PRESS RETURN: $'
- ;
- DOUBL$SPACE:
- DB ' $' ;REALLY 4 SPACES
- ;
- MENU$BUFF:
- DB ' - 00$'
- ;
- OFFSET0 DB 1
- OFFSET1 DB 0,0,0
- ;
- END$OF$TABLE:
- DW DIRTABLE
- ;
- FILE$COUNT:
- DB 0
- COLUMN$CNT:
- DB 0
- LINE$COUNT:
- DB 0
- ;
- def$fcb equ 5ch
- menu$drive:
- ds 1
- ;
- IF MBAS$PROG
- bas$drive:
- ds 1
- SRCH$FCB:
- DB '????????BAS',0
- ENDIF
- ;
- if cbas$prog
- bas$drive:
- ds 1
- srch$fcb:
- db '????????INT',0
- endif
- ;
- if com$prog
- SRCH$FCB:
- DB '????????COM',0
- endif
- ;
- srch$fcb$len: equ $-srch$fcb
- ;
- DIR$TABLE:
- DB 255
- ;
- STACK$AREA EQU 200*14 + 30
- ;
- INPUT$BUFF EQU STACK$AREA
- ;
- ;
- ; EQUATES:
- ;
- BDOS EQU 5
- NBR$COL EQU 3
- CCP$LEN EQU 0e00h+0800h
- SCREEN$HGT: EQU 20
- cmd$buf$len: equ 128
- ;
- END