TITLE 'SBMS-K6HIJ 8080 MONITOR, V6.1 09-20-80' PAGE 56 ; ; AMS80 - AMSAT STANDARD 8080 MONITOR ; ; VERSION 1.0, 09NOV75 ; VERSION 1.1, 02APR75 - MOVE TO HIGH MEM AND REMOVE INT PROCS ; VERSION 1.2, 18AUG78 - ADD CASSETTE TAPE HANDLERS ; VERSION 1.3, 30OCT78 - ADD I/O PORT DRIVE COMMANDS ; VERSION 5.0, 12AUG79 - ADD PRINTER DRIVER ; VERSION 5.1, 20SEP79 - ADD MEMORY TEST ; VERSION 5.2, 22DEC79 - ADD DISASEMBLER ; VERSION 6.0, 25MAY80 - ADD ROM PROGRAMER ; VERSION 6.1, 20SEP80 - MODIFY TO RBK/K6HIJ SYSTEM ; ; RICHARD B. KOLBLY, K6HIJ ; JET PROPULSION LABORATORY ; P.O. BOX 997/GOLDSTONE ; BARSTOW, CALIFORNIA 92311 ; ; (714) 288-8296 ; ; ; MODIFIED BY RICHARD L BERG ; 1137 E WILLAMS ; BARSTOW CALIF 92311 ; (714) 256-9317 ; ; (DERIVED FROM THE AMSAT MONITOR BY R. C. ALLEN, W5SXD) ; ; THIS MONITOR IS A MINIMUM 8080 SYSTEM MONITOR ; FOR USE BY THE JET PROPULSION LABORATORY MTF ; DATA ACQUISITION SYSTEM. IT PROVIDES THE BASIC ; STRUCTURE NECCESSARY FOR OPERATION OF AN 8080- ; BASED SYSTEM. ; ; THIS STANDARD BASE SYSTEM WILL ALLOW MEMORY EXAMINE AND ; MODIFY, LOADING AND DUMPING OF MEMORY TO TARBELL- ; FORMAT CASSETTE TAPE ROUTINES, AND PROVIDE UTILITY ; ROUTINES FOR OTHER PROGRAMS. ; ; DEFINE THE SYSTEM MEMORY PARAMETERS ; ROM: EQU 0E400H ;START OF READ-ONLY-MEMORY RAM: EQU 0DF00H ;START OF READ-WRITE MEMORY RAMSZ: EQU 256 ;SIZE OF USED RAM AREA IN BYTES STACK: EQU RAM+RAMSZ ;TOP OF MONITOR STACK ; AND END OF MONITOR RAM ; ; DEFINE THE TELETYPE I/O PORTS ; TTYO EQU 1 ;TELETYPE OUTPUT PORT TTYI EQU 1 ;TELETYPE INPUT PORT TTYS EQU 0 ;TELETYPE STATUS PORT TOBSY EQU 80H ;B7 = 1 IF TTYO BUSY TIBSY EQU 1 ;B0 = 1 IF NO TTYI DATA AVAILABLE PTRST EQU 02H ;PRINTER STATUS PORT PTROUT EQU 03H ;PRINTER OUTPUT PORT PTRIST EQU 80H ;STATUS BYTE ; ; DEFINE TTY CONTROL CHARS ; CR EQU 0DH ;CARRIAGE RETURN LF EQU 0AH ;LINE FEED FF EQU 0CH ;FORM FEED RBO EQU 7FH ;RUB-OUT TOFF EQU 14H ;TAPE OFF COMMAND TON EQU 12H ;TAPE ON COMMAND XOFF EQU 13H ;PUNCH OFF COMMAND XON EQU 11H ;PUNCH ON COMMAND ; ; START OF SYSTEM ; ORG ROM ; ; MONITOR SUPPORT SUBROUTINE VECTORS ; ; THE FOLLOWING SET OF JUMPS ARE PROVIDED SO ; USER PROGRAMS CAN REFERENCE COMMON ENTRY POINTS ; TO THE VARIOUS ROUTINES. THESE LOCATIONS WILL ; REMAIN CONSTANT WHILE THE ACTUAL LOCATION OF EACH ; ROUTINE MAY CHANGE FROM ONE REVISION LEVEL TO THE ; NEXT. ; ; THE CALLING SEQUENCE FOR EACH SUBROUTAL LOCATION OF EACH ; ROUTINE MAY CHANGE FROM ONE REVISION LEVEL TO THE ; NEXT. ; ; THE CALLING SEQUENCE FOR EACH SUBROUT ; MONITOR ENTRY POINT ; EXEC: JMP BEGIN @TYPE: JMP TYPE ;TYPE A CHARACTER FROM 'A' @GETCH: JMP GETCH ;GET CHAR TO A (NO ECHO) @NEXT: JMP NEXT ;GET NEXT COMMAND @PU3: JMP PU3 ;SPACE & GET HEX WORD @CHIN: JMP CHIN ;GET CHAR TO 'A' WITH ECHO ; ( PARITY SET OFF ) @MSG: JMP MSG ;TYPE MSG, POINTER IN HL ; ( MSG TERMINATED BY 0FFH ) @CRET: JMP CRET ;TYPE CR, LF, RUB-OUT @SPACE: JMP SPACE ;TYPE A SPACE @THXN: JMP THXN ;TYPE B3-B0 OF 'A' IN HEX ; ( ONE ASCII CHARACTER ) @THXB: JMP THXB ;TYPE 'A' IN ASCII-HEX 2 CH @THXW: JMP THXW ;TYPE 'HL' IN ASCII-HEX 4 CH @GHXN: JMP GHXN ;GET HEX NIBBLE TO B3-B0 'A' @GHXB: JMP GHXB ;GET HEX BYTE FROM TTYI > 'A' @GHXW: JMP GHXW ;GET HEX WORD TO HL @STORE: JMP STORE ;STORE A BYTE M,A WITH CHECK @NEGDE: JMP NEGDE ;NEGATE THE DE REGISTER @OK?: JMP OK? ;TYPE ' OK? ' AND WAIT FOR ; SPACE IF OK, OTHERS WILL ; PRINT ABORT MSG AND RETURN ; TO MONITOR. @STOP: JMP STOP ;STOPS LISTING WITH SPACE BAR ; RETURN WILL START THINGS AGAIN, ; SPACE BAR WILL GIVE ONE MORE LINE, ; BREAK WILL RETURN TO MONITOR. ; ; BEGIN MONITOR ; BEGIN: SHLD SVHL ;SAVE HL PAIR LXI H,TMPA ;SET PSEUDO MVI M,0 ; CARRY TO 0 JNC $+5 ; NO CARRY ON INPUT MVI M,1 ;PSEUDO CY TO 1 POP H ;POP CALL ADDRESS IF ANY SHLD SVPC ; AND SAVE PC LXI H,-2 ;FETCH SP DAD SP ; ADJUSTING FOR POP SHLD SVSP ;SAVE USER STACK POINTER LXI SP,SVA+1 ;SET SP FOR REGISTER SAVE PUSH PSW ;SAVE A,PSW PUSH B ;SAVE BC PUSH D ;SAVE DE LXI H,SVF ;POINT TO SAVED PSB MOV A,M ; ALD FETCHIT ANI 0FEH ;ZERO CY MOV B,A ; AND SAVE LDA TMPA ;GET INPUT SAVED CY ORA B ; AND INSERT MOV M,A ;RESTORE PSB WITH OK CY LXI SP,STACK ;SET SP TO EXEC STACK AREA LXI H,IOBYTE ;POINT TO PORT CONTROL MVI M,0 ;SET TO NO PRINTER INX H MVI M,0 INX H MVI M,66 ;INITIALIZE PRINTER FORM LENGTH INX H MVI M,0 LXI H,M0 ;TYPE ENTRY CALL MSG ; MESSAGE MENU: LXI H,M10 ;TYPE MENU CALL MSG ; MESSAGE ; ; NEXT MONITOR COMMAND ; NEXT: LXI SP,STACK ;RESTORE SP LXI H,M1 ;TYPE CALL MSG ; PROMPTER LXI H,ST1 MVI M,0C2H CALL CHIN ;GET COMMAND CHAR MOV B,A ; AND SAVE COMMAND ; ; SEARCH OPERATION TABLE FOR COMMAND ; LXI H,OPTAB ;FETCH TABLE VECTOR SRCH: MOV A,M ;GET TABLE COMMAND BYTE CPI -1 ;CHECK FOR END OF TABLE JZ ILLEG ;MUST BE ILLEGAL INPUT CMP B ;COMPARE TO INPUT JZ FNDCM ;FOUND COMMAND INX H ;BUMP TO INX H ; NEXT INX H ; COMMAND JMP SRCH ;AND CONTINUE ; ; UNDEFINED COMMAND, TYPE ERROR MESSAGE ; ILLEG: LXI H,M2 ;UNDEFINED CALL MSG ; MESSAGE JMP NEXT ;TRY AGAIN ; ; FOUND COMMAND, NOW FETCH ADDRESS AND EXECUTE COMMAND ; FNDCM: INX H ;BUMP TO LOW ADDRESS BYTE MOV E,M ; AND FETCH IT INX H ;GET HIGH MOV D,M ; ADDRESS BYTE XCHG ;ADDRESS TO HL PCHL ; GOTO COMMAND PROCESSOR ; ; OPERATION DECODE/DISPATCH TABLE ; OPTAB: DB 'A' ;COMMAND DW GETAD ; TO GET ADDRESS DB CR ;COMMAND DW NEXT ; EFFECTIVE NOP DB '.' ;COMMAND DW LOCAT ; TO EXAMINE CURRENT LOCATION DB LF ;COMMAND DW NXLOC ; TO EXAMINE NEXT LOCATION DB '-' ;COMMAND DW LSTLC ; TO EXAMINE PREVIOUS LOCATION DB 'D' ;COMMAND DW DUMP ; TO DUMP MEMORY AREA DB 'F' ;COMMAND DW FILL ; TO FILL MEMORY DB 'G' ;COMMAND DW GOTO ; TO GOTO MEMORY LOCATION DB 'M' ;COMMAND DW MOVE ; TO MOVE AREA OF MEMORY DB 'C' ;COMMAND DW GETXA ; TO GET XEQ ADDRESS DB 'J' ;COMMAND DW JUMP ; TO JUMP TO MEMORY LOCATION DB 'R' ;COMMAND DW REGEX ; REGISTER EXAMINE DB 'O' ;COMMAND DW WRITE ; WRITE MEMORY TO CASSETTE DB 'V' ;COMMAND DW VERFY ; VERIFY CASSETTE TO MEMORY DB 'I' ;COMMAND DW TREAD ; READ CASSETTE INTO MEMORY DB 'S' ;COMMAND DW SRCH1 ;SEARCH MEMORY DB 'E' ;COMMAND DW PORTI ;READ A PORT DB 'W' ;COMMAND DW PORTO ;WRITE TO A PORT DB 'B' ;COMMAND DW RPROG ;(B)LOW A 2708 ROM DB 'X' ;COMMAND DW CPM ;JUMP TO CP/M SYSTEM DB 'T' ;COMMAND DW SIZE ;DISPLAY TOP OF MEMORY DB 'L' ;COMMAND DW MENU ;DISPLAY MENU DB 'Z' ;COMMAND DW 0000H ;JUMP TO ADDRESS ZERO DB 'U' ;CONTROL DW ASSEM ;JUMP TO DISSASEMBLER DB 'H' ;CONTROL DW MATH ;HEX MATH DB 'P' ;CONTROL DW PONOFF ;PRINT ON/OFF DB 'K' ;CONTROL DW WIDTH ;PRINTER WIDTH DB 'Q' ;CONTROL DW FORM ;FORM FEED CONTROL DB 'Y' ;COMTROL DW PSP ;CHANGE PRINTER SPACING DB 01BH ;CONTROL DW MEMT ;8080 MEM-TEST DB '=' ;CONTROL DW COPY ;COPY A ROM ROUTINE DB -1 ;END OF TABLE CODE ; ; PRINTER LINE SPACING ; PSP: MVI A,CR CALL PTR LXI H,IOBYTE;TURN PRINTER OFF MVI M,0 LXI H,M14 ;GET LINE SPACING MES CALL MSG ;GO PRINT IT PSP1: CALL GETCH ;GET CHARACTER ANI 7FH CALL TYPE ;GO PRINT IT CPI CR ;CR? JZ PSP1 ;YES DO IT AGAIN CPI 31H ;6 LINES PER INCH JZ LS6 ;GO DO IT CPI 32H ;8 LINES PER INCH JZ LS8 ;GO DO IT CPI 33H ;12 LINES PER INCH JZ LS12 ;GO DO IT JMP PSP1 ; LS6: LXI H,PFF ;SET FORM FEED COUNT MVI M,66 ;TO 66 LINES LXI H,YMSG1 ;SEND MESSAGE TO PRINTER JMP LS ; LS8: LXI H,PFF ;SET FORM FEED COUNT MVI M,88 ;TO 88 LINES LXI H,YMSG2 ;SEND MESSAGE TO PRINTER JMP LS ; LS12: LXI H,PFF ;SET FORM FEED COUNT MVI M,132 ;TO 132 LINES LXI H,YMSG3 ;SEND MESSAGE TO PRINTER JMP LS ; LS: CALL OK? ;IS THIS WHAT YOU WANT MVI B,4 ;SET UP CHARACTER COUNT PMSG: MOV A,M ;GET CHARACTER CALL PTR ;SEND TO PRINTER INX H ;BUMP CHARACTER COUNTER DCR B ;DECREMENT COUNT JNZ PMSG ;IF NOT DONE, DO NEXT CHARACTER JMP NEXT ;EXIT ; ; DO A FORM FEED TO PRINTER ; FORM: CALL FORM1 JMP NEXT FORM1: PUSH PSW ;SAVE ACCUMULATOR FORM2: MVI A,LF ;PUT LF FOR PRINT CALL PTR ;SEND TO PRINTER LDA PFF1 ;CHECK FORM FEED COUNT ORA A ;SET FLAGS... JNZ FORM2 ;NOT ZERO, KEEP PRINTING LF'S POP PSW ;RESTORE ACCUMULATOR RET ; ; DRIVER FOR CHANGING PRINTER WIDTH ; (PRINTER FORMAT CHANGES ARE FOR DEC LA-34 PRINTER) ; WIDTH: MVI A,CR CALL PTR LXI H,IOBYTE;TURN PRINTER OF MVI M,0 LXI H,M13 ;GET WIDTH MES CALL MSG ;GO PRINT IT W1: CALL GETCH ;GET FIRST CHARACTER ANI 7FH CALL TYPE ;GO PRINT IT CPI 0DH ;CR? JZ WIDTH ;YES DO AGIAN CPI 31H ; '1' = 10 CHARACTERS PER INCH JZ W80 ;GO DO IT CPI 32H ; '2' = 12 CHARACTERS PER INCH JZ W96 ;GO DO IT CPI 33H ; '3' = 13.5 CHARACTERS PER INCH JZ W132 ;GO DO IT CPI 34H ; '4' = 16.5 CHARACTERS PER INCH JZ W216 ;GO DO IT JMP W1 ;DO AGAIN ; W80: LXI H,XMSG1 ;SET UP PRINTER CONTROL JMP LS ;WIDTH ; W96: LXI H,XMSG2 ;SET UP FOR 12 CPI JMP LS ;WIDTH ; W132: LXI H,XMSG3 ;READY FOR 13.5 CPI JMP LS ;WIDTH ; W216: LXI H,XMSG4 ;SET UP FOR 16.5 CPI JMP LS ;WIDTH ; XMSG1: DB 1BH,'[0w' XMSG2: DB 1BH,'[2w' XMSG3: DB 1BH,'[3w' XMSG4: DB 1BH,'[4w' YMSG1: DB 1BH,'[0z' YMSG2: DB 1BH,'[2z' YMSG3º DÂ 1BH,'[3z' ; ; SEARCH MEMORY S AAAA BBBB CC CC CC CC CC . ; AAAA = STARTING ADDRESS FOR SEARCH ; BBBB = ENDING ADDRESS FOR SEARCH ; CC = DATA IN HEX TO LOOK FOR ; OR USE X FOR I DONT CARE. ; . = END OF SEARCH STRING ; ; EXAMPLE 1000 2500 DB 01 X X C9 . ; SRCH1: CALL PU3 CALL PU3 CALL NEGDE CALL SPACE CALL STOR JC ILLCH CALL OK? CALL CRET SRCH2: CALL FOUND CALL LAST JMP SRCH2 STOR: PUSH H LXI H,STD ST: CALL GHXB JC ST2 ST5: MOV M,A INX H CALL SPACE JMP ST ST2: CPI 'X' JZ ST5 CPI '.' JZ ST4 ST3: POP H RET ST4: MOV M,A JMP ST3 FOUND: PUSH D PUSH H LXI D,STD F1: LDAX D CMP M JZ F3 CPI 'X' JZ F3 CPI '.' JZ F4 F2: POP H POP D RET F3: INX H INX D JMP F1 F4: POP H PUSH H LXI D,STD CALL THXW F5: CALL SPACE LDAX D CPI '.' JZ F6 MOV A,M CALL THXB INX H INX D JMP F5 F6: CALL CRET CALL STOP JMP F2 ; ; HEX MATH ; MATH CALL PU3 CALL PU3 XCHG CALL OK? PUSH H DAD D CALL THXW CALL SPACE POP H PUSH H CALL MAT1 POP H XCHG CALL MAT1 JMP NEXT MAT1: ORA A MOV A,E SBB L MOV L,A MOV A,D SBB H MOV H,A CALL THXW CALL SPACE RET ; ; BOOT THE CP/M SYSTEM ; CPM: XRA A ;THIS ROUTINE OUT 0F9H ;WILL RETURN OUT 0FAH ;THE HEAD OF OUT 0FBH ;DISC AND MVI A,03H ;LOAD THE OUT 0F8H ;BOOT LOADER IN 0FCH ;FROM THE DISC XRA A ;EXICUTE AND MOV L,A ;JUMP TO CP/M MOV H,A ;OPERATING SYSTEM INR A OUT 0FAH MVI A,08CH OUT 0F8H CPM1: IN 0FCH ORA A JP CPM2 IN 0FBH MOV M,A INX H JMP CPM1 CPM2: IN 0F8H ;GET STATUS ORA A ;SET FLAGS JZ 007DH ;GOOD LOAD, GO TO CP/M CMA ;MAKE RIGHT FOR IMSAI FRONT PANEL OUT 0FFH ;SEND ERROR MESSAGE TO FRONT PANEL JMP NEXT ;INVALID LOAD, RETURN TO MONITOR ; ; FIND SIZE OF RAM ; SIZE: CALL SPACE CALL MEMSZ DCX H CALL THXW JMP NEXT MEMSZ: LXI H,0-1 MEMO: INX H MOV A,M CMA MOV M,A CMP M CMA MOV M,A JZ MEMO RET ; ; TELETYPE I/O ROUTINES ; ; ; ROUTINE TO TYPE A CHARACTER ; ; CALLING SEQUENCE ... ; ; LDA CHAR ;CHARACTER IN 'A' REG ; CALL TYPE ;TYPE IT ; ... ;RETURN HERE AFTER PRINT ; ; STARTED ; ; ALL REGISTERS PRESERVED ; TYPE: PUSH PSW ;SAVE CHARACTER LDA IOBYTE ;TEST FOR DISPLAY ANI 1 ;MASK CONSOLE FUNCTION CPI 1 ;IS PRINTER ON JZ $+7 ;NOT ZERO, MUST BE OFF POP PSW ;RESTORE FOR STACK BALANCE JMP TTY ;SEND TO SERIAL PORT POP PSW CALL PTR JMP TTY PTR: CPI FF ;IF CHAR IS A FORM FEED (0CH)... JZ FORM1 ;...IT IS NOT PROCESSED HERE! PUSH PSW ;SAVE FOR STACK BALANCE IN PTRST ;GET PRINTER STATUS ANI PTRIST ;LOOK AT PRINTER STATUS JNZ $-4 ; AND LOOP TILL READY POP PSW ;RESTORE PSW OUT PTROUT ; AND PRINT CHARACTER CPI LF ;IS IT A LINE FEED? RNZ ;NO, ALL DONE PUSH PSW ;LINE FEED REQUIRES... PUSH H ;...SPECIAL PROCESSING LDA PFF1 ;GET LINE COUNT LXI H,PFF ;POINT TO MAXIMUM LINES/PAGE INR A ;BUMP LINE COUNT CMP M ;COMPARE WITH MAX ALLOWED JNZ PTR1 ;NOT THERE YET,EXIT XRA A ;RESET LINES COUNT PTR1: STA PFF1 ;STORE COUNT POP H ;GET HL BACK POP PSW ;...AND ACCUMULATOR RET TTY: PUSH PSW ;SAVE PSW IN TTYS ;GET TTY STATUS ANI TOBSY ;LOOK AT TTYO STATUS JNZ $-4 ; AND LOOP TILL READY POP PSW ;RESTORE PSW OUT TTYO ; AND TYP CHARACTER RET ;EXIT TO CALLER ; ; ROUTINE TO GET A CHARACTER FROM TTY ; ; CALLING SEQUENCE ... ; ; CALL GETCH ;GET CHARACTER ; ... ;RETURN HERE WITH CHAR IN 'A' ; ; ALL REGISTERS PRESERVED EXCEPT 'A' WHICH ; CONTAINS THE INPUT CHARACTER. ; GETCH: PUSH PSW ;SAVE PSW IN TTYS ;GET TTY STATUS ANI TIBSY ;CHECK FOR DATA READY JNZ $-4 ; AND LOOP POP PSW ;RESTORE STATUS IN TTYI ;AND FETCH CHARACTER RET ;EXIT TO CALLER ; ; CHIN - ROUTINE TO INPUT ONE CHARACTER, ; STRIP OFF PARITY, AND ECHO IF ABOVE ; A SPACE (I.E., NOT CR, LF, ETC.) ; ; CALLING SEQUENCE ... ; ; CALL CHIN ;CHARACTER IN ; ... ;RETURN AFTER ECHO STARTED ; ;WITH CHAR .AND. 7FH IN 'A' ; CHIN: MVI A,-1 ;SET ECHO STA ECHO ; FLAG ON CHINN: CALL GETCH ;GET CHARACTER ANI 7FH ;STRIP PARITY PUSH PSW ;SAVE DATA LDA ECHO ; AND CHECK ANA A ; ECHO FLAG JNZ $+5 ;ECHO SET POP PSW ;ECHO NOT SET RET ; SO RETURN POP PSW ;RESTORE DATA AND ECHO CPI ' ' ;CHECK FOR CONTROL CNC TYPE ;TYPE IF >= SPACE RET ;RETURN ; ; MESSAGE PRINT ROUTINE ; ; CALLING SEQUENCE ... ; ; LXI H,ADRESS ;ADDRESS OF MESSAGE ; CALL MSG ;CALL ROUTINE ; ... ;RETURN HERE AFTER LAST CHAR ; ; INITIATED, ALL REGISTERS ; ; PRESERVED ; MSG: PUSH PSW ;SAVE PSW PUSH H ;SAVE HL MNXT: MOV A,M ;GET A CHARACTER CPI -1 ;CHECK FOR 377Q/0FFH/-1 TERMTR JZ MDONE ;FOUND THE TERMINATOR CALL TYPE ;TYPE THE CHARACTER INX H ;BUMP MEM VECTOR JMP MNXT ; AND CONTINUE MDONE: POP H ;RESTORE HL POP PSW ; AND PSW RET ;EXIT TO CALLER ; ; ROUTINE TO TYPE CR, LF, RBO ; ; CALLING SEQUENCE ... ; ; CALL CRET ; ... ;RETURN HERE WITH ALL ; ;REGISTERS PRESERVED ; CRET: PUSH H ;SAVE HL LXI H,CRMSG ;ADDRESS OF CRLFRBO MSG CALL MSG ;TYPE IT POP H ;RESTORE HL RET ; AND RETURN CRMSG: DB CR,LF,-1 ; ; ROUTINE TO TYPE ONE SPACE ; ; CALLING SEQUENCE ... ; ; CALL SPACE ; ... ;RETURN HERE ; ; ALL REGISTERS PRESERVED ; SPACE: PUSH PSW ;SAVE A,PSW MVI A,' ' ;GET A SPACE CALL TYPE ; AND DO IT POP PSW ;RESTORE PSW RET ;AND RETURN ; ; ROUTINE TO TYPE VALUE IN 'A' IN HEX ON TTY ; ; CALLING SEQUENCE ... ; ; LDA DATA ;DATA BYTE IN 'A' ; CALL THXB ;TYPE IN HEX ; ... ;RETURN HERE ; ; ALL REGS PRESERVED ; THXB: PUSH PSW ;SAVE A,PSB RRC ;SHIFT RRC ; TO RRC ; LEFT RRC ; NIBBLE CALL THXN ;TYPE HEX NIBBLE POP PSW ;RESTORE DATA CALL THXN ;TYPE RIGHT NIBBLE RET ; AND EXIT ; ; ROUTINE TO TYPE ON ASCII CHARACTER REPRESENTING ; BITS 3-0 OF 'A' IN HEX ; ; CALLING SEQUENCE ... ; ; LDA DATA ;DATA NIBBLE IN BITS 3-0 ; CALL THXN ;TYPE NIBBLE IN HEX ; ... ;RETURNS HERE ; ; ALL REGS PRESERVED, AND CONTENTS OF 'A' BITS 7-4 ; ARE NOT SIGNIFICANT AND ARE IGNORED. ; THXN: PUSH PSW ;SAVE PSW ANI 0FH ;ISOLATE NIBBLE B3>B0 CPI 10 ;SEE IF > 9 JC $+5 ;NIBBLE <= 9 ADI 7 ;ADJUST ALPHA CHAR ADI '0' ; ADD IN ASCII 0 CALL TYPE ;AND TYPE THE NIBBLE POP PSW ;RESTORE PSW RET ; AND RETURN ; ; ROUTINE TO TYPE A WORD IN HEX ; ; LHLD WORD ;WORD IN HL ; CALL THXW ;TYPE IT IN HEX ; ... ;RETURN HERE ; ; ALL REGISTERS PRESERVED ; THXW: PUSH PSW ;SAVE PSW MOV A,H ;GET HIGH BYTE CALL THXB ; AND TYPE IT MOV A,L ;GET LOW BYTE CALL THXB ; AND TYPE IT POP PSW ;RESTORE PSW RET ; AND RETURN ; ; ROUTINE TO GET ONE HEX CHARACTER FROM TTY ; ; CALLING SEQUENCE ... ; ; CALL GHXN ;GET HEX NIBBLE ; JC NONHX ;CY SET IF NON HEX ; ... ;HEX NIBBLE IN 'A' B3-B0 ; ; IF THE CHARACTER ENTERED IS 0 TO 9 OR A TO F THEN ; 'A' WILL BE SET TO THE BINARY VALUE 0 TO F AND ; THE CARRY WILL BE RESET. ; ; IF THE CHARACTER ENTERED IS NOT A VALID HEX DIGIT ; THEN THE 'A' REGISTER WILL CONTAIN THE ASCII CHAR ; AND THE CARRY WILL BE SET TO A 1. ; ; ALL REGISTERS EXCEPT PSW PRESERVED ; GHXN: CALL CHINN ;GET CHARACTER IN ;(CHINN IN CASE NOT ECHO) CPI '0' ;RETURN IF RC ; < '0' CPI ':' ;SEE IF NUMERIC JC GHX1 ;CHAR IS 0 TO 9 CPI 'A' ;SEE IF A TO F RC ;CHAR ':' TO '@' CPI 'G' ;SEE IF > 'F' CMC ;INVERT CY SENSE RC ;CHAR > 'F' SUI 7 ;CHAR IS A TO F SO ADJUST GHX1: SUI '0' ;ADJUST TO BINARY RET ; AND EXIT ; ; ROUTINE TO GET ON HEX BYTE FROM TTYI ; ; CALLING SEQUENCE ... ; ; CALL GHXB ;GET HEX BYTE ; JC NONHX ;SAME AS GHXN, NON-HEX INPUT ; ... ;HEX BYTE IN 'A' ; ; ALL REGS EXCEPT PSW PRESERVED, CY SET AS IN GHXN ; GHXB: CALL GHXN ;GET LEFT NIBBLE RC ;LEAVE IF NON-HEX PUSH B ;SAVE BC RLC ;SHIFT RLC ; TO RLC ; LEFT RLC ; NIBBLE MOV B,A ;AND SAVE IN B CALL GHXN ;GET RIGHT NIBBLE JC $+4 ;JMP IF NON-HEX ADD B ;ADD IN LEFT NIBBLE POP B ;RESTORE BC RET ;AND EXIT ; ; ROUTINE TO GET A HEX WORD FROM TTYI ; ; CALLING SEQUENCE ... ; ; CALL GHXW ;GET HEX WORD TO HL ; JC NONHX ;NON-HEX IF CY SET ; ... ;OK, WORD IN HL ; ; IF INPUT VALUE IS VALID HEX THEN VALUE WILL BE IN HL ; WITH ALL OTHER REGISTERS PRESERVED AND CY RST ; ; IF INPUT IS INVALID, HL WILL BE PARTIALLY MODIFIED ; AND CY WILL BE SET AND 'A' WILL HAVE THE ; ILLEGAL NON-HEX CHARACTER. ; GHXW: STC ;SET AND CMC ; CLEAR CY PUSH PSW ;SAVE STATUS CALL GHXB ;GET HIGH HEX BYTE MOV H,A ;AND SET TO H JNC GHX2 ;JMP IF VALID POP PSW ;RESTORE STATUS MOV A,H ;SET A TO BAD CHARACTER STC ;SET CY RET ; AND EXIT GHX2: CALL GHXB ;GET LOW HEX BYTE MOV L,A ; AND SET TO L JNC GHX3 ;JMP IF VALID POP PSW ;INVALID, RESTORE STATUS MOV A,L ;SET A TO BAD CHAR STC ; SET CARRY RET ; AND RETURN GHX3: POP PSW ;ALL OK RET ; SO RET WITH HL SET TO WORD ; ; ROUTINE TO STORE A BYTE IN MEMORY WITH READ-BACK CHK ; ; CALLING SEQUENCE ... ; ; ... ;ADDRESS IN HL ; ... ;DATA IN 'A' ; CALL STORE ;STORE THE BYTE ; ... ;RETURNN HERE IF OK ; ; ALL REGISTERS PRESERVED ; ; IF READ-BACK CHECK FAILS, AND APPROPRIATE ERROR ; MESSAGE WILL BE TYPED, AND CONTROL RETURNED TO ; THE MONITOR. ; STORE: MOV M,A ;STORE THE BYTE CMP M ;READ-BACK CHECK RZ ;LEAVE IF OK PUSH H ;ERROR, SAVE VECTOR LXI H,M4 ;TYPE ERROR CALL MSG ; MESSAGE POP H ;RESTORE VECTOR CALL THXW ; AND TYPE ADDRESS JMP NEXT ;AND RETURN TO EXEC ; ; MEMORY EXAMINE/MODIFY ROUTINES ; ; THE FOLLOWING ROUTINES HANDLE MEMORY EXAMINES ; AND MODIFIES. THE ADDRESS OF THE MEMORY LOCATION ; CURRENTLY BEING ACCESSED IS IN 'ADR'. TO INITIALISE ; 'ADR', THE MONITOR COMMAND 'A' IS USED. ; ; ** A 1234 ; ; WILL SET THE 'ADR' TO THE VALUE 1234 (HEX) ; ; THE ROUTINE WILL THEN RETURN THE CARRIAGE, ; TYPE VALUE OF 'ADR' AND IT'S CONTENTS IN HEX, ; AND WAIT FOR ONE OF THE FOLLOWING INPUTS: ; ; A VALID HEX BYTE TO REPLACE THE VALUE TYPED ; IN WHICH CASE THE ROUTINE WILL ; 'STORE' THE BYTE, INCREMENT 'ADR', AND ; DO THE NEXT ADDRESS. ; ; A LINE-FEED WILL CAUSE THE NEXT ADDRESS TO BE ; ACCESSED WITH-OUT MODIFYING THE CURRENT ONE ; ; A CARRIAGE-RETURN WILL RETURN CONTROL TO THE ; MONITOR. ; ; A MINUS SIGN WILL CAUSE THE 'ADR' TO BE ; DECREMENTED BY ONE. ; ; THE LF AND '-' MAY BE ENTERED AS A ; MONITOR COMMAND ALSO AND WILL PERFORM THE SAME ; FUNCTION. ; ; IN ADDITION, THE COMMAND '.' FROM THE ; MONITOR WILL CAUSE THE CONTENTS OF THE CURRENT ; 'ADR' TO BE TYPED AS IF THE COMMAND 'A' WITH ; 'ADR' HAD BEEN ENTERED. ; GETAD: ;FROM COMMAND 'A' CALL SPACE ;TYPE A SPACE CALL GHXW ; AND GET 'ADR' JNC GTA1 ;JMP IF VALID ILLCH: LXI H,M3 ;ILLEGAL INPUT JMP ILLEG+3 ; MESSAGE AND BACK TO ; MONITOR. GTA1: SHLD ADR ;SAVE 'ADR' LOCAT: ;FROM COMMAND '.' ALSO CALL CRET ;RETURN CARRIAGE LHLD ADR ;FETCH 'ADR' CALL THXW ; AND PRINT IT CALL SPACE ;SPACE MOV A,M ;FETCH CONTENTS CALL THXB ; AND TYPE CALL SPACE ;SPACE CALL GHXB ; AND GET DATA OR COMMAND JC NONHX ;NON-HEX INPUT CALL STORE ;STORE THE NEW VALUE MOV A,M ; AND CALL SPACE ; ECHO CALL THXB ; VALUE NXLOC: ;FROM COMMAND 'LF' ALSO LHLD ADR ;ACCESS INX H ; NEXT JMP GTA1 ;AND CONTINUE NONHX: CPI CR ;IF CR JZ NEXT ; RETURN TO MONITOR CPI LF ;IF LF JZ NXLOC ; ACCESS NEXT 'ADR' CPI '-' ;IF - ACCESS LAST JNZ ILLCH ;NOT CR, LF, OR - SO ILLEGAL LSTLC: ;FROM COMMAND '-' ALSO LHLD ADR ;DECREMENT DCX H ; 'ADR' JMP GTA1 ;AND CONTINUE ; ; ROUTINE TO NEGATE THE DE REGISTER ; ; CALLING SEQUENCE ... ; ; ... ;VALUE IN DE ; CALL NEGDE ;NEGATE DE ; ... ;RETURN HERE WITH DE= -DE ; NEGDE: PUSH PSW ;SAVE PSW MOV A,D ;FETCH D CMA ;COMPELEMENT MOV D,A ;AND RESTORE MOV A,E ;FETCH E CMA ; COMPLEMENT MOV E,A ; AND RESTORE INX D ;ADD ONE TO D POP PSW ;RESTORE PSW RET ;AND EXIT ; ; ROUTINE TO DUMP A BLOCK OF MEMORY TO TTY ; ; THIS ROUTINE WILL DUMP A BLOCK OF MEMORY ; ON THE TTY, 16 BYTES PER LINE WITH THE ADDRESS ; AT THE START OF EACH LINE. ; ; THE FOLLOWING MONITOR COMMAND IS USED: ; ; ** D XXXX YYYY ; ; WILL CAUSE THE CONTENTS OF MEMORY LOCATIONS ; XXXX TO YYYY TO BE PRINTED. XXXX AND YYYY MUST ; BOTH BE VALID FOUR DIGIT HEX ADDRESSES AND IF ; XXXX >= YYYY ONLY LOCATION XXXX WILL BE PRINTED. ; ; AFTER THE FIRST LINE, ALL LINES WILL START WITH AN ; ADDRESS THAT IS AN EVEN MULTIPLE OF 16. ; ; DUMP: CALL PU3 ;GET HEX ADDRESS CALL PU3 ;GET ANOTHER CALL OK? ; ; FROM ADDRESS IN HL, TO ADDRESS IN DE ; CALL NEGDE ;NEGATE DE FOR END CHECK DMRET: CALL CRET ;RETURN CARRIAGE CALL STOP ;LOOK FOR A STOP CALL THXW ;TYPE VECTOR ADDRESS DMN1: CALL SPACE DMNXT: CALL SPACE ;SPACE MOV A,M ;GET DATA CALL THXB ; AND DISPLAY CALL LAST1 ;SEE IF DONE MOV A,L ;CHECK FOR MOD 8 ANI 0FH CPI 8 ; ADDRESS JZ DMN1 ;SPACE IF MOD 8 CPI 0 ;CHECK FOR END OF LINE JZ DMN2 ;NEW LINE IF MOD 16 JMP DMNXT ; CONTINUE IF NOT ; LAST1: PUSH H ;SAVE MEM VECTOR DAD D ; ADD NEGATIVE END ADDRESS JC LAST2 ;DONE IF CARRY POP H ;RESTORE VECTOR INX H ;BUMP AND RET ; EXIT ; LAST2: POP H LAST3: INX H MOV A,L ANI 0FH JZ DMN2 CALL SPACE CALL SPACE CALL SPACE CPI 9 JNC LAST3 CPI 8 JNC LAST4 JMP LAST3 LAST4 CALL SPACE JMP LAST3 ; DMN2: DCX H MOV A,L ANI 0F0H MOV L,A CALL SPACE DMN3: CALL SPACE DMN4: MOV A,M CPI 020H JC DMN5 MOV A,M CPI 07FH JNC DMN5 JMP DMN6 DMN5: MVI A,02EH JMP DMN7 DMN6: MOV A,M DMN7: CALL TYPE CALL LAST MOV A,L ANI 0FH CPI 8 JZ DMN3 CPI 0 JZ DMRET JMP DMN4 ; ; STOP DRIVER A SPACE WILL STOP THINGS A RETURN WILL ; GET THINGS GOING AGIAN AND A BREAK WILL RETURN ; YOU TO THE MONITOR ; STOP: IN TTYS ;GET TTY STATUS ANI TIBSY ;CHECK FOR DATA READY JNZ STOP4 ;NO TTY INTRY GO STOP1: CALL GETCH ;GET A CHARACTER ANI 07FH ;STRIP PARITY CPI 00 ;CHECK FOR BREAK JZ NEXT CPI 0DH ;CHECK FOR RETURN JZ STOP3 CPI 20H ;CHECK FOR SPACE BAR JZ STOP2 JMP STOP1 ;LOOPING STOP2: MVI A,0CAH STA ST1 ;STORE IN RAM JMP STOPGO STOP3: MVI A,0C2H STA ST1 ;STORE IN RAM JMP STOPGO STOP4: LDA ST1 ;GET GO/NO WORD CPI 0CAH ;CHECK IF SPACE BAR JZ STOP1 STOPGO: RET ; ; JUMP - ROUTINE TO TRANSFER CONTROL ; ; THIS ROUTINE WILL ACCEPT AN ADDRESS FROM TTYI ; AND THEN RESTORE ALL REGISTERS TO THE STATE AS ; SAVED IN RAM ON ENTRY TO THE MONITOR AND TRANSFER ; CONTROL TO THE ADDRESS ENTERED. ; ; ** J 1234 ; ; JUMP TO LOCATION 1234H ; ; IN ADDITION TWO OTHER MODES ARE POSSIBLE. ; ; THE COMMAND ; ** J (CR) ; ; WILL CAUSE THE ADDRESS SAVED AS A RESULT OF ; A RST 0 TO BE USED FOR THE EXECUTION ADDRESS. ; INSERTING A RST 0 IN A PROGRAM AS A BREAKPOINT ; WILL CAUSE THE ENTIRE MACHINE STATE TO BE SAVED ; AND THE J (CR) WILL RETURN YOU TO THE POINT AFTER ; THE RST 0. ; OF COURSE, IF THE RST 0 REPLACED PART OF AN ; INSTRUCTION YOU MUST REPLACE THE RST 0 AND ; MODIFY THE ADDRESS WITH 'RP=' SO THAT YOU WILL GET ; BACK INTO THE PROGRAM AT THE PROPER PLACE. ; ; ALSO ; ; THE COMMAND ; ** J (LF) ; ; WILL CAUSE THE ADDRESS ENTERED WITH THE 'X' ; COMMAND TO BE USED AS IF IT WERE TYPED IN. ; ; THE CARRIAGE RETURN AND LINE FEED RESPONSES WILL ; CAUSE THE ADDRESS TO BE TYPED FOR VERFIFICATION AND ; AFTER THE ADDRESS THE 'OK?' PROMPT WILL REQUIRE A ; SPACE REPLY FOR EXECUTION TO PROCEED. OTHERWISE ; THE OPERATION WILL BE ABORTED. ; ; JUMP: ;COMMAND 'J' CALL SPACE ;SPACE CALL GHXW ;GET ADDRESS JNC JMP3 ;HEX ADDRESS ENTERED CPI CR ;SEE IF CR RESPONSE JNZ JMP1 ; NO, GO CHECK FOR LF LHLD SVPC ;GET SAVED PC VALUE JMP JMP2 ; AND GO PROCESS JMP1: CPI LF ;CHECK FOR LF RESPONSE JNZ ILLCH ; ALL OTHERS ILLEGAL LHLD XEQAD ;GET XEQ ADDRESS FROM 'X' JMP2: CALL THXW ;TYPE ADDRESS JMP3: CALL OK? ;OK? SHLD GOGO+1 ;SET UP FINAL JUMP MVI A,0C3H ;JMP COMMAND STA GOGO ; TO RAM LXI SP,SVE ;RESTORE REGS POP D ; TO POP B ; VALUES POP PSW ; IN RAM LHLD SVSP ;SAVED SP SPHL ;SET NEW SP LHLD SVHL ;AND HL JMP GOGO ; AND EXECUTE ; ; COMMAND 'G' - DIRECT GOTO ADDRESS ; GOTO: CALL PU3 ;GET HEX ADDRESS XCHG ; TO HL CALL OK? ;VFY PCHL ; THEN JMP ADR ; ; COMMAND 'X' - SET EXECUTION ADDRESS FOR 'J' ; GETXA: CALL PU3 ;GET HEX ADDRESS XCHG ;TO HL SHLD XEQAD ;SAVE IT JMP NEXT ; AND BACK TO NEXT ; ; OK? - ROUTINE TO VERIFY OPERATION ; ; CALLING SEQUENCE ... ; ; CALL OK? ;VERIFY ; ... ;RETURN HERE IF SPACE ; ;ABORT IF NOT ; ; ALL REGISTERS PRESERVED ; OK?: PUSH PSW ;SAVE PSW PUSH H ; AND HL LXI H,M7 ;ADR OF 'OK?' MSG CALL MSG ;PRINT IT LXI H,M8 ;POSSIBLE ABORT CALL CHIN ;GET ANSWER CPI ' ' ; SPACE? JNZ ILLEG+3 ;NO, GO ABORT POP H ;RESTORE HL POP PSW ; AND PSW RET ; AND LEAVE ; ; ROUTINE TO CHECK FOR LAST OPERATION IN ; DUMP, FILL, MOVE, ETC. ; LAST: PUSH H ;SAVE MEM VECTOR DAD D ; ADD NEGATIVE END ADDRESS JC NEXT ;DONE IF CARRY POP H ;RESTORE VECTOR INX H ;BUMP AND RET ; EXIT ; ; COMMAND 'M' - MOVE MEMORY BLOCK ; ; FORMAT ; ** M XXXX YYYY ZZZZ OK? ; ; WILL MOVE THE BLOCK OF MEMORY STARTING AT ; XXXX AND ENDING AT AND INCLUDING YYYY TO THE ; BLOCK STARTING AT ZZZZ. ; OBSERVE THE FOLLOWING RESTRICTIONS.... ; ; ; EITHER ZZZZ <= XXXX ; ; OR ZZZZ > YYYY ; ; THE ROUTINE MOVES BYTES IN ASCENDING MEMORY ORDER ; SO IF THE HEX ADDRESS VALUES DO NOT SATISFY ; THE ABOVE RULES, MOVED DATA WILL OVERWRITE DATA TO ; BE MOVED. ; MOVE: CALL PU3 ;GET XXXX PUSH D ;SAVE ON STACK CALL PU3 ;GET YYYY TO DE CALL PU3 ;GET ZZZZ TO DE, YYYY TO HL XCHG ;DE=Y, HL=Z, TOP=X XTHL ;DE=Y, TOP=Z, HL=X CALL NEGDE ;DE=-Y, TOP=Z, HL=X CALL OK? MOV1: MOV A,M ;GET THRU X XTHL ;HL=Z, TOP=X CALL STORE ;CHECKED STORE INX H ;BUMP Z XTHL ;RESTORE CALL LAST ;CHECK FOR END JMP MOV1 ; AND CONTINUE ; ; COMMAND /F/. FILL A BLOCK OF MEMORY WITH VALUE ; ; FORMAT: ; ** F XXXX YYYY VV OK? ; ; WILL CAUSE MEMORY LOCATIONS XXXX THRU YYYY ; INCLUSIVE TO BE SET TO THE VALUE VV (HEX). ; FILL: CALL PU3 ;DE=X CALL PU3 ;DE=Y, HL=X CALL NEGDE ;DE=-Y CALL SPACE CALL GHXB ;GET VV -> 'A' JC ILLCH ;MUST BE VALID HEX CALL OK? FILL1: CALL STORE ;STUFF IT CALL LAST ; CHECK IT JMP FILL1 ; AND CONTINUE IT ; **** TARBELL CASSETTE DRIVERS **** ; THIS IS A LIBRARY ROUTINE FOR THE MTF80 MONITOR AND USES ; SEVERAL SUBROUTINES WITHIN THE MONITOR. ; ; RICHARD B. KOLBLY SEPTEMBER 12, 1978 ; ; TAPE SYSTEM EQUATES! ; CASC EQU 6EH ;CASSETTE STATUS PORT CASD EQU 6FH ;CASSETTE DATA PORT RON EQU 11H ;READER ON BIT ROFF EQU 10H ;READER OFF BIT ; WRITE: CALL PU3 ;MONITOR ROUTINE TO GET REGISTER CALL PU3 CALL OK? ;MONITOR ROUTINE TO VERIFY ; ; *** HL HAS STORT ADDRESS,DE HAS BLOCK LENGTH *** ; MVI A,RON ;GET MOTOR START BIT OUT CASC ;SEND TO INTERFACE MVI A,20 ;SET UP FOR 20-SEC LEADER CALL LEDR ;WAIT! CALL TAPEW ;WRITE THE BLOCK TO TAPE! MVI A,ROFF ; ... RECORDER OFF! OUT CASC MVI A,07H ;WAKE UP OPERATOR CALL TYPE ;...WITH ALARM BELL! JMP NEXT ;BACK TO MONITOR... ; ; TREAD: CALL PU3 CALL PU3 CALL OK? SHLD BLKAD ;STORE BLOCK IN CASE OF ERROR.. MVI A,RON ;TURN RECORDER ON AND RESET OUT CASC CALL TAPER ;READ BLOCK OF TAPE MVI A,ROFF ;MOTOR OFF OUT CASC MVI A,07H ;WAKE UP OPERATOR... CALL TYPE ;...WITH ALARM BELL! JC TERR ;IF CARRY, TAPE ERROR JMP NEXT ;NO ERROR,BACK TO MONITOR ; ; TAPE ERROR REPORTING ROUTINE ; TERR: LXI H,M6 ;GET ERROR MESSAGE CALL MSG ;WRITE IT! LHLD BLKAD ;GET BLOCK THAT WAS BAD CALL THXW ;TYPE IT ON CONSOLE JMP NEXT ;ERROR REPORTED,GO HOME ; ; ROUTINE TO VERIFY THAT TAPE AGREES WITH MEMORY ; VERFY: CALL PU3 CALL PU3 CALL OK? ;REGISTERS SET UP MVI A,RON ;START RECORDER OUT CASC ;DO IT!!! LXI B,0 ;CLEAR B REGISTER FOR ERROR COUNT VLOP: IN CASC ;GET STATUS ANI 10H ;CHECK READY BIT JNZ VLOP ;WAIT TIL DATA AVAILABLE IN CASD ;GET DATA CMP M ;COMPARE WITH MEMORY JZ $+4 ;IF GOOD, SKIP... INX B ;OTHERWISE,UP THE ERROR COUNT INX H ;INCREMENT MEMORY POINTER DCX D ;DECREMENT BLOCK LENGTH COUNTER XRA A ;CLEAR ACCUMULATOR CMP D ;CHECK D AND E REGISTERS... JNZ VLOP ; ...FOR... CMP E ; ....BEING EMPTY! JNZ VLOP ; KEEP ON TRUCKING!!! MVI A,ROFF ;DONE WITH VERIFY,... OUT CASC ; ...TURN OFF RECORDER XRA A ; CHECK FOR ... CMP B ; ...ZERO... JNZ VEROR ; ...ERRORS CMP C ; JNZ VEROR ;DO ERROR ROUTINE... MVI A,07H ; WAKE UP OPERATOR... CALL TYPE ; ...WITH ALARM BELL! JMP NEXT ;BACK TO MONITOR ; VEROR: MOV L,C MOV H,B ;SET UP TO TYPE ERRORS CALL THXW ;TYPE NUMBER OF ERRORS ON CONSOLE LXI H,M9 ;GET APPROPRIATE ERROR MESSAGE CALL MSG ;WRITE POSTAMBLE JMP NEXT ;HOME AT LAST!!! M9: DB 'H ERRORS',07H,-1 ; ;UTILITY ROUTINES FOR USE IN TARBELL TAPE HANDLERS ; TAPEW: MVI B,0 ;SET CHECKSUM TO ZERO MVI A,3CH ;GET START BYTE CALL COUT ;WRITE TO CASSETTE MVI A,0E6H ;GET SYNC BYTE CALL COUT ;WRITE IT ON TAPE LOOP: MOV A,M ;GET BYTE FROM MEMORY CALL COUT ;WRITE TO TAPE ADD B ;GENERATE CHECKSUM MOV B,A ;PUT IN B REGISTER INX H ;INCREMENT MEMORY COUNTER DCX D ;DECREMENT BYTE COUNT XRA A ;CLEAR FOR END-OF COUNT CHECK CMP D ;HIGH ORDER ZERO? JNZ LOOP ;NO, GET MORE... CMP E ;LOW ORDER? JNZ LOOP ;NOT ZERO, DO MORE YET! MOV A,B ;PREPARE TO WRITE CHECKSUM CALL COUT ;CHECKSUM ON TAPE!!! RET ;DONE, BACK TO CALLER... COUT: PUSH PSW ;SAVE ACCUMULATOR IN CASC ;GET STATUS ANI 20H ;CHECK WOUTPUT READY JNZ $-4 ;LOOP TIL' READY POP PSW ;RECOVER DATA OUT CASD ;WRITE TO CASSETTE DATA RET ;BACK... ; ; TAPE READ SUBROUTINE...CALL WITH START IN HL, ; BLOCK LENGTH IN DE,...RETURNS WITH CY SET IF ; CHECKSUM ERROR AND ASSUMES MOTOR IS RUNNING! ; TAPER: MVI B,0 ;CLEAR CHECKSUM TIN: IN CASC ;GET STATUS ANI 10H ;CHECK READY BIT JNZ TIN ;LOOP TIL READY IN CASD ;GET INFORMATION CALL STORE ;PUT IN MEMORY ADD B ;GENERATE CHECKSUM... MOV B,A ;...AND SAVE IT INX H ;INCREMENT MEMORY POINTER DCX D ;DECREMENT BYTE COUNT XRA A ;NOW... CMP D ; ...CHECK... JNZ TIN ; ...FOR THE... CMP E ; ...END! JNZ TIN CHEK: IN CASC ANI 10H JNZ CHEK STC ;SET CARRY FLAG... CMC ;...AND CLEAR IT IN CASD ;NOW GET THE CHECKSUM OFF TAPE CMP B ;DOES CHECKSUM AGREE WITH TAPE? RZ ;RETURN IF NO ERROR STC ;IF ERROR, SET CARRY FLAG... RET ;AND RETURN ; ; DELAY ROUTINE---CALL WITH A REGISTER WITH APPROX NUMBER OF ; SECONDS REQUIRED...RETURNS WITH REGISTERS PRESERVED EXCEPT ; ACCUMULATOR. ; LEDR: ADD A ;DOUBLE ACCUMULATOR PUSH B ;SAVE REGISTERS FOR FURTHER USE MOV B,A ;STORE IN B REGISTER MVI C,-1 ;FILL C REGISTER XRA A ;CLEAR ACCUMULATOR DCR A ;COUNT IT DOWN JNZ $-1 ;LOOP TIL EMPTY DCR C ;COUNT DOWN C REGISTER JNZ $-6 ;LOOP AGAIN... DCR B ;COUNT DOWN MAIN REGISTER.. JNZ $-12 ;LOOP TIL EMPTY POP B ;DONE,RESTORE BC REGISTERS RET ; ; REGISTER EXAMINE/MODIFY ROUTINE ; ; THE MONITOR COMMAND 'R' FOLLOWED BY A SINGLE ; CHARACTER WILL CAUSE THE ENTRY SAVED ; CONTENTS OF THAT REGISTER TO BE PRINTED AND A ; MODIFICATION ACCEPTED. IF THE 'R' IS FOLLOWED BY ; A CR THEN ALL OF THE REGISTERS WILL BE PRINTED. ; ; RA - ACC ; RF - FLAGS, PSB ; RB - B ; RC - C ; RD - D ; RE - E ; RH - H ; RL - L ; RS - SP ; RP - PROGRAM COUNTER IF MONITOR 'CALLED' ; ; R(CR) - PRINT ALL REGISTERS ; ; REGISTERS S AND P WILL BE PRINTED AS 4 HEX DIGITS ; AND MODIFICATIONS TO THEM MUST BE 4 DIGITS ALSO. ; RXLST: DB 'AFBCDEHL',0 ;REGISTER LIST REGEX: ;FROM COMMAND 'R' CALL CHIN ;GET REGISTER ID CPI CR ;CHECK FOR CR JZ REXAL ;DO ALL IF CR PUSH PSW ;SAVE ID MVI A,'=' ;TYPE CALL TYPE ; = POP PSW ;RESTORE ID LXI D,SVPC ;ADDRESS OF PC CPI 'P' ;SEE IF JZ RX2 ;PRINT PC INX D ;POINT TO INX D ; SP CPI 'S' ;CHECK S JZ RX2 ; DO SP MOV B,A ;SAVE ID LXI H,RXLST ;LIST VECTOR LXI D,SVA ;ADDRESS OF 'A' STORAGE RX0: MOV A,M ;GET TABLE ID ANA A ;CHECK FOR END JZ ILLCH ;NOT IN TABLE CMP B ;CHECK INPUT ID JZ RX1 ;FOUND IT INX H ;NEXT TBL DCX D ;NEXT REG JMP RX0 ;CONTINUE RX1: LDAX D ;GET THE RGE CALL THXB ; AND PRINT IT CALL SPACE ;SPACE CALL GHXB ;AND WAIT FOR REQUEST JC RX1A ;NON-HEX SO SEE IF CR STAX D ;STORE INPUT IN RG JMP NEXT ;AND BACK TO MONITOR RX1A: CPI CR ;CR OK JZ NEXT ;BACK TO MON JMP ILLCH ;OTHERS ILLEGAL RX2: XCHG ;RG ADR TO HL MOV E,M ;GET LOW S OR P INX H ;BUMP VECTOR MOV D,M ;GET HIGH S OR P XCHG ;RG VAL TO HL CALL THXW ;TYPE WORD CALL SPACE ;SPACE CALL GHXW ;AND GET REQUEST JC RX1A ;IF NON-HEX XCHG ;RSTORE RAM VECTOR FOR RG MOV M,D ;STORE HIGH S OR P DCX H ;BUMP VECTOR DOWN MOV M,E ;STORE LOW S OR P JMP NEXT ;BACK TO MON RXTSE: CALL SPACE ;SPACE CALL TYPE ; TYPE ID MVI A,'=' ; THEN CALL TYPE ; = RET ; AND RETURN REXAL: CALL CRET ;RETURN CARRIAGE FOR ALL REGS LXI D,SVA ;ADDRESS OF 'A' LXI H,RXLST ;ID LIST RXA1: MOV A,M ;GET ID ANA A ;CHECK FOR LAST JZ RXA2 ;DONE SINGLES CALL RXTSE ;TYPE SPACE, ID, AND = LDAX D ;GET REG DCX D ;BUMP RG PNTR INX H ; AND LIST PNTR CALL THXB ;TYPE REGISTER JMP RXA1 ; AND CONTINUE RXA2: MVI A,'P' ;DO PC CALL RXTSE ;SP, ID, = LHLD SVPC ;GET PC CALL THXW ; AND PRINT MVI A,'S' ; DO SP CALL RXTSE ;SP,ID,= LHLD SVSP ;GET SP CALL THXW ;AND PRINT JMP NEXT ;BACK TO MON PU3: CALL SPACE ;SPACE CALL GHXW ;GET HEX WORD JC ILLCH ;IF BAD XCHG ;SAVE TO DE RET ; AND RETURN ;$$$$$$ ; TEST A PORT - CALLING SEQUENCE.... ; E XX YY ; DISPLAYS DATA YY FROM INPUT FORT XX ; PORTI: CALL SPACE CALL GHXB ;GET PORT NUMBER PUSH H LXI H,TEMPI ;POINT TO RAM LOCATION MVI M,0DBH ;SET UP 'INP' INSTR. INX H MOV M,A ;PORT NAME INX H ;NEXT LOCATION MVI M,0C9H ;RETURN INSTRUCTION CALL TEMPI ;DO IT! CALL SPACE CALL THXB ;TYPE DATA FROM PORT POP H ;RESTORE ORIGNAL REG JMP NEXT ;DONE!!! ; ; ROUTINE TO WRITE DATA TO A DESIGNATED PORT. ; CALLING SEQUENCE... ; **W XX YY OK? ; ; SENDS DATA YY TO PORT XX ; PORTO: CALL SPACE CALL GHXB ;GET PORT LOCATION STA TMPA ;SAVE IT! CALL SPACE CALL GHXB ;GET DATA TO BE SENT PUSH PSW ;SAVE ON STACK CALL OK? ;VERIFY OPERATION LXI H,TEMPI MVI M,0D3H ;'OUT' INSTRUCTION LDA TMPA ;GET PORT ASSIGNMENT INX H MOV M,A ;SET LOCATION INX H MVI M,0C9H ;'RET' INSTRUCTION POP PSW ;GET DATA BACK CALL TEMPI ; DO ASSIGNMENT! JMP NEXT ;DONE, BACK TO MONITOR ; ; ROUTINE TO TURN PRINTER ON OR OFF ; PONOFF: LDA IOBYTE ;GET ASSIGNMENT PUSH PSW ;SAVE ANI 1 ;MASK CONSOLE BITS CPI 1 ;TEST FOR PRINTER ON JZ POFF ;SEE IF TTY LXI H,M11 ;PRINTER ON CALL MSG ;..PRINT IT CALL OK? ;VERIFY POP PSW ;ZERO,MUST BE PRINTER OFF INR A ;TURN ON PRINTER PON: STA IOBYTE ; JMP NEXT ;TO MONITOR POFF: LXI H,M12 ;PRINTER OFF CALL MSG ;..PRINT IT CALL OK? ;VERIFY POP PSW ;HERE IF PRINTER ON ANI 0FCH ;TURN PRINTER OFF JMP PON ; ; SYSTEM MESSAGES ; M0: DB CR,LF,'SBMS/K6HIJ V6.0 09/20/80',LF,-1 M1: DB CR,LF,'MON> ',-1 M2: DB ' IS UNDEFINED',-1 M3: DB ' ??',-1 M4: DB CR,LF,'MEM WRITE ERROR AT ',-1 M5: DB ' PAUSE ',-1 M6: DB ' CHKSM ERR, BLOCK ',-1 M7: DB ' OK? ',-1 M8: DB ' ABORTED!',-1 M10: DB CR,LF,' A = ADDRESS EXAM . = EXAM CURRENT',CR,LF DB ' CR= EFFECTIVE NOP LF= EXAM NEXT',CR,LF DB ' - = EXAM LAST D = DUMP MEMORY',CR,LF DB ' F = FILL MEMORY G = GOTO MEM LOCATION',CR,LF DB ' M = MOVE MEMORY C = GET XEQ ADDRESS',CR,LF DB ' J = JUMP TO MEM R = REGISTER EXAM',CR,LF DB ' O = WRITE CASSETTE I = READ CASSETTE',CR,LF DB ' V = VERIFY CAS-MEM S = SEARCH MEM FOR XX',CR,LF DB ' E = READ A PORT W = WRITE TO A PORT',CR,LF DB ' B = PROGRAM ROM X = BOOT CP/M',CR,LF DB ' T = TOP OF RAM P = PRINTER ON/OFF',CR,LF DB ' H = HEX MATH K = SET PRINTER WIDTH',CR,LF DB ' Z = JUMP TO 0000H Y = PRINTER LINE SPACING',CR,LF DB ' U = DISASSEMBLER Q = PRINTER FORM FEED',CR,LF DB ' Z = JUMP TO 0000H L = PRINT MENU',CR,LF DB 'ESC= MEMORY TEST = = COPY ROM TO MEMORY',CR,LF,-1 M11: DB ' PRINTER ON',-1 M12: DB ' PRINTER OFF',-1 M13: DB CR,LF,' WHICH PRINTER CPI 10(1),12(2),13.5(3) OR 16.5(4)?',-1 M14: DB CR,LF,' WHICH PRINTER LINE/INCH 6(1),8(2) OR 12(3)? ',-1 ; ; INTEL DISASEMBLER ; ASSEM: CALL PU3 XCHG SHLD PC CALL OK? JMP DISAS RDBYT: LHLD PC MOV A,M INX H SHLD PC RET RGPRN: INR A ANI 07 CPI 06 JC RGP1 ADI 03 RGP1: CPI 05 JC RGP2 ADI 02 RGP2: ADI 41H MOV C,A JMP CO DECOD: MOV B,A ANI 0F0H RRC RRC RRC RRC ADI 90H DAA ACI 40H DAA MOV C,A CALL CO MOV A,B ANI 0FH ADI 90H DAA ACI 40H DAA MOV C,A JMP CO PRINT: MVI B,4 P1: MOV C,M CALL CO INX H DCR B JNZ P1 MVI C,20H JMP CO XTRAC: MOV A,D ANI 38H RRC RRC RRC RET CCPRN: CALL XTRAC ADD A MOV C,A LXI H,CCODE DAD B MOV C,M CALL CO INX H MOV C,M CALL CO MVI C,20H CALL CO JMP CO RPPRN: CALL XTRAC ANI 06 CPI 06 JNZ RGPRN MVI C,53H CALL CO MVI C,50H JMP CO DISAS: CALL STOP MVI C,0DH CALL CO MVI C,0AH CALL CO LHLD PC MOV A,H CALL DECOD MOV A,L CALL DECOD MVI C,20H CALL CO CALL CO CALL RDBYT CALL THXB MVI C,20H CALL CO INVA: LXI H,TABI LOOP1: CMP M JZ INVAL MOV D,A MVI A,0FDH CMP M JZ VALID MOV A,D INX H JMP LOOP1 INVAL: MVI C,'-' CALL CO CALL CO CALL CO JMP DISAS VALID: MOV A,D MOV D,A LXI H,TABLE LXI B,11H D1: CMP M JZ TG1 INX H DCR C JNZ D1 MVI C,0AH D2: CMP M JZ TG2 INX H DCR C JNZ D2 MVI C,6 D3: CMP M JZ TG3 INX H DCR C JNZ D3 ANI 0C0H CPI 40H JZ MG0 CPI 80H JZ MG1 MOV A,D ANI 0C7H SUI 04 JZ MG2 DCR A JZ MG3 DCR A JZ MG4 MOV A,D ANI 0C0H JZ MG5 MOV A,D ANI 0C7H SUI 0C0H JZ MG6 SUI 02 JZ MG7 SUI 02 JZ MG8 SUI 03 JZ MG9 MOV A,D ANI 07 MOV C,A LXI H,PPOP-1 DAD B CALL PRINT CALL XTRAC CPI 06 JNZ D6 LXI H,PPSW CALL PRINT JMP DISAS MG9: LXI H,PRST CALL PRINT CALL XTRAC CALL DECOD JMP DISAS MG8: MVI C,43H CALL CO CALL CCPRN JMP D7 MG7: MVI C,4AH CALL CO CALL CCPRN JMP D7 MG6: MVI C,52H CALL CO CALL CCPRN JMP DISAS MG5: LXI H,PLXI MOV A,D ANI 0FH DCR A JZ MGS1 CPI 04 JC D4 SUI 05 D4: ADD A ADD A MOV C,A DAD B CALL PRINT CALL RPPRN JMP DISAS MGS1: CALL PRINT CALL RPPRN MVI C,2CH CALL CO JMP D7 MG4: LXI H,PMVI CALL PRINT CALL XTRAC CALL RGPRN MVI C,2CH CALL CO JMP D8 MG3: LXI H,PDCR JMP D5 MG2: LXI H,PINR D5: CALL PRINT CALL XTRAC D6: CALL RGPRN JMP DISAS MG1: MOV A,D ANI 38H RRC MOV C,A LXI H,PADD DAD B CALL PRINT JMP D9 MG0: LXI H,PMOV CALL PRINT CALL XTRAC CALL RGPRN MVI C,2CH CALL CO D9: MOV A,D ANI 07 CALL RGPRN JMP DISAS TG3: MOV A,C ADD A ADD A MOV C,A LXI H,TAB3-4 DAD B CALL PRINT D7: CALL RDBYT MOV D,A CALL RDBYT CALL DECOD MOV A,D CALL DECOD JMP DISAS TG2: MOV A,C ADD A ADD A MOV C,A LXI H,TAB2-4 DAD B CALL PRINT D8: CALL RDBYT CALL DECOD JMP DISAS TG1: MOV A,C ADD A ADD A MOV C,A LXI H,TAB1-4 DAD B CALL PRINT JMP DISAS TABLE: DB 0 DB 7H DB 0FH DB 17H DB 1FH DB 27H DB 2FH DB 37H DB 3FH DB 76H DB 0C9H DB 0E3H DB 0E9H DB 0EBH DB 0F3H DB 0F9H DB 0FBH DB 0C6H DB 0CEH DB 0D3H DB 0D6H DB 0DBH DB 0DEH DB 0E6H DB 0EEH DB 0F6H DB 0FEH DB 22H DB 2AH DB 32H DB 3AH DB 0C3H DB 0CDH TAB1: DB 'EI SPHLDI XCHG' DB 'PCHLXTHLRET HLT ' DB 'CMC STC CMA DAA ' DB 'RAR RAL RRC RLC ' DB 'NOP ' TAB2: DB 'CPI ORI XRI ANI ' DB 'SBI IN SUI OUT ' DB 'ACI ADI ' TAB3: DB 'CALLJMP LDA STA ' DB 'LHLDSHLD' PMOV: DB 'MOV ' PADD: DB 'ADD ADC SUB SBB ' DB 'ANA XRA ORA CMP ' PINR: DB 'INR ' PDCR: DB 'DCR ' PMVI: DB 'MVI ' PLXI: DB 'LXI STAXINX DAD ' DB 'LDAXDCX ' PRST: DB 'RST ' PPSW: DB 'PSW ' PPOP: DB 'POP PUSH' CCODE: DB 'NZZ NCC ' DB 'POPEP M ' CO: PUSH PSW MOV A,C CALL TYPE POP PSW RET TABI: DB 8H DB 10H DB 18H DB 20H DB 28H DB 30H DB 38H DB 0CBH DB 0D9H DB 0DDH DB 0EDH DB 0FDH ZZEND: DB -1 ; ; 8080/Z-80 MEMORY TEST VERSION 1.1 ; ; THERE IS NO MEMORY TEST AVAILABLE THAT CAN BE ; CALLED THE "DEFINITIVE MEMORLY TEST PROGRAM". ; ; THE FOLLOWING IS ONE THAT WILL AT LEAST PROVIDE ; SOME DIAGNOSTIC ASSISTANCE, AS WELL AS SOME ; DEGREE OF CONFIDENCE. ; ; THE BEST TEST IS A FEW WEEKS OF TIME, RUNNING ; THE SYSTEM, AND EXERCISING THE SYSTEM AS A ; WHOLE. YOU WILL KNOW SOON ENOUGH IF THE ; MEMORY IS SOUND ; ; THIS PROGRAM STARTS AT ADDRESS 0DF00H. (YOU MAY TEST ; MEMORY FROM 0000H ON UPWARDS. MAX=0FFFFH). THE ; PROGRAM HAS BEAN MODIFIED TO RUN IN ROM AND WILL TEST ; MEMORY FROM 0000H UPWARD. ; ; THIS PROGRAM WILL SIGN ON, AND ASK FOR THE RANGE. ; THIS SHOULD BE GIVEN IN HEX; "START"[,]"FINISH". ; IT WILL TEST CONTINOUSLY UNTILL A CONTROL-C IS ; SEEN ON THE KEYBOARD. ERRORS WILL BE PRINTED OUT ; WITH THE ADDRESS OF THE ERROR, THE TEST BYTE, ; AND THE MEMORY ERROR PATTERN. THE BITS THAT DON'T ; AGREE ARE "1". ALSO, WHILE THE TEST IS IN PROGRESS, ; A NUMBER WILL BE PRINTED ON THE CONSOLE FOR EACH ; LOOP THROUGH ALL TESTS. EXA 1,,,4,,,71,,,4,,6. ; ; ; STAT: EQU 0H ;STATUS PORT DATA: EQU 1H ;DATA PORT TTBE: EQU 80H ;XMIT EMPTY TTDA: EQU 1H ;RECIEVE DATA AVAILABLE CR: EQU 0DH ;CARAGE RETURN LF: EQU 0AH ;LINE FEED ; ; ; MEMT: LXI SP,STACK;SET UP A STACK LXI H,MSG0 ;SIGN ON MESSAGE CALL TYP LXI H,TEMP ;INITIALIZE TEMP. VALUES MVI M,0 INX H MVI M,40H CALL PU3 ;GET FIRST ADDRESS TO TEST CALL PU3 ;GET LAST ADDRESS WE WANT TO CHECK... CALL OK? ;...AND MAKE SURE THAT'S WHAT WE WANT!!! ; DOIT: PUSH H ;START TESTING T1: MVI M,0AAH ;10101010 PATTERN INX H MVI M,55H ;01010101 PATTERN CALL HILO ;RANGE SATISFIED YET? JNC T1 CALL DELAY ;BITS ARE TRICKY AT TIMES POP H ;RESTORE START POINTER PUSH H ;SAVE IN STACK T2: MVI A,0AAH MOV B,M ;PICK UP MEMORY BYTE CMP B ;NOW VERIFY MEMORY CNZ ERROR ;TELL IF BAD INX H MVI A,55H MOV B,M CMP B CNZ ERROR CALL HILO ;RANGE TEST JNC T2 POP H PUSH H T3: MVI M,055H ;REVERSE (CHECKERBOARD) INX H MVI M,0AAH CALL HILO JNC T3 CALL DELAY POP H PUSH H T4: MVI A,55H MOV B,M CMP B CNZ ERROR INX H MVI A,0AAH MOV B,M CMP B CNZ ERROR CALL HILO JNC T4 POP H PUSH H T5: MVI M,0FFH ;ALL ONES CALL HILO JNC T5 CALL DELAY POP H PUSH H T6: MVI A,0FFH MOV B,M CMP B CNZ ERROR CALL HILO JNC T6 POP H PUSH H MVI C,0 ;SEQUENTIAL NUMBERS TEST T7: MOV M,C ;START WITH ZERO INR C CALL HILO JNC T7 CALL DELAY POP H PUSH H MVI C,0 T8: MOV A,C INR C MOV B,M CMP B CNZ ERROR CALL HILO JNC T8 POP H PUSH H T9: MOV M,H ;PAGE DECODING TEST INR H CALL HILO+1 ;JUST INCREMENT H REG JNC T9 CALL DELAY POP H PUSH H TA: MOV A,H MOV B,M CMP B CNZ ERROR INR H CALL HILO+1 JNC TA POP H PUSH H TB: MOV A,M ;FAST COMPLIMENT TEST CMA MOV M,A MOV B,M CMP B CNZ ERROR MVI M,00H ;ZERO MEMORY TEST CALL HILO JNC TB CALL DELAY POP H PUSH H TC: XRA A ;TEST FOR STILL ZERO MOV B,M CMP B CNZ ERROR CALL HILO JNC TC CALL STO ;SEE IF CONSOLE WANT TO ABORT LXI H,TEMPO ;PICK UP COUNTER MOV A,M ANI 7 ORI '0' ;COUNT OF THE NUMBER OF CALL SEND ; TIMES THROUGH THE MEMORY INR M CM LINE ;CRLF EACH 64 CHARACTERS POP H JMP DOIT ;DO ALL OF THIS AGAIN ; ; ; STO: IN STAT ;SEE IF CONSOLE WANTS TO STOP ANI TTDA RNZ IN DATA ANI 7FH CPI 3 ;CONTROL-C RNZ JMP BEGIN ;INSERT A MONITOR JUMP HERE DELAY: MVI H,0FFH ;CAN BE SHORTENED IF TESTING DELO: MVI L,0FFH ;LARGE AMOUNTS OF MEMORY DCR L JNZ $-1 DCR H JNZ DELO RET HILO: INX H MOV A,E SUB L MOV A,D SBB H RET ; ERROR: PUSH PSW ;SAVE TEST BYTE LDA TEMP ;SEND MESSAGE? ORA A JNZ NO ;NO CMA STA TEMP ;MESSAGE SENT PUSH H LXI H,MSG1 CALL TYP POP H NO: MOV A,H ;SEND HIGH BYTE OF ADDRESS CALL WRIT2 MOV A,L ;AND LOW BYTE CALL WRIT2 CALL BLK ;SPACE OVER POP PSW ;GET TEST BYTE PUSH PSW ;SAVE AGAIN CALL WRIT2 ;PRINT IT CALL BLK POP PSW ;GET BYTE BACK XRA B ;DET BAD BIT LOC. MVI B,8 ;NUMBER OF BITS/BYTE BIT: RAL ;SET/RESET CARRY PUSH PSW ;SAVE THE BAD BITS MVI A,('0')/2 ADC A ;MAKE '0' OR '1' CALL SEND POP PSW ;GET BAD BYTE DCR B JNZ BIT ;PUMP EM OUT. CALL CRLF JMP STO ;SEE IF CONSOLE WANTS TO STOP WRIT2: PUSH PSW ;BINARY TO ASCII HEX RRC RRC RRC RRC CALL STDDA POP PSW STDDA: ANI 0FH ;THIS DAA IS CUTE ADI 90H DAA ;(THANKS, INTEL) ACI 40H DAA ; SEND: JMP TYPE ;MAIN TELETYPE OUTPUT BLK: MVI A,' ' CALL SEND JMP SEND LINE: MVI M,40H ;RESET TEST COUNTER CRLF MVI A,CR ;CRLF ON CONSOLE CALL SEND MVI A,LF JMP SEND ; CHK: CPI ',' ;SPACE OR COMMA BETWEEN ADDR RZ CPI ' ' RZ CPI CR ;TERMINATION? JNZ MEMT ;HHMMM..... MOV A,B DCR A JNZ MEMT ;TOO MANY OR TOO FEW PARAMS JMP CRLF ; KBD: IN STAT ;MAIN TELETYPE INPUT ROUTINE ANI TTDA JNZ KBD IN DATA ANI 7FH ;CLR PARITY JMP SEND ;ECHO INPUT ; TYP: CALL STO ;TEST FOR AN ABORT MOV A,M ;MESSAGE SENDER ROUTINE ORA A RZ CALL SEND INX H JMP TYP ; ; ; MSG0: DB CR,LF DB 'MEMORY TEST VER. 1.1' DB CR,LF DB 'RANGE- ',00 MSG1: DB CR,LF DB 'ADDR TEST 76543210 -BAD BITS' DB CR,LF,00 ; ; ; TITLE 'ROM 2708 EPROM PROGRAMMER' ; PAGE 56 ; ; SOFTWARE WRITTEN BY RANCIS ADAMS ; MODIFIED BY RICHARD L BERG ; SUBROUTINES FROM AMS80 MONITOR ; ; HARDWARE DESIGNED BY: ; FRANCIS ADAMS ; 685 LAGUNA DRIVE ; CORAONA, CALIF.,91720 ; 1-414-737-0170 ; ; PROGRAM TIME 3:20 ; RAMM EQU 0DFFFH POFF1 EQU 0A8H QTYP EQU 0FC01H PROM EQU 9 L4AS EQU 80H L8AS EQU 90H H2AS EQU 0A8H L4DS EQU 0B0H H4DS EQU 0C0H DISA EQU 0A8H OF26 EQU 0F0H BEEP EQU 07H ON12 EQU 0A0H ;CR EQU 0AH ;LF EQU 0DH ; ; AMS80 SUBROUTINES USED ; ;THXB EQU 0E01EH ;GHXW EQU 0E02AH ;THXW EQU 0E021H ;TYPE EQU 0E003H ;GETCH EQU 0E006H ;MSG EQU 0E012H ;OK? EQU 0E033H ;ILLEG EQU 0E0A5H ;M8 EQU 0F08DH ;NEXT EQU 0E009H ;STOP EQU 0E036H ; COPY: LXI SP,STACK CALL RPROG1 LXI H,MSG2A CALL MSG CALL GHXW ;GET LOAD ADDRESS TO HL CALL OK? LXI D,0 COPY2: CALL ADRS CALL STALL IN PROM MOV M,A PUSH H PUSH D XCHG DAD B POP D POP H INX D INX H JNC COPY2 JMP NEXT RPROG: LXI SP,STACK CALL RPROG1 JMP RPROG2 RPROG1: LXI H,00 SHLD ROMST LXI B,QTYP MVI A,26 CALL TYPE MVI A,DISA OUT PROM RET RPROG2: LXI H,MSG2 CALL MSG CALL OK? CALL CHKS LXI H,MSG1A CALL MSG JMP PROG CHKS: LXI D,0 CALL ADRS CALL STALL IN PROM CPI 0FFH CNZ ERROR2 PUSH D XCHG DAD B POP D INX D JNC CHKS+3 RET MSG1A: DB 'IF NO ERRORS LISTED',CR,LF DB 'ENABLE PROGRAMMER',CR,LF DB ' INPUT STARTING ADDRESS' DB CR,LF,07H,2AH,-1 MSG2: DB 'CHECKING FOR ERASED EPROM' DB CR,LF,CR,LF,-1 MSG2A: DB 'COPY ROM TO LOCATION ',-1 MSG3: DB 'PROGRAMMING COMPLETE, TURN' DB CR,LF,07H DB ' PROGRAM SWITCH TO READ' DB CR,LF,-1 MSG3A: DB 'VERIFYING EPROM',CR,LF,-1 MSG4: DB 'THE PRECEEDING LIST REPRESENTS' DB CR,LF DB 'ERRORS IN EROM, IF NO LIST' DB CR,07H,LF,CR,LF DB 'PROGRAMMING COMPLETE',-1 ADRS: MOV A,E ANI 0FH ADI L4AS OUT PROM MOV A,E RAR RAR RAR RAR ANI 0FH ADI L8AS OUT PROM MOV A,D ANI 03H ADI H2AS OUT PROM RET ADR1: MOV A,E ANI 0FH ADI L4AS OUT PROM MOV A,E RAR RAR RAR RAR ANI 0FH ADI L8AS OUT PROM MOV A,D ANI 03H STA ROMST2 ADI 0A0H OUT PROM RET ERROR1: MVI A,BEEP CALL TYPE CALL THXW MVI A,20H CALL TYPE MOV A,M CALL THXB MVI A,20H CALL TYPE ERROR2: MVI A,BEEP CALL TYPE XCHG CALL THXW MVI A,20H CALL TYPE IN PROM CALL THXB MVI A,LF CALL TYPE MVI A,CR CALL TYPE XCHG CALL STOP RET PROG: CALL GHXW CALL OK? SHLD ROMST1 MVI A,CR CALL TYPE MVI A,LF CALL TYPE MVI A,ON12 OUT PROM PRO1: LXI D,0 LHLD ROMST1 PRO2: CALL QUIT CALL ADR1 CALL DATA1 CALL PULS PUSH H PUSH D XCHG DAD B JC PASS POP D POP H INX H INX D LXI SP,STACK JMP PRO2 PULS: MVI A,70H OUT PROM MVI A,18H DCR A JNZ $-1 MVI A,0F0H OUT PROM RET DATA1: MOV A,M ANI 0FH ADI L4DS OUT PROM MOV A,M RAR RAR RAR RAR ANI 0FH ADI H4DS OUT PROM RET PASS: LHLD ROMST INX H SHLD ROMST LXI D,0FE0BH DAD D JNC PRO1 VERF: LDA ROMST2 ADI POFF1 OUT PROM LXI H,MSG3 CALL MSG CALL OK? LXI H,MSG3A CALL MSG LHLD ROMST1 LXI D,0 VERF1: CALL QUIT CALL ADRS CALL STALL IN PROM CMP M CNZ ERROR1 PUSH D PUSH H XCHG DAD B POP H INX H POP D INX D JNC VERF1 LXI H,MSG4 CALL MSG JMP NEXT STALL: MVI A,0FFH DCR A JNZ $-1 RET QUIT: IN 1 ANI 7FH CPI 1BH JZ TERM RET TERM: MVI A,DISA OUT PROM LXI H,M8 JMP ILLEG+3 ENDROM: EQU $ ; ; SYSTEM RAM AREA DEFINITIONS ; ORG RAM ; MONITOR REGISTER SAVE AREA ; SVPC: SVPCL: DS 1 ;SAVED PC LOW SVPCH: DS 1 ;SAVED PC HIGH SVSP: SVSPL: DS 1 ;SAVED SP LOW SVSPH: DS 1 ;SAVED SP HIGH SVHL: SVL: DS 1 ;SAVED L SVH: DS 1 ;SAVED H SVE: DS 1 ;SAVED E SVD: DS 1 ;SAVED D SVC: DS 1 ;SAVED C SVB: DS 1 ;SAVED B SVF: DS 1 ;SAVED PSB, FLAGS SVA: DS 1 ;SAVED ACC ECHO: DS 1 ;CHIN ECHO FLAG, <>0=ECHO ;=0 = NO ECHO ADR: DS 2 ;EXAMINE/MODIFY ADDRESS TMPA: ;TEMP STORAGE LOCATIONS GOGO: DS 3 ;'JUMP' STORAGE TEMPI: DS 3 ;SPACE FOR PORT DRIVER ROUTINES XEQAD: DS 2 ;'X' EXECUTION ADDRESS BLKAD: DS 2 ;'L' BLOCK ADDRESS ;VDPTR: DS 2 ; VIDEO DISPLAY CURSOR POINTER ;VDHLD: DS 1 ; VIDEO DISPLAY CHARACTER HOLD ;SPEED: DS 1 ; CRT DISPLAY SPEED FLAG IOBYTE: DS 1 ;I/O CONFIGURATION BYTE BA1: DS 1 ;BAUD CONTROL PFF: DS 1 ;FORM FEED NUMBER PFF1: DS 1 ;FORM FEED COUNTER PW1: DS 2 ;PRINTER WIDTH PW2: DS 2 ;TEMP STORAGE PSP2: DS 1 ;PRINTER LINES/INCH PSP3: DS 2 ;TEMP STORAGE ST1: DS 1 ;STOP TEMP STORAGE PC: DS 2 ;START ADD OF DISAS STD: DS 1 ;STORAGE AREA FOR SEARCH TEMP: DS 1 TEMPO: DS 1 ROMST: DS 2 ;STORAGE FOR ROM PROGRAMER ROMST1: DS 2 ROMST2: DS 2 END