ORG #8000 .. 08/20/17: D. Hunter .. UT4V - version modified for MicroVIP .. uses scratch pad at C000 rather than 8C00 .. replaced output port functions because those are for the CDP18S020 board .. .. NOTES: .. 1. This was written for teletype speeds, use 300 baud for the serial port .. 2. The RCA list file format is designed to be compatible with the !M command .. so a listing can be sent to UT4 directly without needing a separate .. hex or binary file .. 3. Q (inverted) = serial out, EF2 (inverted) = serial in ................................................................................. .. UT4 IS A UTILITY PROGRAM TO ALTER .. MEMORY, DUMP MEMORY AND BEGIN PROGRAM .. EXECUTION AT A GIVEN LOCATION. THE COMMANDS ACCEPTED ARE: .. .. $PHHHH (BEGIN EXECUTION AT THE SPECIFIED LOCATION WITH R0 AS PROGRAM COUNTER) .. !MHHHH (PUT DATA AT SPECIFIED LOCATION) .. ?MHHHH HHHH (OUTPUT DATA FROM SPECIFIED LOCATION FOR SPECIFIC COUNT) .. .. AT THE BEGINNING OF A COMMAND ALL CHARACTERS ARE .. IGNORED UNTIL A ?,! OR $ IS ENCOUNTERED. IN THE ?M AND !M COMMANDS .. NON HEX CHARACTERS ARE IGNORED AFTER M UNTIL A .. HEX IS READ, THEN THE FIRST NON HEX CHARACTER MUST BE A SPACE. .. NON HEX CHARACTERS BETWEEN HEX PAIRS OF THE DATA IN .. THE !M COMMAND ARE IGNORED EXCEPT FOR CR, SEMICOLON AND COMMA. .. THE BAUD RATE OF UT4 IS DEPENDENT UPON THE TERMINAL BEING USED. .. A CR OR LF IS ENTERED AT THE BEGINNING TO SPECIFY THE APPROPRIATE .. DELAY BETWEEN BITS. UT4 WILL ECHO CHARACTERS IF A CR IS CHOSEN AS THE .. TIMING CHARACTER. ECHOING WILL NOT TAKE PLACE IF A LF IS INPUT .. AS THE TIMING CHARACTER. .. UT4, AT INITIALIZATION, STORES ALL REGISTERS BETWEEN 8C00 AND 8C1F IF IT .. FINDS RAM THERE. (BUT R0, R1 AND R4.1 ARE CLOBBERED) PTER: EQU #00 .. AUXILIARY FOR MAIN ROUTINE CL: EQU #01 .. CLOBBERED ST: EQU #02 .. STACK POINTER-ONLY .. REFERENCE TO RAM SUB: EQU #03 .. SUBROUTINE PC PC: EQU #05 .. MAIN PROGRAM COUNTER SWITCH: EQU #01 .. DISTINGUISHES BETWEEN ?M AND !M DELAY: EQU #0C .. DELAY ROUTINE PROGRAM COUNTER ASL: EQU #0D .. HEX ASSEMBLY REG ON INPUT. .. AUX FOR HEX OUTPUT CENTER: EQU #0D .. USED TO COUNT OUTPUT BYTES AUX: EQU #0E .. AUX.1 HOLDS BIT-TIME CONSTANT CHAR: EQU #0F .. CHAR.1 HOLDS I/O BYTE .. .. ENTER IN R0 NOP LDI A.1(UT4) .. SET PC WHILE PHI R0 .. ROM MAPPED TO LOWEST PAGE .. .. THE FOLLOWING WRITE REGISTER CONTENTS INTO .. C000-C01F IF IT EXISTS. BFFE IS ASSUMED NOT .. TO BE RAM (ELSE ROUTINE OVERRUNS) LDI #C0 PHI CL .. CL IS CLOBBERED .. BY THIS ROUTINE LDI #1E PLO CL .. SET UP WHRE RF.0 .. IS TO GO, MINUS 1 LDI #A0 PHI R4 .. R4.1 STORES A MODIFIED .. INSTRUCTION SEX CL LOOP2: LDI #D0 STR CL .. SET UP SEP INSTRUCTION .. FOR RETURN XOR .. CHECK THAT IT WROTE BNZ UT4 DEC CL .. PREPARE FOR MODIFIED .. INSTRUCTION GHI R4 ADI #70 .. SEE IF IT IS IN THE 90'S BDF * + #04 ADI #21 .. IF NO, 8N BECOMES 9N ADI #7F .. IF YES, 9N BECOMES 8(N-1) PHI R4 STR CL .. SET MODIFIED INSTR .. INTO RAM XOR .. CK THAT IT WROTE BNZ UT4 .. EXIT WHEN OUT OF RAM SEP CL .. GO TO EXECUTE INSTR .. (80-9F) STR CL .. STORE RESULT IN RAM DEC CL DEC CL .. BACK UP FOR NEXT BYTE BR LOOP2 UT4: GHI R0 PHI PC PHI SUB .. #80-> PC.1 .. AND SUB.1 LDI A.0(UT4A) PLO PC SEP PC UT4A: SEX PC DIS ,#55 .. NOTE PC=5 ASSUMED HERE OUT 5 ,#01 .. SELECT Q FOR SERIAL OUTPUT SEX PC .. NOP SEX PC .. NOP LDI A.0(TIMALC) PLO SUB .. READ ONE .. TO SET TIMER SEP SUB .. .. INITIALIZATION NOW DONE .. START: LDI A.0(TYPE5D) PLO SUB SEP SUB ,#0D .. CR = CARRIAGE RETURN ST2: SEP SUB ,#0A .. LF = LINE FEED SEP SUB ,#2A .. * AS PROMPT CHARACTER IGNORE: LDI #00 PLO ASL PHI ASL .. PREPARE TO INPUT .. HEX DIGITS, CLEAR ASL LDI A.0(READAH) PLO SUB SEP SUB .. INPUT COMMAND XRI #24 .. IS IT $ ? BZ DOLLAR XRI #05 .. IS IT ! ? (TEST WITH $.XOR.!) PLO SWITCH .. AND SAVE RESULT LSZ .. EQUIV TO BR RDARGS XRI #1E .. IS IT ? .. ? (TEST WITH $.XOR.!.XOR.?) BNZ IGNORE .. IGNORE ALL UNTIL A COMMAND IS .. READ .. .. THE FOLLOWING IS COMMON FOR ?M AND !M .. (SWITCH.0 = 0 FOR THE LATTER) .. RDARGS: SEP SUB .. NOTE SUB AT READAH. NOW .. READ HEX ARGS XRI #4D .. SHOULD BE M BNZ SYNERR RD1: SEP SUB BNF * - #01 .. IGNORE NON HEX CHARS. .. AFTER M. SEP SUB BDF * - #01 .. READ IN FIRST ARG .. (LOCATION IN MEMORY) XRI #20 .. NEXT CHAR SHOULD BE A SPACE BNZ SYNERR GHI ASL PHI PTER GLO ASL PLO PTER .. PTER NOW POINTS INTO .. USER MEMORY GLO SWITCH .. LOOK AT SWITCH BZ EX1 .. IF 0 IT WAS ! .. OTHERWISE IT WAS ? .. THE FOLLOWING DOES (?M LOC COUNT) COMMAND .. LDI #00 PLO ASL PHI ASL .. CLEAR ASL RD2: SEP SUB BDF RD2 .. READ IN SECOND ARG .. (NUMBER OF BYTES) XRI #0D .. NEXT CK FOR CR BNZ SYNERR LDI A.0(TYPE5D) PLO SUB .. TYPE GLO ASL PLO SWITCH GHI ASL PHI SWITCH LINE: SEP SUB ,#0A .. LF LINE1: GHI PTER PHI CHAR .. PREPARE LINE READING LDI A.0(TYPE2) PLO SUB SEP SUB .. TYPE 2 HEX DIGIT GLO PTER PHI CHAR LDI A.0(TYPE2) PLO SUB SEP SUB SEP SUB .. TYPE SPACE ,#20 .. TLOOP: LDA PTER PHI CHAR .. FETCH 1 BYTE FOR TYPING LDI A.0(TYPE2) PLO SUB SEP SUB .. TYPE 2 HEX DEC SWITCH GLO SWITCH BNZ TL3 .. BRANCH IF NOT DONE YET GHI SWITCH BZ START .. BRANCH IF DONE TL3: GLO PTER ANI #0F .. IF PTER IS DIV BY 16 BNZ TL2 SEP SUB ,#3B .. IF YES, TYPE ; THEN SEP SUB ,#0D .. CR AND BR LINE TL2: SHR .. DIV BY 2? BDF TLOOP .. IF NO LOOP BACK, ELSE BR TLOOP - #02 .. AND THEN LOOP BACK .. .. THE FOLLOWING DOES (!M LOC DATA) COMMAND .. ENTER AT EX1 .. .. EFFECT OF THE FOLLOWING IS TO READ IN HEX .. TERMINATING WITH A CR, IGNORING NON-HEX CHARS .. PAIRS; EXCEPTIONS: A COMMA BEFORE A CR ALLOWS .. THE INPUT TO CONTINUE ON THE NEXT LINE AND A .. SEMICOLON ALLOWS AN !M COMMAND TO .. BE ASSUMED .. EX3: SEP SUB .. INPUT UNTIL A HEX IS READ BNF EX3 .. EX2: SEP SUB .. LOOKING FOR SECOND HEX DIGIT BNF SYNERR .. BR IF NOT HEX GLO ASL STR PTER .. **SET BYTE** INC PTER EX1: SEP SUB .. NOTE SUB AT READAH BDF EX2 .. BR IF HEX XRI #0D .. CHECK IF CR BZ START EX4: XRI #21 .. ELSE CK IF COMMA .. (TEST WITH CR.XOR.,) BZ EX3 .. IF ELSE BRANCH XRI #17 .. CK FOR SEMICOLON (TEST WITH .. CR.XOR.,.XOR.;) BNZ EX1 .. IGNORE ALL ELSE SEP SUB .. ON SEMI IGNORE ALL UNTIL CR .. THEN LOOP BACK XRI #0D BNZ * - #03 BR RD1 .. THEN BRANCH BACK .. FOR !M COMMAND .. SYNERR: LDI A.0(TYPE5D) PLO SUB .. GENERAL RESULT OF SYNTACTIC ERROR SEP SUB ,#0D .. CR LBR FSYNER .. FINISH ERROR MSG .. .. THE FOLLOWING DOES $P HHHH ORG #80D6 DOLLAR: SEP SUB .. NOTE SUB.0 = READAH XRI #50 .. SHOULD BE P BNZ SYNERR D1: SEP SUB BDF D1 .. ASSEMBLE HEX .. STRING INTO ASL XRI #0D .. FIRST NON-HEX MUST BE CR BNZ SYNERR GHI ASL PHI R0 GLO ASL PLO R0 .. SET UP NEXT PC LDI A.0(TYPE5D) PLO SUB SEP SUB ,#0A .. LF SEX PC RET ,#00 .. AND USER PROGRAM BEGINS (IN R0) .. EXIT TO UT4 .. .. .. .. SUBROUTINES .. .. DELAY ROUTINE .. DELAY IS 2(1_AUX.1(3+@SUB)) .. USED BY TYPE, READ, AND TIMALC. .. AUX.1 IS ASSUMED TO HOLD A DELAY CONSTANT .. = ((BIT TIME OF TERMINAL)/(20*INSTR TIME OF COSMAC)) - 1. .. THIS CONSTANT CAN BE GENERATED .. AUTOMATICALLY BY THE TIMALC ROUTINE. .. DEXIT: SEP SUB DELAY1: GHI AUX SHR PLO AUX .. SHIFT OUT ECHO FLAG DELAY2: DEC AUX .. AUX.0 HOLDS BASIC BIT DELAY LDA SUB SMI #01 .. PICK UP A CONSTANT BNZ * - #02 .. LOOP AS SPECIFIED BY CALL GLO AUX .. DONE YET? BZ DEXIT DEC SUB .. POINTS SUB AT DELAY POINTER BR DELAY2 .. .. ROUTINE TO CALCULATE BIT TIME AND ECHO FLAG. .. WAITS FOR LF (NO ECHO) OR CR (ECHO) TO BE TYPED IN. .. ALSO SETS UP POINTER TO DELAY ROUTINE. .. AUX.1 ENDS UP HOLDING, IN THE MOST SIGNIFICANT 7 BITS, .. THE DELAY CONSTANT. LEAST SIGNIFICANT BIT IS 0 FOR ECHO, .. 1 FOR NO ECHO .. TIMALC: GHI SUB PHI DELAY LDI #00 PLO AUX PLO CHAR LDI A.0(DELAY1) PLO DELAY .. DELAY ROUTINE READY B2 * .. WAIT FOR START BIT BN2 * .. WAIT FOR FIRST NON-ZERO BIT LDI #03 .. SET UP FOR 10 EXECUTIONS .. SO ROUND-OFF IS MINIMAL TC2: SMI #01 BNZ * - #02 GLO CHAR .. LOOK TO SEE IF DATA CHANGED .. PREVIOUSLY BNZ ZRONE .. BR IF IT HAD B2 INCR .. ELSE LOOK FOR CHANGE TO 0 NOW .. BRANCH IF NO INC CHAR .. IF YES, SET SWITCH ZRONE: B2 DAUX .. LOOK FOR CHANGE TO 1, .. BR IF YES INCR: INC AUX LDI #07 .. SET UP FOR 20 INSTR LOOP BR TC2 .. AUX.0 NOW HOLDS #LOOPS IN 2 BIT TIMES DAUX: DEC AUX DEC AUX .. REDUCE COUNT TO BALANCE FIXED .. OVERLOAD IN CALLING DELAY GLO AUX ORI #01 PHI AUX .. LSB AUX.1 = SEP RC .. 1.5 BIT TIME DELAY ,#0C BN2 WAIT .. BR IF LF => NO ECHO, LSB AUX.1=1 GHI AUX ANI #FE PHI AUX .. CR => ECHO, LSB AUX.1=0 WAIT: SEP RC ,#26 SEP R5 .. .. .. .. READ ROUTINE -- READS 1 BYTE INTO CHAR.1 .. WHEN ENTERED VIA READAH, THEN .. IF INPUT IS A HEX DIGIT ITS HEX VALUE .. IS SHIFTED INTO ASL FROM THE RIGHT .. AND DF=1, ELSE DF=0; CLOBBERS CHAR, AUX.0 (ASL .. ON READAH). LEAVES BYTE IN D (BUT CLOBBERED IF .. SUBR LINKAGE IS USED). LEAVES PC AT READAH .. ENTRY POINT; EXITS TO R5 .. .. WARNING: READ PROCESS HAS NOT FINISHED. DO .. NOT TYPE IMMEDIATELY, OR ELSE ENTER TYPE VIA .. TYPE5D .. ORG #812F CKDEC: ADI #07 .. CHECK FOR ASCII DECIMAL POINT BDF NFND ADI #0A BDF FND .. SUB NET 30 NFND: ADI #00 .. SETS DF = 0 REXIT: GHI CHAR .. CHAR INTO D SEP R5 READAH: LDI #00 SKP .. SKIP OVER TO READ1 READ: GLO SUB .. CONSTANT WITH A VALUE 0 LSKP TTYRED: LDI #01 READ1: PLO CHAR .. SET ENTRY FLAG READ2: LDI #80 PHI CHAR .. INITIALIZE INPUT BYTE .. WHEN SHIFTED 80 IS 1, WILL BE DONE SEX SUB GLO CHAR SHR .. DF=1 ENTRY VIA TTYRED BNF TTY1-#02 .. OUT 7 .. ,#80 .. READER ON SEX SUB .. NOP SEX SUB .. NOP BN2 * .. WAIT FOR END OF LAST DATA BIT TTY1: B2 * .. WAIT FOR PRESENT START BIT SEP RC ,#02 .. DELAY HALF BIT TIME B2 TTY1 .. BR IF NO START BIT GLO CHAR SHR .. ENTRY VIA TTYRED? BNF NOBIT .. BR IF NO .. OUT 7 .. ,#40 SEX SUB .. NOP SEX SUB .. NOP .. NOBIT: SEX R2 NOP .. RESET X, AND DELAY BIT: GHI AUX SHR .. ECHO? BDF NOECHO .. BR IF NO B2 OUTBIT .. IS THE BIT A 1? SEQ .. SET Q BR NOECHO OUTBIT: REQ .. RESET Q NOP .. DELAY NOECHO: SEP RC ,#07 .. WAIT ONE BIT TIME NOP NOP .. MORE DELAY GHI CHAR SHR PHI CHAR .. SHIFT THE INPUT CHAR BDF NEXT .. BR IF INPUT FINISHED .. D=CHAR.1 ORI #80 BN2 NOBIT .. BR IF INPUT WAS A ZERO PHI CHAR BR BIT .. CONTINUE LOOP NEXT: REQ .. OUTPUT THE STOP BIT BZ READ2 .. BR IF D=0 ->CHAR.1 .. IS A NULL GLO CHAR .. CK ENTRY FLAG BNZ REXIT .. BR IF ENTRY WAS VIA READ GHI CHAR SMI #41 .. CK FOR ASCII HEX BNF CKDEC .. (AT TOP OF ROUTINE) SMI #06 .. CK FOR A THRU F BDF NFND .. .. FND: SHL SHL SHL SHL ADI #08 SHL FND1: PLO AUX .. READY TO SHIFT INTO RD GLO ASL SHLC PLO ASL .. SHIFT LOW HALF GHI ASL SHLC PHI ASL .. SHIFT HIGH HALF GLO AUX SHL BNZ FND1 .. BR IF NOT FINISHED BR REXIT .. .. TYPE ROUTINE -- TYPES 1 BYTE FROM @R5!, @R6!, .. OR CHAR.1, OR TYPES A BYTE AS TWO HEX DIGITS .. FROM CHAR.1 FOLLOWS A LINE FEED BY SIX NULLS. .. USES 2 AUXILIARY REGS - AUX AND CHAR - PLUS .. RAM LOCATION @ST.EXITS READY TO TYPE 1 BYTE .. FROM @R5!. EXITS TO R5 .. WHEN ENTERED AT TYPE5D, PAUSES TO ALLOW AN .. EARLIER READ TO COMPLETE. .. .. AUX.0 HOLDS OUTPUT CHAR (AT FIRST), THEN .. THE DELAY CONSTNT BETWEEN BITS. CHAR.0 HOLDS .. THE NUMBER OF BITS (11) IN ITS LOWER DIGIT, .. AND IN ITS UPPER DIGIT HOLDS A CODE-- .. 0 FOR BYTE OUTPUT .. 1 FOR FIRST HEX OUTPUT .. 2 FOR LST NULL OUTPUT .. 8 FOR LF OUTPUT .. ORG #819C TYPE5D: SEP RC ,#17 .. 3 BIT TIME DELAY SKP .. SKP TO TYPE 5 TEXIT: SEP R5 TYPE5: LDA R5 SKP .. ENTRY FOR UT4 SKIP TO TYPE TYPE6: LDA R6 SKP .. ENTRY FOR G.P. IMMED TH TYPE: GHI CHAR TY1: PLO AUX .. SAVE BYTE FOR LATER XRI #0A .. IS IT LINE FEED? BNZ TY2 LDI #8B .. (# OF BITS) + (# OF NULLS .. TO FOLLOW LF+1) BR TY3 TYPE2: GHI CHAR .. UT4 ENTRY TY4: SHR SHR SHR SHR .. SHIFT FIRST HEX TO RIGHT ADI #F6 .. CONVERT TO HEX BNF * + #04 .. IF A OR MORE ADI #07 .. ADD NET 37 SMI #C6 PLO AUX .. ELSE ADD NET 30 LDI #1B .. 10+(# OF BITS) LSKP .. EQUIV TO BR TY3 .. TY2: LDI #0B .. (# OF BITS TO OUTPUT) TY3: PLO CHAR .. SAVE MAIN TALLY VALUE .. .. BEGIN: SEQ .. START BIT GLO AUX .. GET CHAR TO BE TYPED PLO RD .. SAVE THE CHAR .. (AUX.0 CLOBBERED) PREBIT: SEP RC ,#07 .. WAIT ONE BIT TIME .. RETURN FROM DELAY WITH D=0 DEC CHAR .. DEC THE BIT COUNTER SD .. SET DF=1 GLO RD SHRC PLO RD .. SHIFT OUTPUT CHAR BDF OUT1B .. BR IF THE BIT IS A 1 SEQ .. ELSE SET Q TO ZERO BR OUT1B + #02 OUT1B: REQ .. SET Q TO 1 NOP .. DELAY GLO CHAR ANI #0F .. FINISHED TYPING? NOP NOP .. DELAY (14 INSTR.LOOP) BNZ PREBIT .. BR IF NOT FINISHED NXCHAR: GLO CHAR ADI #FB PLO CHAR .. SET UP FOR NEXT CHAR BNF TEXIT .. BUT EXIT IF NO MORE SMI #1B .. TEST FOR ALTERNATIVES BZ TEXIT .. IF JUST TYPED LST NULL BNF HEX2 .. IF JUST TYPED FIRST HEX .. JUST TYPE LF OR NULL LDI #00 .. PREPARE TO TYPE NULL BR HX22 .. HEX2: GHI CHAR ANI #0F .. GET 2ND HEX DIGIT ADI #F6 .. CONVERT TO HEX BNF * + #04 .. IF A MORE ADI #07 .. ADD NET 37 SMI #C6 .. ELSE ALL NET 30 HX22: PLO AUX .. STORE CHAR AWAY BR BEGIN .. FSYNER: SEP SUB ,#0A .. LF SEP SUB ,#3F .. ? LBR START ,#00 .. FILLER END