home *** CD-ROM | disk | FTP | other *** search
- title 'MAKE Utility RSX for CP/M Plus'
-
-
- public GUSER ; return actual user number in <A>
- public NEXT ; call BDOS via RSX chain
- public UBDOS ; call BDOS with user number at (DE)-1
-
- extrn PARSMF ; parse make filename into FCB, <A> = error code
- extrn OPENMF ; open make file, <A> = error code
- extrn UNGETC ; store char in <A> back into file
- extrn GETC ; get one char from file into <A>
- extrn CLOSMF ; close make file, return EOF in <A>
- extrn PARFCB ; parse file at <HL> into FCB at <DE>
-
- ; constant definitions
-
- FALSE equ 0
- TRUE equ NOT FALSE
- EOF equ 1AH
- CR equ 13
- LF equ 10
- TAB equ 9
- TEST equ FALSE
-
-
- ; BDOS function calls
-
- WBOOT equ 0 ; warm boot
- CONOUT equ 2 ; output char in <E> to console
- DIRCONIO equ 6 ; direct console input/output/status
- PRINTS equ 9 ; print string at console
- RDCON equ 10 ; read console input buffer
- SETDMA equ 26 ; set DMA address
- SETUSR equ 32 ; set/get user number
- GETSCB equ 49 ; get/set system control block
- RDSTAMP equ 102 ; get date&time stamp of file
- GETPRC equ 108 ; get/set program return code
-
-
- ; RSX- Header
-
- cseg
- serial: db 0,0,0,0,0,0
- start: jmp ftest ; start of program
- NEXT: jmp 0 ; link to next RSX in chain
- prev: dw 0 ; link to prev. RSX in chain
- remove: db TRUE ; remove RSX on warm start (altered by MAKE.COM)
- nonbank: db FALSE ; load in every CP/M Plus system
- rname: db 'MAKERSX ' ; name of RSX (tested by MAKE.COM)
- loader: db 0,0,0 ; reserved for LOADER module usage
-
-
- ; MAKE variables filled in by MAKE.COM :
-
- cseg
- make$verbose: db FALSE ; is TRUE after /V option
- next$pb1: db 15h
- db 0FEh
- next$com: dw 0 ; address of next multiple command
- next$pb2: db 12h
- db 0FFh
- next$page: db 0 ; page of command RSX
-
-
- ; parse file name of make file :
-
- cseg
- make$parse: jmp PARSMF
-
-
- ; open make file
-
- cseg
- make$open: jmp OPENMF
-
-
- ; filter for BDOS 10 : read console input
-
- ftest: mvi a,RDCON ; is it read console buffer ?
- cmp c
- jnz NEXT ; no : jump to next RSX in chain
-
- mov a,e ; is prewritten input used ?
- ora d
- jz NEXT ; skip RSX, cannot deal with unknown
- ; characters, CCP don't use it
-
- lda remove ; is RSX active ?
- ora a ; or is it DONE, waiting for removal ?
- jnz NEXT ; skip RSX if DONE>
-
- ; process valid read console call
-
- trap$rdcon: xchg ; save address of console buffer
- shld rdcon$addr
-
- mvi c,GETPRC ; get program return code
- lxi d,0FFFFH ; ( NOT reset in CCP so far )
- call NEXT
- inr h ; H = 0FFH?
- jz abort$make ; because of faulty program execution
-
- ; save BDOS DMA address
-
- mvi c,GETSCB ; get entry in SCB
- lxi d,scb$dma
- call NEXT
- shld user$dma ; because we need it
-
- ; get drive search chain out of SCB
-
- mvi c,GETSCB
- lxi d,scb$drive12
- call NEXT
- shld drive1
- mvi c,GETSCB
- lxi d,scb$drive34
- call NEXT
- shld drive3
-
- ; test for CTRL-C
-
- mvi c,DIRCONIO ; direct console IO
- mvi e,0FFh ; input/status
- call NEXT
- cpi 3 ; CTRL-C
- jz break$make
-
- ; test for next execution or evaluation line
-
- test$next: call GETC ; read char from make file
- cpi EOF ; end of file reached ?
- jz make$end ; yes: terminate make normaly
- cpi ' ' ; space or TAB ?
- jz test$condition ; yes: execute or skip tabbed line
- cpi TAB
- jz test$condition
- cpi 20H ; other control char ?
- jc test$next ; skip it
-
- call UNGETC ; char back into make file
-
- ; read object file name from makefile
-
- make$next: mvi a,FALSE ; clear make-flag (default := no operation)
- sta make$flag
- sta EOL$flag ; end of line of make file not reached
- sta EOF$flag ; end of make file not reached
-
- call read$name ; read file name into name buffer
-
- lda EOF$flag ; end of file ?
- ora a
- jz make$next1
- lda name$buffer ; and name buffer empty ?
- ora a
- jz make$end ; yes: terminate make rsx
- jmp EOF$error ; no : rapport EOF error
-
- make$next1: lda name$buffer ; test first char of name buffer
- ora a
- jz test$next ; skip empty line
-
- lda EOL$flag ; (unexpected) end of input line after file name?
- ora a
- jnz format$error ; yes: bad formatted make file
-
- call parse$name ; parse file name into RSX$FCB
- ora a ; parse error ?
- jnz format$error ; yes: bad formatted make file
-
- call get$date ; try to find date$time stamp for this file
- ora a ; file not found ?
- jnz make$object ; yes: make file
-
- mov a,b ; date =0 ? (stamp inactive)
- ora c
- jz make$object ; make file anyway
-
- lxi h,obj$date ; store date & time of object file
- mov m,c ; BC = date
- inx h
- mov m,b
- inx h
- mov m,d ; D = hour
- inx h
- mov m,e ; E = minute
-
- jmp make$colon ; read colon after object filename
-
- make$object: call set$makef ; set make flag
-
- ; read colon from makefile
-
- make$colon: call read$name ; read over ':'
-
- lda EOF$flag ; unexpected end of file ?
- ora a
- jnz EOF$error ; rapport error
-
- lda name$buffer ; name buffer contains ':' ?
- cpi ':'
- jnz format$error ; no: bad formatted make file
-
- lda EOL$flag ; (unexpected) end of input line after colon?
- ora a
- jnz obj$older ; yes: unconditional execution
-
- ; read list of dependency files
-
- depend$list: lda EOL$flag ; end of input line reached ?
- ora a
- jnz test$condition ; yes: execute line if make$flag is set
-
- call read$name ; read next file name
-
- lda EOF$flag ; unexpected end of file ?
- ora a
- jnz EOF$error ; rapport error
-
- lda name$buffer ; name buffer empty (=empty rest of line) ?
- ora a
- jz test$condition ; test & execute make line
-
- call parse$name ; parse file name into RSX$FCB
- ora a ; parse error ?
- jnz format$error ; yes: bad formatted make file
-
- lda make$flag ; nesessary to test file ?
- ora a
- jnz depend$list
-
- call get$date ; try to find date&time stamp for this file
- ora a ; file found ?
- jz test$date
-
- lda RSX$FCB ; no: drive specified ?
- ora a
- jnz not$found ; ERROR: file not found, abort make
-
- test$1: lda drive1 ; first drive in search chain
- cpi 0FFH ; empty ?
- jz test$2
- ora a ; default drive ?
- jz test$2
- sta RSX$FCB ; drive ID into FCB
-
- call get$date ; try to find date&time stamp for this file
- ora a ; file found ?
- jz test$date
-
- test$2: lda drive2 ; second drive in search chain
- cpi 0FFH ; empty ?
- jz test$3
- ora a ; default drive ?
- jz test$3
- sta RSX$FCB ; drive ID into FCB
-
- call get$date ; try to find date&time stamp for this file
- ora a ; file found ?
- jz test$date
-
- test$3: lda drive3 ; third drive in search chain
- cpi 0FFH ; empty ?
- jz test$4
- ora a ; default drive ?
- jz test$4
- sta RSX$FCB ; drive ID into FCB
-
- call get$date ; try to find date&time stamp for this file
- ora a ; file found ?
- jz test$date
-
- test$4: lda drive4 ; fourth drive in search chain
- cpi 0FFH ; empty ?
- jz not$found
- ora a ; default drive ?
- jz not$found
- sta RSX$FCB ; drive ID into FCB
-
- call get$date ; try to find date&time stamp for this file
- ora a ; file found ?
- jnz not$found
-
- test$date: mov a,b ; stamp inactive ?
- ora c
- jz obj$older
-
- lxi h,obj$date+1 ; compare with date & time of object file
- mov a,m ; obj.date - dep.date
- sub b ; high byte first
- jc obj$older
- jnz depend$list
- dcx h ; then low byte
- mov a,m
- sub c
- jc obj$older ; than dep. list
- jnz depend$list ; object younger than dep. :
-
- inx h ; obj.time - dep.time
- inx h
- mov a,m ; A = hour
- sub d
- jc obj$older ; than dep. list
- jnz depend$list ; object younger than dep. :
-
- inx h
- mov a,m ; A = minute
- sub e
- jc obj$older ; than dep. list
- jnz depend$list ; object younger than dep. :
- obj$older: call set$makef ; set make flag
- jmp depend$list ; continue with parsing
-
- ; test make$flag and execute/skip make command line
-
- test$condition: lda make$flag ; is make$flag set ?
- ora a
- jz test$false
-
- test$true: lhld rdcon$addr ; copy line into RDCON buffer
- mov c,m ; max. count
- inx h
- inx h
- mvi b,0
-
- skip$loop: push b
- push h
- call GETC ; into a
- pop h
- pop b
- cpi CR ; end of line ?
- jz term$line
- cpi EOF
- jz eof$line
- cpi 21H
- jc skip$loop
- jmp insert$char
-
- line$loop: push b
- push h
- call GETC ; into a
- pop h
- pop b
- cpi CR ; end of line ?
- jz term$line
- cpi EOF
- jz eof$line
-
- insert$char: mov m,a
-
- push b ; print input of RDCON call
- push h
- mvi c,CONOUT
- mov e,a
- call NEXT
- pop h
- pop b
-
- inx h
- inr b
- dcr c
- jnz line$loop
- jmp long$line ; line is too long to fit into console buffer
-
- term$line: lhld rdcon$addr ; store char count in buffer
- inx h
- mov m,b
- mvi c,CONOUT ; print CR/LF
- mvi e,CR
- call NEXT
- jmp restore$dma ; restore user dma address
-
- eof$line: call set$remove ; this is the last call
- jmp term$line
-
- test$false: call getchar ; get char in A
- cpi EOF
- jz make$end
- cpi CR
- jnz test$false
- call getchar
- jmp test$next ; try next line of make file
-
- ; normal end of make file
-
- make$end: call disp$done
- call restore$dma
- call set$remove
- lda next$page ; is there a command pending ?
- ora a
- jz origin
- lhld rdcon$addr ; store empty line into console buffer
- inx h
- mvi m,0
- ret ; return to caller
-
-
- ; unfiltered BDOS 10 call
-
- origin: lhld rdcon$addr ; restore registers
- xchg
- mvi c,RDCON
- jmp NEXT ; and reach call to next RSX in chain
-
-
- ; restore user dma address
-
- restore$dma: mvi c,SETDMA ; set dma address to old value
- lhld user$dma
- xchg
- call NEXT
- ret
-
- ; set remove flag in RSX
-
- set$remove: mvi a,TRUE
- sta remove
- mvi c,GETSCB ; reset address of next command line
- lxi d,next$pb1
- call NEXT
- mvi c,GETSCB ; reset page of next command line
- lxi d,next$pb2
- jmp NEXT
-
-
- ; abort MAKE :
-
- abort$make: mvi c,PRINTS ; send error msg
- lxi d,abort$msg
- call NEXT
-
- abort$close: call CLOSMF ; close make file
-
- abort: call set$remove
-
- mvi c,GETPRC ; set program return code
- lxi d,0FF00H
- call NEXT
- mvi c,WBOOT
- jmp NEXT
-
- EOF$error: mvi c,PRINTS ; send error msg
- lxi d,EOF$msg
- call NEXT
- jmp abort
-
- disp$done: mvi c,PRINTS
- lxi d,done$msg
- jmp NEXT
-
- format$error: mvi c,PRINTS
- lxi d,format$msg
- call NEXT
- jmp abort$close
-
- not$found: mvi c,PRINTS
- lxi d,found$msg
- call NEXT
- jmp abort$close
-
- long$line: mvi c,PRINTS
- lxi d,long$msg
- call NEXT
- jmp abort$close
-
- break$make: mvi c,PRINTS
- lxi d,break$msg
- call NEXT
- jmp abort$close
-
-
- ; read a sequence of characters from make file
-
- getchar: push b
- push h
- call GETC ; from make file into A
- push psw
- mov e,a ; display char if /V option is on
- mvi c,CONOUT
- lda make$verbose
- ora a
- cnz NEXT
- pop psw
- pop h
- pop b
- ret
-
- read$name: lxi h,name$buffer ; let HL point into (empty) name buffer
- mvi b,29 ; number of free chars in buffer
-
- skip$lead$sp: call getchar
- cpi EOF ; end of file ?
- jz read$name$EOF
- cpi CR ; end of line ?
- jz read$name$EOL
- cpi 21H ; space or other control char ?
- jc skip$lead$sp
- cpi '\' ; line extender ?
- jz skip$EOL
- cpi ';' ; comment-line ?
- jz skip$comment
-
- store$char: mov m,a ; store into buffer
- inx h
- dcr b ; free chars -1
- jz format$error
-
- next$char: call getchar ; read subsequent chars
- cpi EOF ; end of file ?
- jz read$name$EOF
- cpi CR ; end of line ?
- jz read$name$EOL
- cpi TAB ; tabulator ?
- jz read$name$end
- cpi 20H ; space ?
- jz read$name$end
- jc next$char ; skip control characters
- cpi '\'
- jz skip$EOL
- jmp store$char ; else store character into buffer
-
- read$name$EOF: mvi a,TRUE ; set EOF-Flag
- sta EOF$flag
-
- read$name$EOL: mvi a,TRUE ; set EOL-Flag
- sta EOL$flag
- lda make$verbose ; send cr/lf if /v option
- ora a
- jz read$name$end
- call getchar
- read$name$end: mvi m,0 ; append NUL delimiter
- ret
-
- skip$EOL: call getchar ; from make file into A
- cpi EOF ; end of file ?
- jz read$name$EOF
- cpi CR ; end of line ?
- jnz skip$EOL
- call getchar
- jmp skip$lead$sp
-
- skip$comment: call getchar
- cpi EOF
- jz read$name$EOF
- cpi CR
- jnz skip$comment
- call getchar
- jmp read$name$end
-
- parse$name: lxi h,name$buffer ; parse file name into directory FCB
- lxi d,RSX$FCB
- jmp PARFCB
-
-
- ; get a time/date stamp from a file in RSX$FCB
-
- get$date: lxi h,RSX$FCB+1 ; check to find ? or * in file name/type
- mvi b,11
- check$loop: mov a,m ; get char
- cpi '?' ; '?' ?
- jz ambig$error ; is not allowed in any file name
- cpi '*'
- jz ambig$error
- inx h
- dcr b
- jnz check$loop
-
- if TEST
- mvi c,PRINTS
- lxi d,search$msg
- call NEXT
- endif
-
- mvi c,RDSTAMP ; read stamps for this file
- lxi d,RSX$FCB
- call UBDOS
- ora a ; error ?
- rnz ; return with A <> 0
-
- lxi h,RSX$FCB+28 ; HL points to update stamp
- call get$stamp
- mov a,c ; valid stamp ?
- ora b
- cz get$create ; no:try create stamp
- if TEST
- call out$date
- endif
- xra a ; A = 0 = ok
- ret
-
- get$create: lxi h,RSX$FCB+24 ; HL points to create stamp
- get$stamp: mov c,m ; BC := date
- inx h
- mov b,m
- inx h
- mov d,m ; D := hour
- inx h
- mov e,m ; E := minute
- ret
-
- ambig$error: mvi c,PRINTS
- lxi d,ambig$msg
- call NEXT
- jmp abort$close
-
- if TEST
- out$date: push b
- push d
- mvi a,' '
- call out$c
- pop d
- pop b
- push b
- push d
- mov a,b
- call out$hex
- pop d
- pop b
- push b
- push d
- mov a,c
- call out$hex
- mvi a,' '
- call out$c
- pop d
- pop b
- push b
- push d
- mov a,d
- call out$hex
- mvi a,':'
- call out$c
- pop d
- pop b
- push b
- push d
- mov a,e
- call out$hex
- pop d
- pop b
- ret
-
- out$hex: push psw
- rlc
- rlc
- rlc
- rlc
- call out$nib
- pop psw
-
- out$nib: ani 0Fh
- adi '0'
- cpi '9'+1
- cnc add$nib
-
- out$c: mvi c,CONOUT
- mov e,a
- jmp NEXT
-
- add$nib: adi 'A'-'9'-1
- ret
- endif
-
- ; set make flag
-
- cseg
- set$makef: mvi a,TRUE
- sta make$flag
- ret
-
- ; call bdos file system with another user number
-
- cseg
- UBDOS: dcx d ; DE points to user number(+1) of file
- ldax d
- inx d ; restore DE to old value
- ora a ; normal execution if file has
- jz NEXT ; no user number set
-
- push b ; save BC,DE
- push d
- push psw ; save user number(+1) of file
-
- call GUSER ; <A> := actual user number
- sta user$store ; save it
-
- pop psw ; user number(+1) of file
- dcr a
- call set$user ; set it
-
- pop d ; restore BC,DE
- pop b
- call NEXT ; make original BDOS call
- push psw ; save AF,HL
- push h
-
- lda user$store ; set actual user number
- call set$user ; to original value
-
- pop h ; restore AF,HL
- pop psw
- ret ; and return to caller
-
- ; get actual user number into <A>
-
- cseg
- GUSER: mvi e,0FFh
- mvi c,SETUSR
- jmp NEXT
-
- ; set user number to <A>
-
- cseg
- set$user: mov e,a
- mvi c,SETUSR
- jmp NEXT
-
-
- ; data area :
-
- dseg
- scb$drive12: db 4CH ; get drive 1,2
- db 0
- scb$drive34: db 4EH ; get drive 3,4
- db 0
- test$ccp: db 18H ; offset of ccp running flag
- db 0
- scb$dma: db 3CH ; offset of current DMA address
- db 0
- make$flag: db FALSE ; is TRUE if make condition satisfied
-
- abort$msg: db 'MAKE aborted by unsuccessfull program return',13,10,'$'
- ambig$msg: db 'MAKE aborted by ambiguous file name',13,10,'$'
- format$msg: db 'MAKE aborted by bad format of make file',13,10,'$'
- EOF$msg: db 'MAKE aborted by wrong end of make file',13,10,'$'
- found$msg: db 'MAKE aborted because file not found',13,10,'$'
- long$msg: db 'MAKE aborted because command line too long',13,10,'$'
- break$msg: db 'MAKE aborted by user',13,10,'$'
- done$msg: db 'DONE>$'
- if TEST
- search$msg: db 'SEARCHING$'
- endif
-
- rdcon$addr: ds 2 ; holds address of read console buffer
- user$dma: ds 2 ; holds address of users dma buffer
- name$buffer: ds 30 ; buffer for CP/M Plus filename
- RSX$USER: ds 1 ; user number of dir. search
- RSX$FCB: ds 36 ; FCB for directory search
- RSX$PASS: ds 8 ; password of file
- obj$date: ds 2 ; date of object file
- obj$time: ds 2 ; time of object file
- EOF$flag: ds 1 ; TRUE if end of makefile reached
- EOL$flag: ds 1 ; TRUE if end of line in makefile reached
- drive1: ds 1 ; drive search chain
- drive2: ds 1
- drive3: ds 1
- drive4: ds 1
- user$store: ds 1 ; temporary storage of actual user number
-
- end
-