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
/
CPM
/
ZCPR33
/
S-Z
/
SLTRAP.LBR
/
SLTRAP.ZZ0
/
SLTRAP.Z80
Wrap
Text File
|
2000-06-30
|
12KB
|
629 lines
; SLTRAP RCP
; By Paul Pomerleau
; January 13, 1986.
;
; This RCP traps all output going to the console or the printer
; and deposits it into a file. Trapping starts with:
; 'SOPEN filename.typ' (or LOPEN)
; and ends with:
; 'SCLOSE' (or LCLOSE)
;
; This code assembles with ZASM (Cromemco) ONLY!
;
; Maybe someday I (or someone else) will comment this better,
; clean up the code (It's very wasteful). For now, please except
; my apologies.
VERS equ 12
BDOS equ 5
*INCLUDE1 Z3BASE.LIB ; USE BASE ADDRESSES
;
; SYSTEM Entry Point
;
org RCP ; passed for Z3BASE
db 'Z3RCP' ; Flag for Package Loader
db 06 ; How long each name is
CTAB:
db 'H ' ; Help for RCP
dw CLIST
db 'SOPEN '
dw OPEN
db 'LOPEN '
dw LOPEN
db 'KEY '
dw KEY
db 'SCLOSE'
dw CLOSE
db 'LCLOSE'
dw LCLOSE
CTAB1:
db 0
;
; Banner Name of Rcp:
; Command List Routine
;
CLIST:
ld de,RCP$NAME
jp STRING
;
; Routines for SCR-TRAPing. From here to end, all is neccessary.
;
ORIGNAME equ 5ch
ONKEY equ '\' - '@'
;
KEY: ld de,KEYSTR
call STRING ; Print msg
GETKEY: ld e,0ffh
call DCIO ; Bring in a key
or a
jr z,GETKEY ; Keep at it 'till we get a key
ld (KEYON + 1),a ; Save key
bit 7,a
jr z,NOTHIGH ; Check for high bit
push af
ld e,'~' ; Print a ~
call DCIO
pop af
NOTHIGH:
and 01111111b ; Remove high bit
cp ' '
jr nc,NOTCTRL ; Check for control char
push af
ld e,'^' ; Print a '^'
call DCIO
pop af
add a,'@' ; Make normal char
NOTCTRL:
ld e,a
jp DCIO ; Print it
OPEN: ld a,(OPENFLG) ; Check to see if a file is already open
or a
jr z,CONTOPEN ; No
ld de,ALREADY ; Yes, print and abort
jp STRING
CONTOPEN:
ld hl,FILE
ld de,FILE + 1
ld bc,35
xor a
ld (hl),a ; Zap the whole FCB
ldir
ld hl,ORIGNAME
ld de,FILE
ld bc,13
ldir ; Move file name to protected memory
ld a,'?'
ld bc,0bh
ld hl,FILE + 1
cpir ; Check entire name for ambiguity
jr z,AMBIG
ld a,(5ch)
or a
jr nz,STOREU
ld c,25
call BDOS
inc a
ld (FILE),a
STOREU: ld hl,5ch + 13 ; Get user number
ld a,(hl)
ld (UNUM + 1),a ; Store it to user routine
call TOU ; Go to proper user #
ld c,13h
call FCBBDOS
ld c,16h
call FCBBDOS
ld c,16h
inc a ; 0ffh = No room
jp z,FULL ; No good? Then abort
ld de,OPENMSG
call STRING
ld hl,BUFFER
ld (POINTER),hl ; POINTER => first char of BUFFER
xor a
ld (ON),a
ld (COUNTER),a
ld hl,(1) ; Get BOOT location
ld de,0ah ; Offset for JP <LOCATON>
add hl,de
ld (JCON),hl ; Save location for JP to CONSOLE OUT
ld e,(hl)
inc hl
ld d,(hl) ; Move to de
ld (CON),de ; Save DE
ld de,NEWOUT
ld (hl),d
dec hl
ld (hl),e ; Fill our NEWOUT location in
ld hl,(1) ; Get BOOT location
ld de,07h ; Offset for JP <LOCATON>
add hl,de
ld (JCONIN),hl ; Save location for JP to CONSOLE IN
ld e,(hl)
inc hl
ld d,(hl) ; Move to de
ld (CONIN),de ; Save DE
ld de,NEWIN
ld (hl),d
dec hl
ld (hl),e ; Fill our NEWOUT location in
call SETBDOS
ld a,0ffh
ld (OPENFLG),a ; Show that there is a S file open
jp BACKU ; Come back to normal U
AMBIG: ld de,AMBIGSTR
jp STRING ; Print the message
NEWIN: call ORIGIN ; Bring key in
KEYON: cp ONKEY ; Is it the trigger key?
ret nz
ld a,(ON)
cpl
ld (ON),a ; Flip On to Off or Off to On
jp ORIGIN ; Get a new key
NEWOUT: push bc
call ORIGOUT ; Print the char
pop bc
ld a,(ON) ; Are we in trap mode?
or a
ret z
ld a,c
cp 26 ; EOF?
ret z
NOUT2: push hl
ld hl,(POINTER) ; Consider BUFFER point
ld (hl),c ; Store the Char
inc hl ; Go to next char in buffer
ld (POINTER),hl ; Save that point
pop hl
ld a,(COUNTER) ; Consider # of chars in buffer
inc a
cp 80h ; Time to write?
jr z,WRITE
ld (COUNTER),a ; Save counter
ret
WRITE: ld a,(BDOSFLG)
or a
jr z,DOWRITE
ld (PEND),a
push hl
push de
push bc
ld hl,BUFFER
ld (POINTER),hl
ld de,BUFF2
ld bc,128
ldir
xor a
ld (COUNTER),a
pop bc
pop de
pop hl
ret
DOWRITE:
push hl
call TOU ; Go to file's user number
ld c,26 ; Set dma
ld de,BUFFER ; At buffer
call BDOSCALL
xor a
ld (COUNTER),a ; No chars (start fresh)
ld hl,BUFFER
ld (POINTER),hl ; No chars in buffer
ld c,21 ; Write sequential
call FCBBDOS
pop hl
or a
jr nz,FULL ; No good, write msg
jp BACKU ; Come back to normal U ;~
FINISH:
push hl
call TOU ; Go to file's user number
ld c,26 ; Set dma
ld de,BUFF2 ; At buffer
call BDOSCALL
ld c,21 ; Write sequential
call FCBBDOS
pop hl
or a
jr nz,FULL ; No good, write msg
jr BACKU ; Come back to normal U
FULL: call BACKU ; Come back to normal U
ld de,FULLMSG
jp STRING
CLOSE: ld a,(OPENFLG) ; Is there really a file open?
or a
jr nz,CONTCLOSE ; Yes, Skip
ld de,NONE ; No
jp STRING
CONTCLOSE:
call CLRBDOS
xor a
ld (OPENFLG),a ; Save fact that there is no file open
ld hl,(JCONIN) ; Get place to restore
ld de,(CONIN) ; Get location that LISTST should JP to
ld (hl),e
inc hl
ld (hl),d ; Put in a JP and the location
ld hl,(JCON) ; Place to restore
ld de,(CON) ; Location to JP to
ld (hl),e
inc hl
ld (hl),d ; Put into place
call TOU ; Go to proper user #
ld c,26 ; Write an end of file
call NOUT2
ld a,(COUNTER) ; Was buffer just written?
or a
jr z,DONTWRITE ; Yes, don't write
ld c,26
ld de,BUFFER
call BDOSCALL ; Set DMA to BUFFER
ld c,21
call FCBBDOS ; Write sequential
DONTWRITE:
ld c,16
call FCBBDOS ; Close file
inc a
jr z,FULL ; No? Print msg.
ld de,CLOSEMSG
call STRING
jr BACKU ; Come back to normal U
STRING: ld c,9
jp BDOS
FCBBDOS:
ld de,FILE
jp BDOS
TOU: ld e,0ffh
call USER ; Get current user number
ld (CURU),a ; Store it
UNUM: ld e,00
jp USER ; Set to file's
BACKU: ld c,26
ld de,(DMA)
call BDOSCALL
ld a,(CURU) ; Get current user number
ld e,a
jp USER ; Go to it
;;;;;;;;;;;;;;; HACK, HEW, CUT, RIP!
LOPEN: ld a,(LOPENFLG) ; Check to see if a file is already open
or a
jr z,LCONTOPEN ; No
ld de,ALREADY ; Yes, print and abort
jp STRING
LCONTOPEN:
ld hl,LFILE
ld de,LFILE + 1
ld bc,35
xor a
ld (hl),a ; Zap the whole FCB
ldir
ld hl,ORIGNAME
ld de,LFILE
ld bc,13
ldir ; Move file name to protected memory
ld a,'?'
ld bc,0bh
ld hl,LFILE + 1
cpir ; Check entire name for ambiguity
jp z,AMBIG
ld a,(5ch)
or a
jr nz,LSTOREU
ld c,25
call BDOS
inc a
ld (LFILE),a
LSTOREU: ld hl,5ch + 13 ; Get user number
ld a,(hl)
ld (LUNUM + 1),a ; Store it to user routine
call LTOU ; Go to proper user #
ld c,13h
call LFCBBDOS ; Delete file
ld c,16h
call LFCBBDOS ; Create file
inc a ; 0ffh = No room
jp z,LFULL ; No good? Then abort
ld de,OPENMSG
call STRING
ld hl,LBUFFER
ld (LPOINTER),hl ; POINTER => first char of BUFFER
xor a
ld (LCOUNTER),a
ld hl,(1) ; Get BOOT location
ld de,0dh ; Offset for JP <LOCATON>
add hl,de
ld (JLIST),hl ; Save location for JP to list
ld e,(hl)
inc hl
ld d,(hl) ; Move to de
ld (LIST),de ; Save DE
ld de,NLOUT
ld (hl),d
dec hl
ld (hl),e ; Fill our NLOUT location in
ld hl,(1) ; Get BOOT address, again
ld de,2ah ; Offset for <JP> LOCATON
add hl,de
ld (JLISTST),hl ; Save JP LISTST location
ld (hl),3eh ; LD A,
inc hl
ld e,(hl)
ld (hl),0ffh ; 0ffh
inc hl
ld d,(hl)
ld (hl),0c9h ; RET instruction
ld (LISTST),de ; Save Location for JP
call SETBDOS
ld a,0ffh
ld (LOPENFLG),a ; And register the fact
jp LBACKU ; Come back to normal U
NLOUT:
ld a,c
cp 26
ret z
ZNLOUT: ld hl,(LPOINTER) ; Consider BUFFER point
ld (hl),c ; Store the Char
inc hl ; Go to next char in buffer
ld (LPOINTER),hl ; Save that point
ld a,(LCOUNTER) ; Consider # of chars in buffer
inc a
cp 80h ; Time to write?
jr z,LWRITE
ld (LCOUNTER),a ; Save counter
ret
LWRITE: xor a
ld (LCOUNTER),a ; No chars (start fresh)
ld hl,LBUFFER
ld (LPOINTER),hl ; No chars in buffer
ld a,(BDOSFLG)
or a
jr z,LDOWRITE
ld (LPEND),a
ret
LDOWRITE:
call LTOU ; Go to file's user number
ld c,26 ; Set dma
ld de,LBUFFER ; At buffer
call BDOSCALL
ld c,21 ; Write sequential
call LFCBBDOS
or a
jr nz,LFULL ; No good, write msg
jr LBACKU ; Come back to normal U
LFULL: call LBACKU ; Come back to normal U
ld de,FULLMSG
jp STRING
LCLOSE: ld a,(LOPENFLG) ; Is there really a file open?
or a
jr nz,LCONTCLOSE ; Yes, Skip
ld de,NONE ; No
jp STRING
LCONTCLOSE:
call CLRBDOS
xor a
ld (LOPENFLG),a ; Save fact that there is no file open
ld hl,(JLISTST) ; Get place to restore
ld de,(LISTST) ; Get location that LISTST should JP to
ld (hl),0c3h ; JP
inc hl
ld (hl),e
inc hl
ld (hl),d ; Put in a JP and the location
ld hl,(JLIST) ; Place to restore
ld de,(LIST) ; Location to JP to
ld (hl),e
inc hl
ld (hl),d ; Put into place
call LTOU ; Go to proper user #
ld c,26 ; Write an end of file
call ZNLOUT
ld a,(LCOUNTER) ; Was buffer just written?
or a
jr z,LDONTWRITE ; Yes, don't write
ld c,26
ld de,LBUFFER
call BDOSCALL ; Set DMA to BUFFER
ld c,21
call LFCBBDOS ; Write sequential
LDONTWRITE:
ld c,16
call LFCBBDOS ; Close file
inc a
jr z,LFULL ; No? Print msg.
ld de,CLOSEMSG
call STRING
jr LBACKU ; Come back to normal U
LFCBBDOS:
ld de,LFILE
jp BDOS
LTOU: ld e,0ffh
call USER ; Get current user number
ld (LCURU),a ; Store it
LUNUM: ld e,00
jp USER ; Set to file's
LBACKU: ld c,26
ld de,(DMA)
call BDOSCALL
ld a,(LCURU) ; Get current user number
ld e,a
jp USER ; Go to it
LFULLMSG:
db 'LTRCP Msg: Disk Full.$'
JLIST: dw 0
LIST: dw 0
JLISTST:
dw 0
LISTST: dw 0
LCURU: db 0
LOPENFLG:
db 0
LCOUNTER:
db 0
LPOINTER:
dw LBUFFER
LFILE:
ds 36
LBUFFER:
ds 129
;;;;;;;;;;;;;;; Paste, Glue, Tape!
;;;;;;;;;;;;;;; Suction, Damn it, I need more suction!
SETBDOS:
ld a,(LOPENFLG)
ld hl,OPENFLG
or (hl)
ret nz
ld hl,(6)
ld (BDOSCALL + 1),hl
ld de,3
sbc hl,de
ld (6),hl
ld (hl),0c3h
inc hl
ld de,CALLBDOS
ld (hl),e
inc hl
ld (hl),d
ret
CLRBDOS:
ld a,(LOPENFLG)
ld hl,OPENFLG
xor (hl)
ret z
ld hl,(BDOSCALL + 1)
ld (6),hl
ret
CALLBDOS:
ld a,0ffh
ld (BDOSFLG),a
ld a,c
cp 26
jr nz,NOTDMA
ld (DMA),de
NOTDMA:
call BDOSCALL
push af
xor a
ld (BDOSFLG),a
ld a,(PEND)
or a
jr z,P1
xor a
ld (PEND),a
call FINISH
P1: ld a,(LPEND)
or a
jr z,P2
xor a
ld (LPEND),a
call LWRITE
P2: pop af
ret
BDOSCALL:
jp 0000
USER: ld c,32
jp BDOS
DCIO: ld c,6
jp BDOS
OPENMSG:
db 'File open.$'
CLOSEMSG:
db 'File closed.$'
RCP$NAME:
db 'SLTRAP RCP vers ',(vers / 10) + '0'
db '.',(vers mod 10) + '0',13,10
db 'KEY',9,9,'- Change screen trigger key.',13,10
db 'SOPEN name.typ',9,'- Open a file for screen output.',13,10
db 'LOPEN name.typ',9,'- Open a file for list output.',13,10
db 'SCLOSE',9,9,'- Close the screen file.',13,10
db 'LCLOSE',9,9,'- Close the list file.$'
ALREADY:
db 'File already open.$'
NONE: db 'No file open.$'
AMBIGSTR:
db 'Bad file name.$'
FULLMSG:
db 'STRCP Msg: Disk Full.$'
KEYSTR: db 'Trigger key: $'
ORIGOUT:
db 0c3h ; JP
CON: dw 0
JCON: dw 0
ORIGIN:
db 0c3h ; JP
CONIN: dw 0
JCONIN: dw 0
ON: db 0
CURU: db 0
PEND: db 0
LPEND: db 0
BDOSFLG:
db 0
OPENFLG:
db 0
COUNTER:
db 0
POINTER:
dw BUFFER
DMA: dw 0000
FILE: ds 36
BUFFER: ds 129
BUFF2: ds 128
END
jr