; PROGRAM: Z33FILLD.Z80 ; VERSION: 1.0D [beta test] ; DATE: 19 March 1988 ; AUTHOR: Fred Haines ; PURPOSE: Fills memory from a starting address to an ending address ; with a single byte, all three specified from the command ; line in hexadecimal. ; Copyright 1988 by Fred Haines. A ZSIG submission. This program is ; made freely available to the Z System community for all noncommercial ; purposes. Please send source code of any improvements to the author ; at 733 N King's Rd #331, Los Angeles CA 90069. ; Syntax: FILL ssss eeee [bb] ; Fill memory from address SSSS to address EEEE with ; byte BB (defaults to 00h), all values hexadecimal. ; Version 1.0d - Fred Haines 3-25-88 ; ; Eliminated program banner unless help is requested, and made report ; of memory filled dependent upon quiet flag - if quiet is set, you see ; nothing at all. Introduced several economies of code which Rob ; Friefeld pointed out, and changed my mind again about the syntax of ; the ending address. If, under the influence of DDT and other debuggers, ; you type FILL 0900 09FF 1A (or even FILL 0900,09FF,1A, with commas or ; any other punctuation) you will fill up to and including 09FF, and ; FILL 0900 0900 1A will fill the single byte at 0900h. ; Version 1.0c - Fred Haines 3-20-88 ; ; Reset flags with OR A instruction at top of SUBTRACT routine to ; make SBC a true 16-bit subtract operation, permitted correction of ; spatchcocked code requiring extra INC HL instructions. Revised ; logic back to earlier idea to exclude end address from fill. I ; wanted the syntax to follow DDT's F command's, but discovered that ; it doesn't allow you to fill a single byte (Fnnn0,nnn1,0), and I ; thought that was a capacity worth having. So this version again ; requires you to type FILL 0800 0900 to zero a page, rather than ; FILL 0800 08FF. ; Version 1.0b - Fred Haines 3-19-88 ; ; V1.0a was inadvertantly released with an earlier, incorrect version ; of this file with a catastrophic error in it. ; Version 1.0a - Fred Haines 3-18-88 ; ; End address is now included in fill. Some error checking introduced - ; three-digit addresses accepted. Syntax changed to use spaces or any ; punctuation. Result reported to console. Now self-renaming. ; Version 1.0 ; ; End address eeee is not included in the fill. Write FILL 0700,0800,00 ; rather than FILL 0700,07FF,00. No error checking, but perhaps it doesn't ; need it. Not self-renaming... What else are you going to call it? PHIL? ; The truth is I couldn't figure out how to get it to rename itself, since ; GETEFCB doesn't work for me, returns junk. VERS EQU 10 Z3ENV DEFL 0FE00H FALSE EQU 0 TRUE EQU NOT FALSE EXT BOUT ; print character in A to console EXT EPRINT ; exact print routine EXT EVAL16 ; ASCII-to-binary conversion EXT FILLBC ; memory fill routine EXT GETEFCB ; address of external FCB EXT GETQUIET ; get quiet flag EXT ISPUN ; is character punctuation? EXT ISSP ; is character a space? EXT PA2HC EXT PHL4HC ; print HL as 4-digit hex EXT SKSP ; skip space EXT SKPUN ; skip punctuation EXT Z3INIT ; init buffers ; CP/M equates FCB EQU 5CH ; FCB CR EQU 13 ; LF EQU 10 ; TBUFF EQU 0080h ; pointers to start address of memory to ; environment definition - type 3 header ENTRY: JR START0 ; must use relative jump NOP ; filler DB 'Z3ENV',3 ; type-3 environment Z3EADR: DW Z3ENV ; filled in by Z33 DW ENTRY ; intended load address START0: LD HL,0 ; point to warmboot entry LD A,(HL) ; save the byte there DI ; protect against interrupts LD (HL),0C9H ; replace warmboot with return opcode RST 0 ; call address 0, pushing RETADDR ; onto stack RETADDR: LD (HL),A ; restore byte at 0 DEC SP ; get stack pointer to point DEC SP ; to the value of RETADDR POP HL ; get it into HL and restore stack EI ; we can allow interrupts again LD DE,RETADDR ; this is where we should be XOR A ; clear carry flag PUSH HL ; save address again SBC HL,DE ; subtract - we should have 0 now POP HL ; restore value of RETADDR JR Z,START ; if addresses matched, begin real code LD DE,NOTZ33MSG-RETADDR ; offset to message ADD HL,DE EX DE,HL ; switch pointer to message into DE LD C,9 JP 0005H ; return via BDOS print string function NOTZ33MSG: DB 'Not Z33+$' ; abort message if not Z33-compatible ; start of program - initialize and look for help request START: LD HL,(Z3EADR) ; Point to ZCPR3 environment CALL Z3INIT ; initialize LD A,(FCB+1) ; get first char of command tail CP ' ' ; no command tail? JR Z,HELP ; print help screen CP '/' ; help requested? JP NZ,EXTRACT ; if not, go get the input ; print help screen HELP: CALL EPRINT DB 'Z33FILL version ' DB VERS/10+'0','.',(VERS MOD 10)+'0',' [ZSIG] loaded at ',0 LD HL,ENTRY CALL PHL4HC ; print address at which program is linked CALL EPRINT DB 'h' DB CR,LF,LF DB 'Syntax: ',0 CALL COMNAM CALL EPRINT DB ' ssss eeee [bb]',CR,LF,LF DB 'Fill memory from address SSSS to address EEEE with',CR,LF DB 'byte BB (defaults to 00h), all values hexadecimal.',CR,LF DB 0 RET ; get input parameters from command line tail at 0082h EXTRACT: LD HL,TBUFF+2 ; point to start address in command tail CALL EVAL16 ; convert to binary in DE LD (LOW),DE ; ..and store to buffer CALL SKSP ; skip over spaces CALL SKPUN ; ..or punctuation CALL EVAL16 ; convert end address to binary in DE LD (HIGH),DE ; ..and store to buffer CALL SKSP ; skip over spaces CALL SKPUN ; ..or punctuation LD A,(HL) ; get fill character into A OR A ; gives Z if A=0 CALL NZ,EVAL16 ; if not terminator, evaluate ; subtract low address from high to get number of bytes to fill SUBTRACT: OR A ; reset flags LD HL,(HIGH) ; get high address from temporary storage LD DE,(LOW) ; ..and low address too SBC HL,DE ; 16-bit result in HL JR C,ERROR ; bail out if high lower than low PUSH HL ; ..pushed onto the stack POP BC ; ..and popped back up in another register INC BC ; add 1 to correct arithmetic EX DE,HL ; switch start address (low) from DE into HL FILL: CALL FILLBC ; start address now in HL, number of bytes to ; ..fill in BC, and fill byte in A ; report activity to console if quiet not set REPORT: CALL GETQUIET ; check quiet flag RET NZ ; ..and quit if quiet set CALL EPRINT ; report result to console DB 'Z33FILL: memory from ',0 LD HL,TBUFF+2 ; get starting address again LD B,4 ; get set to read four characters CALL PRNT ; ..and print them to console CALL EPRINT ; continue with message DB 'h to ',0 CALL SKSP ; skip space CALL SKPUN ; ..or punctuation LD B,4 ; set to read four more characters CALL PRNT CALL EPRINT ; continue with message DB 'h filled with ',0 LD A,(HL) ; get fill byte in A OR A ; get flag to check for zero JR Z,NULL ; go print it to console CALL SKSP ; else, skip space CALL SKPUN ; ..or punctuation to get to input fill byte LD B,2 ; print two characters CALL PRNT JR FINISH NULL: CALL PA2HC FINISH: CALL EPRINT ; and finish the message DB 'h.',0 RET PRNT: LD A,(HL) ; get character to print into A CALL ISSP ; is it a space? RET Z ; quit CALL ISPUN ; or some other punctuation? RET Z ; skip back, else CALL BOUT ; ..print it to console INC HL ; bump pointer to next character DJNZ PRNT ; if not done loop for another character RET ; input error trap ERROR: CALL EPRINT ; print error message DB 'Starting address must be below ending address.',0 RET ; ..and go home ; print actual command name in help screen, otherwise default to FILL COMNAM: CALL GETEFCB ; get address of Z system's external FCB JR Z,NOEFCB ; if there isn't one, use POKE as command name LD B,8 ; counter for maximum characters in file name COMNML: INC HL ; command name starts at EFCB + 1 LD A,(HL) ; get first character in A CP ' ' ; is it the space used as terminator? CALL NZ,BOUT ; if not, print it to console DJNZ COMNML ; ..and keep going until we do hit a space RET NOEFCB: CALL EPRINT DB 'FILL',0 ; default command name in help screen RET ; data storage HIGH: DS 2 ; two-byte buffer for end address LOW: DS 2 ; buffer for start address END