title '//SKIP.MAC Transfer control in Submit file' ; ; by Gary Novasielski. ; ; 2.1 86/10/16 $$$.SUB file always on A0: for CCP+ ; ; 2.0 85/10/20 accepts ";" indicating remainder of ; line is a comment. C.B. Falconer ; version equ 21; was 10 ; @msg set 9 @opn set 15 @cls set 16 @del set 19 @usr set 32 query equ 0ffh; queries to CPM ; cpmbase equ 0 boot set cpmbase bdos set boot+5 tbuff equ boot+80h tpa equ boot+100h ctrl equ ' '-1; Ctrl char mask cr set ctrl and 'M' lf set ctrl and 'J' ; cpm macro func,operand if not nul operand lxi d,operand endif;; of not nul operand if not nul func mvi c,@&func endif call bdos endm ; fcbs2 equ 14 fcbrc equ 15 fcbr0 equ 33; Offsets into File Control Blocks fcbr1 equ 34 fcbr2 equ 35 ; org tpa ; skipprog: jmp pastc ; db ' V', version/10+'0', '.', version mod 10+'0' db ' Copyright (c) 1982 Gary P. Novosielski ' db ctrl and 'Z' ; pastc: lxi h,0; Clear HL dad sp; Get Stack Pointer value lxi sp,lclstak; Set up local stack push h; Save old SP on new stack ; " " mvi a,query call sgusr sta user; save entry user mvi e,0 cpm usr; rest is on user 0 lxi h,tbuff; point to Command Buffer mov a,m; get count inr a; Point past end of string call hlxa; Index the pointer mvi m,0; Insist on null terminator ; " " lxi h,tbuff+1; base of command buffer call scnb; scan to first non-blank ora a; An argument present? jnz evalarg; Yes, evaluate it. cpi ';' jnz evalarg; not terminated by ; for comment lxi h,1; Else default to one jmp evalexit; Don't do the loop ; evalarg: xchg; Scan pointer to DE lxi h,0; initialize value evaloop: ldax d; Get character ora a; Terminator? jz evalexit; exit loop cpi ';' jz evalexit; rest of line is comment ; " " call isnum; Test range 0-9 ASCII jc notnum; argument not numeric sui '0'; Make it binary ; " " ; Multiply current value in HL by 10 mov b,h mov c,l dad b; *2 dad h; *4 dad b; *5 dad h; *10 ; " " ; Add in new value from A call hlxa ; " " inx d; bump argument pointer jmp evaloop ; ; Range test. Must be 1-127 evalexit: mov a,l ani 080h ora h jnz rangerr ora l jz exit; Skip 0 lines = do nothing ; " " ; OK so far. Now skip over (L) lines in the .SUB file push h; Save the value cpm opn,subfile; Open the $$$.SUB file. pop d; Restore the value ; " " inr a; Test return code. jz suberr; Not within a .SUB file?? lxi h,subfile+fcbrc; Record counter for the extent mov a,m ; " " sub e; Reduce by number skipped and jc nelerr; (Not enough lines remaining) ; " " mov m,a; put back into the FCB xra a; And a zero goes into sta subfile+fcbs2; the S2 byte to mark file altered cpm cls,subfile; Write change to directory. inr a; Trouble? jz suberr ; " " ; Ok, all finished. exit: call suser; restore entry user pop h; Old SP sphl; Restore Stack ret; to Console Command Processor ; suberr: call abend db 'Error accessing .SUB file.' db '$' ; ; Argument is not numeric notnum: call abend db '//SKIP argument not numeric.' db '$' ; rangerr: nelerr: call abend db '//SKIP argument exceeds file size.' db '$' ; abend: pop d; Message address cpm msg; Send to console cpm del,subfile; Abort the jobstream cpm msg,cancel call suser; restore entry user jmp boot ; cancel: db '...CANCELED' db '$' ; ; ; Utility subroutines ; ; set user # suser: lda user ; " " ; set/get user # sgusr: mov e,a cpm usr ret ; ; Index HL by the value of A. Returned flags not defined ; a,f,h,l hlxa: add l mov l,a adc h sub l mov h,a ret ; ; Scan over leading blanks. Return char in A ; a,f,h,l scnb: mov a,m cpi ' ' rnz inx h jmp scnb ; ; Return carry set if not ASCII decimal char 0-9. ; f isnum: cpi '0' rc cpi '9'+1 cmc ret ; user: db 0; User # at entry ; subfile: db 1; Drive A: db '$$$ SUB' db 0,0,0,0 ds subfile-$+36 ; ds 48 lclstak equ $ ; end skipprog