;--------------------------------------------------------------------- ; SPCANCEL.ASM program to cancel a selected spool queue entry ; For CP/M+ Print Spooler Version 1.3 (development version). ; (c) Andy Metcalfe, March 1989. ;--------------------------------------------------------------------- ; getdir equ 43 ; Get spool directory qlist equ 44 ; Get address of spool queue abortp equ 45 ; Cancel one queue entry ; ;--------------------------------------------------------------------- ; extrn blkmov ; Block move B chars from [DE] to [HL] extrn suxhd ; Subtract DE from HL extrn conchr ; Print char A at console extrn cncrlf ; Print at console extrn cstrng ; Print '$' terminated string at console extrn strtyp ; Set string format (contiguous/MBASIC) extrn cmphd ; Compare HL & DE extrn pnamef ; Print filename with fcb [DE] extrn pdecml ; Print decimal value of HL extrn ascbin ; Convert ASCII string to 16 bit binary ; ;--------------------------------------------------------------------- ; jp gostop ; db 'SPCANCEL v1.3 ' db '(c) March 1989 by Andy Metcalfe ' ; gostop: ld sp,stack ld c,getver call bdos ; Version check cp 31h ld de,noplus jp c,error ; No go if earlier than v3.1 ; ld a,(cpmbuf) or a ld de,nospec jp z,error ; Error if command line not specified ; ld a,qlist ld (rsxpb),a call gorsx ; HL=queue list data address or 00ffh ld de,00ffh call cmphd ; No answer? ld de,qempty jp z,error ; Don't proceed if queue empty ; ld a,(hl) or a jp z,error ; Qnow=0, so queue empty ; ld (qnow),a ; Else store it inc hl ld a,(hl) ld (qnext),a ; Pointer to next free element inc hl ld a,(hl) ld (qmax),a ; Max no of queue entries inc hl ; HL addresses first queue entry ld (qstart),hl ; Save address of queue start ; ; Parse command line for queue index no of file to cancel ; xor a call strtyp ; String format = contiguous ld hl,cpmbuf call ascbin ; Convert command line tail to binary in DE ld a,e ld (qstop),a ; Save queue no to stop (low byte) ld a,d or a ; Check if high byte 0 ld de,qbad jp nz,error ; If not, overflowed ld a,b or a ; Ascbin error code jp nz,error ; Error: queue non numeric or overflowed ; ; Validate queue index number ; ld a,(qstop) call qvalid or a ld de,qbad jp z,error ; Queue no out of range or already cancelled ; ; Call RSX getdir to find out location of spool directory ; ld a,getdir ld (rsxpb),a call gorsx ; H=spool directory user area, L=drive ld a,h ld (splusr),a ld a,l ld (spldrv),a ; ; Call RSX abortp to cancel printing ; ld a,abortp ld (rsxpb),a ld a,(qstop) ld (rsxpb+2),a call gorsx ; Tell the RSX to cancel printing that file ; ; Erase copy of cancelled file in spool directory ; ld hl,ifcb ; HL=address of fcb to use for erase ld a,(qstop) ; A=index of file to cancel call makfcb ; Make a "SPOOLED.nnn" fcb with correct index no call erafil ; Erase it ; ; Chain queue lister program (SPQ.COM) ; ld de,comand ld hl,cpmbuf ld b,4 call blkmov ; Transfer 4 byte command to default DMA buffer at 0080h ld c,chprog ; BDOS function 47 (Chain Program) ld e,0ffh ; Chain flag: leave default drive/user alone jp bdos ; Chain SPQ.COM (assumes default drive/user ; Or search chain etc set, otherwise warm boots) ; ;--------------------------------------------------------------------- ; Error handler ; error: call cstrng ld c,wboot jp bdos ; ;--------------------------------------------------------------------- ; Call RSX using parameter block [rsxpb] ; gorsx: ld de,rsxpb ld c,calrsx jp bdos ; ;--------------------------------------------------------------------- ; Validate queue index no in A against qnow & qnext ; NB Doesn't check whether printing of this file has ; already been cancelled. ; qvalid: ld e,a ld a,(qnext) ld c,a ld a,(qnow) ld b,a cp c ; Qnow=qnow? jp nc,valid ; Yes: maybe valid xor a ret ; Else invalid ; ; Queue not wrapped round: valid if qnow<=index AND index=qnext, so invalid ; ; Queue no within range: check whether cancelled already ; valid: call pointq ; HL=address of queue entry ld de,12 add hl,de ; HL addresses queue no entry ld a,(hl) cpl ; A=0 if cancelled, so invalid or a ret z ld a,0ffh ret ; ;--------------------------------------------------------------------- ; Routine to multiply A by 16, returning result in HL. ; All registers preserved. ; NOTE: Alternative method would be to copy A to HL, then shift ; left 4 times. ; mlt16: push de push af ld hl,0 ld de,16 mlt16a: or a jp z,mlt16b add hl,de dec a jp mlt16a ; mlt16b: pop af pop de ret ; ;--------------------------------------------------------------------- ; Return HL=address of queue entry with index no A. ; A, BC and DE are preserved. ; pointq: push af dec a push de call mlt16 ; HL=16*(queue no-1), or offset to entry ex de,hl ld hl,(qstart) ; HL=address of queue add hl,de ; HL addresses queue entry pop de pop af ret ; ;--------------------------------------------------------------------- ; Erase current file in spool directory ; erafil: call gousr ; Go to spool user area ld de,ifcb ld c,delete call bdos ; Try to delete spooled file call bakusr ; Back to original user area ret ; ;--------------------------------------------------------------------- ; Routine to set up an fcb, at [HL], for a spooled file with ; queue index no in A. ; The fcb is of the form d:SPOOLED.nnn, where nnn is the queue ; index no. ; makfcb: push af ld a,(spldrv) ld (hl),a ; Set up drive code ld de,filnam inc hl ld b,8 ; 8 bytes to copy call blkmov ; Copy default filename to fcb ('SPOOLED') pop af ex de,hl ; DE addresses filetype ld l,a ld h,0 ; HL=index no to store push de ; Save fcb pointer ld de,-100 call places ; Count 100s (returned in A, HL contains remainder) pop de ; HL addresses filetype ld (de),a ; Set first digit inc de push de ld de,-10 call places ; Count 10's pop de ld (de),a inc de ld a,l ; A=remainder add a,'0' ; Add bias ld (de),a ; Store least significant digit ret ; places: ld c,'0'-1 ; Bias less 1 ploop: inc c add hl,de jp c,ploop ; Repeat if CY=1 call suxhd ; HL=HL-DE ld a,c ; Returned char in A ret ; Char in A ; ;--------------------------------------------------------------------- ; Save current user no in [userno], and set user area to that of ; the spool directory. ; gousr: push hl push de push bc push af ld e,0ffh ld c,user call bdos ; Get current user no ld (userno),a ; Saved ld a,(splusr) ; User no to set for spool directory ld e,a ld c,user call bdos ; Go there pop af pop bc pop de pop hl ret ; ;--------------------------------------------------------------------- ; Restore user no stored by gousr ; bakusr: push hl push de push bc push af ld a,(userno) ld e,a ld c,user call bdos pop af pop bc pop de pop hl ret ; ;--------------------------------------------------------------------- ; Program messages ; dseg ; noplus: db 'Sorry, this program requires CP/M+',cr,lf,'$' ; nospec: db cr,lf,'ERROR: Queue index number not specified',cr,lf db 'The correct syntax is: SPCANCEL n, where n is the queue' db cr,lf,'index number of the file to cancel',cr,lf,'$' ; qempty: db cr,lf,'*** The Spool Queue Is Empty ***',cr,lf,'$' ; qbad: db cr,lf,'ERROR: Invalid queue index number',cr,lf,'$' ; ;--------------------------------------------------------------------- ; Scratch Pad Area ; splusr: db 15 spldrv: ds 1 userno: ds 1 qnow: ds 1 qnext: ds 1 qmax: ds 1 qstop: ds 1 rsxpb: ds 2 qstart: ds 2 ifcb: ds 33 filnam: db 'SPOOLED ' comand: db 'SPQ',0 ; CCP command line to chain queue lister ds 50 stack equ $ ; end