; ; Program: REG ; Author: Richard Conn ; Version: 1.0 ; Date: 5 Mar 84 ; VERSION EQU 11 ; ; Version 1.1 mods, April 13, 1988 by Bruce Morgen ; Convert to Zilog and Type 3 format with safety header, establish ; "-" and "+" as synonyms for "M" and "P", respectively. No smart ; help message as REG is rather unlikely to ever be renamed. Put ; in test for values higher than 255 on immediate set options. ; The MSB of the errant value is poked into the program error flag ; for possible use in conditional scripts via IF [~]ER. ;VERSION EQU 10 ; ; REG is used to access the ZCPR3 Registers. It can set a value, ; display a value or all values, increment, and decrement them. ; ; ; Equates for Key Values ; Z3ENV DEFL 0FE00H ; Address of ZCPR3 environment FCB EQU 5CH FCB2 EQU 6CH CR EQU 0DH LF EQU 0AH ; ; External Z3LIB and SYSLIB Routines ; EXT Z3INIT,GETREG,PUTREG,GETMSG,GETQUIET,PUTER2 EXT EVAL10,EPRINT,COUT,CRLF,PADC ; ; Environment Definition ; External ZCPR3 Environment Descriptor ; TYPE 3 HEADER ; Code modified as suggested by Charles Irvine to function correctly with ; interrupts enabled. Program will abort with an error message when not ; loaded to the correct address (attempt to run it under CP/M or Z30). 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 a 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: LD HL,(Z3EADR) ; ; Start of Program -- Initialize ZCPR3 Environment ; CALL Z3INIT ; Initialize the ZCPR3 Environment ; ; Print Banner ; CALL GETQUIET JR NZ,QUIET CALL EPRINT DB 'REG, Version ' DB (VERSION/10)+'0','.',(VERSION MOD 10)+'0',CR,LF,0 ; ; Check for Availability of Registers ; QUIET: CALL GETMSG JR Z,NOMSG ; ; Check for Command ; LD HL,FCB+1 ; Pt to first FCB LD A,(HL) ; Get first char CP ' ' ; Check for help JR Z,HELP CP '/' ; Also help JR Z,HELP CP '#' ; Display all JP Z,DISPALL CP 'D' ; Display JP Z,DISPLAY CP 'M' ; Minus (decrement) JP Z,MINUS CP '-' ; Minus (decrement) JP Z,MINUS CP 'P' ; Plus (increment) JP Z,PLUS CP '+' ; Plus (increment) JP Z,PLUS CP 'S' ; Set JP Z,SETRG CP '0' ; Convert to binary JR C,HELP CP '9'+1 ; Range? JR NC,HELP JP DISP1 ; ; Print Error Message ; NOMSG: CALL EPRINT DB CR,LF,'No Registers Available',0 RET ; ; Print Help Message ; HELP: CALL EPRINT DB CR,LF,'REG - Set/Display/Increment/Decrement Registers' DB CR,LF,'Syntax:' DB CR,LF,' REG Dr or REG r <-- Display Reg r' DB CR,LF,' REG Mr or REG -r <-- Minus (Decrement) Reg r' DB CR,LF,' REG Pr or REG +r <-- Plus (Increment) Reg r' DB CR,LF,' REG Sr val <-- Set Reg r to val' DB CR,LF,'where "r" may be 0-9 for' DB CR,LF,'one reg or # for all regs' DB 0 RET ; ; Display Register ; DISPLAY: INC HL ; Pt to value LD A,(HL) ; Get it DISP1: CP '#' ; Display all? JR Z,DISPALL ; ; Display Particular Register ; CALL COMPREG ; Compute register number in B CALL GETREG ; Return register value in A ; ; Print Register whose Number is in B and Value in A ; REGPRINT: LD C,A ; Value in C CALL EPRINT DB ' Reg ',0 LD A,B ADD A,'0' ; Convert to ASCII CALL COUT CALL EPRINT DB ' = ',0 LD A,C ; Print value JP PADC ; ; Display All Registers ; DISPALL: LD B,0 ; Loop 0 to 9 DISPA1: CALL GETREG ; Get register CALL REGPRINT ; Print register CALL EPRINT DB ' ',0 INC B ; Increment count LD A,B ; Check for new line AND 3 CALL Z,CRLF LD A,B ; Check for done CP 10 JR NZ,DISPA1 RET ; ; Convert ASCII Char in A to Register Number in B with error check ; COMPREG: CP '0' ; Convert to binary JR C,RERR CP '9'+1 JR NC,RERR SUB '0' ; Convert to binary LD B,A ; Return value in B RET RERR: LD B,A ; Save char POP AF ; Clear stack CALL EPRINT DB ' Invld Reg ID: ',0 LD A,B ; Get char JP COUT ; ; Set Register Value ; SETRG: INC HL ; Pt to register LD A,(HL) ; Get char CP '#' ; All registers? JR Z,SETALL CALL COMPREG ; Get register number in B LD HL,FCB2+1 ; Pt to value CALL EVAL10 ; Evaluate INC D ; Don't allow big number DEC D JR NZ,TOOBIG LD C,A ; Save value in C CALL PUTREG ; Set register JR REGPRINT ; Print value ; ; Set All Registers ; SETALL: LD HL,FCB2+1 ; Pt to value CALL EVAL10 INC D ; Don't allow big number DEC D JR NZ,TOOBIG LD C,A ; Value in C LD B,0 ; Set 10 registers SETA1: LD A,C ; Get value CALL PUTREG ; Set value INC B ; Increment reg number LD A,B CP 10 JR NZ,SETA1 JR DISPALL ; Display all registers TOOBIG: CALL EPRINT DB CR,LF,'Register value cannot exceed 255',0 LD A,D ; MSB to A JP PUTER2 ; Poke as Program Error and quit ; ; Reg = Reg - 1 ; MINUS: INC HL ; Pt to number LD A,(HL) ; Get it CP '#' ; All? JR Z,MINALL CALL COMPREG ; Compute register number CALL GETREG ; Get register DEC A ; -1 CALL PUTREG ; Restore register JP REGPRINT ; Print result ; ; All Registers - 1 ; MINALL: LD B,0 ; Set loop MINA1: CALL GETREG ; Get register DEC A ; -1 CALL PUTREG ; Restore register INC B ; Count LD A,B ; Done? CP 10 JR NZ,MINA1 JP DISPALL ; Display all regs ; ; Reg = Reg + 1 ; PLUS: INC HL ; Pt to register LD A,(HL) ; Get it CP '#' ; All? JR Z,PLUSALL CALL COMPREG ; Compute value CALL GETREG ; Get value INC A ; +1 CALL PUTREG ; Put value JP REGPRINT ; Print value PLUSALL: LD B,0 ; Set counter PLUSA1: CALL GETREG ; Increment value INC A CALL PUTREG INC B ; Count LD A,B CP 10 JR NZ,PLUSA1 JP DISPALL ; Print reg values END